diff --git a/.github/workflows/generate-builds.yml b/.github/workflows/generate-builds.yml index 19f25345bc..ab6335a362 100644 --- a/.github/workflows/generate-builds.yml +++ b/.github/workflows/generate-builds.yml @@ -15,7 +15,7 @@ jobs: with: submodules: true - name: Configure ccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1.2.22 with: save: ${{ github.ref_name == github.event.repository.default_branch }} key: ${{ runner.os }}-otr-ccache-${{ github.ref }}-${{ github.sha }} @@ -83,7 +83,7 @@ jobs: with: submodules: true - name: Configure ccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1.2.22 with: create-symlink: true save: ${{ github.ref_name == github.event.repository.default_branch }} @@ -163,7 +163,7 @@ jobs: sudo apt-get update sudo apt-get install -y $(cat .github/workflows/apt-deps.txt) - name: Configure ccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1.2.22 with: save: ${{ github.ref_name == github.event.repository.default_branch }} key: ${{ runner.os }}-ccache-${{ github.ref }}-${{ github.sha }} @@ -277,7 +277,7 @@ jobs: with: submodules: true - name: Configure sccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1.2.22 with: variant: sccache max-size: "2G" diff --git a/.gitmodules b/.gitmodules index 7098d9d082..6716a1dddd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,7 @@ [submodule "libultraship"] path = libultraship url = https://github.com/kenix3/libultraship.git + branch = port-maintenance [submodule "ZAPDTR"] path = ZAPDTR url = https://github.com/harbourmasters/ZAPDTR diff --git a/CMakeLists.txt b/CMakeLists.txt index 4429cc5994..3e0743c5cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,10 +81,24 @@ add_compile_options($<$:/utf-8>) add_compile_options($<$:/Zc:preprocessor>) if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + if(NOT CMAKE_VS_PLATFORM_NAME) + set(CMAKE_VS_PLATFORM_NAME "x64") + endif() + + if("${CMAKE_VS_PLATFORM_NAME}" MATCHES "^[Aa][Rr][Mm]64$") + set(SOH_WINDOWS_ARM64 TRUE) + else() + set(SOH_WINDOWS_ARM64 FALSE) + endif() + include(CMake/automate-vcpkg.cmake) set(VCPKG_TRIPLET x64-windows-static) set(VCPKG_TARGET_TRIPLET x64-windows-static) + if(SOH_WINDOWS_ARM64) + set(VCPKG_TRIPLET arm64-windows-static) + set(VCPKG_TARGET_TRIPLET arm64-windows-static) + endif() vcpkg_bootstrap() vcpkg_install_packages(zlib bzip2 libzip libpng sdl2 sdl2-net glew glfw3 nlohmann-json tinyxml2 spdlog libogg libvorbis opus opusfile) @@ -103,7 +117,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") message("${CMAKE_VS_PLATFORM_NAME} architecture in use") if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64" - OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")) + OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32" + OR SOH_WINDOWS_ARM64)) message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!") endif() endif() @@ -121,6 +136,10 @@ set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_OBJCXX_FLAGS_RELEASE "-O2 -DNDEBUG") endif() +# IEEE 754 compliant floating-point rounding on arm64 macOS +if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + add_compile_options(-Xarch_arm64 -ffp-contract=off) +endif() if(NOT CMAKE_BUILD_TYPE ) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index 8fcd5966a0..55a336aa67 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -120,19 +120,20 @@ You can use a `flake.nix` file to instantly setup a development environment usin inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + pinned.url = "github:NixOS/nixpkgs/e6f23dc08d3624daab7094b701aa3954923c6bbb"; flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { self, nixpkgs, flake-utils }: + outputs = { self, nixpkgs, pinned, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; + pinned-pkgs = pinned.legacyPackages.${system}; in { devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ # Build tools - clang git cmake ninja @@ -144,6 +145,10 @@ You can use a `flake.nix` file to instantly setup a development environment usin SDL2.dev SDL2_net + # Assets pipeline + python3 + imagemagick + # Other libraries libpng libzip @@ -155,7 +160,7 @@ You can use a `flake.nix` file to instantly setup a development environment usin bzip2 # X11 libraries - xorg.libX11 + libx11 # Audio libraries libogg @@ -166,10 +171,16 @@ You can use a `flake.nix` file to instantly setup a development environment usin libopus.dev opusfile opusfile.dev + + # Runtime dependencies + zenity + ] ++ [ + # Version of clang-format used by decomp + pinned-pkgs.clang_14 ]; shellHook = '' echo "Shipwright development environment loaded" - echo "Available tools: clang, git, cmake, ninja" + echo "Available tools: clang, git, cmake, ninja, python3" ''; }; }); diff --git a/libultraship b/libultraship index fdcaf63367..1d98291404 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit fdcaf6336776d24a6408d016b0a52243f108f250 +Subproject commit 1d9829140444268827a1369095bcc93518ff3b4d diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 31955ebf90..1a92150509 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -22,10 +22,21 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") if(NOT CMAKE_VS_PLATFORM_NAME) set(CMAKE_VS_PLATFORM_NAME "x64") endif() + if("${CMAKE_VS_PLATFORM_NAME}" MATCHES "^[Aa][Rr][Mm]64$") + set(SOH_WINDOWS_ARM64 TRUE) + else() + set(SOH_WINDOWS_ARM64 FALSE) + endif() + if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64" OR SOH_WINDOWS_ARM64) + set(SOH_WINDOWS_64BIT TRUE) + else() + set(SOH_WINDOWS_64BIT FALSE) + endif() message("${CMAKE_VS_PLATFORM_NAME} architecture in use") if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64" - OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")) + OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32" + OR SOH_WINDOWS_ARM64)) message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!") endif() endif() @@ -235,7 +246,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") set_target_properties(${PROJECT_NAME} PROPERTIES VS_GLOBAL_KEYWORD "Win32Proj" ) - if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") + if(SOH_WINDOWS_64BIT) set_target_properties(${PROJECT_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE" ) @@ -259,7 +270,7 @@ endif() ################################################################################ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY) - if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") + if(SOH_WINDOWS_64BIT) string(CONCAT "MSVC_RUNTIME_LIBRARY_STR" $<$: MultiThreadedDebug @@ -329,7 +340,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE assets ) if (CMAKE_SYSTEM_NAME STREQUAL "Windows") - if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") + if(SOH_WINDOWS_64BIT) target_compile_definitions(${PROJECT_NAME} PRIVATE "$<$:" "_DEBUG;" @@ -410,7 +421,7 @@ endif() # Compile and link options ################################################################################ if(MSVC) - if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") + if(SOH_WINDOWS_64BIT) target_compile_options(${PROJECT_NAME} PRIVATE $<$: /w; @@ -447,7 +458,7 @@ if(MSVC) ${DEFAULT_CXX_EXCEPTION_HANDLING} ) endif() - if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") + if(SOH_WINDOWS_64BIT) target_link_options(${PROJECT_NAME} PRIVATE $<$: /INCREMENTAL @@ -635,7 +646,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") link_libraries(Opus::opus) find_package(OpusFile CONFIG REQUIRED) link_libraries(OpusFile::opusfile CONFIG REQUIRED) - if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") + if(SOH_WINDOWS_64BIT) set(ADDITIONAL_LIBRARY_DEPENDENCIES "libultraship;" "ZAPDLib;" diff --git a/soh/assets/custom/lang/en_US.json b/soh/assets/custom/lang/en_US.json new file mode 100644 index 0000000000..ca7396d8a3 --- /dev/null +++ b/soh/assets/custom/lang/en_US.json @@ -0,0 +1,1038 @@ +{ + "language_name": "English (US)", + "randomizer": { + "tricks": { + "acute_angle_clip": { + "name": "Acute angle clip", + "description": "Enables locations requiring jumpslash clips through walls which meet at an acute angle." + }, + "advanced_clips": { + "name": "Advanced clips", + "description": "Enables locations requiring clips through walls and objects requiring precise jumps or other tricks." + }, + "blank_a": { + "name": "Blank A", + "description": "Enables locations requiring blank A button; NOTE: this requires the 'Quick Putaway' restoration." + }, + "doom_jump": { + "name": "Doom Jump", + "description": "Enables locations requiring doom jumps." + }, + "epg": { + "name": "Entrance Point Glitch", + "description": "Enables locations requiring use of the Entrance Point Glitch." + }, + "equip_swap": { + "name": "Equip Swap", + "description": "Enables locations requiring use of equip swap; NOTE: this may expect the 'Allow cursor to be over any slot' enhancement to be turned off." + }, + "equip_swap_expects_dins": { + "name": "Equip Swap Requires Din's Fire", + "description": "Enables locations requiring use of equip swap once Din's Fire is found." + }, + "flame_storage": { + "name": "Flame Storage", + "description": "Enables locations requiring flame storage." + }, + "ground_clip": { + "name": "Ground Clip", + "description": "Enables locations requiring ground clips." + }, + "hess": { + "name": "HESS", + "description": "Enables locations requiring a Hyper Extended Super Slide." + }, + "hookshot_clip": { + "name": "Hookshot Clip", + "description": "Enables locations requiring Hookshot clips." + }, + "hookshot_jump": { + "name": "Hookshot Jump", + "description": "Enables locations requiring Hookshot jumps." + }, + "isg": { + "name": "ISG", + "description": "Enables locations requiring use of the infinite sword glitch." + }, + "visible_collision": { + "name": "Ignore Visible Collision", + "description": [ + "Allows ignoring visible barriers and objects that do not actually stop Link from walking, climbing or ", + "hitting things, without clipping.\n\n", + "This notably allows for walking through Kak's gate backwards, climb into the back of Impa's house as ", + "Adult from the coop,", + "and hitting Rusted Switches or boulders through Blocks, Ice and Walls.\n\n", + "This trick only applies to case where doing the thing is trivial, instances where it only works from ", + "certain angles are not part of this trick,", + "neither are any form of clips, including clipping Link's hitbox inside boulders with a jumpslash." + ] + }, + "hookshot_ladders": { + "name": "Hookshot Ladders", + "description": [ + "You can skip climb for hookshottable ladders can be skipped by hookshotting the top of the ladder from ", + "the correct distance and angle.\n", + "This is more difficult for some ladders than others, and a few are not possible.\n", + "Hookshotting climbable walls in the same way is not a trick, as it is trivial to get an angle that ", + "correctly ledge grabs." + ] + }, + "grottos_without_agony": { + "name": "Hidden Grottos without Stone of Agony", + "description": "Allows entering hidden grottos without the Stone of Agony." + }, + "fewer_tunic_requirements": { + "name": "Fewer Tunic Requirements", + "description": [ + "Normally the only hot area logic expects you to navigate without a Goron Tunic is Death Mountain Crater\n", + "and you are not expected to navigate underwater sections without a Zora Tunic.\n\n", + "With this trick you are expected to do any underwater area except Central Pillar,\n", + "any hot area except Volvagia and the Block lift room in Fire Temple\n", + "and the health needed to logically navigate Crater is decreased." + ] + }, + "unintuitive_jumps": { + "name": "Unintuitive Jumps", + "description": [ + "Many ledges can be overcome with particular jumps which are simple to execute without items.\n", + "This includes jumping from heights to dive deeper without scales,\n", + "though this trick doesn't cover Water Temple's Dragon Room." + ] + }, + "rusted_switches": { + "name": "Hammer Rusted Switches Through Walls", + "description": [ + "Applies to:\n", + "- Hitting Fire Temple Highest Goron Chest's Rusted Switch in the SoT Block without Song of Time.\n", + "- Hitting the rusted switch in Water Trial through the Ice.", + "- Hitting MQ Fire Temple Lizalfos Maze's Rusted Switch in the wall.\n", + "- Having Adult hammer the rock in the west side crawlspace of MQ Spirit so child can get through without bombchus.", + "- MQ Spirit Trial's Rusted Switch between the thrones without hitting the eye target to drop an Iron Knuckle." + ] + }, + "fire_rings": { + "name": "Fire Ring", + "description": [ + "Fire Rings can be run into while Link is invincible from having taken damage, ", + "letting you interact with some objects inside them such as large chests" + ] + }, + "bunny_hood_jumps": { + "name": "Bunny Hood Jumps", + "description": "Allows reaching locations using Bunny Hood's extended jumps." + }, + "damage_boost_simple": { + "name": "Simple damage boosts", + "description": "Allows damage boosts in order to reach further locations. Can be combined with \"Simple hover boosts\" for reaching far distances." + }, + "hover_boost_simple": { + "name": "Simple hover boosts", + "description": "Allows equipping of hover boots when Link is moving at high speeds to extend distance covered, often after recoil. Can be combined with \"Simple damage boosts\" for greater uses." + }, + "bombchu_beehives": { + "name": "Bombchu Beehives", + "description": "Allows exploding beehives with Bombchus." + }, + "blue_fire_mud_walls": { + "name": "Blue Fire Beyond Red Ice", + "description": [ + "Use Blue Fire to break mud walls, detonate bomb flowers, and break floor to King Dodongo.\n", + "Does not apply to MQ Dead Hand bomb flowers.\n", + "Using blue fire on bombflower to stop rolling goron also requires \"Stop Link the Goron with Din's Fire\".\n", + "Using blue fire arrows to break floor in King Dodongo's chamber also requires \"Dodongo's Cavern Smash the Boss Lobby Floor\"." + ] + }, + "open_underwater_chest": { + "name": "Open Underwater Chests", + "description": "Underwater chests can be opened by wearing iron boots and hookshotting the chest." + }, + "boulder_collision": { + "name": "Flawed Boulder Collision", + "description": [ + "From afar, boulder collision is disabled, allowing projectiles to pass through them.\n", + "Additionally, boulders do not have projectile collision from below, allow them to be shot into in some cases." + ] + }, + "item_extension": { + "name": "Item Extension", + "description": [ + "Slightly extends the range of projectiles such as Hookshot, Bow or Slingshot. Also allows clipping ", + "projectile past collision. Used for:\n", + "- Retrieving DMT Gold Skulltula beside bomb flower\n", + "- Hitting switch through wall in Spirit Temple's big mirror room with Bow, Slingshot, or Hookshot\n", + "- Hitting switch through wall in Spirit Trial with Bow or Slingshot\n", + "- Hitting switch through gate in Shadow Temple MQ with Bow or Slingshot" + ] + }, + "big_skulltula_pause_lift": { + "name": "Big Skulltula Pause Lift", + "description": "Pausing while a big skulltula is bobbing upwards slightly lifts it, eventually allowing passage without any items." + }, + "ground_jump": { + "name": "Ground Jump", + "description": "Enables requiring ground jumps." + }, + "ground_jump_hard": { + "name": "Hard Ground Jumps", + "description": [ + "Enables ground jumps which require some precision outside of setting up jump,\n", + "such as needing extra height with jumpslash or jumping while running with hover boots." + ] + }, + "slide_jump": { + "name": "Sliding Jumps", + "description": "Running forward while sliding sideways on ice can be used to jump on platforms." + }, + "voidout_collection": { + "name": "Voidout Collection", + "description": [ + "Some items can be collected by jumping to them, even if it results in voiding out. Used for:\n", + "- OGC Gold Skulltula\n", + "- HC wonder items without swim\n", + "- ZR wonder items without swim\n", + "- ZR Waterfall freestanding rupees without swim\n", + "- GV wonder items without swim\n", + "- GV Octorok grotto rupees without swim\n", + "- Colossus oasis fairies\n", + "- Deku Tree freestanding hearts before boss\n", + "- Water Temple near boss key chest Gold Skulltula\n", + "- Shadow MQ after boat and before boss Gold Skulltulas" + ] + }, + "bomb_detonation": { + "name": "Precise Bomb Detonation", + "description": [ + "This trick enables methods that rely on precisely timing the detonation of bombs, ", + "such as detonating bombs on the surface of the water to destroy underwater rocks ", + "or getting the Gold Skulltula in the first room of forest temple as Child." + ] + }, + "kf_adult_gs": { + "name": "Adult Kokiri Forest GS with Hover Boots", + "description": "Can be obtained without Hookshot by using the Hover Boots off of one of the roots." + }, + "lw_bridge": { + "name": "Jump onto the Lost Woods Bridge as Adult with Nothing", + "description": "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean." + }, + "lw_mido_backflip": { + "name": "Backflip over Mido as Adult", + "description": "With a specific position and angle, you can backflip over Mido." + }, + "lost_wood_navi_dive": { + "name": "Lost Woods Navi dive", + "description": "You need Deku Sticks or Kokiri Sword to dive with Navi for entering Zora's River." + }, + "lw_gs_bean": { + "name": "Lost Woods Adult GS without Bean", + "description": "You can collect the token with a precise Hookshot use, as long as you can kill the Skulltula somehow first. It can be killed using Longshot, Bow, Bombchus or Din's Fire." + }, + "hc_storms_gs": { + "name": "Hyrule Castle Storms Grotto GS with Just Boomerang", + "description": "With precise throws, the Boomerang alone can kill the Skulltula and collect the token, without first needing to blow up the wall." + }, + "hf_big_poe_without_epona": { + "name": "Big Poe without Epona", + "description": "Big Poes have a chance of appearing without Epona, you can shoot them quickly with only bow." + }, + "kak_tower_gs": { + "name": "Kakariko Tower GS with Jumpslash", + "description": "Climb the tower as high as you can without touching the Gold Skulltula, then let go and jumpslash immediately. By jump-slashing from as low on the ladder as possible to still hit the Skulltula, this trick can be done without taking fall damage." + }, + "kak_child_windmill_poh": { + "name": "Windmill PoH as Child with Precise Jumpslash", + "description": "Can jump up to the spinning platform from below as child with a precise jumpslash timed with the platforms rotation." + }, + "kak_rooftop_gs": { + "name": "Kakariko Rooftop GS with Hover Boots", + "description": [ + "Take the Hover Boots from the entrance to Impa's House over to the rooftop of Skulltula House. \n", + "From there, a precise Hover Boots backwalk with backflip can be used to get onto a hill above the side of the village.\n", + "And then from there you can Hover onto Impa's rooftop to kill the Skulltula and backflip into the token." + ] + }, + "gy_poh": { + "name": "Graveyard Freestanding PoH with Boomerang", + "description": "Using a precise moving setup you can obtain the Piece of Heart by having the Boomerang interact with it along the return path." + }, + "gy_child_dampe_race_poh": { + "name": "Second Dampe Race as Child", + "description": "It is possible to complete the second dampe race as child in under a minute, but it is a strict time limit." + }, + "gy_shadow_fire_arrows": { + "name": "Shadow Temple Entry with Fire Arrows", + "description": "It is possible to light all of the torches to open the Shadow Temple entrance with just Fire Arrows, but you must be very quick, precise, and strategic with how you take your shots." + }, + "dmt_shieldless_climb": { + "name": "Death Mountain Trail Child Climb Without Shield", + "description": [ + "Child can make it past the eruption to reach DMT Summit without a Hylian Shield or Nayru's Love", + "by backwalking or simply taking damage." + ] + }, + "dmt_soil_gs": { + "name": "Death Mountain Trail Soil GS without Destroying Boulder", + "description": "Bugs will go into the soft soil even while the boulder is still blocking the entrance. Then, using a precise moving setup you can kill the Gold Skulltula and obtain the token by having the Boomerang interact with it along the return path." + }, + "dmt_bombable": { + "name": "Death Mountain Trail Chest with Strength", + "description": "Child Link can blow up the wall using a nearby bomb flower. You must backwalk with the flower and then quickly throw it toward the wall." + }, + "dmt_hovers_lower_gs": { + "name": "Death Mountain Trail Lower Red Rock GS with Hover Boots", + "description": "After killing the Skulltula, the token can be collected without needing to destroy the rock by backflipping down onto it with the Hover Boots. First use the Hover Boots to stand on a nearby fence, and go for the Skulltula Token from there." + }, + "dmt_bean_lower_gs": { + "name": "Death Mountain Trail Lower Red Rock GS with Magic Bean", + "description": "After killing the Skulltula, the token can be collected without needing to destroy the rock by jumping down onto it from the bean plant, midflight, with precise timing and positioning." + }, + "dmt_js_lower_gs": { + "name": "Death Mountain Trail Lower Red Rock GS with Jumpslash", + "description": "After killing the Skulltula, the token can be collected without needing to destroy the rock by jumpslashing from a precise angle." + }, + "dmt_climb_hovers": { + "name": "Death Mountain Trail Climb with Hover Boots", + "description": "It is possible to use the Hover Boots to bypass needing to destroy the boulders blocking the path to the top of Death Mountain." + }, + "dmt_upper_gs": { + "name": "Death Mountain Trail Upper Red Rock GS with Backflip", + "description": "After killing the Skulltula, the token can be collected by backflipping into the rock at the correct angle." + }, + "dmt_bolero_biggoron": { + "name": "Deliver Eye Drops with Bolero of Fire", + "description": [ + "Playing a warp song normally causes a trade item to spoil immediately, however, it is possible use Bolero to reach Biggoron and still deliver the Eye Drops before they spoil. If you do not wear the Goron Tunic, the heat timer inside the crater will override the trade item's timer.\n", + "When you exit to Death Mountain Trail you will have one second to show the Eye Drops before they expire. You can get extra time to show the Eye Drops if you warp immediately upon receiving them.\n", + "If you don't have many hearts, you may have to reset the heat timer by quickly dipping in and out of Darunia's chamber or quickly equipping and unequipping the Goron Tunic.\n", + "This trick does not apply if \"Randomize Warp Song Destinations\" is enabled, or if the settings are such that trade items do not need to be delivered within a time limit." + ] + }, + "gc_pot": { + "name": "Goron City Spinning Pot PoH with Bombchu", + "description": "A Bombchu can be used to stop the spinning pot, but it can be quite finicky to get it to work." + }, + "gc_pot_strength": { + "name": "Goron City Spinning Pot PoH with Strength", + "description": "Allows for stopping the Goron City Spinning Pot using a Bomb Flower alone, requiring strength in lieu of inventory explosives." + }, + "gc_rolling_strength": { + "name": "Rolling Goron (Hot Rodder Goron) as Child with Strength", + "description": "Use the Bomb Flower on the stairs or near Medigoron. Timing is tight, especially without backwalking." + }, + "gc_leftmost": { + "name": "Goron City Maze Left Chest with Hover Boots", + "description": "A precise backwalk starting from on top of the crate and ending with a precisely-timed backflip can reach this chest without needing either the Hammer or Silver Gauntlets." + }, + "gc_grotto": { + "name": "Goron City Grotto with Hookshot While Taking Damage", + "description": "It is possible to reach the Goron City Grotto by quickly using the Hookshot while in the midst of taking damage from the lava floor." + }, + "gc_link_goron_dins": { + "name": "Stop Link the Goron with Din's Fire", + "description": "The timing is quite awkward." + }, + "dmc_hover_bean_poh": { + "name": "Crater's Bean PoH with Hover Boots", + "description": "Hover from the base of the bridge near Goron City and walk up the very steep slope." + }, + "dmc_bolero_jump": { + "name": "Death Mountain Crater Jump to Bolero", + "description": "As Adult, using a shield to drop a pot while you have the perfect speed and position, the pot can push you that little extra distance you need to jump across the gap in the bridge." + }, + "dmc_boulder_js": { + "name": "Death Mountain Crater Upper to Lower with Hammer", + "description": "With the Hammer, you can jumpslash the rock twice in the same jump in order to destroy it before you fall into the lava." + }, + "dmc_boulder_skip": { + "name": "Death Mountain Crater Upper to Lower Boulder Skip", + "description": "As adult, With careful positioning, you can jump to the ledge where the boulder is, then use repeated ledge grabs to shimmy to a climbable ledge. This trick supersedes \"Death Mountain Crater Upper to Lower with Hammer\"." + }, + "zr_lower": { + "name": "Zora's River Lower Freestanding PoH as Adult with Nothing", + "description": "Adult can reach this PoH with a precise jump, no Hover Boots required." + }, + "zr_upper": { + "name": "Zora's River Upper Freestanding PoH as Adult with Nothing", + "description": "Adult can reach this PoH with a precise jump, no Hover Boots required." + }, + "zr_hovers": { + "name": "Zora's Domain Entry with Hover Boots", + "description": "Can hover behind the waterfall as adult." + }, + "zr_cucco": { + "name": "Zora's Domain Entry with Cucco", + "description": "You can fly behind the waterfall with a Cucco as child." + }, + "zd_king_zora_skip": { + "name": "Skip King Zora as Adult with Nothing", + "description": "With a precise jump as adult, it is possible to get on the fence next to King Zora from the front to access Zora's Fountain." + }, + "zd_gs": { + "name": "Zora's Domain GS with No Additional Items", + "description": "A precise jumpslash can kill the Skulltula and recoil back onto the top of the frozen waterfall. To kill it, the logic normally guarantees one of Hookshot, Bow, or Magic." + }, + "zf_great_fairy_without_explosives": { + "name": "Zora's Fountain Great Fairy without Explosives", + "description": "It's possible to use silver gauntlets to pick up the silver rock and hammer to break the rock below it, allowing you to ledge grab the edge of the hole and get past the breakable wall (hammer can't break the wall itself)." + }, + "lh_lab_wall_gs": { + "name": "Lake Hylia Lab Wall GS with Jumpslash", + "description": "The jumpslash to actually collect the token is somewhat precise." + }, + "lh_lab_diving": { + "name": "Lake Hylia Lab Dive without Gold Scale", + "description": "Remove the Iron Boots in the midst of Hookshotting the underwater crate." + }, + "lh_water_hookshot": { + "name": "Water Temple Entry without Iron Boots using Hookshot", + "description": "When entering Water Temple using Gold Scale instead of Iron Boots, the Longshot is usually used to be able to hit the switch and open the gate. But, by standing in a particular spot, the switch can be hit with only the reach of the Hookshot." + }, + "gv_crate_hovers": { + "name": "Gerudo Valley Crate PoH as Adult with Hover Boots", + "description": "From the far side of Gerudo Valley, a precise Hover Boots movement and jump-slash recoil can allow adult to reach the ledge with the crate PoH without needing Longshot. You will take fall damage." + }, + "gv_child_cucco_jump": { + "name": "Gerudo Valley Jump Fence with Cucco", + "description": "Using cucco as child, it's possible to jumpslash over the gate." + }, + "gv_hookshot_bridge": { + "name": "Gerudo Valley Bridge with only Hookshot", + "description": "Using Hookshot Extension and a precise setup, you can cross the broken bridge in Gerudo Valley with only a Hookshot." + }, + "gv_child_tent": { + "name": "Gerudo Valley Enter Carpenter's Tent as Child", + "description": "The loading zone for Carpenter's Tent is accessible to child." + }, + "pass_guards_with_nothing": { + "name": "Sneak Past Moving Gerudo Guards with No Items", + "description": "The logic normally guarantees Bow or Hookshot to stun them from a distance, but every moving guard can be passed with basic movement and AI manipulation" + }, + "gf_wasteland_gate_sidehop_skip": { + "name": "Gerudo's Fortress Gate Skip with Sidehop", + "description": [ + "You can sidehop out of bounds from the tower, then sidehop again on the other side of the gate.\n\n", + "This is easiest and most useful for Child, but Adult can also do this to skip the Gerudo Jabber Nut." + ] + }, + "gf_adult_skip_wasteland_gate": { + "name": "Gerudo's Fortress Skip Wasteland Gate as Adult", + "description": [ + "As adult a precise jumpslash out of bounds with hoverboots from above the jail can be used to get past the gate.\n\n", + "This can also be used to reach the tower and lower the gate for child without climb." + ] + }, + "gf_warrior_with_difficult_weapon": { + "name": "Gerudo's Fortress Warriors with Difficult Weapons", + "description": "Warriors can be defeated with Slingshot or Bombchus." + }, + "gf_ledge_clip_into_gtg": { + "name": "Ledge Clip into Training Ground", + "description": "Adult Link can use a ledge clip to enter Gerudo Training Ground without Gerudo Card." + }, + "hw_bunny_crossing": { + "name": "Wasteland Crossing with Bunny Hood", + "description": "You can beat the quicksand by using the increased speed of the Bunny Hood. Note that jumping to the carpet merchant as child typically requires a fairly precise jumpslash." + }, + "hw_crossing": { + "name": "Wasteland Crossing without Hover Boots or Longshot", + "description": "You can beat the quicksand by backwalking across it in a specific way. Note that jumping to the carpet merchant as child typically requires a fairly precise jumpslash." + }, + "lens_hw": { + "name": "Lensless Wasteland", + "description": "By memorizing the path, you can travel through the Wasteland without using the Lens of Truth to see the Poe. The equivalent trick for going in reverse through the Wasteland is \"Reverse Wasteland\"." + }, + "hw_reverse": { + "name": "Reverse Wasteland", + "description": [ + "By memorizing the path, you can travel through the Wasteland in reverse. Note that jumping to the carpet merchant as child typically requires a fairly precise jumpslash.\n", + "The equivalent trick for going forward through the Wasteland is \"Lensless Wasteland\".\n", + "To cross the river of sand with no additional items, be sure to also enable \"Wasteland Crossing without Hover Boots or Longshot\".\n", + "Unless all overworld entrances are randomized, Child Link will not be expected to do anything at Gerudo's Fortress." + ] + }, + "colossus_gs": { + "name": "Colossus Hill GS with Hookshot", + "description": "Somewhat precise. If you kill enough Leevers you can get enough of a break to take some time to aim more carefully." + }, + "deku_basement_gs": { + "name": "Deku Tree Basement Vines GS with Jumpslash", + "description": "Can be defeated by doing a precise jumpslash." + }, + "deku_b1_skip": { + "name": "Deku Tree Basement without Slingshot", + "description": "A precise jump can be used to skip needing to use the Slingshot to go around B1 of the Deku Tree. If used with the \"Closed Forest\" setting, a Slingshot will not be guaranteed to exist somewhere inside the Forest. This trick applies to both Vanilla and Master Quest." + }, + "deku_b1_bow_webs": { + "name": "Deku Tree Basement Web to Gohma with Bow", + "description": [ + "All spider web walls in the Deku Tree basement can be burnt as adult with just a bow by shooting through torches. ", + "This trick only applies to the circular web leading to Gohma; the two vertical webs are always in logic. Backflip onto the chest near the torch at the bottom of the vine wall. ", + "With precise positioning you can shoot through the torch to the right edge of the circular web. This allows completion of adult Deku Tree with no fire source." + ] + }, + "deku_b1_backflip_over_spiked_log": { + "name": "Deku Tree Basement Backflip over Spiked Log", + "description": "Allows backflipping over the spiked log in the Deku Tree basement in Vanilla. Only relevant if \"Shuffle Swim\" is enabled." + }, + "deku_mq_compass_gs": { + "name": "Deku Tree MQ Compass Room GS Boulders with Just Hammer", + "description": "Climb to the top of the vines, then let go and jumpslash immediately to destroy the boulders using the Hammer, without needing to spawn a Song of Time block." + }, + "deku_mq_log": { + "name": "Deku Tree MQ Roll Under the Spiked Log", + "description": "You can get past the spiked log by rolling to briefly shrink your hitbox. As adult, the timing is a bit more precise." + }, + "dc_scarecrow_gs": { + "name": "Dodongo's Cavern Scarecrow GS with Armos Statue", + "description": "You can jump off an Armos Statue to reach the alcove with the Gold Skulltula. It takes quite a long time to pull the statue the entire way. The jump to the alcove can be a bit picky when done as child." + }, + "dc_vines_gs": { + "name": "Dodongo's Cavern Vines GS from Below with Longshot", + "description": "The vines upon which this Skulltula rests are one-sided collision. You can use the Longshot to get it from below, by shooting it through the vines, bypassing the need to lower the staircase." + }, + "dc_stairs_with_bow": { + "name": "Dodongo's Cavern Stairs with Bow", + "description": "The Bow can be used to knock down the stairs with two well-timed shots." + }, + "dc_slingshot_skip": { + "name": "Dodongo's Cavern Child Slingshot Skips", + "description": "With precise platforming, child can cross the platforms while the flame circles are there. When enabling this trick, it's recommended that you also enable the Adult variant: \"Dodongo's Cavern Spike Trap Room Jump without Hover Boots\"." + }, + "dc_scrub_room": { + "name": "Dodongo's Cavern Two Scrub Room with Strength", + "description": "With help from a conveniently-positioned block, Adult can quickly carry a Bomb Flower over to destroy the mud wall blocking the room with two Deku Scrubs." + }, + "dc_jump": { + "name": "Dodongo's Cavern Spike Trap Room Jump without Hover Boots", + "description": "The jump is Adult Link only. Applies to both Vanilla and MQ." + }, + "dc_hammer_floor": { + "name": "Dodongo's Cavern Smash the Boss Lobby Floor", + "description": "The bombable floor before King Dodongo can be destroyed with Hammer if hit in the very center. This is only relevant with Shuffle Boss Entrances or if Dodongo's Cavern is MQ and either variant of \"Dodongo's Cavern MQ Light the Eyes with Strength\" is on." + }, + "dc_dodongo_chu": { + "name": "Dodongo's Cavern Dodongo with Only Bombchus", + "description": "With precise timing you can feed King Dodongo a bombchu during a backflip" + }, + "dc_mq_stairs_with_only_strength": { + "name": "Dodongo's Cavern MQ Stairs With Only Strength", + "description": "Taking a bomb from the back can be used to lower stairs without using stick to drop bomb from wall." + }, + "dc_mq_child_bombs": { + "name": "Dodongo's Cavern MQ Early Bomb Bag Area as Child", + "description": "With a precise jumpslash from above, you can reach the Bomb Bag area as only child without needing a Slingshot. You will take fall damage." + }, + "dc_mq_child_eyes": { + "name": "Dodongo's Cavern MQ Light the Eyes with Strength as Child", + "description": [ + "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes.\n", + "To perform this trick as child is significantly more difficult than adult.\n", + "The player is also expected to complete the DC back area without explosives, including getting past the Armos wall to the switch for the boss door." + ] + }, + "dc_mq_adult_eyes": { + "name": "Dodongo's Cavern MQ Light the Eyes with Strength as Adult", + "description": "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes." + }, + "dc_eyes_chu": { + "name": "Dodongo's Cavern Light the Eyes with Bombchus", + "description": "You can light the dodongo head's eyes with bombchus from the main room, allowing instant access to the end of the dungeon." + }, + "jabu_alcove_jump_dive": { + "name": "Jabu Underwater Alcove as Adult with Jump Dive", + "description": "Standing above the underwater tunnel leading to the scrub, jump down and swim through the tunnel. This allows adult to access the alcove with no Scale or Iron Boots. In Vanilla Jabu, this alcove has a business scrub. In MQ Jabu, it has the compass chest and a door switch for the main floor." + }, + "jabu_boss_hover": { + "name": "Jabu Near Boss Room with Hover Boots", + "description": "A box for the blue switch can be carried over by backwalking with one while the elevator is at its peak. Alternatively, you can skip transporting a box by quickly rolling from the switch and opening the door before it closes. However, the timing for this is very tight." + }, + "jabu_near_boss_ranged": { + "name": "Jabu Near Boss Ceiling Switch/GS without Boomerang or Explosives", + "description": [ + "Vanilla Jabu: From near the entrance into the room, you can hit the switch that opens the door to the boss room using a precisely-aimed use of the Slingshot, Bow, or Longshot. ", + "As well, if you climb to the top of the vines you can stand on the right edge of the platform and shoot around the glass. From this distance, even the Hookshot can reach the switch. ", + "This trick is only relevant if \"Shuffle Boss Entrances\" is enabled.\n", + "MQ Jabu: A Gold Skulltula Token can be collected with Longshot using the same methods as hitting the switch in Vanilla." + ] + }, + "jabu_near_boss_explosives": { + "name": "Jabu Near Boss Ceiling Switch with Explosives", + "description": "You can hit the switch that opens the door to the boss room using a precisely-aimed Bombchu. Also, using the Hover Boots, adult can throw a Bomb at the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled." + }, + "jabu_b1_cube_hover": { + "name": "Jabu B1 Pass Cube with Hover Boots", + "description": "It's possible reach pots past cube with only hover boots." + }, + "lens_jabu_mq": { + "name": "Jabu MQ without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Jabu MQ." + }, + "jabu_mq_rang_jump": { + "name": "Jabu MQ Compass Chest with Boomerang", + "description": "Boomerang can reach the cow switch to spawn the chest by targeting the cow, jumping off of the ledge where the chest spawns, and throwing the Boomerang in midair." + }, + "jabu_mq_sot_gs": { + "name": "Jabu MQ Song of Time Block GS with Boomerang", + "description": "Allow the Boomerang to return to you through the Song of Time block to grab the token." + }, + "jabu_barinade_pots": { + "name": "Jabu Barinade with Pots", + "description": "Barinade can be damaged with pots, requiring only boomerang to defeat." + }, + "lens_botw": { + "name": "Bottom of the Well without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Bottom of the Well." + }, + "bottom_of_the_well_navi_dive": { + "name": "Bottom of the Well Navi dive", + "description": "You need Deku Sticks or Kokiri Sword to dive with Navi for entering Bottom of the Well." + }, + "botw_child_deadhand": { + "name": "Child Dead Hand without Kokiri Sword", + "description": "Requires 9 sticks or 5 jumpslashes." + }, + "botw_basement": { + "name": "Bottom of the Well Map Chest with Strength & Sticks", + "description": "The chest in the basement can be reached with strength by doing a jumpslash with a lit stick to access the Bomb Flowers." + }, + "botw_pits": { + "name": "Bottom of the Well MQ Jump Over the Pits", + "description": "While the pits in Bottom of the Well don't allow you to jump just by running straight at them, you can still get over them by side-hopping or backflipping across. With explosives, this allows you to access the central areas without Zelda's Lullaby. With Zelda's Lullaby, it allows you to access the west inner room without explosives." + }, + "botw_mq_deadhand_key": { + "name": "Bottom of the Well MQ Dead Hand Freestanding Key with Boomerang", + "description": "Boomerang can fish the item out of the rubble without needing explosives to blow it up." + }, + "forest_first_gs": { + "name": "Forest Temple First Room GS with Melee Weapons", + "description": "Allows killing this Skulltula with Sword or Sticks by jumpslashing it as you let go from the vines." + }, + "forest_courtyard_east_gs": { + "name": "Forest Temple East Courtyard GS with Boomerang", + "description": "Precise Boomerang throws can allow child to kill the Skulltula and collect the token." + }, + "forest_vines": { + "name": "Forest Temple East Courtyard Vines with Hookshot", + "description": "The vines in Forest Temple leading to where the well drain switch is in the standard form can be barely reached with just the Hookshot. Applies to MQ also." + }, + "forest_courtyard_ledge": { + "name": "Forest Temple NE Courtyard Ledge with Hover Boots", + "description": "With precise Hover Boots movement you can fall down to this ledge from upper balconies. If done precisely enough, it is not necessary to take fall damage. In MQ, this skips a Longshot requirement. In Vanilla, this can skip a Hookshot requirement in entrance randomizer." + }, + "forest_doorframe": { + "name": "Forest Temple East Courtyard Door Frame with Hover Boots", + "description": [ + "A precise Hover Boots movement from the upper balconies in this courtyard can be used to get on top of the door frame. Applies to both Vanilla and Master Quest.\n", + "In Vanilla, from on top the door frame you can summon Pierre, allowing you to access the falling ceiling room early.\n", + "In Master Quest, this allows you to obtain the GS on the door frame as adult without Hookshot or Song of Time." + ] + }, + "forest_outside_backdoor": { + "name": "Forest Temple Outside Backdoor with Jumpslash", + "description": "A jumpslash recoil can be used to reach the ledge in the block puzzle room that leads to the west courtyard. This skips a potential Hover Boots requirement in Vanilla, and it can sometimes apply in MQ as well. This trick can be performed as both ages." + }, + "forest_courtyard_hearts_boomerang": { + "name": "Forest Temple Courtyard Hearts with Boomerang", + "description": "A well aimed boomerang from the water's edge can reach the hearts from ground level. If unable to swim, you can back away from the water while the boomerang is returning so the hearts land on the ground." + }, + "forest_well_swim": { + "name": "Swim Through Forest Temple Well with Hookshot", + "description": "Shoot the vines in the well as low and as far to the right as possible, and then immediately swim under the ceiling to the right. This is usually only useful in Master Quest." + }, + "forest_mq_block_puzzle": { + "name": "Skip Forest Temple MQ Block Puzzle with Bombchu", + "description": "Send the Bombchu straight up the center of the wall directly to the left upon entering the room." + }, + "forest_mq_js_hallway_switch": { + "name": "Forest Temple MQ Twisted Hallway Switch with Jumpslash", + "description": "The switch to twist the hallway can be hit with a jumpslash through the glass block. To get in front of the switch, either use the Hover Boots or hit the shortcut switch at the top of the room and jump from the glass blocks that spawn. Sticks can be used as child, but the Kokiri Sword is too short to reach through the glass." + }, + "forest_mq_hookshot_hallway_switch": { + "name": "Forest Temple MQ Twisted Hallway Switch with Hookshot", + "description": "There's a very small gap between the glass block and the wall. Through that gap you can hookshot the target on the ceiling." + }, + "forest_mq_rang_hallway_switch": { + "name": "Forest Temple MQ Twisted Hallway Switch with Boomerang", + "description": "The Boomerang can return to Link through walls, allowing child to hit the hallway switch. This can be used to allow adult to pass through later, or in conjunction with \"Forest Temple Outside Backdoor with Jumpslash\"." + }, + "forest_mq_child_doorframe": { + "name": "Forest Temple MQ Doorframe GS as Child without Boomerang", + "description": [ + "If Adult burns the courtyard webbing with Fire Arrows (which is a permanent flag in Ship Rando) ", + "then Child can climb up to the balconies and jump to the SoT block from the railing, ", + "and from there either roll jump or jump against the wall to reach the doorframe.\n", + "From there, The GS can be killed with a crouchstab, explosives or other ranged weapon and collected by climbing down." + ] + }, + "fire_sot": { + "name": "Fire Temple Song of Time Room GS without Song of Time", + "description": "A precise jump can be used to reach this room." + }, + "fire_strength": { + "name": "Fire Temple Climb without Strength", + "description": "A precise jump can be used to skip pushing the block." + }, + "fire_scarecrow": { + "name": "Fire Temple East Tower without Scarecrow's Song", + "description": "Also known as \"Pixelshot\". The Longshot can reach the target on the elevator itself, allowing you to skip needing to spawn the scarecrow." + }, + "fire_skip_flame_walls": { + "name": "Fire Temple Skip Flame Walls", + "description": [ + "If you move quickly you can sneak past the edge of a flame wall before rises up to block you. To ", + "do it without taking damage is more precise. Allows progress without needing either a Small Key or ", + "Hover Boots. In MQ if either \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" or ", + "\"with Precise Jump\" are enabled, this also allows progress deeper into the dungeon without Hookshot.\n", + "Child can sidehop past fire wall in MQ lobby." + ] + }, + "fire_mq_near_boss": { + "name": "Fire Temple MQ Chest Near Boss without Breaking Crate", + "description": "The hitbox for the torch extends a bit outside of the crate. Shoot a flaming arrow at the side of the crate to light the torch without needing to get over there and break the crate." + }, + "fire_mq_blocked_chest": { + "name": "Fire Temple MQ Big Lava Room Blocked Door without Hookshot", + "description": "There is a gap between the hitboxes of the flame wall in the big lava room. If you know where this gap is located, you can jump through it and skip needing to use the Hookshot. To do this without taking damage is more precise." + }, + "fire_mq_bk_chest": { + "name": "Fire Temple MQ Boss Key Chest without Bow", + "description": "It is possible to light both of the timed torches to unbar the door to the boss key chest's room with just Din's Fire if you move very quickly between the two torches. It is also possible to unbar the door with just Din's Fire by abusing an oversight in the way the game counts how many torches have been lit." + }, + "fire_mq_climb": { + "name": "Fire Temple MQ Climb without Fire Source", + "description": "You can use the Hover Boots to hover around to the climbable wall, skipping the need to use a fire source and spawn a Hookshot target." + }, + "fire_mq_maze_side_room": { + "name": "Fire Temple MQ Lizalfos Maze Side Room without Box", + "description": "You can walk from the blue switch to the door and quickly open the door before the bars reclose. This skips needing to reach the upper sections of the maze to get a box to place on the switch." + }, + "fire_mq_maze_hovers": { + "name": "Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots", + "description": "Use the Hover Boots off of a crate to climb to the upper maze without needing to spawn and use the Hookshot targets." + }, + "fire_mq_maze_jump": { + "name": "Fire Temple MQ Lower to Upper Lizalfos Maze with Precise Jump", + "description": "A precise jump off of a crate can be used to climb to the upper maze without needing to spawn and use the Hookshot targets. This trick supersedes both \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" and \"Fire Temple MQ Lizalfos Maze Side Room without Box\"." + }, + "fire_mq_above_maze_gs": { + "name": "Fire Temple MQ Above Flame Wall Maze GS from Below with Longshot", + "description": "The floor of the room that contains this Skulltula is only solid from above. From the maze below, the Longshot can be shot through the ceiling to obtain the token with two fewer small keys than normal." + }, + "water_longshot_torch": { + "name": "Water Temple Torch Longshot", + "description": [ + "Stand on the eastern side of the central pillar and longshot the torches on the bottom level. Swim through the corridor and float up to the top level. This allows access to this area and lower water levels without Iron Boots.\n", + "The majority of the tricks that allow you to skip Iron Boots in the Water Temple are not going to be relevant unless this trick is first enabled." + ] + }, + "water_cracked_wall_hovers": { + "name": "Water Temple Cracked Wall with Hover Boots", + "description": "With a midair side-hop while wearing the Hover Boots, you can reach the cracked wall without needing to raise the water up to the middle level." + }, + "water_cracked_wall": { + "name": "Water Temple Cracked Wall with No Additional Items", + "description": "A precise jumpslash (among other methods) will get you to the cracked wall without needing the Hover Boots or to raise the water to the middle level. This trick supersedes \"Water Temple Cracked Wall with Hover Boots\"." + }, + "water_bk_region": { + "name": "Water Temple Boss Key Region with Hover Boots", + "description": "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the following room can also be obtained with just the Hover Boots." + }, + "water_north_basement_ledge_jump": { + "name": "Water Temple North Basement Ledge with Precise Jump", + "description": "In the northern basement there's a ledge from where, in Vanilla Water Temple, boulders roll out into the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise jump, it can be done without them. This trick applies to both Vanilla and Master Quest." + }, + "water_fw_central_gs": { + "name": "Water Temple Central Pillar GS with Farore's Wind", + "description": "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang." + }, + "water_irons_central_gs": { + "name": "Water Temple Central Pillar GS with Iron Boots", + "description": "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you do not leave the room, even if you were to raise the water up to the highest level. With the Iron Boots to go through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot." + }, + "water_central_bow": { + "name": "Water Temple Central Bow Target without Longshot or Hover Boots", + "description": "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the hallway and make through it before the gate closes. It can also be done as child, using the Slingshot instead of the Bow." + }, + "water_hookshot_falling_platform_gs": { + "name": "Water Temple Falling Platform Room GS with Hookshot", + "description": "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Hookshot." + }, + "water_rang_falling_platform_gs": { + "name": "Water Temple Falling Platform Room GS with Boomerang", + "description": "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Boomerang." + }, + "water_river_gs": { + "name": "Water Temple River GS without Iron Boots", + "description": "Standing on the exposed ground toward the end of the river, a precise Longshot use can obtain the token. The Longshot cannot normally reach far enough to kill the Skulltula, however. You'll first have to find some other way of killing it." + }, + "water_dragon_jump_dive": { + "name": "Water Temple Dragon Statue Jump Dive", + "description": "If you come into the dragon statue room from the serpent river, you can sidehop down from above and get into the tunnel without needing either Iron Boots or a Scale. This trick applies to both Vanilla and Master Quest. In Vanilla, you must shoot the switch from above with the Bow, and then quickly get through the tunnel before the gate closes." + }, + "water_adult_dragon": { + "name": "Water Temple Dragon Statue Switch from Above the Water as Adult", + "description": [ + "Normally you need both Hookshot and Iron Boots to hit the switch and swim through the tunnel to get to the chest. But by hitting the switch from dry land, using one of Bombchus, Hookshot, or Bow, it is possible to skip one or both of those requirements.\n", + "After the gate has been opened, besides just using the Iron Boots, a well-timed dive with at least the Silver Scale could be used to swim through the tunnel. If coming from the serpent river, a jump dive can also be used to get into the tunnel." + ] + }, + "water_child_dragon": { + "name": "Water Temple Dragon Statue Switch from Above the Water as Child", + "description": [ + "It is possible for child to hit the switch from dry land using one of Bombchus, Slingshot or Boomerang. Then, to get to the chest, child can dive through the tunnel using at least the Silver Scale. ", + "The timing and positioning of this dive needs to be perfect to actually make it under the gate, and it all needs to be done very quickly to be able to get through before the gate closes.\n", + "Be sure to enable \"Water Temple Dragon Statue Switch from Above the Water as Adult\" for adult's variant of this trick." + ] + }, + "water_mq_central_pillar": { + "name": "Water Temple MQ Central Pillar with Fire Arrows", + "description": [ + "Slanted torches have misleading hitboxes. Whenever you see a slanted torch jutting out of the wall, you can expect most or all of its hitbox is actually on the other side that wall. ", + "This can make slanted torches very finicky to light when using arrows. ", + "The torches in the central pillar of MQ Water Temple are a particularly egregious example. Logic normally expects Din's Fire and Song of Time." + ] + }, + "water_iron_boots_ledge_grab": { + "name": "Water Temple Ledge Grab While Surfacing with Iron Boots", + "description": [ + "Diving in front of ledge tapping B to swim up faster, then equipping iron boots while surfacing allows you to ", + "ledge grab to the higher ground. This can be used to reach ledge to boss door and vanilla compass chest, or ", + "MQ storage room" + ] + }, + "water_invisible_hookshot_target": { + "name": "Water Temple Invisible Hookshot Target", + "description": [ + "Invisible hookshot geometry can be used in MQ to get over the gate that blocks you from going to this ", + "Skulltula early, skipping a small key as well as needing Hovers or Scarecrow to reach the locked door.\n", + "In vanilla this can be used to get past without bronze scale." + ] + }, + "water_morpha_without_hookshot": { + "name": "Water Temple Morpha without Hookshot", + "description": "It is possible to slash at Morpha without hookshot." + }, + "lens_shadow": { + "name": "Shadow Temple Stationary Objects without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Shadow Temple for most areas in the dungeon except for crossing the moving platform in the huge pit room and for fighting Bongo Bongo." + }, + "lens_shadow_platform": { + "name": "Shadow Temple Invisible Moving Platform without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Shadow Temple to cross the invisible moving platform in the huge pit room in either direction." + }, + "lens_bongo": { + "name": "Shadow Temple Bongo Bongo without Lens of Truth", + "description": "Bongo Bongo can be defeated without the use of Lens of Truth, as the hands give a pretty good idea of where the eye is." + }, + "shadow_umbrella_hover": { + "name": "Shadow Temple Stone Umbrella Skip", + "description": "A very precise Hover Boots movement from off of the lower chest can get you on top of the falling spikes without needing to pull the block. Applies to both Vanilla and Master Quest." + }, + "shadow_umbrella_clip": { + "name": "Shadow Temple Stone Umbrella Clip", + "description": "Backflipping as the falling spikes fall clips above without needing any other requirements. Applies to both Vanilla and Master Quest." + }, + "shadow_umbrella_gs": { + "name": "Shadow Temple Falling Spikes GS with Hover Boots", + "description": "After killing the Skulltula, a very precise Hover Boots movement from off of the lower chest can get you on top of the falling spikes without needing to pull the block. From there, another very precise Hover Boots movement can be used to obtain the token without needing the Hookshot. Applies to both Vanilla and Master Quest." + }, + "shadow_freestanding_key": { + "name": "Shadow Temple Freestanding Key with Bombchu", + "description": "Release the Bombchu with good timing so that it explodes near the bottom of the pot." + }, + "shadow_statue": { + "name": "Shadow Temple River Statue with Bombchu", + "description": "By sending a Bombchu around the edge of the gorge, you can knock down the statue without needing a Bow. Applies in both Vanilla and MQ Shadow." + }, + "shadow_bongo": { + "name": "Shadow Temple Bongo Bongo without projectiles", + "description": "Using precise sword slashes, Bongo Bongo can be defeated without using projectiles. This is only relevant in conjunction with Shadow Temple dungeon shortcuts or shuffled boss entrances." + }, + "lens_shadow_mq": { + "name": "Shadow Temple MQ Stationary Objects without Lens of Truth", + "description": [ + "Removes the requirements for the Lens of Truth in Shadow Temple MQ for most areas in the dungeon.\n", + "See \"Shadow Temple MQ Invisible Moving Platform without Lens of Truth\", \"Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth\", \"Shadow Temple MQ 2nd Dead Hand without Lens of Truth\", and \"Shadow Temple Bongo Bongo without Lens of Truth\" for exceptions." + ] + }, + "lens_shadow_mq_invisible_blades": { + "name": "Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth", + "description": "Removes the requirement for the Lens of Truth or Nayru's Love in Shadow Temple MQ for the Invisible Blades room Silver Rupee collection." + }, + "lens_shadow_mq_platform": { + "name": "Shadow Temple MQ Invisible Moving Platform without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Shadow Temple MQ to cross the invisible moving platform in the huge pit room in either direction." + }, + "lens_shadow_mq_deadhand": { + "name": "Shadow Temple MQ 2nd Dead Hand without Lens of Truth", + "description": "Dead Hand spawns in a random spot within the room. Having Lens removes the hassle of having to comb the room looking for his spawn location." + }, + "shadow_mq_gap": { + "name": "Shadow Temple MQ Truth Spinner Gap with Longshot", + "description": "You can Longshot a torch and jump-slash recoil onto the tongue. It works best if you Longshot the right torch from the left side of the room." + }, + "shadow_mq_invisible_blades": { + "name": "Shadow Temple MQ Invisible Blades without Song of Time", + "description": "The Like Like can be used to boost you into the Silver Rupee or Recovery Hearts that normally require Song of Time. This cannot be performed on OHKO since the Like Like does not boost you high enough if you die." + }, + "shadow_mq_huge_pit": { + "name": "Shadow Temple MQ Lower Huge Pit without Fire Source", + "description": "Normally a frozen eye switch spawns some platforms that you can use to climb down, but there's actually a small piece of ground that you can stand on that you can just jump down to." + }, + "shadow_mq_windy_walkway": { + "name": "Shadow Temple MQ Windy Walkway Reverse without Hover Boots", + "description": "It is possible to jump from the alcove in the windy hallway to the middle platform. There are two methods: wait out the fan opposite the door and hold forward, or jump to the right to be pushed by the fan there towards the platform ledge. Note that jumps of this distance are inconsistent, but still possible." + }, + "lens_spirit": { + "name": "Spirit Temple without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Spirit Temple." + }, + "spirit_child_chu": { + "name": "Spirit Temple Child Side Bridge with Bombchu", + "description": "A carefully-timed Bombchu can hit the switch." + }, + "spirit_west_ledge": { + "name": "Spirit Temple Statue Room West Ledge Checks with Boomerang", + "description": [ + "By carefully walking onto the upper arm of the statue, it's possible to get a good angle on the ", + "Gold Skulltula (In Vanilla) and the farthest pot (In MQ) to collect the checks with Boomerang. ", + "The nearest pot in MQ can be reached from the forearm and is always in logic." + ] + }, + "spirit_lower_adult_switch": { + "name": "Spirit Temple Lower Adult Switch with Bombs", + "description": "A bomb can be used to hit the switch on the ceiling, but it must be thrown from a particular distance away and with precise timing." + }, + "spirit_statue_jump": { + "name": "Spirit Temple Statue Room Jump from Hands to Upper Ledges", + "description": "A precise jump to obtain the following as adult without needing one of Hover Boots, or Hookshot (in Vanilla) or Song of Time (in MQ): - Spirit Temple Statue Room Northeast Chest - Spirit Temple GS Lobby - Spirit Temple MQ Central Chamber Top Left Pot (Left) - Spirit Temple MQ Central Chamber Top Left Pot (Right)" + }, + "spirit_platform_hookshot": { + "name": "Spirit Temple Main Room Hookshot to Boss Platform", + "description": "Precise hookshot aiming at the platform chains can be used to reach the boss platform from the middle landings. Using a jumpslash immediately after reaching a chain makes aiming more lenient. Relevant only when Spirit Temple boss shortcuts are on." + }, + "spirit_map_chest": { + "name": "Spirit Temple Map Chest with Bow", + "description": "To get a line of sight from the upper torch to the map chest torches, you must pull an Armos statue all the way up the stairs." + }, + "spirit_sun_chest": { + "name": "Spirit Temple Sun Block Room Chest with Bow", + "description": [ + "Using the blocks in the room as platforms you can get lines of sight to all three torches. ", + "The timer on the torches is quite short so you must move quickly in order to light all three.\n", + "A backflip can be used instead to light torches without pushing blocks." + ] + }, + "spirit_wall": { + "name": "Spirit Temple Shifting Wall with No Additional Items", + "description": "Logic normally guarantees a way of dealing with both the Beamos and the Walltula before climbing the wall." + }, + "lens_spirit_mq": { + "name": "Spirit Temple MQ without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Spirit Temple MQ." + }, + "spirit_mq_sun_block_sot": { + "name": "Spirit Temple MQ Sun Block Room as Child without Song of Time", + "description": [ + "While adult can easily jump directly to the switch that unbars the door to the sun block room, child Link cannot make the jump without spawning a Song of Time block to jump from. ", + "You can skip this by throwing the crate down onto the switch from above, which does unbar the door, however the crate immediately breaks, so you must move quickly to get through the door before it closes back up." + ] + }, + "spirit_mq_sun_block_gs": { + "name": "Spirit Temple MQ Sun Block Room GS with Boomerang", + "description": "Throw the Boomerang in such a way that it curves through the side of the glass block to hit the Gold Skulltula." + }, + "spirit_mq_lower_adult": { + "name": "Spirit Temple MQ Lower Adult without Fire Arrows", + "description": "By standing in a precise position it is possible to light two of the torches with a single use of Din's Fire. This saves enough time to be able to light all three torches with only Din's Fire." + }, + "spirit_mq_frozen_eye": { + "name": "Spirit Temple MQ Frozen Eye Switch without Fire", + "description": "You can melt the ice by shooting an arrow through a torch. The only way to find a line of sight for this shot is to first spawn a Song of Time block, and then stand on the very edge of it." + }, + "ice_stalagmite_clip": { + "name": "Ice Cavern Stalagmite Clips", + "description": "Most stalagmites blocking path in Ice Cavern can be clipped past with basic movement. Also applies to Water Trial." + }, + "ice_stalagmite_hookshot": { + "name": "Ice Cavern Stalagmites with Hookshot", + "description": "Shooting stalagmites with hookshot in the right way also breaks them. Also applies to Water Trial." + }, + "ice_block_gs": { + "name": "Ice Cavern Block Room GS with Hover Boots", + "description": "The Hover Boots can be used to get in front of the Skulltula to kill it with a jumpslash. Then, the Hover Boots can again be used to obtain the Token, all without Hookshot or Boomerang." + }, + "ice_mq_red_ice_gs": { + "name": "Ice Cavern MQ Red Ice GS without Song of Time", + "description": "If you side-hop into the perfect position, you can briefly stand on the platform with the red ice just long enough to dump some blue fire." + }, + "ice_mq_scarecrow": { + "name": "Ice Cavern MQ Scarecrow GS with No Additional Items", + "description": "As adult a precise jump can be used to reach this alcove." + }, + "lens_gtg": { + "name": "Gerudo Training Ground without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Gerudo Training Ground." + }, + "gtg_without_hookshot": { + "name": "Gerudo Training Ground Left Side Silver Rupees without Hookshot", + "description": [ + "After collecting the rest of the Silver Rupees in the room, you can reach the final Silver Rupee on the ceiling by being pulled up into it after getting grabbed by the Wallmaster. Then, you must also reach the exit of the room without the use of the Hookshot.\n", + "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do so without taking damage is more precise." + ] + }, + "gtg_fake_wall": { + "name": "Reach Gerudo Training Ground Fake Wall Ledge with Hover Boots", + "description": "A precise Hover Boots use from the top of the chest can allow you to grab the ledge without needing the usual requirements. In Master Quest, this always skips a Song of Time requirement. In Vanilla, this skips a Hookshot requirement, but is only relevant if \"Gerudo Training Ground Left Side Silver Rupees without Hookshot\" is enabled." + }, + "gtg_lava_jump": { + "name": "Gerudo Training Grounds Itemless Lava Room Jump", + "description": "A precise rolling jump can be used to jump between all but the furthest platforms in the lava room." + }, + "gtg_statue_jump": { + "name": "Gerudo Training Grounds Statue Room Jump", + "description": "A precise rolling jump or a jump and jumpslash can be used to jump from the upper ledge to one of the pillars in the eye statue room." + }, + "lens_gtg_mq": { + "name": "Gerudo Training Ground MQ without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Gerudo Training Ground MQ." + }, + "gtg_mq_with_hookshot": { + "name": "Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot", + "description": "The highest Silver Rupee can be obtained by hookshooting the target and then immediately jumpslashing toward the Rupee." + }, + "gtg_mq_without_hookshot": { + "name": "Gerudo Training Ground MQ Left Side Silver Rupees without Hookshot", + "description": [ + "After collecting the rest of the Silver Rupees in the room, you can reach the final Silver Rupee on the ceiling by being pulled up into it after getting grabbed by the Wallmaster. The Wallmaster will not track you to directly underneath the rupee. You should take the last step to be under the rupee after the Wallmaster has begun its attempt to grab you.\n", + "Also included with this trick is that fact that the switch that unbars the door to the final chest of GTG can be hit without a projectile, using a precise jumpslash.\n", + "This trick supersedes \"Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot\"." + ] + }, + "lens_ganon": { + "name": "Ganon's Castle without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Ganon's Castle." + }, + "ganon_spirit_trial_hookshot": { + "name": "Spirit Trial without Hookshot", + "description": "The highest rupee can be obtained as adult by performing a precise jump and a well-timed jumpslash off of an Armos." + }, + "lens_ganon_mq": { + "name": "Ganon's Castle MQ without Lens of Truth", + "description": "Removes the requirements for the Lens of Truth in Ganon's Castle MQ." + }, + "ganon_mq_fire_trial": { + "name": "Fire Trial MQ with Hookshot", + "description": "It's possible to hook the target at the end of fire trial with just Hookshot, but it requires precise aim and perfect positioning. The main difficulty comes from getting on the very corner of the obelisk without falling into the lava." + }, + "ganon_mq_shadow_trial": { + "name": "Shadow Trial MQ Torch with Bow", + "description": "You can light the torch in this room without a fire source by shooting an arrow through the lit torch at the beginning of the room. Because the room is so dark and the unlit torch is so far away, it can be difficult to aim the shot correctly." + }, + "ganon_mq_light_trial": { + "name": "Light Trial MQ without Hookshot", + "description": "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. In this case to do it without taking damage is especially precise." + } + } + } +} \ No newline at end of file diff --git a/soh/assets/custom/textures/buttons/ABtn.png b/soh/assets/custom/textures/buttons/ABtn.png index 031924cb96..2a481b2601 100644 Binary files a/soh/assets/custom/textures/buttons/ABtn.png and b/soh/assets/custom/textures/buttons/ABtn.png differ diff --git a/soh/assets/custom/textures/buttons/ABtnOutline.png b/soh/assets/custom/textures/buttons/ABtnOutline.png index b3c9d3aab8..e9a9853e79 100644 Binary files a/soh/assets/custom/textures/buttons/ABtnOutline.png and b/soh/assets/custom/textures/buttons/ABtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/AnalogStick.png b/soh/assets/custom/textures/buttons/AnalogStick.png index d3fec7d015..1a21a82452 100644 Binary files a/soh/assets/custom/textures/buttons/AnalogStick.png and b/soh/assets/custom/textures/buttons/AnalogStick.png differ diff --git a/soh/assets/custom/textures/buttons/AnalogStickOutline.png b/soh/assets/custom/textures/buttons/AnalogStickOutline.png index e4d8d71907..b89d81ff0a 100644 Binary files a/soh/assets/custom/textures/buttons/AnalogStickOutline.png and b/soh/assets/custom/textures/buttons/AnalogStickOutline.png differ diff --git a/soh/assets/custom/textures/buttons/BBtn.png b/soh/assets/custom/textures/buttons/BBtn.png index 8e2fbb54b5..78286f3648 100644 Binary files a/soh/assets/custom/textures/buttons/BBtn.png and b/soh/assets/custom/textures/buttons/BBtn.png differ diff --git a/soh/assets/custom/textures/buttons/BBtnOutline.png b/soh/assets/custom/textures/buttons/BBtnOutline.png index fab802f3bd..70477a5042 100644 Binary files a/soh/assets/custom/textures/buttons/BBtnOutline.png and b/soh/assets/custom/textures/buttons/BBtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/CDown.png b/soh/assets/custom/textures/buttons/CDown.png index f30cec2b3b..14802a8b17 100644 Binary files a/soh/assets/custom/textures/buttons/CDown.png and b/soh/assets/custom/textures/buttons/CDown.png differ diff --git a/soh/assets/custom/textures/buttons/CDownOutline.png b/soh/assets/custom/textures/buttons/CDownOutline.png index 9324c282d4..7f0f101b79 100644 Binary files a/soh/assets/custom/textures/buttons/CDownOutline.png and b/soh/assets/custom/textures/buttons/CDownOutline.png differ diff --git a/soh/assets/custom/textures/buttons/CLeft.png b/soh/assets/custom/textures/buttons/CLeft.png index 43b04412fb..622ca95b31 100644 Binary files a/soh/assets/custom/textures/buttons/CLeft.png and b/soh/assets/custom/textures/buttons/CLeft.png differ diff --git a/soh/assets/custom/textures/buttons/CLeftOutline.png b/soh/assets/custom/textures/buttons/CLeftOutline.png index c0d48f659f..9f3f431056 100644 Binary files a/soh/assets/custom/textures/buttons/CLeftOutline.png and b/soh/assets/custom/textures/buttons/CLeftOutline.png differ diff --git a/soh/assets/custom/textures/buttons/CRight.png b/soh/assets/custom/textures/buttons/CRight.png index c2d1afabfa..408bbd3f88 100644 Binary files a/soh/assets/custom/textures/buttons/CRight.png and b/soh/assets/custom/textures/buttons/CRight.png differ diff --git a/soh/assets/custom/textures/buttons/CRightOutline.png b/soh/assets/custom/textures/buttons/CRightOutline.png index d450084ead..2588f537c7 100644 Binary files a/soh/assets/custom/textures/buttons/CRightOutline.png and b/soh/assets/custom/textures/buttons/CRightOutline.png differ diff --git a/soh/assets/custom/textures/buttons/CUp.png b/soh/assets/custom/textures/buttons/CUp.png index aca4647285..48ad7bbabb 100644 Binary files a/soh/assets/custom/textures/buttons/CUp.png and b/soh/assets/custom/textures/buttons/CUp.png differ diff --git a/soh/assets/custom/textures/buttons/CUpOutline.png b/soh/assets/custom/textures/buttons/CUpOutline.png index b21cd3ae99..5728c4eb7d 100644 Binary files a/soh/assets/custom/textures/buttons/CUpOutline.png and b/soh/assets/custom/textures/buttons/CUpOutline.png differ diff --git a/soh/assets/custom/textures/buttons/DPadDown.png b/soh/assets/custom/textures/buttons/DPadDown.png index cec0af1e55..6908a30648 100644 Binary files a/soh/assets/custom/textures/buttons/DPadDown.png and b/soh/assets/custom/textures/buttons/DPadDown.png differ diff --git a/soh/assets/custom/textures/buttons/DPadDownOutline.png b/soh/assets/custom/textures/buttons/DPadDownOutline.png index e8dca39b69..041d28a80d 100644 Binary files a/soh/assets/custom/textures/buttons/DPadDownOutline.png and b/soh/assets/custom/textures/buttons/DPadDownOutline.png differ diff --git a/soh/assets/custom/textures/buttons/DPadLeft.png b/soh/assets/custom/textures/buttons/DPadLeft.png index 2a4a09b798..ed46aad1d6 100644 Binary files a/soh/assets/custom/textures/buttons/DPadLeft.png and b/soh/assets/custom/textures/buttons/DPadLeft.png differ diff --git a/soh/assets/custom/textures/buttons/DPadLeftOutline.png b/soh/assets/custom/textures/buttons/DPadLeftOutline.png index ba3dbf4e8a..defe8828a2 100644 Binary files a/soh/assets/custom/textures/buttons/DPadLeftOutline.png and b/soh/assets/custom/textures/buttons/DPadLeftOutline.png differ diff --git a/soh/assets/custom/textures/buttons/DPadRight.png b/soh/assets/custom/textures/buttons/DPadRight.png index e7854a2192..3819c97625 100644 Binary files a/soh/assets/custom/textures/buttons/DPadRight.png and b/soh/assets/custom/textures/buttons/DPadRight.png differ diff --git a/soh/assets/custom/textures/buttons/DPadRightOutline.png b/soh/assets/custom/textures/buttons/DPadRightOutline.png index f6b4764c62..7abf16f56d 100644 Binary files a/soh/assets/custom/textures/buttons/DPadRightOutline.png and b/soh/assets/custom/textures/buttons/DPadRightOutline.png differ diff --git a/soh/assets/custom/textures/buttons/DPadUp.png b/soh/assets/custom/textures/buttons/DPadUp.png index 8d70d96dad..650709038b 100644 Binary files a/soh/assets/custom/textures/buttons/DPadUp.png and b/soh/assets/custom/textures/buttons/DPadUp.png differ diff --git a/soh/assets/custom/textures/buttons/DPadUpOutline.png b/soh/assets/custom/textures/buttons/DPadUpOutline.png index 8ad2d79597..ff4f32aec6 100644 Binary files a/soh/assets/custom/textures/buttons/DPadUpOutline.png and b/soh/assets/custom/textures/buttons/DPadUpOutline.png differ diff --git a/soh/assets/custom/textures/buttons/InputViewerBackground.png b/soh/assets/custom/textures/buttons/InputViewerBackground.png index 091d686c00..fbf241d44c 100644 Binary files a/soh/assets/custom/textures/buttons/InputViewerBackground.png and b/soh/assets/custom/textures/buttons/InputViewerBackground.png differ diff --git a/soh/assets/custom/textures/buttons/LBtn.png b/soh/assets/custom/textures/buttons/LBtn.png index 351ea383a7..8793cf623b 100644 Binary files a/soh/assets/custom/textures/buttons/LBtn.png and b/soh/assets/custom/textures/buttons/LBtn.png differ diff --git a/soh/assets/custom/textures/buttons/LBtnOutline.png b/soh/assets/custom/textures/buttons/LBtnOutline.png index 10cca9c8f5..1f2535c505 100644 Binary files a/soh/assets/custom/textures/buttons/LBtnOutline.png and b/soh/assets/custom/textures/buttons/LBtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/Mod1.png b/soh/assets/custom/textures/buttons/Mod1.png index 69496db6a7..d1024e737b 100644 Binary files a/soh/assets/custom/textures/buttons/Mod1.png and b/soh/assets/custom/textures/buttons/Mod1.png differ diff --git a/soh/assets/custom/textures/buttons/Mod1Outline.png b/soh/assets/custom/textures/buttons/Mod1Outline.png index 0149bf0f54..8a652bfa2c 100644 Binary files a/soh/assets/custom/textures/buttons/Mod1Outline.png and b/soh/assets/custom/textures/buttons/Mod1Outline.png differ diff --git a/soh/assets/custom/textures/buttons/Mod2.png b/soh/assets/custom/textures/buttons/Mod2.png index afb0576d16..e3e5499e23 100644 Binary files a/soh/assets/custom/textures/buttons/Mod2.png and b/soh/assets/custom/textures/buttons/Mod2.png differ diff --git a/soh/assets/custom/textures/buttons/Mod2Outline.png b/soh/assets/custom/textures/buttons/Mod2Outline.png index 06464c553e..b6ccdcace6 100644 Binary files a/soh/assets/custom/textures/buttons/Mod2Outline.png and b/soh/assets/custom/textures/buttons/Mod2Outline.png differ diff --git a/soh/assets/custom/textures/buttons/RBtn.png b/soh/assets/custom/textures/buttons/RBtn.png index ecb96bd6c1..9b0e5fa554 100644 Binary files a/soh/assets/custom/textures/buttons/RBtn.png and b/soh/assets/custom/textures/buttons/RBtn.png differ diff --git a/soh/assets/custom/textures/buttons/RBtnOutline.png b/soh/assets/custom/textures/buttons/RBtnOutline.png index afeba32eb2..a5aa0fdc90 100644 Binary files a/soh/assets/custom/textures/buttons/RBtnOutline.png and b/soh/assets/custom/textures/buttons/RBtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/RightStick.png b/soh/assets/custom/textures/buttons/RightStick.png index 6b8490aafd..5441035844 100644 Binary files a/soh/assets/custom/textures/buttons/RightStick.png and b/soh/assets/custom/textures/buttons/RightStick.png differ diff --git a/soh/assets/custom/textures/buttons/RightStickOutline.png b/soh/assets/custom/textures/buttons/RightStickOutline.png index 8fbd54fcc3..d1f4537236 100644 Binary files a/soh/assets/custom/textures/buttons/RightStickOutline.png and b/soh/assets/custom/textures/buttons/RightStickOutline.png differ diff --git a/soh/assets/custom/textures/buttons/StartBtn.png b/soh/assets/custom/textures/buttons/StartBtn.png index ec85f26195..df17aba19d 100644 Binary files a/soh/assets/custom/textures/buttons/StartBtn.png and b/soh/assets/custom/textures/buttons/StartBtn.png differ diff --git a/soh/assets/custom/textures/buttons/StartBtnOutline.png b/soh/assets/custom/textures/buttons/StartBtnOutline.png index a7902edbda..b8bee0332e 100644 Binary files a/soh/assets/custom/textures/buttons/StartBtnOutline.png and b/soh/assets/custom/textures/buttons/StartBtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/ZBtn.png b/soh/assets/custom/textures/buttons/ZBtn.png index 4fee52d576..967c7dffd5 100644 Binary files a/soh/assets/custom/textures/buttons/ZBtn.png and b/soh/assets/custom/textures/buttons/ZBtn.png differ diff --git a/soh/assets/custom/textures/buttons/ZBtnOutline.png b/soh/assets/custom/textures/buttons/ZBtnOutline.png index 5832ed3390..ed87dd369e 100644 Binary files a/soh/assets/custom/textures/buttons/ZBtnOutline.png and b/soh/assets/custom/textures/buttons/ZBtnOutline.png differ diff --git a/soh/assets/objects/object_custom_equip/object_custom_equip.h b/soh/assets/objects/object_custom_equip/object_custom_equip.h index 380116a0f9..399a824f9a 100644 --- a/soh/assets/objects/object_custom_equip/object_custom_equip.h +++ b/soh/assets/objects/object_custom_equip/object_custom_equip.h @@ -7,6 +7,9 @@ #define dgCustomBowDL "__OTR__objects/object_custom_equip/gCustomBowDL" static const ALIGN_ASSET(2) char gCustomBowDL[] = dgCustomBowDL; +#define dgCustomFPSBowDL "__OTR__objects/object_custom_equip/gCustomFPSBowDL" +static const ALIGN_ASSET(2) char gCustomFPSBowDL[] = dgCustomFPSBowDL; + #define dgCustomHammerDL "__OTR__objects/object_custom_equip/gCustomHammerDL" static const ALIGN_ASSET(2) char gCustomHammerDL[] = dgCustomHammerDL; @@ -16,6 +19,15 @@ static const ALIGN_ASSET(2) char gCustomHookshotDL[] = dgCustomHookshotDL; #define dgCustomLongshotDL "__OTR__objects/object_custom_equip/gCustomLongshotDL" static const ALIGN_ASSET(2) char gCustomLongshotDL[] = dgCustomLongshotDL; +#define dgCustomFPSSlingshotDL "__OTR__objects/object_custom_equip/gCustomFPSSlingshotDL" +static const ALIGN_ASSET(2) char gCustomFPSSlingshotDL[] = dgCustomFPSSlingshotDL; + +#define dgCustomFPSHookshotDL "__OTR__objects/object_custom_equip/gCustomFPSHookshotDL" +static const ALIGN_ASSET(2) char gCustomFPSHookshotDL[] = dgCustomFPSHookshotDL; + +#define dgCustomFPSLongshotDL "__OTR__objects/object_custom_equip/gCustomFPSLongshotDL" +static const ALIGN_ASSET(2) char gCustomFPSLongshotDL[] = dgCustomFPSLongshotDL; + #define dgCustomHookshotTipDL "__OTR__objects/object_custom_equip/gCustomHookshotTipDL" static const ALIGN_ASSET(2) char gCustomHookshotTipDL[] = dgCustomHookshotTipDL; diff --git a/soh/assets/objects/object_link_boy/object_link_boy.h b/soh/assets/objects/object_link_boy/object_link_boy.h index a36662a804..f1ed9c7a04 100644 --- a/soh/assets/objects/object_link_boy/object_link_boy.h +++ b/soh/assets/objects/object_link_boy/object_link_boy.h @@ -510,5 +510,30 @@ static const ALIGN_ASSET(2) char gLinkAdultVtx_0340A0[] = dgLinkAdultVtx_0340A0; #define dgLinkAdultVtx_02E7E0 "__OTR__objects/object_link_boy/gLinkAdultVtx_02E7E0" static const ALIGN_ASSET(2) char gLinkAdultVtx_02E7E0[] = dgLinkAdultVtx_02E7E0; +// Adult-fitted mask display lists (for use when adult Link wears child masks via the AdultMasks enhancement) +#define dgLinkAdultKeatonMaskDL "__OTR__objects/object_link_boy/gLinkAdultKeatonMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultKeatonMaskDL[] = dgLinkAdultKeatonMaskDL; + +#define dgLinkAdultSkullMaskDL "__OTR__objects/object_link_boy/gLinkAdultSkullMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultSkullMaskDL[] = dgLinkAdultSkullMaskDL; + +#define dgLinkAdultSpookyMaskDL "__OTR__objects/object_link_boy/gLinkAdultSpookyMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultSpookyMaskDL[] = dgLinkAdultSpookyMaskDL; + +#define dgLinkAdultBunnyHoodDL "__OTR__objects/object_link_boy/gLinkAdultBunnyHoodDL" +static const ALIGN_ASSET(2) char gLinkAdultBunnyHoodDL[] = dgLinkAdultBunnyHoodDL; + +#define dgLinkAdultGoronMaskDL "__OTR__objects/object_link_boy/gLinkAdultGoronMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultGoronMaskDL[] = dgLinkAdultGoronMaskDL; + +#define dgLinkAdultZoraMaskDL "__OTR__objects/object_link_boy/gLinkAdultZoraMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultZoraMaskDL[] = dgLinkAdultZoraMaskDL; + +#define dgLinkAdultGerudoMaskDL "__OTR__objects/object_link_boy/gLinkAdultGerudoMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultGerudoMaskDL[] = dgLinkAdultGerudoMaskDL; + +#define dgLinkAdultMaskOfTruthDL "__OTR__objects/object_link_boy/gLinkAdultMaskOfTruthDL" +static const ALIGN_ASSET(2) char gLinkAdultMaskOfTruthDL[] = dgLinkAdultMaskOfTruthDL; + #endif // OBJECTS_OBJECT_LINK_BOY_H diff --git a/soh/assets/xml/GC_MQ_D/objects/object_bv.xml b/soh/assets/xml/GC_MQ_D/objects/object_bv.xml index af3c295a35..f31e1afe59 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_bv.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/objects/object_fd.xml b/soh/assets/xml/GC_MQ_D/objects/object_fd.xml index 80313d34d4..2bbc28746b 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_fd.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/objects/object_fhg.xml b/soh/assets/xml/GC_MQ_D/objects/object_fhg.xml index 35c3934505..6d6bdae89c 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_fhg.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/objects/object_ganon.xml b/soh/assets/xml/GC_MQ_D/objects/object_ganon.xml index 27c36a5f2f..c5dd938235 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_ganon.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/objects/object_goma.xml b/soh/assets/xml/GC_MQ_D/objects/object_goma.xml index e7a6d0a544..543d9ce2a1 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_goma.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/objects/object_kingdodongo.xml b/soh/assets/xml/GC_MQ_D/objects/object_kingdodongo.xml index 9b104b3ea9..956685611e 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/objects/object_mo.xml b/soh/assets/xml/GC_MQ_D/objects/object_mo.xml index f31a345d6a..512d1dd123 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_mo.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/objects/object_sst.xml b/soh/assets/xml/GC_MQ_D/objects/object_sst.xml index 31e4f8140b..1920edee45 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_sst.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_sst.xml @@ -18,7 +18,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/objects/object_tw.xml b/soh/assets/xml/GC_MQ_D/objects/object_tw.xml index be51f0b6cb..82158c8386 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_tw.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_D/textures/boss_title_cards.xml b/soh/assets/xml/GC_MQ_D/textures/boss_title_cards.xml index 3667d2bdfa..43c00f622e 100644 --- a/soh/assets/xml/GC_MQ_D/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_MQ_D/textures/boss_title_cards.xml @@ -1,52 +1,52 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + \ No newline at end of file diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_bv.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_bv.xml index d2ebf275ba..719c978ea5 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_bv.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_fd.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_fd.xml index 2609579670..82b95b00a8 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_fd.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_fhg.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_fhg.xml index 669875aaf8..13627bd282 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_fhg.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_ganon.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_ganon.xml index c654c7fec9..c0da891053 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_ganon.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_goma.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_goma.xml index 922678a3cf..bfe6df0fca 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_goma.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_kingdodongo.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_kingdodongo.xml index 5ef07a26f7..ec6690dff3 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_mo.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_mo.xml index 4c4be74c83..ab6a52a0fa 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_mo.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_sst.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_sst.xml index b874b9a418..640e41b7ad 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_sst.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_tw.xml b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_tw.xml index c7fd2a60be..01b49235f9 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/objects/object_tw.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_J/textures/boss_title_cards.xml b/soh/assets/xml/GC_MQ_NTSC_J/textures/boss_title_cards.xml index 84f555bd10..793220e7cf 100644 --- a/soh/assets/xml/GC_MQ_NTSC_J/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_MQ_NTSC_J/textures/boss_title_cards.xml @@ -1,42 +1,42 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_bv.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_bv.xml index d2ebf275ba..719c978ea5 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_bv.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_fd.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_fd.xml index 2609579670..82b95b00a8 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_fd.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_fhg.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_fhg.xml index 669875aaf8..13627bd282 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_fhg.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_ganon.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_ganon.xml index c654c7fec9..c0da891053 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_ganon.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_goma.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_goma.xml index 922678a3cf..bfe6df0fca 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_goma.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_kingdodongo.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_kingdodongo.xml index 5ef07a26f7..ec6690dff3 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_mo.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_mo.xml index 4c4be74c83..ab6a52a0fa 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_mo.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_sst.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_sst.xml index b874b9a418..640e41b7ad 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_sst.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_tw.xml b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_tw.xml index c7fd2a60be..01b49235f9 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/objects/object_tw.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_NTSC_U/textures/boss_title_cards.xml b/soh/assets/xml/GC_MQ_NTSC_U/textures/boss_title_cards.xml index 84f555bd10..793220e7cf 100644 --- a/soh/assets/xml/GC_MQ_NTSC_U/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_MQ_NTSC_U/textures/boss_title_cards.xml @@ -1,42 +1,42 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_bv.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_bv.xml index f8ffddaeeb..b0810c705f 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_bv.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_fd.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_fd.xml index a1c51c7248..db64a39b1f 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_fd.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_fhg.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_fhg.xml index e159e25049..79a47a6b64 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_fhg.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_ganon.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_ganon.xml index 27c36a5f2f..c5dd938235 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_ganon.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_goma.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_goma.xml index e7a6d0a544..543d9ce2a1 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_goma.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_kingdodongo.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_kingdodongo.xml index 9b104b3ea9..956685611e 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_mo.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_mo.xml index b4528ef317..2900d54bdc 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_mo.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_sst.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_sst.xml index 191c67cc89..52a66b441e 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_sst.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_tw.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_tw.xml index be51f0b6cb..82158c8386 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_tw.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_MQ_PAL_F/textures/boss_title_cards.xml b/soh/assets/xml/GC_MQ_PAL_F/textures/boss_title_cards.xml index 3667d2bdfa..43c00f622e 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/textures/boss_title_cards.xml @@ -1,52 +1,52 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + \ No newline at end of file diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_bv.xml b/soh/assets/xml/GC_NMQ_D/objects/object_bv.xml index f8ffddaeeb..b0810c705f 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_bv.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_fd.xml b/soh/assets/xml/GC_NMQ_D/objects/object_fd.xml index a1c51c7248..db64a39b1f 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_fd.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_fhg.xml b/soh/assets/xml/GC_NMQ_D/objects/object_fhg.xml index e159e25049..79a47a6b64 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_fhg.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml b/soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml index 27c36a5f2f..c5dd938235 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_goma.xml b/soh/assets/xml/GC_NMQ_D/objects/object_goma.xml index e7a6d0a544..543d9ce2a1 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_goma.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_kingdodongo.xml b/soh/assets/xml/GC_NMQ_D/objects/object_kingdodongo.xml index 9b104b3ea9..956685611e 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_mo.xml b/soh/assets/xml/GC_NMQ_D/objects/object_mo.xml index b4528ef317..2900d54bdc 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_mo.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_sst.xml b/soh/assets/xml/GC_NMQ_D/objects/object_sst.xml index 191c67cc89..52a66b441e 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_sst.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_tw.xml b/soh/assets/xml/GC_NMQ_D/objects/object_tw.xml index be51f0b6cb..82158c8386 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_tw.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/textures/boss_title_cards.xml b/soh/assets/xml/GC_NMQ_D/textures/boss_title_cards.xml index 3667d2bdfa..43c00f622e 100644 --- a/soh/assets/xml/GC_NMQ_D/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_NMQ_D/textures/boss_title_cards.xml @@ -1,52 +1,52 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + \ No newline at end of file diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_bv.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_bv.xml index d2ebf275ba..719c978ea5 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_bv.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_fd.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_fd.xml index 2609579670..82b95b00a8 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_fd.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_fhg.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_fhg.xml index 669875aaf8..13627bd282 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_fhg.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_ganon.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_ganon.xml index c654c7fec9..c0da891053 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_ganon.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_goma.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_goma.xml index 922678a3cf..bfe6df0fca 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_goma.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_kingdodongo.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_kingdodongo.xml index 5ef07a26f7..ec6690dff3 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_mo.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_mo.xml index 4c4be74c83..ab6a52a0fa 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_mo.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_sst.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_sst.xml index b874b9a418..640e41b7ad 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_sst.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_tw.xml b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_tw.xml index c7fd2a60be..01b49235f9 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_tw.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J/textures/boss_title_cards.xml b/soh/assets/xml/GC_NMQ_NTSC_J/textures/boss_title_cards.xml index 84f555bd10..793220e7cf 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J/textures/boss_title_cards.xml @@ -1,42 +1,42 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_bv.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_bv.xml index d2ebf275ba..719c978ea5 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_bv.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_fd.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_fd.xml index 2609579670..82b95b00a8 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_fd.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_fhg.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_fhg.xml index 669875aaf8..13627bd282 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_fhg.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_ganon.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_ganon.xml index c654c7fec9..c0da891053 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_ganon.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_goma.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_goma.xml index 922678a3cf..bfe6df0fca 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_goma.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_kingdodongo.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_kingdodongo.xml index 5ef07a26f7..ec6690dff3 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_mo.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_mo.xml index 4c4be74c83..ab6a52a0fa 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_mo.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_sst.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_sst.xml index b874b9a418..640e41b7ad 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_sst.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_tw.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_tw.xml index c7fd2a60be..01b49235f9 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_tw.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_J_CE/textures/boss_title_cards.xml b/soh/assets/xml/GC_NMQ_NTSC_J_CE/textures/boss_title_cards.xml index 84f555bd10..793220e7cf 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_J_CE/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_J_CE/textures/boss_title_cards.xml @@ -1,42 +1,42 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_bv.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_bv.xml index d2ebf275ba..719c978ea5 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_bv.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_fd.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_fd.xml index 2609579670..82b95b00a8 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_fd.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_fhg.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_fhg.xml index 669875aaf8..13627bd282 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_fhg.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_ganon.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_ganon.xml index c654c7fec9..c0da891053 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_ganon.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_goma.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_goma.xml index 922678a3cf..bfe6df0fca 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_goma.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_kingdodongo.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_kingdodongo.xml index 5ef07a26f7..ec6690dff3 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_mo.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_mo.xml index 4c4be74c83..ab6a52a0fa 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_mo.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_sst.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_sst.xml index b874b9a418..640e41b7ad 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_sst.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_tw.xml b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_tw.xml index c7fd2a60be..01b49235f9 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_tw.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_NTSC_U/textures/boss_title_cards.xml b/soh/assets/xml/GC_NMQ_NTSC_U/textures/boss_title_cards.xml index 84f555bd10..793220e7cf 100644 --- a/soh/assets/xml/GC_NMQ_NTSC_U/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_NMQ_NTSC_U/textures/boss_title_cards.xml @@ -1,42 +1,42 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_bv.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_bv.xml index f8ffddaeeb..b0810c705f 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_bv.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_fd.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_fd.xml index a1c51c7248..db64a39b1f 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_fd.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_fhg.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_fhg.xml index e159e25049..79a47a6b64 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_fhg.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml index 27c36a5f2f..c5dd938235 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_goma.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_goma.xml index e7a6d0a544..543d9ce2a1 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_goma.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_kingdodongo.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_kingdodongo.xml index 9b104b3ea9..956685611e 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_kingdodongo.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_mo.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_mo.xml index b4528ef317..2900d54bdc 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_mo.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_sst.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_sst.xml index 191c67cc89..52a66b441e 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_sst.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_tw.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_tw.xml index be51f0b6cb..82158c8386 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_tw.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/textures/boss_title_cards.xml b/soh/assets/xml/GC_NMQ_PAL_F/textures/boss_title_cards.xml index 3667d2bdfa..43c00f622e 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/textures/boss_title_cards.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/textures/boss_title_cards.xml @@ -1,52 +1,52 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + \ No newline at end of file diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_bv.xml b/soh/assets/xml/N64_NTSC_10/objects/object_bv.xml index d2ebf275ba..719c978ea5 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_bv.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_fd.xml b/soh/assets/xml/N64_NTSC_10/objects/object_fd.xml index 2609579670..82b95b00a8 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_fd.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_fhg.xml b/soh/assets/xml/N64_NTSC_10/objects/object_fhg.xml index 669875aaf8..13627bd282 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_fhg.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_ganon.xml b/soh/assets/xml/N64_NTSC_10/objects/object_ganon.xml index c654c7fec9..c0da891053 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_ganon.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_goma.xml b/soh/assets/xml/N64_NTSC_10/objects/object_goma.xml index 922678a3cf..bfe6df0fca 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_goma.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_kingdodongo.xml b/soh/assets/xml/N64_NTSC_10/objects/object_kingdodongo.xml index 5ef07a26f7..ec6690dff3 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_kingdodongo.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_mo.xml b/soh/assets/xml/N64_NTSC_10/objects/object_mo.xml index 4c4be74c83..ab6a52a0fa 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_mo.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_sst.xml b/soh/assets/xml/N64_NTSC_10/objects/object_sst.xml index b874b9a418..640e41b7ad 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_sst.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/objects/object_tw.xml b/soh/assets/xml/N64_NTSC_10/objects/object_tw.xml index c7fd2a60be..01b49235f9 100644 --- a/soh/assets/xml/N64_NTSC_10/objects/object_tw.xml +++ b/soh/assets/xml/N64_NTSC_10/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_10/textures/boss_title_cards.xml b/soh/assets/xml/N64_NTSC_10/textures/boss_title_cards.xml index 84f555bd10..793220e7cf 100644 --- a/soh/assets/xml/N64_NTSC_10/textures/boss_title_cards.xml +++ b/soh/assets/xml/N64_NTSC_10/textures/boss_title_cards.xml @@ -1,42 +1,42 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_bv.xml b/soh/assets/xml/N64_NTSC_11/objects/object_bv.xml index d2ebf275ba..719c978ea5 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_bv.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_fd.xml b/soh/assets/xml/N64_NTSC_11/objects/object_fd.xml index 2609579670..82b95b00a8 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_fd.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_fhg.xml b/soh/assets/xml/N64_NTSC_11/objects/object_fhg.xml index 669875aaf8..13627bd282 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_fhg.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_ganon.xml b/soh/assets/xml/N64_NTSC_11/objects/object_ganon.xml index c654c7fec9..c0da891053 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_ganon.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_goma.xml b/soh/assets/xml/N64_NTSC_11/objects/object_goma.xml index 922678a3cf..bfe6df0fca 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_goma.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_kingdodongo.xml b/soh/assets/xml/N64_NTSC_11/objects/object_kingdodongo.xml index 5ef07a26f7..ec6690dff3 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_kingdodongo.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_mo.xml b/soh/assets/xml/N64_NTSC_11/objects/object_mo.xml index 4c4be74c83..ab6a52a0fa 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_mo.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_sst.xml b/soh/assets/xml/N64_NTSC_11/objects/object_sst.xml index b874b9a418..640e41b7ad 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_sst.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/objects/object_tw.xml b/soh/assets/xml/N64_NTSC_11/objects/object_tw.xml index c7fd2a60be..01b49235f9 100644 --- a/soh/assets/xml/N64_NTSC_11/objects/object_tw.xml +++ b/soh/assets/xml/N64_NTSC_11/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_11/textures/boss_title_cards.xml b/soh/assets/xml/N64_NTSC_11/textures/boss_title_cards.xml index 84f555bd10..793220e7cf 100644 --- a/soh/assets/xml/N64_NTSC_11/textures/boss_title_cards.xml +++ b/soh/assets/xml/N64_NTSC_11/textures/boss_title_cards.xml @@ -1,42 +1,42 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_bv.xml b/soh/assets/xml/N64_NTSC_12/objects/object_bv.xml index d2ebf275ba..719c978ea5 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_bv.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_fd.xml b/soh/assets/xml/N64_NTSC_12/objects/object_fd.xml index 2609579670..82b95b00a8 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_fd.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_fhg.xml b/soh/assets/xml/N64_NTSC_12/objects/object_fhg.xml index 669875aaf8..13627bd282 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_fhg.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_ganon.xml b/soh/assets/xml/N64_NTSC_12/objects/object_ganon.xml index c654c7fec9..c0da891053 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_ganon.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_goma.xml b/soh/assets/xml/N64_NTSC_12/objects/object_goma.xml index 922678a3cf..bfe6df0fca 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_goma.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_kingdodongo.xml b/soh/assets/xml/N64_NTSC_12/objects/object_kingdodongo.xml index 5ef07a26f7..ec6690dff3 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_kingdodongo.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_mo.xml b/soh/assets/xml/N64_NTSC_12/objects/object_mo.xml index 4c4be74c83..ab6a52a0fa 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_mo.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_sst.xml b/soh/assets/xml/N64_NTSC_12/objects/object_sst.xml index b874b9a418..640e41b7ad 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_sst.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/objects/object_tw.xml b/soh/assets/xml/N64_NTSC_12/objects/object_tw.xml index c7fd2a60be..01b49235f9 100644 --- a/soh/assets/xml/N64_NTSC_12/objects/object_tw.xml +++ b/soh/assets/xml/N64_NTSC_12/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/N64_NTSC_12/textures/boss_title_cards.xml b/soh/assets/xml/N64_NTSC_12/textures/boss_title_cards.xml index 84f555bd10..793220e7cf 100644 --- a/soh/assets/xml/N64_NTSC_12/textures/boss_title_cards.xml +++ b/soh/assets/xml/N64_NTSC_12/textures/boss_title_cards.xml @@ -1,42 +1,42 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/soh/assets/xml/N64_PAL_10/objects/object_bv.xml b/soh/assets/xml/N64_PAL_10/objects/object_bv.xml index f8ffddaeeb..b0810c705f 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_bv.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/objects/object_fd.xml b/soh/assets/xml/N64_PAL_10/objects/object_fd.xml index a1c51c7248..db64a39b1f 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_fd.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/objects/object_fhg.xml b/soh/assets/xml/N64_PAL_10/objects/object_fhg.xml index e159e25049..79a47a6b64 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_fhg.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/objects/object_ganon.xml b/soh/assets/xml/N64_PAL_10/objects/object_ganon.xml index 27c36a5f2f..c5dd938235 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_ganon.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/objects/object_goma.xml b/soh/assets/xml/N64_PAL_10/objects/object_goma.xml index e7a6d0a544..543d9ce2a1 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_goma.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/objects/object_kingdodongo.xml b/soh/assets/xml/N64_PAL_10/objects/object_kingdodongo.xml index 9b104b3ea9..956685611e 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_kingdodongo.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/objects/object_mo.xml b/soh/assets/xml/N64_PAL_10/objects/object_mo.xml index b4528ef317..2900d54bdc 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_mo.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/objects/object_sst.xml b/soh/assets/xml/N64_PAL_10/objects/object_sst.xml index 191c67cc89..52a66b441e 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_sst.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/objects/object_tw.xml b/soh/assets/xml/N64_PAL_10/objects/object_tw.xml index be51f0b6cb..82158c8386 100644 --- a/soh/assets/xml/N64_PAL_10/objects/object_tw.xml +++ b/soh/assets/xml/N64_PAL_10/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_10/textures/boss_title_cards.xml b/soh/assets/xml/N64_PAL_10/textures/boss_title_cards.xml index 3667d2bdfa..43c00f622e 100644 --- a/soh/assets/xml/N64_PAL_10/textures/boss_title_cards.xml +++ b/soh/assets/xml/N64_PAL_10/textures/boss_title_cards.xml @@ -1,52 +1,52 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + \ No newline at end of file diff --git a/soh/assets/xml/N64_PAL_11/objects/object_bv.xml b/soh/assets/xml/N64_PAL_11/objects/object_bv.xml index f8ffddaeeb..b0810c705f 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_bv.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_bv.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/objects/object_fd.xml b/soh/assets/xml/N64_PAL_11/objects/object_fd.xml index a1c51c7248..db64a39b1f 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_fd.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_fd.xml @@ -28,7 +28,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/objects/object_fhg.xml b/soh/assets/xml/N64_PAL_11/objects/object_fhg.xml index e159e25049..79a47a6b64 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_fhg.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_fhg.xml @@ -38,7 +38,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/objects/object_ganon.xml b/soh/assets/xml/N64_PAL_11/objects/object_ganon.xml index 27c36a5f2f..c5dd938235 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_ganon.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/objects/object_goma.xml b/soh/assets/xml/N64_PAL_11/objects/object_goma.xml index e7a6d0a544..543d9ce2a1 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_goma.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_goma.xml @@ -159,7 +159,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/objects/object_kingdodongo.xml b/soh/assets/xml/N64_PAL_11/objects/object_kingdodongo.xml index 9b104b3ea9..956685611e 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_kingdodongo.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_kingdodongo.xml @@ -48,7 +48,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/objects/object_mo.xml b/soh/assets/xml/N64_PAL_11/objects/object_mo.xml index b4528ef317..2900d54bdc 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_mo.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_mo.xml @@ -6,7 +6,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/objects/object_sst.xml b/soh/assets/xml/N64_PAL_11/objects/object_sst.xml index 191c67cc89..52a66b441e 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_sst.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_sst.xml @@ -17,7 +17,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/objects/object_tw.xml b/soh/assets/xml/N64_PAL_11/objects/object_tw.xml index be51f0b6cb..82158c8386 100644 --- a/soh/assets/xml/N64_PAL_11/objects/object_tw.xml +++ b/soh/assets/xml/N64_PAL_11/objects/object_tw.xml @@ -273,7 +273,7 @@ - + diff --git a/soh/assets/xml/N64_PAL_11/textures/boss_title_cards.xml b/soh/assets/xml/N64_PAL_11/textures/boss_title_cards.xml index 3667d2bdfa..43c00f622e 100644 --- a/soh/assets/xml/N64_PAL_11/textures/boss_title_cards.xml +++ b/soh/assets/xml/N64_PAL_11/textures/boss_title_cards.xml @@ -1,52 +1,52 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + \ No newline at end of file diff --git a/soh/include/functions.h b/soh/include/functions.h index 760b77f735..54f2c2b5dd 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -890,13 +890,13 @@ void SkelCurve_SetAnim(SkelAnimeCurve* skelCurve, TransformUpdateIndex* transUpd s32 SkelCurve_Update(PlayState* play, SkelAnimeCurve* skelCurve); void SkelCurve_Draw(Actor* actor, PlayState* play, SkelAnimeCurve* skelCurve, OverrideCurveLimbDraw overrideLimbDraw, PostCurveLimbDraw postLimbDraw, s32 lod, void* data); -s32 func_8006CFC0(s32 scene); -void func_8006D074(PlayState* play); -void func_8006D0AC(PlayState* play); -void func_8006D0EC(PlayState* play, Player* player); -void func_8006D684(PlayState* play, Player* player); -void func_8006DC68(PlayState* play, Player* player); -void func_8006DD9C(Actor* actor, Vec3f* arg1, s16 arg2); +s32 Horse_CanSpawn(s32 scene); +void Horse_ResetHorseData(PlayState* play); +void Horse_FixLakeHyliaPosition(PlayState* play); +void Horse_SetupInGameplay(PlayState* play, Player* player); +void Horse_SetupInCutscene(PlayState* play, Player* player); +void Horse_InitPlayerHorse(PlayState* play, Player* player); +void Horse_RotateToPoint(Actor* actor, Vec3f* arg1, s16 arg2); s32 Jpeg_Decode(void* data, void* zbuffer, void* workBuff, u32 workSize); void KaleidoSetup_Update(PlayState* play); void KaleidoSetup_Init(PlayState* play); diff --git a/soh/include/z64item.h b/soh/include/z64item.h index 6e0e1d2c76..137ed09a85 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -594,9 +594,8 @@ typedef enum { /* 0x7A */ GID_SONG_TIME, /* 0x7B */ GID_SONG_STORM, /* 0x7C */ GID_TRIFORCE_PIECE, - /* 0x7D */ GID_ROCS_FEATHER, - /* 0x7E */ GID_FISHING_POLE, - /* 0x7F */ GID_MAXIMUM + /* 0x7D */ GID_FISHING_POLE, + /* 0x7E */ GID_MAXIMUM } GetItemDrawID; diff --git a/soh/soh/Enhancements/Cheats/DropsDontDie.cpp b/soh/soh/Enhancements/Cheats/DropsDontDie.cpp new file mode 100644 index 0000000000..ccf4f339f0 --- /dev/null +++ b/soh/soh/Enhancements/Cheats/DropsDontDie.cpp @@ -0,0 +1,12 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipInit.hpp" + +static void RegisterDropsDontDie() { + COND_VB_SHOULD(VB_ITEM00_TIMER_TICK, CVarGetInteger(CVAR_CHEAT("DropsDontDie"), 0), { + EnItem00* item00 = va_arg(args, EnItem00*); + if (item00->unk_154 <= 0) + *should = false; + }); +} + +static RegisterShipInitFunc initFunc(RegisterDropsDontDie, { CVAR_CHEAT("DropsDontDie") }); diff --git a/soh/soh/Enhancements/Cheats/Infinite/Ammo.cpp b/soh/soh/Enhancements/Cheats/Infinite/Ammo.cpp index c5a0297de6..a4fabc4251 100644 --- a/soh/soh/Enhancements/Cheats/Infinite/Ammo.cpp +++ b/soh/soh/Enhancements/Cheats/Infinite/Ammo.cpp @@ -1,5 +1,6 @@ #include #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/randomizer/SeedContext.h" #include "soh/OTRGlobals.h" #include "soh/ShipInit.hpp" #include "z64save.h" diff --git a/soh/soh/Enhancements/Cheats/NoBugsDespawn.cpp b/soh/soh/Enhancements/Cheats/NoBugsDespawn.cpp new file mode 100644 index 0000000000..b770ef863a --- /dev/null +++ b/soh/soh/Enhancements/Cheats/NoBugsDespawn.cpp @@ -0,0 +1,25 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "macros.h" +#include "src/overlays/actors/ovl_En_Insect/z_en_insect.h" + +extern s16 D_80A7DEB8; +} + +static void OnActorInitNoBugsDespawn(void* refActor) { + EnInsect* insect = reinterpret_cast(refActor); + + if ((insect->actor.params & 2) && insect->soilActor == NULL) { + insect->insectFlags &= ~4; + D_80A7DEB8--; + } +} + +static void RegisterNoBugsDespawn() { + COND_ID_HOOK(OnActorInit, ACTOR_EN_INSECT, CVarGetInteger(CVAR_CHEAT("NoBugsDespawn"), 0), + OnActorInitNoBugsDespawn); +} + +static RegisterShipInitFunc initFunc(RegisterNoBugsDespawn, { CVAR_CHEAT("NoBugsDespawn") }); diff --git a/soh/soh/Enhancements/Cheats/NoFishDespawn.cpp b/soh/soh/Enhancements/Cheats/NoFishDespawn.cpp new file mode 100644 index 0000000000..7d8213f13c --- /dev/null +++ b/soh/soh/Enhancements/Cheats/NoFishDespawn.cpp @@ -0,0 +1,8 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipInit.hpp" + +static void RegisterNoFishDespawn() { + COND_VB_SHOULD(VB_FISH_TIMER_TICK, CVarGetInteger(CVAR_CHEAT("NoFishDespawn"), 0), { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterNoFishDespawn, { CVAR_CHEAT("NoFishDespawn") }); diff --git a/soh/soh/Enhancements/Difficulty/DivingGameTimer.cpp b/soh/soh/Enhancements/Difficulty/DivingGameTimer.cpp new file mode 100644 index 0000000000..ff5e717aa4 --- /dev/null +++ b/soh/soh/Enhancements/Difficulty/DivingGameTimer.cpp @@ -0,0 +1,21 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "functions.h" +extern GameInfo* gGameInfo; +} + +static constexpr int32_t CVAR_DIVING_GAME_TIME_DEFAULT = 50; +#define CVAR_DIVING_GAME_TIME_NAME CVAR_ENHANCEMENT("DivingGame.TimeLimit") +#define CVAR_DIVING_GAME_TIME_VALUE CVarGetInteger(CVAR_DIVING_GAME_TIME_NAME, CVAR_DIVING_GAME_TIME_DEFAULT) +#define CVAR_DIVING_GAME_TIME_SET (CVAR_DIVING_GAME_TIME_VALUE != CVAR_DIVING_GAME_TIME_DEFAULT) + +static void RegisterDIvingGameTimeLimit() { + COND_VB_SHOULD(VB_SET_DIVING_GAME_TIME_LIMIT, CVAR_DIVING_GAME_TIME_SET, { + Interface_SetTimer(BREG(2) + CVAR_DIVING_GAME_TIME_VALUE); + *should = false; + }); +} + +static RegisterShipInitFunc initFunc(RegisterDIvingGameTimeLimit, { CVAR_DIVING_GAME_TIME_NAME }); diff --git a/soh/soh/Enhancements/Difficulty/HorsebackArchery.cpp b/soh/soh/Enhancements/Difficulty/HorsebackArchery.cpp new file mode 100644 index 0000000000..f268a5b175 --- /dev/null +++ b/soh/soh/Enhancements/Difficulty/HorsebackArchery.cpp @@ -0,0 +1,45 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "functions.h" +#include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h" +extern SaveContext gSaveContext; + +extern void EnGe1_TalkAfterGame_Archery(EnGe1* enGe1, PlayState* play); +} + +static void RegisterHorsebackArcheryEnhancements() { + COND_VB_SHOULD(VB_PLAY_HORSEBACK_ARCHERY, + CVarGetInteger(CVAR_ENHANCEMENT("CustomizeHorsebackArchery"), 0) && + CVarGetInteger(CVAR_ENHANCEMENT("InstantHorsebackArcheryWin"), 0), + { + EnGe1* enGe1 = va_arg(args, EnGe1*); + PlayState* play = va_arg(args, PlayState*); + Rupees_ChangeBy(-20); + Flags_SetEventChkInf(EVENTCHKINF_PLAYED_HORSEBACK_ARCHERY); + gSaveContext.minigameScore = 1500; + Message_CloseTextbox(play); + enGe1->actionFunc = EnGe1_TalkAfterGame_Archery; + *should = false; + }); + + COND_VB_SHOULD(VB_SCORE_HORSEBACK_ARCHERY_TARGET, + CVarGetInteger(CVAR_ENHANCEMENT("CustomizeHorsebackArchery"), 0) && + CVarGetInteger(CVAR_ENHANCEMENT("HorsebackArcheryAlwaysScore"), 0), + { + s32* scoreIndex = va_arg(args, s32*); + *scoreIndex = 2; // inner ring = 100 points + }); + + COND_VB_SHOULD(VB_SET_HORSEBACK_ARCHERY_AMMO, CVarGetInteger(CVAR_ENHANCEMENT("CustomizeHorsebackArchery"), 0), { + InterfaceContext* interfaceCtx = va_arg(args, InterfaceContext*); + interfaceCtx->hbaAmmo = CVarGetInteger(CVAR_ENHANCEMENT("HorsebackArcheryAmmo"), 20); + *should = false; + }); +} + +static RegisterShipInitFunc + initFunc(RegisterHorsebackArcheryEnhancements, + { CVAR_ENHANCEMENT("CustomizeHorsebackArchery"), CVAR_ENHANCEMENT("InstantHorsebackArcheryWin"), + CVAR_ENHANCEMENT("HorsebackArcheryAlwaysScore"), CVAR_ENHANCEMENT("HorsebackArcheryAmmo") }); diff --git a/soh/soh/Enhancements/Difficulty/HyperBosses.cpp b/soh/soh/Enhancements/Difficulty/HyperBosses.cpp new file mode 100644 index 0000000000..8d3b06b1d4 --- /dev/null +++ b/soh/soh/Enhancements/Difficulty/HyperBosses.cpp @@ -0,0 +1,64 @@ +#include +#include "soh/ShipInit.hpp" +#include "functions.h" +#include "macros.h" +#include "variables.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/boss-rush/BossRush.h" + +extern "C" PlayState* gPlayState; + +#define CVAR_HYPER_BOSSES_DEFAULT 0 +#define CVAR_HYPER_BOSSES_NAME CVAR_ENHANCEMENT("HyperBosses") +#define CVAR_HYPER_BOSSES_VALUE CVarGetInteger(CVAR_HYPER_BOSSES_NAME, CVAR_HYPER_BOSSES_DEFAULT) + +bool IsHyperBossesActive() { + return CVAR_HYPER_BOSSES_VALUE || + (IS_BOSS_RUSH && + gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES); +} + +void MakeHyperBosses(void* refActor) { + // Run the update function a second time to make bosses move and act twice as fast. + + Player* player = GET_PLAYER(gPlayState); + Actor* actor = static_cast(refActor); + + uint8_t isBossActor = actor->id == ACTOR_BOSS_GOMA || // Gohma + actor->id == ACTOR_BOSS_DODONGO || // King Dodongo + actor->id == ACTOR_EN_BDFIRE || // King Dodongo Fire Breath + actor->id == ACTOR_BOSS_VA || // Barinade + actor->id == ACTOR_BOSS_GANONDROF || // Phantom Ganon + actor->id == ACTOR_EN_FHG_FIRE || // Phantom Ganon/Ganondorf Energy Ball/Thunder + actor->id == ACTOR_EN_FHG || // Phantom Ganon's Horse + actor->id == ACTOR_BOSS_FD || actor->id == ACTOR_BOSS_FD2 || // Volvagia (grounded/flying) + actor->id == ACTOR_EN_VB_BALL || // Volvagia Rocks + actor->id == ACTOR_BOSS_MO || // Morpha + actor->id == ACTOR_BOSS_SST || // Bongo Bongo + actor->id == ACTOR_BOSS_TW || // Twinrova + actor->id == ACTOR_BOSS_GANON || // Ganondorf + actor->id == ACTOR_BOSS_GANON2; // Ganon + + // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some bosses. + if (IsHyperBossesActive() && isBossActor && !Player_InBlockingCsMode(gPlayState, player)) { + // Barinade needs to be updated in sequence to avoid unintended behaviour. + if (actor->id == ACTOR_BOSS_VA) { + // params -1 is BOSSVA_BODY + if (actor->params == -1) { + Actor* actorList = gPlayState->actorCtx.actorLists[ACTORCAT_BOSS].head; + while (actorList != NULL) { + GameInteractor::RawAction::UpdateActor(actorList); + actorList = actorList->next; + } + } + } else { + GameInteractor::RawAction::UpdateActor(actor); + } + } +} + +static void UpdateHyperBossesState() { + COND_HOOK(OnActorUpdate, IsHyperBossesActive(), MakeHyperBosses); +} + +static RegisterShipInitFunc initFunc(UpdateHyperBossesState, { CVAR_HYPER_BOSSES_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/Difficulty/PermanentLosses.cpp b/soh/soh/Enhancements/Difficulty/PermanentLosses.cpp index cab0aa7d43..5a7935fd7c 100644 --- a/soh/soh/Enhancements/Difficulty/PermanentLosses.cpp +++ b/soh/soh/Enhancements/Difficulty/PermanentLosses.cpp @@ -1,4 +1,5 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/randomizer/randomizer.h" #include "soh/OTRGlobals.h" #include "soh/SaveManager.h" #include "soh/ShipInit.hpp" @@ -64,7 +65,7 @@ static void DeleteFileOnDeath() { SaveManager::Instance->DeleteZeldaFile(gSaveContext.fileNum); hasAffectedHealth = false; std::reinterpret_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) ->Dispatch("reset"); } } diff --git a/soh/soh/Enhancements/ExtraModes/EnemyRandomizer.cpp b/soh/soh/Enhancements/ExtraModes/EnemyRandomizer.cpp index f518106c7c..1ec49e0afe 100644 --- a/soh/soh/Enhancements/ExtraModes/EnemyRandomizer.cpp +++ b/soh/soh/Enhancements/ExtraModes/EnemyRandomizer.cpp @@ -1,5 +1,6 @@ #include "functions.h" #include "macros.h" +#include "soh/ShipUtils.h" #include "soh/Enhancements/randomizer/SeedContext.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/ObjectExtension/ObjectExtension.h" @@ -483,9 +484,11 @@ static u8 GetRandomizedEnemy(PlayState* play, s16* actorId, s16* posX, s16* posY // This should probably be handled on OTR generation in the future when object dependency is fully removed. // Remove bats and Skulltulas from graveyard. // Remove Octorok in Lost Woods. + // Remove signs in Gerudo Fortress as child if (((*actorId == ACTOR_EN_FIREFLY || (*actorId == ACTOR_EN_SW && *params == 0)) && play->sceneNum == SCENE_GRAVEYARD) || - (*actorId == ACTOR_EN_OKUTA && play->sceneNum == SCENE_LOST_WOODS)) { + (*actorId == ACTOR_EN_OKUTA && play->sceneNum == SCENE_LOST_WOODS) || + (*actorId == ACTOR_EN_KANBAN && play->sceneNum == SCENE_GERUDOS_FORTRESS && LINK_IS_CHILD)) { return 0; } diff --git a/soh/soh/Enhancements/ExtraModes/MirroredWorld.cpp b/soh/soh/Enhancements/ExtraModes/MirroredWorld.cpp index 98d9c2c0d8..304046bb4a 100644 --- a/soh/soh/Enhancements/ExtraModes/MirroredWorld.cpp +++ b/soh/soh/Enhancements/ExtraModes/MirroredWorld.cpp @@ -1,6 +1,6 @@ #include "soh/Enhancements/cosmetics/authenticGfxPatches.h" -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/Enhancements/randomizer/3drando/random.hpp" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipUtils.h" #include "soh/Enhancements/randomizer/SeedContext.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/ResourceManagerHelpers.h" @@ -25,20 +25,22 @@ static bool MirroredWorld_IsInDungeon(int32_t sceneNum) { (sceneNum == SCENE_GANON_BOSS); } -static void MirroredWorld_InitRandomSeed(int32_t sceneNum) { +static void MirroredWorld_InitRandomSeed(int32_t sceneNum, uint64_t* randState) { uint32_t seed = sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt); - Random_Init(seed); + ShipUtils::RandInit(seed, randState); } static bool MirroredWorld_ShouldApply(int32_t sceneNum) { + uint64_t randState = 0; switch (CVAR_MIRRORED_WORLD_MODE_VALUE) { case MIRRORED_WORLD_ALWAYS: return true; case MIRRORED_WORLD_RANDOM_SEEDED: - MirroredWorld_InitRandomSeed(sceneNum); + MirroredWorld_InitRandomSeed(sceneNum, &randState); + return ShipUtils::Random(0, 2, &randState) == 0; case MIRRORED_WORLD_RANDOM: - return Random(0, 2) == 1; + return ShipUtils::Random(0, 2) == 0; case MIRRORED_WORLD_DUNGEONS_ALL: return MirroredWorld_IsInDungeon(sceneNum); case MIRRORED_WORLD_DUNGEONS_VANILLA: @@ -46,9 +48,10 @@ static bool MirroredWorld_ShouldApply(int32_t sceneNum) { case MIRRORED_WORLD_DUNGEONS_MQ: return MirroredWorld_IsInDungeon(sceneNum) && ResourceMgr_IsSceneMasterQuest(sceneNum); case MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED: - MirroredWorld_InitRandomSeed(sceneNum); + MirroredWorld_InitRandomSeed(sceneNum, &randState); + return MirroredWorld_IsInDungeon(sceneNum) && ShipUtils::Random(0, 2, &randState) == 0; case MIRRORED_WORLD_DUNGEONS_RANDOM: - return MirroredWorld_IsInDungeon(sceneNum) && (Random(0, 2) == 1); + return MirroredWorld_IsInDungeon(sceneNum) && ShipUtils::Random(0, 2) == 0; default: return false; } diff --git a/soh/soh/Enhancements/ExtraModes/RandomizedEnemySizes.cpp b/soh/soh/Enhancements/ExtraModes/RandomizedEnemySizes.cpp index acb4b94d3b..671a7e6b93 100644 --- a/soh/soh/Enhancements/ExtraModes/RandomizedEnemySizes.cpp +++ b/soh/soh/Enhancements/ExtraModes/RandomizedEnemySizes.cpp @@ -1,6 +1,7 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ObjectExtension/ActorMaximumHealth.h" #include "soh/ShipInit.hpp" +#include "soh/ShipUtils.h" extern "C" { #include "functions.h" @@ -30,25 +31,17 @@ static void RandomizedEnemySizes(void* refActor) { return; } - float randomNumber; - float randomScale; - // Dodongo, Volvagia and Dead Hand are always smaller because they're impossible when bigger. bool smallOnlyEnemy = actor->id == ACTOR_BOSS_DODONGO || actor->id == ACTOR_BOSS_FD || actor->id == ACTOR_BOSS_FD2 || actor->id == ACTOR_EN_DH; - bool bigActor = !smallOnlyEnemy && (rand() % 2); + bool bigActor = !smallOnlyEnemy && ShipUtils::Random(0, 2) == 0; - // Big actor + float randomScale; if (bigActor) { - randomNumber = rand() % 200; - // Between 100% and 300% size. - randomScale = 1.0f + (randomNumber / 100); + randomScale = 1.0f + ShipUtils::RandomDouble() * 2.0f; } else { - // Small actor - randomNumber = rand() % 90; - // Between 10% and 100% size. - randomScale = 0.1f + (randomNumber / 100); + randomScale = 0.1f + ShipUtils::RandomDouble() * 0.9f; } Actor_SetScale(actor, actor->scale.z * randomScale); diff --git a/soh/soh/Enhancements/FileSelectEnhancements.cpp b/soh/soh/Enhancements/FileSelectEnhancements.cpp index 08dd815094..7f26d02c18 100644 --- a/soh/soh/Enhancements/FileSelectEnhancements.cpp +++ b/soh/soh/Enhancements/FileSelectEnhancements.cpp @@ -84,7 +84,7 @@ void SohFileSelect_ShowPresetModal() { return; } std::shared_ptr modal = static_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Modal Window")); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Modal Window")); if (modal->IsPopupOpen("Take a look at our presets!")) { modal->DismissPopup(); } else { diff --git a/soh/soh/Enhancements/Fixes/FixWaterMQLock.cpp b/soh/soh/Enhancements/Fixes/FixWaterMQLock.cpp new file mode 100644 index 0000000000..c4a9c78457 --- /dev/null +++ b/soh/soh/Enhancements/Fixes/FixWaterMQLock.cpp @@ -0,0 +1,26 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "src/overlays/actors/ovl_En_Door/z_en_door.h" +extern PlayState* gPlayState; +} + +static constexpr int32_t CVAR_MQ_WATER_LOCK_DEFAULT = 0; +#define CVAR_MQ_WATER_LOCK_FIX_NAME CVAR_ENHANCEMENT("MQWaterLockFix") +#define CVAR_MQ_WATER_LOCK_VALUE CVarGetInteger(CVAR_MQ_WATER_LOCK_FIX_NAME, CVAR_MQ_WATER_LOCK_DEFAULT) + +static void OnInitEnDoor(void* refActor) { + EnDoor* enDoor = reinterpret_cast(refActor); + if (gPlayState->sceneNum == SCENE_WATER_TEMPLE && ResourceMgr_IsGameMasterQuest() && + enDoor->actor.params == 22659) { + enDoor->actor.params = 22660; + } +} + +static void RegisterMQWaterLockFix() { + COND_ID_HOOK(OnActorInit, ACTOR_EN_DOOR, IS_RANDO || CVAR_MQ_WATER_LOCK_VALUE, OnInitEnDoor); +} + +static RegisterShipInitFunc initFunc(RegisterMQWaterLockFix, { CVAR_MQ_WATER_LOCK_FIX_NAME, "IS_RANDO" }); diff --git a/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp b/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp new file mode 100644 index 0000000000..f4d8331f70 --- /dev/null +++ b/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp @@ -0,0 +1,38 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipInit.hpp" +#include "soh/ResourceManagerHelpers.h" + +extern "C" { +#include "macros.h" +#include "functions.h" +#include "objects/object_link_boy/object_link_boy.h" +extern SaveContext gSaveContext; +} + +static const char* sAdultMaskDLists[] = { + gLinkAdultKeatonMaskDL, gLinkAdultSkullMaskDL, gLinkAdultSpookyMaskDL, gLinkAdultBunnyHoodDL, + gLinkAdultGoronMaskDL, gLinkAdultZoraMaskDL, gLinkAdultGerudoMaskDL, gLinkAdultMaskOfTruthDL, +}; + +static void RegisterAgeDependentMasks() { + COND_VB_SHOULD(VB_DRAW_PLAYER_MASK, CVarGetInteger(CVAR_SETTING("AltAssets"), 1), { + if (!LINK_IS_ADULT) + return; + + PlayerMask currentMask = (PlayerMask)va_arg(args, int); + PlayState* play = va_arg(args, PlayState*); + + int maskIndex = currentMask - 1; + if (maskIndex < 0 || maskIndex >= 8) + return; + + const char* adultDL = sAdultMaskDLists[maskIndex]; + if (!ResourceGetIsCustomByName(adultDL) && !ResourceMgr_FileExists(adultDL)) + return; + + *should = false; + gSPDisplayList(play->state.gfxCtx->polyOpa.p++, (Gfx*)adultDL); + }); +} + +static RegisterShipInitFunc initFunc(RegisterAgeDependentMasks, { CVAR_SETTING("AltAssets") }); diff --git a/soh/soh/Enhancements/Graphics/DisableHeatHaze.cpp b/soh/soh/Enhancements/Graphics/DisableHeatHaze.cpp new file mode 100644 index 0000000000..0f49725cb3 --- /dev/null +++ b/soh/soh/Enhancements/Graphics/DisableHeatHaze.cpp @@ -0,0 +1,8 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipInit.hpp" + +void RegisterDisableHeatHaze() { + COND_VB_SHOULD(VB_HOT_ROOM_DISTORTION, CVarGetInteger(CVAR_SETTING("A11yNoHeatHaze"), 0), { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterDisableHeatHaze, { CVAR_SETTING("A11yNoHeatHaze") }); diff --git a/soh/soh/Enhancements/DisableJabuWobble.cpp b/soh/soh/Enhancements/Graphics/DisableJabuWobble.cpp similarity index 100% rename from soh/soh/Enhancements/DisableJabuWobble.cpp rename to soh/soh/Enhancements/Graphics/DisableJabuWobble.cpp diff --git a/soh/soh/Enhancements/DisableKokiriDrawDistance.cpp b/soh/soh/Enhancements/Graphics/DisableKokiriDrawDistance.cpp similarity index 100% rename from soh/soh/Enhancements/DisableKokiriDrawDistance.cpp rename to soh/soh/Enhancements/Graphics/DisableKokiriDrawDistance.cpp diff --git a/soh/soh/Enhancements/DisableSandstorm.cpp b/soh/soh/Enhancements/Graphics/DisableSandstorm.cpp similarity index 100% rename from soh/soh/Enhancements/DisableSandstorm.cpp rename to soh/soh/Enhancements/Graphics/DisableSandstorm.cpp diff --git a/soh/soh/Enhancements/RemoveSpinAttackDarkness.cpp b/soh/soh/Enhancements/Graphics/RemoveSpinAttackDarkness.cpp similarity index 94% rename from soh/soh/Enhancements/RemoveSpinAttackDarkness.cpp rename to soh/soh/Enhancements/Graphics/RemoveSpinAttackDarkness.cpp index 9658170301..6349a7818e 100644 --- a/soh/soh/Enhancements/RemoveSpinAttackDarkness.cpp +++ b/soh/soh/Enhancements/Graphics/RemoveSpinAttackDarkness.cpp @@ -18,8 +18,8 @@ void Custom_EnMThunder_Update(Actor* thisx, PlayState* play) { enMThunder->actionFunc(enMThunder, play); // don't call this part, it's what makes the spin attack darkness happen - // func_80A9F314(play, this->unk_1BC); - blueRadius = enMThunder->unk_1AC; + // func_80A9F314(play, this->dimmingIntensity); + blueRadius = enMThunder->spinAttackTimer; redGreen = (u32)(blueRadius * 255.0f) & 0xFF; Lights_PointNoGlowSetInfo(&enMThunder->lightInfo, enMThunder->actor.world.pos.x, enMThunder->actor.world.pos.y, enMThunder->actor.world.pos.z, redGreen, redGreen, (u32)(blueRadius * 100.0f), diff --git a/soh/soh/Enhancements/ArrowCycle.cpp b/soh/soh/Enhancements/Items/ArrowCycle.cpp similarity index 95% rename from soh/soh/Enhancements/ArrowCycle.cpp rename to soh/soh/Enhancements/Items/ArrowCycle.cpp index f8b9a84fb5..a60f562f12 100644 --- a/soh/soh/Enhancements/ArrowCycle.cpp +++ b/soh/soh/Enhancements/Items/ArrowCycle.cpp @@ -82,9 +82,9 @@ static ArrowType GetArrowTypeForArrow(s8 itemAction) { static bool CanCycleArrows() { Player* player = GET_PLAYER(gPlayState); - return LINK_IS_ADULT && !gSaveContext.minigameState && gPlayState->sceneNum != SCENE_SHOOTING_GALLERY && - !(player->stateFlags1 & PLAYER_STATE1_ON_HORSE) && player->rideActor == NULL && - INV_CONTENT(SLOT_BOW) == ITEM_BOW && + return (LINK_IS_ADULT || CVarGetInteger(CVAR_CHEAT("TimelessEquipment"), 0)) && !gSaveContext.minigameState && + gPlayState->sceneNum != SCENE_SHOOTING_GALLERY && !(player->stateFlags1 & PLAYER_STATE1_ON_HORSE) && + player->rideActor == NULL && INV_CONTENT(SLOT_BOW) == ITEM_BOW && (INV_CONTENT(ITEM_ARROW_FIRE) == ITEM_ARROW_FIRE || INV_CONTENT(ITEM_ARROW_ICE) == ITEM_ARROW_ICE || INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT); } diff --git a/soh/soh/Enhancements/AssignableTunicsAndBoots.cpp b/soh/soh/Enhancements/Items/AssignableTunicsAndBoots.cpp similarity index 100% rename from soh/soh/Enhancements/AssignableTunicsAndBoots.cpp rename to soh/soh/Enhancements/Items/AssignableTunicsAndBoots.cpp diff --git a/soh/soh/Enhancements/Items/BetterBombchuShopping.cpp b/soh/soh/Enhancements/Items/BetterBombchuShopping.cpp index 90989ed246..4982670d2a 100644 --- a/soh/soh/Enhancements/Items/BetterBombchuShopping.cpp +++ b/soh/soh/Enhancements/Items/BetterBombchuShopping.cpp @@ -1,4 +1,5 @@ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include diff --git a/soh/soh/Enhancements/Items/BlueFireArrows.cpp b/soh/soh/Enhancements/Items/BlueFireArrows.cpp new file mode 100644 index 0000000000..985767853a --- /dev/null +++ b/soh/soh/Enhancements/Items/BlueFireArrows.cpp @@ -0,0 +1,55 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/randomizer/SeedContext.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h" +#include "overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.h" + +extern PlayState* gPlayState; +} + +static void UpdateBlueFireCollidersBgBreakwall(void* actorPtr) { + BgBreakwall* thisx = (BgBreakwall*)actorPtr; + thisx->collider.info.bumper.dmgFlags |= DMG_ARROW_ICE; +} + +static void UpdateBlueFireCollidersBgIceShelter(void* actorPtr) { + BgIceShelter* thisx = (BgIceShelter*)actorPtr; + thisx->cylinder1.base.acFlags |= AC_TYPE_PLAYER; + thisx->cylinder1.info.bumper.dmgFlags |= DMG_ARROW_ICE; + thisx->cylinder2.base.acFlags |= AC_TYPE_PLAYER; + thisx->cylinder2.info.bumper.dmgFlags |= DMG_ARROW_ICE; +} + +static bool CheckAC(Actor* ac) { + return ac != NULL && ac->id == ACTOR_EN_ARROW && ac->child != NULL && ac->child->id == ACTOR_ARROW_ICE; +} + +void RegisterBlueFireArrowsHooks() { + bool shouldRegister = + CVarGetInteger(CVAR_ENHANCEMENT("BlueFireArrows"), 0) || (IS_RANDO && RAND_GET_OPTION(RSK_BLUE_FIRE_ARROWS)); + + COND_ID_HOOK(OnActorInit, ACTOR_BG_BREAKWALL, shouldRegister, UpdateBlueFireCollidersBgBreakwall); + COND_ID_HOOK(OnActorInit, ACTOR_BG_ICE_SHELTER, shouldRegister, UpdateBlueFireCollidersBgIceShelter); + + // fix bug where cylinder2 never checks acFlags + COND_VB_SHOULD(VB_BG_ICE_SHELTER_HIT, shouldRegister, { + BgIceShelter* thisx = va_arg(args, BgIceShelter*); + + if (thisx->cylinder2.base.acFlags & AC_HIT) { + thisx->cylinder2.base.acFlags &= ~AC_HIT; + *should = true; + } + }); + + COND_VB_SHOULD(VB_BG_ICE_SHELTER_MELT, shouldRegister, { + BgIceShelter* thisx = va_arg(args, BgIceShelter*); + + if (CheckAC(thisx->cylinder1.base.ac) || CheckAC(thisx->cylinder2.base.ac)) { + *should = true; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterBlueFireArrowsHooks, { "IS_RANDO", CVAR_ENHANCEMENT("BlueFireArrows") }); diff --git a/soh/soh/Enhancements/InjectItemCounts.cpp b/soh/soh/Enhancements/Items/InjectItemCounts.cpp similarity index 98% rename from soh/soh/Enhancements/InjectItemCounts.cpp rename to soh/soh/Enhancements/Items/InjectItemCounts.cpp index 8d66ba2712..caa2cf9d0e 100644 --- a/soh/soh/Enhancements/InjectItemCounts.cpp +++ b/soh/soh/Enhancements/Items/InjectItemCounts.cpp @@ -1,4 +1,5 @@ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "variables.h" diff --git a/soh/soh/Enhancements/ItemUnequip.cpp b/soh/soh/Enhancements/Items/ItemUnequip.cpp similarity index 100% rename from soh/soh/Enhancements/ItemUnequip.cpp rename to soh/soh/Enhancements/Items/ItemUnequip.cpp diff --git a/soh/soh/Enhancements/MaskSelect.cpp b/soh/soh/Enhancements/Items/MaskSelect.cpp similarity index 100% rename from soh/soh/Enhancements/MaskSelect.cpp rename to soh/soh/Enhancements/Items/MaskSelect.cpp diff --git a/soh/soh/Enhancements/RemoteBombchu.cpp b/soh/soh/Enhancements/Items/RemoteBombchu.cpp similarity index 100% rename from soh/soh/Enhancements/RemoteBombchu.cpp rename to soh/soh/Enhancements/Items/RemoteBombchu.cpp diff --git a/soh/soh/Enhancements/SunlightArrows.cpp b/soh/soh/Enhancements/Items/SunlightArrows.cpp similarity index 100% rename from soh/soh/Enhancements/SunlightArrows.cpp rename to soh/soh/Enhancements/Items/SunlightArrows.cpp diff --git a/soh/soh/Enhancements/UnsheatheWithoutSlashing.cpp b/soh/soh/Enhancements/Items/UnsheatheWithoutSlashing.cpp similarity index 100% rename from soh/soh/Enhancements/UnsheatheWithoutSlashing.cpp rename to soh/soh/Enhancements/Items/UnsheatheWithoutSlashing.cpp diff --git a/soh/soh/Enhancements/Lang/Lang.cpp b/soh/soh/Enhancements/Lang/Lang.cpp new file mode 100644 index 0000000000..981e372c3f --- /dev/null +++ b/soh/soh/Enhancements/Lang/Lang.cpp @@ -0,0 +1,143 @@ +#include "Lang.h" + +#include "soh/SohGui/MenuTypes.h" +#include "soh/SohGui/SohGui.hpp" +#include "soh/SohGui/SohMenu.h" +#include "soh/util.h" + +#include "ship/Context.h" +#include "ship/resource/File.h" +#include "ship/resource/ResourceManager.h" +#include "ship/resource/type/Json.h" +#include "ship/utils/StringHelper.h" + +#include "spdlog/spdlog.h" + +#include + +namespace SohGui { +extern std::shared_ptr mSohMenu; +} + +static bool initialized = false; +static std::map langs; + +#define LANGUAGE_CVAR CVAR_SETTING("Language") +#define DEFAULT_LANGUAGE "en_US" + +std::string Lang::Translate(const char* path) { + if (!initialized) { + SPDLOG_ERROR("Tried to obtain a translation before the translation data is initialized"); + assert(false); + return "ERROR: Language data not initialized yet"; + } + + std::string currentLang = CVarGetString(LANGUAGE_CVAR, DEFAULT_LANGUAGE); + + if (!langs.contains(currentLang)) { + SPDLOG_WARN("Current language ({}) doesn't exist, trying to fall back to default language ({})", + currentLang.c_str(), DEFAULT_LANGUAGE); + + currentLang = DEFAULT_LANGUAGE; + + if (!langs.contains(currentLang)) { + SPDLOG_ERROR("Default language ({}) doesn't exist", DEFAULT_LANGUAGE); + assert(false); + return "ERROR: Language data not found"; + } + + CVarSetString(LANGUAGE_CVAR, DEFAULT_LANGUAGE); + SPDLOG_WARN("Fallback to default language ({}) was succesful", DEFAULT_LANGUAGE); + } + + nlohmann::json currentLangData = langs[currentLang]; + + std::vector segments = SohUtils::StringSplit(std::string(path), "."); + + std::string lastSegment = segments[segments.size() - 1]; + + segments.pop_back(); + + for (const auto& segment : segments) { + if (!currentLangData.contains(segment)) { + SPDLOG_WARN("Current language ({}) doesn't have data for the requested path ({})", currentLang.c_str(), + path); + return std::string(path); + } + + currentLangData = currentLangData[segment]; + } + + if (!currentLangData.contains(lastSegment)) { + SPDLOG_WARN("Current language ({}) doesn't have data for the requested path ({})", currentLang.c_str(), path); + return std::string(path); + } + + if (currentLangData[lastSegment].is_string()) { + return currentLangData[lastSegment].get(); + } + + if (currentLangData[lastSegment].is_array()) { + std::string translatedString = ""; + + for (const auto& item : currentLangData[lastSegment]) { + if (!item.is_string()) { + SPDLOG_WARN("Current language ({}) has an array with a non-string at the requested path ({})", + currentLang.c_str(), path); + return std::string(path); + } + + translatedString += item.get(); + } + + return translatedString; + } + + SPDLOG_WARN("Current language ({}) doesn't have either a string or an array at the requested path ({})", + currentLang.c_str(), path); + return std::string(path); +} + +void Lang::LoadLangs() { + auto initData = std::make_shared(); + initData->Format = RESOURCE_FORMAT_BINARY; + initData->Type = static_cast(Ship::ResourceType::Json); + initData->ResourceVersion = 0; + const static std::string folder = "lang/*"; + auto langFiles = Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(folder); + size_t start = std::string(folder).size() - 1; + for (size_t i = 0; i < langFiles->size(); i++) { + std::string filePath = langFiles->at(i); + auto json = std::static_pointer_cast( + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(filePath, true, initData)); + + std::string fileName = filePath.substr(start, filePath.size() - start - 5); // 5 for length of ".json" + langs.insert_or_assign(fileName, json->Data); + } + initialized = true; +} + +void LanguageCustomWidget(WidgetInfo& info) { + ImGui::Text("Select Language:"); + for (const auto& [id, data] : langs) { + if (ImGui::Button(StringHelper::Sprintf("%s [%s]", data["language_name"].get_ref().c_str(), + id.c_str()) + .c_str())) { + CVarSetString(LANGUAGE_CVAR, id.c_str()); + } + } +} + +void RegisterLangWidgets() { + return; + + // TODO: Improve & enable this when everything is set up + + SohGui::mSohMenu->AddSidebarEntry("Settings", "Language", 1); + WidgetPath path = { "Settings", "Language", SECTION_COLUMN_1 }; + SohGui::mSohMenu->AddWidget(path, "LanguageWidget", WIDGET_CUSTOM) + .CustomFunction(LanguageCustomWidget) + .HideInSearch(true); +} + +static RegisterMenuInitFunc menuInitFunc(RegisterLangWidgets); \ No newline at end of file diff --git a/soh/soh/Enhancements/Lang/Lang.h b/soh/soh/Enhancements/Lang/Lang.h new file mode 100644 index 0000000000..3bf3a886f7 --- /dev/null +++ b/soh/soh/Enhancements/Lang/Lang.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace Lang { +std::string Translate(const char* path); +void LoadLangs(); +} // namespace Lang \ No newline at end of file diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index 12354dce41..8701a41764 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -7,15 +7,44 @@ #include #include #include "soh/OTRGlobals.h" +#include "soh/util.h" #include "soh/SohGui/MenuTypes.h" #include "soh/SohGui/SohMenu.h" #include "soh/SohGui/SohGui.hpp" #include "soh/Enhancements/randomizer/randomizer_check_tracker.h" #include "soh/Enhancements/randomizer/randomizer_entrance_tracker.h" #include "soh/Enhancements/randomizer/randomizer_item_tracker.h" +#include "soh/Enhancements/randomizer/settings.h" namespace fs = std::filesystem; +/** + * Replace characters to prevent crashes from invalid paths (e.g, "test :)" creating an NTFS Alternate Data Stream + * instead of a regular file). + */ +static std::string SanitizeFilename(const std::string& name) { + std::string result; + result.reserve(name.size()); + for (const char c : name) { + if (c == '<' || c == '>' || c == ':' || c == '"' || c == '/' || c == '\\' || c == '|' || c == '?' || c == '*' || + c < 32) { + result += '_'; + } else { + result += c; + } + } + + while (!result.empty() && (result.back() == '.' || result.back() == ' ')) { + result.pop_back(); + } + + if (result.empty()) { + result = "Unnamed"; + } + + return result; +} + namespace SohGui { extern std::shared_ptr mSohMenu; } // namespace SohGui @@ -72,7 +101,7 @@ static BlockInfo blockInfo[PRESET_SECTION_MAX] = { }; std::string FormatPresetPath(std::string name) { - return fmt::format("{}/{}.json", presetFolder, name); + return fmt::format("{}/{}.json", presetFolder, SanitizeFilename(name)); } void applyPreset(std::string presetName, std::vector includeSections) { @@ -107,7 +136,7 @@ void applyPreset(std::string presetName, std::vector includeSecti } else { auto block = item.value(); if (sectionStrategy == "merge") { - auto currentJson = Ship::Context::GetInstance()->GetConfig()->GetNestedJson(); + auto currentJson = Ship::Context::GetRawInstance()->GetConfig()->GetNestedJson(); if (currentJson.contains("CVars") && currentJson["CVars"].contains(item.key())) { block = currentJson["CVars"][item.key()]; // Recursively merge the two json objects @@ -115,9 +144,9 @@ void applyPreset(std::string presetName, std::vector includeSecti } } - Ship::Context::GetInstance()->GetConfig()->SetBlock(fmt::format("{}.{}", "CVars", item.key()), - block); - Ship::Context::GetInstance()->GetConsoleVariables()->Load(); + Ship::Context::GetRawInstance()->GetConfig()->SetBlock(fmt::format("{}.{}", "CVars", item.key()), + block); + Ship::Context::GetRawInstance()->GetConsoleVariables()->Load(); } } if (i == PRESET_SECTION_RANDOMIZER) { @@ -159,7 +188,7 @@ void DrawPresetSelector(std::vector includeSections, std::string if (ImGui::Selectable(iter->c_str(), *iter == currentIndex)) { CVarSetString(selectorCvar.c_str(), iter->c_str()); currentIndex = *iter; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } @@ -217,16 +246,19 @@ void LoadPresets() { } if (fs::exists(presetFolder)) { for (auto const& preset : fs::directory_iterator(presetFolder)) { - std::ifstream ifs(preset.path()); + try { + std::ifstream ifs(preset.path()); + if (auto json = nlohmann::json::parse(ifs); !json.contains("presetName")) { + spdlog::error(fmt::format("Attempted to load file {} as a preset, but was not a preset file.", + preset.path().filename().string())); + } else { + ParsePreset(json, preset.path().filename().stem().string()); + } - auto json = nlohmann::json::parse(ifs); - if (!json.contains("presetName")) { - spdlog::error(fmt::format("Attempted to load file {} as a preset, but was not a preset file.", - preset.path().filename().string())); - } else { - ParsePreset(json, preset.path().filename().stem().string()); + ifs.close(); + } catch (const std::exception& e) { + spdlog::error("Failed to load preset {}: {}", preset.path().filename().string(), e.what()); } - ifs.close(); } } auto initData = std::make_shared(); @@ -234,12 +266,12 @@ void LoadPresets() { initData->Type = static_cast(Ship::ResourceType::Json); initData->ResourceVersion = 0; std::string folder = "presets/*"; - auto builtIns = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(folder); + auto builtIns = Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(folder); size_t start = std::string(folder).size() - 1; for (size_t i = 0; i < builtIns->size(); i++) { std::string filePath = builtIns->at(i); auto json = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(filePath, true, initData)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(filePath, true, initData)); std::string fileName = filePath.substr(start, filePath.size() - start - 5); // 5 for length of ".json" ParsePreset(json->Data, fileName); @@ -252,8 +284,16 @@ void SavePreset(std::string& presetName) { } presets[presetName].presetValues["presetName"] = presetName; presets[presetName].presetValues["fileType"] = FILE_TYPE_PRESET; + + std::string safeFilename = SanitizeFilename(presetName); std::ofstream file( - fmt::format("{}/{}.json", Ship::Context::GetInstance()->LocateFileAcrossAppDirs("presets"), presetName)); + fmt::format("{}/{}.json", Ship::Context::GetRawInstance()->LocateFileAcrossAppDirs("presets"), safeFilename)); + + if (!file.is_open()) { + spdlog::error("Failed to save preset '{}': Could not create file", presetName); + return; + } + file << presets[presetName].presetValues.dump(4); file.close(); LoadPresets(); @@ -293,7 +333,7 @@ void DrawNewPresetPopup() { .Padding({ 6.0f, 6.0f }) .Color(THEME_COLOR))) { presets[newPresetName] = {}; - auto config = Ship::Context::GetInstance()->GetConfig()->GetNestedJson(); + auto config = Ship::Context::GetRawInstance()->GetConfig()->GetNestedJson(); for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { if (saveSection[i]) { for (size_t j = 0; j < blockInfo[i].sections.size(); j++) { @@ -459,7 +499,7 @@ void RegisterPresetsWidgets() { SohGui::mSohMenu->AddWidget(path, "PresetsWidget", WIDGET_CUSTOM) .CustomFunction(PresetsCustomWidget) .HideInSearch(true); - presetFolder = Ship::Context::GetInstance()->GetPathRelativeToAppDirectory("presets"); + presetFolder = Ship::Context::GetRawInstance()->GetPathRelativeToAppDirectory("presets"); std::fill_n(saveSection, PRESET_SECTION_MAX, true); LoadPresets(); } diff --git a/soh/soh/Enhancements/NoSkulltulaFreeze.cpp b/soh/soh/Enhancements/QoL/NoSkulltulaFreeze.cpp similarity index 95% rename from soh/soh/Enhancements/NoSkulltulaFreeze.cpp rename to soh/soh/Enhancements/QoL/NoSkulltulaFreeze.cpp index abefde2b56..66e6132a17 100644 --- a/soh/soh/Enhancements/NoSkulltulaFreeze.cpp +++ b/soh/soh/Enhancements/QoL/NoSkulltulaFreeze.cpp @@ -1,4 +1,5 @@ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "variables.h" diff --git a/soh/soh/Enhancements/QoL/OcarinaTimeTravel.cpp b/soh/soh/Enhancements/QoL/OcarinaTimeTravel.cpp new file mode 100644 index 0000000000..12b220e6b2 --- /dev/null +++ b/soh/soh/Enhancements/QoL/OcarinaTimeTravel.cpp @@ -0,0 +1,63 @@ +#include +#include "soh/ShipInit.hpp" +#include "functions.h" +#include "macros.h" +#include "variables.h" +#include "soh/Enhancements/enhancementTypes.h" +#include "soh/Enhancements/SwitchAge.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" + +extern "C" PlayState* gPlayState; + +#define CVAR_OCARINA_TIME_TRAVEL_DEFAULT 0 +#define CVAR_OCARINA_TIME_TRAVEL_NAME CVAR_ENHANCEMENT("TimeTravel") +#define CVAR_OCARINA_TIME_TRAVEL_VALUE CVarGetInteger(CVAR_OCARINA_TIME_TRAVEL_NAME, CVAR_OCARINA_TIME_TRAVEL_DEFAULT) + +/// Switches Link's age and respawns him at the last entrance he entered. +void OcarinaTimeTravel() { + if (!GameInteractor::IsSaveLoaded(true)) { + return; + } + + Actor* player = &GET_PLAYER(gPlayState)->actor; + Actor* nearbyTimeBlockEmpty = + Actor_FindNearby(gPlayState, player, ACTOR_OBJ_WARP2BLOCK, ACTORCAT_ITEMACTION, 300.0f); + Actor* nearbyTimeBlock = Actor_FindNearby(gPlayState, player, ACTOR_OBJ_TIMEBLOCK, ACTORCAT_ITEMACTION, 300.0f); + Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.0f); + Actor* nearbyDoorOfTime = Actor_FindNearby(gPlayState, player, ACTOR_DOOR_TOKI, ACTORCAT_BG, 500.0f); + Actor* nearbyFrogs = Actor_FindNearby(gPlayState, player, ACTOR_EN_FR, ACTORCAT_NPC, 300.0f); + Actor* nearbyGossipStone = Actor_FindNearby(gPlayState, player, ACTOR_EN_GS, ACTORCAT_NPC, 300.0f); + bool justPlayedSoT = gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME; + bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && + !nearbyFrogs && !nearbyGossipStone; + bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); + bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); + 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(); + } +} + +static void RegisterOcarinaTimeTravel() { + COND_HOOK(OnOcarinaSongAction, CVAR_OCARINA_TIME_TRAVEL_VALUE, OcarinaTimeTravel); +} + +static RegisterShipInitFunc initFunc(RegisterOcarinaTimeTravel, { CVAR_OCARINA_TIME_TRAVEL_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/QoL/OpenAllHours.cpp b/soh/soh/Enhancements/QoL/OpenAllHours.cpp index b46db53c37..fd8d1a2ad9 100644 --- a/soh/soh/Enhancements/QoL/OpenAllHours.cpp +++ b/soh/soh/Enhancements/QoL/OpenAllHours.cpp @@ -1,4 +1,5 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/randomizer/randomizer.h" #include "soh/OTRGlobals.h" #include "soh/ShipInit.hpp" diff --git a/soh/soh/Enhancements/RebottleBlueFire.cpp b/soh/soh/Enhancements/QoL/RebottleBlueFire.cpp similarity index 100% rename from soh/soh/Enhancements/RebottleBlueFire.cpp rename to soh/soh/Enhancements/QoL/RebottleBlueFire.cpp diff --git a/soh/soh/Enhancements/ResetHotKey.cpp b/soh/soh/Enhancements/QoL/ResetHotKey.cpp similarity index 92% rename from soh/soh/Enhancements/ResetHotKey.cpp rename to soh/soh/Enhancements/QoL/ResetHotKey.cpp index b57ae4ff2b..644b797f07 100644 --- a/soh/soh/Enhancements/ResetHotKey.cpp +++ b/soh/soh/Enhancements/QoL/ResetHotKey.cpp @@ -22,7 +22,7 @@ static void OnGameStateMainStartResetHotkey() { CHECK_BTN_ALL(gGameState->input[0].cur.button, mask)) { auto consoleWin = std::reinterpret_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")); if (consoleWin) { consoleWin->Dispatch("reset"); diff --git a/soh/soh/Enhancements/ReworkedTargeting.cpp b/soh/soh/Enhancements/QoL/ReworkedTargeting.cpp similarity index 100% rename from soh/soh/Enhancements/ReworkedTargeting.cpp rename to soh/soh/Enhancements/QoL/ReworkedTargeting.cpp diff --git a/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp b/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp index 78b1a45ba8..676e05d953 100644 --- a/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp +++ b/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp @@ -29,8 +29,10 @@ CollisionHeader* getGraveyardCollisionHeader() { * 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::Scene* scene = (SOH::Scene*)Ship::Context::GetRawInstance() + ->GetResourceManager() + ->LoadResource(GRAVEYARD_SCENE_FILEPATH) + .get(); SOH::SetCollisionHeader* sceneCmd = nullptr; for (size_t i = 0; i < scene->commands.size(); i++) { auto cmd = scene->commands[i]; diff --git a/soh/soh/Enhancements/Restorations/N64WeirdFrames/WeirdAnimation.cpp b/soh/soh/Enhancements/Restorations/N64WeirdFrames/WeirdAnimation.cpp index c4cbc4bfec..4fd6427232 100644 --- a/soh/soh/Enhancements/Restorations/N64WeirdFrames/WeirdAnimation.cpp +++ b/soh/soh/Enhancements/Restorations/N64WeirdFrames/WeirdAnimation.cpp @@ -36,7 +36,7 @@ void WeirdAnimation::Build() { auto& animation = animationData.emplace(); for (const auto& neighborName : neighborAnimations) { - const auto neighbor = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(neighborName); + const auto neighbor = Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(neighborName); const auto prevSize = animation.size(); animation.resize(prevSize + neighbor->GetPointerSize()); diff --git a/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp b/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp index 7c56fab244..7b55b3c81e 100644 --- a/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp +++ b/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp @@ -19,9 +19,8 @@ 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) { + if (doorShutter->gfxType == SHUTTER_BACK_LOCKED || doorShutter->gfxType == SHUTTER_PG_BARS || + doorShutter->gfxType == SHUTTER_BOSS || doorShutter->gfxType == SHUTTER_GOHMA_BLOCK) { *should = (SHUTTER_DOOR_RANGE_X < fabsf(relPlayerPos.x) || SHUTTER_DOOR_RANGE_Y < fabsf(relPlayerPos.y)); } }); diff --git a/soh/soh/Enhancements/SwitchAge.cpp b/soh/soh/Enhancements/SwitchAge.cpp new file mode 100644 index 0000000000..1e3973fe0c --- /dev/null +++ b/soh/soh/Enhancements/SwitchAge.cpp @@ -0,0 +1,64 @@ +#include "soh/Enhancements/SwitchAge.h" +#include +#include "soh/Enhancements/enhancementTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" + +extern "C" { +#include +#include "macros.h" +#include "soh/cvar_prefixes.h" +#include "variables.h" +#include "functions.h" + +extern SaveContext gSaveContext; +extern PlayState* gPlayState; +} + +/// Switches Link's age and respawns him at the last entrance he entered. +void SwitchAge() { + if (gPlayState == NULL) + return; + + Player* player = GET_PLAYER(gPlayState); + + // Hyrule Castle: Very likely to fall through floor, so we force a specific entrance + if (gPlayState->sceneNum == SCENE_HYRULE_CASTLE || gPlayState->sceneNum == SCENE_OUTSIDE_GANONS_CASTLE) { + gPlayState->nextEntranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT; + } else { + gSaveContext.respawnFlag = 1; + gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; + + // Preserve the player's position and orientation + gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = gPlayState->nextEntranceIndex; + gSaveContext.respawn[RESPAWN_MODE_DOWN].roomIndex = gPlayState->roomCtx.curRoom.num; + gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = player->actor.world.pos; + gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = player->actor.shape.rot.y; + + if (gPlayState->roomCtx.curRoom.behaviorType2 < 4) { + gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0DFF; + } else { + // Scenes with static backgrounds use a special camera we need to preserve + Camera* camera = GET_ACTIVE_CAM(gPlayState); + s16 camId = camera->camDataIdx; + gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0D00 | camId; + } + } + + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_INSTANT; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK_FAST; + gPlayState->linkAgeOnLoad ^= 1; + + // Discover adult/child spawns + if (gPlayState->linkAgeOnLoad == LINK_AGE_ADULT) { + Entrance_SetEntranceDiscovered(ENTR_HYRULE_FIELD_10, false); + } else { + Entrance_SetEntranceDiscovered(ENTR_LINKS_HOUSE_CHILD_SPAWN, false); + } + + static HOOK_ID hookId = 0; + hookId = REGISTER_VB_SHOULD(VB_INFLICT_VOID_DAMAGE, { + *should = false; + GameInteractor::Instance->UnregisterGameHookForID(hookId); + }); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/SwitchAge.h b/soh/soh/Enhancements/SwitchAge.h new file mode 100644 index 0000000000..646e9b59e5 --- /dev/null +++ b/soh/soh/Enhancements/SwitchAge.h @@ -0,0 +1,3 @@ +#pragma once + +void SwitchAge(); \ No newline at end of file diff --git a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp index 5e213d26d3..57ef0286ab 100644 --- a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp +++ b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp @@ -6,6 +6,10 @@ #include "assets/soh_assets.h" #include "soh/SohGui/ImGuiUtils.h" +#include + +#include + extern "C" { #include "macros.h" #include "functions.h" @@ -83,18 +87,22 @@ static void TimeDisplayGetTimer(uint32_t timeID) { Player* player = GET_PLAYER(gPlayState); uint32_t timer1 = gSaveContext.timerSeconds; + auto gui = std::dynamic_pointer_cast( + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui())); + switch (timeID) { case DISPLAY_IN_GAME_TIMER: - textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("GAMEPLAY_TIMER"); + textureDisplay = gui->GetTextureByName("GAMEPLAY_TIMER"); + textureDisplay = gui->GetTextureByName("GAMEPLAY_TIMER"); timeDisplayTime = formatTimeDisplay(GAMEPLAYSTAT_TOTAL_TIME).c_str(); break; case DISPLAY_TIME_OF_DAY: if (gSaveContext.dayTime >= DAY_BEGINS && gSaveContext.dayTime < NIGHT_BEGINS) { - textureDisplay = - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("DAY_TIME_TIMER"); + textureDisplay = gui->GetTextureByName("DAY_TIME_TIMER"); + textureDisplay = gui->GetTextureByName("DAY_TIME_TIMER"); } else { - textureDisplay = - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("NIGHT_TIME_TIMER"); + textureDisplay = gui->GetTextureByName("NIGHT_TIME_TIMER"); + textureDisplay = gui->GetTextureByName("NIGHT_TIME_TIMER"); } timeDisplayTime = convertDayTime(gSaveContext.dayTime).c_str(); break; @@ -107,18 +115,22 @@ static void TimeDisplayGetTimer(uint32_t timeID) { : COLOR_LIGHT_BLUE) : COLOR_WHITE; if (gSaveContext.timerState <= TIMER_STATE_ENV_HAZARD_TICK) { - textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - gPlayState->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_3 - ? itemMapping[ITEM_TUNIC_GORON].name - : itemMapping[ITEM_TUNIC_ZORA].name); + textureDisplay = + gui->GetTextureByName(gPlayState->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_3 + ? itemMapping[ITEM_TUNIC_GORON].name + : itemMapping[ITEM_TUNIC_ZORA].name); + textureDisplay = + gui->GetTextureByName(gPlayState->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_3 + ? itemMapping[ITEM_TUNIC_GORON].name + : itemMapping[ITEM_TUNIC_ZORA].name); } if (gSaveContext.timerState >= TIMER_STATE_DOWN_PREVIEW) { - textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - itemMapping[ITEM_SWORD_MASTER].name); + textureDisplay = gui->GetTextureByName(itemMapping[ITEM_SWORD_MASTER].name); + textureDisplay = gui->GetTextureByName(itemMapping[ITEM_SWORD_MASTER].name); } } else { - textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - itemMapping[ITEM_TUNIC_KOKIRI].name); + textureDisplay = gui->GetTextureByName(itemMapping[ITEM_TUNIC_KOKIRI].name); + textureDisplay = gui->GetTextureByName(itemMapping[ITEM_TUNIC_KOKIRI].name); timeDisplayTime = "-:--"; } break; @@ -132,7 +144,8 @@ static void TimeDisplayGetTimer(uint32_t timeID) { timeDisplayTime = convertNaviTime(NAVI_COOLDOWN - gSaveContext.naviTimer).c_str(); textColor = COLOR_GREY; } - textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("NAVI_TIMER"); + textureDisplay = gui->GetTextureByName("NAVI_TIMER"); + textureDisplay = gui->GetTextureByName("NAVI_TIMER"); break; default: break; @@ -203,13 +216,15 @@ void TimeDisplayWindow::Draw() { } if (textToDecode[i] == '.') { ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (8.0f * fontScale)); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - digitList[textureIndex].first), + ImGui::Image(std::dynamic_pointer_cast( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(digitList[textureIndex].first), ImVec2(8.0f * fontScale, 8.0f * fontScale), ImVec2(0, 0.5f), ImVec2(1, 1), textColor, ImVec4(0, 0, 0, 0)); } else { - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - digitList[textureIndex].first), + ImGui::Image(std::dynamic_pointer_cast( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(digitList[textureIndex].first), ImVec2(8.0f * fontScale, 16.0f * fontScale), ImVec2(0, 0), ImVec2(1, 1), textColor, ImVec4(0, 0, 0, 0)); } @@ -247,17 +262,18 @@ static void TimeDisplayInitTimers() { } void TimeDisplayWindow::InitElement() { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("GAMEPLAY_TIMER", gClockIconTex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("DAY_TIME_TIMER", gSunIconTex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("NIGHT_TIME_TIMER", gMoonIconTex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("NAVI_TIMER", gNaviIconTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("GAMEPLAY_TIMER", gClockIconTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("DAY_TIME_TIMER", gSunIconTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("NIGHT_TIME_TIMER", gMoonIconTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("NAVI_TIMER", gNaviIconTex, ImVec4(1, 1, 1, 1)); for (auto& load : digitList) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(load.first.c_str(), load.second, - ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(load.first.c_str(), load.second, ImVec4(1, 1, 1, 1)); } TimeDisplayInitSettings(); diff --git a/soh/soh/Enhancements/TimeSavers/MarketSneak.cpp b/soh/soh/Enhancements/TimeSavers/MarketSneak.cpp index a8b190bf11..b1567cb4c9 100644 --- a/soh/soh/Enhancements/TimeSavers/MarketSneak.cpp +++ b/soh/soh/Enhancements/TimeSavers/MarketSneak.cpp @@ -1,4 +1,5 @@ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include diff --git a/soh/soh/Enhancements/TimeSavers/QuitFishingAtDoor.cpp b/soh/soh/Enhancements/TimeSavers/QuitFishingAtDoor.cpp index 3d408a0566..ea275d593b 100644 --- a/soh/soh/Enhancements/TimeSavers/QuitFishingAtDoor.cpp +++ b/soh/soh/Enhancements/TimeSavers/QuitFishingAtDoor.cpp @@ -1,4 +1,5 @@ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include diff --git a/soh/soh/Enhancements/SkipAmyPuzzle.cpp b/soh/soh/Enhancements/TimeSavers/SkipAmyPuzzle.cpp similarity index 100% rename from soh/soh/Enhancements/SkipAmyPuzzle.cpp rename to soh/soh/Enhancements/TimeSavers/SkipAmyPuzzle.cpp diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/TimeSavers/timesaver_hook_handlers.cpp similarity index 99% rename from soh/soh/Enhancements/timesaver_hook_handlers.cpp rename to soh/soh/Enhancements/TimeSavers/timesaver_hook_handlers.cpp index 204de040fa..34e1716975 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/TimeSavers/timesaver_hook_handlers.cpp @@ -58,8 +58,8 @@ void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) { Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); enMa1->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; play->msgCtx.ocarinaMode = OCARINA_MODE_04; - enMa1->actionFunc = func_80AA0D88; - enMa1->unk_1E0 = 1; + enMa1->actionFunc = EnMa1_Idle; + enMa1->singingDisabled = 1; enMa1->interactInfo.talkState = NPC_TALK_STATE_IDLE; return; } @@ -174,7 +174,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { // LACS - u8 meetsLACSRequirements = + bool meetsLACSRequirements = LINK_IS_ADULT && (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && @@ -519,7 +519,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; case VB_PLAY_DISPEL_BARRIER_CS: { - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { static s16 trialEntrances[] = { 0, ENTR_INSIDE_GANONS_CASTLE_3, @@ -916,14 +916,14 @@ void TimeSaverOnActorInitHandler(void* actorRef) { if (innerActor->id == ACTOR_EN_MA1 && (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), IS_RANDO) || IS_RANDO)) { EnMa1* enMa1 = static_cast(innerActorRef); - if (enMa1->actionFunc == func_80AA106C) { + if (enMa1->actionFunc == EnMa1_StartTeachSong) { enMa1->actionFunc = EnMa1_EndTeachSong; GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); enMa1UpdateHook = 0; enMa1KillHook = 0; // They've already learned the song - } else if (enMa1->actionFunc == func_80AA0D88) { + } else if (enMa1->actionFunc == EnMa1_Idle) { GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); enMa1UpdateHook = 0; diff --git a/soh/soh/Enhancements/Warping.cpp b/soh/soh/Enhancements/Warping.cpp index 0a21a21fc4..ad29a3c0c3 100644 --- a/soh/soh/Enhancements/Warping.cpp +++ b/soh/soh/Enhancements/Warping.cpp @@ -30,7 +30,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(WarpPoint, entranceId, roomNum, pos, rotY, bo std::map warpPoints; void LoadConfig() { - auto allConfig = Ship::Context::GetInstance()->GetConfig()->GetNestedJson(); + auto allConfig = Ship::Context::GetRawInstance()->GetConfig()->GetNestedJson(); if (allConfig.find("WarpPoints") == allConfig.end() || !allConfig["WarpPoints"].is_object()) { allConfig["WarpPoints"] = nlohmann::json::object(); } @@ -38,10 +38,10 @@ void LoadConfig() { } void SaveConfig() { - auto allConfig = Ship::Context::GetInstance()->GetConfig()->GetNestedJson(); + auto allConfig = Ship::Context::GetRawInstance()->GetConfig()->GetNestedJson(); allConfig["WarpPoints"] = warpPoints; - Ship::Context::GetInstance()->GetConfig()->SetBlock("WarpPoints", warpPoints); - Ship::Context::GetInstance()->GetConfig()->Save(); + Ship::Context::GetRawInstance()->GetConfig()->SetBlock("WarpPoints", warpPoints); + Ship::Context::GetRawInstance()->GetConfig()->Save(); } void Warp(WarpPoint& warpPoint) { diff --git a/soh/soh/Enhancements/audio/AudioCollection.cpp b/soh/soh/Enhancements/audio/AudioCollection.cpp index 631d3094f1..f1e323d7e9 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.cpp +++ b/soh/soh/Enhancements/audio/AudioCollection.cpp @@ -399,7 +399,7 @@ void AudioCollection::RemoveFromShufflePool(SequenceInfo* seqInfo) { excludedSequences.insert(seqInfo); includedSequences.erase(seqInfo); CVarSetInteger(cvarKey.c_str(), 1); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } void AudioCollection::AddToShufflePool(SequenceInfo* seqInfo) { @@ -407,7 +407,7 @@ void AudioCollection::AddToShufflePool(SequenceInfo* seqInfo) { includedSequences.insert(seqInfo); excludedSequences.erase(seqInfo); CVarClear(cvarKey.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } void AudioCollection::InitializeShufflePool() { diff --git a/soh/soh/Enhancements/audio/AudioCollection.h b/soh/soh/Enhancements/audio/AudioCollection.h index 5659de99fa..391e9c7b44 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.h +++ b/soh/soh/Enhancements/audio/AudioCollection.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include enum SeqType { SEQ_NOSHUFFLE = 0, diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 699ec522b1..ce3bc7c245 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -6,7 +6,7 @@ #include #include #include -#include "../randomizer/3drando/random.hpp" +#include "soh/ShipUtils.h" #include "soh/OTRGlobals.h" #include "soh/cvar_prefixes.h" #include @@ -14,7 +14,9 @@ #include "soh/SohGui/SohGui.hpp" #include "AudioCollection.h" #include "soh/Enhancements/enhancementTypes.h" +#include "soh/ShipUtils.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/randomizer/SeedContext.h" extern "C" { #include "z64save.h" @@ -265,7 +267,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); ResetGroup(map, type); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -277,7 +279,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); RandomizeGroup(type); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -289,7 +291,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); LockGroup(map, type); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -301,7 +303,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); UnlockGroup(map, type); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -362,7 +364,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN if (ImGui::Selectable(seqData.label.c_str())) { CVarSetInteger(cvarKey.c_str(), value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); UpdateCurrentBGM(defaultValue, type); } @@ -389,7 +391,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN .Color(THEME_COLOR))) { CVarClear(cvarKey.c_str()); CVarClear(cvarLockKey.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); UpdateCurrentBGM(defaultValue, seqData.category); } ImGui::SameLine(); @@ -408,12 +410,12 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN if (validSequences.size()) { auto it = validSequences.begin(); - const auto& seqData = *std::next(it, rand() % validSequences.size()); + const auto& seqData = *std::next(it, ShipUtils::Random(0, validSequences.size())); CVarSetInteger(cvarKey.c_str(), seqData->sequenceId); if (locked) { CVarClear(cvarLockKey.c_str()); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); UpdateCurrentBGM(defaultValue, type); } } @@ -430,7 +432,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN } else { CVarSetInteger(cvarLockKey.c_str(), 1); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } ImGui::EndTable(); @@ -818,7 +820,7 @@ void AudioEditor_RandomizeAll() { RandomizeGroup(type); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } @@ -827,14 +829,14 @@ void AudioEditor_AutoRandomizeAll() { RandomizeGroup(type, false); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } void AudioEditor_RandomizeGroup(SeqType group) { RandomizeGroup(group); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } @@ -843,14 +845,14 @@ void AudioEditor_ResetAll() { ResetGroup(AudioCollection::Instance->GetAllSequences(), type); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } void AudioEditor_ResetGroup(SeqType group) { ResetGroup(AudioCollection::Instance->GetAllSequences(), group); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } @@ -859,7 +861,7 @@ void AudioEditor_LockAll() { LockGroup(AudioCollection::Instance->GetAllSequences(), type); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } void AudioEditor_UnlockAll() { @@ -867,7 +869,7 @@ void AudioEditor_UnlockAll() { UnlockGroup(AudioCollection::Instance->GetAllSequences(), type); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } void RegisterAudioWidgets() { diff --git a/soh/soh/Enhancements/audio/AudioEditor.h b/soh/soh/Enhancements/audio/AudioEditor.h index b05c7b88e2..d308c9bd35 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.h +++ b/soh/soh/Enhancements/audio/AudioEditor.h @@ -1,5 +1,5 @@ #pragma once -#include "stdint.h" +#include #ifdef __cplusplus diff --git a/soh/soh/Enhancements/controls/InputViewer.cpp b/soh/soh/Enhancements/controls/InputViewer.cpp index 9e46497b54..c585588413 100644 --- a/soh/soh/Enhancements/controls/InputViewer.cpp +++ b/soh/soh/Enhancements/controls/InputViewer.cpp @@ -13,6 +13,10 @@ #include "soh/SohGui/UIWidgets.hpp" #include "soh/SohGui/SohGui.hpp" +#include + +#include + using namespace UIWidgets; // Text colors @@ -47,15 +51,17 @@ void InputViewer::RenderButton(std::string btnTexture, std::string btnOutlineTex // Render Outline based on settings if (outlineMode == BUTTON_OUTLINE_ALWAYS_SHOWN || (outlineMode == BUTTON_OUTLINE_NOT_PRESSED && !state) || (outlineMode == BUTTON_OUTLINE_PRESSED && state)) { - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnOutlineTexture), size, - ImVec2(0, 0), ImVec2(1.0f, 1.0f)); + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(btnOutlineTexture), + size, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); } // Render button if pressed if (state) { ImGui::SetCursorPos(pos); ImGui::SetNextItemAllowOverlap(); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnTexture), size, - ImVec2(0, 0), ImVec2(1.0f, 1.0f)); + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(btnTexture), + size, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); } } @@ -72,80 +78,80 @@ void InputViewer::DrawElement() { if (CVarGetInteger(CVAR_WINDOW("InputViewer"), 0)) { static bool sButtonTexturesLoaded = false; if (!sButtonTexturesLoaded) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Input-Viewer-Background", "textures/buttons/InputViewerBackground.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn", - "textures/buttons/ABtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn", - "textures/buttons/BBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn", - "textures/buttons/LBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn", - "textures/buttons/RBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn", - "textures/buttons/ZBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Start-Btn", "textures/buttons/StartBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left", - "textures/buttons/CLeft.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right", - "textures/buttons/CRight.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up", - "textures/buttons/CUp.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down", - "textures/buttons/CDown.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Analog-Stick", "textures/buttons/AnalogStick.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Dpad-Left", "textures/buttons/DPadLeft.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Dpad-Right", "textures/buttons/DPadRight.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up", - "textures/buttons/DPadUp.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Dpad-Down", "textures/buttons/DPadDown.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-1", - "textures/buttons/Mod1.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-2", - "textures/buttons/Mod2.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Right-Stick", "textures/buttons/RightStick.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "A-Btn Outline", "textures/buttons/ABtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "B-Btn Outline", "textures/buttons/BBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "L-Btn Outline", "textures/buttons/LBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "R-Btn Outline", "textures/buttons/RBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Z-Btn Outline", "textures/buttons/ZBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Start-Btn Outline", "textures/buttons/StartBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "C-Left Outline", "textures/buttons/CLeftOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "C-Right Outline", "textures/buttons/CRightOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "C-Up Outline", "textures/buttons/CUpOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "C-Down Outline", "textures/buttons/CDownOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Analog-Stick Outline", "textures/buttons/AnalogStickOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Dpad-Left Outline", "textures/buttons/DPadLeftOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Dpad-Right Outline", "textures/buttons/DPadRightOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Dpad-Up Outline", "textures/buttons/DPadUpOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Dpad-Down Outline", "textures/buttons/DPadDownOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Modifier-1 Outline", "textures/buttons/Mod1Outline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Modifier-2 Outline", "textures/buttons/Mod2Outline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( - "Right-Stick Outline", "textures/buttons/RightStickOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Input-Viewer-Background", "textures/buttons/InputViewerBackground.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("A-Btn", "textures/buttons/ABtn.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("B-Btn", "textures/buttons/BBtn.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("L-Btn", "textures/buttons/LBtn.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("R-Btn", "textures/buttons/RBtn.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Z-Btn", "textures/buttons/ZBtn.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Start-Btn", "textures/buttons/StartBtn.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("C-Left", "textures/buttons/CLeft.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("C-Right", "textures/buttons/CRight.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("C-Up", "textures/buttons/CUp.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("C-Down", "textures/buttons/CDown.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Analog-Stick", "textures/buttons/AnalogStick.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Dpad-Left", "textures/buttons/DPadLeft.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Dpad-Right", "textures/buttons/DPadRight.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Dpad-Up", "textures/buttons/DPadUp.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Dpad-Down", "textures/buttons/DPadDown.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Modifier-1", "textures/buttons/Mod1.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Modifier-2", "textures/buttons/Mod2.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Right-Stick", "textures/buttons/RightStick.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("A-Btn Outline", "textures/buttons/ABtnOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("B-Btn Outline", "textures/buttons/BBtnOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("L-Btn Outline", "textures/buttons/LBtnOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("R-Btn Outline", "textures/buttons/RBtnOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Z-Btn Outline", "textures/buttons/ZBtnOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Start-Btn Outline", "textures/buttons/StartBtnOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("C-Left Outline", "textures/buttons/CLeftOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("C-Right Outline", "textures/buttons/CRightOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("C-Up Outline", "textures/buttons/CUpOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("C-Down Outline", "textures/buttons/CDownOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Analog-Stick Outline", "textures/buttons/AnalogStickOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Dpad-Left Outline", "textures/buttons/DPadLeftOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Dpad-Right Outline", "textures/buttons/DPadRightOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Dpad-Up Outline", "textures/buttons/DPadUpOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Dpad-Down Outline", "textures/buttons/DPadDownOutline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Modifier-1 Outline", "textures/buttons/Mod1Outline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Modifier-2 Outline", "textures/buttons/Mod2Outline.png"); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadTextureFromRawImage("Right-Stick Outline", "textures/buttons/RightStickOutline.png"); sButtonTexturesLoaded = true; } @@ -162,7 +168,9 @@ void InputViewer::DrawElement() { CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED); const bool useGlobalOutlineMode = CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1); - ImVec2 bgSize = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureSize("Input-Viewer-Background"); + ImVec2 bgSize = + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureSize("Input-Viewer-Background"); ImVec2 scaledBGSize = ImVec2(bgSize.x * scale, bgSize.y * scale); ImGui::SetNextWindowSize( @@ -181,7 +189,7 @@ void InputViewer::DrawElement() { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); OSContPad* pads = - std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetControlDeck())->GetPads(); ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | @@ -199,7 +207,8 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); // Background ImGui::Image( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Input-Viewer-Background"), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("Input-Viewer-Background"), scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); } @@ -350,7 +359,8 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); ImGui::Image( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick Outline"), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("Analog-Stick Outline"), scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); } const int analogStickMode = @@ -361,8 +371,10 @@ void InputViewer::DrawElement() { ImGui::SetCursorPos( ImVec2(aPos.x + maxStickDistance * ((float)(pads[0].stick_x) / MAX_AXIS_RANGE) * scale, aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale)); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick"), - scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); + ImGui::Image( + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("Analog-Stick"), + scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); } // Right Stick @@ -374,7 +386,8 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); ImGui::Image( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick Outline"), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("Right-Stick Outline"), scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); } const int rightStickMode = @@ -385,8 +398,10 @@ void InputViewer::DrawElement() { ImGui::SetCursorPos( ImVec2(aPos.x + maxRightStickDistance * ((float)(pads[0].right_stick_x) / MAX_AXIS_RANGE) * scale, aPos.y - maxRightStickDistance * ((float)(pads[0].right_stick_y) / MAX_AXIS_RANGE) * scale)); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick"), - scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); + ImGui::Image( + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("Right-Stick"), + scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f)); } // Analog stick angle text diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp index 2346d97715..2cf63ddefb 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -77,7 +77,7 @@ void SohInputEditorWindow::UpdateElement() { } if (mInputEditorPopupOpen && ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopupId)) { - Ship::Context::GetInstance()->GetControlDeck()->BlockGameInput(INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID); + Ship::Context::GetRawInstance()->GetControlDeck()->BlockGameInput(INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID); // continue to block input for a third of a second after getting the mapping mGameInputBlockTimer = ImGui::GetIO().Framerate / 3; @@ -89,24 +89,24 @@ void SohInputEditorWindow::UpdateElement() { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->BlockGamepadNavigation(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->BlockGamepadNavigation(); } else { if (mGameInputBlockTimer != INT32_MAX) { mGameInputBlockTimer--; if (mGameInputBlockTimer <= 0) { - Ship::Context::GetInstance()->GetControlDeck()->UnblockGameInput( + Ship::Context::GetRawInstance()->GetControlDeck()->UnblockGameInput( INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID); mGameInputBlockTimer = INT32_MAX; } } - if (Ship::Context::GetInstance()->GetWindow()->GetGui()->GamepadNavigationEnabled()) { + if (Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GamepadNavigationEnabled()) { mMappingInputBlockTimer = ImGui::GetIO().Framerate / 3; } else { mMappingInputBlockTimer = INT32_MAX; } - Ship::Context::GetInstance()->GetWindow()->GetGui()->UnblockGamepadNavigation(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->UnblockGamepadNavigation(); } } @@ -245,7 +245,7 @@ void SohInputEditorWindow::DrawButtonLineAddMappingButton(uint8_t port, N64Butto ImGui::CloseCurrentPopup(); } // todo: figure out why optional params (using id = "" in the definition) wasn't working - if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetButton(bitmask) @@ -258,7 +258,7 @@ void SohInputEditorWindow::DrawButtonLineAddMappingButton(uint8_t port, N64Butto } void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64ButtonMask bitmask, std::string id) { - auto mapping = Ship::Context::GetInstance() + auto mapping = Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetButton(bitmask) @@ -308,7 +308,7 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt mInputEditorPopupOpen = false; ImGui::CloseCurrentPopup(); } - if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetButton(bitmask) @@ -348,7 +348,7 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt ImGui::Text("Axis Threshold\n\nThe extent to which the joystick\nmust be moved or the trigger\npressed to " "initiate the assigned\nbutton action."); - auto globalSettings = Ship::Context::GetInstance()->GetControlDeck()->GetGlobalSDLDeviceSettings(); + auto globalSettings = Ship::Context::GetRawInstance()->GetControlDeck()->GetGlobalSDLDeviceSettings(); if (sdlAxisDirectionToButtonMapping->AxisIsStick()) { ImGui::Text("Stick axis threshold:"); @@ -443,7 +443,7 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); if (ImGui::Button(StringHelper::Sprintf("%s###removeButtonMappingButton%s", ICON_FA_TIMES, id.c_str()).c_str(), ImVec2(ImGui::CalcTextSize(ICON_FA_TIMES).x + SCALE_IMGUI_SIZE(10.0f), 0.0f))) { - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetButton(bitmask) @@ -489,7 +489,7 @@ void SohInputEditorWindow::DrawStickDirectionLineAddMappingButton(uint8_t port, } if (stick == Ship::LEFT) { if (mMappingInputBlockTimer == INT32_MAX && - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetLeftStick() @@ -499,7 +499,7 @@ void SohInputEditorWindow::DrawStickDirectionLineAddMappingButton(uint8_t port, } } else { if (mMappingInputBlockTimer == INT32_MAX && - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetRightStick() @@ -515,13 +515,13 @@ void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port, Ship::Direction direction, std::string id) { std::shared_ptr mapping = nullptr; if (stick == Ship::LEFT) { - mapping = Ship::Context::GetInstance() + mapping = Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetLeftStick() ->GetAxisDirectionMappingById(direction, id); } else { - mapping = Ship::Context::GetInstance() + mapping = Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetRightStick() @@ -576,7 +576,7 @@ void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port, if (stick == Ship::LEFT) { if (mMappingInputBlockTimer == INT32_MAX && - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetLeftStick() @@ -586,7 +586,7 @@ void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port, } } else { if (mMappingInputBlockTimer == INT32_MAX && - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetRightStick() @@ -606,13 +606,13 @@ void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port, StringHelper::Sprintf("%s###removeStickDirectionMappingButton%s", ICON_FA_TIMES, id.c_str()).c_str(), ImVec2(ImGui::CalcTextSize(ICON_FA_TIMES).x + SCALE_IMGUI_SIZE(10.0f), 0.0f))) { if (stick == Ship::LEFT) { - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetLeftStick() ->ClearAxisDirectionMapping(direction, id); } else { - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetRightStick() @@ -646,9 +646,9 @@ void SohInputEditorWindow::DrawStickSection(uint8_t port, uint8_t stick, int32_t static int8_t sX, sY; std::shared_ptr controllerStick = nullptr; if (stick == Ship::LEFT) { - controllerStick = Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLeftStick(); + controllerStick = Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetLeftStick(); } else { - controllerStick = Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetRightStick(); + controllerStick = Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetRightStick(); } controllerStick->Process(sX, sY); DrawAnalogPreview(StringHelper::Sprintf("##AnalogPreview%d", id).c_str(), ImVec2(sX, sY)); @@ -790,7 +790,7 @@ void SohInputEditorWindow::UpdateBitmaskToMappingIds(uint8_t port) { // todo: do we need this now that ControllerButton exists? for (auto [bitmask, button] : - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetAllButtons()) { + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetAllButtons()) { for (auto [id, mapping] : button->GetAllButtonMappings()) { // using a vector here instead of a set because i want newly added mappings // to go to the end of the list instead of autosorting @@ -806,10 +806,11 @@ void SohInputEditorWindow::UpdateStickDirectionToMappingIds(uint8_t port) { // todo: do we need this? for (auto stick : { std::make_pair>( - Ship::LEFT, Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLeftStick()), + Ship::LEFT, + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetLeftStick()), std::make_pair>( Ship::RIGHT, - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetRightStick()) }) { + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetRightStick()) }) { for (auto direction : { Ship::LEFT, Ship::RIGHT, Ship::UP, Ship::DOWN }) { for (auto [id, mapping] : stick.second->GetAllAxisDirectionMappingByDirection(direction)) { // using a vector here instead of a set because i want newly added mappings @@ -829,7 +830,8 @@ void SohInputEditorWindow::DrawRemoveRumbleMappingButton(uint8_t port, std::stri ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); if (ImGui::Button(StringHelper::Sprintf("%s###removeRumbleMapping%s", ICON_FA_TIMES, id.c_str()).c_str(), ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetRumble()->ClearRumbleMapping(id); + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetRumble()->ClearRumbleMapping( + id); } ImGui::PopStyleVar(); } @@ -852,7 +854,7 @@ void SohInputEditorWindow::DrawAddRumbleMappingButton(uint8_t port) { ImGui::CloseCurrentPopup(); } - if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetRumble() @@ -869,7 +871,7 @@ bool SohInputEditorWindow::TestingRumble() { } void SohInputEditorWindow::DrawRumbleSection(uint8_t port) { - for (auto [id, mapping] : Ship::Context::GetInstance() + for (auto [id, mapping] : Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetRumble() @@ -1012,7 +1014,7 @@ void SohInputEditorWindow::DrawRemoveLEDMappingButton(uint8_t port, std::string ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); if (ImGui::Button(StringHelper::Sprintf("%s###removeLEDMapping%s", ICON_FA_TIMES, id.c_str()).c_str(), ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLED()->ClearLEDMapping(id); + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetLED()->ClearLEDMapping(id); } ImGui::PopStyleVar(); } @@ -1035,7 +1037,7 @@ void SohInputEditorWindow::DrawAddLEDMappingButton(uint8_t port) { ImGui::CloseCurrentPopup(); } - if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetLED() @@ -1049,7 +1051,7 @@ void SohInputEditorWindow::DrawAddLEDMappingButton(uint8_t port) { void SohInputEditorWindow::DrawLEDSection(uint8_t port) { for (auto [id, mapping] : - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLED()->GetAllLEDMappings()) { + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetLED()->GetAllLEDMappings()) { ImGui::AlignTextToFramePadding(); ImGui::SetNextItemOpen(true, ImGuiCond_Once); auto open = ImGui::TreeNode( @@ -1105,7 +1107,7 @@ void SohInputEditorWindow::DrawLEDSection(uint8_t port) { color.b = colorVec.z * 255.0; CVarSetColor24(CVAR_SETTING("LEDPort1Color"), color); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); ImGui::Text("Custom Color"); @@ -1141,7 +1143,7 @@ void SohInputEditorWindow::DrawRemoveGyroMappingButton(uint8_t port, std::string ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); if (ImGui::Button(StringHelper::Sprintf("%s###removeGyroMapping%s", ICON_FA_TIMES, id.c_str()).c_str(), ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetGyro()->ClearGyroMapping(); + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetGyro()->ClearGyroMapping(); } ImGui::PopStyleVar(); } @@ -1164,7 +1166,7 @@ void SohInputEditorWindow::DrawAddGyroMappingButton(uint8_t port) { ImGui::CloseCurrentPopup(); } - if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(port) ->GetGyro() @@ -1178,7 +1180,7 @@ void SohInputEditorWindow::DrawAddGyroMappingButton(uint8_t port) { void SohInputEditorWindow::DrawGyroSection(uint8_t port) { auto mapping = - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetGyro()->GetGyroMapping(); + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(port)->GetGyro()->GetGyroMapping(); if (mapping != nullptr) { auto id = mapping->GetGyroMappingId(); ImGui::AlignTextToFramePadding(); @@ -1322,7 +1324,7 @@ void SohInputEditorWindow::DrawMapping(CustomButtonMap& mapping, float labelWidt } if (ImGui::Selectable(i->second, i->first == currentButton)) { CVarSetInteger(mapping.cVarName, i->first); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } ImGui::EndCombo(); @@ -1409,7 +1411,7 @@ void SohInputEditorWindow::DrawCameraControlPanel() { if (!CVarGetInteger(CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), 0)) { CVarClear(CVAR_SETTING("FirstPersonCameraSensitivity.X")); CVarClear(CVAR_SETTING("FirstPersonCameraSensitivity.Y")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } if (CVarGetInteger(CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), 0)) { @@ -1514,7 +1516,8 @@ void SohInputEditorWindow::DrawDeviceToggles(uint8_t portIndex) { ImGui::PopItemFlag(); - auto connectedDeviceManager = Ship::Context::GetInstance()->GetControlDeck()->GetConnectedPhysicalDeviceManager(); + auto connectedDeviceManager = + Ship::Context::GetRawInstance()->GetControlDeck()->GetConnectedPhysicalDeviceManager(); for (const auto& [instanceId, name] : connectedDeviceManager->GetConnectedSDLGamepadNames()) { ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); @@ -1743,7 +1746,7 @@ void SohInputEditorWindow::DrawClearAllButton(uint8_t portIndex) { ImGui::CloseCurrentPopup(); } if (ImGui::Button("Clear All")) { - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->ClearAllMappings(); + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(portIndex)->ClearAllMappings(); ImGui::CloseCurrentPopup(); } PopStyleButton(); @@ -1776,11 +1779,11 @@ void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) { ImGui::CloseCurrentPopup(); } if (ImGui::Button("Set defaults")) { - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(portIndex) ->ClearAllMappingsForDeviceType(Ship::PhysicalDeviceType::Keyboard); - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings( + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings( Ship::PhysicalDeviceType::Keyboard); shouldClose = true; ImGui::CloseCurrentPopup(); @@ -1806,11 +1809,11 @@ void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) { ImGui::CloseCurrentPopup(); } if (ImGui::Button("Set defaults")) { - Ship::Context::GetInstance() + Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(portIndex) ->ClearAllMappingsForDeviceType(Ship::PhysicalDeviceType::SDLGamepad); - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings( + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings( Ship::PhysicalDeviceType::SDLGamepad); shouldClose = true; ImGui::CloseCurrentPopup(); @@ -1869,7 +1872,7 @@ void RegisterInputEditorWidgets() { .Callback([](WidgetInfo& info) { bool enabled = CVarGetInteger(CVAR_SETTING("EnableMouse"), 0) && CVarGetInteger(CVAR_SETTING("AutoCaptureMouse"), 1); - auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()); wnd->SetAutoCaptureMouse(enabled); }) .Options( @@ -1885,7 +1888,7 @@ void RegisterInputEditorWidgets() { .Callback([](WidgetInfo& info) { bool enabled = CVarGetInteger(CVAR_SETTING("EnableMouse"), 0) && CVarGetInteger(CVAR_SETTING("AutoCaptureMouse"), 1); - auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()); wnd->SetAutoCaptureMouse(enabled); }) .Options(CheckboxOptions() diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.h b/soh/soh/Enhancements/controls/SohInputEditorWindow.h index a6815f060a..53d8861c68 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.h +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.h @@ -1,6 +1,6 @@ #pragma once -#include "stdint.h" +#include #include #include #include diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 077732809b..09c4069d87 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -14,6 +14,7 @@ #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/enhancementTypes.h" +#include "soh/Enhancements/randomizer/SeedContext.h" extern "C" { #include "z64.h" @@ -1638,7 +1639,7 @@ void C_Button_Dropdown(const char* Header_Title, const char* Table_ID, const cha ImGui::EndTable(); } std::shared_ptr controller = - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(0); + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(0); for (auto [id, mapping] : controller->GetButton(BTN_DDOWN)->GetAllButtonMappings()) { controller->GetButton(BTN_CUSTOM_OCARINA_NOTE_F4)->AddButtonMapping(mapping); } @@ -2216,7 +2217,7 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { CVarSetInteger((cosmeticOption.changedCvar), 1); ApplySideEffects(cosmeticOption); ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } // the longest option name ImGui::SameLine((ImGui::CalcTextSize("Message Light Blue (None No Shadow)").x * 1.0f) + 60.0f); @@ -2225,7 +2226,7 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { UIWidgets::ButtonOptions().Size(ImVec2(80, 31)).Padding(ImVec2(2.0f, 0.0f)).Color(THEME_COLOR))) { RandomizeColor(cosmeticOption); ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (cosmeticOption.supportsRainbow) { ImGui::SameLine(); @@ -2234,7 +2235,7 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { CVarSetInteger((cosmeticOption.changedCvar), 1); ApplySideEffects(cosmeticOption); ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } ImGui::SameLine(); @@ -2248,7 +2249,7 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { UIWidgets::ButtonOptions().Size(ImVec2(80, 31)).Padding(ImVec2(2.0f, 0.0f)))) { ResetColor(cosmeticOption); ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } } @@ -2621,7 +2622,7 @@ void CosmeticsEditorWindow::InitElement() { cosmeticOption.currentColor.z = cvarColor.b / 255.0f; cosmeticOption.currentColor.w = cvarColor.a / 255.0f; } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); ApplyAuthenticGfxPatches(); } @@ -2634,7 +2635,7 @@ void CosmeticsEditor_RandomizeAll() { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } @@ -2646,7 +2647,7 @@ void CosmeticsEditor_AutoRandomizeAll() { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } @@ -2659,7 +2660,7 @@ void CosmeticsEditor_RandomizeGroup(CosmeticGroup group) { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } @@ -2670,7 +2671,7 @@ void CosmeticsEditor_ResetAll() { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } @@ -2681,7 +2682,7 @@ void CosmeticsEditor_ResetGroup(CosmeticGroup group) { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } diff --git a/soh/soh/Enhancements/cosmetics/NoMasterSword.cpp b/soh/soh/Enhancements/cosmetics/NoMasterSword.cpp index be011c675b..1126021e49 100644 --- a/soh/soh/Enhancements/cosmetics/NoMasterSword.cpp +++ b/soh/soh/Enhancements/cosmetics/NoMasterSword.cpp @@ -1,4 +1,5 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/randomizer/randomizer.h" #include "soh/ShipInit.hpp" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index a762354f67..792bfad3fb 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include #include @@ -8,7 +8,7 @@ #include "../../../include/z64item.h" #include "../../../include/z64.h" #include "../../../include/message_data_textbox_types.h" -#include "../randomizer/3drando/text.hpp" +#include "text.h" #undef MESSAGE_END diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 4df57e274e..205e44dc60 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -219,6 +219,10 @@ typedef enum { TEXT_SHEIK_HAVE_HOOK = 0x7010, TEXT_ALTAR_CHILD = 0x7040, TEXT_CHEST_GAME_PROCEED = 0x704C, + TEXT_BEGGAR_BUY_BLUE_FIRE = 0x70F0, + TEXT_BEGGAR_BUY_FISH = 0x70F1, + TEXT_BEGGAR_BUY_BUGS = 0x70F2, + TEXT_BEGGAR_BUY_FAIRY = 0x70F3, TEXT_GHOST_SHOP_EXPLAINATION = 0x70F4, TEXT_GHOST_SHOP_CARD_HAS_POINTS = 0x70F5, TEXT_GHOST_SHOP_BUY_NORMAL_POE = 0x70F6, diff --git a/soh/soh/Enhancements/custom-message/text.cpp b/soh/soh/Enhancements/custom-message/text.cpp new file mode 100644 index 0000000000..0023261dbc --- /dev/null +++ b/soh/soh/Enhancements/custom-message/text.cpp @@ -0,0 +1,98 @@ +#include "text.h" +#include + +Text::Text() = default; + +Text::Text(std::string english_, std::string french_, std::string german_) + : english(std::move(english_)), french(std::move(french_)), german(std::move(german_)), spanish("") { + spanish = english; +} + +Text::Text(std::string english_, std::string french_, std::string german_, std::string spanish_) + : english(std::move(english_)), french(std::move(french_)), german(std::move(german_)), + spanish(std::move(spanish_)) { +} + +Text::Text(std::string english_) : english(std::move(english_)), french(""), german(""), spanish("") { + french = spanish = german = english; +} + +const std::string& Text::GetEnglish() const { + return english; +} + +const std::string& Text::GetFrench() const { + return french.length() > 0 ? french : english; +} + +const std::string& Text::GetGerman() const { + return german.length() > 0 ? german : english; +} + +const std::string& Text::GetSpanish() const { + return spanish.length() > 0 ? spanish : english; +} + +const std::string& Text::GetForLanguage(uint8_t language) const { + switch (language) { + case 0: + return GetEnglish(); + case 2: + return GetFrench(); + case 1: + return GetGerman(); + default: + return GetEnglish(); + } +} + +Text Text::operator+(const Text& right) const { + return Text{ + english + right.GetEnglish(), + french + right.GetFrench(), + german + right.GetGerman(), + spanish + right.GetSpanish(), + }; +} + +Text Text::operator+(const std::string& right) const { + return Text{ + english + right, + french + right, + german + right, + spanish + right, + }; +} + +bool Text::operator==(const Text& right) const { + return english == right.english; +} + +bool Text::operator==(const std::string& right) const { + return english == right || french == right || german == right || spanish == right; +} + +bool Text::operator!=(const Text& right) const { + return !operator==(right); +} + +static void replaceAll(std::string& target, const std::string& oldStr, const std::string& replacement) { + size_t position = target.find(oldStr); + while (position != std::string::npos) { + target.replace(position, oldStr.length(), replacement); + position = target.find(oldStr); + } +} + +void Text::Replace(const std::string& oldStr, const std::string& newStr) { + for (std::string& str : { std::ref(english), std::ref(french), std::ref(german), std::ref(spanish) }) { + replaceAll(str, oldStr, newStr); + } +} + +void Text::Replace(const std::string& oldStr, const Text& newText) { + replaceAll(english, oldStr, newText.GetEnglish()); + replaceAll(french, oldStr, newText.GetFrench()); + replaceAll(german, oldStr, newText.GetGerman()); + replaceAll(spanish, oldStr, newText.GetSpanish()); +} diff --git a/soh/soh/Enhancements/custom-message/text.h b/soh/soh/Enhancements/custom-message/text.h new file mode 100644 index 0000000000..3cca375930 --- /dev/null +++ b/soh/soh/Enhancements/custom-message/text.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +class Text { + public: + Text(); + Text(std::string english_, std::string french_, std::string german_); + Text(std::string english_, std::string french_, std::string german_, std::string spanish_); + explicit Text(std::string english_); + + const std::string& GetEnglish() const; + const std::string& GetFrench() const; + const std::string& GetGerman() const; + const std::string& GetSpanish() const; + const std::string& GetForLanguage(uint8_t language) const; + + Text operator+(const Text& right) const; + Text operator+(const std::string& right) const; + + bool operator==(const Text& right) const; + bool operator==(const std::string& right) const; + bool operator!=(const Text& right) const; + + void Replace(const std::string& oldStr, const std::string& newStr); + void Replace(const std::string& oldStr, const Text& newText); + + std::string english = ""; + std::string french = ""; + std::string german = ""; + std::string spanish = ""; +}; diff --git a/soh/soh/Enhancements/customequipment.cpp b/soh/soh/Enhancements/customequipment.cpp index 06e6453802..a33e34d851 100644 --- a/soh/soh/Enhancements/customequipment.cpp +++ b/soh/soh/Enhancements/customequipment.cpp @@ -1,18 +1,20 @@ #include -#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" #include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_child/object_link_child.h" #include "objects/object_custom_equip/object_custom_equip.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/ShipInit.hpp" #include "soh/ResourceManagerHelpers.h" -#include "soh_assets.h" -#include "kaleido.h" #include "soh/cvar_prefixes.h" +extern "C" { +#include "variables.h" +#include "macros.h" + extern SaveContext gSaveContext; extern PlayState* gPlayState; -extern void Overlay_DisplayText(float duration, const char* text); +} + void DummyPlayer_Update(Actor* actor, PlayState* play); static void UpdatePatchCustomEquipmentDlists(); @@ -55,6 +57,22 @@ static const char* GetBrokenLongswordInSheathDL() { { gCustomBrokenLongswordInSheathDL, gCustomBreakableLongswordInSheathDL, gCustomLongswordInSheathDL }); } +static const char* GetCustomFPSSlingshotDL() { + return ResolveCustomChain({ gCustomFPSSlingshotDL, gCustomSlingshotDL }); +} + +static const char* GetCustomFPSBowDL() { + return ResolveCustomChain({ gCustomFPSBowDL, gCustomBowDL }); +} + +static const char* GetCustomFPSHookshotDL() { + return ResolveCustomChain({ gCustomFPSHookshotDL, gCustomHookshotDL }); +} + +static const char* GetCustomFPSLongshotDL() { + return ResolveCustomChain({ gCustomFPSLongshotDL, gCustomLongshotDL }); +} + static void UpdateCustomEquipmentSetModel(Player* player, u8 ModelGroup) { (void)ModelGroup; @@ -66,33 +84,17 @@ static void UpdateCustomEquipmentSetModel(Player* player, u8 ModelGroup) { } static void UpdateCustomEquipment() { - if (!GameInteractor::IsSaveLoaded() || gPlayState == nullptr) { - return; - } - - Player* player = GET_PLAYER(gPlayState); - if (player == nullptr || IsDummyPlayer(player)) { + if (!GameInteractor::IsSaveLoaded() || gPlayState == nullptr || GET_PLAYER(gPlayState) == nullptr || + IsDummyPlayer(GET_PLAYER(gPlayState))) { return; } RefreshCustomEquipment(); } -static void PatchCustomEquipment() { - COND_HOOK(OnPlayerSetModels, true, UpdateCustomEquipmentSetModel); - COND_HOOK(OnLinkEquipmentChange, true, UpdateCustomEquipment); - COND_HOOK(OnLinkSkeletonInit, true, UpdateCustomEquipment); - COND_HOOK(OnAssetAltChange, true, UpdateCustomEquipment); -} - -static RegisterShipInitFunc initFunc(PatchCustomEquipment); - static void RefreshCustomEquipment() { - if (!GameInteractor::IsSaveLoaded() || gPlayState == NULL || GET_PLAYER(gPlayState) == nullptr) { - return; - } - - if (IsDummyPlayer(GET_PLAYER(gPlayState))) { + if (!GameInteractor::IsSaveLoaded() || gPlayState == nullptr || GET_PLAYER(gPlayState) == nullptr || + IsDummyPlayer(GET_PLAYER(gPlayState))) { return; } @@ -417,8 +419,8 @@ static void ApplyCommonEquipmentPatches() { ApplyPatchEntries({ { gLinkAdultRightHandHoldingHookshotNearDL, gCustomHookshotDL, "customHookshot1", "customHookshot2", "customHookshot3", rightHandClosed }, - { gLinkAdultRightHandHoldingHookshotFarDL, gCustomHookshotDL, "customHookshotFPS1", "customHookshotFPS2", - "customHookshotFPS3", fpsHand }, + { gLinkAdultRightHandHoldingHookshotFarDL, GetCustomFPSHookshotDL(), "customHookshotFPS1", + "customHookshotFPS2", "customHookshotFPS3", fpsHand }, }); } @@ -426,8 +428,8 @@ static void ApplyCommonEquipmentPatches() { ApplyPatchEntries({ { gLinkAdultRightHandHoldingHookshotNearDL, gCustomLongshotDL, "customHookshot1", "customHookshot2", "customHookshot3", rightHandClosed }, - { gLinkAdultRightHandHoldingHookshotFarDL, gCustomLongshotDL, "customHookshotFPS1", "customHookshotFPS2", - "customHookshotFPS3", fpsHand }, + { gLinkAdultRightHandHoldingHookshotFarDL, GetCustomFPSLongshotDL(), "customHookshotFPS1", + "customHookshotFPS2", "customHookshotFPS3", fpsHand }, }); } @@ -458,16 +460,16 @@ static void ApplyCommonEquipmentPatches() { "customChildOcarina3", rightHandNear }, { gLinkAdultRightHandHoldingBowNearDL, gCustomBowDL, "customBow1", "customBow2", "customBow3", rightHandClosed }, - { gLinkAdultRightHandHoldingBowFirstPersonDL, gCustomBowDL, "customBowFPS1", "customBowFPS2", "customBowFPS3", - fpsHand }, + { gLinkAdultRightHandHoldingBowFirstPersonDL, GetCustomFPSBowDL(), "customBowFPS1", "customBowFPS2", + "customBowFPS3", fpsHand }, { gLinkAdultLeftHandHoldingHammerNearDL, gCustomHammerDL, "customHammer1", "customHammer2", "customHammer3", leftHandClosed }, { gLinkChildLeftFistAndBoomerangNearDL, gCustomBoomerangDL, "customBoomerang1", "customBoomerang2", "customBoomerang3", leftHandClosed }, { gLinkChildRightHandHoldingSlingshotNearDL, gCustomSlingshotDL, "customSlingshot1", "customSlingshot2", "customSlingshot3", rightHandClosed }, - { gLinkChildRightArmStretchedSlingshotDL, gCustomSlingshotDL, "customSlingshotFPS1", "customSlingshotFPS2", - "customSlingshotFPS3", fpsHand }, + { gLinkChildRightArmStretchedSlingshotDL, GetCustomFPSSlingshotDL(), "customSlingshotFPS1", + "customSlingshotFPS2", "customSlingshotFPS3", fpsHand }, }); ApplyPatchEntries({ @@ -479,8 +481,8 @@ static void ApplyCommonEquipmentPatches() { "customBoomerang3", leftHandClosed }, { gLinkChildRightHandHoldingSlingshotNearDL, gCustomSlingshotDL, "customSlingshot1", "customSlingshot2", "customSlingshot3", rightHandClosed }, - { gLinkChildRightArmStretchedSlingshotDL, gCustomSlingshotDL, "customSlingshotFPS1", "customSlingshotFPS2", - "customSlingshotFPS3", fpsHand }, + { gLinkChildRightArmStretchedSlingshotDL, GetCustomFPSSlingshotDL(), "customSlingshotFPS1", + "customSlingshotFPS2", "customSlingshotFPS3", fpsHand }, }); } @@ -521,3 +523,12 @@ void UpdatePatchCustomEquipmentDlists() { sPrevAltAssetsEnabled = ResourceMgr_IsAltAssetsEnabled(); } + +static void PatchCustomEquipment() { + COND_HOOK(OnPlayerSetModels, true, UpdateCustomEquipmentSetModel); + COND_HOOK(OnLinkEquipmentChange, true, UpdateCustomEquipment); + COND_HOOK(OnLinkSkeletonInit, true, UpdateCustomEquipment); + COND_HOOK(OnAssetAltChange, true, UpdateCustomEquipment); +} + +static RegisterShipInitFunc initFunc(PatchCustomEquipment); diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 7fecad83ac..6aabdb33a6 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -12,6 +12,7 @@ #include "soh/Enhancements/cosmetics/CosmeticsEditor.h" #include "soh/Enhancements/audio/AudioEditor.h" #include "soh/Enhancements/randomizer/logic.h" +#include "soh/Enhancements/randomizer/randomizer.h" #define Path _Path #define PATH_HACK @@ -35,15 +36,15 @@ extern PlayState* gPlayState; #include #include -#define CMD_REGISTER Ship::Context::GetInstance()->GetConsole()->AddCommand +#define CMD_REGISTER Ship::Context::GetRawInstance()->GetConsole()->AddCommand // TODO: Commands should be using the output passed in. -#define ERROR_MESSAGE \ - std::reinterpret_pointer_cast( \ - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) \ +#define ERROR_MESSAGE \ + std::reinterpret_pointer_cast( \ + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) \ ->SendErrorMessage -#define INFO_MESSAGE \ - std::reinterpret_pointer_cast( \ - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) \ +#define INFO_MESSAGE \ + std::reinterpret_pointer_cast( \ + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) \ ->SendInfoMessage static bool ActorSpawnHandler(std::shared_ptr Console, const std::vector& args, @@ -526,7 +527,7 @@ static bool FileSelectHandler(std::shared_ptr Console, const std: static bool QuitHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { - Ship::Context::GetInstance()->GetWindow()->Close(); + Ship::Context::GetRawInstance()->GetWindow()->Close(); return 0; } @@ -1771,7 +1772,7 @@ void DebugConsole_Init(void) { "Available Checks - Process Undiscovered Exits", { { "enable", Ship::ArgumentType::NUMBER, true } } }); - Ship::Context::GetInstance()->GetConsole()->AddCommand( + Ship::Context::GetRawInstance()->GetConsole()->AddCommand( "acr", { AvailableChecksRecalculateHandler, "Available Checks - Recalculate", { @@ -1779,5 +1780,5 @@ void DebugConsole_Init(void) { { "ChildDay|ChildNight|AdultDay|AdultNight", Ship::ArgumentType::TEXT, true }, } }); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } diff --git a/soh/soh/Enhancements/debugconsole.h b/soh/soh/Enhancements/debugconsole.h index 148dadcbc2..c41c641bb7 100644 --- a/soh/soh/Enhancements/debugconsole.h +++ b/soh/soh/Enhancements/debugconsole.h @@ -1,5 +1,5 @@ #pragma once -#include "stdint.h" +#include void DebugConsole_Init(void); diff --git a/soh/soh/Enhancements/debugger/SohConsoleWindow.cpp b/soh/soh/Enhancements/debugger/SohConsoleWindow.cpp index 19be376ed7..a47d60812d 100644 --- a/soh/soh/Enhancements/debugger/SohConsoleWindow.cpp +++ b/soh/soh/Enhancements/debugger/SohConsoleWindow.cpp @@ -3,14 +3,6 @@ #include "soh/SohGui/UIWidgets.hpp" #include "soh/SohGui/SohGui.hpp" -void SohConsoleWindow::InitElement() { - ConsoleWindow::InitElement(); -} - -void SohConsoleWindow::UpdateElement() { - ConsoleWindow::UpdateElement(); -} - void SohConsoleWindow::DrawElement() { ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); UIWidgets::PushStyleInput(THEME_COLOR); diff --git a/soh/soh/Enhancements/debugger/SohConsoleWindow.h b/soh/soh/Enhancements/debugger/SohConsoleWindow.h index b84399ad63..9ae390d146 100644 --- a/soh/soh/Enhancements/debugger/SohConsoleWindow.h +++ b/soh/soh/Enhancements/debugger/SohConsoleWindow.h @@ -9,8 +9,6 @@ class SohConsoleWindow : public Ship::ConsoleWindow { using ConsoleWindow::ConsoleWindow; protected: - void InitElement() override; - void UpdateElement() override; void DrawElement() override; }; diff --git a/soh/soh/Enhancements/debugger/SohGfxDebuggerWindow.cpp b/soh/soh/Enhancements/debugger/SohGfxDebuggerWindow.cpp index def23caccb..2843f5fa5c 100644 --- a/soh/soh/Enhancements/debugger/SohGfxDebuggerWindow.cpp +++ b/soh/soh/Enhancements/debugger/SohGfxDebuggerWindow.cpp @@ -1,5 +1,7 @@ #include "SohGfxDebuggerWindow.h" #include "soh/OTRGlobals.h" +#include +#include "soh/cvar_prefixes.h" void SohGfxDebuggerWindow::InitElement() { GfxDebuggerWindow::InitElement(); diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 3c99ea19ee..dfd425eea0 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1,5 +1,6 @@ #include "debugSaveEditor.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/Enhancements/randomizer/randomizer.h" #include "soh/util.h" #include "soh/SohGui/ImGuiUtils.h" #include "soh/OTRGlobals.h" @@ -16,6 +17,8 @@ #include #include +#include + extern "C" { #include #include "variables.h" @@ -518,7 +521,8 @@ void DrawInfoTab() { void DrawBGSItemFlag(uint8_t itemID) { const ItemMapEntry& slotEntry = itemMapping[itemID]; - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1)); } @@ -546,7 +550,8 @@ void DrawInventoryTab() { if (item == ITEM_ROCS_FEATHER) { auto ret = ImGui::ImageButton( "ROCS_FEATHER", - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ROCS_FEATHER"), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("ROCS_FEATHER"), ImVec2(48.0f, 48.0f), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { selectedIndex = index; @@ -556,7 +561,8 @@ void DrawInventoryTab() { const ItemMapEntry& slotEntry = itemMapping.find(item)->second; auto ret = ImGui::ImageButton( slotEntry.name.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(slotEntry.name), ImVec2(48.0f, 48.0f), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { selectedIndex = index; @@ -605,10 +611,11 @@ void DrawInventoryTab() { } const ItemMapEntry& slotEntry = possibleItems[pickerIndex]; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton( - slotEntry.name.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton(slotEntry.name.c_str(), + std::dynamic_pointer_cast( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(slotEntry.name), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); PopStyleButton(); if (ret) { gSaveContext.inventory.items[selectedIndex] = slotEntry.id; @@ -640,8 +647,10 @@ void DrawInventoryTab() { ImGui::PushItemWidth(IMAGE_SIZE); ImGui::BeginGroup(); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[item].name), - ImVec2(IMAGE_SIZE, IMAGE_SIZE)); + ImGui::Image( + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(itemMapping[item].name), + ImVec2(IMAGE_SIZE, IMAGE_SIZE)); PushStyleInput(THEME_COLOR); ImGui::InputScalar("##ammoInput", ImGuiDataType_S8, &AMMO(item)); PopStyleInput(); @@ -1232,9 +1241,11 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const uint8_t item = value < items.size() ? items[value] : ITEM_NONE; if (item != ITEM_NONE) { const ItemMapEntry& slotEntry = itemMapping[item]; - if (ImGui::ImageButton(slotEntry.name.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1))) { + if (ImGui::ImageButton( + slotEntry.name.c_str(), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(slotEntry.name), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1))) { ImGui::OpenPopup(upgradePopupPicker); } } else { @@ -1263,7 +1274,8 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const const ItemMapEntry& slotEntry = itemMapping[items[pickerIndex]]; auto ret = ImGui::ImageButton( slotEntry.name.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(slotEntry.name), ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { Inventory_ChangeUpgrade(categoryId, pickerIndex); @@ -1299,10 +1311,11 @@ void DrawEquipmentTab() { bool hasEquip = (bitMask & gSaveContext.inventory.equipment) != 0; const ItemMapEntry& entry = itemMapping[equipmentValues[i]]; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton(entry.name.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasEquip ? entry.name : entry.nameFaded), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton( + entry.name.c_str(), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasEquip ? entry.name : entry.nameFaded), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { if (hasEquip) { gSaveContext.inventory.equipment &= ~bitMask; @@ -1434,10 +1447,11 @@ void DrawQuestItemButton(uint32_t item) { uint32_t bitMask = 1 << entry.id; bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton(entry.name.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasQuestItem ? entry.name : entry.nameFaded), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton( + entry.name.c_str(), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { if (hasQuestItem) { gSaveContext.inventory.questItems &= ~bitMask; @@ -1457,7 +1471,8 @@ void DrawDungeonItemButton(uint32_t item, uint32_t scene) { PushStyleButton(Colors::DarkGray); auto ret = ImGui::ImageButton( entry.name.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem ? entry.name : entry.nameFaded), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasItem ? entry.name : entry.nameFaded), ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { if (hasItem) { @@ -1503,10 +1518,11 @@ void DrawQuestStatusTab() { uint32_t bitMask = 1 << entry.id; bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton(entry.name.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasQuestItem ? entry.name : entry.nameFaded), - ImVec2(32.0f, 48.0f), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton( + entry.name.c_str(), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded), + ImVec2(32.0f, 48.0f), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { if (hasQuestItem) { gSaveContext.inventory.questItems &= ~bitMask; @@ -1583,9 +1599,10 @@ void DrawQuestStatusTab() { if (dungeonItemsScene != SCENE_JABU_JABU_BOSS) { float lineHeight = ImGui::GetTextLineHeightWithSpacing(); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - itemMapping[ITEM_KEY_SMALL].name), - ImVec2(lineHeight, lineHeight)); + ImGui::Image( + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(itemMapping[ITEM_KEY_SMALL].name), + ImVec2(lineHeight, lineHeight)); ImGui::SameLine(); PushStyleInput(THEME_COLOR); if (ImGui::InputScalar("##Keys", ImGuiDataType_S8, @@ -1974,6 +1991,6 @@ void SaveEditorWindow::DrawElement() { } void SaveEditorWindow::InitElement() { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ROCS_FEATHER", gRocsFeatherTex, - ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ROCS_FEATHER", gRocsFeatherTex, ImVec4(1, 1, 1, 1)); } diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 2d3c87ba61..856b3002a3 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -1,10 +1,9 @@ #pragma once -#include #include #include #include -#include +#include #include "soh/Enhancements/randomizer/randomizerTypes.h" #include diff --git a/soh/soh/Enhancements/debugger/dlViewer.cpp b/soh/soh/Enhancements/debugger/dlViewer.cpp index 60a6e07c87..1447259c61 100644 --- a/soh/soh/Enhancements/debugger/dlViewer.cpp +++ b/soh/soh/Enhancements/debugger/dlViewer.cpp @@ -67,7 +67,7 @@ std::map cmdMap = { }; void PerformDisplayListSearch() { - auto result = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles( + auto result = Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->ListFiles( "*" + std::string(searchString) + "*DL*"); displayListSearchResults.clear(); @@ -130,7 +130,7 @@ void DLViewerWindow::DrawElement() { try { auto res = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(activeDisplayList)); if (res->GetInitData()->Type != static_cast(Fast::ResourceType::DisplayList)) { ImGui::Text("Resource type is not a Display List. Please choose another."); diff --git a/soh/soh/Enhancements/debugger/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp index f906f4a96a..afc83ab507 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.cpp +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -3,13 +3,17 @@ #include "soh/SohGui/SohGui.hpp" #include "soh/OTRGlobals.h" #include "soh/ShipInit.hpp" +#include "soh/Enhancements/game-interactor/GameInteractor.h" extern "C" { +#include #include #include "variables.h" #include "functions.h" #include "macros.h" #include "soh/cvar_prefixes.h" +#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" + extern PlayState* gPlayState; void GfxPrint_SetColor(GfxPrint* printer, u32 r, u32 g, u32 b, u32 a); void GfxPrint_SetPos(GfxPrint* printer, s32 x, s32 y); @@ -20,103 +24,120 @@ s32 GfxPrint_Printf(GfxPrint* printer, const char* fmt, ...); #define CVAR_DEFAULT 0 #define CVAR_VALUE CVarGetInteger(CVAR_NAME, CVAR_DEFAULT) -ImVec4 WHITE = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); +std::map valueViewerSettings; // clang-format off -std::vector valueTable = { - { "Time", "gSaveContext.dayTime", "TIME:", TYPE_U16, false, []() -> void* { return &gSaveContext.dayTime; }, WHITE }, - { "Age", "gSaveContext.linkAge", "AGE:", TYPE_S32, false, []() -> void* { return &gSaveContext.linkAge; }, WHITE }, - { "Health", "gSaveContext.health", "HP:", TYPE_S16, false, []() -> void* { return &gSaveContext.health; }, WHITE }, - { "Navi Timer", "gSaveContext.naviTimer", "NAVI:", TYPE_U16, false, []() -> void* { return &gSaveContext.naviTimer; }, WHITE }, - { "Scene ID", "play->sceneNum", "SCENE:", TYPE_S16, true, []() -> void* { return &gPlayState->sceneNum; }, WHITE }, - { "Room ID", "play->roomCtx.curRoom.num", "ROOM:", TYPE_S8, true, []() -> void* { return &gPlayState->roomCtx.curRoom.num; }, WHITE }, - { "Entrance ID", "gSaveContext.entranceIndex", "ENTR:", TYPE_S32, false, []() -> void* { return &gSaveContext.entranceIndex; }, WHITE }, - { "Cutscene ID", "gSaveContext.cutsceneIndex", "CUTS:", TYPE_S32, false, []() -> void* { return &gSaveContext.cutsceneIndex; }, WHITE }, - { "Link X", "Player->actor.world.pos.x", "X:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.x; }, WHITE }, - { "Link Y", "Player->actor.world.pos.y", "Y:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.y; }, WHITE }, - { "Link Z", "Player->actor.world.pos.z", "Z:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.z; }, WHITE }, - { "Link Yaw", "Player->actor.world.rot.y", "ROT:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.rot.y; }, WHITE }, - { "Link Velocity", "Player->linearVelocity", "V:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->linearVelocity; }, WHITE }, - { "Link X Velocity", "Player->actor.velocity.x", "XV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.x; }, WHITE }, - { "Link Y Velocity", "Player->actor.velocity.y", "YV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.y; }, WHITE }, - { "Link Z Velocity", "Player->actor.velocity.z", "ZV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.z; }, WHITE }, - { "Text ID", "play->msgCtx.textId", "TEXTID:", TYPE_U16, true, []() -> void* { return &gPlayState->msgCtx.textId; }, WHITE }, - { "Analog Stick X", "play->state.input->cur.stick_x", "AX:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_x; }, WHITE }, - { "Analog Stick Y", "play->state.input->cur.stick_y", "AY:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_y; }, WHITE }, - { "getItemID", "Player->getItemId", "ITEM:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemId; }, WHITE }, - { "getItemEntry", "Player->getItemEntry", "IE:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemEntry.itemId; }, WHITE }, +std::array valueTable = {{ + { "Time", "gSaveContext.dayTime", "TIME:", TYPE_U16, false, []() -> void* { return &gSaveContext.dayTime; }}, + { "Age", "gSaveContext.linkAge", "AGE:", TYPE_S32, false, []() -> void* { return &gSaveContext.linkAge; }}, + { "Health", "gSaveContext.health", "HP:", TYPE_S16, false, []() -> void* { return &gSaveContext.health; }}, + { "Navi Timer", "gSaveContext.naviTimer", "NAVI:", TYPE_U16, false, []() -> void* { return &gSaveContext.naviTimer; }}, + { "Scene ID", "play->sceneNum", "SCENE:", TYPE_S16, true, []() -> void* { return &gPlayState->sceneNum; }}, + { "Room ID", "play->roomCtx.curRoom.num", "ROOM:", TYPE_S8, true, []() -> void* { return &gPlayState->roomCtx.curRoom.num; }}, + { "Entrance ID", "gSaveContext.entranceIndex", "ENTR:", TYPE_S32, false, []() -> void* { return &gSaveContext.entranceIndex; }}, + { "Cutscene ID", "gSaveContext.cutsceneIndex", "CUTS:", TYPE_S32, false, []() -> void* { return &gSaveContext.cutsceneIndex; }}, + { "Link X", "Player->actor.world.pos.x", "X:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.x; }}, + { "Link Y", "Player->actor.world.pos.y", "Y:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.y; }}, + { "Link Z", "Player->actor.world.pos.z", "Z:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.z; }}, + { "Link Yaw", "Player->actor.world.rot.y", "ROT:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.rot.y; }}, + { "Link Velocity", "Player->linearVelocity", "V:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->linearVelocity; }}, + { "Link X Velocity", "Player->actor.velocity.x", "XV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.x; }}, + { "Link Y Velocity", "Player->actor.velocity.y", "YV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.y; }}, + { "Link Z Velocity", "Player->actor.velocity.z", "ZV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.z; }}, + { "Text ID", "play->msgCtx.textId", "TEXTID:", TYPE_U16, true, []() -> void* { return &gPlayState->msgCtx.textId; }}, + { "Analog Stick X", "play->state.input->cur.stick_x", "AX:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_x; }}, + { "Analog Stick Y", "play->state.input->cur.stick_y", "AY:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_y; }}, + { "getItemID", "Player->getItemId", "ITEM:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemId; }}, + { "getItemEntry", "Player->getItemEntry", "IE:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemEntry.itemId; }}, + { "Movement Angle", "Player->yaw", "YAW:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->yaw; }}, + { "Last Item Pressed", "Player->heldItemButton", "LASTI:", TYPE_S8, true, []() -> void* { return &GET_PLAYER(gPlayState)->heldItemButton; }}, + { "Stick Timer", "Player->unk_860", "STICK:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->unk_860; }}, + { "Last damage value", "Player->melee[0].info.dmgFlags", "DMG:", TYPE_U32, true, []() -> void* { return &GET_PLAYER(gPlayState)->meleeWeaponQuads[0].info.toucher.dmgFlags; }}, + { "Camera Angle", "play->mainCamera.camDir.y", "CAMY:", TYPE_S16, true, []() -> void* { return &gPlayState->mainCamera.camDir.y; }}, + { "Camera XZ Speed", "play->mainCamera.xzSpeed", "CAMXZV:", TYPE_FLOAT, true, []() -> void* { return &gPlayState->mainCamera.xzSpeed; }}, + { "Frame Counter", "play->state.frames", "FRAM:", TYPE_S32, true, []() -> void* { return &gPlayState->state.frames; }}, + { "Cutscene Pointer", "play->csCtx.segment", "CSP:", TYPE_PTR, true, []() -> void* { return &gPlayState->csCtx.segment; }}, + { "Framerate Divisor", "R_UPDATE_RATE", "FRDV:", TYPE_S16, false, []() -> void* { return &R_UPDATE_RATE; }}, + { "Next HUD mode", "gSaveContext.nextHudMode", "HUD:", TYPE_S16, false, []() -> void* { return &gSaveContext.unk_13E8; }}, + { "Temp B Value", "gSaveContext.buttonStatus[0]", "TEMPB:", TYPE_U8, false, []() -> void* { return &gSaveContext.buttonStatus[0]; }}, + { "Blue Warp Timer", "DoorWarp1->warpTimer", "WARPT:", TYPE_U16, true, []() -> void* { DoorWarp1 *actor = (DoorWarp1 *)Actor_Find(&gPlayState->actorCtx, ACTOR_DOOR_WARP1 ,ACTORCAT_ITEMACTION); if(actor) { return &actor->warpTimer; } else { return nullptr; }}}, /* TODO: Find these (from GZ) - "XZ Units Traveled (Camera based speed variable)" f32 0x801C9018 - "Movement Angle" x16 0x801DBB1C - "Camera Angle" u16 0x801C907C - "Time of Day" x16 0x8011AC8C - "Global Frame Counter" s32 0x801C8DFC - "Lit Deku Stick Timer" u16 0x801DBB40 - "Cutscene Pointer" u32 0x801CAAC8 - "Get Item Value" s8 0x801DB714 "Last RNG Value" x32 0x80105A80 - "Last Item Button Pressed" u8 0x801DB430 - "Last Damage Value" x32 0x801DB7DC - "Temp B Value" u8 0x8011C062 - "Framerate Divisor" u8 0x801C7861 - "Heads Up Display (HUD)" u16 0x8011C068 "Analog Stick Angle" s16 0x803AA698 - "Deku Tree Warp Timer (Reload Room)" u16 0x801F0352 - "Dodongo's Cavern Warp Timer" u16 0x801E30B2 - "Jabu-Jabu Warp Timer" u16 0x802008B2 - "Forest Temple Warp Timer" u16 0x801EC5B2 - "Fire Temple Warp Timer" u16 0x801F3E42 - "Water Temple Warp Timer" u16 0x801F8762 - "Shadow Temple Warp Timer" u16 0x801F48A2 - "Spirit Temple Warp Timer" u16 0x801FD562 - "Deku Tree Warp Timer" u16 0x801F83A2 */ -}; +}}; // clang-format on +void LoadValueConfig() { + auto allConfig = Ship::Context::GetRawInstance()->GetConfig()->GetNestedJson(); + if (allConfig.find("ValueViewer") == allConfig.end() || !allConfig["ValueViewer"].is_array()) { + allConfig["ValueViewer"] = nlohmann::json::array(); + } + valueViewerSettings = allConfig["ValueViewer"]; +} + +void SaveValueConfig() { + auto allConfig = Ship::Context::GetRawInstance()->GetConfig()->GetNestedJson(); + allConfig["ValueViewer"] = valueViewerSettings; + Ship::Context::GetRawInstance()->GetConfig()->SetBlock("ValueViewer", valueViewerSettings); + Ship::Context::GetRawInstance()->GetConfig()->Save(); +} + extern "C" void ValueViewer_Draw(GfxPrint* printer) { - for (size_t i = 0; i < valueTable.size(); i++) { + for (size_t i = 0; i < VVE_MAX; i++) { ValueTableElement& element = valueTable[i]; - if (!element.isActive || !element.isPrinted || (gPlayState == NULL && element.requiresPlayState)) + if (!valueViewerSettings.contains((ValueViewerEntry)i) || (gPlayState == NULL && element.requiresPlayState)) continue; - GfxPrint_SetColor(printer, element.color.x * 255, element.color.y * 255, element.color.z * 255, - element.color.w * 255); - GfxPrint_SetPos(printer, element.x, element.y); + ValueSetting& setting = valueViewerSettings[(ValueViewerEntry)i]; + if (!setting.isPrinted) + continue; + void* elementValue = element.valueFn(); + if (elementValue == NULL) + continue; + GfxPrint_SetColor(printer, setting.color.x * 255, setting.color.y * 255, setting.color.z * 255, + setting.color.w * 255); + GfxPrint_SetPos(printer, setting.x, setting.y); switch (element.type) { case TYPE_S8: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), - *(s8*)element.valueFn()); + GfxPrint_Printf(printer, (setting.typeFormat ? "%s0x%x" : "%s%d"), setting.prefix.c_str(), + *(s8*)elementValue); break; case TYPE_U8: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), - *(u8*)element.valueFn()); + GfxPrint_Printf(printer, (setting.typeFormat ? "%s0x%x" : "%s%u"), setting.prefix.c_str(), + *(u8*)elementValue); break; case TYPE_S16: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), - *(s16*)element.valueFn()); + GfxPrint_Printf(printer, (setting.typeFormat ? "%s0x%x" : "%s%d"), setting.prefix.c_str(), + *(s16*)elementValue); break; case TYPE_U16: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), - *(u16*)element.valueFn()); + GfxPrint_Printf(printer, (setting.typeFormat ? "%s0x%x" : "%s%u"), setting.prefix.c_str(), + *(u16*)elementValue); break; case TYPE_S32: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), - *(s32*)element.valueFn()); + GfxPrint_Printf(printer, (setting.typeFormat ? "%s0x%x" : "%s%d"), setting.prefix.c_str(), + *(s32*)elementValue); break; case TYPE_U32: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), - *(u32*)element.valueFn()); + GfxPrint_Printf(printer, (setting.typeFormat ? "%s0x%x" : "%s%u"), setting.prefix.c_str(), + *(u32*)elementValue); + break; + case TYPE_PTR: + GfxPrint_Printf(printer, "%s%p", setting.prefix.c_str(), *(void**)elementValue); break; case TYPE_CHAR: - GfxPrint_Printf(printer, "%s%c", element.prefix.c_str(), *(char*)element.valueFn()); + GfxPrint_Printf(printer, "%s%c", setting.prefix.c_str(), *(char*)elementValue); break; case TYPE_STRING: - GfxPrint_Printf(printer, "%s%s", element.prefix.c_str(), (char*)element.valueFn()); + GfxPrint_Printf(printer, "%s%s", setting.prefix.c_str(), (char*)elementValue); break; case TYPE_FLOAT: - GfxPrint_Printf(printer, (element.typeFormat ? "%s%4.1f" : "%s%f"), element.prefix.c_str(), - *(float*)element.valueFn()); + GfxPrint_Printf(printer, (setting.typeFormat ? "%s%4.1f" : "%s%f"), setting.prefix.c_str(), + *(float*)elementValue); break; + default: + SPDLOG_ERROR("ValueViewer_Draw reached `default`, got {}", static_cast(element.type)); + assert(false); } } } @@ -158,14 +179,14 @@ void ValueViewerWindow::DrawElement() { UIWidgets::CVarCheckbox("Enable Printing", CVAR_NAME, UIWidgets::CheckboxOptions().Color(THEME_COLOR)); ImGui::BeginGroup(); - static int selectedElement = -1; + static size_t selectedElement = -1; std::string selectedElementText = (selectedElement == -1) ? "Select a value" : (std::string(valueTable[selectedElement].name) + " (" + std::string(valueTable[selectedElement].path) + ")"); UIWidgets::PushStyleCombobox(THEME_COLOR); if (ImGui::BeginCombo("##valueViewerElement", selectedElementText.c_str())) { for (size_t i = 0; i < valueTable.size(); i++) { - if (valueTable[i].isActive) + if (valueViewerSettings.contains((ValueViewerEntry)i)) continue; bool isSelected = (selectedElement == i); std::string elementText = (std::string(valueTable[i].name) + " (" + std::string(valueTable[i].path) + ")"); @@ -182,64 +203,85 @@ void ValueViewerWindow::DrawElement() { ImGui::SameLine(); UIWidgets::PushStyleButton(THEME_COLOR); if (selectedElement != -1 && ImGui::Button("+")) { - valueTable[selectedElement].isActive = true; + valueViewerSettings.insert( + { (ValueViewerEntry)selectedElement, + { valueTable[selectedElement].prefix, ImVec4(1.0f, 1.0f, 1.0f, 1.0f), false, false, 0, 0 } }); selectedElement = -1; + SaveValueConfig(); } UIWidgets::PopStyleButton(); ImGui::EndGroup(); for (size_t i = 0; i < valueTable.size(); i++) { ValueTableElement& element = valueTable[i]; - if (!element.isActive || (gPlayState == NULL && element.requiresPlayState)) + if (!valueViewerSettings.contains((ValueViewerEntry)i) || (gPlayState == NULL && element.requiresPlayState)) + continue; + void* elementValue = element.valueFn(); + if (elementValue == nullptr) continue; UIWidgets::PushStyleButton(THEME_COLOR); UIWidgets::PushStyleCheckbox(THEME_COLOR); ImGui::AlignTextToFramePadding(); if (ImGui::Button((ICON_FA_TIMES + std::string("##") + std::string(element.name)).c_str())) { - element.isActive = false; - element.isPrinted = false; + valueViewerSettings.erase((ValueViewerEntry)i); + UIWidgets::PopStyleCheckbox(); + UIWidgets::PopStyleButton(); + SaveValueConfig(); + continue; } UIWidgets::PopStyleCheckbox(); UIWidgets::PopStyleButton(); + ValueSetting& setting = valueViewerSettings[(ValueViewerEntry)i]; ImGui::SameLine(); ImGui::Text("%s:", element.name); ImGui::SameLine(); switch (element.type) { case TYPE_S8: - ImGui::Text(element.typeFormat ? "0x%x" : "%d", *(s8*)element.valueFn()); + ImGui::Text(setting.typeFormat ? "0x%x" : "%d", *(s8*)elementValue); break; case TYPE_U8: - ImGui::Text(element.typeFormat ? "0x%x" : "%u", *(u8*)element.valueFn()); + ImGui::Text(setting.typeFormat ? "0x%x" : "%u", *(u8*)elementValue); break; case TYPE_S16: - ImGui::Text(element.typeFormat ? "0x%x" : "%d", *(s16*)element.valueFn()); + ImGui::Text(setting.typeFormat ? "0x%x" : "%d", *(s16*)elementValue); break; case TYPE_U16: - ImGui::Text(element.typeFormat ? "0x%x" : "%u", *(u16*)element.valueFn()); + ImGui::Text(setting.typeFormat ? "0x%x" : "%u", *(u16*)elementValue); break; case TYPE_S32: - ImGui::Text(element.typeFormat ? "0x%x" : "%d", *(s32*)element.valueFn()); + ImGui::Text(setting.typeFormat ? "0x%x" : "%d", *(s32*)elementValue); break; case TYPE_U32: - ImGui::Text(element.typeFormat ? "0x%x" : "%u", *(u32*)element.valueFn()); + ImGui::Text(setting.typeFormat ? "0x%x" : "%u", *(u32*)elementValue); + break; + case TYPE_PTR: + ImGui::Text("%p", *(void**)elementValue); break; case TYPE_CHAR: - ImGui::Text("%c", *(char*)element.valueFn()); + ImGui::Text("%c", *(char*)elementValue); break; case TYPE_STRING: - ImGui::Text("%s", (char*)element.valueFn()); + ImGui::Text("%s", (char*)elementValue); break; case TYPE_FLOAT: - ImGui::Text(element.typeFormat ? "%4.1f" : "%f", *(float*)element.valueFn()); + ImGui::Text(setting.typeFormat ? "%4.1f" : "%f", *(float*)elementValue); break; + default: + SPDLOG_ERROR("ValueViewerWindow::DrawElement reached `default`, got {}", + static_cast(element.type)); + assert(false); } ImGui::SameLine(); UIWidgets::PushStyleCheckbox(THEME_COLOR); if (element.type <= TYPE_U32) { - ImGui::Checkbox(("Hex##" + std::string(element.name)).c_str(), &element.typeFormat); + if (ImGui::Checkbox(("Hex##" + std::string(element.name)).c_str(), &setting.typeFormat)) { + SaveValueConfig(); + } ImGui::SameLine(); } else if (element.type == TYPE_FLOAT) { - ImGui::Checkbox(("Trim##" + std::string(element.name)).c_str(), &element.typeFormat); + if (ImGui::Checkbox(("Trim##" + std::string(element.name)).c_str(), &setting.typeFormat)) { + SaveValueConfig(); + } ImGui::SameLine(); } UIWidgets::PopStyleCheckbox(); @@ -247,20 +289,26 @@ void ValueViewerWindow::DrawElement() { ImGui::BeginGroup(); if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ValueViewerEnablePrinting"), 0)) { UIWidgets::PushStyleCheckbox(THEME_COLOR); - ImGui::Checkbox(("Print##" + std::string(element.name)).c_str(), &element.isPrinted); + if (ImGui::Checkbox(("Print##" + std::string(element.name)).c_str(), &setting.isPrinted)) { + SaveValueConfig(); + } UIWidgets::PopStyleCheckbox(); - if (element.isPrinted) { + if (setting.isPrinted) { char* prefix = (char*)element.prefix.c_str(); ImGui::SameLine(); ImGui::SetNextItemWidth(80.0f); UIWidgets::PushStyleInput(THEME_COLOR); if (ImGui::InputText(("Prefix##" + std::string(element.name)).c_str(), prefix, 10)) { - element.prefix = prefix; + setting.prefix = prefix; + SaveValueConfig(); } UIWidgets::PopStyleInput(); ImGui::SameLine(); - ImGui::ColorEdit3(("##color" + std::string(element.name)).c_str(), (float*)&element.color, - ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel); + if (ImGui::ColorEdit3(("##color" + std::string(element.name)).c_str(), (float*)&setting.color, + ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { + + SaveValueConfig(); + } ImGui::SameLine(); UIWidgets::PushStyleCheckbox(THEME_COLOR); if (ImGui::Button(("Position##" + std::string(element.name)).c_str())) { @@ -268,8 +316,12 @@ void ValueViewerWindow::DrawElement() { } UIWidgets::PopStyleCheckbox(); if (ImGui::BeginPopup(("Position Picker##" + std::string(element.name)).c_str())) { - ImGui::DragInt("X", (int*)&element.x, 1.0f, 0, 44); - ImGui::DragInt("Y", (int*)&element.y, 1.0f, 0, 29); + if (ImGui::DragInt("X", (int*)&setting.x, 1.0f, 0, 44)) { + SaveValueConfig(); + } + if (ImGui::DragInt("Y", (int*)&setting.y, 1.0f, 0, 29)) { + SaveValueConfig(); + } ImGui::EndPopup(); } } @@ -280,4 +332,9 @@ void ValueViewerWindow::DrawElement() { } void ValueViewerWindow::InitElement() { + static bool loadedConfig = false; + if (!loadedConfig) { + LoadValueConfig(); + loadedConfig = true; + } } diff --git a/soh/soh/Enhancements/debugger/valueViewer.h b/soh/soh/Enhancements/debugger/valueViewer.h index 04d698d2c8..c841f19c63 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.h +++ b/soh/soh/Enhancements/debugger/valueViewer.h @@ -11,6 +11,7 @@ typedef enum { TYPE_U16, TYPE_S32, TYPE_U32, + TYPE_PTR, TYPE_CHAR, TYPE_STRING, TYPE_FLOAT, @@ -25,13 +26,56 @@ typedef struct { ValueType type; bool requiresPlayState; ValueFn valueFn; +} ValueTableElement; + +typedef struct { + std::string prefix; ImVec4 color; - bool isActive; bool isPrinted; bool typeFormat; uint32_t x; uint32_t y; -} ValueTableElement; +} ValueSetting; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ImVec4, x, y, z, w) +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ValueSetting, prefix, color, isPrinted, typeFormat, x, y) + +typedef enum { + VVE_TIME, + VVE_AGE, + VVE_HEALTH, + VVE_NAVI_TIMER, + VVE_SCENE_ID, + VVE_ROOM_ID, + VVE_ENTRANCE_ID, + VVE_CUTSCENE_ID, + VVE_LINK_X_POS, + VVE_LINK_Y_POS, + VVE_LINK_Z_POS, + VVE_LINK_YAW, + VVE_LINK_VELOCITY, + VVE_LINK_X_VELOCITY, + VVE_LINK_Y_VELOCITY, + VVE_LINK_Z_VELOCITY, + VVE_TEXT_ID, + VVE_ANALOG_STICK_X, + VVE_ANALOG_STICK_Y, + VVE_GETITEMID, + VVE_GETITEMENTRY, + VVE_MOVEMENT_ANGLE, + VVE_LAST_ITEM_PRESSED, + VVE_STICK_TIMER, + VVE_LAST_DAMAGE_VALUE, + VVE_CAMERA_ANGLE, + VVE_CAMERA_SPEED, + VVE_GLOBAL_FRAME_COUNTER, + VVE_CUTSCENE_POINTER, + VVE_FRAMERATE_DIVISOR, + VVE_NEXT_HUD_MOD, + VVE_TEMP_B_VALUE, + VVE_BLUE_WARP_TIMER, + VVE_MAX, +} ValueViewerEntry; class ValueViewerWindow final : public Ship::GuiWindow { public: diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp index 5f7547cc48..4a772a2b49 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp @@ -259,9 +259,12 @@ void ElectrocutePlayer::_Apply() { // MARK: - KnockbackPlayer GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() { + if (!GameInteractor::IsPlayerInControl()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || - player->stateFlags2 & PLAYER_STATE2_CRAWLING) { + if (player->stateFlags2 & PLAYER_STATE2_CRAWLING) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor.cpp index 315500424f..d8e6abdb66 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.cpp @@ -51,15 +51,49 @@ bool GameInteractor::IsSaveLoaded(bool allowDbgSave) { } bool GameInteractor::IsGameplayPaused() { + if (gPlayState == NULL) { + return true; + } + Player* player = GET_PLAYER(gPlayState); + if (player == NULL) { + return true; + } + return (Player_InBlockingCsMode(gPlayState, player) || gPlayState->pauseCtx.state != 0 || gPlayState->msgCtx.msgMode != 0) ? true : false; } +bool GameInteractor::IsPlayerInControl() { + if (gPlayState == NULL) { + return false; + } + + Player* player = GET_PLAYER(gPlayState); + if (player == NULL) { + return false; + } + + if (gSaveContext.gameMode != GAMEMODE_NORMAL) { + return false; + } + + if (!((gSaveContext.fileNum >= 0 && gSaveContext.fileNum <= 2) || gSaveContext.fileNum == 0xFF)) { + return false; + } + + if (Player_InBlockingCsMode(gPlayState, player) || gPlayState->pauseCtx.state != 0 || + gPlayState->msgCtx.msgMode != 0 || player->unk_6AD == 4) { + return false; + } + + return true; +} + bool GameInteractor::CanSpawnActor() { - return GameInteractor::IsSaveLoaded() && !GameInteractor::IsGameplayPaused(); + return GameInteractor::IsPlayerInControl(); } bool GameInteractor::CanAddOrTakeAmmo(int16_t amount, int16_t item) { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 8d2055fbef..abe3c29974 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -530,6 +530,7 @@ class GameInteractor { // Helpers static bool IsSaveLoaded(bool allowDbgSave = false); static bool IsGameplayPaused(); + static bool IsPlayerInControl(); static bool CanSpawnActor(); static bool CanAddOrTakeAmmo(int16_t amount, int16_t item); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 5d3e99c79b..2cceebc484 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -63,6 +63,7 @@ DEFINE_HOOK(OnDialogMessage, ()); DEFINE_HOOK(OnPresentTitleCard, ()); DEFINE_HOOK(OnInterfaceUpdate, ()); DEFINE_HOOK(OnKaleidoscopeUpdate, (int16_t inDungeonScene)); +DEFINE_HOOK(OnMinimapDrawCompassIcons, ()); DEFINE_HOOK(OnPresentFileSelect, ()); DEFINE_HOOK(OnUpdateFileSelectSelection, (uint16_t optionIndex)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 3375d30c78..b754e9c949 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -298,6 +298,10 @@ void GameInteractor_ExecuteOnKaleidoscopeUpdate(int16_t inDungeonScene) { GameInteractor::Instance->ExecuteHooks(inDungeonScene); } +void GameInteractor_ExecuteOnMinimapDrawCompassIcons() { + GameInteractor::Instance->ExecuteHooks(); +} + // MARK: - Main Menu void GameInteractor_ExecuteOnPresentFileSelect() { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index e998812f52..c93568712b 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -69,6 +69,7 @@ void GameInteractor_ExecuteOnDialogMessage(); void GameInteractor_ExecuteOnPresentTitleCard(); void GameInteractor_ExecuteOnInterfaceUpdate(); void GameInteractor_ExecuteOnKaleidoscopeUpdate(int16_t inDungeonScene); +void GameInteractor_ExecuteOnMinimapDrawCompassIcons(); // MARK: - Main Menu void GameInteractor_ExecuteOnPresentFileSelect(); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp index 9ffdb24523..9267724456 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp @@ -1,9 +1,10 @@ #include "GameInteractor.h" #include -#include "soh/Enhancements/randomizer/3drando/random.hpp" +#include "soh/ShipUtils.h" #include #include "soh/Enhancements/debugger/colViewer.h" #include "soh/Enhancements/nametag.h" +#include "soh/ShipUtils.h" extern "C" { #include "variables.h" @@ -410,15 +411,11 @@ void GameInteractor::RawAction::EmulateButtonPress(int32_t button) { } void GameInteractor::RawAction::EmulateRandomButtonPress(uint32_t chancePercentage) { - uint32_t emulatedButton; - uint32_t randomNumber = rand(); + uint32_t randomNumber = ShipUtils::Random(0, 1400); uint32_t possibleButtons[14] = { BTN_CRIGHT, BTN_CLEFT, BTN_CDOWN, BTN_CUP, BTN_R, BTN_L, BTN_DRIGHT, BTN_DLEFT, BTN_DDOWN, BTN_DUP, BTN_START, BTN_Z, BTN_B, BTN_A }; - - emulatedButton = possibleButtons[randomNumber % 14]; - if (randomNumber % 100 < chancePercentage) { - GameInteractor::State::EmulatedButtons |= emulatedButton; + GameInteractor::State::EmulatedButtons |= possibleButtons[randomNumber / 100]; } } @@ -431,7 +428,7 @@ void GameInteractor::RawAction::SetRandomWind(bool active) { if (active) { GameInteractor::State::RandomWindActive = 1; if (GameInteractor::State::RandomWindSecondsSinceLastDirectionChange == 0) { - player->pushedYaw = (rand() % 49152) - 32767; + player->pushedYaw = ShipUtils::Random(0, 0xc000) - 0x8000; GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 5; } else { GameInteractor::State::RandomWindSecondsSinceLastDirectionChange--; @@ -498,7 +495,7 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset } // Generate point in random angle with a radius. - float angle = static_cast(RandomDouble() * 2 * M_PI); + float angle = static_cast(ShipUtils::RandomDouble() * 2 * M_PI); float radius = 150; float posXOffset = radius * cos(angle); float posZOffset = radius * sin(angle); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 956711edc9..64b47de7d1 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -195,14 +195,38 @@ typedef enum { // - `*EnTk` VB_BE_VALID_GRAVEDIGGING_SPOT, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - 'EnHy*' + VB_BEGGAR_GIVE_ITEM, + // #### `result` // ```c // this->collider.base.acFlags & 2 || blueFireArrowHit // ``` // #### `args` - // - None + // - `*BgBreakwall` VB_BG_BREAKWALL_BREAK, + // #### `result` + // ```c + // this->cylinder1.base.acFlags & AC_HIT + // ``` + // #### `args` + // - `*BgIceShelter` + VB_BG_ICE_SHELTER_HIT, + + // #### `result` + // ```c + // (this->cylinder1.base.ac != NULL) && (this->cylinder1.base.ac->id == ACTOR_EN_ICE_HONO) + // ``` + // #### `args` + // - `*BgIceShelter` + VB_BG_ICE_SHELTER_MELT, + // #### `result` // ```c // this->timer > 0 && this->timer <= 100 @@ -244,6 +268,15 @@ typedef enum { // - `*Actor` (interactRangeActor) VB_BOTTLE_ACTOR, + // #### `result` + // Actor is ACTOR_OBJ_BOMBIWA, or ACTOR_OBJ_HAMISHI + // ```c + // Flags_GetSwitch(play, this->actor.params & 0x3F) + // ``` + // #### `args` + // - `*Actor` (interactRangeActor) + VB_BOULDER_BREAK_FLAG, + // #### `result` // ```c // true @@ -547,6 +580,15 @@ typedef enum { // - '*Player' VB_DRAW_ADDITIONAL_RETICLES, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `PlayerMask currentMask` + // - `*PlayState play` + VB_DRAW_PLAYER_MASK, + // #### `result` // In `Interface_DrawAmmoCount`: // ```c @@ -884,6 +926,31 @@ typedef enum { // - `*EnGe1` VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnGe1` + // - `*PlayState` + VB_PLAY_HORSEBACK_ARCHERY, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*s32` (scoreIndex: 0=30pts, 1=60pts, 2=100pts) + VB_SCORE_HORSEBACK_ARCHERY_TARGET, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*InterfaceContext` + VB_SET_HORSEBACK_ARCHERY_AMMO, + // #### `result` // ```c // true @@ -1252,6 +1319,14 @@ typedef enum { // - None VB_HEARTS_INCREASE_WITH_CONTAINERS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*BgIceTurara` + VB_ICICLE_SETUP_DRAW, + // #### `result` // ```c // (respawnFlag == 1) || (respawnFlag == -1) @@ -1284,6 +1359,14 @@ typedef enum { // - `*EnItem00` VB_ITEM00_DESPAWN, + // #### `result` + // ```c + // this->unk_15A > 0 + // ``` + // #### `args` + // - `*EnItem00` + VB_ITEM00_TIMER_TICK, + // #### `result` // ```c // true @@ -1292,6 +1375,14 @@ typedef enum { // - None VB_JABU_WOBBLE, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_HOT_ROOM_DISTORTION, + // #### `result` // ```c // true @@ -1936,6 +2027,22 @@ typedef enum { // - `*EnRd` VB_REDEAD_GIBDO_FREEZE_LINK, + // #### `result` + // ```c + // this->alpha <= 0 + // ``` + // #### `args` + // - `*BgIceShelter` + VB_RED_ICE_DROP_ITEM, + + // #### `result` + // ```c + // !((this->dyna.actor.params >> 6) & 1) && (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) + // ``` + // #### `args` + // - `*BgIceShelter` + VB_RED_ICE_MELTED_FLAG, + // #### `result` // #### `result` // ```c @@ -1969,6 +2076,14 @@ typedef enum { // - None VB_REVERT_SPOILING_ITEMS, + // #### `result` + // ```c + // varies + // ``` + // #### `args` + // - `*EnIshi`, `*ObjBombiwa`, or `*ObjHamishi` + VB_ROCK_DROP_ITEM, + // #### `result` // ```c // !Flags_GetInfTable(INFTABLE_145) @@ -2021,6 +2136,14 @@ typedef enum { // - `*EnNiwLady` VB_SET_CUCCO_COUNT, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_SET_DIVING_GAME_TIME_LIMIT, + // #### `result` // ```c // SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2 @@ -2109,6 +2232,14 @@ typedef enum { // - None VB_SHOW_TITLE_CARD, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_SKIP_TALKING, + // #### `result` // ```c // (collectible >= 0) && (collectible <= 0x19 @@ -2179,6 +2310,14 @@ typedef enum { // - `*BossVa` VB_SPAWN_BLUE_WARP, + // #### `result` + // ```c + // this->timer == 4 + // ``` + // #### `args` + // - `*EnButte` + VB_SPAWN_BUTTERFLY_FAIRY, + // #### `result` // ```c // INV_CONTENT(ITEM_ARROW_FIRE) == ITEM_NONE @@ -2240,6 +2379,22 @@ typedef enum { // - None VB_SPEAK, + // #### `result` + // ```c + // this->dyna.actor.params == TURARA_STALACTITE_REGROW + // ``` + // #### `args` + // - `*BgIceTurara` + VB_STALACTITE_DROP_ITEM, + + // #### `result` + // ```c + // this->collider.base.acFlags & AC_HIT + // ``` + // #### `args` + // - `*BgIceTurara` + VB_STALAGMITE_DROP_ITEM, + // #### `result` // ```c // varies, never set should to true @@ -2404,6 +2559,42 @@ typedef enum { // - None VB_WIN_GORON_POT, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnWonderItem` + VB_WONDER_DROP_ITEM, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - 'Vec3f' pos + // - 'f32' rotY + VB_WONDER_HEISHI_ITEM, + + // #### `result` + // ```c + // (gSaveContext.dayTime < 0xB888 || IS_DAY) && ((!IS_RANDO && + // !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) || (IS_RANDO && !metZelda)) + // (gSaveContext.dayTime >= 0xB889) || !IS_DAY || (!IS_RANDO && + // Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) || (IS_RANDO && metZelda) + // ``` + // #### `args` + // - EnHeishi1* + VB_WONDER_HEISHI_PATROLLING, + + // #### `result` + // ```c + // (this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag) + // ``` + // #### `args` + // - `None` + VB_WONDER_SPAWN, + // #### `result` // ```c // true @@ -2526,6 +2717,15 @@ typedef enum { // - *EnGirlACanBuyResult VB_CAN_BUY_BOMBCHUS, + // #### `result` + // ```c + // false + // ``` + // #### `args` + // - *EnGirlACanBuyResult + // - `RAND_INF` + VB_CAN_BUY_SHOP_SHIELD_OR_TUNIC, + // #### `result` // ```c // true @@ -2549,14 +2749,6 @@ typedef enum { // - `*BgHidanDalm` VB_HAMMER_TOTEM_BREAK, - // #### `result` - // ```c - // Actor_GetCollidedExplosive(play, &this->collider.base) != NULL - // ``` - // #### `args` - // - `*BgHidanKowarerukabe` - VB_FIRE_TEMPLE_BOMBABLE_WALL_BREAK, - // #### `result` // ```c // true @@ -2591,6 +2783,22 @@ typedef enum { // - `*FileChooseContext` VB_FILE_SELECT_DRAW_FILE_INFO_BOX, + // #### `result` + // ```c + // Actor_GetCollidedExplosive(play, &this->collider.base) != NULL + // ``` + // #### `args` + // - `*BgHidanKowarerukabe` + VB_FIRE_TEMPLE_BOMBABLE_WALL_BREAK, + + // #### `result` + // ```c + // this->timer > 0 + // ``` + // #### `args` + // - None + VB_FISH_TIMER_TICK, + // #### `result` // ```c // true diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index 68e78032a2..59b0ae2fb7 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -3,6 +3,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "ship/utils/StringHelper.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/Enhancements/randomizer/SeedContext.h" #include "soh/ShipInit.hpp" #include "soh/ShipUtils.h" diff --git a/soh/soh/Enhancements/mod_menu.cpp b/soh/soh/Enhancements/mod_menu.cpp index ff9a459baa..92e1fd9b8a 100644 --- a/soh/soh/Enhancements/mod_menu.cpp +++ b/soh/soh/Enhancements/mod_menu.cpp @@ -54,7 +54,7 @@ void SetEnabledModsCVarValue() { } CVarSetString(CVAR_ENABLED_MODS_NAME, s.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } void AfterModChange() { @@ -105,7 +105,7 @@ std::vector& GetModFiles(bool enabled) { } std::shared_ptr GetArchiveManager() { - return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager(); + return Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager(); } bool IsValidExtension(std::string extension) { @@ -334,8 +334,8 @@ void ModMenuWindow::DrawElement() { gfx_texture_cache_clear(); SOH::SkeletonPatcher::ClearSkeletons(); */ - Ship::Context::GetInstance()->GetConsoleVariables()->Save(); - Ship::Context::GetInstance()->GetWindow()->Close(); + Ship::Context::GetRawInstance()->GetConsoleVariables()->Save(); + Ship::Context::GetRawInstance()->GetWindow()->Close(); }); } } diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp deleted file mode 100644 index 6d7ecf3b74..0000000000 --- a/soh/soh/Enhancements/mods.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include "mods.h" -#include -#include "game-interactor/GameInteractor.h" -#include "soh/Enhancements/boss-rush/BossRush.h" -#include "soh/Enhancements/enhancementTypes.h" -#include - -extern "C" { -#include -#include "macros.h" -#include "soh/cvar_prefixes.h" -#include "variables.h" -#include "functions.h" - -extern SaveContext gSaveContext; -extern PlayState* gPlayState; -} - -/// Switches Link's age and respawns him at the last entrance he entered. -void SwitchAge() { - if (gPlayState == NULL) - return; - - Player* player = GET_PLAYER(gPlayState); - - // Hyrule Castle: Very likely to fall through floor, so we force a specific entrance - if (gPlayState->sceneNum == SCENE_HYRULE_CASTLE || gPlayState->sceneNum == SCENE_OUTSIDE_GANONS_CASTLE) { - gPlayState->nextEntranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT; - } else { - gSaveContext.respawnFlag = 1; - gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; - - // Preserve the player's position and orientation - gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = gPlayState->nextEntranceIndex; - gSaveContext.respawn[RESPAWN_MODE_DOWN].roomIndex = gPlayState->roomCtx.curRoom.num; - gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = player->actor.world.pos; - gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = player->actor.shape.rot.y; - - if (gPlayState->roomCtx.curRoom.behaviorType2 < 4) { - gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0DFF; - } else { - // Scenes with static backgrounds use a special camera we need to preserve - Camera* camera = GET_ACTIVE_CAM(gPlayState); - s16 camId = camera->camDataIdx; - gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0D00 | camId; - } - } - - gPlayState->transitionTrigger = TRANS_TRIGGER_START; - gPlayState->transitionType = TRANS_TYPE_INSTANT; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK_FAST; - gPlayState->linkAgeOnLoad ^= 1; - - // Discover adult/child spawns - if (gPlayState->linkAgeOnLoad == LINK_AGE_ADULT) { - Entrance_SetEntranceDiscovered(ENTR_HYRULE_FIELD_10, false); - } else { - Entrance_SetEntranceDiscovered(ENTR_LINKS_HOUSE_CHILD_SPAWN, false); - } - - static HOOK_ID hookId = 0; - hookId = REGISTER_VB_SHOULD(VB_INFLICT_VOID_DAMAGE, { - *should = false; - GameInteractor::Instance->UnregisterGameHookForID(hookId); - }); -} - -/// Switches Link's age and respawns him at the last entrance he entered. -void RegisterOcarinaTimeTravel() { - GameInteractor::Instance->RegisterGameHook([]() { - if (!GameInteractor::IsSaveLoaded(true) || !CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0)) { - return; - } - - Actor* player = &GET_PLAYER(gPlayState)->actor; - Actor* nearbyTimeBlockEmpty = - Actor_FindNearby(gPlayState, player, ACTOR_OBJ_WARP2BLOCK, ACTORCAT_ITEMACTION, 300.0f); - Actor* nearbyTimeBlock = Actor_FindNearby(gPlayState, player, ACTOR_OBJ_TIMEBLOCK, ACTORCAT_ITEMACTION, 300.0f); - Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.0f); - Actor* nearbyDoorOfTime = Actor_FindNearby(gPlayState, player, ACTOR_DOOR_TOKI, ACTORCAT_BG, 500.0f); - Actor* nearbyFrogs = Actor_FindNearby(gPlayState, player, ACTOR_EN_FR, ACTORCAT_NPC, 300.0f); - Actor* nearbyGossipStone = Actor_FindNearby(gPlayState, player, ACTOR_EN_GS, ACTORCAT_NPC, 300.0f); - bool justPlayedSoT = gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME; - bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && - !nearbyFrogs && !nearbyGossipStone; - bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); - bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); - 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(); - } - }); -} - -bool IsHyperBossesActive() { - return CVarGetInteger(CVAR_ENHANCEMENT("HyperBosses"), 0) || - (IS_BOSS_RUSH && - gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES); -} - -void UpdateHyperBossesState() { - static uint32_t actorUpdateHookId = 0; - if (actorUpdateHookId != 0) { - GameInteractor::Instance->UnregisterGameHook(actorUpdateHookId); - actorUpdateHookId = 0; - } - - if (IsHyperBossesActive()) { - actorUpdateHookId = - GameInteractor::Instance->RegisterGameHook([](void* refActor) { - // Run the update function a second time to make bosses move and act twice as fast. - - Player* player = GET_PLAYER(gPlayState); - Actor* actor = static_cast(refActor); - - uint8_t isBossActor = actor->id == ACTOR_BOSS_GOMA || // Gohma - actor->id == ACTOR_BOSS_DODONGO || // King Dodongo - actor->id == ACTOR_EN_BDFIRE || // King Dodongo Fire Breath - actor->id == ACTOR_BOSS_VA || // Barinade - actor->id == ACTOR_BOSS_GANONDROF || // Phantom Ganon - actor->id == ACTOR_EN_FHG_FIRE || // Phantom Ganon/Ganondorf Energy Ball/Thunder - actor->id == ACTOR_EN_FHG || // Phantom Ganon's Horse - actor->id == ACTOR_BOSS_FD || - actor->id == ACTOR_BOSS_FD2 || // Volvagia (grounded/flying) - actor->id == ACTOR_EN_VB_BALL || // Volvagia Rocks - actor->id == ACTOR_BOSS_MO || // Morpha - actor->id == ACTOR_BOSS_SST || // Bongo Bongo - actor->id == ACTOR_BOSS_TW || // Twinrova - actor->id == ACTOR_BOSS_GANON || // Ganondorf - actor->id == ACTOR_BOSS_GANON2; // Ganon - - // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some bosses. - if (IsHyperBossesActive() && isBossActor && !Player_InBlockingCsMode(gPlayState, player)) { - // Barinade needs to be updated in sequence to avoid unintended behaviour. - if (actor->id == ACTOR_BOSS_VA) { - // params -1 is BOSSVA_BODY - if (actor->params == -1) { - Actor* actorList = gPlayState->actorCtx.actorLists[ACTORCAT_BOSS].head; - while (actorList != NULL) { - GameInteractor::RawAction::UpdateActor(actorList); - actorList = actorList->next; - } - } - } else { - GameInteractor::RawAction::UpdateActor(actor); - } - } - }); - } -} - -void RegisterHyperBosses() { - UpdateHyperBossesState(); - GameInteractor::Instance->RegisterGameHook( - [](int16_t fileNum) { UpdateHyperBossesState(); }); -} - -void InitMods() { - RegisterOcarinaTimeTravel(); - RegisterHyperBosses(); -} diff --git a/soh/soh/Enhancements/mods.h b/soh/soh/Enhancements/mods.h deleted file mode 100644 index 9a0c6794bf..0000000000 --- a/soh/soh/Enhancements/mods.h +++ /dev/null @@ -1,18 +0,0 @@ -#include - -#ifndef MODS_H -#define MODS_H - -#ifdef __cplusplus -extern "C" { -#endif - -void UpdateHyperBossesState(); -void InitMods(); -void SwitchAge(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp b/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp deleted file mode 100644 index cec16a468f..0000000000 --- a/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "custom_messages.hpp" -#include "../../custom-message/CustomMessageManager.h" -#include "z64item.h" - -namespace CustomMessages { -using namespace std::literals::string_literals; - -std::string MESSAGE_END() { - return "\x7F\x00"s; -} -std::string WAIT_FOR_INPUT() { - return "\x7F\x01"s; -} -std::string HORIZONTAL_SPACE(uint8_t x) { - return "\x7F\x02"s + char(x); -} -std::string GO_TO(uint16_t x) { - return "\x7F\x03"s + char(x >> 8) + char(x & 0x00FF); -} -std::string INSTANT_TEXT_ON() { - return "\x7F\x04"s; -} -std::string INSTANT_TEXT_OFF() { - return "\x7F\x05"s; -} -std::string SHOP_MESSAGE_BOX() { - return "\x7F\x06\x00"s; -} -std::string EVENT_TRIGGER() { - return "\x7F\x07"s; -} -std::string DELAY_FRAMES(uint8_t x) { - return "\x7F\x08"s + char(x); -} -std::string CLOSE_AFTER(uint8_t x) { - return "\x7F\x0A"s + char(x); -} -std::string PLAYER_NAME() { - return "\x7F\x0B"s; -} -std::string PLAY_OCARINA() { - return "\x7F\x0C"s; -} -std::string ITEM_OBTAINED(uint8_t x) { - return "\x7F\x0F"s + char(x); -} -std::string SET_SPEED(uint8_t x) { - return "\x7F\x10"s + char(x); -} -std::string SKULLTULAS_DESTROYED() { - return "\x7F\x15"s; -} -std::string CURRENT_TIME() { - return "\x7F\x17"s; -} -std::string UNSKIPPABLE() { - return "\x7F\x19"s; -} -std::string TWO_WAY_CHOICE() { - return "\x1B"s; -} -std::string NEWLINE() { - return "\x7F\x1C"s; -} -std::string COLOR(std::string x) { - return "\x7F\x1D"s + x; -} -std::string CENTER_TEXT() { - return "\x7F\x1E"s; -} -std::string IF_NOT_MQ() { - return "\x7F\x29"s; -} -std::string MQ_ELSE() { - return "\x7F\x2A"s; -} -std::string MQ_END() { - return "\x7F\x2B"s; -} -} // namespace CustomMessages diff --git a/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp b/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp deleted file mode 100644 index 71a0e66b0d..0000000000 --- a/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include - -#include "text.hpp" - -namespace CustomMessages { -std::string MESSAGE_END(); -std::string WAIT_FOR_INPUT(); -std::string HORIZONTAL_SPACE(uint8_t x); -std::string GO_TO(uint16_t x); -std::string INSTANT_TEXT_ON(); -std::string INSTANT_TEXT_OFF(); -std::string SHOP_MESSAGE_BOX(); -std::string EVENT_TRIGGER(); -std::string DELAY_FRAMES(uint8_t x); -std::string CLOSE_AFTER(uint8_t x); -std::string PLAYER_NAME(); -std::string PLAY_OCARINA(); -std::string ITEM_OBTAINED(uint8_t x); -std::string SET_SPEED(uint8_t x); -std::string SKULLTULAS_DESTROYED(); -std::string CURRENT_TIME(); -std::string UNSKIPPABLE(); -std::string TWO_WAY_CHOICE(); -std::string NEWLINE(); -std::string COLOR(std::string x); -std::string CENTER_TEXT(); -std::string IF_NOT_MQ(); -std::string MQ_ELSE(); -std::string MQ_END(); -} // namespace CustomMessages diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 5f92344c6c..cb15b8f70c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -3,9 +3,9 @@ #include "../dungeon.h" #include "../SeedContext.h" #include "item_pool.hpp" -#include "random.hpp" #include "starting_inventory.hpp" #include "hints.hpp" +#include "random.hpp" #include "shops.hpp" #include "pool_functions.hpp" #include "soh/Enhancements/randomizer/static_data.h" @@ -81,30 +81,30 @@ static void PropagateTimeTravel(GetAccessibleLocationsStruct& gals, RandomizerGe static bool UpdateToDAccess(Entrance* entrance, Region* connection) { StartPerformanceTimer(PT_TOD_ACCESS); - bool ageTimePropogated = false; + bool ageTimePropagated = false; Region* parent = entrance->GetParentRegion(); if (!connection->childDay && parent->childDay && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) { connection->childDay = true; - ageTimePropogated = true; + ageTimePropagated = true; } if (!connection->childNight && parent->childNight && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) { connection->childNight = true; - ageTimePropogated = true; + ageTimePropagated = true; } if (!connection->adultDay && parent->adultDay && entrance->CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) { connection->adultDay = true; - ageTimePropogated = true; + ageTimePropagated = true; } if (!connection->adultNight && parent->adultNight && entrance->CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight)) { connection->adultNight = true; - ageTimePropogated = true; + ageTimePropagated = true; } StopPerformanceTimer(PT_TOD_ACCESS); - return ageTimePropogated; + return ageTimePropagated; } // Check if key locations in the overworld are accessable @@ -402,7 +402,8 @@ bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals (quest == RCQUEST_VANILLA && ctx->GetDungeons()->GetDungeonFromScene(parentRegion->scene)->IsVanilla()) || (quest == RCQUEST_MQ && ctx->GetDungeons()->GetDungeonFromScene(parentRegion->scene)->IsMQ())); - if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, logic->CalculatingAvailableChecks)) { + if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, logic->CalculatingAvailableChecks) && + !logic->ShopItemNotForSale(loc)) { location->AddToPool(); if (locItem == RG_NONE || logic->CalculatingAvailableChecks) { @@ -545,7 +546,7 @@ std::vector ReachabilitySearch(const std::vectorGetItemLocation(loc)->GetPlacedRandomizerGet() != RG_NONE && !calculatingAvailableChecks) { return false; } @@ -569,10 +570,12 @@ void GeneratePlaythrough() { do { gals.InitLoop(); for (size_t i = 0; i < gals.regionPool.size(); i++) { + resetSphere: ProcessRegion(RegionTable(gals.regionPool[i]), gals, RG_NONE, false, true); if (gals.resetSphere) { gals.resetSphere = false; - i = -1; + i = 0; + goto resetSphere; } } if (gals.itemSphere.size() > 0) { @@ -787,12 +790,17 @@ static void CalculateBarren() { NotBarren[RA_NONE] = true; NotBarren[RA_LINKS_POCKET] = true; + // When shop shields/tunics are gated behind finding a shield, those items become relevant, so + // regions holding a shield or tunic should not be hinted foolish. + const bool shieldTunicGate = ctx->GetOption(RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL).Is(RO_GENERIC_ON); + for (RandomizerCheck loc : ctx->allLocations) { Rando::ItemLocation* itemLoc = ctx->GetItemLocation(loc); std::set locAreas = itemLoc->GetAreas(); for (auto locArea : locAreas) { // If a location has a major item or is a way of the hero location, it is not barren - if (NotBarren[locArea] == false && (itemLoc->GetPlacedItem().IsMajorItem() || itemLoc->IsWothCandidate())) { + if (NotBarren[locArea] == false && (itemLoc->GetPlacedItem().IsMajorItem() || itemLoc->IsWothCandidate() || + (shieldTunicGate && itemLoc->GetPlacedItem().IsShieldOrTunic()))) { NotBarren[locArea] = true; } } @@ -891,14 +899,12 @@ static void AssumedFill(const std::vector& items, const std::vect // retry if there are no more locations to place items if (accessibleLocations.empty()) { - SPDLOG_DEBUG("CANNOT PLACE {}. TRYING_AGAIN...", Rando::StaticData::RetrieveItem(item).GetName().GetEnglish()); // reset any locations that got an item for (RandomizerCheck loc : attemptedLocations) { ctx->GetItemLocation(loc)->SetPlacedItem(RG_NONE); - // itemsPlaced--; } attemptedLocations.clear(); @@ -933,102 +939,94 @@ static void AssumedFill(const std::vector& items, const std::vect } while (unsuccessfulPlacement); } +static std::vector GetStonesInPool(std::vector pool) { + return FilterFromPool(pool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD && + Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_KOKIRI_EMERALD && + Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_ZORA_SAPPHIRE; + }); +} + +static std::vector GetMedallionsInPool(std::vector pool) { + return FilterFromPool(pool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD && + Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_FOREST_MEDALLION && + Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_LIGHT_MEDALLION; + }); +} + // This function will specifically randomize dungeon rewards for the End of Dungeons // setting, or randomize one dungeon reward to Link's Pocket if that setting is on +// RANDOTODO this function assumes only 1 of each reward can exist, fix it when starting items are refactored static void RandomizeDungeonRewards() { auto ctx = Rando::Context::GetInstance(); - // End of Dungeons includes Link's Pocket - if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || - ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { - // make temporary pools of stones and medallions, get rewards - std::vector stones = FilterFromPool(itemPool, [](const auto i) { - return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD && - Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_KOKIRI_EMERALD && - Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_ZORA_SAPPHIRE; - }); - std::vector medallions = FilterFromPool(itemPool, [](const auto i) { - return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD && - Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_FOREST_MEDALLION && - Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_LIGHT_MEDALLION; - }); - std::vector rewards = FilterAndEraseFromPool(itemPool, [](const auto i) { - return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; - }); + std::vector rewards = FilterFromPool(itemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; + }); - 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(); + if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_DUNGEON_REWARD) && rewards.size() >= 9) { + RandomizerGet pocketItem = RG_GREEN_RUPEE; + std::vector pocketPossibilities = {}; + + if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_ANY_STONE)) { + // get existing stones + pocketPossibilities = GetStonesInPool(rewards); + } else if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_LIGHT_MEDALLION)) { + // check if Light medallion exists + std::vector lightMedallion = FilterFromPool(rewards, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetRandomizerGet() == RG_LIGHT_MEDALLION; + }); + // If there are no light med, then Link's pocket can't get one + if (!lightMedallion.empty()) { + pocketPossibilities = { RG_LIGHT_MEDALLION }; } - ctx->GetItemLocation(RC_GIFT_FROM_RAURU)->PlaceVanillaItem(); - } else { // Randomize dungeon rewards with assumed fill - std::vector rewardLocations(Rando::StaticData::dungeonRewardLocations); - // If there are less than 9 dungeon rewards, prioritize actual dungeons for placement - if (rewards.size() < 9) { - ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); - } else { - if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).IsNot(RO_LINKS_POCKET_REWARD)) { - if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_STONE)) { - // get one stone - RandomizerGet startingStone = RandomElement(stones, true); - // erase from rewards so remaining are placed - erase_if(rewards, [&](RandomizerGet r) { return r == startingStone; }); - ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingStone); - } else { - // get one medallion - RandomizerGet startingMedallion = RandomElement(medallions, true); - // erase from rewards so remaining are placed - erase_if(rewards, [&](RandomizerGet r) { return r == startingMedallion; }); - ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingMedallion); - } - } else { - rewardLocations.push_back(RC_LINKS_POCKET); - } - } - AssumedFill(rewards, rewardLocations); + } else if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_ANY_MEDALLION)) { + // get existing medallions + pocketPossibilities = GetMedallionsInPool(rewards); + } else if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_ANY_REWARD)) { + // get all existing rewards + pocketPossibilities = rewards; } - } else if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_DUNGEON_REWARD)) { - // make temporary pools of stones, medallions, and rewards - std::vector stones = FilterFromPool(itemPool, [](const auto i) { - return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD && - Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_KOKIRI_EMERALD && - Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_ZORA_SAPPHIRE; - }); - std::vector medallions = FilterFromPool(itemPool, [](const auto i) { - return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD && - Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_FOREST_MEDALLION && - Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_LIGHT_MEDALLION; - }); - std::vector rewards = FilterFromPool(itemPool, [](const auto i) { - return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; - }); - // If there are no remaining stones/medallions, then Link's pocket won't get one - if (rewards.empty()) { - ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); - return; - } - if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_STONE)) { + + if (!pocketPossibilities.empty()) { // get one stone - RandomizerGet startingStone = RandomElement(stones, true); - ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingStone); - // erase stone from item pool - FilterAndEraseFromPool(itemPool, [startingStone](const RandomizerGet i) { return i == startingStone; }); - } else if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_MEDALLION)) { - // get one medallion - RandomizerGet startingMedallion = RandomElement(medallions, true); - ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingMedallion); - // erase medallion from item pool - FilterAndEraseFromPool(itemPool, - [startingMedallion](const RandomizerGet i) { return i == startingMedallion; }); - } else { - // get one reward - RandomizerGet startingReward = RandomElement(rewards, true); - - ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingReward); - // erase the stone/medallion from the Item Pool - FilterAndEraseFromPool(itemPool, [startingReward](const RandomizerGet i) { return i == startingReward; }); + pocketItem = RandomElement(pocketPossibilities); } + // erase from rewards so remaining are placed + std::erase_if(rewards, [&](RandomizerGet r) { return r == pocketItem; }); + // and from the item pool so it's not placed twice + std::erase_if(itemPool, [pocketItem](const RandomizerGet i) { return i == pocketItem; }); + // and add to the pocket + ctx->PlaceItemInLocation(RC_LINKS_POCKET, pocketItem); + } + + // If we didn't place the Light Medallion on pocket, and we have rewards in their own dungeons or at the end of + // dungeons... + if ((ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA) || + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_OWN_DUNGEON)) && + ctx->GetOption(RSK_LINKS_POCKET).IsNot(RO_LINKS_POCKET_DUNGEON_REWARD)) { + // place it on Gift From Rauru + ctx->GetItemLocation(RC_GIFT_FROM_RAURU)->PlaceVanillaItem(); + // then erase from rewards so remaining are placed + std::erase_if(rewards, [&](RandomizerGet r) { return r == RG_LIGHT_MEDALLION; }); + // and from the item pool so it's not placed twice + std::erase_if(itemPool, [](const RandomizerGet i) { return i == RG_LIGHT_MEDALLION; }); + } + + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { + std::erase_if(itemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; + }); + AssumedFill(rewards, Rando::StaticData::dungeonRewardLocations); + } else if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { + for (RandomizerCheck loc : Rando::StaticData::dungeonRewardLocations) { + ctx->GetItemLocation(loc)->PlaceVanillaItem(); + } + // Then remove rewards from the item pool + std::erase_if(itemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; + }); } } @@ -1078,6 +1076,12 @@ static void RandomizeOwnDungeon(const Rando::DungeonInfo* dungeon) { }); AddElementsToPool(dungeonItems, dungeonSmallKeys); } + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_OWN_DUNGEON) && + dungeon->GetReward() != RG_NONE) { + std::vector dungeonReward = + FilterAndEraseFromPool(itemPool, [dungeon](const RandomizerGet i) { return (i == dungeon->GetReward()); }); + AddElementsToPool(dungeonItems, dungeonReward); + } if ((ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) || @@ -1088,7 +1092,7 @@ static void RandomizeOwnDungeon(const Rando::DungeonInfo* dungeon) { AddElementsToPool(dungeonItems, dungeonBossKey); } - // randomize boss key and small keys together for even distribution + // randomize boss key, small keys, and rewards together for even distribution AssumedFill(dungeonItems, dungeonLocations); // randomize map and compass separately since they're not progressive @@ -1179,6 +1183,14 @@ static void RandomizeDungeonItems() { AddElementsToPool(overworldItems, rewards); } + if (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_LOCATION).Is(RO_TRIFORCE_HUNT_LOCATION_ANY_DUNGEON)) { + auto triforcePieces = FilterAndEraseFromPool(itemPool, [](const auto i) { return i == RG_TRIFORCE_PIECE; }); + AddElementsToPool(anyDungeonItems, triforcePieces); + } else if (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_LOCATION).Is(RO_TRIFORCE_HUNT_LOCATION_OVERWORLD)) { + auto triforcePieces = FilterAndEraseFromPool(itemPool, [](const auto i) { return i == RG_TRIFORCE_PIECE; }); + AddElementsToPool(overworldItems, triforcePieces); + } + // Randomize Any Dungeon and Overworld pools AssumedFill(anyDungeonItems, anyDungeonLocations, true); AssumedFill(overworldItems, ctx->overworldLocations, true); @@ -1279,7 +1291,7 @@ int Fill() { } SetAreas(); // erase temporary shop items - FilterAndEraseFromPool(itemPool, [](const auto item) { + std::erase_if(itemPool, [](const auto item) { return Rando::StaticData::RetrieveItem(item).GetItemType() == ITEMTYPE_SHOP; }); StopPerformanceTimer(PT_ENTRANCE_SHUFFLE); @@ -1431,8 +1443,7 @@ int Fill() { StartPerformanceTimer(PT_REMAINING_ITEMS); // Fast fill for the rest of the pool SPDLOG_INFO("Shuffling Remaining Items"); - std::vector remainingPool = FilterAndEraseFromPool(itemPool, [](const auto i) { return true; }); - FastFill(remainingPool, GetAllEmptyLocations(), false); + FastFill(std::move(itemPool), GetAllEmptyLocations(), false); StopPerformanceTimer(PT_REMAINING_ITEMS); StartPerformanceTimer(PT_PLAYTHROUGH_GENERATION); @@ -1440,7 +1451,6 @@ int Fill() { StopPerformanceTimer(PT_PLAYTHROUGH_GENERATION); // Successful placement, produced beatable result if (ctx->playthroughBeatable && !placementFailure) { - SPDLOG_INFO("Calculating Playthrough..."); StartPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); PareDownPlaythrough(); diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index f541feeef5..1de7336627 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -1,10 +1,7 @@ -#include "custom_messages.hpp" - #include "../randomizerTypes.h" #include "../SeedContext.h" #include "../static_data.h" -using namespace CustomMessages; using namespace std::literals::string_literals; // Big thanks to Lioncache, Gabyelnuevo, Danius88, and Charade for their translations! @@ -2237,10 +2234,9 @@ void StaticData::HintTable_Init() { /*french*/ "J'ai entendu dire que Ganondorf aurait caché les #Flèches de Lumière# dans #[[1]]#.", {QM_YELLOW, QM_RED})); - hintTextTable[RHT_BOSS_KEY_HINT] = HintText(CustomMessage("The #boss key# for this door is in #[[1]]#!", + hintTextTable[RHT_BOSS_KEY_HINT] = HintText(CustomMessage("%c@! I can hear Rauru's guidance! He's saying the %ykey for this door%c is in %w[[1]]%c!", /*german*/ TODO_TRANSLATE, - /*french*/ TODO_TRANSLATE, - {QM_GREEN, QM_RED})); + /*french*/ TODO_TRANSLATE)); hintTextTable[RHT_DAMPE_DIARY] = HintText(CustomMessage("Whoever reads this, please enter #[[1]]#. I will let you have my #stretching, shrinking keepsake#.^I'm waiting for you.&--Dampé", /*german*/ "Wer immer dies liest, der möge #[[1]]# nach meinem #langen, kurzen Schatz# suchen.^Ich warte!&Boris", @@ -2281,9 +2277,9 @@ void StaticData::HintTable_Init() { | Static Entrance Hint | ---------------------------*/ - hintTextTable[RHT_WARP_SONG] = HintText(CustomMessage("Warp to&#[[1]]#?&" + TWO_WAY_CHOICE() + "#OK&No#", - /*german*/ "Das Ziel liegt&#[[1]]#!&" + TWO_WAY_CHOICE() + "#Ja!&Nein!#", - /*french*/ "Se téléporter vers&#[[1]]#?&" + TWO_WAY_CHOICE() + "#OK!&Non#", + hintTextTable[RHT_WARP_SONG] = HintText(CustomMessage("Warp to&#[[1]]#?&" + CustomMessage::TWO_WAY_CHOICE() + "#OK&No#", + /*german*/ "Das Ziel liegt&#[[1]]#!&" + CustomMessage::TWO_WAY_CHOICE() + "#Ja!&Nein!#", + /*french*/ "Se téléporter vers&#[[1]]#?&" + CustomMessage::TWO_WAY_CHOICE() + "#OK!&Non#", {QM_RED, QM_GREEN})); /*-------------------------- diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp index c77441ee58..ce68ff495c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp @@ -131,6 +131,14 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Deku-Baum# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans l'Arbre Mojo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DEKU_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Deku Tree# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_DEKU_TREE] = HintText(CustomMessage("They say that a #wonder item in the Deku Tree# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Deku-Baum# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans l'Arbre Mojo# cache #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | DODONGOS CAVERN | ---------------------------*/ @@ -313,6 +321,14 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Dodongos Höhle# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans la Caverne Dodongo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DODONGOS_BOULDER] = HintText(CustomMessage("They say that a #boulder in Dodongo's Cavern# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_DODONGOS_CAVERN] = HintText(CustomMessage("They say that #reading a pedestal in Dodongo's Cavern# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Podests in Dodongos Höhle# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un piédestal dans la Caverne Dodongo# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | JABU JABUS BELLY | ---------------------------*/ @@ -480,6 +496,14 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Jabu-Jabus Bauch# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Ventre de Jabu-Jabu# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_JABU_BOULDER] = HintText(CustomMessage("They say that a #boulder in Jabu Jabu's Belly# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_JABU_JABU] = HintText(CustomMessage("They say that a #wonder item in Jabu Jabu's Belly# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in Jabu-Jabus Bauch# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Ventre de Jabu-Jabu# cache #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | FOREST TEMPLE | ---------------------------*/ @@ -922,6 +946,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Feuertempel# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Temple du Feu# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_WONDER_ITEM_FIRE_TEMPLE] = HintText(CustomMessage("They say that a #wonder item in Fire Temple# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Feuertempel# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Temple du Feu# cache #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | WATER TEMPLE | ---------------------------*/ @@ -1073,6 +1101,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Wassertempel# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Temple de l'Eau# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_WONDER_ITEM_WATER_TEMPLE] = HintText(CustomMessage("They say that a #wonder item in Water Temple# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Wassertempel# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Temple de l'Eau# cache #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | SPIRIT TEMPLE | ---------------------------*/ @@ -1330,6 +1362,18 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Geistertempel# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Temple de l'Esprit# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_SPIRIT_TEMPLE_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Spirit Temple# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_SPIRIT_TEMPLE] = HintText(CustomMessage("They say that #reading a statue in Spirit Temple# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen einer Statue im Geistertempel# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire une statue dans le Temple de l'Esprit# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_SPIRIT_TEMPLE] = HintText(CustomMessage("They say that a #wonder item in Spirit Temple# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Geistertempel# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Temple de l'Esprit# cache #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | SHADOW TEMPLE | ---------------------------*/ @@ -1597,6 +1641,14 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Schattentempel# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Temple de l'Ombre# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_SIGN_SHADOW_TEMPLE] = HintText(CustomMessage("They say that #reading a sign in Shadow Temple# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes im Schattentempel# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans le Temple de l'Ombre# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_SHADOW_TEMPLE] = HintText(CustomMessage("They say that a #wonder item in Shadow Temple# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Schattentempel# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Temple de l'Ombre# cache #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | BOTTOM OF THE WELL | ---------------------------*/ @@ -1743,6 +1795,13 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß etwas #Gras auf dem Grund des Brunnens# #[[1]]# verstecke.", /*french*/ "Selon moi, de l'#herbe dans le Puits# cache #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_BOTW_BOULDER] = HintText(CustomMessage("They say that a #boulder in Bottom of the Well# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM] = HintText(CustomMessage("They say that a #wonder item in the Bottom of the Well# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand auf dem Grund des Brunnens# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Puits# cache #[[1]]#.", {QM_RED, QM_GREEN})); /*-------------------------- | ICE CAVERN | @@ -1834,6 +1893,14 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*french*/ "Selon moi, #appeler la pluie près de l’entrée d’une grotte gelée# révèle #[[1]]#.", {QM_RED, QM_GREEN})); // /*spanish*/ Según dicen, una #Skulltula tras un ardiente hielo# otorga #[[1]]#. + hintTextTable[RHT_ICE_CAVERN_ICICLE] = HintText(CustomMessage("They say that #breaking an icicle in a frozen cavern# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Zerschlagen eines Eiszapfens in einer gefrorenen Kaverne# #[[1]]# enthülle.", + /*french*/ "Selon moi, #briser un stalactite de glace dans la Caverne Polaire# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ICE_CAVERN_RED_ICE] = HintText(CustomMessage("They say that #melting red ice in a frozen cavern# gives #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Schmelzen von rotem Eis in einer gefrorenen Kaverne# #[[1]]# gäbe.", + /*french*/ "Selon moi, #faire fondre la glace rouge dans la Caverne Polaire# donne #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | Gerudo Training Ground | ---------------------------*/ @@ -2024,6 +2091,18 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in der Gerudo-Trainingsarena# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Gymnase Gerudo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_WONDER_ITEM_GERUDO_TRAINING_GROUND] = HintText(CustomMessage("They say that a #wonder item in Gerudo Training Ground# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in der Gerudo-Trainingsarena# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Gymnase Gerudo# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_ICICLE] = HintText(CustomMessage("They say that #breaking an icicle in in Gerudo Training Ground# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Zerschlagen eines Eiszapfens in der Gerudo-Trainingsarena# #[[1]]# enthülle.", + /*french*/ "Selon moi, #briser un stalactite de glace dans le Gymnase Gerudo# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_RED_ICE] = HintText(CustomMessage("They say that #melting red ice in Gerudo Training Ground# gives #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Schmelzen von rotem Eis in der Gerudo-Trainingsarena# #[[1]]# gäbe.", + /*french*/ "Selon moi, #faire fondre la glace rouge dans le Gymnase Gerudo# donne #[[1]]#.", {QM_RED, QM_GREEN})); + /*-------------------------- | GANONS CASTLE | ---------------------------*/ @@ -2233,6 +2312,17 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß ein #Herz in Ganons Schloß# #[[1]]# verstecke.", /*french*/ "Selon moi, un #coeur dans le Château de Ganon# cache #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GANONS_CASTLE_WONDER_ITEM] = HintText(CustomMessage("They say that a #wonder item in Ganon's Castle# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in Ganons Schloß# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Château de Ganon# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GANONS_CASTLE_ICICLE] = HintText(CustomMessage("They say that #breaking an icicle in Ganon's Castle# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Zerschlagen eines Eiszapfens Ganons Schloß# #[[1]]# enthülle.", + /*french*/ "Selon moi, #briser un stalactite de glace dans le Château de Ganon# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GANONS_CASTLE_RED_ICE] = HintText(CustomMessage("They say that #melting red ice in a Ganon's Castle# gives #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Schmelzen von rotem Eis in Ganons Schloß# #[[1]]# gäbe.", + /*french*/ "Selon moi, #faire fondre la glace rouge dans le Château de Ganon# donne #[[1]]#.", {QM_RED, QM_GREEN})); // clang-format on } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index aca29a0146..fa53cea590 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -2102,39 +2102,381 @@ 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_KF_ROCK] = HintText(CustomMessage("They say that a #rock in Kokiri Forest# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ "Selon moi, une #roche dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Lost Woods# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_ROCK] = HintText(CustomMessage("They say that a #rock at Hyrule Castle# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_HC_BOULDER] = HintText(CustomMessage("They say that a #boulder at Hyrule Castle# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_OGC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder outside Ganon's Castle# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_OGC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder outside Ganon's Castle# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMC_ROCK] = HintText(CustomMessage("They say that a #rock in Death Mountain Crater# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Death Mountain Crater# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Death Mountain Crater# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GV_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_ROCK] = HintText(CustomMessage("They say that a #rock in Gerudo Valley# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_BOULDER] = HintText(CustomMessage("They say that a #boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_ROCK] = HintText(CustomMessage("They say that a #rock on Hyrule Field# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_BOULDER] = HintText(CustomMessage("They say that a #boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KAK_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder at Kakariko Village# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_KAK_ROCK] = HintText(CustomMessage("They say that a #rock at Kakariko Village# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GY_ROCK] = HintText(CustomMessage("They say that a #rock in a graveyard# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_ROCK] = HintText(CustomMessage("They say that a #rock at Lake Hylia# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZD_ROCK] = HintText(CustomMessage("They say that a #rock in Zora's Domain# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZF_BOULDER] = HintText(CustomMessage("They say that a #boulder in Zora's Fountain# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Zora's Fountain# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_ROCK] = HintText(CustomMessage("They say that a #rock along a river# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZR_BOULDER] = HintText(CustomMessage("They say that a #boulder along a river# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMT_ROCK] = HintText(CustomMessage("They say that a #rock on Death Mountain Trail# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_BOULDER] = HintText(CustomMessage("They say that a #boulder on Death Mountain Trail# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Death Mountain Trail# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_ROCK] = HintText(CustomMessage("They say that a #rock in Goron City# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Goron City# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Goron City# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Goron City# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + + hintTextTable[RHT_COLOSSUS_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in a desert# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_COLOSSUS_ROCK] = HintText(CustomMessage("They say that a #rock in a desert# contains #[[1]]#.", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_TREE_HYRULE_FIELD] = HintText(CustomMessage("They say that a #tree in Hyrule Field# contains #[[1]]#.", - /*german*/ "", + /*german*/ TODO_TRANSLATE, /*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*/ "", + /*german*/ TODO_TRANSLATE, /*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*/ "", + /*german*/ TODO_TRANSLATE, /*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*/ "", + /*german*/ TODO_TRANSLATE, /*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*/ "", + /*german*/ TODO_TRANSLATE, /*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*/ "", + /*german*/ TODO_TRANSLATE, /*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN })); hintTextTable[RHT_BUSH_HYRULE_FIELD] = HintText(CustomMessage("They say that a #bush in Hyrule Field# contains #[[1]]#.", - /*german*/ "", + /*german*/ TODO_TRANSLATE, /*french*/ "Selon moi, un #buisson dans la Plaine d'Hyrule# cache #[[1]]#.", { QM_RED, QM_GREEN })); hintTextTable[RHT_BUSH_ZORAS_FOUNTAIN] = HintText(CustomMessage("They say that a #bush in Zora's Fountain# contains #[[1]]#.", - /*german*/ "", + /*german*/ TODO_TRANSLATE, /*french*/ "Selon moi, un #buisson à la Fontaine Zora# cache #[[1]]#.", { QM_RED, QM_GREEN })); + + hintTextTable[RHT_BUTTERFLY_FAIRY_HYRULE_CASTLE] = HintText(CustomMessage("They say that a #butterfly near the castle# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling in der Nähe des Schlosses# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon près du château# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_LOST_WOODS] = HintText(CustomMessage("They say that a #butterfly in the woods# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling im Wald# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon dans les bois# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_GRAVEYARD] = HintText(CustomMessage("They say that a #butterfly in the graveyard# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling auf dem Friedhof# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon dans le cimetière# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_ZORAS_RIVER] = HintText(CustomMessage("They say that a #butterfly near a river# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling in der Nähe eines Flusses# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon près d'une rivière# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_ZORAS_FOUNTAIN] = HintText(CustomMessage("They say that a #butterfly on a log# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling auf einem Baumstamm# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon sur une bûche# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_LAKE_HYLIA] = HintText(CustomMessage("They say that a #butterfly near a lake# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling in der Nähe eines Sees# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon près d'un lac# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_KF_GROTTO] = HintText(CustomMessage("They say that a #butterfly in a forest village grotto# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling in einer Grotte des Walddorfes# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon dans une grotte du village de la forêt# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_LW_GROTTO] = HintText(CustomMessage("They say that a #butterfly underground in the woods# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling unterirdisch im Wald# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon sous terre dans les bois# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_DMT_GROTTO] = HintText(CustomMessage("They say that a #butterfly underground near a mountain village# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling unterirdisch nahe eines Bergdorfes# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon sous terre près d'un village de montagne# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_DMC_GROTTO] = HintText(CustomMessage("They say that a #butterfly underground in a crater# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling unterirdisch in einem Krater# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon sous terre dans un cratère# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_HF_GROTTO] = HintText(CustomMessage("They say that a #butterfly underground in a field# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling unterirdisch auf einem Feld# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon sous terre dans un champ# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_KAK_GROTTO] = HintText(CustomMessage("They say that a #butterfly underground in Kakariko# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling unterirdisch in Kakariko# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon sous terre dans Cocorico# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BUTTERFLY_FAIRY_ZR_GROTTO] = HintText(CustomMessage("They say that a #butterfly underground near a river# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schmetterling unterirdisch in der Nähe eines Flusses# #[[1]]# enthülle.", + /*french*/ "Selon moi, #un papillon sous terre près d'une rivière# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_KOKIRI_FOREST] = HintText(CustomMessage("They say that #reading a sign in a forest# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in einem Wald# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans un fôret# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_LINKS_HOUSE] = HintText(CustomMessage("They say that #reading a sign in Link's House# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in Links Haus# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans la Maison de Link# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_DEKU_THEATER] = HintText(CustomMessage("They say that #reading a sign in an underground theater# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in einem unterirdischen Theater# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans un théâtre souterrain# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_HYRULE_FIELD] = HintText(CustomMessage("They say that #reading a sign in an underground theater# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in der Ebene von Hyrule# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans la Plaine d'Hyrule# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_MK_SHOOTING_GALLERY] = HintText(CustomMessage("They say that #reading before shooting in youth# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen vor dem Schießen in der Jugend# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire avant de tirer dans sa jeunesse# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_KAK_SHOOTING_GALLERY] = HintText(CustomMessage("They say that #reading before shooting in maturity# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen vor dem Schießen im Erwachsenenalter# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire avant de tirer dans sa maturité# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_HAPPY_MASK_SHOP] = HintText(CustomMessage("They say that #reading a sign in a mask shop# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in einem Maskenladen# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans un magasin de masques# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_TEMPLE_OF_TIME] = HintText(CustomMessage("They say that #reading a sign in a mask shop# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Altars im Tempel der Zeit# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un autel dans le Temple du Temps# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_HYRULE_CASTLE] = HintText(CustomMessage("They say that #reading a sign near the castle# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in der Nähe des Schloßes# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau rès du château# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_KAKARIKO_VILLAGE] = HintText(CustomMessage("They say that #reading a sign in Kakariko Village# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in Kakariko# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans le Village de Cocorico# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_GRAVEYARD] = HintText(CustomMessage("They say that #reading in the graveyard# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen auf dem Friedhof# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire dans le cimetière# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_DEATH_MOUNTAIN_TRAIL] = HintText(CustomMessage("They say that #reading a sign on Death Mountain Trail# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes auf dem Todesberggipfel-Pfad# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau sur le sentier de la Montagne de la Mort# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_GORON_CITY] = HintText(CustomMessage("They say that #reading a sign in Goron City# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in Goronia# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans le Village Goron# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_DEATH_MOUNTAIN_CRATER] = HintText(CustomMessage("They say that #reading a sign in Death Mountain Crater# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes im Todeskrater# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau sur le Mont du Péril# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_ZORAS_RIVER] = HintText(CustomMessage("They say that #reading a sign near a river# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in der Nähe eines Flusses# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau près d'une rivière# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_ZORAS_DOMAIN] = HintText(CustomMessage("They say that #reading a sign in Zora's Domain# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in Zoras Reich# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans le Domaine Zora# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_ZORAS_FOUNTAIN] = HintText(CustomMessage("They say that #reading a sign in Zora's Fountain# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in Zoras Quelle# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans la Fontaine Zora# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_LAKE_HYLIA] = HintText(CustomMessage("They say that #reading near a lake# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen in der Nähe eines Sees# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire près d'un lac# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_FISHING_POND] = HintText(CustomMessage("They say that #reading a sign in a fishing pond# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in einem Fischteich# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans un étang de pêche# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_GERUDO_VALLEY] = HintText(CustomMessage("They say that #reading a sign in Gerudo Valley# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes im Gerudotalh# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans une vallée# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_GERUDO_FORTRESS] = HintText(CustomMessage("They say that #reading a sign in Gerudo Fortress# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in der Gerudo-Festung# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans la Forteresse Gerudo# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SIGN_HAUNTED_WASTELAND] = HintText(CustomMessage("They say that #reading a sign in Haunted Wasteland# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Lesen eines Schildes in der Gespensterwüste# #[[1]]# enthülle.", + /*french*/ "Selon moi, #lire un panneau dans le Désert Hanté# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_KOKIRI_FOREST] = HintText(CustomMessage("They say that a #wonder item in Kokiri Forest# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Kokiri-Wald# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans la Fôret Kokiri# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_HYRULE_FIELD] = HintText(CustomMessage("They say that a #wonder item in Hyrule Field# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in der Ebene von Hyrule# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans la Plaine d'Hyrule# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_MARKET] = HintText(CustomMessage("They say that a #wonder item in the Market# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand auf dem Markt# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans la Place du Marché# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_LON_LON_RANCH] = HintText(CustomMessage("They say that a #wonder item in Lon Lon Ranch# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand auf der Lon Lon-Farm# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Ranch Lon Lon# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_HYRULE_CASTLE] = HintText(CustomMessage("They say that a #wonder item in Hyrule Castle# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Schloss von Hyrule# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux au Château d'Hyrule# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_CASTLE_COURTYARD_ZELDA] = HintText(CustomMessage("They say that #shooting a window in a castle# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Schießen auf ein Fenster in einem Schloss# #[[1]]# enthülle.", + /*french*/ "Selon moi, #tirer sur une fenêtre dans un château# donne #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_LOST_WOODS] = HintText(CustomMessage("They say that a #wonder item in the woods# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in den Wäldern# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans des bois# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_SACRED_FOREST_MEADOW] = HintText(CustomMessage("They say that a #wonder item in a forest meadow# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand auf einer Waldlichtung# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le sanctuaire des bois# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_KAKARIKO_VILLAGE] = HintText(CustomMessage("They say that a #wonder item in Kakariko Village# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in Kakariko# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans le Village de Cocorico# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_DAMPES_GRAVE] = HintText(CustomMessage("They say that a #wonder item in a gravekeeper's tomb# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Grab des Totengräbers# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans la tombe du fossoyeur# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_DEATH_MOUNTAIN_CRATER] = HintText(CustomMessage("They say that a #wonder item in Death Mountain's Crater# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Todeskrater# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux sur le Mont du Péril# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_ZORAS_RIVER] = HintText(CustomMessage("They say that a #wonder item in a river# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in einem Fluss# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans une rivière# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_ZORAS_RIVER] = HintText(CustomMessage("They say that a #wonder item in Zora's Fountain# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in Zoras Quelle# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans la Fontaine Zora# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_GERUDO_VALLEY] = HintText(CustomMessage("They say that a #wonder item in Gerudo Valley# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Gerudotal# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans une vallée# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_GERUDOS_FORTRESS] = HintText(CustomMessage("They say that a #wonder item in Gerudo Fortress# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand in der Gerudo-Festung# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans la Forteresse Gerudo# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_THIEVES_HIDEOUT] = HintText(CustomMessage("They say that a #wonder item in Thieve's Hideout# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand im Versteck der Diebe# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux dans a Cachette des Voleurs# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WONDER_ITEM_DESERT_COLOSSUS] = HintText(CustomMessage("They say that a #wonder item near the temple of the sand# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand nahe des Tempels des Sandes# #[[1]]# verstecke.", + /*french*/ "Selon moi, un #objet merveilleux près du temple du sable# cache #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BEGGAR_MARKET] = HintText(CustomMessage("They say that #trading with a beggar in the market# gives #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Handeln mit einem Bettler auf dem Markt# #[[1]]# gäbe.", + /*french*/ "Selon moi, #échanger avec un mendiant sur le marché# donne #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BEGGAR_KAKARIKO_VILLAGE] = HintText(CustomMessage("They say that #trading with a beggar in Kakariko Village# gives #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Handeln mit einem Bettler in Kakariko# #[[1]]# gäbe.", + /*french*/ "Selon moi, #échanger avec un mendiant dans le Village de Cocorico# donne #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_RED_ICE_ZORAS_DOMAIN] = HintText(CustomMessage("They say that #melting red ice in Zora's Domain# gives #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Schmelzen von rotem Eis in Zoras Reich# #[[1]]# gäbe.", + /*french*/ "Selon moi, #faire fondre la glace rouge dans le Domaine Zora# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // clang-format on } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 5783be19ca..2b2fd83f10 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -1964,11 +1964,11 @@ void StaticData::HintTable_Init_Item() { CustomMessage("a gold fragment", /*german*/"ein Goldfragment", /*french*/"un fragment d'or")}); // /*spanish*/un fragmento dorado - hintTextTable[RHT_ROCS_FEATHER] = HintText(CustomMessage("Roc's Feather", /*german*/"Roc's Feather", /*french*/"Roc's Feather"), + hintTextTable[RHT_ROCS_FEATHER] = HintText(CustomMessage("Roc's Feather", /*german*/"Greifenfeder", /*french*/"Plume de Roc"), {}, { - CustomMessage("a feather", /*german*/"a feather", /*french*/"a feather"), - CustomMessage("a chicken wing", /*german*/"a chicken wing", /*french*/"a chicken wing"), - CustomMessage("a blue wing", /*german*/"a blue wing", /*french*/"a blue wing")}); + CustomMessage("a feather", /*german*/TODO_TRANSLATE, /*french*/"une plume"), + CustomMessage("a chicken wing", /*german*/TODO_TRANSLATE, /*french*/"une aile de poulet"), + CustomMessage("a blue wing", /*german*/TODO_TRANSLATE, /*french*/"une aile bleue")}); hintTextTable[RHT_BEAN_SOUL] = HintText(CustomMessage("a bean soul", /*german*/"eine bohnenseele", /*french*/"une âme de haricot")); diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index 8c3c425e8d..b5f0935173 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -211,117 +211,87 @@ const std::array hintSettingTable{{ }, }}; -uint8_t StonesRequiredBySettings() { - auto ctx = Rando::Context::GetInstance(); - uint8_t stones = 0; - if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) { - stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get(); - } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { - stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get() - 6; - } else if ((ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) && - (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON))) { - stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - 6; - } - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { - stones = std::max({ stones, ctx->GetOption(RSK_LACS_STONE_COUNT).Get() }); - } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { - stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 6) }); - } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) && - ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { - stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 6) }); - } - return stones; -} +struct BridgeReqConfig { + RandomizerSettingKey bridgeDirectKey; + RandomizerSettingKey lacsDirectKey; + RandoOptionRainbowBridge bridgeEnum; + RandoOptionGanonsBossKey lacsEnum; + uint8_t offset; +}; -uint8_t MedallionsRequiredBySettings() { +static constexpr BridgeReqConfig StonesConfig{ RSK_RAINBOW_BRIDGE_STONE_COUNT, RSK_LACS_STONE_COUNT, RO_BRIDGE_STONES, + RO_GANON_BOSS_KEY_LACS_STONES, 6 }; +static constexpr BridgeReqConfig MedallionsConfig{ RSK_RAINBOW_BRIDGE_MEDALLION_COUNT, RSK_LACS_MEDALLION_COUNT, + RO_BRIDGE_MEDALLIONS, RO_GANON_BOSS_KEY_LACS_MEDALLIONS, 3 }; +static constexpr BridgeReqConfig TokensConfig{ RSK_RAINBOW_BRIDGE_TOKEN_COUNT, RSK_LACS_TOKEN_COUNT, RO_BRIDGE_TOKENS, + RO_GANON_BOSS_KEY_LACS_TOKENS, 0 }; + +static uint8_t RequiredBySettings(const BridgeReqConfig& cfg) { auto ctx = Rando::Context::GetInstance(); - uint8_t medallions = 0; - if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS)) { - medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get(); + uint8_t count = 0; + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(cfg.bridgeEnum)) { + count = ctx->GetOption(cfg.bridgeDirectKey).Get(); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { - medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get() - 3; + count = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get() - cfg.offset; } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { - medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - 3; + count = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - cfg.offset; } - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) { - medallions = std::max(medallions, ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get()); + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(cfg.lacsEnum)) { + count = std::max(count, ctx->GetOption(cfg.lacsDirectKey).Get()); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { - medallions = std::max(medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 3)); + count = std::max(count, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - cfg.offset)); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { - medallions = std::max(medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 3)); + count = std::max(count, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - cfg.offset)); } - return medallions; + return count; } -uint8_t TokensRequiredBySettings() { - auto ctx = Rando::Context::GetInstance(); - uint8_t tokens = 0; - if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { - tokens = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get(); - } - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { - tokens = std::max(tokens, ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get()); - } - return tokens; +static uint8_t StonesRequiredBySettings() { + return RequiredBySettings(StonesConfig); +} +static uint8_t MedallionsRequiredBySettings() { + return RequiredBySettings(MedallionsConfig); +} +static uint8_t TokensRequiredBySettings() { + return RequiredBySettings(TokensConfig); } -std::vector>> conditionalAlwaysHints = { - std::make_pair(RC_MARKET_10_BIG_POES, - []() { - auto ctx = Rando::Context::GetInstance(); - return ctx->GetOption(RSK_BIG_POE_COUNT).Get() > 3 && !ctx->GetOption(RSK_BIG_POES_HINT); - }), - std::make_pair(RC_DEKU_THEATER_MASK_OF_TRUTH, - []() { - auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_MASK_SHOP_HINT) && !ctx->GetOption(RSK_MASK_QUEST); - }), - std::make_pair(RC_SONG_FROM_OCARINA_OF_TIME, - []() { - auto ctx = Rando::Context::GetInstance(); - return StonesRequiredBySettings() < 2 && !ctx->GetOption(RSK_OOT_HINT); - }), - std::make_pair(RC_HF_OCARINA_OF_TIME_ITEM, []() { return StonesRequiredBySettings() < 2; }), - std::make_pair(RC_SHEIK_IN_KAKARIKO, []() { return MedallionsRequiredBySettings() < 5; }), - std::make_pair(RC_DMT_TRADE_CLAIM_CHECK, - []() { - auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_BIGGORON_HINT); - }), - std::make_pair(RC_KAK_30_GOLD_SKULLTULA_REWARD, - []() { - auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_KAK_30_SKULLS_HINT) && TokensRequiredBySettings() < 30; - }), - std::make_pair(RC_KAK_40_GOLD_SKULLTULA_REWARD, - []() { - auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_KAK_40_SKULLS_HINT) && TokensRequiredBySettings() < 40; - }), - std::make_pair(RC_KAK_50_GOLD_SKULLTULA_REWARD, - []() { - auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_KAK_50_SKULLS_HINT) && TokensRequiredBySettings() < 50; - }), - std::make_pair(RC_ZR_FROGS_OCARINA_GAME, - []() { - auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_FROGS_HINT); - }), - std::make_pair(RC_KF_LINKS_HOUSE_COW, - []() { - auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_MALON_HINT); - }), - std::make_pair(RC_KAK_100_GOLD_SKULLTULA_REWARD, - []() { - auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_KAK_100_SKULLS_HINT) && TokensRequiredBySettings() < 100; - }), +// An 'always' hint that only applies under certain settings. Suppressed when the user +// has enabled `dedicatedHint` (since a dedicated hint renders the gossip-stone hint redundant), +// or when `extra` is present and returns false. RSK_NONE in `dedicatedHint` means no suppression. +struct ConditionalAlwaysHint { + RandomizerCheck loc; + RandomizerSettingKey dedicatedHint; + std::function extra; }; +std::vector conditionalAlwaysHints = { + // clang-format off + { RC_MARKET_10_BIG_POES, RSK_BIG_POES_HINT, []() { return Rando::Context::GetInstance()->GetOption(RSK_BIG_POE_COUNT).Get() > 3; } }, + { RC_DEKU_THEATER_MASK_OF_TRUTH, RSK_MASK_SHOP_HINT, []() { return !Rando::Context::GetInstance()->GetOption(RSK_MASK_QUEST); } }, + { RC_SONG_FROM_OCARINA_OF_TIME, RSK_OOT_HINT, []() { return StonesRequiredBySettings() < 2; } }, + { RC_HF_OCARINA_OF_TIME_ITEM, RSK_OOT_HINT, []() { return StonesRequiredBySettings() < 2; } }, + { RC_SHEIK_IN_KAKARIKO, RSK_NONE, []() { return MedallionsRequiredBySettings() < 5; } }, + { RC_DMT_TRADE_CLAIM_CHECK, RSK_BIGGORON_HINT, nullptr }, + { RC_KAK_30_GOLD_SKULLTULA_REWARD, RSK_KAK_30_SKULLS_HINT, []() { return TokensRequiredBySettings() < 30; } }, + { RC_KAK_40_GOLD_SKULLTULA_REWARD, RSK_KAK_40_SKULLS_HINT, []() { return TokensRequiredBySettings() < 40; } }, + { RC_KAK_50_GOLD_SKULLTULA_REWARD, RSK_KAK_50_SKULLS_HINT, []() { return TokensRequiredBySettings() < 50; } }, + { RC_ZR_FROGS_OCARINA_GAME, RSK_FROGS_HINT, nullptr }, + { RC_KF_LINKS_HOUSE_COW, RSK_MALON_HINT, nullptr }, + { RC_KAK_100_GOLD_SKULLTULA_REWARD, RSK_KAK_100_SKULLS_HINT, []() { return TokensRequiredBySettings() < 100; } }, + // clang-format on +}; + +static bool ConditionalAlwaysHintApplies(const ConditionalAlwaysHint& h) { + auto ctx = Rando::Context::GetInstance(); + if (h.dedicatedHint != RSK_NONE && ctx->GetOption(h.dedicatedHint)) { + return false; + } + return !h.extra || h.extra(); +} + static std::vector GetEmptyGossipStones() { auto emptyGossipStones = GetEmptyLocations(Rando::StaticData::GetGossipStoneLocations()); return emptyGossipStones; @@ -466,13 +436,6 @@ static std::vector FilterHintability(std::vector 0) { auto ctx = Rando::Context::GetInstance(); @@ -534,101 +497,106 @@ void CreateWarpSongTexts() { } } -int32_t getRandomWeight(int32_t totalWeight) { - if (totalWeight <= 1) { - return 1; - } - return Random(1, totalWeight); +static int32_t getRandomWeight(uint32_t totalWeight) { + return totalWeight <= 1 ? 1 : Random(1, totalWeight); } -static void DistributeHints(std::vector& selected, size_t stoneCount, - std::vector distTable, uint8_t junkWieght, bool addFixed = true) { - int32_t totalWeight = junkWieght; // Start with our Junk Weight, the natural chance of a junk hint - - for (size_t c = 0; c < distTable.size(); - c++) { // Gather the weights of each distribution and, if it's the first pass, apply fixed hints - totalWeight += distTable[c].weight; // Note that PlaceHints will set weights of distributions to zero if it - // can't place anything from them - if (addFixed) { - selected[c] += distTable[c].fixed; - stoneCount -= distTable[c].fixed * distTable[c].copies; - } - } - int32_t currentWeight = getRandomWeight(totalWeight); // Initialise with the first random weight from 1 to the - // total. - while (stoneCount > 0 && - totalWeight > - 0) { // Loop until we run out of stones or have no TotalWeight. 0 totalWeight means junkWeight is 0 - // and that all weights have been 0'd out for another reason, and skips to placing all junk hints - for (size_t distribution = 0; distribution < distTable.size(); distribution++) { - currentWeight -= - distTable[distribution] - .weight; // go over each distribution, subtracting the weight each time. Once we reach zero or less, - if (currentWeight <= 0) { // tell the system to make 1 of that hint, unless not enough stones remain - if (stoneCount >= distTable[distribution].copies && distTable[distribution].copies > 0) { - selected[distribution] += 1; // if we have enough stones, and copies are not zero, assign 1 to this - // hint type, remove the stones, and break - stoneCount -= distTable[distribution].copies; - break; // This leaves the whole for loop - } else { // If we don't have the stones, or copies is 0 despite there being the wieght to trigger a hit, - // temporerally set wieght to zero - totalWeight -= - distTable[distribution] - .weight; // Unlike PlaceHint, distTable is passed by value here, making this temporary - distTable[distribution].weight = - 0; // this is so we can still roll this hint type if more stones free up later - break; - } - } - } - // if there's still weight then it's junk, as the leftover weight is junkWeight - if (currentWeight > - 0) { // zero TotalWeight breaks the while loop and hits the fallback, so skipping this is fine in that case - selected[selected.size() - 1] += 1; - stoneCount -= 1; - } - currentWeight = getRandomWeight(totalWeight); - } - // if stones are left, assign junk to every remaining stone as a fallback. - if (stoneCount > 0) { - selected[static_cast(selected.size()) - 1] += static_cast(stoneCount); - } -} - -uint8_t PlaceHints(std::vector& selectedHints, std::vector& distTable) { +static void DistributeAndPlaceHints(std::vector& distTable, size_t totalStones) { auto ctx = Rando::Context::GetInstance(); - uint8_t curSlot = 0; - for (HintDistributionSetting distribution : distTable) { - std::vector hintTypePool = FilterHintability(ctx->allLocations, distribution.filter); - for (uint8_t numHint = 0; numHint < selectedHints[curSlot]; numHint++) { - hintTypePool = FilterHintability(hintTypePool); - SPDLOG_DEBUG("Attempting to make hint of type: {}", - StaticData::hintTypeNames[distribution.type].GetEnglish(MF_CLEAN)); - RandomizerCheck hintedLocation = RC_UNKNOWN_CHECK; + const uint8_t junkIdx = distTable.size(); - hintedLocation = CreateRandomHint(hintTypePool, distribution.copies, distribution.type, distribution.name); - - if (hintedLocation == RC_UNKNOWN_CHECK) { // if hint failed to place, remove all wieght and copies then - // return the number of stones to redistribute - uint8_t hintsToRemove = (selectedHints[curSlot] - numHint) * distribution.copies; - selectedHints[curSlot] = 0; // as distTable is passed by refernce here, these changes stick for the rest - // of this seed generation - distTable[curSlot].copies = 0; // and prevent future distribution from choosing this slot - distTable[curSlot].weight = 0; - return hintsToRemove; + // Apply fixed hints upfront (they don't participate in weighted selection) + for (size_t i = 0; i < distTable.size(); i++) { + if (distTable[i].fixed == 0) { + continue; + } + uint8_t placed = 0; + for (uint8_t c = 0; c < distTable[i].fixed; c++) { + std::vector hintPool = FilterHintability(ctx->allLocations, distTable[i].filter); + SPDLOG_DEBUG("Attempting fixed hint of type: {}", + StaticData::hintTypeNames[distTable[i].type].GetEnglish(MF_CLEAN)); + RandomizerCheck fixedLoc = + CreateRandomHint(hintPool, distTable[i].copies, distTable[i].type, distTable[i].name); + if (fixedLoc == RC_UNKNOWN_CHECK) { + distTable[i].weight = 0; + distTable[i].copies = 0; + break; } - if (Rando::StaticData::GetLocation(hintedLocation)->IsDungeon()) { - distribution.dungeonLimit -= 1; - if (distribution.dungeonLimit == 0) { - FilterFromPool(hintTypePool, FilterOverworldLocations); + placed++; + if (Rando::StaticData::GetLocation(fixedLoc)->IsDungeon()) { + distTable[i].dungeonLimit -= 1; + if (distTable[i].dungeonLimit == 0) { + hintPool = FilterFromPool(hintPool, FilterOverworldLocations); } } } - selectedHints[curSlot] = 0; - curSlot += 1; + totalStones -= placed * distTable[i].copies; + } + + while (totalStones > 0) { + // Pick a weighted distribution type (junk included) + uint32_t totalWeight = 0; + for (size_t i = 0; i < distTable.size(); i++) { + totalWeight += distTable[i].weight; + } + + // No weighted types left, fill remaining with junk + if (totalWeight == 0) { + for (size_t c = 0; c < totalStones; c++) { + // duplicate junk hints are possible for now + AddGossipStoneHintCopies(1, HINT_TYPE_HINT_KEY, "Junk", { GetRandomJunkHint() }); + } + return; + } + + uint32_t roll = getRandomWeight(totalWeight); + uint32_t cursor = 0; + uint8_t chosenType = junkIdx; + for (size_t i = 0; i < distTable.size(); i++) { + cursor += distTable[i].weight; + if (roll <= cursor) { + chosenType = static_cast(i); + break; + } + } + + if (chosenType == junkIdx) { + AddGossipStoneHintCopies(1, HINT_TYPE_HINT_KEY, "Junk", { GetRandomJunkHint() }); + totalStones -= 1; + continue; + } + + auto& dist = distTable[chosenType]; + + // Need at least `copies` stones to place one instance of this type + if (dist.copies == 0 || totalStones < dist.copies) { + dist.weight = 0; + dist.copies = 0; + continue; + } + + // Build hint pool and attempt placement + std::vector hintPool = FilterHintability(ctx->allLocations, dist.filter); + SPDLOG_DEBUG("Attempting to make hint of type: {}", StaticData::hintTypeNames[dist.type].GetEnglish(MF_CLEAN)); + + RandomizerCheck hintedLocation = CreateRandomHint(hintPool, dist.copies, dist.type, dist.name); + if (hintedLocation == RC_UNKNOWN_CHECK) { + // Placement failed, disable this type entirely + dist.weight = 0; + dist.copies = 0; + continue; + } + + // Track dungeon limit + if (Rando::StaticData::GetLocation(hintedLocation)->IsDungeon()) { + dist.dungeonLimit -= 1; + if (dist.dungeonLimit == 0) { + hintPool = FilterFromPool(hintPool, FilterOverworldLocations); + } + } + + totalStones -= dist.copies; } - CreateJunkHints(selectedHints[selectedHints.size() - 1]); - return 0; } void CreateStoneHints() { @@ -661,10 +629,9 @@ void CreateStoneHints() { } } - for (auto& hint : conditionalAlwaysHints) { - RandomizerCheck loc = hint.first; - if (hint.second() && ctx->GetItemLocation(loc)->IsHintable()) { - alwaysHintLocations.push_back(loc); + for (const auto& hint : conditionalAlwaysHints) { + if (ConditionalAlwaysHintApplies(hint) && ctx->GetItemLocation(hint.loc)->IsHintable()) { + alwaysHintLocations.push_back(hint.loc); } } @@ -679,16 +646,8 @@ void CreateStoneHints() { } size_t totalStones = GetEmptyGossipStones().size(); - std::vector selectedHints; - selectedHints.resize(distTable.size() + 1); - DistributeHints(selectedHints, totalStones, distTable, hintSetting.junkWeight); - - while (totalStones != 0) { - totalStones = PlaceHints(selectedHints, distTable); - if (totalStones != 0) { - DistributeHints(selectedHints, totalStones, distTable, hintSetting.junkWeight, false); - } - } + distTable.push_back({ "Junk", HINT_TYPE_HINT_KEY, hintSetting.junkWeight, 0, 1, NoFilter }); + DistributeAndPlaceHints(distTable, totalStones); // Getting gossip stone locations temporarily sets one location to not be reachable. // Call the function one last time to get rid of false positives on locations not @@ -719,55 +678,40 @@ std::vector FindItemsAndMarkHinted(std::vector i return locations; } -void CreateChildAltarHint() { +static void CreateAltarHint(RandomizerHint hintKey, HintType hintType, std::vector rewards, + RandomizerCheck altarCheck) { auto ctx = Rando::Context::GetInstance(); - if (!ctx->GetHint(RH_ALTAR_CHILD)->IsEnabled()) { - std::vector stoneLocs = {}; - std::vector stoneAreas = {}; - if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { - // force marking the rewards as hinted if they are at the end of dungeons as they can be inferred - if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || - ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { - stoneLocs = FindItemsAndMarkHinted({ RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE }, {}); - } else { - stoneLocs = FindItemsAndMarkHinted({ RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE }, - { RC_ALTAR_HINT_CHILD }); - } - for (auto loc : stoneLocs) { - if (loc != RC_UNKNOWN_CHECK) { - stoneAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); - } + if (ctx->GetHint(hintKey)->IsEnabled()) { + return; + } + std::vector locs = {}; + std::vector areas = {}; + if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { + // force marking the rewards as hinted if they are at the end of dungeons as they can be inferred + const bool rewardsInferrable = + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA); + locs = FindItemsAndMarkHinted(rewards, rewardsInferrable ? std::vector{} + : std::vector{ altarCheck }); + for (auto loc : locs) { + if (loc != RC_UNKNOWN_CHECK) { + areas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); } } - ctx->AddHint(RH_ALTAR_CHILD, Hint(RH_ALTAR_CHILD, HINT_TYPE_ALTAR_CHILD, {}, stoneLocs, stoneAreas)); } + ctx->AddHint(hintKey, Hint(hintKey, hintType, {}, locs, areas)); +} + +void CreateChildAltarHint() { + CreateAltarHint(RH_ALTAR_CHILD, HINT_TYPE_ALTAR_CHILD, { RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE }, + RC_ALTAR_HINT_CHILD); } void CreateAdultAltarHint() { - auto ctx = Rando::Context::GetInstance(); - if (!ctx->GetHint(RH_ALTAR_ADULT)->IsEnabled()) { - std::vector medallionLocs = {}; - std::vector medallionAreas = {}; - if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { - // force marking the rewards as hinted if they are at the end of dungeons as they can be inferred - if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || - ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { - medallionLocs = FindItemsAndMarkHinted({ RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, - RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION }, - {}); - } else { - medallionLocs = FindItemsAndMarkHinted({ RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, - RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION }, - { RC_ALTAR_HINT_ADULT }); - } - for (auto loc : medallionLocs) { - if (loc != RC_UNKNOWN_CHECK) { - medallionAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); - } - } - } - ctx->AddHint(RH_ALTAR_ADULT, Hint(RH_ALTAR_ADULT, HINT_TYPE_ALTAR_ADULT, {}, medallionLocs, medallionAreas)); - } + CreateAltarHint(RH_ALTAR_ADULT, HINT_TYPE_ALTAR_ADULT, + { RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, RG_WATER_MEDALLION, + RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION }, + RC_ALTAR_HINT_ADULT); } void CreateStaticHintFromData(RandomizerHint hint, StaticHintInfo staticData) { diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.hpp b/soh/soh/Enhancements/randomizer/3drando/hints.hpp index 365904274f..d9cd86879d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.hpp @@ -4,8 +4,6 @@ #include #include -#include "text.hpp" -#include "random.hpp" #include #include "../randomizerTypes.h" #include "../../custom-message/CustomMessageManager.h" diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 4e6101301e..97f06fd129 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -303,7 +303,7 @@ void GenerateItemPool() { ctx->PlaceItemInLocation(RC_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, false, true); } - bool rewardIceTraps = ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Get() >= RO_DUNGEON_REWARDS_ANY_DUNGEON; + bool rewardIceTraps = ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Get() >= RO_DUNGEON_REWARDS_OWN_DUNGEON; AddFixedItemToPool(RG_KOKIRI_EMERALD, 1, rewardIceTraps); AddFixedItemToPool(RG_GORON_RUBY, 1, rewardIceTraps); AddFixedItemToPool(RG_ZORA_SAPPHIRE, 1, rewardIceTraps); @@ -436,6 +436,27 @@ void GenerateItemPool() { ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); PlaceItemsForType(RCTYPE_POT, overworldPotsActive, dungeonPotsActive); + // 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 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, ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && overworldCratesActive, + ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && dungeonCratesActive); + PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); + + // Shuffle Rocks + bool rocksActive = ctx->GetOption(RSK_SHUFFLE_ROCKS).Get(); + PlaceItemsForType(RCTYPE_ROCK, rocksActive, rocksActive); + + // Shuffle Boulders + bool overworldBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); + bool dungeonBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); + PlaceItemsForType(RCTYPE_BOULDER, overworldBouldersActive, dungeonBouldersActive); + // Shuffle Trees bool treesActive = (bool)ctx->GetOption(RSK_SHUFFLE_TREES); PlaceItemsForType(RCTYPE_TREE, treesActive, false); @@ -447,15 +468,12 @@ void GenerateItemPool() { bool bushesActive = (bool)ctx->GetOption(RSK_SHUFFLE_BUSHES); PlaceItemsForType(RCTYPE_BUSH, bushesActive, 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 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, ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && overworldCratesActive, - ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && dungeonCratesActive); - PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); + // Shuffle Wonder Items + bool overworldWonderItemsActive = ctx->GetOption(RSK_SHUFFLE_WONDER_ITEMS).Is(RO_SHUFFLE_WONDER_ITEMS_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_WONDER_ITEMS).Is(RO_SHUFFLE_WONDER_ITEMS_ALL); + bool dungeonWonderItemsActive = ctx->GetOption(RSK_SHUFFLE_WONDER_ITEMS).Is(RO_SHUFFLE_WONDER_ITEMS_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_WONDER_ITEMS).Is(RO_SHUFFLE_WONDER_ITEMS_ALL); + PlaceItemsForType(RCTYPE_WONDER_ITEM, overworldWonderItemsActive, dungeonWonderItemsActive); if (ctx->GetOption(RSK_FISHSANITY).Is(RO_FISHSANITY_HYRULE_LOACH)) { AddFixedItemToPool(RG_PURPLE_RUPEE, 1); @@ -490,6 +508,10 @@ void GenerateItemPool() { ctx->PlaceItemInLocation(RC_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, false, true); } + // Shuffle Beggar + bool beggarActive = (bool)ctx->GetOption(RSK_SHUFFLE_BEGGAR); + PlaceItemsForType(RCTYPE_BEGGAR, beggarActive, false); + if (ctx->GetOption(RSK_SHUFFLE_FROG_SONG_RUPEES)) { AddFixedItemToPool(RG_PURPLE_RUPEE, 5); } else { @@ -593,7 +615,7 @@ void GenerateItemPool() { ctx->PlaceItemInLocation(RC_TH_DEAD_END_CARPENTER, RG_RECOVERY_HEART, false, true); ctx->PlaceItemInLocation(RC_TH_DOUBLE_CELL_CARPENTER, RG_RECOVERY_HEART, false, true); ctx->PlaceItemInLocation(RC_TH_STEEP_SLOPE_CARPENTER, RG_RECOVERY_HEART, false, true); - + ctx->PlaceItemInLocation(RC_TH_FREED_CARPENTERS, RG_BLUE_RUPEE, false, true); } else if (ctx->GetOption(RSK_GERUDO_KEYS).IsNot(RO_GERUDO_KEYS_VANILLA)) { if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST)) { AddItemToPool(RG_GERUDO_FORTRESS_SMALL_KEY, 2, 1, 1, 1); @@ -608,7 +630,6 @@ void GenerateItemPool() { AddItemToPool(RG_GERUDO_FORTRESS_SMALL_KEY, 5, 4, 4, 4); } } - } else { if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST)) { ctx->PlaceItemInLocation(RC_TH_1_TORCH_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); @@ -626,9 +647,6 @@ void GenerateItemPool() { // Gerudo Membership Card if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { AddItemToPool(RG_GERUDO_MEMBERSHIP_CARD, 2, 1, 1, 1); - if (ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_CARPENTERS_FREE)) { - ctx->PlaceItemInLocation(RC_TH_FREED_CARPENTERS, RG_BLUE_RUPEE, false, true); - } } else { ctx->PlaceItemInLocation(RC_TH_FREED_CARPENTERS, RG_GERUDO_MEMBERSHIP_CARD, false, true); } diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index 35f21ce20d..a0886da62f 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -1,15 +1,7 @@ -#include -#include -#include -#include -#include -#include - #include "menu.hpp" #include "playthrough.hpp" -#include "spoiler_log.hpp" -#include "../location_access.h" #include "soh/Enhancements/debugger/performanceTimer.h" +#include "soh/ShipUtils.h" #include #include "../../randomizer/randomizerTypes.h" @@ -26,10 +18,14 @@ bool GenerateRandomizer(std::set excludedLocations, std::set(time(NULL))); // if a blank seed was entered, make a random one if (seedInput.empty()) { - seedInput = std::to_string(rand()); + char seedString[11]; + for (size_t i = 0; i < 10; i++) { + seedString[i] = '0' + ShipUtils::Random(0, 10); + } + seedString[10] = '\0'; + seedInput = std::string(seedString); } else if (seedInput.rfind("seed_testing_count", 0) == 0 && seedInput.length() > 18) { int count; try { diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.hpp b/soh/soh/Enhancements/randomizer/3drando/menu.hpp index b40c97c2da..767472b1d4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include "soh/Enhancements/randomizer/randomizerTypes.h" diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index b6a3aeed9e..6b58bc8019 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -94,7 +94,12 @@ int Playthrough_Repeat(std::set excludedLocations, std::setSetSeedString(std::to_string(rand())); + char seedString[11]; + for (size_t i = 0; i < 10; i++) { + seedString[i] = '0' + ShipUtils::Random(0, 10); + } + seedString[10] = '\0'; + ctx->SetSeedString(std::string(seedString)); repeatedSeed = SohUtils::Hash(ctx->GetSeedString()); ctx->SetSeed(repeatedSeed); SPDLOG_DEBUG("testing seed: %d", repeatedSeed); diff --git a/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp b/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp index 5edcb0fdaa..2a93f40c3b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp @@ -2,28 +2,19 @@ #include #include -#include #include -template static void erase_if(std::vector& vector, Predicate pred) { - vector.erase(std::remove_if(begin(vector), end(vector), pred), end(vector)); -} - -template -std::vector FilterFromPool(std::vector& vector, Predicate pred, bool eraseAfterFilter = false) { +template std::vector FilterFromPool(std::vector& vector, Predicate pred) { std::vector filteredPool = {}; std::copy_if(vector.begin(), vector.end(), std::back_inserter(filteredPool), pred); - - if (eraseAfterFilter) { - erase_if(vector, pred); - } - return filteredPool; } template std::vector FilterAndEraseFromPool(std::vector& vector, Predicate pred) { - return FilterFromPool(vector, pred, true); + auto filtered = FilterFromPool(vector, pred); + std::erase_if(vector, pred); + return filtered; } template void AddElementsToPool(std::vector& toPool, const FromPool& fromPool) { @@ -33,7 +24,3 @@ template void AddElementsToPool(std::vector& template bool ElementInContainer(T& element, const Container& container) { return std::find(container.begin(), container.end(), element) != container.end(); } - -template bool IsAnyOf(First&& first, T&&... t) { - return ((first == t) || ...); -} diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp deleted file mode 100644 index 76f26f9123..0000000000 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "menu.hpp" -#include "../static_data.h" -#include "../item_location.h" -#include "../location_access.h" -#include "rando_main.hpp" -#include "../SeedContext.h" -#include -#include -#include -#include "soh/OTRGlobals.h" -#include "soh/cvar_prefixes.h" - -void RandoMain::GenerateRando(std::set excludedLocations, std::set enabledTricks, - std::string seedString) { - - Rando::Context::GetInstance()->SetSeedGenerated(GenerateRandomizer(excludedLocations, enabledTricks, seedString)); - - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); -} diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp deleted file mode 100644 index 77e98b2fda..0000000000 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "soh/Enhancements/randomizer/item.h" - -#include -namespace RandoMain { -void GenerateRando(std::set excludedLocations, std::set enabledTricks, - std::string seedInput); -} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/random.cpp b/soh/soh/Enhancements/randomizer/3drando/random.cpp index 73b97f6b64..b0b3f796ee 100644 --- a/soh/soh/Enhancements/randomizer/3drando/random.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/random.cpp @@ -9,10 +9,6 @@ void Random_Init(uint64_t seed) { ShipUtils::RandInit(seed, &rando_state); } -uint32_t next32() { - return ShipUtils::next32(&rando_state); -} - // Returns a random integer in range [min, max-1] uint32_t Random(uint32_t min, uint32_t max) { return ShipUtils::Random(min, max, &rando_state); diff --git a/soh/soh/Enhancements/randomizer/3drando/random.hpp b/soh/soh/Enhancements/randomizer/3drando/random.hpp index b08e7807f4..5c8eefd3b5 100644 --- a/soh/soh/Enhancements/randomizer/3drando/random.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/random.hpp @@ -3,7 +3,7 @@ #include "soh/ShipUtils.h" #include #include -#include +#include #include #include #include diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index d0cc4489b0..b3835cb5ea 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -200,9 +200,11 @@ uint16_t GetCheapBalancedPrice() { return -1; } -// Get 0 to 7, or a random number from 1-7 depending on shopsanity setting +// Get 0 to 8, or a random number, depending on shopsanity setting. The 8th item is only allowed with No Logic, +// since logic otherwise requires at least one buyable refill to remain reachable in each shop. int GetShopsanityReplaceAmount() { auto ctx = Rando::Context::GetInstance(); + const int maxReplace = ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) ? 8 : 7; if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { return 0; } else if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT)) { @@ -223,12 +225,12 @@ int GetShopsanityReplaceAmount() { } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_SEVEN_ITEMS)) { return 7; } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_EIGHT_ITEMS)) { - return 8; // temporarily unreachable due to logic limitations + return maxReplace; // Clamped to 7 unless No Logic } else { assert(false); return 0; } - } else { // Random, get number in [1, 7] - return Random(1, 8); + } else { // Random, get number in [1, maxReplace] + return Random(1, maxReplace + 1); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp index 13dae5fa29..f6409ed2cd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp @@ -2,9 +2,6 @@ #include #include -#include -#include -#include "../randomizerTypes.h" using RandomizerHash = std::array; diff --git a/soh/soh/Enhancements/randomizer/3drando/text.hpp b/soh/soh/Enhancements/randomizer/3drando/text.hpp deleted file mode 100644 index 6e53ac11b5..0000000000 --- a/soh/soh/Enhancements/randomizer/3drando/text.hpp +++ /dev/null @@ -1,166 +0,0 @@ -#pragma once - -#include -#include - -#define PLURAL 0 -#define SINGULAR 1 - -class Text { - public: - Text() = default; - Text(std::string english_, std::string french_, std::string german_) - : english(std::move(english_)), french(std::move(french_)), german(std::move(german_)), spanish(std::move("")) { - // spanish defaults to english text until a translation is provided. - spanish = english; - } - Text(std::string english_, std::string french_, std::string german_, std::string spanish_) - : english(std::move(english_)), french(std::move(french_)), german(std::move(german_)), spanish(std::move("")) { - } - Text(std::string english_) - : english(std::move(english_)), french(std::move("")), german(std::move("")), spanish(std::move("")) { - // default unprovided languages to english text - french = spanish = german = english; - } - - const std::string& GetEnglish() const { - return english; - } - - const std::string& GetFrench() const { - if (french.length() > 0) { - return french; - } - return english; - } - - const std::string& GetGerman() const { - if (german.length() > 0) { - return german; - } - return english; - } - const std::string& GetSpanish() const { - if (spanish.length() > 0) { - return spanish; - } - return english; - } - - const std::string& GetForLanguage(uint8_t language) const { - switch (language) { - case 0: // LANGUAGE_ENG: changed to resolve #include loops - return GetEnglish(); - case 2: // LANGUAGE_FRA: - return GetFrench(); - case 1: // LANGUAGE_GER: - return GetGerman(); - default: - return GetEnglish(); - } - } - - Text operator+(const Text& right) const { - return Text{ - english + right.GetEnglish(), - french + right.GetFrench(), - german + right.GetGerman(), - spanish + right.GetSpanish(), - }; - } - - Text operator+(const std::string& right) const { - return Text{ - english + right, - french + right, - german + right, - spanish + right, - }; - } - - bool operator==(const Text& right) const { - return english == right.english; - } - - bool operator==(const std::string& right) const { - return english == right || french == right || german == right || spanish == right; - } - - bool operator!=(const Text& right) const { - return !operator==(right); - } - - void Replace(std::string oldStr, std::string newStr) { - - for (std::string* str : { &english, &french, &german, &spanish }) { - size_t position = str->find(oldStr); - while (position != std::string::npos) { - str->replace(position, oldStr.length(), newStr); - position = str->find(oldStr); - } - } - } - - void Replace(std::string oldStr, Text newText) { - size_t position = english.find(oldStr); - while (position != std::string::npos) { - english.replace(position, oldStr.length(), newText.GetEnglish()); - position = english.find(oldStr); - } - position = french.find(oldStr); - while (position != std::string::npos) { - french.replace(position, oldStr.length(), newText.GetFrench()); - position = french.find(oldStr); - } - position = german.find(oldStr); - while (position != std::string::npos) { - german.replace(position, oldStr.length(), newText.GetGerman()); - position = german.find(oldStr); - } - position = spanish.find(oldStr); - while (position != std::string::npos) { - spanish.replace(position, oldStr.length(), newText.GetSpanish()); - position = spanish.find(oldStr); - } - } - - // Convert first char to upper case - Text Capitalize(void) const { - Text cap = *this + ""; - for (std::string* str : { &cap.english, &cap.french, &cap.german, &cap.spanish }) { - (*str)[0] = std::toupper((*str)[0]); - } - return cap; - } - - // find the appropriate bars that separate singular from plural - void SetForm(int form) { - for (std::string* str : { &english, &french, &german, &spanish }) { - - size_t firstBar = str->find('|'); - if (firstBar != std::string::npos) { - - size_t secondBar = str->find('|', firstBar + 1); - if (secondBar != std::string::npos) { - - size_t thirdBar = str->find('|', secondBar + 1); - if (thirdBar != std::string::npos) { - - if (form == SINGULAR) { - str->erase(secondBar, thirdBar - secondBar); - } else { - str->erase(firstBar, secondBar - firstBar); - } - } - } - } - } - // remove the remaining bar - this->Replace("|", ""); - } - - std::string english = ""; - std::string french = ""; - std::string german = ""; - std::string spanish = ""; -}; diff --git a/soh/soh/Enhancements/randomizer/BigPoes.cpp b/soh/soh/Enhancements/randomizer/BigPoes.cpp index e83b196755..fc58f85018 100644 --- a/soh/soh/Enhancements/randomizer/BigPoes.cpp +++ b/soh/soh/Enhancements/randomizer/BigPoes.cpp @@ -1,4 +1,5 @@ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "variables.h" diff --git a/soh/soh/Enhancements/randomizer/Bombchus.cpp b/soh/soh/Enhancements/randomizer/Bombchus.cpp index 8690a83292..6977b23185 100644 --- a/soh/soh/Enhancements/randomizer/Bombchus.cpp +++ b/soh/soh/Enhancements/randomizer/Bombchus.cpp @@ -1,6 +1,7 @@ #include #include "soh/ShipInit.hpp" #include "src/overlays/actors/ovl_En_GirlA/z_en_girla.h" +#include "soh/Enhancements/randomizer/SeedContext.h" extern "C" { #include "z64save.h" diff --git a/soh/soh/Enhancements/randomizer/ColoredMapsAndCompasses.cpp b/soh/soh/Enhancements/randomizer/ColoredMapsAndCompasses.cpp index 161cf87b0c..fe6d6d3c51 100644 --- a/soh/soh/Enhancements/randomizer/ColoredMapsAndCompasses.cpp +++ b/soh/soh/Enhancements/randomizer/ColoredMapsAndCompasses.cpp @@ -5,6 +5,7 @@ #include "objects/object_gi_compass/object_gi_compass.h" #include "objects/object_gi_map/object_gi_map.h" #include "soh/OTRGlobals.h" +#include "soh/Enhancements/randomizer/SeedContext.h" extern "C" { #include "variables.h" @@ -17,10 +18,9 @@ extern "C" { CVarGetInteger(CVAR_COLORED_MAPS_AND_COMPASSES_NAME, CVAR_COLORED_MAPS_AND_COMPASSES_DEFAULT) void RegisterColoredMapsAndCompasses() { - s8 mapsAndCompassesCanBeOutsideDungeon = + bool mapsAndCompassesCanBeOutsideDungeon = IS_RANDO && DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_SHUFFLE_MAPANDCOMPASS); - s8 isColoredMapsAndCompassesEnabled = mapsAndCompassesCanBeOutsideDungeon && CVAR_COLORED_MAPS_AND_COMPASSES_VALUE; - if (isColoredMapsAndCompassesEnabled) { + if (mapsAndCompassesCanBeOutsideDungeon && CVAR_COLORED_MAPS_AND_COMPASSES_VALUE) { ResourceMgr_PatchGfxByName(gGiDungeonMapDL, "Map_PrimColor", 5, gsDPNoOp()); ResourceMgr_PatchGfxByName(gGiDungeonMapDL, "Map_EnvColor", 6, gsDPNoOp()); ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_PrimColor", 5, gsDPNoOp()); diff --git a/soh/soh/Enhancements/randomizer/LakeHyliaWaterControl.cpp b/soh/soh/Enhancements/randomizer/LakeHyliaWaterControl.cpp new file mode 100644 index 0000000000..17903949ab --- /dev/null +++ b/soh/soh/Enhancements/randomizer/LakeHyliaWaterControl.cpp @@ -0,0 +1,151 @@ +#include +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include "soh/Enhancements/custom-message/CustomMessageTypes.h" + +extern "C" { +extern PlayState* gPlayState; +#include "macros.h" +#include "functions.h" +#include "variables.h" +#include "src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h" + +extern s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId); +extern void BgSpot06Objects_WaterPlaneCutsceneRise(BgSpot06Objects*, PlayState*); +extern void BgSpot06Objects_WaterPlaneCutsceneLower(BgSpot06Objects*, PlayState*); +extern void BgSpot06Objects_LockFloat(BgSpot06Objects*, PlayState*); +} + +#define WATER_LEVEL_RAISED (-1313) + +// Main water control switch +static Actor* sSwitchMain = nullptr; +// Alternate control switch on fishing island +static Actor* sSwitchIsland = nullptr; +static Actor* sLock = nullptr; +static u8 sPrevFlagState = 0; + +static void SpawnSwitches(PlayState* play) { + // Object containing floor switch data (and ice block data) + Object_Spawn(&play->objectCtx, OBJECT_GAMEPLAY_DANGEON_KEEP); + + bool waterTempleCleared = Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP); + bool waterLowered = !Flags_GetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); + // Persist the water level across scene reloads. + if (waterTempleCleared && waterLowered) { + Flags_SetSwitch(play, 0x3E); + } + + s16 switchParams; + if (waterTempleCleared) { + // Toggle-able floor switch + switchParams = 0x3E10; + } else { + // Frozen rusty switch, same flag as above. It's glitched and can't be pressed + switchParams = 0x3E81; + } + + sSwitchMain = + // Spawn a floor switch + Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_SWITCH, -896.0f, -1243.0f, 6953.0f, 0, 0, 0, switchParams); + // Spawn a sign + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KANBAN, -970.0f, -1242.0f, 6954.0f, 0, 0, 0, + 0x0000 | (TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN & 0xFF)); + if (!waterTempleCleared) { + // Spawn a Navi check spot when Water Temple isn't cleared + Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, -896.0f, -1243.0f, 6953.0f, 0, 0, 0, + 0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF)); + } + + // Second switch on the fishing pond island. Up against the wall + sSwitchIsland = + // Spawn a floor switch + Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_SWITCH, 1320.0f, -1218.7f, 4025.0f, 0, 0, 0, switchParams); + // Spawn a sign + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KANBAN, 1320.0f, -1217.7f, 3951.0f, 0, -0x4000, 0, + 0x0000 | (TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN & 0xFF)); + if (!waterTempleCleared) { + // Spawn a Navi check spot when Water Temple isn't cleared + Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, 1320.0f, -1218.7f, 4025.0f, 0, 0, 0, + 0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF)); + } + + sPrevFlagState = Flags_GetSwitch(play, 0x3E) != 0; +} + +void RegisterLakeHyliaWaterControl() { + COND_HOOK(OnSceneSpawnActors, IS_RANDO, []() { + // Bail early for water control system for child, non-rando, or wrong scene + if (LINK_IS_ADULT && gPlayState->sceneNum == SCENE_LAKE_HYLIA) { + SpawnSwitches(gPlayState); + } + }); + + // Strip the ice-block bit so melting it doesn't toggle flag 0x3E. + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_SWITCH, IS_RANDO, [](void* actorRef) { + Actor* actor = static_cast(actorRef); + if (actor == sSwitchMain || actor == sSwitchIsland) { + actor->params &= ~0x80; + } + }); + + // Keep track of the floating lock + COND_ID_HOOK(OnActorInit, ACTOR_BG_SPOT06_OBJECTS, IS_RANDO, [](void* actorRef) { + Actor* actor = static_cast(actorRef); + if (actor->params == 1 /* LHO_WATER_TEMPLE_ENTRANCE_LOCK */) { + sLock = actor; + } + }); + + COND_ID_HOOK(OnActorUpdate, ACTOR_BG_SPOT06_OBJECTS, IS_RANDO, [](void* actorRef) { + Actor* actor = static_cast(actorRef); + if (actor->params != 2 /* LHO_WATER_PLANE */ || !LINK_IS_ADULT) { + return; + } + BgSpot06Objects* waterPlane = reinterpret_cast(actor); + + if (sLock != nullptr) { + BgSpot06Objects* lockObj = reinterpret_cast(sLock); + if (lockObj->actionFunc == BgSpot06Objects_LockFloat) { + // If we're in LockFloat, change the Y position to track the water surface + sLock->home.pos.y = waterPlane->lakeHyliaWaterLevel + WATER_LEVEL_RAISED; + } + } + + u8 flagState = Flags_GetSwitch(gPlayState, 0x3E) != 0; + if (sPrevFlagState == flagState) { + return; + } + sPrevFlagState = flagState; + waterPlane->actionFunc = + flagState ? BgSpot06Objects_WaterPlaneCutsceneLower : BgSpot06Objects_WaterPlaneCutsceneRise; + }); + + // Synchronize pressed states of both main and island switches + COND_HOOK(OnPlayerUpdate, IS_RANDO, []() { + if (gPlayState->sceneNum != SCENE_LAKE_HYLIA) { + return; + } + if (sSwitchMain == nullptr || sSwitchIsland == nullptr) { + return; + } + DynaPolyActor* mainSwitch = reinterpret_cast(sSwitchMain); + DynaPolyActor* islandSwitch = reinterpret_cast(sSwitchIsland); + u32 merged = (mainSwitch->interactFlags | islandSwitch->interactFlags) & DYNA_INTERACT_PLAYER_ON_TOP; + if (merged == 0) { + return; + } + mainSwitch->interactFlags |= merged; + islandSwitch->interactFlags |= merged; + }); + + COND_HOOK(OnPlayDestroy, IS_RANDO, []() { + sSwitchMain = nullptr; + sSwitchIsland = nullptr; + sLock = nullptr; + sPrevFlagState = 0; + }); +} + +static RegisterShipInitFunc registerLakeHyliaWaterControl(RegisterLakeHyliaWaterControl, { "IS_RANDO" }); diff --git a/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp b/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp index fe934456c4..dbec1554c1 100644 --- a/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp +++ b/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp @@ -1,6 +1,7 @@ #include #include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/randomizer/SeedContext.h" #include "soh/ShipInit.hpp" extern "C" { diff --git a/soh/soh/Enhancements/randomizer/MedallionLockedTrials.cpp b/soh/soh/Enhancements/randomizer/MedallionLockedTrials.cpp index 1c769d9e9c..3cd2585e66 100644 --- a/soh/soh/Enhancements/randomizer/MedallionLockedTrials.cpp +++ b/soh/soh/Enhancements/randomizer/MedallionLockedTrials.cpp @@ -1,5 +1,6 @@ #include "soh/OTRGlobals.h" #include "soh/ShipInit.hpp" +#include "soh/Enhancements/randomizer/SeedContext.h" extern "C" { extern PlayState* gPlayState; diff --git a/soh/soh/Enhancements/randomizer/Messages/EntranceHints.cpp b/soh/soh/Enhancements/randomizer/Messages/EntranceHints.cpp index f219e41095..5722668cf0 100644 --- a/soh/soh/Enhancements/randomizer/Messages/EntranceHints.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/EntranceHints.cpp @@ -1,5 +1,6 @@ #include "soh/Enhancements/randomizer/entrance.h" #include "soh/Enhancements/randomizer/randomizer_entrance_tracker.h" +#include "soh/Enhancements/randomizer/randomizer.h" #include extern "C" { diff --git a/soh/soh/Enhancements/randomizer/Messages/Goron.cpp b/soh/soh/Enhancements/randomizer/Messages/Goron.cpp index 9515890c08..c683388aea 100644 --- a/soh/soh/Enhancements/randomizer/Messages/Goron.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/Goron.cpp @@ -3,6 +3,7 @@ * trapped Gorons have when you free them. */ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include diff --git a/soh/soh/Enhancements/randomizer/Messages/GossipStoneHints.cpp b/soh/soh/Enhancements/randomizer/Messages/GossipStoneHints.cpp index 70d2235a63..f7e2847bf0 100644 --- a/soh/soh/Enhancements/randomizer/Messages/GossipStoneHints.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/GossipStoneHints.cpp @@ -3,6 +3,7 @@ * hints. */ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { extern PlayState* gPlayState; diff --git a/soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp b/soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp index cd1ae01692..d52dba31cb 100644 --- a/soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp @@ -10,6 +10,7 @@ #include "soh/Enhancements/custom-message/CustomMessageTypes.h" #include "soh/Enhancements/randomizer/Traps.h" #include "soh/Enhancements/randomizer/item.h" +#include "soh/Enhancements/randomizer/randomizer.h" #include "soh/ShipInit.hpp" #include diff --git a/soh/soh/Enhancements/randomizer/Messages/MerchantMessages.cpp b/soh/soh/Enhancements/randomizer/Messages/MerchantMessages.cpp index 747d4a9ee0..c0651d48ff 100644 --- a/soh/soh/Enhancements/randomizer/Messages/MerchantMessages.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/MerchantMessages.cpp @@ -8,6 +8,7 @@ */ #include #include "soh/ObjectExtension/ObjectExtension.h" +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { extern PlayState* gPlayState; diff --git a/soh/soh/Enhancements/randomizer/Messages/Miscellaneous.cpp b/soh/soh/Enhancements/randomizer/Messages/Miscellaneous.cpp index 1393c00c8e..832cf45652 100644 --- a/soh/soh/Enhancements/randomizer/Messages/Miscellaneous.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/Miscellaneous.cpp @@ -6,6 +6,7 @@ */ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include diff --git a/soh/soh/Enhancements/randomizer/Messages/Navi.cpp b/soh/soh/Enhancements/randomizer/Messages/Navi.cpp index e03f16d306..430841ec8c 100644 --- a/soh/soh/Enhancements/randomizer/Messages/Navi.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/Navi.cpp @@ -3,6 +3,7 @@ * for the Rando-Relevant Navi Hints enhancement. */ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include diff --git a/soh/soh/Enhancements/randomizer/Messages/Rupees.cpp b/soh/soh/Enhancements/randomizer/Messages/Rupees.cpp index 712f15d56e..3681770c85 100644 --- a/soh/soh/Enhancements/randomizer/Messages/Rupees.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/Rupees.cpp @@ -2,6 +2,7 @@ * This file is for handling the Randomize Rupee Names enhancement */ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "variables.h" diff --git a/soh/soh/Enhancements/randomizer/Messages/StaticHints.cpp b/soh/soh/Enhancements/randomizer/Messages/StaticHints.cpp index 31d7e64eab..1ae35bdd9a 100644 --- a/soh/soh/Enhancements/randomizer/Messages/StaticHints.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/StaticHints.cpp @@ -8,6 +8,7 @@ #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "z64scene.h" #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { extern PlayState* gPlayState; diff --git a/soh/soh/Enhancements/randomizer/Plandomizer.cpp b/soh/soh/Enhancements/randomizer/Plandomizer.cpp index 7efd9c99d6..314151efbd 100644 --- a/soh/soh/Enhancements/randomizer/Plandomizer.cpp +++ b/soh/soh/Enhancements/randomizer/Plandomizer.cpp @@ -18,6 +18,10 @@ #include "soh/Enhancements/randomizer/Traps.h" #include "soh/Enhancements/randomizer/3drando/shops.hpp" +#include + +#include + extern "C" { #include "include/z64item.h" #include "objects/gameplay_keep/gameplay_keep.h" @@ -306,8 +310,8 @@ ImVec4 plandomizerGetItemColor(Rando::Item randoItem) { } if (randoItem.GetItemType() == ITEMTYPE_SONG) { uint32_t questID = Rando::Logic::RandoGetToQuestItem[randoItem.GetRandomizerGet()]; - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - songMapping.at((QuestItem)questID).name); + textureID = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(songMapping.at((QuestItem)questID).name); itemColor = songMapping.at((QuestItem)questID).color; imageSize = ImVec2(24.0f, 32.0f); imagePadding = 6.0f; @@ -380,17 +384,21 @@ void PlandomizerItemImageCorrection(Rando::Item randoItem) { itemColor = plandomizerGetItemColor(randoItem); if (randoItem.GetItemType() == ITEMTYPE_SMALLKEY || randoItem.GetItemType() == ITEMTYPE_FORTRESS_SMALLKEY) { - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_KEY_SMALL"); + textureID = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("ITEM_KEY_SMALL"); return; } if (randoItem.GetItemType() == ITEMTYPE_BOSSKEY) { - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_KEY_BOSS"); + textureID = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("ITEM_KEY_BOSS"); return; } for (auto& map : itemImageMap) { if (map.first == randoItem.GetRandomizerGet()) { - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(map.second.c_str()); + textureID = + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(map.second.c_str()); if (map.second.find("ITEM_ARROWS") != std::string::npos) { textureUV0 = ImVec2(0, 1); textureUV1 = ImVec2(1, 0); @@ -404,17 +412,19 @@ void PlandomizerItemImageCorrection(Rando::Item randoItem) { } if (randoItem.GetRandomizerGet() >= RG_GOHMA_SOUL && randoItem.GetRandomizerGet() <= RG_GANON_SOUL) { - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("BOSS_SOUL"); + textureID = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("BOSS_SOUL"); } if (randoItem.GetRandomizerGet() >= RG_OCARINA_A_BUTTON && randoItem.GetRandomizerGet() <= RG_OCARINA_C_RIGHT_BUTTON) { - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_TIME"); + textureID = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("ITEM_OCARINA_TIME"); } if (textureID == 0) { - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - itemMapping[randoItem.GetGIEntry()->itemId].name); + textureID = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(itemMapping[randoItem.GetGIEntry()->itemId].name); } } @@ -973,13 +983,16 @@ void PlandomizerDrawOptions() { PlandoPushImageButtonStyle(); for (auto& hash : plandoHash) { ImGui::PushID(index); - textureID = - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(gSeedTextures[hash].tex); + textureID = std::dynamic_pointer_cast( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(gSeedTextures[hash].tex); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 2.0f)); - auto upRet = ImGui::ImageButton( - "HASH_ARROW_UP", - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("HASH_ARROW_UP"), - ImVec2(35.0f, 18.0f), ImVec2(1, 1), ImVec2(0, 0), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); + auto upRet = ImGui::ImageButton("HASH_ARROW_UP", + std::dynamic_pointer_cast( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("HASH_ARROW_UP"), + ImVec2(35.0f, 18.0f), ImVec2(1, 1), ImVec2(0, 0), + ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); ImGui::PopStyleVar(); if (upRet) { if (hash + 1 >= gSeedTextures.size()) { @@ -990,10 +1003,12 @@ void PlandomizerDrawOptions() { } ImGui::Image(textureID, ImVec2(35.0f, 35.0f)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 2.0f)); - auto downRet = ImGui::ImageButton( - "HASH_ARROW_DWN", - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("HASH_ARROW_DWN"), - ImVec2(35.0f, 18.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); + auto downRet = ImGui::ImageButton("HASH_ARROW_DWN", + std::dynamic_pointer_cast( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("HASH_ARROW_DWN"), + ImVec2(35.0f, 18.0f), ImVec2(0, 0), ImVec2(1, 1), + ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); ImGui::PopStyleVar(); if (downRet) { if (hash == 0) { @@ -1171,25 +1186,26 @@ void PlandomizerWindow::DrawElement() { } void PlandomizerWindow::InitElement() { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_RUPEE_GRAYSCALE", gRupeeCounterIconTex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_HEART_GRAYSCALE", gHeartFullTex, - ImVec4(0.87f, 0.10f, 0.10f, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_SEEDS", gItemIconDekuSeedsTex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_SMALL", gDropArrows1Tex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_MEDIUM", gDropArrows2Tex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_LARGE", gDropArrows3Tex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ICE_TRAP", gMagicArrowEquipEffectTex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("HASH_ARROW_UP", gEmptyCDownArrowTex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("HASH_ARROW_DWN", gEmptyCDownArrowTex, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("BOSS_SOUL", gBossSoulTex, ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("TRIFORCE_PIECE", gTriforcePieceTex, - ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_RUPEE_GRAYSCALE", gRupeeCounterIconTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_HEART_GRAYSCALE", gHeartFullTex, ImVec4(0.87f, 0.10f, 0.10f, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_SEEDS", gItemIconDekuSeedsTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_ARROWS_SMALL", gDropArrows1Tex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_ARROWS_MEDIUM", gDropArrows2Tex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_ARROWS_LARGE", gDropArrows3Tex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_ICE_TRAP", gMagicArrowEquipEffectTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("HASH_ARROW_UP", gEmptyCDownArrowTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("HASH_ARROW_DWN", gEmptyCDownArrowTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("BOSS_SOUL", gBossSoulTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("TRIFORCE_PIECE", gTriforcePieceTex, ImVec4(1, 1, 1, 1)); } diff --git a/soh/soh/Enhancements/randomizer/RCToRandInf.cpp b/soh/soh/Enhancements/randomizer/RCToRandInf.cpp new file mode 100644 index 0000000000..0cde9e4665 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/RCToRandInf.cpp @@ -0,0 +1,3060 @@ +#include "./RCToRandInf.h" + +std::map rcToRandomizerInf = { + { RC_KF_LINKS_HOUSE_COW, RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW }, + { RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT }, + { RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT }, + { RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE }, + { RC_LW_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR }, + { RC_LW_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT }, + { RC_SFM_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR }, + { RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT }, + { RC_HF_DEKU_SCRUB_GROTTO, RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO }, + { RC_HF_COW_GROTTO_COW, RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW }, + { RC_LH_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT }, + { RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT }, + { RC_LH_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER }, + { RC_GV_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR }, + { RC_GV_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT }, + { RC_GV_COW, RAND_INF_COWS_MILKED_GV_COW }, + { RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR }, + { RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT }, + { RC_KAK_IMPAS_HOUSE_COW, RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW }, + { RC_DMT_COW_GROTTO_COW, RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW }, + { RC_GC_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT }, + { RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT }, + { RC_GC_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER }, + { RC_DMC_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB }, + { RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT }, + { RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT }, + { RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER }, + { RC_ZR_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR }, + { RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT }, + { RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT }, + { RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT }, + { RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER }, + { RC_LLR_STABLES_LEFT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW }, + { RC_LLR_STABLES_RIGHT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW }, + { RC_LLR_TOWER_LEFT_COW, RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW }, + { RC_LLR_TOWER_RIGHT_COW, RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW }, + { RC_DEKU_TREE_MQ_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB }, + { RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT }, + { RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS }, + { RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT }, + { RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY }, + { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR }, + { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT }, + { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE }, + { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS }, + { RC_JABU_JABUS_BELLY_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB }, + { RC_JABU_JABUS_BELLY_MQ_COW, RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW }, + { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT }, + { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT }, + { RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT }, + { RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT }, + { RC_KF_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1 }, + { RC_KF_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_2 }, + { RC_KF_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_3 }, + { RC_KF_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_4 }, + { RC_KF_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_5 }, + { RC_KF_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_6 }, + { RC_KF_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_7 }, + { RC_KF_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_8 }, + { RC_GC_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_1 }, + { RC_GC_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_2 }, + { RC_GC_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_3 }, + { RC_GC_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_4 }, + { RC_GC_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_5 }, + { RC_GC_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_6 }, + { RC_GC_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_7 }, + { RC_GC_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_8 }, + { RC_ZD_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_1 }, + { RC_ZD_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_2 }, + { RC_ZD_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_3 }, + { RC_ZD_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_4 }, + { RC_ZD_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_5 }, + { RC_ZD_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_6 }, + { RC_ZD_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_7 }, + { RC_ZD_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_8 }, + { RC_KAK_BAZAAR_ITEM_1, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_1 }, + { RC_KAK_BAZAAR_ITEM_2, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_2 }, + { RC_KAK_BAZAAR_ITEM_3, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_3 }, + { RC_KAK_BAZAAR_ITEM_4, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_4 }, + { RC_KAK_BAZAAR_ITEM_5, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_5 }, + { RC_KAK_BAZAAR_ITEM_6, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_6 }, + { RC_KAK_BAZAAR_ITEM_7, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_7 }, + { RC_KAK_BAZAAR_ITEM_8, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_8 }, + { RC_KAK_POTION_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_1 }, + { RC_KAK_POTION_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_2 }, + { RC_KAK_POTION_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_3 }, + { RC_KAK_POTION_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_4 }, + { RC_KAK_POTION_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_5 }, + { RC_KAK_POTION_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_6 }, + { RC_KAK_POTION_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_7 }, + { RC_KAK_POTION_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_8 }, + { RC_MARKET_BAZAAR_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_1 }, + { RC_MARKET_BAZAAR_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_2 }, + { RC_MARKET_BAZAAR_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_3 }, + { RC_MARKET_BAZAAR_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_4 }, + { RC_MARKET_BAZAAR_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_5 }, + { RC_MARKET_BAZAAR_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_6 }, + { RC_MARKET_BAZAAR_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_7 }, + { RC_MARKET_BAZAAR_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_8 }, + { RC_MARKET_POTION_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_1 }, + { RC_MARKET_POTION_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_2 }, + { RC_MARKET_POTION_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_3 }, + { RC_MARKET_POTION_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_4 }, + { RC_MARKET_POTION_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_5 }, + { RC_MARKET_POTION_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_6 }, + { RC_MARKET_POTION_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_7 }, + { RC_MARKET_POTION_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_8 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_1 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_2 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_3 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_4 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_5 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8 }, + { RC_TOT_MASTER_SWORD, RAND_INF_TOT_MASTER_SWORD }, + { RC_GC_MEDIGORON, RAND_INF_MERCHANTS_MEDIGORON }, + { RC_KAK_GRANNYS_SHOP, RAND_INF_MERCHANTS_GRANNYS_SHOP }, + { RC_WASTELAND_BOMBCHU_SALESMAN, RAND_INF_MERCHANTS_CARPET_SALESMAN }, + { RC_ZR_MAGIC_BEAN_SALESMAN, RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN }, + { RC_LW_TRADE_COJIRO, RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO }, + { RC_GV_TRADE_SAW, RAND_INF_ADULT_TRADES_GV_TRADE_SAW }, + { RC_DMT_TRADE_BROKEN_SWORD, RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD }, + { RC_LH_TRADE_FROG, RAND_INF_ADULT_TRADES_LH_TRADE_FROG }, + { RC_DMT_TRADE_EYEDROPS, RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS }, + { RC_LH_CHILD_FISHING, RAND_INF_CHILD_FISHING }, + { RC_LH_ADULT_FISHING, RAND_INF_ADULT_FISHING }, + { RC_MARKET_10_BIG_POES, RAND_INF_10_BIG_POES }, + { RC_KAK_100_GOLD_SKULLTULA_REWARD, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD }, + { RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT }, + { RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT }, + { RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO }, + { RC_SFM_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_SFM_STORMS_GROTTO }, + { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT }, + { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT }, + { RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT }, + { RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT }, + { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT }, + { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT }, + { RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO }, + { RC_LLR_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LLR_GROTTO }, + { RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT }, + { RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT }, + { RC_DMT_COW_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMT_COW_GROTTO }, + { RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT }, + { RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT }, + { RC_GC_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GC_GROTTO }, + { RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT }, + { RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT }, + { RC_DMC_HAMMER_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO }, + { RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT }, + { RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT }, + { RC_ZR_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_ZR_STORMS_GROTTO }, + { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT }, + { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT }, + { RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA }, + { RC_LH_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LH_GROTTO }, + { RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO }, + { RC_COLOSSUS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_COLOSSUS_GROTTO }, + { RC_LH_CHILD_FISH_1, RAND_INF_CHILD_FISH_1 }, + { RC_LH_CHILD_FISH_2, RAND_INF_CHILD_FISH_2 }, + { RC_LH_CHILD_FISH_3, RAND_INF_CHILD_FISH_3 }, + { RC_LH_CHILD_FISH_4, RAND_INF_CHILD_FISH_4 }, + { RC_LH_CHILD_FISH_5, RAND_INF_CHILD_FISH_5 }, + { RC_LH_CHILD_FISH_6, RAND_INF_CHILD_FISH_6 }, + { RC_LH_CHILD_FISH_7, RAND_INF_CHILD_FISH_7 }, + { RC_LH_CHILD_FISH_8, RAND_INF_CHILD_FISH_8 }, + { RC_LH_CHILD_FISH_9, RAND_INF_CHILD_FISH_9 }, + { RC_LH_CHILD_FISH_10, RAND_INF_CHILD_FISH_10 }, + { RC_LH_CHILD_FISH_11, RAND_INF_CHILD_FISH_11 }, + { RC_LH_CHILD_FISH_12, RAND_INF_CHILD_FISH_12 }, + { RC_LH_CHILD_FISH_13, RAND_INF_CHILD_FISH_13 }, + { RC_LH_CHILD_FISH_14, RAND_INF_CHILD_FISH_14 }, + { RC_LH_CHILD_FISH_15, RAND_INF_CHILD_FISH_15 }, + { RC_LH_CHILD_LOACH_1, RAND_INF_CHILD_LOACH_1 }, + { RC_LH_CHILD_LOACH_2, RAND_INF_CHILD_LOACH_2 }, + { RC_LH_ADULT_FISH_1, RAND_INF_ADULT_FISH_1 }, + { RC_LH_ADULT_FISH_2, RAND_INF_ADULT_FISH_2 }, + { RC_LH_ADULT_FISH_3, RAND_INF_ADULT_FISH_3 }, + { RC_LH_ADULT_FISH_4, RAND_INF_ADULT_FISH_4 }, + { RC_LH_ADULT_FISH_5, RAND_INF_ADULT_FISH_5 }, + { RC_LH_ADULT_FISH_6, RAND_INF_ADULT_FISH_6 }, + { RC_LH_ADULT_FISH_7, RAND_INF_ADULT_FISH_7 }, + { RC_LH_ADULT_FISH_8, RAND_INF_ADULT_FISH_8 }, + { RC_LH_ADULT_FISH_9, RAND_INF_ADULT_FISH_9 }, + { RC_LH_ADULT_FISH_10, RAND_INF_ADULT_FISH_10 }, + { RC_LH_ADULT_FISH_11, RAND_INF_ADULT_FISH_11 }, + { RC_LH_ADULT_FISH_12, RAND_INF_ADULT_FISH_12 }, + { RC_LH_ADULT_FISH_13, RAND_INF_ADULT_FISH_13 }, + { RC_LH_ADULT_FISH_14, RAND_INF_ADULT_FISH_14 }, + { RC_LH_ADULT_FISH_15, RAND_INF_ADULT_FISH_15 }, + { RC_LH_ADULT_LOACH, RAND_INF_ADULT_LOACH }, + { RC_ZR_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO }, + { RC_DMC_UPPER_GROTTO_FISH, RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO }, + { RC_DMT_STORMS_GROTTO_FISH, RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO }, + { RC_KAK_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO }, + { RC_HF_NEAR_MARKET_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO }, + { RC_HF_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO }, + { RC_HF_SOUTHEAST_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO }, + { RC_KF_STORMS_GROTTO_FISH, RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO }, + { RC_ZD_FISH_1, RAND_INF_ZD_FISH_1 }, + { RC_ZD_FISH_2, RAND_INF_ZD_FISH_2 }, + { RC_ZD_FISH_3, RAND_INF_ZD_FISH_3 }, + { RC_ZD_FISH_4, RAND_INF_ZD_FISH_4 }, + { RC_ZD_FISH_5, RAND_INF_ZD_FISH_5 }, + // Grass + { RC_KF_CHILD_GRASS_1, RAND_INF_KF_CHILD_GRASS_1 }, + { RC_KF_CHILD_GRASS_2, RAND_INF_KF_CHILD_GRASS_2 }, + { RC_KF_CHILD_GRASS_3, RAND_INF_KF_CHILD_GRASS_3 }, + { RC_KF_CHILD_GRASS_4, RAND_INF_KF_CHILD_GRASS_4 }, + { RC_KF_CHILD_GRASS_5, RAND_INF_KF_CHILD_GRASS_5 }, + { RC_KF_CHILD_GRASS_6, RAND_INF_KF_CHILD_GRASS_6 }, + { RC_KF_CHILD_GRASS_7, RAND_INF_KF_CHILD_GRASS_7 }, + { RC_KF_CHILD_GRASS_8, RAND_INF_KF_CHILD_GRASS_8 }, + { RC_KF_CHILD_GRASS_9, RAND_INF_KF_CHILD_GRASS_9 }, + { RC_KF_CHILD_GRASS_10, RAND_INF_KF_CHILD_GRASS_10 }, + { RC_KF_CHILD_GRASS_11, RAND_INF_KF_CHILD_GRASS_11 }, + { RC_KF_CHILD_GRASS_12, RAND_INF_KF_CHILD_GRASS_12 }, + { RC_KF_CHILD_GRASS_MAZE_1, RAND_INF_KF_CHILD_GRASS_MAZE_1 }, + { RC_KF_CHILD_GRASS_MAZE_2, RAND_INF_KF_CHILD_GRASS_MAZE_2 }, + { RC_KF_CHILD_GRASS_MAZE_3, RAND_INF_KF_CHILD_GRASS_MAZE_3 }, + { RC_KF_ADULT_GRASS_1, RAND_INF_KF_ADULT_GRASS_1 }, + { RC_KF_ADULT_GRASS_2, RAND_INF_KF_ADULT_GRASS_2 }, + { RC_KF_ADULT_GRASS_3, RAND_INF_KF_ADULT_GRASS_3 }, + { RC_KF_ADULT_GRASS_4, RAND_INF_KF_ADULT_GRASS_4 }, + { RC_KF_ADULT_GRASS_5, RAND_INF_KF_ADULT_GRASS_5 }, + { RC_KF_ADULT_GRASS_6, RAND_INF_KF_ADULT_GRASS_6 }, + { RC_KF_ADULT_GRASS_7, RAND_INF_KF_ADULT_GRASS_7 }, + { RC_KF_ADULT_GRASS_8, RAND_INF_KF_ADULT_GRASS_8 }, + { RC_KF_ADULT_GRASS_9, RAND_INF_KF_ADULT_GRASS_9 }, + { RC_KF_ADULT_GRASS_10, RAND_INF_KF_ADULT_GRASS_10 }, + { RC_KF_ADULT_GRASS_11, RAND_INF_KF_ADULT_GRASS_11 }, + { RC_KF_ADULT_GRASS_12, RAND_INF_KF_ADULT_GRASS_12 }, + { RC_KF_ADULT_GRASS_13, RAND_INF_KF_ADULT_GRASS_13 }, + { RC_KF_ADULT_GRASS_14, RAND_INF_KF_ADULT_GRASS_14 }, + { RC_KF_ADULT_GRASS_15, RAND_INF_KF_ADULT_GRASS_15 }, + { RC_KF_ADULT_GRASS_16, RAND_INF_KF_ADULT_GRASS_16 }, + { RC_KF_ADULT_GRASS_17, RAND_INF_KF_ADULT_GRASS_17 }, + { RC_KF_ADULT_GRASS_18, RAND_INF_KF_ADULT_GRASS_18 }, + { RC_KF_ADULT_GRASS_19, RAND_INF_KF_ADULT_GRASS_19 }, + { RC_KF_ADULT_GRASS_20, RAND_INF_KF_ADULT_GRASS_20 }, + { RC_LW_GRASS_1, RAND_INF_LW_GRASS_1 }, + { RC_LW_GRASS_2, RAND_INF_LW_GRASS_2 }, + { RC_LW_GRASS_3, RAND_INF_LW_GRASS_3 }, + { RC_LW_GRASS_4, RAND_INF_LW_GRASS_4 }, + { RC_LW_GRASS_5, RAND_INF_LW_GRASS_5 }, + { RC_LW_GRASS_6, RAND_INF_LW_GRASS_6 }, + { RC_LW_GRASS_7, RAND_INF_LW_GRASS_7 }, + { RC_LW_GRASS_8, RAND_INF_LW_GRASS_8 }, + { RC_LW_GRASS_9, RAND_INF_LW_GRASS_9 }, + { RC_MARKET_GRASS_1, RAND_INF_MARKET_GRASS_1 }, + { RC_MARKET_GRASS_2, RAND_INF_MARKET_GRASS_2 }, + { RC_MARKET_GRASS_3, RAND_INF_MARKET_GRASS_3 }, + { RC_MARKET_GRASS_4, RAND_INF_MARKET_GRASS_4 }, + { RC_MARKET_GRASS_5, RAND_INF_MARKET_GRASS_5 }, + { RC_MARKET_GRASS_6, RAND_INF_MARKET_GRASS_6 }, + { RC_MARKET_GRASS_7, RAND_INF_MARKET_GRASS_7 }, + { RC_MARKET_GRASS_8, RAND_INF_MARKET_GRASS_8 }, + { RC_HC_GRASS_1, RAND_INF_HC_GRASS_1 }, + { RC_HC_GRASS_2, RAND_INF_HC_GRASS_2 }, + { RC_KAK_GRASS_1, RAND_INF_KAK_GRASS_1 }, + { RC_KAK_GRASS_2, RAND_INF_KAK_GRASS_2 }, + { RC_KAK_GRASS_3, RAND_INF_KAK_GRASS_3 }, + { RC_KAK_GRASS_4, RAND_INF_KAK_GRASS_4 }, + { RC_KAK_GRASS_5, RAND_INF_KAK_GRASS_5 }, + { RC_KAK_GRASS_6, RAND_INF_KAK_GRASS_6 }, + { RC_KAK_GRASS_7, RAND_INF_KAK_GRASS_7 }, + { RC_KAK_GRASS_8, RAND_INF_KAK_GRASS_8 }, + { RC_GY_GRASS_1, RAND_INF_GY_GRASS_1 }, + { RC_GY_GRASS_2, RAND_INF_GY_GRASS_2 }, + { RC_GY_GRASS_3, RAND_INF_GY_GRASS_3 }, + { RC_GY_GRASS_4, RAND_INF_GY_GRASS_4 }, + { RC_GY_GRASS_5, RAND_INF_GY_GRASS_5 }, + { RC_GY_GRASS_6, RAND_INF_GY_GRASS_6 }, + { RC_GY_GRASS_7, RAND_INF_GY_GRASS_7 }, + { RC_GY_GRASS_8, RAND_INF_GY_GRASS_8 }, + { RC_GY_GRASS_9, RAND_INF_GY_GRASS_9 }, + { RC_GY_GRASS_10, RAND_INF_GY_GRASS_10 }, + { RC_GY_GRASS_11, RAND_INF_GY_GRASS_11 }, + { RC_GY_GRASS_12, RAND_INF_GY_GRASS_12 }, + { RC_LH_GRASS_1, RAND_INF_LH_GRASS_1 }, + { RC_LH_GRASS_2, RAND_INF_LH_GRASS_2 }, + { RC_LH_GRASS_3, RAND_INF_LH_GRASS_3 }, + { RC_LH_GRASS_4, RAND_INF_LH_GRASS_4 }, + { RC_LH_GRASS_5, RAND_INF_LH_GRASS_5 }, + { RC_LH_GRASS_6, RAND_INF_LH_GRASS_6 }, + { RC_LH_GRASS_7, RAND_INF_LH_GRASS_7 }, + { RC_LH_GRASS_8, RAND_INF_LH_GRASS_8 }, + { RC_LH_GRASS_9, RAND_INF_LH_GRASS_9 }, + { RC_LH_GRASS_10, RAND_INF_LH_GRASS_10 }, + { RC_LH_GRASS_11, RAND_INF_LH_GRASS_11 }, + { RC_LH_GRASS_12, RAND_INF_LH_GRASS_12 }, + { RC_LH_GRASS_13, RAND_INF_LH_GRASS_13 }, + { RC_LH_GRASS_14, RAND_INF_LH_GRASS_14 }, + { RC_LH_GRASS_15, RAND_INF_LH_GRASS_15 }, + { RC_LH_GRASS_16, RAND_INF_LH_GRASS_16 }, + { RC_LH_GRASS_17, RAND_INF_LH_GRASS_17 }, + { RC_LH_GRASS_18, RAND_INF_LH_GRASS_18 }, + { RC_LH_GRASS_19, RAND_INF_LH_GRASS_19 }, + { RC_LH_GRASS_20, RAND_INF_LH_GRASS_20 }, + { RC_LH_GRASS_21, RAND_INF_LH_GRASS_21 }, + { RC_LH_GRASS_22, RAND_INF_LH_GRASS_22 }, + { RC_LH_GRASS_23, RAND_INF_LH_GRASS_23 }, + { RC_LH_GRASS_24, RAND_INF_LH_GRASS_24 }, + { RC_LH_GRASS_25, RAND_INF_LH_GRASS_25 }, + { RC_LH_GRASS_26, RAND_INF_LH_GRASS_26 }, + { RC_LH_GRASS_27, RAND_INF_LH_GRASS_27 }, + { RC_LH_GRASS_28, RAND_INF_LH_GRASS_28 }, + { RC_LH_GRASS_29, RAND_INF_LH_GRASS_29 }, + { RC_LH_GRASS_30, RAND_INF_LH_GRASS_30 }, + { RC_LH_GRASS_31, RAND_INF_LH_GRASS_31 }, + { RC_LH_GRASS_32, RAND_INF_LH_GRASS_32 }, + { RC_LH_GRASS_33, RAND_INF_LH_GRASS_33 }, + { RC_LH_GRASS_34, RAND_INF_LH_GRASS_34 }, + { RC_LH_GRASS_35, RAND_INF_LH_GRASS_35 }, + { RC_LH_GRASS_36, RAND_INF_LH_GRASS_36 }, + { RC_LH_CHILD_GRASS_1, RAND_INF_LH_CHILD_GRASS_1 }, + { RC_LH_CHILD_GRASS_2, RAND_INF_LH_CHILD_GRASS_2 }, + { RC_LH_CHILD_GRASS_3, RAND_INF_LH_CHILD_GRASS_3 }, + { RC_LH_CHILD_GRASS_4, RAND_INF_LH_CHILD_GRASS_4 }, + { RC_LH_WARP_PAD_GRASS_1, RAND_INF_LH_WARP_PAD_GRASS_1 }, + { RC_LH_WARP_PAD_GRASS_2, RAND_INF_LH_WARP_PAD_GRASS_2 }, + { RC_HF_NEAR_KF_GRASS_1, RAND_INF_HF_NEAR_KF_GRASS_1 }, + { RC_HF_NEAR_KF_GRASS_2, RAND_INF_HF_NEAR_KF_GRASS_2 }, + { RC_HF_NEAR_KF_GRASS_3, RAND_INF_HF_NEAR_KF_GRASS_3 }, + { RC_HF_NEAR_KF_GRASS_4, RAND_INF_HF_NEAR_KF_GRASS_4 }, + { RC_HF_NEAR_KF_GRASS_5, RAND_INF_HF_NEAR_KF_GRASS_5 }, + { RC_HF_NEAR_KF_GRASS_6, RAND_INF_HF_NEAR_KF_GRASS_6 }, + { RC_HF_NEAR_KF_GRASS_7, RAND_INF_HF_NEAR_KF_GRASS_7 }, + { RC_HF_NEAR_KF_GRASS_8, RAND_INF_HF_NEAR_KF_GRASS_8 }, + { RC_HF_NEAR_KF_GRASS_9, RAND_INF_HF_NEAR_KF_GRASS_9 }, + { RC_HF_NEAR_KF_GRASS_10, RAND_INF_HF_NEAR_KF_GRASS_10 }, + { RC_HF_NEAR_KF_GRASS_11, RAND_INF_HF_NEAR_KF_GRASS_11 }, + { RC_HF_NEAR_KF_GRASS_12, RAND_INF_HF_NEAR_KF_GRASS_12 }, + { RC_HF_NEAR_MARKET_GRASS_1, RAND_INF_HF_NEAR_MARKET_GRASS_1 }, + { RC_HF_NEAR_MARKET_GRASS_2, RAND_INF_HF_NEAR_MARKET_GRASS_2 }, + { RC_HF_NEAR_MARKET_GRASS_3, RAND_INF_HF_NEAR_MARKET_GRASS_3 }, + { RC_HF_NEAR_MARKET_GRASS_4, RAND_INF_HF_NEAR_MARKET_GRASS_4 }, + { RC_HF_NEAR_MARKET_GRASS_5, RAND_INF_HF_NEAR_MARKET_GRASS_5 }, + { RC_HF_NEAR_MARKET_GRASS_6, RAND_INF_HF_NEAR_MARKET_GRASS_6 }, + { RC_HF_NEAR_MARKET_GRASS_7, RAND_INF_HF_NEAR_MARKET_GRASS_7 }, + { RC_HF_NEAR_MARKET_GRASS_8, RAND_INF_HF_NEAR_MARKET_GRASS_8 }, + { RC_HF_NEAR_MARKET_GRASS_9, RAND_INF_HF_NEAR_MARKET_GRASS_9 }, + { RC_HF_NEAR_MARKET_GRASS_10, RAND_INF_HF_NEAR_MARKET_GRASS_10 }, + { RC_HF_NEAR_MARKET_GRASS_11, RAND_INF_HF_NEAR_MARKET_GRASS_11 }, + { RC_HF_NEAR_MARKET_GRASS_12, RAND_INF_HF_NEAR_MARKET_GRASS_12 }, + { RC_HF_SOUTH_GRASS_1, RAND_INF_HF_SOUTH_GRASS_1 }, + { RC_HF_SOUTH_GRASS_2, RAND_INF_HF_SOUTH_GRASS_2 }, + { RC_HF_SOUTH_GRASS_3, RAND_INF_HF_SOUTH_GRASS_3 }, + { RC_HF_SOUTH_GRASS_4, RAND_INF_HF_SOUTH_GRASS_4 }, + { RC_HF_SOUTH_GRASS_5, RAND_INF_HF_SOUTH_GRASS_5 }, + { RC_HF_SOUTH_GRASS_6, RAND_INF_HF_SOUTH_GRASS_6 }, + { RC_HF_SOUTH_GRASS_7, RAND_INF_HF_SOUTH_GRASS_7 }, + { RC_HF_SOUTH_GRASS_8, RAND_INF_HF_SOUTH_GRASS_8 }, + { RC_HF_SOUTH_GRASS_9, RAND_INF_HF_SOUTH_GRASS_9 }, + { RC_HF_SOUTH_GRASS_10, RAND_INF_HF_SOUTH_GRASS_10 }, + { RC_HF_SOUTH_GRASS_11, RAND_INF_HF_SOUTH_GRASS_11 }, + { RC_HF_SOUTH_GRASS_12, RAND_INF_HF_SOUTH_GRASS_12 }, + { RC_HF_CENTRAL_GRASS_1, RAND_INF_HF_CENTRAL_GRASS_1 }, + { RC_HF_CENTRAL_GRASS_2, RAND_INF_HF_CENTRAL_GRASS_2 }, + { RC_HF_CENTRAL_GRASS_3, RAND_INF_HF_CENTRAL_GRASS_3 }, + { RC_HF_CENTRAL_GRASS_4, RAND_INF_HF_CENTRAL_GRASS_4 }, + { RC_HF_CENTRAL_GRASS_5, RAND_INF_HF_CENTRAL_GRASS_5 }, + { RC_HF_CENTRAL_GRASS_6, RAND_INF_HF_CENTRAL_GRASS_6 }, + { RC_HF_CENTRAL_GRASS_7, RAND_INF_HF_CENTRAL_GRASS_7 }, + { RC_HF_CENTRAL_GRASS_8, RAND_INF_HF_CENTRAL_GRASS_8 }, + { RC_HF_CENTRAL_GRASS_9, RAND_INF_HF_CENTRAL_GRASS_9 }, + { RC_HF_CENTRAL_GRASS_10, RAND_INF_HF_CENTRAL_GRASS_10 }, + { RC_HF_CENTRAL_GRASS_11, RAND_INF_HF_CENTRAL_GRASS_11 }, + { RC_HF_CENTRAL_GRASS_12, RAND_INF_HF_CENTRAL_GRASS_12 }, + { RC_ZR_GRASS_1, RAND_INF_ZR_GRASS_1 }, + { RC_ZR_GRASS_2, RAND_INF_ZR_GRASS_2 }, + { RC_ZR_GRASS_3, RAND_INF_ZR_GRASS_3 }, + { RC_ZR_GRASS_4, RAND_INF_ZR_GRASS_4 }, + { RC_ZR_GRASS_5, RAND_INF_ZR_GRASS_5 }, + { RC_ZR_GRASS_6, RAND_INF_ZR_GRASS_6 }, + { RC_ZR_GRASS_7, RAND_INF_ZR_GRASS_7 }, + { RC_ZR_GRASS_8, RAND_INF_ZR_GRASS_8 }, + { RC_ZR_GRASS_9, RAND_INF_ZR_GRASS_9 }, + { RC_ZR_GRASS_10, RAND_INF_ZR_GRASS_10 }, + { RC_ZR_GRASS_11, RAND_INF_ZR_GRASS_11 }, + { RC_ZR_GRASS_12, RAND_INF_ZR_GRASS_12 }, + { RC_ZR_NEAR_FREESTANDING_POH_GRASS, RAND_INF_ZR_NEAR_FREESTANDING_POH_GRASS }, + // Grotto Grass + { RC_KF_STORMS_GROTTO_GRASS_1, RAND_INF_KF_STORMS_GROTTO_GRASS_1 }, + { RC_KF_STORMS_GROTTO_GRASS_2, RAND_INF_KF_STORMS_GROTTO_GRASS_2 }, + { RC_KF_STORMS_GROTTO_GRASS_3, RAND_INF_KF_STORMS_GROTTO_GRASS_3 }, + { RC_KF_STORMS_GROTTO_GRASS_4, RAND_INF_KF_STORMS_GROTTO_GRASS_4 }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_1, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_1 }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2 }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3 }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4 }, + { RC_HF_NEAR_MARKET_GROTTO_GRASS_1, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_1 }, + { RC_HF_NEAR_MARKET_GROTTO_GRASS_2, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_2 }, + { RC_HF_NEAR_MARKET_GROTTO_GRASS_3, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_3 }, + { RC_HF_NEAR_MARKET_GROTTO_GRASS_4, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_4 }, + { RC_HF_OPEN_GROTTO_GRASS_1, RAND_INF_HF_OPEN_GROTTO_GRASS_1 }, + { RC_HF_OPEN_GROTTO_GRASS_2, RAND_INF_HF_OPEN_GROTTO_GRASS_2 }, + { RC_HF_OPEN_GROTTO_GRASS_3, RAND_INF_HF_OPEN_GROTTO_GRASS_3 }, + { RC_HF_OPEN_GROTTO_GRASS_4, RAND_INF_HF_OPEN_GROTTO_GRASS_4 }, + { RC_HF_SOUTHEAST_GROTTO_GRASS_1, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_1 }, + { RC_HF_SOUTHEAST_GROTTO_GRASS_2, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_2 }, + { RC_HF_SOUTHEAST_GROTTO_GRASS_3, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_3 }, + { RC_HF_SOUTHEAST_GROTTO_GRASS_4, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_4 }, + { RC_HF_COW_GROTTO_GRASS_1, RAND_INF_HF_COW_GROTTO_GRASS_1 }, + { RC_HF_COW_GROTTO_GRASS_2, RAND_INF_HF_COW_GROTTO_GRASS_2 }, + { RC_KAK_OPEN_GROTTO_GRASS_1, RAND_INF_KAK_OPEN_GROTTO_GRASS_1 }, + { RC_KAK_OPEN_GROTTO_GRASS_2, RAND_INF_KAK_OPEN_GROTTO_GRASS_2 }, + { RC_KAK_OPEN_GROTTO_GRASS_3, RAND_INF_KAK_OPEN_GROTTO_GRASS_3 }, + { RC_KAK_OPEN_GROTTO_GRASS_4, RAND_INF_KAK_OPEN_GROTTO_GRASS_4 }, + { RC_DMT_STORMS_GROTTO_GRASS_1, RAND_INF_DMT_STORMS_GROTTO_GRASS_1 }, + { RC_DMT_STORMS_GROTTO_GRASS_2, RAND_INF_DMT_STORMS_GROTTO_GRASS_2 }, + { RC_DMT_STORMS_GROTTO_GRASS_3, RAND_INF_DMT_STORMS_GROTTO_GRASS_3 }, + { RC_DMT_STORMS_GROTTO_GRASS_4, RAND_INF_DMT_STORMS_GROTTO_GRASS_4 }, + { RC_DMT_COW_GROTTO_GRASS_1, RAND_INF_DMT_COW_GROTTO_GRASS_1 }, + { RC_DMT_COW_GROTTO_GRASS_2, RAND_INF_DMT_COW_GROTTO_GRASS_2 }, + { RC_DMC_UPPER_GROTTO_GRASS_1, RAND_INF_DMC_UPPER_GROTTO_GRASS_1 }, + { RC_DMC_UPPER_GROTTO_GRASS_2, RAND_INF_DMC_UPPER_GROTTO_GRASS_2 }, + { RC_DMC_UPPER_GROTTO_GRASS_3, RAND_INF_DMC_UPPER_GROTTO_GRASS_3 }, + { RC_DMC_UPPER_GROTTO_GRASS_4, RAND_INF_DMC_UPPER_GROTTO_GRASS_4 }, + { RC_ZR_OPEN_GROTTO_GRASS_1, RAND_INF_ZR_OPEN_GROTTO_GRASS_1 }, + { RC_ZR_OPEN_GROTTO_GRASS_2, RAND_INF_ZR_OPEN_GROTTO_GRASS_2 }, + { RC_ZR_OPEN_GROTTO_GRASS_3, RAND_INF_ZR_OPEN_GROTTO_GRASS_3 }, + { RC_ZR_OPEN_GROTTO_GRASS_4, RAND_INF_ZR_OPEN_GROTTO_GRASS_4 }, + // Dungeon Grass + { RC_DEKU_TREE_LOBBY_GRASS_1, RAND_INF_DEKU_TREE_LOBBY_GRASS_1 }, + { RC_DEKU_TREE_LOBBY_GRASS_2, RAND_INF_DEKU_TREE_LOBBY_GRASS_2 }, + { RC_DEKU_TREE_LOBBY_GRASS_3, RAND_INF_DEKU_TREE_LOBBY_GRASS_3 }, + { RC_DEKU_TREE_2F_GRASS_1, RAND_INF_DEKU_TREE_2F_GRASS_1 }, + { RC_DEKU_TREE_2F_GRASS_2, RAND_INF_DEKU_TREE_2F_GRASS_2 }, + { RC_DEKU_TREE_SLINGSHOT_GRASS_1, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_1 }, + { RC_DEKU_TREE_SLINGSHOT_GRASS_2, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_2 }, + { RC_DEKU_TREE_SLINGSHOT_GRASS_3, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_3 }, + { RC_DEKU_TREE_SLINGSHOT_GRASS_4, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_4 }, + { RC_DEKU_TREE_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_COMPASS_GRASS_1 }, + { RC_DEKU_TREE_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_COMPASS_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_3, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_3 }, + { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4 }, + { RC_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_TORCHES_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_TORCHES_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_LARVAE_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_LARVAE_GRASS_2 }, + { RC_DEKU_TREE_BEFORE_BOSS_GRASS_1, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_1 }, + { RC_DEKU_TREE_BEFORE_BOSS_GRASS_2, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_2 }, + { RC_DEKU_TREE_BEFORE_BOSS_GRASS_3, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_3 }, + { RC_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS, RAND_INF_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS }, + { RC_DODONGOS_CAVERN_BLADE_GRASS, RAND_INF_DODONGOS_CAVERN_BLADE_GRASS }, + { RC_DODONGOS_CAVERN_SINGLE_EYE_GRASS, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_GRASS }, + { RC_DODONGOS_CAVERN_BEFORE_BOSS_GRASS, RAND_INF_DODONGOS_CAVERN_BEFORE_BOSS_GRASS }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_1 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_2 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_3 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_4, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_4 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_5, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_5 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_6, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_6 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3 }, + // MQ Dungeon Grass + { RC_DEKU_TREE_MQ_LOBBY_GRASS_1, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_1 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_2, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_2 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_3, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_3 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_4, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_4 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_5, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_5 }, + { RC_DEKU_TREE_MQ_2F_GRASS_1, RAND_INF_DEKU_TREE_MQ_2F_GRASS_1 }, + { RC_DEKU_TREE_MQ_2F_GRASS_2, RAND_INF_DEKU_TREE_MQ_2F_GRASS_2 }, + { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_1, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_1 }, + { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_2, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_2 }, + { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_3, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_3 }, + { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_4, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_4 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_1 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_2 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_3, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_3 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_4, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_4 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_5, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_5 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_6, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_6 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_7, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_7 }, + { RC_DEKU_TREE_MQ_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_1 }, + { RC_DEKU_TREE_MQ_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_2 }, + { RC_DEKU_TREE_MQ_COMPASS_GRASS_3, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_3 }, + { RC_DEKU_TREE_MQ_COMPASS_GRASS_4, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3 }, + { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3 }, + { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_3 }, + { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_3 }, + { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5 }, + { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_3 }, + { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1 }, + { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2 }, + { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3 }, + { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1 }, + { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2 }, + { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3 }, + { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_4, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_4 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_GRASS, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_GRASS }, + { RC_DODONGOS_CAVERN_MQ_BACK_POE_GRASS, RAND_INF_DODONGOS_CAVERN_MQ_BACK_POE_GRASS }, + { RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1, RAND_INF_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1 }, + { RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2, RAND_INF_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_PIT_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_PIT_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3 }, + { RC_JABU_JABUS_BELLY_MQ_JIGGLIES_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_GRASS }, + { RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS }, + { RC_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS }, + { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_3 }, + { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_4, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_4 }, + // Shared Dungeon Grass + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_1, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_1 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_2, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_2 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_3, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_3 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_4, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_4 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_5, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_5 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_6, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_7, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8 }, + // End Grass + + { RC_KF_LINKS_HOUSE_POT, RAND_INF_KF_LINKS_HOUSE_POT }, + { RC_KF_TWINS_HOUSE_POT_1, RAND_INF_KF_TWINS_HOUSE_POT_1 }, + { RC_KF_TWINS_HOUSE_POT_2, RAND_INF_KF_TWINS_HOUSE_POT_2 }, + { RC_KF_BROTHERS_HOUSE_POT_1, RAND_INF_KF_BROTHERS_HOUSE_POT_1 }, + { RC_KF_BROTHERS_HOUSE_POT_2, RAND_INF_KF_BROTHERS_HOUSE_POT_2 }, + { RC_TH_BREAK_ROOM_FRONT_POT, RAND_INF_TH_BREAK_ROOM_FRONT_POT }, + { RC_TH_BREAK_ROOM_BACK_POT, RAND_INF_TH_BREAK_ROOM_BACK_POT }, + { RC_TH_KITCHEN_POT_1, RAND_INF_TH_KITCHEN_POT_1 }, + { RC_TH_KITCHEN_POT_2, RAND_INF_TH_KITCHEN_POT_2 }, + { RC_TH_1_TORCH_CELL_RIGHT_POT, RAND_INF_TH_1_TORCH_CELL_RIGHT_POT }, + { RC_TH_1_TORCH_CELL_MID_POT, RAND_INF_TH_1_TORCH_CELL_MID_POT }, + { RC_TH_1_TORCH_CELL_LEFT_POT, RAND_INF_TH_1_TORCH_CELL_LEFT_POT }, + { RC_TH_STEEP_SLOPE_RIGHT_POT, RAND_INF_TH_STEEP_SLOPE_RIGHT_POT }, + { RC_TH_STEEP_SLOPE_LEFT_POT, RAND_INF_TH_STEEP_SLOPE_LEFT_POT }, + { RC_TH_NEAR_DOUBLE_CELL_RIGHT_POT, RAND_INF_TH_NEAR_DOUBLE_CELL_RIGHT_POT }, + { RC_TH_NEAR_DOUBLE_CELL_MID_POT, RAND_INF_TH_NEAR_DOUBLE_CELL_MID_POT }, + { RC_TH_NEAR_DOUBLE_CELL_LEFT_POT, RAND_INF_NEAR_DOUBLE_CELL_LEFT_POT }, + { RC_TH_RIGHTMOST_JAILED_POT, RAND_INF_TH_RIGHTMOST_JAILED_POT }, + { RC_TH_RIGHT_MIDDLE_JAILED_POT, RAND_INF_TH_RIGHT_MIDDLE_JAILED_POT }, + { RC_TH_LEFT_MIDDLE_JAILED_POT, RAND_INF_TH_LEFT_MIDDLE_JAILED_POT }, + { RC_TH_LEFTMOST_JAILED_POT, RAND_INF_TH_LEFTMOST_JAILED_POT }, + { RC_WASTELAND_NEAR_GS_POT_1, RAND_INF_WASTELAND_NEAR_GS_POT_1 }, + { RC_WASTELAND_NEAR_GS_POT_2, RAND_INF_WASTELAND_NEAR_GS_POT_2 }, + { RC_WASTELAND_NEAR_GS_POT_3, RAND_INF_WASTELAND_NEAR_GS_POT_3 }, + { RC_WASTELAND_NEAR_GS_POT_4, RAND_INF_WASTELAND_NEAR_GS_POT_4 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_1, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_2, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_3, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_4, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_5, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_6, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_7, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_8, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_9, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_10, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_11, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_12, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_13, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_14, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_15, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_16, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_17, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_18, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_19, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_20, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_21, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_22, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_23, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_24, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_25, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_26, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_27, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_28, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_29, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_30, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_31, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_32, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_33, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_34, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_35, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_36, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_37, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_38, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_39, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_40, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_41, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_42, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_43, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_44, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_1, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_2, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_3, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_4, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_5, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_6, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_7, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_8, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_9, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_10, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_11, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_1, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_2, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_3, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3 }, + { RC_KAK_NEAR_POTION_SHOP_POT_1, RAND_INF_KAK_NEAR_POTION_SHOP_POT_1 }, + { RC_KAK_NEAR_POTION_SHOP_POT_2, RAND_INF_KAK_NEAR_POTION_SHOP_POT_2 }, + { RC_KAK_NEAR_POTION_SHOP_POT_3, RAND_INF_KAK_NEAR_POTION_SHOP_POT_3 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_1, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_2, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_3, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_1, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_2, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_3, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3 }, + { RC_KAK_NEAR_MEDICINE_SHOP_POT_1, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1 }, + { RC_KAK_NEAR_MEDICINE_SHOP_POT_2, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2 }, + { RC_GY_DAMPES_GRAVE_POT_1, RAND_INF_GY_DAMPES_GRAVE_POT_1 }, + { RC_GY_DAMPES_GRAVE_POT_2, RAND_INF_GY_DAMPES_GRAVE_POT_2 }, + { RC_GY_DAMPES_GRAVE_POT_3, RAND_INF_GY_DAMPES_GRAVE_POT_3 }, + { RC_GY_DAMPES_GRAVE_POT_4, RAND_INF_GY_DAMPES_GRAVE_POT_4 }, + { RC_GY_DAMPES_GRAVE_POT_5, RAND_INF_GY_DAMPES_GRAVE_POT_5 }, + { RC_GY_DAMPES_GRAVE_POT_6, RAND_INF_GY_DAMPES_GRAVE_POT_6 }, + { RC_GC_LOWER_STAIRCASE_POT_1, RAND_INF_GC_LOWER_STAIRCASE_POT_1 }, + { RC_GC_LOWER_STAIRCASE_POT_2, RAND_INF_GC_LOWER_STAIRCASE_POT_2 }, + { RC_GC_UPPER_STAIRCASE_POT_1, RAND_INF_GC_UPPER_STAIRCASE_POT_1 }, + { RC_GC_UPPER_STAIRCASE_POT_2, RAND_INF_GC_UPPER_STAIRCASE_POT_2 }, + { RC_GC_UPPER_STAIRCASE_POT_3, RAND_INF_GC_UPPER_STAIRCASE_POT_3 }, + { RC_GC_MEDIGORON_POT_1, RAND_INF_GC_MEDIGORON_POT_1 }, + { RC_GC_DARUNIA_POT_1, RAND_INF_GC_DARUNIA_POT_1 }, + { RC_GC_DARUNIA_POT_2, RAND_INF_GC_DARUNIA_POT_2 }, + { RC_GC_DARUNIA_POT_3, RAND_INF_GC_DARUNIA_POT_3 }, + { RC_DMC_NEAR_GC_POT_1, RAND_INF_DMC_NEAR_GC_POT_1 }, + { RC_DMC_NEAR_GC_POT_2, RAND_INF_DMC_NEAR_GC_POT_2 }, + { RC_DMC_NEAR_GC_POT_3, RAND_INF_DMC_NEAR_GC_POT_3 }, + { RC_DMC_NEAR_GC_POT_4, RAND_INF_DMC_NEAR_GC_POT_4 }, + { RC_ZD_NEAR_SHOP_POT_1, RAND_INF_ZD_NEAR_SHOP_POT_1 }, + { RC_ZD_NEAR_SHOP_POT_2, RAND_INF_ZD_NEAR_SHOP_POT_2 }, + { RC_ZD_NEAR_SHOP_POT_3, RAND_INF_ZD_NEAR_SHOP_POT_3 }, + { RC_ZD_NEAR_SHOP_POT_4, RAND_INF_ZD_NEAR_SHOP_POT_4 }, + { RC_ZD_NEAR_SHOP_POT_5, RAND_INF_ZD_NEAR_SHOP_POT_5 }, + { RC_ZF_HIDDEN_CAVE_POT_1, RAND_INF_ZF_HIDDEN_CAVE_POT_1 }, + { RC_ZF_HIDDEN_CAVE_POT_2, RAND_INF_ZF_HIDDEN_CAVE_POT_2 }, + { RC_ZF_HIDDEN_CAVE_POT_3, RAND_INF_ZF_HIDDEN_CAVE_POT_3 }, + { RC_ZF_NEAR_JABU_POT_1, RAND_INF_ZF_NEAR_JABU_POT_1 }, + { RC_ZF_NEAR_JABU_POT_2, RAND_INF_ZF_NEAR_JABU_POT_2 }, + { RC_ZF_NEAR_JABU_POT_3, RAND_INF_ZF_NEAR_JABU_POT_3 }, + { RC_ZF_NEAR_JABU_POT_4, RAND_INF_ZF_NEAR_JABU_POT_4 }, + { RC_LLR_FRONT_POT_1, RAND_INF_LLR_FRONT_POT_1 }, + { RC_LLR_FRONT_POT_2, RAND_INF_LLR_FRONT_POT_2 }, + { RC_LLR_FRONT_POT_3, RAND_INF_LLR_FRONT_POT_3 }, + { RC_LLR_FRONT_POT_4, RAND_INF_LLR_FRONT_POT_4 }, + { RC_LLR_RAIN_SHED_POT_1, RAND_INF_LLR_RAIN_SHED_POT_1 }, + { RC_LLR_RAIN_SHED_POT_2, RAND_INF_LLR_RAIN_SHED_POT_2 }, + { RC_LLR_RAIN_SHED_POT_3, RAND_INF_LLR_RAIN_SHED_POT_3 }, + { RC_LLR_TALONS_HOUSE_POT_1, RAND_INF_LLR_TALONS_HOUSE_POT_1 }, + { RC_LLR_TALONS_HOUSE_POT_2, RAND_INF_LLR_TALONS_HOUSE_POT_2 }, + { RC_LLR_TALONS_HOUSE_POT_3, RAND_INF_LLR_TALONS_HOUSE_POT_3 }, + { RC_HF_COW_GROTTO_POT_1, RAND_INF_HF_COW_GROTTO_POT_1 }, + { RC_HF_COW_GROTTO_POT_2, RAND_INF_HF_COW_GROTTO_POT_2 }, + { RC_HC_STORMS_GROTTO_POT_1, RAND_INF_HC_STORMS_GROTTO_POT_1 }, + { RC_HC_STORMS_GROTTO_POT_2, RAND_INF_HC_STORMS_GROTTO_POT_2 }, + { RC_HC_STORMS_GROTTO_POT_3, RAND_INF_HC_STORMS_GROTTO_POT_3 }, + { RC_HC_STORMS_GROTTO_POT_4, RAND_INF_HC_STORMS_GROTTO_POT_4 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4 }, + { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1 }, + { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2 }, + { RC_DODONGOS_CAVERN_BLADE_POT_1, RAND_INF_DODONGOS_CAVERN_BLADE_POT_1 }, + { RC_DODONGOS_CAVERN_BLADE_POT_2, RAND_INF_DODONGOS_CAVERN_BLADE_POT_2 }, + { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1 }, + { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_1, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_2, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_3, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_4, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_5, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_6, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_1, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_2, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_3, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5 }, + { RC_FOREST_TEMPLE_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_LOBBY_POT_1 }, + { RC_FOREST_TEMPLE_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_LOBBY_POT_2 }, + { RC_FOREST_TEMPLE_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_LOBBY_POT_3 }, + { RC_FOREST_TEMPLE_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_LOBBY_POT_4 }, + { RC_FOREST_TEMPLE_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_LOBBY_POT_5 }, + { RC_FOREST_TEMPLE_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_LOBBY_POT_6 }, + { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1 }, + { RC_FOREST_TEMPLE_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3 }, + { RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1 }, + { RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2 }, + { RC_WATER_TEMPLE_TORCH_POT_1, RAND_INF_WATER_TEMPLE_TORCH_POT_1 }, + { RC_WATER_TEMPLE_TORCH_POT_2, RAND_INF_WATER_TEMPLE_TORCH_POT_2 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3 }, + { RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1 }, + { RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_1, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_2, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_3, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_4, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4 }, + { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1 }, + { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2 }, + { RC_WATER_TEMPLE_RIVER_POT_1, RAND_INF_WATER_TEMPLE_RIVER_POT_1 }, + { RC_WATER_TEMPLE_RIVER_POT_2, RAND_INF_WATER_TEMPLE_RIVER_POT_2 }, + { RC_WATER_TEMPLE_LIKE_LIKE_POT_1, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1 }, + { RC_WATER_TEMPLE_LIKE_LIKE_POT_2, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2 }, + { RC_WATER_TEMPLE_BOSS_KEY_POT_1, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1 }, + { RC_WATER_TEMPLE_BOSS_KEY_POT_2, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2 }, + { RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5 }, + { RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1 }, + { RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4 }, + { RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1 }, + { RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2 }, + { RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1 }, + { RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4 }, + { RC_SPIRIT_TEMPLE_LOBBY_POT_1, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1 }, + { RC_SPIRIT_TEMPLE_LOBBY_POT_2, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_1, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_2, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_3, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_4, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4 }, + { RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1 }, + { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1 }, + { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6 }, + { RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1 }, + { RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4 }, + { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_1, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_2, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_3, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_4, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_5, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_6, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_7, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_8, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_9, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_10, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_11, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_12, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_13, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_14, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_15, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_16, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_17, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_18, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT }, + { RC_ICE_CAVERN_HALL_POT_1, RAND_INF_ICE_CAVERN_HALL_POT_1 }, + { RC_ICE_CAVERN_HALL_POT_2, RAND_INF_ICE_CAVERN_HALL_POT_2 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_1, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_2, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_3, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3 }, + { RC_ICE_CAVERN_NEAR_END_POT_1, RAND_INF_ICE_CAVERN_NEAR_END_POT_1 }, + { RC_ICE_CAVERN_NEAR_END_POT_2, RAND_INF_ICE_CAVERN_NEAR_END_POT_2 }, + { RC_ICE_CAVERN_FROZEN_POT_1, RAND_INF_ICE_CAVERN_FROZEN_POT_1 }, + + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6 }, + { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3 }, + { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1 }, + { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2 }, + { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3 }, + { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3 }, + { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4 }, + { RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT }, + { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3 }, + { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1 }, + { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2 }, + { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1 }, + { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1 }, + { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2 }, + { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1 }, + { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2 }, + { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3 }, + { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4 }, + { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5 }, + { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8 }, + { RC_ICE_CAVERN_MQ_ENTRANCE_POT, RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT }, + { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1 }, + { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4 }, + { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1 }, + { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2 }, + { RC_ICE_CAVERN_MQ_COMPASS_POT_1, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1 }, + { RC_ICE_CAVERN_MQ_COMPASS_POT_2, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5 }, + { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3 }, + { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1 }, + { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5 }, + { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1 }, + { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2 }, + { RC_WATER_TEMPLE_MQ_RIVER_POT_1, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1 }, + { RC_WATER_TEMPLE_MQ_RIVER_POT_2, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2 }, + { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1 }, + { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3 }, + { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1 }, + { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4 }, + { RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2 }, + // Crates + { + RC_GV_FREESTANDING_POH_CRATE, + RAND_INF_GV_FREESTANDING_POH_CRATE, + }, + { + RC_GV_NEAR_COW_CRATE, + RAND_INF_GV_NEAR_COW_CRATE, + }, + { + RC_GV_CRATE_BRIDGE_1, + RAND_INF_GV_CRATE_BRIDGE_1, + }, + { + RC_GV_CRATE_BRIDGE_2, + RAND_INF_GV_CRATE_BRIDGE_2, + }, + { + RC_GV_CRATE_BRIDGE_3, + RAND_INF_GV_CRATE_BRIDGE_3, + }, + { + RC_GV_CRATE_BRIDGE_4, + RAND_INF_GV_CRATE_BRIDGE_4, + }, + { + RC_GF_ABOVE_JAIL_CRATE, + RAND_INF_GF_ABOVE_JAIL_CRATE, + }, + { + RC_GF_SOUTHMOST_CENTER_CRATE, + RAND_INF_GF_SOUTHMOST_CENTER_CRATE, + }, + { + RC_GF_MID_SOUTH_CENTER_CRATE, + RAND_INF_GF_MID_SOUTH_CENTER_CRATE, + }, + { + RC_GF_MID_NORTH_CENTER_CRATE, + RAND_INF_GF_MID_NORTH_CENTER_CRATE, + }, + { + RC_GF_NORTHMOST_CENTER_CRATE, + RAND_INF_GF_NORTHMOST_CENTER_CRATE, + }, + { + RC_GF_OUTSKIRTS_NE_CRATE, + RAND_INF_GF_OUTSKIRTS_NE_CRATE, + }, + { + RC_GF_OUTSKIRTS_NW_CRATE, + RAND_INF_GF_OUTSKIRTS_NW_CRATE, + }, + { + RC_GF_HBA_RANGE_CRATE_1, + RAND_INF_GF_HBA_RANGE_CRATE_1, + }, + { + RC_GF_HBA_RANGE_CRATE_2, + RAND_INF_GF_HBA_RANGE_CRATE_2, + }, + { + RC_GF_HBA_RANGE_CRATE_3, + RAND_INF_GF_HBA_RANGE_CRATE_3, + }, + { + RC_GF_HBA_RANGE_CRATE_4, + RAND_INF_GF_HBA_RANGE_CRATE_4, + }, + { + RC_GF_HBA_RANGE_CRATE_5, + RAND_INF_GF_HBA_RANGE_CRATE_5, + }, + { + RC_GF_HBA_RANGE_CRATE_6, + RAND_INF_GF_HBA_RANGE_CRATE_6, + }, + { + RC_GF_HBA_RANGE_CRATE_7, + RAND_INF_GF_HBA_RANGE_CRATE_7, + }, + { + RC_GF_HBA_CANOPY_EAST_CRATE, + RAND_INF_GF_HBA_CANOPY_EAST_CRATE, + }, + { + RC_GF_HBA_CANOPY_WEST_CRATE, + RAND_INF_GF_HBA_CANOPY_WEST_CRATE, + }, + { + RC_GF_NORTH_TARGET_EAST_CRATE, + RAND_INF_GF_NORTH_TARGET_EAST_CRATE, + }, + { + RC_GF_NORTH_TARGET_WEST_CRATE, + RAND_INF_GF_NORTH_TARGET_WEST_CRATE, + }, + { + RC_GF_NORTH_TARGET_CHILD_CRATE, + RAND_INF_GF_NORTH_TARGET_CHILD_CRATE, + }, + { + RC_GF_SOUTH_TARGET_EAST_CRATE, + RAND_INF_GF_SOUTH_TARGET_EAST_CRATE, + }, + { + RC_GF_SOUTH_TARGET_WEST_CRATE, + RAND_INF_GF_SOUTH_TARGET_WEST_CRATE, + }, + { + RC_TH_NEAR_KITCHEN_LEFTMOST_CRATE, + RAND_INF_TH_NEAR_KITCHEN_LEFTMOST_CRATE, + }, + { + RC_TH_NEAR_KITCHEN_MID_LEFT_CRATE, + RAND_INF_TH_NEAR_KITCHEN_MID_LEFT_CRATE, + }, + { + RC_TH_NEAR_KITCHEN_MID_RIGHT_CRATE, + RAND_INF_TH_NEAR_KITCHEN_MID_RIGHT_CRATE, + }, + { + RC_TH_NEAR_KITCHEN_RIGHTMOST_CRATE, + RAND_INF_TH_NEAR_KITCHEN_RIGHTMOST_CRATE, + }, + { + RC_TH_KITCHEN_CRATE, + RAND_INF_TH_KITCHEN_CRATE, + }, + { + RC_TH_BREAK_HALLWAY_OUTER_CRATE, + RAND_INF_TH_BREAK_HALLWAY_OUTER_CRATE, + }, + { + RC_TH_BREAK_HALLWAY_INNER_CRATE, + RAND_INF_TH_BREAK_HALLWAY_INNER_CRATE, + }, + { + RC_TH_BREAK_ROOM_RIGHT_CRATE, + RAND_INF_TH_BREAK_ROOM_RIGHT_CRATE, + }, + { + RC_TH_BREAK_ROOM_LEFT_CRATE, + RAND_INF_TH_BREAK_ROOM_LEFT_CRATE, + }, + { + RC_TH_1_TORCH_CELL_CRATE, + RAND_INF_TH_1_TORCH_CELL_CRATE, + }, + { + RC_TH_DEAD_END_CELL_CRATE, + RAND_INF_TH_DEAD_END_CELL_CRATE, + }, + { + RC_TH_DOUBLE_CELL_LEFT_CRATE, + RAND_INF_TH_DOUBLE_CELL_LEFT_CRATE, + }, + { + RC_TH_DOUBLE_CELL_RIGHT_CRATE, + RAND_INF_TH_DOUBLE_CELL_RIGHT_CRATE, + }, + { + RC_HW_BEFORE_QUICKSAND_CRATE, + RAND_INF_HW_BEFORE_QUICKSAND_CRATE, + }, + { + RC_HW_AFTER_QUICKSAND_CRATE_1, + RAND_INF_HW_AFTER_QUICKSAND_CRATE_1, + }, + { + RC_HW_AFTER_QUICKSAND_CRATE_2, + RAND_INF_HW_AFTER_QUICKSAND_CRATE_2, + }, + { + RC_HW_AFTER_QUICKSAND_CRATE_3, + RAND_INF_HW_AFTER_QUICKSAND_CRATE_3, + }, + { + RC_HW_NEAR_COLOSSUS_CRATE, + RAND_INF_HW_NEAR_COLOSSUS_CRATE, + }, + { + RC_MK_NEAR_BAZAAR_CRATE_1, + RAND_INF_MK_NEAR_BAZAAR_CRATE_1, + }, + { + RC_MK_NEAR_BAZAAR_CRATE_2, + RAND_INF_MK_NEAR_BAZAAR_CRATE_2, + }, + { + RC_MK_SHOOTING_GALLERY_CRATE_1, + RAND_INF_MK_SHOOTING_GALLERY_CRATE_1, + }, + { + RC_MK_SHOOTING_GALLERY_CRATE_2, + RAND_INF_MK_SHOOTING_GALLERY_CRATE_2, + }, + { + RC_MK_LOST_DOG_HOUSE_CRATE, + RAND_INF_MK_LOST_DOG_HOUSE_CRATE, + }, + { + RC_MK_GUARD_HOUSE_CRATE_1, + RAND_INF_MK_GUARD_HOUSE_CRATE_1, + }, + { + RC_MK_GUARD_HOUSE_CRATE_2, + RAND_INF_MK_GUARD_HOUSE_CRATE_2, + }, + { + RC_MK_GUARD_HOUSE_CRATE_3, + RAND_INF_MK_GUARD_HOUSE_CRATE_3, + }, + { + RC_MK_GUARD_HOUSE_CRATE_4, + RAND_INF_MK_GUARD_HOUSE_CRATE_4, + }, + { + RC_MK_GUARD_HOUSE_CRATE_5, + RAND_INF_MK_GUARD_HOUSE_CRATE_5, + }, + { + RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_1, + RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_1, + }, + { + RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_2, + RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_2, + }, + { + RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_3, + RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_3, + }, + { + RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_4, + RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_4, + }, + { + RC_KAK_NEAR_POTION_SHOP_ADULT_CRATE, + RAND_INF_KAK_NEAR_POTION_SHOP_ADULT_CRATE, + }, + { + RC_KAK_NEAR_SHOOTING_GALLERY_ADULT_CRATE, + RAND_INF_KAK_NEAR_SHOOTING_GALLERY_ADULT_CRATE, + }, + { + RC_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_1, + RAND_INF_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_1, + }, + { + RC_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_2, + RAND_INF_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_2, + }, + { + RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, + RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, + }, + { + RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, + RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, + }, + { + RC_KAK_NEAR_BAZAAR_ADULT_CRATE_1, + RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_1, + }, + { + RC_KAK_NEAR_BAZAAR_ADULT_CRATE_2, + RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_2, + }, + { + RC_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, + RAND_INF_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, + }, + { + RC_KAK_NEAR_GY_CHILD_CRATE, + RAND_INF_KAK_NEAR_GY_CHILD_CRATE, + }, + { + RC_KAK_NEAR_WINDMILL_CHILD_CRATE, + RAND_INF_KAK_NEAR_WINDMILL_CHILD_CRATE, + }, + { + RC_KAK_NEAR_FENCE_CHILD_CRATE, + RAND_INF_KAK_NEAR_FENCE_CHILD_CRATE, + }, + { + RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, + RAND_INF_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, + }, + { + RC_KAK_NEAR_BAZAAR_CHILD_CRATE, + RAND_INF_KAK_NEAR_BAZAAR_CHILD_CRATE, + }, + { + RC_GRAVEYARD_CRATE, + RAND_INF_GRAVEYARD_CRATE, + }, + { + RC_GC_MAZE_CRATE, + RAND_INF_GC_MAZE_CRATE, + }, + { + RC_DMC_CRATE, + RAND_INF_DMC_CRATE, + }, + { + RC_LLR_NEAR_TREE_CRATE, + RAND_INF_LLR_NEAR_TREE_CRATE, + }, + { + RC_LH_LAB_CRATE, + RAND_INF_LH_LAB_CRATE, + }, + + { + RC_DEKU_TREE_MQ_LOBBY_CRATE, + RAND_INF_DEKU_TREE_MQ_LOBBY_CRATE, + }, + { + RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_1, + RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_1, + }, + { + RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_2, + RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_3, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_3, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_4, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_4, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_5, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_5, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, + }, + { + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_3, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_3, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_4, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_4, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_5, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_5, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_6, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_6, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_7, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_7, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_8, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_8, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_9, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_9, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_10, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_10, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_11, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_11, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_12, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_12, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_13, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_13, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_14, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_14, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_7, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_7, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_UPPER_CRATE, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_UPPER_CRATE, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_UPPER_CRATE, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_UPPER_CRATE, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_HALL_CRATE, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_HALL_CRATE, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, + }, + { + RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, + RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, + }, + { + RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, + RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, + }, + { + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_1, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_1, + }, + { + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_2, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_2, + }, + { + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_3, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_3, + }, + { + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_4, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_4, + }, + { + RC_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, + }, + + { + RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, + RAND_INF_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, + }, + { + RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, + RAND_INF_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, + }, + { + RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, + RAND_INF_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, + }, + { + RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, + RAND_INF_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, + }, + { + RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, + RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, + }, + { + RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, + RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, + }, + + { + RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, + RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, + }, + { + RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, + RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, + }, + { + RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_1, + RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_1, + }, + { + RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_2, + RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_2, + }, + { + RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, + RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, + }, + { + RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, + RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, + }, + { + RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, + RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_SMALL_CRATE, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_SMALL_CRATE, + }, + { + RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_1, + RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_1, + }, + { + RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, + RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, + }, + { + RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, + RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, + }, + { + RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, + RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, + }, + { + RC_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, + RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, + }, + { + RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, + RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, + }, + { RC_KF_CIRCLE_ROCK_1, RAND_INF_KF_CIRCLE_ROCK_1 }, + { RC_KF_CIRCLE_ROCK_2, RAND_INF_KF_CIRCLE_ROCK_2 }, + { RC_KF_CIRCLE_ROCK_3, RAND_INF_KF_CIRCLE_ROCK_3 }, + { RC_KF_CIRCLE_ROCK_4, RAND_INF_KF_CIRCLE_ROCK_4 }, + { RC_KF_CIRCLE_ROCK_5, RAND_INF_KF_CIRCLE_ROCK_5 }, + { RC_KF_CIRCLE_ROCK_6, RAND_INF_KF_CIRCLE_ROCK_6 }, + { RC_KF_CIRCLE_ROCK_7, RAND_INF_KF_CIRCLE_ROCK_7 }, + { RC_KF_CIRCLE_ROCK_8, RAND_INF_KF_CIRCLE_ROCK_8 }, + { RC_KF_ROCK_BY_SARIAS_HOUSE, RAND_INF_KF_ROCK_BY_SARIAS_HOUSE }, + { RC_KF_ROCK_BEHIND_SARIAS_HOUSE, RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE }, + { RC_KF_ROCK_BY_MIDOS_HOUSE, RAND_INF_KF_ROCK_BY_MIDOS_HOUSE }, + { RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE }, + { RC_LW_BOULDER_BY_GORON_CITY, RAND_INF_LW_BOULDER_BY_GORON_CITY }, + { RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW }, + { RC_LW_RUPEE_BOULDER, RAND_INF_LW_RUPEE_BOULDER }, + { RC_HC_ROCK_1, RAND_INF_HC_ROCK_1 }, + { RC_HC_ROCK_2, RAND_INF_HC_ROCK_2 }, + { RC_HC_ROCK_3, RAND_INF_HC_ROCK_3 }, + { RC_HC_BOULDER, RAND_INF_HC_BOULDER }, + { RC_OGC_BRONZE_BOULDER_1, RAND_INF_OGC_BRONZE_BOULDER_1 }, + { RC_OGC_BRONZE_BOULDER_2, RAND_INF_OGC_BRONZE_BOULDER_2 }, + { RC_OGC_BRONZE_BOULDER_3, RAND_INF_OGC_BRONZE_BOULDER_3 }, + { RC_OGC_SILVER_BOULDER_1, RAND_INF_OGC_SILVER_BOULDER_1 }, + { RC_OGC_SILVER_BOULDER_2, RAND_INF_OGC_SILVER_BOULDER_2 }, + { RC_OGC_SILVER_BOULDER_3, RAND_INF_OGC_SILVER_BOULDER_3 }, + { RC_OGC_SILVER_BOULDER_4, RAND_INF_OGC_SILVER_BOULDER_4 }, + { RC_DMC_CIRCLE_ROCK_1, RAND_INF_DMC_CIRCLE_ROCK_1 }, + { RC_DMC_CIRCLE_ROCK_2, RAND_INF_DMC_CIRCLE_ROCK_2 }, + { RC_DMC_CIRCLE_ROCK_3, RAND_INF_DMC_CIRCLE_ROCK_3 }, + { RC_DMC_CIRCLE_ROCK_4, RAND_INF_DMC_CIRCLE_ROCK_4 }, + { RC_DMC_CIRCLE_ROCK_5, RAND_INF_DMC_CIRCLE_ROCK_5 }, + { RC_DMC_CIRCLE_ROCK_6, RAND_INF_DMC_CIRCLE_ROCK_6 }, + { RC_DMC_CIRCLE_ROCK_7, RAND_INF_DMC_CIRCLE_ROCK_7 }, + { RC_DMC_CIRCLE_ROCK_8, RAND_INF_DMC_CIRCLE_ROCK_8 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_1, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_2, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_3, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_4, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_5, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5 }, + { RC_DMC_GOSSIP_ROCK_1, RAND_INF_DMC_GOSSIP_ROCK_1 }, + { RC_DMC_GOSSIP_ROCK_2, RAND_INF_DMC_GOSSIP_ROCK_2 }, + { RC_DMC_BOULDER_1, RAND_INF_DMC_BOULDER_1 }, + { RC_DMC_BOULDER_2, RAND_INF_DMC_BOULDER_2 }, + { RC_DMC_BOULDER_3, RAND_INF_DMC_BOULDER_3 }, + { RC_DMC_BRONZE_BOULDER_1, RAND_INF_DMC_BRONZE_BOULDER_1 }, + { RC_DMC_BRONZE_BOULDER_2, RAND_INF_DMC_BRONZE_BOULDER_2 }, + { RC_DMC_BRONZE_BOULDER_3, RAND_INF_DMC_BRONZE_BOULDER_3 }, + { RC_DMC_BRONZE_BOULDER_SHORTCUT, RAND_INF_DMC_BRONZE_BOULDER_SHORTCUT }, + { RC_GV_SILVER_BOULDER, RAND_INF_GV_SILVER_BOULDER }, + { RC_GV_ROCK_1, RAND_INF_GV_ROCK_1 }, + { RC_GV_ROCK_2, RAND_INF_GV_ROCK_2 }, + { RC_GV_ROCK_3, RAND_INF_GV_ROCK_3 }, + { RC_GV_UNDERWATER_ROCK_1, RAND_INF_GV_UNDERWATER_ROCK_1 }, + { RC_GV_UNDERWATER_ROCK_2, RAND_INF_GV_UNDERWATER_ROCK_2 }, + { RC_GV_UNDERWATER_ROCK_3, RAND_INF_GV_UNDERWATER_ROCK_3 }, + { RC_GV_ROCK_ACROSS_BRIDGE_1, RAND_INF_GV_ROCK_ACROSS_BRIDGE_1 }, + { RC_GV_ROCK_ACROSS_BRIDGE_2, RAND_INF_GV_ROCK_ACROSS_BRIDGE_2 }, + { RC_GV_ROCK_ACROSS_BRIDGE_3, RAND_INF_GV_ROCK_ACROSS_BRIDGE_3 }, + { RC_GV_ROCK_ACROSS_BRIDGE_4, RAND_INF_GV_ROCK_ACROSS_BRIDGE_4 }, + { RC_GV_BOULDER_1, RAND_INF_GV_BOULDER_1 }, + { RC_GV_BOULDER_2, RAND_INF_GV_BOULDER_2 }, + { RC_GV_BOULDER_ACROSS_BRIDGE, RAND_INF_GV_BOULDER_ACROSS_BRIDGE }, + { RC_GV_BRONZE_BOULDER_1, RAND_INF_GV_BRONZE_BOULDER_1 }, + { RC_GV_BRONZE_BOULDER_2, RAND_INF_GV_BRONZE_BOULDER_2 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6 }, + { RC_HF_SILVER_BOULDER, RAND_INF_HF_SILVER_BOULDER }, + { RC_HF_ROCK_1, RAND_INF_HF_ROCK_1 }, + { RC_HF_ROCK_2, RAND_INF_HF_ROCK_2 }, + { RC_HF_ROCK_3, RAND_INF_HF_ROCK_3 }, + { RC_HF_ROCK_4, RAND_INF_HF_ROCK_4 }, + { RC_HF_ROCK_5, RAND_INF_HF_ROCK_5 }, + { RC_HF_ROCK_6, RAND_INF_HF_ROCK_6 }, + { RC_HF_ROCK_7, RAND_INF_HF_ROCK_7 }, + { RC_HF_ROCK_8, RAND_INF_HF_ROCK_8 }, + { RC_HF_BOULDER_NORTH, RAND_INF_HF_BOULDER_NORTH }, + { RC_HF_BOULDER_BY_MARKET, RAND_INF_HF_BOULDER_BY_MARKET }, + { RC_HF_BOULDER_SOUTH, RAND_INF_HF_BOULDER_SOUTH }, + { RC_HF_BRONZE_BOULDER_1, RAND_INF_HF_BRONZE_BOULDER_1 }, + { RC_HF_BRONZE_BOULDER_2, RAND_INF_HF_BRONZE_BOULDER_2 }, + { RC_HF_BRONZE_BOULDER_3, RAND_INF_HF_BRONZE_BOULDER_3 }, + { RC_HF_BRONZE_BOULDER_4, RAND_INF_HF_BRONZE_BOULDER_4 }, + { RC_KAK_SILVER_BOULDER, RAND_INF_KAK_SILVER_BOULDER }, + { RC_KAK_ROCK_1, RAND_INF_KAK_ROCK_1 }, + { RC_KAK_ROCK_2, RAND_INF_KAK_ROCK_2 }, + { RC_GY_ROCK, RAND_INF_GY_ROCK }, + { RC_LH_ROCK, RAND_INF_LH_ROCK }, + { RC_ZD_CIRCLE_ROCK_1, RAND_INF_ZD_CIRCLE_ROCK_1 }, + { RC_ZD_CIRCLE_ROCK_2, RAND_INF_ZD_CIRCLE_ROCK_2 }, + { RC_ZD_CIRCLE_ROCK_3, RAND_INF_ZD_CIRCLE_ROCK_3 }, + { RC_ZD_CIRCLE_ROCK_4, RAND_INF_ZD_CIRCLE_ROCK_4 }, + { RC_ZD_CIRCLE_ROCK_5, RAND_INF_ZD_CIRCLE_ROCK_5 }, + { RC_ZD_CIRCLE_ROCK_6, RAND_INF_ZD_CIRCLE_ROCK_6 }, + { RC_ZD_CIRCLE_ROCK_7, RAND_INF_ZD_CIRCLE_ROCK_7 }, + { RC_ZD_CIRCLE_ROCK_8, RAND_INF_ZD_CIRCLE_ROCK_8 }, + { RC_ZF_BOULDER, RAND_INF_ZF_BOULDER }, + { RC_ZF_SILVER_BOULDER, RAND_INF_ZF_SILVER_BOULDER }, + { RC_ZF_UNDERGROUND_BOULDER, RAND_INF_ZF_UNDERGROUND_BOULDER }, + { RC_ZR_BOULDER_1, RAND_INF_ZR_BOULDER_1 }, + { RC_ZR_BOULDER_2, RAND_INF_ZR_BOULDER_2 }, + { RC_ZR_BOULDER_3, RAND_INF_ZR_BOULDER_3 }, + { RC_ZR_BOULDER_4, RAND_INF_ZR_BOULDER_4 }, + { RC_ZR_CIRCLE_ROCK_1, RAND_INF_ZR_CIRCLE_ROCK_1 }, + { RC_ZR_CIRCLE_ROCK_2, RAND_INF_ZR_CIRCLE_ROCK_2 }, + { RC_ZR_CIRCLE_ROCK_3, RAND_INF_ZR_CIRCLE_ROCK_3 }, + { RC_ZR_CIRCLE_ROCK_4, RAND_INF_ZR_CIRCLE_ROCK_4 }, + { RC_ZR_CIRCLE_ROCK_5, RAND_INF_ZR_CIRCLE_ROCK_5 }, + { RC_ZR_CIRCLE_ROCK_6, RAND_INF_ZR_CIRCLE_ROCK_6 }, + { RC_ZR_CIRCLE_ROCK_7, RAND_INF_ZR_CIRCLE_ROCK_7 }, + { RC_ZR_CIRCLE_ROCK_8, RAND_INF_ZR_CIRCLE_ROCK_8 }, + { RC_ZR_UPPER_CIRCLE_BOULDER, RAND_INF_ZR_UPPER_CIRCLE_BOULDER }, + { RC_ZR_UPPER_CIRCLE_ROCK_1, RAND_INF_ZR_UPPER_CIRCLE_ROCK_1 }, + { RC_ZR_UPPER_CIRCLE_ROCK_2, RAND_INF_ZR_UPPER_CIRCLE_ROCK_2 }, + { RC_ZR_UPPER_CIRCLE_ROCK_3, RAND_INF_ZR_UPPER_CIRCLE_ROCK_3 }, + { RC_ZR_UPPER_CIRCLE_ROCK_4, RAND_INF_ZR_UPPER_CIRCLE_ROCK_4 }, + { RC_ZR_UPPER_CIRCLE_ROCK_5, RAND_INF_ZR_UPPER_CIRCLE_ROCK_5 }, + { RC_ZR_UPPER_CIRCLE_ROCK_6, RAND_INF_ZR_UPPER_CIRCLE_ROCK_6 }, + { RC_ZR_UPPER_CIRCLE_ROCK_7, RAND_INF_ZR_UPPER_CIRCLE_ROCK_7 }, + { RC_ZR_UPPER_CIRCLE_ROCK_8, RAND_INF_ZR_UPPER_CIRCLE_ROCK_8 }, + { RC_ZR_ROCK, RAND_INF_ZR_ROCK }, + { RC_ZR_UNDERWATER_ROCK_1, RAND_INF_ZR_UNDERWATER_ROCK_1 }, + { RC_ZR_UNDERWATER_ROCK_2, RAND_INF_ZR_UNDERWATER_ROCK_2 }, + { RC_ZR_UNDERWATER_ROCK_3, RAND_INF_ZR_UNDERWATER_ROCK_3 }, + { RC_ZR_UNDERWATER_ROCK_4, RAND_INF_ZR_UNDERWATER_ROCK_4 }, + { RC_DMT_ROCK_1, RAND_INF_DMT_ROCK_1 }, + { RC_DMT_ROCK_2, RAND_INF_DMT_ROCK_2 }, + { RC_DMT_ROCK_3, RAND_INF_DMT_ROCK_3 }, + { RC_DMT_ROCK_4, RAND_INF_DMT_ROCK_4 }, + { RC_DMT_ROCK_5, RAND_INF_DMT_ROCK_5 }, + { RC_DMT_SUMMIT_ROCK, RAND_INF_DMT_SUMMIT_ROCK }, + { RC_DMT_CIRCLE_ROCK_1, RAND_INF_DMT_CIRCLE_ROCK_1 }, + { RC_DMT_CIRCLE_ROCK_2, RAND_INF_DMT_CIRCLE_ROCK_2 }, + { RC_DMT_CIRCLE_ROCK_3, RAND_INF_DMT_CIRCLE_ROCK_3 }, + { RC_DMT_CIRCLE_ROCK_4, RAND_INF_DMT_CIRCLE_ROCK_4 }, + { RC_DMT_CIRCLE_ROCK_5, RAND_INF_DMT_CIRCLE_ROCK_5 }, + { RC_DMT_CIRCLE_ROCK_6, RAND_INF_DMT_CIRCLE_ROCK_6 }, + { RC_DMT_CIRCLE_ROCK_7, RAND_INF_DMT_CIRCLE_ROCK_7 }, + { RC_DMT_CIRCLE_ROCK_8, RAND_INF_DMT_CIRCLE_ROCK_8 }, + { RC_DMT_CHILD_BOULDER, RAND_INF_DMT_CHILD_BOULDER }, + { RC_DMT_BOULDER_1, RAND_INF_DMT_BOULDER_1 }, + { RC_DMT_BOULDER_2, RAND_INF_DMT_BOULDER_2 }, + { RC_DMT_COW_BOULDER, RAND_INF_DMT_COW_BOULDER }, + { RC_DMT_BRONZE_BOULDER_1, RAND_INF_DMT_BRONZE_BOULDER_1 }, + { RC_DMT_BRONZE_BOULDER_2, RAND_INF_DMT_BRONZE_BOULDER_2 }, + { RC_DMT_BRONZE_BOULDER_3, RAND_INF_DMT_BRONZE_BOULDER_3 }, + { RC_DMT_BRONZE_BOULDER_4, RAND_INF_DMT_BRONZE_BOULDER_4 }, + { RC_DMT_BRONZE_BOULDER_5, RAND_INF_DMT_BRONZE_BOULDER_5 }, + { RC_DMT_BRONZE_BOULDER_6, RAND_INF_DMT_BRONZE_BOULDER_6 }, + { RC_DMT_BRONZE_BOULDER_7, RAND_INF_DMT_BRONZE_BOULDER_7 }, + { RC_DMT_BRONZE_BOULDER_8, RAND_INF_DMT_BRONZE_BOULDER_8 }, + { RC_DMT_BRONZE_BOULDER_9, RAND_INF_DMT_BRONZE_BOULDER_9 }, + { RC_DMT_BRONZE_BOULDER_10, RAND_INF_DMT_BRONZE_BOULDER_10 }, + { RC_DMT_BRONZE_BOULDER_11, RAND_INF_DMT_BRONZE_BOULDER_11 }, + { RC_GC_LW_BOULDER_1, RAND_INF_GC_LW_BOULDER_1 }, + { RC_GC_LW_BOULDER_2, RAND_INF_GC_LW_BOULDER_2 }, + { RC_GC_LW_BOULDER_3, RAND_INF_GC_LW_BOULDER_3 }, + { RC_GC_ENTRANCE_BOULDER_1, RAND_INF_GC_ENTRANCE_BOULDER_1 }, + { RC_GC_ENTRANCE_BOULDER_2, RAND_INF_GC_ENTRANCE_BOULDER_2 }, + { RC_GC_ENTRANCE_BOULDER_3, RAND_INF_GC_ENTRANCE_BOULDER_3 }, + { RC_GC_MAZE_SILVER_BOULDER_1, RAND_INF_GC_MAZE_SILVER_BOULDER_1 }, + { RC_GC_MAZE_SILVER_BOULDER_2, RAND_INF_GC_MAZE_SILVER_BOULDER_2 }, + { RC_GC_MAZE_SILVER_BOULDER_3, RAND_INF_GC_MAZE_SILVER_BOULDER_3 }, + { RC_GC_MAZE_SILVER_BOULDER_4, RAND_INF_GC_MAZE_SILVER_BOULDER_4 }, + { RC_GC_MAZE_SILVER_BOULDER_5, RAND_INF_GC_MAZE_SILVER_BOULDER_5 }, + { RC_GC_MAZE_SILVER_BOULDER_6, RAND_INF_GC_MAZE_SILVER_BOULDER_6 }, + { RC_GC_MAZE_SILVER_BOULDER_7, RAND_INF_GC_MAZE_SILVER_BOULDER_7 }, + { RC_GC_MAZE_SILVER_BOULDER_8, RAND_INF_GC_MAZE_SILVER_BOULDER_8 }, + { RC_GC_MAZE_SILVER_BOULDER_9, RAND_INF_GC_MAZE_SILVER_BOULDER_9 }, + { RC_GC_MAZE_SILVER_BOULDER_10, RAND_INF_GC_MAZE_SILVER_BOULDER_10 }, + { RC_GC_MAZE_SILVER_BOULDER_11, RAND_INF_GC_MAZE_SILVER_BOULDER_11 }, + { RC_GC_MAZE_SILVER_BOULDER_12, RAND_INF_GC_MAZE_SILVER_BOULDER_12 }, + { RC_GC_MAZE_SILVER_BOULDER_13, RAND_INF_GC_MAZE_SILVER_BOULDER_13 }, + { RC_GC_MAZE_SILVER_BOULDER_14, RAND_INF_GC_MAZE_SILVER_BOULDER_14 }, + { RC_GC_MAZE_SILVER_BOULDER_15, RAND_INF_GC_MAZE_SILVER_BOULDER_15 }, + { RC_GC_MAZE_SILVER_BOULDER_16, RAND_INF_GC_MAZE_SILVER_BOULDER_16 }, + { RC_GC_MAZE_SILVER_BOULDER_17, RAND_INF_GC_MAZE_SILVER_BOULDER_17 }, + { RC_GC_MAZE_SILVER_BOULDER_18, RAND_INF_GC_MAZE_SILVER_BOULDER_18 }, + { RC_GC_MAZE_SILVER_BOULDER_19, RAND_INF_GC_MAZE_SILVER_BOULDER_19 }, + { RC_GC_MAZE_SILVER_BOULDER_20, RAND_INF_GC_MAZE_SILVER_BOULDER_20 }, + { RC_GC_MAZE_SILVER_BOULDER_21, RAND_INF_GC_MAZE_SILVER_BOULDER_21 }, + { RC_GC_MAZE_SILVER_BOULDER_22, RAND_INF_GC_MAZE_SILVER_BOULDER_22 }, + { RC_GC_MAZE_SILVER_BOULDER_23, RAND_INF_GC_MAZE_SILVER_BOULDER_23 }, + { RC_GC_MAZE_SILVER_BOULDER_24, RAND_INF_GC_MAZE_SILVER_BOULDER_24 }, + { RC_GC_MAZE_SILVER_BOULDER_25, RAND_INF_GC_MAZE_SILVER_BOULDER_25 }, + { RC_GC_MAZE_SILVER_BOULDER_26, RAND_INF_GC_MAZE_SILVER_BOULDER_26 }, + { RC_GC_MAZE_SILVER_BOULDER_27, RAND_INF_GC_MAZE_SILVER_BOULDER_27 }, + { RC_GC_MAZE_SILVER_BOULDER_28, RAND_INF_GC_MAZE_SILVER_BOULDER_28 }, + { RC_GC_MAZE_SILVER_BOULDER_29, RAND_INF_GC_MAZE_SILVER_BOULDER_29 }, + { RC_GC_MAZE_BOULDER_1, RAND_INF_GC_MAZE_BOULDER_1 }, + { RC_GC_MAZE_BOULDER_2, RAND_INF_GC_MAZE_BOULDER_2 }, + { RC_GC_MAZE_BOULDER_3, RAND_INF_GC_MAZE_BOULDER_3 }, + { RC_GC_MAZE_BOULDER_4, RAND_INF_GC_MAZE_BOULDER_4 }, + { RC_GC_MAZE_BOULDER_5, RAND_INF_GC_MAZE_BOULDER_5 }, + { RC_GC_MAZE_BOULDER_6, RAND_INF_GC_MAZE_BOULDER_6 }, + { RC_GC_MAZE_BOULDER_7, RAND_INF_GC_MAZE_BOULDER_7 }, + { RC_GC_MAZE_BOULDER_8, RAND_INF_GC_MAZE_BOULDER_8 }, + { RC_GC_MAZE_BOULDER_9, RAND_INF_GC_MAZE_BOULDER_9 }, + { RC_GC_MAZE_BOULDER_10, RAND_INF_GC_MAZE_BOULDER_10 }, + { RC_GC_MAZE_BRONZE_BOULDER_1, RAND_INF_GC_MAZE_BRONZE_BOULDER_1 }, + { RC_GC_MAZE_BRONZE_BOULDER_2, RAND_INF_GC_MAZE_BRONZE_BOULDER_2 }, + { RC_GC_MAZE_BRONZE_BOULDER_3, RAND_INF_GC_MAZE_BRONZE_BOULDER_3 }, + { RC_GC_MAZE_BRONZE_BOULDER_4, RAND_INF_GC_MAZE_BRONZE_BOULDER_4 }, + { RC_GC_MAZE_BRONZE_BOULDER_5, RAND_INF_GC_MAZE_BRONZE_BOULDER_5 }, + { RC_GC_MAZE_ROCK, RAND_INF_GC_MAZE_ROCK }, + { RC_COLOSSUS_SILVER_BOULDER, RAND_INF_COLOSSUS_SILVER_BOULDER }, + { RC_COLOSSUS_ROCK, RAND_INF_COLOSSUS_ROCK }, + { RC_COLOSSUS_CIRCLE_1_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8 }, + { RC_HC_STORMS_GROTTO_ROCK_1, RAND_INF_HC_STORMS_GROTTO_ROCK_1 }, + { RC_HC_STORMS_GROTTO_ROCK_2, RAND_INF_HC_STORMS_GROTTO_ROCK_2 }, + { RC_HC_STORMS_GROTTO_ROCK_3, RAND_INF_HC_STORMS_GROTTO_ROCK_3 }, + { RC_HC_STORMS_GROTTO_ROCK_4, RAND_INF_HC_STORMS_GROTTO_ROCK_4 }, + { RC_HC_STORMS_GROTTO_ROCK_5, RAND_INF_HC_STORMS_GROTTO_ROCK_5 }, + { RC_HC_STORMS_GROTTO_ROCK_6, RAND_INF_HC_STORMS_GROTTO_ROCK_6 }, + { RC_HC_STORMS_GROTTO_ROCK_7, RAND_INF_HC_STORMS_GROTTO_ROCK_7 }, + { RC_HC_STORMS_GROTTO_ROCK_8, RAND_INF_HC_STORMS_GROTTO_ROCK_8 }, + { RC_BOTW_BOULDER_1, RAND_INF_BOTW_BOULDER_1 }, + { RC_BOTW_BOULDER_2, RAND_INF_BOTW_BOULDER_2 }, + { RC_BOTW_BOULDER_3, RAND_INF_BOTW_BOULDER_3 }, + { RC_BOTW_BOULDER_4, RAND_INF_BOTW_BOULDER_4 }, + { RC_BOTW_BOULDER_5, RAND_INF_BOTW_BOULDER_5 }, + { RC_BOTW_BOULDER_6, RAND_INF_BOTW_BOULDER_6 }, + { RC_DEKU_TREE_MQ_BOULDER_1, RAND_INF_DEKU_TREE_MQ_BOULDER_1 }, + { RC_DEKU_TREE_MQ_BOULDER_2, RAND_INF_DEKU_TREE_MQ_BOULDER_2 }, + { RC_DEKU_TREE_MQ_BOULDER_3, RAND_INF_DEKU_TREE_MQ_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12 }, + { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3 }, + { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER }, + { RC_BOTW_MQ_BOULDER_1, RAND_INF_BOTW_MQ_BOULDER_1 }, + { RC_BOTW_MQ_BOULDER_2, RAND_INF_BOTW_MQ_BOULDER_2 }, + { RC_BOTW_MQ_BOULDER_3, RAND_INF_BOTW_MQ_BOULDER_3 }, + { RC_MARKET_TREE, RAND_INF_MARKET_TREE }, + { RC_HC_NEAR_GUARDS_TREE_1, RAND_INF_HC_NEAR_GUARDS_TREE_1 }, + { RC_HC_NEAR_GUARDS_TREE_2, RAND_INF_HC_NEAR_GUARDS_TREE_2 }, + { RC_HC_NEAR_GUARDS_TREE_3, RAND_INF_HC_NEAR_GUARDS_TREE_3 }, + { RC_HC_NEAR_GUARDS_TREE_4, RAND_INF_HC_NEAR_GUARDS_TREE_4 }, + { RC_HC_NEAR_GUARDS_TREE_5, RAND_INF_HC_NEAR_GUARDS_TREE_5 }, + { RC_HC_NEAR_GUARDS_TREE_6, RAND_INF_HC_NEAR_GUARDS_TREE_6 }, + { RC_HC_SKULLTULA_TREE, RAND_INF_HC_SKULLTULA_TREE }, + { RC_HC_GROTTO_TREE, RAND_INF_HC_GROTTO_TREE }, + { RC_HC_NL_TREE_1, RAND_INF_HC_NL_TREE_1 }, + { RC_HC_NL_TREE_2, RAND_INF_HC_NL_TREE_2 }, + { RC_HF_NEAR_KAK_TREE, RAND_INF_HF_NEAR_KAK_TREE }, + { RC_HF_NEAR_KAK_SMALL_TREE, RAND_INF_HF_NEAR_KAK_SMALL_TREE }, + { RC_HF_NEAR_MARKET_TREE_1, RAND_INF_HF_NEAR_MARKET_TREE_1 }, + { RC_HF_NEAR_MARKET_TREE_2, RAND_INF_HF_NEAR_MARKET_TREE_2 }, + { RC_HF_NEAR_MARKET_TREE_3, RAND_INF_HF_NEAR_MARKET_TREE_3 }, + { RC_HF_NEAR_LLR_TREE, RAND_INF_HF_NEAR_LLR_TREE }, + { RC_HF_NEAR_LH_TREE, RAND_INF_HF_NEAR_LH_TREE }, + { RC_HF_CHILD_NEAR_GV_TREE, RAND_INF_HF_CHILD_NEAR_GV_TREE }, + { RC_HF_ADULT_NEAR_GV_TREE, RAND_INF_HF_ADULT_NEAR_GV_TREE }, + { RC_HF_NEAR_ZR_TREE, RAND_INF_HF_NEAR_ZR_TREE }, + { RC_HF_NORTHWEST_TREE_1, RAND_INF_HF_NORTHWEST_TREE_1 }, + { RC_HF_NORTHWEST_TREE_2, RAND_INF_HF_NORTHWEST_TREE_2 }, + { RC_HF_NORTHWEST_TREE_3, RAND_INF_HF_NORTHWEST_TREE_3 }, + { RC_HF_NORTHWEST_TREE_4, RAND_INF_HF_NORTHWEST_TREE_4 }, + { RC_HF_NORTHWEST_TREE_5, RAND_INF_HF_NORTHWEST_TREE_5 }, + { RC_HF_NORTHWEST_TREE_6, RAND_INF_HF_NORTHWEST_TREE_6 }, + { RC_HF_EAST_TREE_1, RAND_INF_HF_EAST_TREE_1 }, + { RC_HF_EAST_TREE_2, RAND_INF_HF_EAST_TREE_2 }, + { RC_HF_EAST_TREE_3, RAND_INF_HF_EAST_TREE_3 }, + { RC_HF_EAST_TREE_4, RAND_INF_HF_EAST_TREE_4 }, + { RC_HF_EAST_TREE_5, RAND_INF_HF_EAST_TREE_5 }, + { RC_HF_EAST_TREE_6, RAND_INF_HF_EAST_TREE_6 }, + { RC_HF_SOUTHEAST_TREE_1, RAND_INF_HF_SOUTHEAST_TREE_1 }, + { RC_HF_SOUTHEAST_TREE_2, RAND_INF_HF_SOUTHEAST_TREE_2 }, + { RC_HF_SOUTHEAST_TREE_3, RAND_INF_HF_SOUTHEAST_TREE_3 }, + { RC_HF_SOUTHEAST_TREE_4, RAND_INF_HF_SOUTHEAST_TREE_4 }, + { RC_HF_SOUTHEAST_TREE_5, RAND_INF_HF_SOUTHEAST_TREE_5 }, + { RC_HF_SOUTHEAST_TREE_6, RAND_INF_HF_SOUTHEAST_TREE_6 }, + { RC_HF_SOUTHEAST_TREE_7, RAND_INF_HF_SOUTHEAST_TREE_7 }, + { RC_HF_SOUTHEAST_TREE_8, RAND_INF_HF_SOUTHEAST_TREE_8 }, + { RC_HF_SOUTHEAST_TREE_9, RAND_INF_HF_SOUTHEAST_TREE_9 }, + { RC_HF_SOUTHEAST_TREE_10, RAND_INF_HF_SOUTHEAST_TREE_10 }, + { RC_HF_SOUTHEAST_TREE_11, RAND_INF_HF_SOUTHEAST_TREE_11 }, + { RC_HF_SOUTHEAST_TREE_12, RAND_INF_HF_SOUTHEAST_TREE_12 }, + { RC_HF_SOUTHEAST_TREE_13, RAND_INF_HF_SOUTHEAST_TREE_13 }, + { RC_HF_SOUTHEAST_TREE_14, RAND_INF_HF_SOUTHEAST_TREE_14 }, + { RC_HF_SOUTHEAST_TREE_15, RAND_INF_HF_SOUTHEAST_TREE_15 }, + { RC_HF_SOUTHEAST_TREE_16, RAND_INF_HF_SOUTHEAST_TREE_16 }, + { RC_HF_SOUTHEAST_TREE_17, RAND_INF_HF_SOUTHEAST_TREE_17 }, + { RC_HF_SOUTHEAST_TREE_18, RAND_INF_HF_SOUTHEAST_TREE_18 }, + { RC_HF_SOUTHEAST_TREE_19, RAND_INF_HF_SOUTHEAST_TREE_19 }, + { RC_HF_CHILD_SOUTHEAST_TREE_1, RAND_INF_HF_CHILD_SOUTHEAST_TREE_1 }, + { RC_HF_CHILD_SOUTHEAST_TREE_2, RAND_INF_HF_CHILD_SOUTHEAST_TREE_2 }, + { RC_HF_CHILD_SOUTHEAST_TREE_3, RAND_INF_HF_CHILD_SOUTHEAST_TREE_3 }, + { RC_HF_CHILD_SOUTHEAST_TREE_4, RAND_INF_HF_CHILD_SOUTHEAST_TREE_4 }, + { RC_HF_CHILD_SOUTHEAST_TREE_5, RAND_INF_HF_CHILD_SOUTHEAST_TREE_5 }, + { RC_HF_CHILD_SOUTHEAST_TREE_6, RAND_INF_HF_CHILD_SOUTHEAST_TREE_6 }, + { RC_HF_TEKTITE_GROTTO_TREE, RAND_INF_HF_TEKTITE_GROTTO_TREE }, + { RC_ZF_TREE, RAND_INF_ZF_TREE }, + { RC_ZR_TREE, RAND_INF_ZR_TREE }, + { RC_KAK_TREE, RAND_INF_KAK_TREE }, + { RC_LLR_TREE, RAND_INF_LLR_TREE }, + { RC_HF_BUSH_NEAR_LAKE_1, RAND_INF_HF_BUSH_NEAR_LAKE_1 }, + { RC_HF_BUSH_NEAR_LAKE_2, RAND_INF_HF_BUSH_NEAR_LAKE_2 }, + { RC_HF_BUSH_NEAR_LAKE_3, RAND_INF_HF_BUSH_NEAR_LAKE_3 }, + { RC_HF_BUSH_NEAR_LAKE_4, RAND_INF_HF_BUSH_NEAR_LAKE_4 }, + { RC_HF_BUSH_NEAR_LAKE_5, RAND_INF_HF_BUSH_NEAR_LAKE_5 }, + { RC_HF_BUSH_NEAR_LAKE_6, RAND_INF_HF_BUSH_NEAR_LAKE_6 }, + { RC_HF_BUSH_NEAR_LAKE_7, RAND_INF_HF_BUSH_NEAR_LAKE_7 }, + { RC_HF_BUSH_NEAR_LAKE_8, RAND_INF_HF_BUSH_NEAR_LAKE_8 }, + { RC_HF_BUSH_NEAR_LAKE_9, RAND_INF_HF_BUSH_NEAR_LAKE_9 }, + { RC_HF_BUSH_NEAR_LAKE_10, RAND_INF_HF_BUSH_NEAR_LAKE_10 }, + { RC_HF_BUSH_NEAR_LAKE_11, RAND_INF_HF_BUSH_NEAR_LAKE_11 }, + { RC_HF_NORTHERN_BUSH_1, RAND_INF_HF_NORTHERN_BUSH_1 }, + { RC_HF_NORTHERN_BUSH_2, RAND_INF_HF_NORTHERN_BUSH_2 }, + { RC_HF_NORTHERN_BUSH_3, RAND_INF_HF_NORTHERN_BUSH_3 }, + { RC_HF_NORTHERN_BUSH_4, RAND_INF_HF_NORTHERN_BUSH_4 }, + { RC_HF_NORTHERN_BUSH_5, RAND_INF_HF_NORTHERN_BUSH_5 }, + { RC_HF_NORTHERN_BUSH_6, RAND_INF_HF_NORTHERN_BUSH_6 }, + { RC_HF_CHILD_NORTHERN_BUSH_1, RAND_INF_HF_CHILD_NORTHERN_BUSH_1 }, + { RC_HF_CHILD_NORTHERN_BUSH_2, RAND_INF_HF_CHILD_NORTHERN_BUSH_2 }, + { RC_HF_CHILD_NORTHERN_BUSH_3, RAND_INF_HF_CHILD_NORTHERN_BUSH_3 }, + { RC_HF_CHILD_NORTHERN_BUSH_4, RAND_INF_HF_CHILD_NORTHERN_BUSH_4 }, + { RC_HF_CHILD_NORTHERN_BUSH_5, RAND_INF_HF_CHILD_NORTHERN_BUSH_5 }, + { RC_HF_CHILD_NORTHERN_BUSH_6, RAND_INF_HF_CHILD_NORTHERN_BUSH_6 }, + { RC_HF_CHILD_NORTHERN_BUSH_7, RAND_INF_HF_CHILD_NORTHERN_BUSH_7 }, + { RC_HF_CHILD_NORTHERN_BUSH_8, RAND_INF_HF_CHILD_NORTHERN_BUSH_8 }, + { RC_HF_CHILD_NORTHERN_BUSH_9, RAND_INF_HF_CHILD_NORTHERN_BUSH_9 }, + { RC_HF_CHILD_NORTHERN_BUSH_10, RAND_INF_HF_CHILD_NORTHERN_BUSH_10 }, + { RC_HF_CHILD_NORTHERN_BUSH_11, RAND_INF_HF_CHILD_NORTHERN_BUSH_11 }, + { RC_HF_BUSH_BY_ROCKY_PATH_1, RAND_INF_HF_BUSH_BY_ROCKY_PATH_1 }, + { RC_HF_BUSH_BY_ROCKY_PATH_2, RAND_INF_HF_BUSH_BY_ROCKY_PATH_2 }, + { RC_HF_BUSH_BY_ROCKY_PATH_3, RAND_INF_HF_BUSH_BY_ROCKY_PATH_3 }, + { RC_HF_BUSH_BY_ROCKY_PATH_4, RAND_INF_HF_BUSH_BY_ROCKY_PATH_4 }, + { RC_HF_BUSH_BY_ROCKY_PATH_5, RAND_INF_HF_BUSH_BY_ROCKY_PATH_5 }, + { RC_HF_BUSH_BY_ROCKY_PATH_6, RAND_INF_HF_BUSH_BY_ROCKY_PATH_6 }, + { RC_HF_SOUTHERN_BUSH_1, RAND_INF_HF_SOUTHERN_BUSH_1 }, + { RC_HF_SOUTHERN_BUSH_2, RAND_INF_HF_SOUTHERN_BUSH_2 }, + { RC_HF_SOUTHERN_BUSH_3, RAND_INF_HF_SOUTHERN_BUSH_3 }, + { RC_HF_SOUTHERN_BUSH_4, RAND_INF_HF_SOUTHERN_BUSH_4 }, + { RC_HF_SOUTHERN_BUSH_5, RAND_INF_HF_SOUTHERN_BUSH_5 }, + { RC_HF_SOUTHERN_BUSH_6, RAND_INF_HF_SOUTHERN_BUSH_6 }, + { RC_HF_SOUTHERN_BUSH_7, RAND_INF_HF_SOUTHERN_BUSH_7 }, + { RC_HF_SOUTHERN_BUSH_8, RAND_INF_HF_SOUTHERN_BUSH_8 }, + { RC_HF_SOUTHERN_BUSH_9, RAND_INF_HF_SOUTHERN_BUSH_9 }, + { RC_HF_SOUTHERN_BUSH_10, RAND_INF_HF_SOUTHERN_BUSH_10 }, + { RC_HF_SOUTHERN_BUSH_11, RAND_INF_HF_SOUTHERN_BUSH_11 }, + { RC_HF_SOUTHERN_BUSH_12, RAND_INF_HF_SOUTHERN_BUSH_12 }, + { RC_HF_CHILD_SOUTHERN_BUSH_1, RAND_INF_HF_CHILD_SOUTHERN_BUSH_1 }, + { RC_HF_CHILD_SOUTHERN_BUSH_2, RAND_INF_HF_CHILD_SOUTHERN_BUSH_2 }, + { RC_HF_CHILD_SOUTHERN_BUSH_3, RAND_INF_HF_CHILD_SOUTHERN_BUSH_3 }, + { RC_HF_CHILD_SOUTHERN_BUSH_4, RAND_INF_HF_CHILD_SOUTHERN_BUSH_4 }, + { RC_HF_CHILD_SOUTHERN_BUSH_5, RAND_INF_HF_CHILD_SOUTHERN_BUSH_5 }, + { RC_HF_CHILD_SOUTHERN_BUSH_6, RAND_INF_HF_CHILD_SOUTHERN_BUSH_6 }, + { RC_HF_CHILD_SOUTHERN_BUSH_7, RAND_INF_HF_CHILD_SOUTHERN_BUSH_7 }, + { RC_HF_CHILD_SOUTHERN_BUSH_8, RAND_INF_HF_CHILD_SOUTHERN_BUSH_8 }, + { RC_HF_CHILD_SOUTHERN_BUSH_9, RAND_INF_HF_CHILD_SOUTHERN_BUSH_9 }, + { RC_HF_CHILD_SOUTHERN_BUSH_10, RAND_INF_HF_CHILD_SOUTHERN_BUSH_10 }, + { RC_HF_CHILD_SOUTHERN_BUSH_11, RAND_INF_HF_CHILD_SOUTHERN_BUSH_11 }, + { RC_HF_CHILD_SOUTHERN_BUSH_12, RAND_INF_HF_CHILD_SOUTHERN_BUSH_12 }, + { RC_ZF_BUSH_1, RAND_INF_ZF_BUSH_1 }, + { RC_ZF_BUSH_2, RAND_INF_ZF_BUSH_2 }, + { RC_ZF_BUSH_3, RAND_INF_ZF_BUSH_3 }, + { RC_ZF_BUSH_4, RAND_INF_ZF_BUSH_4 }, + { RC_ZF_BUSH_5, RAND_INF_ZF_BUSH_5 }, + { RC_ZF_BUSH_6, RAND_INF_ZF_BUSH_6 }, + { RC_KF_DEKU_TREE_RECTANGLE_SIGN, RAND_INF_KF_DEKU_TREE_RECTANGLE_SIGN }, + { RC_KF_STEPPING_STONES_RECTANGLE_SIGN, RAND_INF_KF_STEPPING_STONES_RECTANGLE_SIGN }, + { RC_KF_LINKS_HOUSE_RECTANGLE_SIGN, RAND_INF_KF_LINKS_HOUSE_RECTANGLE_SIGN }, + { RC_KF_FIRST_TRAINING_CENTER_RECTANGLE_SIGN, RAND_INF_KF_FIRST_TRAINING_CENTER_RECTANGLE_SIGN }, + { RC_KF_SECOND_TRAINING_CENTER_RECTANGLE_SIGN, RAND_INF_KF_SECOND_TRAINING_CENTER_RECTANGLE_SIGN }, + { RC_KF_AFTER_CRAWLSPACE_RECTANGLE_SIGN, RAND_INF_KF_AFTER_CRAWLSPACE_RECTANGLE_SIGN }, + { RC_KF_CRAWL_RECTANGLE_RECTANGLE_SIGN, RAND_INF_KF_CRAWL_RECTANGLE_RECTANGLE_SIGN }, + { RC_KF_LOST_WOODS_RECTANGLE_SIGN, RAND_INF_KF_LOST_WOODS_RECTANGLE_SIGN }, + { RC_KF_HOUSE_OF_TWINS_ARROW_SIGN, RAND_INF_KF_HOUSE_OF_TWINS_ARROW_SIGN }, + { RC_KF_SHOP_ARROW_SIGN, RAND_INF_KF_SHOP_ARROW_SIGN }, + { RC_KF_SARIAS_HOUSE_ARROW_SIGN, RAND_INF_KF_SARIAS_HOUSE_ARROW_SIGN }, + { RC_KF_LOST_WOODS_ARROW_SIGN, RAND_INF_KF_LOST_WOODS_ARROW_SIGN }, + { RC_KF_MIDOS_HOUSE_ARROW_SIGN, RAND_INF_KF_MIDOS_HOUSE_ARROW_SIGN }, + { RC_KF_TRAINING_CENTER_ENTRANCE_ARROW_SIGN, RAND_INF_KF_TRAINING_CENTER_ENTRANCE_ARROW_SIGN }, + { RC_KF_INNER_TRAINING_CENTER_ARROW_SIGN, RAND_INF_KF_INNER_TRAINING_CENTER_ARROW_SIGN }, + { RC_KF_KNOW_IT_ALL_BROTHERS_HOUSE_ARROW_SIGN, RAND_INF_KF_KNOW_IT_ALL_BROTHERS_HOUSE_ARROW_SIGN }, + { RC_KF_BOULDER_MAZE_RECTANGLE_SIGN, RAND_INF_KF_BOULDER_MAZE_RECTANGLE_SIGN }, + { RC_KF_LINKS_HOUSE_SIGN, RAND_INF_KF_LINKS_HOUSE_SIGN }, + { RC_LW_THEATER_RECTANGLE_SIGN, RAND_INF_LW_THEATER_RECTANGLE_SIGN }, + { RC_HF_CASTLE_EXIT_ARROW_SIGN, RAND_INF_HF_CASTLE_EXIT_ARROW_SIGN }, + { RC_HF_WOODED_EXIT_ARROW_SIGN, RAND_INF_HF_WOODED_EXIT_ARROW_SIGN }, + { RC_HF_ROCKY_PATH_EXIT_ARROW_SIGN, RAND_INF_HF_ROCKY_PATH_EXIT_ARROW_SIGN }, + { RC_HF_FENCED_ARROW_SIGN, RAND_INF_HF_FENCED_ARROW_SIGN }, + { RC_HF_CENTER_EXIT_ARROW_SIGN, RAND_INF_HF_CENTER_EXIT_ARROW_SIGN }, + { RC_HF_RIVER_EXIT_ARROW_SIGN, RAND_INF_HF_RIVER_EXIT_ARROW_SIGN }, + { RC_HF_STAIRS_EXIT_ARROW_SIGN, RAND_INF_HF_STAIRS_EXIT_ARROW_SIGN }, + { RC_MK_SHOOTING_GALLERY_RECTANGLE_SIGN, RAND_INF_MK_SHOOTING_GALLERY_RECTANGLE_SIGN }, + { RC_MK_MASK_SHOP_SIGN, RAND_INF_MK_MASK_SHOP_SIGN }, + { RC_TOT_ALTAR, RAND_INF_TOT_ALTAR }, + { RC_HC_DEAD_END_RECTANGLE_SIGN, RAND_INF_HC_DEAD_END_RECTANGLE_SIGN }, + { RC_KAK_GUARD_GATE_RECTANGLE_SIGN, RAND_INF_KAK_GUARD_GATE_RECTANGLE_SIGN }, + { RC_KAK_WELL_RECTANGLE_SIGN, RAND_INF_KAK_WELL_RECTANGLE_SIGN }, + { RC_KAK_SOUTHEAST_EXIT_ARROW_SIGN, RAND_INF_KAK_SOUTHEAST_EXIT_ARROW_SIGN }, + { RC_KAK_FRONT_GATE_ARROW_SIGN, RAND_INF_KAK_FRONT_GATE_ARROW_SIGN }, + { RC_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN, RAND_INF_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN }, + { RC_GY_ENTRANCE_RECTANGLE_SIGN, RAND_INF_GY_ENTRANCE_RECTANGLE_SIGN }, + { RC_GY_ENTRANCE_PLINTH, RAND_INF_GY_ENTRANCE_PLINTH }, + { RC_GY_RIGHT_OF_ROYAL_TOMB_GRAVE, RAND_INF_GY_RIGHT_OF_ROYAL_TOMB_GRAVE }, + { RC_GY_LEFT_OF_ROYAL_TOMB_GRAVE, RAND_INF_GY_LEFT_OF_ROYAL_TOMB_GRAVE }, + { RC_GY_ROYAL_TOMB_GRAVE, RAND_INF_GY_ROYAL_TOMB_GRAVE }, + { RC_DMT_ABOVE_DODONGO_RECTANGLE_SIGN, RAND_INF_DMT_ABOVE_DODONGO_RECTANGLE_SIGN }, + { RC_DMT_ADULT_CENTER_EXIT_ARROW_SIGN, RAND_INF_DMT_ADULT_CENTER_EXIT_ARROW_SIGN }, + { RC_DMT_CHILD_CENTER_EXIT_RECTANGLE_SIGN, RAND_INF_DMT_CHILD_CENTER_EXIT_RECTANGLE_SIGN }, + { RC_DMT_DODONGOS_CAVERN_RECTANGLE_SIGN, RAND_INF_DMT_DODONGOS_CAVERN_RECTANGLE_SIGN }, + { RC_DMT_CENTER_TRAIL_RECTANGLE_SIGN, RAND_INF_DMT_CENTER_TRAIL_RECTANGLE_SIGN }, + { RC_DMT_TO_UPPER_TRAIL_ARROW_SIGN, RAND_INF_DMT_TO_UPPER_TRAIL_ARROW_SIGN }, + { RC_DMT_UPPER_EXIT_ARROW_SIGN, RAND_INF_DMT_UPPER_EXIT_ARROW_SIGN }, + { RC_DMT_TO_CENTER_EXIT_ARROW_SIGN, RAND_INF_DMT_TO_CENTER_EXIT_ARROW_SIGN }, + { RC_DMT_LOWER_EXIT_ARROW_SIGN, RAND_INF_DMT_LOWER_EXIT_ARROW_SIGN }, + { RC_GC_CHILD_ROLLING_GORON_RECTANGLE_SIGN, RAND_INF_GC_CHILD_ROLLING_GORON_RECTANGLE_SIGN }, + { RC_DMC_BRIDGE_EXIT_ARROW_SIGN, RAND_INF_DMC_BRIDGE_EXIT_ARROW_SIGN }, + { RC_ZR_SLEEPLESS_WATERFALL_PLAQUE, RAND_INF_ZR_SLEEPLESS_WATERFALL_PLAQUE }, + { RC_ZD_SHOP_RECTANGLE_SIGN, RAND_INF_ZD_SHOP_RECTANGLE_SIGN }, + { RC_ZD_ENTRANCE_RECTANGLE_SIGN, RAND_INF_ZD_ENTRANCE_RECTANGLE_SIGN }, + { RC_ZD_KING_ZORA_PATH_ARROW_SIGN, RAND_INF_ZD_KING_ZORA_PATH_ARROW_SIGN }, + { RC_ZD_NEAR_KING_ZORA_RECTANGLE_SIGN, RAND_INF_ZD_NEAR_KING_ZORA_RECTANGLE_SIGN }, + { RC_ZD_NEAR_KING_ZORA_ARROW_SIGN, RAND_INF_ZD_NEAR_KING_ZORA_ARROW_SIGN }, + { RC_ZF_JABU_JABU_PLATFORM_RECTANGLE_SIGN, RAND_INF_ZF_JABU_JABU_PLATFORM_RECTANGLE_SIGN }, + { RC_ZF_ENTRANCE_ARROW_SIGN, RAND_INF_ZF_ENTRANCE_ARROW_SIGN }, + { RC_LH_LAB_RECTANGLE_SIGN, RAND_INF_LH_LAB_RECTANGLE_SIGN }, + { RC_LH_NORTH_EXIT_ARROW_SIGN, RAND_INF_LH_NORTH_EXIT_ARROW_SIGN }, + { RC_LH_FISHING_SIGN, RAND_INF_LH_FISHING_SIGN }, + { RC_LH_ISLAND_PEDESTAL, RAND_INF_LH_ISLAND_PEDESTAL }, + { RC_LH_FISHING_POND_RECTANGLE_SIGN, RAND_INF_LH_FISHING_POND_RECTANGLE_SIGN }, + { RC_GV_BRIDGE_RECTANGLE_SIGN, RAND_INF_GV_BRIDGE_RECTANGLE_SIGN }, + { RC_GV_EAST_EXIT_ARROW_SIGN, RAND_INF_GV_EAST_EXIT_ARROW_SIGN }, + { RC_GF_EAST_EXIT_ARROW_SIGN, RAND_INF_GF_EAST_EXIT_ARROW_SIGN }, + { RC_GF_HBA_RECTANGLE_SIGN, RAND_INF_GF_HBA_RECTANGLE_SIGN }, + { RC_GF_GATE_EXIT_RECTANGLE_SIGN, RAND_INF_GF_GATE_EXIT_RECTANGLE_SIGN }, + { RC_GF_GTG_ENTRANCE_RECTANGLE_SIGN, RAND_INF_GF_GTG_ENTRANCE_RECTANGLE_SIGN }, + { RC_HW_CARPET_SALESMAN_ARROW_SIGN, RAND_INF_HW_CARPET_SALESMAN_ARROW_SIGN }, + { RC_HW_POE_ALTAR, RAND_INF_HW_POE_ALTAR }, + { RC_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL, RAND_INF_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL }, + { RC_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN, RAND_INF_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN }, + { RC_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE, RAND_INF_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE }, + { RC_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE, RAND_INF_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE }, + { RC_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN, RAND_INF_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN }, + // Wonder Items + { RC_KF_WONDER_TRAINING_1, RAND_INF_KF_WONDER_TRAINING_1 }, + { RC_KF_WONDER_TRAINING_2, RAND_INF_KF_WONDER_TRAINING_2 }, + { RC_KF_WONDER_TRAINING_3, RAND_INF_KF_WONDER_TRAINING_3 }, + { RC_KF_WONDER_SHOP, RAND_INF_KF_WONDER_SHOP }, + { RC_KF_WONDER_SIGN, RAND_INF_KF_WONDER_SIGN }, + { RC_KF_WONDER_PLATFORMS_1, RAND_INF_KF_WONDER_PLATFORMS_1 }, + { RC_KF_WONDER_PLATFORMS_2, RAND_INF_KF_WONDER_PLATFORMS_2 }, + { RC_KF_WONDER_CRAWL_GRASS_1, RAND_INF_KF_WONDER_CRAWL_GRASS_1 }, + { RC_KF_WONDER_CRAWL_GRASS_2, RAND_INF_KF_WONDER_CRAWL_GRASS_2 }, + { RC_HF_WONDER_BRIDGE_1, RAND_INF_HF_WONDER_BRIDGE_1 }, + { RC_HF_WONDER_BRIDGE_2, RAND_INF_HF_WONDER_BRIDGE_2 }, + { RC_HF_WONDER_BRIDGE_3, RAND_INF_HF_WONDER_BRIDGE_3 }, + { RC_MKT_WONDER_DAY_1, RAND_INF_MKT_WONDER_DAY_1 }, + { RC_MKT_WONDER_DAY_2, RAND_INF_MKT_WONDER_DAY_2 }, + { RC_MKT_WONDER_DAY_3, RAND_INF_MKT_WONDER_DAY_3 }, + { RC_MKT_WONDER_DAY_4, RAND_INF_MKT_WONDER_DAY_4 }, + { RC_MKT_WONDER_DAY_5, RAND_INF_MKT_WONDER_DAY_5 }, + { RC_MKT_WONDER_NIGHT_1, RAND_INF_MKT_WONDER_NIGHT_1 }, + { RC_MKT_WONDER_NIGHT_2, RAND_INF_MKT_WONDER_NIGHT_2 }, + { RC_LLR_WONDER_BIG_FENCE, RAND_INF_LLR_WONDER_BIG_FENCE }, + { RC_LLR_WONDER_SMALL_FENCE, RAND_INF_LLR_WONDER_SMALL_FENCE }, + { RC_HC_WONDER_LEFT_TORCH, RAND_INF_HC_WONDER_LEFT_TORCH }, + { RC_HC_WONDER_RIGHT_TORCH, RAND_INF_HC_WONDER_RIGHT_TORCH }, + { RC_HC_WONDER_MOAT_1, RAND_INF_HC_WONDER_MOAT_1 }, + { RC_HC_WONDER_MOAT_2, RAND_INF_HC_WONDER_MOAT_2 }, + { RC_HC_WONDER_MOAT_3, RAND_INF_HC_WONDER_MOAT_3 }, + { RC_HC_WONDER_MOAT_4, RAND_INF_HC_WONDER_MOAT_4 }, + { RC_HC_WONDER_MOAT_5, RAND_INF_HC_WONDER_MOAT_5 }, + { RC_HC_WONDER_MOAT_6, RAND_INF_HC_WONDER_MOAT_6 }, + { RC_HC_WONDER_MOAT_7, RAND_INF_HC_WONDER_MOAT_7 }, + { RC_HC_WONDER_MOAT_8, RAND_INF_HC_WONDER_MOAT_8 }, + { RC_HC_WONDER_MOAT_9, RAND_INF_HC_WONDER_MOAT_9 }, + { RC_HC_WONDER_MOAT_10, RAND_INF_HC_WONDER_MOAT_10 }, + { RC_HC_WONDER_COURTYARD_RIGHT_WINDOW, RAND_INF_HC_WONDER_COURTYARD_RIGHT_WINDOW }, + { RC_HC_WONDER_COURTYARD_LEFT_WINDOW, RAND_INF_HC_WONDER_COURTYARD_LEFT_WINDOW }, + { RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_1, RAND_INF_LW_WONDER_BACK_SKULL_KIDS_GRASS_1 }, + { RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_2, RAND_INF_LW_WONDER_BACK_SKULL_KIDS_GRASS_2 }, + { RC_LW_WONDER_FRONT_SKULL_KIDS_GRASS, RAND_INF_LW_WONDER_FRONT_SKULL_KIDS_GRASS }, + { RC_SFM_WONDER_ENTRANCE, RAND_INF_SFM_WONDER_ENTRANCE }, + { RC_SFM_WONDER_MAZE_1, RAND_INF_SFM_WONDER_MAZE_1 }, + { RC_SFM_WONDER_MAZE_2, RAND_INF_SFM_WONDER_MAZE_2 }, + { RC_SFM_WONDER_MAZE_3, RAND_INF_SFM_WONDER_MAZE_3 }, + { RC_SFM_WONDER_MAZE_4, RAND_INF_SFM_WONDER_MAZE_4 }, + { RC_SFM_WONDER_MAZE_5, RAND_INF_SFM_WONDER_MAZE_5 }, + { RC_KAK_WONDER_UNDER_CONSTRUCTION, RAND_INF_KAK_WONDER_UNDER_CONSTRUCTION }, + { RC_KAK_WONDER_ABOVE_COW, RAND_INF_KAK_WONDER_ABOVE_COW }, + { RC_GY_WONDER_DAMPE_RACE_1, RAND_INF_GY_WONDER_DAMPE_RACE_1 }, + { RC_GY_WONDER_DAMPE_RACE_2, RAND_INF_GY_WONDER_DAMPE_RACE_2 }, + { RC_GY_WONDER_DAMPE_RACE_3, RAND_INF_GY_WONDER_DAMPE_RACE_3 }, + { RC_GY_WONDER_DAMPE_RACE_4, RAND_INF_GY_WONDER_DAMPE_RACE_4 }, + { RC_GY_WONDER_DAMPE_RACE_5, RAND_INF_GY_WONDER_DAMPE_RACE_5 }, + { RC_GY_WONDER_DAMPE_RACE_6, RAND_INF_GY_WONDER_DAMPE_RACE_6 }, + { RC_GY_WONDER_DAMPE_RACE_7, RAND_INF_GY_WONDER_DAMPE_RACE_7 }, + { RC_GY_WONDER_DAMPE_RACE_8, RAND_INF_GY_WONDER_DAMPE_RACE_8 }, + { RC_GY_WONDER_DAMPE_RACE_9, RAND_INF_GY_WONDER_DAMPE_RACE_9 }, + { RC_GY_WONDER_DAMPE_RACE_10, RAND_INF_GY_WONDER_DAMPE_RACE_10 }, + { RC_GY_WONDER_DAMPE_RACE_11, RAND_INF_GY_WONDER_DAMPE_RACE_11 }, + { RC_GY_WONDER_DAMPE_RACE_12, RAND_INF_GY_WONDER_DAMPE_RACE_12 }, + { RC_GY_WONDER_DAMPE_RACE_13, RAND_INF_GY_WONDER_DAMPE_RACE_13 }, + { RC_GY_WONDER_DAMPE_RACE_14, RAND_INF_GY_WONDER_DAMPE_RACE_14 }, + { RC_GY_WONDER_DAMPE_RACE_15, RAND_INF_GY_WONDER_DAMPE_RACE_15 }, + { RC_DMC_WONDER_BENEATH_BRIDGE_PLATFORM, RAND_INF_DMC_WONDER_BENEATH_BRIDGE_PLATFORM }, + { RC_ZR_WONDER_NEAR_DOMAIN_1, RAND_INF_ZR_WONDER_NEAR_DOMAIN_1 }, + { RC_ZR_WONDER_NEAR_DOMAIN_2, RAND_INF_ZR_WONDER_NEAR_DOMAIN_2 }, + { RC_ZR_WONDER_NEAR_DOMAIN_3, RAND_INF_ZR_WONDER_NEAR_DOMAIN_3 }, + { RC_ZR_WONDER_NEAR_DOMAIN_4, RAND_INF_ZR_WONDER_NEAR_DOMAIN_4 }, + { RC_ZR_WONDER_BEFORE_LADDER_1, RAND_INF_ZR_WONDER_BEFORE_LADDER_1 }, + { RC_ZR_WONDER_BEFORE_LADDER_2, RAND_INF_ZR_WONDER_BEFORE_LADDER_2 }, + { RC_ZR_WONDER_BEFORE_LADDER_3, RAND_INF_ZR_WONDER_BEFORE_LADDER_3 }, + { RC_ZR_WONDER_BEFORE_LADDER_4, RAND_INF_ZR_WONDER_BEFORE_LADDER_4 }, + { RC_ZR_WONDER_BEFORE_LADDER_5, RAND_INF_ZR_WONDER_BEFORE_LADDER_5 }, + { RC_ZR_WONDER_BEFORE_LADDER_6, RAND_INF_ZR_WONDER_BEFORE_LADDER_6 }, + { RC_ZR_WONDER_AFTER_LADDER_1, RAND_INF_ZR_WONDER_AFTER_LADDER_1 }, + { RC_ZR_WONDER_AFTER_LADDER_2, RAND_INF_ZR_WONDER_AFTER_LADDER_2 }, + { RC_ZR_WONDER_AFTER_LADDER_3, RAND_INF_ZR_WONDER_AFTER_LADDER_3 }, + { RC_ZR_WONDER_FROG_BRIDGE_1, RAND_INF_ZR_WONDER_FROG_BRIDGE_1 }, + { RC_ZR_WONDER_FROG_BRIDGE_2, RAND_INF_ZR_WONDER_FROG_BRIDGE_2 }, + { RC_ZR_WONDER_FROG_BRIDGE_3, RAND_INF_ZR_WONDER_FROG_BRIDGE_3 }, + { RC_ZR_WONDER_PILLARS_1, RAND_INF_ZR_WONDER_PILLARS_1 }, + { RC_ZR_WONDER_PILLARS_2, RAND_INF_ZR_WONDER_PILLARS_2 }, + { RC_ZR_WONDER_PILLARS_3, RAND_INF_ZR_WONDER_PILLARS_3 }, + { RC_ZR_WONDER_PILLARS_4, RAND_INF_ZR_WONDER_PILLARS_4 }, + { RC_ZR_WONDER_LOWER_LAND_BRIDGE_1, RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_1 }, + { RC_ZR_WONDER_LOWER_LAND_BRIDGE_2, RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_2 }, + { RC_ZR_WONDER_LOWER_LAND_BRIDGE_3, RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_3 }, + { RC_ZR_WONDER_LOWER_LAND_BRIDGE_4, RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_4 }, + { RC_ZR_WONDER_NEAR_CUCCO_1, RAND_INF_ZR_WONDER_NEAR_CUCCO_1 }, + { RC_ZR_WONDER_NEAR_CUCCO_2, RAND_INF_ZR_WONDER_NEAR_CUCCO_2 }, + { RC_ZR_WONDER_NEAR_CUCCO_3, RAND_INF_ZR_WONDER_NEAR_CUCCO_3 }, + { RC_ZR_WONDER_LOWER_RIVER_1, RAND_INF_ZR_WONDER_LOWER_RIVER_1 }, + { RC_ZR_WONDER_LOWER_RIVER_2, RAND_INF_ZR_WONDER_LOWER_RIVER_2 }, + { RC_ZR_WONDER_LOWER_RIVER_3, RAND_INF_ZR_WONDER_LOWER_RIVER_3 }, + { RC_ZR_WONDER_LOWER_RIVER_4, RAND_INF_ZR_WONDER_LOWER_RIVER_4 }, + { RC_ZF_WONDER_ROCK, RAND_INF_ZF_WONDER_ROCK }, + { RC_GV_WONDER_LOWER_WATERFALL, RAND_INF_GV_WONDER_LOWER_WATERFALL }, + { RC_GV_WONDER_UPPER_WATERFALL, RAND_INF_GV_WONDER_UPPER_WATERFALL }, + { RC_GF_WONDER_ENTRANCE_SIGN, RAND_INF_GF_WONDER_ENTRANCE_SIGN }, + { RC_GF_WONDER_ARCHERY_SIGN, RAND_INF_GF_WONDER_ARCHERY_SIGN }, + { RC_TH_WONDER_1_TORCH_1, RAND_INF_TH_WONDER_1_TORCH_1 }, + { RC_TH_WONDER_1_TORCH_2, RAND_INF_TH_WONDER_1_TORCH_2 }, + { RC_TH_WONDER_STEEP_SLOPE_LOWER_EXIT, RAND_INF_TH_WONDER_STEEP_SLOPE_LOWER_EXIT }, + { RC_TH_WONDER_STEEP_SLOPE_UPPER_EXIT, RAND_INF_TH_WONDER_STEEP_SLOPE_UPPER_EXIT }, + { RC_TH_WONDER_DOUBLE_JAIL_LOWER_EXIT, RAND_INF_TH_WONDER_DOUBLE_JAIL_LOWER_EXIT }, + { RC_TH_WONDER_DOUBLE_JAIL_UPPER_EXIT, RAND_INF_TH_WONDER_DOUBLE_JAIL_UPPER_EXIT }, + { RC_TH_WONDER_KITCHEN_SKULL, RAND_INF_TH_WONDER_KITCHEN_SKULL }, + { RC_TH_WONDER_KITCHEN_SOUP, RAND_INF_TH_WONDER_KITCHEN_SOUP }, + { RC_TH_WONDER_DEAD_END_SKULL_ENTRANCE, RAND_INF_TH_WONDER_DEAD_END_SKULL_ENTRANCE }, + { RC_TH_WONDER_DEAD_END_SKULL_NEAR_JAIL, RAND_INF_TH_WONDER_DEAD_END_SKULL_NEAR_JAIL }, + { RC_TH_WONDER_BREAK_ROOM_BOTTOM_SKULL, RAND_INF_TH_WONDER_BREAK_ROOM_BOTTOM_SKULL }, + { RC_TH_WONDER_BREAK_ROOM_TOP_SKULL, RAND_INF_TH_WONDER_BREAK_ROOM_TOP_SKULL }, + { RC_COLOSSUS_WONDER_OASIS_TREE_1, RAND_INF_COLOSSUS_WONDER_OASIS_TREE_1 }, + { RC_COLOSSUS_WONDER_OASIS_TREE_2, RAND_INF_COLOSSUS_WONDER_OASIS_TREE_2 }, + { RC_COLOSSUS_WONDER_OASIS_CHILD_TREE, RAND_INF_COLOSSUS_WONDER_OASIS_CHILD_TREE }, + { RC_COLOSSUS_WONDER_GF_TREE_1, RAND_INF_COLOSSUS_WONDER_GF_TREE_1 }, + { RC_COLOSSUS_WONDER_GF_TREE_2, RAND_INF_COLOSSUS_WONDER_GF_TREE_2 }, + { RC_SHADOW_TEMPLE_WONDER_THREE_POTS, RAND_INF_SHADOW_TEMPLE_WONDER_THREE_POTS }, + { RC_GERUDO_TRAINING_GROUND_WONDER_BEAMOS_ROOM, RAND_INF_GERUDO_TRAINING_GROUND_WONDER_BEAMOS_ROOM }, + { RC_GERUDO_TRAINING_GROUND_WONDER_EYE_STATUE_ROOM, RAND_INF_GERUDO_TRAINING_GROUND_WONDER_EYE_STATUE_ROOM }, + { RC_GERUDO_TRAINING_GROUND_WONDER_TORCH_SLUGS_ROOM, RAND_INF_GERUDO_TRAINING_GROUND_WONDER_TORCH_SLUGS_ROOM }, + { RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_1, RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_1 }, + { RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_2, RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_2 }, + { RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_3, RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_3 }, + { RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_4, RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_4 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_LEFT_COW, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_LEFT_COW }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_RIGHT_COW, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_RIGHT_COW }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_ELEVATOR_COW, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ELEVATOR_COW }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_COW, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_COW }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_AFTER_BIG_OCTO, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_AFTER_BIG_OCTO }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_JIGGLIES_COW, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_JIGGLIES_COW }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_LEFT_COW, RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_LEFT_COW }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_1, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_1 }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_2, + RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_2 }, + { RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1, RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1 }, + { RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2, RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2 }, + { RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3, RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3 }, + { RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT, RAND_INF_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT }, + { RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW, RAND_INF_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW }, + { RC_FIRE_TEMPLE_MQ_WONDER_LIZALFOS_MAZE, RAND_INF_FIRE_TEMPLE_MQ_WONDER_LIZALFOS_MAZE }, + { RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1, RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1 }, + { RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2, RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2 }, + { RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1, RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1 }, + { RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2, RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2 }, + { RC_FIRE_TEMPLE_MQ_WONDER_TORCH_ROOM, RAND_INF_FIRE_TEMPLE_MQ_WONDER_TORCH_ROOM }, + { RC_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE, RAND_INF_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE }, + { RC_FIRE_TEMPLE_MQ_WONDER_AFTER_FLARE_DANCER, RAND_INF_FIRE_TEMPLE_MQ_WONDER_AFTER_FLARE_DANCER }, + { RC_FIRE_TEMPLE_MQ_WONDER_STAIRCASE, RAND_INF_FIRE_TEMPLE_MQ_WONDER_STAIRCASE }, + { RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM, RAND_INF_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM }, + { RC_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM, RAND_INF_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM }, + { RC_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM, RAND_INF_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1, + RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1 }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2, + RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2 }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3, + RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3 }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1, RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1 }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2, RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2 }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3, RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3 }, + { RC_WATER_TEMPLE_MQ_WONDER_AFTER_DARK_LINK, RAND_INF_WATER_TEMPLE_MQ_WONDER_AFTER_DARK_LINK }, + { RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE, RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE }, + { RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE, RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE }, + { RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_PORTRAIT, RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_PORTRAIT }, + { RC_WATER_TEMPLE_MQ_WONDER_TRIPLE_TORCHES, RAND_INF_WATER_TEMPLE_MQ_WONDER_TRIPLE_TORCHES }, + { RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_1, RAND_INF_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_1 }, + { RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2, RAND_INF_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2 }, + { RC_WATER_TEMPLE_MQ_WONDER_FREESTANDING_ROOM, RAND_INF_WATER_TEMPLE_MQ_WONDER_FREESTANDING_ROOM }, + { RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_1, RAND_INF_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_1 }, + { RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_2, RAND_INF_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_2 }, + { RC_WATER_TEMPLE_MQ_WONDER_UNDER_PILLAR_ROOM, RAND_INF_WATER_TEMPLE_MQ_WONDER_UNDER_PILLAR_ROOM }, + { RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_HALLWAY, RAND_INF_WATER_TEMPLE_MQ_WONDER_LIZALFOS_HALLWAY }, + { RC_WATER_TEMPLE_MQ_WONDER_GS_STORAGE_ROOM, RAND_INF_WATER_TEMPLE_MQ_WONDER_GS_STORAGE_ROOM }, + { RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER, RAND_INF_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER }, + { RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH, RAND_INF_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH }, + { RC_SHADOW_TEMPLE_MQ_WONDER_THREE_POTS, RAND_INF_SHADOW_TEMPLE_MQ_WONDER_THREE_POTS }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3 }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4, RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4 }, + { RC_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM, RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM }, + { RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE, RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE }, + { RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL, RAND_INF_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL }, + // Beggar + { RC_MK_BEGGAR_BUGS, RAND_INF_MK_BEGGAR_BUGS }, + { RC_MK_BEGGAR_FISH, RAND_INF_MK_BEGGAR_FISH }, + { RC_MK_BEGGAR_BLUE_FIRE, RAND_INF_MK_BEGGAR_BLUE_FIRE }, + { RC_KAK_BEGGAR_BUGS, RAND_INF_KAK_BEGGAR_BUGS }, + { RC_KAK_BEGGAR_FISH, RAND_INF_KAK_BEGGAR_FISH }, + { RC_KAK_BEGGAR_BLUE_FIRE, RAND_INF_KAK_BEGGAR_BLUE_FIRE }, + // Icicles + { RC_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE, RAND_INF_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE }, + { RC_ICE_CAVERN_ENTRANCE_MIDDLE_STALAGMITE, RAND_INF_ICE_CAVERN_ENTRANCE_MIDDLE_STALAGMITE }, + { RC_ICE_CAVERN_ENTRANCE_RIGHT_STALAGMITE, RAND_INF_ICE_CAVERN_ENTRANCE_RIGHT_STALAGMITE }, + { RC_ICE_CAVERN_ENTRANCE_STALACTITE_1, RAND_INF_ICE_CAVERN_ENTRANCE_STALACTITE_1 }, + { RC_ICE_CAVERN_ENTRANCE_STALACTITE_2, RAND_INF_ICE_CAVERN_ENTRANCE_STALACTITE_2 }, + { RC_ICE_CAVERN_LOBBY_STALACTITE, RAND_INF_ICE_CAVERN_LOBBY_STALACTITE }, + { RC_ICE_CAVERN_LOBBY_LEFT_STALAGMITE, RAND_INF_ICE_CAVERN_LOBBY_LEFT_STALAGMITE }, + { RC_ICE_CAVERN_LOBBY_MIDDLE_STALAGMITE, RAND_INF_ICE_CAVERN_LOBBY_MIDDLE_STALAGMITE }, + { RC_ICE_CAVERN_LOBBY_RIGHT_STALAGMITE, RAND_INF_ICE_CAVERN_LOBBY_RIGHT_STALAGMITE }, + { RC_ICE_CAVERN_AFTER_LOBBY_STALACTITE, RAND_INF_ICE_CAVERN_AFTER_LOBBY_STALACTITE }, + { RC_ICE_CAVERN_AFTER_LOBBY_LEFT_STALAGMITE, RAND_INF_ICE_CAVERN_AFTER_LOBBY_LEFT_STALAGMITE }, + { RC_ICE_CAVERN_AFTER_LOBBY_CENTER_LEFT_STALAGMITE, RAND_INF_ICE_CAVERN_AFTER_LOBBY_CENTER_LEFT_STALAGMITE }, + { RC_ICE_CAVERN_AFTER_LOBBY_CENTER_RIGHT_STALAGMITE, RAND_INF_ICE_CAVERN_AFTER_LOBBY_CENTER_RIGHT_STALAGMITE }, + { RC_ICE_CAVERN_AFTER_LOBBY_RIGHT_STALAGMITE, RAND_INF_ICE_CAVERN_AFTER_LOBBY_RIGHT_STALAGMITE }, + { RC_ICE_CAVERN_SPINNING_BLADE_LEFT_STALAGMITE, RAND_INF_ICE_CAVERN_SPINNING_BLADE_LEFT_STALAGMITE }, + { RC_ICE_CAVERN_SPINNING_BLADE_MIDDLE_STALAGMITE, RAND_INF_ICE_CAVERN_SPINNING_BLADE_MIDDLE_STALAGMITE }, + { RC_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE, RAND_INF_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE }, + { RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_1, RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_1 }, + { RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_2, RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_2 }, + { RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_3, RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_3 }, + { RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_4, RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_4 }, + { RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_5, RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_5 }, + { RC_ICE_CAVERN_MAP_HALLWAY_LEFT_STALAGMITE, RAND_INF_ICE_CAVERN_MAP_HALLWAY_LEFT_STALAGMITE }, + { RC_ICE_CAVERN_MAP_HALLWAY_MIDDLE_STALAGMITE, RAND_INF_ICE_CAVERN_MAP_HALLWAY_MIDDLE_STALAGMITE }, + { RC_ICE_CAVERN_MAP_HALLWAY_RIGHT_STALAGMITE, RAND_INF_ICE_CAVERN_MAP_HALLWAY_RIGHT_STALAGMITE }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_2, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_2 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_3, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_3 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_4, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_4 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_5, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_5 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_1, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_1 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_2, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_2 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_1, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_1 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_2, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_2 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_3, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_3 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_4, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_4 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_5, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_5 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_6, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_6 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_1, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_1 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_2, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_2 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_3, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_3 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_1, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_1 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_2, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_2 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_3, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_3 }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_4, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_4 }, + { RC_ICE_CAVERN_PUSH_BLOCK_HALL_LEFT_STALAGMITE, RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_LEFT_STALAGMITE }, + { RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_LEFT_STALAGMITE, + RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_LEFT_STALAGMITE }, + { RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_STALAGMITE, RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_STALAGMITE }, + { RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_RIGHT_STALAGMITE, + RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_RIGHT_STALAGMITE }, + { RC_ICE_CAVERN_PUSH_BLOCK_HALL_RIGHT_STALAGMITE, RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_RIGHT_STALAGMITE }, + { RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_1, RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_1 }, + { RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2, RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2 }, + { RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3, RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3 }, + { RC_ICE_CAVERN_NEAR_END_STALACTITE_1, RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_1 }, + { RC_ICE_CAVERN_NEAR_END_STALACTITE_2, RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_2 }, + { RC_ICE_CAVERN_NEAR_END_STALACTITE_3, RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_3 }, + { RC_ICE_CAVERN_NEAR_END_STALACTITE_4, RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_4 }, + { RC_ICE_CAVERN_NEAR_END_STALAGMITE_1, RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_1 }, + { RC_ICE_CAVERN_NEAR_END_STALAGMITE_2, RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_2 }, + { RC_ICE_CAVERN_NEAR_END_STALAGMITE_3, RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_3 }, + { RC_ICE_CAVERN_NEAR_END_STALAGMITE_4, RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_4 }, + { RC_ICE_CAVERN_NEAR_END_STALAGMITE_5, RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_5 }, + { RC_ICE_CAVERN_NEAR_END_STALAGMITE_6, RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_6 }, + { RC_ICE_CAVERN_NEAR_END_STALAGMITE_7, RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_7 }, + { RC_ICE_CAVERN_NEAR_END_STALAGMITE_8, RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_8 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_1 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_3, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_3 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_4, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_4 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_5, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_5 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_6, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_6 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_7, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_7 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_8, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_8 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_9, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_9 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_10, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_10 }, + { RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_1 }, + { RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_1 }, + { RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_1 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_3, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_3 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_4, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_4 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_5, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_5 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_6, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_6 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_7, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_7 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_8, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_8 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_9, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_9 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_10, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_10 }, + { RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_11, RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_11 }, + { RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_1, RAND_INF_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_1 }, + { RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_2, RAND_INF_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_2 }, + { RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_1, RAND_INF_ICE_CAVERN_MQ_LOBBY_STALACTITE_1 }, + { RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_2, RAND_INF_ICE_CAVERN_MQ_LOBBY_STALACTITE_2 }, + { RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_1, RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_1 }, + { RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_2, RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_2 }, + { RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_3, RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_3 }, + { RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_4, RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_4 }, + { RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_5, RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_5 }, + { RC_ICE_CAVERN_MQ_HUB_STALAGMITE_1, RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_1 }, + { RC_ICE_CAVERN_MQ_HUB_STALAGMITE_2, RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_2 }, + { RC_ICE_CAVERN_MQ_HUB_STALAGMITE_3, RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_3 }, + { RC_ICE_CAVERN_MQ_HUB_STALAGMITE_4, RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_4 }, + { RC_ICE_CAVERN_MQ_HUB_STALAGMITE_5, RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_5 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_2, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_2 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_3, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_3 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_4, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_4 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_5, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_5 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_6, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_6 }, + { RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_7, RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_7 }, + { RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_1, RAND_INF_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_1 }, + { RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_2, RAND_INF_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_2 }, + { RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_1, RAND_INF_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_1 }, + { RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_2, RAND_INF_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_2 }, + { RC_ICE_CAVERN_MQ_BEFORE_SCARECROW_STALAGMITE, RAND_INF_ICE_CAVERN_MQ_BEFORE_SCARECROW_STALAGMITE }, + { RC_ICE_CAVERN_MQ_SCARECROW_ROOM_STALACTITE, RAND_INF_ICE_CAVERN_MQ_SCARECROW_ROOM_STALACTITE }, + { RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_1, RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_1 }, + { RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_2, RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_2 }, + { RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_3, RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_3 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_3, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_3 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_4, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_4 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_5, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_5 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_1, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_2, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_2 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_3, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_3 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_4, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_4 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_LEFT_STALACTITE, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_LEFT_STALACTITE }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2 }, + { RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_3, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_3 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_3, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_3 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_3, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_3 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_4, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_4 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_3, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_3 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_4, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_4 }, + // Red Ice + { RC_ZD_KING_ZORA_RED_ICE, RAND_INF_ZD_KING_ZORA_RED_ICE }, + { RC_ZD_ZORA_SHOP_RED_ICE, RAND_INF_ZD_ZORA_SHOP_RED_ICE }, + { RC_ICE_CAVERN_ENTRANCE_RED_ICE, RAND_INF_ICE_CAVERN_ENTRANCE_RED_ICE }, + { RC_ICE_CAVERN_LOBBY_LEFT_RED_ICE, RAND_INF_ICE_CAVERN_LOBBY_LEFT_RED_ICE }, + { RC_ICE_CAVERN_LOBBY_RIGHT_RED_ICE, RAND_INF_ICE_CAVERN_LOBBY_RIGHT_RED_ICE }, + { RC_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE, RAND_INF_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE }, + { RC_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE, RAND_INF_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE }, + { RC_ICE_CAVERN_HEART_PIECE_ROOM_CHEST_RED_ICE, RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CHEST_RED_ICE }, + { RC_ICE_CAVERN_MAP_ROOM_POT_RED_ICE, RAND_INF_ICE_CAVERN_MAP_ROOM_POT_RED_ICE }, + { RC_ICE_CAVERN_MAP_ROOM_CHEST_RED_ICE, RAND_INF_ICE_CAVERN_MAP_ROOM_CHEST_RED_ICE }, + { RC_ICE_CAVERN_SILVER_RUPEE_RED_ICE, RAND_INF_ICE_CAVERN_SILVER_RUPEE_RED_ICE }, + { RC_ICE_CAVERN_NEAR_END_LEFT_RED_ICE, RAND_INF_ICE_CAVERN_NEAR_END_LEFT_RED_ICE }, + { RC_ICE_CAVERN_NEAR_END_MIDDLE_RED_ICE, RAND_INF_ICE_CAVERN_NEAR_END_MIDDLE_RED_ICE }, + { RC_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE, RAND_INF_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE }, + { RC_GANONS_CASTLE_WATER_TRIAL_DOOR_RED_ICE, RAND_INF_GANONS_CASTLE_WATER_TRIAL_DOOR_RED_ICE }, + { RC_GANONS_CASTLE_WATER_TRIAL_RUSTED_SWITCH_RED_ICE, RAND_INF_GANONS_CASTLE_WATER_TRIAL_RUSTED_SWITCH_RED_ICE }, + { RC_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_RED_ICE, RAND_INF_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_RED_ICE }, + { RC_ICE_CAVERN_MQ_HUB_WEST_LEFT_RED_ICE, RAND_INF_ICE_CAVERN_MQ_HUB_WEST_LEFT_RED_ICE }, + { RC_ICE_CAVERN_MQ_HUB_WEST_MIDDLE_RED_ICE, RAND_INF_ICE_CAVERN_MQ_HUB_WEST_MIDDLE_RED_ICE }, + { RC_ICE_CAVERN_MQ_HUB_WEST_RIGHT_RED_ICE, RAND_INF_ICE_CAVERN_MQ_HUB_WEST_RIGHT_RED_ICE }, + { RC_ICE_CAVERN_MQ_HUB_LEDGE_LEFT_RED_ICE, RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_LEFT_RED_ICE }, + { RC_ICE_CAVERN_MQ_HUB_LEDGE_MIDDLE_RED_ICE, RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_MIDDLE_RED_ICE }, + { RC_ICE_CAVERN_MQ_HUB_LEDGE_RIGHT_RED_ICE, RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_RIGHT_RED_ICE }, + { RC_ICE_CAVERN_MQ_COMPASS_RED_ICE, RAND_INF_ICE_CAVERN_MQ_COMPASS_RED_ICE }, + { RC_ICE_CAVERN_MQ_MAP_RED_ICE, RAND_INF_ICE_CAVERN_MQ_MAP_RED_ICE }, + { RC_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE, RAND_INF_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE }, + { RC_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE, RAND_INF_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE }, + { RC_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE, RAND_INF_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_BACK_LEFT_RED_ICE, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_BACK_LEFT_RED_ICE }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_1, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_2, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_3, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_3 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_4, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_4 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5 }, +}; \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/RCToRandInf.h b/soh/soh/Enhancements/randomizer/RCToRandInf.h new file mode 100644 index 0000000000..bba37b1790 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/RCToRandInf.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include "randomizerTypes.h" + +// There has been some talk about potentially just using the RC identifier to store flags rather than randomizer inf, so +// for now we're not going to store randomzierInf in the randomizer check objects, we're just going to map them 1:1 here +extern std::map rcToRandomizerInf; \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/RocsFeather.cpp b/soh/soh/Enhancements/randomizer/RocsFeather.cpp index e90b4d3c14..6e4fa71697 100644 --- a/soh/soh/Enhancements/randomizer/RocsFeather.cpp +++ b/soh/soh/Enhancements/randomizer/RocsFeather.cpp @@ -1,5 +1,6 @@ #include #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/randomizer/SeedContext.h" #include "soh/ShipInit.hpp" #include diff --git a/soh/soh/Enhancements/randomizer/SeedContext.cpp b/soh/soh/Enhancements/randomizer/SeedContext.cpp index 089bb5c0ad..71bbd84d2b 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -13,6 +13,7 @@ #include "soh/util.h" #include "../kaleido.h" #include "soh/Enhancements/randomizer/Traps.h" +#include "soh/Enhancements/randomizer/randomizer.h" #include #include @@ -50,6 +51,8 @@ Context::Context() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_ROCKS], + &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], @@ -196,6 +199,7 @@ void Context::GenerateLocationPool() { !(location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO)) || + (location.GetRCType() == RCTYPE_BEGGAR && mOptions[RSK_SHUFFLE_BEGGAR].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) || (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && @@ -207,14 +211,22 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_NLCRATE && (mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF) || 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_ROCK && !mOptions[RSK_SHUFFLE_ROCKS]) || + (location.GetRCType() == RCTYPE_BOULDER && mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OFF)) || (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_BUTTERFLY_FAIRY && !mOptions[RSK_SHUFFLE_BUTTERFLY_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_BUSH && !mOptions[RSK_SHUFFLE_BUSHES]) || + (location.GetRCType() == RCTYPE_ICICLE && !mOptions[RSK_SHUFFLE_ICICLES]) || + (location.GetRCType() == RCTYPE_RED_ICE && !mOptions[RSK_SHUFFLE_RED_ICE]) || + (location.GetRCType() == RCTYPE_SIGN && mOptions[RSK_SHUFFLE_SIGNS].Is(RO_SHUFFLE_SIGNS_OFF)) || + (location.GetRCType() == RCTYPE_WONDER_ITEM && + mOptions[RSK_SHUFFLE_WONDER_ITEMS].Is(RO_SHUFFLE_WONDER_ITEMS_OFF)) || (location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || (location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) { @@ -227,12 +239,17 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_DUNGEONS)) || (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_DUNGEONS)) || (location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_DUNGEONS)) || + (location.GetRCType() == RCTYPE_WONDER_ITEM && + mOptions[RSK_SHUFFLE_WONDER_ITEMS].Is(RO_SHUFFLE_WONDER_ITEMS_DUNGEONS)) || (location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS)) || (location.GetRCType() == RCTYPE_NLCRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS)) || + (location.GetRCType() == RCTYPE_BOULDER && + mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_DUNGEONS)) || + (location.GetRCType() == RCTYPE_SIGN && mOptions[RSK_SHUFFLE_SIGNS].Is(RO_SHUFFLE_SIGNS_DUNGEONS))) { continue; } // If we've gotten past all the conditions where an overworld location should not be @@ -247,13 +264,19 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_OVERWORLD)) || (location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OVERWORLD)) || + (location.GetRCType() == RCTYPE_WONDER_ITEM && + mOptions[RSK_SHUFFLE_WONDER_ITEMS].Is(RO_SHUFFLE_WONDER_ITEMS_OVERWORLD)) || (location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD)) || (location.GetRCType() == RCTYPE_NLCRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD)) || + (location.GetRCType() == RCTYPE_BOULDER && + mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OVERWORLD)) || + (location.GetRCType() == RCTYPE_SIGN && + mOptions[RSK_SHUFFLE_SIGNS].Is(RO_SHUFFLE_SIGNS_OVERWORLD))) { continue; } // also add to that dungeon's location list. diff --git a/soh/soh/Enhancements/randomizer/SeedContext.h b/soh/soh/Enhancements/randomizer/SeedContext.h index 9ca42751a9..46b117616c 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.h +++ b/soh/soh/Enhancements/randomizer/SeedContext.h @@ -4,7 +4,7 @@ #include "z64save.h" #include "item_location.h" #include "item_override.h" -#include "3drando/text.hpp" +#include "soh/Enhancements/custom-message/text.h" #include "hint.h" #include "fishsanity.h" #include "trial.h" diff --git a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp index 4f50d5acbc..230773c0f2 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp @@ -1,6 +1,8 @@ #include #include "static_data.h" #include "soh/ObjectExtension/ObjectExtension.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h" @@ -74,11 +76,33 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { } } +static CheckIdentity IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { + CheckIdentity beehiveIdentity; + + beehiveIdentity.randomizerInf = RAND_INF_MAX; + beehiveIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + if (sceneNum == SCENE_GROTTOS) { + respawnData = TWO_ACTOR_PARAMS(xPosition, respawnData); + } else { + respawnData = TWO_ACTOR_PARAMS(xPosition, 0); + } + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_OBJ_COMB, sceneNum, respawnData); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + beehiveIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + beehiveIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return beehiveIdentity; +} + void ObjComb_RandomizerInit(void* actor) { ObjComb* objComb = static_cast(actor); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - auto beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive( - gPlayState->sceneNum, (s16)objComb->actor.world.pos.x, respawnData); + auto beehiveIdentity = IdentifyBeehive(gPlayState->sceneNum, (s16)objComb->actor.world.pos.x, respawnData); ObjectExtension::GetInstance().Set(actor, std::move(beehiveIdentity)); objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait; } diff --git a/soh/soh/Enhancements/randomizer/ShuffleBeggar.cpp b/soh/soh/Enhancements/randomizer/ShuffleBeggar.cpp new file mode 100644 index 0000000000..f16fcded51 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleBeggar.cpp @@ -0,0 +1,134 @@ +#include +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" + +extern "C" { +#include "overlays/actors/ovl_En_Hy/z_en_hy.h" +extern PlayState* gPlayState; +} + +static CheckIdentity IdentifyBeggar(s32 sceneNum, s32 textId) { + CheckIdentity beggarIdentity; + beggarIdentity.randomizerInf = RAND_INF_MAX; + beggarIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_HY, sceneNum, textId); + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifyBeggar did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + } else { + beggarIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + beggarIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return beggarIdentity; +} + +CheckIdentity ShuffleBeggar_GetBeggarIdentity(int32_t textId) { + CheckIdentity beggarIdentity; + s16 sceneNum = gPlayState->sceneNum; + + beggarIdentity = IdentifyBeggar(sceneNum, textId); + + return beggarIdentity; +} + +uint8_t EnHy_RandomizerHoldsItem(int32_t textId) { + CheckIdentity beggarIdentity = ShuffleBeggar_GetBeggarIdentity(textId); + if (beggarIdentity.randomizerCheck == RC_UNKNOWN_CHECK || !IS_RANDO || + Flags_GetRandomizerInf(beggarIdentity.randomizerInf)) { + return false; + } + return true; +} + +void BuildEnHyMessage_BlueFire(uint16_t* textId, bool* loadFromMessageTable) { + if (!EnHy_RandomizerHoldsItem(TEXT_BEGGAR_BUY_BLUE_FIRE)) { + return; + } + + CustomMessage msg = CustomMessage( + "%cBlue Fire%w! I'll trade you %rsomething special%w for it. No returns! I get new " + "special inventory %bevery 7 years or so%w...", + "%cBlaues Feuer%w! Ich tausche es gegen %retwas Besonderes%w. Und nicht feilschen, okay! Ich bekomme neue " + "besondere Ware %balle 7 Jahre oder so%w...", + "%cFeu bleu%w ! Je l'échange contre %rquelque chose de spécial%w. Pas de retour ! Je reçois de nouveaux " + "articles spéciaux %btous les 7 ans environ%w..."); + msg.AutoFormat(); + msg.LoadIntoFont(); + *loadFromMessageTable = false; +} + +void BuildEnHyMessage_Fish(uint16_t* textId, bool* loadFromMessageTable) { + if (!EnHy_RandomizerHoldsItem(TEXT_BEGGAR_BUY_FISH)) { + return; + } + CustomMessage msg = CustomMessage( + "A %pfish%w! I'll trade you %rsomething special%w for it. No returns! I get new " + "special inventory %bevery 7 years or so%w...", + "Ein %pFisch%w! Ich tausche ihn gegen %retwas Besonderes%w. Und nicht feilschen, okay! Ich bekomme neue " + "besondere Ware %balle 7 Jahre oder so%w...", + "Un %ppoisson%w ! Je l'échange contre %rquelque chose de spécial%w. Pas de retour ! Je reçois de nouveaux " + "articles spéciaux %btous les 7 ans environ%w..."); + msg.AutoFormat(); + msg.LoadIntoFont(); + *loadFromMessageTable = false; +} + +void BuildEnHyMessage_Bug(uint16_t* textId, bool* loadFromMessageTable) { + if (!EnHy_RandomizerHoldsItem(TEXT_BEGGAR_BUY_BUGS)) { + return; + } + CustomMessage msg = + CustomMessage("A tiny %gbug%w! I'll trade you %rsomething special%w for it. No returns! I get new " + "special inventory %bevery 7 years or so%w...", + "Ein kleiner %gKäfer%w! Ich tausche ihn gegen %retwas Besonderes%w. Und nicht feilschen, okay! " + "Ich bekomme neue " + "besondere Ware %balle 7 Jahre oder so%w...", + "Un petit %ginsecte%w ! Je l'échange contre %rquelque chose de spécial%w. Pas de retour ! Je " + "reçois de nouveaux " + "articles spéciaux %btous les 7 ans environ%w..."); + msg.AutoFormat(); + msg.LoadIntoFont(); + *loadFromMessageTable = false; +} + +void RegisterShuffleBeggar() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BEGGAR).Get(); + + COND_VB_SHOULD(VB_BEGGAR_GIVE_ITEM, shouldRegister, { + EnHy* enHy = va_arg(args, EnHy*); + int32_t beggarTextId = enHy->actor.textId; + + if (beggarTextId != TEXT_BEGGAR_BUY_FAIRY) { + if (EnHy_RandomizerHoldsItem(beggarTextId)) { + CheckIdentity beggarIdentity = ShuffleBeggar_GetBeggarIdentity(beggarTextId); + Flags_SetRandomizerInf(beggarIdentity.randomizerInf); + *should = false; + } + } + }); + + COND_ID_HOOK(OnOpenText, TEXT_BEGGAR_BUY_BLUE_FIRE, shouldRegister, BuildEnHyMessage_BlueFire); + COND_ID_HOOK(OnOpenText, TEXT_BEGGAR_BUY_FISH, shouldRegister, BuildEnHyMessage_Fish); + COND_ID_HOOK(OnOpenText, TEXT_BEGGAR_BUY_BUGS, shouldRegister, BuildEnHyMessage_Bug); +} + +void Rando::StaticData::RegisterBeggarLocations() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + // Randomizer Check Randomizer Check Quest RCType Area Actor ID Scene ID Params Short Name Hint Text Key Vanilla Item Spoiler Collection Check + locationTable[RC_MK_BEGGAR_BUGS] = Location::Base(RC_MK_BEGGAR_BUGS, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_MARKET, ACTOR_EN_HY, SCENE_MARKET_DAY, 0x70F2, "Beggar Bugs", RHT_BEGGAR_MARKET, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BEGGAR_BUGS)); + locationTable[RC_MK_BEGGAR_FISH] = Location::Base(RC_MK_BEGGAR_FISH, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_MARKET, ACTOR_EN_HY, SCENE_MARKET_DAY, 0x70F1, "Beggar Fish", RHT_BEGGAR_MARKET, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BEGGAR_FISH)); + locationTable[RC_MK_BEGGAR_BLUE_FIRE] = Location::Base(RC_MK_BEGGAR_BLUE_FIRE, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_MARKET, ACTOR_EN_HY, SCENE_MARKET_DAY, 0x70F0, "Beggar Blue Fire", RHT_BEGGAR_MARKET, RG_HUGE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BEGGAR_BLUE_FIRE)); + locationTable[RC_KAK_BEGGAR_BUGS] = Location::Base(RC_KAK_BEGGAR_BUGS, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_HY, SCENE_KAKARIKO_VILLAGE, 0x70F2, "Beggar Bugs", RHT_BEGGAR_KAKARIKO_VILLAGE, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_BEGGAR_BUGS)); + locationTable[RC_KAK_BEGGAR_FISH] = Location::Base(RC_KAK_BEGGAR_FISH, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_HY, SCENE_KAKARIKO_VILLAGE, 0x70F1, "Beggar Fish", RHT_BEGGAR_KAKARIKO_VILLAGE, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_BEGGAR_FISH)); + locationTable[RC_KAK_BEGGAR_BLUE_FIRE] = Location::Base(RC_KAK_BEGGAR_BLUE_FIRE, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_HY, SCENE_KAKARIKO_VILLAGE, 0x70F0, "Beggar Blue Fire", RHT_BEGGAR_KAKARIKO_VILLAGE, RG_HUGE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_BEGGAR_BLUE_FIRE)); + // clang-format on +} + +static RegisterShipInitFunc registerShuffleBeggar(RegisterShuffleBeggar, { "IS_RANDO" }); +static RegisterShipInitFunc registerBeggarLocations(Rando::StaticData::RegisterBeggarLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleCows.cpp b/soh/soh/Enhancements/randomizer/ShuffleCows.cpp index 6660912be6..ff9937dbae 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCows.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCows.cpp @@ -1,5 +1,7 @@ #include #include "static_data.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "src/overlays/actors/ovl_En_Cow/z_en_cow.h" @@ -29,18 +31,40 @@ void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) { if (moved) { // Reposition collider - func_809DEE9C(enCow); + EnCow_SetColliderPos(enCow); } } +static CheckIdentity IdentifyCow(s32 sceneNum, s32 posX, s32 posZ) { + CheckIdentity cowIdentity; + + cowIdentity.randomizerInf = RAND_INF_MAX; + cowIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = 0x00; + // Only need to pass params if in a scene with two cows + if (sceneNum == SCENE_GROTTOS || sceneNum == SCENE_STABLE || sceneNum == SCENE_LON_LON_BUILDINGS) { + actorParams = TWO_ACTOR_PARAMS(posX, posZ); + } + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_COW, sceneNum, actorParams); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + cowIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + cowIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return cowIdentity; +} + void RegisterShuffleCows() { bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_COWS); COND_VB_SHOULD(VB_GIVE_ITEM_FROM_COW, shouldRegister, { EnCow* enCow = va_arg(args, EnCow*); - CheckIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow( - gPlayState->sceneNum, static_cast(enCow->actor.world.pos.x), - static_cast(enCow->actor.world.pos.z)); + CheckIdentity cowIdentity = IdentifyCow(gPlayState->sceneNum, static_cast(enCow->actor.world.pos.x), + static_cast(enCow->actor.world.pos.z)); // Has this cow already rewarded an item? if (!Flags_GetRandomizerInf(cowIdentity.randomizerInf)) { Flags_SetRandomizerInf(cowIdentity.randomizerInf); diff --git a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp index a1216ce010..2f835d965c 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp @@ -5,6 +5,8 @@ #include "global.h" #include "soh/ObjectExtension/ObjectExtension.h" #include "item_category_adj.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "variables.h" @@ -185,6 +187,63 @@ void ObjKibako_RandomizerSpawnCollectible(ObjKibako* smallCrateActor, PlayState* item00->actor.world.rot.y = static_cast(Rand_CenteredFloat(65536.0f)); } +static CheckIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ) { + CheckIdentity crateIdentity; + uint32_t crateSceneNum = sceneNum; + + // pretend night is day to align crates in market and align GF child/adult crates + if (sceneNum == SCENE_MARKET_NIGHT) { + crateSceneNum = SCENE_MARKET_DAY; + } else if (sceneNum == SCENE_GERUDOS_FORTRESS && gPlayState->linkAgeOnLoad == 1 && posX == 310) { + if (posZ == -1830) { + posZ = -1842; + } else if (posZ == -1770) { + posZ = -1782; + } + } + + crateIdentity.randomizerInf = RAND_INF_MAX; + crateIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_OBJ_KIBAKO2, crateSceneNum, actorParams); + + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifyCrate did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + assert(false); + } else { + crateIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + crateIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return crateIdentity; +} + +static CheckIdentity IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ) { + CheckIdentity smallCrateIdentity; + uint32_t smallCrateSceneNum = sceneNum; + + smallCrateIdentity.randomizerInf = RAND_INF_MAX; + smallCrateIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_OBJ_KIBAKO, smallCrateSceneNum, actorParams); + + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifyCrate did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + assert(false); + } else { + smallCrateIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + smallCrateIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return smallCrateIdentity; +} + void ObjKibako2_RandomizerInit(void* actorRef) { Actor* actor = static_cast(actorRef); auto logicSetting = RAND_GET_OPTION(RSK_LOGIC_RULES); @@ -210,8 +269,7 @@ void ObjKibako2_RandomizerInit(void* actorRef) { ObjKibako2* crateActor = static_cast(actorRef); - auto crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCrate(gPlayState->sceneNum, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); + auto crateIdentity = IdentifyCrate(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); ObjectExtension::GetInstance().Set(actor, std::move(crateIdentity)); } @@ -223,8 +281,7 @@ void ObjKibako_RandomizerInit(void* actorRef) { ObjKibako* smallCrateActor = static_cast(actorRef); - auto crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifySmallCrate( - gPlayState->sceneNum, (s16)actor->home.pos.x, (s16)actor->home.pos.z); + auto crateIdentity = IdentifySmallCrate(gPlayState->sceneNum, (s16)actor->home.pos.x, (s16)actor->home.pos.z); ObjectExtension::GetInstance().Set(actor, std::move(crateIdentity)); } diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp index 730366949c..1d40ed87a0 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp @@ -5,12 +5,14 @@ #include "static_data.h" #include "soh/Enhancements/item-tables/ItemTableTypes.h" #include "soh/ObjectExtension/ObjectExtension.h" +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" #include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h" #include "src/overlays/actors/ovl_En_Gs/z_en_gs.h" #include "src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h" +#include "src/overlays/actors/ovl_En_Butte/z_en_butte.h" } #define FAIRY_FLAG_TIMED (1 << 8) @@ -53,7 +55,7 @@ bool ShuffleFairies_FairyExists(CheckIdentity fairyIdentity) { return false; } -CheckIdentity ShuffleFairies_GetFairyIdentity(int32_t params) { +CheckIdentity ShuffleFairies_GetFairyIdentity(int32_t params, ActorID id) { CheckIdentity fairyIdentity; s16 sceneNum = gPlayState->sceneNum; fairyIdentity.randomizerInf = RAND_INF_MAX; @@ -62,8 +64,7 @@ CheckIdentity ShuffleFairies_GetFairyIdentity(int32_t params) { sceneNum = SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY; } - Rando::Location* location = - OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_ELF, sceneNum, params); + Rando::Location* location = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(id, sceneNum, params); if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { LUSLOG_WARN("FairyGetIdentity did not receive a valid RC value (%d).", location->GetRandomizerCheck()); @@ -76,8 +77,8 @@ CheckIdentity ShuffleFairies_GetFairyIdentity(int32_t params) { return fairyIdentity; } -static bool SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params, FairyType fairyType) { - CheckIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params); +static bool SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params, FairyType fairyType, ActorID id) { + CheckIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params, id); if (!Flags_GetRandomizerInf(fairyIdentity.randomizerInf)) { Actor* fairy = Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0, 0, 0, fairyType); @@ -93,7 +94,9 @@ void RegisterShuffleFairies() { 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; + bool shouldRegisterButterfly = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BUTTERFLY_FAIRIES); + bool shouldRegister = shouldRegisterFountain || shouldRegisterStone || shouldRegisterBean || shouldRegisterSong || + shouldRegisterButterfly; // Grant item when picking up fairy. COND_VB_SHOULD(VB_FAIRY_HEAL, shouldRegister, { @@ -123,7 +126,8 @@ void RegisterShuffleFairies() { s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0; for (s16 index = 0; index < 8; index++) { int32_t params = (grottoId << 8) | index; - if (SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, params, FAIRY_HEAL)) { + if (SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, params, FAIRY_HEAL, + ACTOR_EN_ELF)) { fairySpawned = true; } } @@ -139,7 +143,7 @@ void RegisterShuffleFairies() { for (s16 index = 0; index < 3; index++) { int32_t params = ((objBean->dyna.actor.params & 0x3F) << 8) | index; if (SpawnFairy(objBean->dyna.actor.world.pos.x, objBean->dyna.actor.world.pos.y, - objBean->dyna.actor.world.pos.z, params, FAIRY_HEAL)) { + objBean->dyna.actor.world.pos.z, params, FAIRY_HEAL, ACTOR_EN_ELF)) { fairySpawned = true; } } @@ -152,7 +156,7 @@ void RegisterShuffleFairies() { 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)) { + TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z), FAIRY_HEAL_BIG, ACTOR_EN_ELF)) { *should = false; } }); @@ -185,11 +189,11 @@ void RegisterShuffleFairies() { // stop spawning the vanilla fairy as well when these fairies exist, otherwise both // the randomized and the vanilla fairy will spawn. When the randomized fairy is already // collected, the vanilla code will handle that part automatically. - CheckIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params); + CheckIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params, ACTOR_EN_ELF); if (!ShuffleFairies_FairyExists(fairyIdentity)) { Player* player = GET_PLAYER(gPlayState); if (SpawnFairy(player->actor.world.pos.x, (player->actor.world.pos.y + 20), player->actor.world.pos.z, - params, fairyType)) { + params, fairyType, ACTOR_EN_ELF)) { Audio_PlayActorSound2(&gossipStone->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); // Set vanilla check for fairy spawned so it doesn't spawn the vanilla fairy afterwards as well. gossipStone->unk_19D = 0; @@ -200,6 +204,18 @@ void RegisterShuffleFairies() { } } }); + + // Spawn a fairy from a butterfly + COND_VB_SHOULD(VB_SPAWN_BUTTERFLY_FAIRY, shouldRegisterButterfly, { + if (*should) { + EnButte* enButte = va_arg(args, EnButte*); + int32_t params = (gPlayState->sceneNum == SCENE_GROTTOS) ? Grotto_CurrentGrotto() : enButte->actor.params; + if (SpawnFairy(enButte->actor.focus.pos.x, enButte->actor.focus.pos.y, enButte->actor.focus.pos.z, + TWO_ACTOR_PARAMS(params, (int32_t)enButte->actor.home.pos.y), FAIRY_HEAL, ACTOR_EN_BUTTE)) { + *should = false; + } + } + }); } void Rando::StaticData::RegisterFairyLocations() { @@ -406,6 +422,26 @@ void Rando::StaticData::RegisterFairyLocations() { 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_HC_NEAR_WALL_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_HC_NEAR_WALL_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1, 1476), "Near Wall Butterfly Fairy", RHT_BUTTERFLY_FAIRY_HYRULE_CASTLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_WALL_BUTTERFLY_FAIRY)); + locationTable[RC_HC_NEAR_STAIRS_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_HC_NEAR_STAIRS_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1, 1493), "Near Stairs Butterfly Fairy", RHT_BUTTERFLY_FAIRY_HYRULE_CASTLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_STAIRS_BUTTERFLY_FAIRY)); + locationTable[RC_HC_NEAR_BOULDER_PATH_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_HC_NEAR_BOULDER_PATH_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1, 1413), "Near Boulder Path Butterfly Fairy", RHT_BUTTERFLY_FAIRY_HYRULE_CASTLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_BOULDER_PATH_BUTTERFLY_FAIRY)); + locationTable[RC_HC_NEAR_ARCHWAY_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_HC_NEAR_ARCHWAY_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1, 1478), "Near Archway Butterfly Fairy", RHT_BUTTERFLY_FAIRY_HYRULE_CASTLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_ARCHWAY_BUTTERFLY_FAIRY)); + locationTable[RC_LW_MEADOW_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_LW_MEADOW_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(1, 28), "Meadow Butterfly Fairy", RHT_BUTTERFLY_FAIRY_LOST_WOODS, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_MEADOW_BUTTERFLY_FAIRY)); + locationTable[RC_GY_NEAR_HUT_GRAVE_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_GY_NEAR_HUT_GRAVE_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(1, 137), "Grave Butterfly Fairy", RHT_BUTTERFLY_FAIRY_GRAVEYARD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_NEAR_HUT_GRAVE_BUTTERFLY_FAIRY)); + locationTable[RC_ZR_NEAR_ROCK_CIRCLE_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_ZR_NEAR_ROCK_CIRCLE_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(1, 164), "Near Rock Circle Butterfly Fairy", RHT_BUTTERFLY_FAIRY_ZORAS_RIVER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_ROCK_CIRCLE_BUTTERFLY_FAIRY)); + locationTable[RC_ZR_WATERFALL_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_ZR_WATERFALL_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(1, 1010), "Waterfall Butterfly Fairy", RHT_BUTTERFLY_FAIRY_ZORAS_RIVER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WATERFALL_BUTTERFLY_FAIRY)); + locationTable[RC_ZF_LOG_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_ZF_LOG_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(1, 169), "Log Butterfly Fairy", RHT_BUTTERFLY_FAIRY_ZORAS_FOUNTAIN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_LOG_BUTTERFLY_FAIRY)); + locationTable[RC_LH_SCARECROW_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_LH_SCARECROW_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(1, -1254), "Scarecrow Butterfly Fairy", RHT_BUTTERFLY_FAIRY_LAKE_HYLIA, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SCARECROW_BUTTERFLY_FAIRY)); + locationTable[RC_KF_STORMS_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_KF_STORMS_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1B, 44), "Storms Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_KF_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_BUTTERFLY_FAIRY)); + locationTable[RC_LW_TUNNEL_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_LW_TUNNEL_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1A, 44), "Tunnel Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_LW_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_TUNNEL_GROTTO_BUTTERFLY_FAIRY)); + locationTable[RC_DMT_STORMS_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_DMT_STORMS_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x8, 44), "Storms Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_DMT_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_BUTTERFLY_FAIRY)); + locationTable[RC_DMC_UPPER_BOULDER_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_DMC_UPPER_BOULDER_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x6, 44), "Upper Boulder Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_DMC_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_BOULDER_GROTTO_BUTTERFLY_FAIRY)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_HF_NEAR_MARKET_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x10, 44), "Near Market Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_HF_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_BUTTERFLY_FAIRY)); + locationTable[RC_HF_SOUTHEAST_BOULDER_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_HF_SOUTHEAST_BOULDER_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x14, 44), "Southeast Boulder Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_HF_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_BOULDER_GROTTO_BUTTERFLY_FAIRY)); + locationTable[RC_HF_OPEN_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_HF_OPEN_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x13, 44), "Open Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_HF_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_BUTTERFLY_FAIRY)); + locationTable[RC_KAK_OPEN_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_KAK_OPEN_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0xA, 44), "Open Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_KAK_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_BUTTERFLY_FAIRY)); + locationTable[RC_ZR_OPEN_GROTTO_BUTTERFLY_FAIRY] = Location::ButterflyFairy(RC_ZR_OPEN_GROTTO_BUTTERFLY_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x4, 44), "Open Grotto Butterfly Fairy", RHT_BUTTERFLY_FAIRY_ZR_GROTTO, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_BUTTERFLY_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)); diff --git a/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp index cd43ee7508..53d81d85bb 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp @@ -1,4 +1,5 @@ #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "variables.h" diff --git a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp index 14053bff55..0dd29be179 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp @@ -3,6 +3,8 @@ #include "static_data.h" #include "item_category_adj.h" #include "soh/ObjectExtension/ObjectExtension.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "variables.h" @@ -114,6 +116,69 @@ void EnKusa_RandomizerSpawnCollectible(EnKusa* grassActor, PlayState* play) { item00->actor.world.rot.y = static_cast(Rand_CenteredFloat(65536.0f)); } +static CheckIdentity IdentifyGrass(s32 sceneNum, s32 posX, s32 posZ, s32 respawnData, s32 linkAge) { + CheckIdentity grassIdentity; + + grassIdentity.randomizerInf = RAND_INF_MAX; + grassIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + if (sceneNum == SCENE_GROTTOS) { + respawnData = TWO_ACTOR_PARAMS(posX, respawnData); + } else { + // We'll just pretend it's always daytime for our market bushes. + if (sceneNum == SCENE_MARKET_NIGHT) { + sceneNum = SCENE_MARKET_DAY; + + /* + The two bushes by the tree are not in the same spot + between night and day. We'll assume the coordinates + of the daytime bushes so that we can count them as + the same locations. + */ + if (posX == -74) { + posX = -106; + posZ = 277; + } + if (posX == -87) { + posX = -131; + posZ = 225; + } + } + + /* + Same as with Market. ZR has a bush slightly off pos + between Child and Adult. This is to merge them into + a single location. + */ + if (sceneNum == SCENE_ZORAS_RIVER) { + if (posX == 233) { + posX = 231; + posZ = -1478; + } + } + + // The two bushes behind the sign in KF should be separate + // locations between Child and Adult. + if (sceneNum == SCENE_KOKIRI_FOREST && linkAge == 0) { + if (posX == -498 || posX == -523) { + posZ = 0xFF; + } + } + + respawnData = TWO_ACTOR_PARAMS(posX, posZ); + } + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_KUSA, sceneNum, respawnData); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + grassIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + grassIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return grassIdentity; +} + void EnKusa_RandomizerInit(void* actorRef) { Actor* actor = static_cast(actorRef); @@ -123,8 +188,8 @@ void EnKusa_RandomizerInit(void* actorRef) { EnKusa* grassActor = static_cast(actorRef); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - auto grassIdentity = OTRGlobals::Instance->gRandomizer->IdentifyGrass( - gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z, respawnData, gPlayState->linkAgeOnLoad); + auto grassIdentity = IdentifyGrass(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z, + respawnData, gPlayState->linkAgeOnLoad); ObjectExtension::GetInstance().Set(actor, std::move(grassIdentity)); } diff --git a/soh/soh/Enhancements/randomizer/ShuffleIcicles.cpp b/soh/soh/Enhancements/randomizer/ShuffleIcicles.cpp new file mode 100644 index 0000000000..fc0adcebe0 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleIcicles.cpp @@ -0,0 +1,331 @@ +#include "soh/ObjectExtension/ObjectExtension.h" +#include "item_category_adj.h" +#include "particle_cmc.h" +#include "soh/frame_interpolation.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" + +extern "C" { +#include "functions.h" +#include "overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.h" +#include "objects/object_tk/object_tk.h" +extern PlayState* gPlayState; +} + +struct StalactiteDropped {}; +static ObjectExtension::Register StalactiteDroppedRegister; + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +extern "C" void DrawItemHalo(Actor* icicleActor) { + // If the regrowing stalactite has already dropped, return + if (ObjectExtension::GetInstance().Has(icicleActor)) { + return; + } + + GetItemCategory getItemCategory; + bool cmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + int isNotCMC = !cmc || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + const auto icicleIdentity = ObjectExtension::GetInstance().Get(icicleActor); + + GetItemEntry icicleItem = + Rando::Context::GetInstance()->GetFinalGIEntry(icicleIdentity->randomizerCheck, true, GI_NONE); + getItemCategory = Randomizer_AdjustItemCategory(icicleItem); + + if (isNotCMC) { + getItemCategory = ITEM_CATEGORY_MAJOR; + } + Color_RGBA8 primColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_PRIMARY); + + // Align halo to center of icicles + // Ice Cavern HP room is slightly different for stalactites + f32 yOffset = (icicleActor->params == 0) ? 135.0f : 45.0f; + f32 xOffset = -23.0f; + f32 zOffset = (icicleActor->params == 0) ? 5.0f + : (gPlayState->sceneNum == SCENE_ICE_CAVERN && gPlayState->roomCtx.curRoom.num == 11) ? 4.0f + : 2.0f; + + // Rotate and draw halo with CMC colors + Matrix_Translate(icicleActor->world.pos.x + xOffset, icicleActor->world.pos.y + yOffset, + icicleActor->world.pos.z + zOffset, MTXMODE_NEW); + Matrix_RotateZ(-M_PI / 2, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + OPEN_DISPS(gPlayState->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(gPlayState->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetGrayscaleColor(POLY_OPA_DISP++, primColor.r, primColor.g, primColor.b, 175); + gSPGrayscale(POLY_OPA_DISP++, true); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gDampeHaloDL); + gSPGrayscale(POLY_OPA_DISP++, false); + CLOSE_DISPS(gPlayState->state.gfxCtx); +} + +uint8_t BgIceTurara_RandomizerHoldsItem(Actor* actor) { + const auto icicleIdentity = ObjectExtension::GetInstance().Get(actor); + if (icicleIdentity == nullptr) { + return false; + } + + RandomizerCheck rc = icicleIdentity->randomizerCheck; + + // Don't pull randomized item if icicle isn't randomized or is already checked + if (!IS_RANDO || Flags_GetRandomizerInf(icicleIdentity->randomizerInf) || + icicleIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { + return false; + } else { + return true; + } +} + +void BgIceTurara_RandomizerSpawnCollectible(void* actor) { + BgIceTurara* icicleActor = (BgIceTurara*)actor; + const auto icicleIdentity = ObjectExtension::GetInstance().Get(&icicleActor->dyna.actor); + + EnItem00* item00 = + (EnItem00*)Item_DropCollectible2(gPlayState, &icicleActor->dyna.actor.world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = icicleIdentity->randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(icicleIdentity->randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 8.0f; + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = static_cast(Rand_CenteredFloat(65536.0f)); +} + +static CheckIdentity IdentifyIcicle(s32 sceneNum, s32 posX, s32 posZ) { + struct CheckIdentity icicleIdentity; + uint32_t icicleSceneNum = sceneNum; + + icicleIdentity.randomizerInf = RAND_INF_MAX; + icicleIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_BG_ICE_TURARA, icicleSceneNum, actorParams); + + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifyIcicle did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + assert(false); + } else { + icicleIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + icicleIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return icicleIdentity; +} + +void RegisterShuffleIcicles() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_ICICLES).Get(); + + COND_ID_HOOK(OnActorInit, ACTOR_BG_ICE_TURARA, shouldRegister, [](void* actorRef) { + Actor* actor = static_cast(actorRef); + BgIceTurara* icicleActor = static_cast(actorRef); + + auto icicleIdentity = IdentifyIcicle(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + ObjectExtension::GetInstance().Set(actor, std::move(icicleIdentity)); + }); + + // Draw halo around icicles + COND_VB_SHOULD(VB_ICICLE_SETUP_DRAW, shouldRegister, { + BgIceTurara* icicleActor = va_arg(args, BgIceTurara*); + if (BgIceTurara_RandomizerHoldsItem(&icicleActor->dyna.actor) && + !ObjectExtension::GetInstance().Has(&icicleActor->dyna.actor)) { + DrawItemHalo(&icicleActor->dyna.actor); + } + }); + + // Drop item for stalagmites + COND_VB_SHOULD(VB_STALAGMITE_DROP_ITEM, shouldRegister, { + BgIceTurara* icicleActor = va_arg(args, BgIceTurara*); + + if (*should) { + if (BgIceTurara_RandomizerHoldsItem(&icicleActor->dyna.actor)) { + BgIceTurara_RandomizerSpawnCollectible(&icicleActor->dyna.actor); + } + } + }); + + // Drop item for stalactites + COND_VB_SHOULD(VB_STALACTITE_DROP_ITEM, shouldRegister, { + BgIceTurara* icicleActor = va_arg(args, BgIceTurara*); + + if (BgIceTurara_RandomizerHoldsItem(&icicleActor->dyna.actor)) { + // Set and check if regrowing stalactite has already dropped + if (*should) { + auto& ext = ObjectExtension::GetInstance(); + if (!ext.Has(&icicleActor->dyna.actor)) { + ext.Set(&icicleActor->dyna.actor, StalactiteDropped{}); + BgIceTurara_RandomizerSpawnCollectible(&icicleActor->dyna.actor); + } + } else { + BgIceTurara_RandomizerSpawnCollectible(&icicleActor->dyna.actor); + } + } + }); + + // Remove the drop indicator when the actor is destroyed + COND_ID_HOOK(OnActorDestroy, ACTOR_BG_ICE_TURARA, shouldRegister, + [](void* actor) { ObjectExtension::GetInstance().Remove(actor); }); +} + +void Rando::StaticData::RegisterIcicleLocations() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Spoiler Collection Check + locationTable[RC_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(295, 2386), "Entrance Left Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_ENTRANCE_MIDDLE_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_ENTRANCE_MIDDLE_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(313, 2446), "Entrance Middle Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_MIDDLE_STALAGMITE)); + locationTable[RC_ICE_CAVERN_ENTRANCE_RIGHT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_ENTRANCE_RIGHT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(400, 2443), "Entrance Right Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_RIGHT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_ENTRANCE_STALACTITE_1] = Location::Icicle(RC_ICE_CAVERN_ENTRANCE_STALACTITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(499, 2229), "Entrance Stalactite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_STALACTITE_1)); + locationTable[RC_ICE_CAVERN_ENTRANCE_STALACTITE_2] = Location::Icicle(RC_ICE_CAVERN_ENTRANCE_STALACTITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(536, 2071), "Entrance Stalactite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_STALACTITE_2)); + locationTable[RC_ICE_CAVERN_LOBBY_STALACTITE] = Location::Icicle(RC_ICE_CAVERN_LOBBY_STALACTITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-18, 1760), "Lobby Stalactite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_STALACTITE)); + locationTable[RC_ICE_CAVERN_LOBBY_LEFT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_LOBBY_LEFT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-62, 1642), "Lobby Left Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_LEFT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_LOBBY_MIDDLE_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_LOBBY_MIDDLE_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-19, 1676), "Lobby Middle Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_MIDDLE_STALAGMITE)); + locationTable[RC_ICE_CAVERN_LOBBY_RIGHT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_LOBBY_RIGHT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(36, 1643), "Lobby Right Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_RIGHT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_AFTER_LOBBY_STALACTITE] = Location::Icicle(RC_ICE_CAVERN_AFTER_LOBBY_STALACTITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-237, 472), "After Lobby Stalactite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_AFTER_LOBBY_STALACTITE)); + locationTable[RC_ICE_CAVERN_AFTER_LOBBY_LEFT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_AFTER_LOBBY_LEFT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-308, 322), "After Lobby Left Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_AFTER_LOBBY_LEFT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_AFTER_LOBBY_CENTER_LEFT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_AFTER_LOBBY_CENTER_LEFT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-272, 348), "After Lobby Center Left Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_AFTER_LOBBY_CENTER_LEFT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_AFTER_LOBBY_CENTER_RIGHT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_AFTER_LOBBY_CENTER_RIGHT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-226, 371), "After Lobby Center Right Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_AFTER_LOBBY_CENTER_RIGHT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_AFTER_LOBBY_RIGHT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_AFTER_LOBBY_RIGHT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-187, 395), "After Lobby Right Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_AFTER_LOBBY_RIGHT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_SPINNING_BLADE_LEFT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_SPINNING_BLADE_LEFT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(44, -139), "Spinning Blade Left Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SPINNING_BLADE_LEFT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_SPINNING_BLADE_MIDDLE_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_SPINNING_BLADE_MIDDLE_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(22, -170), "Spinning Blade Middle Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SPINNING_BLADE_MIDDLE_STALAGMITE)); + locationTable[RC_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-9, -175), "Spinning Blade Right Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_1] = Location::Icicle(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1264, -890), "Map Hallway Stalactite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_1)); + locationTable[RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_2] = Location::Icicle(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1141, -946), "Map Hallway Stalactite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_2)); + locationTable[RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_3] = Location::Icicle(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1229, -1134), "Map Hallway Stalactite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_3)); + locationTable[RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_4] = Location::Icicle(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_4, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1063, -1300), "Map Hallway Stalactite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_4)); + locationTable[RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_5] = Location::Icicle(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_5, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1088, -1505), "Map Hallway Stalactite 5", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_5)); + locationTable[RC_ICE_CAVERN_MAP_HALLWAY_LEFT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_MAP_HALLWAY_LEFT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(951, -1217), "Map Hallway Left Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_HALLWAY_LEFT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_MAP_HALLWAY_MIDDLE_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_MAP_HALLWAY_MIDDLE_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1029, -1217), "Map Hallway Middle Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_HALLWAY_MIDDLE_STALAGMITE)); + locationTable[RC_ICE_CAVERN_MAP_HALLWAY_RIGHT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_MAP_HALLWAY_RIGHT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1187, -1217), "Map Hallway Right Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_HALLWAY_RIGHT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1026, 296), "Heart Piece Room Center Stalactite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_2] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1092, 274), "Heart Piece Room Center Stalactite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_2)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_3] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1058, 369), "Heart Piece Room Center Stalactite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_3)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_4] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_4, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1148, 347), "Heart Piece Room Center Stalactite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_4)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_5] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_5, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1252, 356), "Heart Piece Room Center Stalactite 5", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_5)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_1] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1187, 66), "Heart Piece Room Left Stalactite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_1)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_2] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1347, 110), "Heart Piece Room Left Stalactite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_2)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1361, 312), "Heart Piece Room Center Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1336, 343), "Heart Piece Room Center Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_3] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1348, 382), "Heart Piece Room Center Stalagmite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_3)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_4] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_4, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1321, 404), "Heart Piece Room Center Stalagmite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_4)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_5] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_5, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1341, 438), "Heart Piece Room Center Stalagmite 5", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_5)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_6] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_6, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1317, 470), "Heart Piece Room Center Stalagmite 6", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_6)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1223, 195), "Heart Piece Room Left Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1257, 202), "Heart Piece Room Left Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_3] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1297, 200), "Heart Piece Room Left Stalagmite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_3)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1159, 552), "Heart Piece Room Right Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1191, 565), "Heart Piece Room Right Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_3] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1227, 549), "Heart Piece Room Right Stalagmite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_3)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_4] = Location::Icicle(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_4, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1267, 559), "Heart Piece Room Right Stalagmite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_4)); + locationTable[RC_ICE_CAVERN_PUSH_BLOCK_HALL_LEFT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_PUSH_BLOCK_HALL_LEFT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-518, -601), "Push Block Hall Left Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_LEFT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_LEFT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_LEFT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-487, -600), "Push Block Hall Center Left Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_LEFT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-451, -604), "Push Block Hall Center Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_STALAGMITE)); + locationTable[RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_RIGHT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_RIGHT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-414, -610), "Push Block Hall Center Right Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_RIGHT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_PUSH_BLOCK_HALL_RIGHT_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_PUSH_BLOCK_HALL_RIGHT_STALAGMITE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-373, -605), "Push Block Hall Right Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_RIGHT_STALAGMITE)); + locationTable[RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_1] = Location::Icicle(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-385, -686), "Push Block Hall Stalactite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_1)); + locationTable[RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2] = Location::Icicle(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-314, -768), "Push Block Hall Stalactite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2)); + locationTable[RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3] = Location::Icicle(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-359, -862), "Push Block Hall Stalactite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALACTITE_1] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALACTITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1231, 170), "Near End Stalactite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_1)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALACTITE_2] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALACTITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1328, 215), "Near End Stalactite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_2)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALACTITE_3] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALACTITE_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1412, 246), "Near End Stalactite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_3)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALACTITE_4] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALACTITE_4, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1571, 422), "Near End Stalactite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_4)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALAGMITE_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1288, 184), "Near End Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALAGMITE_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1367, 206), "Near End Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALAGMITE_3] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALAGMITE_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1349, 270), "Near End Stalagmite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_3)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALAGMITE_4] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALAGMITE_4, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1514, 307), "Near End Stalagmite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_4)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALAGMITE_5] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALAGMITE_5, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1507, 443), "Near End Stalagmite 5", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_5)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALAGMITE_6] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALAGMITE_6, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1624, 431), "Near End Stalagmite 6", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_6)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALAGMITE_7] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALAGMITE_7, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1587, 497), "Near End Stalagmite 7", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_7)); + locationTable[RC_ICE_CAVERN_NEAR_END_STALAGMITE_8] = Location::Icicle(RC_ICE_CAVERN_NEAR_END_STALAGMITE_8, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1595, 600), "Near End Stalagmite 8", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_8)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_1] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1687, -859), "Water Trial Stalagmite 1", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_1)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_2] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1706, -884), "Water Trial Stalagmite 2", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_2)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_3] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_3, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1735, -898), "Water Trial Stalagmite 3", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_3)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_4] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_4, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1761, -887), "Water Trial Stalagmite 4", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_4)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_5] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_5, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1787, -871), "Water Trial Stalagmite 5", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_5)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_6] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_6, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1783, -833), "Water Trial Stalagmite 6", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_6)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_7] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_7, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1770, -798), "Water Trial Stalagmite 7", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_7)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_8] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_8, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1737, -787), "Water Trial Stalagmite 8", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_8)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_9] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_9, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1698, -797), "Water Trial Stalagmite 9", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_9)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_10] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_10, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1683, -828), "Water Trial Stalagmite 10", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_10)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_1] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1966, -1089), "Water Trial Left Stalagmite 1", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_1)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_2] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2040, -1015), "Water Trial Left Stalagmite 2", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_2)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_1] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1980, -590), "Water Trial Right Stalagmite 1", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_1)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_2] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2058, -655), "Water Trial Right Stalagmite 2", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_2)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_1] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1549, -836), "Water Trial Stalactite 1", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_1)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_2] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1611, -843), "Water Trial Stalactite 2", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_2)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_3] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_3, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1657, -882), "Water Trial Stalactite 3", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_3)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_4] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_4, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1651, -805), "Water Trial Stalactite 4", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_4)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_5] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_5, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1761, -949), "Water Trial Stalactite 5", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_5)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_6] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_6, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1714, -757), "Water Trial Stalactite 6", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_6)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_7] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_7, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1811, -905), "Water Trial Stalactite 7", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_7)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_8] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_8, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1769, -761), "Water Trial Stalactite 8", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_8)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_9] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_9, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1821, -817), "Water Trial Stalactite 9", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_9)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_10] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_10, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1996, -1033), "Water Trial Stalactite 10", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_10)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_11] = Location::Icicle(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_11, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1995, -648), "Water Trial Stalactite 11", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_11)); + locationTable[RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(287, 2346), "Entrance Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(324, 2280), "Entrance Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(268, 980), "Lobby Stalactite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_LOBBY_STALACTITE_1)); + locationTable[RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(204, 910), "Lobby Stalactite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_LOBBY_STALACTITE_2)); + locationTable[RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-351, 423), "After Lobby Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-288, 402), "After Lobby Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_3] = Location::Icicle(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_3, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-258, 461), "After Lobby Stalagmite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_3)); + locationTable[RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_4] = Location::Icicle(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_4, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-212, 398), "After Lobby Stalagmite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_4)); + locationTable[RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_5] = Location::Icicle(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_5, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-19, 193), "After Lobby Stalagmite 5", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_5)); + locationTable[RC_ICE_CAVERN_MQ_HUB_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(607, -170), "Hub Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_MQ_HUB_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(598, -213), "Hub Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_MQ_HUB_STALAGMITE_3] = Location::Icicle(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_3, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(597, -256), "Hub Stalagmite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_3)); + locationTable[RC_ICE_CAVERN_MQ_HUB_STALAGMITE_4] = Location::Icicle(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_4, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(614, -292), "Hub Stalagmite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_4)); + locationTable[RC_ICE_CAVERN_MQ_HUB_STALAGMITE_5] = Location::Icicle(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_5, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(640, -312), "Hub Stalagmite 5", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_5)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1170, 97), "Map Room Left Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1149, 64), "Map Room Left Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1334, 473), "Map Room Center Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1327, 442), "Map Room Center Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_3] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_3, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1321, 410), "Map Room Center Stalagmite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_3)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_4] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_4, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1325, 369), "Map Room Center Stalagmite 4", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_4)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_5] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_5, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1344, 332), "Map Room Center Stalagmite 5", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_5)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_6] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_6, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1375, 291), "Map Room Center Stalagmite 6", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_6)); + locationTable[RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_7] = Location::Icicle(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_7, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1345, 260), "Map Room Center Stalagmite 7", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_7)); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(742, -2464), "Compass Left Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(783, -2453), "Compass Left Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(903, -2353), "Compass Right Stalagmite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_1)); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(929, -2303), "Compass Right Stalagmite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_2)); + locationTable[RC_ICE_CAVERN_MQ_BEFORE_SCARECROW_STALAGMITE] = Location::Icicle(RC_ICE_CAVERN_MQ_BEFORE_SCARECROW_STALAGMITE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-261, -840), "Before Scarecrow Stalagmite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_BEFORE_SCARECROW_STALAGMITE)); + locationTable[RC_ICE_CAVERN_MQ_SCARECROW_ROOM_STALACTITE] = Location::Icicle(RC_ICE_CAVERN_MQ_SCARECROW_ROOM_STALACTITE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-763, -896), "Scarecrow Room Stalactite", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_SCARECROW_ROOM_STALACTITE)); + locationTable[RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_1] = Location::Icicle(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1524, 326), "West Corridor Stalactite 1", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_1)); + locationTable[RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_2] = Location::Icicle(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1583, 609), "West Corridor Stalactite 2", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_2)); + locationTable[RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_3] = Location::Icicle(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_3, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1487, 569), "West Corridor Stalactite 3", RHT_ICE_CAVERN_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_3)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1265, -2067), "Boulder Room Stalagmite 1", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1235, -2054), "Boulder Room Stalagmite 2", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_3] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_3, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1205, -2080), "Boulder Room Stalagmite 3", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_3)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_4] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_4, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1170, -2080), "Boulder Room Stalagmite 4", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_4)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_5] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_5, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1183, -2132), "Boulder Room Stalagmite 5", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_5)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_1] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1261, -1001), "Boulder Room Right Stalactite 1", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_1)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_2] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1247, -1096), "Boulder Room Right Stalactite 2", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_2)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_3] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_3, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1182, -1181), "Boulder Room Right Stalactite 3", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_3)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_4] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_4, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1255, -1273), "Boulder Room Right Stalactite 4", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_4)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_LEFT_STALACTITE] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_LEFT_STALACTITE, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1884, -1024), "Boulder Room Left Stalactite", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_LEFT_STALACTITE)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1263, -2028), "Boulder Room Top Right Stalactite 1", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1216, -2029), "Boulder Room Top Right Stalactite 2", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3] = Location::Icicle(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1168, -2028), "Boulder Room Top Right Stalactite 3", RHT_GERUDO_TRAINING_GROUND_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_1] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1791, -1141), "Water Trial Left Stalactite 1", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_1)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_2] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1890, -1068), "Water Trial Left Stalactite 2", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_2)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_3] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2002, -1068), "Water Trial Left Stalactite 3", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_3)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_1] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1864, -568), "Water Trial Right Stalactite 1", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_1)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_2] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1937, -658), "Water Trial Right Stalactite 2", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_2)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_3] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2054, -667), "Water Trial Right Stalactite 3", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_3)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_1] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1868, -1175), "Water Trial Left Stalagmite 1", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_1)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_2] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1908, -1151), "Water Trial Left Stalagmite 2", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_2)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_3] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1960, -1123), "Water Trial Left Stalagmite 3", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_3)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_4] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2008, -1115), "Water Trial Left Stalagmite 4", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_4)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_1] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1916, -511), "Water Trial Right Stalagmite 1", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_1)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_2] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1936, -551), "Water Trial Right Stalagmite 2", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_2)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_3] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1984, -567), "Water Trial Right Stalagmite 3", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_3)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_4] = Location::Icicle(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2044, -591), "Water Trial Right Stalagmite 4", RHT_GANONS_CASTLE_ICICLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_4)); + // clang-format on +} + +static RegisterShipInitFunc initFunc_ShuffleIcicles(RegisterShuffleIcicles, { "IS_RANDO" }); +static RegisterShipInitFunc registerIcicleLocations(Rando::StaticData::RegisterIcicleLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShufflePots.cpp b/soh/soh/Enhancements/randomizer/ShufflePots.cpp index 3dd2c43837..a803460917 100644 --- a/soh/soh/Enhancements/randomizer/ShufflePots.cpp +++ b/soh/soh/Enhancements/randomizer/ShufflePots.cpp @@ -3,6 +3,8 @@ #include "static_data.h" #include "item_category_adj.h" #include "soh/ObjectExtension/ObjectExtension.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h" @@ -99,6 +101,32 @@ void ObjTsubo_RandomizerSpawnCollectible(ObjTsubo* potActor, PlayState* play) { item00->actor.world.rot.y = static_cast(Rand_CenteredFloat(65536.0f)); } +static CheckIdentity IdentifyPot(s32 sceneNum, s32 posX, s32 posZ) { + CheckIdentity potIdentity; + uint32_t potSceneNum = sceneNum; + + if (sceneNum == SCENE_GANONDORF_BOSS) { + potSceneNum = SCENE_GANONS_TOWER; + } + + potIdentity.randomizerInf = RAND_INF_MAX; + potIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_OBJ_TSUBO, potSceneNum, actorParams); + + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifyPot did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + } else { + potIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + potIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return potIdentity; +} + void RegisterShufflePots() { bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_POTS); @@ -106,8 +134,7 @@ void RegisterShufflePots() { Actor* actor = static_cast(actorRef); ObjTsubo* potActor = static_cast(actorRef); - auto potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot(gPlayState->sceneNum, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); + auto potIdentity = IdentifyPot(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); ObjectExtension::GetInstance().Set(actor, std::move(potIdentity)); }); diff --git a/soh/soh/Enhancements/randomizer/ShuffleRedIce.cpp b/soh/soh/Enhancements/randomizer/ShuffleRedIce.cpp new file mode 100644 index 0000000000..979b13367e --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRedIce.cpp @@ -0,0 +1,235 @@ +#include "soh/OTRGlobals.h" +#include "soh/ObjectExtension/ObjectExtension.h" +#include "item_category_adj.h" +#include "particle_cmc.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" + +extern "C" { +#include "functions.h" +#include "overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.h" +#include "objects/object_ice_objects/object_ice_objects.h" +extern PlayState* gPlayState; +} + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +uint8_t BgIceShelter_RandomizerHoldsItem(Actor* actor) { + const auto redIceIdentity = ObjectExtension::GetInstance().Get(actor); + if (redIceIdentity == nullptr) { + return false; + } + + RandomizerCheck rc = redIceIdentity->randomizerCheck; + + // Don't pull randomized item if icicle isn't randomized or is already checked + if (!IS_RANDO || Flags_GetRandomizerInf(redIceIdentity->randomizerInf) || + redIceIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { + return false; + } else { + return true; + } +} + +static void BgIceShelter_RandomizerDraw(Actor* actor, Color_RGBA8* primColor, Color_RGBA8* secColor, + Color_RGBA8* envColor) { + Vec3f pos; + s32 type = (actor->params >> 8) & 7; + static Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + static Vec3f accel = { 0.0f, 0.0f, 0.0f }; + + velocity.y = -0.05f; + accel.y = -0.025f; + + // align for King Zora's much bigger red ice + f32 xzScale = (type == RED_ICE_KING_ZORA) ? 30.0f : 15.0f; + f32 yOffset = (type == RED_ICE_KING_ZORA) ? 200.0f : 0.0f; + f32 zOffset = (type == RED_ICE_KING_ZORA) ? 50.0f : 0.0f; + + pos.x = Rand_CenteredFloat(xzScale) + actor->world.pos.x; + pos.y = (Rand_ZeroOne() * 15.0f) + actor->world.pos.y + yOffset; + pos.z = Rand_CenteredFloat(xzScale) + actor->world.pos.z + zOffset; + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, secColor, envColor, 2000, 100); + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, primColor, envColor, 2000, 100); +} + +void BgIceShelter_RandomizerDrawSetup(void* actor) { + GetItemCategory getItemCategory; + Actor* redIceActor = (Actor*)actor; + + // If not a randomized item or too far, don't draw + if (!BgIceShelter_RandomizerHoldsItem(redIceActor) || redIceActor->xzDistToPlayer > 1000.0f) { + return; + } + + bool cmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + + int isNotCMC = !cmc || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + + Color_RGBA8 primColor; + Color_RGBA8 secColor; + Color_RGBA8 envColor; + + const auto redIceIdentity = ObjectExtension::GetInstance().Get(redIceActor); + if (redIceIdentity == nullptr) { + return; + } + + GetItemEntry redIceItem = + Rando::Context::GetInstance()->GetFinalGIEntry(redIceIdentity->randomizerCheck, true, GI_NONE); + getItemCategory = Randomizer_AdjustItemCategory(redIceItem); + + if (isNotCMC) { + getItemCategory = ITEM_CATEGORY_MAJOR; + } + primColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_PRIMARY); + secColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_SECONDARY); + envColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_FLARE); + BgIceShelter_RandomizerDraw(redIceActor, &primColor, &secColor, &envColor); +} + +void BgIceShelter_RandomizerSpawnCollectible(Actor* actor) { + const auto redIceIdentity = ObjectExtension::GetInstance().Get(actor); + Player* player = GET_PLAYER(gPlayState); + + // If King Zora, autocollect to avoid spawning issues + if (redIceIdentity->randomizerCheck == RC_ZD_KING_ZORA_RED_ICE) { + Flags_SetRandomizerInf(redIceIdentity->randomizerInf); + } else { + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(gPlayState, &actor->world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = redIceIdentity->randomizerInf; + item00->itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(redIceIdentity->randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 8.0f; + // In general, spawn in place, but for checks with objects blocking, spawn out toward player + if ((redIceIdentity->randomizerCheck >= RC_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE && + redIceIdentity->randomizerCheck <= RC_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE) || + redIceIdentity->randomizerCheck == RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE || + redIceIdentity->randomizerCheck == RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE || + redIceIdentity->randomizerCheck == RC_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE) { + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = + Math_Vec3f_Yaw(&item00->actor.world.pos, &player->actor.world.pos) + (s16)Rand_CenteredFloat(16384.0f); + } else { + item00->actor.speedXZ = 0.0f; + item00->actor.world.rot.y = static_cast(Rand_CenteredFloat(65536.0f)); + } + } +} + +static CheckIdentity IdentifyRedIce(s32 sceneNum, s32 posX, s32 posZ) { + struct CheckIdentity redIceIdentity; + uint32_t redIceSceneNum = sceneNum; + + // Handle KZ moving + if (sceneNum == SCENE_ZORAS_DOMAIN && LINK_IS_ADULT && posX == 531 && posZ == -1818) { + posX = 628; + } + + redIceIdentity.randomizerInf = RAND_INF_MAX; + redIceIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_BG_ICE_SHELTER, redIceSceneNum, actorParams); + + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifyRedIce did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + assert(false); + } else { + redIceIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + redIceIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return redIceIdentity; +} + +void RegisterShuffleRedIce() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_RED_ICE).Get(); + + COND_VB_SHOULD(VB_RED_ICE_MELTED_FLAG, shouldRegister, { + BgIceShelter* redIceActor = va_arg(args, BgIceShelter*); + Actor* actor = (Actor*)redIceActor; + + auto redIceIdentity = IdentifyRedIce(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + ObjectExtension::GetInstance().Set(actor, std::move(redIceIdentity)); + + if (*should) { + if (BgIceShelter_RandomizerHoldsItem(&redIceActor->dyna.actor)) { + BgIceShelter_RandomizerSpawnCollectible(actor); + } + } + }); + + // Draw particle effect to indicate a randomized item + COND_ID_HOOK(OnActorUpdate, ACTOR_BG_ICE_SHELTER, shouldRegister, BgIceShelter_RandomizerDrawSetup); + + // Collect item for melting red ice + COND_VB_SHOULD(VB_RED_ICE_DROP_ITEM, shouldRegister, { + BgIceShelter* redIceActor = va_arg(args, BgIceShelter*); + + if (*should) { + if (BgIceShelter_RandomizerHoldsItem(&redIceActor->dyna.actor)) { + BgIceShelter_RandomizerSpawnCollectible(&redIceActor->dyna.actor); + } + } + }); +} + +void Rando::StaticData::RegisterRedIceLocations() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Spoiler Collection Check + locationTable[RC_ZD_KING_ZORA_RED_ICE] = Location::RedIce(RC_ZD_KING_ZORA_RED_ICE, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(628, -1818), "King Zora Red Ice", RHT_RED_ICE_ZORAS_DOMAIN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_KING_ZORA_RED_ICE)); + locationTable[RC_ZD_ZORA_SHOP_RED_ICE] = Location::RedIce(RC_ZD_ZORA_SHOP_RED_ICE, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(483, 214), "Zora Shop Red Ice", RHT_RED_ICE_ZORAS_DOMAIN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_ZORA_SHOP_RED_ICE)); + locationTable[RC_ICE_CAVERN_ENTRANCE_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_ENTRANCE_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(411, 2332), "Entrance Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_RED_ICE)); + locationTable[RC_ICE_CAVERN_LOBBY_LEFT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_LOBBY_LEFT_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-105, 854), "Lobby Left Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_LEFT_RED_ICE)); + locationTable[RC_ICE_CAVERN_LOBBY_RIGHT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_LOBBY_RIGHT_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(119, 856), "Lobby Right Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_RIGHT_RED_ICE)); + locationTable[RC_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(651, -232), "Spinning Blade East Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE)); + locationTable[RC_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-134, -415), "Spinning Blade West Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1261, 68), "Heart Piece Room Freestanding Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE)); + locationTable[RC_ICE_CAVERN_HEART_PIECE_ROOM_CHEST_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_HEART_PIECE_ROOM_CHEST_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1201, 643), "Heart Piece Room Chest Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CHEST_RED_ICE)); + locationTable[RC_ICE_CAVERN_MAP_ROOM_POT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MAP_ROOM_POT_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(366, -2036), "Map Room Pot Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_ROOM_POT_RED_ICE)); + locationTable[RC_ICE_CAVERN_MAP_ROOM_CHEST_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MAP_ROOM_CHEST_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(277, -2600), "Map Room Chest Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_ROOM_CHEST_RED_ICE)); + locationTable[RC_ICE_CAVERN_SILVER_RUPEE_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_SILVER_RUPEE_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1126, -1577), "Silver Rupee Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_RUPEE_RED_ICE)); + locationTable[RC_ICE_CAVERN_NEAR_END_LEFT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_NEAR_END_LEFT_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1422, 586), "Near End Left Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_LEFT_RED_ICE)); + locationTable[RC_ICE_CAVERN_NEAR_END_MIDDLE_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_NEAR_END_MIDDLE_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1459, 625), "Near End Middle Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_MIDDLE_RED_ICE)); + locationTable[RC_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1488, 676), "Near End Right Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_DOOR_RED_ICE] = Location::RedIce(RC_GANONS_CASTLE_WATER_TRIAL_DOOR_RED_ICE, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2212, -840), "Water Trial Door Red Ice", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_DOOR_RED_ICE)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_RUSTED_SWITCH_RED_ICE] = Location::RedIce(RC_GANONS_CASTLE_WATER_TRIAL_RUSTED_SWITCH_RED_ICE, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2912, -1420), "Water Trial Rusted Switch Red Ice", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_RUSTED_SWITCH_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_HUB_WEST_LEFT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_HUB_WEST_LEFT_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-142, -377), "Hub West Left Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_WEST_LEFT_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_HUB_WEST_MIDDLE_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_HUB_WEST_MIDDLE_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-121, -418), "Hub West Middle Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_WEST_MIDDLE_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_HUB_WEST_RIGHT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_HUB_WEST_RIGHT_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-134, -462), "Hub West Right Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_WEST_RIGHT_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_HUB_LEDGE_LEFT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_HUB_LEDGE_LEFT_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(577, -818), "Hub Ledge Left Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_LEFT_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_HUB_LEDGE_MIDDLE_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_HUB_LEDGE_MIDDLE_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(614, -770), "Hub Ledge Middle Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_MIDDLE_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_HUB_LEDGE_RIGHT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_HUB_LEDGE_RIGHT_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(656, -722), "Hub Ledge Right Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_RIGHT_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_COMPASS_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(376, -2048), "Compass Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_COMPASS_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_MAP_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_MAP_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1201, 648), "Map Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_MAP_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1335, -159), "Scarecrow Left Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1386, -159), "Scarecrow Middle Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE)); + locationTable[RC_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE] = Location::RedIce(RC_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1438, -155), "Scarecrow Right Red Ice", RHT_ICE_CAVERN_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_RED_ICE] = Location::RedIce(RC_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_RED_ICE, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-864, -2745), "Stalfos Room Red Ice", RHT_GERUDO_TRAINING_GROUND_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_RED_ICE)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1754, -1152), "Water Trial First Room Left Red Ice", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1743, -529), "Water Trial First Room Right Red Ice", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_BACK_LEFT_RED_ICE] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_BACK_LEFT_RED_ICE, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2096, -1011), "Water Trial First Room Back Left Red Ice", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_BACK_LEFT_RED_ICE)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_1] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2209, -889), "Water Trial First Room Door Red Ice 1", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_1)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_2] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2198, -845), "Water Trial First Room Door Red Ice 2", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_2)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_3] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2194, -797), "Water Trial First Room Door Red Ice 3", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_3)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_4] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2200, -755), "Water Trial First Room Door Red Ice 4", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_4)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3370, -729), "Water Trial Silver Rupee Red Ice", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3370, -776), "Water Trial Second Door Red Ice 1", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3370, -834), "Water Trial Second Door Red Ice 2", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3370, -889), "Water Trial Second Door Red Ice 3", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3370, -950), "Water Trial Second Door Red Ice 4", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5] = Location::RedIce(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2906, -1482), "Water Trial Second Door Red Ice 5", RHT_GANONS_CASTLE_RED_ICE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5)); + // clang-format on +} + +static RegisterShipInitFunc initFunc_ShuffleRedIce(RegisterShuffleRedIce, { "IS_RANDO" }); +static RegisterShipInitFunc registerRedIceLocations(Rando::StaticData::RegisterRedIceLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp new file mode 100644 index 0000000000..a86eb55b60 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp @@ -0,0 +1,630 @@ +#include "ShuffleRocks.h" +#include "static_data.h" +#include "soh/ObjectExtension/ObjectExtension.h" +#include "item_category_adj.h" +#include "particle_cmc.h" +#include "soh/frame_interpolation.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" + +extern "C" { +#include "variables.h" +#include "macros.h" +#include "functions.h" +#include "overlays/actors/ovl_En_Ishi/z_en_ishi.h" +#include "overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h" +#include "overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "objects/object_bombiwa/object_bombiwa.h" +#include "objects/object_tk/object_tk.h" +extern PlayState* gPlayState; +} + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +static void Sparkles(PlayState* play, Actor* actor, bool boulder, CheckIdentity rockIdentity) { + GraphicsContext* __gfxCtx = play->state.gfxCtx; + int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + + GetItemCategory getItemCategory; + if (csmc && (!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { + auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); + getItemCategory = Randomizer_AdjustItemCategory(itemEntry); + } else { + getItemCategory = ITEM_CATEGORY_MAJOR; + } + + Color_RGBA8 primColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_PRIMARY); + + f32 yOffset = !boulder ? 40.0f : actor->id == ACTOR_OBJ_BOMBIWA ? 160.0f : 180.0f; + f32 xOffset = !boulder ? -24.0f : actor->id == ACTOR_OBJ_BOMBIWA ? -90.0f : -90.0f; + f32 zOffset = !boulder ? 4.0f : actor->id == ACTOR_OBJ_BOMBIWA ? 14.5f : 14.5f; + + // Rotate and draw halo with CMC colors + if (rockIdentity.randomizerCheck == RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER || + rockIdentity.randomizerCheck == RC_ZF_UNDERGROUND_BOULDER) { + yOffset = -114.0f; + xOffset = -165.0f; + zOffset = 19.0f; + Matrix_Translate(actor->world.pos.x + xOffset, actor->world.pos.y + yOffset, actor->world.pos.z + zOffset, + MTXMODE_NEW); + Matrix_Scale(0.055f, 0.055f, 0.055f, MTXMODE_APPLY); + } else { + Matrix_Translate(actor->world.pos.x + xOffset, actor->world.pos.y + yOffset, actor->world.pos.z + zOffset, + MTXMODE_NEW); + Matrix_RotateZ(-M_PI / 2, MTXMODE_APPLY); + if (boulder) { + Matrix_Scale(0.04f, 0.04f, 0.04f, MTXMODE_APPLY); + } else { + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + } + } + + OPEN_DISPS(gPlayState->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(gPlayState->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetGrayscaleColor(POLY_OPA_DISP++, primColor.r, primColor.g, primColor.b, 175); + gSPGrayscale(POLY_OPA_DISP++, true); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gDampeHaloDL); + gSPGrayscale(POLY_OPA_DISP++, false); + CLOSE_DISPS(gPlayState->state.gfxCtx); +} + +extern "C" void EnIshi_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((EnIshi*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + if (rockActor->actor.params & 1) { + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); + } else { + Gfx_DrawDListOpa(play, (Gfx*)gFieldKakeraDL); + } + CLOSE_DISPS(play->state.gfxCtx); + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + Sparkles(play, &rockActor->actor, !!(rockActor->actor.params & 1), *rockIdentity); + } +} + +extern "C" void ObjBombiwa_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((ObjBombiwa*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + Gfx_DrawDListOpa(play, (Gfx*)object_bombiwa_DL_0009E0); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)object_bombiwa_DL_0009E0); + CLOSE_DISPS(play->state.gfxCtx); + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + Sparkles(play, &rockActor->actor, true, *rockIdentity); + } +} + +extern "C" void ObjHamishi_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((ObjHamishi*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 170, 130, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); + CLOSE_DISPS(play->state.gfxCtx); + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + Sparkles(play, &rockActor->actor, true, *rockIdentity); + } +} + +uint8_t Rock_RandomizerHoldsItem(CheckIdentity rockIdentity, PlayState* play, bool isBoulder) { + RandomizerCheck rc = rockIdentity.randomizerCheck; + if (rc == RC_MAX || rc == RC_UNKNOWN_CHECK) + return false; + + uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); + uint8_t setting = + Rando::Context::GetInstance()->GetOption(isBoulder ? RSK_SHUFFLE_BOULDERS : RSK_SHUFFLE_ROCKS).Get(); + + // Don't pull randomized item if rock isn't randomized or is already checked + return IS_RANDO && + ((!isBoulder && setting) || (isBoulder && (setting == RO_SHUFFLE_BOULDERS_ALL || + (isDungeon && setting == RO_SHUFFLE_BOULDERS_DUNGEONS) || + (!isDungeon && setting == RO_SHUFFLE_BOULDERS_OVERWORLD)))) && + !Flags_GetRandomizerInf(rockIdentity.randomizerInf); +} + +void Rock_RandomizerSpawnCollectible(Actor* actor, CheckIdentity rockIdentity, PlayState* play) { + LUSLOG_INFO("ROCKdrop %d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &actor->world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = rockIdentity.randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 9.0f; + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f); + switch (rockIdentity.randomizerCheck) { + case RC_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER: + item00->actor.world.rot.y = 0x8000; + break; + case RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_LOW: + item00->actor.velocity.y = 15.0f; + [[fallthrough]]; + case RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_HIGH: + item00->actor.world.rot.y = 0x0; + item00->actor.speedXZ = 8.0f; + break; + case RC_GC_MAZE_BOULDER_1: + case RC_GC_MAZE_BOULDER_2: + case RC_GC_MAZE_BOULDER_3: + case RC_GC_MAZE_BOULDER_4: + case RC_GC_MAZE_BOULDER_5: + case RC_GC_MAZE_BOULDER_6: + case RC_GC_MAZE_BOULDER_7: + case RC_GC_MAZE_BOULDER_8: + case RC_GC_MAZE_BOULDER_9: + case RC_GC_MAZE_BOULDER_10: + case RC_GC_MAZE_BRONZE_BOULDER_1: + case RC_GC_MAZE_BRONZE_BOULDER_2: + case RC_GC_MAZE_BRONZE_BOULDER_3: + case RC_GC_MAZE_BRONZE_BOULDER_4: + case RC_GC_MAZE_BRONZE_BOULDER_5: + case RC_DMC_BRONZE_BOULDER_SHORTCUT: + case RC_ZF_UNDERGROUND_BOULDER: + case RC_DEKU_TREE_MQ_BOULDER_1: + case RC_DEKU_TREE_MQ_BOULDER_2: + case RC_DEKU_TREE_MQ_BOULDER_3: + case RC_ZR_BOULDER_4: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11: + case RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12: + case RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER: + case RC_SPIRIT_TEMPLE_MQ_CRAWLSPACE_BOULDER: + item00->actor.speedXZ = 0.0f; + break; + default:; + } +} + +static CheckIdentity IdentifyRock(s32 sceneNum, s32 posX, s32 posZ) { + CheckIdentity rockIdentity; + + rockIdentity.randomizerInf = RAND_INF_MAX; + rockIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + Rando::Location* location = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor( + ACTOR_EN_ISHI, sceneNum, TWO_ACTOR_PARAMS(posX, posZ)); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + rockIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + rockIdentity.randomizerCheck = location->GetRandomizerCheck(); + } else { + LUSLOG_WARN("IdentifyRock did not receive a valid RC value %d,%d.", posX, posZ); + } + + return rockIdentity; +} + +void EnIshi_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + EnIshi* rockActor = static_cast(actorRef); + auto rockIdentity = IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_WARN("ROCK ishi %d\t:\t%d, %d", rockIdentity.randomizerCheck, actor->params & 1, + (s16)actor->world.pos.x, (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK ishi%d %d\t:\t%d, %d", rockIdentity.randomizerCheck, actor->params & 1, + (s16)actor->world.pos.x, (s16)actor->world.pos.z); + } + + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, actor->params & 1) && rockActor->actor.draw != nullptr) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = EnIshi_RandomizerDraw; + } +} + +void ObjBombiwa_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + ObjBombiwa* rockActor = static_cast(actorRef); + auto rockIdentity = IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_INFO("ROCK bombiwa\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK bombiwa%d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true) && rockActor->actor.draw != nullptr) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = ObjBombiwa_RandomizerDraw; + } +} + +void ObjHamishi_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + ObjHamishi* rockActor = static_cast(actorRef); + auto rockIdentity = IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_WARN("ROCK hamishi\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK hamishi%d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true) && rockActor->actor.draw != nullptr) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = ObjHamishi_RandomizerDraw; + } +} + +void RegisterShuffleRock() { + bool shouldRegister = IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_ROCKS) || RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS)); + bool shouldRegisterBoulder = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_ISHI, shouldRegister, EnIshi_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerInit); + + COND_VB_SHOULD(VB_ROCK_DROP_ITEM, shouldRegister, { + Actor* rockActor = va_arg(args, Actor*); + const auto rockIdentity = ObjectExtension::GetInstance().Get(rockActor); + if (rockIdentity != nullptr && + Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, + rockActor->id == ACTOR_OBJ_BOMBIWA || rockActor->id == ACTOR_OBJ_HAMISHI || + rockActor->params & 1)) { + Rock_RandomizerSpawnCollectible(rockActor, *rockIdentity, gPlayState); + rockIdentity->randomizerCheck = RC_MAX; + rockIdentity->randomizerInf = RAND_INF_MAX; + *should = false; + } + }); + + COND_VB_SHOULD(VB_BOULDER_BREAK_FLAG, shouldRegisterBoulder, { + if (*should) { + Actor* rockActor = va_arg(args, Actor*); + // hook called before OnActorInit sets up object extension + auto rockIdentity = + IdentifyRock(gPlayState->sceneNum, (s16)rockActor->world.pos.x, (s16)rockActor->world.pos.z); + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { + Rock_RandomizerSpawnCollectible(rockActor, rockIdentity, gPlayState); + } + } + }); +} + +void Rando::StaticData::RegisterRockLocations() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + locationTable[RC_KF_CIRCLE_ROCK_1] = Location::Rock(RC_KF_CIRCLE_ROCK_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-292, -350), "KF Circle Rock 1", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CIRCLE_ROCK_1)); + locationTable[RC_KF_CIRCLE_ROCK_2] = Location::Rock(RC_KF_CIRCLE_ROCK_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-235, -373), "KF Circle Rock 2", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CIRCLE_ROCK_2)); + locationTable[RC_KF_CIRCLE_ROCK_3] = Location::Rock(RC_KF_CIRCLE_ROCK_3, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-212, -430), "KF Circle Rock 3", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CIRCLE_ROCK_3)); + locationTable[RC_KF_CIRCLE_ROCK_4] = Location::Rock(RC_KF_CIRCLE_ROCK_4, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-235, -486), "KF Circle Rock 4", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CIRCLE_ROCK_4)); + locationTable[RC_KF_CIRCLE_ROCK_5] = Location::Rock(RC_KF_CIRCLE_ROCK_5, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-292, -510), "KF Circle Rock 5", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CIRCLE_ROCK_5)); + locationTable[RC_KF_CIRCLE_ROCK_6] = Location::Rock(RC_KF_CIRCLE_ROCK_6, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-348, -486), "KF Circle Rock 6", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CIRCLE_ROCK_6)); + locationTable[RC_KF_CIRCLE_ROCK_7] = Location::Rock(RC_KF_CIRCLE_ROCK_7, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-372, -430), "KF Circle Rock 7", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CIRCLE_ROCK_7)); + locationTable[RC_KF_CIRCLE_ROCK_8] = Location::Rock(RC_KF_CIRCLE_ROCK_8, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-348, -373), "KF Circle Rock 8", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CIRCLE_ROCK_8)); + locationTable[RC_KF_ROCK_BY_SARIAS_HOUSE] = Location::Rock(RC_KF_ROCK_BY_SARIAS_HOUSE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(248, 601), "Sarias House Rock KF", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_ROCK_BY_SARIAS_HOUSE)); + locationTable[RC_KF_ROCK_BEHIND_SARIAS_HOUSE] = Location::Rock(RC_KF_ROCK_BEHIND_SARIAS_HOUSE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(726, 961), "Behind Sarias House Rock KF", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE)); + locationTable[RC_KF_ROCK_BY_MIDOS_HOUSE] = Location::Rock(RC_KF_ROCK_BY_MIDOS_HOUSE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-672, -623), "Midos House Rock KF", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_ROCK_BY_MIDOS_HOUSE)); + locationTable[RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE] = Location::Rock(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-1361, 145), "Know It Alls House Rock KF", RHT_KF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE)); + + locationTable[RC_LW_BOULDER_BY_GORON_CITY] = Location::Boulder(RC_LW_BOULDER_BY_GORON_CITY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(915, -925), "Goron City Boulder LW", RHT_LW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BOULDER_BY_GORON_CITY)); + locationTable[RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW] = Location::Boulder(RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(670, -2520), "Sacred Forest Meadow Boulder LW", RHT_LW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW)); + locationTable[RC_LW_RUPEE_BOULDER] = Location::Boulder(RC_LW_RUPEE_BOULDER, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(1720, -2510), "Rupee Boulder LW", RHT_LW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_RUPEE_BOULDER)); + + locationTable[RC_HC_ROCK_1] = Location::Rock(RC_HC_ROCK_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-216, 2977), "HC Rock 1", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_1)); + locationTable[RC_HC_ROCK_2] = Location::Rock(RC_HC_ROCK_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-110, 3006), "HC Rock 2", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_2)); + locationTable[RC_HC_ROCK_3] = Location::Rock(RC_HC_ROCK_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-129, 2897), "HC Rock 3", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_3)); + locationTable[RC_HC_BOULDER] = Location::Boulder(RC_HC_BOULDER, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(2730, 2540), "HC Boulder", RHT_HC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_BOULDER)); + locationTable[RC_OGC_BRONZE_BOULDER_1] = Location::Boulder(RC_OGC_BRONZE_BOULDER_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2324, 533), "OGC Bronze Boulder 1", RHT_OGC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_BRONZE_BOULDER_1)); + locationTable[RC_OGC_BRONZE_BOULDER_2] = Location::Boulder(RC_OGC_BRONZE_BOULDER_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1590, 787), "OGC Bronze Boulder 2", RHT_OGC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_BRONZE_BOULDER_2)); + locationTable[RC_OGC_BRONZE_BOULDER_3] = Location::Boulder(RC_OGC_BRONZE_BOULDER_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1661, 748), "OGC Bronze Boulder 3", RHT_OGC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_BRONZE_BOULDER_3)); + locationTable[RC_OGC_SILVER_BOULDER_1] = Location::Boulder(RC_OGC_SILVER_BOULDER_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1606, 685), "OGC Silver Boulder 1", RHT_OGC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_SILVER_BOULDER_1)); + locationTable[RC_OGC_SILVER_BOULDER_2] = Location::Boulder(RC_OGC_SILVER_BOULDER_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1766, 726), "OGC Silver Boulder 2", RHT_OGC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_SILVER_BOULDER_2)); + locationTable[RC_OGC_SILVER_BOULDER_3] = Location::Boulder(RC_OGC_SILVER_BOULDER_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1701, 661), "OGC Silver Boulder 3", RHT_OGC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_SILVER_BOULDER_3)); + locationTable[RC_OGC_SILVER_BOULDER_4] = Location::Boulder(RC_OGC_SILVER_BOULDER_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2260, 560), "OGC Silver Boulder 4", RHT_OGC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_SILVER_BOULDER_4)); + + locationTable[RC_DMC_ROCK_BY_FIRE_TEMPLE_1] = Location::Rock(RC_DMC_ROCK_BY_FIRE_TEMPLE_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-50, -714), "DMC Fire Temple Rock 1", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1)); + locationTable[RC_DMC_ROCK_BY_FIRE_TEMPLE_2] = Location::Rock(RC_DMC_ROCK_BY_FIRE_TEMPLE_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-26, -807), "DMC Fire Temple Rock 2", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2)); + locationTable[RC_DMC_ROCK_BY_FIRE_TEMPLE_3] = Location::Rock(RC_DMC_ROCK_BY_FIRE_TEMPLE_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(61, -763), "DMC Fire Temple Rock 3", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3)); + locationTable[RC_DMC_ROCK_BY_FIRE_TEMPLE_4] = Location::Rock(RC_DMC_ROCK_BY_FIRE_TEMPLE_4, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(71, -610), "DMC Fire Temple Rock 4", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4)); + locationTable[RC_DMC_ROCK_BY_FIRE_TEMPLE_5] = Location::Rock(RC_DMC_ROCK_BY_FIRE_TEMPLE_5, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(79, -700), "DMC Fire Temple Rock 5", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5)); + locationTable[RC_DMC_CIRCLE_ROCK_1] = Location::Rock(RC_DMC_CIRCLE_ROCK_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(40, 1850), "DMC Circle Rock 1", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_CIRCLE_ROCK_1)); + locationTable[RC_DMC_CIRCLE_ROCK_2] = Location::Rock(RC_DMC_CIRCLE_ROCK_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(96, 1826), "DMC Circle Rock 2", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_CIRCLE_ROCK_2)); + locationTable[RC_DMC_CIRCLE_ROCK_3] = Location::Rock(RC_DMC_CIRCLE_ROCK_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(120, 1770), "DMC Circle Rock 3", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_CIRCLE_ROCK_3)); + locationTable[RC_DMC_CIRCLE_ROCK_4] = Location::Rock(RC_DMC_CIRCLE_ROCK_4, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(96, 1713), "DMC Circle Rock 4", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_CIRCLE_ROCK_4)); + locationTable[RC_DMC_CIRCLE_ROCK_5] = Location::Rock(RC_DMC_CIRCLE_ROCK_5, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(40, 1690), "DMC Circle Rock 5", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_CIRCLE_ROCK_5)); + locationTable[RC_DMC_CIRCLE_ROCK_6] = Location::Rock(RC_DMC_CIRCLE_ROCK_6, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-16, 1713), "DMC Circle Rock 6", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_CIRCLE_ROCK_6)); + locationTable[RC_DMC_CIRCLE_ROCK_7] = Location::Rock(RC_DMC_CIRCLE_ROCK_7, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-40, 1770), "DMC Circle Rock 7", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_CIRCLE_ROCK_7)); + locationTable[RC_DMC_CIRCLE_ROCK_8] = Location::Rock(RC_DMC_CIRCLE_ROCK_8, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-16, 1826), "DMC Circle Rock 8", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_CIRCLE_ROCK_8)); + locationTable[RC_DMC_GOSSIP_ROCK_1] = Location::Rock(RC_DMC_GOSSIP_ROCK_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1261, 1533), "DMC Gossip Rock 1", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_ROCK_1)); + locationTable[RC_DMC_GOSSIP_ROCK_2] = Location::Rock(RC_DMC_GOSSIP_ROCK_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1356, 1541), "DMC Gossip Rock 2", RHT_DMC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_ROCK_2)); + locationTable[RC_DMC_BOULDER_1] = Location::Boulder(RC_DMC_BOULDER_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-504, 1070), "DMC Boulder 1", RHT_DMC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BOULDER_1)); + locationTable[RC_DMC_BOULDER_2] = Location::Boulder(RC_DMC_BOULDER_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(236, 1199), "DMC Boulder 2", RHT_DMC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BOULDER_2)); + locationTable[RC_DMC_BOULDER_3] = Location::Boulder(RC_DMC_BOULDER_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(40, 1770), "DMC Boulder 3", RHT_DMC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BOULDER_3)); + locationTable[RC_DMC_BRONZE_BOULDER_1] = Location::Boulder(RC_DMC_BRONZE_BOULDER_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1699, -472), "DMC Bronze Boulder 1", RHT_DMC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BRONZE_BOULDER_1)); + locationTable[RC_DMC_BRONZE_BOULDER_2] = Location::Boulder(RC_DMC_BRONZE_BOULDER_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1332, 921), "DMC Bronze Boulder 2", RHT_DMC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BRONZE_BOULDER_2)); + locationTable[RC_DMC_BRONZE_BOULDER_3] = Location::Boulder(RC_DMC_BRONZE_BOULDER_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1303, 975), "DMC Bronze Boulder 3", RHT_DMC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BRONZE_BOULDER_3)); + locationTable[RC_DMC_BRONZE_BOULDER_SHORTCUT] = Location::Boulder(RC_DMC_BRONZE_BOULDER_SHORTCUT, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1060, 944), "DMC Bronze Shortcut Boulder", RHT_DMC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BRONZE_BOULDER_SHORTCUT)); + + locationTable[RC_GV_SILVER_BOULDER] = Location::Boulder(RC_GV_SILVER_BOULDER, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(280, 1470), "GV Silver Boulder", RHT_GV_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_SILVER_BOULDER)); + locationTable[RC_GV_ROCK_1] = Location::Rock(RC_GV_ROCK_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(2738, 297), "GV Rock 1", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_ROCK_1)); + locationTable[RC_GV_ROCK_2] = Location::Rock(RC_GV_ROCK_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(2715, 316), "GV Rock 2", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_ROCK_2)); + locationTable[RC_GV_ROCK_3] = Location::Rock(RC_GV_ROCK_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(2699, 275), "GV Rock 3", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_ROCK_3)); + locationTable[RC_GV_UNDERWATER_ROCK_1] = Location::Rock(RC_GV_UNDERWATER_ROCK_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(1559, -63), "GV Underwater Rock 1", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_UNDERWATER_ROCK_1)); + locationTable[RC_GV_UNDERWATER_ROCK_2] = Location::Rock(RC_GV_UNDERWATER_ROCK_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(1605, 26), "GV Underwater Rock 2", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_UNDERWATER_ROCK_2)); + locationTable[RC_GV_UNDERWATER_ROCK_3] = Location::Rock(RC_GV_UNDERWATER_ROCK_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(1686, -33), "GV Underwater Rock 3", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_UNDERWATER_ROCK_3)); + locationTable[RC_GV_ROCK_ACROSS_BRIDGE_1] = Location::Rock(RC_GV_ROCK_ACROSS_BRIDGE_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-666, -899), "GV Rock Across Bridge 1", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_ROCK_ACROSS_BRIDGE_1)); + locationTable[RC_GV_ROCK_ACROSS_BRIDGE_2] = Location::Rock(RC_GV_ROCK_ACROSS_BRIDGE_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-526, -890), "GV Rock Across Bridge 2", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_ROCK_ACROSS_BRIDGE_2)); + locationTable[RC_GV_ROCK_ACROSS_BRIDGE_3] = Location::Rock(RC_GV_ROCK_ACROSS_BRIDGE_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-607, -791), "GV Rock Across Bridge 3", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_ROCK_ACROSS_BRIDGE_3)); + locationTable[RC_GV_ROCK_ACROSS_BRIDGE_4] = Location::Rock(RC_GV_ROCK_ACROSS_BRIDGE_4, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-458, -782), "GV Rock Across Bridge 4", RHT_GV_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_ROCK_ACROSS_BRIDGE_4)); + locationTable[RC_GV_BOULDER_1] = Location::Boulder(RC_GV_BOULDER_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(751, 569), "GV Boulder 1", RHT_GV_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BOULDER_1)); + locationTable[RC_GV_BOULDER_2] = Location::Boulder(RC_GV_BOULDER_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(545, -510), "GV Boulder 2", RHT_GV_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BOULDER_2)); + locationTable[RC_GV_BOULDER_ACROSS_BRIDGE] = Location::Boulder(RC_GV_BOULDER_ACROSS_BRIDGE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-954, 577), "GV Boulder Across Bridge", RHT_GV_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BOULDER_ACROSS_BRIDGE)); + locationTable[RC_GV_BRONZE_BOULDER_1] = Location::Boulder(RC_GV_BRONZE_BOULDER_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(861, -778), "GV Bronze Boulder 1", RHT_GV_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRONZE_BOULDER_1)); + locationTable[RC_GV_BRONZE_BOULDER_2] = Location::Boulder(RC_GV_BRONZE_BOULDER_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(735, 375), "GV Bronze Boulder 2", RHT_GV_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRONZE_BOULDER_2)); + locationTable[RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1] = Location::Boulder(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-1352, 767), "GV Bronze Boulder Across Bridge 1", RHT_GV_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1)); + locationTable[RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2] = Location::Boulder(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-1695, -350), "GV Bronze Boulder Across Bridge 2", RHT_GV_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2)); + locationTable[RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3] = Location::Boulder(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-1001, 637), "GV Bronze Boulder Across Bridge 3", RHT_GV_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3)); + locationTable[RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4] = Location::Boulder(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-1291, 787), "GV Bronze Boulder Across Bridge 4", RHT_GV_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4)); + locationTable[RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5] = Location::Boulder(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-1416, 778), "GV Bronze Boulder Across Bridge 5", RHT_GV_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5)); + locationTable[RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6] = Location::Boulder(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-1256, 856), "GV Bronze Boulder Across Bridge 6", RHT_GV_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6)); + + locationTable[RC_HF_SILVER_BOULDER] = Location::Boulder(RC_HF_SILVER_BOULDER, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(674, 8256), "HF Silver Boulder", RHT_HF_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SILVER_BOULDER)); + locationTable[RC_HF_ROCK_1] = Location::Rock(RC_HF_ROCK_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7875, 6995), "HF Circle Rock 1", RHT_HF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCK_1)); + locationTable[RC_HF_ROCK_2] = Location::Rock(RC_HF_ROCK_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7818, 6971), "HF Circle Rock 2", RHT_HF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCK_2)); + locationTable[RC_HF_ROCK_3] = Location::Rock(RC_HF_ROCK_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7795, 6915), "HF Circle Rock 3", RHT_HF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCK_3)); + locationTable[RC_HF_ROCK_4] = Location::Rock(RC_HF_ROCK_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7818, 6858), "HF Circle Rock 4", RHT_HF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCK_4)); + locationTable[RC_HF_ROCK_5] = Location::Rock(RC_HF_ROCK_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7875, 6835), "HF Circle Rock 5", RHT_HF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCK_5)); + locationTable[RC_HF_ROCK_6] = Location::Rock(RC_HF_ROCK_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7931, 6858), "HF Circle Rock 6", RHT_HF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCK_6)); + locationTable[RC_HF_ROCK_7] = Location::Rock(RC_HF_ROCK_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7955, 6915), "HF Circle Rock 7", RHT_HF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCK_7)); + locationTable[RC_HF_ROCK_8] = Location::Rock(RC_HF_ROCK_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7931, 6971), "HF Circle Rock 8", RHT_HF_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCK_8)); + locationTable[RC_HF_BOULDER_NORTH] = Location::Boulder(RC_HF_BOULDER_NORTH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4450, -425), "HF Boulder North", RHT_HF_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BOULDER_NORTH)); + locationTable[RC_HF_BOULDER_BY_MARKET] = Location::Boulder(RC_HF_BOULDER_BY_MARKET, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1425, 810), "Market Boulder HF", RHT_HF_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BOULDER_BY_MARKET)); + locationTable[RC_HF_BOULDER_SOUTH] = Location::Boulder(RC_HF_BOULDER_SOUTH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-270, 12350), "HF Boulder South", RHT_HF_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BOULDER_SOUTH)); + locationTable[RC_HF_BRONZE_BOULDER_1] = Location::Boulder(RC_HF_BRONZE_BOULDER_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7870, 6920), "HF Bronze Boulder 1", RHT_HF_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BRONZE_BOULDER_1)); + locationTable[RC_HF_BRONZE_BOULDER_2] = Location::Boulder(RC_HF_BRONZE_BOULDER_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-7804, 7983), "HF Bronze Boulder 2", RHT_HF_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BRONZE_BOULDER_2)); + locationTable[RC_HF_BRONZE_BOULDER_3] = Location::Boulder(RC_HF_BRONZE_BOULDER_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-8397, 7947), "HF Bronze Boulder 3", RHT_HF_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BRONZE_BOULDER_3)); + locationTable[RC_HF_BRONZE_BOULDER_4] = Location::Boulder(RC_HF_BRONZE_BOULDER_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6461, 8220), "HF Bronze Boulder 4", RHT_HF_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BRONZE_BOULDER_4)); + + locationTable[RC_KAK_SILVER_BOULDER] = Location::Boulder(RC_KAK_SILVER_BOULDER, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(1436, 1361), "Kak Silver Boulder", RHT_KAK_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_SILVER_BOULDER)); + locationTable[RC_KAK_ROCK_1] = Location::Rock(RC_KAK_ROCK_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(220, -1236), "Kak Rock 1", RHT_KAK_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_ROCK_1)); + locationTable[RC_KAK_ROCK_2] = Location::Rock(RC_KAK_ROCK_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-664, 1288), "Kak Rock 2", RHT_KAK_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_ROCK_2)); + locationTable[RC_GY_ROCK] = Location::Rock(RC_GY_ROCK, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(-1193, 693), "GY Rock", RHT_GY_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_ROCK)); + + locationTable[RC_LH_ROCK] = Location::Rock(RC_LH_ROCK, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(1222, 3953), "LH Rock", RHT_LH_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_ROCK)); + + locationTable[RC_ZD_CIRCLE_ROCK_1] = Location::Rock(RC_ZD_CIRCLE_ROCK_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(462, -696), "ZD Circle Rock 1", RHT_ZD_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_CIRCLE_ROCK_1)); + locationTable[RC_ZD_CIRCLE_ROCK_2] = Location::Rock(RC_ZD_CIRCLE_ROCK_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(518, -719), "ZD Circle Rock 2", RHT_ZD_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_CIRCLE_ROCK_2)); + locationTable[RC_ZD_CIRCLE_ROCK_3] = Location::Rock(RC_ZD_CIRCLE_ROCK_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(542, -776), "ZD Circle Rock 3", RHT_ZD_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_CIRCLE_ROCK_3)); + locationTable[RC_ZD_CIRCLE_ROCK_4] = Location::Rock(RC_ZD_CIRCLE_ROCK_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(518, -832), "ZD Circle Rock 4", RHT_ZD_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_CIRCLE_ROCK_4)); + locationTable[RC_ZD_CIRCLE_ROCK_5] = Location::Rock(RC_ZD_CIRCLE_ROCK_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(462, -856), "ZD Circle Rock 5", RHT_ZD_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_CIRCLE_ROCK_5)); + locationTable[RC_ZD_CIRCLE_ROCK_6] = Location::Rock(RC_ZD_CIRCLE_ROCK_6, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(405, -832), "ZD Circle Rock 6", RHT_ZD_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_CIRCLE_ROCK_6)); + locationTable[RC_ZD_CIRCLE_ROCK_7] = Location::Rock(RC_ZD_CIRCLE_ROCK_7, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, -776), "ZD Circle Rock 7", RHT_ZD_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_CIRCLE_ROCK_7)); + locationTable[RC_ZD_CIRCLE_ROCK_8] = Location::Rock(RC_ZD_CIRCLE_ROCK_8, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(405, -719), "ZD Circle Rock 8", RHT_ZD_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_CIRCLE_ROCK_8)); + locationTable[RC_ZF_BOULDER] = Location::Boulder(RC_ZF_BOULDER, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(189, 2586), "ZF Boulder", RHT_ZF_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOULDER)); + locationTable[RC_ZF_SILVER_BOULDER] = Location::Boulder(RC_ZF_SILVER_BOULDER, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(316, 2634), "ZF Silver Boulder", RHT_ZF_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_SILVER_BOULDER)); + locationTable[RC_ZF_UNDERGROUND_BOULDER] = Location::Boulder(RC_ZF_UNDERGROUND_BOULDER, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(317, 2631), "ZF Underground Boulder", RHT_ZF_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_UNDERGROUND_BOULDER)); + locationTable[RC_ZR_BOULDER_1] = Location::Boulder(RC_ZR_BOULDER_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1456, 434), "ZR Boulder 1", RHT_ZR_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BOULDER_1)); + locationTable[RC_ZR_BOULDER_2] = Location::Boulder(RC_ZR_BOULDER_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1518, 435), "ZR Boulder 2", RHT_ZR_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BOULDER_2)); + locationTable[RC_ZR_BOULDER_3] = Location::Boulder(RC_ZR_BOULDER_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1576, 430), "ZR Boulder 3", RHT_ZR_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BOULDER_3)); + locationTable[RC_ZR_BOULDER_4] = Location::Boulder(RC_ZR_BOULDER_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1400, 482), "ZR Boulder 4", RHT_ZR_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BOULDER_4)); + locationTable[RC_ZR_CIRCLE_ROCK_1] = Location::Rock(RC_ZR_CIRCLE_ROCK_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1635, -53), "ZR Circle Rock 1", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_CIRCLE_ROCK_1)); + locationTable[RC_ZR_CIRCLE_ROCK_2] = Location::Rock(RC_ZR_CIRCLE_ROCK_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1578, -76), "ZR Circle Rock 2", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_CIRCLE_ROCK_2)); + locationTable[RC_ZR_CIRCLE_ROCK_3] = Location::Rock(RC_ZR_CIRCLE_ROCK_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1555, -133), "ZR Circle Rock 3", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_CIRCLE_ROCK_3)); + locationTable[RC_ZR_CIRCLE_ROCK_4] = Location::Rock(RC_ZR_CIRCLE_ROCK_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1578, -189), "ZR Circle Rock 4", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_CIRCLE_ROCK_4)); + locationTable[RC_ZR_CIRCLE_ROCK_5] = Location::Rock(RC_ZR_CIRCLE_ROCK_5, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1635, -213), "ZR Circle Rock 5", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_CIRCLE_ROCK_5)); + locationTable[RC_ZR_CIRCLE_ROCK_6] = Location::Rock(RC_ZR_CIRCLE_ROCK_6, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1691, -189), "ZR Circle Rock 6", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_CIRCLE_ROCK_6)); + locationTable[RC_ZR_CIRCLE_ROCK_7] = Location::Rock(RC_ZR_CIRCLE_ROCK_7, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1715, -133), "ZR Circle Rock 7", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_CIRCLE_ROCK_7)); + locationTable[RC_ZR_CIRCLE_ROCK_8] = Location::Rock(RC_ZR_CIRCLE_ROCK_8, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1691, -76), "ZR Circle Rock 8", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_CIRCLE_ROCK_8)); + locationTable[RC_ZR_UPPER_CIRCLE_BOULDER] = Location::Boulder(RC_ZR_UPPER_CIRCLE_BOULDER, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(672, -366), "ZR Upper Circle Boulder", RHT_ZR_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_BOULDER)); + locationTable[RC_ZR_UPPER_CIRCLE_ROCK_1] = Location::Rock(RC_ZR_UPPER_CIRCLE_ROCK_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(668, -290), "ZR Upper Circle Rock 1", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_ROCK_1)); + locationTable[RC_ZR_UPPER_CIRCLE_ROCK_2] = Location::Rock(RC_ZR_UPPER_CIRCLE_ROCK_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(724, -313), "ZR Upper Circle Rock 2", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_ROCK_2)); + locationTable[RC_ZR_UPPER_CIRCLE_ROCK_3] = Location::Rock(RC_ZR_UPPER_CIRCLE_ROCK_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(748, -370), "ZR Upper Circle Rock 3", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_ROCK_3)); + locationTable[RC_ZR_UPPER_CIRCLE_ROCK_4] = Location::Rock(RC_ZR_UPPER_CIRCLE_ROCK_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(724, -426), "ZR Upper Circle Rock 4", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_ROCK_4)); + locationTable[RC_ZR_UPPER_CIRCLE_ROCK_5] = Location::Rock(RC_ZR_UPPER_CIRCLE_ROCK_5, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(668, -450), "ZR Upper Circle Rock 5", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_ROCK_5)); + locationTable[RC_ZR_UPPER_CIRCLE_ROCK_6] = Location::Rock(RC_ZR_UPPER_CIRCLE_ROCK_6, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(611, -426), "ZR Upper Circle Rock 6", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_ROCK_6)); + locationTable[RC_ZR_UPPER_CIRCLE_ROCK_7] = Location::Rock(RC_ZR_UPPER_CIRCLE_ROCK_7, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(588, -370), "ZR Upper Circle Rock 7", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_ROCK_7)); + locationTable[RC_ZR_UPPER_CIRCLE_ROCK_8] = Location::Rock(RC_ZR_UPPER_CIRCLE_ROCK_8, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(611, -313), "ZR Upper Circle Rock 8", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UPPER_CIRCLE_ROCK_8)); + locationTable[RC_ZR_ROCK] = Location::Rock(RC_ZR_ROCK, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(2044, -786), "ZR Rock", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_ROCK)); + locationTable[RC_ZR_UNDERWATER_ROCK_1] = Location::Rock(RC_ZR_UNDERWATER_ROCK_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(2425, -446), "ZR Underwater Rock 1", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UNDERWATER_ROCK_1)); + locationTable[RC_ZR_UNDERWATER_ROCK_2] = Location::Rock(RC_ZR_UNDERWATER_ROCK_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(2425, -524), "ZR Underwater Rock 2", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UNDERWATER_ROCK_2)); + locationTable[RC_ZR_UNDERWATER_ROCK_3] = Location::Rock(RC_ZR_UNDERWATER_ROCK_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(2503, -571), "ZR Underwater Rock 3", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UNDERWATER_ROCK_3)); + locationTable[RC_ZR_UNDERWATER_ROCK_4] = Location::Rock(RC_ZR_UNDERWATER_ROCK_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(2550, -415), "ZR Underwater Rock 4", RHT_ZR_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_UNDERWATER_ROCK_4)); + + // 5 rocks by dc + locationTable[RC_DMT_ROCK_1] = Location::Rock(RC_DMT_ROCK_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1816, -513), "DMT Rock 1", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_ROCK_1)); + locationTable[RC_DMT_ROCK_2] = Location::Rock(RC_DMT_ROCK_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1831, -614), "DMT Rock 2", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_ROCK_2)); + locationTable[RC_DMT_ROCK_3] = Location::Rock(RC_DMT_ROCK_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1857, -536), "DMT Rock 3", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_ROCK_3)); + locationTable[RC_DMT_ROCK_4] = Location::Rock(RC_DMT_ROCK_4, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1878, -465), "DMT Rock 4", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_ROCK_4)); + locationTable[RC_DMT_ROCK_5] = Location::Rock(RC_DMT_ROCK_5, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1787, -550), "DMT Rock 5", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_ROCK_5)); + locationTable[RC_DMT_SUMMIT_ROCK] = Location::Rock(RC_DMT_SUMMIT_ROCK, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-327, -4286), "DMT Summit Rock", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_SUMMIT_ROCK)); + locationTable[RC_DMT_CIRCLE_ROCK_1] = Location::Rock(RC_DMT_CIRCLE_ROCK_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-383, -1126), "DMT Circle Rock 1", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CIRCLE_ROCK_1)); + locationTable[RC_DMT_CIRCLE_ROCK_2] = Location::Rock(RC_DMT_CIRCLE_ROCK_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-326, -1149), "DMT Circle Rock 2", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CIRCLE_ROCK_2)); + locationTable[RC_DMT_CIRCLE_ROCK_3] = Location::Rock(RC_DMT_CIRCLE_ROCK_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-303, -1206), "DMT Circle Rock 3", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CIRCLE_ROCK_3)); + locationTable[RC_DMT_CIRCLE_ROCK_4] = Location::Rock(RC_DMT_CIRCLE_ROCK_4, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-326, -1262), "DMT Circle Rock 4", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CIRCLE_ROCK_4)); + locationTable[RC_DMT_CIRCLE_ROCK_5] = Location::Rock(RC_DMT_CIRCLE_ROCK_5, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-383, -1286), "DMT Circle Rock 5", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CIRCLE_ROCK_5)); + locationTable[RC_DMT_CIRCLE_ROCK_6] = Location::Rock(RC_DMT_CIRCLE_ROCK_6, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-439, -1262), "DMT Circle Rock 6", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CIRCLE_ROCK_6)); + locationTable[RC_DMT_CIRCLE_ROCK_7] = Location::Rock(RC_DMT_CIRCLE_ROCK_7, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-463, -1206), "DMT Circle Rock 7", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CIRCLE_ROCK_7)); + locationTable[RC_DMT_CIRCLE_ROCK_8] = Location::Rock(RC_DMT_CIRCLE_ROCK_8, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-439, -1149), "DMT Circle Rock 8", RHT_DMT_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CIRCLE_ROCK_8)); + locationTable[RC_DMT_CHILD_BOULDER] = Location::Boulder(RC_DMT_CHILD_BOULDER, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1060, -51), "DMT Child Boulder", RHT_DMT_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CHILD_BOULDER)); + locationTable[RC_DMT_BOULDER_1] = Location::Boulder(RC_DMT_BOULDER_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-625, -55), "DMT Boulder 1", RHT_DMT_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BOULDER_1)); + locationTable[RC_DMT_BOULDER_2] = Location::Boulder(RC_DMT_BOULDER_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-808, -59), "DMT Boulder 2", RHT_DMT_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BOULDER_2)); + locationTable[RC_DMT_COW_BOULDER] = Location::Boulder(RC_DMT_COW_BOULDER, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-688, -285), "Cow Boulder", RHT_DMT_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_BOULDER)); + locationTable[RC_DMT_BRONZE_BOULDER_1] = Location::Boulder(RC_DMT_BRONZE_BOULDER_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1175, -803), "DMT Bronze Boulder 1", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_1)); + locationTable[RC_DMT_BRONZE_BOULDER_2] = Location::Boulder(RC_DMT_BRONZE_BOULDER_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1948, 1706), "DMT Bronze Boulder 2", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_2)); + locationTable[RC_DMT_BRONZE_BOULDER_3] = Location::Boulder(RC_DMT_BRONZE_BOULDER_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-2019, 1101), "DMT Bronze Boulder 3", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_3)); + locationTable[RC_DMT_BRONZE_BOULDER_4] = Location::Boulder(RC_DMT_BRONZE_BOULDER_4, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1658, -88), "DMT Bronze Boulder 4", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_4)); + locationTable[RC_DMT_BRONZE_BOULDER_5] = Location::Boulder(RC_DMT_BRONZE_BOULDER_5, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1753, 445), "DMT Bronze Boulder 5", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_5)); + locationTable[RC_DMT_BRONZE_BOULDER_6] = Location::Boulder(RC_DMT_BRONZE_BOULDER_6, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1018, 1283), "DMT Bronze Boulder 6", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_6)); + locationTable[RC_DMT_BRONZE_BOULDER_7] = Location::Boulder(RC_DMT_BRONZE_BOULDER_7, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1986, 727), "DMT Bronze Boulder 7", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_7)); + locationTable[RC_DMT_BRONZE_BOULDER_8] = Location::Boulder(RC_DMT_BRONZE_BOULDER_8, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-23, -3196), "DMT Bronze Boulder 8", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_8)); + locationTable[RC_DMT_BRONZE_BOULDER_9] = Location::Boulder(RC_DMT_BRONZE_BOULDER_9, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-343, -2794), "DMT Bronze Boulder 9", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_9)); + locationTable[RC_DMT_BRONZE_BOULDER_10] = Location::Boulder(RC_DMT_BRONZE_BOULDER_10, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-154, -2484), "DMT Bronze Boulder 10", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_10)); + locationTable[RC_DMT_BRONZE_BOULDER_11] = Location::Boulder(RC_DMT_BRONZE_BOULDER_11, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1590, -402), "DMT Bronze Boulder 11", RHT_DMT_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BRONZE_BOULDER_11)); + + locationTable[RC_GC_LW_BOULDER_1] = Location::Boulder(RC_GC_LW_BOULDER_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(416, 1049), "GC Goron City Boulder 1", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_LW_BOULDER_1)); + locationTable[RC_GC_LW_BOULDER_2] = Location::Boulder(RC_GC_LW_BOULDER_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(470, 1031), "GC Goron City Boulder 2", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_LW_BOULDER_2)); + locationTable[RC_GC_LW_BOULDER_3] = Location::Boulder(RC_GC_LW_BOULDER_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(367, 1078), "GC Goron City Boulder 3", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_LW_BOULDER_3)); + locationTable[RC_GC_ENTRANCE_BOULDER_1] = Location::Boulder(RC_GC_ENTRANCE_BOULDER_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-670, 470), "GC Entrance Boulder 1", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_ENTRANCE_BOULDER_1)); + locationTable[RC_GC_ENTRANCE_BOULDER_2] = Location::Boulder(RC_GC_ENTRANCE_BOULDER_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-607, 419), "GC Entrance Boulder 2", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_ENTRANCE_BOULDER_2)); + locationTable[RC_GC_ENTRANCE_BOULDER_3] = Location::Boulder(RC_GC_ENTRANCE_BOULDER_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-756, 474), "GC Entrance Boulder 3", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_ENTRANCE_BOULDER_3)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_1] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1479, -794), "GC Maze Silver Boulder 1", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_1)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_2] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1478, -855), "GC Maze Silver Boulder 2", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_2)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_3] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1474, -624), "GC Maze Silver Boulder 3", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_3)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_4] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_4, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1471, -993), "GC Maze Silver Boulder 4", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_4)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_5] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_5, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1467, -1064), "GC Maze Silver Boulder 5", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_5)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_6] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_6, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1460, -1121), "GC Maze Silver Boulder 6", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_6)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_7] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_7, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1451, -567), "GC Maze Silver Boulder 7", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_7)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_8] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_8, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1448, -672), "GC Maze Silver Boulder 8", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_8)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_9] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_9, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1440, -1174), "GC Maze Silver Boulder 9", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_9)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_10] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_10, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1437, -1342), "GC Maze Silver Boulder 10", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_10)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_11] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_11, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1424, -1245), "GC Maze Silver Boulder 11", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_11)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_12] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_12, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1424, -609), "GC Maze Silver Boulder 12", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_12)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_13] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_13, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1399, -1300), "GC Maze Silver Boulder 13", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_13)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_14] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_14, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1394, -654), "GC Maze Silver Boulder 14", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_14)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_15] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_15, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1343, -698), "GC Maze Silver Boulder 15", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_15)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_16] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_16, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1319, -1086), "GC Maze Silver Boulder 16", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_16)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_17] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_17, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1312, -1039), "GC Maze Silver Boulder 17", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_17)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_18] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_18, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1306, -837), "GC Maze Silver Boulder 18", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_18)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_19] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_19, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1279, -656), "GC Maze Silver Boulder 19", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_19)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_20] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_20, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1255, -840), "GC Maze Silver Boulder 20", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_20)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_21] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_21, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1246, -1075), "GC Maze Silver Boulder 21", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_21)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_22] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_22, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1244, -589), "GC Maze Silver Boulder 22", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_22)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_23] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_23, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1210, -852), "GC Maze Silver Boulder 23", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_23)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_24] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_24, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1206, -627), "GC Maze Silver Boulder 24", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_24)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_25] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_25, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1187, -896), "GC Maze Silver Boulder 25", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_25)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_26] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_26, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1157, -954), "GC Maze Silver Boulder 26", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_26)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_27] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_27, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1130, -1137), "GC Maze Silver Boulder 27", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_27)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_28] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_28, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1120, -1001), "GC Maze Silver Boulder 28", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_28)); + locationTable[RC_GC_MAZE_SILVER_BOULDER_29] = Location::Boulder(RC_GC_MAZE_SILVER_BOULDER_29, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1179, -1098), "GC Maze Silver Boulder 29", RHT_GC_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_SILVER_BOULDER_29)); + locationTable[RC_GC_MAZE_BOULDER_1] = Location::Boulder(RC_GC_MAZE_BOULDER_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1342, -628), "GC Maze Boulder 1", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_1)); + locationTable[RC_GC_MAZE_BOULDER_2] = Location::Boulder(RC_GC_MAZE_BOULDER_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1456, -501), "GC Maze Boulder 2", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_2)); + locationTable[RC_GC_MAZE_BOULDER_3] = Location::Boulder(RC_GC_MAZE_BOULDER_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1233, -511), "GC Maze Boulder 3", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_3)); + locationTable[RC_GC_MAZE_BOULDER_4] = Location::Boulder(RC_GC_MAZE_BOULDER_4, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1137, -657), "GC Maze Boulder 4", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_4)); + locationTable[RC_GC_MAZE_BOULDER_5] = Location::Boulder(RC_GC_MAZE_BOULDER_5, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1124, -913), "GC Maze Boulder 5", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_5)); + locationTable[RC_GC_MAZE_BOULDER_6] = Location::Boulder(RC_GC_MAZE_BOULDER_6, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1326, -771), "GC Maze Boulder 6", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_6)); + locationTable[RC_GC_MAZE_BOULDER_7] = Location::Boulder(RC_GC_MAZE_BOULDER_7, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1469, -737), "GC Maze Boulder 7", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_7)); + locationTable[RC_GC_MAZE_BOULDER_8] = Location::Boulder(RC_GC_MAZE_BOULDER_8, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1476, -921), "GC Maze Boulder 8", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_8)); + locationTable[RC_GC_MAZE_BOULDER_9] = Location::Boulder(RC_GC_MAZE_BOULDER_9, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1391, -1087), "GC Maze Boulder 9", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_9)); + locationTable[RC_GC_MAZE_BOULDER_10] = Location::Boulder(RC_GC_MAZE_BOULDER_10, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1222, -997), "GC Maze Boulder 10", RHT_GC_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BOULDER_10)); + locationTable[RC_GC_MAZE_BRONZE_BOULDER_1] = Location::Boulder(RC_GC_MAZE_BRONZE_BOULDER_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1541, -631), "GC Maze Bronze Boulder 1", RHT_GC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BRONZE_BOULDER_1)); + locationTable[RC_GC_MAZE_BRONZE_BOULDER_2] = Location::Boulder(RC_GC_MAZE_BRONZE_BOULDER_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1536, -861), "GC Maze Bronze Boulder 2", RHT_GC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BRONZE_BOULDER_2)); + locationTable[RC_GC_MAZE_BRONZE_BOULDER_3] = Location::Boulder(RC_GC_MAZE_BRONZE_BOULDER_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1536, -1102), "GC Maze Bronze Boulder 3", RHT_GC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BRONZE_BOULDER_3)); + locationTable[RC_GC_MAZE_BRONZE_BOULDER_4] = Location::Boulder(RC_GC_MAZE_BRONZE_BOULDER_4, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1534, -752), "GC Maze Bronze Boulder 4", RHT_GC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BRONZE_BOULDER_4)); + locationTable[RC_GC_MAZE_BRONZE_BOULDER_5] = Location::Boulder(RC_GC_MAZE_BRONZE_BOULDER_5, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1536, -991), "GC Maze Bronze Boulder 5", RHT_GC_BRONZE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_BRONZE_BOULDER_5)); + locationTable[RC_GC_MAZE_ROCK] = Location::Rock(RC_GC_MAZE_ROCK, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1197, -1329), "GC Maze Rock", RHT_GC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_ROCK)); + + locationTable[RC_COLOSSUS_SILVER_BOULDER] = Location::Boulder(RC_COLOSSUS_SILVER_BOULDER, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(61, -1301), "Colossus Silver Boulder", RHT_COLOSSUS_SILVER_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_SILVER_BOULDER)); + locationTable[RC_COLOSSUS_ROCK] = Location::Rock(RC_COLOSSUS_ROCK, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(1537, 667), "Colossus Rock", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_ROCK)); + locationTable[RC_COLOSSUS_CIRCLE_1_ROCK_1] = Location::Rock(RC_COLOSSUS_CIRCLE_1_ROCK_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-250, -1272), "Colossus Circle 1 Rock 1", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1)); + locationTable[RC_COLOSSUS_CIRCLE_1_ROCK_2] = Location::Rock(RC_COLOSSUS_CIRCLE_1_ROCK_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-193, -1295), "Colossus Circle 1 Rock 2", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2)); + locationTable[RC_COLOSSUS_CIRCLE_1_ROCK_3] = Location::Rock(RC_COLOSSUS_CIRCLE_1_ROCK_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-170, -1352), "Colossus Circle 1 Rock 3", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3)); + locationTable[RC_COLOSSUS_CIRCLE_1_ROCK_4] = Location::Rock(RC_COLOSSUS_CIRCLE_1_ROCK_4, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-193, -1408), "Colossus Circle 1 Rock 4", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4)); + locationTable[RC_COLOSSUS_CIRCLE_1_ROCK_5] = Location::Rock(RC_COLOSSUS_CIRCLE_1_ROCK_5, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-250, -1432), "Colossus Circle 1 Rock 5", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5)); + locationTable[RC_COLOSSUS_CIRCLE_1_ROCK_6] = Location::Rock(RC_COLOSSUS_CIRCLE_1_ROCK_6, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-306, -1408), "Colossus Circle 1 Rock 6", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6)); + locationTable[RC_COLOSSUS_CIRCLE_1_ROCK_7] = Location::Rock(RC_COLOSSUS_CIRCLE_1_ROCK_7, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-330, -1352), "Colossus Circle 1 Rock 7", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7)); + locationTable[RC_COLOSSUS_CIRCLE_1_ROCK_8] = Location::Rock(RC_COLOSSUS_CIRCLE_1_ROCK_8, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-306, -1295), "Colossus Circle 1 Rock 8", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8)); + locationTable[RC_COLOSSUS_CIRCLE_2_ROCK_1] = Location::Rock(RC_COLOSSUS_CIRCLE_2_ROCK_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-834, -766), "Colossus Circle 2 Rock 1", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1)); + locationTable[RC_COLOSSUS_CIRCLE_2_ROCK_2] = Location::Rock(RC_COLOSSUS_CIRCLE_2_ROCK_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-777, -789), "Colossus Circle 2 Rock 2", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2)); + locationTable[RC_COLOSSUS_CIRCLE_2_ROCK_3] = Location::Rock(RC_COLOSSUS_CIRCLE_2_ROCK_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-754, -846), "Colossus Circle 2 Rock 3", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3)); + locationTable[RC_COLOSSUS_CIRCLE_2_ROCK_4] = Location::Rock(RC_COLOSSUS_CIRCLE_2_ROCK_4, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-777, -902), "Colossus Circle 2 Rock 4", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4)); + locationTable[RC_COLOSSUS_CIRCLE_2_ROCK_5] = Location::Rock(RC_COLOSSUS_CIRCLE_2_ROCK_5, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-834, -926), "Colossus Circle 2 Rock 5", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5)); + locationTable[RC_COLOSSUS_CIRCLE_2_ROCK_6] = Location::Rock(RC_COLOSSUS_CIRCLE_2_ROCK_6, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-890, -902), "Colossus Circle 2 Rock 6", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6)); + locationTable[RC_COLOSSUS_CIRCLE_2_ROCK_7] = Location::Rock(RC_COLOSSUS_CIRCLE_2_ROCK_7, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-914, -846), "Colossus Circle 2 Rock 7", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7)); + locationTable[RC_COLOSSUS_CIRCLE_2_ROCK_8] = Location::Rock(RC_COLOSSUS_CIRCLE_2_ROCK_8, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(-890, -789), "Colossus Circle 2 Rock 8", RHT_COLOSSUS_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8)); + + locationTable[RC_HC_STORMS_GROTTO_ROCK_1] = Location::Rock(RC_HC_STORMS_GROTTO_ROCK_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1811, 813), "HC Storms Grotto Rock 1", RHT_HC_STORMS_GROTTO_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_ROCK_1)); + locationTable[RC_HC_STORMS_GROTTO_ROCK_2] = Location::Rock(RC_HC_STORMS_GROTTO_ROCK_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1867, 789), "HC Storms Grotto Rock 2", RHT_HC_STORMS_GROTTO_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_ROCK_2)); + locationTable[RC_HC_STORMS_GROTTO_ROCK_3] = Location::Rock(RC_HC_STORMS_GROTTO_ROCK_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1891, 733), "HC Storms Grotto Rock 3", RHT_HC_STORMS_GROTTO_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_ROCK_3)); + locationTable[RC_HC_STORMS_GROTTO_ROCK_4] = Location::Rock(RC_HC_STORMS_GROTTO_ROCK_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1867, 676), "HC Storms Grotto Rock 4", RHT_HC_STORMS_GROTTO_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_ROCK_4)); + locationTable[RC_HC_STORMS_GROTTO_ROCK_5] = Location::Rock(RC_HC_STORMS_GROTTO_ROCK_5, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1811, 653), "HC Storms Grotto Rock 5", RHT_HC_STORMS_GROTTO_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_ROCK_5)); + locationTable[RC_HC_STORMS_GROTTO_ROCK_6] = Location::Rock(RC_HC_STORMS_GROTTO_ROCK_6, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1754, 676), "HC Storms Grotto Rock 6", RHT_HC_STORMS_GROTTO_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_ROCK_6)); + locationTable[RC_HC_STORMS_GROTTO_ROCK_7] = Location::Rock(RC_HC_STORMS_GROTTO_ROCK_7, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1731, 733), "HC Storms Grotto Rock 7", RHT_HC_STORMS_GROTTO_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_ROCK_7)); + locationTable[RC_HC_STORMS_GROTTO_ROCK_8] = Location::Rock(RC_HC_STORMS_GROTTO_ROCK_8, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1754, 789), "HC Storms Grotto Rock 8", RHT_HC_STORMS_GROTTO_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_ROCK_8)); + + locationTable[RC_BOTW_BOULDER_1] = Location::Boulder(RC_BOTW_BOULDER_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-684, -734), "BOTW Boulder 1", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_1)); + locationTable[RC_BOTW_BOULDER_2] = Location::Boulder(RC_BOTW_BOULDER_2, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-632, -805), "BOTW Boulder 2", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_2)); + locationTable[RC_BOTW_BOULDER_3] = Location::Boulder(RC_BOTW_BOULDER_3, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(333, -681), "BOTW Boulder 3", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_3)); + locationTable[RC_BOTW_BOULDER_4] = Location::Boulder(RC_BOTW_BOULDER_4, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(409, -637), "BOTW Boulder 4", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_4)); + locationTable[RC_BOTW_BOULDER_5] = Location::Boulder(RC_BOTW_BOULDER_5, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(334, -8), "BOTW Boulder 5", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_5)); + locationTable[RC_BOTW_BOULDER_6] = Location::Boulder(RC_BOTW_BOULDER_6, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(312, 64), "BOTW Boulder 6", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_6)); + + locationTable[RC_DEKU_TREE_MQ_BOULDER_1] = Location::Boulder(RC_DEKU_TREE_MQ_BOULDER_1, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-1237, 1558), "Deku Tree MQ Boulder 1", RHT_DEKU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BOULDER_1)); + locationTable[RC_DEKU_TREE_MQ_BOULDER_2] = Location::Boulder(RC_DEKU_TREE_MQ_BOULDER_2, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-1183, 1522), "Deku Tree MQ Boulder 2", RHT_DEKU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BOULDER_2)); + locationTable[RC_DEKU_TREE_MQ_BOULDER_3] = Location::Boulder(RC_DEKU_TREE_MQ_BOULDER_3, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-1129, 1469), "Deku Tree MQ Boulder 3", RHT_DEKU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BOULDER_3)); + + locationTable[RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-435, -1720), "Dodongo's MQ Lobby Boulder 1", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(432, -1719), "Dodongo's MQ Lobby Boulder 2", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(807, -874), "Dodongo's MQ Mouth Bridge Boulder 1", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(802, -972), "Dodongo's MQ Mouth Bridge Boulder 2", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(783, -923), "Dodongo's MQ Mouth Bridge Boulder 3", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3)); + locationTable[RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2464, -402), "Dodongo's MQ Right Side Boulder 1", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2942, -495), "Dodongo's MQ Right Side Boulder 2", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4219, -1651), "Dodongo's MQ Lizalfos Room Boulder 1", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4178, -1602), "Dodongo's MQ Lizalfos Room Boulder 2", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4162, -1581), "Dodongo's MQ Lizalfos Room Boulder 3", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4133, -1561), "Dodongo's MQ Lizalfos Room Boulder 4", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4091, -1510), "Dodongo's MQ Lizalfos Room Boulder 5", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4067, -1487), "Dodongo's MQ Lizalfos Room Boulder 6", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4028, -1472), "Dodongo's MQ Lizalfos Room Boulder 7", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3965, -1473), "Dodongo's MQ Lizalfos Room Boulder 8", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3898, -1467), "Dodongo's MQ Lizalfos Room Boulder 9", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3832, -1437), "Dodongo's MQ Lizalfos Room Boulder 10", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3799, -1383), "Dodongo's MQ Lizalfos Room Boulder 11", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11)); + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3760, -1318), "Dodongo's MQ Lizalfos Room Boulder 12", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12)); + locationTable[RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER] = Location::Boulder(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2737, -1058), "Dodongo's MQ Two Flames Boulder", RHT_DODONGOS_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER)); + + locationTable[RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1, -296), "Jabu MQ Entrance Boulder", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(350, -3533), "Jabu MQ Holes Room Boulder 1", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-192, -3211), "Jabu MQ Holes Room Boulder 2", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(245, -2792), "Jabu MQ Holes Wall Boulder 1", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(220, -2790), "Jabu MQ Holes Wall Boulder 2", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(274, -2790), "Jabu MQ Holes Wall Boulder 3", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(31, -5177), "Jabu MQ Forked Corridor Boulder 1", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-37, -5173), "Jabu MQ Forked Corridor Boulder 2", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-885, -5907), "Jabu MQ Tailpasaran Boulder", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER] = Location::Boulder(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-411, -5682), "Jabu MQ Tailpasaran Wall Boulder", RHT_JABU_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER)); + + // skip spirit temple boulder, so adult can clear without collecting check for child to pass + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-160, 270), "Spirit MQ Entrance Boulder 1", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(160, 270), "Spirit MQ Entrance Boulder 2", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(350, 220), "Spirit MQ Entrance Eye Boulder", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER)); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0, -60), "Spirit MQ Entrance Ceiling Boulder", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CRAWLSPACE_BOULDER] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_CRAWLSPACE_BOULDER, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1060, -680), "Spirit MQ Crawlspace Boulder", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CRAWLSPACE_BOULDER)); + locationTable[RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-593, -1340), "Spirit MQ Gibdo Boulder", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER)); + locationTable[RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_LOW] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_LOW, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-421, -1036), "Spirit MQ Gibdo Low Boulder", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_LOW)); + locationTable[RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_HIGH] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_HIGH, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-786, -930), "Spirit MQ Gibdo High Boulder", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_HIGH)); + locationTable[RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER] = Location::Boulder(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1070, -290), "Spirit MQ Early Adult Boulder", RHT_SPIRIT_TEMPLE_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER)); + + locationTable[RC_BOTW_MQ_BOULDER_1] = Location::Boulder(RC_BOTW_MQ_BOULDER_1, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-370, -160), "BotW MQ Boulder 1", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_MQ_BOULDER_1)); + locationTable[RC_BOTW_MQ_BOULDER_2] = Location::Boulder(RC_BOTW_MQ_BOULDER_2, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-521, -353), "BotW MQ Boulder 2", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_MQ_BOULDER_2)); + locationTable[RC_BOTW_MQ_BOULDER_3] = Location::Boulder(RC_BOTW_MQ_BOULDER_3, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-541, -404), "BotW MQ Boulder 3", RHT_BOTW_BOULDER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_MQ_BOULDER_3)); + // clang-format-on +} + +static RegisterShipInitFunc initFunc(RegisterShuffleRock, { "IS_RANDO" }); +static RegisterShipInitFunc initFunc2(Rando::StaticData::RegisterRockLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.h b/soh/soh/Enhancements/randomizer/ShuffleRocks.h new file mode 100644 index 0000000000..9784af34bb --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.h @@ -0,0 +1,15 @@ +#ifndef SHUFFLEROCKS_H +#define SHUFFLEROCKS_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +void EnIshi_RandomizerInit(void* actorRef); +#ifdef __cplusplus +}; +#endif + +#endif // SHUFFLEROCKS_H diff --git a/soh/soh/Enhancements/randomizer/ShuffleSigns.cpp b/soh/soh/Enhancements/randomizer/ShuffleSigns.cpp new file mode 100644 index 0000000000..fadfe5b66f --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleSigns.cpp @@ -0,0 +1,320 @@ +#include +#include "soh/ObjectExtension/ObjectExtension.h" +#include "item_category_adj.h" +#include "particle_cmc.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" + +extern "C" { +extern PlayState* gPlayState; +#include "overlays/actors/ovl_En_Kanban/z_en_kanban.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.h" +#include "overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.h" +} + +uint8_t Sign_RandomizerHoldsItem(Actor* actor, PlayState* play) { + const auto signIdentity = ObjectExtension::GetInstance().Get(actor); + if (signIdentity == nullptr) { + return false; + } + + RandomizerCheck rc = signIdentity->randomizerCheck; + uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); + auto signSetting = RAND_GET_OPTION(RSK_SHUFFLE_SIGNS); + + // Don't pull randomized item if sign isn't randomized or is already checked + if (!IS_RANDO || (signSetting.Is(RO_SHUFFLE_SIGNS_OVERWORLD) && isDungeon) || + (signSetting.Is(RO_SHUFFLE_SIGNS_DUNGEONS) && !isDungeon) || + Flags_GetRandomizerInf(signIdentity->randomizerInf) || signIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { + return false; + } else { + return true; + } +} + +static void Sign_RandomizerDraw(Actor* actor, Color_RGBA8* primColor, Color_RGBA8* secColor, Color_RGBA8* envColor) { + Vec3f pos; + Vec3f velocity = { 0.0f, -0.05f, 0.0f }; + Vec3f accel = { 0.0f, -0.025f, 0.0f }; + float yKanbanOffset = LINK_IS_CHILD && actor->id == ACTOR_EN_KANBAN ? 15.0f : 0.0f; + + pos.x = Rand_CenteredFloat(10.0f) + actor->world.pos.x; + pos.y = (Rand_ZeroOne() * 10.0f) + actor->world.pos.y + yKanbanOffset; + pos.z = Rand_CenteredFloat(10.0f) + actor->world.pos.z; + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, secColor, envColor, 2000, 100); + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, primColor, envColor, 2000, 100); +} + +void Sign_RandomizerDrawSetup(void* actor) { + Actor* signActor = (Actor*)actor; + + // If not a randomized item or too far, don't draw + if (!Sign_RandomizerHoldsItem(signActor, gPlayState) || signActor->xzDistToPlayer > 1000.0f) { + return; + } + + bool cmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + + int isNotCMC = !cmc || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + + const auto signIdentity = ObjectExtension::GetInstance().Get(signActor); + if (signIdentity == nullptr) { + return; + } + + GetItemEntry signItem = + Rando::Context::GetInstance()->GetFinalGIEntry(signIdentity->randomizerCheck, true, GI_NONE); + GetItemCategory getItemCategory = isNotCMC ? ITEM_CATEGORY_MAJOR : Randomizer_AdjustItemCategory(signItem); + + Color_RGBA8 primColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_PRIMARY); + Color_RGBA8 secColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_SECONDARY); + Color_RGBA8 envColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_FLARE); + Sign_RandomizerDraw(signActor, &primColor, &secColor, &envColor); +} + +void Sign_RandomizerSpawnCollectible(Actor* actor) { + const auto signIdentity = ObjectExtension::GetInstance().Get(actor); + + if (signIdentity == nullptr) { + return; + } + Flags_SetRandomizerInf(signIdentity->randomizerInf); +} + +void Sign_RoyalTombSpawnCollectible(int16_t flagType, int16_t flag) { + if (!Flags_GetRandomizerInf(RAND_INF_GY_ROYAL_TOMB_GRAVE) && + Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) { + Flags_SetRandomizerInf(RAND_INF_GY_ROYAL_TOMB_GRAVE); + } +} + +static CheckIdentity IdentifySign(s32 sceneNum, s32 posX, s32 posZ, s32 id) { + CheckIdentity signIdentity; + uint32_t signSceneNum = sceneNum; + Rando::Location* location = nullptr; + + // align child/adult signs + if (sceneNum == SCENE_KAKARIKO_VILLAGE && LINK_IS_ADULT && posX == 1165 && posZ == 1545) { + posZ = 1550; + } else if (sceneNum == SCENE_GRAVEYARD && LINK_IS_ADULT) { + if (id == ACTOR_EN_WONDER_TALK2 && posX == -807 && posZ == 266) { + posX = -805; + } else if (id == ACTOR_EN_WONDER_TALK) { + if (posX == 634 && posZ == 260) { + posX = 654; + posZ = 258; + } else if (posX == 634 && posZ == -100) { + posX = 654; + posZ = -102; + } else if (posX == 753 && posZ == 85) { + posX = 752; + } + } + } else if (sceneNum == SCENE_ZORAS_RIVER && LINK_IS_ADULT && posX == 4097 && posZ == -1399) { + posX = 4096; + posZ = -1401; + } + + signIdentity.randomizerInf = RAND_INF_MAX; + signIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + + switch (id) { + case ACTOR_EN_KANBAN: + location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_KANBAN, signSceneNum, actorParams); + break; + case ACTOR_EN_A_OBJ: + location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_A_OBJ, signSceneNum, actorParams); + break; + case ACTOR_EN_WONDER_TALK2: + location = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_WONDER_TALK2, signSceneNum, + actorParams); + break; + case ACTOR_EN_WONDER_TALK: + location = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_WONDER_TALK, signSceneNum, + actorParams); + break; + default: + return signIdentity; + } + + if (location == nullptr || location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifySign did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + } else { + signIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + signIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return signIdentity; +} + +void RegisterShuffleSigns() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_SIGNS).Get(); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_KANBAN, shouldRegister, [](void* actorRef) { + Actor* actor = static_cast(actorRef); + EnKanban* signActor = static_cast(actorRef); + + auto signIdentity = + IdentifySign(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z, actor->id); + ObjectExtension::GetInstance().Set(actor, std::move(signIdentity)); + }); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_A_OBJ, shouldRegister, [](void* actorRef) { + Actor* actor = static_cast(actorRef); + EnAObj* signActor = static_cast(actorRef); + + auto signIdentity = + IdentifySign(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z, actor->id); + ObjectExtension::GetInstance().Set(actor, std::move(signIdentity)); + }); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_WONDER_TALK, shouldRegister, [](void* actorRef) { + Actor* actor = static_cast(actorRef); + EnWonderTalk* signActor = static_cast(actorRef); + + auto signIdentity = + IdentifySign(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z, actor->id); + ObjectExtension::GetInstance().Set(actor, std::move(signIdentity)); + }); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_WONDER_TALK2, shouldRegister, [](void* actorRef) { + Actor* actor = static_cast(actorRef); + EnWonderTalk2* signActor = static_cast(actorRef); + + auto signIdentity = + IdentifySign(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z, actor->id); + ObjectExtension::GetInstance().Set(actor, std::move(signIdentity)); + }); + + // Draw particle effect to indicate a randomized item + COND_ID_HOOK(OnActorUpdate, ACTOR_EN_KANBAN, shouldRegister, Sign_RandomizerDrawSetup); + + COND_ID_HOOK(OnActorUpdate, ACTOR_EN_A_OBJ, shouldRegister, Sign_RandomizerDrawSetup); + + COND_ID_HOOK(OnActorUpdate, ACTOR_EN_WONDER_TALK, shouldRegister, Sign_RandomizerDrawSetup); + + COND_ID_HOOK(OnActorUpdate, ACTOR_EN_WONDER_TALK2, shouldRegister, Sign_RandomizerDrawSetup); + + COND_VB_SHOULD(VB_SKIP_TALKING, shouldRegister, { + Actor* talkActor = GET_PLAYER(gPlayState)->talkActor; + if (talkActor != NULL) { + switch (talkActor->id) { + case ACTOR_EN_KANBAN: + case ACTOR_EN_A_OBJ: + case ACTOR_EN_WONDER_TALK: + case ACTOR_EN_WONDER_TALK2: + if (Sign_RandomizerHoldsItem(talkActor, gPlayState)) { + Sign_RandomizerSpawnCollectible(talkActor); + *should = false; + } + break; + default: + break; + } + } + }); + + // Give Royal Tomb item if destroyed + COND_HOOK(OnFlagSet, shouldRegister, Sign_RoyalTombSpawnCollectible); +} + +void Rando::StaticData::RegisterSignLocations() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + // Overworld Signs + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Actor Id Spoiler Collection Check +locationTable[RC_KF_DEKU_TREE_RECTANGLE_SIGN] = Location::Sign(RC_KF_DEKU_TREE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(871, 311), "Deku Tree Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RECTANGLE_SIGN)); +locationTable[RC_KF_STEPPING_STONES_RECTANGLE_SIGN] = Location::Sign(RC_KF_STEPPING_STONES_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(607, -80), "Stepping Stones Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STEPPING_STONES_RECTANGLE_SIGN)); +locationTable[RC_KF_LINKS_HOUSE_RECTANGLE_SIGN] = Location::Sign(RC_KF_LINKS_HOUSE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(49, 967), "Link's House Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_LINKS_HOUSE_RECTANGLE_SIGN)); +locationTable[RC_KF_FIRST_TRAINING_CENTER_RECTANGLE_SIGN] = Location::Sign(RC_KF_FIRST_TRAINING_CENTER_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-494, 598), "First Training Center Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_FIRST_TRAINING_CENTER_RECTANGLE_SIGN)); +locationTable[RC_KF_SECOND_TRAINING_CENTER_RECTANGLE_SIGN] = Location::Sign(RC_KF_SECOND_TRAINING_CENTER_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-538, 718), "Second Training Center Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SECOND_TRAINING_CENTER_RECTANGLE_SIGN)); +locationTable[RC_KF_AFTER_CRAWLSPACE_RECTANGLE_SIGN] = Location::Sign(RC_KF_AFTER_CRAWLSPACE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-784, 1675), "After Crawlspace Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_AFTER_CRAWLSPACE_RECTANGLE_SIGN)); +locationTable[RC_KF_CRAWL_RECTANGLE_RECTANGLE_SIGN] = Location::Sign(RC_KF_CRAWL_RECTANGLE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-845, 1018), "Crawl Rectangle Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_CRAWL_RECTANGLE_RECTANGLE_SIGN)); +locationTable[RC_KF_LOST_WOODS_RECTANGLE_SIGN] = Location::Sign(RC_KF_LOST_WOODS_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-1432, -426), "Lost Woods Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_LOST_WOODS_RECTANGLE_SIGN)); +locationTable[RC_KF_HOUSE_OF_TWINS_ARROW_SIGN] = Location::Sign(RC_KF_HOUSE_OF_TWINS_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1089, 473), "House of Twins Arrow Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_HOUSE_OF_TWINS_ARROW_SIGN)); +locationTable[RC_KF_SHOP_ARROW_SIGN] = Location::Sign(RC_KF_SHOP_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(728, -195), "Shop Arrow Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SHOP_ARROW_SIGN)); +locationTable[RC_KF_SARIAS_HOUSE_ARROW_SIGN] = Location::Sign(RC_KF_SARIAS_HOUSE_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(436, 601), "Saria's House Arrow Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_HOUSE_ARROW_SIGN)); +locationTable[RC_KF_LOST_WOODS_ARROW_SIGN] = Location::Sign(RC_KF_LOST_WOODS_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-170, -1335), "Lost Woods Arrow Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_LOST_WOODS_ARROW_SIGN)); +locationTable[RC_KF_MIDOS_HOUSE_ARROW_SIGN] = Location::Sign(RC_KF_MIDOS_HOUSE_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-512, -459), "Mido's House Arrow Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_MIDOS_HOUSE_ARROW_SIGN)); +locationTable[RC_KF_TRAINING_CENTER_ENTRANCE_ARROW_SIGN] = Location::Sign(RC_KF_TRAINING_CENTER_ENTRANCE_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-779, 424), "Training Center Entrance Arrow Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_TRAINING_CENTER_ENTRANCE_ARROW_SIGN)); +locationTable[RC_KF_INNER_TRAINING_CENTER_ARROW_SIGN] = Location::Sign(RC_KF_INNER_TRAINING_CENTER_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-924, 928), "Inner Training Center Arrow Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_INNER_TRAINING_CENTER_ARROW_SIGN)); +locationTable[RC_KF_KNOW_IT_ALL_BROTHERS_HOUSE_ARROW_SIGN] = Location::Sign(RC_KF_KNOW_IT_ALL_BROTHERS_HOUSE_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-1008, 479), "Know-It-All Brothers House Arrow Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_KNOW_IT_ALL_BROTHERS_HOUSE_ARROW_SIGN)); +locationTable[RC_KF_BOULDER_MAZE_RECTANGLE_SIGN] = Location::Sign(RC_KF_BOULDER_MAZE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-273, 2173), "Boulder Maze Rectangle Sign", RHT_SIGN_KOKIRI_FOREST, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BOULDER_MAZE_RECTANGLE_SIGN)); +locationTable[RC_KF_LINKS_HOUSE_SIGN] = Location::Sign(RC_KF_LINKS_HOUSE_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_LINKS_HOUSE, TWO_ACTOR_PARAMS(78, 116), "Link's House Sign", RHT_SIGN_LINKS_HOUSE, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_LINKS_HOUSE_SIGN)); +locationTable[RC_LW_THEATER_RECTANGLE_SIGN] = Location::Sign(RC_LW_THEATER_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3898, 1228), "Theater Rectangle Sign", RHT_SIGN_DEKU_THEATER, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_THEATER_RECTANGLE_SIGN)); +locationTable[RC_HF_CASTLE_EXIT_ARROW_SIGN] = Location::Sign(RC_HF_CASTLE_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-130, 2105), "Castle Exit Arrow Sign", RHT_SIGN_HYRULE_FIELD, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CASTLE_EXIT_ARROW_SIGN)); +locationTable[RC_HF_WOODED_EXIT_ARROW_SIGN] = Location::Sign(RC_HF_WOODED_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3952, 7232), "Wooded Exit Arrow Sign", RHT_SIGN_HYRULE_FIELD, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_WOODED_EXIT_ARROW_SIGN)); +locationTable[RC_HF_ROCKY_PATH_EXIT_ARROW_SIGN] = Location::Sign(RC_HF_ROCKY_PATH_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-8780, 7680), "Rocky Path Exit Arrow Sign", RHT_SIGN_HYRULE_FIELD, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ROCKY_PATH_EXIT_ARROW_SIGN)); +locationTable[RC_HF_FENCED_ARROW_SIGN] = Location::Sign(RC_HF_FENCED_ARROW_SIGN, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4935, 14045), "Fenced Arrow Sign", RHT_SIGN_HYRULE_FIELD, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FENCED_ARROW_SIGN)); +locationTable[RC_HF_CENTER_EXIT_ARROW_SIGN] = Location::Sign(RC_HF_CENTER_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1564, 4318), "Center Exit Arrow Sign", RHT_SIGN_HYRULE_FIELD, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CENTER_EXIT_ARROW_SIGN)); +locationTable[RC_HF_RIVER_EXIT_ARROW_SIGN] = Location::Sign(RC_HF_RIVER_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(5925, 3805), "River Exit Arrow Sign", RHT_SIGN_HYRULE_FIELD, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_RIVER_EXIT_ARROW_SIGN)); +locationTable[RC_HF_STAIRS_EXIT_ARROW_SIGN] = Location::Sign(RC_HF_STAIRS_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3230, 570), "Stairs Exit Arrow Sign", RHT_SIGN_HYRULE_FIELD, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_STAIRS_EXIT_ARROW_SIGN)); +locationTable[RC_MK_SHOOTING_GALLERY_RECTANGLE_SIGN] = Location::Sign(RC_MK_SHOOTING_GALLERY_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_MARKET, SCENE_SHOOTING_GALLERY, TWO_ACTOR_PARAMS(59, 365), "Shooting Gallery Rectangle Sign", RHT_SIGN_MK_SHOOTING_GALLERY, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_SHOOTING_GALLERY_RECTANGLE_SIGN)); +locationTable[RC_MK_MASK_SHOP_SIGN] = Location::Sign(RC_MK_MASK_SHOP_SIGN, RCQUEST_BOTH, RCAREA_MARKET, SCENE_HAPPY_MASK_SHOP, TWO_ACTOR_PARAMS(-112, 31), "Mask Shop Sign", RHT_SIGN_HAPPY_MASK_SHOP, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_MASK_SHOP_SIGN)); +locationTable[RC_TOT_ALTAR] = Location::Sign(RC_TOT_ALTAR, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME, TWO_ACTOR_PARAMS(0, 1330), "Altar", RHT_SIGN_TEMPLE_OF_TIME, ACTOR_EN_WONDER_TALK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_ALTAR)); +locationTable[RC_HC_DEAD_END_RECTANGLE_SIGN] = Location::Sign(RC_HC_DEAD_END_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(2351, 2634), "Dead End Rectangle Sign", RHT_SIGN_HYRULE_CASTLE, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_DEAD_END_RECTANGLE_SIGN)); +locationTable[RC_KAK_GUARD_GATE_RECTANGLE_SIGN] = Location::Sign(RC_KAK_GUARD_GATE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(210, -1275), "Guard Gate Rectangle Sign", RHT_SIGN_KAKARIKO_VILLAGE, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_GUARD_GATE_RECTANGLE_SIGN)); +locationTable[RC_KAK_WELL_RECTANGLE_SIGN] = Location::Sign(RC_KAK_WELL_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(655, 525), "Well Rectangle Sign", RHT_SIGN_KAKARIKO_VILLAGE, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_WELL_RECTANGLE_SIGN)); +locationTable[RC_KAK_SOUTHEAST_EXIT_ARROW_SIGN] = Location::Sign(RC_KAK_SOUTHEAST_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(1165, 1550), "Southeast Exit Arrow Sign", RHT_SIGN_KAKARIKO_VILLAGE, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_SOUTHEAST_EXIT_ARROW_SIGN)); +locationTable[RC_KAK_FRONT_GATE_ARROW_SIGN] = Location::Sign(RC_KAK_FRONT_GATE_ARROW_SIGN, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-2590, 965), "Front Gate Arrow Sign", RHT_SIGN_KAKARIKO_VILLAGE, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_FRONT_GATE_ARROW_SIGN)); +locationTable[RC_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN] = Location::Sign(RC_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_SHOOTING_GALLERY, TWO_ACTOR_PARAMS(59, 365), "Shooting Gallery Rectangle Sign", RHT_SIGN_KAK_SHOOTING_GALLERY, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN)); +locationTable[RC_GY_ENTRANCE_RECTANGLE_SIGN] = Location::Sign(RC_GY_ENTRANCE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(-1110, 430), "Entrance Rectangle Sign", RHT_SIGN_GRAVEYARD, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_ENTRANCE_RECTANGLE_SIGN)); +locationTable[RC_GY_ENTRANCE_PLINTH] = Location::Sign(RC_GY_ENTRANCE_PLINTH, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(-805, 266), "Entrance Plinth", RHT_SIGN_GRAVEYARD, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_ENTRANCE_PLINTH)); +locationTable[RC_GY_RIGHT_OF_ROYAL_TOMB_GRAVE] = Location::Sign(RC_GY_RIGHT_OF_ROYAL_TOMB_GRAVE, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(654, 258), "Right of Royal Tomb Grave", RHT_SIGN_GRAVEYARD, ACTOR_EN_WONDER_TALK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_RIGHT_OF_ROYAL_TOMB_GRAVE)); +locationTable[RC_GY_LEFT_OF_ROYAL_TOMB_GRAVE] = Location::Sign(RC_GY_LEFT_OF_ROYAL_TOMB_GRAVE, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(654, -102), "Left of Royal Tomb Grave", RHT_SIGN_GRAVEYARD, ACTOR_EN_WONDER_TALK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_LEFT_OF_ROYAL_TOMB_GRAVE)); +locationTable[RC_GY_ROYAL_TOMB_GRAVE] = Location::Sign(RC_GY_ROYAL_TOMB_GRAVE, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(752, 85), "Royal Tomb Grave", RHT_SIGN_GRAVEYARD, ACTOR_EN_WONDER_TALK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_ROYAL_TOMB_GRAVE)); +locationTable[RC_DMT_ABOVE_DODONGO_RECTANGLE_SIGN] = Location::Sign(RC_DMT_ABOVE_DODONGO_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1300, -496), "Above Dodongo Rectangle Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_ABOVE_DODONGO_RECTANGLE_SIGN)); +locationTable[RC_DMT_ADULT_CENTER_EXIT_ARROW_SIGN] = Location::Sign(RC_DMT_ADULT_CENTER_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-299, -1787), "Adult Center Exit Arrow Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_ADULT_CENTER_EXIT_ARROW_SIGN)); +locationTable[RC_DMT_CHILD_CENTER_EXIT_RECTANGLE_SIGN] = Location::Sign(RC_DMT_CHILD_CENTER_EXIT_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-299, -1787), "Child Center Exit Rectangle Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CHILD_CENTER_EXIT_RECTANGLE_SIGN)); +locationTable[RC_DMT_DODONGOS_CAVERN_RECTANGLE_SIGN] = Location::Sign(RC_DMT_DODONGOS_CAVERN_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1834, -571), "Dodongo's Cavern Rectangle Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_DODONGOS_CAVERN_RECTANGLE_SIGN)); +locationTable[RC_DMT_CENTER_TRAIL_RECTANGLE_SIGN] = Location::Sign(RC_DMT_CENTER_TRAIL_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1260, 540), "Center Trail Rectangle Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_CENTER_TRAIL_RECTANGLE_SIGN)); +locationTable[RC_DMT_TO_UPPER_TRAIL_ARROW_SIGN] = Location::Sign(RC_DMT_TO_UPPER_TRAIL_ARROW_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1127, 44), "To Upper Trail Arrow Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_TO_UPPER_TRAIL_ARROW_SIGN)); +locationTable[RC_DMT_UPPER_EXIT_ARROW_SIGN] = Location::Sign(RC_DMT_UPPER_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-40, -4410), "Upper Exit Arrow Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_UPPER_EXIT_ARROW_SIGN)); +locationTable[RC_DMT_TO_CENTER_EXIT_ARROW_SIGN] = Location::Sign(RC_DMT_TO_CENTER_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-735, 595), "To Center Exit Arrow Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_TO_CENTER_EXIT_ARROW_SIGN)); +locationTable[RC_DMT_LOWER_EXIT_ARROW_SIGN] = Location::Sign(RC_DMT_LOWER_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1300, 2155), "Lower Exit Arrow Sign", RHT_SIGN_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_LOWER_EXIT_ARROW_SIGN)); +locationTable[RC_GC_CHILD_ROLLING_GORON_RECTANGLE_SIGN] = Location::Sign(RC_GC_CHILD_ROLLING_GORON_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(333, -684), "Child Rolling Goron Rectangle Sign", RHT_SIGN_GORON_CITY, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_CHILD_ROLLING_GORON_RECTANGLE_SIGN)); +locationTable[RC_DMC_BRIDGE_EXIT_ARROW_SIGN] = Location::Sign(RC_DMC_BRIDGE_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1610, 95), "Bridge Exit Arrow Sign", RHT_SIGN_DEATH_MOUNTAIN_CRATER, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BRIDGE_EXIT_ARROW_SIGN)); +locationTable[RC_ZR_SLEEPLESS_WATERFALL_PLAQUE] = Location::Sign(RC_ZR_SLEEPLESS_WATERFALL_PLAQUE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4096, -1401), "Sleepless Waterfall Plaque", RHT_SIGN_ZORAS_RIVER, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_SLEEPLESS_WATERFALL_PLAQUE)); +locationTable[RC_ZD_SHOP_RECTANGLE_SIGN] = Location::Sign(RC_ZD_SHOP_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(477, 318), "Shop Rectangle Sign", RHT_SIGN_ZORAS_DOMAIN, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_SHOP_RECTANGLE_SIGN)); +locationTable[RC_ZD_ENTRANCE_RECTANGLE_SIGN] = Location::Sign(RC_ZD_ENTRANCE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(-980, -210), "Entrance Rectangle Sign", RHT_SIGN_ZORAS_DOMAIN, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_ENTRANCE_RECTANGLE_SIGN)); +locationTable[RC_ZD_KING_ZORA_PATH_ARROW_SIGN] = Location::Sign(RC_ZD_KING_ZORA_PATH_ARROW_SIGN, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(217, 150), "King Zora Path Arrow Sign", RHT_SIGN_ZORAS_DOMAIN, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_KING_ZORA_PATH_ARROW_SIGN)); +locationTable[RC_ZD_NEAR_KING_ZORA_RECTANGLE_SIGN] = Location::Sign(RC_ZD_NEAR_KING_ZORA_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(720, -1345), "Near King Zora Rectangle Sign", RHT_SIGN_ZORAS_DOMAIN, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_KING_ZORA_RECTANGLE_SIGN)); +locationTable[RC_ZD_NEAR_KING_ZORA_ARROW_SIGN] = Location::Sign(RC_ZD_NEAR_KING_ZORA_ARROW_SIGN, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(345, -1572), "Near King Zora Arrow Sign", RHT_SIGN_ZORAS_DOMAIN, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_KING_ZORA_ARROW_SIGN)); +locationTable[RC_ZF_JABU_JABU_PLATFORM_RECTANGLE_SIGN] = Location::Sign(RC_ZF_JABU_JABU_PLATFORM_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1900, 208), "Jabu-Jabu Platform Rectangle Sign", RHT_SIGN_ZORAS_FOUNTAIN, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_JABU_PLATFORM_RECTANGLE_SIGN)); +locationTable[RC_ZF_ENTRANCE_ARROW_SIGN] = Location::Sign(RC_ZF_ENTRANCE_ARROW_SIGN, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-2557, 486), "Entrance Arrow Sign", RHT_SIGN_ZORAS_FOUNTAIN, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_ENTRANCE_ARROW_SIGN)); +locationTable[RC_LH_LAB_RECTANGLE_SIGN] = Location::Sign(RC_LH_LAB_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-2300, 3670), "Lab Rectangle Sign", RHT_SIGN_LAKE_HYLIA, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_RECTANGLE_SIGN)); +locationTable[RC_LH_NORTH_EXIT_ARROW_SIGN] = Location::Sign(RC_LH_NORTH_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-1835, 995), "North Exit Arrow Sign", RHT_SIGN_LAKE_HYLIA, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_NORTH_EXIT_ARROW_SIGN)); +locationTable[RC_LH_FISHING_SIGN] = Location::Sign(RC_LH_FISHING_SIGN, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(1341, 3779), "Fishing Sign", RHT_SIGN_LAKE_HYLIA, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_FISHING_SIGN)); +locationTable[RC_LH_ISLAND_PEDESTAL] = Location::Sign(RC_LH_ISLAND_PEDESTAL, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-491, 7259), "Island Pedestal", RHT_SIGN_LAKE_HYLIA, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_ISLAND_PEDESTAL)); +locationTable[RC_LH_FISHING_POND_RECTANGLE_SIGN] = Location::Sign(RC_LH_FISHING_POND_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_FISHING_POND, TWO_ACTOR_PARAMS(53, 982), "Fishing Pond Rectangle Sign", RHT_SIGN_FISHING_POND, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_FISHING_POND_RECTANGLE_SIGN)); +locationTable[RC_GV_BRIDGE_RECTANGLE_SIGN] = Location::Sign(RC_GV_BRIDGE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(359, 254), "Bridge Rectangle Sign", RHT_SIGN_GERUDO_VALLEY, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BRIDGE_RECTANGLE_SIGN)); +locationTable[RC_GV_EAST_EXIT_ARROW_SIGN] = Location::Sign(RC_GV_EAST_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(2778, 593), "East Exit Arrow Sign", RHT_SIGN_GERUDO_VALLEY, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_EAST_EXIT_ARROW_SIGN)); +locationTable[RC_GF_EAST_EXIT_ARROW_SIGN] = Location::Sign(RC_GF_EAST_EXIT_ARROW_SIGN, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-730, -70), "East Exit Arrow Sign", RHT_SIGN_GERUDO_FORTRESS, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_EAST_EXIT_ARROW_SIGN)); +locationTable[RC_GF_HBA_RECTANGLE_SIGN] = Location::Sign(RC_GF_HBA_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(3635, -360), "HBA Rectangle Sign", RHT_SIGN_GERUDO_FORTRESS, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_HBA_RECTANGLE_SIGN)); +locationTable[RC_GF_GATE_EXIT_RECTANGLE_SIGN] = Location::Sign(RC_GF_GATE_EXIT_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-1850, -3250), "Gate Exit Rectangle Sign", RHT_SIGN_GERUDO_FORTRESS, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_GATE_EXIT_RECTANGLE_SIGN)); +locationTable[RC_GF_GTG_ENTRANCE_RECTANGLE_SIGN] = Location::Sign(RC_GF_GTG_ENTRANCE_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(14, -1159), "GTG Entrance Rectangle Sign", RHT_SIGN_GERUDO_FORTRESS, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_GTG_ENTRANCE_RECTANGLE_SIGN)); +locationTable[RC_HW_CARPET_SALESMAN_ARROW_SIGN] = Location::Sign(RC_HW_CARPET_SALESMAN_ARROW_SIGN, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(2104, 2389), "Carpet Salesman Arrow Sign", RHT_SIGN_HAUNTED_WASTELAND, ACTOR_EN_A_OBJ, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HW_CARPET_SALESMAN_ARROW_SIGN)); +locationTable[RC_HW_POE_ALTAR] = Location::Sign(RC_HW_POE_ALTAR, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(645, -2234), "Poe Altar", RHT_SIGN_HAUNTED_WASTELAND, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HW_POE_ALTAR)); +// Dungeon Signs +locationTable[RC_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL] = Location::Sign(RC_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL, RCQUEST_BOTH, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(578, -929), "Top Floor Pedestal", RHT_SIGN_DODONGOS_CAVERN, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL)); +locationTable[RC_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN] = Location::Sign(RC_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(910, -192), "Truthspinner Rectangle Sign", RHT_SIGN_SHADOW_TEMPLE, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN)); +locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN] = Location::Sign(RC_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN, RCQUEST_BOTH, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(1132, 4103), "Falling Spikes Rectangle Sign", RHT_SIGN_SHADOW_TEMPLE, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN)); +locationTable[RC_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE] = Location::Sign(RC_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE, RCQUEST_BOTH, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-282, 312), "Left Snake Statue", RHT_SIGN_SPIRIT_TEMPLE, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE)); +locationTable[RC_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE] = Location::Sign(RC_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE, RCQUEST_BOTH, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(302, 310), "Right Snake Statue", RHT_SIGN_SPIRIT_TEMPLE, ACTOR_EN_WONDER_TALK2, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE)); +// MQ Dungeon Signs +locationTable[RC_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN] = Location::Sign(RC_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2893, 2705), "Lower Pit Rectangle Sign", RHT_SIGN_SHADOW_TEMPLE, ACTOR_EN_KANBAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN)); + + // clang-format on +} + +static RegisterShipInitFunc initFunc_ShuffleSigns(RegisterShuffleSigns, { "IS_RANDO" }); +static RegisterShipInitFunc registerSignLocations(Rando::StaticData::RegisterSignLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleSpeak.cpp b/soh/soh/Enhancements/randomizer/ShuffleSpeak.cpp index 14f8d91b26..96b150fede 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleSpeak.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleSpeak.cpp @@ -1,8 +1,10 @@ #include +#include "z64.h" +#include "functions.h" +#include "soh/Enhancements/randomizer/SeedContext.h" +#include "overlays/actors/ovl_En_Ossan/z_en_ossan.h" extern "C" { extern PlayState* gPlayState; -#include "functions.h" -#include "overlays/actors/ovl_En_Ossan/z_en_ossan.h" } void RegisterShuffleSpeak() { diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index da99a2dd66..1d0fe2f6f8 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -3,6 +3,8 @@ #include "static_data.h" #include "soh/ObjectExtension/ObjectExtension.h" #include "item_category_adj.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "variables.h" @@ -124,6 +126,29 @@ void EnWood02_RandomizerSpawnCollectible(EnWood02* treeActor, PlayState* play) { treeIdentity->randomizerCheck = RC_UNKNOWN_CHECK; } +static CheckIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { + CheckIdentity treeIdentity; + + if (sceneNum == SCENE_MARKET_NIGHT) { + sceneNum = SCENE_MARKET_DAY; + } + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_WOOD02, sceneNum, actorParams); + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK && + (location->GetRCType() != RCTYPE_NLTREE || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) { + treeIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + treeIdentity.randomizerCheck = location->GetRandomizerCheck(); + return treeIdentity; + } + + treeIdentity.randomizerInf = RAND_INF_MAX; + treeIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + return treeIdentity; +} + void EnWood02_RandomizerInit(void* actorRef) { EnWood02* treeActor = static_cast(actorRef); if ((treeActor->actor.params <= WOOD_TREE_KAKARIKO_ADULT && @@ -131,8 +156,8 @@ void EnWood02_RandomizerInit(void* actorRef) { (treeActor->actor.params > WOOD_TREE_KAKARIKO_ADULT && treeActor->actor.params <= WOOD_BUSH_BLACK_LARGE_SPAWNED && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BUSHES).Get())) { - auto treeIdentity = OTRGlobals::Instance->gRandomizer->IdentifyTree( - gPlayState->sceneNum, (s16)treeActor->actor.world.pos.x, (s16)treeActor->actor.world.pos.z); + auto treeIdentity = + IdentifyTree(gPlayState->sceneNum, (s16)treeActor->actor.world.pos.x, (s16)treeActor->actor.world.pos.z); if (treeIdentity.randomizerInf != RAND_INF_MAX && treeIdentity.randomizerCheck != RC_UNKNOWN_CHECK) { ObjectExtension::GetInstance().Set(actorRef, std::move(treeIdentity)); } diff --git a/soh/soh/Enhancements/randomizer/ShuffleWonderItems.cpp b/soh/soh/Enhancements/randomizer/ShuffleWonderItems.cpp new file mode 100644 index 0000000000..59026cac1e --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleWonderItems.cpp @@ -0,0 +1,547 @@ +#include +#include +#include "soh/ResourceManagerHelpers.h" +#include "soh/ObjectExtension/ObjectExtension.h" +#include "soh/ObjectExtension/ActorListIndex.h" +#include "item_category_adj.h" +#include "particle_cmc.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" + +extern "C" { +#include "overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.h" +#include "overlays/actors/ovl_En_Heishi1/z_en_heishi1.h" +extern PlayState* gPlayState; +extern Vec3f sTagPointsFree[9]; +extern Vec3f sTagPointsOrdered[9]; +} + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +// Many wonder items spawn on top of each other, offset position to make them all distinct +static std::unordered_map sStackedWonderOffsets = { + { RC_COLOSSUS_WONDER_OASIS_TREE_1, { 8.0f, 0.0f, -8.0f } }, + { RC_COLOSSUS_WONDER_OASIS_TREE_2, { 5.0f, 0.0f, -8.0f } }, + + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1, { 6.0f, 15.0f, 6.0f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2, { 12.0f, 0.0f, 0.0f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3, { -4.0f, -2.0f, 25.0f } }, + + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1, { -6.0f, -14.0f, 2.0f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2, { 5.0f, 0.0f, -10.0f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3, { 4.0f, -2.0f, 5.0f } }, + + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1, { 5.0f, 6.0f, 0.0f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2, { 0.0f, 0.0f, 0.0f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3, { 0.0f, 0.0f, 0.0f } }, + + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1, { -2.0f, 0.0f, 15.0f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2, { 1.0f, -11.0f, -5.0f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3, { 0.0f, -12.0f, 0.0f } }, + + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1, { -7.5f, 0.0f, -7.5f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2, { -7.5f, 0.0f, 7.5f } }, + { RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3, { 7.5f, 0.0f, 7.5f } }, + + { RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1, { -7.5f, 0.0f, -7.5f } }, + { RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2, { -7.5f, 0.0f, 7.5f } }, + { RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3, { 7.5f, 0.0f, 7.5f } }, + + { RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT, { 0.0f, 0.0f, -8.0f } }, + { RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW, { 0.0f, 0.0f, 8.0f } }, + + { RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1, { -8.0f, 0.0f, 0.0f } }, + { RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2, { 8.0f, 0.0f, 0.0f } }, + + { RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1, { 0.0f, 0.0f, -8.0f } }, + { RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2, { 0.0f, 0.0f, 8.0f } }, + + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1, { -5.0f, 1.0f, -5.0f } }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2, { 0.0f, -3.0f, -11.0f } }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3, { 0.0f, -14.0f, -15.0f } }, + + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1, { 0.0f, 9.0f, 10.0f } }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2, { 0.0f, -7.0f, 10.0f } }, + { RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3, { 0.0f, 0.0f, 10.0f } }, + + { RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER, { 0.0f, 0.0f, -8.0f } }, + { RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH, { 0.0f, 0.0f, 8.0f } }, + + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1, { -22.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2, { -7.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3, { 7.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4, { 22.5f, 0.0f, 0.0f } }, + + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1, { -22.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2, { -7.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3, { 7.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4, { 22.5f, 0.0f, 0.0f } }, + + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1, { -22.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2, { -7.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3, { 7.5f, 0.0f, 0.0f } }, + { RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4, { 22.5f, 0.0f, 0.0f } }, +}; + +static Vec3f GetStackOffset(RandomizerCheck rc) { + auto it = sStackedWonderOffsets.find(rc); + return it != sStackedWonderOffsets.end() ? it->second : Vec3f{ 0.0f, 0.0f, 0.0f }; +} + +void SpawnNTSC1011WonderItem() { + if (LINK_IS_ADULT && gPlayState->sceneNum == SCENE_ZORAS_FOUNTAIN) { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_WONDER_ITEM, -667, 320, 1053, 0, 0, 1, 4799); + } else if (LINK_IS_ADULT && gPlayState->sceneNum == SCENE_DEATH_MOUNTAIN_CRATER) { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_WONDER_ITEM, 6, 311, -640, 0, 0, 1, 4799); + } +} + +static CheckIdentity IdentifyWonderItem(s32 sceneNum, s32 par1, s32 par2) { + CheckIdentity wonderIdentity; + uint32_t wonderSceneNum = sceneNum; + + // align oasis trees in colossus between child/adult + if (sceneNum == SCENE_DESERT_COLOSSUS && LINK_IS_ADULT) { + if (par1 == 1157 && par2 == 2388) { + par1 = 1161; + par2 = 2383; + } else if (par1 == 1114 && par2 == 2580) { + par1 = 1113; + par2 = 2581; + } + } + + wonderIdentity.randomizerInf = RAND_INF_MAX; + wonderIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(par1, par2); + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_WONDER_ITEM, wonderSceneNum, actorParams); + + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifyWonderItem did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + } else { + wonderIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + wonderIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return wonderIdentity; +} + +uint8_t EnWonderItem_RandomizerHoldsItem(EnWonderItem* wonderActor, PlayState* play) { + const CheckIdentity* wonderIdentity = ObjectExtension::GetInstance().Get(&wonderActor->actor); + if (wonderIdentity == nullptr) { + Actor* actor = &wonderActor->actor; + s16 actorIndex = GetActorListIndex(actor); + bool isDungeonScene = (play->sceneNum >= SCENE_DEKU_TREE && play->sceneNum <= SCENE_GERUDO_TRAINING_GROUND) || + play->sceneNum == SCENE_INSIDE_GANONS_CASTLE; + // For dungeons, use room Id and actor index. For overworld, use xz coordinates. + auto newIdentity = isDungeonScene + ? IdentifyWonderItem(play->sceneNum, (s16)play->roomCtx.curRoom.num, actorIndex) + : IdentifyWonderItem(play->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + + ObjectExtension::GetInstance().Set(actor, std::move(newIdentity)); + wonderIdentity = ObjectExtension::GetInstance().Get(actor); + if (wonderIdentity == nullptr) { + return false; + } + } + RandomizerCheck rc = wonderIdentity->randomizerCheck; + uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); + auto wonderSetting = RAND_GET_OPTION(RSK_SHUFFLE_WONDER_ITEMS); + if (!IS_RANDO || (wonderSetting.Is(RO_SHUFFLE_WONDER_ITEMS_OVERWORLD) && isDungeon) || + (wonderSetting.Is(RO_SHUFFLE_WONDER_ITEMS_DUNGEONS) && !isDungeon) || + Flags_GetRandomizerInf(wonderIdentity->randomizerInf) || wonderIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { + return false; + } else { + return true; + } +} + +static void EnWonderItem_RandomizerDraw(EnWonderItem* wonderActor, Color_RGBA8* primColor, Color_RGBA8* secColor, + Color_RGBA8* envColor, CheckIdentity* wonderIdentity) { + Vec3f pos; + Vec3f velocity = { 0.0f, -0.05f, 0.0f }; + Vec3f accel = { 0.0f, -0.025f, 0.0f }; + + // Draw particles at tag spots if applicable, otherwise at wonder item actor location + if (wonderActor->wonderMode == WONDERITEM_MULTITAG_ORDERED) { + for (s32 i = 0, mask = 1; i < wonderActor->numTagPoints; i++, mask <<= 1) { + if (!(wonderActor->tagFlags & mask)) { + pos.x = Rand_CenteredFloat(1.0f) + sTagPointsOrdered[i].x; + pos.y = (Rand_ZeroOne() * 25.0f) + sTagPointsOrdered[i].y + 10; + pos.z = Rand_CenteredFloat(1.0f) + sTagPointsOrdered[i].z; + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, secColor, envColor, 2000, 100); + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, primColor, envColor, 2000, 100); + } + } + } else if (wonderActor->wonderMode == WONDERITEM_MULTITAG_FREE) { + for (s32 i = 0, mask = 1; i < wonderActor->numTagPoints; i++, mask <<= 1) { + if (!(wonderActor->tagFlags & mask)) { + pos.x = Rand_CenteredFloat(1.0f) + sTagPointsFree[i].x; + pos.y = (Rand_ZeroOne() * 25.0f) + sTagPointsFree[i].y + 10; + pos.z = Rand_CenteredFloat(1.0f) + sTagPointsFree[i].z; + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, secColor, envColor, 2000, 100); + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, primColor, envColor, 2000, 100); + } + } + } else { + Vec3f offset = GetStackOffset(wonderIdentity->randomizerCheck); + pos.x = Rand_CenteredFloat(1.0f) + wonderActor->actor.world.pos.x + offset.x; + pos.y = (Rand_ZeroOne() * 25.0f) + wonderActor->actor.world.pos.y + 10 + offset.y; + pos.z = Rand_CenteredFloat(1.0f) + wonderActor->actor.world.pos.z + offset.z; + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, secColor, envColor, 2000, 100); + EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, primColor, envColor, 2000, 100); + } +} + +void EnWonderItem_RandomizerDrawSetup(void* refActor) { + EnWonderItem* wonderActor = static_cast(refActor); + + // If not a randomized item or too far, don't draw. + // If item is unshuffled or collected, kill wonder actor if switch flag is set. + if (!EnWonderItem_RandomizerHoldsItem(wonderActor, gPlayState)) { + if ((wonderActor->switchFlag >= 0) && Flags_GetSwitch(gPlayState, wonderActor->switchFlag)) { + Actor_Kill(&wonderActor->actor); + } + return; + } else if (wonderActor->actor.xzDistToPlayer > 1000.0f) { + return; + } + + bool cmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + + int isNotCMC = !cmc || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + + const auto wonderIdentity = ObjectExtension::GetInstance().Get(refActor); + if (wonderIdentity == nullptr) { + return; + } + + GetItemEntry wonderItem = + Rando::Context::GetInstance()->GetFinalGIEntry(wonderIdentity->randomizerCheck, true, GI_NONE); + GetItemCategory getItemCategory = isNotCMC ? ITEM_CATEGORY_MAJOR : Randomizer_AdjustItemCategory(wonderItem); + + Color_RGBA8 primColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_PRIMARY); + Color_RGBA8 secColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_SECONDARY); + Color_RGBA8 envColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_FLARE); + EnWonderItem_RandomizerDraw(wonderActor, &primColor, &secColor, &envColor, wonderIdentity); +} + +void EnWonderItem_RandomizerSpawnCollectible(EnWonderItem* wonderActor, PlayState* play) { + const auto wonderIdentity = ObjectExtension::GetInstance().Get(&wonderActor->actor); + EnItem00* item00; + Player* player = GET_PLAYER(gPlayState); + + // Hyrule courtyard left window handled separately to replace the bomb the guard throws + if (wonderIdentity == nullptr || wonderIdentity->randomizerCheck == RC_HC_WONDER_COURTYARD_LEFT_WINDOW) { + return; + } + // if activated via tag points, autocollect the check, otherwise spawn the item toward the player + // Water Temple MQ hookshot staircase can easily spawn unreachable items, autocollect + // Jabu MQ holes cow always spawns the item OOB (vanilla bug), autocollect + if (wonderActor->wonderMode == WONDERITEM_MULTITAG_FREE || wonderActor->wonderMode == WONDERITEM_PROXIMITY_DROP || + wonderActor->wonderMode == WONDERITEM_MULTITAG_ORDERED || + (wonderIdentity->randomizerCheck >= RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1 && + wonderIdentity->randomizerCheck <= RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3) || + wonderIdentity->randomizerCheck == RC_JABU_JABUS_BELLY_MQ_HOLES_COW) { + Flags_SetRandomizerInf(wonderIdentity->randomizerInf); + } else { + item00 = (EnItem00*)Item_DropCollectible(play, &wonderActor->actor.world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = wonderIdentity->randomizerInf; + item00->itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(wonderIdentity->randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + if (gPlayState->sceneNum != SCENE_INSIDE_GANONS_CASTLE) { + item00->actor.velocity.y = 3.0f; + item00->actor.speedXZ = 3.0f; + item00->actor.world.rot.y = + Math_Vec3f_Yaw(&item00->actor.world.pos, &player->actor.world.pos) + (s16)Rand_CenteredFloat(16384.0f); + } + } +} + +void WonderHeishi_RandomizerSpawnCollectible(PlayState* play, Vec3f pos, f32 rotY) { + EnItem00* item00; + Player* player = GET_PLAYER(gPlayState); + + item00 = (EnItem00*)Item_DropCollectible(play, &pos, ITEM00_SOH_DUMMY); + item00->randoInf = RAND_INF_HC_WONDER_COURTYARD_LEFT_WINDOW; + item00->itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(RC_HC_WONDER_COURTYARD_LEFT_WINDOW, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = Rand_CenteredFloat(5.0f) + 10.0f; + item00->actor.speedXZ = Rand_CenteredFloat(5.0f) + 10.0f; + item00->actor.world.rot.y = rotY; +} + +void RegisterShuffleWonderItems() { + bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_WONDER_ITEMS); + bool isNtscUs1011 = false; + for (uint32_t i = 0; i < ResourceMgr_GetNumGameVersions(); i++) { + if (ResourceMgr_GetGameVersion(i) == OOT_NTSC_US_10 || ResourceMgr_GetGameVersion(i) == OOT_NTSC_US_11) { + isNtscUs1011 = true; + } + } + bool shouldRegisterOverworld = RAND_GET_OPTION(RSK_SHUFFLE_WONDER_ITEMS).Is(RO_SHUFFLE_WONDER_ITEMS_ALL) || + RAND_GET_OPTION(RSK_SHUFFLE_WONDER_ITEMS).Is(RO_SHUFFLE_WONDER_ITEMS_OVERWORLD); + bool shouldRegisterNTSC1011 = shouldRegister && isNtscUs1011 && shouldRegisterOverworld; + + // Draw particle effect in wonder item spot to indicate a randomized item + COND_ID_HOOK(OnActorUpdate, ACTOR_EN_WONDER_ITEM, shouldRegister, EnWonderItem_RandomizerDrawSetup); + + // Spawn missing wonder items for NTSC 1.0 and NTSC 1.1 + COND_HOOK(OnSceneSpawnActors, shouldRegisterNTSC1011, SpawnNTSC1011WonderItem); + + // Prevent or delay actor kill until EnWonderItem_RandomizerDrawSetup in case item isn't yet collected + COND_VB_SHOULD(VB_WONDER_SPAWN, shouldRegister, { *should = false; }); + + // Do not spawn vanilla wonder item, instead spawn the randomized item + COND_VB_SHOULD(VB_WONDER_DROP_ITEM, shouldRegister, { + EnWonderItem* wonderActor = va_arg(args, EnWonderItem*); + if (EnWonderItem_RandomizerHoldsItem(wonderActor, gPlayState)) { + EnWonderItem_RandomizerSpawnCollectible(wonderActor, gPlayState); + *should = false; + } + }); + + // Do not spawn castle courtyard guard bomb, instead spawn the randomized item + COND_VB_SHOULD(VB_WONDER_HEISHI_ITEM, shouldRegisterOverworld, { + if (!Flags_GetRandomizerInf(RAND_INF_HC_WONDER_COURTYARD_LEFT_WINDOW)) { + Vec3f* pos = va_arg(args, Vec3f*); + f32 rotY = (f32)va_arg(args, double); + + WonderHeishi_RandomizerSpawnCollectible(gPlayState, *pos, rotY); + *should = false; + } + }); + + // If courtyard items are uncollected, keep guards patrolling + COND_VB_SHOULD(VB_WONDER_HEISHI_PATROLLING, shouldRegisterOverworld, { + EnHeishi1* guardActor = va_arg(args, EnHeishi1*); + if (!Flags_GetRandomizerInf(RAND_INF_HC_WONDER_COURTYARD_LEFT_WINDOW) || + !Flags_GetRandomizerInf(RAND_INF_HC_WONDER_COURTYARD_RIGHT_WINDOW)) { + *should = guardActor->type != 5; + } + }); +} + +void Rando::StaticData::RegisterWonderItemLocations() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + // Overworld Wonder Items + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Vanilla Spoiler Collection Check + locationTable[RC_KF_WONDER_TRAINING_1] = Location::WonderItem(RC_KF_WONDER_TRAINING_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-747, 951), "Wonder Training 1", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_TRAINING_1)); + locationTable[RC_KF_WONDER_TRAINING_2] = Location::WonderItem(RC_KF_WONDER_TRAINING_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-677, 899), "Wonder Training 2", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_TRAINING_2)); + locationTable[RC_KF_WONDER_TRAINING_3] = Location::WonderItem(RC_KF_WONDER_TRAINING_3, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-698, 830), "Wonder Training 3", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_TRAINING_3)); + locationTable[RC_KF_WONDER_SHOP] = Location::WonderItem(RC_KF_WONDER_SHOP, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_SHOP, TWO_ACTOR_PARAMS(146, -97), "Wonder Shop", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_SHOP)); + locationTable[RC_KF_WONDER_SIGN] = Location::WonderItem(RC_KF_WONDER_SIGN, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-488, 600), "Wonder Sign", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_SIGN)); + locationTable[RC_KF_WONDER_PLATFORMS_1] = Location::WonderItem(RC_KF_WONDER_PLATFORMS_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(364, 28), "Wonder Platforms 1", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_PLATFORMS_1)); + locationTable[RC_KF_WONDER_PLATFORMS_2] = Location::WonderItem(RC_KF_WONDER_PLATFORMS_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1074, 178), "Wonder Platforms 2", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_PLATFORMS_2)); + locationTable[RC_KF_WONDER_CRAWL_GRASS_1] = Location::WonderItem(RC_KF_WONDER_CRAWL_GRASS_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-590, 1635), "Wonder Crawl Grass 1", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_CRAWL_GRASS_1)); + locationTable[RC_KF_WONDER_CRAWL_GRASS_2] = Location::WonderItem(RC_KF_WONDER_CRAWL_GRASS_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-584, 1762), "Wonder Crawl Grass 2", RHT_WONDER_ITEM_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_WONDER_CRAWL_GRASS_2)); + locationTable[RC_HF_WONDER_BRIDGE_1] = Location::WonderItem(RC_HF_WONDER_BRIDGE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-99, 662), "Wonder Bridge Left", RHT_WONDER_ITEM_HYRULE_FIELD, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_WONDER_BRIDGE_1)); + locationTable[RC_HF_WONDER_BRIDGE_2] = Location::WonderItem(RC_HF_WONDER_BRIDGE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1, 665), "Wonder Bridge Center", RHT_WONDER_ITEM_HYRULE_FIELD, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_WONDER_BRIDGE_2)); + locationTable[RC_HF_WONDER_BRIDGE_3] = Location::WonderItem(RC_HF_WONDER_BRIDGE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(93, 659), "Wonder Bridge Right", RHT_WONDER_ITEM_HYRULE_FIELD, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_WONDER_BRIDGE_3)); + locationTable[RC_MKT_WONDER_DAY_1] = Location::WonderItem(RC_MKT_WONDER_DAY_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-523, -340), "Wonder Day Balcony 1", RHT_WONDER_ITEM_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MKT_WONDER_DAY_1)); + locationTable[RC_MKT_WONDER_DAY_2] = Location::WonderItem(RC_MKT_WONDER_DAY_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-523, -224), "Wonder Day Balcony 2", RHT_WONDER_ITEM_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MKT_WONDER_DAY_2)); + locationTable[RC_MKT_WONDER_DAY_3] = Location::WonderItem(RC_MKT_WONDER_DAY_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-521, -113), "Wonder Day Balcony 3", RHT_WONDER_ITEM_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MKT_WONDER_DAY_3)); + locationTable[RC_MKT_WONDER_DAY_4] = Location::WonderItem(RC_MKT_WONDER_DAY_4, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-521, -2), "Wonder Day Balcony 4", RHT_WONDER_ITEM_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MKT_WONDER_DAY_4)); + locationTable[RC_MKT_WONDER_DAY_5] = Location::WonderItem(RC_MKT_WONDER_DAY_5, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-516, 117), "Wonder Day Balcony 5", RHT_WONDER_ITEM_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MKT_WONDER_DAY_5)); + locationTable[RC_MKT_WONDER_NIGHT_1] = Location::WonderItem(RC_MKT_WONDER_NIGHT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_NIGHT, TWO_ACTOR_PARAMS(-524, -246), "Wonder Night Balcony 1", RHT_WONDER_ITEM_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MKT_WONDER_NIGHT_1)); + locationTable[RC_MKT_WONDER_NIGHT_2] = Location::WonderItem(RC_MKT_WONDER_NIGHT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_NIGHT, TWO_ACTOR_PARAMS(-521, 27), "Wonder Night Balcony 2", RHT_WONDER_ITEM_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MKT_WONDER_NIGHT_2)); + locationTable[RC_LLR_WONDER_BIG_FENCE] = Location::WonderItem(RC_LLR_WONDER_BIG_FENCE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(-443, -311), "Wonder Big Fence", RHT_WONDER_ITEM_LON_LON_RANCH, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_WONDER_BIG_FENCE)); + locationTable[RC_LLR_WONDER_SMALL_FENCE] = Location::WonderItem(RC_LLR_WONDER_SMALL_FENCE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(295, -979), "Wonder Small Fence", RHT_WONDER_ITEM_LON_LON_RANCH, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_WONDER_SMALL_FENCE)); + locationTable[RC_HC_WONDER_LEFT_TORCH] = Location::WonderItem(RC_HC_WONDER_LEFT_TORCH, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-502, 468), "Wonder Left Torch", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_LEFT_TORCH)); + locationTable[RC_HC_WONDER_RIGHT_TORCH] = Location::WonderItem(RC_HC_WONDER_RIGHT_TORCH, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-72, 468), "Wonder Right Torch", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_RIGHT_TORCH)); + locationTable[RC_HC_WONDER_MOAT_1] = Location::WonderItem(RC_HC_WONDER_MOAT_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(706, -663), "Wonder Moat Past Boxes", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_1)); + locationTable[RC_HC_WONDER_MOAT_2] = Location::WonderItem(RC_HC_WONDER_MOAT_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(755, -118), "Wonder Moat Past Gate 1", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_2)); + locationTable[RC_HC_WONDER_MOAT_3] = Location::WonderItem(RC_HC_WONDER_MOAT_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(725, 112), "Wonder Moat Past Gate 2", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_3)); + locationTable[RC_HC_WONDER_MOAT_4] = Location::WonderItem(RC_HC_WONDER_MOAT_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(754, 395), "Wonder Moat Before Gate 1", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_4)); + locationTable[RC_HC_WONDER_MOAT_5] = Location::WonderItem(RC_HC_WONDER_MOAT_5, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(403, 587), "Wonder Moat Before Gate 2", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_5)); + locationTable[RC_HC_WONDER_MOAT_6] = Location::WonderItem(RC_HC_WONDER_MOAT_6, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(62, 555), "Wonder Moat Before Gate 3", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_6)); + locationTable[RC_HC_WONDER_MOAT_7] = Location::WonderItem(RC_HC_WONDER_MOAT_7, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-256, 598), "Wonder Moat Before Gate 4", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_7)); + locationTable[RC_HC_WONDER_MOAT_8] = Location::WonderItem(RC_HC_WONDER_MOAT_8, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-557, 568), "Wonder Moat Before Gate 5", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_8)); + locationTable[RC_HC_WONDER_MOAT_9] = Location::WonderItem(RC_HC_WONDER_MOAT_9, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-819, 613), "Wonder Moat Before Gate 6", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_9)); + locationTable[RC_HC_WONDER_MOAT_10] = Location::WonderItem(RC_HC_WONDER_MOAT_10, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-1190, 561), "Wonder Moat Before Gate 7", RHT_WONDER_ITEM_HYRULE_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_MOAT_10)); + locationTable[RC_HC_WONDER_COURTYARD_RIGHT_WINDOW] = Location::WonderItem(RC_HC_WONDER_COURTYARD_RIGHT_WINDOW, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_CASTLE_COURTYARD_ZELDA, TWO_ACTOR_PARAMS(0, -481), "Wonder Courtyard Right Window", RHT_WONDER_ITEM_CASTLE_COURTYARD_ZELDA, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_COURTYARD_RIGHT_WINDOW)); + locationTable[RC_HC_WONDER_COURTYARD_LEFT_WINDOW] = Location::WonderItem(RC_HC_WONDER_COURTYARD_LEFT_WINDOW, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_CASTLE_COURTYARD_ZELDA, TWO_ACTOR_PARAMS(0, 476), "Wonder Courtyard Left Window", RHT_WONDER_ITEM_CASTLE_COURTYARD_ZELDA, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_WONDER_COURTYARD_LEFT_WINDOW)); + locationTable[RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_1] = Location::WonderItem(RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(1371, 497), "Wonder Back Skull Kids Grass 1", RHT_WONDER_ITEM_LOST_WOODS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_WONDER_BACK_SKULL_KIDS_GRASS_1)); + locationTable[RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_2] = Location::WonderItem(RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(1038, 557), "Wonder Back Skull Kids Grass 2", RHT_WONDER_ITEM_LOST_WOODS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_WONDER_BACK_SKULL_KIDS_GRASS_2)); + locationTable[RC_LW_WONDER_FRONT_SKULL_KIDS_GRASS] = Location::WonderItem(RC_LW_WONDER_FRONT_SKULL_KIDS_GRASS, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(1256, 194), "Wonder Front Skull Kids Grass", RHT_WONDER_ITEM_LOST_WOODS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_WONDER_FRONT_SKULL_KIDS_GRASS)); + locationTable[RC_SFM_WONDER_ENTRANCE] = Location::WonderItem(RC_SFM_WONDER_ENTRANCE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(-351, 2121), "Wonder Entrance Grass", RHT_WONDER_ITEM_SACRED_FOREST_MEADOW, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_WONDER_ENTRANCE)); + locationTable[RC_SFM_WONDER_MAZE_1] = Location::WonderItem(RC_SFM_WONDER_MAZE_1, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(100, 1375), "Wonder First Row Grass", RHT_WONDER_ITEM_SACRED_FOREST_MEADOW, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_WONDER_MAZE_1)); + locationTable[RC_SFM_WONDER_MAZE_2] = Location::WonderItem(RC_SFM_WONDER_MAZE_2, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(100, 1084), "Wonder Second Row Grass 1", RHT_WONDER_ITEM_SACRED_FOREST_MEADOW, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_WONDER_MAZE_2)); + locationTable[RC_SFM_WONDER_MAZE_3] = Location::WonderItem(RC_SFM_WONDER_MAZE_3, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(-204, 1283), "Wonder Second Row Grass 2", RHT_WONDER_ITEM_SACRED_FOREST_MEADOW, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_WONDER_MAZE_3)); + locationTable[RC_SFM_WONDER_MAZE_4] = Location::WonderItem(RC_SFM_WONDER_MAZE_4, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(-199, 177), "Wonder End of Maze Grass 1", RHT_WONDER_ITEM_SACRED_FOREST_MEADOW, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_WONDER_MAZE_4)); + locationTable[RC_SFM_WONDER_MAZE_5] = Location::WonderItem(RC_SFM_WONDER_MAZE_5, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(299, 285), "Wonder End of Maze Grass 2", RHT_WONDER_ITEM_SACRED_FOREST_MEADOW, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_WONDER_MAZE_5)); + locationTable[RC_KAK_WONDER_UNDER_CONSTRUCTION] = Location::WonderItem(RC_KAK_WONDER_UNDER_CONSTRUCTION, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(148, 1165), "Wonder Under Construction", RHT_WONDER_ITEM_KAKARIKO_VILLAGE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_WONDER_UNDER_CONSTRUCTION)); + locationTable[RC_KAK_WONDER_ABOVE_COW] = Location::WonderItem(RC_KAK_WONDER_ABOVE_COW, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_IMPAS_HOUSE, TWO_ACTOR_PARAMS(153, -266), "Wonder Above Impa's Cow", RHT_WONDER_ITEM_KAKARIKO_VILLAGE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_WONDER_ABOVE_COW)); + locationTable[RC_GY_WONDER_DAMPE_RACE_1] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(391, -2681), "Wonder Dampe's Grave 1", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_1)); + locationTable[RC_GY_WONDER_DAMPE_RACE_2] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(394, -2588), "Wonder Dampe's Grave 2", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_2)); + locationTable[RC_GY_WONDER_DAMPE_RACE_3] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(475, -2591), "Wonder Dampe's Grave 3", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_3)); + locationTable[RC_GY_WONDER_DAMPE_RACE_4] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(562, -2588), "Wonder Dampe's Grave 4", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_4)); + locationTable[RC_GY_WONDER_DAMPE_RACE_5] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(621, -3219), "Wonder Dampe's Grave 5", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_5)); + locationTable[RC_GY_WONDER_DAMPE_RACE_6] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(570, -5778), "Wonder Dampe's Grave 6", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_6)); + locationTable[RC_GY_WONDER_DAMPE_RACE_7] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_7, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(353, -5825), "Wonder Dampe's Grave 7", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_7)); + locationTable[RC_GY_WONDER_DAMPE_RACE_8] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_8, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(1666, -5736), "Wonder Dampe's Grave 8", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_8)); + locationTable[RC_GY_WONDER_DAMPE_RACE_9] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_9, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2549, -4598), "Wonder Dampe's Grave 9", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_9)); + locationTable[RC_GY_WONDER_DAMPE_RACE_10] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_10, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2547, -4847), "Wonder Dampe's Grave 10", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_10)); + locationTable[RC_GY_WONDER_DAMPE_RACE_11] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_11, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2726, -3634), "Wonder Dampe's Grave 11", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_11)); + locationTable[RC_GY_WONDER_DAMPE_RACE_12] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_12, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2728, -3500), "Wonder Dampe's Grave 12", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_12)); + locationTable[RC_GY_WONDER_DAMPE_RACE_13] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_13, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2633, -3394), "Wonder Dampe's Grave 13", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_13)); + locationTable[RC_GY_WONDER_DAMPE_RACE_14] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_14, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2377, -3398), "Wonder Dampe's Grave 14", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_14)); + locationTable[RC_GY_WONDER_DAMPE_RACE_15] = Location::WonderItem(RC_GY_WONDER_DAMPE_RACE_15, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(1308, -3125), "Wonder Dampe's Grave 15", RHT_WONDER_ITEM_DAMPES_GRAVE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_WONDER_DAMPE_RACE_15)); + locationTable[RC_DMC_WONDER_BENEATH_BRIDGE_PLATFORM] = Location::WonderItem(RC_DMC_WONDER_BENEATH_BRIDGE_PLATFORM, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(6, -640), "Wonder Beneath Bridge Platform", RHT_WONDER_ITEM_DEATH_MOUNTAIN_CRATER, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_WONDER_BENEATH_BRIDGE_PLATFORM)); + locationTable[RC_ZR_WONDER_NEAR_DOMAIN_1] = Location::WonderItem(RC_ZR_WONDER_NEAR_DOMAIN_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(3329, -1499), "Wonder Near Domain 1", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_NEAR_DOMAIN_1)); + locationTable[RC_ZR_WONDER_NEAR_DOMAIN_2] = Location::WonderItem(RC_ZR_WONDER_NEAR_DOMAIN_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(3161, -1493), "Wonder Near Domain 2", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_NEAR_DOMAIN_2)); + locationTable[RC_ZR_WONDER_NEAR_DOMAIN_3] = Location::WonderItem(RC_ZR_WONDER_NEAR_DOMAIN_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(2987, -1499), "Wonder Near Domain 3", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_NEAR_DOMAIN_3)); + locationTable[RC_ZR_WONDER_NEAR_DOMAIN_4] = Location::WonderItem(RC_ZR_WONDER_NEAR_DOMAIN_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(2831, -1421), "Wonder Near Domain 4", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_NEAR_DOMAIN_4)); + locationTable[RC_ZR_WONDER_BEFORE_LADDER_1] = Location::WonderItem(RC_ZR_WONDER_BEFORE_LADDER_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(1287, -363), "Wonder Before Ladder 1", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_BEFORE_LADDER_1)); + locationTable[RC_ZR_WONDER_BEFORE_LADDER_2] = Location::WonderItem(RC_ZR_WONDER_BEFORE_LADDER_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(1144, -296), "Wonder Before Ladder 2", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_BEFORE_LADDER_2)); + locationTable[RC_ZR_WONDER_BEFORE_LADDER_3] = Location::WonderItem(RC_ZR_WONDER_BEFORE_LADDER_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(1021, -224), "Wonder Before Ladder 3", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_BEFORE_LADDER_3)); + locationTable[RC_ZR_WONDER_BEFORE_LADDER_4] = Location::WonderItem(RC_ZR_WONDER_BEFORE_LADDER_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(902, -150), "Wonder Before Ladder 4", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_BEFORE_LADDER_4)); + locationTable[RC_ZR_WONDER_BEFORE_LADDER_5] = Location::WonderItem(RC_ZR_WONDER_BEFORE_LADDER_5, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(786, -74), "Wonder Before Ladder 5", RHT_WONDER_ITEM_ZORAS_RIVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_BEFORE_LADDER_5)); + locationTable[RC_ZR_WONDER_BEFORE_LADDER_6] = Location::WonderItem(RC_ZR_WONDER_BEFORE_LADDER_6, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(670, 3), "Wonder Before Ladder 6", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_BEFORE_LADDER_6)); + locationTable[RC_ZR_WONDER_AFTER_LADDER_1] = Location::WonderItem(RC_ZR_WONDER_AFTER_LADDER_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(520, 12), "Wonder After Ladder 1", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_AFTER_LADDER_1)); + locationTable[RC_ZR_WONDER_AFTER_LADDER_2] = Location::WonderItem(RC_ZR_WONDER_AFTER_LADDER_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(353, 9), "Wonder After Ladder 2", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_AFTER_LADDER_2)); + locationTable[RC_ZR_WONDER_AFTER_LADDER_3] = Location::WonderItem(RC_ZR_WONDER_AFTER_LADDER_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(158, 6), "Wonder After Ladder 3", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_AFTER_LADDER_3)); + locationTable[RC_ZR_WONDER_FROG_BRIDGE_1] = Location::WonderItem(RC_ZR_WONDER_FROG_BRIDGE_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(1204, -608), "Wonder Frog Bridge 1", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_FROG_BRIDGE_1)); + locationTable[RC_ZR_WONDER_FROG_BRIDGE_2] = Location::WonderItem(RC_ZR_WONDER_FROG_BRIDGE_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(1124, -803), "Wonder Frog Bridge 2", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_FROG_BRIDGE_2)); + locationTable[RC_ZR_WONDER_FROG_BRIDGE_3] = Location::WonderItem(RC_ZR_WONDER_FROG_BRIDGE_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(1020, -973), "Wonder Frog Bridge 3", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_FROG_BRIDGE_3)); + locationTable[RC_ZR_WONDER_PILLARS_1] = Location::WonderItem(RC_ZR_WONDER_PILLARS_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(509, -1223), "Wonder Pillars 1", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_PILLARS_1)); + locationTable[RC_ZR_WONDER_PILLARS_2] = Location::WonderItem(RC_ZR_WONDER_PILLARS_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(269, -1018), "Wonder Pillars 2", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_PILLARS_2)); + locationTable[RC_ZR_WONDER_PILLARS_3] = Location::WonderItem(RC_ZR_WONDER_PILLARS_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(9, -1158), "Wonder Pillars 3", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_PILLARS_3)); + locationTable[RC_ZR_WONDER_PILLARS_4] = Location::WonderItem(RC_ZR_WONDER_PILLARS_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-145, -938), "Wonder Pillars 4", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_PILLARS_4)); + locationTable[RC_ZR_WONDER_LOWER_LAND_BRIDGE_1] = Location::WonderItem(RC_ZR_WONDER_LOWER_LAND_BRIDGE_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-147, -736), "Wonder Lower Land Bridge 1", RHT_WONDER_ITEM_ZORAS_RIVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_1)); + locationTable[RC_ZR_WONDER_LOWER_LAND_BRIDGE_2] = Location::WonderItem(RC_ZR_WONDER_LOWER_LAND_BRIDGE_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-141, -588), "Wonder Lower Land Bridge 2", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_2)); + locationTable[RC_ZR_WONDER_LOWER_LAND_BRIDGE_3] = Location::WonderItem(RC_ZR_WONDER_LOWER_LAND_BRIDGE_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-142, -383), "Wonder Lower Land Bridge 3", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_3)); + locationTable[RC_ZR_WONDER_LOWER_LAND_BRIDGE_4] = Location::WonderItem(RC_ZR_WONDER_LOWER_LAND_BRIDGE_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-141, -218), "Wonder Lower Land Bridge 4", RHT_WONDER_ITEM_ZORAS_RIVER, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_4)); + locationTable[RC_ZR_WONDER_NEAR_CUCCO_1] = Location::WonderItem(RC_ZR_WONDER_NEAR_CUCCO_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-860, -38), "Wonder Near Cucco 1", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_NEAR_CUCCO_1)); + locationTable[RC_ZR_WONDER_NEAR_CUCCO_2] = Location::WonderItem(RC_ZR_WONDER_NEAR_CUCCO_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1063, -4), "Wonder Near Cucco 2", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_NEAR_CUCCO_2)); + locationTable[RC_ZR_WONDER_NEAR_CUCCO_3] = Location::WonderItem(RC_ZR_WONDER_NEAR_CUCCO_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1296, 242), "Wonder Near Cucco 3", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_NEAR_CUCCO_3)); + locationTable[RC_ZR_WONDER_LOWER_RIVER_1] = Location::WonderItem(RC_ZR_WONDER_LOWER_RIVER_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1287, 457), "Wonder Lower River 1", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_LOWER_RIVER_1)); + locationTable[RC_ZR_WONDER_LOWER_RIVER_2] = Location::WonderItem(RC_ZR_WONDER_LOWER_RIVER_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1288, 668), "Wonder Lower River 2", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_LOWER_RIVER_2)); + locationTable[RC_ZR_WONDER_LOWER_RIVER_3] = Location::WonderItem(RC_ZR_WONDER_LOWER_RIVER_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1290, 862), "Wonder Lower River 3", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_LOWER_RIVER_3)); + locationTable[RC_ZR_WONDER_LOWER_RIVER_4] = Location::WonderItem(RC_ZR_WONDER_LOWER_RIVER_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1288, 1052), "Wonder Lower River 4", RHT_WONDER_ITEM_ZORAS_RIVER, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_WONDER_LOWER_RIVER_4)); + locationTable[RC_ZF_WONDER_ROCK] = Location::WonderItem(RC_ZF_WONDER_ROCK, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-667, 1053), "Wonder Scarecrow Rock", RHT_WONDER_ITEM_ZORAS_FOUNTAIN, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_WONDER_ROCK)); + locationTable[RC_GV_WONDER_LOWER_WATERFALL] = Location::WonderItem(RC_GV_WONDER_LOWER_WATERFALL, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-45, -298), "Wonder Lower Waterfall", RHT_WONDER_ITEM_GERUDO_VALLEY, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_WONDER_LOWER_WATERFALL)); + locationTable[RC_GV_WONDER_UPPER_WATERFALL] = Location::WonderItem(RC_GV_WONDER_UPPER_WATERFALL, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(47, -2620), "Wonder Upper Waterfall", RHT_WONDER_ITEM_GERUDO_VALLEY, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_WONDER_UPPER_WATERFALL)); + locationTable[RC_GF_WONDER_ENTRANCE_SIGN] = Location::WonderItem(RC_GF_WONDER_ENTRANCE_SIGN, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-814, -810), "Wonder Entrance Sign", RHT_WONDER_ITEM_GERUDOS_FORTRESS, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_WONDER_ENTRANCE_SIGN)); + locationTable[RC_GF_WONDER_ARCHERY_SIGN] = Location::WonderItem(RC_GF_WONDER_ARCHERY_SIGN, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(1094, -412), "Wonder Archery Sign", RHT_WONDER_ITEM_GERUDOS_FORTRESS, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_WONDER_ARCHERY_SIGN)); + locationTable[RC_TH_WONDER_1_TORCH_1] = Location::WonderItem(RC_TH_WONDER_1_TORCH_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-305, -2633), "Wonder 1 Torch Outer Exit Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_1_TORCH_1)); + locationTable[RC_TH_WONDER_1_TORCH_2] = Location::WonderItem(RC_TH_WONDER_1_TORCH_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-307, -2200), "Wonder 1 Torch Inner Exit Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_1_TORCH_2)); + locationTable[RC_TH_WONDER_STEEP_SLOPE_LOWER_EXIT] = Location::WonderItem(RC_TH_WONDER_STEEP_SLOPE_LOWER_EXIT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(71, -928), "Wonder Steep Slope Lower Exit Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_STEEP_SLOPE_LOWER_EXIT)); + locationTable[RC_TH_WONDER_STEEP_SLOPE_UPPER_EXIT] = Location::WonderItem(RC_TH_WONDER_STEEP_SLOPE_UPPER_EXIT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(77, -1345), "Wonder Steep Slope Upper Exit Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_STEEP_SLOPE_UPPER_EXIT)); + locationTable[RC_TH_WONDER_DOUBLE_JAIL_LOWER_EXIT] = Location::WonderItem(RC_TH_WONDER_DOUBLE_JAIL_LOWER_EXIT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-65, 173), "Wonder Double Jail Lower Exit Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_DOUBLE_JAIL_LOWER_EXIT)); + locationTable[RC_TH_WONDER_DOUBLE_JAIL_UPPER_EXIT] = Location::WonderItem(RC_TH_WONDER_DOUBLE_JAIL_UPPER_EXIT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(709, 180), "Wonder Double Jail Upper Exit Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_DOUBLE_JAIL_UPPER_EXIT)); + locationTable[RC_TH_WONDER_KITCHEN_SKULL] = Location::WonderItem(RC_TH_WONDER_KITCHEN_SKULL, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1204, -610), "Wonder Kitchen Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_KITCHEN_SKULL)); + locationTable[RC_TH_WONDER_KITCHEN_SOUP] = Location::WonderItem(RC_TH_WONDER_KITCHEN_SOUP, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1940, -585), "Wonder Kitchen Soup", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_KITCHEN_SOUP)); + locationTable[RC_TH_WONDER_DEAD_END_SKULL_ENTRANCE] = Location::WonderItem(RC_TH_WONDER_DEAD_END_SKULL_ENTRANCE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1666, -2323), "Wonder Dead End Entrance Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_DEAD_END_SKULL_ENTRANCE)); + locationTable[RC_TH_WONDER_DEAD_END_SKULL_NEAR_JAIL] = Location::WonderItem(RC_TH_WONDER_DEAD_END_SKULL_NEAR_JAIL, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1378, -2829), "Wonder Dead End Near Jail Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_DEAD_END_SKULL_NEAR_JAIL)); + locationTable[RC_TH_WONDER_BREAK_ROOM_BOTTOM_SKULL] = Location::WonderItem(RC_TH_WONDER_BREAK_ROOM_BOTTOM_SKULL, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(820, -3511), "Wonder Break Room Bottom Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_BREAK_ROOM_BOTTOM_SKULL)); + locationTable[RC_TH_WONDER_BREAK_ROOM_TOP_SKULL] = Location::WonderItem(RC_TH_WONDER_BREAK_ROOM_TOP_SKULL, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(38, -3509), "Wonder Break Room Top Skull", RHT_WONDER_ITEM_THIEVES_HIDEOUT, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_WONDER_BREAK_ROOM_TOP_SKULL)); + locationTable[RC_COLOSSUS_WONDER_OASIS_TREE_1] = Location::WonderItem(RC_COLOSSUS_WONDER_OASIS_TREE_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(1161, 2383), "Wonder Oasis Tree 1", RHT_WONDER_ITEM_DESERT_COLOSSUS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_WONDER_OASIS_TREE_1)); + locationTable[RC_COLOSSUS_WONDER_OASIS_TREE_2] = Location::WonderItem(RC_COLOSSUS_WONDER_OASIS_TREE_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(1113, 2581), "Wonder Oasis Tree 2", RHT_WONDER_ITEM_DESERT_COLOSSUS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_WONDER_OASIS_TREE_2)); + locationTable[RC_COLOSSUS_WONDER_OASIS_CHILD_TREE] = Location::WonderItem(RC_COLOSSUS_WONDER_OASIS_CHILD_TREE, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(456, 2325), "Wonder Oasis Child Tree", RHT_WONDER_ITEM_DESERT_COLOSSUS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_WONDER_OASIS_CHILD_TREE)); + locationTable[RC_COLOSSUS_WONDER_GF_TREE_1] = Location::WonderItem(RC_COLOSSUS_WONDER_GF_TREE_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(2406, -1407), "Wonder Great Fairy Tree 1", RHT_WONDER_ITEM_DESERT_COLOSSUS, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_WONDER_GF_TREE_1)); + locationTable[RC_COLOSSUS_WONDER_GF_TREE_2] = Location::WonderItem(RC_COLOSSUS_WONDER_GF_TREE_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(2098, -1402), "Wonder Great Fairy Tree 2", RHT_WONDER_ITEM_DESERT_COLOSSUS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_WONDER_GF_TREE_2)); + // Dungeon Wonder Items + locationTable[RC_SHADOW_TEMPLE_WONDER_THREE_POTS] = Location::WonderItem(RC_SHADOW_TEMPLE_WONDER_THREE_POTS, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(12, 1), "Wonder Three Pots Sign", RHT_WONDER_ITEM_SHADOW_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WONDER_THREE_POTS)); + locationTable[RC_GERUDO_TRAINING_GROUND_WONDER_BEAMOS_ROOM] = Location::WonderItem(RC_GERUDO_TRAINING_GROUND_WONDER_BEAMOS_ROOM, RCQUEST_VANILLA, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(7, 12), "Wonder Beamos Sign", RHT_WONDER_ITEM_GERUDO_TRAINING_GROUND, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_WONDER_BEAMOS_ROOM)); + locationTable[RC_GERUDO_TRAINING_GROUND_WONDER_EYE_STATUE_ROOM] = Location::WonderItem(RC_GERUDO_TRAINING_GROUND_WONDER_EYE_STATUE_ROOM, RCQUEST_VANILLA, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(4, 2), "Wonder Top of Eye Statue", RHT_WONDER_ITEM_GERUDO_TRAINING_GROUND, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_WONDER_EYE_STATUE_ROOM)); + locationTable[RC_GERUDO_TRAINING_GROUND_WONDER_TORCH_SLUGS_ROOM] = Location::WonderItem(RC_GERUDO_TRAINING_GROUND_WONDER_TORCH_SLUGS_ROOM, RCQUEST_VANILLA, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(5, 16), "Wonder Torch Slug Sign", RHT_WONDER_ITEM_GERUDO_TRAINING_GROUND, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_WONDER_TORCH_SLUGS_ROOM)); + // MQ Dungeon Wonder Items + locationTable[RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_1] = Location::WonderItem(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_1, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(7, 12), "MQ Wonder Basement Grave 1", RHT_WONDER_ITEM_DEKU_TREE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_1)); + locationTable[RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_2] = Location::WonderItem(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_2, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(7, 11), "MQ Wonder Basement Grave 2", RHT_WONDER_ITEM_DEKU_TREE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_2)); + locationTable[RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_3] = Location::WonderItem(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_3, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(7, 10), "MQ Wonder Basement Grave 3", RHT_WONDER_ITEM_DEKU_TREE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_3)); + locationTable[RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_4] = Location::WonderItem(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_4, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(7, 9), "MQ Wonder Basement Grave 4", RHT_WONDER_ITEM_DEKU_TREE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_4)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_LEFT_COW] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_LEFT_COW, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(0, 13), "MQ Wonder Entrance Cow Left", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_LEFT_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_RIGHT_COW] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_RIGHT_COW, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(0, 14), "MQ Wonder Entrance Cow Right", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_RIGHT_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_ELEVATOR_COW] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_ELEVATOR_COW, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(1, 19), "MQ Wonder Elevator Cow", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ELEVATOR_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_COW] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_HOLES_COW, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(2, 13), "MQ Wonder Holes Cow", RHT_WONDER_ITEM_JABU_JABU, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(3, 15), "MQ Wonder Basement Right Cow 1", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(3, 13), "MQ Wonder Basement Right Cow 2", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(3, 14), "MQ Wonder Basement Right Cow 3", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(3, 18), "MQ Wonder Basement Left Cow 1", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(3, 16), "MQ Wonder Basement Left Cow 2", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(3, 17), "MQ Wonder Basement Left Cow 3", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_AFTER_BIG_OCTO] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_AFTER_BIG_OCTO, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(6, 7), "MQ Wonder After Big Octo Cow", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_AFTER_BIG_OCTO)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_JIGGLIES_COW] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_JIGGLIES_COW, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(4, 13), "MQ Wonder Jigglies Cow", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_JIGGLIES_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 21), "MQ Wonder Like Like Right Cow 1", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 20), "MQ Wonder Like Like Right Cow 2", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 19), "MQ Wonder Like Like Right Cow 3", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 24), "MQ Wonder Like Like Left Cow 1", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 23), "MQ Wonder Like Like Left Cow 2", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 22), "MQ Wonder Like Like Left Cow 3", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 29), "MQ Wonder Like Like Grass 1", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 28), "MQ Wonder Like Like Grass 2", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(11, 27), "MQ Wonder Like Like Grass 3", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_LEFT_COW] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_LEFT_COW, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(5, 10), "MQ Wonder Before Boss Left Cow", RHT_WONDER_ITEM_JABU_JABU, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_LEFT_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_1] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(5, 9), "MQ Wonder Before Boss Right Cow 1", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_2] = Location::WonderItem(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(5, 11), "MQ Wonder Before Boss Right Cow 2", RHT_WONDER_ITEM_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_2)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(4, 6), "MQ Wonder Shortcut Room 1", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(4, 7), "MQ Wonder Shortcut Room 2", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(4, 8), "MQ Wonder Shortcut Room 3", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(19, 9), "MQ Wonder Boss Key Room Hookshot", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(19, 10), "MQ Wonder Boss Key Room Bow", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_LIZALFOS_MAZE] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_LIZALFOS_MAZE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(5, 19), "MQ Wonder Lizalfos Maze", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_LIZALFOS_MAZE)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(7, 6), "MQ Wonder East Tower Large Face 1", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(7, 7), "MQ Wonder East Tower Large Face 2", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(7, 4), "MQ Wonder East Tower Small Face 1", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(7, 5), "MQ Wonder East Tower Small Face 2", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_TORCH_ROOM] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_TORCH_ROOM, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(16, 0), "MQ Wonder Torch Room", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_TORCH_ROOM)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(10, 42), "MQ Wonder Fire Maze", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_AFTER_FLARE_DANCER] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_AFTER_FLARE_DANCER, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(12, 0), "MQ Wonder After Flare Dancer", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_AFTER_FLARE_DANCER)); + locationTable[RC_FIRE_TEMPLE_MQ_WONDER_STAIRCASE] = Location::WonderItem(RC_FIRE_TEMPLE_MQ_WONDER_STAIRCASE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(14, 1), "MQ Wonder Hammer Staircase", RHT_WONDER_ITEM_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_WONDER_STAIRCASE)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(19, 5), "MQ Wonder Lizalfos Room", RHT_WONDER_ITEM_WATER_TEMPLE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(17, 7), "MQ Wonder Longshot Room", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(18, 3), "MQ Wonder Stalfos Room", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(5, 4), "MQ Wonder Hookshot Staircase Right 1", RHT_WONDER_ITEM_WATER_TEMPLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(5, 3), "MQ Wonder Hookshot Staircase Right 2", RHT_WONDER_ITEM_WATER_TEMPLE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(5, 2), "MQ Wonder Hookshot Staircase Right 3", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(5, 11), "MQ Wonder Hookshot Staircase Left 1", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(5, 10), "MQ Wonder Hookshot Staircase Left 2", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(5, 9), "MQ Wonder Hookshot Staircase Left 3", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_AFTER_DARK_LINK] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_AFTER_DARK_LINK, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(7, 0), "MQ Wonder After Dark Link", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_AFTER_DARK_LINK)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(8, 4), "MQ Wonder Dragon Room Left Eye", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(8, 6), "MQ Wonder Dragon Room Right Eye", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_PORTRAIT] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_PORTRAIT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(8, 5), "MQ Wonder Dragon Room Portrait", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_PORTRAIT)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_TRIPLE_TORCHES] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_TRIPLE_TORCHES, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(3, 3), "MQ Wonder Triple Torches Room", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_TRIPLE_TORCHES)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_1] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(15, 0), "MQ Wonder Water Sprouts 1", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_1)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(15, 1), "MQ Wonder Water Sprouts 2", RHT_WONDER_ITEM_WATER_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_FREESTANDING_ROOM] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_FREESTANDING_ROOM, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(16, 0), "MQ Wonder Freestanding Room", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_FREESTANDING_ROOM)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_1] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(11, 1), "MQ Wonder Before Boss 1", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_1)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_2] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(11, 0), "MQ Wonder Before Boss 2", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_2)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_UNDER_PILLAR_ROOM] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_UNDER_PILLAR_ROOM, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(2, 24), "MQ Wonder Under Pillar Room", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_UNDER_PILLAR_ROOM)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_HALLWAY] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_HALLWAY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(20, 2), "MQ Wonder Lizalfos Hallway", RHT_WONDER_ITEM_WATER_TEMPLE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_LIZALFOS_HALLWAY)); + locationTable[RC_WATER_TEMPLE_MQ_WONDER_GS_STORAGE_ROOM] = Location::WonderItem(RC_WATER_TEMPLE_MQ_WONDER_GS_STORAGE_ROOM, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(10, 1), "MQ Wonder GS Storage Room", RHT_WONDER_ITEM_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_WONDER_GS_STORAGE_ROOM)); + locationTable[RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER] = Location::WonderItem(RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(18, 8), "MQ Wonder Chest Hammer", RHT_WONDER_ITEM_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER)); + locationTable[RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH] = Location::WonderItem(RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(18, 9), "MQ Wonder Chest Sword", RHT_WONDER_ITEM_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH)); + locationTable[RC_SHADOW_TEMPLE_MQ_WONDER_THREE_POTS] = Location::WonderItem(RC_SHADOW_TEMPLE_MQ_WONDER_THREE_POTS, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(12, 1), "MQ Wonder Three Pots Sign", RHT_WONDER_ITEM_SHADOW_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_WONDER_THREE_POTS)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0, 5), "MQ Wonder Main Room West Sign 1", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0, 6), "MQ Wonder Main Room West Sign 2", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0, 8), "MQ Wonder Main Room West Sign 3", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0, 10), "MQ Wonder Main Room West Sign 4", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0, 12), "MQ Wonder Main Room East Sign 1", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0, 11), "MQ Wonder Main Room East Sign 2", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0, 9), "MQ Wonder Main Room East Sign 3", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0, 7), "MQ Wonder Main Room East Sign 4", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(5, 0), "MQ Wonder East Room Sign 1", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(5, 1), "MQ Wonder East Room Sign 2", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(5, 2), "MQ Wonder East Room Sign 3", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4] = Location::WonderItem(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(5, 3), "MQ Wonder East Room Sign 4", RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM] = Location::WonderItem(RC_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(7, 9), "MQ Wonder Dinolfos Sign", RHT_WONDER_ITEM_GERUDO_TRAINING_GROUND, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE] = Location::WonderItem(RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(4, 4), "MQ Wonder Top of Eye Statue", RHT_WONDER_ITEM_GERUDO_TRAINING_GROUND, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE)); + locationTable[RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL] = Location::WonderItem(RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(12, 12), "MQ Wonder Shadow Trial Bombflower", RHT_GANONS_CASTLE_WONDER_ITEM, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL)); + + // clang-format on +} + +static RegisterShipInitFunc registerShuffleWonderItems(RegisterShuffleWonderItems, { "IS_RANDO" }); +static RegisterShipInitFunc registerWonderItemLocations(Rando::StaticData::RegisterWonderItemLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/Traps.cpp b/soh/soh/Enhancements/randomizer/Traps.cpp index 050913a4a0..d6334ba3a7 100644 --- a/soh/soh/Enhancements/randomizer/Traps.cpp +++ b/soh/soh/Enhancements/randomizer/Traps.cpp @@ -2,7 +2,7 @@ #include "soh/Enhancements/randomizer/SeedContext.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/randomizer/static_data.h" -#include "soh/Enhancements/randomizer/3drando/random.hpp" +#include "soh/ShipUtils.h" #include @@ -1431,19 +1431,19 @@ Text Rando::Traps::GetTrapName(uint16_t id) { } // Randomly get the easy, medium, or hard name for the given item id - return RandomElement(trickNameTable[id]); + return ShipUtils::RandomElement(trickNameTable[id]); } RandomizerGet Rando::Traps::GetTrapTrickModel() { auto ctx = Rando::Context::GetInstance(); - RandomizerGet trickModel = RandomElementFromSet(ctx->possibleIceTrapModels); + RandomizerGet trickModel = ShipUtils::RandomElementFromSet(ctx->possibleIceTrapModels); if (trickModel == RG_EMPTY_BOTTLE) { - trickModel = RandomElement(Rando::StaticData::normalBottles); + trickModel = ShipUtils::RandomElement(Rando::StaticData::normalBottles); } else if (trickModel == RG_GUARD_HOUSE_KEY) { - trickModel = RandomElement(Rando::StaticData::overworldKeys); + trickModel = ShipUtils::RandomElement(Rando::StaticData::overworldKeys); } else if (trickModel == RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) { - trickModel = RandomElement(Rando::StaticData::beanSouls); + trickModel = ShipUtils::RandomElement(Rando::StaticData::beanSouls); } return trickModel; @@ -1456,7 +1456,8 @@ bool Rando::Traps::ShouldJunkItemBeTrap() { return false; } - if (ctx->GetOption(RSK_ICE_TRAP_PERCENT).Is(100) || Random(0, 100) < ctx->GetOption(RSK_ICE_TRAP_PERCENT).Get()) { + if (ctx->GetOption(RSK_ICE_TRAP_PERCENT).Is(100) || + ShipUtils::Random(0, 100) < ctx->GetOption(RSK_ICE_TRAP_PERCENT).Get()) { return true; } diff --git a/soh/soh/Enhancements/randomizer/Traps.h b/soh/soh/Enhancements/randomizer/Traps.h index d8f29093dd..cf8f8905ce 100644 --- a/soh/soh/Enhancements/randomizer/Traps.h +++ b/soh/soh/Enhancements/randomizer/Traps.h @@ -6,7 +6,7 @@ #include "soh/Enhancements/custom-message/CustomMessageManager.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" -#include "soh/Enhancements/randomizer/3drando/text.hpp" +#include "soh/Enhancements/custom-message/text.h" #include "libultraship/libultra/types.h" namespace Rando { diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index f16ae7440c..db5f2294bf 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -5,6 +5,7 @@ #include "soh_assets.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "z64.h" @@ -86,7 +87,7 @@ Color_RGB8 MapOrCompassColor[10] = { extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry) { - s8 isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 1); + bool isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 1); int slot = getItemEntry->drawItemId - RG_FOREST_TEMPLE_SMALL_KEY; Gfx* customIconDLs[] = { @@ -171,7 +172,7 @@ extern "C" void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEnt } extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry) { - s8 isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 1); + bool isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 1); s16 slot = getItemEntry->drawItemId - RG_FOREST_TEMPLE_BOSS_KEY; std::string CvarValue[6] = { @@ -235,7 +236,7 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt } extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry) { - s8 isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 1); + bool isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 1); int slot = getItemEntry->drawItemId - RG_FOREST_TEMPLE_KEY_RING; Gfx* CustomIconDLs[] = { diff --git a/soh/soh/Enhancements/randomizer/dungeon.cpp b/soh/soh/Enhancements/randomizer/dungeon.cpp index cf37b5f39d..6cb077c630 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/dungeon.cpp @@ -7,14 +7,16 @@ namespace Rando { DungeonInfo::DungeonInfo(std::string name_, const RandomizerHintTextKey hintKey_, const RandomizerGet map_, const RandomizerGet compass_, const RandomizerGet smallKey_, const RandomizerGet keyRing_, - const RandomizerGet bossKey_, RandomizerArea area_, const uint8_t vanillaKeyCount_, - const uint8_t mqKeyCount_, const RandomizerSettingKey mqSetting_) + const RandomizerGet bossKey_, RandomizerGet reward_, RandomizerArea area_, + const uint8_t vanillaKeyCount_, const uint8_t mqKeyCount_, + const RandomizerSettingKey mqSetting_) : name(std::move(name_)), hintKey(hintKey_), map(map_), compass(compass_), smallKey(smallKey_), keyRing(keyRing_), - bossKey(bossKey_), area(area_), vanillaKeyCount(vanillaKeyCount_), mqKeyCount(mqKeyCount_), + bossKey(bossKey_), reward(reward_), area(area_), vanillaKeyCount(vanillaKeyCount_), mqKeyCount(mqKeyCount_), mqSetting(mqSetting_) { } DungeonInfo::DungeonInfo() - : hintKey(RHT_NONE), map(RG_NONE), compass(RG_NONE), smallKey(RG_NONE), keyRing(RG_NONE), bossKey(RG_NONE) { + : hintKey(RHT_NONE), map(RG_NONE), compass(RG_NONE), smallKey(RG_NONE), keyRing(RG_NONE), bossKey(RG_NONE), + reward(RG_NONE) { } DungeonInfo::~DungeonInfo() = default; @@ -82,6 +84,10 @@ RandomizerGet DungeonInfo::GetBossKey() const { return bossKey; } +RandomizerGet DungeonInfo::GetReward() const { + return reward; +} + RandomizerSettingKey DungeonInfo::GetMQSetting() const { return mqSetting; } @@ -147,40 +153,44 @@ std::vector DungeonInfo::GetDungeonLocations() const { Dungeons::Dungeons() { dungeonList[DEKU_TREE] = DungeonInfo("Deku Tree", RHT_DEKU_TREE, RG_DEKU_TREE_MAP, RG_DEKU_TREE_COMPASS, RG_NONE, - RG_NONE, RG_NONE, RA_DEKU_TREE, 0, 0, RSK_MQ_DEKU_TREE); + RG_NONE, RG_NONE, RG_KOKIRI_EMERALD, RA_DEKU_TREE, 0, 0, RSK_MQ_DEKU_TREE); dungeonList[DODONGOS_CAVERN] = DungeonInfo("Dodongo's Cavern", RHT_DODONGOS_CAVERN, RG_DODONGOS_CAVERN_MAP, RG_DODONGOS_CAVERN_COMPASS, - RG_NONE, RG_NONE, RG_NONE, RA_DODONGOS_CAVERN, 0, 0, RSK_MQ_DODONGOS_CAVERN); + RG_NONE, RG_NONE, RG_NONE, RG_GORON_RUBY, RA_DODONGOS_CAVERN, 0, 0, RSK_MQ_DODONGOS_CAVERN); dungeonList[JABU_JABUS_BELLY] = DungeonInfo("Jabu Jabu's Belly", RHT_JABU_JABUS_BELLY, RG_JABU_JABUS_BELLY_MAP, RG_JABU_JABUS_BELLY_COMPASS, - RG_NONE, RG_NONE, RG_NONE, RA_JABU_JABUS_BELLY, 0, 0, RSK_MQ_JABU_JABU); - dungeonList[FOREST_TEMPLE] = DungeonInfo( - "Forest Temple", RHT_FOREST_TEMPLE, RG_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_COMPASS, RG_FOREST_TEMPLE_SMALL_KEY, - RG_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_BOSS_KEY, RA_FOREST_TEMPLE, 5, 6, RSK_MQ_FOREST_TEMPLE); + RG_NONE, RG_NONE, RG_NONE, RG_ZORA_SAPPHIRE, RA_JABU_JABUS_BELLY, 0, 0, RSK_MQ_JABU_JABU); + dungeonList[FOREST_TEMPLE] = + DungeonInfo("Forest Temple", RHT_FOREST_TEMPLE, RG_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_COMPASS, + RG_FOREST_TEMPLE_SMALL_KEY, RG_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_BOSS_KEY, + RG_FOREST_MEDALLION, RA_FOREST_TEMPLE, 5, 6, RSK_MQ_FOREST_TEMPLE); dungeonList[FIRE_TEMPLE] = DungeonInfo("Fire Temple", RHT_FIRE_TEMPLE, RG_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_COMPASS, RG_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_BOSS_KEY, - RA_FIRE_TEMPLE, 8, 5, RSK_MQ_FIRE_TEMPLE); - dungeonList[WATER_TEMPLE] = DungeonInfo( - "Water Temple", RHT_WATER_TEMPLE, RG_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_COMPASS, RG_WATER_TEMPLE_SMALL_KEY, - RG_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_BOSS_KEY, RA_WATER_TEMPLE, 6, 2, RSK_MQ_WATER_TEMPLE); - dungeonList[SPIRIT_TEMPLE] = DungeonInfo( - "Spirit Temple", RHT_SPIRIT_TEMPLE, RG_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_COMPASS, RG_SPIRIT_TEMPLE_SMALL_KEY, - RG_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_BOSS_KEY, RA_SPIRIT_TEMPLE, 5, 7, RSK_MQ_SPIRIT_TEMPLE); - dungeonList[SHADOW_TEMPLE] = DungeonInfo( - "Shadow Temple", RHT_SHADOW_TEMPLE, RG_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_COMPASS, RG_SHADOW_TEMPLE_SMALL_KEY, - RG_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_BOSS_KEY, RA_SHADOW_TEMPLE, 5, 6, RSK_MQ_SHADOW_TEMPLE); + RG_FIRE_MEDALLION, RA_FIRE_TEMPLE, 8, 5, RSK_MQ_FIRE_TEMPLE); + dungeonList[WATER_TEMPLE] = + DungeonInfo("Water Temple", RHT_WATER_TEMPLE, RG_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_COMPASS, + RG_WATER_TEMPLE_SMALL_KEY, RG_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_BOSS_KEY, RG_WATER_MEDALLION, + RA_WATER_TEMPLE, 6, 2, RSK_MQ_WATER_TEMPLE); + dungeonList[SPIRIT_TEMPLE] = + DungeonInfo("Spirit Temple", RHT_SPIRIT_TEMPLE, RG_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_COMPASS, + RG_SPIRIT_TEMPLE_SMALL_KEY, RG_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_BOSS_KEY, + RG_SPIRIT_MEDALLION, RA_SPIRIT_TEMPLE, 5, 7, RSK_MQ_SPIRIT_TEMPLE); + dungeonList[SHADOW_TEMPLE] = + DungeonInfo("Shadow Temple", RHT_SHADOW_TEMPLE, RG_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_COMPASS, + RG_SHADOW_TEMPLE_SMALL_KEY, RG_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_BOSS_KEY, + RG_SHADOW_MEDALLION, RA_SHADOW_TEMPLE, 5, 6, RSK_MQ_SHADOW_TEMPLE); dungeonList[BOTTOM_OF_THE_WELL] = DungeonInfo("Bottom of the Well", RHT_BOTTOM_OF_THE_WELL, RG_BOTTOM_OF_THE_WELL_MAP, RG_BOTTOM_OF_THE_WELL_COMPASS, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_KEY_RING, - RG_NONE, RA_BOTTOM_OF_THE_WELL, 3, 2, RSK_MQ_BOTTOM_OF_THE_WELL); + RG_NONE, RG_NONE, RA_BOTTOM_OF_THE_WELL, 3, 2, RSK_MQ_BOTTOM_OF_THE_WELL); dungeonList[ICE_CAVERN] = DungeonInfo("Ice Cavern", RHT_ICE_CAVERN, RG_ICE_CAVERN_MAP, RG_ICE_CAVERN_COMPASS, - RG_NONE, RG_NONE, RG_NONE, RA_ICE_CAVERN, 0, 0, RSK_MQ_ICE_CAVERN); + RG_NONE, RG_NONE, RG_NONE, RG_NONE, RA_ICE_CAVERN, 0, 0, RSK_MQ_ICE_CAVERN); dungeonList[GERUDO_TRAINING_GROUND] = DungeonInfo( "Gerudo Training Ground", RHT_GERUDO_TRAINING_GROUND, RG_NONE, RG_NONE, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, - RG_GERUDO_TRAINING_GROUND_KEY_RING, RG_NONE, RA_GERUDO_TRAINING_GROUND, 9, 3, RSK_MQ_GTG); - dungeonList[GANONS_CASTLE] = - DungeonInfo("Ganon's Castle", RHT_GANONS_CASTLE, RG_NONE, RG_NONE, RG_GANONS_CASTLE_SMALL_KEY, - RG_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_BOSS_KEY, RA_GANONS_CASTLE, 2, 3, RSK_MQ_GANONS_CASTLE); + RG_GERUDO_TRAINING_GROUND_KEY_RING, RG_NONE, RG_NONE, RA_GERUDO_TRAINING_GROUND, 9, 3, RSK_MQ_GTG); + dungeonList[GANONS_CASTLE] = DungeonInfo( + "Ganon's Castle", RHT_GANONS_CASTLE, RG_NONE, RG_NONE, RG_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_KEY_RING, + RG_GANONS_CASTLE_BOSS_KEY, RG_NONE, RA_GANONS_CASTLE, 2, 3, RSK_MQ_GANONS_CASTLE); } Dungeons::~Dungeons() = default; diff --git a/soh/soh/Enhancements/randomizer/dungeon.h b/soh/soh/Enhancements/randomizer/dungeon.h index ba81d289d6..8685f913ee 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.h +++ b/soh/soh/Enhancements/randomizer/dungeon.h @@ -11,8 +11,8 @@ namespace Rando { class DungeonInfo { public: DungeonInfo(std::string name_, RandomizerHintTextKey hintKey_, RandomizerGet map_, RandomizerGet compass_, - RandomizerGet smallKey_, RandomizerGet keyRing_, RandomizerGet bossKey_, RandomizerArea area_, - uint8_t vanillaKeyCount_, uint8_t mqKeyCount_, RandomizerSettingKey mqSetting_); + RandomizerGet smallKey_, RandomizerGet keyRing_, RandomizerGet bossKey_, RandomizerGet reward_, + RandomizerArea area_, uint8_t vanillaKeyCount_, uint8_t mqKeyCount_, RandomizerSettingKey mqSetting_); DungeonInfo(); ~DungeonInfo(); @@ -32,6 +32,7 @@ class DungeonInfo { RandomizerGet GetMap() const; RandomizerGet GetCompass() const; RandomizerGet GetBossKey() const; + RandomizerGet GetReward() const; RandomizerSettingKey GetMQSetting() const; void SetDungeonKnown(bool known); void PlaceVanillaMap() const; @@ -50,6 +51,7 @@ class DungeonInfo { RandomizerGet smallKey; RandomizerGet keyRing; RandomizerGet bossKey; + RandomizerGet reward; RandomizerSettingKey mqSetting; bool isDungeonModeKnown = true; uint8_t vanillaKeyCount{}; @@ -94,4 +96,4 @@ class Dungeons { private: std::array dungeonList; }; -} // namespace Rando \ No newline at end of file +} // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 9af7ddba71..47aacb76bb 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -3,6 +3,7 @@ #include "3drando/fill.hpp" #include "3drando/pool_functions.hpp" #include "3drando/item_pool.hpp" +#include "3drando/random.hpp" #include "../debugger/performanceTimer.h" #include "soh/Enhancements/gameconsole.h" #include "z64camera.h" @@ -397,8 +398,8 @@ void SetAllEntrancesData() { { EntranceType::ThievesHideout, RR_TH_KITCHEN_OPPOSITE_CORRIDOR, RR_GF_NEAR_GS, ENTR_GERUDOS_FORTRESS_10 } }, { { EntranceType::ThievesHideout, RR_GF_BELOW_CHEST, RR_TH_BREAK_ROOM, ENTR_THIEVES_HIDEOUT_10 }, { EntranceType::ThievesHideout, RR_TH_BREAK_ROOM, RR_GF_BELOW_CHEST, ENTR_GERUDOS_FORTRESS_11 } }, - { { EntranceType::ThievesHideout, RR_GF_ABOVE_JAIL, RR_TH_BREAK_ROOM_CORRIDOR, ENTR_THIEVES_HIDEOUT_11 }, - { EntranceType::ThievesHideout, RR_TH_BREAK_ROOM_CORRIDOR, RR_GF_ABOVE_JAIL, ENTR_GERUDOS_FORTRESS_12 } }, + { { EntranceType::ThievesHideout, RR_GF_ABOVE_JAIL, RR_TH_BREAK_ROOM_UPPER_CORRIDOR, ENTR_THIEVES_HIDEOUT_11 }, + { EntranceType::ThievesHideout, RR_TH_BREAK_ROOM_UPPER_CORRIDOR, RR_GF_ABOVE_JAIL, ENTR_GERUDOS_FORTRESS_12 } }, { { EntranceType::ThievesHideout, RR_GF_BELOW_GS, RR_TH_DEAD_END_CELL, ENTR_THIEVES_HIDEOUT_12 }, { EntranceType::ThievesHideout, RR_TH_DEAD_END_CELL, RR_GF_BELOW_GS, ENTR_GERUDOS_FORTRESS_13 } }, @@ -655,7 +656,7 @@ BuildOneWayTargets(std::vector typesToInclude, AddElementsToPool(oneWayEntrances, GetShuffleableEntrances(poolType, false)); } // Filter out any that are passed in the exclusion list - FilterAndEraseFromPool(oneWayEntrances, [&exclude](Entrance* entrance) { + std::erase_if(oneWayEntrances, [&exclude](Entrance* entrance) { std::pair entranceBeingChecked(entrance->GetParentRegionKey(), entrance->GetConnectedRegionKey()); return ElementInContainer(entranceBeingChecked, exclude); @@ -1333,7 +1334,7 @@ int EntranceShuffler::ShuffleAllEntrances() { GetShuffleableEntrances(EntranceType::Overworld, excludeOverworldReverse); // Only shuffle GV Lower Stream -> Lake Hylia if decoupled entrances are on if (!ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) { - FilterAndEraseFromPool(entrancePools[EntranceType::Overworld], [](const Entrance* entrance) { + std::erase_if(entrancePools[EntranceType::Overworld], [](const Entrance* entrance) { return entrance->GetParentRegionKey() == RR_GV_LOWER_STREAM && entrance->GetConnectedRegionKey() == RR_LAKE_HYLIA; }); diff --git a/soh/soh/Enhancements/randomizer/fishsanity.cpp b/soh/soh/Enhancements/randomizer/fishsanity.cpp index fd7dffc19a..7daf3a0ebd 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.cpp +++ b/soh/soh/Enhancements/randomizer/fishsanity.cpp @@ -6,6 +6,9 @@ #include "functions.h" #include "macros.h" #include +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "src/overlays/actors/ovl_Fishing/z_fishing.h" @@ -54,6 +57,28 @@ Color_RGB8 fsPulseColor = { 30, 240, 200 }; static s16 fishGroupCounter = 0; static bool enableAdvance = false; +static CheckIdentity IdentifyFish(s32 sceneNum, s32 actorParams) { + CheckIdentity fishIdentity; + + fishIdentity.randomizerInf = RAND_INF_MAX; + fishIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + // Fishsanity will determine what the identity of the fish should be + if (sceneNum == SCENE_FISHING_POND) { + return OTRGlobals::Instance->gRandoContext->GetFishsanity()->IdentifyPondFish(actorParams); + } + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_FISH, sceneNum, actorParams); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + fishIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + fishIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return fishIdentity; +} + namespace Rando { const CheckIdentity Fishsanity::defaultIdentity = { RAND_INF_MAX, RC_UNKNOWN_CHECK }; bool Fishsanity::fishsanityHelpersInit = false; @@ -133,9 +158,8 @@ Fishsanity::GetFishingPondLocations(FishsanityOptionsSource optionsSource) { } // NOTE: This only works because we can assume activeFish is already sorted; changes that break this assumption will // also break this - FilterAndEraseFromPool(remainingFish, [&](RandomizerCheck loc) { - return std::binary_search(activeFish.begin(), activeFish.end(), loc); - }); + std::erase_if(remainingFish, + [&](RandomizerCheck loc) { return std::binary_search(activeFish.begin(), activeFish.end(), loc); }); return std::make_pair(activeFish, remainingFish); } @@ -365,7 +389,7 @@ void Fishsanity::OnActorInitHandler(void* refActor) { actor->params = 0x100 | gSaveContext.respawn[RESPAWN_MODE_RETURN].data; } - fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + fish = IdentifyFish(gPlayState->sceneNum, actor->params); // Render fish as randomized item if (Rando::Fishsanity::IsFish(&fish) && !Flags_GetRandomizerInf(fish.randomizerInf)) { if (!drawEnFish) { @@ -382,7 +406,7 @@ void Fishsanity::OnActorInitHandler(void* refActor) { // Initialize fishsanity metadata on this actor Fishing* fishActor = static_cast(refActor); // fishActor->fishsanityParams = actor->params; - fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + fish = IdentifyFish(gPlayState->sceneNum, actor->params); // With every pond fish shuffled, caught fish will not spawn unless all fish have been caught. if (RAND_GET_OPTION(RSK_FISHSANITY_POND_COUNT).Get() > 16 && !fs->GetPondCleared()) { @@ -413,8 +437,7 @@ void Fishsanity::OnActorUpdateHandler(void* refActor) { // State 6 -> Fish caught and hoisted if (fish->fishState == 6) { - CheckIdentity identity = - OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + CheckIdentity identity = IdentifyFish(gPlayState->sceneNum, actor->params); if (identity.randomizerCheck != RC_UNKNOWN_CHECK) { Flags_SetRandomizerInf(identity.randomizerInf); enableAdvance = true; @@ -428,7 +451,7 @@ void Fishsanity::OnActorUpdateHandler(void* refActor) { } if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { - CheckIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + CheckIdentity fish = IdentifyFish(gPlayState->sceneNum, actor->params); EnFish* fishActor = static_cast(refActor); if (Rando::Fishsanity::IsFish(&fish) && Flags_GetRandomizerInf(fish.randomizerInf)) { // Reset draw method @@ -505,7 +528,7 @@ void Fishsanity_DrawEffShadow(Actor* actor, Lights* lights, PlayState* play) { } void Fishsanity_DrawEnFish(struct Actor* actor, struct PlayState* play) { - CheckIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(play->sceneNum, actor->params); + CheckIdentity fish = IdentifyFish(play->sceneNum, actor->params); GetItemEntry randoItem = Rando::Context::GetInstance()->GetFinalGIEntry(fish.randomizerCheck, true, GI_FISH); if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { randoItem = GET_ITEM_MYSTERY; @@ -565,7 +588,7 @@ void RegisterShuffleFish() { Actor* actor = va_arg(args, Actor*); auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { - auto fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + auto fish = IdentifyFish(gPlayState->sceneNum, actor->params); if (fish.randomizerCheck != RC_UNKNOWN_CHECK && !Flags_GetRandomizerInf(fish.randomizerInf)) { Flags_SetRandomizerInf(fish.randomizerInf); actor->parent = &GET_PLAYER(gPlayState)->actor; diff --git a/soh/soh/Enhancements/randomizer/fishsanity.h b/soh/soh/Enhancements/randomizer/fishsanity.h index 3105521bab..88538badb9 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.h +++ b/soh/soh/Enhancements/randomizer/fishsanity.h @@ -25,6 +25,8 @@ typedef enum { } FishsanityCheckType; #ifdef __cplusplus +#include "soh/Enhancements/randomizer/location.h" + namespace Rando { /** @@ -80,7 +82,7 @@ class Fishsanity { /** * @brief Returns the identity for a caught pond fish given its params. - * Not for use externally from rando, use Randomizer::IdentifyFish + * Not for use externally from rando * * @param fishParams Actor parameters for the fish to identify */ diff --git a/soh/soh/Enhancements/randomizer/hint.cpp b/soh/soh/Enhancements/randomizer/hint.cpp index 47c7b46d9a..a5954e9e02 100644 --- a/soh/soh/Enhancements/randomizer/hint.cpp +++ b/soh/soh/Enhancements/randomizer/hint.cpp @@ -4,6 +4,7 @@ #include "SeedContext.h" #include #include "static_data.h" +#include "3drando/random.hpp" namespace Rando { Hint::Hint() { diff --git a/soh/soh/Enhancements/randomizer/hint.h b/soh/soh/Enhancements/randomizer/hint.h index 7ff46a104a..3c820bcdb9 100644 --- a/soh/soh/Enhancements/randomizer/hint.h +++ b/soh/soh/Enhancements/randomizer/hint.h @@ -1,6 +1,6 @@ #pragma once -#include "3drando/text.hpp" +#include "soh/Enhancements/custom-message/text.h" #include "3drando/hints.hpp" #include "../custom-message/CustomMessageManager.h" #include "randomizerTypes.h" diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 9ac629fe8f..865d149c2f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -14,6 +14,8 @@ #include "soh/ShipInit.hpp" #include "soh/ObjectExtension/ObjectExtension.h" #include "item_category_adj.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "macros.h" @@ -57,6 +59,7 @@ extern "C" { #include "src/overlays/actors/ovl_Fishing/z_fishing.h" #include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h" #include "src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h" +#include "src/overlays/actors/ovl_En_GirlA/z_en_girla.h" #include "draw.h" static ObjectExtension::Register RegisterDnsItemEntryOverride; @@ -443,6 +446,23 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { randomizerQueuedItemEntry = GET_ITEM_NONE; } + if (receivedItemEntry.modIndex == MOD_NONE) { + switch (receivedItemEntry.itemId) { + case ITEM_SHIELD_DEKU: + Flags_SetRandomizerInf(RAND_INF_HAS_FOUND_DEKU_SHIELD); + break; + case ITEM_SHIELD_HYLIAN: + Flags_SetRandomizerInf(RAND_INF_HAS_FOUND_HYLIAN_SHIELD); + break; + case ITEM_TUNIC_GORON: + Flags_SetRandomizerInf(RAND_INF_HAS_FOUND_GORON_TUNIC); + break; + case ITEM_TUNIC_ZORA: + Flags_SetRandomizerInf(RAND_INF_HAS_FOUND_ZORA_TUNIC); + break; + } + } + if (receivedItemEntry.modIndex == MOD_RANDOMIZER && receivedItemEntry.getItemId == RG_MAGIC_BEAN_PACK) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_PLANTING_BEANS)) { gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_CRATER].swch |= (1 << 3); @@ -898,6 +918,46 @@ void RandomizerOnDialogMessageHandler() { extern "C" void func_80A5475C(EnHeishi2* CastleGuard, PlayState* play); +static ScrubIdentity IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respawnData) { + struct ScrubIdentity scrubIdentity; + + scrubIdentity.identity.randomizerInf = RAND_INF_MAX; + scrubIdentity.identity.randomizerCheck = RC_UNKNOWN_CHECK; + scrubIdentity.getItemId = GI_NONE; + scrubIdentity.itemPrice = -1; + + // Scrubs that are 0x06 are loaded as 0x03 when child, switching from selling arrows to seeds + if (actorParams == 0x06) + actorParams = 0x03; + + if (sceneNum == SCENE_GROTTOS) { + actorParams = TWO_ACTOR_PARAMS(actorParams, respawnData); + } + + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_DNS, sceneNum, actorParams); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + if (location->GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO || + location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || + location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE) { + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) { + return scrubIdentity; + } + } else if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_ALL) { + return scrubIdentity; + } + + scrubIdentity.identity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + scrubIdentity.identity.randomizerCheck = location->GetRandomizerCheck(); + scrubIdentity.getItemId = (GetItemID)Rando::StaticData::RetrieveItem(location->GetVanillaItem()).GetItemID(); + scrubIdentity.itemPrice = + OTRGlobals::Instance->gRandoContext->GetItemLocation(scrubIdentity.identity.randomizerCheck)->GetPrice(); + } + + return scrubIdentity; +} + void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { va_list args; va_copy(args, originalArgs); @@ -917,6 +977,18 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_CRAWL: *should = *should && Flags_GetRandomizerInf(RAND_INF_CAN_CRAWL); break; + case VB_CAN_BUY_SHOP_SHIELD_OR_TUNIC: { + // Gate non-randomized shop shields/tunics behind finding a non-shop copy. + if (RAND_GET_OPTION(RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL).Is(RO_GENERIC_ON)) { + EnGirlACanBuyResult* canBuy = va_arg(args, EnGirlACanBuyResult*); + RandomizerInf requiredInf = (RandomizerInf)va_arg(args, int); + if (!Flags_GetRandomizerInf(requiredInf)) { + *canBuy = CANBUY_RESULT_CANT_GET_NOW; + *should = true; + } + } + break; + } case VB_ALLOW_ENTRANCE_CS_FOR_EITHER_AGE: { s32 entranceIndex = va_arg(args, s32); @@ -1476,8 +1548,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_BUSINESS_SCRUB_DESPAWN: { EnShopnuts* enShopnuts = va_arg(args, EnShopnuts*); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - ScrubIdentity scrubIdentity = OTRGlobals::Instance->gRandomizer->IdentifyScrub( - gPlayState->sceneNum, enShopnuts->actor.params, respawnData); + ScrubIdentity scrubIdentity = IdentifyScrub(gPlayState->sceneNum, enShopnuts->actor.params, respawnData); if (scrubIdentity.identity.randomizerCheck != RC_UNKNOWN_CHECK) { *should = Flags_GetRandomizerInf(scrubIdentity.identity.randomizerInf); @@ -1658,7 +1729,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l Flags_SetInfTable(INFTABLE_191); gSaveContext.dogParams = 0; gSaveContext.dogIsLost = false; - enHy->actionFunc = func_80A7127C; + enHy->actionFunc = EnHy_Fidget; *should = false; break; } @@ -2153,8 +2224,7 @@ void RandomizerOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_EN_DNS) { EnDns* enDns = static_cast(actorRef); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - auto scrubIdentity = - OTRGlobals::Instance->gRandomizer->IdentifyScrub(gPlayState->sceneNum, enDns->actor.params, respawnData); + auto scrubIdentity = IdentifyScrub(gPlayState->sceneNum, enDns->actor.params, respawnData); if (scrubIdentity.identity.randomizerCheck != RC_UNKNOWN_CHECK) { // DNS uses pointers so we're creating our own entry instead of modifying the original @@ -2535,7 +2605,7 @@ void RandomizerOnActorUpdateHandler(void* refActor) { } else if (actor->id == ACTOR_DOOR_SHUTTER) { DoorShutter* shutterDoor = reinterpret_cast(actor); if (shutterDoor->doorType == SHUTTER_KEY_LOCKED) { - shutterDoor->unk_16E = 0; + shutterDoor->unlockTimer = 0; } } else if (actor->id == ACTOR_DOOR_GERUDO) { DoorGerudo* gerudoDoor = reinterpret_cast(actor); diff --git a/soh/soh/Enhancements/randomizer/item.cpp b/soh/soh/Enhancements/randomizer/item.cpp index e784612f7c..14a35a8d29 100644 --- a/soh/soh/Enhancements/randomizer/item.cpp +++ b/soh/soh/Enhancements/randomizer/item.cpp @@ -9,6 +9,7 @@ #include "macros.h" #include "functions.h" #include "../../OTRGlobals.h" +#include "soh/Enhancements/randomizer/randomizer.h" namespace Rando { Item::Item() @@ -77,6 +78,12 @@ const std::string& Item::GetColor() const { } bool Item::IsAdvancement() const { + // With the shop shield/tunic gate on, a found Deku/Hylian Shield unlocks its shop copy, so it must + // be treated as progression. Tunics already are. + if (!advancement && (randomizerGet == RG_DEKU_SHIELD || randomizerGet == RG_HYLIAN_SHIELD) && + Context::GetInstance()->GetOption(RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL).Is(RO_GENERIC_ON)) { + return true; + } return advancement; } @@ -477,6 +484,23 @@ bool Item::IsMajorItem() const { return IsAdvancement(); } +bool Item::IsShieldOrTunic() const { + switch (randomizerGet) { + case RG_DEKU_SHIELD: + case RG_HYLIAN_SHIELD: + case RG_MIRROR_SHIELD: + case RG_GORON_TUNIC: + case RG_ZORA_TUNIC: + case RG_BUY_DEKU_SHIELD: + case RG_BUY_HYLIAN_SHIELD: + case RG_BUY_GORON_TUNIC: + case RG_BUY_ZORA_TUNIC: + return true; + default: + return false; + } +} + RandomizerHintTextKey Item::GetHintKey() const { return hintKey; } diff --git a/soh/soh/Enhancements/randomizer/item.h b/soh/soh/Enhancements/randomizer/item.h index f484159102..a0c7b68e4f 100644 --- a/soh/soh/Enhancements/randomizer/item.h +++ b/soh/soh/Enhancements/randomizer/item.h @@ -3,7 +3,7 @@ #include #include -#include "3drando/text.hpp" +#include "soh/Enhancements/custom-message/text.h" #include "randomizerTypes.h" #include "soh/Enhancements/item-tables/ItemTableTypes.h" #include "3drando/hints.hpp" @@ -59,6 +59,7 @@ class Item { bool IsPlaythrough() const; bool IsBottleItem() const; bool IsMajorItem() const; + bool IsShieldOrTunic() const; RandomizerHintTextKey GetHintKey() const; const HintText& GetHint() const; GetItemCategory GetCategory(); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 8772176061..e28d3057a6 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -18,252 +18,252 @@ void Rando::StaticData::InitItemTable() { // clang-format off itemTable[RG_NONE] = Item(RG_NONE, Text{ "No Item", "Rien", "Kein Artikel" }, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_NONE, ITEM_NONE, 0, 0, 0, 0, 0, ITEM_CATEGORY_JUNK, MOD_NONE); // Randomizer Get Randomizer Get Name Text Type Get Item ID Adv. Logic Value Hint Text Key Item ID Object ID Draw ID Text ID field Chest Animation Item Category Mod Index - itemTable[RG_KOKIRI_SWORD] = Item(RG_KOKIRI_SWORD, Text{ "Kokiri Sword", "Épée Kokiri", "Kokiri-Schwert" }, ITEMTYPE_EQUIP, GI_SWORD_KOKIRI, true, LOGIC_KOKIRI_SWORD, RHT_KOKIRI_SWORD, ITEM_SWORD_KOKIRI, OBJECT_GI_SWORD_1, GID_SWORD_KOKIRI, 0xA4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}); - itemTable[RG_MASTER_SWORD] = Item(RG_MASTER_SWORD, Text{ "Master Sword", "Épée de Legende", "Master-Schwert"}, ITEMTYPE_EQUIP, 0xE0, true, LOGIC_MASTER_SWORD, RHT_MASTER_SWORD, ITEM_SWORD_MASTER, OBJECT_TOKI_OBJECTS, GID_SWORD_BGS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "das ", "le "}); + itemTable[RG_KOKIRI_SWORD] = Item(RG_KOKIRI_SWORD, Text{ "Kokiri Sword", "Épée Kokiri", "Kokiri-Schwert" }, ITEMTYPE_EQUIP, GI_SWORD_KOKIRI, true, LOGIC_KOKIRI_SWORD, RHT_KOKIRI_SWORD, ITEM_SWORD_KOKIRI, OBJECT_GI_SWORD_1, GID_SWORD_KOKIRI, 0xA4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "l'", "das "}); + itemTable[RG_MASTER_SWORD] = Item(RG_MASTER_SWORD, Text{ "Master Sword", "Épée de Legende", "Master-Schwert"}, ITEMTYPE_EQUIP, 0xE0, true, LOGIC_MASTER_SWORD, RHT_MASTER_SWORD, ITEM_SWORD_MASTER, OBJECT_TOKI_OBJECTS, GID_SWORD_BGS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "l'", "das "}); itemTable[RG_MASTER_SWORD].SetCustomDrawFunc(Randomizer_DrawMasterSword); - itemTable[RG_GIANTS_KNIFE] = Item(RG_GIANTS_KNIFE, Text{ "Giant's Knife", "Lame des Géants", "Langschwert" }, ITEMTYPE_EQUIP, GI_SWORD_KNIFE, true, LOGIC_NONE, RHT_GIANTS_KNIFE, ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x4B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}); + itemTable[RG_GIANTS_KNIFE] = Item(RG_GIANTS_KNIFE, Text{ "Giant's Knife", "Lame des Géants", "Langschwert" }, ITEMTYPE_EQUIP, GI_SWORD_KNIFE, true, LOGIC_NONE, RHT_GIANTS_KNIFE, ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x4B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "la ", "das "}); itemTable[RG_BIGGORON_SWORD] = Item(RG_BIGGORON_SWORD, Text{ "Biggoron's Sword", "Épée de Biggoron", "Biggoron-Schwert" }, ITEMTYPE_EQUIP, GI_SWORD_BGS, true, LOGIC_BIGGORON_SWORD, RHT_BIGGORON_SWORD, ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x0C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_DEKU_SHIELD] = Item(RG_DEKU_SHIELD, Text{ "Deku Shield", "Bouclier Mojo", "Deku-Schild" }, ITEMTYPE_EQUIP, GI_SHIELD_DEKU, false, LOGIC_DEKU_SHIELD, RHT_DEKU_SHIELD, ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "einen ", "un "}); - itemTable[RG_HYLIAN_SHIELD] = Item(RG_HYLIAN_SHIELD, Text{ "Hylian Shield", "Bouclier Hylien", "Hylia-Schild" }, ITEMTYPE_EQUIP, GI_SHIELD_HYLIAN, false, LOGIC_HYLIAN_SHIELD, RHT_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "einen ", "un "}); - itemTable[RG_MIRROR_SHIELD] = Item(RG_MIRROR_SHIELD, Text{ "Mirror Shield", "Bouclier Miroir", "Spiegelschild" }, ITEMTYPE_EQUIP, GI_SHIELD_MIRROR, true, LOGIC_MIRROR_SHIELD, RHT_MIRROR_SHIELD, ITEM_SHIELD_MIRROR, OBJECT_GI_SHIELD_3, GID_SHIELD_MIRROR, 0x4E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_GORON_TUNIC] = Item(RG_GORON_TUNIC, Text{ "Goron Tunic", "Tunique Goron", "Goronen-Tunika" }, ITEMTYPE_EQUIP, GI_TUNIC_GORON, true, LOGIC_GORON_TUNIC, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_ZORA_TUNIC] = Item(RG_ZORA_TUNIC, Text{ "Zora Tunic", "Tunique Zora", "Zora-Tunika" }, ITEMTYPE_EQUIP, GI_TUNIC_ZORA, true, LOGIC_ZORA_TUNIC, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_IRON_BOOTS] = Item(RG_IRON_BOOTS, Text{ "Iron Boots", "Bottes de plomb", "Eisenstiefel" }, ITEMTYPE_EQUIP, GI_BOOTS_IRON, true, LOGIC_IRON_BOOTS, RHT_IRON_BOOTS, ITEM_BOOTS_IRON, OBJECT_GI_BOOTS_2, GID_BOOTS_IRON, 0x53, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "les "}); - itemTable[RG_HOVER_BOOTS] = Item(RG_HOVER_BOOTS, Text{ "Hover Boots", "Bottes de airs", "Gleitstiefel" }, ITEMTYPE_EQUIP, GI_BOOTS_HOVER, true, LOGIC_HOVER_BOOTS, RHT_HOVER_BOOTS, ITEM_BOOTS_HOVER, OBJECT_GI_HOVERBOOTS, GID_BOOTS_HOVER, 0x54, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "les "}); - itemTable[RG_BOOMERANG] = Item(RG_BOOMERANG, Text{ "Boomerang", "Boomerang", "Bumerang" }, ITEMTYPE_ITEM, GI_BOOMERANG, true, LOGIC_BOOMERANG, RHT_BOOMERANG, ITEM_BOOMERANG, OBJECT_GI_BOOMERANG, GID_BOOMERANG, 0x35, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_LENS_OF_TRUTH] = Item(RG_LENS_OF_TRUTH, Text{ "Lens of Truth", "Monocle de Vérité", "Auge der Wahrheit" }, ITEMTYPE_ITEM, GI_LENS, true, LOGIC_LENS_OF_TRUTH, RHT_LENS_OF_TRUTH, ITEM_LENS, OBJECT_GI_GLASSES, GID_LENS, 0x39, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "la "}); - itemTable[RG_MEGATON_HAMMER] = Item(RG_MEGATON_HAMMER, Text{ "Megaton Hammer", "Masse des Titans", "Stahlhammer" }, ITEMTYPE_ITEM, GI_HAMMER, true, LOGIC_HAMMER, RHT_MEGATON_HAMMER, ITEM_HAMMER, OBJECT_GI_HAMMER, GID_HAMMER, 0x38, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_STONE_OF_AGONY] = Item(RG_STONE_OF_AGONY, Text{ "Stone of Agony", "Pierre de Souffrance", "Stein des Wissens" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, LOGIC_STONE_OF_AGONY, RHT_STONE_OF_AGONY, ITEM_STONE_OF_AGONY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, 0x68, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "la "}); - 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 Arrows", "Flèches de Feu", "Feuerpfeile" }, 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 Arrows", "Flèches de Glace", "Eispfeile" }, 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 Arrows", "Flèches de Lumière", "Lichtpfeile" }, 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, {"the ", "die ", "la "}); - 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, {"a ", "eine ", "un "}); - 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, {"the ", "das ", "le "}); - 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_HEALTH, MOD_RANDOMIZER); + itemTable[RG_DEKU_SHIELD] = Item(RG_DEKU_SHIELD, Text{ "Deku Shield", "Bouclier Mojo", "Deku-Schild" }, ITEMTYPE_EQUIP, GI_SHIELD_DEKU, false, LOGIC_DEKU_SHIELD, RHT_DEKU_SHIELD, ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "un ", "einen "}); + itemTable[RG_HYLIAN_SHIELD] = Item(RG_HYLIAN_SHIELD, Text{ "Hylian Shield", "Bouclier Hylien", "Hylia-Schild" }, ITEMTYPE_EQUIP, GI_SHIELD_HYLIAN, false, LOGIC_HYLIAN_SHIELD, RHT_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "un ", "einen "}); + itemTable[RG_MIRROR_SHIELD] = Item(RG_MIRROR_SHIELD, Text{ "Mirror Shield", "Bouclier Miroir", "Spiegelschild" }, ITEMTYPE_EQUIP, GI_SHIELD_MIRROR, true, LOGIC_MIRROR_SHIELD, RHT_MIRROR_SHIELD, ITEM_SHIELD_MIRROR, OBJECT_GI_SHIELD_3, GID_SHIELD_MIRROR, 0x4E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "}); + itemTable[RG_GORON_TUNIC] = Item(RG_GORON_TUNIC, Text{ "Goron Tunic", "Tunique Goron", "Goronen-Tunika" }, ITEMTYPE_EQUIP, GI_TUNIC_GORON, true, LOGIC_GORON_TUNIC, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "une ", "eine "}); + itemTable[RG_ZORA_TUNIC] = Item(RG_ZORA_TUNIC, Text{ "Zora Tunic", "Tunique Zora", "Zora-Tunika" }, ITEMTYPE_EQUIP, GI_TUNIC_ZORA, true, LOGIC_ZORA_TUNIC, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "une ", "eine "}); + itemTable[RG_IRON_BOOTS] = Item(RG_IRON_BOOTS, Text{ "Iron Boots", "Bottes de plomb", "Eisenstiefel" }, ITEMTYPE_EQUIP, GI_BOOTS_IRON, true, LOGIC_IRON_BOOTS, RHT_IRON_BOOTS, ITEM_BOOTS_IRON, OBJECT_GI_BOOTS_2, GID_BOOTS_IRON, 0x53, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "les ", "die "}); + itemTable[RG_HOVER_BOOTS] = Item(RG_HOVER_BOOTS, Text{ "Hover Boots", "Bottes de airs", "Gleitstiefel" }, ITEMTYPE_EQUIP, GI_BOOTS_HOVER, true, LOGIC_HOVER_BOOTS, RHT_HOVER_BOOTS, ITEM_BOOTS_HOVER, OBJECT_GI_HOVERBOOTS, GID_BOOTS_HOVER, 0x54, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "les ", "die "}); + itemTable[RG_BOOMERANG] = Item(RG_BOOMERANG, Text{ "Boomerang", "Boomerang", "Bumerang" }, ITEMTYPE_ITEM, GI_BOOMERANG, true, LOGIC_BOOMERANG, RHT_BOOMERANG, ITEM_BOOMERANG, OBJECT_GI_BOOMERANG, GID_BOOMERANG, 0x35, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "}); + itemTable[RG_LENS_OF_TRUTH] = Item(RG_LENS_OF_TRUTH, Text{ "Lens of Truth", "Monocle de Vérité", "Auge der Wahrheit" }, ITEMTYPE_ITEM, GI_LENS, true, LOGIC_LENS_OF_TRUTH, RHT_LENS_OF_TRUTH, ITEM_LENS, OBJECT_GI_GLASSES, GID_LENS, 0x39, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "die "}); + itemTable[RG_MEGATON_HAMMER] = Item(RG_MEGATON_HAMMER, Text{ "Megaton Hammer", "Masse des Titans", "Stahlhammer" }, ITEMTYPE_ITEM, GI_HAMMER, true, LOGIC_HAMMER, RHT_MEGATON_HAMMER, ITEM_HAMMER, OBJECT_GI_HAMMER, GID_HAMMER, 0x38, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "la ", "den "}); + itemTable[RG_STONE_OF_AGONY] = Item(RG_STONE_OF_AGONY, Text{ "Stone of Agony", "Pierre de Souffrance", "Stein des Wissens" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, LOGIC_STONE_OF_AGONY, RHT_STONE_OF_AGONY, ITEM_STONE_OF_AGONY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, 0x68, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "la ", "den "}); + 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, {"", "le ", ""}); + 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, {"", "le ", ""}); + 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, {"", "l'", ""}); + itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrows", "Flèche de Feu", "Feuerpfeile" }, 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, {"", "la ", ""}); + itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrows", "Flèche de Glace", "Eispfeile" }, 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, {"", "la ", ""}); + itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrows", "Flèche de Lumière", "Lichtpfeile" }, 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, {"", "la ", ""}); + 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, {"the ", "la ", "die "}); + itemTable[RG_MAGIC_BEAN] = Item(RG_MAGIC_BEAN, Text{ "Magic Bean", "Haricot Magique", "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, {"a ", "un ", "eine "}); + 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, {"the ", "le ", "das "}); + itemTable[RG_DOUBLE_DEFENSE] = Item(RG_DOUBLE_DEFENSE, Text{ "Double Defense", "Double Défense", "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_HEALTH, MOD_RANDOMIZER, {"", "la ", ""}); itemTable[RG_DOUBLE_DEFENSE].SetCustomDrawFunc(Randomizer_DrawDoubleDefense); // Trade Quest Items - itemTable[RG_WEIRD_EGG] = Item(RG_WEIRD_EGG, Text{ "Weird Egg", "Oeuf Curieux", "Seltsames Ei" }, ITEMTYPE_ITEM, GI_WEIRD_EGG, true, LOGIC_WEIRD_EGG, RHT_WEIRD_EGG, ITEM_WEIRD_EGG, OBJECT_GI_EGG, GID_EGG, 0x9A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}); - 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, {"the ", "das ", "le "}); + itemTable[RG_WEIRD_EGG] = Item(RG_WEIRD_EGG, Text{ "Weird Egg", "Oeuf Curieux", "Seltsames Ei" }, ITEMTYPE_ITEM, GI_WEIRD_EGG, true, LOGIC_WEIRD_EGG, RHT_WEIRD_EGG, ITEM_WEIRD_EGG, OBJECT_GI_EGG, GID_EGG, 0x9A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "l'", "das "}); + 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, {"", "la ", ""}); + 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, {"the ", "l'", "das "}); 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, {"the ", "den ", "le "}); - 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, {"the ", "den ", "la "}); - 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, {"the ", "die ", "la "}); - itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Zerbrochenes 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, {"the ", "das ", "le "}); - 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, {"the ", "das ", "la "}); - 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, {"the ", "den ", "la "}); - 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, {"the ", "die ", "les "}); - itemTable[RG_CLAIM_CHECK] = Item(RG_CLAIM_CHECK, Text{ "Claim Check", "Certificat", "Zertifikat" }, ITEMTYPE_ITEM, GI_CLAIM_CHECK, true, LOGIC_CLAIM_CHECK, RHT_CLAIM_CHECK, ITEM_CLAIM_CHECK, OBJECT_GI_TICKETSTONE, GID_CLAIM_CHECK, 0x0A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}); + 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, {"the ", "le ", "den "}); + 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, {"the ", "la ", "den "}); + 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, {"the ", "la ", "die "}); + itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Zerbrochenes 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, {"the ", "l'", "das "}); + 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, {"the ", "l'", "das "}); + 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, {"the ", "le ", "den "}); + 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, {"the ", "les ", "die "}); + itemTable[RG_CLAIM_CHECK] = Item(RG_CLAIM_CHECK, Text{ "Claim Check", "Certificat", "Zertifikat" }, ITEMTYPE_ITEM, GI_CLAIM_CHECK, true, LOGIC_CLAIM_CHECK, RHT_CLAIM_CHECK, ITEM_CLAIM_CHECK, OBJECT_GI_TICKETSTONE, GID_CLAIM_CHECK, 0x0A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "}); // Skulltula Token - itemTable[RG_GOLD_SKULLTULA_TOKEN] = Item(RG_GOLD_SKULLTULA_TOKEN, Text{ "Gold Skulltula Token", "Symbole de Skulltula d'Or", "Goldenes Skulltula-Symbol" }, ITEMTYPE_TOKEN, GI_SKULL_TOKEN, true, LOGIC_GOLD_SKULLTULA_TOKENS, RHT_GOLD_SKULLTULA_TOKEN, ITEM_SKULL_TOKEN, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, 0xB4, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SKULLTULA_TOKEN, MOD_NONE, {"a ", "ein ", "un "}); + itemTable[RG_GOLD_SKULLTULA_TOKEN] = Item(RG_GOLD_SKULLTULA_TOKEN, Text{ "Gold Skulltula Token", "Symbole de Skulltula d'Or", "Goldenes Skulltula-Symbol" }, ITEMTYPE_TOKEN, GI_SKULL_TOKEN, true, LOGIC_GOLD_SKULLTULA_TOKENS, RHT_GOLD_SKULLTULA_TOKEN, ITEM_SKULL_TOKEN, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, 0xB4, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SKULLTULA_TOKEN, MOD_NONE, {"a ", "un ", "ein "}); // Progressive Items - itemTable[RG_PROGRESSIVE_HOOKSHOT] = Item(RG_PROGRESSIVE_HOOKSHOT, Text{ "Progressive Hookshot", "Grappin (prog.)", "Progressiver Fanghaken" }, ITEMTYPE_ITEM, 0x80, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_PROGRESSIVE_HOOKSHOT, ITEM_CATEGORY_MAJOR, {"a ", "einen ", " un"}, "%g", true); - itemTable[RG_PROGRESSIVE_STRENGTH] = Item(RG_PROGRESSIVE_STRENGTH, Text{ "Strength Upgrade", "Amélioration de Force (prog.)", "Progressives Kraft-Upgrade" }, ITEMTYPE_ITEM, 0x81, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_PROGRESSIVE_STRENGTH, ITEM_CATEGORY_MAJOR, {"a ", "ein ", "une "}, "%g", true); - itemTable[RG_PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{ "Progressive Bomb Bag", "Sac de Bombes (prog.)", "Progressive Bombentasche" }, ITEMTYPE_ITEM, 0x82, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_PROGRESSIVE_BOMB_BAG, ITEM_CATEGORY_MAJOR, {"a ", "eine ", "un "}, "%g", true); - itemTable[RG_PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{ "Progressive Bow", "Arc (prog.)", "Progressiver Bogen" }, ITEMTYPE_ITEM, 0x83, true, LOGIC_PROGRESSIVE_BOW, RHT_PROGRESSIVE_BOW, ITEM_CATEGORY_MAJOR, {"a ", "einen ", "un "}, "%g", true); - itemTable[RG_PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Progressive Steinschleuder" }, ITEMTYPE_ITEM, 0x84, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_PROGRESSIVE_SLINGSHOT, ITEM_CATEGORY_MAJOR, {"a ", "eine ", "un "}, "%g", true); - itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Progressive Geldbörse" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, ITEM_CATEGORY_MAJOR, {"a ", "ein ", "un "}, "%g", true); - itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Progressive Schuppe" }, ITEMTYPE_ITEM, 0x86, true, LOGIC_PROGRESSIVE_SCALE, RHT_PROGRESSIVE_SCALE, ITEM_CATEGORY_MAJOR, {"a ", "eine ", "une "}, "%g", true); - itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Progressive Nuß-Kapazität" }, ITEMTYPE_ITEM, 0x87, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_PROGRESSIVE_NUT_UPGRADE, ITEM_CATEGORY_MAJOR, {"a ", "eine ", "une "}, "%g", true).CustomIcon(gItemIconDekuNutTex); - itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Progressive Stab-Kapazität" }, ITEMTYPE_ITEM, 0x88, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_PROGRESSIVE_STICK_UPGRADE, ITEM_CATEGORY_MAJOR, {"a ", "eine ", "un "}, "%g", true).CustomIcon(gItemIconDekuStickTex); - itemTable[RG_PROGRESSIVE_MAGIC_METER] = Item(RG_PROGRESSIVE_MAGIC_METER, Text{ "Progressive Magic Meter", "Jauge de Magie (prog.)", "Progressives Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_PROGRESSIVE_MAGIC_METER, ITEM_CATEGORY_MAJOR, {"a ", "ein ", "un "}, "%g", true).CustomIcon(gQuestIconMagicJarBigTex, ICON_SIZE_24); - itemTable[RG_PROGRESSIVE_OCARINA] = Item(RG_PROGRESSIVE_OCARINA, Text{ "Progressive Ocarina", "Ocarina (prog.)", "Progressive Okarina" }, ITEMTYPE_ITEM, 0x8B, true, LOGIC_PROGRESSIVE_OCARINA, RHT_PROGRESSIVE_OCARINA, ITEM_CATEGORY_MAJOR, {"a ", "eine ", "un "}, "%g", true); - itemTable[RG_PROGRESSIVE_GORONSWORD] = Item(RG_PROGRESSIVE_GORONSWORD, Text{ "Progressive Goron Sword", "Épée Goron (prog.)", "Progressives Goronen-Schwert" }, ITEMTYPE_ITEM, 0xD4, true, LOGIC_PROGRESSIVE_GIANT_KNIFE, RHT_PROGRESSIVE_GORONSWORD, ITEM_CATEGORY_MAJOR, {"a ", "ein ", "une "}, "%g", true); + itemTable[RG_PROGRESSIVE_HOOKSHOT] = Item(RG_PROGRESSIVE_HOOKSHOT, Text{ "Progressive Hookshot", "Grappin (prog.)", "Progressiver Fanghaken" }, ITEMTYPE_ITEM, 0x80, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_PROGRESSIVE_HOOKSHOT, ITEM_CATEGORY_MAJOR, {"a ", "un ", "einen "}, "%g", true); + itemTable[RG_PROGRESSIVE_STRENGTH] = Item(RG_PROGRESSIVE_STRENGTH, Text{ "Strength Upgrade", "Amélioration de Force (prog.)", "Progressives Kraft-Upgrade" }, ITEMTYPE_ITEM, 0x81, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_PROGRESSIVE_STRENGTH, ITEM_CATEGORY_MAJOR, {"a ", "une ", "ein "}, "%g", true); + itemTable[RG_PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{ "Progressive Bomb Bag", "Sac de Bombes (prog.)", "Progressive Bombentasche" }, ITEMTYPE_ITEM, 0x82, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_PROGRESSIVE_BOMB_BAG, ITEM_CATEGORY_MAJOR, {"a ", "un ", "eine "}, "%g", true); + itemTable[RG_PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{ "Progressive Bow", "Arc (prog.)", "Progressiver Bogen" }, ITEMTYPE_ITEM, 0x83, true, LOGIC_PROGRESSIVE_BOW, RHT_PROGRESSIVE_BOW, ITEM_CATEGORY_MAJOR, {"a ", "un ", "einen "}, "%g", true); + itemTable[RG_PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Progressive Steinschleuder" }, ITEMTYPE_ITEM, 0x84, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_PROGRESSIVE_SLINGSHOT, ITEM_CATEGORY_MAJOR, {"a ", "un ", "eine "}, "%g", true); + itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Progressive Geldbörse" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, ITEM_CATEGORY_MAJOR, {"a ", "une ", "ein "}, "%g", true); + itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Progressive Schuppe" }, ITEMTYPE_ITEM, 0x86, true, LOGIC_PROGRESSIVE_SCALE, RHT_PROGRESSIVE_SCALE, ITEM_CATEGORY_MAJOR, {"a ", "une ", "eine "}, "%g", true); + itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Progressive Nuß-Kapazität" }, ITEMTYPE_ITEM, 0x87, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_PROGRESSIVE_NUT_UPGRADE, ITEM_CATEGORY_MAJOR, {"a ", "une ", "eine "}, "%g", true).CustomIcon(gItemIconDekuNutTex); + itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Progressive Stab-Kapazität" }, ITEMTYPE_ITEM, 0x88, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_PROGRESSIVE_STICK_UPGRADE, ITEM_CATEGORY_MAJOR, {"a ", "une ", "eine "}, "%g", true).CustomIcon(gItemIconDekuStickTex); + itemTable[RG_PROGRESSIVE_MAGIC_METER] = Item(RG_PROGRESSIVE_MAGIC_METER, Text{ "Progressive Magic Meter", "Jauge de Magie (prog.)", "Progressives Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_PROGRESSIVE_MAGIC_METER, ITEM_CATEGORY_MAJOR, {"a ", "une ", "ein "}, "%g", true).CustomIcon(gQuestIconMagicJarBigTex, ICON_SIZE_24); + itemTable[RG_PROGRESSIVE_OCARINA] = Item(RG_PROGRESSIVE_OCARINA, Text{ "Progressive Ocarina", "Ocarina (prog.)", "Progressive Okarina" }, ITEMTYPE_ITEM, 0x8B, true, LOGIC_PROGRESSIVE_OCARINA, RHT_PROGRESSIVE_OCARINA, ITEM_CATEGORY_MAJOR, {"a ", "un ", "eine "}, "%g", true); + itemTable[RG_PROGRESSIVE_GORONSWORD] = Item(RG_PROGRESSIVE_GORONSWORD, Text{ "Progressive Goron Sword", "Épée Goron (prog.)", "Progressives Goronen-Schwert" }, ITEMTYPE_ITEM, 0xD4, true, LOGIC_PROGRESSIVE_GIANT_KNIFE, RHT_PROGRESSIVE_GORONSWORD, ITEM_CATEGORY_MAJOR, {"a ", "une ", "ein "}, "%g", true); // Bottles - itemTable[RG_EMPTY_BOTTLE] = Item(RG_EMPTY_BOTTLE, Text{ "Empty Bottle", "Bouteille Vide", "Leere Flasche" }, ITEMTYPE_ITEM, GI_BOTTLE, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_MILK, ITEM_BOTTLE, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x42, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"an ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_MILK] = Item(RG_BOTTLE_WITH_MILK, Text{ "Bottle with Milk", "Bouteille avec du Lait", "Flasche mit Milch" }, ITEMTYPE_ITEM, GI_MILK_BOTTLE, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_MILK, ITEM_MILK_BOTTLE, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_RED_POTION] = Item(RG_BOTTLE_WITH_RED_POTION, Text{ "Bottle with Red Potion", "Bouteille avec une Potion Rouge", "Flasche mit rotem Elixier" }, ITEMTYPE_ITEM, 0x8C, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_RED_POTION, RG_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_GREEN_POTION] = Item(RG_BOTTLE_WITH_GREEN_POTION, Text{ "Bottle with Green Potion", "Bouteille avec une Potion Verte", "Flasche mit grünem Elixier" }, ITEMTYPE_ITEM, 0x8D, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_GREEN_POTION, RG_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_BLUE_POTION] = Item(RG_BOTTLE_WITH_BLUE_POTION, Text{ "Bottle with Blue Potion", "Bouteille avec une Potion Bleue", "Flasche mit blauem Elixier" }, ITEMTYPE_ITEM, 0x8E, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BLUE_POTION, RG_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_FAIRY] = Item(RG_BOTTLE_WITH_FAIRY, Text{ "Bottle with Fairy", "Bouteille avec une Fée", "Flasche mit Fee" }, ITEMTYPE_ITEM, 0x8F, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_FAIRY, RG_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_FISH] = Item(RG_BOTTLE_WITH_FISH, Text{ "Bottle with Fish", "Bouteille avec un Poisson", "Flasche mit Fisch" }, ITEMTYPE_ITEM, 0x90, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_FISH, RG_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_BLUE_FIRE] = Item(RG_BOTTLE_WITH_BLUE_FIRE, Text{ "Bottle with Blue Fire", "Bouteille avec une Flamme Bleue", "Flasche mit blauem Feuer" }, ITEMTYPE_ITEM, 0x91, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BLUE_FIRE, RG_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_BUGS] = Item(RG_BOTTLE_WITH_BUGS, Text{ "Bottle with Bugs", "Bouteille avec des Insectes", "Flasche mit Wanzen" }, ITEMTYPE_ITEM, 0x92, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BUGS, RG_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "une "}); - itemTable[RG_BOTTLE_WITH_POE] = Item(RG_BOTTLE_WITH_POE, Text{ "Bottle with Poe", "Bouteille avec un Esprit", "Flasche mit einem Geist" }, ITEMTYPE_ITEM, 0x94, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_POE, RG_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "une "}); - itemTable[RG_RUTOS_LETTER] = Item(RG_RUTOS_LETTER, Text{ "Bottle with Ruto's Letter", "Bouteille avec la Lettre de Ruto", "Flasche mit Rutos Brief" }, ITEMTYPE_ITEM, GI_LETTER_RUTO, true, LOGIC_RUTOS_LETTER, RHT_RUTOS_LETTER, ITEM_LETTER_RUTO, OBJECT_GI_BOTTLE_LETTER, GID_LETTER_RUTO, 0x99, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"a ", "einen ", "un "}); - itemTable[RG_BOTTLE_WITH_BIG_POE] = Item(RG_BOTTLE_WITH_BIG_POE, Text{ "Bottle with Big Poe", "Bouteille avec une Âme", "Flasche mit Seele" }, ITEMTYPE_ITEM, 0x93, true, LOGIC_BOTTLE_WITH_BIG_POE, RHT_BOTTLE_WITH_BIG_POE, RG_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "einen ", "un "}); + itemTable[RG_EMPTY_BOTTLE] = Item(RG_EMPTY_BOTTLE, Text{ "Empty Bottle", "Bouteille Vide", "Leere Flasche" }, ITEMTYPE_ITEM, GI_BOTTLE, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_MILK, ITEM_BOTTLE, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x42, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"an ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_MILK] = Item(RG_BOTTLE_WITH_MILK, Text{ "Bottle with Milk", "Bouteille avec du Lait", "Flasche mit Milch" }, ITEMTYPE_ITEM, GI_MILK_BOTTLE, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_MILK, ITEM_MILK_BOTTLE, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"a ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_RED_POTION] = Item(RG_BOTTLE_WITH_RED_POTION, Text{ "Bottle with Red Potion", "Bouteille avec une Potion Rouge", "Flasche mit rotem Elixier" }, ITEMTYPE_ITEM, 0x8C, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_RED_POTION, RG_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_GREEN_POTION] = Item(RG_BOTTLE_WITH_GREEN_POTION, Text{ "Bottle with Green Potion", "Bouteille avec une Potion Verte", "Flasche mit grünem Elixier" }, ITEMTYPE_ITEM, 0x8D, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_GREEN_POTION, RG_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_BLUE_POTION] = Item(RG_BOTTLE_WITH_BLUE_POTION, Text{ "Bottle with Blue Potion", "Bouteille avec une Potion Bleue", "Flasche mit blauem Elixier" }, ITEMTYPE_ITEM, 0x8E, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BLUE_POTION, RG_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_FAIRY] = Item(RG_BOTTLE_WITH_FAIRY, Text{ "Bottle with Fairy", "Bouteille avec une Fée", "Flasche mit Fee" }, ITEMTYPE_ITEM, 0x8F, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_FAIRY, RG_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_FISH] = Item(RG_BOTTLE_WITH_FISH, Text{ "Bottle with Fish", "Bouteille avec un Poisson", "Flasche mit Fisch" }, ITEMTYPE_ITEM, 0x90, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_FISH, RG_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_BLUE_FIRE] = Item(RG_BOTTLE_WITH_BLUE_FIRE, Text{ "Bottle with Blue Fire", "Bouteille avec une Flamme Bleue", "Flasche mit blauem Feuer" }, ITEMTYPE_ITEM, 0x91, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BLUE_FIRE, RG_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_BUGS] = Item(RG_BOTTLE_WITH_BUGS, Text{ "Bottle with Bugs", "Bouteille avec des Insectes", "Flasche mit Wanzen" }, ITEMTYPE_ITEM, 0x92, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BUGS, RG_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "eine "}); + itemTable[RG_BOTTLE_WITH_POE] = Item(RG_BOTTLE_WITH_POE, Text{ "Bottle with Poe", "Bouteille avec un Esprit", "Flasche mit einem Geist" }, ITEMTYPE_ITEM, 0x94, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_POE, RG_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "eine "}); + itemTable[RG_RUTOS_LETTER] = Item(RG_RUTOS_LETTER, Text{ "Bottle with Ruto's Letter", "Bouteille avec la Lettre de Ruto", "Flasche mit Rutos Brief" }, ITEMTYPE_ITEM, GI_LETTER_RUTO, true, LOGIC_RUTOS_LETTER, RHT_RUTOS_LETTER, ITEM_LETTER_RUTO, OBJECT_GI_BOTTLE_LETTER, GID_LETTER_RUTO, 0x99, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"a ", "une ", "einen "}); + itemTable[RG_BOTTLE_WITH_BIG_POE] = Item(RG_BOTTLE_WITH_BIG_POE, Text{ "Bottle with Big Poe", "Bouteille avec une Âme", "Flasche mit Seele" }, ITEMTYPE_ITEM, 0x93, true, LOGIC_BOTTLE_WITH_BIG_POE, RHT_BOTTLE_WITH_BIG_POE, RG_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "une ", "einen "}); // Songs - itemTable[RG_ZELDAS_LULLABY] = Item(RG_ZELDAS_LULLABY, Text{ "Zelda's Lullaby", "Berceuse de Zelda", "Zeldas Wiegenlied" }, ITEMTYPE_SONG, 0xC1, true, LOGIC_ZELDAS_LULLABY, RHT_ZELDAS_LULLABY, ITEM_SONG_LULLABY, OBJECT_GI_MELODY, GID_SONG_ZELDA, 0xD4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_EPONAS_SONG] = Item(RG_EPONAS_SONG, Text{ "Epona's Song", "Chant d'Epona", "Eponas Lied" }, ITEMTYPE_SONG, 0xC2, true, LOGIC_EPONAS_SONG, RHT_EPONAS_SONG, ITEM_SONG_EPONA, OBJECT_GI_MELODY, GID_SONG_EPONA, 0xD2, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_SARIAS_SONG] = Item(RG_SARIAS_SONG, Text{ "Saria's Song", "Chant de Saria", "Salias Lied" }, ITEMTYPE_SONG, 0xC3, true, LOGIC_SARIAS_SONG, RHT_SARIAS_SONG, ITEM_SONG_SARIA, OBJECT_GI_MELODY, GID_SONG_SARIA, 0xD1, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_SUNS_SONG] = Item(RG_SUNS_SONG, Text{ "Sun's Song", "Chant du Soleil", "Hymne der Sonne" }, ITEMTYPE_SONG, 0xC4, true, LOGIC_SUNS_SONG, RHT_SUNS_SONG, ITEM_SONG_SUN, OBJECT_GI_MELODY, GID_SONG_SUN, 0xD3, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_SONG_OF_TIME] = Item(RG_SONG_OF_TIME, Text{ "Song of Time", "Chant du Temps", "Hymne der Zeit" }, ITEMTYPE_SONG, 0xC5, true, LOGIC_SONG_OF_TIME, RHT_SONG_OF_TIME, ITEM_SONG_TIME, OBJECT_GI_MELODY, GID_SONG_TIME, 0xD5, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "la "}); - itemTable[RG_SONG_OF_STORMS] = Item(RG_SONG_OF_STORMS, Text{ "Song of Storms", "Chant des Tempêtes", "Hymne des Sturms" }, ITEMTYPE_SONG, 0xC6, true, LOGIC_SONG_OF_STORMS, RHT_SONG_OF_STORMS, ITEM_SONG_STORMS, OBJECT_GI_MELODY, GID_SONG_STORM, 0xD6, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}); - itemTable[RG_MINUET_OF_FOREST] = Item(RG_MINUET_OF_FOREST, Text{ "Minuet of Forest", "Menuet des Bois", "Menuett des Waldes" }, ITEMTYPE_SONG, 0xBB, true, LOGIC_MINUET_OF_FOREST, RHT_MINUET_OF_FOREST, ITEM_SONG_MINUET, OBJECT_GI_MELODY, GID_SONG_MINUET, 0x73, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}); - itemTable[RG_BOLERO_OF_FIRE] = Item(RG_BOLERO_OF_FIRE, Text{ "Bolero of Fire", "Boléro du Feu", "Bolero des Feuers" }, ITEMTYPE_SONG, 0xBC, true, LOGIC_BOLERO_OF_FIRE, RHT_BOLERO_OF_FIRE, ITEM_SONG_BOLERO, OBJECT_GI_MELODY, GID_SONG_BOLERO, 0x74, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_SERENADE_OF_WATER] = Item(RG_SERENADE_OF_WATER, Text{ "Serenade of Water", "Sérénade de l'Eau", "Serenade des Wassers" }, ITEMTYPE_SONG, 0xBD, true, LOGIC_SERENADE_OF_WATER, RHT_SERENADE_OF_WATER, ITEM_SONG_SERENADE, OBJECT_GI_MELODY, GID_SONG_SERENADE, 0x75, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "la "}); - itemTable[RG_NOCTURNE_OF_SHADOW] = Item(RG_NOCTURNE_OF_SHADOW, Text{ "Nocturne of Shadow", "Nocturne de l'Ombre", "Nocturne des Schattens" }, ITEMTYPE_SONG, 0xBF, true, LOGIC_NOCTURNE_OF_SHADOW, RHT_NOCTURNE_OF_SHADOW, ITEM_SONG_NOCTURNE, OBJECT_GI_MELODY, GID_SONG_NOCTURNE, 0x77, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "le "}); - itemTable[RG_REQUIEM_OF_SPIRIT] = Item(RG_REQUIEM_OF_SPIRIT, Text{ "Requiem of Spirit", "Requiem des Esprits", "Requiem der Geister" }, ITEMTYPE_SONG, 0xBE, true, LOGIC_REQUIEM_OF_SPIRIT, RHT_REQUIEM_OF_SPIRIT, ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}); - itemTable[RG_PRELUDE_OF_LIGHT] = Item(RG_PRELUDE_OF_LIGHT, Text{ "Prelude of Light", "Prélude de la Lumière", "Kantate des Lichts" }, ITEMTYPE_SONG, 0xC0, true, LOGIC_PRELUDE_OF_LIGHT, RHT_PRELUDE_OF_LIGHT, ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}); + itemTable[RG_ZELDAS_LULLABY] = Item(RG_ZELDAS_LULLABY, Text{ "Zelda's Lullaby", "Berceuse de Zelda", "Zeldas Wiegenlied" }, ITEMTYPE_SONG, 0xC1, true, LOGIC_ZELDAS_LULLABY, RHT_ZELDAS_LULLABY, ITEM_SONG_LULLABY, OBJECT_GI_MELODY, GID_SONG_ZELDA, 0xD4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"", "la ", ""}); + itemTable[RG_EPONAS_SONG] = Item(RG_EPONAS_SONG, Text{ "Epona's Song", "Chant d'Epona", "Eponas Lied" }, ITEMTYPE_SONG, 0xC2, true, LOGIC_EPONAS_SONG, RHT_EPONAS_SONG, ITEM_SONG_EPONA, OBJECT_GI_MELODY, GID_SONG_EPONA, 0xD2, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"", "le ", ""}); + itemTable[RG_SARIAS_SONG] = Item(RG_SARIAS_SONG, Text{ "Saria's Song", "Chant de Saria", "Salias Lied" }, ITEMTYPE_SONG, 0xC3, true, LOGIC_SARIAS_SONG, RHT_SARIAS_SONG, ITEM_SONG_SARIA, OBJECT_GI_MELODY, GID_SONG_SARIA, 0xD1, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"", "le ", ""}); + itemTable[RG_SUNS_SONG] = Item(RG_SUNS_SONG, Text{ "Sun's Song", "Chant du Soleil", "Hymne der Sonne" }, ITEMTYPE_SONG, 0xC4, true, LOGIC_SUNS_SONG, RHT_SUNS_SONG, ITEM_SONG_SUN, OBJECT_GI_MELODY, GID_SONG_SUN, 0xD3, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"", "le ", ""}); + itemTable[RG_SONG_OF_TIME] = Item(RG_SONG_OF_TIME, Text{ "Song of Time", "Chant du Temps", "Hymne der Zeit" }, ITEMTYPE_SONG, 0xC5, true, LOGIC_SONG_OF_TIME, RHT_SONG_OF_TIME, ITEM_SONG_TIME, OBJECT_GI_MELODY, GID_SONG_TIME, 0xD5, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}); + itemTable[RG_SONG_OF_STORMS] = Item(RG_SONG_OF_STORMS, Text{ "Song of Storms", "Chant des Tempêtes", "Hymne des Sturms" }, ITEMTYPE_SONG, 0xC6, true, LOGIC_SONG_OF_STORMS, RHT_SONG_OF_STORMS, ITEM_SONG_STORMS, OBJECT_GI_MELODY, GID_SONG_STORM, 0xD6, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}); + itemTable[RG_MINUET_OF_FOREST] = Item(RG_MINUET_OF_FOREST, Text{ "Minuet of Forest", "Menuet des Bois", "Menuett des Waldes" }, ITEMTYPE_SONG, 0xBB, true, LOGIC_MINUET_OF_FOREST, RHT_MINUET_OF_FOREST, ITEM_SONG_MINUET, OBJECT_GI_MELODY, GID_SONG_MINUET, 0x73, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}); + itemTable[RG_BOLERO_OF_FIRE] = Item(RG_BOLERO_OF_FIRE, Text{ "Bolero of Fire", "Boléro du Feu", "Bolero des Feuers" }, ITEMTYPE_SONG, 0xBC, true, LOGIC_BOLERO_OF_FIRE, RHT_BOLERO_OF_FIRE, ITEM_SONG_BOLERO, OBJECT_GI_MELODY, GID_SONG_BOLERO, 0x74, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "}); + itemTable[RG_SERENADE_OF_WATER] = Item(RG_SERENADE_OF_WATER, Text{ "Serenade of Water", "Sérénade de l'Eau", "Serenade des Wassers" }, ITEMTYPE_SONG, 0xBD, true, LOGIC_SERENADE_OF_WATER, RHT_SERENADE_OF_WATER, ITEM_SONG_SERENADE, OBJECT_GI_MELODY, GID_SONG_SERENADE, 0x75, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "la ", "die "}); + itemTable[RG_NOCTURNE_OF_SHADOW] = Item(RG_NOCTURNE_OF_SHADOW, Text{ "Nocturne of Shadow", "Nocturne de l'Ombre", "Nocturne des Schattens" }, ITEMTYPE_SONG, 0xBF, true, LOGIC_NOCTURNE_OF_SHADOW, RHT_NOCTURNE_OF_SHADOW, ITEM_SONG_NOCTURNE, OBJECT_GI_MELODY, GID_SONG_NOCTURNE, 0x77, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "die "}); + itemTable[RG_REQUIEM_OF_SPIRIT] = Item(RG_REQUIEM_OF_SPIRIT, Text{ "Requiem of Spirit", "Requiem des Esprits", "Requiem der Geister" }, ITEMTYPE_SONG, 0xBE, true, LOGIC_REQUIEM_OF_SPIRIT, RHT_REQUIEM_OF_SPIRIT, ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}); + itemTable[RG_PRELUDE_OF_LIGHT] = Item(RG_PRELUDE_OF_LIGHT, Text{ "Prelude of Light", "Prélude de la Lumière", "Kantate des Lichts" }, ITEMTYPE_SONG, 0xC0, true, LOGIC_PRELUDE_OF_LIGHT, RHT_PRELUDE_OF_LIGHT, ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}); // Maps and Compasses - itemTable[RG_DEKU_TREE_MAP] = Item(RG_DEKU_TREE_MAP, Text{ "Great Deku Tree Map", "Carte de l'Arbre Mojo", "Karte des Deku-Baums" }, ITEMTYPE_MAP, 0xA5, false, LOGIC_MAP_DEKU_TREE, RHT_DEKU_TREE_MAP, RG_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the", " die ", "la "}, "%g"); + itemTable[RG_DEKU_TREE_MAP] = Item(RG_DEKU_TREE_MAP, Text{ "Great Deku Tree Map", "Carte de l'Arbre Mojo", "Karte des Deku-Baums" }, ITEMTYPE_MAP, 0xA5, false, LOGIC_MAP_DEKU_TREE, RHT_DEKU_TREE_MAP, RG_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the", "la ", "die "}, "%g"); itemTable[RG_DEKU_TREE_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_DODONGOS_CAVERN_MAP] = Item(RG_DODONGOS_CAVERN_MAP, Text{ "Dodongo's Cavern Map", "Carte de la Caverne Dodongo", "Karte der Dodongo-Höhle" }, ITEMTYPE_MAP, 0xA6, false, LOGIC_MAP_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN_MAP, RG_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%r"); + itemTable[RG_DODONGOS_CAVERN_MAP] = Item(RG_DODONGOS_CAVERN_MAP, Text{ "Dodongo's Cavern Map", "Carte de la Caverne Dodongo", "Karte der Dodongo-Höhle" }, ITEMTYPE_MAP, 0xA6, false, LOGIC_MAP_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN_MAP, RG_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%r"); itemTable[RG_DODONGOS_CAVERN_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_JABU_JABUS_BELLY_MAP] = Item(RG_JABU_JABUS_BELLY_MAP, Text{ "Jabu-Jabu's Belly Map", "Carte du Ventre de Jabu-Jabu", "Karte des Jabu-Jabu-Bauchs" }, ITEMTYPE_MAP, 0xA7, false, LOGIC_MAP_JABU_JABUS_BELLY, RHT_JABU_JABUS_BELLY_MAP, RG_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%b"); + itemTable[RG_JABU_JABUS_BELLY_MAP] = Item(RG_JABU_JABUS_BELLY_MAP, Text{ "Jabu-Jabu's Belly Map", "Carte du Ventre de Jabu-Jabu", "Karte des Jabu-Jabu-Bauchs" }, ITEMTYPE_MAP, 0xA7, false, LOGIC_MAP_JABU_JABUS_BELLY, RHT_JABU_JABUS_BELLY_MAP, RG_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%b"); itemTable[RG_JABU_JABUS_BELLY_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_FOREST_TEMPLE_MAP] = Item(RG_FOREST_TEMPLE_MAP, Text{ "Forest Temple Map", "Carte du Temple de la Forêt", "Karte des Waldtempels" }, ITEMTYPE_MAP, 0xA8, false, LOGIC_MAP_FOREST_TEMPLE, RHT_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%g"); + itemTable[RG_FOREST_TEMPLE_MAP] = Item(RG_FOREST_TEMPLE_MAP, Text{ "Forest Temple Map", "Carte du Temple de la Forêt", "Karte des Waldtempels" }, ITEMTYPE_MAP, 0xA8, false, LOGIC_MAP_FOREST_TEMPLE, RHT_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%g"); itemTable[RG_FOREST_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_FIRE_TEMPLE_MAP] = Item(RG_FIRE_TEMPLE_MAP, Text{ "Fire Temple Map", "Carte due Temple de Feu", "Karte des Feuertempels" }, ITEMTYPE_MAP, 0xA9, false, LOGIC_MAP_FIRE_TEMPLE, RHT_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%r"); + itemTable[RG_FIRE_TEMPLE_MAP] = Item(RG_FIRE_TEMPLE_MAP, Text{ "Fire Temple Map", "Carte due Temple de Feu", "Karte des Feuertempels" }, ITEMTYPE_MAP, 0xA9, false, LOGIC_MAP_FIRE_TEMPLE, RHT_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%r"); itemTable[RG_FIRE_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_WATER_TEMPLE_MAP] = Item(RG_WATER_TEMPLE_MAP, Text{ "Water Temple Map", "Carte du Temple de l'Eau", "Karte des Wassertempels" }, ITEMTYPE_MAP, 0xAA, false, LOGIC_MAP_WATER_TEMPLE, RHT_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%b"); + itemTable[RG_WATER_TEMPLE_MAP] = Item(RG_WATER_TEMPLE_MAP, Text{ "Water Temple Map", "Carte du Temple de l'Eau", "Karte des Wassertempels" }, ITEMTYPE_MAP, 0xAA, false, LOGIC_MAP_WATER_TEMPLE, RHT_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%b"); itemTable[RG_WATER_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_SPIRIT_TEMPLE_MAP] = Item(RG_SPIRIT_TEMPLE_MAP, Text{ "Spirit Temple Map", "Carte due Temple de l'Esprit", "Karte des Geistertempels" }, ITEMTYPE_MAP, 0xAB, false, LOGIC_MAP_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%y"); + itemTable[RG_SPIRIT_TEMPLE_MAP] = Item(RG_SPIRIT_TEMPLE_MAP, Text{ "Spirit Temple Map", "Carte due Temple de l'Esprit", "Karte des Geistertempels" }, ITEMTYPE_MAP, 0xAB, false, LOGIC_MAP_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%y"); itemTable[RG_SPIRIT_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_SHADOW_TEMPLE_MAP] = Item(RG_SHADOW_TEMPLE_MAP, Text{ "Shadow Temple Map", "Carte du Temple de l'Ombre", "Karte des Schattentempels" }, ITEMTYPE_MAP, 0xAC, false, LOGIC_MAP_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%p"); + itemTable[RG_SHADOW_TEMPLE_MAP] = Item(RG_SHADOW_TEMPLE_MAP, Text{ "Shadow Temple Map", "Carte du Temple de l'Ombre", "Karte des Schattentempels" }, ITEMTYPE_MAP, 0xAC, false, LOGIC_MAP_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%p"); itemTable[RG_SHADOW_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_BOTTOM_OF_THE_WELL_MAP] = Item(RG_BOTTOM_OF_THE_WELL_MAP, Text{ "Bottom of the Well Map", "Carte du Puits", "Karte des Grund des Brunnens" }, ITEMTYPE_MAP, 0xAD, false, LOGIC_MAP_BOTTOM_OF_THE_WELL, RHT_BOTTOM_OF_THE_WELL_MAP, RG_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%p"); + itemTable[RG_BOTTOM_OF_THE_WELL_MAP] = Item(RG_BOTTOM_OF_THE_WELL_MAP, Text{ "Bottom of the Well Map", "Carte du Puits", "Karte des Grund des Brunnens" }, ITEMTYPE_MAP, 0xAD, false, LOGIC_MAP_BOTTOM_OF_THE_WELL, RHT_BOTTOM_OF_THE_WELL_MAP, RG_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%p"); itemTable[RG_BOTTOM_OF_THE_WELL_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_ICE_CAVERN_MAP] = Item(RG_ICE_CAVERN_MAP, Text{ "Ice Cavern Map", "Carte de la Caverne Polaire", "Karte der Eishöhle" }, ITEMTYPE_MAP, 0xAE, false, LOGIC_MAP_ICE_CAVERN, RHT_ICE_CAVERN_MAP, RG_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}, "%c"); + itemTable[RG_ICE_CAVERN_MAP] = Item(RG_ICE_CAVERN_MAP, Text{ "Ice Cavern Map", "Carte de la Caverne Polaire", "Karte der Eishöhle" }, ITEMTYPE_MAP, 0xAE, false, LOGIC_MAP_ICE_CAVERN, RHT_ICE_CAVERN_MAP, RG_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "die "}, "%c"); itemTable[RG_ICE_CAVERN_MAP].SetCustomDrawFunc(Randomizer_DrawMap); - itemTable[RG_DEKU_TREE_COMPASS] = Item(RG_DEKU_TREE_COMPASS, Text{ "Great Deku Tree Compass", "Boussole de l'Arbre Mojo", "Kompaß des Deku-Baums" }, ITEMTYPE_COMPASS, 0x9B, false, LOGIC_COMPASS_DEKU_TREE, RHT_DEKU_TREE_COMPASS, RG_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%g"); + itemTable[RG_DEKU_TREE_COMPASS] = Item(RG_DEKU_TREE_COMPASS, Text{ "Great Deku Tree Compass", "Boussole de l'Arbre Mojo", "Kompaß des Deku-Baums" }, ITEMTYPE_COMPASS, 0x9B, false, LOGIC_COMPASS_DEKU_TREE, RHT_DEKU_TREE_COMPASS, RG_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%g"); itemTable[RG_DEKU_TREE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_DODONGOS_CAVERN_COMPASS] = Item(RG_DODONGOS_CAVERN_COMPASS, Text{ "Dodongo's Cavern Compass", "Boussole de la Caverne Dodongo", "Kompaß der Dodongo-Höhle" }, ITEMTYPE_COMPASS, 0x9C, false, LOGIC_COMPASS_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN_COMPASS, RG_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%r"); + itemTable[RG_DODONGOS_CAVERN_COMPASS] = Item(RG_DODONGOS_CAVERN_COMPASS, Text{ "Dodongo's Cavern Compass", "Boussole de la Caverne Dodongo", "Kompaß der Dodongo-Höhle" }, ITEMTYPE_COMPASS, 0x9C, false, LOGIC_COMPASS_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN_COMPASS, RG_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%r"); itemTable[RG_DODONGOS_CAVERN_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_JABU_JABUS_BELLY_COMPASS] = Item(RG_JABU_JABUS_BELLY_COMPASS, Text{ "Jabu-Jabu's Belly Compass", "Boussole du Ventre de Jabu-Jabu", "Kompaß des Jabu-Jabu-Bauchs" }, ITEMTYPE_COMPASS, 0x9D, false, LOGIC_COMPASS_JABU_JABUS_BELLY, RHT_JABU_JABUS_BELLY_COMPASS, RG_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%b"); + itemTable[RG_JABU_JABUS_BELLY_COMPASS] = Item(RG_JABU_JABUS_BELLY_COMPASS, Text{ "Jabu-Jabu's Belly Compass", "Boussole du Ventre de Jabu-Jabu", "Kompaß des Jabu-Jabu-Bauchs" }, ITEMTYPE_COMPASS, 0x9D, false, LOGIC_COMPASS_JABU_JABUS_BELLY, RHT_JABU_JABUS_BELLY_COMPASS, RG_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%b"); itemTable[RG_JABU_JABUS_BELLY_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_FOREST_TEMPLE_COMPASS] = Item(RG_FOREST_TEMPLE_COMPASS, Text{ "Forest Temple Compass", "Boussole du Temple de la Forêt", "Kompaß des Waldtempels" }, ITEMTYPE_COMPASS, 0x9E, false, LOGIC_COMPASS_FOREST_TEMPLE, RHT_FOREST_TEMPLE_COMPASS, RG_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%g"); + itemTable[RG_FOREST_TEMPLE_COMPASS] = Item(RG_FOREST_TEMPLE_COMPASS, Text{ "Forest Temple Compass", "Boussole du Temple de la Forêt", "Kompaß des Waldtempels" }, ITEMTYPE_COMPASS, 0x9E, false, LOGIC_COMPASS_FOREST_TEMPLE, RHT_FOREST_TEMPLE_COMPASS, RG_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%g"); itemTable[RG_FOREST_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_FIRE_TEMPLE_COMPASS] = Item(RG_FIRE_TEMPLE_COMPASS, Text{ "Fire Temple Compass", "Boussole du Temple du Feu", "Kompaß des Feuertempels" }, ITEMTYPE_COMPASS, 0x9F, false, LOGIC_COMPASS_FIRE_TEMPLE, RHT_FIRE_TEMPLE_COMPASS, RG_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%r"); + itemTable[RG_FIRE_TEMPLE_COMPASS] = Item(RG_FIRE_TEMPLE_COMPASS, Text{ "Fire Temple Compass", "Boussole du Temple du Feu", "Kompaß des Feuertempels" }, ITEMTYPE_COMPASS, 0x9F, false, LOGIC_COMPASS_FIRE_TEMPLE, RHT_FIRE_TEMPLE_COMPASS, RG_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%r"); itemTable[RG_FIRE_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_WATER_TEMPLE_COMPASS] = Item(RG_WATER_TEMPLE_COMPASS, Text{ "Water Temple Compass", "Boussole du Temple de l'Eau", "Kompaß des Wassertempels" }, ITEMTYPE_COMPASS, 0xA0, false, LOGIC_COMPASS_WATER_TEMPLE, RHT_WATER_TEMPLE_COMPASS, RG_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%b"); + itemTable[RG_WATER_TEMPLE_COMPASS] = Item(RG_WATER_TEMPLE_COMPASS, Text{ "Water Temple Compass", "Boussole du Temple de l'Eau", "Kompaß des Wassertempels" }, ITEMTYPE_COMPASS, 0xA0, false, LOGIC_COMPASS_WATER_TEMPLE, RHT_WATER_TEMPLE_COMPASS, RG_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%b"); itemTable[RG_WATER_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_SPIRIT_TEMPLE_COMPASS] = Item(RG_SPIRIT_TEMPLE_COMPASS, Text{ "Spirit Temple Compass", "Boussole due Temple de l'Esprit", "Kompaß des Geistertempels" }, ITEMTYPE_COMPASS, 0xA1, false, LOGIC_COMPASS_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_COMPASS, RG_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%y"); + itemTable[RG_SPIRIT_TEMPLE_COMPASS] = Item(RG_SPIRIT_TEMPLE_COMPASS, Text{ "Spirit Temple Compass", "Boussole due Temple de l'Esprit", "Kompaß des Geistertempels" }, ITEMTYPE_COMPASS, 0xA1, false, LOGIC_COMPASS_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_COMPASS, RG_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%y"); itemTable[RG_SPIRIT_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_SHADOW_TEMPLE_COMPASS] = Item(RG_SHADOW_TEMPLE_COMPASS, Text{ "Shadow Temple Compass", "Boussole du Temple de l'Ombre", "Kompaß des Schattentempels" }, ITEMTYPE_COMPASS, 0xA2, false, LOGIC_COMPASS_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_COMPASS, RG_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%p"); + itemTable[RG_SHADOW_TEMPLE_COMPASS] = Item(RG_SHADOW_TEMPLE_COMPASS, Text{ "Shadow Temple Compass", "Boussole du Temple de l'Ombre", "Kompaß des Schattentempels" }, ITEMTYPE_COMPASS, 0xA2, false, LOGIC_COMPASS_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_COMPASS, RG_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%p"); itemTable[RG_SHADOW_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_BOTTOM_OF_THE_WELL_COMPASS] = Item(RG_BOTTOM_OF_THE_WELL_COMPASS, Text{ "Bottom of the Well Compass", "Boussole du Puits", "Kompaß des Grund des Brunnens" }, ITEMTYPE_COMPASS, 0xA3, false, LOGIC_COMPASS_BOTTOM_OF_THE_WELL, RHT_BOTTOM_OF_THE_WELL_COMPASS, RG_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%p"); + itemTable[RG_BOTTOM_OF_THE_WELL_COMPASS] = Item(RG_BOTTOM_OF_THE_WELL_COMPASS, Text{ "Bottom of the Well Compass", "Boussole du Puits", "Kompaß des Grund des Brunnens" }, ITEMTYPE_COMPASS, 0xA3, false, LOGIC_COMPASS_BOTTOM_OF_THE_WELL, RHT_BOTTOM_OF_THE_WELL_COMPASS, RG_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%p"); itemTable[RG_BOTTOM_OF_THE_WELL_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); - itemTable[RG_ICE_CAVERN_COMPASS] = Item(RG_ICE_CAVERN_COMPASS, Text{ "Ice Cavern Compass", "Boussole de la Caverne Polaire", "Kompaß der Eishöhle" }, ITEMTYPE_COMPASS, 0xA4, false, LOGIC_COMPASS_ICE_CAVERN, RHT_ICE_CAVERN_COMPASS, RG_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "la "}, "%c"); + itemTable[RG_ICE_CAVERN_COMPASS] = Item(RG_ICE_CAVERN_COMPASS, Text{ "Ice Cavern Compass", "Boussole de la Caverne Polaire", "Kompaß der Eishöhle" }, ITEMTYPE_COMPASS, 0xA4, false, LOGIC_COMPASS_ICE_CAVERN, RHT_ICE_CAVERN_COMPASS, RG_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "den "}, "%c"); itemTable[RG_ICE_CAVERN_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); // Boss Keys - itemTable[RG_FOREST_TEMPLE_BOSS_KEY] = Item(RG_FOREST_TEMPLE_BOSS_KEY, Text{ "Forest Temple Boss Key", "Clé d'Or du Temple de la Forêt", "Master-Schlüssel des Waldtempels" }, ITEMTYPE_BOSSKEY, 0x95, true, LOGIC_BOSS_KEY_FOREST_TEMPLE, RHT_FOREST_TEMPLE_BOSS_KEY, RG_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}, "%g").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); + itemTable[RG_FOREST_TEMPLE_BOSS_KEY] = Item(RG_FOREST_TEMPLE_BOSS_KEY, Text{ "Forest Temple Boss Key", "Clé d'Or du Temple de la Forêt", "Master-Schlüssel des Waldtempels" }, ITEMTYPE_BOSSKEY, 0x95, true, LOGIC_BOSS_KEY_FOREST_TEMPLE, RHT_FOREST_TEMPLE_BOSS_KEY, RG_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}, "%g").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); itemTable[RG_FOREST_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); - itemTable[RG_FIRE_TEMPLE_BOSS_KEY] = Item(RG_FIRE_TEMPLE_BOSS_KEY, Text{ "Fire Temple Boss Key", "Clé d'Or du Temple du Feu", "Master-Schlüssel des Feuertempels" }, ITEMTYPE_BOSSKEY, 0x96, true, LOGIC_BOSS_KEY_FIRE_TEMPLE, RHT_FIRE_TEMPLE_BOSS_KEY, RG_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}, "%r").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); + itemTable[RG_FIRE_TEMPLE_BOSS_KEY] = Item(RG_FIRE_TEMPLE_BOSS_KEY, Text{ "Fire Temple Boss Key", "Clé d'Or du Temple du Feu", "Master-Schlüssel des Feuertempels" }, ITEMTYPE_BOSSKEY, 0x96, true, LOGIC_BOSS_KEY_FIRE_TEMPLE, RHT_FIRE_TEMPLE_BOSS_KEY, RG_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}, "%r").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); itemTable[RG_FIRE_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); - itemTable[RG_WATER_TEMPLE_BOSS_KEY] = Item(RG_WATER_TEMPLE_BOSS_KEY, Text{ "Water Temple Boss Key", "Clé d'Or du Temple de l'Eau", "Master-Schlüssel des Wassertempels" }, ITEMTYPE_BOSSKEY, 0x97, true, LOGIC_BOSS_KEY_WATER_TEMPLE, RHT_WATER_TEMPLE_BOSS_KEY, RG_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}, "%b").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); + itemTable[RG_WATER_TEMPLE_BOSS_KEY] = Item(RG_WATER_TEMPLE_BOSS_KEY, Text{ "Water Temple Boss Key", "Clé d'Or du Temple de l'Eau", "Master-Schlüssel des Wassertempels" }, ITEMTYPE_BOSSKEY, 0x97, true, LOGIC_BOSS_KEY_WATER_TEMPLE, RHT_WATER_TEMPLE_BOSS_KEY, RG_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}, "%b").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); itemTable[RG_WATER_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); - itemTable[RG_SPIRIT_TEMPLE_BOSS_KEY] = Item(RG_SPIRIT_TEMPLE_BOSS_KEY, Text{ "Spirit Temple Boss Key", "Clé d'Or du Temple de l'Esprit", "Master-Schlüssel des Geistertempels" }, ITEMTYPE_BOSSKEY, 0x98, true, LOGIC_BOSS_KEY_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOSS_KEY, RG_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}, "%y").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); + itemTable[RG_SPIRIT_TEMPLE_BOSS_KEY] = Item(RG_SPIRIT_TEMPLE_BOSS_KEY, Text{ "Spirit Temple Boss Key", "Clé d'Or du Temple de l'Esprit", "Master-Schlüssel des Geistertempels" }, ITEMTYPE_BOSSKEY, 0x98, true, LOGIC_BOSS_KEY_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOSS_KEY, RG_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}, "%y").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); itemTable[RG_SPIRIT_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); - itemTable[RG_SHADOW_TEMPLE_BOSS_KEY] = Item( RG_SHADOW_TEMPLE_BOSS_KEY, Text{ "Shadow Temple Boss Key", "Clé d'Or du Temple de l'Ombre", "Master-Schlüssel des Schattentempels" }, ITEMTYPE_BOSSKEY, 0x99, true, LOGIC_BOSS_KEY_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_BOSS_KEY, RG_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}, "%p").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); + itemTable[RG_SHADOW_TEMPLE_BOSS_KEY] = Item( RG_SHADOW_TEMPLE_BOSS_KEY, Text{ "Shadow Temple Boss Key", "Clé d'Or du Temple de l'Ombre", "Master-Schlüssel des Schattentempels" }, ITEMTYPE_BOSSKEY, 0x99, true, LOGIC_BOSS_KEY_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_BOSS_KEY, RG_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}, "%p").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); itemTable[RG_SHADOW_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); - itemTable[RG_GANONS_CASTLE_BOSS_KEY] = Item(RG_GANONS_CASTLE_BOSS_KEY, Text{ "Ganon's Castle Boss Key", "Clé d'Or du Château de Ganon", "Master-Schlüssel von Ganons Schloß" }, ITEMTYPE_BOSSKEY, 0x9A, true, LOGIC_BOSS_KEY_GANONS_CASTLE, RHT_GANONS_CASTLE_BOSS_KEY, RG_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}, "%r").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); + itemTable[RG_GANONS_CASTLE_BOSS_KEY] = Item(RG_GANONS_CASTLE_BOSS_KEY, Text{ "Ganon's Castle Boss Key", "Clé d'Or du Château de Ganon", "Master-Schlüssel von Ganons Schloß" }, ITEMTYPE_BOSSKEY, 0x9A, true, LOGIC_BOSS_KEY_GANONS_CASTLE, RHT_GANONS_CASTLE_BOSS_KEY, RG_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}, "%r").CustomIcon(gQuestIconDungeonBossKeyTex, ICON_SIZE_24); itemTable[RG_GANONS_CASTLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); - itemTable[RG_FOREST_TEMPLE_SMALL_KEY] = Item(RG_FOREST_TEMPLE_SMALL_KEY, Text{ "Forest Temple Small Key", "Petite Clé du Temple de la Forêt", "Kleiner Schlüssel für den Waldtempel" }, ITEMTYPE_SMALLKEY, 0xAF, true, LOGIC_FOREST_TEMPLE_KEYS, RHT_FOREST_TEMPLE_SMALL_KEY, RG_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%g").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_FOREST_TEMPLE_SMALL_KEY] = Item(RG_FOREST_TEMPLE_SMALL_KEY, Text{ "Forest Temple Small Key", "Petite Clé du Temple de la Forêt", "Kleiner Schlüssel für den Waldtempel" }, ITEMTYPE_SMALLKEY, 0xAF, true, LOGIC_FOREST_TEMPLE_KEYS, RHT_FOREST_TEMPLE_SMALL_KEY, RG_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%g").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_FOREST_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_FIRE_TEMPLE_SMALL_KEY] = Item(RG_FIRE_TEMPLE_SMALL_KEY, Text{ "Fire Temple Small Key", "Petite Clé du Temple du Feu", "Kleiner Schlüssel für den Feuertempel" }, ITEMTYPE_SMALLKEY, 0xB0, true, LOGIC_FIRE_TEMPLE_KEYS, RHT_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%r").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_FIRE_TEMPLE_SMALL_KEY] = Item(RG_FIRE_TEMPLE_SMALL_KEY, Text{ "Fire Temple Small Key", "Petite Clé du Temple du Feu", "Kleiner Schlüssel für den Feuertempel" }, ITEMTYPE_SMALLKEY, 0xB0, true, LOGIC_FIRE_TEMPLE_KEYS, RHT_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%r").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_FIRE_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_WATER_TEMPLE_SMALL_KEY] = Item(RG_WATER_TEMPLE_SMALL_KEY, Text{ "Water Temple Small Key", "Petite Clé du Temple de l'Eau", "Kleiner Schlüssel für den Wassertempel" }, ITEMTYPE_SMALLKEY, 0xB1, true, LOGIC_WATER_TEMPLE_KEYS, RHT_WATER_TEMPLE_SMALL_KEY, RG_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%b").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_WATER_TEMPLE_SMALL_KEY] = Item(RG_WATER_TEMPLE_SMALL_KEY, Text{ "Water Temple Small Key", "Petite Clé du Temple de l'Eau", "Kleiner Schlüssel für den Wassertempel" }, ITEMTYPE_SMALLKEY, 0xB1, true, LOGIC_WATER_TEMPLE_KEYS, RHT_WATER_TEMPLE_SMALL_KEY, RG_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%b").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_WATER_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_SPIRIT_TEMPLE_SMALL_KEY] = Item(RG_SPIRIT_TEMPLE_SMALL_KEY, Text{ "Spirit Temple Small Key", "Petite Clé du Temple de l'Esprit", "Kleiner Schlüssel für den Geistertempel" }, ITEMTYPE_SMALLKEY, 0xB2, true, LOGIC_SPIRIT_TEMPLE_KEYS, RHT_SPIRIT_TEMPLE_SMALL_KEY, RG_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%y").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_SPIRIT_TEMPLE_SMALL_KEY] = Item(RG_SPIRIT_TEMPLE_SMALL_KEY, Text{ "Spirit Temple Small Key", "Petite Clé du Temple de l'Esprit", "Kleiner Schlüssel für den Geistertempel" }, ITEMTYPE_SMALLKEY, 0xB2, true, LOGIC_SPIRIT_TEMPLE_KEYS, RHT_SPIRIT_TEMPLE_SMALL_KEY, RG_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%y").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_SPIRIT_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_SHADOW_TEMPLE_SMALL_KEY] = Item(RG_SHADOW_TEMPLE_SMALL_KEY, Text{ "Shadow Temple Small Key", "Petite Clé du Temple de l'Ombre", "Kleiner Schlüssel für den Schattentempel" }, ITEMTYPE_SMALLKEY, 0xB3, true, LOGIC_SHADOW_TEMPLE_KEYS, RHT_SHADOW_TEMPLE_SMALL_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%p").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_SHADOW_TEMPLE_SMALL_KEY] = Item(RG_SHADOW_TEMPLE_SMALL_KEY, Text{ "Shadow Temple Small Key", "Petite Clé du Temple de l'Ombre", "Kleiner Schlüssel für den Schattentempel" }, ITEMTYPE_SMALLKEY, 0xB3, true, LOGIC_SHADOW_TEMPLE_KEYS, RHT_SHADOW_TEMPLE_SMALL_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%p").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_SHADOW_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_BOTTOM_OF_THE_WELL_SMALL_KEY] = Item(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, Text{ "Bottom of the Well Small Key", "Petite Clé du Puits", "Kleiner Schlüssel für den Grund des Brunnens" }, ITEMTYPE_SMALLKEY, 0xB4, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%p").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_BOTTOM_OF_THE_WELL_SMALL_KEY] = Item(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, Text{ "Bottom of the Well Small Key", "Petite Clé du Puits", "Kleiner Schlüssel für den Grund des Brunnens" }, ITEMTYPE_SMALLKEY, 0xB4, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%p").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_BOTTOM_OF_THE_WELL_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_GERUDO_TRAINING_GROUND_SMALL_KEY] = Item(RG_GERUDO_TRAINING_GROUND_SMALL_KEY, Text{ "Training Ground Small Key", "Petite Clé du Gymnase Gerudo", "Kleiner Schlüssel für das Gerudo-Trainingsgelände" }, ITEMTYPE_SMALLKEY, 0xB5, true, LOGIC_GERUDO_TRAINING_GROUND_KEYS, RHT_GERUDO_TRAINING_GROUND_SMALL_KEY, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%y").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_GERUDO_TRAINING_GROUND_SMALL_KEY] = Item(RG_GERUDO_TRAINING_GROUND_SMALL_KEY, Text{ "Training Ground Small Key", "Petite Clé du Gymnase Gerudo", "Kleiner Schlüssel für das Gerudo-Trainingsgelände" }, ITEMTYPE_SMALLKEY, 0xB5, true, LOGIC_GERUDO_TRAINING_GROUND_KEYS, RHT_GERUDO_TRAINING_GROUND_SMALL_KEY, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%y").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_GERUDO_TRAINING_GROUND_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_GERUDO_FORTRESS_SMALL_KEY] = Item(RG_GERUDO_FORTRESS_SMALL_KEY, Text{ "Gerudo Fortress Small Key", "Petite Clé du Repaire des Voleurs", "Kleiner Schlüssel für die Gerudo-Festung" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xB6, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_SMALL_KEY, RG_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%y").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_GERUDO_FORTRESS_SMALL_KEY] = Item(RG_GERUDO_FORTRESS_SMALL_KEY, Text{ "Gerudo Fortress Small Key", "Petite Clé du Repaire des Voleurs", "Kleiner Schlüssel für die Gerudo-Festung" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xB6, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_SMALL_KEY, RG_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%y").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_GERUDO_FORTRESS_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{ "Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Kleiner Schlüssel für Ganons Schloß" }, ITEMTYPE_SMALLKEY, 0xB7, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "einen ", "une "}, "%r").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{ "Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Kleiner Schlüssel für Ganons Schloß" }, ITEMTYPE_SMALLKEY, 0xB7, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"a ", "une ", "einen "}, "%r").CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_GANONS_CASTLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_TREASURE_GAME_SMALL_KEY] = Item(RG_TREASURE_GAME_SMALL_KEY, Text{ "Chest Game Small Key", "Petite Clé du jeu la Chasse-aux-Trésors", "Kleiner Schlüssel für das Truhenspiel" }, ITEMTYPE_SMALLKEY, GI_DOOR_KEY, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_SMALL_KEY, ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_NONE, {"a ", "einen ", "une "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); - itemTable[RG_GUARD_HOUSE_KEY] = Item(RG_GUARD_HOUSE_KEY, Text{ "Guard House Key", "Clé de la Maison des Gardes", "Schlüssel für das Haus der Wachen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GUARD_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_GUARD_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_TREASURE_GAME_SMALL_KEY] = Item(RG_TREASURE_GAME_SMALL_KEY, Text{ "Chest Game Small Key", "Petite Clé du jeu la Chasse-aux-Trésors", "Kleiner Schlüssel für das Truhenspiel" }, ITEMTYPE_SMALLKEY, GI_DOOR_KEY, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_SMALL_KEY, ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_NONE, {"a ", "une ", "einen "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_GUARD_HOUSE_KEY] = Item(RG_GUARD_HOUSE_KEY, Text{ "Guard House Key", "Clé de la Maison des Gardes", "Schlüssel für das Haus der Wachen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GUARD_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_GUARD_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_GUARD_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_MARKET_BAZAAR_KEY] = Item(RG_MARKET_BAZAAR_KEY, Text{ "Market Bazaar Key", "Clé du Bazar de la Place du Marché", "Schlüssel für den Basar des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_BAZAAR_KEY, RHT_OVERWORLD_KEY, RG_MARKET_BAZAAR_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_MARKET_BAZAAR_KEY] = Item(RG_MARKET_BAZAAR_KEY, Text{ "Market Bazaar Key", "Clé du Bazar de la Place du Marché", "Schlüssel für den Basar des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_BAZAAR_KEY, RHT_OVERWORLD_KEY, RG_MARKET_BAZAAR_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_MARKET_BAZAAR_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_MARKET_POTION_SHOP_KEY] = Item(RG_MARKET_POTION_SHOP_KEY, Text{ "Market Potion Shop Key", "Clé du Magasin de Potions de la Place du Marché", "Schlüssel für den Magie-Laden des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_MARKET_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_MARKET_POTION_SHOP_KEY] = Item(RG_MARKET_POTION_SHOP_KEY, Text{ "Market Potion Shop Key", "Clé du Magasin de Potions de la Place du Marché", "Schlüssel für den Magie-Laden des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_MARKET_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_MARKET_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_MASK_SHOP_KEY] = Item(RG_MASK_SHOP_KEY, Text{ "Mask Shop Key", "Clé de la Foire aux Masques", "Schlüssel für den Maskenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MASK_SHOP_KEY, RHT_OVERWORLD_KEY, RG_MASK_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_MASK_SHOP_KEY] = Item(RG_MASK_SHOP_KEY, Text{ "Mask Shop Key", "Clé de la Foire aux Masques", "Schlüssel für den Maskenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MASK_SHOP_KEY, RHT_OVERWORLD_KEY, RG_MASK_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_MASK_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_MARKET_SHOOTING_GALLERY_KEY] = Item(RG_MARKET_SHOOTING_GALLERY_KEY, Text{ "Market Shooting Gallery Key", "Clé du Stand de Tir de la Place du Marché", "Schlüssel für die Schießbude des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_SHOOTING_GALLERY_KEY, RHT_OVERWORLD_KEY, RG_MARKET_SHOOTING_GALLERY_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_MARKET_SHOOTING_GALLERY_KEY] = Item(RG_MARKET_SHOOTING_GALLERY_KEY, Text{ "Market Shooting Gallery Key", "Clé du Stand de Tir de la Place du Marché", "Schlüssel für die Schießbude des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_SHOOTING_GALLERY_KEY, RHT_OVERWORLD_KEY, RG_MARKET_SHOOTING_GALLERY_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_MARKET_SHOOTING_GALLERY_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_BOMBCHU_BOWLING_KEY] = Item(RG_BOMBCHU_BOWLING_KEY, Text{ "Bombchu Bowling Alley Key", "Clé du Bowling Teigneux", "Schlüssel für die Minenbowlingbahn" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOMBCHU_BOWLING_KEY, RHT_OVERWORLD_KEY, RG_BOMBCHU_BOWLING_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_BOMBCHU_BOWLING_KEY] = Item(RG_BOMBCHU_BOWLING_KEY, Text{ "Bombchu Bowling Alley Key", "Clé du Bowling Teigneux", "Schlüssel für die Minenbowlingbahn" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOMBCHU_BOWLING_KEY, RHT_OVERWORLD_KEY, RG_BOMBCHU_BOWLING_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_BOMBCHU_BOWLING_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_TREASURE_CHEST_GAME_BUILDING_KEY] = Item(RG_TREASURE_CHEST_GAME_BUILDING_KEY, Text{ "Treasure Chest Game Building Key", "Clé de la Chasse au Trésor", "Schlüssel für das Haus des Schatzkisten-Pokers" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_TREASURE_CHEST_GAME_BUILDING_KEY,RHT_OVERWORLD_KEY, RG_TREASURE_CHEST_GAME_BUILDING_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_TREASURE_CHEST_GAME_BUILDING_KEY] = Item(RG_TREASURE_CHEST_GAME_BUILDING_KEY, Text{ "Treasure Chest Game Building Key", "Clé de la Chasse au Trésor", "Schlüssel für das Haus des Schatzkisten-Pokers" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_TREASURE_CHEST_GAME_BUILDING_KEY,RHT_OVERWORLD_KEY, RG_TREASURE_CHEST_GAME_BUILDING_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_TREASURE_CHEST_GAME_BUILDING_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_BOMBCHU_SHOP_KEY] = Item(RG_BOMBCHU_SHOP_KEY, Text{ "Bombchu Shop Key", "Clé du Magasin de Missiles", "Schlüssel für den Krabbelminenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOMBCHU_SHOP_KEY, RHT_OVERWORLD_KEY, RG_BOMBCHU_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_BOMBCHU_SHOP_KEY] = Item(RG_BOMBCHU_SHOP_KEY, Text{ "Bombchu Shop Key", "Clé du Magasin de Missiles", "Schlüssel für den Krabbelminenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOMBCHU_SHOP_KEY, RHT_OVERWORLD_KEY, RG_BOMBCHU_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_BOMBCHU_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_RICHARDS_HOUSE_KEY] = Item(RG_RICHARDS_HOUSE_KEY, Text{ "Richard's House Key", "Clé de la Maison de Kiki", "Schlüssel (Richards Haus)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_RICHARDS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_RICHARDS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_RICHARDS_HOUSE_KEY] = Item(RG_RICHARDS_HOUSE_KEY, Text{ "Richard's House Key", "Clé de la Maison de Kiki", "Schlüssel (Richards Haus)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_RICHARDS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_RICHARDS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_RICHARDS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_ALLEY_HOUSE_KEY] = Item(RG_ALLEY_HOUSE_KEY, Text{ "Alley House Key", "Clé de la Maison de la Ruelle", "Schlüssel für das Gäßchenhaus" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_ALLEY_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_ALLEY_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_ALLEY_HOUSE_KEY] = Item(RG_ALLEY_HOUSE_KEY, Text{ "Alley House Key", "Clé de la Maison de la Ruelle", "Schlüssel für das Gäßchenhaus" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_ALLEY_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_ALLEY_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_ALLEY_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_KAK_BAZAAR_KEY] = Item(RG_KAK_BAZAAR_KEY, Text{ "Kakariko Bazaar Key", "Clé du Bazar de Cocorico", "Schlüssel für den Basar von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_BAZAAR_KEY, RHT_OVERWORLD_KEY, RG_KAK_BAZAAR_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_KAK_BAZAAR_KEY] = Item(RG_KAK_BAZAAR_KEY, Text{ "Kakariko Bazaar Key", "Clé du Bazar de Cocorico", "Schlüssel für den Basar von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_BAZAAR_KEY, RHT_OVERWORLD_KEY, RG_KAK_BAZAAR_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_KAK_BAZAAR_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_KAK_POTION_SHOP_KEY] = Item(RG_KAK_POTION_SHOP_KEY, Text{ "Kakariko Potion Shop Key", "Clé du Magasin de Potions de Cocorico", "Schlüssel für den Magie-Laden von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_KAK_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_KAK_POTION_SHOP_KEY] = Item(RG_KAK_POTION_SHOP_KEY, Text{ "Kakariko Potion Shop Key", "Clé du Magasin de Potions de Cocorico", "Schlüssel für den Magie-Laden von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_KAK_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_KAK_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_BOSS_HOUSE_KEY] = Item(RG_BOSS_HOUSE_KEY, Text{ "Boss's House Key", "Clé de la Maison du Chef des Ouvriers", "Schlüssel für das Haus des Chefs" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOSS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_BOSS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_BOSS_HOUSE_KEY] = Item(RG_BOSS_HOUSE_KEY, Text{ "Boss's House Key", "Clé de la Maison du Chef des Ouvriers", "Schlüssel für das Haus des Chefs" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOSS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_BOSS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_BOSS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_GRANNYS_POTION_SHOP_KEY] = Item(RG_GRANNYS_POTION_SHOP_KEY, Text{ "Granny's Potion Shop Key", "Clé de l'Apothicaire", "Schlüssel (Asas Hexenladen)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GRANNYS_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_GRANNYS_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_GRANNYS_POTION_SHOP_KEY] = Item(RG_GRANNYS_POTION_SHOP_KEY, Text{ "Granny's Potion Shop Key", "Clé de l'Apothicaire", "Schlüssel (Asas Hexenladen)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GRANNYS_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_GRANNYS_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_GRANNYS_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_SKULLTULA_HOUSE_KEY] = Item(RG_SKULLTULA_HOUSE_KEY, Text{ "Skulltula House Key", "Clé de la Maison des Araignées", "Schlüssel für das Skulltula-Haus" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_SKULLTULA_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_SKULLTULA_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_SKULLTULA_HOUSE_KEY] = Item(RG_SKULLTULA_HOUSE_KEY, Text{ "Skulltula House Key", "Clé de la Maison des Araignées", "Schlüssel für das Skulltula-Haus" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_SKULLTULA_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_SKULLTULA_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_SKULLTULA_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_IMPAS_HOUSE_KEY] = Item(RG_IMPAS_HOUSE_KEY, Text{ "Impa's House Key", "Clé de la Maison d'Impa", "Schlüssel (Impas Haus)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_IMPAS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_IMPAS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_IMPAS_HOUSE_KEY] = Item(RG_IMPAS_HOUSE_KEY, Text{ "Impa's House Key", "Clé de la Maison d'Impa", "Schlüssel (Impas Haus)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_IMPAS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_IMPAS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_IMPAS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_WINDMILL_KEY] = Item(RG_WINDMILL_KEY, Text{ "Windmill Key", "Clé du Moulin", "Schlüssel für die Windmühle" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_WINDMILL_KEY, RHT_OVERWORLD_KEY, RG_WINDMILL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_WINDMILL_KEY] = Item(RG_WINDMILL_KEY, Text{ "Windmill Key", "Clé du Moulin", "Schlüssel für die Windmühle" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_WINDMILL_KEY, RHT_OVERWORLD_KEY, RG_WINDMILL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_WINDMILL_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_KAK_SHOOTING_GALLERY_KEY] = Item(RG_KAK_SHOOTING_GALLERY_KEY, Text{ "Kakariko Shooting Gallery Key", "Clé du Stand de Tir de Cocorico", "Schlüssel für die Schießbude von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_SHOOTING_GALLERY_KEY, RHT_OVERWORLD_KEY, RG_KAK_SHOOTING_GALLERY_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_KAK_SHOOTING_GALLERY_KEY] = Item(RG_KAK_SHOOTING_GALLERY_KEY, Text{ "Kakariko Shooting Gallery Key", "Clé du Stand de Tir de Cocorico", "Schlüssel für die Schießbude von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_SHOOTING_GALLERY_KEY, RHT_OVERWORLD_KEY, RG_KAK_SHOOTING_GALLERY_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_KAK_SHOOTING_GALLERY_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_DAMPES_HUT_KEY] = Item(RG_DAMPES_HUT_KEY, Text{ "Dampe's Hut Key", "Clé de la Cabane d'Igor", "Schlüssel (Hütte des Totengräbers)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_DAMPES_HUT_KEY, RHT_OVERWORLD_KEY, RG_DAMPES_HUT_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_DAMPES_HUT_KEY] = Item(RG_DAMPES_HUT_KEY, Text{ "Dampe's Hut Key", "Clé de la Cabane d'Igor", "Schlüssel (Hütte des Totengräbers)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_DAMPES_HUT_KEY, RHT_OVERWORLD_KEY, RG_DAMPES_HUT_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_DAMPES_HUT_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_TALONS_HOUSE_KEY] = Item(RG_TALONS_HOUSE_KEY, Text{ "Talon's House Key", "Clé de la Maison de Talon", "Schlüssel (Talons Haus)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_TALONS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_TALONS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_TALONS_HOUSE_KEY] = Item(RG_TALONS_HOUSE_KEY, Text{ "Talon's House Key", "Clé de la Maison de Talon", "Schlüssel (Talons Haus)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_TALONS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_TALONS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_TALONS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_STABLES_KEY] = Item(RG_STABLES_KEY, Text{ "Stables Key", "Clé des Écuries", "Schlüssel für die Ställe" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_STABLES_KEY, RHT_OVERWORLD_KEY, RG_STABLES_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_STABLES_KEY] = Item(RG_STABLES_KEY, Text{ "Stables Key", "Clé des Écuries", "Schlüssel für die Ställe" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_STABLES_KEY, RHT_OVERWORLD_KEY, RG_STABLES_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_STABLES_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_BACK_TOWER_KEY] = Item(RG_BACK_TOWER_KEY, Text{ "Back Tower Key", "Clé du Silo", "Schlüssel für den hinteren Turm" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BACK_TOWER_KEY, RHT_OVERWORLD_KEY, RG_BACK_TOWER_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_BACK_TOWER_KEY] = Item(RG_BACK_TOWER_KEY, Text{ "Back Tower Key", "Clé du Silo", "Schlüssel für den hinteren Turm" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BACK_TOWER_KEY, RHT_OVERWORLD_KEY, RG_BACK_TOWER_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_BACK_TOWER_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_HYLIA_LAB_KEY] = Item(RG_HYLIA_LAB_KEY, Text{ "Hylia Laboratory Key", "Clé du Laboratoire du Lac Hylia", "Schlüssel für das Hylia-Labor" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_HYLIA_LAB_KEY, RHT_OVERWORLD_KEY, RG_HYLIA_LAB_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_HYLIA_LAB_KEY] = Item(RG_HYLIA_LAB_KEY, Text{ "Hylia Laboratory Key", "Clé du Laboratoire du Lac Hylia", "Schlüssel für das Hylia-Labor" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_HYLIA_LAB_KEY, RHT_OVERWORLD_KEY, RG_HYLIA_LAB_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_HYLIA_LAB_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); - itemTable[RG_FISHING_HOLE_KEY] = Item(RG_FISHING_HOLE_KEY, Text{ "Fishing Hole Key", "Clé de l'Étang", "Schlüssel für den Fischweiher" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_FISHING_HOLE_KEY, RHT_OVERWORLD_KEY, RG_FISHING_HOLE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "la "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); + itemTable[RG_FISHING_HOLE_KEY] = Item(RG_FISHING_HOLE_KEY, Text{ "Fishing Hole Key", "Clé de l'Étang", "Schlüssel für den Fischweiher" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_FISHING_HOLE_KEY, RHT_OVERWORLD_KEY, RG_FISHING_HOLE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "la ", "den "}).CustomIcon(gQuestIconSmallKeyTex, ICON_SIZE_24); itemTable[RG_FISHING_HOLE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey); // Key Rings - itemTable[RG_FOREST_TEMPLE_KEY_RING] = Item(RG_FOREST_TEMPLE_KEY_RING, Text{ "Forest Temple Key Ring", "Trousseau du Temple de la Forêt", "Schlüsselbund für den Waldtempel" }, ITEMTYPE_SMALLKEY, 0xD5, true, LOGIC_FOREST_TEMPLE_KEYS, RHT_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%g"); + itemTable[RG_FOREST_TEMPLE_KEY_RING] = Item(RG_FOREST_TEMPLE_KEY_RING, Text{ "Forest Temple Key Ring", "Trousseau du Temple de la Forêt", "Schlüsselbund für den Waldtempel" }, ITEMTYPE_SMALLKEY, 0xD5, true, LOGIC_FOREST_TEMPLE_KEYS, RHT_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%g"); itemTable[RG_FOREST_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_FIRE_TEMPLE_KEY_RING] = Item(RG_FIRE_TEMPLE_KEY_RING, Text{ "Fire Temple Key Ring", "Trousseau du Temple du Feu", "Schlüsselbund für den Feuertempel" }, ITEMTYPE_SMALLKEY, 0xD6, true, LOGIC_FIRE_TEMPLE_KEYS, RHT_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%r"); + itemTable[RG_FIRE_TEMPLE_KEY_RING] = Item(RG_FIRE_TEMPLE_KEY_RING, Text{ "Fire Temple Key Ring", "Trousseau du Temple du Feu", "Schlüsselbund für den Feuertempel" }, ITEMTYPE_SMALLKEY, 0xD6, true, LOGIC_FIRE_TEMPLE_KEYS, RHT_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%r"); itemTable[RG_FIRE_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_WATER_TEMPLE_KEY_RING] = Item(RG_WATER_TEMPLE_KEY_RING, Text{ "Water Temple Key Ring", "Trousseau du Temple de l'Eau", "Schlüsselbund für den Wassertempel" }, ITEMTYPE_SMALLKEY, 0xD7, true, LOGIC_WATER_TEMPLE_KEYS, RHT_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%b"); + itemTable[RG_WATER_TEMPLE_KEY_RING] = Item(RG_WATER_TEMPLE_KEY_RING, Text{ "Water Temple Key Ring", "Trousseau du Temple de l'Eau", "Schlüsselbund für den Wassertempel" }, ITEMTYPE_SMALLKEY, 0xD7, true, LOGIC_WATER_TEMPLE_KEYS, RHT_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%b"); itemTable[RG_WATER_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_SPIRIT_TEMPLE_KEY_RING] = Item(RG_SPIRIT_TEMPLE_KEY_RING, Text{ "Spirit Temple Key Ring", "Trousseau du Temple de l'Esprit", "Schlüsselbund für den Geistertempel" }, ITEMTYPE_SMALLKEY, 0xD8, true, LOGIC_SPIRIT_TEMPLE_KEYS, RHT_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%y"); + itemTable[RG_SPIRIT_TEMPLE_KEY_RING] = Item(RG_SPIRIT_TEMPLE_KEY_RING, Text{ "Spirit Temple Key Ring", "Trousseau du Temple de l'Esprit", "Schlüsselbund für den Geistertempel" }, ITEMTYPE_SMALLKEY, 0xD8, true, LOGIC_SPIRIT_TEMPLE_KEYS, RHT_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%y"); itemTable[RG_SPIRIT_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_SHADOW_TEMPLE_KEY_RING] = Item(RG_SHADOW_TEMPLE_KEY_RING, Text{ "Shadow Temple Key Ring", "Trousseau du Temple de l'Ombre", "Schlüsselbund für den Schattentempel" }, ITEMTYPE_SMALLKEY, 0xD9, true, LOGIC_SHADOW_TEMPLE_KEYS, RHT_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%p"); + itemTable[RG_SHADOW_TEMPLE_KEY_RING] = Item(RG_SHADOW_TEMPLE_KEY_RING, Text{ "Shadow Temple Key Ring", "Trousseau du Temple de l'Ombre", "Schlüsselbund für den Schattentempel" }, ITEMTYPE_SMALLKEY, 0xD9, true, LOGIC_SHADOW_TEMPLE_KEYS, RHT_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%p"); itemTable[RG_SHADOW_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING] = Item(RG_BOTTOM_OF_THE_WELL_KEY_RING, Text{ "Bottom of the Well Key Ring", "Trousseau du Puits", "Schlüsselbund für den Grund des Brunnens" }, ITEMTYPE_SMALLKEY, 0xDA, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_KEY_RING, RG_BOTTOM_OF_THE_WELL_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%p"); + itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING] = Item(RG_BOTTOM_OF_THE_WELL_KEY_RING, Text{ "Bottom of the Well Key Ring", "Trousseau du Puits", "Schlüsselbund für den Grund des Brunnens" }, ITEMTYPE_SMALLKEY, 0xDA, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_KEY_RING, RG_BOTTOM_OF_THE_WELL_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%p"); itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_GERUDO_TRAINING_GROUND_KEY_RING] = Item(RG_GERUDO_TRAINING_GROUND_KEY_RING, Text{ "Training Ground Key Ring", "Trousseau du Gymnase Gerudo", "Schlüsselbund für das Gerudo-Trainingsgelände" }, ITEMTYPE_SMALLKEY, 0xDB, true, LOGIC_GERUDO_TRAINING_GROUND_KEYS, RHT_GERUDO_TRAINING_GROUND_KEY_RING, RG_GERUDO_TRAINING_GROUND_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%y"); + itemTable[RG_GERUDO_TRAINING_GROUND_KEY_RING] = Item(RG_GERUDO_TRAINING_GROUND_KEY_RING, Text{ "Training Ground Key Ring", "Trousseau du Gymnase Gerudo", "Schlüsselbund für das Gerudo-Trainingsgelände" }, ITEMTYPE_SMALLKEY, 0xDB, true, LOGIC_GERUDO_TRAINING_GROUND_KEYS, RHT_GERUDO_TRAINING_GROUND_KEY_RING, RG_GERUDO_TRAINING_GROUND_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%y"); itemTable[RG_GERUDO_TRAINING_GROUND_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_GERUDO_FORTRESS_KEY_RING] = Item(RG_GERUDO_FORTRESS_KEY_RING, Text{ "Gerudo Fortress Key Ring", "Trousseau du Repaire des Voleurs", "Schlüsselbund für die Gerudo-Festung" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xDC, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_KEY_RING, RG_GERUDO_FORTRESS_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%y"); + itemTable[RG_GERUDO_FORTRESS_KEY_RING] = Item(RG_GERUDO_FORTRESS_KEY_RING, Text{ "Gerudo Fortress Key Ring", "Trousseau du Repaire des Voleurs", "Schlüsselbund für die Gerudo-Festung" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xDC, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_KEY_RING, RG_GERUDO_FORTRESS_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%y"); itemTable[RG_GERUDO_FORTRESS_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_GANONS_CASTLE_KEY_RING] = Item(RG_GANONS_CASTLE_KEY_RING, Text{ "Ganon's Castle Key Ring", "Trousseau du Château de Ganon", "Schlüsselbund für Ganons Schloß" }, ITEMTYPE_SMALLKEY, 0xDD, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}, "%r"); + itemTable[RG_GANONS_CASTLE_KEY_RING] = Item(RG_GANONS_CASTLE_KEY_RING, Text{ "Ganon's Castle Key Ring", "Trousseau du Château de Ganon", "Schlüsselbund für Ganons Schloß" }, ITEMTYPE_SMALLKEY, 0xDD, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}, "%r"); itemTable[RG_GANONS_CASTLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_TREASURE_GAME_KEY_RING] = Item(RG_TREASURE_GAME_KEY_RING, Text{ "Chest Game Key Ring", "Trousseau du jeu la Chasse-aux-Trésors", "Schlüsselbund für das Truhenspiel" }, ITEMTYPE_SMALLKEY, 0xDE, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_KEY_RING, RG_TREASURE_GAME_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "den ", "le "}); + itemTable[RG_TREASURE_GAME_KEY_RING] = Item(RG_TREASURE_GAME_KEY_RING, Text{ "Chest Game Key Ring", "Trousseau du jeu la Chasse-aux-Trésors", "Schlüsselbund für das Truhenspiel" }, ITEMTYPE_SMALLKEY, 0xDE, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_KEY_RING, RG_TREASURE_GAME_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}); itemTable[RG_TREASURE_GAME_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); // Dungeon Rewards - itemTable[RG_KOKIRI_EMERALD] = Item(RG_KOKIRI_EMERALD, Text{ "Kokiri's Emerald", "Émeraude Kokiri", "Kokiri-Smaragd" }, ITEMTYPE_DUNGEONREWARD, 0xCB, true, LOGIC_KOKIRI_EMERALD, RHT_KOKIRI_EMERALD, ITEM_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}, "%g"); - itemTable[RG_GORON_RUBY] = Item(RG_GORON_RUBY, Text{ "Goron's Ruby", "Rubis Goron", "Goronen-Rubin" }, ITEMTYPE_DUNGEONREWARD, 0xCC, true, LOGIC_GORON_RUBY, RHT_GORON_RUBY, ITEM_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}, "%r"); - itemTable[RG_ZORA_SAPPHIRE] = Item(RG_ZORA_SAPPHIRE, Text{ "Zora's Sapphire", "Saphir Zora", "Zora-Saphir" }, ITEMTYPE_DUNGEONREWARD, 0xCD, true, LOGIC_ZORA_SAPPHIRE, RHT_ZORA_SAPPHIRE, ITEM_ZORA_SAPPHIRE, OBJECT_GI_JEWEL, GID_ZORA_SAPPHIRE, 0x82, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", " le"}, "%b"); - itemTable[RG_FOREST_MEDALLION] = Item(RG_FOREST_MEDALLION, Text{ "Forest Medallion", "Médaillon de la Forêt", "Amulett des Waldes" }, ITEMTYPE_DUNGEONREWARD, 0xCE, true, LOGIC_FOREST_MEDALLION, RHT_FOREST_MEDALLION, ITEM_MEDALLION_FOREST, OBJECT_GI_MEDAL, GID_MEDALLION_FOREST, 0x3E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}, "%g"); - itemTable[RG_FIRE_MEDALLION] = Item(RG_FIRE_MEDALLION, Text{ "Fire Medallion", "Médaillon du Feu", "Amulett des Feuers" }, ITEMTYPE_DUNGEONREWARD, 0xCF, true, LOGIC_FIRE_MEDALLION, RHT_FIRE_MEDALLION, ITEM_MEDALLION_FIRE, OBJECT_GI_MEDAL, GID_MEDALLION_FIRE, 0x3C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}, "%r"); - itemTable[RG_WATER_MEDALLION] = Item(RG_WATER_MEDALLION, Text{ "Water Medallion", "Médaillon de l'Eau", "Amulett des Wassers" }, ITEMTYPE_DUNGEONREWARD, 0xD0, true, LOGIC_WATER_MEDALLION, RHT_WATER_MEDALLION, ITEM_MEDALLION_WATER, OBJECT_GI_MEDAL, GID_MEDALLION_WATER, 0x3D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}, "%b"); - itemTable[RG_SPIRIT_MEDALLION] = Item(RG_SPIRIT_MEDALLION, Text{ "Spirit Medallion", "Médaillon de l'Esprit", "Amulett der Geister" }, ITEMTYPE_DUNGEONREWARD, 0xD1, true, LOGIC_SPIRIT_MEDALLION, RHT_SPIRIT_MEDALLION, ITEM_MEDALLION_SPIRIT, OBJECT_GI_MEDAL, GID_MEDALLION_SPIRIT, 0x3F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}, "%y"); - itemTable[RG_SHADOW_MEDALLION] = Item(RG_SHADOW_MEDALLION, Text{ "Shadow Medallion", "Médaillon de l'Ombre", "Amulett des Schattens" }, ITEMTYPE_DUNGEONREWARD, 0xD2, true, LOGIC_SHADOW_MEDALLION, RHT_SHADOW_MEDALLION, ITEM_MEDALLION_SHADOW, OBJECT_GI_MEDAL, GID_MEDALLION_SHADOW, 0x41, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}, "%p"); - itemTable[RG_LIGHT_MEDALLION] = Item(RG_LIGHT_MEDALLION, Text{ "Light Medallion", "Médaillon de la Lumière", "Amulett des Lichts" }, ITEMTYPE_DUNGEONREWARD, 0xD3, true, LOGIC_LIGHT_MEDALLION, RHT_LIGHT_MEDALLION, ITEM_MEDALLION_LIGHT, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT, 0x40, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}, "%y"); + itemTable[RG_KOKIRI_EMERALD] = Item(RG_KOKIRI_EMERALD, Text{ "Kokiri's Emerald", "Émeraude Kokiri", "Kokiri-Smaragd" }, ITEMTYPE_DUNGEONREWARD, 0xCB, true, LOGIC_KOKIRI_EMERALD, RHT_KOKIRI_EMERALD, ITEM_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "l'", "den "}, "%g"); + itemTable[RG_GORON_RUBY] = Item(RG_GORON_RUBY, Text{ "Goron's Ruby", "Rubis Goron", "Goronen-Rubin" }, ITEMTYPE_DUNGEONREWARD, 0xCC, true, LOGIC_GORON_RUBY, RHT_GORON_RUBY, ITEM_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "}, "%r"); + itemTable[RG_ZORA_SAPPHIRE] = Item(RG_ZORA_SAPPHIRE, Text{ "Zora's Sapphire", "Saphir Zora", "Zora-Saphir" }, ITEMTYPE_DUNGEONREWARD, 0xCD, true, LOGIC_ZORA_SAPPHIRE, RHT_ZORA_SAPPHIRE, ITEM_ZORA_SAPPHIRE, OBJECT_GI_JEWEL, GID_ZORA_SAPPHIRE, 0x82, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", " le", "den "}, "%b"); + itemTable[RG_FOREST_MEDALLION] = Item(RG_FOREST_MEDALLION, Text{ "Forest Medallion", "Médaillon de la Forêt", "Amulett des Waldes" }, ITEMTYPE_DUNGEONREWARD, 0xCE, true, LOGIC_FOREST_MEDALLION, RHT_FOREST_MEDALLION, ITEM_MEDALLION_FOREST, OBJECT_GI_MEDAL, GID_MEDALLION_FOREST, 0x3E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}, "%g"); + itemTable[RG_FIRE_MEDALLION] = Item(RG_FIRE_MEDALLION, Text{ "Fire Medallion", "Médaillon du Feu", "Amulett des Feuers" }, ITEMTYPE_DUNGEONREWARD, 0xCF, true, LOGIC_FIRE_MEDALLION, RHT_FIRE_MEDALLION, ITEM_MEDALLION_FIRE, OBJECT_GI_MEDAL, GID_MEDALLION_FIRE, 0x3C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}, "%r"); + itemTable[RG_WATER_MEDALLION] = Item(RG_WATER_MEDALLION, Text{ "Water Medallion", "Médaillon de l'Eau", "Amulett des Wassers" }, ITEMTYPE_DUNGEONREWARD, 0xD0, true, LOGIC_WATER_MEDALLION, RHT_WATER_MEDALLION, ITEM_MEDALLION_WATER, OBJECT_GI_MEDAL, GID_MEDALLION_WATER, 0x3D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}, "%b"); + itemTable[RG_SPIRIT_MEDALLION] = Item(RG_SPIRIT_MEDALLION, Text{ "Spirit Medallion", "Médaillon de l'Esprit", "Amulett der Geister" }, ITEMTYPE_DUNGEONREWARD, 0xD1, true, LOGIC_SPIRIT_MEDALLION, RHT_SPIRIT_MEDALLION, ITEM_MEDALLION_SPIRIT, OBJECT_GI_MEDAL, GID_MEDALLION_SPIRIT, 0x3F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}, "%y"); + itemTable[RG_SHADOW_MEDALLION] = Item(RG_SHADOW_MEDALLION, Text{ "Shadow Medallion", "Médaillon de l'Ombre", "Amulett des Schattens" }, ITEMTYPE_DUNGEONREWARD, 0xD2, true, LOGIC_SHADOW_MEDALLION, RHT_SHADOW_MEDALLION, ITEM_MEDALLION_SHADOW, OBJECT_GI_MEDAL, GID_MEDALLION_SHADOW, 0x41, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}, "%p"); + itemTable[RG_LIGHT_MEDALLION] = Item(RG_LIGHT_MEDALLION, Text{ "Light Medallion", "Médaillon de la Lumière", "Amulett des Lichts" }, ITEMTYPE_DUNGEONREWARD, 0xD3, true, LOGIC_LIGHT_MEDALLION, RHT_LIGHT_MEDALLION, ITEM_MEDALLION_LIGHT, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT, 0x40, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}, "%y"); // Generic Items - itemTable[RG_RECOVERY_HEART] = Item(RG_RECOVERY_HEART, Text{ "Recovery Heart", "Coeur de Vie", "Herz" }, ITEMTYPE_ITEM, GI_HEART, false, LOGIC_NONE, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "ein ", "un "}); - itemTable[RG_GREEN_RUPEE] = Item(RG_GREEN_RUPEE, Text{ "Green Rupee", "Rubis Vert", "Grüner Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_GREEN_RUPEE, ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0x6F, 0x00, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_GREG_RUPEE] = Item(RG_GREG_RUPEE, Text{ "Greg the Green Rupee", "Rubis Greg", "Greg Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN, true, LOGIC_GREG, RHT_GREG_RUPEE, RG_GREG_RUPEE, OBJECT_GI_RUPY, GID_RUPEE_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER).CustomIcon(gItemIconMaskGoronTex); - itemTable[RG_BLUE_RUPEE] = Item(RG_BLUE_RUPEE, Text{ "Blue Rupee", "Rubis Bleu", "Blauer Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_BLUE, false, LOGIC_NONE, RHT_BLUE_RUPEE, ITEM_RUPEE_BLUE, OBJECT_GI_RUPY, GID_RUPEE_BLUE, 0xCC, 0x01, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_RED_RUPEE] = Item(RG_RED_RUPEE, Text{ "Red Rupee", "Rubis Rouge", "Roter Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_RED, false, LOGIC_NONE, RHT_RED_RUPEE, ITEM_RUPEE_RED, OBJECT_GI_RUPY, GID_RUPEE_RED, 0xF0, 0x02, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_PURPLE_RUPEE] = Item(RG_PURPLE_RUPEE, Text{ "Purple Rupee", "Rubis Pourpre", "Violetter Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_PURPLE, false, LOGIC_NONE, RHT_PURPLE_RUPEE, ITEM_RUPEE_PURPLE, OBJECT_GI_RUPY, GID_RUPEE_PURPLE, 0xF1, 0x14, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_HUGE_RUPEE] = Item(RG_HUGE_RUPEE, Text{ "Huge Rupee", "Énorme Rubis", "Riesiger Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_GOLD, false, LOGIC_NONE, RHT_HUGE_RUPEE, ITEM_RUPEE_GOLD, OBJECT_GI_RUPY, GID_RUPEE_GOLD, 0xF2, 0x13, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_PIECE_OF_HEART] = Item(RG_PIECE_OF_HEART, Text{ "Piece of Heart", "Quart de Coeur", "Herzstück" }, ITEMTYPE_ITEM, GI_HEART_PIECE, true, LOGIC_PIECE_OF_HEART, RHT_PIECE_OF_HEART, ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xC2, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_HEALTH, MOD_NONE, {"a ", "ein ", "un "}); - itemTable[RG_HEART_CONTAINER] = Item(RG_HEART_CONTAINER, Text{ "Heart Container", "Réceptacle de Coeur", "Herzcontainer" }, ITEMTYPE_ITEM, GI_HEART_CONTAINER_2, true, LOGIC_HEART_CONTAINER, RHT_HEART_CONTAINER, ITEM_HEART_CONTAINER, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xC6, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_HEALTH, MOD_NONE, {"a ", "einen ", "un "}); + itemTable[RG_RECOVERY_HEART] = Item(RG_RECOVERY_HEART, Text{ "Recovery Heart", "Coeur de Vie", "Herz" }, ITEMTYPE_ITEM, GI_HEART, false, LOGIC_NONE, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "ein "}); + itemTable[RG_GREEN_RUPEE] = Item(RG_GREEN_RUPEE, Text{ "Green Rupee", "Rubis Vert", "Grüner Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_GREEN_RUPEE, ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0x6F, 0x00, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "eine "}); + itemTable[RG_GREG_RUPEE] = Item(RG_GREG_RUPEE, Text{ "Greg the Green Rupee", "Greg le Rubis Vert", "Greg Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN, true, LOGIC_GREG, RHT_GREG_RUPEE, RG_GREG_RUPEE, OBJECT_GI_RUPY, GID_RUPEE_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER).CustomIcon(gItemIconMaskGoronTex); + itemTable[RG_BLUE_RUPEE] = Item(RG_BLUE_RUPEE, Text{ "Blue Rupee", "Rubis Bleu", "Blauer Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_BLUE, false, LOGIC_NONE, RHT_BLUE_RUPEE, ITEM_RUPEE_BLUE, OBJECT_GI_RUPY, GID_RUPEE_BLUE, 0xCC, 0x01, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "eine "}); + itemTable[RG_RED_RUPEE] = Item(RG_RED_RUPEE, Text{ "Red Rupee", "Rubis Rouge", "Roter Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_RED, false, LOGIC_NONE, RHT_RED_RUPEE, ITEM_RUPEE_RED, OBJECT_GI_RUPY, GID_RUPEE_RED, 0xF0, 0x02, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "eine "}); + itemTable[RG_PURPLE_RUPEE] = Item(RG_PURPLE_RUPEE, Text{ "Purple Rupee", "Rubis Pourpre", "Violetter Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_PURPLE, false, LOGIC_NONE, RHT_PURPLE_RUPEE, ITEM_RUPEE_PURPLE, OBJECT_GI_RUPY, GID_RUPEE_PURPLE, 0xF1, 0x14, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "eine "}); + itemTable[RG_HUGE_RUPEE] = Item(RG_HUGE_RUPEE, Text{ "Huge Rupee", "Énorme Rubis", "Riesiger Rubin" }, ITEMTYPE_ITEM, GI_RUPEE_GOLD, false, LOGIC_NONE, RHT_HUGE_RUPEE, ITEM_RUPEE_GOLD, OBJECT_GI_RUPY, GID_RUPEE_GOLD, 0xF2, 0x13, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "un ", "eine "}); + itemTable[RG_PIECE_OF_HEART] = Item(RG_PIECE_OF_HEART, Text{ "Piece of Heart", "Quart de Coeur", "Herzstück" }, ITEMTYPE_ITEM, GI_HEART_PIECE, true, LOGIC_PIECE_OF_HEART, RHT_PIECE_OF_HEART, ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xC2, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_HEALTH, MOD_NONE, {"a ", "un ", "ein "}); + itemTable[RG_HEART_CONTAINER] = Item(RG_HEART_CONTAINER, Text{ "Heart Container", "Réceptacle de Coeur", "Herzcontainer" }, ITEMTYPE_ITEM, GI_HEART_CONTAINER_2, true, LOGIC_HEART_CONTAINER, RHT_HEART_CONTAINER, ITEM_HEART_CONTAINER, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xC6, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_HEALTH, MOD_NONE, {"a ", "un ", "einen "}); itemTable[RG_ICE_TRAP] = Item(RG_ICE_TRAP, Text{ "Ice Trap", "Piège de Glace", "Eisfalle" }, ITEMTYPE_ITEM, RG_ICE_TRAP, false, LOGIC_NONE, RHT_ICE_TRAP, RG_ICE_TRAP, OBJECT_GI_RUPY, GID_RUPEE_GOLD, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_MILK] = Item(RG_MILK, Text{ "Milk", "Lait", "Milch" }, ITEMTYPE_ITEM, GI_MILK, false, LOGIC_NONE, RHT_NONE, ITEM_MILK, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE); - itemTable[RG_FISH] = Item(RG_FISH, Text{ "Fish", "Poisson", "Fisch" }, ITEMTYPE_ITEM, GI_FISH, false, LOGIC_NONE, RHT_NONE, ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}); + itemTable[RG_FISH] = Item(RG_FISH, Text{ "Fish", "Poisson", "Fisch" }, ITEMTYPE_ITEM, GI_FISH, false, LOGIC_NONE, RHT_NONE, ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "einen "}); // Refills itemTable[RG_BOMBS_5] = Item(RG_BOMBS_5, Text{ "Bombs (5)", "Bombes (5)", "Bomben (5)" }, ITEMTYPE_REFILL, GI_BOMBS_5, false, LOGIC_NONE, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBS_10] = Item(RG_BOMBS_10, Text{ "Bombs (10)", "Bombes (10)", "Bomben (10)" }, ITEMTYPE_REFILL, GI_BOMBS_10, false, LOGIC_NONE, RHT_BOMBS_10, ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); @@ -278,12 +278,12 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_DEKU_NUTS_5] = Item(RG_DEKU_NUTS_5, Text{ "Deku Nuts (5)", "Noix Mojo (5)", "Deku-Nüsse (5)" }, ITEMTYPE_REFILL, GI_NUTS_5, false, LOGIC_NONE, RHT_DEKU_NUTS_5, ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_DEKU_NUTS_10] = Item(RG_DEKU_NUTS_10, Text{ "Deku Nuts (10)", "Noix Mojo (10)", "Deku-Nüsse (10)" }, ITEMTYPE_REFILL, GI_NUTS_10, false, LOGIC_NONE, RHT_DEKU_NUTS_10, ITEM_NUTS_10, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_DEKU_SEEDS_30] = Item(RG_DEKU_SEEDS_30, Text{ "Deku Seeds (30)", "Graines Mojo (30)", "Deku-Samen (30)" }, ITEMTYPE_REFILL, GI_SEEDS_30, false, LOGIC_NONE, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); - itemTable[RG_DEKU_STICK_1] = Item(RG_DEKU_STICK_1, Text{ "Deku Stick (1)", "Bâton Mojo (1)", "Deku-Stab (1)" }, ITEMTYPE_REFILL, GI_STICKS_1, false, LOGIC_NONE, RHT_DEKU_STICK_1, ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}); - itemTable[RG_RED_POTION_REFILL] = Item(RG_RED_POTION_REFILL, Text{ "Red Potion Refill", "Recharge de Potion Rouge", "Nachfüllpackung des roten Elixiers" }, ITEMTYPE_REFILL, GI_POTION_RED, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_GREEN_POTION_REFILL] = Item(RG_GREEN_POTION_REFILL, Text{ "Green Potion Refill", "Recharge de Potion Verte", "Nachfüllpackung des grünen Elixiers" }, ITEMTYPE_REFILL, GI_POTION_GREEN, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "eine ", "une "}); - itemTable[RG_BLUE_POTION_REFILL] = Item(RG_BLUE_POTION_REFILL, Text{ "Blue Potion Refill", "Recharge de Potion Bleue", "Nachfüllpackung des blauen Elixiers" }, ITEMTYPE_REFILL, GI_POTION_BLUE, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "eine ", "une "}); + itemTable[RG_DEKU_STICK_1] = Item(RG_DEKU_STICK_1, Text{ "Deku Stick (1)", "Bâton Mojo (1)", "Deku-Stab (1)" }, ITEMTYPE_REFILL, GI_STICKS_1, false, LOGIC_NONE, RHT_DEKU_STICK_1, ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "einen "}); + itemTable[RG_RED_POTION_REFILL] = Item(RG_RED_POTION_REFILL, Text{ "Red Potion Refill", "Recharge de Potion Rouge", "Nachfüllpackung des roten Elixiers" }, ITEMTYPE_REFILL, GI_POTION_RED, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "une ", "eine "}); + itemTable[RG_GREEN_POTION_REFILL] = Item(RG_GREEN_POTION_REFILL, Text{ "Green Potion Refill", "Recharge de Potion Verte", "Nachfüllpackung des grünen Elixiers" }, ITEMTYPE_REFILL, GI_POTION_GREEN, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "une ", "eine "}); + itemTable[RG_BLUE_POTION_REFILL] = Item(RG_BLUE_POTION_REFILL, Text{ "Blue Potion Refill", "Recharge de Potion Bleue", "Nachfüllpackung des blauen Elixiers" }, ITEMTYPE_REFILL, GI_POTION_BLUE, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "une ", "eine "}); // Treasure Game - itemTable[RG_TREASURE_GAME_HEART] = Item(RG_TREASURE_GAME_HEART, Text{ "Piece of Heart (WINNER)", "Quart de Coeur (Chasse-aux-Trésors)", "Herzstück (Schatztruhenminispiel)" }, ITEMTYPE_ITEM, GI_HEART_PIECE_WIN, true, LOGIC_PIECE_OF_HEART, RHT_TREASURE_GAME_HEART, ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xFA, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "das ", "le "}); + itemTable[RG_TREASURE_GAME_HEART] = Item(RG_TREASURE_GAME_HEART, Text{ "Piece of Heart (WINNER)", "Quart de Coeur (Chasse-aux-Trésors)", "Herzstück (Schatztruhenminispiel)" }, ITEMTYPE_ITEM, GI_HEART_PIECE_WIN, true, LOGIC_PIECE_OF_HEART, RHT_TREASURE_GAME_HEART, ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xFA, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "le ", "das "}); itemTable[RG_TREASURE_GAME_GREEN_RUPEE] = Item(RG_TREASURE_GAME_GREEN_RUPEE, Text{ "Green Rupee (LOSER)", "Rubis Vert (Chasse-aux-Trésors)", "Grüner Rubin (Schatztruhenminispiel)" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN_LOSE, false, LOGIC_NONE, RHT_TREASURE_GAME_GREEN_RUPEE, ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0xF4, 0x00, CHEST_ANIM_SHORT, ITEM_CATEGORY_MAJOR, MOD_NONE); // Shop itemTable[RG_BUY_DEKU_NUTS_5] = Item(RG_BUY_DEKU_NUTS_5, Text{ "Buy Deku Nut (5)", "Acheter: Noix Mojo (5)", "Deku-Nuß kaufen (5)" }, ITEMTYPE_SHOP, GI_NUTS_5_2, true, LOGIC_NUT_ACCESS, RHT_DEKU_NUTS_5, ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 15); @@ -294,28 +294,28 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BUY_DEKU_STICK_1] = Item(RG_BUY_DEKU_STICK_1, Text{ "Buy Deku Stick (1)", "Acheter: Bâton Mojo (1)", "Deku-Stab kaufen (1)" }, ITEMTYPE_SHOP, GI_STICKS_1, true, LOGIC_STICK_ACCESS, RHT_DEKU_STICK_1, ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 10); itemTable[RG_BUY_BOMBS_10] = Item(RG_BUY_BOMBS_10, Text{ "Buy Bombs (10)", "Acheter: Bombes (10)", "Bomben kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBS_10, true, LOGIC_BUY_BOMB, RHT_BOMBS_10, ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 50); itemTable[RG_BUY_FISH] = Item(RG_BUY_FISH, Text{ "Buy Fish", "Acheter: Poisson", "Fisch kaufen" }, ITEMTYPE_SHOP, GI_FISH, true, LOGIC_FISH_ACCESS, RHT_BOTTLE_WITH_FISH, ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 200); - itemTable[RG_BUY_RED_POTION_30] = Item(RG_BUY_RED_POTION_30, Text{ "Buy Red Potion [30]", "Acheter: Potion Rouge [30]", "Rotes Elixier kaufen [30]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 30); - itemTable[RG_BUY_GREEN_POTION] = Item(RG_BUY_GREEN_POTION, Text{ "Buy Green Potion", "Acheter: Potion Verte", "Grünes Elixier kaufen" }, ITEMTYPE_SHOP, GI_POTION_GREEN, true, LOGIC_BUY_MAGIC_POTION, RHT_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 30); - itemTable[RG_BUY_BLUE_POTION] = Item(RG_BUY_BLUE_POTION, Text{ "Buy Blue Potion", "Acheter: Potion Bleue", "Blaues Elixier kaufen" }, ITEMTYPE_SHOP, GI_POTION_BLUE, true, LOGIC_BUY_MAGIC_POTION, RHT_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 100); - itemTable[RG_BUY_HYLIAN_SHIELD] = Item(RG_BUY_HYLIAN_SHIELD, Text{ "Buy Hylian Shield", "Acheter: Bouclier Hylien", "Hylia-Schild kaufen" }, ITEMTYPE_SHOP, GI_SHIELD_HYLIAN, true, LOGIC_HYLIAN_SHIELD, RHT_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 80); - itemTable[RG_BUY_DEKU_SHIELD] = Item(RG_BUY_DEKU_SHIELD, Text{ "Buy Deku Shield", "Acheter: Bouclier Mojo", "Deku-Schild kaufen" }, ITEMTYPE_SHOP, GI_SHIELD_DEKU, true, LOGIC_DEKU_SHIELD, RHT_DEKU_SHIELD, ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 40); - itemTable[RG_BUY_GORON_TUNIC] = Item(RG_BUY_GORON_TUNIC, Text{ "Buy Goron Tunic", "Acheter: Tunique Goron", "Goronen-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_GORON, true, LOGIC_GORON_TUNIC, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 200); - itemTable[RG_BUY_ZORA_TUNIC] = Item(RG_BUY_ZORA_TUNIC, Text{ "Buy Zora Tunic", "Acheter: Tunique Zora", "Zora-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_ZORA, true, LOGIC_ZORA_TUNIC, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 300); - itemTable[RG_BUY_HEART] = Item(RG_BUY_HEART, Text{ "Buy Heart", "Acheter: Coeur de Vie", "Herz kaufen" }, ITEMTYPE_SHOP, GI_HEART, false, LOGIC_NONE, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 10); + itemTable[RG_BUY_RED_POTION_30] = Item(RG_BUY_RED_POTION_30, Text{ "Buy Red Potion [30]", "Acheter: Potion Rouge [30]", "Rotes Elixier kaufen [30]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "une ", "einen "}, "%g", false, 30); + itemTable[RG_BUY_GREEN_POTION] = Item(RG_BUY_GREEN_POTION, Text{ "Buy Green Potion", "Acheter: Potion Verte", "Grünes Elixier kaufen" }, ITEMTYPE_SHOP, GI_POTION_GREEN, true, LOGIC_BUY_MAGIC_POTION, RHT_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "une ", "einen "}, "%g", false, 30); + itemTable[RG_BUY_BLUE_POTION] = Item(RG_BUY_BLUE_POTION, Text{ "Buy Blue Potion", "Acheter: Potion Bleue", "Blaues Elixier kaufen" }, ITEMTYPE_SHOP, GI_POTION_BLUE, true, LOGIC_BUY_MAGIC_POTION, RHT_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "une ", "einen "}, "%g", false, 100); + itemTable[RG_BUY_HYLIAN_SHIELD] = Item(RG_BUY_HYLIAN_SHIELD, Text{ "Buy Hylian Shield", "Acheter: Bouclier Hylien", "Hylia-Schild kaufen" }, ITEMTYPE_SHOP, GI_SHIELD_HYLIAN, true, LOGIC_HYLIAN_SHIELD, RHT_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "un ", "einen "}, "%g", false, 80); + itemTable[RG_BUY_DEKU_SHIELD] = Item(RG_BUY_DEKU_SHIELD, Text{ "Buy Deku Shield", "Acheter: Bouclier Mojo", "Deku-Schild kaufen" }, ITEMTYPE_SHOP, GI_SHIELD_DEKU, true, LOGIC_DEKU_SHIELD, RHT_DEKU_SHIELD, ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "un ", "einen "}, "%g", false, 40); + itemTable[RG_BUY_GORON_TUNIC] = Item(RG_BUY_GORON_TUNIC, Text{ "Buy Goron Tunic", "Acheter: Tunique Goron", "Goronen-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_GORON, true, LOGIC_GORON_TUNIC, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "une ", "einen "}, "%g", false, 200); + itemTable[RG_BUY_ZORA_TUNIC] = Item(RG_BUY_ZORA_TUNIC, Text{ "Buy Zora Tunic", "Acheter: Tunique Zora", "Zora-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_ZORA, true, LOGIC_ZORA_TUNIC, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"a ", "une ", "einen "}, "%g", false, 300); + itemTable[RG_BUY_HEART] = Item(RG_BUY_HEART, Text{ "Buy Heart", "Acheter: Coeur de Vie", "Herz kaufen" }, ITEMTYPE_SHOP, GI_HEART, false, LOGIC_NONE, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "einen "}, "%g", false, 10); itemTable[RG_BUY_BOMBCHUS_10] = Item(RG_BUY_BOMBCHUS_10, Text{ "Buy Bombchu (10)", "Acheter: Missiles (10)", "Krabbelminen kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_10, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHUS_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 99); itemTable[RG_BUY_BOMBCHUS_20] = Item(RG_BUY_BOMBCHUS_20, Text{ "Buy Bombchu (20)", "Acheter: Missiles (20)", "Krabbelminen kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_20, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHUS_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 180); itemTable[RG_BUY_DEKU_SEEDS_30] = Item(RG_BUY_DEKU_SEEDS_30, Text{ "Buy Deku Seeds (30)", "Acheter: Graines Mojo (30)", "Deku-Samen kaufen (30)" }, ITEMTYPE_SHOP, GI_SEEDS_30, true, LOGIC_BUY_SEED, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 30); itemTable[RG_SOLD_OUT] = Item(RG_SOLD_OUT, Text{ "Sold Out", "Rupture de stock", "Ausverkauft" }, ITEMTYPE_SHOP, RG_SOLD_OUT, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_JUNK, {}, "%g", false, 0); itemTable[RG_BUY_BLUE_FIRE] = Item(RG_BUY_BLUE_FIRE, Text{ "Buy Blue Fire", "Acheter: Flamme Bleue", "Blaues Feuer kaufen" }, ITEMTYPE_SHOP, GI_BLUE_FIRE, true, LOGIC_BLUE_FIRE_ACCESS, RHT_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 300); - itemTable[RG_BUY_BOTTLE_BUG] = Item(RG_BUY_BOTTLE_BUG, Text{ "Buy Bottle Bug", "Acheter: Insecte en bouteille", "Flaschenkäfer kaufen" }, ITEMTYPE_SHOP, GI_BUGS, true, LOGIC_BUG_ACCESS, RHT_BOTTLE_WITH_BUGS, ITEM_BUG, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 50); - itemTable[RG_BUY_POE] = Item(RG_BUY_POE, Text{ "Buy Poe", "Acheter: Esprit", "Geist kaufen" }, ITEMTYPE_SHOP, RG_BUY_POE, false, LOGIC_NONE, RHT_BOTTLE_WITH_BIG_POE, ITEM_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 30); - itemTable[RG_BUY_FAIRYS_SPIRIT] = Item(RG_BUY_FAIRYS_SPIRIT, Text{ "Buy Fairy's Spirit", "Acheter: Esprit de Fée", "Feengeist kaufen" }, ITEMTYPE_SHOP, GI_FAIRY, true, LOGIC_FAIRY_ACCESS, RHT_BOTTLE_WITH_FAIRY, ITEM_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 50); + itemTable[RG_BUY_BOTTLE_BUG] = Item(RG_BUY_BOTTLE_BUG, Text{ "Buy Bottle Bug", "Acheter: Insecte en bouteille", "Flaschenkäfer kaufen" }, ITEMTYPE_SHOP, GI_BUGS, true, LOGIC_BUG_ACCESS, RHT_BOTTLE_WITH_BUGS, ITEM_BUG, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "einen "}, "%g", false, 50); + itemTable[RG_BUY_POE] = Item(RG_BUY_POE, Text{ "Buy Poe", "Acheter: Esprit", "Geist kaufen" }, ITEMTYPE_SHOP, RG_BUY_POE, false, LOGIC_NONE, RHT_BOTTLE_WITH_BIG_POE, ITEM_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "einen "}, "%g", false, 30); + itemTable[RG_BUY_FAIRYS_SPIRIT] = Item(RG_BUY_FAIRYS_SPIRIT, Text{ "Buy Fairy's Spirit", "Acheter: Esprit de Fée", "Feengeist kaufen" }, ITEMTYPE_SHOP, GI_FAIRY, true, LOGIC_FAIRY_ACCESS, RHT_BOTTLE_WITH_FAIRY, ITEM_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "un ", "einen "}, "%g", false, 50); itemTable[RG_BUY_ARROWS_10] = Item(RG_BUY_ARROWS_10, Text{ "Buy Arrows (10)", "Acheter: Flèches (10)", "Pfeile kaufen (10)" }, ITEMTYPE_SHOP, GI_ARROWS_SMALL, true, LOGIC_BUY_ARROW, RHT_ARROWS_10, ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 20); itemTable[RG_BUY_BOMBS_20] = Item(RG_BUY_BOMBS_20, Text{ "Buy Bombs (20)", "Acheter: Bombes (20)", "Bomben kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBS_20, true, LOGIC_BUY_BOMB, RHT_BOMBS_20, ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 80); itemTable[RG_BUY_BOMBS_30] = Item(RG_BUY_BOMBS_30, Text{ "Buy Bombs (30)", "Acheter: Bombes (30)", "Bomben kaufen (30)" }, ITEMTYPE_SHOP, GI_BOMBS_30, true, LOGIC_BUY_BOMB, RHT_BOMBS_20, ITEM_BOMBS_30, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 120); itemTable[RG_BUY_BOMBS_535] = Item(RG_BUY_BOMBS_535, Text{ "Buy Bombs (5) [35]", "Acheter: Bombes (5) [35]", "Bomben kaufen (5) [35]" }, ITEMTYPE_SHOP, GI_BOMBS_5, true, LOGIC_BUY_BOMB, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, {}, "%g", false, 35); - itemTable[RG_BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{ "Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Rotes Elixier kaufen [40]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 40); - itemTable[RG_BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{ "Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Rotes Elixier kaufen [50]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "einen ", "un "}, "%g", false, 50); + itemTable[RG_BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{ "Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Rotes Elixier kaufen [40]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "une ", "einen "}, "%g", false, 40); + itemTable[RG_BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{ "Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Rotes Elixier kaufen [50]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, {"a ", "une ", "einen "}, "%g", false, 50); // Misc. itemTable[RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL] = Item(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, Text{ "Death Mountain Crater Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER).CustomIcon(gItemIconMagicBeanTex); itemTable[RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); @@ -355,106 +355,106 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_TWINROVA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_GANON_SOUL] = Item(RG_GANON_SOUL, Text{ "Ganon's Soul", "Âme de Ganon", "Ganons Seele" }, ITEMTYPE_ITEM, 0xE8, true, LOGIC_CAN_SUMMON_GANON, RHT_GANON_SOUL, RG_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {}, "%r").CustomIcon(gBossSoulTex); itemTable[RG_GANON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); - itemTable[RG_FISHING_POLE] = Item(RG_FISHING_POLE, Text{ "Fishing Pole", "Canne à Pêche", "Angelrute" }, ITEMTYPE_ITEM, RG_FISHING_POLE, true, LOGIC_FISHING_POLE, RHT_FISHING_POLE, RG_FISHING_POLE, OBJECT_GI_FISH, GID_FISHING_POLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "das ", "le "}); + itemTable[RG_FISHING_POLE] = Item(RG_FISHING_POLE, Text{ "Fishing Pole", "Canne à Pêche", "Angelrute" }, ITEMTYPE_ITEM, RG_FISHING_POLE, true, LOGIC_FISHING_POLE, RHT_FISHING_POLE, RG_FISHING_POLE, OBJECT_GI_FISH, GID_FISHING_POLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "das "}); itemTable[RG_FISHING_POLE].SetCustomDrawFunc(Randomizer_DrawFishingPoleGI); - itemTable[RG_OCARINA_A_BUTTON] = Item(RG_OCARINA_A_BUTTON, Text{ "Ocarina A Button", "Touche A de l'Ocarina", "Taste A der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_A_BUTTON, RHT_OCARINA_A_BUTTON, RG_OCARINA_A_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "den ", "le "}); + itemTable[RG_OCARINA_A_BUTTON] = Item(RG_OCARINA_A_BUTTON, Text{ "Ocarina A Button", "Touche A de l'Ocarina", "Taste A der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_A_BUTTON, RHT_OCARINA_A_BUTTON, RG_OCARINA_A_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "den "}); itemTable[RG_OCARINA_A_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); - itemTable[RG_OCARINA_C_UP_BUTTON] = Item(RG_OCARINA_C_UP_BUTTON, Text{ "Ocarina C Up Button", "Touche C-Haut de l'Ocarina", "Taste C-Oben der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_UP_BUTTON, RHT_OCARINA_C_UP_BUTTON, RG_OCARINA_C_UP_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "den ", "le "}); + itemTable[RG_OCARINA_C_UP_BUTTON] = Item(RG_OCARINA_C_UP_BUTTON, Text{ "Ocarina C Up Button", "Touche C-Haut de l'Ocarina", "Taste C-Oben der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_UP_BUTTON, RHT_OCARINA_C_UP_BUTTON, RG_OCARINA_C_UP_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "den "}); itemTable[RG_OCARINA_C_UP_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); - itemTable[RG_OCARINA_C_DOWN_BUTTON] = Item(RG_OCARINA_C_DOWN_BUTTON, Text{ "Ocarina C Down Button", "Touche C-Bas de l'Ocarina", "Taste C-Unten der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_DOWN_BUTTON, RHT_OCARINA_C_DOWN_BUTTON, RG_OCARINA_C_DOWN_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "den ", "le "}); + itemTable[RG_OCARINA_C_DOWN_BUTTON] = Item(RG_OCARINA_C_DOWN_BUTTON, Text{ "Ocarina C Down Button", "Touche C-Bas de l'Ocarina", "Taste C-Unten der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_DOWN_BUTTON, RHT_OCARINA_C_DOWN_BUTTON, RG_OCARINA_C_DOWN_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "den "}); itemTable[RG_OCARINA_C_DOWN_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); - itemTable[RG_OCARINA_C_LEFT_BUTTON] = Item(RG_OCARINA_C_LEFT_BUTTON, Text{ "Ocarina C Left Button", "Touche C-Gauche de l'Ocarina", "Taste C-Links der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_LEFT_BUTTON, RG_OCARINA_C_LEFT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "den ", "le "}); + itemTable[RG_OCARINA_C_LEFT_BUTTON] = Item(RG_OCARINA_C_LEFT_BUTTON, Text{ "Ocarina C Left Button", "Touche C-Gauche de l'Ocarina", "Taste C-Links der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_LEFT_BUTTON, RG_OCARINA_C_LEFT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "den "}); itemTable[RG_OCARINA_C_LEFT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); - itemTable[RG_OCARINA_C_RIGHT_BUTTON] = Item(RG_OCARINA_C_RIGHT_BUTTON, Text{ "Ocarina C Right Button", "Touche C-Droit de l'Ocarina", "Taste C-Rechts der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_RIGHT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "den ", "le "}); + itemTable[RG_OCARINA_C_RIGHT_BUTTON] = Item(RG_OCARINA_C_RIGHT_BUTTON, Text{ "Ocarina C Right Button", "Touche C-Droit de l'Ocarina", "Taste C-Rechts der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_RIGHT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "den "}); itemTable[RG_OCARINA_C_RIGHT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); - itemTable[RG_KEATON_MASK] = Item(RG_KEATON_MASK, Text{ "Keaton Mask", "Masque du Renard", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_KEATON_MASK, true, LOGIC_NONE, RHT_MASK_KEATON, RG_KEATON_MASK, OBJECT_GI_KI_TAN_MASK, GID_MASK_KEATON, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_SKULL_MASK] = Item(RG_SKULL_MASK, Text{ "Skull Mask", "Masque de Mort", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_SKULL_MASK, true, LOGIC_NONE, RHT_MASK_SKULL, RG_SKULL_MASK, OBJECT_GI_SKJ_MASK, GID_MASK_SKULL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_SPOOKY_MASK] = Item(RG_SPOOKY_MASK, Text{ "Spooky Mask", "Masque d'Effroi", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_SPOOKY_MASK, true, LOGIC_NONE, RHT_MASK_SPOOKY, RG_SPOOKY_MASK, OBJECT_GI_REDEAD_MASK, GID_MASK_SPOOKY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_BUNNY_HOOD] = Item(RG_BUNNY_HOOD, Text{ "Bunny Hood", "Masque du Lapin", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_BUNNY_HOOD, true, LOGIC_NONE, RHT_MASK_BUNNY, RG_BUNNY_HOOD, OBJECT_GI_RABIT_MASK, GID_MASK_BUNNY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_GORON_MASK] = Item(RG_GORON_MASK, Text{ "Goron Mask", "Masque de Goron", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_GORON_MASK, true, LOGIC_NONE, RHT_MASK_GORON, RG_GORON_MASK, OBJECT_GI_GOLONMASK, GID_MASK_GORON, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_ZORA_MASK] = Item(RG_ZORA_MASK, Text{ "Zora Mask", "Masque de Zora", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_ZORA_MASK, true, LOGIC_NONE, RHT_MASK_ZORA, RG_ZORA_MASK, OBJECT_GI_ZORAMASK, GID_MASK_ZORA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_GERUDO_MASK] = Item(RG_GERUDO_MASK, Text{ "Gerudo Mask", "Masque de Gerudo", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_GERUDO_MASK, true, LOGIC_NONE, RHT_MASK_GERUDO, RG_GERUDO_MASK, OBJECT_GI_GERUDOMASK, GID_MASK_GERUDO, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_MASK_OF_TRUTH] = Item(RG_MASK_OF_TRUTH, Text{ "Mask of Truth", "Masque de Vérité", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_MASK_OF_TRUTH, true, LOGIC_NONE, RHT_MASK_TRUTH, RG_MASK_OF_TRUTH, OBJECT_GI_TRUTH_MASK, GID_MASK_TRUTH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_KEATON_MASK] = Item(RG_KEATON_MASK, Text{ "Keaton Mask", "Masque du Renard", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_KEATON_MASK, true, LOGIC_NONE, RHT_MASK_KEATON, RG_KEATON_MASK, OBJECT_GI_KI_TAN_MASK, GID_MASK_KEATON, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"", "le ", ""}); + itemTable[RG_SKULL_MASK] = Item(RG_SKULL_MASK, Text{ "Skull Mask", "Masque de Mort", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_SKULL_MASK, true, LOGIC_NONE, RHT_MASK_SKULL, RG_SKULL_MASK, OBJECT_GI_SKJ_MASK, GID_MASK_SKULL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"", "le ", ""}); + itemTable[RG_SPOOKY_MASK] = Item(RG_SPOOKY_MASK, Text{ "Spooky Mask", "Masque d'Effroi", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_SPOOKY_MASK, true, LOGIC_NONE, RHT_MASK_SPOOKY, RG_SPOOKY_MASK, OBJECT_GI_REDEAD_MASK, GID_MASK_SPOOKY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"", "le ", ""}); + itemTable[RG_BUNNY_HOOD] = Item(RG_BUNNY_HOOD, Text{ "Bunny Hood", "Masque du Lapin", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_BUNNY_HOOD, true, LOGIC_NONE, RHT_MASK_BUNNY, RG_BUNNY_HOOD, OBJECT_GI_RABIT_MASK, GID_MASK_BUNNY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"", "le ", ""}); + itemTable[RG_GORON_MASK] = Item(RG_GORON_MASK, Text{ "Goron Mask", "Masque de Goron", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_GORON_MASK, true, LOGIC_NONE, RHT_MASK_GORON, RG_GORON_MASK, OBJECT_GI_GOLONMASK, GID_MASK_GORON, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"", "le ", ""}); + itemTable[RG_ZORA_MASK] = Item(RG_ZORA_MASK, Text{ "Zora Mask", "Masque de Zora", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_ZORA_MASK, true, LOGIC_NONE, RHT_MASK_ZORA, RG_ZORA_MASK, OBJECT_GI_ZORAMASK, GID_MASK_ZORA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"", "le ", ""}); + itemTable[RG_GERUDO_MASK] = Item(RG_GERUDO_MASK, Text{ "Gerudo Mask", "Masque de Gerudo", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_GERUDO_MASK, true, LOGIC_NONE, RHT_MASK_GERUDO, RG_GERUDO_MASK, OBJECT_GI_GERUDOMASK, GID_MASK_GERUDO, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"", "le ", ""}); + itemTable[RG_MASK_OF_TRUTH] = Item(RG_MASK_OF_TRUTH, Text{ "Mask of Truth", "Masque de Vérité", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_MASK_OF_TRUTH, true, LOGIC_NONE, RHT_MASK_TRUTH, RG_MASK_OF_TRUTH, OBJECT_GI_TRUTH_MASK, GID_MASK_TRUTH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"", "le ", ""}); - itemTable[RG_SPEAK_DEKU] = Item(RG_SPEAK_DEKU, Text{ "Deku Jabber Nut", "Noix Blabla Mojo", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_DEKU, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SPEAK_DEKU] = Item(RG_SPEAK_DEKU, Text{ "Deku Jabber Nut", "Noix Blabla Mojo", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_DEKU, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_SPEAK_DEKU].SetCustomDrawFunc(Randomizer_DrawJabberNut); - itemTable[RG_SPEAK_GERUDO] = Item(RG_SPEAK_GERUDO, Text{ "Gerudo Jabber Nut", "Noix Blabla Gerudo", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_GERUDO, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SPEAK_GERUDO] = Item(RG_SPEAK_GERUDO, Text{ "Gerudo Jabber Nut", "Noix Blabla Gerudo", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_GERUDO, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_SPEAK_GERUDO].SetCustomDrawFunc(Randomizer_DrawJabberNut); - itemTable[RG_SPEAK_GORON] = Item(RG_SPEAK_GORON, Text{ "Goron Jabber Nut", "Noix Blabla Goron", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_GORON, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SPEAK_GORON] = Item(RG_SPEAK_GORON, Text{ "Goron Jabber Nut", "Noix Blabla Goron", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_GORON, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_SPEAK_GORON].SetCustomDrawFunc(Randomizer_DrawJabberNut); - itemTable[RG_SPEAK_HYLIAN] = Item(RG_SPEAK_HYLIAN, Text{ "Hylian Jabber Nut", "Noix Blabla Hylienne", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_HYLIAN, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SPEAK_HYLIAN] = Item(RG_SPEAK_HYLIAN, Text{ "Hylian Jabber Nut", "Noix Blabla Hylienne", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_HYLIAN, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_SPEAK_HYLIAN].SetCustomDrawFunc(Randomizer_DrawJabberNut); - itemTable[RG_SPEAK_KOKIRI] = Item(RG_SPEAK_KOKIRI, Text{ "Kokiri Jabber Nut", "Noix Blabla Kokiri", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_KOKIRI, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SPEAK_KOKIRI] = Item(RG_SPEAK_KOKIRI, Text{ "Kokiri Jabber Nut", "Noix Blabla Kokiri", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_KOKIRI, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_SPEAK_KOKIRI].SetCustomDrawFunc(Randomizer_DrawJabberNut); - itemTable[RG_SPEAK_ZORA] = Item(RG_SPEAK_ZORA, Text{ "Zora Jabber Nut", "Noix Blabla Zora", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_ZORA, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SPEAK_ZORA] = Item(RG_SPEAK_ZORA, Text{ "Zora Jabber Nut", "Noix Blabla Zora", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK_ZORA, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_SPEAK_ZORA].SetCustomDrawFunc(Randomizer_DrawJabberNut); - itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_SCALE, RHT_NONE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "die ", "le "}); + itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_SCALE, RHT_NONE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "l'", "die "}); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); - itemTable[RG_POWER_BRACELET] = Item(RG_POWER_BRACELET, Text{ "Power Bracelet", TODO_TRANSLATE, TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_BRACELET, true, LOGIC_NONE, RHT_NONE, RG_POWER_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER).CustomIcon(gItemIconGoronsBraceletTex); + itemTable[RG_POWER_BRACELET] = Item(RG_POWER_BRACELET, Text{ "Power Bracelet", "Bracelets de Force", TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_BRACELET, true, LOGIC_NONE, RHT_NONE, RG_POWER_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "les ", TODO_TRANSLATE}).CustomIcon(gItemIconGoronsBraceletTex); itemTable[RG_POWER_BRACELET].SetCustomDrawFunc(Randomizer_DrawPowerBracelet); - itemTable[RG_CLIMB] = Item(RG_CLIMB, Text{ "Climb", TODO_TRANSLATE, "Grimper" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_CLIMB, RG_CLIMB, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_CLIMB] = Item(RG_CLIMB, Text{ "Climb", "Grimper", TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_CLIMB, RG_CLIMB, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_CLIMB].SetCustomDrawFunc(Randomizer_DrawLadder); itemTable[RG_CRAWL] = Item(RG_CRAWL, Text{ "Crawl", "Ramper", "Kriechen" }, ITEMTYPE_ITEM, GI_SHIELD_DEKU, true, LOGIC_NONE, RHT_CRAWL, RG_CRAWL, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_CRAWL].SetCustomDrawFunc(Randomizer_DrawKneePads); - itemTable[RG_OPEN_CHEST] = Item(RG_OPEN_CHEST, Text{ "Open Chests", TODO_TRANSLATE, TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_KEY_SMALL, true, LOGIC_NONE, RHT_OPEN_CHEST, RG_OPEN_CHEST, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_OPEN_CHEST] = Item(RG_OPEN_CHEST, Text{ "Open Chests", "Ouvrir des coffres", TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_KEY_SMALL, true, LOGIC_NONE, RHT_OPEN_CHEST, RG_OPEN_CHEST, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OPEN_CHEST].SetCustomDrawFunc(Randomizer_DrawOpenChest); - itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "un "}).CustomIcon(gItemIconBombchuTex); + itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "un ", "eine "}).CustomIcon(gItemIconBombchuTex); itemTable[RG_PROGRESSIVE_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); - itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "le "}).CustomIcon(gItemIconQuiver50Tex); - itemTable[RG_BOMB_BAG_INF] = Item(RG_BOMB_BAG_INF, Text{ "Infinite Bomb Bag", "Sac de Bombes Infini", "Unendliche Bombentasche" }, ITEMTYPE_ITEM, RG_BOMB_BAG_INF, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BOMB_BAG_INF, RG_BOMB_BAG_INF, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "le "}).CustomIcon(gItemIconBombBag40Tex); - itemTable[RG_BULLET_BAG_INF] = Item(RG_BULLET_BAG_INF, Text{ "Infinite Bullet Bag", "Sac de Graines Infinis", "Unendliche Samentasche" }, ITEMTYPE_ITEM, RG_BULLET_BAG_INF, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BULLET_BAG_INF, RG_BULLET_BAG_INF, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "le "}).CustomIcon(gItemIconBulletBag50Tex); - itemTable[RG_STICK_UPGRADE_INF] = Item(RG_STICK_UPGRADE_INF, Text{ "Infinite Stick Capacity", "Bâtons Mojo Infinis", "Unendliche Stab-Kapazität" }, ITEMTYPE_ITEM, RG_STICK_UPGRADE_INF, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_STICK_UPGRADE_INF, RG_STICK_UPGRADE_INF, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}).CustomIcon(gItemIconDekuStickTex); - itemTable[RG_NUT_UPGRADE_INF] = Item(RG_NUT_UPGRADE_INF, Text{ "Infinite Nut Capacity", "Noix Mojo Infinies", "Unendliche Nuß-Kapazität" }, ITEMTYPE_ITEM, RG_NUT_UPGRADE_INF, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_NUT_UPGRADE_INF, RG_NUT_UPGRADE_INF, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "die ", "la "}).CustomIcon(gItemIconDekuNutTex); - itemTable[RG_MAGIC_INF] = Item(RG_MAGIC_INF, Text{ "Infinite Magic Meter", "Magie Infinie", "Unendliches Magisches Maß" }, 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, {"the ", "die ", "le "}).CustomIcon(gQuestIconMagicJarBigTex, ICON_SIZE_24); - itemTable[RG_BOMBCHU_INF] = Item(RG_BOMBCHU_INF, Text{ "Infinite Bombchus", "Missiles Teigneux Infinis", "Unendliche Krabbelminen" }, 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, {"the ", "den ", "les "}).CustomIcon(gItemIconBombchuTex); + itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "le ", "den "}).CustomIcon(gItemIconQuiver50Tex); + itemTable[RG_BOMB_BAG_INF] = Item(RG_BOMB_BAG_INF, Text{ "Infinite Bomb Bag", "Sac de Bombes Infini", "Unendliche Bombentasche" }, ITEMTYPE_ITEM, RG_BOMB_BAG_INF, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BOMB_BAG_INF, RG_BOMB_BAG_INF, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "le ", "die "}).CustomIcon(gItemIconBombBag40Tex); + itemTable[RG_BULLET_BAG_INF] = Item(RG_BULLET_BAG_INF, Text{ "Infinite Bullet Bag", "Sac de Graines Infinis", "Unendliche Samentasche" }, ITEMTYPE_ITEM, RG_BULLET_BAG_INF, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BULLET_BAG_INF, RG_BULLET_BAG_INF, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "le ", "die "}).CustomIcon(gItemIconBulletBag50Tex); + itemTable[RG_STICK_UPGRADE_INF] = Item(RG_STICK_UPGRADE_INF, Text{ "Infinite Stick Capacity", "Bâtons Mojo Infinis", "Unendliche Stab-Kapazität" }, ITEMTYPE_ITEM, RG_STICK_UPGRADE_INF, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_STICK_UPGRADE_INF, RG_STICK_UPGRADE_INF, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "les ", "die "}).CustomIcon(gItemIconDekuStickTex); + itemTable[RG_NUT_UPGRADE_INF] = Item(RG_NUT_UPGRADE_INF, Text{ "Infinite Nut Capacity", "Noix Mojo Infinies", "Unendliche Nuß-Kapazität" }, ITEMTYPE_ITEM, RG_NUT_UPGRADE_INF, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_NUT_UPGRADE_INF, RG_NUT_UPGRADE_INF, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "les ", "die "}).CustomIcon(gItemIconDekuNutTex); + itemTable[RG_MAGIC_INF] = Item(RG_MAGIC_INF, Text{ "Infinite Magic Meter", "Magie Infinie", "Unendliches Magisches Maß" }, 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, {"the ", "la ", "die "}).CustomIcon(gQuestIconMagicJarBigTex, ICON_SIZE_24); + itemTable[RG_BOMBCHU_INF] = Item(RG_BOMBCHU_INF, Text{ "Infinite Bombchus", "Missiles Teigneux Infinis", "Unendliche Krabbelminen" }, 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, {"the ", "les ", "den "}).CustomIcon(gItemIconBombchuTex); 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, {"the ", "die ", "le "}).CustomIcon(gItemIconGiantsWalletTex); + 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, {"the ", "la ", "die "}).CustomIcon(gItemIconGiantsWalletTex); - 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, {"the ", "den ", "la "}); + 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, {"the ", "la ", "den "}); itemTable[RG_SKELETON_KEY].SetCustomDrawFunc(Randomizer_DrawSkeletonKey); - itemTable[RG_DEKU_STICK_BAG] = Item(RG_DEKU_STICK_BAG, Text{ "Deku Stick Bag", "Sac de Bâton Mojo", "Deku-Stab-Tasche" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_NONE, RG_DEKU_STICK_BAG, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "un "}).CustomIcon(gItemIconDekuStickTex); + itemTable[RG_DEKU_STICK_BAG] = Item(RG_DEKU_STICK_BAG, Text{ "Deku Stick Bag", "Sac de Bâton Mojo", "Deku-Stab-Tasche" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_NONE, RG_DEKU_STICK_BAG, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "un ", "eine "}).CustomIcon(gItemIconDekuStickTex); - itemTable[RG_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "Sac de Noix Mojo", "Deku-Nuß-Tasche" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_NONE, RG_DEKU_NUT_BAG, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "un "}).CustomIcon(gItemIconDekuNutTex); + itemTable[RG_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "Sac de Noix Mojo", "Deku-Nuß-Tasche" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_NONE, RG_DEKU_NUT_BAG, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "un ", "eine "}).CustomIcon(gItemIconDekuNutTex); - itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_EVENT, RG_TRIFORCE, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_MAJOR, {"the ", "die ", "la "}); + itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_EVENT, RG_TRIFORCE, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_MAJOR, {"the ", "la ", "die "}); itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_LESSER); // Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen) - itemTable[RG_HOOKSHOT] = Item(RG_HOOKSHOT, Text{ "Hookshot", "Grappin", "Fanghaken" }, ITEMTYPE_ITEM, GI_HOOKSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_HOOKSHOT, ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_LONGSHOT] = Item(RG_LONGSHOT, Text{ "Longshot", "Super-Grappin", "Enterhaken" }, ITEMTYPE_ITEM, GI_LONGSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_LONGSHOT, ITEM_LONGSHOT, OBJECT_GI_HOOKSHOT, GID_LONGSHOT, 0x4F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_FAIRY_OCARINA] = Item(RG_FAIRY_OCARINA, Text{ "Fairy Ocarina", "Ocarina des fées", "Feen-Okarina" }, ITEMTYPE_ITEM, GI_OCARINA_FAIRY, true, LOGIC_PROGRESSIVE_OCARINA, RHT_FAIRY_OCARINA, ITEM_OCARINA_FAIRY, OBJECT_GI_OCARINA_0, GID_OCARINA_FAIRY, 0x4A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "la "}); - itemTable[RG_OCARINA_OF_TIME] = Item(RG_OCARINA_OF_TIME, Text{ "Ocarina of Time", "Ocarina du Temps", "Okarina der Zeit" }, ITEMTYPE_ITEM, GI_OCARINA_OOT, true, LOGIC_PROGRESSIVE_OCARINA, RHT_OCARINA_OF_TIME, ITEM_OCARINA_TIME, OBJECT_GI_OCARINA, GID_OCARINA_TIME, 0x3A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "le "}); - itemTable[RG_BOMB_BAG] = Item(RG_BOMB_BAG, Text{ "Bomb Bag", "Sac de Bombes", "Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_20, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BOMB_BAG, ITEM_BOMB_BAG_20, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_20, 0x58, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "le "}); - itemTable[RG_BIG_BOMB_BAG] = Item(RG_BIG_BOMB_BAG, Text{ "Big Bomb Bag", "Grand Sac de Bombes", "Große Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_30, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BIG_BOMB_BAG, ITEM_BOMB_BAG_30, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_30, 0x59, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "die ", "le "}); - itemTable[RG_BIGGEST_BOMB_BAG] = Item(RG_BIGGEST_BOMB_BAG, Text{ "Biggest Bomb Bag", "Énorme Sac de Bombes", "Größte Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_40, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BIGGEST_BOMB_BAG, ITEM_BOMB_BAG_40, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, 0x5A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "die ", "le "}); - itemTable[RG_FAIRY_BOW] = Item(RG_FAIRY_BOW, Text{ "Fairy Bow", "Arc des Fées", "Feen-Bogen" }, ITEMTYPE_ITEM, GI_BOW, true, LOGIC_PROGRESSIVE_BOW, RHT_FAIRY_BOW, ITEM_BOW, OBJECT_GI_BOW, GID_BOW, 0x31, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_BIG_QUIVER] = Item(RG_BIG_QUIVER, Text{ "Big Quiver", "Grand carquois", "Großer Köcher" }, ITEMTYPE_ITEM, GI_QUIVER_40, true, LOGIC_PROGRESSIVE_BOW, RHT_BIG_QUIVER, ITEM_QUIVER_40, OBJECT_GI_ARROWCASE, GID_QUIVER_40, 0x56, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_BIGGEST_QUIVER] = Item(RG_BIGGEST_QUIVER, Text{ "Biggest Quiver", "Énorme carquois", "Größter Köcher" }, ITEMTYPE_ITEM, GI_QUIVER_50, true, LOGIC_PROGRESSIVE_BOW, RHT_BIGGEST_QUIVER, ITEM_QUIVER_50, OBJECT_GI_ARROWCASE, GID_QUIVER_50, 0x57, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_FAIRY_SLINGSHOT] = Item(RG_FAIRY_SLINGSHOT, Text{ "Fairy Slingshot", "Lance-Pierre des Fées", "Feen-Schleuder" }, ITEMTYPE_ITEM, GI_SLINGSHOT, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_FAIRY_SLINGSHOT, ITEM_SLINGSHOT, OBJECT_GI_PACHINKO, GID_SLINGSHOT, 0x30, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "le "}); - itemTable[RG_BIG_BULLET_BAG] = Item(RG_BIG_BULLET_BAG, Text{ "Big Deku Seed Bullet Bag", "Grand sac de graines mojo", "Große Deku-Samentasche" }, ITEMTYPE_ITEM, GI_BULLET_BAG_40, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BIG_BULLET_BAG, ITEM_BULLET_BAG_40, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_BIGGEST_BULLET_BAG] = Item(RG_BIGGEST_BULLET_BAG, Text{ "Biggest Deku Seed Bullet Bag", "Énorme sac de graines mojo", "Größte Deku-Samentasche" }, ITEMTYPE_ITEM, GI_BULLET_BAG_50, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BIGGEST_BULLET_BAG, ITEM_BULLET_BAG_50, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "den ", "le "}); - itemTable[RG_GORONS_BRACELET] = Item(RG_GORONS_BRACELET, Text{ "Goron's Bracelet", "Bracelet Goron", "Goronen-Armband" }, ITEMTYPE_ITEM, GI_BRACELET, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_GORONS_BRACELET, ITEM_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, 0x79, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "das ", "le "}); - itemTable[RG_SILVER_GAUNTLETS] = Item(RG_SILVER_GAUNTLETS, Text{ "Silver Gauntlets", "Gantelets d'argent", "Silberhandschuhe" }, ITEMTYPE_ITEM, GI_GAUNTLETS_SILVER, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_SILVER_GAUNTLETS, ITEM_GAUNTLETS_SILVER, OBJECT_GI_GLOVES, GID_GAUNTLETS_SILVER, 0x5B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "die ", "les "}); - itemTable[RG_GOLDEN_GAUNTLETS] = Item(RG_GOLDEN_GAUNTLETS, Text{ "Golden Gauntlets", "Gantelets d'or", "Goldhandschuhe" }, 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, {"the ", "die ", "les "}); - 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, {"the ", "die ", "le "}); - 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, {"the ", "die ", "le "}); - itemTable[RG_ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{ "Adult Wallet", "Grande Bourse", "Erwachsenengeldbö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, {"the ", "die ", "le "}); - itemTable[RG_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesige Geldbö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, {"the ", "die ", "le "}); - 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, {"the ", "die ", "le "}).CustomIcon(gItemIconGiantsWalletTex); - 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, {"the ", "die ", "le "}).CustomIcon(gItemIconAdultsWalletTex); + itemTable[RG_HOOKSHOT] = Item(RG_HOOKSHOT, Text{ "Hookshot", "Grappin", "Fanghaken" }, ITEMTYPE_ITEM, GI_HOOKSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_HOOKSHOT, ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "}); + itemTable[RG_LONGSHOT] = Item(RG_LONGSHOT, Text{ "Longshot", "Super-Grappin", "Enterhaken" }, ITEMTYPE_ITEM, GI_LONGSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_LONGSHOT, ITEM_LONGSHOT, OBJECT_GI_HOOKSHOT, GID_LONGSHOT, 0x4F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "}); + itemTable[RG_FAIRY_OCARINA] = Item(RG_FAIRY_OCARINA, Text{ "Fairy Ocarina", "Ocarina des fées", "Feen-Okarina" }, ITEMTYPE_ITEM, GI_OCARINA_FAIRY, true, LOGIC_PROGRESSIVE_OCARINA, RHT_FAIRY_OCARINA, ITEM_OCARINA_FAIRY, OBJECT_GI_OCARINA_0, GID_OCARINA_FAIRY, 0x4A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "l'", "die "}); + itemTable[RG_OCARINA_OF_TIME] = Item(RG_OCARINA_OF_TIME, Text{ "Ocarina of Time", "Ocarina du Temps", "Okarina der Zeit" }, ITEMTYPE_ITEM, GI_OCARINA_OOT, true, LOGIC_PROGRESSIVE_OCARINA, RHT_OCARINA_OF_TIME, ITEM_OCARINA_TIME, OBJECT_GI_OCARINA, GID_OCARINA_TIME, 0x3A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "l'", "die "}); + itemTable[RG_BOMB_BAG] = Item(RG_BOMB_BAG, Text{ "Bomb Bag", "Sac de Bombes", "Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_20, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BOMB_BAG, ITEM_BOMB_BAG_20, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_20, 0x58, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "die "}); + itemTable[RG_BIG_BOMB_BAG] = Item(RG_BIG_BOMB_BAG, Text{ "Big Bomb Bag", "Grand Sac de Bombes", "Große Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_30, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BIG_BOMB_BAG, ITEM_BOMB_BAG_30, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_30, 0x59, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "le ", "die "}); + itemTable[RG_BIGGEST_BOMB_BAG] = Item(RG_BIGGEST_BOMB_BAG, Text{ "Biggest Bomb Bag", "Énorme Sac de Bombes", "Größte Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_40, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BIGGEST_BOMB_BAG, ITEM_BOMB_BAG_40, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, 0x5A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "l'", "die "}); + itemTable[RG_FAIRY_BOW] = Item(RG_FAIRY_BOW, Text{ "Fairy Bow", "Arc des Fées", "Feen-Bogen" }, ITEMTYPE_ITEM, GI_BOW, true, LOGIC_PROGRESSIVE_BOW, RHT_FAIRY_BOW, ITEM_BOW, OBJECT_GI_BOW, GID_BOW, 0x31, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "l'", "den "}); + itemTable[RG_BIG_QUIVER] = Item(RG_BIG_QUIVER, Text{ "Big Quiver", "Grand carquois", "Großer Köcher" }, ITEMTYPE_ITEM, GI_QUIVER_40, true, LOGIC_PROGRESSIVE_BOW, RHT_BIG_QUIVER, ITEM_QUIVER_40, OBJECT_GI_ARROWCASE, GID_QUIVER_40, 0x56, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "le ", "den "}); + itemTable[RG_BIGGEST_QUIVER] = Item(RG_BIGGEST_QUIVER, Text{ "Biggest Quiver", "Énorme carquois", "Größter Köcher" }, ITEMTYPE_ITEM, GI_QUIVER_50, true, LOGIC_PROGRESSIVE_BOW, RHT_BIGGEST_QUIVER, ITEM_QUIVER_50, OBJECT_GI_ARROWCASE, GID_QUIVER_50, 0x57, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "l' ", "den "}); + itemTable[RG_FAIRY_SLINGSHOT] = Item(RG_FAIRY_SLINGSHOT, Text{ "Fairy Slingshot", "Lance-Pierre des Fées", "Feen-Schleuder" }, ITEMTYPE_ITEM, GI_SLINGSHOT, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_FAIRY_SLINGSHOT, ITEM_SLINGSHOT, OBJECT_GI_PACHINKO, GID_SLINGSHOT, 0x30, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "die "}); + itemTable[RG_BIG_BULLET_BAG] = Item(RG_BIG_BULLET_BAG, Text{ "Big Deku Seed Bullet Bag", "Grand sac de graines mojo", "Große Deku-Samentasche" }, ITEMTYPE_ITEM, GI_BULLET_BAG_40, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BIG_BULLET_BAG, ITEM_BULLET_BAG_40, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "le ", "den "}); + itemTable[RG_BIGGEST_BULLET_BAG] = Item(RG_BIGGEST_BULLET_BAG, Text{ "Biggest Deku Seed Bullet Bag", "Énorme sac de graines mojo", "Größte Deku-Samentasche" }, ITEMTYPE_ITEM, GI_BULLET_BAG_50, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BIGGEST_BULLET_BAG, ITEM_BULLET_BAG_50, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, {"the ", "l'", "den "}); + itemTable[RG_GORONS_BRACELET] = Item(RG_GORONS_BRACELET, Text{ "Goron's Bracelet", "Bracelet Goron", "Goronen-Armband" }, ITEMTYPE_ITEM, GI_BRACELET, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_GORONS_BRACELET, ITEM_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, 0x79, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "das "}); + itemTable[RG_SILVER_GAUNTLETS] = Item(RG_SILVER_GAUNTLETS, Text{ "Silver Gauntlets", "Gantelets d'argent", "Silberhandschuhe" }, ITEMTYPE_ITEM, GI_GAUNTLETS_SILVER, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_SILVER_GAUNTLETS, ITEM_GAUNTLETS_SILVER, OBJECT_GI_GLOVES, GID_GAUNTLETS_SILVER, 0x5B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "les ", "die "}); + itemTable[RG_GOLDEN_GAUNTLETS] = Item(RG_GOLDEN_GAUNTLETS, Text{ "Golden Gauntlets", "Gantelets d'or", "Goldhandschuhe" }, 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, {"the ", "les ", "die "}); + 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, {"the ", "l'", "die "}); + 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, {"the ", "l'", "die "}); + itemTable[RG_ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{ "Adult Wallet", "Grande Bourse", "Erwachsenengeldbö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, {"the ", "la ", "die "}); + itemTable[RG_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesige Geldbö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, {"the ", "la ", "die "}); + 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, {"the ", "la ", "die "}).CustomIcon(gItemIconGiantsWalletTex); + 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, {"the ", "la ", "die "}).CustomIcon(gItemIconAdultsWalletTex); 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).CustomIcon(gItemIconDekuNutTex); 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).CustomIcon(gItemIconDekuNutTex); 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).CustomIcon(gItemIconDekuStickTex); itemTable[RG_DEKU_STICK_CAPACITY_30] = Item(RG_DEKU_STICK_CAPACITY_30, Text{ "Deku Stick Capacity (30)", "Capacité de Bâtons Mojo (30)", "Deku-Stab-Kapazität (30)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_DEKU_STICK_CAPACITY_30, ITEM_STICK_UPGRADE_30, OBJECT_GI_STICK, GID_STICK, 0x91, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE).CustomIcon(gItemIconDekuStickTex); - itemTable[RG_MAGIC_SINGLE] = Item(RG_MAGIC_SINGLE, Text{ "Magic Meter", "Jauge de Magie", "Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_SINGLE, RG_MAGIC_SINGLE, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "das ", "le "}).CustomIcon(gQuestIconMagicJarSmallTex, ICON_SIZE_24); - itemTable[RG_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verbessertes Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_DOUBLE, RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "das ", "le "}).CustomIcon(gQuestIconMagicJarBigTex, ICON_SIZE_24); - itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Triforce Piece", "Triforce-Fragment" }, ITEMTYPE_ITEM, 0xDF, true, LOGIC_TRIFORCE_PIECES, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "ein ", "un "}).CustomIcon(gTriforcePieceTex); - itemTable[RG_ROCS_FEATHER] = Item(RG_ROCS_FEATHER, Text{ "Roc's Feather", "Roc's Feather", "Roc's Feather" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_ROCS_FEATHER, RHT_ROCS_FEATHER, RG_ROCS_FEATHER, OBJECT_GI_BOMB_2, GID_ROCS_FEATHER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "ein ", "un "}).CustomIcon(gRocsFeatherTex); + itemTable[RG_MAGIC_SINGLE] = Item(RG_MAGIC_SINGLE, Text{ "Magic Meter", "Jauge de Magie", "Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_SINGLE, RG_MAGIC_SINGLE, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "das "}).CustomIcon(gQuestIconMagicJarSmallTex, ICON_SIZE_24); + itemTable[RG_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verbessertes Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_DOUBLE, RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "la ", "das "}).CustomIcon(gQuestIconMagicJarBigTex, ICON_SIZE_24); + itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Morceau de Triforce", "Triforce-Fragment" }, ITEMTYPE_ITEM, 0xDF, true, LOGIC_TRIFORCE_PIECES, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "un ", "ein "}).CustomIcon(gTriforcePieceTex); + itemTable[RG_ROCS_FEATHER] = Item(RG_ROCS_FEATHER, Text{ "Roc's Feather", "Plume de Roc", "Grefenfeider" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_ROCS_FEATHER, RHT_ROCS_FEATHER, RG_ROCS_FEATHER, OBJECT_GI_BOMB_2, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "la ", "ein "}).CustomIcon(gRocsFeatherTex); itemTable[RG_ROCS_FEATHER].SetCustomDrawFunc(Randomizer_DrawRocsFeather); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/item_location.cpp b/soh/soh/Enhancements/randomizer/item_location.cpp index 01d31ed6d6..713bb560d0 100644 --- a/soh/soh/Enhancements/randomizer/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/item_location.cpp @@ -1,6 +1,7 @@ #include "item_location.h" #include "SeedContext.h" #include "logic.h" +#include "3drando/random.hpp" namespace Rando { ItemLocation::ItemLocation() : rc(RC_UNKNOWN_CHECK) { diff --git a/soh/soh/Enhancements/randomizer/item_location.h b/soh/soh/Enhancements/randomizer/item_location.h index a04f5c2cf9..54e3ea55ca 100644 --- a/soh/soh/Enhancements/randomizer/item_location.h +++ b/soh/soh/Enhancements/randomizer/item_location.h @@ -1,7 +1,7 @@ #pragma once #include "randomizerTypes.h" -#include "3drando/text.hpp" +#include "soh/Enhancements/custom-message/text.h" #include "static_data.h" #include "option.h" diff --git a/soh/soh/Enhancements/randomizer/item_override.h b/soh/soh/Enhancements/randomizer/item_override.h index 355d1e51e1..8ab34c0ad3 100644 --- a/soh/soh/Enhancements/randomizer/item_override.h +++ b/soh/soh/Enhancements/randomizer/item_override.h @@ -1,7 +1,7 @@ #pragma once #include "randomizerTypes.h" -#include "3drando/text.hpp" +#include "soh/Enhancements/custom-message/text.h" namespace Rando { /// @brief Class representing overrides of individual items. Used for trick names and models for ice traps. diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index cb2d6dbe5b..a530051a81 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -562,6 +562,23 @@ Rando::Location Rando::Location::SmallCrate(RandomizerCheck rc, RandomizerCheckQ false, collectionCheck }; } +Rando::Location Rando::Location::Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_ROCK, area_, ACTOR_EN_ISHI, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + +Rando::Location Rando::Location::Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_BOULDER, area_, ACTOR_EN_ISHI, + scene_, actorParams_, std::move(shortName_), hintKey, RG_BOMBS_5, + 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, @@ -589,6 +606,15 @@ Rando::Location Rando::Location::Bush(RandomizerCheck rc, RandomizerCheckQuest q false, collectionCheck }; } +Rando::Location Rando::Location::WonderItem(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_WONDER_ITEM, area_, ACTOR_EN_WONDER_ITEM, + 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, @@ -629,6 +655,15 @@ Rando::Location Rando::Location::SongFairy(RandomizerCheck rc, RandomizerCheckQu false, collectionCheck }; } +Rando::Location Rando::Location::ButterflyFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, + RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, RandomizerHintTextKey hintKey, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_BUTTERFLY_FAIRY, area_, ACTOR_EN_BUTTE, + scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE, + false, collectionCheck }; +} + Rando::Location Rando::Location::Grass(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, @@ -637,3 +672,27 @@ Rando::Location Rando::Location::Grass(RandomizerCheck rc, RandomizerCheckQuest scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, false, collectionCheck }; } + +Rando::Location Rando::Location::Sign(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, ActorID actorId, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_SIGN, area_, actorId, scene_, actorParams_, std::move(shortName_), + hintKey, RG_NONE, false, collectionCheck }; +} + +Rando::Location Rando::Location::Icicle(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_ICICLE, area_, ACTOR_BG_ICE_TURARA, + scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE, + false, collectionCheck }; +} + +Rando::Location Rando::Location::RedIce(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_RED_ICE, area_, ACTOR_BG_ICE_SHELTER, + scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE, + false, collectionCheck }; +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index 24b192cc34..9426ebd36c 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -67,15 +67,7 @@ class Location { actorParams(actorParams_), shortName(std::move(shortName_)), spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - if (spoilerName.length() < 23) { - excludedOption = LocationOption(rc, spoilerName); - } else { - const size_t lastSpace = spoilerName.rfind(' ', 23); - std::string settingText = spoilerName; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = LocationOption(rc, spoilerName); - } + excludedOption = LocationOption(rc, spoilerName); } Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, @@ -87,15 +79,7 @@ class Location { actorParams(actorParams_), shortName(shortName_), spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - if (spoilerName.length() < 23) { - excludedOption = LocationOption(rc, spoilerName); - } else { - const size_t lastSpace = spoilerName.rfind(' ', 23); - std::string settingText = spoilerName; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = LocationOption(rc, spoilerName); - } + excludedOption = LocationOption(rc, spoilerName); } static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) { @@ -245,6 +229,14 @@ class Location { RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + + static Location Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + 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); @@ -257,6 +249,23 @@ class Location { int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location Sign(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + ActorID actorId_, SpoilerCollectionCheck collectionCheck); + + static Location WonderItem(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck); + + static Location Icicle(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + SpoilerCollectionCheck collectionCheck); + + static Location RedIce(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + SpoilerCollectionCheck collectionCheck); + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_); @@ -282,6 +291,10 @@ class Location { SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck); + static Location ButterflyFairy(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_); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index c63ca54a4f..a802598ea7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -120,7 +120,7 @@ void RegionTable_Init_BottomOfTheWell() { ENTRANCE(RR_BOTW_B3_OOZE, true), }); - areaTable[RR_BOTW_SKULL_WALL_ROOM] = Region("Bottom of the Well SKull Wall Room", SCENE_BOTTOM_OF_THE_WELL, { + areaTable[RR_BOTW_SKULL_WALL_ROOM] = Region("Bottom of the Well Skull Wall Room", SCENE_BOTTOM_OF_THE_WELL, { //Events EVENT_ACCESS(LOGIC_STICK_ACCESS, logic->CanGetDekuBabaSticks()), EVENT_ACCESS(LOGIC_NUT_ACCESS, logic->CanGetDekuBabaNuts()), @@ -203,17 +203,32 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_BOTW_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_3, logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_BASEMENT)) || + (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_BOTW_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_6, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_BOTW_HIDDEN_POTS, logic->CanClimbHighLadder()), //It's possible to abuse boulder's limited range of collision detection to detonate the flowers through the boulder with bow, but this is a glitch //the exact range is just past the furthest away plank in the green goo section - ENTRANCE(RR_BOTW_B3_BOMB_FLOWERS, AnyAgeTime([]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BOTW_BASEMENT) && logic->CanUse(RG_STICKS)) || (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanUse(RG_FAIRY_BOW));})), + ENTRANCE(RR_BOTW_B3_BOMB_FLOWERS, AnyAgeTime([]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BOTW_BASEMENT) && logic->CanUse(RG_STICKS)) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_FAIRY_BOW));})), ENTRANCE(RR_BOTW_B3_BLOCKED_GRASS, AnyAgeTime([]{return logic->BlastOrSmash();})), ENTRANCE(RR_BOTW_B3_CHEST_AREA, AnyAgeTime([]{return logic->BlastOrSmash();})), }); - areaTable[RR_BOTW_B3_BOMB_FLOWERS] = Region("Bottom of the Well B3 Bomb Flowers", SCENE_BOTTOM_OF_THE_WELL, {}, {}, { + areaTable[RR_BOTW_B3_BOMB_FLOWERS] = Region("Bottom of the Well B3 Bomb Flowers", SCENE_BOTTOM_OF_THE_WELL, {}, { + //Locations + LOCATION(RC_BOTW_BOULDER_1, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_2, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_3, logic->CanDetonateUprightBombFlower()), + LOCATION(RC_BOTW_BOULDER_4, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_5, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_6, logic->HasItem(RG_GORONS_BRACELET)), + }, { //Exits ENTRANCE(RR_BOTW_B3_OOZE, logic->CanDetonateUprightBombFlower()), ENTRANCE(RR_BOTW_B3_BLOCKED_GRASS, logic->HasItem(RG_GORONS_BRACELET)), @@ -268,7 +283,7 @@ void RegionTable_Init_BottomOfTheWell() { //Item extension can get a fairy by either shooting the pot through the grate and letting the fairy fly through the wall //This cannot be done if the pot has an item in it, as it cannot be collected this way. (ctx->GetTrickOption(RT_ITEM_EXTENSION) && (ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_OFF) || ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_OVERWORLD)) && logic->CanHitEyeTargets()) || - (ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->IsChild ? logic->CanHitEyeTargets() : logic->CanUse(RG_FAIRY_SLINGSHOT))), + (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->IsChild ? logic->CanHitEyeTargets() : logic->CanUse(RG_FAIRY_SLINGSHOT))), //It is possible to hit the water switch with a pot from RR_BOTW_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 @@ -280,10 +295,21 @@ void RegionTable_Init_BottomOfTheWell() { //Instead of blowing up the boulder, you can aim through the lower left side with sling(either age) or as child with bow //Not even bow extension seems to get adult's bow to work //this would be a trick - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, (AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()) || - (ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->IsChild ? logic->CanHitEyeTargets() : logic->CanUse(RG_FAIRY_SLINGSHOT))), - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()), - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, (AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()) || + (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->IsChild ? logic->CanHitEyeTargets() : logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()), + LOCATION(RC_BOTW_MQ_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4, logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits ENTRANCE(RR_BOTW_ENTRYWAY, logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT))), @@ -321,6 +347,10 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4, logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits ENTRANCE(RR_BOTW_MQ_MIDDLE, true), @@ -350,7 +380,11 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_MQ_PIT_CAGE] = Region("Bottom of the Well MQ Pit Cage", SCENE_BOTTOM_OF_THE_WELL, { //Events EVENT_ACCESS(LOGIC_BOTW_MQ_OPENED_WEST_ROOM, true), - }, {}, { + }, { + //Locations + LOCATION(RC_BOTW_MQ_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_3, logic->BlastOrSmash()), + }, { //Exits ENTRANCE(RR_BOTW_MQ_PERIMETER, logic->BlastOrSmash() && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || ctx->GetTrickOption(RT_BOTW_PITS))), ENTRANCE(RR_BOTW_MQ_MIDDLE, (bool)ctx->GetTrickOption(RT_BOTW_PITS)), @@ -367,9 +401,9 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_MQ_CRYPT] = Region("Bottom of the Well MQ Crypt", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), }, { //Exits ENTRANCE(RR_BOTW_MQ_BEHIND_MOAT, logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2)), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index dfda237195..7e7cb56e43 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -63,7 +63,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_2F_MIDDLE_ROOM] = Region("Deku Tree 2F Middle Room", SCENE_DEKU_TREE, {}, {}, { //Exits - ENTRANCE(RR_DEKU_TREE_LOBBY, AnyAgeTime([]{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);})), + ENTRANCE(RR_DEKU_TREE_LOBBY_2F, AnyAgeTime([]{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);})), ENTRANCE(RR_DEKU_TREE_SLINGSHOT_ROOM, AnyAgeTime([]{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);})), }); @@ -93,7 +93,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_COMPASS_GRASS_2, logic->CanCutShrubs()), }, { //Exits - ENTRANCE(RR_DEKU_TREE_LOBBY, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + ENTRANCE(RR_DEKU_TREE_LOBBY_3F, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), ENTRANCE(RR_DEKU_TREE_BOSS_ENTRYWAY, false), }); @@ -189,7 +189,10 @@ void RegionTable_Init_DekuTree() { EVENT_ACCESS(LOGIC_NUT_ACCESS, logic->CanGetDekuBabaNuts()), EVENT_ACCESS(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK, logic->HasItem(RG_POWER_BRACELET)), EVENT_ACCESS(LOGIC_DEKU_TREE_B1_BROKE_WEB, logic->HasFireSource()), - }, {}, { + }, { + //Locations + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, !!ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), + }, { //Exits ENTRANCE(RR_DEKU_TREE_BASEMENT_LOWER, true), ENTRANCE(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, logic->CanUse(RG_CRAWL)), @@ -200,9 +203,10 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_OUTSIDE_BOSS_ROOM] = Region("Deku Tree Outside Boss Room", SCENE_DEKU_TREE, {}, { //Locations - LOCATION(RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, logic->IsAdult || (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + // Can be grabbed by jumping to it from above, might deserve its own trick + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ((logic->CanUse(RG_HOVER_BOOTS) || logic->IsAdult) && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, logic->IsAdult || (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), LOCATION(RC_DEKU_TREE_BEFORE_BOSS_GRASS_1, logic->CanCutShrubs() && logic->HasFireSourceWithTorch()), LOCATION(RC_DEKU_TREE_BEFORE_BOSS_GRASS_2, logic->CanCutShrubs() && logic->HasFireSourceWithTorch()), LOCATION(RC_DEKU_TREE_BEFORE_BOSS_GRASS_3, logic->CanCutShrubs() && logic->HasFireSourceWithTorch()), @@ -314,16 +318,26 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_3, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_1, logic->CanUse(RG_BOOMERANG) && + AnyAgeTime([]{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS)));})), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_2, logic->CanUse(RG_BOOMERANG) && + AnyAgeTime([]{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS)));})), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_3, logic->CanUse(RG_BOOMERANG) && + AnyAgeTime([]{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS)));})), }, { //Exits ENTRANCE(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, true), - ENTRANCE(RR_DEKU_TREE_MQ_PAST_BOULDER_VINES, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME))) && AnyAgeTime([]{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_MEGATON_HAMMER) && ((logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) && logic->HasItem(RG_CLIMB))));})), + ENTRANCE(RR_DEKU_TREE_MQ_PAST_BOULDER_VINES, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME))) && + AnyAgeTime([]{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_MEGATON_HAMMER) && ((logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) && logic->HasItem(RG_CLIMB))));})), }); areaTable[RR_DEKU_TREE_MQ_PAST_BOULDER_VINES] = Region("Deku Tree MQ Past Boulder Vines", SCENE_DEKU_TREE, {}, { //Locations LOCATION(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_3, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_DEKU_TREE_MQ_COMPASS_ROOM, logic->BlastOrSmash()), @@ -421,6 +435,10 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_1, logic->CanJumpslashExceptHammer()), + LOCATION(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_2, logic->CanJumpslashExceptHammer()), + LOCATION(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_3, logic->CanJumpslashExceptHammer()), + LOCATION(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_4, logic->CanJumpslashExceptHammer()), }, { //Exits ENTRANCE(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, logic->CanUse(RG_CRAWL) && AnyAgeTime([]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);})), @@ -447,10 +465,11 @@ void RegionTable_Init_DekuTree() { EVENT_ACCESS(LOGIC_DEKU_TREE_B1_BROKE_WEB, logic->HasFireSource()), }, { //Locations - LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), - LOCATION(RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), + LOCATION(RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, !!ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), }, { //Exits ENTRANCE(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, logic->CanUse(RG_CRAWL)), @@ -461,9 +480,9 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = Region("Deku Tree MQ Outside Boss Room", SCENE_DEKU_TREE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, logic->IsAdult || (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ((logic->CanUse(RG_HOVER_BOOTS) || logic->IsAdult) && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, logic->IsAdult || (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3, logic->CanCutShrubs()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index a562b6c1d1..357a2f9868 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -242,6 +242,7 @@ void RegionTable_Init_DodongosCavern() { }, { //Locations LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, logic->CanBreakMudWalls() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL, logic->CanRead()), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_LOBBY, true), @@ -291,6 +292,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_BEGINNING, true), @@ -328,7 +331,13 @@ void RegionTable_Init_DodongosCavern() { //Events EVENT_ACCESS(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE)), EVENT_ACCESS(LOGIC_DC_EYES_LIT, logic->HasExplosives() || (logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS) && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))))), - }, {}, { + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + LOCATION(RC_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL, logic->CanRead()), + }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_LOBBY, true), ENTRANCE(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), @@ -452,6 +461,18 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, logic->BlastOrSmash() && (logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_BOOMERANG))), }, { //Exits //Falling down gets you stuck with nothing there, not a useful exit for logic @@ -465,11 +486,12 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, logic->BlastOrSmash() || (logic->HasItem(RG_GORONS_BRACELET) && (logic->CanHitSwitch() || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP)))), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, true), //crate platforming skips the puzzle - ENTRANCE(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, logic->IsAdult || (AnyAgeTime([]{return logic->BlastOrSmash() || (logic->CanAttack() && logic->HasItem(RG_GORONS_BRACELET));}))), + ENTRANCE(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, logic->IsAdult || (AnyAgeTime([]{return logic->BlastOrSmash() || (logic->CanAttack() && logic->HasItem(RG_GORONS_BRACELET));})) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP)), }); areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER] = Region("Dodongos Cavern MQ Torch Puzzle Upper", SCENE_DODONGOS_CAVERN, { @@ -491,10 +513,12 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE] = Region("Dodongos Cavern MQ Lower Right Side", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->EffectiveHealth() != 1 || logic->CanUse(RG_NAYRUS_LOVE)))), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_LOBBY, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index 60f51f75dc..9e50d285b6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -174,7 +174,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_SHORTCUT_ROOM] = Region("Fire Temple Shortcut Room", SCENE_FIRE_TEMPLE, {}, { }, { //Exits - ENTRANCE(RR_FIRE_TEMPLE_LAVA_GEYSER_1F, logic->SmallKeys(SCENE_FIRE_TEMPLE, 4)), + ENTRANCE(RR_FIRE_TEMPLE_LAVA_GEYSER_2F, logic->SmallKeys(SCENE_FIRE_TEMPLE, 4)), ENTRANCE(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT)), ENTRANCE(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, logic->IsAdult && logic->HasItem(RG_CLIMB) && ((logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH)) || logic->CanGroundJump()) && logic->CanHitSwitch(ED_BOMB_THROW)), }); @@ -283,7 +283,7 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)), }, { //Exits - ENTRANCE(RR_FIRE_TEMPLE_GS_CLIMB_4F, true), + ENTRANCE(RR_FIRE_TEMPLE_GS_CLIMB_5F, true), ENTRANCE(RR_FIRE_TEMPLE_NARROW_PATH_ROOM, logic->TakeDamage()), }); @@ -626,9 +626,11 @@ void RegionTable_Init_FireTemple() { EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanUse(RG_HOOKSHOT)), }, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, logic->HookshotOrBoomerang()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, logic->HookshotOrBoomerang()), + LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, logic->HookshotOrBoomerang()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, logic->HookshotOrBoomerang()), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW, logic->HookshotOrBoomerang() && logic->CanUse(RG_FAIRY_BOW)), }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, true), @@ -676,7 +678,12 @@ void RegionTable_Init_FireTemple() { ENTRANCE(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, true), }); - areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER] = Region("Fire Temple MQ Shortcut Room Lower", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER] = Region("Fire Temple MQ Shortcut Room Lower", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3, logic->CanUse(RG_MEGATON_HAMMER)), + }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_MID, (logic->HasFireSource() && (logic->IsAdult || (logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_CLIMB)))) || (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_CLIMB))), @@ -697,7 +704,10 @@ void RegionTable_Init_FireTemple() { ENTRANCE(RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE, true), }); - areaTable[RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE] = Region("Fire Temple MQ Lower Lizalfos Maze", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE] = Region("Fire Temple MQ Lower Lizalfos Maze", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_LIZALFOS_MAZE, logic->CanUse(RG_HOOKSHOT)), + }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, true), //Explosives can also reach this room. Chus is relatively simple, they need to detonate on the first horizontal bar up from the floor while horizontally near the switch, but bombs are much harder @@ -797,7 +807,13 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_TORCH_SLUG_CLIMB] = Region("Fire Temple MQ Torch Slug Climb", SCENE_FIRE_TEMPLE, { //Events EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanUse(RG_HOOKSHOT)), - }, {}, { + }, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2, logic->CanUse(RG_HOOKSHOT)), + }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_ABOVE_MAZE, true), ENTRANCE(RR_FIRE_TEMPLE_MQ_BURNING_BLOCK, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_CLIMB)), @@ -842,6 +858,7 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, logic->CanBreakCrates() && logic->FireTimer() >= 16), LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, logic->CanBreakSmallCrates() && logic->FireTimer() >= 24), LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, logic->CanBreakSmallCrates() && logic->FireTimer() >= 16), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_TORCH_ROOM, logic->CanUse(RG_HOOKSHOT) && logic->FireTimer() >= 16), }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_ABOVE_CAGE, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->FireTimer() >= 24), @@ -945,6 +962,7 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, logic->CanUse(RG_BOOMERANG)), LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE, logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_BOOMERANG)), }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_GS_LIZALFOS_ROOM, true), @@ -972,6 +990,7 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER, true), @@ -992,7 +1011,10 @@ void RegionTable_Init_FireTemple() { ENTRANCE(RR_FIRE_TEMPLE_MQ_LOCKED_CLIMB, true), }); - areaTable[RR_FIRE_TEMPLE_MQ_LOCKED_CLIMB] = Region("Fire Temple MQ Locked Climb", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_LOCKED_CLIMB] = Region("Fire Temple MQ Locked Climb", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_AFTER_FLARE_DANCER, logic->CanUse(RG_HOOKSHOT)), + }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER, true), ENTRANCE(RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_ROOM, logic->SmallKeys(SCENE_FIRE_TEMPLE, 4) && logic->HasItem(RG_CLIMB)), @@ -1032,7 +1054,10 @@ void RegionTable_Init_FireTemple() { ENTRANCE(RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_4F, logic->SmallKeys(SCENE_FIRE_TEMPLE, 5)), }); - areaTable[RR_FIRE_TEMPLE_MQ_BASE_OF_COLLAPSING_STAIRS] = Region("Fire Temple MQ Base of Collapsing Stairs", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_BASE_OF_COLLAPSING_STAIRS] = Region("Fire Temple MQ Base of Collapsing Stairs", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_STAIRCASE, logic->Get(LOGIC_FIRE_HIT_STAIRS) && logic->CanUse(RG_HOOKSHOT)), + }, { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_TOP_OF_COLLAPSING_STAIRS, logic->Get(LOGIC_FIRE_HIT_STAIRS) && logic->IsAdult), ENTRANCE(RR_FIRE_TEMPLE_MQ_ABOVE_FIRE_MAZE, logic->CanUse(RG_HOOKSHOT)), @@ -1052,7 +1077,10 @@ void RegionTable_Init_FireTemple() { #pragma endregion // Boss Room - areaTable[RR_FIRE_TEMPLE_BOSS_ENTRYWAY] = Region("Fire Temple Boss Entryway", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_BOSS_ENTRYWAY] = Region("Fire Temple Boss Entryway", SCENE_FIRE_TEMPLE, {}, { + // Locations + LOCATION(RC_FIRE_BOSS_KEY_HINT, true), + }, { // Exits ENTRANCE(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla() && false), ENTRANCE(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM, ctx->GetDungeon(FIRE_TEMPLE)->IsMQ() && false), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index 891b0e21f9..f60a0c2b89 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -21,7 +21,9 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_TREES] = Region("Forest Temple Trees", SCENE_FOREST_TEMPLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && ((logic->IsAdult && logic->CanUse(RG_BOMB_BAG)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslashExceptHammer() || (logic->IsChild && logic->CanUse(RG_BOMB_BAG)))))), + LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && + (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOOMERANG) || ((logic->IsAdult || ctx->GetTrickOption(RT_BOMB_DETONATION)) && logic->CanUse(RG_BOMB_BAG)) || + (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && logic->CanJumpslashExceptHammer()))), }, { //Exits ENTRANCE(RR_FOREST_TEMPLE_ENTRYWAY, true), @@ -192,8 +194,8 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_BLUE_BUBBLE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits - ENTRANCE(RR_FOREST_TEMPLE_NW_COURTYARD_LOWER, AnyAgeTime([]{return logic->CanKillEnemy(RE_BLUE_BUBBLE);})), - ENTRANCE(RR_FOREST_TEMPLE_NE_COURTYARD_UPPER, AnyAgeTime([]{return logic->CanKillEnemy(RE_BLUE_BUBBLE);})), + ENTRANCE(RR_FOREST_TEMPLE_NW_COURTYARD_UPPER_ALCOVE, AnyAgeTime([]{return logic->CanKillEnemy(RE_BLUE_BUBBLE);})), + ENTRANCE(RR_FOREST_TEMPLE_NE_COURTYARD_UPPER, AnyAgeTime([]{return logic->CanKillEnemy(RE_BLUE_BUBBLE);})), }); areaTable[RR_FOREST_TEMPLE_SEWER] = Region("Forest Temple Sewer", SCENE_FOREST_TEMPLE, {}, { @@ -207,7 +209,7 @@ void RegionTable_Init_ForestTemple() { ENTRANCE(RR_FOREST_TEMPLE_NE_COURTYARD_LOWER, logic->HasItem(RG_BRONZE_SCALE)), }); - areaTable[RR_FOREST_TEMPLE_DRAINED_SEWER] = Region("Forest Temple Drained Well", SCENE_FOREST_TEMPLE, {}, { + areaTable[RR_FOREST_TEMPLE_DRAINED_SEWER] = Region("Forest Temple Drained Sewer", SCENE_FOREST_TEMPLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, true), @@ -827,7 +829,10 @@ void RegionTable_Init_ForestTemple() { #pragma endregion // Boss Room - areaTable[RR_FOREST_TEMPLE_BOSS_ENTRYWAY] = Region("Forest Temple Boss Entryway", SCENE_FOREST_TEMPLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_BOSS_ENTRYWAY] = Region("Forest Temple Boss Entryway", SCENE_FOREST_TEMPLE, {}, { + // Locations + LOCATION(RC_FOREST_BOSS_KEY_HINT, true), + }, { // Exits ENTRANCE(RR_FOREST_TEMPLE_BASEMENT, ctx->GetDungeon(FOREST_TEMPLE)->IsVanilla() && logic->Get(LOGIC_FOREST_OPEN_BOSS_HALLWAY)), ENTRANCE(RR_FOREST_TEMPLE_MQ_BASEMENT, ctx->GetDungeon(FOREST_TEMPLE)->IsMQ() && logic->Get(LOGIC_FOREST_OPEN_BOSS_HALLWAY)), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index fa05da9d77..3af0ffcad2 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -72,7 +72,7 @@ void RegionTable_Init_GanonsCastle() { }); areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM] = Region("Ganon's Castle Forest Trial Beamos Room", SCENE_INSIDE_GANONS_CASTLE, { - EVENT_ACCESS(LOGIC_FOREST_TRIAL_SILVER_RUPEES, logic->IsAdult || logic->CanUse(RG_HOOKSHOT)), // child can get these by voiding after switch + EVENT_ACCESS(LOGIC_FOREST_TRIAL_SILVER_RUPEES, logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || (logic->IsChild && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), // child can get these by voiding after switch }, {}, { //Exits ENTRANCE(RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM, true), @@ -154,8 +154,34 @@ void RegionTable_Init_GanonsCastle() { EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)), }, { //Locations - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_5, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_6, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_7, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_8, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_9, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_10, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_1, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_2, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_3, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_4, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_5, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_6, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_7, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_8, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_9, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_10, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_11, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_DOOR_RED_ICE, logic->BlueFire()), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MAIN, true), @@ -165,16 +191,25 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM] = Region("Ganon's Castle Water Trial Block Room", SCENE_INSIDE_GANONS_CASTLE, { //Events EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanBreakPots()), - EVENT_ACCESS(LOGIC_WATER_TRIAL_RUSTED_SWITCH, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->CanMiddairGroundJump()) && - (logic->BlueFire() || ctx->GetTrickOption(RT_VISIBLE_COLLISION)) && - logic->CanUse(RG_MEGATON_HAMMER)), }, { //Locations - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots()), }, { //Exits - ENTRANCE(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, true), - ENTRANCE(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_END, logic->IsAdult || (logic->HasItem(RG_POWER_BRACELET) && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)), + ENTRANCE(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, true), + ENTRANCE(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_SWITCH, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->CanMiddairGroundJump())), + ENTRANCE(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_END, logic->IsAdult || (logic->HasItem(RG_POWER_BRACELET) && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)), + }); + + areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_SWITCH] = Region("Ganon's Castle Water Trial Block Room Switch", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EVENT_ACCESS(LOGIC_WATER_TRIAL_RUSTED_SWITCH, (logic->BlueFire() || ctx->GetTrickOption(RT_VISIBLE_COLLISION)) && logic->CanUse(RG_MEGATON_HAMMER)), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RUSTED_SWITCH_RED_ICE, logic->BlueFire()), + }, { + //Exits + ENTRANCE(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, true), }); areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_END] = Region("Ganon's Castle Water Trial Block Room End", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { @@ -368,7 +403,7 @@ void RegionTable_Init_GanonsCastle() { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_LOBBY, true), ENTRANCE(RR_GANONS_CASTLE_MQ_FOREST_TRIAL_STALFOS_ROOM, !ctx->GetOption(RSK_MEDALLION_LOCKED_TRIALS) || logic->HasItem(RG_FOREST_MEDALLION)), - ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_OPEN_DOOR, !ctx->GetOption(RSK_MEDALLION_LOCKED_TRIALS) || logic->HasItem(RG_FIRE_MEDALLION)), + ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FROM_OPEN, !ctx->GetOption(RSK_MEDALLION_LOCKED_TRIALS) || logic->HasItem(RG_FIRE_MEDALLION)), ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM, !ctx->GetOption(RSK_MEDALLION_LOCKED_TRIALS) || logic->HasItem(RG_WATER_MEDALLION)), ENTRANCE(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE, !ctx->GetOption(RSK_MEDALLION_LOCKED_TRIALS) || logic->HasItem(RG_SHADOW_MEDALLION)), ENTRANCE(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_CHAIRS_ROOM, !ctx->GetOption(RSK_MEDALLION_LOCKED_TRIALS) || logic->HasItem(RG_SPIRIT_MEDALLION)), @@ -462,7 +497,6 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_OPEN_DOOR] = Region("Ganon's Castle MQ Fire Trial Open Door", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_MAIN, true), - ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FROM_OPEN, true), }); areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FROM_OPEN] = Region("Ganon's Castle MQ Fire Trial From Open Door", SCENE_INSIDE_GANONS_CASTLE, { @@ -495,7 +529,7 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, logic->CanBreakPots()), }, { //Exits - ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_OPEN_DOOR, true), + ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_BARRED_DOOR, true), }); areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM] = Region("Ganon's Castle MQ Water Trial Geyser Room", SCENE_INSIDE_GANONS_CASTLE, { @@ -503,8 +537,29 @@ void RegionTable_Init_GanonsCastle() { EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, logic->CanJumpslash() || logic->HasExplosives()), // bow can also hit at right angle }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_1, true), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_2, true), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_3, true), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_1, true), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_2, true), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_3, true), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_BACK_LEFT_RED_ICE, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_1, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_2, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_3, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_4, logic->BlueFire()), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_MAIN, true), @@ -514,16 +569,31 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM] = Region("Ganon's Castle MQ Water Trial Block Room", SCENE_INSIDE_GANONS_CASTLE, { //Events EVENT_ACCESS(LOGIC_WATER_TRIAL_MQ_SILVER_RUPEES, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->CanMiddairGroundJump()) && logic->BlueFire()), - EVENT_ACCESS(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE, (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS)) || (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_POWER_BRACELET) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)), - }, {}, { + EVENT_ACCESS(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE, (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS)) || ((logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS)/* && logic->CanUse(RG_ROLL)*/)) && logic->HasItem(RG_POWER_BRACELET) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE))), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->CanMiddairGroundJump()) && logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && logic->CanUse(RG_BOOMERANG)), + }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM, logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 3)), - ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM_END, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && (logic->IsAdult || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_POWER_BRACELET)) || logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP))), + ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM_END, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && (logic->IsAdult || ((logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS)/* && logic->CanUse(RG_ROLL)*/)) && logic->HasItem(RG_POWER_BRACELET)) || logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP))), }); areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM_END] = Region("Ganon's Castle MQ Water Trial Block Room End", SCENE_INSIDE_GANONS_CASTLE, { EVENT_ACCESS(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE, logic->BlueFire()), - }, {}, { + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE)), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE)), + }, { ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE)), ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_FINAL_ROOM, logic->Get(LOGIC_WATER_TRIAL_MQ_SILVER_RUPEES)), }); @@ -565,7 +635,10 @@ void RegionTable_Init_GanonsCastle() { //Events //A torch run from RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE is possible but tight, so would be a trick EVENT_ACCESS(LOGIC_SHADOW_TRIAL_FIRST_CHEST, logic->CanDetonateUprightBombFlower()), - }, {}, { + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL, (logic->CanDetonateBombFlowers() || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE))) && (logic->TakeDamage() || logic->CanUse(RG_NAYRUS_LOVE))), + }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM, logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)), ENTRANCE(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_BEAMOS_TORCH, true), @@ -754,11 +827,11 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_TOWER_STAIRS_4] = Region("Ganon's Tower Stairs 4", SCENE_GANONS_TOWER, {}, {}, { //Exits - ENTRANCE(RR_GANONS_TOWER_FLOOR_3, true), - ENTRANCE(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, true), + ENTRANCE(RR_GANONS_TOWER_FLOOR_3, true), + ENTRANCE(RR_GANONS_TOWER_POT_ROOM, true), }); - areaTable[RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR] = Region("Ganon's Tower Before Ganondorf's Lair", SCENE_GANONS_TOWER, {}, { + areaTable[RR_GANONS_TOWER_POT_ROOM] = Region("Ganon's Tower Pot Room", SCENE_GANONS_TOWER, {}, { // Locations LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_1, logic->CanBreakPots()), LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_2, logic->CanBreakPots()), @@ -780,7 +853,16 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_18, logic->CanBreakPots()), }, { //Exits - ENTRANCE(RR_GANONS_TOWER_FLOOR_3, AnyAgeTime([]{return true;})), + ENTRANCE(RR_GANONS_TOWER_STAIRS_4, true;), + ENTRANCE(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, true;), + }); + + areaTable[RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR] = Region("Ganon's Tower Before Ganondorf's Lair", SCENE_GANONS_TOWER, {}, { + //Locations + LOCATION(RC_GANONS_BOSS_KEY_HINT, true), + }, { + //Exits + ENTRANCE(RR_GANONS_TOWER_POT_ROOM, false;), ENTRANCE(RR_GANONS_TOWER_GANONDORF_LAIR, AnyAgeTime([]{return logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY);})), }); @@ -789,7 +871,7 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONDORF_HINT, logic->HasBossSoul(RG_GANON_SOUL)), }, { //Exits - ENTRANCE(RR_GANONS_CASTLE_ESCAPE, logic->CanKillEnemy(RE_GANONDORF)), + ENTRANCE(RR_GANONS_CASTLE_ESCAPE, logic->CanKillEnemy(RE_GANONDORF)), }); areaTable[RR_GANONS_CASTLE_ESCAPE] = Region("Ganon's Castle Escape", SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index dd8b6c85a0..1c15462734 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -107,7 +107,10 @@ void RegionTable_Init_GerudoTrainingGround() { ENTRANCE(RR_GERUDO_TRAINING_GROUND_BEHIND_HEAVY_BLOCK, true), }); - areaTable[RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER] = Region("Gerudo Training Ground Eye Statue Upper", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { + areaTable[RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER] = Region("Gerudo Training Ground Eye Statue Upper", SCENE_GERUDO_TRAINING_GROUND, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_WONDER_EYE_STATUE_ROOM, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_GTG_STATUE_JUMP))), // Shuffle roll: Jumpslash doesn't require roll, jump only does + }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER, true), ENTRANCE(RR_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_ROOM_UPPER, true), @@ -137,10 +140,11 @@ void RegionTable_Init_GerudoTrainingGround() { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, logic->CanAttack() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, (logic->CanUse(RG_MEGATON_HAMMER) || (logic->TakeDamage() && ctx->GetTrickOption(RT_FIRE_RINGS))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_WONDER_TORCH_SLUGS_ROOM, logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - ENTRANCE(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER, logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_FAIRY_BOW)), - ENTRANCE(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, true), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER, logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_FAIRY_BOW)), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM_UPPER_LEDGE, true), }); areaTable[RR_GERUDO_TRAINING_GROUND_LAVA_ROOM] = Region("Gerudo Training Ground Lava Room", SCENE_GERUDO_TRAINING_GROUND, { @@ -172,6 +176,7 @@ void RegionTable_Init_GerudoTrainingGround() { LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->CanKillEnemy(RE_BEAMOS) && logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, true), LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_WONDER_BEAMOS_ROOM, logic->CanUse(RG_FAIRY_BOW)), }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_LOBBY, true), @@ -240,7 +245,22 @@ void RegionTable_Init_GerudoTrainingGround() { ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM, AnyAgeTime([]{return logic->CanKillEnemy(RE_IRON_KNUCKLE);})), }); - areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM] = Region("Gerudo Training Ground MQ Left Side", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM] = Region("Gerudo Training Ground MQ Left Side", SCENE_GERUDO_TRAINING_GROUND, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_5, logic->CanClearStalagmite()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_1, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_2, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_3, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_4, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_LEFT_STALACTITE, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3, true), + }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM, true), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, AnyAgeTime([]{return logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_MQ_WITHOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_HOOKSHOT));})), @@ -257,9 +277,9 @@ void RegionTable_Init_GerudoTrainingGround() { LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM, true), - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK, logic->Get(LOGIC_GTG_PUSHED_HEAVY_BLOCK)), - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, logic->IsAdult && AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}) && (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->IsAdult && logic->CanGroundJump()))), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM, true), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK, logic->Get(LOGIC_GTG_PUSHED_HEAVY_BLOCK)), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_ALCOVE, logic->IsAdult && (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->IsAdult && logic->CanGroundJump()))), }); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK] = Region("Gerudo Training Ground MQ Behind Block", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { @@ -275,12 +295,23 @@ void RegionTable_Init_GerudoTrainingGround() { ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK, true), }); - areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE] = Region("Gerudo Training Ground MQ Statue Room Ledge", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { - //Exits + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_ALCOVE] = Region("Gerudo Training Ground MQ Stalfos Room Alcove", SCENE_GERUDO_TRAINING_GROUND, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_RED_ICE, logic->BlueFire()), + }, { ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, true), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, logic->Get(LOGIC_GTG_UNLOCKED_DOOR_BEHIND_HEAVY_BLOCK)), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE] = Region("Gerudo Training Ground MQ Statue Room Ledge", SCENE_GERUDO_TRAINING_GROUND, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE, logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_GTG_STATUE_JUMP))), // Shuffle roll: Jumpslash doesn't require roll, jump only does + }, { + //Exits + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_ALCOVE, true), //implies dropping down to hit the switch. Using swords, especially master, is a bit awkward, may be trick worthy, but is only relevant with other tricks - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM, AnyAgeTime([]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG);})), - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM, true), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM, AnyAgeTime([]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG);})), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM, true), }); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM] = Region("Gerudo Training Ground MQ Magenta Fire Room", SCENE_GERUDO_TRAINING_GROUND, {}, { @@ -400,7 +431,8 @@ void RegionTable_Init_GerudoTrainingGround() { //is logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true) && logic->CanKillEnemy(RE_ARMOS, ED_CLOSE, true, 1, true) broken down to exclude sticks, as it takes too many to clear the room //Proper enemy kill room ammo logic is needed to handle this room //some combinations may be impossible without taking damage, keep an eye out for issues here - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM, logic->CanUse(RG_FAIRY_BOW)), }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 176ffaee88..4df089717f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -18,8 +18,20 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_BEGINNING] = Region("Ice Cavern Beginning", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ICE_CAVERN_LOBBY_RUPEE, logic->BlueFire()), // can get with rang trick + LOCATION(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ICE_CAVERN_LOBBY_RUPEE, logic->BlueFire()), // can get with rang trick + LOCATION(RC_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_ENTRANCE_MIDDLE_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_ENTRANCE_RIGHT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_ENTRANCE_STALACTITE_1, true), + LOCATION(RC_ICE_CAVERN_ENTRANCE_STALACTITE_2, true), + LOCATION(RC_ICE_CAVERN_LOBBY_STALACTITE, true), + LOCATION(RC_ICE_CAVERN_LOBBY_LEFT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_LOBBY_MIDDLE_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_LOBBY_RIGHT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_ENTRANCE_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_LOBBY_LEFT_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_LOBBY_RIGHT_RED_ICE, logic->BlueFire()), }, { //Exits ENTRANCE(RR_ICE_CAVERN_ENTRYWAY, true), @@ -29,12 +41,22 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_HUB] = Region("Ice Cavern Hub", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), - LOCATION(RC_ICE_CAVERN_HALL_POT_1, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_HALL_POT_2, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_1, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_2, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_3, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), + LOCATION(RC_ICE_CAVERN_HALL_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_HALL_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_3, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_AFTER_LOBBY_STALACTITE, true), + LOCATION(RC_ICE_CAVERN_AFTER_LOBBY_LEFT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_AFTER_LOBBY_CENTER_LEFT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_AFTER_LOBBY_CENTER_RIGHT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_AFTER_LOBBY_RIGHT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_LEFT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_MIDDLE_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE, logic->BlueFire()), }, { //Exits ENTRANCE(RR_ICE_CAVERN_BEGINNING, true), @@ -49,14 +71,24 @@ void RegionTable_Init_IceCavern() { EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, true), }, { //Locations - LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), // Bow extension is possible, but very precise: X = 403, Z = 2062-3, Rot = -11475, needs a setup and is its own trick - LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, (logic->CanBreakPots() && logic->BlueFire()) || logic->HasExplosives() || - (ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanJumpslash()) || - (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_HOOKSHOT))), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, true), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, true), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, true), + LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, (logic->CanBreakPots() && logic->BlueFire()) || logic->HasExplosives() || + (ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanJumpslash()) || + (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, true), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, true), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, true), + LOCATION(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_1, true), + LOCATION(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_2, true), + LOCATION(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_3, true), + LOCATION(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_4, true), + LOCATION(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_5, true), + LOCATION(RC_ICE_CAVERN_MAP_HALLWAY_LEFT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MAP_HALLWAY_MIDDLE_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MAP_HALLWAY_RIGHT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_POT_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_CHEST_RED_ICE, logic->BlueFire()), }, { //Exits ENTRANCE(RR_ICE_CAVERN_HUB, true), @@ -67,9 +99,31 @@ void RegionTable_Init_IceCavern() { EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, true), }, { //Locations - LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, (logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, (logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire()), // can skip blue fire with rang trick - LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->HookshotOrBoomerang()), + LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, (logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, (logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire()), // can skip blue fire with rang trick + LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->HookshotOrBoomerang()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1, true), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_2, true), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_3, true), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_4, true), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_5, true), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_1, logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_2, logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_5, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_6, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE, (logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CHEST_RED_ICE, (logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire()), }, { //Exits ENTRANCE(RR_ICE_CAVERN_HUB, true), @@ -78,15 +132,24 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_BLOCK_ROOM] = Region("Ice Cavern Block Room", SCENE_ICE_CAVERN, {}, { //Locations // trick involves backflip, could be merged into general trick - LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH))), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH))), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_LEFT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_LEFT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_RIGHT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_RIGHT_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_1, true), + LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2, true), + LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3, true), + LOCATION(RC_ICE_CAVERN_SILVER_RUPEE_RED_ICE, (logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))) && logic->BlueFire()), }, { //Exits ENTRANCE(RR_ICE_CAVERN_HUB, logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)), ENTRANCE(RR_ICE_CAVERN_BLOCK_ROOM_BLUE_FIRE, logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))), - ENTRANCE(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, (logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))) && AnyAgeTime([]{return logic->BlueFire();})), + ENTRANCE(RR_ICE_CAVERN_AFTER_BLOCK_ROOM, (logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))) && AnyAgeTime([]{return logic->BlueFire();})), }); areaTable[RR_ICE_CAVERN_BLOCK_ROOM_BLUE_FIRE] = Region("Ice Cavern Block Room Blue Fire", SCENE_ICE_CAVERN, { @@ -102,16 +165,38 @@ void RegionTable_Init_IceCavern() { ENTRANCE(RR_ICE_CAVERN_BLOCK_ROOM, true), }); + areaTable[RR_ICE_CAVERN_AFTER_BLOCK_ROOM] = Region("Ice Cavern After Block Room", SCENE_ICE_CAVERN, {}, { + //Locations + LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->BlueFire() && logic->HasItem(RG_POWER_BRACELET)), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALACTITE_1, true), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALACTITE_2, true), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALACTITE_3, true), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALACTITE_4, true), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALAGMITE_5, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALAGMITE_6, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALAGMITE_7, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_NEAR_END_STALAGMITE_8, logic->CanClearStalagmite()), + }, { + //Exits + ENTRANCE(RR_ICE_CAVERN_BLOCK_ROOM, true), + ENTRANCE(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, AnyAgeTime([]{return logic->BlueFire();})), + }); + // this represents being past the red ice barricade, not just past the silver rupee door areaTable[RR_ICE_CAVERN_BEFORE_FINAL_ROOM] = Region("Ice Cavern Before Final Room", SCENE_ICE_CAVERN, {}, { //Locations - //Assumes RR_ICE_CAVERN_BLOCK_ROOM access - LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->BlueFire() && logic->HasItem(RG_POWER_BRACELET)), - LOCATION(RC_ICE_CAVERN_NEAR_END_POT_1, logic->CanBreakPots() && logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_NEAR_END_POT_1, logic->CanBreakPots() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_NEAR_END_LEFT_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_NEAR_END_MIDDLE_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE, logic->BlueFire()), }, { //Exits - ENTRANCE(RR_ICE_CAVERN_BLOCK_ROOM, AnyAgeTime([]{return logic->BlueFire();})), + ENTRANCE(RR_ICE_CAVERN_AFTER_BLOCK_ROOM, AnyAgeTime([]{return logic->BlueFire();})), ENTRANCE(RR_ICE_CAVERN_FINAL_ROOM, true), }); @@ -127,7 +212,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER] = Region("Ice Cavern Final Room Underwater", SCENE_ICE_CAVERN, {}, {}, { //Exits - ENTRANCE(RR_ICE_CAVERN_FINAL_ROOM, logic->CanUse(RG_BRONZE_SCALE)), + ENTRANCE(RR_ICE_CAVERN_FINAL_ROOM, logic->HasItem(RG_BRONZE_SCALE)), ENTRANCE(RR_ICE_CAVERN_ABOVE_BEGINNING, logic->CanUse(RG_IRON_BOOTS)), }); @@ -142,7 +227,11 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_BEGINNING] = Region("Ice Cavern MQ Beginning", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_ENTRANCE_POT, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_ENTRANCE_POT, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_1, true), + LOCATION(RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_2, true), }, { //Exits ENTRANCE(RR_ICE_CAVERN_ENTRYWAY, true), @@ -156,12 +245,28 @@ void RegionTable_Init_IceCavern() { EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanBreakPots()), }, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_5, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_5, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_WEST_LEFT_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_WEST_MIDDLE_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_WEST_RIGHT_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_LEDGE_LEFT_RED_ICE, (logic->IsAdult /*|| logic->CanGroundJump()*/) && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_LEDGE_MIDDLE_RED_ICE, (logic->IsAdult /*|| logic->CanGroundJump()*/) && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MQ_HUB_LEDGE_RIGHT_RED_ICE, (logic->IsAdult /*|| logic->CanGroundJump()*/) && logic->BlueFire()), }, { //Exits ENTRANCE(RR_ICE_CAVERN_MQ_MAP_ROOM, AnyAgeTime([]{return logic->CanKillEnemy(RE_WHITE_WOLFOS) && logic->CanKillEnemy(RE_FREEZARD);})), @@ -176,7 +281,17 @@ void RegionTable_Init_IceCavern() { EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)), }, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && AnyAgeTime([]{return logic->CanHitSwitch();}) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && AnyAgeTime([]{return logic->CanHitSwitch();}) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_3, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_4, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_5, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_6, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_7, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_MAP_RED_ICE, logic->BlueFire()), }, {}); areaTable[RR_ICE_CAVERN_MQ_SCARECROW_ROOM] = Region("Ice Cavern MQ Scarecrow Room", SCENE_ICE_CAVERN, { @@ -185,8 +300,13 @@ void RegionTable_Init_IceCavern() { }, { //Locations //Implies being able to kill the skull if you hit the switch - LOCATION(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, (logic->BlueFire() && logic->HasItem(RG_POWER_BRACELET) && logic->CanKillEnemy(RE_GOLD_SKULLTULA)) || logic->CanHitSwitch(logic->IsAdult ? ED_LONG_JUMPSLASH : ED_BOMB_THROW)), - LOCATION(RC_ICE_CAVERN_MQ_GS_SCARECROW, logic->ReachScarecrow() || (logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))), + LOCATION(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, (logic->BlueFire() && logic->HasItem(RG_POWER_BRACELET) && logic->CanKillEnemy(RE_GOLD_SKULLTULA)) || logic->CanHitSwitch(logic->IsAdult ? ED_LONG_JUMPSLASH : ED_BOMB_THROW)), + LOCATION(RC_ICE_CAVERN_MQ_GS_SCARECROW, logic->ReachScarecrow() || (logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))), + LOCATION(RC_ICE_CAVERN_MQ_BEFORE_SCARECROW_STALAGMITE, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_SCARECROW_ROOM_STALACTITE, true), + LOCATION(RC_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE, logic->IsChild && ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS) && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE, logic->IsChild && ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS) && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE, logic->IsChild && ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS) && logic->CanUse(RG_BOOMERANG)), }, { //Exits ENTRANCE(RR_ICE_CAVERN_MQ_HUB, logic->BlueFire()), @@ -196,8 +316,14 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_WEST_CORRIDOR] = Region("Ice Cavern MQ West Corridor", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_1, true), + LOCATION(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_2, true), + LOCATION(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_3, true), + LOCATION(RC_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE, logic->BlueFire()), }, { //Exits ENTRANCE(RR_ICE_CAVERN_MQ_SCARECROW_ROOM, logic->BlueFire()), @@ -209,14 +335,20 @@ void RegionTable_Init_IceCavern() { EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, true), }, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)), //It is possible for child with master, BGS or sticks, or adult with BGS, to hit this switch through the ice with a crouchstab, but it's precise and unintuitive for a trick - LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives()), // can get with rang trick + LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives()), // can get with rang trick //doing RT_ICE_MQ_RED_ICE_GS as child is untested, as I could not perform the trick reliably even as adult - LOCATION(RC_ICE_CAVERN_MQ_GS_RED_ICE, (logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS))) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || - (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS)) || (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT))), - LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_1, logic->CanBreakPots()), - LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_GS_RED_ICE, (logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS))) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || + (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS)) || (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_2, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_RED_ICE, (logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS))) && (logic->CanKillEnemy(RE_GOLD_SKULLTULA) || logic->TakeDamage())) || + (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS))), }, {}); areaTable[RR_ICE_CAVERN_MQ_STALFOS_ROOM] = Region("Ice Cavern MQ Stalfos Room", SCENE_ICE_CAVERN, {}, { @@ -231,7 +363,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_STALFOS_ROOM_UNDERWATER] = Region("Ice Cavern MQ Stalfos Room Underwater", SCENE_ICE_CAVERN, {}, {}, { //Exits - ENTRANCE(RR_ICE_CAVERN_MQ_STALFOS_ROOM, logic->CanUse(RG_BRONZE_SCALE)), + ENTRANCE(RR_ICE_CAVERN_MQ_STALFOS_ROOM, logic->HasItem(RG_BRONZE_SCALE)), ENTRANCE(RR_ICE_CAVERN_MQ_ABOVE_BEGINNING, logic->CanUse(RG_IRON_BOOTS)), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index 3d40a71157..e9a4abae18 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -60,7 +60,7 @@ void RegionTable_Init_JabuJabusBelly() { ENTRANCE(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_NORTH, true), }); - areaTable[RR_JABU_JABUS_BELLY_B1_JIGGLY] = Region("Jabu Jabus Belly B1 Cube", SCENE_JABU_JABU, { + areaTable[RR_JABU_JABUS_BELLY_B1_JIGGLY] = Region("Jabu Jabus Belly B1 Jiggly", SCENE_JABU_JABU, { //Events EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanUse(RG_BOOMERANG) || (logic->CanBreakPots() && ctx->GetTrickOption(RT_JABU_B1_CUBE_HOVER) && logic->CanUse(RG_HOVER_BOOTS))), }, { @@ -86,7 +86,7 @@ void RegionTable_Init_JabuJabusBelly() { //there's tricks for getting here with bunny-jumps or just side-hops ENTRANCE(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_CLIMB)), ENTRANCE(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH, logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE)), - ENTRANCE(RR_JABU_JABUS_BELLY_HOLES_BASEMENT, true), + ENTRANCE(RR_JABU_JABUS_BELLY_HOLES_LOWER_DOOR_LEDGE, true), }); areaTable[RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH] = Region("Jabu Jabus Belly Water Switch Room South", SCENE_JABU_JABU, {}, { @@ -266,12 +266,15 @@ void RegionTable_Init_JabuJabusBelly() { EVENT_ACCESS(LOGIC_NUT_ACCESS, logic->CanBreakPots()), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_LEFT_COW, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_RIGHT_COW, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_ENTRYWAY, true), @@ -283,12 +286,13 @@ void RegionTable_Init_JabuJabusBelly() { EVENT_ACCESS(LOGIC_JABU_MQ_LIFT_ROOM_COW, logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, true), - LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, true), - LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, logic->CanUse(RG_IRON_BOOTS)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, logic->CanUse(RG_IRON_BOOTS)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_ELEVATOR_COW, logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_BEGINNING, true), @@ -317,11 +321,17 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM] = Region("Jabu Jabus Belly MQ Holes Room", SCENE_JABU_JABU, { //Events - EVENT_ACCESS(LOGIC_JABU_MQ_FORKED_ROOM_DOOR, (logic->HasExplosives() || ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION)) && logic->CanUse(RG_FAIRY_SLINGSHOT)), + EVENT_ACCESS(LOGIC_JABU_MQ_FORKED_ROOM_DOOR, (logic->HasExplosives() || ctx->GetTrickOption(RT_BOULDER_COLLISION)) && logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_1, logic->CanCutShrubs() && logic->HasExplosives()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_2, logic->CanCutShrubs() && logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_1, logic->CanCutShrubs() && logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_2, logic->CanCutShrubs() && logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_COW, (logic->HasExplosives() || ctx->GetTrickOption(RT_BOULDER_COLLISION)) && logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, logic->HasExplosives()), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, true), @@ -329,7 +339,10 @@ void RegionTable_Init_JabuJabusBelly() { ENTRANCE(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM_PAST_JIGGLY, logic->CanUse(RG_BOOMERANG)), }); - areaTable[RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM_PAST_JIGGLY] = Region("Jabu Jabus Belly MQ Holes Room Past Jiggly", SCENE_JABU_JABU, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM_PAST_JIGGLY] = Region("Jabu Jabus Belly MQ Holes Room Past Jiggly", SCENE_JABU_JABU, { + //Events + EVENT_ACCESS(LOGIC_JABU_MQ_FORKED_ROOM_DOOR, ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_FAIRY_SLINGSHOT)), + }, {}, { ENTRANCE(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, logic->CanUse(RG_BOOMERANG)), //It is possible to open the door here without crossing the jiggly using RT_DISTANT_BOULDER and good timing ENTRANCE(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, logic->Get(LOGIC_JABU_MQ_FORKED_ROOM_DOOR)), @@ -342,6 +355,12 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3, logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, logic->HasItem(RG_CLIMB)), @@ -374,7 +393,11 @@ void RegionTable_Init_JabuJabusBelly() { ENTRANCE(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, true), }); - areaTable[RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR] = Region("Jabu Jabus Belly MQ Forked Corridor", SCENE_JABU_JABU, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR] = Region("Jabu Jabus Belly MQ Forked Corridor", SCENE_JABU_JABU, {}, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, logic->BlastOrSmash()), + }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, logic->CanUse(RG_BOOMERANG)), //If some mode lets an age use sticks and not sling, and other use sling and not sticks, this needs changing @@ -409,7 +432,9 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_FORK_NORTH_WEST] = Region("Jabu Jabus Belly MQ Fork North West", SCENE_JABU_JABU, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, logic->HasExplosives() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, logic->BlastOrSmash() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_TO_FORK_NORTH_WEST, true), @@ -432,12 +457,21 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_FORK_NORTH_EAST] = Region("Jabu Jabus Belly MQ Fork North East", SCENE_JABU_JABU, {}, { //Locations //Implies CanKillEnemy(RE_LIKE_LIKE) - LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, logic->CanBreakPots()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, logic->CanBreakPots()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, logic->CanCutShrubs()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, logic->CanBreakSmallCrates()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, logic->CanBreakSmallCrates()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, logic->CanBreakSmallCrates()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, logic->CanBreakSmallCrates()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3, logic->HasExplosives()), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, true), @@ -489,18 +523,20 @@ void RegionTable_Init_JabuJabusBelly() { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_AFTER_BIG_OCTO, logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_JIGGLIES_ROOM, true), ENTRANCE(RR_JABU_JABUS_BELLY_MQ_BIGOCTO, logic->TakeDamage() && AnyAgeTime([]{return logic->CanKillEnemy(RE_BIG_OCTO);})), }); - areaTable[RR_JABU_JABUS_BELLY_MQ_JIGGLIES_ROOM] = Region("Jabu Jabus Belly MQ Cubes Room", SCENE_JABU_JABU, {}, { + areaTable[RR_JABU_JABUS_BELLY_MQ_JIGGLIES_ROOM] = Region("Jabu Jabus Belly MQ Jigglies Room", SCENE_JABU_JABU, {}, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_COW, logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_JABU_JABUS_BELLY_MQ_JIGGLIES_GRASS, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_1, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanBreakSmallCrates()), LOCATION(RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_2, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanBreakSmallCrates()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_JIGGLIES_COW, logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_ABOVE_BIGOCTO, true), @@ -538,11 +574,14 @@ void RegionTable_Init_JabuJabusBelly() { EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanBreakPots()), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, (logic->HasItem(RG_CLIMB) && (logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT)))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_LONGSHOT))), - LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, logic->CanBreakPots()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, (logic->HasItem(RG_CLIMB) && (logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT)))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_LONGSHOT))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_LEFT_COW, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_1, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_2, logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_TO_NEAR_BOSS_ROOM, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index f5cf059855..c374402a9d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -16,7 +16,10 @@ void RegionTable_Init_ShadowTemple() { #pragma region Vanilla - areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN, logic->CanRead()), + }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_ENTRYWAY, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))), ENTRANCE(RR_SHADOW_TEMPLE_WHISPERING_WALLS_START, ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)), @@ -148,11 +151,12 @@ void RegionTable_Init_ShadowTemple() { // See MQ for comments areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA] = Region("Shadow Temple Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (logic->IsAdult && logic->CanGroundJumpslash())), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (logic->IsAdult && logic->CanGroundJumpslash())), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, !!ctx->GetTrickOption(RT_VISIBLE_COLLISION)), @@ -341,6 +345,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_THREE_SKULL_JARS] = Region("Shadow Temple Three Skull Jars", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->HasItem(RG_GORONS_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)), + LOCATION(RC_SHADOW_TEMPLE_WONDER_THREE_POTS, logic->CanUse(RG_FAIRY_BOW)), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MAZE, true), @@ -358,11 +363,14 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_PRE_BOSS_ROOM] = Region("Shadow Temple Pre Boss Room", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - ENTRANCE(RR_SHADOW_TEMPLE_BEYOND_BOAT, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 5)), - ENTRANCE(RR_SHADOW_TEMPLE_BOSS_DOOR, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS)), + ENTRANCE(RR_SHADOW_TEMPLE_ACROSS_CHASM, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 5)), + ENTRANCE(RR_SHADOW_TEMPLE_BOSS_DOOR, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS)), }); - areaTable[RR_SHADOW_TEMPLE_BOSS_DOOR] = Region("Shadow Temple Boss Door", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_BOSS_DOOR] = Region("Shadow Temple Boss Door", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_BOSS_KEY_HINT, true), + }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS)), ENTRANCE(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, true), @@ -527,6 +535,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Region("Shadow Temple MQ Lower Huge Pit", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3, logic->CanUse(RG_LONGSHOT)), @@ -562,6 +571,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, true), @@ -670,7 +680,7 @@ void RegionTable_Init_ShadowTemple() { //Locations //It's a trick on N64 to kill this and drop down to collect this with normal weapons, as doing so without the statue being dropped voids you to before the boat //hilariously, you can hit this with a pot before you bring down statue, but there's no great way to reset it without crossing. the statue's collision is very inconvenient afterwards - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, logic->CanBreakPots()), }, { @@ -707,8 +717,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_BOSS_DOOR] = Region("Shadow Temple MQ Boss Door", SCENE_SHADOW_TEMPLE, {}, { //Locations - //you can drop onto this and the respawn is reasonable - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_BOSS_KEY_HINT, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, (logic->HookshotOrBoomerang() || ((logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM, logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), @@ -736,7 +746,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_THREE_SKULL_JARS] = Region("Shadow Temple MQ Three Skull Jars", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_WONDER_THREE_POTS, logic->CanUse(RG_FAIRY_BOW)), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index de04fda773..55461f1417 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -23,8 +23,10 @@ void RegionTable_Init_SpiritTemple() { EVENT_ACCESS(LOGIC_FORWARDS_SPIRIT_ADULT, logic->IsAdult), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_1, logic->CanBreakPots()), - LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE, logic->CanRead()), + LOCATION(RC_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE, logic->CanRead()), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_ENTRYWAY, true), @@ -136,15 +138,15 @@ void RegionTable_Init_SpiritTemple() { RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG);})), }, { //Exits - ENTRANCE(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, true), - ENTRANCE(RR_SPIRIT_TEMPLE_STATUE_ROOM, logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), + ENTRANCE(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, true), + ENTRANCE(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), }); areaTable[RR_SPIRIT_TEMPLE_ADULT_SIDE_HUB] = Region("Spirit Temple Adult Side Hub", SCENE_SPIRIT_TEMPLE, {}, {}, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_FOYER, true), ENTRANCE(RR_SPIRIT_TEMPLE_SAND_PIT, AnyAgeTime([]{return logic->CanHitSwitch(logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH) ? ED_BOMB_THROW : ED_BOOMERANG);})), - ENTRANCE(RR_SPIRIT_TEMPLE_BOULDERS, AnyAgeTime([]{return logic->CanHitSwitch(logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH) ? ED_BOMB_THROW : ED_BOOMERANG);})), + ENTRANCE(RR_SPIRIT_TEMPLE_ABOVE_BOULDERS, AnyAgeTime([]{return logic->CanHitSwitch(logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH) ? ED_BOMB_THROW : ED_BOOMERANG);})), ENTRANCE(RR_SPIRIT_TEMPLE_1F_MIRROR_ROOM, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 1)), }); @@ -202,7 +204,7 @@ void RegionTable_Init_SpiritTemple() { ENTRANCE(RR_SPIRIT_TEMPLE_STATUE_ROOM_ADULT, logic->HasItem(RG_POWER_BRACELET) || logic->SunlightArrows()), }); - areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD] = Region("Spirit Temple Statue Rooom Child", SCENE_SPIRIT_TEMPLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD] = Region("Spirit Temple Statue Room Child", SCENE_SPIRIT_TEMPLE, {}, { //Locations //Assumes RR_SPIRIT_TEMPLE_STATUE_ROOM access LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));}, false, @@ -212,13 +214,14 @@ void RegionTable_Init_SpiritTemple() { RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);})), }, { //Exits - ENTRANCE(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, true), - ENTRANCE(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, true), + ENTRANCE(RR_SPIRIT_TEMPLE_STATUE_ROOM, true), + ENTRANCE(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, true), + ENTRANCE(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, true), ENTRANCE(RR_SPIRIT_TEMPLE_GS_LEDGE, logic->CanUse(RG_HOVER_BOOTS) || logic->ReachScarecrow()), // RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled - ENTRANCE(RR_SPIRIT_TEMPLE_PLATFORM, logic->Get(LOGIC_SPIRIT_PLATFORM_LOWERED) && - (logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)))), - ENTRANCE(RR_SPIRIT_TEMPLE_EMPTY_STAIRS, logic->HasItem(RG_POWER_BRACELET)), + ENTRANCE(RR_SPIRIT_TEMPLE_PLATFORM, logic->Get(LOGIC_SPIRIT_PLATFORM_LOWERED) && + (logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)))), + ENTRANCE(RR_SPIRIT_TEMPLE_EMPTY_STAIRS, logic->HasItem(RG_POWER_BRACELET)), //!QUANTUM LOGIC! //When child enters spirit in reverse, has 4 keys, and dungeon entrance shuffle is off, //Child cannot lock themselves out of desert colossus access as if they save the west hand lock for last @@ -241,8 +244,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_GS_LEDGE] = Region("Spirit Temple GS ledge", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);}, false, - RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) ? ED_BOOMERANG : ED_HOOKSHOT);}, + LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);}, false, + RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) ? ED_BOOMERANG : ED_HOOKSHOT);}, RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT);})), }, { //Exits @@ -282,8 +285,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_EMPTY_STAIRS] = Region("Spirit Temple Empty Stairs", SCENE_SPIRIT_TEMPLE, {}, {}, { //Exits - ENTRANCE(RR_SPIRIT_TEMPLE_STATUE_ROOM, true), - ENTRANCE(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, true), + ENTRANCE(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, true), + ENTRANCE(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, true), }); areaTable[RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM] = Region("Spirit Temple Sun Block Room", SCENE_SPIRIT_TEMPLE, {}, {}, { @@ -329,7 +332,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_RIGHT_HAND_EXIT] = Region("Spirit Temple Right Hand Exit", SCENE_SPIRIT_TEMPLE, {}, {}, { //Exits - ENTRANCE(RR_SPIRIT_TEMPLE_CHILD_THRONE, true), + ENTRANCE(RR_SPIRIT_TEMPLE_CHILD_THRONE, true), ENTRANCE(RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, true), }); @@ -532,7 +535,10 @@ void RegionTable_Init_SpiritTemple() { //WARNING these events are not glitchproofed and assume you need all keys to reach from the front EVENT_ACCESS(LOGIC_REVERSE_SPIRIT_CHILD, logic->IsChild), EVENT_ACCESS(LOGIC_REVERSE_SPIRIT_ADULT, logic->IsAdult), - }, {}, { + }, { + //Locations + LOCATION(RC_SPIRIT_BOSS_KEY_HINT, true), + }, { // Exits ENTRANCE(RR_SPIRIT_TEMPLE_STATUE_ROOM, true), //CanBunnyJump with a jumpslash can reach either hand and with good timing the platform as child. the latter is definitely a trick, the former may not be @@ -555,13 +561,20 @@ void RegionTable_Init_SpiritTemple() { }, { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST) && + ((AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->IsChild ? logic->CanHitEyeTargets() : logic->CanUse(RG_FAIRY_SLINGSHOT)))), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Get(LOGIC_SPIRIT_1F_SILVER_RUPEES) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE, logic->CanRead()), + LOCATION(RC_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE, logic->CanRead()), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_ENTRYWAY, true), @@ -572,7 +585,6 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_CHILD_SIDE_HUB] = Region("Spirit Temple MQ Child Side Hub", SCENE_SPIRIT_TEMPLE, { //Events - //not technically a rusted switch, but a boulder through a wall, but is part of the same trick on N64 EVENT_ACCESS(LOGIC_SPIRIT_MQ_CRAWL_BOULDER, logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanUse(RG_MEGATON_HAMMER))), }, { //Locations @@ -582,9 +594,9 @@ void RegionTable_Init_SpiritTemple() { (ctx->GetTrickOption(RT_FIRE_RINGS) && ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->TakeDamage() && logic->CanJumpslash())), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets() || logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_FIRE_RINGS) && ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->TakeDamage() && logic->CanJumpslash())), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CRAWLSPACE_BOULDER, logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER) && logic->CanUse(RG_CRAWL)), }, { //Exits - //Nabooru's legs are technically visible one way collision here, but I'm not sure if this counts ENTRANCE(RR_SPIRIT_TEMPLE_MQ_FOYER, logic->CanUse(RG_CRAWL)), ENTRANCE(RR_SPIRIT_TEMPLE_MQ_GIBDO_GRAVES, AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG);})), ENTRANCE(RR_SPIRIT_TEMPLE_MQ_ANUBIS_BRIDGE_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG);})), @@ -596,7 +608,11 @@ void RegionTable_Init_SpiritTemple() { EVENT_ACCESS(LOGIC_SPIRIT_MQ_GIBDOS_CLEARED, logic->HasItem(RG_POWER_BRACELET) && ((logic->CanUse(RG_BOMBCHU_5) && logic->CanHitEyeTargets()) || logic->CanUse(RG_HOVER_BOOTS)/* || (IsAdult && CanBunnyJump())*/) && logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 3)), - }, {}, { + }, { + //Location + LOCATION(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_HIGH, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_LOW, logic->BlastOrSmash()), + }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_CHILD_SIDE_HUB, true), ENTRANCE(RR_SPIRIT_TEMPLE_MQ_GIBDO_POTS, logic->HasItem(RG_POWER_BRACELET) && @@ -608,6 +624,7 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_TURNTABLE, logic->Get(LOGIC_SPIRIT_MQ_GIBDOS_CLEARED)), @@ -909,8 +926,9 @@ void RegionTable_Init_SpiritTemple() { EVENT_ACCESS(LOGIC_SPIRIT_1F_SILVER_RUPEES, logic->CanUse(RG_MEGATON_HAMMER)), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_FOYER, logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && (logic->CanUseSword() || logic->CanUse(RG_STICKS)))), @@ -982,6 +1000,8 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH, logic->CanJumpslashExceptHammer()), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, true), @@ -1114,7 +1134,10 @@ void RegionTable_Init_SpiritTemple() { //WARNING these events are not glitchproofed and assume you need all keys to reach from the front EVENT_ACCESS(LOGIC_REVERSE_SPIRIT_CHILD, logic->IsChild), EVENT_ACCESS(LOGIC_REVERSE_SPIRIT_ADULT, logic->IsAdult), - }, {}, { + }, { + //Locations + LOCATION(RC_SPIRIT_BOSS_KEY_HINT, true), + }, { // Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, true), //CanBunnyJump with a jumpslash can reach either hand and with good timing the platform as child. the latter is definitely a trick, the former may not be diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index cfd2b39259..5dc39724d1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -175,7 +175,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MAP_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4);}) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits - ENTRANCE(RR_WATER_TEMPLE_SIDE_TOWER_1F, AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4);})), + ENTRANCE(RR_WATER_TEMPLE_LOW_EMBLEM, AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4);})), }); areaTable[RR_WATER_TEMPLE_CRACKED_WALL] = Region("Water Temple Cracked Wall", SCENE_WATER_TEMPLE, {}, { @@ -239,6 +239,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, logic->CanBreakPots(ED_HOOKSHOT, false, true) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), }, { //Exits + ENTRANCE(RR_WATER_TEMPLE_BOULDERS_NORTH, true), ENTRANCE(RR_WATER_TEMPLE_BLOCK_ROOM, true), ENTRANCE(RR_WATER_TEMPLE_BLOCK_ROOM_STAIRS, logic->CanUse(RG_HOVER_BOOTS)), }); @@ -265,6 +266,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BLOCK_ROOM_STAIRS] = Region("Water Temple Block Room Stairs", SCENE_WATER_TEMPLE, {}, {}, { //Exits ENTRANCE(RR_WATER_TEMPLE_BLOCK_ROOM, true), + ENTRANCE(RR_WATER_TEMPLE_3_JETS_SWITCH, true), ENTRANCE(RR_WATER_TEMPLE_BLOCK_ROOM_TARGET, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)), }); @@ -276,8 +278,8 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_3_JETS_NO_SWITCH] = Region("Water Temple 3 Jets Room No Switch", SCENE_WATER_TEMPLE, {}, {}, { //Exits - ENTRANCE(RR_WATER_TEMPLE_3_JETS_SWITCH, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanStandingShield())), - ENTRANCE(RR_WATER_TEMPLE_CANAL_ALCOVE, true), + ENTRANCE(RR_WATER_TEMPLE_3_JETS_SWITCH, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanStandingShield())), + ENTRANCE(RR_WATER_TEMPLE_CANAL_ALCOVE, true), }); areaTable[RR_WATER_TEMPLE_CANAL_ALCOVE] = Region("Water Temple Canal Alcove", SCENE_WATER_TEMPLE, {}, { @@ -289,14 +291,14 @@ void RegionTable_Init_WaterTemple() { logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->HasItem(RG_BRONZE_SCALE) && logic->IsAdult ? ED_SHORT_JUMPSLASH : ED_BOOMERANG))), }, { //Exits - ENTRANCE(RR_WATER_TEMPLE_3_JETS_SWITCH, true), - ENTRANCE(RR_WATER_TEMPLE_BOULDER_CANAL, logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), - ENTRANCE(RR_WATER_TEMPLE_BEHIND_CANAL, logic->IsAdult && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->HasItem(RG_BRONZE_SCALE)), + ENTRANCE(RR_WATER_TEMPLE_3_JETS_NO_SWITCH, true), + ENTRANCE(RR_WATER_TEMPLE_BOULDER_CANAL, logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), + ENTRANCE(RR_WATER_TEMPLE_BEHIND_CANAL, logic->IsAdult && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->HasItem(RG_BRONZE_SCALE)), }); areaTable[RR_WATER_TEMPLE_BOULDER_CANAL] = Region("Water Temple Boulder Canal", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)) || (((logic->IsAdult && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)) || (logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOOMERANG))) && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits //making the jump as adult without jumpslash is possible, but hard enough to be a trick @@ -630,7 +632,10 @@ void RegionTable_Init_WaterTemple() { ENTRANCE(RR_WATER_TEMPLE_TRAPPED_SLOPE, true), }); - areaTable[RR_WATER_TEMPLE_TRAPPED_SLOPE] = Region("Water Temple Trapped Slope", SCENE_WATER_TEMPLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_TRAPPED_SLOPE] = Region("Water Temple Trapped Slope", SCENE_WATER_TEMPLE, {}, { + //Locations + LOCATION(RC_WATER_BOSS_KEY_HINT, true), + }, { ENTRANCE(RR_WATER_TEMPLE_RISING_TARGET_LEDGE, true), ENTRANCE(RR_WATER_TEMPLE_BOSS_ENTRYWAY, true), }); @@ -760,13 +765,20 @@ void RegionTable_Init_WaterTemple() { ENTRANCE(RR_WATER_TEMPLE_MQ_BOSS_DOOR_RAMP, true), }); - areaTable[RR_WATER_TEMPLE_MQ_BOSS_DOOR_RAMP] = Region("Water Temple MQ Boss Door Ramp", SCENE_WATER_TEMPLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_MQ_BOSS_DOOR_RAMP] = Region("Water Temple MQ Boss Door Ramp", SCENE_WATER_TEMPLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_1, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_2, logic->CanUse(RG_HOOKSHOT)), + }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_RISING_TARGET_LEDGE, true), ENTRANCE(RR_WATER_TEMPLE_MQ_BOSS_DOOR, logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_ICE_ARROWS) || logic->CanUse(RG_NAYRUS_LOVE)), }); - areaTable[RR_WATER_TEMPLE_MQ_BOSS_DOOR] = Region("Water Temple MQ Boss Door", SCENE_WATER_TEMPLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_MQ_BOSS_DOOR] = Region("Water Temple MQ Boss Door", SCENE_WATER_TEMPLE, {}, { + //Locations + LOCATION(RC_WATER_BOSS_KEY_HINT, true), + }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_BOSS_DOOR_RAMP, logic->CanUse(RG_ICE_ARROWS) || logic->TakeDamage()), ENTRANCE(RR_WATER_TEMPLE_BOSS_ENTRYWAY, true), @@ -789,7 +801,8 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_SIDE_TOWER_2F] = Region("Water Temple MQ Side Tower 2F", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->CanUse(RG_HOOKSHOT) && ((logic->WaterLevel(WL_MID) && logic->HasItem(RG_OPEN_CHEST)) || logic->CanOpenUnderwaterChest())), + LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->CanUse(RG_HOOKSHOT) && ((logic->WaterLevel(WL_MID) && logic->HasItem(RG_OPEN_CHEST)) || logic->CanOpenUnderwaterChest())), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM, logic->CanUse(RG_HOOKSHOT) && (logic->WaterLevel(WL_MID) || logic->CanUse(RG_IRON_BOOTS))), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_SIDE_TOWER_1F, logic->WaterLevel(WL_LOW) || logic->CanUse(RG_IRON_BOOTS)), @@ -810,7 +823,8 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_3_STALFOS_ROOM] = Region("Water Temple MQ 3 Stalfos Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_LOW_EMBLEM, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 4)), @@ -821,7 +835,8 @@ void RegionTable_Init_WaterTemple() { EVENT_ACCESS(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS, logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE)), }, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_SIDE_TOWER_1F, true), @@ -901,7 +916,8 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_PILLAR_B1_FINAL] = Region("Water Temple MQ Central Pillar B1 Final", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_UNDER_PILLAR_ROOM, logic->CanUse(RG_HOOKSHOT)), }, {}); areaTable[RR_WATER_TEMPLE_MQ_STORAGE_ROOM] = Region("Water Temple MQ Storage Room", SCENE_WATER_TEMPLE, {}, { @@ -944,6 +960,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, logic->CanBreakSmallCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_GS_STORAGE_ROOM, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_MAIN, true), @@ -978,6 +995,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_HALLWAY, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_3F_CENTRAL_A, logic->CanUse(RG_HOOKSHOT)), @@ -1024,13 +1042,29 @@ void RegionTable_Init_WaterTemple() { ENTRANCE(RR_WATER_TEMPLE_MQ_2F_CENTRAL_H, logic->WaterLevel(WL_HIGH) && logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)), }); - areaTable[RR_WATER_TEMPLE_MQ_WATERFALL] = Region("Water Temple Waterfall", SCENE_WATER_TEMPLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_MQ_WATERFALL] = Region("Water Temple Waterfall", SCENE_WATER_TEMPLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3, logic->CanUse(RG_LONGSHOT)), + }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_OUTSIDE_WATERFALL, logic->SmallKeys(SCENE_WATER_TEMPLE, 1)), ENTRANCE(RR_WATER_TEMPLE_MQ_WATERFALL_TOP, logic->CanUse(RG_LONGSHOT)), }); - areaTable[RR_WATER_TEMPLE_MQ_WATERFALL_TOP] = Region("Water Temple Waterfall Top", SCENE_WATER_TEMPLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_MQ_WATERFALL_TOP] = Region("Water Temple Waterfall Top", SCENE_WATER_TEMPLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3, logic->CanUse(RG_HOOKSHOT)), + }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_WATERFALL, logic->CanUse(RG_LONGSHOT) && logic->CanHitSwitch(ED_FAR)), ENTRANCE(RR_WATER_TEMPLE_MQ_STALFOS_PIT, true), @@ -1097,8 +1131,9 @@ void RegionTable_Init_WaterTemple() { EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanBreakPots()), }, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, logic->CanBreakPots()), - LOCATION(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_AFTER_DARK_LINK, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_DARK_LINK_ROOM, true), @@ -1138,6 +1173,8 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_RIVER_POTS, logic->CanUse(RG_LONGSHOT)), @@ -1155,6 +1192,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, logic->CanBreakSmallCrates()), LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, logic->CanBreakSmallCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_PORTRAIT, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), @@ -1164,8 +1202,10 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR] = Region("Water Temple MQ Dragon Room Door", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE, logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 8), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE, logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 8), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_RIVER_POTS, logic->CanUse(RG_LONGSHOT)), @@ -1261,6 +1301,8 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, logic->CanBreakCrates()), + // A vanilla bug causes a glitched damage value on hardware and undefined behavior in SOH. Matching the resulting damage triggers with an additional array entry. + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_TRIPLE_TORCHES, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW)), }, {}); areaTable[RR_WATER_TEMPLE_MQ_SPIKE_MOAT] = Region("Water Temple MQ Spike Moat", SCENE_WATER_TEMPLE, {}, {}, { @@ -1309,9 +1351,9 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_CANAL_ALCOVE] = Region("Water Temple MQ Canal Alcove", SCENE_WATER_TEMPLE, {}, {}, { //Exits - ENTRANCE(RR_WATER_TEMPLE_MQ_3_JETS_ROOM, logic->SmallKeys(SCENE_WATER_TEMPLE, 2)), - ENTRANCE(RR_WATER_TEMPLE_MQ_SCARECROW_CANAL, logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), - ENTRANCE(RR_WATER_TEMPLE_MQ_BEHIND_CANAL, logic->IsAdult && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->HasItem(RG_BRONZE_SCALE)), + ENTRANCE(RR_WATER_TEMPLE_MQ_3_JETS_ROOM_SWITCH_SIDE, logic->SmallKeys(SCENE_WATER_TEMPLE, 2)), + ENTRANCE(RR_WATER_TEMPLE_MQ_SCARECROW_CANAL, logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), + ENTRANCE(RR_WATER_TEMPLE_MQ_BEHIND_CANAL, logic->IsAdult && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->HasItem(RG_BRONZE_SCALE)), }); areaTable[RR_WATER_TEMPLE_MQ_BEHIND_CANAL] = Region("Water Temple MQ Behind Canal", SCENE_WATER_TEMPLE, {}, {}, { @@ -1322,23 +1364,38 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_FREESTANDING_ROOM] = Region("Water Temple MQ Freestanding Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, logic->CanBreakPots()), - LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, logic->CanBreakPots()), - LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_FREESTANDING_ROOM, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_BEHIND_CANAL, AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS);})), }); - areaTable[RR_WATER_TEMPLE_MQ_3_JETS_ROOM] = Region("Water Temple MQ 3 Jets Room", SCENE_WATER_TEMPLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_MQ_3_JETS_ROOM_SWITCH_SIDE] = Region("Water Temple MQ 3 Jets Room Switch Side", SCENE_WATER_TEMPLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_1, true), + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2, logic->CanHitSwitch()), + }, { //Exits - ENTRANCE(RR_WATER_TEMPLE_MQ_CANAL_ALCOVE, logic->SmallKeys(SCENE_WATER_TEMPLE, 2) && logic->CanHitSwitch(ED_BOOMERANG)), - ENTRANCE(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, logic->CanHitSwitch() && logic->HasFireSource()), + ENTRANCE(RR_WATER_TEMPLE_MQ_CANAL_ALCOVE, logic->SmallKeys(SCENE_WATER_TEMPLE, 2)), + ENTRANCE(RR_WATER_TEMPLE_MQ_3_JETS_ROOM_NO_SWITCH_SIDE, logic->CanHitSwitch()), + // No Switch Side requires CanHitSwitch(ED_BOOMERANG) to get to this entrance. This is covered by No Switch -> Switch entrance. + ENTRANCE(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, logic->CanHitSwitch(ED_BOOMERANG) && logic->HasFireSource()), + }); + + areaTable[RR_WATER_TEMPLE_MQ_3_JETS_ROOM_NO_SWITCH_SIDE] = Region("Water Temple MQ 3 Jets Room No Switch Side", SCENE_WATER_TEMPLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2, logic->IsAdult), + }, { + //Exits + ENTRANCE(RR_WATER_TEMPLE_MQ_3_JETS_ROOM_SWITCH_SIDE, logic->CanHitSwitch(ED_BOOMERANG) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanHammerRecoilHover())), }); areaTable[RR_WATER_TEMPLE_MQ_DODONGO_ROOM] = Region("Water Temple MQ Dodongo Room", SCENE_WATER_TEMPLE, {}, { @@ -1352,8 +1409,8 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, logic->CanBreakCrates()), }, { //Exits - ENTRANCE(RR_WATER_TEMPLE_MQ_3_JETS_ROOM, (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) && AnyAgeTime([]{return logic->CanKillEnemy(RE_DODONGO, ED_CLOSE, true, 5);})), - ENTRANCE(RR_WATER_TEMPLE_MQ_CRATE_VORTEX_CAGE, (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) && AnyAgeTime([]{return logic->CanKillEnemy(RE_DODONGO, ED_CLOSE, true, 5);})), + ENTRANCE(RR_WATER_TEMPLE_MQ_3_JETS_ROOM_NO_SWITCH_SIDE, (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) && AnyAgeTime([]{return logic->CanKillEnemy(RE_DODONGO, ED_CLOSE, true, 5);})), + ENTRANCE(RR_WATER_TEMPLE_MQ_CRATE_VORTEX_CAGE, (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) && AnyAgeTime([]{return logic->CanKillEnemy(RE_DODONGO, ED_CLOSE, true, 5);})), }); areaTable[RR_WATER_TEMPLE_MQ_CRATE_VORTEX_CAGE] = Region("Water Temple MQ Crate Vortex Cage", SCENE_WATER_TEMPLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index 40ba46fcf4..d1c293b79b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -28,6 +28,9 @@ void RegionTable_Init_CastleGrounds() { }, { //Locations LOCATION(RC_HC_MALON_EGG, logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_HC_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_HC_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_HC_ROCK_3, logic->CanBreakRocks()), LOCATION(RC_HC_GS_TREE, logic->CanBonkTrees() && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), LOCATION(RC_HC_SKULLTULA_TREE, logic->CanBonkTrees()), }, { @@ -56,14 +59,20 @@ void RegionTable_Init_CastleGrounds() { EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanUse(RG_STICKS)), }, { //Locations - LOCATION(RC_HC_NEAR_GUARDS_TREE_1, logic->CanBonkTrees()), - LOCATION(RC_HC_NEAR_GUARDS_TREE_2, logic->CanBonkTrees()), - LOCATION(RC_HC_NEAR_GUARDS_TREE_3, logic->CanBonkTrees()), - LOCATION(RC_HC_NEAR_GUARDS_TREE_4, logic->CanBonkTrees()), - LOCATION(RC_HC_NEAR_GUARDS_TREE_5, logic->CanBonkTrees()), - LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()), - LOCATION(RC_HC_NL_TREE_1, false), - LOCATION(RC_HC_NL_TREE_2, false), + LOCATION(RC_HC_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HC_NL_TREE_1, false), + LOCATION(RC_HC_NL_TREE_2, false), + LOCATION(RC_HC_NEAR_WALL_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), + LOCATION(RC_HC_NEAR_STAIRS_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), + LOCATION(RC_HC_NEAR_BOULDER_PATH_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), + LOCATION(RC_HC_NEAR_ARCHWAY_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), + LOCATION(RC_HC_DEAD_END_RECTANGLE_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_HC_GATE, true), @@ -88,9 +97,21 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_HC_MOAT] = Region("Hyrule Castle Grounds", SCENE_HYRULE_CASTLE, {}, { //Locations - LOCATION(RC_HC_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_HC_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_HC_GROTTO_TREE, logic->CanBonkTrees()), + LOCATION(RC_HC_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_HC_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HC_GROTTO_TREE, logic->CanBonkTrees()), + LOCATION(RC_HC_WONDER_LEFT_TORCH, logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_HC_WONDER_RIGHT_TORCH, logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_HC_WONDER_MOAT_1, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), + LOCATION(RC_HC_WONDER_MOAT_2, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), // Requires backflip with Iron Boots + LOCATION(RC_HC_WONDER_MOAT_3, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), // Requires backflip with Iron Boots + LOCATION(RC_HC_WONDER_MOAT_4, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), + LOCATION(RC_HC_WONDER_MOAT_5, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), // Requires backflip with Iron Boots + LOCATION(RC_HC_WONDER_MOAT_6, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), // Requires backflip with Iron Boots + LOCATION(RC_HC_WONDER_MOAT_7, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), // Requires backflip with Iron Boots + LOCATION(RC_HC_WONDER_MOAT_8, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), // Requires backflip with Iron Boots + LOCATION(RC_HC_WONDER_MOAT_9, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), // Requires backflip with Iron Boots + LOCATION(RC_HC_WONDER_MOAT_10, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION)), // Requires backflip with Iron Boots }, { //Exits ENTRANCE(RR_HC_GATE, true), @@ -107,8 +128,10 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_HC_GARDEN] = Region("HC Garden", SCENE_CASTLE_COURTYARD_ZELDA, {}, { //Locations - LOCATION(RC_HC_ZELDAS_LETTER, logic->HasItem(RG_SPEAK_HYLIAN)), - LOCATION(RC_SONG_FROM_IMPA, logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_HC_ZELDAS_LETTER, logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_SONG_FROM_IMPA, logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_HC_WONDER_COURTYARD_RIGHT_WINDOW, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_HC_WONDER_COURTYARD_LEFT_WINDOW, logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits ENTRANCE(RR_HC_DRAIN_LEDGE, true), // if this ever gets shuffled leaving garden area should come out crawlspace @@ -146,6 +169,14 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_3, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_4, logic->CanBreakPots()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_8, logic->CanBreakRocks()), }, { //Exits ENTRANCE(RR_HC_STORMS_GROTTO, true), @@ -161,7 +192,14 @@ void RegionTable_Init_CastleGrounds() { EVENT_ACCESS(LOGIC_BUILD_RAINBOW_BRIDGE, logic->CanBuildRainbowBridge()), }, { //Locations - LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_OGC_GS, logic->HookshotOrBoomerang() || ((logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)) && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))) , + LOCATION(RC_OGC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), }, { //Exits ENTRANCE(RR_CASTLE_GROUNDS, logic->AtNight), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index 0574afb70f..3ad8990729 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -20,58 +20,73 @@ void RegionTable_Init_DeathMountainCrater() { // clang-format off areaTable[RR_DMC_UPPER_ENTRY] = Region("DMC Upper Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations - LOCATION(RC_DMC_WALL_FREESTANDING_POH, (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), + //You can also walk off the edge at a shallow angle to not grab the wall, then drift to land in the alcove. + LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 16 || logic->Hearts() >= 3) && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || + (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && + (((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCUpperToPad())))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCPotsToPad() && logic->DMCUpperToPots() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && + (((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCUpperToPad())))), }, { //Exits ENTRANCE(RR_DMC_CRATE, true), ENTRANCE(RR_DMC_ROCK_GROTTO, logic->FireTimer() >= 8 || logic->Hearts() >= 2), ENTRANCE(RR_DMC_CRACKED_WALL, (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), ENTRANCE(RR_DMC_SCRUB, logic->FireTimer() >= 16 || logic->Hearts() >= 3), + //implied hookshot use to cross the bridge ENTRANCE(RR_DMC_BLOCKED_EXIT, ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && logic->DMCUpperToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_POTS, ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->DMCUpperToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_POT_GROTTO_EXIT, ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->DMCUpperToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_CENTRAL, ((logic->FireTimer() >= 64 || logic->Hearts() >= 12) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_FAR_PLATFORM, (logic->IsAdult && (logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCUpperToPots() && logic->DMCPotsToPad() && logic->ReachDistantScarecrow()) || (logic->FireTimer() >= 24 || logic->Hearts() >= 5) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS)), - ENTRANCE(RR_DMC_TEMPLE_EXIT, ((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCUpperToPad()))), }); areaTable[RR_DMC_ROCKS_GROTTO_ENTRY] = Region("DMC Rocks Grotto Entry", SCENE_DEATH_MOUNTAIN_CRATER, { }, { //Locations - LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 8 || logic->Hearts() >= 2), + LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 8 || logic->Hearts() >= 2) && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || + (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && + (((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCUpperToPad())))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)) || - (logic->IsAdult && (logic->FireTimer() >= 64 || logic->Hearts() >= 12) && logic->DMCPotsToPad() && logic->DMCUpperToPots() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && + (((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCUpperToPad())))), }, { //Exits ENTRANCE(RR_DMC_CRATE, logic->FireTimer() >= 8 || logic->Hearts() >= 2), ENTRANCE(RR_DMC_ROCK_GROTTO, true), ENTRANCE(RR_DMC_CRACKED_WALL, (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), ENTRANCE(RR_DMC_SCRUB, logic->FireTimer() >= 16 || logic->Hearts() >= 3), + //implied hookshot use to cross the bridge ENTRANCE(RR_DMC_BLOCKED_EXIT, ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->DMCUpperToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_POTS, ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->DMCUpperToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_POT_GROTTO_EXIT, ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCUpperToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_CENTRAL, ((logic->FireTimer() >= 64 || logic->Hearts() >= 12) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 3) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ((logic->FireTimer() >= 40 || logic->Hearts() >= 3) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_FAR_PLATFORM, (logic->IsAdult && (logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCUpperToPots() && logic->DMCPotsToPad() && logic->ReachDistantScarecrow()) || (logic->FireTimer() >= 16 || logic->Hearts() >= 3) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS)), - ENTRANCE(RR_DMC_TEMPLE_EXIT, ((logic->FireTimer() >= 64 || logic->Hearts() >= 12) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 3) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 64 || logic->Hearts() >= 12) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 40 || logic->Hearts() >= 3) && logic->DMCUpperToPad()))), }); areaTable[RR_DMC_BLOCKED_ENTRY] = Region("DMC Blocked Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations - LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && logic->CanClimbLadder()) || + LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && logic->CanClimbLadder() && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, ((logic->FireTimer() >= 16 || logic->Hearts() >= 3) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)) || @@ -92,18 +107,19 @@ void RegionTable_Init_DeathMountainCrater() { ENTRANCE(RR_DMC_POTS, logic->FireTimer() >= 8 || logic->Hearts() >= 2), ENTRANCE(RR_DMC_POT_GROTTO_EXIT, logic->FireTimer() >= 16 || logic->Hearts() >= 3), ENTRANCE(RR_DMC_CENTRAL, ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->ReachDistantScarecrow() && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder())), + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_FAR_PLATFORM, (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCPotsToPad() && logic->ReachDistantScarecrow()) || ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder()) || (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS))), - ENTRANCE(RR_DMC_TEMPLE_EXIT, ((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->ReachDistantScarecrow() && logic->CanClimbLadder())), + ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCUpperToPad() && logic->CanClimbLadder()))), }); areaTable[RR_DMC_POTS_ENTRY] = Region("DMC Pots Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations - LOCATION(RC_DMC_WALL_FREESTANDING_POH, (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->CanClimbLadder() || + LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->CanClimbLadder() && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, ((logic->FireTimer() >= 8 || logic->Hearts() >= 2) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)) || @@ -124,18 +140,19 @@ void RegionTable_Init_DeathMountainCrater() { ENTRANCE(RR_DMC_POTS, true), ENTRANCE(RR_DMC_POT_GROTTO_EXIT, logic->FireTimer() >= 8 || logic->Hearts() >= 2), ENTRANCE(RR_DMC_CENTRAL, ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->ReachDistantScarecrow() && logic->CanClimbLadder())), + ((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCUpperToPad() && logic->CanClimbLadder())), ENTRANCE(RR_DMC_FAR_PLATFORM, (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad() && logic->ReachDistantScarecrow()) || ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder())), - ENTRANCE(RR_DMC_TEMPLE_EXIT, ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->ReachDistantScarecrow() && logic->CanClimbLadder())), + ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCUpperToPad() && logic->CanClimbLadder()))), }); areaTable[RR_DMC_POT_GROTTO_ENTRY] = Region("DMC Pot Grotto Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations - LOCATION(RC_DMC_WALL_FREESTANDING_POH, (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->CanClimbLadder() || + LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->CanClimbLadder() && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || - ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), + ((logic->FireTimer() >= 24 || logic->Hearts() >= 5) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT) && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash())))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, (logic->FireTimer() >= 16 || logic->Hearts() >= 3) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && (logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), }, { @@ -154,17 +171,18 @@ void RegionTable_Init_DeathMountainCrater() { ENTRANCE(RR_DMC_POTS, logic->FireTimer() >= 8 || logic->Hearts() >= 2), ENTRANCE(RR_DMC_POT_GROTTO_EXIT, true), ENTRANCE(RR_DMC_CENTRAL, ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->ReachDistantScarecrow() && logic->CanClimbLadder())), + ((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCUpperToPad() && logic->CanClimbLadder())), ENTRANCE(RR_DMC_FAR_PLATFORM, (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad() && logic->ReachDistantScarecrow()) || ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder())), - ENTRANCE(RR_DMC_TEMPLE_EXIT, ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad()) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->ReachDistantScarecrow() && logic->CanClimbLadder())), + ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->DMCPotsToPad()) || + ((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCUpperToPad() && logic->CanClimbLadder()))), }); areaTable[RR_DMC_PAD_ENTRY] = Region("DMC Pad Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations - LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->CanClimbLadder() && logic->DMCPadToPots()) || - ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || + LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && logic->CanClimbLadder() && logic->DMCPadToPots() && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || + ((logic->FireTimer() >= 32 || logic->Hearts() >= 6) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT) && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Hearts() >= 3) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, (logic->FireTimer() >= 24 || logic->Hearts() >= 5) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->DMCPadToPots() || (logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 2) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), @@ -192,7 +210,8 @@ void RegionTable_Init_DeathMountainCrater() { ((logic->FireTimer() >= 40 || logic->Hearts() >= 8) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || (logic->IsAdult && (logic->FireTimer() >= 24 || logic->Hearts() >= 5) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))|| (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Hearts() >= 3) && logic->ReachDistantScarecrow())), - ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), + ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), }); areaTable[RR_DMC_TEMPLE_ENTRY] = Region("DMC Temple Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { @@ -206,37 +225,38 @@ void RegionTable_Init_DeathMountainCrater() { (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Hearts() >= 8) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), }, { //Exits - ENTRANCE(RR_DMC_CRATE, logic->HasItem(RG_CLIMB) && - (((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCPadToPots()) || - ((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), - ENTRANCE(RR_DMC_ROCK_GROTTO, logic->HasItem(RG_CLIMB) && - (((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCPadToPots()) || - ((logic->FireTimer() >= 64 || logic->Hearts() >= 12) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), - ENTRANCE(RR_DMC_CRACKED_WALL, logic->HasItem(RG_CLIMB) && - (((logic->FireTimer() >= 80 || logic->Hearts() >= 15) && logic->DMCPadToPots()) || - ((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), - ENTRANCE(RR_DMC_SCRUB, logic->HasItem(RG_CLIMB) && - (((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCPadToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), - ENTRANCE(RR_DMC_BLOCKED_EXIT, logic->HasItem(RG_CLIMB) && - (((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCPadToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), - ENTRANCE(RR_DMC_POTS, logic->HasItem(RG_CLIMB) && - (((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCPadToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), - ENTRANCE(RR_DMC_POT_GROTTO_EXIT, logic->HasItem(RG_CLIMB) && + ENTRANCE(RR_DMC_CRATE, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCPadToPots()) || + ((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || + (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + ENTRANCE(RR_DMC_ROCK_GROTTO, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && logic->DMCPadToPots()) || + ((logic->FireTimer() >= 64 || logic->Hearts() >= 12) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + ENTRANCE(RR_DMC_CRACKED_WALL, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 80 || logic->Hearts() >= 15) && logic->DMCPadToPots()) || + ((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || + (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + ENTRANCE(RR_DMC_SCRUB, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCPadToPots()) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + ENTRANCE(RR_DMC_BLOCKED_EXIT, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 56 || logic->Hearts() >= 11) && logic->DMCPadToPots()) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + ENTRANCE(RR_DMC_POTS, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCPadToPots()) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + ENTRANCE(RR_DMC_POT_GROTTO_EXIT, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->DMCPadToPots()) || (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), - ENTRANCE(RR_DMC_CENTRAL, logic->HasItem(RG_CLIMB) && (logic->FireTimer() >= 48 || logic->Hearts() >= 9)), - ENTRANCE(RR_DMC_FAR_PLATFORM, logic->HasItem(RG_CLIMB) && - (((logic->FireTimer() >= 88 || logic->Hearts() >= 3) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder() && logic->DMCPadToPots()) || - ((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))|| - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->ReachDistantScarecrow()))), - ENTRANCE(RR_DMC_TEMPLE_EXIT, true), + ENTRANCE(RR_DMC_CENTRAL, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (logic->FireTimer() >= 48 || logic->Hearts() >= 9)), + ENTRANCE(RR_DMC_FAR_PLATFORM, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (((logic->FireTimer() >= 88 || logic->Hearts() >= 3) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder() && logic->DMCPadToPots()) || + ((logic->FireTimer() >= 72 || logic->Hearts() >= 14) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || + (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Hearts() >= 11) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))|| + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Hearts() >= 9) && logic->ReachDistantScarecrow()))), + ENTRANCE(RR_DMC_TEMPLE_EXIT, true), }); areaTable[RR_DMC_CRATE] = Region("DMC Crate", SCENE_DEATH_MOUNTAIN_CRATER, {}, { @@ -248,7 +268,22 @@ void RegionTable_Init_DeathMountainCrater() { ENTRANCE(RR_DEATH_MOUNTAIN_SUMMIT, true), }); - areaTable[RR_DMC_ROCK_GROTTO] = Region("DMC Rock Grotto", SCENE_DEATH_MOUNTAIN_CRATER, {}, {}, { + areaTable[RR_DMC_ROCK_GROTTO] = Region("DMC Rock Grotto", SCENE_DEATH_MOUNTAIN_CRATER, {}, { + //Locations + LOCATION(RC_DMC_CIRCLE_ROCK_1, logic->FireTimer() >= 8 && logic->CanBreakRocks()), + LOCATION(RC_DMC_CIRCLE_ROCK_2, logic->FireTimer() >= 8 && logic->CanBreakRocks()), + LOCATION(RC_DMC_CIRCLE_ROCK_3, logic->FireTimer() >= 8 && logic->CanBreakRocks()), + LOCATION(RC_DMC_CIRCLE_ROCK_4, logic->FireTimer() >= 8 && logic->CanBreakRocks()), + LOCATION(RC_DMC_CIRCLE_ROCK_5, logic->FireTimer() >= 8 && logic->CanBreakRocks()), + LOCATION(RC_DMC_CIRCLE_ROCK_6, logic->FireTimer() >= 8 && logic->CanBreakRocks()), + LOCATION(RC_DMC_CIRCLE_ROCK_7, logic->FireTimer() >= 8 && logic->CanBreakRocks()), + LOCATION(RC_DMC_CIRCLE_ROCK_8, logic->FireTimer() >= 8 && logic->CanBreakRocks()), + //Boulders 1 and 2 are a bit separate, but are in 8 seconds from upper entry and closeer or the same distance + //from all ways to reach upper grotto otherwise, so it works + LOCATION(RC_DMC_BOULDER_1, logic->FireTimer() >= 8 && logic->BlastOrSmash()), + LOCATION(RC_DMC_BOULDER_2, logic->FireTimer() >= 8 && logic->BlastOrSmash()), + LOCATION(RC_DMC_BOULDER_3, logic->FireTimer() >= 8 && logic->BlastOrSmash()), + }, { //Exits ENTRANCE(RR_DMC_UPPER_GROTTO, AnyAgeTime([]{return logic->BlastOrSmash();})), }); @@ -260,7 +295,9 @@ void RegionTable_Init_DeathMountainCrater() { //Locations LOCATION(RC_DMC_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() && logic->HasExplosives()), LOCATION(RC_DMC_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS) && logic->HasExplosives()), - LOCATION(RC_DMC_GOSSIP_STONE, true && logic->HasExplosives()), + LOCATION(RC_DMC_GOSSIP_ROCK_1, logic->IsChild), + LOCATION(RC_DMC_GOSSIP_ROCK_2, logic->IsChild), + LOCATION(RC_DMC_GOSSIP_STONE, logic->HasExplosives()), }, {}); areaTable[RR_DMC_SCRUB] = Region("DMC Scrub", SCENE_DEATH_MOUNTAIN_CRATER, { @@ -282,10 +319,15 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_POTS] = Region("DMC Pots", SCENE_DEATH_MOUNTAIN_CRATER, {}, { // Locations - LOCATION(RC_DMC_NEAR_GC_POT_1, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_1, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + LOCATION(RC_DMC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_SHORTCUT, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRIDGE_EXIT_ARROW_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_GC_DARUNIAS_CHAMBER, true), @@ -302,19 +344,26 @@ void RegionTable_Init_DeathMountainCrater() { EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), }, { //Locations - LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult), - LOCATION(RC_DMC_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanKillEnemy(RE_GOLD_SKULLTULA)), - LOCATION(RC_DMC_NEAR_PLATFORM_RED_RUPEE, logic->IsChild), - LOCATION(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, logic->IsChild), - LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, logic->IsChild), - LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, logic->IsChild), - LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, logic->IsChild), - LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, logic->IsChild), - LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, logic->IsChild), - LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, logic->IsChild), - LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult), + LOCATION(RC_DMC_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanKillEnemy(RE_GOLD_SKULLTULA)), + LOCATION(RC_DMC_NEAR_PLATFORM_RED_RUPEE, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, logic->IsChild), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_1, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_2, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_3, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_4, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_5, logic->IsAdult), + // RANDOTODO: A number of tricks to reach this: sidehop jumpslash or hookshot + jumpslash from bridge platform, chu+shield damage boost + LOCATION(RC_DMC_WONDER_BENEATH_BRIDGE_PLATFORM, logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS))), }, {}); @@ -344,17 +393,18 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_UPPER_GROTTO] = Region("DMC Upper Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_DMC_UPPER_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), - LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), - LOCATION(RC_DMC_UPPER_GROTTO_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_DMC_UPPER_GROTTO_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_DMC_UPPER_GROTTO_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_DMC_UPPER_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_DMC_UPPER_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMC_UPPER_GROTTO_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_DMC_UPPER_GROTTO_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_DMC_UPPER_GROTTO_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_DMC_UPPER_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_DMC_UPPER_BOULDER_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_DMC_ROCKS_GROTTO_ENTRY, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index 891318b262..22ac7b4939 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -10,20 +10,52 @@ void RegionTable_Init_DeathMountainTrail() { EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), }, { //Locations - LOCATION(RC_DMT_CHEST, (logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))), - LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))), - LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->CanGetNightTimeGS() && - ((logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DMT_JS_LOWER_GS) && logic->CanJumpslash())) || - ((ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) && - (logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE) || ((ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) || ctx->GetTrickOption(RT_ITEM_EXTENSION)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))) || logic->CanJumpslash())))), - LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()), - LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()), - LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_DMT_CHEST, (logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))), + LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))), + LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->CanGetNightTimeGS() && + ((logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DMT_JS_LOWER_GS) && logic->CanJumpslash())) || + ((ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) && + (logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE) || ((ctx->GetTrickOption(RT_BOULDER_COLLISION) || ctx->GetTrickOption(RT_ITEM_EXTENSION)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))) || logic->CanJumpslash())))), + LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_DMT_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_DMT_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_DMT_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_DMT_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_DMT_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_DMT_CIRCLE_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_DMT_CIRCLE_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_DMT_CIRCLE_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_DMT_CIRCLE_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_DMT_CIRCLE_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_DMT_CIRCLE_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_DMT_CIRCLE_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_DMT_CIRCLE_ROCK_8, logic->CanBreakRocks()), + LOCATION(RC_DMT_CHILD_BOULDER, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_DMT_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_7, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_11, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_ABOVE_DODONGO_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_DMT_ADULT_CENTER_EXIT_ARROW_SIGN, logic->IsAdult && logic->CanRead()), + LOCATION(RC_DMT_CHILD_CENTER_EXIT_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_DMT_DODONGOS_CAVERN_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_DMT_CENTER_TRAIL_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_DMT_TO_UPPER_TRAIL_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_DMT_TO_CENTER_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_DMT_LOWER_EXIT_ARROW_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_KAK_BEHIND_GATE, true), @@ -36,9 +68,13 @@ void RegionTable_Init_DeathMountainTrail() { areaTable[RR_DEATH_MOUNTAIN_ROCKFALL] = Region("Death Mountain Rockfall", SCENE_DEATH_MOUNTAIN_TRAIL, {}, { //Locations LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->CanGetNightTimeGS() && - (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || + (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_UPPER_GS) && (logic->CanJumpslash() || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives() || (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_FAIRY_SLINGSHOT)) || - (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT)))))), + (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT)))))), + LOCATION(RC_DMT_BRONZE_BOULDER_8, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_9, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_10, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_COW_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_DEATH_MOUNTAIN_TRAIL, true), @@ -58,8 +94,10 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMT_SUMMIT_ROCK, logic->IsChild && logic->CanBreakRocks()), LOCATION(RC_DMT_GOSSIP_STONE, true), LOCATION(RC_BIGGORON_HINT, logic->IsAdult && logic->HasItem(RG_SPEAK_GORON)), + LOCATION(RC_DMT_UPPER_EXIT_ARROW_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_DEATH_MOUNTAIN_ROCKFALL, true), @@ -109,6 +147,7 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_STORMS_GROTTO_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DMT_STORMS_GROTTO_GRASS_3, logic->CanCutShrubs()), LOCATION(RC_DMT_STORMS_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_DMT_STORMS_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_DEATH_MOUNTAIN_TRAIL, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index a60194dd19..e21da0a1d4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -10,20 +10,43 @@ void RegionTable_Init_DesertColossus() { EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->HasItem(RG_POWER_BRACELET)), }, { //Locations - LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL)), - LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanAttack()), - LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), - LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), - LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), + LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL)), + LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanAttack()), + LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_COLOSSUS_ROCK, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_8, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_8, logic->CanBreakRocks()), + LOCATION(RC_COLOSSUS_WONDER_OASIS_TREE_1, (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_COLOSSUS_WONDER_OASIS_TREE_2, (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_COLOSSUS_WONDER_OASIS_CHILD_TREE, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_COLOSSUS_WONDER_GF_TREE_1, (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_COLOSSUS_WONDER_GF_TREE_2, (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits //You can kinda get the fairies without entering the water, but it relies on them cooperating and leevers are jerks. should be a trick - ENTRANCE(RR_DESERT_COLOSSUS_OASIS, logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->HasBottle())), + ENTRANCE(RR_DESERT_COLOSSUS_OASIS, logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->HasBottle() || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), ENTRANCE(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, logic->HasExplosives()), ENTRANCE(RR_SPIRIT_TEMPLE_ENTRYWAY, true), ENTRANCE(RR_WASTELAND_NEAR_COLOSSUS, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 9d797c0e0d..d57288f406 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -9,8 +9,10 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_OUTSKIRTS] = Region("Gerudo Fortress Outskirts", SCENE_GERUDOS_FORTRESS, {}, { //Locations - LOCATION(RC_GF_OUTSKIRTS_NE_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), - LOCATION(RC_GF_OUTSKIRTS_NW_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), + LOCATION(RC_GF_OUTSKIRTS_NE_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), + LOCATION(RC_GF_OUTSKIRTS_NW_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), + LOCATION(RC_GF_EAST_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_GF_WONDER_ENTRANCE_SIGN, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_GV_FORTRESS_SIDE, true), @@ -45,7 +47,10 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_OUTSIDE_GTG] = Region("GF Outside GTG", SCENE_GERUDOS_FORTRESS, { //Events EVENT_ACCESS(LOGIC_GTG_GATE_OPEN, logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_GERUDO)), - }, {}, { + }, { + //Locations + LOCATION(RC_GF_GTG_ENTRANCE_RECTANGLE_SIGN, logic->IsAdult && logic->CanRead()), + }, { //Exits ENTRANCE(RR_GF_TO_GTG, logic->Get(LOGIC_GTG_GATE_OPEN) && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES))), //Jail @@ -197,19 +202,19 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_ABOVE_JAIL] = Region("GF Above Jail", SCENE_GERUDOS_FORTRESS, {}, { //Locations - LOCATION(RC_GF_ABOVE_JAIL_CRATE, true), + LOCATION(RC_GF_ABOVE_JAIL_CRATE, logic->IsAdult), }, { //Exits //there's a trick to reach RR_GF_LONG_ROOF //For some reason, you take fall damage if you backflip onto the fortress but not onto the sand //It's unintuitive to avoid being caught on landing, but that sends you to the same place anyway... - ENTRANCE(RR_GF_OUTSKIRTS, true), - ENTRANCE(RR_GF_NEAR_CHEST, logic->CanUse(RG_LONGSHOT)), - ENTRANCE(RR_GF_BELOW_CHEST, logic->TakeDamage()), - ENTRANCE(RR_GF_JAIL_WINDOW, logic->CanUse(RG_HOOKSHOT)), - ENTRANCE(RR_TH_BREAK_ROOM_CORRIDOR, true), - ENTRANCE(RR_GF_TOWER, ctx->GetTrickOption(RT_GF_ADULT_SKIP_WASTELAND_GATE) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash() && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)), - ENTRANCE(RR_GF_OUTSIDE_GATE, ctx->GetTrickOption(RT_GF_ADULT_SKIP_WASTELAND_GATE) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash()), + ENTRANCE(RR_GF_OUTSKIRTS, ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) || logic->TakeDamage()), + ENTRANCE(RR_GF_NEAR_CHEST, logic->CanUse(RG_LONGSHOT)), + ENTRANCE(RR_GF_BELOW_CHEST, logic->TakeDamage()), + ENTRANCE(RR_GF_JAIL_WINDOW, logic->CanUse(RG_HOOKSHOT)), + ENTRANCE(RR_TH_BREAK_ROOM_UPPER_CORRIDOR, true), + ENTRANCE(RR_GF_TOWER, ctx->GetTrickOption(RT_GF_ADULT_SKIP_WASTELAND_GATE) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash() && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)), + ENTRANCE(RR_GF_OUTSIDE_GATE, ctx->GetTrickOption(RT_GF_ADULT_SKIP_WASTELAND_GATE) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash()), }); areaTable[RR_GF_JAIL_WINDOW] = Region("GF Jail Window", SCENE_GERUDOS_FORTRESS, {}, {}, { @@ -240,6 +245,8 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_NORTH_TARGET_CHILD_CRATE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_GF_SOUTH_TARGET_EAST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_SOUTH_TARGET_WEST_CRATE, logic->CanBreakCrates()), + LOCATION(RC_GF_HBA_RECTANGLE_SIGN, logic->IsAdult && logic->CanRead()), + LOCATION(RC_GF_WONDER_ARCHERY_SIGN, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_GF_OUTSIDE_GTG, logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)), @@ -248,7 +255,10 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_OUTSIDE_GATE] = Region("GF Outside Gate", SCENE_GERUDOS_FORTRESS, { //Events EVENT_ACCESS(LOGIC_GF_GATE_OPEN, logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_SPEAK_GERUDO)), - }, {}, { + }, { + //Locations + LOCATION(RC_GF_GATE_EXIT_RECTANGLE_SIGN, logic->IsAdult && logic->CanRead()), + }, { //Exits ENTRANCE(RR_GF_OUTSKIRTS, logic->Get(LOGIC_GF_GATE_OPEN)), ENTRANCE(RR_WASTELAND_NEAR_FORTRESS, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index d93b877d4e..d1bca0e740 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -10,7 +10,23 @@ void RegionTable_Init_GerudoValley() { EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->IsChild && logic->HasItem(RG_POWER_BRACELET)), }, { //Locations - LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_GV_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_GV_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_GV_UNDERWATER_ROCK_1, (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_BOMB_DETONATION)) || (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))) && + (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->HasItem(RG_POWER_BRACELET)))), + LOCATION(RC_GV_UNDERWATER_ROCK_2, (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_BOMB_DETONATION)) || (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))) && + (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->HasItem(RG_POWER_BRACELET)))), + LOCATION(RC_GV_UNDERWATER_ROCK_3, (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_BOMB_DETONATION)) || (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))) && + (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->HasItem(RG_POWER_BRACELET)))), + LOCATION(RC_GV_BOULDER_1, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BOULDER_2, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRIDGE_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_GV_EAST_EXIT_ARROW_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_HYRULE_FIELD, true), @@ -38,6 +54,8 @@ void RegionTable_Init_GerudoValley() { LOCATION(RC_GV_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GV_GOSSIP_STONE, true), LOCATION(RC_GV_NEAR_COW_CRATE, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_WONDER_LOWER_WATERFALL, logic->IsAdult && (CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL) || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_GV_WONDER_UPPER_WATERFALL, logic->IsAdult && CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL)), }, { //Exits ENTRANCE(RR_GV_UPPER_STREAM_WATER, true), @@ -60,13 +78,17 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_WATERFALL_ALCOVE] = Region("GV Waterfall Alcove", SCENE_GERUDO_VALLEY, {}, { //Locations LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, true), + LOCATION(RC_GV_WONDER_UPPER_WATERFALL, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), }, { //Exits ENTRANCE(RR_GV_UPPER_STREAM, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), ENTRANCE(RR_GV_UPPER_STREAM_WATER, true), }); - areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, {}, { + areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, { + //Locations + LOCATION(RC_GV_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + }, { //Exits ENTRANCE(RR_GV_UPPER_STREAM, ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->TakeDamage()), ENTRANCE(RR_GV_LOWER_STREAM, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS)), @@ -86,14 +108,25 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_FORTRESS_SIDE] = Region("GV Fortress Side", SCENE_GERUDO_VALLEY, {}, { //Locations - LOCATION(RC_GV_CHEST, logic->IsAdult && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT))) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), - LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CHEST, logic->IsAdult && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_1, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_2, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_3, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_4, logic->IsAdult), + LOCATION(RC_GV_BOULDER_ACROSS_BRIDGE, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits ENTRANCE(RR_GF_OUTSKIRTS, true), @@ -112,14 +145,14 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_OCTOROK_GROTTO] = Region("GV Octorok Grotto", SCENE_GROTTOS, {}, { //Locations - LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GV_OCTOROK_GROTTO_RED_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_GV_OCTOROK_GROTTO_RED_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits ENTRANCE(RR_GV_GROTTO_LEDGE, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index e1995b0cec..293964ef9c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -18,24 +18,75 @@ void RegionTable_Init_GoronCity() { (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && (logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)))))), }, { //Locations - LOCATION(RC_GC_MAZE_LEFT_CHEST, (logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GC_MAZE_CENTER_CHEST, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GC_MAZE_RIGHT_CHEST, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->Get(LOGIC_GORON_CITY_CHILD_FIRE) && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), - LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && logic->HasItem(RG_SPEAK_GORON) && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), - LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->Get(LOGIC_GORON_CITY_STOP_ROLLING_GORON_AS_ADULT)), - LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()), - LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()), - LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CallGossipFairyExceptSuns()), - LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_LOWER_STAIRCASE_POT_1, logic->CanBreakPots()), - LOCATION(RC_GC_LOWER_STAIRCASE_POT_2, logic->CanBreakPots()), - LOCATION(RC_GC_UPPER_STAIRCASE_POT_1, logic->CanBreakPots()), - LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()), - LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()), - LOCATION(RC_GC_MAZE_CRATE, logic->BlastOrSmash() || (logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBreakCrates())), - + LOCATION(RC_GC_MAZE_LEFT_CHEST, (logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GC_MAZE_CENTER_CHEST, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GC_MAZE_RIGHT_CHEST, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->Get(LOGIC_GORON_CITY_CHILD_FIRE) && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), + LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && logic->HasItem(RG_SPEAK_GORON) && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), + LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->Get(LOGIC_GORON_CITY_STOP_ROLLING_GORON_AS_ADULT)), + LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()), + LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CallGossipFairyExceptSuns()), + LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_LOWER_STAIRCASE_POT_1, logic->CanBreakPots()), + LOCATION(RC_GC_LOWER_STAIRCASE_POT_2, logic->CanBreakPots()), + LOCATION(RC_GC_UPPER_STAIRCASE_POT_1, logic->CanBreakPots()), + LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()), + LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()), + LOCATION(RC_GC_MAZE_CRATE, logic->BlastOrSmash() || (logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBreakCrates())), + LOCATION(RC_GC_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_GC_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_GC_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_GC_LW_BOULDER_1, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_LW_BOULDER_2, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_LW_BOULDER_3, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_5, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_6, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_7, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_8, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_9, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_10, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_11, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_12, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_13, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_14, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_15, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_16, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_17, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_18, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_19, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_20, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_21, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_22, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_23, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_24, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_25, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_26, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_27, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_28, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_29, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_6, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_7, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_8, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_9, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_10, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_5, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_ROCK, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_CHILD_ROLLING_GORON_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), }, { //Exits ENTRANCE(RR_DEATH_MOUNTAIN_TRAIL, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 77ac0aa44d..2ea38908fa 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -32,6 +32,13 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GY_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_12, logic->CanCutShrubs()), LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), + LOCATION(RC_GY_ROCK, logic->CanBreakRocks()), + LOCATION(RC_GY_NEAR_HUT_GRAVE_BUTTERFLY_FAIRY, logic->IsChild && logic->AtDay && logic->CanUse(RG_STICKS)), + LOCATION(RC_GY_ENTRANCE_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_GY_ENTRANCE_PLINTH, logic->CanRead()), + LOCATION(RC_GY_RIGHT_OF_ROYAL_TOMB_GRAVE, logic->CanRead()), + LOCATION(RC_GY_LEFT_OF_ROYAL_TOMB_GRAVE, logic->CanRead()), + LOCATION(RC_GY_ROYAL_TOMB_GRAVE, logic->CanRead() || logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits ENTRANCE(RR_GRAVEYARD_SHIELD_GRAVE, (logic->IsAdult || logic->AtNight) && logic->HasItem(RG_POWER_BRACELET)), @@ -106,6 +113,21 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, true), LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, true), LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_1, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_2, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_3, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_4, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_5, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_6, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_7, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_8, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_9, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_10, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_11, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_12, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_13, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_14, true), + LOCATION(RC_GY_WONDER_DAMPE_RACE_15, true), }, { //Exits ENTRANCE(RR_THE_GRAVEYARD, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp index a78cb1f53e..8766b6db66 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp @@ -22,16 +22,18 @@ void RegionTable_Init_HauntedWasteland() { EVENT_ACCESS(LOGIC_CARPET_MERCHANT, logic->HasItem(RG_ADULT_WALLET) && GetCheckPrice(RC_WASTELAND_BOMBCHU_SALESMAN) <= GetWalletCapacity() && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))), }, { //Locations - LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_SPEAK_HYLIAN) && GetCheckPrice() <= GetWalletCapacity()), - LOCATION(RC_WASTELAND_GS, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (logic->IsAdult && logic->CanGroundJumpslash())), // need to jumpslash immediately with two handed weapons - LOCATION(RC_WASTELAND_NEAR_GS_POT_1, logic->CanBreakPots()), - LOCATION(RC_WASTELAND_NEAR_GS_POT_2, logic->CanBreakPots()), - LOCATION(RC_WASTELAND_NEAR_GS_POT_3, logic->CanBreakPots()), - LOCATION(RC_WASTELAND_NEAR_GS_POT_4, logic->CanBreakPots()), - LOCATION(RC_HW_AFTER_QUICKSAND_CRATE_1, logic->CanBreakCrates()), - LOCATION(RC_HW_AFTER_QUICKSAND_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_HW_AFTER_QUICKSAND_CRATE_3, logic->CanBreakCrates()), + LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_SPEAK_HYLIAN) && GetCheckPrice() <= GetWalletCapacity()), + LOCATION(RC_WASTELAND_GS, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (logic->IsAdult && logic->CanGroundJumpslash())), // need to jumpslash immediately with two handed weapons + LOCATION(RC_WASTELAND_NEAR_GS_POT_1, logic->CanBreakPots()), + LOCATION(RC_WASTELAND_NEAR_GS_POT_2, logic->CanBreakPots()), + LOCATION(RC_WASTELAND_NEAR_GS_POT_3, logic->CanBreakPots()), + LOCATION(RC_WASTELAND_NEAR_GS_POT_4, logic->CanBreakPots()), + LOCATION(RC_HW_AFTER_QUICKSAND_CRATE_1, logic->CanBreakCrates()), + LOCATION(RC_HW_AFTER_QUICKSAND_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_HW_AFTER_QUICKSAND_CRATE_3, logic->CanBreakCrates()), + LOCATION(RC_HW_CARPET_SALESMAN_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_HW_POE_ALTAR, logic->CanRead()), }, { //Exits ENTRANCE(RR_WASTELAND_NEAR_COLOSSUS, ctx->GetTrickOption(RT_LENS_HW) || logic->CanUse(RG_LENS_OF_TRUTH)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index 6691f0e94b..bc9afbd920 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -11,163 +11,189 @@ void RegionTable_Init_HyruleField() { EVENT_ACCESS(LOGIC_BORROW_RIGHT_MASKS, logic->IsChild && logic->Get(LOGIC_BORROW_BUNNY_HOOD) && logic->HasItem(RG_KOKIRI_EMERALD) && logic->HasItem(RG_GORON_RUBY) && logic->HasItem(RG_ZORA_SAPPHIRE) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)), }, { //Locations - LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), - LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), - LOCATION(RC_HF_POND_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_HF_CENTRAL_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_HF_CENTRAL_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTH_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_MARKET_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_KF_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_HF_NEAR_LLR_TREE, logic->CanBonkTrees()), - LOCATION(RC_HF_NEAR_LH_TREE, logic->CanBonkTrees()), - LOCATION(RC_HF_CHILD_NEAR_GV_TREE, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_HF_ADULT_NEAR_GV_TREE, logic->IsAdult && logic->CanBonkTrees()), - LOCATION(RC_HF_NEAR_ZR_TREE, logic->CanBonkTrees()), - LOCATION(RC_HF_NEAR_KAK_TREE, logic->CanBonkTrees()), - LOCATION(RC_HF_NEAR_KAK_SMALL_TREE, logic->CanBonkTrees()), - LOCATION(RC_HF_NEAR_MARKET_TREE_1, logic->CanBonkTrees()), - LOCATION(RC_HF_NEAR_MARKET_TREE_2, logic->CanBonkTrees()), - LOCATION(RC_HF_NEAR_MARKET_TREE_3, logic->CanBonkTrees()), - LOCATION(RC_HF_NORTHWEST_TREE_1, logic->CanBonkTrees()), - LOCATION(RC_HF_NORTHWEST_TREE_2, logic->CanBonkTrees()), - LOCATION(RC_HF_NORTHWEST_TREE_3, logic->CanBonkTrees()), - LOCATION(RC_HF_NORTHWEST_TREE_4, logic->CanBonkTrees()), - LOCATION(RC_HF_NORTHWEST_TREE_5, logic->CanBonkTrees()), - LOCATION(RC_HF_NORTHWEST_TREE_6, logic->CanBonkTrees()), - LOCATION(RC_HF_EAST_TREE_1, logic->CanBonkTrees()), - LOCATION(RC_HF_EAST_TREE_2, logic->CanBonkTrees()), - LOCATION(RC_HF_EAST_TREE_3, logic->CanBonkTrees()), - LOCATION(RC_HF_EAST_TREE_4, logic->CanBonkTrees()), - LOCATION(RC_HF_EAST_TREE_5, logic->CanBonkTrees()), - LOCATION(RC_HF_EAST_TREE_6, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_1, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_2, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_3, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_4, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_5, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_6, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_7, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_8, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_9, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_10, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_11, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_12, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_13, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_14, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_15, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_16, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_17, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_18, logic->CanBonkTrees()), - LOCATION(RC_HF_SOUTHEAST_TREE_19, logic->CanBonkTrees()), - LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_1, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_2, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_3, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_4, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), - LOCATION(RC_HF_BUSH_NEAR_LAKE_1, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_2, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_3, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_4, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_5, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_6, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_7, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_8, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_9, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_10, true), - LOCATION(RC_HF_BUSH_NEAR_LAKE_11, true), - LOCATION(RC_HF_NORTHERN_BUSH_1, true), - LOCATION(RC_HF_NORTHERN_BUSH_2, true), - LOCATION(RC_HF_NORTHERN_BUSH_3, true), - LOCATION(RC_HF_NORTHERN_BUSH_4, true), - LOCATION(RC_HF_NORTHERN_BUSH_5, true), - LOCATION(RC_HF_NORTHERN_BUSH_6, true), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_1, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_2, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_3, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_4, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_5, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_6, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_7, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_8, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_9, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_10, logic->IsChild), - LOCATION(RC_HF_CHILD_NORTHERN_BUSH_11, logic->IsChild), - LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_1, true), - LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_2, true), - LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_3, true), - LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_4, true), - LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_5, true), - LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_6, true), - LOCATION(RC_HF_SOUTHERN_BUSH_1, true), - LOCATION(RC_HF_SOUTHERN_BUSH_2, true), - LOCATION(RC_HF_SOUTHERN_BUSH_3, true), - LOCATION(RC_HF_SOUTHERN_BUSH_4, true), - LOCATION(RC_HF_SOUTHERN_BUSH_5, true), - LOCATION(RC_HF_SOUTHERN_BUSH_6, true), - LOCATION(RC_HF_SOUTHERN_BUSH_7, true), - LOCATION(RC_HF_SOUTHERN_BUSH_8, true), - LOCATION(RC_HF_SOUTHERN_BUSH_9, true), - LOCATION(RC_HF_SOUTHERN_BUSH_10, true), - LOCATION(RC_HF_SOUTHERN_BUSH_11, true), - LOCATION(RC_HF_SOUTHERN_BUSH_12, true), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_1, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_2, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_3, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_4, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_5, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_6, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_7, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_8, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_9, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_10, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_11, logic->IsChild), - LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_12, logic->IsChild), + LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_HF_POND_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HF_CENTRAL_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_HF_CENTRAL_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTH_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_KF_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_HF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_HF_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_HF_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_HF_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_HF_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_HF_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_HF_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_HF_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_HF_ROCK_8, logic->CanBreakRocks()), + LOCATION(RC_HF_BOULDER_NORTH, logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_BY_MARKET, logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_SOUTH, logic->BlastOrSmash()), + LOCATION(RC_HF_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_NEAR_LLR_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_LH_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_NEAR_GV_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_ADULT_NEAR_GV_TREE, logic->IsAdult && logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_ZR_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_KAK_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_KAK_SMALL_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_7, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_8, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_9, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_10, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_11, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_12, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_13, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_14, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_15, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_16, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_17, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_18, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_19, logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_1, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_2, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_3, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_4, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_BUSH_NEAR_LAKE_1, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_2, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_3, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_4, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_5, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_6, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_7, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_8, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_9, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_10, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_11, true), + LOCATION(RC_HF_NORTHERN_BUSH_1, true), + LOCATION(RC_HF_NORTHERN_BUSH_2, true), + LOCATION(RC_HF_NORTHERN_BUSH_3, true), + LOCATION(RC_HF_NORTHERN_BUSH_4, true), + LOCATION(RC_HF_NORTHERN_BUSH_5, true), + LOCATION(RC_HF_NORTHERN_BUSH_6, true), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_1, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_2, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_3, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_4, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_5, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_6, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_7, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_8, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_9, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_10, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_11, logic->IsChild), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_1, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_2, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_3, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_4, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_5, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_6, true), + LOCATION(RC_HF_SOUTHERN_BUSH_1, true), + LOCATION(RC_HF_SOUTHERN_BUSH_2, true), + LOCATION(RC_HF_SOUTHERN_BUSH_3, true), + LOCATION(RC_HF_SOUTHERN_BUSH_4, true), + LOCATION(RC_HF_SOUTHERN_BUSH_5, true), + LOCATION(RC_HF_SOUTHERN_BUSH_6, true), + LOCATION(RC_HF_SOUTHERN_BUSH_7, true), + LOCATION(RC_HF_SOUTHERN_BUSH_8, true), + LOCATION(RC_HF_SOUTHERN_BUSH_9, true), + LOCATION(RC_HF_SOUTHERN_BUSH_10, true), + LOCATION(RC_HF_SOUTHERN_BUSH_11, true), + LOCATION(RC_HF_SOUTHERN_BUSH_12, true), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_1, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_2, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_3, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_4, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_5, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_6, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_7, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_8, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_9, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_10, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_11, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_12, logic->IsChild), + LOCATION(RC_HF_CASTLE_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_HF_WOODED_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_HF_ROCKY_PATH_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_HF_FENCED_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_HF_CENTER_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_HF_RIVER_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_HF_STAIRS_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_HF_WONDER_BRIDGE_1, logic->IsChild), + LOCATION(RC_HF_WONDER_BRIDGE_2, logic->IsChild), + LOCATION(RC_HF_WONDER_BRIDGE_3, logic->IsChild), }, { //Exits ENTRANCE(RR_LW_BRIDGE, true), @@ -195,17 +221,18 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_SOUTHEAST_BOULDER_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_HYRULE_FIELD, true), @@ -213,17 +240,18 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_OPEN_GROTTO] = Region("HF Open Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_HF_OPEN_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), - LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), - LOCATION(RC_HF_OPEN_GROTTO_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_HF_OPEN_GROTTO_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_HF_OPEN_GROTTO_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_HF_OPEN_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_OPEN_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_OPEN_GROTTO_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_HF_OPEN_GROTTO_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HF_OPEN_GROTTO_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_HF_OPEN_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_OPEN_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_HYRULE_FIELD, true), @@ -278,6 +306,7 @@ void RegionTable_Init_HyruleField() { LOCATION(RC_HF_NEAR_MARKET_GROTTO_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_HF_NEAR_MARKET_GROTTO_GRASS_3, logic->CanCutShrubs()), LOCATION(RC_HF_NEAR_MARKET_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_HYRULE_FIELD, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index de64cc2f74..e4aeb949ad 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -23,7 +23,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->CanGetNightTimeGS() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->CanGetNightTimeGS() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS() && logic->CanBonkTrees() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), - LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && logic->HasItem(RG_CLIMB) && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && logic->HasItem(RG_CLIMB) && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_3, logic->IsChild && logic->CanBreakPots()), @@ -59,7 +59,19 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_NEAR_FENCE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BAZAAR_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_KAK_SILVER_BOULDER, logic->IsAdult && logic->CanUse(RG_SILVER_GAUNTLETS) && + (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOVER_BOOTS) || (logic->HasItem(RG_LONGSHOT) && ((logic->AtDay && logic->HasItem(RG_POWER_BRACELET)) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash() && logic->TakeDamage()))))), + LOCATION(RC_KAK_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_KAK_ROCK_2, logic->CanBreakRocks()), LOCATION(RC_KAK_TREE, logic->CanBonkTrees()), + LOCATION(RC_KAK_GUARD_GATE_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KAK_WELL_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KAK_SOUTHEAST_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_KAK_FRONT_GATE_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_KAK_WONDER_UNDER_CONSTRUCTION, logic->IsChild), + LOCATION(RC_KAK_BEGGAR_BUGS, logic->IsAdult && logic->CanUse(RG_BOTTLE_WITH_BUGS)), + LOCATION(RC_KAK_BEGGAR_FISH, logic->IsAdult && logic->CanUse(RG_BOTTLE_WITH_FISH)), + LOCATION(RC_KAK_BEGGAR_BLUE_FIRE, logic->IsAdult && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)), }, { //Exits ENTRANCE(RR_HYRULE_FIELD, true), @@ -162,7 +174,8 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_IMPAS_HOUSE] = Region("Kak Impas House", SCENE_IMPAS_HOUSE, {}, { //Locations - LOCATION(RC_KAK_IMPAS_HOUSE_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_KAK_IMPAS_HOUSE_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_KAK_WONDER_ABOVE_COW, true), }, { //Exits ENTRANCE(RR_KAKARIKO_VILLAGE, true), @@ -215,7 +228,8 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_SHOOTING_GALLERY] = Region("Kak Shooting Gallery", SCENE_SHOOTING_GALLERY, {}, { //Locations - LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN, logic->IsAdult && logic->CanRead()), }, { //Exits ENTRANCE(RR_KAKARIKO_VILLAGE, true), @@ -271,6 +285,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_OPEN_GROTTO_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_KAK_OPEN_GROTTO_GRASS_3, logic->CanCutShrubs()), LOCATION(RC_KAK_OPEN_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_KAK_OPEN_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_KAK_BACKYARD, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index d0e78f824f..5d65b3afd1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -11,62 +11,96 @@ void RegionTable_Init_KokiriForest() { EVENT_ACCESS(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, logic->IsChild && logic->HasItem(RG_SPEAK_KOKIRI) && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD)), }, { //Locations - LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanGetNightTimeGS()), - LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), - LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && logic->CanGetNightTimeGS() && - (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || - (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)))), - LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild), - LOCATION(RC_KF_BEHIND_MIDOS_RUPEE, logic->IsChild), - LOCATION(RC_KF_SOUTH_GRASS_WEST_RUPEE, logic->IsChild), - LOCATION(RC_KF_SOUTH_GRASS_EAST_RUPEE, logic->IsChild), - LOCATION(RC_KF_NORTH_GRASS_WEST_RUPEE, logic->IsChild), - LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild), - LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_SARIAS_ROOF_WEST_HEART, logic->IsChild), - LOCATION(RC_KF_SARIAS_ROOF_EAST_HEART, logic->IsChild), - LOCATION(RC_KF_SARIAS_ROOF_NORTH_HEART, logic->IsChild), - LOCATION(RC_KF_CHILD_GRASS_1, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_2, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_3, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_4, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_5, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_6, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_7, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_8, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_9, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_10, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_11, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_12, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_1, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_2, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_3, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_4, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_5, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_6, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_7, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_8, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_9, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_10, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_11, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_12, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_13, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_14, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_15, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_16, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_17, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_18, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_19, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_ADULT_GRASS_20, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanGetNightTimeGS()), + LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), + LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && logic->CanGetNightTimeGS() && + (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || + (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)))), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild), + LOCATION(RC_KF_BEHIND_MIDOS_RUPEE, logic->IsChild), + LOCATION(RC_KF_SOUTH_GRASS_WEST_RUPEE, logic->IsChild), + LOCATION(RC_KF_SOUTH_GRASS_EAST_RUPEE, logic->IsChild), + LOCATION(RC_KF_NORTH_GRASS_WEST_RUPEE, logic->IsChild), + LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild), + LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_SARIAS_ROOF_WEST_HEART, logic->IsChild), + LOCATION(RC_KF_SARIAS_ROOF_EAST_HEART, logic->IsChild), + LOCATION(RC_KF_SARIAS_ROOF_NORTH_HEART, logic->IsChild), + LOCATION(RC_KF_CHILD_GRASS_1, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_2, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_3, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_4, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_5, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_6, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_7, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_8, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_9, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_10, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_11, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_12, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_1, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_2, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_3, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_4, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_5, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_6, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_7, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_8, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_9, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_10, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_11, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_12, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_13, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_14, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_15, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_16, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_17, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_18, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_19, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_ADULT_GRASS_20, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_CIRCLE_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_KF_CIRCLE_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_KF_CIRCLE_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_KF_CIRCLE_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_KF_CIRCLE_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_KF_CIRCLE_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_KF_CIRCLE_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_KF_CIRCLE_ROCK_8, logic->CanBreakRocks()), + LOCATION(RC_KF_ROCK_BY_SARIAS_HOUSE, logic->IsChild && logic->CanBreakRocks()), + LOCATION(RC_KF_ROCK_BEHIND_SARIAS_HOUSE, logic->IsChild && logic->CanBreakRocks()), + LOCATION(RC_KF_ROCK_BY_MIDOS_HOUSE, logic->IsChild && logic->CanBreakRocks()), + LOCATION(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, logic->IsChild && logic->CanBreakRocks()), + LOCATION(RC_KF_DEKU_TREE_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_KF_STEPPING_STONES_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_KF_LINKS_HOUSE_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_KF_FIRST_TRAINING_CENTER_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KF_SECOND_TRAINING_CENTER_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KF_CRAWL_RECTANGLE_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KF_LOST_WOODS_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_KF_HOUSE_OF_TWINS_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_KF_SHOP_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_KF_SARIAS_HOUSE_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_KF_MIDOS_HOUSE_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_KF_TRAINING_CENTER_ENTRANCE_ARROW_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KF_INNER_TRAINING_CENTER_ARROW_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KF_KNOW_IT_ALL_BROTHERS_HOUSE_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_KF_WONDER_TRAINING_1, logic->IsChild), + LOCATION(RC_KF_WONDER_TRAINING_2, logic->IsChild), + LOCATION(RC_KF_WONDER_TRAINING_3, logic->IsChild), + LOCATION(RC_KF_WONDER_SIGN, logic->IsChild && logic->CanJumpslashExceptHammer()), + LOCATION(RC_KF_WONDER_PLATFORMS_1, logic->IsChild), + LOCATION(RC_KF_WONDER_PLATFORMS_2, logic->IsChild), + //Technically bad logic, because we can move Mido out of logic, but then we already have KSword... + LOCATION(RC_MIDO_HINT, !ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) && logic->IsChild && logic->HasItem(RG_SPEAK_KOKIRI)), }, { //Exits ENTRANCE(RR_KF_BOULDER_LOOP, logic->CanUse(RG_CRAWL)), @@ -78,20 +112,58 @@ void RegionTable_Init_KokiriForest() { ENTRANCE(RR_KF_HOUSE_OF_TWINS, true), ENTRANCE(RR_KF_KNOW_IT_ALL_HOUSE, true), ENTRANCE(RR_KF_KOKIRI_SHOP, true), - ENTRANCE(RR_KF_OUTSIDE_DEKU_TREE, (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->Get(LOGIC_FOREST_TEMPLE_CLEAR))) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD)), + ENTRANCE(RR_KF_OUTSIDE_DEKU_TREE, (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->Get(LOGIC_FOREST_TEMPLE_CLEAR))) || logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD)), ENTRANCE(RR_KF_OUTSIDE_LOST_WOODS, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS)))), ENTRANCE(RR_KF_RUPEE_ALCOVE, logic->IsAdult && CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL)), ENTRANCE(RR_LW_BRIDGE_FROM_FOREST, logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || logic->Get(LOGIC_DEKU_TREE_CLEAR)), }); + areaTable[RR_KF_OUTSIDE_LOST_WOODS] = Region("KF Outside Lost Woods", SCENE_KOKIRI_FOREST, {}, { + //Locations + LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_KF_LOST_WOODS_ARROW_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KF_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_KF_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_GOSSIP_STONE, true), + }, { + //Exits + ENTRANCE(RR_KOKIRI_FOREST, true), + ENTRANCE(RR_THE_LOST_WOODS, true), + ENTRANCE(RR_KF_RUPEE_ALCOVE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS))), + ENTRANCE(RR_KF_STORMS_GROTTO, logic->CanOpenStormsGrotto()), + }); + + areaTable[RR_KF_RUPEE_ALCOVE] = Region("KF Alcove", SCENE_KOKIRI_FOREST, {}, { + //Locations + LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), + }, { + ENTRANCE(RR_KOKIRI_FOREST, true), + }); + areaTable[RR_KF_BOULDER_LOOP] = Region("KF Boulder Loop", SCENE_KOKIRI_FOREST, {}, { //Locations - LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild), - LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild), - LOCATION(RC_KF_CHILD_GRASS_MAZE_1, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_MAZE_2, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_MAZE_3, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild), + LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild), + LOCATION(RC_KF_CHILD_GRASS_MAZE_1, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_MAZE_2, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_MAZE_3, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_AFTER_CRAWLSPACE_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KF_BOULDER_MAZE_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_KF_WONDER_CRAWL_GRASS_1, logic->IsChild), + LOCATION(RC_KF_WONDER_CRAWL_GRASS_2, logic->IsChild), }, { //Exits ENTRANCE(RR_KOKIRI_FOREST, logic->CanUse(RG_CRAWL)), @@ -124,8 +196,9 @@ void RegionTable_Init_KokiriForest() { areaTable[RR_KF_LINKS_HOUSE] = Region("KF Link's House", SCENE_LINKS_HOUSE, {}, { //Locations - LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->Get(LOGIC_LINKS_COW)), - LOCATION(RC_KF_LINKS_HOUSE_POT, logic->HasItem(RG_POWER_BRACELET)), // TODO: CanBreakPots() restricted + LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->Get(LOGIC_LINKS_COW)), + LOCATION(RC_KF_LINKS_HOUSE_POT, logic->HasItem(RG_POWER_BRACELET)), // TODO: CanBreakPots() restricted + LOCATION(RC_KF_LINKS_HOUSE_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_KF_LINKS_PORCH, true), @@ -137,6 +210,7 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_MIDOS_TOP_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_KF_MIDOS_BOTTOM_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_MIDO_HINT, logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD) && logic->IsChild && logic->HasItem(RG_SPEAK_KOKIRI)), }, { //Exits ENTRANCE(RR_KOKIRI_FOREST, true), @@ -181,44 +255,12 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_SHOP_ITEM_6, logic->HasItem(RG_SPEAK_KOKIRI) && GetCheckPrice() <= GetWalletCapacity()), LOCATION(RC_KF_SHOP_ITEM_7, logic->HasItem(RG_SPEAK_KOKIRI) && GetCheckPrice() <= GetWalletCapacity()), LOCATION(RC_KF_SHOP_ITEM_8, logic->HasItem(RG_SPEAK_KOKIRI) && GetCheckPrice() <= GetWalletCapacity()), + LOCATION(RC_KF_WONDER_SHOP, true), }, { //Exits ENTRANCE(RR_KOKIRI_FOREST, true), }); - areaTable[RR_KF_OUTSIDE_LOST_WOODS] = Region("KF Outside Lost Woods", SCENE_KOKIRI_FOREST, {}, { - //Locations - LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_KF_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), - LOCATION(RC_KF_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_KF_GOSSIP_STONE, true), - }, { - //Exits - ENTRANCE(RR_KOKIRI_FOREST, true), - ENTRANCE(RR_THE_LOST_WOODS, true), - ENTRANCE(RR_KF_RUPEE_ALCOVE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS))), - ENTRANCE(RR_KF_STORMS_GROTTO, logic->CanOpenStormsGrotto()), - }); - - areaTable[RR_KF_RUPEE_ALCOVE] = Region("KF Alcove", SCENE_KOKIRI_FOREST, {}, { - //Locations - LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)), - }, { - ENTRANCE(RR_KOKIRI_FOREST, true), - }); - areaTable[RR_KF_STORMS_GROTTO] = Region("KF Storms Grotto", SCENE_GROTTOS, grottoEvents, { //Locations LOCATION(RC_KF_STORMS_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), @@ -232,6 +274,7 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_STORMS_GROTTO_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_KF_STORMS_GROTTO_GRASS_3, logic->CanCutShrubs()), LOCATION(RC_KF_STORMS_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_KF_STORMS_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_KF_OUTSIDE_LOST_WOODS, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index 5c99fd46ff..1abe5fc54b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -79,6 +79,10 @@ void RegionTable_Init_LakeHylia() { LOCATION(RC_LH_CHILD_GRASS_4, logic->IsChild && logic->CanCutShrubs()), LOCATION(RC_LH_WARP_PAD_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_LH_WARP_PAD_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_LH_SCARECROW_BUTTERFLY_FAIRY, logic->IsChild && logic->CanUse(RG_STICKS)), + LOCATION(RC_LH_LAB_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_LH_NORTH_EXIT_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_LH_ISLAND_PEDESTAL, logic->CanRead()), }, { //Exits ENTRANCE(RR_HF_TO_LAKE_HYLIA, true), @@ -102,7 +106,11 @@ void RegionTable_Init_LakeHylia() { ENTRANCE(RR_WATER_TEMPLE_ENTRYWAY, logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)))), }); - areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, {}, { + areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, { + //Locations + LOCATION(RC_LH_ROCK, logic->CanBreakRocks()), + LOCATION(RC_LH_FISHING_SIGN, logic->CanRead()), + }, { //Exits ENTRANCE(RR_LAKE_HYLIA, logic->HasItem(RG_BRONZE_SCALE)), ENTRANCE(RR_LH_FISHING_POND, logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY)), @@ -130,43 +138,44 @@ void RegionTable_Init_LakeHylia() { // TODO: should some of these helpers be done via events instead? areaTable[RR_LH_FISHING_POND] = Region("LH Fishing Hole", SCENE_FISHING_POND, {}, { //Locations - LOCATION(RC_LH_CHILD_FISHING, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsChild), - LOCATION(RC_LH_CHILD_FISH_1, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_2, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_3, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_4, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_5, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_6, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_7, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_8, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_9, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_10, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_11, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_12, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_13, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_14, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_FISH_15, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_LOACH_1, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_CHILD_LOACH_2, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), - LOCATION(RC_LH_ADULT_FISHING, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult), - LOCATION(RC_LH_ADULT_FISH_1, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_2, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_3, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_4, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_5, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_6, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_7, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_8, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_9, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_10, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_11, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_12, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_13, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_14, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_FISH_15, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_ADULT_LOACH, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), - LOCATION(RC_LH_HYRULE_LOACH, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN)), - LOCATION(RC_FISHING_POLE_HINT, logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_LH_CHILD_FISHING, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsChild), + LOCATION(RC_LH_CHILD_FISH_1, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_2, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_3, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_4, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_5, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_6, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_7, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_8, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_9, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_10, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_11, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_12, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_13, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_14, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_15, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_LOACH_1, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_LOACH_2, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && (logic->IsChild || !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_ADULT_FISHING, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult), + LOCATION(RC_LH_ADULT_FISH_1, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_2, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_3, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_4, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_5, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_6, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_7, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_8, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_9, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_10, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_11, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_12, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_13, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_14, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_15, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_LOACH, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_HYRULE_LOACH, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_FISHING_POLE_HINT, logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_LH_FISHING_POND_RECTANGLE_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_LH_FISHING_ISLAND, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index c71745f109..400b3d98fe 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -11,20 +11,22 @@ void RegionTable_Init_LonLonRanch() { EVENT_ACCESS(LOGIC_LINKS_COW, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay), }, { //Locations - LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), - LOCATION(RC_LLR_GS_TREE, logic->IsChild && logic->CanBonkTrees() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), - LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetNightTimeGS() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), - LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_LLR_FRONT_POT_1, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_LLR_FRONT_POT_2, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_LLR_FRONT_POT_3, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_LLR_FRONT_POT_4, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_LLR_RAIN_SHED_POT_1, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_LLR_RAIN_SHED_POT_2, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_LLR_RAIN_SHED_POT_3, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_LLR_NEAR_TREE_CRATE, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_LLR_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), + LOCATION(RC_LLR_GS_TREE, logic->IsChild && logic->CanBonkTrees() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), + LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetNightTimeGS() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), + LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_FRONT_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_FRONT_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_FRONT_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_FRONT_POT_4, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_RAIN_SHED_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_RAIN_SHED_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_RAIN_SHED_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_NEAR_TREE_CRATE, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_LLR_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_LLR_WONDER_BIG_FENCE, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && (logic->HasItem(RG_CHILD_WALLET) || logic->Get(LOGIC_FREED_EPONA))), + LOCATION(RC_LLR_WONDER_SMALL_FENCE, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && (logic->HasItem(RG_CHILD_WALLET) || logic->Get(LOGIC_FREED_EPONA))), }, { //Exits ENTRANCE(RR_HYRULE_FIELD, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index 6df779cf69..67c122f851 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -48,6 +48,10 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_LW_BOULDER_BY_GORON_CITY, logic->BlastOrSmash()), + LOCATION(RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_1, logic->IsChild), + LOCATION(RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_2, logic->IsChild), + LOCATION(RC_LW_WONDER_FRONT_SKULL_KIDS_GRASS, logic->IsChild), }, { //Exits ENTRANCE(RR_LW_FOREST_EXIT, true), @@ -93,6 +97,9 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GRASS_7, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_8, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, logic->BlastOrSmash()), + LOCATION(RC_LW_RUPEE_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_LW_MEADOW_BUTTERFLY_FAIRY, logic->IsChild && logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_LW_FOREST_EXIT, true), @@ -115,6 +122,7 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3, logic->CanCutShrubs()), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_LW_TUNNEL_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_THE_LOST_WOODS, true), @@ -124,6 +132,7 @@ void RegionTable_Init_LostWoods() { //Locations LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->CanUse(RG_SKULL_MASK)), LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->CanUse(RG_MASK_OF_TRUTH) && logic->HasItem(RG_SPEAK_DEKU)), + LOCATION(RC_LW_THEATER_RECTANGLE_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_LW_BEYOND_MIDO, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 9eabf6c290..558c66539f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -28,6 +28,16 @@ void RegionTable_Init_Market() { LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), LOCATION(RC_MARKET_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_MKT_WONDER_DAY_1, logic->IsChild && logic->AtDay), + LOCATION(RC_MKT_WONDER_DAY_2, logic->IsChild && logic->AtDay), + LOCATION(RC_MKT_WONDER_DAY_3, logic->IsChild && logic->AtDay), + LOCATION(RC_MKT_WONDER_DAY_4, logic->IsChild && logic->AtDay), + LOCATION(RC_MKT_WONDER_DAY_5, logic->IsChild && logic->AtDay), + LOCATION(RC_MKT_WONDER_NIGHT_1, logic->IsChild && logic->AtNight), + LOCATION(RC_MKT_WONDER_NIGHT_2, logic->IsChild && logic->AtNight), + LOCATION(RC_MK_BEGGAR_BUGS, logic->IsChild && logic->AtDay && logic->CanUse(RG_BOTTLE_WITH_BUGS)), + LOCATION(RC_MK_BEGGAR_FISH, logic->IsChild && logic->AtDay && logic->CanUse(RG_BOTTLE_WITH_FISH)), + LOCATION(RC_MK_BEGGAR_BLUE_FIRE, logic->IsChild && logic->AtDay && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)), }, { //Exits ENTRANCE(RR_MARKET_ENTRANCE, true), @@ -149,7 +159,8 @@ void RegionTable_Init_Market() { EVENT_ACCESS(LOGIC_BORROW_RIGHT_MASKS, ctx->GetOption(RSK_MASK_QUEST).Is(RO_MASK_QUEST_COMPLETED) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->Get(LOGIC_CAN_BORROW_MASKS)), }, { //Locations - LOCATION(RC_MASK_SHOP_HINT, true), + LOCATION(RC_MASK_SHOP_HINT, true), + LOCATION(RC_MK_MASK_SHOP_SIGN, logic->CanRead()), }, { //Exits ENTRANCE(RR_THE_MARKET, true), @@ -157,7 +168,8 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_SHOOTING_GALLERY] = Region("Market Shooting Gallery", SCENE_SHOOTING_GALLERY, {}, { //Locations - LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_MK_SHOOTING_GALLERY_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), }, { //Exits ENTRANCE(RR_THE_MARKET, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp index 8d6c7700e3..bececec7e6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp @@ -5,7 +5,10 @@ using namespace Rando; void RegionTable_Init_SacredForestMeadow() { // clang-format off - areaTable[RR_SFM_ENTRYWAY] = Region("SFM Entryway", SCENE_SACRED_FOREST_MEADOW, {}, {}, { + areaTable[RR_SFM_ENTRYWAY] = Region("SFM Entryway", SCENE_SACRED_FOREST_MEADOW, {}, { + //Locations + LOCATION(RC_SFM_WONDER_ENTRANCE, true), + }, { //Exits ENTRANCE(RR_LW_BEYOND_MIDO, true), ENTRANCE(RR_SACRED_FOREST_MEADOW, logic->IsAdult || logic->CanKillEnemy(RE_WOLFOS)), @@ -41,6 +44,11 @@ void RegionTable_Init_SacredForestMeadow() { LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_SFM_SARIA_GOSSIP_STONE, true), + LOCATION(RC_SFM_WONDER_MAZE_1, true), + LOCATION(RC_SFM_WONDER_MAZE_2, true), + LOCATION(RC_SFM_WONDER_MAZE_3, true), + LOCATION(RC_SFM_WONDER_MAZE_4, true), + LOCATION(RC_SFM_WONDER_MAZE_5, true), }, { //Exits ENTRANCE(RR_FOREST_TEMPLE_ENTRYWAY, logic->CanUse(RG_HOOKSHOT)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp index 8871ee293a..3089f75ef4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp @@ -34,6 +34,7 @@ void RegionTable_Init_TempleOfTime() { LOCATION(RC_ALTAR_HINT_CHILD, logic->IsChild), LOCATION(RC_ALTAR_HINT_ADULT, logic->IsAdult), LOCATION(RC_TOT_SHEIK_HINT, logic->IsAdult && logic->HasItem(RG_SPEAK_HYLIAN)), + LOCATION(RC_TOT_ALTAR, logic->CanRead()), }, { //Exits ENTRANCE(RR_TOT_ENTRANCE, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp index 7473541035..e9a448c962 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp @@ -17,6 +17,8 @@ void RegionTable_Init_ThievesHideout() { LOCATION(RC_TH_1_TORCH_CELL_MID_POT, logic->CanBreakPots()), LOCATION(RC_TH_1_TORCH_CELL_LEFT_POT, logic->CanBreakPots()), LOCATION(RC_TH_1_TORCH_CELL_CRATE, logic->CanBreakCrates()), + LOCATION(RC_TH_WONDER_1_TORCH_1, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_TH_WONDER_1_TORCH_2, logic->CanUse(RG_FAIRY_BOW)), LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), }, { //Exits @@ -30,17 +32,19 @@ void RegionTable_Init_ThievesHideout() { EVENT_ACCESS(LOGIC_TH_RESCUED_ALL_CARPENTERS, logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->Get(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER)), }, { //Locations - LOCATION(RC_TH_DOUBLE_CELL_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), - LOCATION(RC_TH_NEAR_DOUBLE_CELL_RIGHT_POT, logic->CanBreakPots()), - LOCATION(RC_TH_NEAR_DOUBLE_CELL_MID_POT, logic->CanBreakPots()), - LOCATION(RC_TH_NEAR_DOUBLE_CELL_LEFT_POT, logic->CanBreakPots()), - LOCATION(RC_TH_RIGHTMOST_JAILED_POT, logic->CanBreakPots()), - LOCATION(RC_TH_RIGHT_MIDDLE_JAILED_POT, logic->CanBreakPots()), - LOCATION(RC_TH_LEFT_MIDDLE_JAILED_POT, logic->CanBreakPots()), - LOCATION(RC_TH_LEFTMOST_JAILED_POT, logic->CanBreakPots()), - LOCATION(RC_TH_DOUBLE_CELL_LEFT_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_DOUBLE_CELL_RIGHT_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), + LOCATION(RC_TH_DOUBLE_CELL_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), + LOCATION(RC_TH_NEAR_DOUBLE_CELL_RIGHT_POT, logic->CanBreakPots()), + LOCATION(RC_TH_NEAR_DOUBLE_CELL_MID_POT, logic->CanBreakPots()), + LOCATION(RC_TH_NEAR_DOUBLE_CELL_LEFT_POT, logic->CanBreakPots()), + LOCATION(RC_TH_RIGHTMOST_JAILED_POT, logic->CanBreakPots()), + LOCATION(RC_TH_RIGHT_MIDDLE_JAILED_POT, logic->CanBreakPots()), + LOCATION(RC_TH_LEFT_MIDDLE_JAILED_POT, logic->CanBreakPots()), + LOCATION(RC_TH_LEFTMOST_JAILED_POT, logic->CanBreakPots()), + LOCATION(RC_TH_DOUBLE_CELL_LEFT_CRATE, logic->CanBreakCrates()), + LOCATION(RC_TH_DOUBLE_CELL_RIGHT_CRATE, logic->CanBreakCrates()), + LOCATION(RC_TH_WONDER_DOUBLE_JAIL_LOWER_EXIT, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_TH_WONDER_DOUBLE_JAIL_UPPER_EXIT, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), }, { //Exits ENTRANCE(RR_GF_OUTSKIRTS, true), @@ -54,9 +58,11 @@ void RegionTable_Init_ThievesHideout() { EVENT_ACCESS(LOGIC_TH_RESCUED_ALL_CARPENTERS, logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->Get(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER)), }, { //Locations - LOCATION(RC_TH_DEAD_END_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), - LOCATION(RC_TH_DEAD_END_CELL_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), + LOCATION(RC_TH_DEAD_END_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), + LOCATION(RC_TH_DEAD_END_CELL_CRATE, logic->CanBreakCrates()), + LOCATION(RC_TH_WONDER_DEAD_END_SKULL_ENTRANCE, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_TH_WONDER_DEAD_END_SKULL_NEAR_JAIL, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), }, { //Exits ENTRANCE(RR_GF_BELOW_GS, true), @@ -68,10 +74,12 @@ void RegionTable_Init_ThievesHideout() { EVENT_ACCESS(LOGIC_TH_RESCUED_ALL_CARPENTERS, logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->Get(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER)), }, { //Locations - LOCATION(RC_TH_STEEP_SLOPE_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), - LOCATION(RC_TH_STEEP_SLOPE_RIGHT_POT, logic->CanBreakPots()), - LOCATION(RC_TH_STEEP_SLOPE_LEFT_POT, logic->CanBreakPots()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), + LOCATION(RC_TH_STEEP_SLOPE_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), + LOCATION(RC_TH_STEEP_SLOPE_RIGHT_POT, logic->CanBreakPots()), + LOCATION(RC_TH_STEEP_SLOPE_LEFT_POT, logic->CanBreakPots()), + LOCATION(RC_TH_WONDER_STEEP_SLOPE_LOWER_EXIT, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_TH_WONDER_STEEP_SLOPE_UPPER_EXIT, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), }, { //Exits ENTRANCE(RR_GF_BOTTOM_OF_LOWER_VINES, true), @@ -93,10 +101,12 @@ void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_KITCHEN_MAIN] = Region("Thieves Hideout Kitchen Bottom", SCENE_THIEVES_HIDEOUT, {}, { //Locations - LOCATION(RC_TH_KITCHEN_POT_1, logic->CanBreakPots() && logic->CanPassEnemy(RE_GERUDO_GUARD)), - LOCATION(RC_TH_KITCHEN_POT_2, logic->CanBreakPots() && logic->CanPassEnemy(RE_GERUDO_GUARD)), - LOCATION(RC_TH_KITCHEN_CRATE, logic->CanBreakCrates() && logic->CanPassEnemy(RE_GERUDO_GUARD)), - LOCATION(RC_TH_KITCHEN_SUN_FAIRY, logic->CanPassEnemy(RE_GERUDO_GUARD) && logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_TH_KITCHEN_POT_1, logic->CanBreakPots() && logic->CanPassEnemy(RE_GERUDO_GUARD)), + LOCATION(RC_TH_KITCHEN_POT_2, logic->CanBreakPots() && logic->CanPassEnemy(RE_GERUDO_GUARD)), + LOCATION(RC_TH_KITCHEN_CRATE, logic->CanBreakCrates() && logic->CanPassEnemy(RE_GERUDO_GUARD)), + LOCATION(RC_TH_KITCHEN_SUN_FAIRY, logic->CanPassEnemy(RE_GERUDO_GUARD) && logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_TH_WONDER_KITCHEN_SKULL, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_TH_WONDER_KITCHEN_SOUP, (logic->TakeDamage() || logic->IsAdult || logic->CanUse(RG_GORON_TUNIC)) && logic->CanPassEnemy(RE_GERUDO_GUARD)), }, { //Exits ENTRANCE(RR_TH_KITCHEN_CORRIDOR, logic->CanPassEnemy(RE_GERUDO_GUARD)), @@ -142,14 +152,25 @@ void RegionTable_Init_ThievesHideout() { (logic->CanPassEnemy(RE_GERUDO_GUARD) && logic->HasExplosives() && logic->CanUse(RG_BOOMERANG))), }, { //Exits - ENTRANCE(RR_GF_BELOW_CHEST, logic->CanPassEnemy(RE_GERUDO_GUARD)), - //Implies logic->CanPassEnemy(RE_GERUDO_GUARD) - ENTRANCE(RR_TH_BREAK_ROOM_CORRIDOR, logic->CanUse(RG_HOOKSHOT)), + ENTRANCE(RR_GF_BELOW_CHEST, logic->CanPassEnemy(RE_GERUDO_GUARD)), + ENTRANCE(RR_TH_BREAK_ROOM_LOWER_CORRIDOR, logic->CanPassEnemy(RE_GERUDO_GUARD)), }); - areaTable[RR_TH_BREAK_ROOM_CORRIDOR] = Region("Thieves Hideout Break Room", SCENE_THIEVES_HIDEOUT, {}, {}, { + areaTable[RR_TH_BREAK_ROOM_LOWER_CORRIDOR] = Region("Thieves Hideout Break Room", SCENE_THIEVES_HIDEOUT, {}, { + //Locations + LOCATION(RC_TH_WONDER_BREAK_ROOM_BOTTOM_SKULL, logic->CanUse(RG_FAIRY_BOW)), + }, { + //Exits + ENTRANCE(RR_TH_BREAK_ROOM, logic->CanPassEnemy(RE_GERUDO_GUARD)), + ENTRANCE(RR_TH_BREAK_ROOM_UPPER_CORRIDOR, logic->CanUse(RG_HOOKSHOT)), + }); + + areaTable[RR_TH_BREAK_ROOM_UPPER_CORRIDOR] = Region("Thieves Hideout Break Room", SCENE_THIEVES_HIDEOUT, {}, { + //Locations + LOCATION(RC_TH_WONDER_BREAK_ROOM_TOP_SKULL, logic->CanUse(RG_FAIRY_BOW)), + }, { //Exits - ENTRANCE(RR_TH_BREAK_ROOM, logic->CanUse(RG_HOOKSHOT)), + ENTRANCE(RR_TH_BREAK_ROOM_LOWER_CORRIDOR, logic->CanUse(RG_HOOKSHOT)), ENTRANCE(RR_GF_ABOVE_JAIL, true), }); } diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 87c97f6b31..0649f5f3d4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -27,7 +27,6 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_FISH_5, logic->IsChild && logic->HasBottle()), LOCATION(RC_ZD_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_ZD_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ZD_GOSSIP_STONE, true), LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->IsChild && logic->CanBreakUpperBeehives()), LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->IsChild && logic->CanBreakUpperBeehives()), LOCATION(RC_ZD_NEAR_SHOP_POT_1, logic->CanBreakPots()), @@ -35,6 +34,22 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_NEAR_SHOP_POT_3, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_4, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_5, logic->CanBreakPots()), + LOCATION(RC_ZD_CIRCLE_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_ZD_CIRCLE_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_ZD_CIRCLE_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_ZD_CIRCLE_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_ZD_CIRCLE_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_ZD_CIRCLE_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_ZD_CIRCLE_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_ZD_CIRCLE_ROCK_8, logic->CanBreakRocks()), + LOCATION(RC_ZD_SHOP_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_ZD_ENTRANCE_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_ZD_KING_ZORA_PATH_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_ZD_NEAR_KING_ZORA_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_ZD_NEAR_KING_ZORA_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_ZD_KING_ZORA_RED_ICE, logic->IsAdult && logic->Get(LOGIC_KING_ZORA_THAWED)), + LOCATION(RC_ZD_ZORA_SHOP_RED_ICE, logic->IsAdult && logic->BlueFire()), + LOCATION(RC_ZD_GOSSIP_STONE, true), }, { //Exits ENTRANCE(RR_ZR_BEHIND_WATERFALL, true), @@ -56,6 +71,7 @@ void RegionTable_Init_ZorasDomain() { }, { //Locations LOCATION(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, logic->IsChild && logic->CanBreakUpperBeehives()), + LOCATION(RC_ZD_KING_ZORA_RED_ICE, logic->IsAdult && logic->Get(LOGIC_KING_ZORA_THAWED)), }, { //Exits ENTRANCE(RR_ZORAS_DOMAIN, logic->Get(LOGIC_DELIVER_RUTOS_LETTER) || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index 4d861b431f..562f8978e8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -10,25 +10,32 @@ void RegionTable_Init_ZorasFountain() { EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_STICKS) && logic->AtDay)), }, { //Locations - LOCATION(RC_ZF_GS_TREE, logic->IsChild && logic->CanBonkTrees() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), - LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), - LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), - LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), - LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), - LOCATION(RC_ZF_NEAR_JABU_POT_1, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_ZF_NEAR_JABU_POT_2, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_ZF_TREE, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_ZF_BUSH_1, logic->IsChild), - LOCATION(RC_ZF_BUSH_2, logic->IsChild), - LOCATION(RC_ZF_BUSH_3, logic->IsChild), - LOCATION(RC_ZF_BUSH_4, logic->IsChild), - LOCATION(RC_ZF_BUSH_5, logic->IsChild), - LOCATION(RC_ZF_BUSH_6, logic->IsChild), + LOCATION(RC_ZF_GS_TREE, logic->IsChild && logic->CanBonkTrees() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))), + LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), + LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), + LOCATION(RC_ZF_NEAR_JABU_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_ZF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_ZF_UNDERGROUND_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash()), + LOCATION(RC_ZF_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZF_BUSH_1, logic->IsChild), + LOCATION(RC_ZF_BUSH_2, logic->IsChild), + LOCATION(RC_ZF_BUSH_3, logic->IsChild), + LOCATION(RC_ZF_BUSH_4, logic->IsChild), + LOCATION(RC_ZF_BUSH_5, logic->IsChild), + LOCATION(RC_ZF_BUSH_6, logic->IsChild), + LOCATION(RC_ZF_LOG_BUTTERFLY_FAIRY, logic->IsChild && logic->AtDay && logic->CanUse(RG_STICKS)), + LOCATION(RC_ZF_JABU_JABU_PLATFORM_RECTANGLE_SIGN, logic->IsChild && logic->CanRead()), + LOCATION(RC_ZF_ENTRANCE_ARROW_SIGN, logic->CanRead()), + LOCATION(RC_ZF_WONDER_ROCK, logic->IsAdult && logic->ReachScarecrow()), }, { //Exits ENTRANCE(RR_ZD_BEHIND_KING_ZORA, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 6eea347272..f62362aecf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -7,20 +7,29 @@ void RegionTable_Init_ZoraRiver() { // clang-format off areaTable[RR_ZR_FRONT] = Region("ZR Front", SCENE_ZORAS_RIVER, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), - LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), + LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_ZR_BOULDER_1, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_2, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_4, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), + // Require backflip with Iron Boots + LOCATION(RC_ZR_WONDER_LOWER_RIVER_1, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_LOWER_RIVER_2, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_LOWER_RIVER_3, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_LOWER_RIVER_4, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), }, { //Exits ENTRANCE(RR_ZORAS_RIVER, logic->IsAdult || logic->BlastOrSmash() || logic->CanUse(RG_HOVER_BOOTS)), @@ -50,12 +59,59 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), + LOCATION(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_CIRCLE_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_ZR_CIRCLE_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_ZR_CIRCLE_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_ZR_CIRCLE_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_ZR_CIRCLE_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_ZR_CIRCLE_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_ZR_CIRCLE_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_ZR_CIRCLE_ROCK_8, logic->CanBreakRocks()), + LOCATION(RC_ZR_ROCK, logic->CanBreakRocks()), + LOCATION(RC_ZR_UNDERWATER_ROCK_1, (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_BOMB_DETONATION)) || (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))) && + (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_UNDERWATER_ROCK_2, (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_BOMB_DETONATION)) || (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))) && + (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_UNDERWATER_ROCK_3, (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_BOMB_DETONATION)) || (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))) && + (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_UNDERWATER_ROCK_4, (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_BOMB_DETONATION)) || (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))) && + (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), LOCATION(RC_ZR_NEAR_FREESTANDING_POH_GRASS, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_ZR_NEAR_ROCK_CIRCLE_BUTTERFLY_FAIRY, logic->IsChild && logic->CanUse(RG_STICKS)), + LOCATION(RC_ZR_WATERFALL_BUTTERFLY_FAIRY, logic->IsChild && logic->CanUse(RG_STICKS)), + LOCATION(RC_ZR_SLEEPLESS_WATERFALL_PLAQUE, logic->CanRead()), + LOCATION(RC_ZR_WONDER_NEAR_DOMAIN_1, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_NEAR_DOMAIN_2, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_NEAR_DOMAIN_3, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_NEAR_DOMAIN_4, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_BEFORE_LADDER_1, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_BEFORE_LADDER_2, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_BEFORE_LADDER_3, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_BEFORE_LADDER_4, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_BEFORE_LADDER_5, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_BEFORE_LADDER_6, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_AFTER_LADDER_1, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_AFTER_LADDER_2, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_AFTER_LADDER_3, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_FROG_BRIDGE_1, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_FROG_BRIDGE_2, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_FROG_BRIDGE_3, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_PILLARS_1, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_PILLARS_2, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_PILLARS_3, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_PILLARS_4, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_LOWER_LAND_BRIDGE_1, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), // Requires backflip with Iron Boots + LOCATION(RC_ZR_WONDER_LOWER_LAND_BRIDGE_2, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_LOWER_LAND_BRIDGE_3, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_LOWER_LAND_BRIDGE_4, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_WONDER_NEAR_CUCCO_1, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), // Requires backflip with Iron Boots + LOCATION(RC_ZR_WONDER_NEAR_CUCCO_2, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), // Requires backflip with Iron Boots + LOCATION(RC_ZR_WONDER_NEAR_CUCCO_3, logic->IsChild && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), + LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), }, { //Exits ENTRANCE(RR_ZR_FRONT, logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash() || logic->HasItem(RG_HOVER_BOOTS)), @@ -74,6 +130,15 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_UPPER_CIRCLE_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_1, logic->CanBreakRocks()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_2, logic->CanBreakRocks()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_3, logic->CanBreakRocks()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_4, logic->CanBreakRocks()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_5, logic->CanBreakRocks()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_6, logic->CanBreakRocks()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_7, logic->CanBreakRocks()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_8, logic->CanBreakRocks()), LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, true), }, { //Exits @@ -120,6 +185,7 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_OPEN_GROTTO_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_ZR_OPEN_GROTTO_GRASS_3, logic->CanCutShrubs()), LOCATION(RC_ZR_OPEN_GROTTO_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_ZR_OPEN_GROTTO_BUTTERFLY_FAIRY, logic->CanUse(RG_STICKS)), }, { //Exits ENTRANCE(RR_ZR_ATOP_LADDER, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/root.cpp b/soh/soh/Enhancements/randomizer/location_access/root.cpp index 4100ce875c..6807672a63 100644 --- a/soh/soh/Enhancements/randomizer/location_access/root.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/root.cpp @@ -14,6 +14,7 @@ void RegionTable_Init_Root() { EVENT_ACCESS(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST)), EVENT_ACCESS(LOGIC_TH_RESCUED_ALL_CARPENTERS, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE)), EVENT_ACCESS(LOGIC_FREED_EPONA, (bool)ctx->GetOption(RSK_SKIP_EPONA_RACE)), + EVENT_ACCESS(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF)), }, { //Locations LOCATION(RC_LINKS_POCKET, true), diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 97f8015ef8..77444cc420 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -982,11 +982,18 @@ void Rando::StaticData::InitLocationTable() { // Other Hints locationTable[RC_GANONDORF_HINT] = Location::OtherHint(RC_GANONDORF_HINT, RCQUEST_BOTH, ACTOR_EN_GANON_MANT, SCENE_GANON_BOSS, "Ganondorf Hint"); + locationTable[RC_FOREST_BOSS_KEY_HINT] = Location::OtherHint(RC_FOREST_BOSS_KEY_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_FOREST_TEMPLE, "Forest Temple Boss Key Hint"); + locationTable[RC_FIRE_BOSS_KEY_HINT] = Location::OtherHint(RC_FIRE_BOSS_KEY_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_FIRE_TEMPLE, "Fire Temple Boss Key Hint"); + locationTable[RC_WATER_BOSS_KEY_HINT] = Location::OtherHint(RC_WATER_BOSS_KEY_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_WATER_TEMPLE, "Water Temple Boss Key Hint"); + locationTable[RC_SPIRIT_BOSS_KEY_HINT] = Location::OtherHint(RC_SPIRIT_BOSS_KEY_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_SPIRIT_TEMPLE, "Spirit Temple Boss Key Hint"); + locationTable[RC_SHADOW_BOSS_KEY_HINT] = Location::OtherHint(RC_SHADOW_BOSS_KEY_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_SHADOW_TEMPLE, "Shadow Temple Boss Key Hint"); + locationTable[RC_GANONS_BOSS_KEY_HINT] = Location::OtherHint(RC_GANONS_BOSS_KEY_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_GANONS_TOWER, "Ganon's Castle Boss Key Hint"); locationTable[RC_SHEIK_HINT_GC] = Location::OtherHint(RC_SHEIK_HINT_GC, RCQUEST_VANILLA, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); locationTable[RC_SHEIK_HINT_MQ_GC] = Location::OtherHint(RC_SHEIK_HINT_MQ_GC, RCQUEST_MQ, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); locationTable[RC_DAMPE_HINT] = Location::OtherHint(RC_DAMPE_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_GRAVEKEEPERS_HUT, "Diary Hint"); locationTable[RC_GREG_HINT] = Location::OtherHint(RC_GREG_HINT, RCQUEST_BOTH, RCAREA_MARKET, ACTOR_EN_TAKARA_MAN, SCENE_TREASURE_BOX_SHOP, "Greg Hint"); locationTable[RC_SARIA_SONG_HINT] = Location::OtherHint(RC_SARIA_SONG_HINT, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, "Sarias Song Hint", "Magic Hint Via Saria's Song"); + locationTable[RC_MIDO_HINT] = Location::OtherHint(RC_MIDO_HINT, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, "Mido Hint"); locationTable[RC_ALTAR_HINT_CHILD] = Location::OtherHint(RC_ALTAR_HINT_CHILD, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Child Altar Hint"); locationTable[RC_ALTAR_HINT_ADULT] = Location::OtherHint(RC_ALTAR_HINT_ADULT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Adult Altar Hint"); locationTable[RC_FISHING_POLE_HINT] = Location::OtherHint(RC_FISHING_POLE_HINT, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, "Fishing Pole Hint"); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 18366f4798..9aa6323d93 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1269,6 +1269,28 @@ bool Logic::BombchusEnabled() { : HasItem(RG_BOMB_BAG); } +// With the shop shield/tunic gate enabled, a shop slot selling a shield/tunic is considered not-for-sale +// in logic until the matching item has been found in the world (which sets its RandomizerInf). Shop slots +// are randomized, so this keys off the item actually placed in the slot rather than a fixed location. +bool Logic::ShopItemNotForSale(RandomizerCheck loc) { + if (ctx->GetOption(RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL).IsNot(RO_GENERIC_ON) || + StaticData::GetLocation(loc)->GetRCType() != RCTYPE_SHOP) { + return false; + } + switch (ctx->GetItemLocation(loc)->GetPlacedRandomizerGet()) { + case RG_BUY_DEKU_SHIELD: + return !CheckRandoInf(RAND_INF_HAS_FOUND_DEKU_SHIELD); + case RG_BUY_HYLIAN_SHIELD: + return !CheckRandoInf(RAND_INF_HAS_FOUND_HYLIAN_SHIELD); + case RG_BUY_GORON_TUNIC: + return !CheckRandoInf(RAND_INF_HAS_FOUND_GORON_TUNIC); + case RG_BUY_ZORA_TUNIC: + return !CheckRandoInf(RAND_INF_HAS_FOUND_ZORA_TUNIC); + default: + return false; + } +} + // TODO: Implement Ammo Drop Setting in place of bombchu drops bool Logic::BombchuRefill() { return Get(LOGIC_BUY_BOMBCHUS) || Get(LOGIC_COULD_PLAY_BOWLING) || Get(LOGIC_CARPET_MERCHANT) || @@ -1330,10 +1352,18 @@ bool Logic::CanBreakSmallCrates() { return CanJumpslash() || HasExplosives() || HasItem(RG_POWER_BRACELET); } +bool Logic::CanBreakRocks() { + return BlastOrSmash() || HasItem(RG_POWER_BRACELET); +} + bool Logic::CanBonkTrees() { return true; } +bool Logic::CanRead() { + return true; +} + bool Logic::HasExplosives() { return CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); } @@ -2073,6 +2103,23 @@ void Logic::ApplyItemEffect(Item& item, bool state) { } break; case ITEMTYPE_EQUIP: { RandomizerGet itemRG = item.GetRandomizerGet(); + // Finding a non-shop shield/tunic unlocks its matching shop copy when that gate is enabled. + switch (itemRG) { + case RG_DEKU_SHIELD: + SetRandoInf(RAND_INF_HAS_FOUND_DEKU_SHIELD, state); + break; + case RG_HYLIAN_SHIELD: + SetRandoInf(RAND_INF_HAS_FOUND_HYLIAN_SHIELD, state); + break; + case RG_GORON_TUNIC: + SetRandoInf(RAND_INF_HAS_FOUND_GORON_TUNIC, state); + break; + case RG_ZORA_TUNIC: + SetRandoInf(RAND_INF_HAS_FOUND_ZORA_TUNIC, state); + break; + default: + break; + } if (itemRG == RG_DEKU_SHIELD || itemRG == RG_HYLIAN_SHIELD) { return; } @@ -2412,7 +2459,7 @@ const std::vector& GetDungeonSmallKeyDoors(SceneID sceneId) { // Load the scene std::shared_ptr scene = std::dynamic_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(scenePath)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(scenePath)); if (scene == nullptr) { return emptyVector; } @@ -2594,6 +2641,11 @@ bool Logic::DMCPadToPots() { return ((CanUse(RG_HOVER_BOOTS) && (IsAdult || (HasItem(RG_CLIMB) /*&& CanUse(RG_ROLL)*/))) || CanUse(RG_HOOKSHOT)); } +// via scarecrow +bool Logic::DMCUpperToPad() { + return IsAdult && TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && ReachDistantScarecrow(); +} + bool Logic::SpiritExplosiveKeyLogic() { return SmallKeys(SCENE_SPIRIT_TEMPLE, HasExplosives() ? 1 : 2); } diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index fd86befc42..9f5883e6a9 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -2,7 +2,7 @@ #include "randomizerTypes.h" #include "SeedContext.h" -#include +#include namespace Rando { @@ -77,6 +77,7 @@ class Logic { bool CanAttack(); bool BombchusEnabled(); bool BombchuRefill(); + bool ShopItemNotForSale(RandomizerCheck loc); bool HookshotOrBoomerang(); bool ScarecrowsSong(); bool BlueFire(); @@ -104,7 +105,9 @@ class Logic { bool CanBreakPots(EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true, bool inWater = false); bool CanBreakCrates(); bool CanBreakSmallCrates(); + bool CanBreakRocks(); bool CanBonkTrees(); + bool CanRead(); bool HasFireSource(); bool HasFireSourceWithTorch(); bool SunlightArrows(); @@ -158,6 +161,7 @@ class Logic { bool DMCUpperToPots(); bool DMCPotsToPad(); bool DMCPadToPots(); + bool DMCUpperToPad(); bool SpiritEastToSwitch(); bool SpiritWestToSkull(); bool SpiritSunBlockSouthLedge(); diff --git a/soh/soh/Enhancements/randomizer/option.cpp b/soh/soh/Enhancements/randomizer/option.cpp index 4f6221c656..5127209816 100644 --- a/soh/soh/Enhancements/randomizer/option.cpp +++ b/soh/soh/Enhancements/randomizer/option.cpp @@ -6,6 +6,7 @@ #include "soh/SohGui/SohGui.hpp" #include "soh/SohGui/SohMenu.h" #include "soh/SohGui/UIWidgets.hpp" +#include "soh/Enhancements/Lang/Lang.h" #include namespace SohGui { @@ -101,14 +102,6 @@ const std::string& Option::GetCVarName() const { return cvarName; } -void Option::SetDelayedOption() { - delayedSelection = contextSelection; -} - -void Option::RestoreDelayedOption() { - contextSelection = delayedSelection; -} - void Option::SetContextIndex(uint8_t idx) { // TODO: Set to Context's OptionValue array. contextSelection = idx; @@ -151,18 +144,10 @@ bool Option::IsCategory(const OptionCategory category) const { return category == this->category; } -bool Option::HasFlag(const int imFlag_) const { - return imFlag_ & imFlags; -} - void Option::AddFlag(const int imFlag_) { imFlags |= imFlag_; } -void Option::SetFlag(const int imFlag_) { - imFlags = imFlag_; -} - void Option::RemoveFlag(const int imFlag_) { imFlags &= ~imFlag_; } @@ -177,15 +162,6 @@ uint8_t Option::GetValueFromText(const std::string text) { return defaultOption; } -void Option::SetContextIndexFromText(const std::string text) { - if (optionsTextToVar.contains(text)) { - SetContextIndex(optionsTextToVar[text]); - } else { - SPDLOG_ERROR("Option {} does not have a var named {}.", name, text); - assert(false); - } -} - Option::Option(size_t key_, std::string name_, std::vector options_, OptionCategory category_, std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_, bool defaultHidden_, WidgetFunc callback_, int imFlags_) @@ -237,77 +213,6 @@ Option::Option(size_t key_, std::string name_, std::vector options_ PopulateTextToNum(); } -bool Option::RenderCheckbox() { - bool changed = false; - bool val = static_cast(CVarGetInteger(cvarName.c_str(), defaultOption)); - UIWidgets::CheckboxOptions widgetOptions = static_cast( - UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip(description.c_str())); - widgetOptions.disabled = disabled; - if (UIWidgets::Checkbox(name.c_str(), &val, widgetOptions)) { - CVarSetInteger(cvarName.c_str(), val); - changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - } - return changed; -} - -bool Option::RenderCombobox() { - bool changed = false; - uint8_t selected = CVarGetInteger(cvarName.c_str(), defaultOption); - if (selected >= static_cast(options.size())) { - selected = static_cast(options.size()); - CVarSetInteger(cvarName.c_str(), selected); - changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - } - UIWidgets::ComboboxOptions widgetOptions = - UIWidgets::ComboboxOptions().Color(THEME_COLOR).Tooltip(description.c_str()); - if (this->GetKey() == RSK_LOGIC_RULES) { - widgetOptions = widgetOptions.LabelPosition(UIWidgets::LabelPositions::None) - .ComponentAlignment(UIWidgets::ComponentAlignments::Right); - } - widgetOptions.disabled = disabled; - if (UIWidgets::Combobox(name.c_str(), &selected, options, widgetOptions)) { - CVarSetInteger(cvarName.c_str(), static_cast(selected)); - changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - } - return changed; -} - -bool Option::RenderSlider() { - bool changed = false; - int val = CVarGetInteger(cvarName.c_str(), defaultOption); - if (val > options.size() - 1) { - val = static_cast(options.size()) - 1; - changed = true; - } - UIWidgets::IntSliderOptions widgetOptions = UIWidgets::IntSliderOptions() - .Color(THEME_COLOR) - .Min(0) - .Max(static_cast(options.size() - 1)) - .Tooltip(description.c_str()) - .Format(options[val].c_str()) - .DefaultValue(defaultOption); - widgetOptions.disabled = disabled; - if (UIWidgets::SliderInt(name.c_str(), &val, widgetOptions)) { - changed = true; - } - if (val < 0) { - val = 0; - changed = true; - } - if (val > options.size() - 1) { - val = static_cast(options.size() - 1); - changed = true; - } - if (changed) { - CVarSetInteger(cvarName.c_str(), val); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - } - return changed; -} - void Option::AddWidget(WidgetPath& path) { auto widget = SohGui::mSohMenu->AddWidget(path, name, widgetType) .Callback(callback) @@ -320,7 +225,13 @@ void Option::AddWidget(WidgetPath& path) { UIWidgets::IntSliderOptions* sliderOpts = (UIWidgets::IntSliderOptions*)info.options.get(); sliderOpts->Format(this->GetOptionText(this->GetOptionIndex()).c_str()); - sliderOpts->Max(this->options.size() - 1); + size_t maxIndex = this->options.size() - 1; + if (this->GetKey() == RSK_SHOPSANITY_COUNT && maxIndex > 7 && + CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != + RO_LOGIC_NO_LOGIC) { + maxIndex = 7; + } + sliderOpts->Max(maxIndex); } }) .CVar(cvarName.c_str()) @@ -357,18 +268,42 @@ RandomizerCheck LocationOption::GetKey() const { return static_cast(key); } +#define RANDO_ENUM_ITEM(enum) { enum, #enum }, + +std::unordered_map trickNames = { +#include "randomizerEnums/RandomizerTrick.h" +}; + +#undef RANDO_ENUM_ITEM + +const static std::string trickPrefix = "randomizer.tricks."; + +static std::string MakeTrickName(RandomizerTrick key) { + const static std::string namePostfix = ".name"; + + std::string trickNamePart = trickNames[key].substr(3); + std::transform(trickNamePart.begin(), trickNamePart.end(), trickNamePart.begin(), ::tolower); + return Lang::Translate((trickPrefix + trickNamePart + namePostfix).c_str()); +} + +static std::string MakeTrickDescription(RandomizerTrick key) { + const static std::string descriptionPostfix = ".description"; + + std::string trickNamePart = trickNames[key].substr(3); + std::transform(trickNamePart.begin(), trickNamePart.end(), trickNamePart.begin(), ::tolower); + return Lang::Translate((trickPrefix + trickNamePart + descriptionPostfix).c_str()); +} + TrickSetting::TrickSetting(RandomizerTrick key_, const RandomizerCheckQuest quest_, const RandomizerArea area_, - std::set tags_, const std::string& name_, const std::string nameTag_, - std::string description_) - : Option(key_, name_, { "Disabled", "Enabled" }, OptionCategory::Setting, "", std::move(description_), - WIDGET_CVAR_CHECKBOX, 0, false, nullptr, IMFLAG_NONE), + std::set tags_, const std::string nameTag_) + : Option(key_, std::move(MakeTrickName(key_)), { "Disabled", "Enabled" }, OptionCategory::Setting, "", + std::move(MakeTrickDescription(key_)), WIDGET_CVAR_CHECKBOX, 0, false, nullptr, IMFLAG_NONE), mQuest(quest_), mArea(area_), mNameTag(nameTag_), mTags(std::move(tags_)) { } TrickSetting TrickSetting::LogicTrick(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, - std::set tags_, const std::string& name_, const std::string nameTag_, - std::string description_) { - return { key_, quest_, area_, std::move(tags_), name_, nameTag_, std::move(description_) }; + std::set tags_, const std::string nameTag_) { + return { key_, quest_, area_, std::move(tags_), nameTag_ }; } RandomizerTrick TrickSetting::GetKey() const { diff --git a/soh/soh/Enhancements/randomizer/option.h b/soh/soh/Enhancements/randomizer/option.h index 7aad721725..a915821d47 100644 --- a/soh/soh/Enhancements/randomizer/option.h +++ b/soh/soh/Enhancements/randomizer/option.h @@ -3,7 +3,7 @@ #ifndef RANDOPTION_H #define RANDOPTION_H -#include +#include #include #include #include @@ -225,16 +225,6 @@ class Option { */ uint8_t GetOptionIndex() const; - /** - * @brief Set the delayedOption to the currently selected index so it can be restored later. - */ - void SetDelayedOption(); - - /** - * @brief Restores the delayedOption back to the selected index. - */ - void RestoreDelayedOption(); - /** * @brief Set the rando context index for this Option. * @@ -296,13 +286,10 @@ class Option { void AddWidget(WidgetPath& path); - bool HasFlag(int imFlag_) const; void AddFlag(int imFlag_); - void SetFlag(int imFlag_); void RemoveFlag(int imFlag_); uint8_t GetValueFromText(std::string text); - void SetContextIndexFromText(std::string text); void SetCallback(WidgetFunc callback); void RunCallback(); @@ -314,14 +301,10 @@ class Option { size_t key; private: - bool RenderCheckbox(); - bool RenderCombobox(); - bool RenderSlider(); void PopulateTextToNum(); std::string name; std::vector options; uint8_t contextSelection = 0; - uint8_t delayedSelection = 0; bool hidden = false; OptionCategory category = OptionCategory::Setting; std::string cvarName; @@ -356,14 +339,11 @@ class TrickSetting : public Option { * @param quest_ MQ, Vanilla, or Both. * @param area_ The area the trick is relevant for. * @param tags_ The set of RandomizerTrickTags for this trick. - * @param name_ The name of the trick. Appears in the menus and spoiler - * @param nameTag_ The 3-8 long name tag of the trick. Appears in the settings and presets file. - * @param description_ A brief description of the trick. + * @param nameTag_ The 3-8 character long name tag of the trick. Appears in the settings and presets file. * @return Option */ static TrickSetting LogicTrick(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, - std::set tags_, const std::string& name_, const std::string nameTag_, - std::string description_); + std::set tags_, const std::string nameTag_); RandomizerTrick GetKey() const; @@ -400,7 +380,7 @@ class TrickSetting : public Option { private: TrickSetting(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, - const std::string& name_, const std::string nameTag_, std::string description_); + const std::string nameTag_); RandomizerCheckQuest mQuest; RandomizerArea mArea; std::string mNameTag; diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 049ea8d3ee..8efc31f49e 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -135,6 +135,12 @@ void Settings::CreateOptionDescriptions() { "The amount of Triforce pieces that will be placed in the world. " "Keep in mind seed generation can fail if more pieces are placed than there are junk items in the item pool."; mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED] = "The amount of Triforce pieces required to win the game."; + mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_LOCATION] = + "Any dungeon - Triforce pieces can only appear inside of any dungeon.\n" + "\n" + "Overworld - Triforce pieces can only appear outside of dungeons.\n" + "\n" + "Anywhere - Triforce pieces can appear anywhere in the world."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_ENTRANCES] = "Shuffle the pool of dungeon entrances, including Bottom of the Well, Ice Cavern and Gerudo Training Ground.\n" "\n" @@ -312,6 +318,34 @@ void Settings::CreateOptionDescriptions() { "only shuffle with No Logic."; mOptionDescriptions[RSK_SHUFFLE_BUSHES] = "Bushes in Hyrule Field & Zora's Fountain will contain randomized items when first walked through."; + mOptionDescriptions[RSK_SHUFFLE_ICICLES] = + "Stalagmites and stalactites in Ice Cavern and Ganon's Castle will contain randomized items when broken.\n" + "Icicles will have a halo around them when carrying randomized items."; + mOptionDescriptions[RSK_SHUFFLE_RED_ICE] = + "Red Ice will give randomized items when melted.\n" + "Red Ice will have a particle effect inside it when it holds a randomized item"; + mOptionDescriptions[RSK_SHUFFLE_SIGNS] = "Signs and readable pedestals, plinths, altars, and graves will grant a " + "randomized item the first time they are read. " + "Signs will have a particle effect when they hold a randomized item.\n" + "\n" + "Off - Signs will not be shuffled.\n" + "\n" + "Dungeons - Only shuffle signs that are within dungeons.\n" + "\n" + "Overworld - Only shuffle signs that are outside of dungeons.\n" + "\n" + "All Signs - Shuffle all signs."; + mOptionDescriptions[RSK_SHUFFLE_WONDER_ITEMS] = + "Wonder items will drop a randomized item the first time they're collected. " + "Wonder items will be marked with swirling particles.\n" + "\n" + "Off - Wonder items will not be shuffled.\n" + "\n" + "Dungeons - Only shuffle wonder items that are within dungeons.\n" + "\n" + "Overworld - Only shuffle wonder items that are outside of dungeons.\n" + "\n" + "All Wonder Items - Shuffle all wonder items."; mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n" "\n" "The fishing pole is required to play the fishing pond minigame."; @@ -341,11 +375,9 @@ void Settings::CreateOptionDescriptions() { "\n" "1-7 Items - Vanilla shop items will be shuffled among different shops, and " "each shop will contain 1-7 non-vanilla shop items.\n" - /* "\n" - "8 Items - All shops will contain 8 non-vanilla shop items.\n" - */ - ; + "8 Items - All shops will contain 8 non-vanilla shop items. " + "Only available with No Logic, since logic otherwise requires at least one buyable refill per shop.\n"; mOptionDescriptions[RSK_SHOPSANITY_PRICES] = "Vanilla - The same price as the item it replaced.\n" "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers.\n" @@ -372,6 +404,10 @@ void Settings::CreateOptionDescriptions() { "After choosing a price, set it to the affordable amount based on the wallet required.\n\n" "Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n" "Use this to enable wallet tier locking, but make shop items not as expensive as they could be."; + mOptionDescriptions[RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL] = + "Non-randomized shields and tunics sold in shops cannot be purchased until you have first found a shield " + "elsewhere. " + "Regions containing a shield or tunic will not be hinted foolish."; mOptionDescriptions[RSK_FISHSANITY] = "Off - Fish will not be shuffled. No changes will be made to fishing behavior.\n\n" "Shuffle only Hyrule Loach - Allows you to earn an item by catching the Hyrule Loach at the fishing pond and " @@ -473,6 +509,9 @@ void Settings::CreateOptionDescriptions() { "\n" "This setting does not effect the item earned from playing\n" "the Song of Storms and the frog song minigame."; + mOptionDescriptions[RSK_SHUFFLE_BEGGAR] = + "Shuffle the rewards the Beggar gives for selling bugs, fish, and Blue Fire.\n" + "The Beggar will give separate rewards to child and adult."; mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE] = "Adds all of the adult trade quest items into the pool, each of which " "can be traded for a unique reward.\n" @@ -507,6 +546,7 @@ void Settings::CreateOptionDescriptions() { "Shuffle fairy spots. These are spots where a big fairy is revealed by a song." "\n" "This excludes gossip stones and magic bean locations."; + mOptionDescriptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES] = "Shuffle fairies from butterfly locations."; mOptionDescriptions[RSK_SHUFFLE_GRASS] = "Grass will drop a randomized item the first time they're cut and collected. " "Grass will have a different appearance when they hold a randomized item.\n" @@ -518,6 +558,8 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only shuffle grass that are outside of dungeons.\n" "\n" "All Grass - Shuffle all grass."; + mOptionDescriptions[RSK_SHUFFLE_ROCKS] = "Shuffle rock locations."; + mOptionDescriptions[RSK_SHUFFLE_BOULDERS] = "Shuffle boulder locations."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] = "Shuffles the location of Spiritual Stones and medallions.\n" "Vanilla - Spiritual Stones and medallions will be given from their respective boss.\n" @@ -772,6 +814,16 @@ void Settings::CreateOptionDescriptions() { "of 20. The second one will upgrade this capacity to 30, and the final one will upgrade the capacity to the " "usual 50.\n\n" "Bombchu Bowling is opened by obtaining the first Bombchu bag."; + mOptionDescriptions[RSK_LINKS_POCKET] = + "Dungeon Reward - Link will start with a Spiritual Stone or Medallion, and specific options will open up\n\n" + "Advancement - Link will start with a useful item.\n\n" + "Anything - Link will start with a random item.\n\n" + "Nothing - Link will not start with a bonus item."; + mOptionDescriptions[RSK_LINKS_POCKET_REWARD] = + "Any Reward - Link starts with a random Spiritual Stone or Medallion\n\n" + "Stone - Link starts with a random Spiritual Stone.\n\n" + "Any Medallion - Link starts with a random Medallion.\n\n" + "Light Medallion - Link starts with the Light Medallion."; mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS] = "Once you obtain a Bombchu Bag, refills will sometimes replace " "Bomb drops that would spawn." "\n" diff --git a/soh/soh/Enhancements/randomizer/particle_cmc.cpp b/soh/soh/Enhancements/randomizer/particle_cmc.cpp new file mode 100644 index 0000000000..3aec408bc7 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/particle_cmc.cpp @@ -0,0 +1,47 @@ +#include "particle_cmc.h" + +// Color of the circle for the particles +static Color_RGBA8 mainColors[7] = { + { 255, 255, 255, 255 }, // Junk + { 170, 50, 0, 255 }, // Lesser + { 250, 0, 0, 255 }, // Health + { 255, 255, 0, 255 }, // Boss Key + { 180, 180, 180, 255 }, // Small Key + { 0, 0, 0, 255 }, // Skulltula Token + { 250, 185, 40, 255 }, // Major +}; + +// Secondary color of the circle for the particles +static Color_RGBA8 secColors[7] = { + { 255, 255, 255, 255 }, // Junk + { 250, 75, 0, 255 }, // Lesser + { 0, 0, 255, 255 }, // Health + { 0, 200, 255, 255 }, // Boss Key + { 130, 130, 130, 255 }, // Small Key + { 255, 250, 190, 255 }, // Skulltula Token + { 255, 220, 135, 255 }, // Major +}; + +// Color of the faded flares stretching off the particles +static Color_RGBA8 flareColors[7] = { + { 135, 135, 135, 255 }, // Junk + { 255, 160, 100, 255 }, // Lesser + { 255, 125, 125, 255 }, // Health + { 0, 200, 255, 255 }, // Boss Key + { 100, 100, 100, 255 }, // Small Key + { 255, 255, 255, 255 }, // Skulltula Token + { 250, 220, 180, 255 }, // Major +}; + +Color_RGBA8 Randomizer_GetParticleCMCColor(GetItemCategory colorIndex, ParticleCMCColorType colorType) { + switch (colorType) { + case COLOR_PRIMARY: + return mainColors[colorIndex]; + case COLOR_SECONDARY: + return secColors[colorIndex]; + case COLOR_FLARE: + return flareColors[colorIndex]; + default: + return mainColors[colorIndex]; + } +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/particle_cmc.h b/soh/soh/Enhancements/randomizer/particle_cmc.h new file mode 100644 index 0000000000..046c25fa4e --- /dev/null +++ b/soh/soh/Enhancements/randomizer/particle_cmc.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/item-tables/ItemTableTypes.h" + +#ifndef PARTICLE_CMC_H +#define PARTICLE_CMC_H + +typedef enum { + COLOR_PRIMARY, + COLOR_SECONDARY, + COLOR_FLARE, +} ParticleCMCColorType; + +#ifdef __cplusplus +extern "C" { +#endif + +Color_RGBA8 Randomizer_GetParticleCMCColor(GetItemCategory colorIndex, ParticleCMCColorType colorType); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 39a8308f3d..ea1af77527 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -8,7 +8,7 @@ #include #include #include -#include "3drando/rando_main.hpp" +#include "3drando/menu.hpp" #include "soh/ResourceManagerHelpers.h" #include "soh/SohGui/SohGui.hpp" #include @@ -28,6 +28,7 @@ #include "randomizerTypes.h" #include "soh/Notification/Notification.h" #include "soh/ObjectExtension/ObjectExtension.h" +#include "soh/Enhancements/randomizer/RCToRandInf.h" extern "C" { #include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h" @@ -47,8 +48,7 @@ std::unordered_map SpoilerfileHintTypeNameToEnum; std::set excludedLocations; std::set spoilerExcludedLocations; -u8 generated; -char* seedString; +bool generated; bool Rando_HandleSpoilerDrop(char* filePath) { if (SohUtils::IsStringEmpty(filePath)) { @@ -90,7 +90,7 @@ Randomizer::Randomizer() { SpoilerfileHintTypeNameToEnum[Rando::StaticData::hintTypeNames[(HintType)c].GetEnglish(MF_CLEAN)] = (HintType)c; } - Ship::Context::GetInstance()->GetFileDropMgr()->RegisterDropHandler(Rando_HandleSpoilerDrop); + Ship::Context::GetRawInstance()->GetFileDropMgr()->RegisterDropHandler(Rando_HandleSpoilerDrop); } Randomizer::~Randomizer() { @@ -214,7 +214,7 @@ bool Randomizer::SpoilerFileExists(const char* spoilerFileName) { "\nwas made by a version that doesn't match the currently running version.\n" + "Loading for this file has been cancelled."); CVarClear(CVAR_GENERAL("SpoilerLog")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } // Update cache @@ -724,2288 +724,7 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe } } -// There has been some talk about potentially just using the RC identifier to store flags rather than randomizer inf, so -// for now we're not going to store randomzierInf in the randomizer check objects, we're just going to map them 1:1 here -std::map rcToRandomizerInf = { - { RC_KF_LINKS_HOUSE_COW, RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW }, - { RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT }, - { RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT }, - { RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE }, - { RC_LW_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR }, - { RC_LW_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT }, - { RC_SFM_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR }, - { RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT }, - { RC_HF_DEKU_SCRUB_GROTTO, RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO }, - { RC_HF_COW_GROTTO_COW, RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW }, - { RC_LH_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT }, - { RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT }, - { RC_LH_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER }, - { RC_GV_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR }, - { RC_GV_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT }, - { RC_GV_COW, RAND_INF_COWS_MILKED_GV_COW }, - { RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR }, - { RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT }, - { RC_KAK_IMPAS_HOUSE_COW, RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW }, - { RC_DMT_COW_GROTTO_COW, RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW }, - { RC_GC_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT }, - { RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT }, - { RC_GC_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER }, - { RC_DMC_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB }, - { RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT }, - { RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT }, - { RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER }, - { RC_ZR_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR }, - { RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT }, - { RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT }, - { RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT }, - { RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER }, - { RC_LLR_STABLES_LEFT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW }, - { RC_LLR_STABLES_RIGHT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW }, - { RC_LLR_TOWER_LEFT_COW, RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW }, - { RC_LLR_TOWER_RIGHT_COW, RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW }, - { RC_DEKU_TREE_MQ_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB }, - { RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT }, - { RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS }, - { RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT }, - { RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY }, - { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR }, - { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT }, - { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE }, - { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS }, - { RC_JABU_JABUS_BELLY_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB }, - { RC_JABU_JABUS_BELLY_MQ_COW, RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW }, - { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT }, - { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT }, - { RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT }, - { RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT }, - { RC_KF_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1 }, - { RC_KF_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_2 }, - { RC_KF_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_3 }, - { RC_KF_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_4 }, - { RC_KF_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_5 }, - { RC_KF_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_6 }, - { RC_KF_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_7 }, - { RC_KF_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_8 }, - { RC_GC_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_1 }, - { RC_GC_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_2 }, - { RC_GC_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_3 }, - { RC_GC_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_4 }, - { RC_GC_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_5 }, - { RC_GC_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_6 }, - { RC_GC_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_7 }, - { RC_GC_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_8 }, - { RC_ZD_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_1 }, - { RC_ZD_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_2 }, - { RC_ZD_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_3 }, - { RC_ZD_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_4 }, - { RC_ZD_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_5 }, - { RC_ZD_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_6 }, - { RC_ZD_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_7 }, - { RC_ZD_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_8 }, - { RC_KAK_BAZAAR_ITEM_1, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_1 }, - { RC_KAK_BAZAAR_ITEM_2, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_2 }, - { RC_KAK_BAZAAR_ITEM_3, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_3 }, - { RC_KAK_BAZAAR_ITEM_4, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_4 }, - { RC_KAK_BAZAAR_ITEM_5, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_5 }, - { RC_KAK_BAZAAR_ITEM_6, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_6 }, - { RC_KAK_BAZAAR_ITEM_7, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_7 }, - { RC_KAK_BAZAAR_ITEM_8, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_8 }, - { RC_KAK_POTION_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_1 }, - { RC_KAK_POTION_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_2 }, - { RC_KAK_POTION_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_3 }, - { RC_KAK_POTION_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_4 }, - { RC_KAK_POTION_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_5 }, - { RC_KAK_POTION_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_6 }, - { RC_KAK_POTION_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_7 }, - { RC_KAK_POTION_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_8 }, - { RC_MARKET_BAZAAR_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_1 }, - { RC_MARKET_BAZAAR_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_2 }, - { RC_MARKET_BAZAAR_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_3 }, - { RC_MARKET_BAZAAR_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_4 }, - { RC_MARKET_BAZAAR_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_5 }, - { RC_MARKET_BAZAAR_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_6 }, - { RC_MARKET_BAZAAR_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_7 }, - { RC_MARKET_BAZAAR_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_8 }, - { RC_MARKET_POTION_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_1 }, - { RC_MARKET_POTION_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_2 }, - { RC_MARKET_POTION_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_3 }, - { RC_MARKET_POTION_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_4 }, - { RC_MARKET_POTION_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_5 }, - { RC_MARKET_POTION_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_6 }, - { RC_MARKET_POTION_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_7 }, - { RC_MARKET_POTION_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_8 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_1 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_2 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_3 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_4 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_5 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8 }, - { RC_TOT_MASTER_SWORD, RAND_INF_TOT_MASTER_SWORD }, - { RC_GC_MEDIGORON, RAND_INF_MERCHANTS_MEDIGORON }, - { RC_KAK_GRANNYS_SHOP, RAND_INF_MERCHANTS_GRANNYS_SHOP }, - { RC_WASTELAND_BOMBCHU_SALESMAN, RAND_INF_MERCHANTS_CARPET_SALESMAN }, - { RC_ZR_MAGIC_BEAN_SALESMAN, RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN }, - { RC_LW_TRADE_COJIRO, RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO }, - { RC_GV_TRADE_SAW, RAND_INF_ADULT_TRADES_GV_TRADE_SAW }, - { RC_DMT_TRADE_BROKEN_SWORD, RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD }, - { RC_LH_TRADE_FROG, RAND_INF_ADULT_TRADES_LH_TRADE_FROG }, - { RC_DMT_TRADE_EYEDROPS, RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS }, - { RC_LH_CHILD_FISHING, RAND_INF_CHILD_FISHING }, - { RC_LH_ADULT_FISHING, RAND_INF_ADULT_FISHING }, - { RC_MARKET_10_BIG_POES, RAND_INF_10_BIG_POES }, - { RC_KAK_100_GOLD_SKULLTULA_REWARD, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD }, - { RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT }, - { RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT }, - { RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO }, - { RC_SFM_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_SFM_STORMS_GROTTO }, - { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT }, - { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT }, - { RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT }, - { RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT }, - { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT }, - { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT }, - { RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO }, - { RC_LLR_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LLR_GROTTO }, - { RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT }, - { RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT }, - { RC_DMT_COW_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMT_COW_GROTTO }, - { RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT }, - { RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT }, - { RC_GC_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GC_GROTTO }, - { RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT }, - { RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT }, - { RC_DMC_HAMMER_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO }, - { RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT }, - { RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT }, - { RC_ZR_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_ZR_STORMS_GROTTO }, - { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT }, - { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT }, - { RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA }, - { RC_LH_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LH_GROTTO }, - { RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO }, - { RC_COLOSSUS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_COLOSSUS_GROTTO }, - { RC_LH_CHILD_FISH_1, RAND_INF_CHILD_FISH_1 }, - { RC_LH_CHILD_FISH_2, RAND_INF_CHILD_FISH_2 }, - { RC_LH_CHILD_FISH_3, RAND_INF_CHILD_FISH_3 }, - { RC_LH_CHILD_FISH_4, RAND_INF_CHILD_FISH_4 }, - { RC_LH_CHILD_FISH_5, RAND_INF_CHILD_FISH_5 }, - { RC_LH_CHILD_FISH_6, RAND_INF_CHILD_FISH_6 }, - { RC_LH_CHILD_FISH_7, RAND_INF_CHILD_FISH_7 }, - { RC_LH_CHILD_FISH_8, RAND_INF_CHILD_FISH_8 }, - { RC_LH_CHILD_FISH_9, RAND_INF_CHILD_FISH_9 }, - { RC_LH_CHILD_FISH_10, RAND_INF_CHILD_FISH_10 }, - { RC_LH_CHILD_FISH_11, RAND_INF_CHILD_FISH_11 }, - { RC_LH_CHILD_FISH_12, RAND_INF_CHILD_FISH_12 }, - { RC_LH_CHILD_FISH_13, RAND_INF_CHILD_FISH_13 }, - { RC_LH_CHILD_FISH_14, RAND_INF_CHILD_FISH_14 }, - { RC_LH_CHILD_FISH_15, RAND_INF_CHILD_FISH_15 }, - { RC_LH_CHILD_LOACH_1, RAND_INF_CHILD_LOACH_1 }, - { RC_LH_CHILD_LOACH_2, RAND_INF_CHILD_LOACH_2 }, - { RC_LH_ADULT_FISH_1, RAND_INF_ADULT_FISH_1 }, - { RC_LH_ADULT_FISH_2, RAND_INF_ADULT_FISH_2 }, - { RC_LH_ADULT_FISH_3, RAND_INF_ADULT_FISH_3 }, - { RC_LH_ADULT_FISH_4, RAND_INF_ADULT_FISH_4 }, - { RC_LH_ADULT_FISH_5, RAND_INF_ADULT_FISH_5 }, - { RC_LH_ADULT_FISH_6, RAND_INF_ADULT_FISH_6 }, - { RC_LH_ADULT_FISH_7, RAND_INF_ADULT_FISH_7 }, - { RC_LH_ADULT_FISH_8, RAND_INF_ADULT_FISH_8 }, - { RC_LH_ADULT_FISH_9, RAND_INF_ADULT_FISH_9 }, - { RC_LH_ADULT_FISH_10, RAND_INF_ADULT_FISH_10 }, - { RC_LH_ADULT_FISH_11, RAND_INF_ADULT_FISH_11 }, - { RC_LH_ADULT_FISH_12, RAND_INF_ADULT_FISH_12 }, - { RC_LH_ADULT_FISH_13, RAND_INF_ADULT_FISH_13 }, - { RC_LH_ADULT_FISH_14, RAND_INF_ADULT_FISH_14 }, - { RC_LH_ADULT_FISH_15, RAND_INF_ADULT_FISH_15 }, - { RC_LH_ADULT_LOACH, RAND_INF_ADULT_LOACH }, - { RC_ZR_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO }, - { RC_DMC_UPPER_GROTTO_FISH, RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO }, - { RC_DMT_STORMS_GROTTO_FISH, RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO }, - { RC_KAK_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO }, - { RC_HF_NEAR_MARKET_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO }, - { RC_HF_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO }, - { RC_HF_SOUTHEAST_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO }, - { RC_KF_STORMS_GROTTO_FISH, RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO }, - { RC_ZD_FISH_1, RAND_INF_ZD_FISH_1 }, - { RC_ZD_FISH_2, RAND_INF_ZD_FISH_2 }, - { RC_ZD_FISH_3, RAND_INF_ZD_FISH_3 }, - { RC_ZD_FISH_4, RAND_INF_ZD_FISH_4 }, - { RC_ZD_FISH_5, RAND_INF_ZD_FISH_5 }, - // Grass - { RC_KF_CHILD_GRASS_1, RAND_INF_KF_CHILD_GRASS_1 }, - { RC_KF_CHILD_GRASS_2, RAND_INF_KF_CHILD_GRASS_2 }, - { RC_KF_CHILD_GRASS_3, RAND_INF_KF_CHILD_GRASS_3 }, - { RC_KF_CHILD_GRASS_4, RAND_INF_KF_CHILD_GRASS_4 }, - { RC_KF_CHILD_GRASS_5, RAND_INF_KF_CHILD_GRASS_5 }, - { RC_KF_CHILD_GRASS_6, RAND_INF_KF_CHILD_GRASS_6 }, - { RC_KF_CHILD_GRASS_7, RAND_INF_KF_CHILD_GRASS_7 }, - { RC_KF_CHILD_GRASS_8, RAND_INF_KF_CHILD_GRASS_8 }, - { RC_KF_CHILD_GRASS_9, RAND_INF_KF_CHILD_GRASS_9 }, - { RC_KF_CHILD_GRASS_10, RAND_INF_KF_CHILD_GRASS_10 }, - { RC_KF_CHILD_GRASS_11, RAND_INF_KF_CHILD_GRASS_11 }, - { RC_KF_CHILD_GRASS_12, RAND_INF_KF_CHILD_GRASS_12 }, - { RC_KF_CHILD_GRASS_MAZE_1, RAND_INF_KF_CHILD_GRASS_MAZE_1 }, - { RC_KF_CHILD_GRASS_MAZE_2, RAND_INF_KF_CHILD_GRASS_MAZE_2 }, - { RC_KF_CHILD_GRASS_MAZE_3, RAND_INF_KF_CHILD_GRASS_MAZE_3 }, - { RC_KF_ADULT_GRASS_1, RAND_INF_KF_ADULT_GRASS_1 }, - { RC_KF_ADULT_GRASS_2, RAND_INF_KF_ADULT_GRASS_2 }, - { RC_KF_ADULT_GRASS_3, RAND_INF_KF_ADULT_GRASS_3 }, - { RC_KF_ADULT_GRASS_4, RAND_INF_KF_ADULT_GRASS_4 }, - { RC_KF_ADULT_GRASS_5, RAND_INF_KF_ADULT_GRASS_5 }, - { RC_KF_ADULT_GRASS_6, RAND_INF_KF_ADULT_GRASS_6 }, - { RC_KF_ADULT_GRASS_7, RAND_INF_KF_ADULT_GRASS_7 }, - { RC_KF_ADULT_GRASS_8, RAND_INF_KF_ADULT_GRASS_8 }, - { RC_KF_ADULT_GRASS_9, RAND_INF_KF_ADULT_GRASS_9 }, - { RC_KF_ADULT_GRASS_10, RAND_INF_KF_ADULT_GRASS_10 }, - { RC_KF_ADULT_GRASS_11, RAND_INF_KF_ADULT_GRASS_11 }, - { RC_KF_ADULT_GRASS_12, RAND_INF_KF_ADULT_GRASS_12 }, - { RC_KF_ADULT_GRASS_13, RAND_INF_KF_ADULT_GRASS_13 }, - { RC_KF_ADULT_GRASS_14, RAND_INF_KF_ADULT_GRASS_14 }, - { RC_KF_ADULT_GRASS_15, RAND_INF_KF_ADULT_GRASS_15 }, - { RC_KF_ADULT_GRASS_16, RAND_INF_KF_ADULT_GRASS_16 }, - { RC_KF_ADULT_GRASS_17, RAND_INF_KF_ADULT_GRASS_17 }, - { RC_KF_ADULT_GRASS_18, RAND_INF_KF_ADULT_GRASS_18 }, - { RC_KF_ADULT_GRASS_19, RAND_INF_KF_ADULT_GRASS_19 }, - { RC_KF_ADULT_GRASS_20, RAND_INF_KF_ADULT_GRASS_20 }, - { RC_LW_GRASS_1, RAND_INF_LW_GRASS_1 }, - { RC_LW_GRASS_2, RAND_INF_LW_GRASS_2 }, - { RC_LW_GRASS_3, RAND_INF_LW_GRASS_3 }, - { RC_LW_GRASS_4, RAND_INF_LW_GRASS_4 }, - { RC_LW_GRASS_5, RAND_INF_LW_GRASS_5 }, - { RC_LW_GRASS_6, RAND_INF_LW_GRASS_6 }, - { RC_LW_GRASS_7, RAND_INF_LW_GRASS_7 }, - { RC_LW_GRASS_8, RAND_INF_LW_GRASS_8 }, - { RC_LW_GRASS_9, RAND_INF_LW_GRASS_9 }, - { RC_MARKET_GRASS_1, RAND_INF_MARKET_GRASS_1 }, - { RC_MARKET_GRASS_2, RAND_INF_MARKET_GRASS_2 }, - { RC_MARKET_GRASS_3, RAND_INF_MARKET_GRASS_3 }, - { RC_MARKET_GRASS_4, RAND_INF_MARKET_GRASS_4 }, - { RC_MARKET_GRASS_5, RAND_INF_MARKET_GRASS_5 }, - { RC_MARKET_GRASS_6, RAND_INF_MARKET_GRASS_6 }, - { RC_MARKET_GRASS_7, RAND_INF_MARKET_GRASS_7 }, - { RC_MARKET_GRASS_8, RAND_INF_MARKET_GRASS_8 }, - { RC_HC_GRASS_1, RAND_INF_HC_GRASS_1 }, - { RC_HC_GRASS_2, RAND_INF_HC_GRASS_2 }, - { RC_KAK_GRASS_1, RAND_INF_KAK_GRASS_1 }, - { RC_KAK_GRASS_2, RAND_INF_KAK_GRASS_2 }, - { RC_KAK_GRASS_3, RAND_INF_KAK_GRASS_3 }, - { RC_KAK_GRASS_4, RAND_INF_KAK_GRASS_4 }, - { RC_KAK_GRASS_5, RAND_INF_KAK_GRASS_5 }, - { RC_KAK_GRASS_6, RAND_INF_KAK_GRASS_6 }, - { RC_KAK_GRASS_7, RAND_INF_KAK_GRASS_7 }, - { RC_KAK_GRASS_8, RAND_INF_KAK_GRASS_8 }, - { RC_GY_GRASS_1, RAND_INF_GY_GRASS_1 }, - { RC_GY_GRASS_2, RAND_INF_GY_GRASS_2 }, - { RC_GY_GRASS_3, RAND_INF_GY_GRASS_3 }, - { RC_GY_GRASS_4, RAND_INF_GY_GRASS_4 }, - { RC_GY_GRASS_5, RAND_INF_GY_GRASS_5 }, - { RC_GY_GRASS_6, RAND_INF_GY_GRASS_6 }, - { RC_GY_GRASS_7, RAND_INF_GY_GRASS_7 }, - { RC_GY_GRASS_8, RAND_INF_GY_GRASS_8 }, - { RC_GY_GRASS_9, RAND_INF_GY_GRASS_9 }, - { RC_GY_GRASS_10, RAND_INF_GY_GRASS_10 }, - { RC_GY_GRASS_11, RAND_INF_GY_GRASS_11 }, - { RC_GY_GRASS_12, RAND_INF_GY_GRASS_12 }, - { RC_LH_GRASS_1, RAND_INF_LH_GRASS_1 }, - { RC_LH_GRASS_2, RAND_INF_LH_GRASS_2 }, - { RC_LH_GRASS_3, RAND_INF_LH_GRASS_3 }, - { RC_LH_GRASS_4, RAND_INF_LH_GRASS_4 }, - { RC_LH_GRASS_5, RAND_INF_LH_GRASS_5 }, - { RC_LH_GRASS_6, RAND_INF_LH_GRASS_6 }, - { RC_LH_GRASS_7, RAND_INF_LH_GRASS_7 }, - { RC_LH_GRASS_8, RAND_INF_LH_GRASS_8 }, - { RC_LH_GRASS_9, RAND_INF_LH_GRASS_9 }, - { RC_LH_GRASS_10, RAND_INF_LH_GRASS_10 }, - { RC_LH_GRASS_11, RAND_INF_LH_GRASS_11 }, - { RC_LH_GRASS_12, RAND_INF_LH_GRASS_12 }, - { RC_LH_GRASS_13, RAND_INF_LH_GRASS_13 }, - { RC_LH_GRASS_14, RAND_INF_LH_GRASS_14 }, - { RC_LH_GRASS_15, RAND_INF_LH_GRASS_15 }, - { RC_LH_GRASS_16, RAND_INF_LH_GRASS_16 }, - { RC_LH_GRASS_17, RAND_INF_LH_GRASS_17 }, - { RC_LH_GRASS_18, RAND_INF_LH_GRASS_18 }, - { RC_LH_GRASS_19, RAND_INF_LH_GRASS_19 }, - { RC_LH_GRASS_20, RAND_INF_LH_GRASS_20 }, - { RC_LH_GRASS_21, RAND_INF_LH_GRASS_21 }, - { RC_LH_GRASS_22, RAND_INF_LH_GRASS_22 }, - { RC_LH_GRASS_23, RAND_INF_LH_GRASS_23 }, - { RC_LH_GRASS_24, RAND_INF_LH_GRASS_24 }, - { RC_LH_GRASS_25, RAND_INF_LH_GRASS_25 }, - { RC_LH_GRASS_26, RAND_INF_LH_GRASS_26 }, - { RC_LH_GRASS_27, RAND_INF_LH_GRASS_27 }, - { RC_LH_GRASS_28, RAND_INF_LH_GRASS_28 }, - { RC_LH_GRASS_29, RAND_INF_LH_GRASS_29 }, - { RC_LH_GRASS_30, RAND_INF_LH_GRASS_30 }, - { RC_LH_GRASS_31, RAND_INF_LH_GRASS_31 }, - { RC_LH_GRASS_32, RAND_INF_LH_GRASS_32 }, - { RC_LH_GRASS_33, RAND_INF_LH_GRASS_33 }, - { RC_LH_GRASS_34, RAND_INF_LH_GRASS_34 }, - { RC_LH_GRASS_35, RAND_INF_LH_GRASS_35 }, - { RC_LH_GRASS_36, RAND_INF_LH_GRASS_36 }, - { RC_LH_CHILD_GRASS_1, RAND_INF_LH_CHILD_GRASS_1 }, - { RC_LH_CHILD_GRASS_2, RAND_INF_LH_CHILD_GRASS_2 }, - { RC_LH_CHILD_GRASS_3, RAND_INF_LH_CHILD_GRASS_3 }, - { RC_LH_CHILD_GRASS_4, RAND_INF_LH_CHILD_GRASS_4 }, - { RC_LH_WARP_PAD_GRASS_1, RAND_INF_LH_WARP_PAD_GRASS_1 }, - { RC_LH_WARP_PAD_GRASS_2, RAND_INF_LH_WARP_PAD_GRASS_2 }, - { RC_HF_NEAR_KF_GRASS_1, RAND_INF_HF_NEAR_KF_GRASS_1 }, - { RC_HF_NEAR_KF_GRASS_2, RAND_INF_HF_NEAR_KF_GRASS_2 }, - { RC_HF_NEAR_KF_GRASS_3, RAND_INF_HF_NEAR_KF_GRASS_3 }, - { RC_HF_NEAR_KF_GRASS_4, RAND_INF_HF_NEAR_KF_GRASS_4 }, - { RC_HF_NEAR_KF_GRASS_5, RAND_INF_HF_NEAR_KF_GRASS_5 }, - { RC_HF_NEAR_KF_GRASS_6, RAND_INF_HF_NEAR_KF_GRASS_6 }, - { RC_HF_NEAR_KF_GRASS_7, RAND_INF_HF_NEAR_KF_GRASS_7 }, - { RC_HF_NEAR_KF_GRASS_8, RAND_INF_HF_NEAR_KF_GRASS_8 }, - { RC_HF_NEAR_KF_GRASS_9, RAND_INF_HF_NEAR_KF_GRASS_9 }, - { RC_HF_NEAR_KF_GRASS_10, RAND_INF_HF_NEAR_KF_GRASS_10 }, - { RC_HF_NEAR_KF_GRASS_11, RAND_INF_HF_NEAR_KF_GRASS_11 }, - { RC_HF_NEAR_KF_GRASS_12, RAND_INF_HF_NEAR_KF_GRASS_12 }, - { RC_HF_NEAR_MARKET_GRASS_1, RAND_INF_HF_NEAR_MARKET_GRASS_1 }, - { RC_HF_NEAR_MARKET_GRASS_2, RAND_INF_HF_NEAR_MARKET_GRASS_2 }, - { RC_HF_NEAR_MARKET_GRASS_3, RAND_INF_HF_NEAR_MARKET_GRASS_3 }, - { RC_HF_NEAR_MARKET_GRASS_4, RAND_INF_HF_NEAR_MARKET_GRASS_4 }, - { RC_HF_NEAR_MARKET_GRASS_5, RAND_INF_HF_NEAR_MARKET_GRASS_5 }, - { RC_HF_NEAR_MARKET_GRASS_6, RAND_INF_HF_NEAR_MARKET_GRASS_6 }, - { RC_HF_NEAR_MARKET_GRASS_7, RAND_INF_HF_NEAR_MARKET_GRASS_7 }, - { RC_HF_NEAR_MARKET_GRASS_8, RAND_INF_HF_NEAR_MARKET_GRASS_8 }, - { RC_HF_NEAR_MARKET_GRASS_9, RAND_INF_HF_NEAR_MARKET_GRASS_9 }, - { RC_HF_NEAR_MARKET_GRASS_10, RAND_INF_HF_NEAR_MARKET_GRASS_10 }, - { RC_HF_NEAR_MARKET_GRASS_11, RAND_INF_HF_NEAR_MARKET_GRASS_11 }, - { RC_HF_NEAR_MARKET_GRASS_12, RAND_INF_HF_NEAR_MARKET_GRASS_12 }, - { RC_HF_SOUTH_GRASS_1, RAND_INF_HF_SOUTH_GRASS_1 }, - { RC_HF_SOUTH_GRASS_2, RAND_INF_HF_SOUTH_GRASS_2 }, - { RC_HF_SOUTH_GRASS_3, RAND_INF_HF_SOUTH_GRASS_3 }, - { RC_HF_SOUTH_GRASS_4, RAND_INF_HF_SOUTH_GRASS_4 }, - { RC_HF_SOUTH_GRASS_5, RAND_INF_HF_SOUTH_GRASS_5 }, - { RC_HF_SOUTH_GRASS_6, RAND_INF_HF_SOUTH_GRASS_6 }, - { RC_HF_SOUTH_GRASS_7, RAND_INF_HF_SOUTH_GRASS_7 }, - { RC_HF_SOUTH_GRASS_8, RAND_INF_HF_SOUTH_GRASS_8 }, - { RC_HF_SOUTH_GRASS_9, RAND_INF_HF_SOUTH_GRASS_9 }, - { RC_HF_SOUTH_GRASS_10, RAND_INF_HF_SOUTH_GRASS_10 }, - { RC_HF_SOUTH_GRASS_11, RAND_INF_HF_SOUTH_GRASS_11 }, - { RC_HF_SOUTH_GRASS_12, RAND_INF_HF_SOUTH_GRASS_12 }, - { RC_HF_CENTRAL_GRASS_1, RAND_INF_HF_CENTRAL_GRASS_1 }, - { RC_HF_CENTRAL_GRASS_2, RAND_INF_HF_CENTRAL_GRASS_2 }, - { RC_HF_CENTRAL_GRASS_3, RAND_INF_HF_CENTRAL_GRASS_3 }, - { RC_HF_CENTRAL_GRASS_4, RAND_INF_HF_CENTRAL_GRASS_4 }, - { RC_HF_CENTRAL_GRASS_5, RAND_INF_HF_CENTRAL_GRASS_5 }, - { RC_HF_CENTRAL_GRASS_6, RAND_INF_HF_CENTRAL_GRASS_6 }, - { RC_HF_CENTRAL_GRASS_7, RAND_INF_HF_CENTRAL_GRASS_7 }, - { RC_HF_CENTRAL_GRASS_8, RAND_INF_HF_CENTRAL_GRASS_8 }, - { RC_HF_CENTRAL_GRASS_9, RAND_INF_HF_CENTRAL_GRASS_9 }, - { RC_HF_CENTRAL_GRASS_10, RAND_INF_HF_CENTRAL_GRASS_10 }, - { RC_HF_CENTRAL_GRASS_11, RAND_INF_HF_CENTRAL_GRASS_11 }, - { RC_HF_CENTRAL_GRASS_12, RAND_INF_HF_CENTRAL_GRASS_12 }, - { RC_ZR_GRASS_1, RAND_INF_ZR_GRASS_1 }, - { RC_ZR_GRASS_2, RAND_INF_ZR_GRASS_2 }, - { RC_ZR_GRASS_3, RAND_INF_ZR_GRASS_3 }, - { RC_ZR_GRASS_4, RAND_INF_ZR_GRASS_4 }, - { RC_ZR_GRASS_5, RAND_INF_ZR_GRASS_5 }, - { RC_ZR_GRASS_6, RAND_INF_ZR_GRASS_6 }, - { RC_ZR_GRASS_7, RAND_INF_ZR_GRASS_7 }, - { RC_ZR_GRASS_8, RAND_INF_ZR_GRASS_8 }, - { RC_ZR_GRASS_9, RAND_INF_ZR_GRASS_9 }, - { RC_ZR_GRASS_10, RAND_INF_ZR_GRASS_10 }, - { RC_ZR_GRASS_11, RAND_INF_ZR_GRASS_11 }, - { RC_ZR_GRASS_12, RAND_INF_ZR_GRASS_12 }, - { RC_ZR_NEAR_FREESTANDING_POH_GRASS, RAND_INF_ZR_NEAR_FREESTANDING_POH_GRASS }, - // Grotto Grass - { RC_KF_STORMS_GROTTO_GRASS_1, RAND_INF_KF_STORMS_GROTTO_GRASS_1 }, - { RC_KF_STORMS_GROTTO_GRASS_2, RAND_INF_KF_STORMS_GROTTO_GRASS_2 }, - { RC_KF_STORMS_GROTTO_GRASS_3, RAND_INF_KF_STORMS_GROTTO_GRASS_3 }, - { RC_KF_STORMS_GROTTO_GRASS_4, RAND_INF_KF_STORMS_GROTTO_GRASS_4 }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_1, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_1 }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2 }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3 }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4 }, - { RC_HF_NEAR_MARKET_GROTTO_GRASS_1, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_1 }, - { RC_HF_NEAR_MARKET_GROTTO_GRASS_2, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_2 }, - { RC_HF_NEAR_MARKET_GROTTO_GRASS_3, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_3 }, - { RC_HF_NEAR_MARKET_GROTTO_GRASS_4, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_4 }, - { RC_HF_OPEN_GROTTO_GRASS_1, RAND_INF_HF_OPEN_GROTTO_GRASS_1 }, - { RC_HF_OPEN_GROTTO_GRASS_2, RAND_INF_HF_OPEN_GROTTO_GRASS_2 }, - { RC_HF_OPEN_GROTTO_GRASS_3, RAND_INF_HF_OPEN_GROTTO_GRASS_3 }, - { RC_HF_OPEN_GROTTO_GRASS_4, RAND_INF_HF_OPEN_GROTTO_GRASS_4 }, - { RC_HF_SOUTHEAST_GROTTO_GRASS_1, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_1 }, - { RC_HF_SOUTHEAST_GROTTO_GRASS_2, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_2 }, - { RC_HF_SOUTHEAST_GROTTO_GRASS_3, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_3 }, - { RC_HF_SOUTHEAST_GROTTO_GRASS_4, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_4 }, - { RC_HF_COW_GROTTO_GRASS_1, RAND_INF_HF_COW_GROTTO_GRASS_1 }, - { RC_HF_COW_GROTTO_GRASS_2, RAND_INF_HF_COW_GROTTO_GRASS_2 }, - { RC_KAK_OPEN_GROTTO_GRASS_1, RAND_INF_KAK_OPEN_GROTTO_GRASS_1 }, - { RC_KAK_OPEN_GROTTO_GRASS_2, RAND_INF_KAK_OPEN_GROTTO_GRASS_2 }, - { RC_KAK_OPEN_GROTTO_GRASS_3, RAND_INF_KAK_OPEN_GROTTO_GRASS_3 }, - { RC_KAK_OPEN_GROTTO_GRASS_4, RAND_INF_KAK_OPEN_GROTTO_GRASS_4 }, - { RC_DMT_STORMS_GROTTO_GRASS_1, RAND_INF_DMT_STORMS_GROTTO_GRASS_1 }, - { RC_DMT_STORMS_GROTTO_GRASS_2, RAND_INF_DMT_STORMS_GROTTO_GRASS_2 }, - { RC_DMT_STORMS_GROTTO_GRASS_3, RAND_INF_DMT_STORMS_GROTTO_GRASS_3 }, - { RC_DMT_STORMS_GROTTO_GRASS_4, RAND_INF_DMT_STORMS_GROTTO_GRASS_4 }, - { RC_DMT_COW_GROTTO_GRASS_1, RAND_INF_DMT_COW_GROTTO_GRASS_1 }, - { RC_DMT_COW_GROTTO_GRASS_2, RAND_INF_DMT_COW_GROTTO_GRASS_2 }, - { RC_DMC_UPPER_GROTTO_GRASS_1, RAND_INF_DMC_UPPER_GROTTO_GRASS_1 }, - { RC_DMC_UPPER_GROTTO_GRASS_2, RAND_INF_DMC_UPPER_GROTTO_GRASS_2 }, - { RC_DMC_UPPER_GROTTO_GRASS_3, RAND_INF_DMC_UPPER_GROTTO_GRASS_3 }, - { RC_DMC_UPPER_GROTTO_GRASS_4, RAND_INF_DMC_UPPER_GROTTO_GRASS_4 }, - { RC_ZR_OPEN_GROTTO_GRASS_1, RAND_INF_ZR_OPEN_GROTTO_GRASS_1 }, - { RC_ZR_OPEN_GROTTO_GRASS_2, RAND_INF_ZR_OPEN_GROTTO_GRASS_2 }, - { RC_ZR_OPEN_GROTTO_GRASS_3, RAND_INF_ZR_OPEN_GROTTO_GRASS_3 }, - { RC_ZR_OPEN_GROTTO_GRASS_4, RAND_INF_ZR_OPEN_GROTTO_GRASS_4 }, - // Dungeon Grass - { RC_DEKU_TREE_LOBBY_GRASS_1, RAND_INF_DEKU_TREE_LOBBY_GRASS_1 }, - { RC_DEKU_TREE_LOBBY_GRASS_2, RAND_INF_DEKU_TREE_LOBBY_GRASS_2 }, - { RC_DEKU_TREE_LOBBY_GRASS_3, RAND_INF_DEKU_TREE_LOBBY_GRASS_3 }, - { RC_DEKU_TREE_2F_GRASS_1, RAND_INF_DEKU_TREE_2F_GRASS_1 }, - { RC_DEKU_TREE_2F_GRASS_2, RAND_INF_DEKU_TREE_2F_GRASS_2 }, - { RC_DEKU_TREE_SLINGSHOT_GRASS_1, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_1 }, - { RC_DEKU_TREE_SLINGSHOT_GRASS_2, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_2 }, - { RC_DEKU_TREE_SLINGSHOT_GRASS_3, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_3 }, - { RC_DEKU_TREE_SLINGSHOT_GRASS_4, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_4 }, - { RC_DEKU_TREE_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_COMPASS_GRASS_1 }, - { RC_DEKU_TREE_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_COMPASS_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_3, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_3 }, - { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4 }, - { RC_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_TORCHES_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_TORCHES_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_LARVAE_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_LARVAE_GRASS_2 }, - { RC_DEKU_TREE_BEFORE_BOSS_GRASS_1, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_1 }, - { RC_DEKU_TREE_BEFORE_BOSS_GRASS_2, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_2 }, - { RC_DEKU_TREE_BEFORE_BOSS_GRASS_3, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_3 }, - { RC_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS, RAND_INF_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS }, - { RC_DODONGOS_CAVERN_BLADE_GRASS, RAND_INF_DODONGOS_CAVERN_BLADE_GRASS }, - { RC_DODONGOS_CAVERN_SINGLE_EYE_GRASS, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_GRASS }, - { RC_DODONGOS_CAVERN_BEFORE_BOSS_GRASS, RAND_INF_DODONGOS_CAVERN_BEFORE_BOSS_GRASS }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_1 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_2 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_3 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_4, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_4 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_5, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_5 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_6, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_6 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3 }, - // MQ Dungeon Grass - { RC_DEKU_TREE_MQ_LOBBY_GRASS_1, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_1 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_2, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_2 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_3, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_3 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_4, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_4 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_5, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_5 }, - { RC_DEKU_TREE_MQ_2F_GRASS_1, RAND_INF_DEKU_TREE_MQ_2F_GRASS_1 }, - { RC_DEKU_TREE_MQ_2F_GRASS_2, RAND_INF_DEKU_TREE_MQ_2F_GRASS_2 }, - { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_1, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_1 }, - { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_2, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_2 }, - { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_3, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_3 }, - { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_4, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_4 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_1 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_2 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_3, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_3 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_4, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_4 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_5, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_5 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_6, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_6 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_7, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_7 }, - { RC_DEKU_TREE_MQ_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_1 }, - { RC_DEKU_TREE_MQ_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_2 }, - { RC_DEKU_TREE_MQ_COMPASS_GRASS_3, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_3 }, - { RC_DEKU_TREE_MQ_COMPASS_GRASS_4, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_4 }, - { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4 }, - { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_4 }, - { RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5 }, - { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_3 }, - { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1 }, - { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2 }, - { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3 }, - { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1 }, - { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2 }, - { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3 }, - { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_4, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_4 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_GRASS, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_GRASS }, - { RC_DODONGOS_CAVERN_MQ_BACK_POE_GRASS, RAND_INF_DODONGOS_CAVERN_MQ_BACK_POE_GRASS }, - { RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1, RAND_INF_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1 }, - { RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2, RAND_INF_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_PIT_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_PIT_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3 }, - { RC_JABU_JABUS_BELLY_MQ_JIGGLIES_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_GRASS }, - { RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS }, - { RC_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS }, - { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1 }, - { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_3 }, - { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_4, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_4 }, - // Shared Dungeon Grass - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_1, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_1 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_2, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_2 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_3, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_3 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_4, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_4 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_5, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_5 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_6, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_7, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8 }, - // End Grass - - { RC_KF_LINKS_HOUSE_POT, RAND_INF_KF_LINKS_HOUSE_POT }, - { RC_KF_TWINS_HOUSE_POT_1, RAND_INF_KF_TWINS_HOUSE_POT_1 }, - { RC_KF_TWINS_HOUSE_POT_2, RAND_INF_KF_TWINS_HOUSE_POT_2 }, - { RC_KF_BROTHERS_HOUSE_POT_1, RAND_INF_KF_BROTHERS_HOUSE_POT_1 }, - { RC_KF_BROTHERS_HOUSE_POT_2, RAND_INF_KF_BROTHERS_HOUSE_POT_2 }, - { RC_TH_BREAK_ROOM_FRONT_POT, RAND_INF_TH_BREAK_ROOM_FRONT_POT }, - { RC_TH_BREAK_ROOM_BACK_POT, RAND_INF_TH_BREAK_ROOM_BACK_POT }, - { RC_TH_KITCHEN_POT_1, RAND_INF_TH_KITCHEN_POT_1 }, - { RC_TH_KITCHEN_POT_2, RAND_INF_TH_KITCHEN_POT_2 }, - { RC_TH_1_TORCH_CELL_RIGHT_POT, RAND_INF_TH_1_TORCH_CELL_RIGHT_POT }, - { RC_TH_1_TORCH_CELL_MID_POT, RAND_INF_TH_1_TORCH_CELL_MID_POT }, - { RC_TH_1_TORCH_CELL_LEFT_POT, RAND_INF_TH_1_TORCH_CELL_LEFT_POT }, - { RC_TH_STEEP_SLOPE_RIGHT_POT, RAND_INF_TH_STEEP_SLOPE_RIGHT_POT }, - { RC_TH_STEEP_SLOPE_LEFT_POT, RAND_INF_TH_STEEP_SLOPE_LEFT_POT }, - { RC_TH_NEAR_DOUBLE_CELL_RIGHT_POT, RAND_INF_TH_NEAR_DOUBLE_CELL_RIGHT_POT }, - { RC_TH_NEAR_DOUBLE_CELL_MID_POT, RAND_INF_TH_NEAR_DOUBLE_CELL_MID_POT }, - { RC_TH_NEAR_DOUBLE_CELL_LEFT_POT, RAND_INF_NEAR_DOUBLE_CELL_LEFT_POT }, - { RC_TH_RIGHTMOST_JAILED_POT, RAND_INF_TH_RIGHTMOST_JAILED_POT }, - { RC_TH_RIGHT_MIDDLE_JAILED_POT, RAND_INF_TH_RIGHT_MIDDLE_JAILED_POT }, - { RC_TH_LEFT_MIDDLE_JAILED_POT, RAND_INF_TH_LEFT_MIDDLE_JAILED_POT }, - { RC_TH_LEFTMOST_JAILED_POT, RAND_INF_TH_LEFTMOST_JAILED_POT }, - { RC_WASTELAND_NEAR_GS_POT_1, RAND_INF_WASTELAND_NEAR_GS_POT_1 }, - { RC_WASTELAND_NEAR_GS_POT_2, RAND_INF_WASTELAND_NEAR_GS_POT_2 }, - { RC_WASTELAND_NEAR_GS_POT_3, RAND_INF_WASTELAND_NEAR_GS_POT_3 }, - { RC_WASTELAND_NEAR_GS_POT_4, RAND_INF_WASTELAND_NEAR_GS_POT_4 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_1, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_2, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_3, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_4, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_5, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_6, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_7, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_8, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_9, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_10, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_11, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_12, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_13, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_14, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_15, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_16, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_17, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_18, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_19, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_20, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_21, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_22, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_23, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_24, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_25, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_26, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_27, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_28, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_29, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_30, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_31, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_32, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_33, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_34, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_35, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_36, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_37, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_38, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_39, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_40, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_41, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_42, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_43, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_44, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_1, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_2, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_3, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_4, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_5, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_6, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_7, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_8, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_9, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_10, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_11, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11 }, - { RC_MK_BACK_ALLEY_HOUSE_POT_1, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1 }, - { RC_MK_BACK_ALLEY_HOUSE_POT_2, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2 }, - { RC_MK_BACK_ALLEY_HOUSE_POT_3, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3 }, - { RC_KAK_NEAR_POTION_SHOP_POT_1, RAND_INF_KAK_NEAR_POTION_SHOP_POT_1 }, - { RC_KAK_NEAR_POTION_SHOP_POT_2, RAND_INF_KAK_NEAR_POTION_SHOP_POT_2 }, - { RC_KAK_NEAR_POTION_SHOP_POT_3, RAND_INF_KAK_NEAR_POTION_SHOP_POT_3 }, - { RC_KAK_NEAR_IMPAS_HOUSE_POT_1, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1 }, - { RC_KAK_NEAR_IMPAS_HOUSE_POT_2, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2 }, - { RC_KAK_NEAR_IMPAS_HOUSE_POT_3, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3 }, - { RC_KAK_NEAR_GUARDS_HOUSE_POT_1, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1 }, - { RC_KAK_NEAR_GUARDS_HOUSE_POT_2, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2 }, - { RC_KAK_NEAR_GUARDS_HOUSE_POT_3, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3 }, - { RC_KAK_NEAR_MEDICINE_SHOP_POT_1, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1 }, - { RC_KAK_NEAR_MEDICINE_SHOP_POT_2, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2 }, - { RC_GY_DAMPES_GRAVE_POT_1, RAND_INF_GY_DAMPES_GRAVE_POT_1 }, - { RC_GY_DAMPES_GRAVE_POT_2, RAND_INF_GY_DAMPES_GRAVE_POT_2 }, - { RC_GY_DAMPES_GRAVE_POT_3, RAND_INF_GY_DAMPES_GRAVE_POT_3 }, - { RC_GY_DAMPES_GRAVE_POT_4, RAND_INF_GY_DAMPES_GRAVE_POT_4 }, - { RC_GY_DAMPES_GRAVE_POT_5, RAND_INF_GY_DAMPES_GRAVE_POT_5 }, - { RC_GY_DAMPES_GRAVE_POT_6, RAND_INF_GY_DAMPES_GRAVE_POT_6 }, - { RC_GC_LOWER_STAIRCASE_POT_1, RAND_INF_GC_LOWER_STAIRCASE_POT_1 }, - { RC_GC_LOWER_STAIRCASE_POT_2, RAND_INF_GC_LOWER_STAIRCASE_POT_2 }, - { RC_GC_UPPER_STAIRCASE_POT_1, RAND_INF_GC_UPPER_STAIRCASE_POT_1 }, - { RC_GC_UPPER_STAIRCASE_POT_2, RAND_INF_GC_UPPER_STAIRCASE_POT_2 }, - { RC_GC_UPPER_STAIRCASE_POT_3, RAND_INF_GC_UPPER_STAIRCASE_POT_3 }, - { RC_GC_MEDIGORON_POT_1, RAND_INF_GC_MEDIGORON_POT_1 }, - { RC_GC_DARUNIA_POT_1, RAND_INF_GC_DARUNIA_POT_1 }, - { RC_GC_DARUNIA_POT_2, RAND_INF_GC_DARUNIA_POT_2 }, - { RC_GC_DARUNIA_POT_3, RAND_INF_GC_DARUNIA_POT_3 }, - { RC_DMC_NEAR_GC_POT_1, RAND_INF_DMC_NEAR_GC_POT_1 }, - { RC_DMC_NEAR_GC_POT_2, RAND_INF_DMC_NEAR_GC_POT_2 }, - { RC_DMC_NEAR_GC_POT_3, RAND_INF_DMC_NEAR_GC_POT_3 }, - { RC_DMC_NEAR_GC_POT_4, RAND_INF_DMC_NEAR_GC_POT_4 }, - { RC_ZD_NEAR_SHOP_POT_1, RAND_INF_ZD_NEAR_SHOP_POT_1 }, - { RC_ZD_NEAR_SHOP_POT_2, RAND_INF_ZD_NEAR_SHOP_POT_2 }, - { RC_ZD_NEAR_SHOP_POT_3, RAND_INF_ZD_NEAR_SHOP_POT_3 }, - { RC_ZD_NEAR_SHOP_POT_4, RAND_INF_ZD_NEAR_SHOP_POT_4 }, - { RC_ZD_NEAR_SHOP_POT_5, RAND_INF_ZD_NEAR_SHOP_POT_5 }, - { RC_ZF_HIDDEN_CAVE_POT_1, RAND_INF_ZF_HIDDEN_CAVE_POT_1 }, - { RC_ZF_HIDDEN_CAVE_POT_2, RAND_INF_ZF_HIDDEN_CAVE_POT_2 }, - { RC_ZF_HIDDEN_CAVE_POT_3, RAND_INF_ZF_HIDDEN_CAVE_POT_3 }, - { RC_ZF_NEAR_JABU_POT_1, RAND_INF_ZF_NEAR_JABU_POT_1 }, - { RC_ZF_NEAR_JABU_POT_2, RAND_INF_ZF_NEAR_JABU_POT_2 }, - { RC_ZF_NEAR_JABU_POT_3, RAND_INF_ZF_NEAR_JABU_POT_3 }, - { RC_ZF_NEAR_JABU_POT_4, RAND_INF_ZF_NEAR_JABU_POT_4 }, - { RC_LLR_FRONT_POT_1, RAND_INF_LLR_FRONT_POT_1 }, - { RC_LLR_FRONT_POT_2, RAND_INF_LLR_FRONT_POT_2 }, - { RC_LLR_FRONT_POT_3, RAND_INF_LLR_FRONT_POT_3 }, - { RC_LLR_FRONT_POT_4, RAND_INF_LLR_FRONT_POT_4 }, - { RC_LLR_RAIN_SHED_POT_1, RAND_INF_LLR_RAIN_SHED_POT_1 }, - { RC_LLR_RAIN_SHED_POT_2, RAND_INF_LLR_RAIN_SHED_POT_2 }, - { RC_LLR_RAIN_SHED_POT_3, RAND_INF_LLR_RAIN_SHED_POT_3 }, - { RC_LLR_TALONS_HOUSE_POT_1, RAND_INF_LLR_TALONS_HOUSE_POT_1 }, - { RC_LLR_TALONS_HOUSE_POT_2, RAND_INF_LLR_TALONS_HOUSE_POT_2 }, - { RC_LLR_TALONS_HOUSE_POT_3, RAND_INF_LLR_TALONS_HOUSE_POT_3 }, - { RC_HF_COW_GROTTO_POT_1, RAND_INF_HF_COW_GROTTO_POT_1 }, - { RC_HF_COW_GROTTO_POT_2, RAND_INF_HF_COW_GROTTO_POT_2 }, - { RC_HC_STORMS_GROTTO_POT_1, RAND_INF_HC_STORMS_GROTTO_POT_1 }, - { RC_HC_STORMS_GROTTO_POT_2, RAND_INF_HC_STORMS_GROTTO_POT_2 }, - { RC_HC_STORMS_GROTTO_POT_3, RAND_INF_HC_STORMS_GROTTO_POT_3 }, - { RC_HC_STORMS_GROTTO_POT_4, RAND_INF_HC_STORMS_GROTTO_POT_4 }, - { RC_DODONGOS_CAVERN_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1 }, - { RC_DODONGOS_CAVERN_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2 }, - { RC_DODONGOS_CAVERN_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3 }, - { RC_DODONGOS_CAVERN_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6 }, - { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3 }, - { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4 }, - { RC_DODONGOS_CAVERN_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1 }, - { RC_DODONGOS_CAVERN_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2 }, - { RC_DODONGOS_CAVERN_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3 }, - { RC_DODONGOS_CAVERN_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4 }, - { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1 }, - { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2 }, - { RC_DODONGOS_CAVERN_BLADE_POT_1, RAND_INF_DODONGOS_CAVERN_BLADE_POT_1 }, - { RC_DODONGOS_CAVERN_BLADE_POT_2, RAND_INF_DODONGOS_CAVERN_BLADE_POT_2 }, - { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1 }, - { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2 }, - { RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3 }, - { RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4 }, - { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1 }, - { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2 }, - { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_1, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_2, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_3, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_4, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_5, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_6, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6 }, - { RC_JABU_JABUS_BELLY_BASEMENT_POT_1, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1 }, - { RC_JABU_JABUS_BELLY_BASEMENT_POT_2, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2 }, - { RC_JABU_JABUS_BELLY_BASEMENT_POT_3, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5 }, - { RC_FOREST_TEMPLE_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_LOBBY_POT_1 }, - { RC_FOREST_TEMPLE_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_LOBBY_POT_2 }, - { RC_FOREST_TEMPLE_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_LOBBY_POT_3 }, - { RC_FOREST_TEMPLE_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_LOBBY_POT_4 }, - { RC_FOREST_TEMPLE_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_LOBBY_POT_5 }, - { RC_FOREST_TEMPLE_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_LOBBY_POT_6 }, - { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1 }, - { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2 }, - { RC_FOREST_TEMPLE_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1 }, - { RC_FOREST_TEMPLE_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2 }, - { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1 }, - { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2 }, - { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3 }, - { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4 }, - { RC_FOREST_TEMPLE_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1 }, - { RC_FOREST_TEMPLE_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2 }, - { RC_FOREST_TEMPLE_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3 }, - { RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1 }, - { RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2 }, - { RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1 }, - { RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2 }, - { RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3 }, - { RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4 }, - { RC_FIRE_TEMPLE_BIG_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1 }, - { RC_FIRE_TEMPLE_BIG_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2 }, - { RC_FIRE_TEMPLE_BIG_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4 }, - { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1 }, - { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2 }, - { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1 }, - { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2 }, - { RC_WATER_TEMPLE_TORCH_POT_1, RAND_INF_WATER_TEMPLE_TORCH_POT_1 }, - { RC_WATER_TEMPLE_TORCH_POT_2, RAND_INF_WATER_TEMPLE_TORCH_POT_2 }, - { RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1 }, - { RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2 }, - { RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3 }, - { RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1 }, - { RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2 }, - { RC_WATER_TEMPLE_BEHIND_GATE_POT_1, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1 }, - { RC_WATER_TEMPLE_BEHIND_GATE_POT_2, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2 }, - { RC_WATER_TEMPLE_BEHIND_GATE_POT_3, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3 }, - { RC_WATER_TEMPLE_BEHIND_GATE_POT_4, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4 }, - { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1 }, - { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2 }, - { RC_WATER_TEMPLE_RIVER_POT_1, RAND_INF_WATER_TEMPLE_RIVER_POT_1 }, - { RC_WATER_TEMPLE_RIVER_POT_2, RAND_INF_WATER_TEMPLE_RIVER_POT_2 }, - { RC_WATER_TEMPLE_LIKE_LIKE_POT_1, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1 }, - { RC_WATER_TEMPLE_LIKE_LIKE_POT_2, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2 }, - { RC_WATER_TEMPLE_BOSS_KEY_POT_1, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1 }, - { RC_WATER_TEMPLE_BOSS_KEY_POT_2, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2 }, - { RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5 }, - { RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1 }, - { RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2 }, - { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1 }, - { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2 }, - { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3 }, - { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4 }, - { RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1 }, - { RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2 }, - { RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1 }, - { RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1 }, - { RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2 }, - { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1 }, - { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2 }, - { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3 }, - { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4 }, - { RC_SPIRIT_TEMPLE_LOBBY_POT_1, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1 }, - { RC_SPIRIT_TEMPLE_LOBBY_POT_2, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2 }, - { RC_SPIRIT_TEMPLE_ANUBIS_POT_1, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1 }, - { RC_SPIRIT_TEMPLE_ANUBIS_POT_2, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2 }, - { RC_SPIRIT_TEMPLE_ANUBIS_POT_3, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3 }, - { RC_SPIRIT_TEMPLE_ANUBIS_POT_4, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4 }, - { RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1 }, - { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1 }, - { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6 }, - { RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1 }, - { RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_WATER_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3 }, - { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3 }, - { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4 }, - { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1 }, - { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_1, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_2, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_3, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_4, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_5, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_6, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_7, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_8, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_9, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_10, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_11, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_12, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_13, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_14, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_15, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_16, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_17, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_18, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12 }, - { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3 }, - { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT }, - { RC_ICE_CAVERN_HALL_POT_1, RAND_INF_ICE_CAVERN_HALL_POT_1 }, - { RC_ICE_CAVERN_HALL_POT_2, RAND_INF_ICE_CAVERN_HALL_POT_2 }, - { RC_ICE_CAVERN_SPINNING_BLADE_POT_1, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1 }, - { RC_ICE_CAVERN_SPINNING_BLADE_POT_2, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2 }, - { RC_ICE_CAVERN_SPINNING_BLADE_POT_3, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3 }, - { RC_ICE_CAVERN_NEAR_END_POT_1, RAND_INF_ICE_CAVERN_NEAR_END_POT_1 }, - { RC_ICE_CAVERN_NEAR_END_POT_2, RAND_INF_ICE_CAVERN_NEAR_END_POT_2 }, - { RC_ICE_CAVERN_FROZEN_POT_1, RAND_INF_ICE_CAVERN_FROZEN_POT_1 }, - - { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1 }, - { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2 }, - { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1 }, - { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2 }, - { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1 }, - { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2 }, - { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1 }, - { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2 }, - { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6 }, - { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1 }, - { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2 }, - { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1 }, - { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2 }, - { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3 }, - { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4 }, - { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1 }, - { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2 }, - { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3 }, - { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1 }, - { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2 }, - { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1 }, - { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2 }, - { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3 }, - { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2 }, - { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3 }, - { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4 }, - { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3 }, - { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4 }, - { RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT }, - { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3 }, - { RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT }, - { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3 }, - { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1 }, - { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2 }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1 }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2 }, - { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1 }, - { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2 }, - { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3 }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1 }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2 }, - { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1 }, - { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2 }, - { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3 }, - { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1 }, - { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2 }, - { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1 }, - { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2 }, - { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3 }, - { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4 }, - { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5 }, - { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8 }, - { RC_ICE_CAVERN_MQ_ENTRANCE_POT, RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT }, - { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1 }, - { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2 }, - { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1 }, - { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2 }, - { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3 }, - { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4 }, - { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1 }, - { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2 }, - { RC_ICE_CAVERN_MQ_COMPASS_POT_1, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1 }, - { RC_ICE_CAVERN_MQ_COMPASS_POT_2, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5 }, - { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3 }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4 }, - { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3 }, - { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1 }, - { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2 }, - { RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3 }, - { RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4 }, - { RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5 }, - { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1 }, - { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2 }, - { RC_WATER_TEMPLE_MQ_RIVER_POT_1, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1 }, - { RC_WATER_TEMPLE_MQ_RIVER_POT_2, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2 }, - { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1 }, - { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2 }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1 }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2 }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3 }, - { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1 }, - { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2 }, - { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1 }, - { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2 }, - { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3 }, - { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4 }, - { RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT }, - { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1 }, - { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2 }, - { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1 }, - { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2 }, - // Crates - { - RC_GV_FREESTANDING_POH_CRATE, - RAND_INF_GV_FREESTANDING_POH_CRATE, - }, - { - RC_GV_NEAR_COW_CRATE, - RAND_INF_GV_NEAR_COW_CRATE, - }, - { - RC_GV_CRATE_BRIDGE_1, - RAND_INF_GV_CRATE_BRIDGE_1, - }, - { - RC_GV_CRATE_BRIDGE_2, - RAND_INF_GV_CRATE_BRIDGE_2, - }, - { - RC_GV_CRATE_BRIDGE_3, - RAND_INF_GV_CRATE_BRIDGE_3, - }, - { - RC_GV_CRATE_BRIDGE_4, - RAND_INF_GV_CRATE_BRIDGE_4, - }, - { - RC_GF_ABOVE_JAIL_CRATE, - RAND_INF_GF_ABOVE_JAIL_CRATE, - }, - { - RC_GF_SOUTHMOST_CENTER_CRATE, - RAND_INF_GF_SOUTHMOST_CENTER_CRATE, - }, - { - RC_GF_MID_SOUTH_CENTER_CRATE, - RAND_INF_GF_MID_SOUTH_CENTER_CRATE, - }, - { - RC_GF_MID_NORTH_CENTER_CRATE, - RAND_INF_GF_MID_NORTH_CENTER_CRATE, - }, - { - RC_GF_NORTHMOST_CENTER_CRATE, - RAND_INF_GF_NORTHMOST_CENTER_CRATE, - }, - { - RC_GF_OUTSKIRTS_NE_CRATE, - RAND_INF_GF_OUTSKIRTS_NE_CRATE, - }, - { - RC_GF_OUTSKIRTS_NW_CRATE, - RAND_INF_GF_OUTSKIRTS_NW_CRATE, - }, - { - RC_GF_HBA_RANGE_CRATE_1, - RAND_INF_GF_HBA_RANGE_CRATE_1, - }, - { - RC_GF_HBA_RANGE_CRATE_2, - RAND_INF_GF_HBA_RANGE_CRATE_2, - }, - { - RC_GF_HBA_RANGE_CRATE_3, - RAND_INF_GF_HBA_RANGE_CRATE_3, - }, - { - RC_GF_HBA_RANGE_CRATE_4, - RAND_INF_GF_HBA_RANGE_CRATE_4, - }, - { - RC_GF_HBA_RANGE_CRATE_5, - RAND_INF_GF_HBA_RANGE_CRATE_5, - }, - { - RC_GF_HBA_RANGE_CRATE_6, - RAND_INF_GF_HBA_RANGE_CRATE_6, - }, - { - RC_GF_HBA_RANGE_CRATE_7, - RAND_INF_GF_HBA_RANGE_CRATE_7, - }, - { - RC_GF_HBA_CANOPY_EAST_CRATE, - RAND_INF_GF_HBA_CANOPY_EAST_CRATE, - }, - { - RC_GF_HBA_CANOPY_WEST_CRATE, - RAND_INF_GF_HBA_CANOPY_WEST_CRATE, - }, - { - RC_GF_NORTH_TARGET_EAST_CRATE, - RAND_INF_GF_NORTH_TARGET_EAST_CRATE, - }, - { - RC_GF_NORTH_TARGET_WEST_CRATE, - RAND_INF_GF_NORTH_TARGET_WEST_CRATE, - }, - { - RC_GF_NORTH_TARGET_CHILD_CRATE, - RAND_INF_GF_NORTH_TARGET_CHILD_CRATE, - }, - { - RC_GF_SOUTH_TARGET_EAST_CRATE, - RAND_INF_GF_SOUTH_TARGET_EAST_CRATE, - }, - { - RC_GF_SOUTH_TARGET_WEST_CRATE, - RAND_INF_GF_SOUTH_TARGET_WEST_CRATE, - }, - { - RC_TH_NEAR_KITCHEN_LEFTMOST_CRATE, - RAND_INF_TH_NEAR_KITCHEN_LEFTMOST_CRATE, - }, - { - RC_TH_NEAR_KITCHEN_MID_LEFT_CRATE, - RAND_INF_TH_NEAR_KITCHEN_MID_LEFT_CRATE, - }, - { - RC_TH_NEAR_KITCHEN_MID_RIGHT_CRATE, - RAND_INF_TH_NEAR_KITCHEN_MID_RIGHT_CRATE, - }, - { - RC_TH_NEAR_KITCHEN_RIGHTMOST_CRATE, - RAND_INF_TH_NEAR_KITCHEN_RIGHTMOST_CRATE, - }, - { - RC_TH_KITCHEN_CRATE, - RAND_INF_TH_KITCHEN_CRATE, - }, - { - RC_TH_BREAK_HALLWAY_OUTER_CRATE, - RAND_INF_TH_BREAK_HALLWAY_OUTER_CRATE, - }, - { - RC_TH_BREAK_HALLWAY_INNER_CRATE, - RAND_INF_TH_BREAK_HALLWAY_INNER_CRATE, - }, - { - RC_TH_BREAK_ROOM_RIGHT_CRATE, - RAND_INF_TH_BREAK_ROOM_RIGHT_CRATE, - }, - { - RC_TH_BREAK_ROOM_LEFT_CRATE, - RAND_INF_TH_BREAK_ROOM_LEFT_CRATE, - }, - { - RC_TH_1_TORCH_CELL_CRATE, - RAND_INF_TH_1_TORCH_CELL_CRATE, - }, - { - RC_TH_DEAD_END_CELL_CRATE, - RAND_INF_TH_DEAD_END_CELL_CRATE, - }, - { - RC_TH_DOUBLE_CELL_LEFT_CRATE, - RAND_INF_TH_DOUBLE_CELL_LEFT_CRATE, - }, - { - RC_TH_DOUBLE_CELL_RIGHT_CRATE, - RAND_INF_TH_DOUBLE_CELL_RIGHT_CRATE, - }, - { - RC_HW_BEFORE_QUICKSAND_CRATE, - RAND_INF_HW_BEFORE_QUICKSAND_CRATE, - }, - { - RC_HW_AFTER_QUICKSAND_CRATE_1, - RAND_INF_HW_AFTER_QUICKSAND_CRATE_1, - }, - { - RC_HW_AFTER_QUICKSAND_CRATE_2, - RAND_INF_HW_AFTER_QUICKSAND_CRATE_2, - }, - { - RC_HW_AFTER_QUICKSAND_CRATE_3, - RAND_INF_HW_AFTER_QUICKSAND_CRATE_3, - }, - { - RC_HW_NEAR_COLOSSUS_CRATE, - RAND_INF_HW_NEAR_COLOSSUS_CRATE, - }, - { - RC_MK_NEAR_BAZAAR_CRATE_1, - RAND_INF_MK_NEAR_BAZAAR_CRATE_1, - }, - { - RC_MK_NEAR_BAZAAR_CRATE_2, - RAND_INF_MK_NEAR_BAZAAR_CRATE_2, - }, - { - RC_MK_SHOOTING_GALLERY_CRATE_1, - RAND_INF_MK_SHOOTING_GALLERY_CRATE_1, - }, - { - RC_MK_SHOOTING_GALLERY_CRATE_2, - RAND_INF_MK_SHOOTING_GALLERY_CRATE_2, - }, - { - RC_MK_LOST_DOG_HOUSE_CRATE, - RAND_INF_MK_LOST_DOG_HOUSE_CRATE, - }, - { - RC_MK_GUARD_HOUSE_CRATE_1, - RAND_INF_MK_GUARD_HOUSE_CRATE_1, - }, - { - RC_MK_GUARD_HOUSE_CRATE_2, - RAND_INF_MK_GUARD_HOUSE_CRATE_2, - }, - { - RC_MK_GUARD_HOUSE_CRATE_3, - RAND_INF_MK_GUARD_HOUSE_CRATE_3, - }, - { - RC_MK_GUARD_HOUSE_CRATE_4, - RAND_INF_MK_GUARD_HOUSE_CRATE_4, - }, - { - RC_MK_GUARD_HOUSE_CRATE_5, - RAND_INF_MK_GUARD_HOUSE_CRATE_5, - }, - { - RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_1, - RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_1, - }, - { - RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_2, - RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_2, - }, - { - RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_3, - RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_3, - }, - { - RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_4, - RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_4, - }, - { - RC_KAK_NEAR_POTION_SHOP_ADULT_CRATE, - RAND_INF_KAK_NEAR_POTION_SHOP_ADULT_CRATE, - }, - { - RC_KAK_NEAR_SHOOTING_GALLERY_ADULT_CRATE, - RAND_INF_KAK_NEAR_SHOOTING_GALLERY_ADULT_CRATE, - }, - { - RC_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_1, - RAND_INF_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_1, - }, - { - RC_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_2, - RAND_INF_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_2, - }, - { - RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, - RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, - }, - { - RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, - RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, - }, - { - RC_KAK_NEAR_BAZAAR_ADULT_CRATE_1, - RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_1, - }, - { - RC_KAK_NEAR_BAZAAR_ADULT_CRATE_2, - RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_2, - }, - { - RC_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, - RAND_INF_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, - }, - { - RC_KAK_NEAR_GY_CHILD_CRATE, - RAND_INF_KAK_NEAR_GY_CHILD_CRATE, - }, - { - RC_KAK_NEAR_WINDMILL_CHILD_CRATE, - RAND_INF_KAK_NEAR_WINDMILL_CHILD_CRATE, - }, - { - RC_KAK_NEAR_FENCE_CHILD_CRATE, - RAND_INF_KAK_NEAR_FENCE_CHILD_CRATE, - }, - { - RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, - RAND_INF_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, - }, - { - RC_KAK_NEAR_BAZAAR_CHILD_CRATE, - RAND_INF_KAK_NEAR_BAZAAR_CHILD_CRATE, - }, - { - RC_GRAVEYARD_CRATE, - RAND_INF_GRAVEYARD_CRATE, - }, - { - RC_GC_MAZE_CRATE, - RAND_INF_GC_MAZE_CRATE, - }, - { - RC_DMC_CRATE, - RAND_INF_DMC_CRATE, - }, - { - RC_LLR_NEAR_TREE_CRATE, - RAND_INF_LLR_NEAR_TREE_CRATE, - }, - { - RC_LH_LAB_CRATE, - RAND_INF_LH_LAB_CRATE, - }, - - { - RC_DEKU_TREE_MQ_LOBBY_CRATE, - RAND_INF_DEKU_TREE_MQ_LOBBY_CRATE, - }, - { - RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_1, - RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_1, - }, - { - RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_2, - RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_2, - }, - { - RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_1, - RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_1, - }, - { - RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_2, - RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_2, - }, - { - RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_3, - RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_3, - }, - { - RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_4, - RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_4, - }, - { - RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_5, - RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_5, - }, - { - RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, - RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, - }, - { - RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, - RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, - }, - { - RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, - RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, - }, - { - RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, - RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, - }, - { - RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, - RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, - }, - { - RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_1, - RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_1, - }, - { - RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, - RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, - }, - { - RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, - RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, - }, - { - RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, - RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, - }, - { - RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, - RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, - }, - { - RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, - RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, - }, - { - RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, - RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, - }, - { - RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, - RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, - }, - { - RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_3, - RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_3, - }, - { - RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_4, - RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_4, - }, - { - RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_5, - RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_5, - }, - { - RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_6, - RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_6, - }, - { - RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, - RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, - }, - { - RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, - RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, - }, - { - RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, - RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, - }, - { - RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, - RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, - }, - { - RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, - RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, - }, - { - RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, - RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, - }, - { - RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, - RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, - }, - { - RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, - RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, - }, - { - RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, - RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, - }, - { - RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, - RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, - }, - { - RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, - RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, - }, - { - RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, - RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, - }, - { - RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, - RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, - }, - { - RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, - RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, - }, - { - RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, - RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, - }, - { - RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, - RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, - }, - { - RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, - RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, - }, - { - RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, - RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_5, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_6, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_6, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_7, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_7, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_8, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_8, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_9, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_9, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_10, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_10, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_11, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_11, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_12, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_12, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_13, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_13, - }, - { - RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_14, - RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_14, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_5, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_6, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_6, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_7, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_7, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_BK_ROOM_UPPER_CRATE, - RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_UPPER_CRATE, - }, - { - RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_DODONGO_ROOM_UPPER_CRATE, - RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_UPPER_CRATE, - }, - { - RC_WATER_TEMPLE_MQ_DODONGO_ROOM_HALL_CRATE, - RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_HALL_CRATE, - }, - { - RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, - }, - { - RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, - RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, - }, - { - RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, - RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, - }, - { - RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_1, - RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_1, - }, - { - RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_2, - RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_2, - }, - { - RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_3, - RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_3, - }, - { - RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_4, - RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_4, - }, - { - RC_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, - RAND_INF_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, - }, - - { - RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, - RAND_INF_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, - }, - { - RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, - RAND_INF_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, - }, - { - RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, - RAND_INF_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, - }, - { - RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, - RAND_INF_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, - }, - { - RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, - RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, - }, - { - RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, - RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, - }, - - { - RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, - RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, - }, - { - RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, - RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, - }, - { - RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_1, - RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_1, - }, - { - RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_2, - RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_2, - }, - { - RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, - RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, - }, - { - RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, - RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, - }, - { - RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, - RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, - }, - { - RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, - RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, - }, - { - RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, - RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, - }, - { - RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, - RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_1, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_1, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_2, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_2, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_3, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_3, - }, - { - RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_4, - RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_4, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, - }, - { - RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_SMALL_CRATE, - RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_SMALL_CRATE, - }, - { - RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_1, - RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_1, - }, - { - RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, - RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, - }, - { - RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, - RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, - }, - { - RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, - RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, - }, - { - RC_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, - RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, - }, - { - RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, - RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, - }, - { RC_MARKET_TREE, RAND_INF_MARKET_TREE }, - { RC_HC_NEAR_GUARDS_TREE_1, RAND_INF_HC_NEAR_GUARDS_TREE_1 }, - { RC_HC_NEAR_GUARDS_TREE_2, RAND_INF_HC_NEAR_GUARDS_TREE_2 }, - { RC_HC_NEAR_GUARDS_TREE_3, RAND_INF_HC_NEAR_GUARDS_TREE_3 }, - { RC_HC_NEAR_GUARDS_TREE_4, RAND_INF_HC_NEAR_GUARDS_TREE_4 }, - { RC_HC_NEAR_GUARDS_TREE_5, RAND_INF_HC_NEAR_GUARDS_TREE_5 }, - { RC_HC_NEAR_GUARDS_TREE_6, RAND_INF_HC_NEAR_GUARDS_TREE_6 }, - { RC_HC_SKULLTULA_TREE, RAND_INF_HC_SKULLTULA_TREE }, - { RC_HC_GROTTO_TREE, RAND_INF_HC_GROTTO_TREE }, - { RC_HC_NL_TREE_1, RAND_INF_HC_NL_TREE_1 }, - { RC_HC_NL_TREE_2, RAND_INF_HC_NL_TREE_2 }, - { RC_HF_NEAR_KAK_TREE, RAND_INF_HF_NEAR_KAK_TREE }, - { RC_HF_NEAR_KAK_SMALL_TREE, RAND_INF_HF_NEAR_KAK_SMALL_TREE }, - { RC_HF_NEAR_MARKET_TREE_1, RAND_INF_HF_NEAR_MARKET_TREE_1 }, - { RC_HF_NEAR_MARKET_TREE_2, RAND_INF_HF_NEAR_MARKET_TREE_2 }, - { RC_HF_NEAR_MARKET_TREE_3, RAND_INF_HF_NEAR_MARKET_TREE_3 }, - { RC_HF_NEAR_LLR_TREE, RAND_INF_HF_NEAR_LLR_TREE }, - { RC_HF_NEAR_LH_TREE, RAND_INF_HF_NEAR_LH_TREE }, - { RC_HF_CHILD_NEAR_GV_TREE, RAND_INF_HF_CHILD_NEAR_GV_TREE }, - { RC_HF_ADULT_NEAR_GV_TREE, RAND_INF_HF_ADULT_NEAR_GV_TREE }, - { RC_HF_NEAR_ZR_TREE, RAND_INF_HF_NEAR_ZR_TREE }, - { RC_HF_NORTHWEST_TREE_1, RAND_INF_HF_NORTHWEST_TREE_1 }, - { RC_HF_NORTHWEST_TREE_2, RAND_INF_HF_NORTHWEST_TREE_2 }, - { RC_HF_NORTHWEST_TREE_3, RAND_INF_HF_NORTHWEST_TREE_3 }, - { RC_HF_NORTHWEST_TREE_4, RAND_INF_HF_NORTHWEST_TREE_4 }, - { RC_HF_NORTHWEST_TREE_5, RAND_INF_HF_NORTHWEST_TREE_5 }, - { RC_HF_NORTHWEST_TREE_6, RAND_INF_HF_NORTHWEST_TREE_6 }, - { RC_HF_EAST_TREE_1, RAND_INF_HF_EAST_TREE_1 }, - { RC_HF_EAST_TREE_2, RAND_INF_HF_EAST_TREE_2 }, - { RC_HF_EAST_TREE_3, RAND_INF_HF_EAST_TREE_3 }, - { RC_HF_EAST_TREE_4, RAND_INF_HF_EAST_TREE_4 }, - { RC_HF_EAST_TREE_5, RAND_INF_HF_EAST_TREE_5 }, - { RC_HF_EAST_TREE_6, RAND_INF_HF_EAST_TREE_6 }, - { RC_HF_SOUTHEAST_TREE_1, RAND_INF_HF_SOUTHEAST_TREE_1 }, - { RC_HF_SOUTHEAST_TREE_2, RAND_INF_HF_SOUTHEAST_TREE_2 }, - { RC_HF_SOUTHEAST_TREE_3, RAND_INF_HF_SOUTHEAST_TREE_3 }, - { RC_HF_SOUTHEAST_TREE_4, RAND_INF_HF_SOUTHEAST_TREE_4 }, - { RC_HF_SOUTHEAST_TREE_5, RAND_INF_HF_SOUTHEAST_TREE_5 }, - { RC_HF_SOUTHEAST_TREE_6, RAND_INF_HF_SOUTHEAST_TREE_6 }, - { RC_HF_SOUTHEAST_TREE_7, RAND_INF_HF_SOUTHEAST_TREE_7 }, - { RC_HF_SOUTHEAST_TREE_8, RAND_INF_HF_SOUTHEAST_TREE_8 }, - { RC_HF_SOUTHEAST_TREE_9, RAND_INF_HF_SOUTHEAST_TREE_9 }, - { RC_HF_SOUTHEAST_TREE_10, RAND_INF_HF_SOUTHEAST_TREE_10 }, - { RC_HF_SOUTHEAST_TREE_11, RAND_INF_HF_SOUTHEAST_TREE_11 }, - { RC_HF_SOUTHEAST_TREE_12, RAND_INF_HF_SOUTHEAST_TREE_12 }, - { RC_HF_SOUTHEAST_TREE_13, RAND_INF_HF_SOUTHEAST_TREE_13 }, - { RC_HF_SOUTHEAST_TREE_14, RAND_INF_HF_SOUTHEAST_TREE_14 }, - { RC_HF_SOUTHEAST_TREE_15, RAND_INF_HF_SOUTHEAST_TREE_15 }, - { RC_HF_SOUTHEAST_TREE_16, RAND_INF_HF_SOUTHEAST_TREE_16 }, - { RC_HF_SOUTHEAST_TREE_17, RAND_INF_HF_SOUTHEAST_TREE_17 }, - { RC_HF_SOUTHEAST_TREE_18, RAND_INF_HF_SOUTHEAST_TREE_18 }, - { RC_HF_SOUTHEAST_TREE_19, RAND_INF_HF_SOUTHEAST_TREE_19 }, - { RC_HF_CHILD_SOUTHEAST_TREE_1, RAND_INF_HF_CHILD_SOUTHEAST_TREE_1 }, - { RC_HF_CHILD_SOUTHEAST_TREE_2, RAND_INF_HF_CHILD_SOUTHEAST_TREE_2 }, - { RC_HF_CHILD_SOUTHEAST_TREE_3, RAND_INF_HF_CHILD_SOUTHEAST_TREE_3 }, - { RC_HF_CHILD_SOUTHEAST_TREE_4, RAND_INF_HF_CHILD_SOUTHEAST_TREE_4 }, - { RC_HF_CHILD_SOUTHEAST_TREE_5, RAND_INF_HF_CHILD_SOUTHEAST_TREE_5 }, - { RC_HF_CHILD_SOUTHEAST_TREE_6, RAND_INF_HF_CHILD_SOUTHEAST_TREE_6 }, - { RC_HF_TEKTITE_GROTTO_TREE, RAND_INF_HF_TEKTITE_GROTTO_TREE }, - { RC_ZF_TREE, RAND_INF_ZF_TREE }, - { RC_ZR_TREE, RAND_INF_ZR_TREE }, - { RC_KAK_TREE, RAND_INF_KAK_TREE }, - { RC_LLR_TREE, RAND_INF_LLR_TREE }, - { RC_HF_BUSH_NEAR_LAKE_1, RAND_INF_HF_BUSH_NEAR_LAKE_1 }, - { RC_HF_BUSH_NEAR_LAKE_2, RAND_INF_HF_BUSH_NEAR_LAKE_2 }, - { RC_HF_BUSH_NEAR_LAKE_3, RAND_INF_HF_BUSH_NEAR_LAKE_3 }, - { RC_HF_BUSH_NEAR_LAKE_4, RAND_INF_HF_BUSH_NEAR_LAKE_4 }, - { RC_HF_BUSH_NEAR_LAKE_5, RAND_INF_HF_BUSH_NEAR_LAKE_5 }, - { RC_HF_BUSH_NEAR_LAKE_6, RAND_INF_HF_BUSH_NEAR_LAKE_6 }, - { RC_HF_BUSH_NEAR_LAKE_7, RAND_INF_HF_BUSH_NEAR_LAKE_7 }, - { RC_HF_BUSH_NEAR_LAKE_8, RAND_INF_HF_BUSH_NEAR_LAKE_8 }, - { RC_HF_BUSH_NEAR_LAKE_9, RAND_INF_HF_BUSH_NEAR_LAKE_9 }, - { RC_HF_BUSH_NEAR_LAKE_10, RAND_INF_HF_BUSH_NEAR_LAKE_10 }, - { RC_HF_BUSH_NEAR_LAKE_11, RAND_INF_HF_BUSH_NEAR_LAKE_11 }, - { RC_HF_NORTHERN_BUSH_1, RAND_INF_HF_NORTHERN_BUSH_1 }, - { RC_HF_NORTHERN_BUSH_2, RAND_INF_HF_NORTHERN_BUSH_2 }, - { RC_HF_NORTHERN_BUSH_3, RAND_INF_HF_NORTHERN_BUSH_3 }, - { RC_HF_NORTHERN_BUSH_4, RAND_INF_HF_NORTHERN_BUSH_4 }, - { RC_HF_NORTHERN_BUSH_5, RAND_INF_HF_NORTHERN_BUSH_5 }, - { RC_HF_NORTHERN_BUSH_6, RAND_INF_HF_NORTHERN_BUSH_6 }, - { RC_HF_CHILD_NORTHERN_BUSH_1, RAND_INF_HF_CHILD_NORTHERN_BUSH_1 }, - { RC_HF_CHILD_NORTHERN_BUSH_2, RAND_INF_HF_CHILD_NORTHERN_BUSH_2 }, - { RC_HF_CHILD_NORTHERN_BUSH_3, RAND_INF_HF_CHILD_NORTHERN_BUSH_3 }, - { RC_HF_CHILD_NORTHERN_BUSH_4, RAND_INF_HF_CHILD_NORTHERN_BUSH_4 }, - { RC_HF_CHILD_NORTHERN_BUSH_5, RAND_INF_HF_CHILD_NORTHERN_BUSH_5 }, - { RC_HF_CHILD_NORTHERN_BUSH_6, RAND_INF_HF_CHILD_NORTHERN_BUSH_6 }, - { RC_HF_CHILD_NORTHERN_BUSH_7, RAND_INF_HF_CHILD_NORTHERN_BUSH_7 }, - { RC_HF_CHILD_NORTHERN_BUSH_8, RAND_INF_HF_CHILD_NORTHERN_BUSH_8 }, - { RC_HF_CHILD_NORTHERN_BUSH_9, RAND_INF_HF_CHILD_NORTHERN_BUSH_9 }, - { RC_HF_CHILD_NORTHERN_BUSH_10, RAND_INF_HF_CHILD_NORTHERN_BUSH_10 }, - { RC_HF_CHILD_NORTHERN_BUSH_11, RAND_INF_HF_CHILD_NORTHERN_BUSH_11 }, - { RC_HF_BUSH_BY_ROCKY_PATH_1, RAND_INF_HF_BUSH_BY_ROCKY_PATH_1 }, - { RC_HF_BUSH_BY_ROCKY_PATH_2, RAND_INF_HF_BUSH_BY_ROCKY_PATH_2 }, - { RC_HF_BUSH_BY_ROCKY_PATH_3, RAND_INF_HF_BUSH_BY_ROCKY_PATH_3 }, - { RC_HF_BUSH_BY_ROCKY_PATH_4, RAND_INF_HF_BUSH_BY_ROCKY_PATH_4 }, - { RC_HF_BUSH_BY_ROCKY_PATH_5, RAND_INF_HF_BUSH_BY_ROCKY_PATH_5 }, - { RC_HF_BUSH_BY_ROCKY_PATH_6, RAND_INF_HF_BUSH_BY_ROCKY_PATH_6 }, - { RC_HF_SOUTHERN_BUSH_1, RAND_INF_HF_SOUTHERN_BUSH_1 }, - { RC_HF_SOUTHERN_BUSH_2, RAND_INF_HF_SOUTHERN_BUSH_2 }, - { RC_HF_SOUTHERN_BUSH_3, RAND_INF_HF_SOUTHERN_BUSH_3 }, - { RC_HF_SOUTHERN_BUSH_4, RAND_INF_HF_SOUTHERN_BUSH_4 }, - { RC_HF_SOUTHERN_BUSH_5, RAND_INF_HF_SOUTHERN_BUSH_5 }, - { RC_HF_SOUTHERN_BUSH_6, RAND_INF_HF_SOUTHERN_BUSH_6 }, - { RC_HF_SOUTHERN_BUSH_7, RAND_INF_HF_SOUTHERN_BUSH_7 }, - { RC_HF_SOUTHERN_BUSH_8, RAND_INF_HF_SOUTHERN_BUSH_8 }, - { RC_HF_SOUTHERN_BUSH_9, RAND_INF_HF_SOUTHERN_BUSH_9 }, - { RC_HF_SOUTHERN_BUSH_10, RAND_INF_HF_SOUTHERN_BUSH_10 }, - { RC_HF_SOUTHERN_BUSH_11, RAND_INF_HF_SOUTHERN_BUSH_11 }, - { RC_HF_SOUTHERN_BUSH_12, RAND_INF_HF_SOUTHERN_BUSH_12 }, - { RC_HF_CHILD_SOUTHERN_BUSH_1, RAND_INF_HF_CHILD_SOUTHERN_BUSH_1 }, - { RC_HF_CHILD_SOUTHERN_BUSH_2, RAND_INF_HF_CHILD_SOUTHERN_BUSH_2 }, - { RC_HF_CHILD_SOUTHERN_BUSH_3, RAND_INF_HF_CHILD_SOUTHERN_BUSH_3 }, - { RC_HF_CHILD_SOUTHERN_BUSH_4, RAND_INF_HF_CHILD_SOUTHERN_BUSH_4 }, - { RC_HF_CHILD_SOUTHERN_BUSH_5, RAND_INF_HF_CHILD_SOUTHERN_BUSH_5 }, - { RC_HF_CHILD_SOUTHERN_BUSH_6, RAND_INF_HF_CHILD_SOUTHERN_BUSH_6 }, - { RC_HF_CHILD_SOUTHERN_BUSH_7, RAND_INF_HF_CHILD_SOUTHERN_BUSH_7 }, - { RC_HF_CHILD_SOUTHERN_BUSH_8, RAND_INF_HF_CHILD_SOUTHERN_BUSH_8 }, - { RC_HF_CHILD_SOUTHERN_BUSH_9, RAND_INF_HF_CHILD_SOUTHERN_BUSH_9 }, - { RC_HF_CHILD_SOUTHERN_BUSH_10, RAND_INF_HF_CHILD_SOUTHERN_BUSH_10 }, - { RC_HF_CHILD_SOUTHERN_BUSH_11, RAND_INF_HF_CHILD_SOUTHERN_BUSH_11 }, - { RC_HF_CHILD_SOUTHERN_BUSH_12, RAND_INF_HF_CHILD_SOUTHERN_BUSH_12 }, - { RC_ZF_BUSH_1, RAND_INF_ZF_BUSH_1 }, - { RC_ZF_BUSH_2, RAND_INF_ZF_BUSH_2 }, - { RC_ZF_BUSH_3, RAND_INF_ZF_BUSH_3 }, - { RC_ZF_BUSH_4, RAND_INF_ZF_BUSH_4 }, - { RC_ZF_BUSH_5, RAND_INF_ZF_BUSH_5 }, - { RC_ZF_BUSH_6, RAND_INF_ZF_BUSH_6 }, -}; - -CheckIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { - struct CheckIdentity beehiveIdentity; - - beehiveIdentity.randomizerInf = RAND_INF_MAX; - beehiveIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - - if (sceneNum == SCENE_GROTTOS) { - respawnData = TWO_ACTOR_PARAMS(xPosition, respawnData); - } else { - respawnData = TWO_ACTOR_PARAMS(xPosition, 0); - } - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_OBJ_COMB, sceneNum, respawnData); - - if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { - beehiveIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - beehiveIdentity.randomizerCheck = location->GetRandomizerCheck(); - } - - return beehiveIdentity; -} - Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams = 0x00) { - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); RandomizerCheck specialRc = RC_UNKNOWN_CHECK; // TODO: Migrate these special cases into table, or at least document why they are special switch (sceneNum) { @@ -3121,6 +840,16 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, specialRc = RC_DODONGOS_CAVERN_GOSSIP_STONE; } break; + case SCENE_SHOOTING_GALLERY: + // special case for shooting gallery sign + if (actorId == ACTOR_EN_KANBAN) { + if (LINK_IS_ADULT) { + specialRc = RC_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN; + } else { + specialRc = RC_MK_SHOOTING_GALLERY_RECTANGLE_SIGN; + } + } + break; } if (specialRc != RC_UNKNOWN_CHECK) { @@ -3141,45 +870,7 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, return Rando::StaticData::GetLocation(RC_UNKNOWN_CHECK); } -ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respawnData) { - struct ScrubIdentity scrubIdentity; - - scrubIdentity.identity.randomizerInf = RAND_INF_MAX; - scrubIdentity.identity.randomizerCheck = RC_UNKNOWN_CHECK; - scrubIdentity.getItemId = GI_NONE; - scrubIdentity.itemPrice = -1; - - // Scrubs that are 0x06 are loaded as 0x03 when child, switching from selling arrows to seeds - if (actorParams == 0x06) - actorParams = 0x03; - - if (sceneNum == SCENE_GROTTOS) { - actorParams = TWO_ACTOR_PARAMS(actorParams, respawnData); - } - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_DNS, sceneNum, actorParams); - - if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { - if (location->GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO || - location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || - location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE) { - if (GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) { - return scrubIdentity; - } - } else if (GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_ALL) { - return scrubIdentity; - } - - scrubIdentity.identity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - scrubIdentity.identity.randomizerCheck = location->GetRandomizerCheck(); - scrubIdentity.getItemId = (GetItemID)Rando::StaticData::RetrieveItem(location->GetVanillaItem()).GetItemID(); - scrubIdentity.itemPrice = - OTRGlobals::Instance->gRandoContext->GetItemLocation(scrubIdentity.identity.randomizerCheck)->GetPrice(); - } - - return scrubIdentity; -} - +// RANDOTODO: Move all Shopsanity stuff to a ShuffleShops.cpp ShopItemIdentity Randomizer::IdentifyShopItem(s32 sceneNum, u8 slotIndex) { ShopItemIdentity shopItemIdentity; @@ -3218,212 +909,6 @@ ShopItemIdentity Randomizer::IdentifyShopItem(s32 sceneNum, u8 slotIndex) { return shopItemIdentity; } -CheckIdentity Randomizer::IdentifyCow(s32 sceneNum, s32 posX, s32 posZ) { - struct CheckIdentity cowIdentity; - - cowIdentity.randomizerInf = RAND_INF_MAX; - cowIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - - s32 actorParams = 0x00; - // Only need to pass params if in a scene with two cows - if (sceneNum == SCENE_GROTTOS || sceneNum == SCENE_STABLE || sceneNum == SCENE_LON_LON_BUILDINGS) { - actorParams = TWO_ACTOR_PARAMS(posX, posZ); - } - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_COW, sceneNum, actorParams); - - if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { - cowIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - cowIdentity.randomizerCheck = location->GetRandomizerCheck(); - } - - return cowIdentity; -} - -CheckIdentity Randomizer::IdentifyPot(s32 sceneNum, s32 posX, s32 posZ) { - struct CheckIdentity potIdentity; - uint32_t potSceneNum = sceneNum; - - if (sceneNum == SCENE_GANONDORF_BOSS) { - potSceneNum = SCENE_GANONS_TOWER; - } - - potIdentity.randomizerInf = RAND_INF_MAX; - potIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - - s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_OBJ_TSUBO, potSceneNum, actorParams); - - if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { - LUSLOG_WARN("IdentifyPot did not receive a valid RC value (%d).", location->GetRandomizerCheck()); - } else { - potIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - potIdentity.randomizerCheck = location->GetRandomizerCheck(); - } - - return potIdentity; -} - -CheckIdentity Randomizer::IdentifyFish(s32 sceneNum, s32 actorParams) { - struct CheckIdentity fishIdentity; - - fishIdentity.randomizerInf = RAND_INF_MAX; - fishIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - - // Fishsanity will determine what the identity of the fish should be - if (sceneNum == SCENE_FISHING_POND) { - return OTRGlobals::Instance->gRandoContext->GetFishsanity()->IdentifyPondFish(actorParams); - } - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_FISH, sceneNum, actorParams); - - if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { - fishIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - fishIdentity.randomizerCheck = location->GetRandomizerCheck(); - } - - return fishIdentity; -} - -CheckIdentity Randomizer::IdentifyGrass(s32 sceneNum, s32 posX, s32 posZ, s32 respawnData, s32 linkAge) { - struct CheckIdentity grassIdentity; - - grassIdentity.randomizerInf = RAND_INF_MAX; - grassIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - - if (sceneNum == SCENE_GROTTOS) { - respawnData = TWO_ACTOR_PARAMS(posX, respawnData); - } else { - // We'll just pretend it's always daytime for our market bushes. - if (sceneNum == SCENE_MARKET_NIGHT) { - sceneNum = SCENE_MARKET_DAY; - - /* - The two bushes by the tree are not in the same spot - between night and day. We'll assume the coordinates - of the daytime bushes so that we can count them as - the same locations. - */ - if (posX == -74) { - posX = -106; - posZ = 277; - } - if (posX == -87) { - posX = -131; - posZ = 225; - } - } - - /* - Same as with Market. ZR has a bush slightly off pos - between Child and Adult. This is to merge them into - a single location. - */ - if (sceneNum == SCENE_ZORAS_RIVER) { - if (posX == 233) { - posX = 231; - posZ = -1478; - } - } - - // The two bushes behind the sign in KF should be separate - // locations between Child and Adult. - if (sceneNum == SCENE_KOKIRI_FOREST && linkAge == 0) { - if (posX == -498 || posX == -523) { - posZ = 0xFF; - } - } - - respawnData = TWO_ACTOR_PARAMS(posX, posZ); - } - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_KUSA, sceneNum, respawnData); - - if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { - grassIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - grassIdentity.randomizerCheck = location->GetRandomizerCheck(); - } - - return grassIdentity; -} - -CheckIdentity Randomizer::IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ) { - struct CheckIdentity crateIdentity; - uint32_t crateSceneNum = sceneNum; - - // pretend night is day to align crates in market and align GF child/adult crates - if (sceneNum == SCENE_MARKET_NIGHT) { - crateSceneNum = SCENE_MARKET_DAY; - } else if (sceneNum == SCENE_GERUDOS_FORTRESS && gPlayState->linkAgeOnLoad == 1 && posX == 310) { - if (posZ == -1830) { - posZ = -1842; - } else if (posZ == -1770) { - posZ = -1782; - } - } - - crateIdentity.randomizerInf = RAND_INF_MAX; - crateIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - - s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_OBJ_KIBAKO2, crateSceneNum, actorParams); - - if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { - LUSLOG_WARN("IdentifyCrate did not receive a valid RC value (%d).", location->GetRandomizerCheck()); - assert(false); - } else { - crateIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - crateIdentity.randomizerCheck = location->GetRandomizerCheck(); - } - - return crateIdentity; -} - -CheckIdentity Randomizer::IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ) { - struct CheckIdentity smallCrateIdentity; - uint32_t smallCrateSceneNum = sceneNum; - - smallCrateIdentity.randomizerInf = RAND_INF_MAX; - smallCrateIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - - s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_OBJ_KIBAKO, smallCrateSceneNum, actorParams); - - if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { - LUSLOG_WARN("IdentifyCrate did not receive a valid RC value (%d).", location->GetRandomizerCheck()); - assert(false); - } else { - smallCrateIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - smallCrateIdentity.randomizerCheck = location->GetRandomizerCheck(); - } - - return smallCrateIdentity; -} - -CheckIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { - struct CheckIdentity treeIdentity; - - if (sceneNum == SCENE_MARKET_NIGHT) { - sceneNum = SCENE_MARKET_DAY; - } - - s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); - Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_WOOD02, sceneNum, actorParams); - if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK && - (location->GetRCType() != RCTYPE_NLTREE || GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) { - treeIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - treeIdentity.randomizerCheck = location->GetRandomizerCheck(); - return treeIdentity; - } - - treeIdentity.randomizerInf = RAND_INF_MAX; - treeIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - return treeIdentity; -} - u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); } @@ -3458,7 +943,7 @@ std::thread randoThread; void GenerateRandomizerImgui(std::string seed = "") { CVarSetInteger(CVAR_GENERAL("RandoGenerating"), 1); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto ctx = Rando::Context::GetInstance(); // RANDOTODO proper UI for selecting if a spoiler loaded should be used for settings Rando::Settings::GetInstance()->SetAllToContext(); @@ -3493,24 +978,22 @@ void GenerateRandomizerImgui(std::string seed = "") { } } - RandoMain::GenerateRando(excludedLocations, enabledTricks, seed); - + Rando::Context::GetInstance()->SetSeedGenerated(GenerateRandomizer(excludedLocations, enabledTricks, seed)); CVarSetInteger(CVAR_GENERAL("RandoGenerating"), 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - generated = 1; + generated = true; GameInteractor::Instance->ExecuteHooks(); } bool GenerateRandomizer(std::string seed /*= ""*/) { if (generated) { - generated = 0; + generated = false; randoThread.join(); } if (CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) == 0) { randoThread = std::thread(&GenerateRandomizerImgui, seed); - return true; } return false; @@ -3521,7 +1004,7 @@ static bool tricksTabOpen = false; void JoinRandoGenerationThread() { if (generated) { - generated = 0; + generated = false; randoThread.join(); } } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index b64a804e4e..371d36bb51 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -1,12 +1,9 @@ #pragma once #include -#include #include -#include #include #include "z64item.h" -#include #include "SeedContext.h" #include #include "soh/Enhancements/randomizer/randomizer_check_objects.h" @@ -15,7 +12,6 @@ #include #include "soh/Enhancements/item-tables/ItemTableTypes.h" #include "../custom-message/CustomMessageTypes.h" -#include "soh/Enhancements/randomizer/fishsanity.h" #define MAX_SEED_STRING_SIZE 1024 @@ -26,23 +22,13 @@ class Randomizer { public: Randomizer(); ~Randomizer(); - static Sprite* GetSeedTexture(uint8_t index); bool SpoilerFileExists(const char* spoilerFileName); bool IsTrialRequired(s32 trialFlag); u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey); RandomizerCheck GetCheckFromRandomizerInf(RandomizerInf randomizerInf); RandomizerInf GetRandomizerInfFromCheck(RandomizerCheck rc); Rando::Location* GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams); - ScrubIdentity IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respawnData); - CheckIdentity IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData); ShopItemIdentity IdentifyShopItem(s32 sceneNum, u8 slotIndex); - CheckIdentity IdentifyCow(s32 sceneNum, s32 posX, s32 posZ); - CheckIdentity IdentifyPot(s32 sceneNum, s32 posX, s32 posZ); - CheckIdentity IdentifyFish(s32 sceneNum, s32 actorParams); - CheckIdentity IdentifyGrass(s32 sceneNum, s32 posX, s32 posZ, s32 respawnData, s32 linkAge); - CheckIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ); - CheckIdentity IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ); - CheckIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h index c13d37f1be..dfdb5d22c6 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h @@ -1563,6 +1563,294 @@ RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE) RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE) // End Crates +// Start Rocks +RANDO_ENUM_ITEM(RC_KF_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RC_KF_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RC_KF_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RC_KF_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RC_KF_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RC_KF_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RC_KF_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RC_KF_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RC_KF_ROCK_BY_SARIAS_HOUSE) +RANDO_ENUM_ITEM(RC_KF_ROCK_BEHIND_SARIAS_HOUSE) +RANDO_ENUM_ITEM(RC_KF_ROCK_BY_MIDOS_HOUSE) +RANDO_ENUM_ITEM(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE) +RANDO_ENUM_ITEM(RC_LW_BOULDER_BY_GORON_CITY) +RANDO_ENUM_ITEM(RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW) +RANDO_ENUM_ITEM(RC_LW_RUPEE_BOULDER) +RANDO_ENUM_ITEM(RC_HC_ROCK_1) +RANDO_ENUM_ITEM(RC_HC_ROCK_2) +RANDO_ENUM_ITEM(RC_HC_ROCK_3) +RANDO_ENUM_ITEM(RC_HC_BOULDER) +RANDO_ENUM_ITEM(RC_OGC_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RC_OGC_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RC_OGC_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RC_OGC_SILVER_BOULDER_1) +RANDO_ENUM_ITEM(RC_OGC_SILVER_BOULDER_2) +RANDO_ENUM_ITEM(RC_OGC_SILVER_BOULDER_3) +RANDO_ENUM_ITEM(RC_OGC_SILVER_BOULDER_4) +RANDO_ENUM_ITEM(RC_DMC_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RC_DMC_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RC_DMC_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RC_DMC_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RC_DMC_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RC_DMC_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RC_DMC_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RC_DMC_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RC_DMC_ROCK_BY_FIRE_TEMPLE_1) +RANDO_ENUM_ITEM(RC_DMC_ROCK_BY_FIRE_TEMPLE_2) +RANDO_ENUM_ITEM(RC_DMC_ROCK_BY_FIRE_TEMPLE_3) +RANDO_ENUM_ITEM(RC_DMC_ROCK_BY_FIRE_TEMPLE_4) +RANDO_ENUM_ITEM(RC_DMC_ROCK_BY_FIRE_TEMPLE_5) +RANDO_ENUM_ITEM(RC_DMC_GOSSIP_ROCK_1) +RANDO_ENUM_ITEM(RC_DMC_GOSSIP_ROCK_2) +RANDO_ENUM_ITEM(RC_DMC_BOULDER_1) +RANDO_ENUM_ITEM(RC_DMC_BOULDER_2) +RANDO_ENUM_ITEM(RC_DMC_BOULDER_3) +RANDO_ENUM_ITEM(RC_DMC_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RC_DMC_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RC_DMC_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RC_DMC_BRONZE_BOULDER_SHORTCUT) +RANDO_ENUM_ITEM(RC_GV_SILVER_BOULDER) +RANDO_ENUM_ITEM(RC_GV_ROCK_1) +RANDO_ENUM_ITEM(RC_GV_ROCK_2) +RANDO_ENUM_ITEM(RC_GV_ROCK_3) +RANDO_ENUM_ITEM(RC_GV_UNDERWATER_ROCK_1) +RANDO_ENUM_ITEM(RC_GV_UNDERWATER_ROCK_2) +RANDO_ENUM_ITEM(RC_GV_UNDERWATER_ROCK_3) +RANDO_ENUM_ITEM(RC_GV_ROCK_ACROSS_BRIDGE_1) +RANDO_ENUM_ITEM(RC_GV_ROCK_ACROSS_BRIDGE_2) +RANDO_ENUM_ITEM(RC_GV_ROCK_ACROSS_BRIDGE_3) +RANDO_ENUM_ITEM(RC_GV_ROCK_ACROSS_BRIDGE_4) +RANDO_ENUM_ITEM(RC_GV_BOULDER_1) +RANDO_ENUM_ITEM(RC_GV_BOULDER_2) +RANDO_ENUM_ITEM(RC_GV_BOULDER_ACROSS_BRIDGE) +RANDO_ENUM_ITEM(RC_GV_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RC_GV_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1) +RANDO_ENUM_ITEM(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2) +RANDO_ENUM_ITEM(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3) +RANDO_ENUM_ITEM(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4) +RANDO_ENUM_ITEM(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5) +RANDO_ENUM_ITEM(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6) +RANDO_ENUM_ITEM(RC_HF_SILVER_BOULDER) +RANDO_ENUM_ITEM(RC_HF_ROCK_1) +RANDO_ENUM_ITEM(RC_HF_ROCK_2) +RANDO_ENUM_ITEM(RC_HF_ROCK_3) +RANDO_ENUM_ITEM(RC_HF_ROCK_4) +RANDO_ENUM_ITEM(RC_HF_ROCK_5) +RANDO_ENUM_ITEM(RC_HF_ROCK_6) +RANDO_ENUM_ITEM(RC_HF_ROCK_7) +RANDO_ENUM_ITEM(RC_HF_ROCK_8) +RANDO_ENUM_ITEM(RC_HF_BOULDER_NORTH) +RANDO_ENUM_ITEM(RC_HF_BOULDER_BY_MARKET) +RANDO_ENUM_ITEM(RC_HF_BOULDER_SOUTH) +RANDO_ENUM_ITEM(RC_HF_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RC_HF_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RC_HF_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RC_HF_BRONZE_BOULDER_4) +RANDO_ENUM_ITEM(RC_KAK_SILVER_BOULDER) +RANDO_ENUM_ITEM(RC_KAK_ROCK_1) +RANDO_ENUM_ITEM(RC_KAK_ROCK_2) +RANDO_ENUM_ITEM(RC_GY_ROCK) +RANDO_ENUM_ITEM(RC_LH_ROCK) +RANDO_ENUM_ITEM(RC_ZD_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RC_ZD_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RC_ZD_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RC_ZD_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RC_ZD_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RC_ZD_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RC_ZD_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RC_ZD_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RC_ZF_BOULDER) +RANDO_ENUM_ITEM(RC_ZF_SILVER_BOULDER) +RANDO_ENUM_ITEM(RC_ZF_UNDERGROUND_BOULDER) +RANDO_ENUM_ITEM(RC_ZR_BOULDER_1) +RANDO_ENUM_ITEM(RC_ZR_BOULDER_2) +RANDO_ENUM_ITEM(RC_ZR_BOULDER_3) +RANDO_ENUM_ITEM(RC_ZR_BOULDER_4) +RANDO_ENUM_ITEM(RC_ZR_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RC_ZR_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RC_ZR_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RC_ZR_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RC_ZR_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RC_ZR_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RC_ZR_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RC_ZR_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_BOULDER) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RC_ZR_UPPER_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RC_ZR_ROCK) +RANDO_ENUM_ITEM(RC_ZR_UNDERWATER_ROCK_1) +RANDO_ENUM_ITEM(RC_ZR_UNDERWATER_ROCK_2) +RANDO_ENUM_ITEM(RC_ZR_UNDERWATER_ROCK_3) +RANDO_ENUM_ITEM(RC_ZR_UNDERWATER_ROCK_4) +RANDO_ENUM_ITEM(RC_DMT_ROCK_1) +RANDO_ENUM_ITEM(RC_DMT_ROCK_2) +RANDO_ENUM_ITEM(RC_DMT_ROCK_3) +RANDO_ENUM_ITEM(RC_DMT_ROCK_4) +RANDO_ENUM_ITEM(RC_DMT_ROCK_5) +RANDO_ENUM_ITEM(RC_DMT_SUMMIT_ROCK) +RANDO_ENUM_ITEM(RC_DMT_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RC_DMT_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RC_DMT_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RC_DMT_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RC_DMT_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RC_DMT_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RC_DMT_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RC_DMT_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RC_DMT_CHILD_BOULDER) +RANDO_ENUM_ITEM(RC_DMT_BOULDER_1) +RANDO_ENUM_ITEM(RC_DMT_BOULDER_2) +RANDO_ENUM_ITEM(RC_DMT_COW_BOULDER) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_4) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_5) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_6) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_7) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_8) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_9) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_10) +RANDO_ENUM_ITEM(RC_DMT_BRONZE_BOULDER_11) +RANDO_ENUM_ITEM(RC_GC_LW_BOULDER_1) +RANDO_ENUM_ITEM(RC_GC_LW_BOULDER_2) +RANDO_ENUM_ITEM(RC_GC_LW_BOULDER_3) +RANDO_ENUM_ITEM(RC_GC_ENTRANCE_BOULDER_1) +RANDO_ENUM_ITEM(RC_GC_ENTRANCE_BOULDER_2) +RANDO_ENUM_ITEM(RC_GC_ENTRANCE_BOULDER_3) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_1) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_2) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_3) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_4) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_5) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_6) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_7) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_8) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_9) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_10) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_11) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_12) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_13) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_14) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_15) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_16) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_17) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_18) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_19) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_20) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_21) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_22) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_23) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_24) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_25) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_26) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_27) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_28) +RANDO_ENUM_ITEM(RC_GC_MAZE_SILVER_BOULDER_29) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_1) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_2) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_3) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_4) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_5) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_6) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_7) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_8) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_9) +RANDO_ENUM_ITEM(RC_GC_MAZE_BOULDER_10) +RANDO_ENUM_ITEM(RC_GC_MAZE_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RC_GC_MAZE_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RC_GC_MAZE_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RC_GC_MAZE_BRONZE_BOULDER_4) +RANDO_ENUM_ITEM(RC_GC_MAZE_BRONZE_BOULDER_5) +RANDO_ENUM_ITEM(RC_GC_MAZE_ROCK) +RANDO_ENUM_ITEM(RC_COLOSSUS_SILVER_BOULDER) +RANDO_ENUM_ITEM(RC_COLOSSUS_ROCK) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_1_ROCK_1) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_1_ROCK_2) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_1_ROCK_3) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_1_ROCK_4) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_1_ROCK_5) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_1_ROCK_6) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_1_ROCK_7) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_1_ROCK_8) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_2_ROCK_1) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_2_ROCK_2) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_2_ROCK_3) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_2_ROCK_4) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_2_ROCK_5) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_2_ROCK_6) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_2_ROCK_7) +RANDO_ENUM_ITEM(RC_COLOSSUS_CIRCLE_2_ROCK_8) +RANDO_ENUM_ITEM(RC_HC_STORMS_GROTTO_ROCK_1) +RANDO_ENUM_ITEM(RC_HC_STORMS_GROTTO_ROCK_2) +RANDO_ENUM_ITEM(RC_HC_STORMS_GROTTO_ROCK_3) +RANDO_ENUM_ITEM(RC_HC_STORMS_GROTTO_ROCK_4) +RANDO_ENUM_ITEM(RC_HC_STORMS_GROTTO_ROCK_5) +RANDO_ENUM_ITEM(RC_HC_STORMS_GROTTO_ROCK_6) +RANDO_ENUM_ITEM(RC_HC_STORMS_GROTTO_ROCK_7) +RANDO_ENUM_ITEM(RC_HC_STORMS_GROTTO_ROCK_8) +RANDO_ENUM_ITEM(RC_BOTW_BOULDER_1) +RANDO_ENUM_ITEM(RC_BOTW_BOULDER_2) +RANDO_ENUM_ITEM(RC_BOTW_BOULDER_3) +RANDO_ENUM_ITEM(RC_BOTW_BOULDER_4) +RANDO_ENUM_ITEM(RC_BOTW_BOULDER_5) +RANDO_ENUM_ITEM(RC_BOTW_BOULDER_6) +RANDO_ENUM_ITEM(RC_DEKU_TREE_MQ_BOULDER_1) +RANDO_ENUM_ITEM(RC_DEKU_TREE_MQ_BOULDER_2) +RANDO_ENUM_ITEM(RC_DEKU_TREE_MQ_BOULDER_3) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_CRAWLSPACE_BOULDER) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_LOW) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_HIGH) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER) +RANDO_ENUM_ITEM(RC_BOTW_MQ_BOULDER_1) +RANDO_ENUM_ITEM(RC_BOTW_MQ_BOULDER_2) +RANDO_ENUM_ITEM(RC_BOTW_MQ_BOULDER_3) +// End Rocks + // Start Trees RANDO_ENUM_ITEM(RC_MARKET_TREE) RANDO_ENUM_ITEM(RC_HC_NEAR_GUARDS_TREE_1) @@ -1777,6 +2065,13 @@ RANDO_ENUM_ITEM(RC_TRIFORCE_COMPLETED) RANDO_ENUM_ITEM(RC_DAMPE_HINT) RANDO_ENUM_ITEM(RC_GREG_HINT) RANDO_ENUM_ITEM(RC_SARIA_SONG_HINT) +RANDO_ENUM_ITEM(RC_MIDO_HINT) +RANDO_ENUM_ITEM(RC_FOREST_BOSS_KEY_HINT) +RANDO_ENUM_ITEM(RC_FIRE_BOSS_KEY_HINT) +RANDO_ENUM_ITEM(RC_WATER_BOSS_KEY_HINT) +RANDO_ENUM_ITEM(RC_SPIRIT_BOSS_KEY_HINT) +RANDO_ENUM_ITEM(RC_SHADOW_BOSS_KEY_HINT) +RANDO_ENUM_ITEM(RC_GANONS_BOSS_KEY_HINT) RANDO_ENUM_ITEM(RC_ALTAR_HINT_CHILD) RANDO_ENUM_ITEM(RC_ALTAR_HINT_ADULT) RANDO_ENUM_ITEM(RC_FISHING_POLE_HINT) @@ -1998,6 +2293,213 @@ RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART) RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART) RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART) RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART) + +// Overworld Wonder Items +RANDO_ENUM_ITEM(RC_KF_WONDER_TRAINING_1) +RANDO_ENUM_ITEM(RC_KF_WONDER_TRAINING_2) +RANDO_ENUM_ITEM(RC_KF_WONDER_TRAINING_3) +RANDO_ENUM_ITEM(RC_KF_WONDER_SHOP) +RANDO_ENUM_ITEM(RC_KF_WONDER_SIGN) +RANDO_ENUM_ITEM(RC_KF_WONDER_PLATFORMS_1) +RANDO_ENUM_ITEM(RC_KF_WONDER_PLATFORMS_2) +RANDO_ENUM_ITEM(RC_KF_WONDER_CRAWL_GRASS_1) +RANDO_ENUM_ITEM(RC_KF_WONDER_CRAWL_GRASS_2) +RANDO_ENUM_ITEM(RC_HF_WONDER_BRIDGE_1) +RANDO_ENUM_ITEM(RC_HF_WONDER_BRIDGE_2) +RANDO_ENUM_ITEM(RC_HF_WONDER_BRIDGE_3) +RANDO_ENUM_ITEM(RC_MKT_WONDER_DAY_1) +RANDO_ENUM_ITEM(RC_MKT_WONDER_DAY_2) +RANDO_ENUM_ITEM(RC_MKT_WONDER_DAY_3) +RANDO_ENUM_ITEM(RC_MKT_WONDER_DAY_4) +RANDO_ENUM_ITEM(RC_MKT_WONDER_DAY_5) +RANDO_ENUM_ITEM(RC_MKT_WONDER_NIGHT_1) +RANDO_ENUM_ITEM(RC_MKT_WONDER_NIGHT_2) +RANDO_ENUM_ITEM(RC_LLR_WONDER_BIG_FENCE) +RANDO_ENUM_ITEM(RC_LLR_WONDER_SMALL_FENCE) +RANDO_ENUM_ITEM(RC_HC_WONDER_LEFT_TORCH) +RANDO_ENUM_ITEM(RC_HC_WONDER_RIGHT_TORCH) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_1) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_2) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_3) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_4) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_5) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_6) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_7) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_8) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_9) +RANDO_ENUM_ITEM(RC_HC_WONDER_MOAT_10) +RANDO_ENUM_ITEM(RC_HC_WONDER_COURTYARD_RIGHT_WINDOW) +RANDO_ENUM_ITEM(RC_HC_WONDER_COURTYARD_LEFT_WINDOW) +RANDO_ENUM_ITEM(RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_1) +RANDO_ENUM_ITEM(RC_LW_WONDER_BACK_SKULL_KIDS_GRASS_2) +RANDO_ENUM_ITEM(RC_LW_WONDER_FRONT_SKULL_KIDS_GRASS) +RANDO_ENUM_ITEM(RC_SFM_WONDER_ENTRANCE) +RANDO_ENUM_ITEM(RC_SFM_WONDER_MAZE_1) +RANDO_ENUM_ITEM(RC_SFM_WONDER_MAZE_2) +RANDO_ENUM_ITEM(RC_SFM_WONDER_MAZE_3) +RANDO_ENUM_ITEM(RC_SFM_WONDER_MAZE_4) +RANDO_ENUM_ITEM(RC_SFM_WONDER_MAZE_5) +RANDO_ENUM_ITEM(RC_KAK_WONDER_UNDER_CONSTRUCTION) +RANDO_ENUM_ITEM(RC_KAK_WONDER_ABOVE_COW) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_1) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_2) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_3) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_4) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_5) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_6) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_7) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_8) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_9) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_10) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_11) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_12) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_13) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_14) +RANDO_ENUM_ITEM(RC_GY_WONDER_DAMPE_RACE_15) +RANDO_ENUM_ITEM(RC_DMC_WONDER_BENEATH_BRIDGE_PLATFORM) +RANDO_ENUM_ITEM(RC_ZR_WONDER_NEAR_DOMAIN_1) +RANDO_ENUM_ITEM(RC_ZR_WONDER_NEAR_DOMAIN_2) +RANDO_ENUM_ITEM(RC_ZR_WONDER_NEAR_DOMAIN_3) +RANDO_ENUM_ITEM(RC_ZR_WONDER_NEAR_DOMAIN_4) +RANDO_ENUM_ITEM(RC_ZR_WONDER_BEFORE_LADDER_1) +RANDO_ENUM_ITEM(RC_ZR_WONDER_BEFORE_LADDER_2) +RANDO_ENUM_ITEM(RC_ZR_WONDER_BEFORE_LADDER_3) +RANDO_ENUM_ITEM(RC_ZR_WONDER_BEFORE_LADDER_4) +RANDO_ENUM_ITEM(RC_ZR_WONDER_BEFORE_LADDER_5) +RANDO_ENUM_ITEM(RC_ZR_WONDER_BEFORE_LADDER_6) +RANDO_ENUM_ITEM(RC_ZR_WONDER_AFTER_LADDER_1) +RANDO_ENUM_ITEM(RC_ZR_WONDER_AFTER_LADDER_2) +RANDO_ENUM_ITEM(RC_ZR_WONDER_AFTER_LADDER_3) +RANDO_ENUM_ITEM(RC_ZR_WONDER_FROG_BRIDGE_1) +RANDO_ENUM_ITEM(RC_ZR_WONDER_FROG_BRIDGE_2) +RANDO_ENUM_ITEM(RC_ZR_WONDER_FROG_BRIDGE_3) +RANDO_ENUM_ITEM(RC_ZR_WONDER_PILLARS_1) +RANDO_ENUM_ITEM(RC_ZR_WONDER_PILLARS_2) +RANDO_ENUM_ITEM(RC_ZR_WONDER_PILLARS_3) +RANDO_ENUM_ITEM(RC_ZR_WONDER_PILLARS_4) +RANDO_ENUM_ITEM(RC_ZR_WONDER_LOWER_LAND_BRIDGE_1) +RANDO_ENUM_ITEM(RC_ZR_WONDER_LOWER_LAND_BRIDGE_2) +RANDO_ENUM_ITEM(RC_ZR_WONDER_LOWER_LAND_BRIDGE_3) +RANDO_ENUM_ITEM(RC_ZR_WONDER_LOWER_LAND_BRIDGE_4) +RANDO_ENUM_ITEM(RC_ZR_WONDER_NEAR_CUCCO_1) +RANDO_ENUM_ITEM(RC_ZR_WONDER_NEAR_CUCCO_2) +RANDO_ENUM_ITEM(RC_ZR_WONDER_NEAR_CUCCO_3) +RANDO_ENUM_ITEM(RC_ZR_WONDER_LOWER_RIVER_1) +RANDO_ENUM_ITEM(RC_ZR_WONDER_LOWER_RIVER_2) +RANDO_ENUM_ITEM(RC_ZR_WONDER_LOWER_RIVER_3) +RANDO_ENUM_ITEM(RC_ZR_WONDER_LOWER_RIVER_4) +RANDO_ENUM_ITEM(RC_ZF_WONDER_ROCK) +RANDO_ENUM_ITEM(RC_GV_WONDER_LOWER_WATERFALL) +RANDO_ENUM_ITEM(RC_GV_WONDER_UPPER_WATERFALL) +RANDO_ENUM_ITEM(RC_GF_WONDER_ENTRANCE_SIGN) +RANDO_ENUM_ITEM(RC_GF_WONDER_ARCHERY_SIGN) +RANDO_ENUM_ITEM(RC_TH_WONDER_1_TORCH_1) +RANDO_ENUM_ITEM(RC_TH_WONDER_1_TORCH_2) +RANDO_ENUM_ITEM(RC_TH_WONDER_STEEP_SLOPE_LOWER_EXIT) +RANDO_ENUM_ITEM(RC_TH_WONDER_STEEP_SLOPE_UPPER_EXIT) +RANDO_ENUM_ITEM(RC_TH_WONDER_DOUBLE_JAIL_LOWER_EXIT) +RANDO_ENUM_ITEM(RC_TH_WONDER_DOUBLE_JAIL_UPPER_EXIT) +RANDO_ENUM_ITEM(RC_TH_WONDER_KITCHEN_SKULL) +RANDO_ENUM_ITEM(RC_TH_WONDER_KITCHEN_SOUP) +RANDO_ENUM_ITEM(RC_TH_WONDER_DEAD_END_SKULL_ENTRANCE) +RANDO_ENUM_ITEM(RC_TH_WONDER_DEAD_END_SKULL_NEAR_JAIL) +RANDO_ENUM_ITEM(RC_TH_WONDER_BREAK_ROOM_BOTTOM_SKULL) +RANDO_ENUM_ITEM(RC_TH_WONDER_BREAK_ROOM_TOP_SKULL) +RANDO_ENUM_ITEM(RC_COLOSSUS_WONDER_OASIS_TREE_1) +RANDO_ENUM_ITEM(RC_COLOSSUS_WONDER_OASIS_TREE_2) +RANDO_ENUM_ITEM(RC_COLOSSUS_WONDER_OASIS_CHILD_TREE) +RANDO_ENUM_ITEM(RC_COLOSSUS_WONDER_GF_TREE_1) +RANDO_ENUM_ITEM(RC_COLOSSUS_WONDER_GF_TREE_2) +// Dungeon Wonder Items +RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_WONDER_THREE_POTS) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_WONDER_BEAMOS_ROOM) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_WONDER_EYE_STATUE_ROOM) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_WONDER_TORCH_SLUGS_ROOM) +// MQ Dungeon Wonder Items +RANDO_ENUM_ITEM(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_1) +RANDO_ENUM_ITEM(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_2) +RANDO_ENUM_ITEM(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_3) +RANDO_ENUM_ITEM(RC_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_4) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_LEFT_COW) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_RIGHT_COW) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_ELEVATOR_COW) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_HOLES_COW) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_AFTER_BIG_OCTO) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_JIGGLIES_COW) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_LEFT_COW) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_1) +RANDO_ENUM_ITEM(RC_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_2) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_LIZALFOS_MAZE) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_TORCH_ROOM) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_AFTER_FLARE_DANCER) +RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_WONDER_STAIRCASE) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_AFTER_DARK_LINK) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_PORTRAIT) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_TRIPLE_TORCHES) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_1) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_FREESTANDING_ROOM) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_1) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_2) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_UNDER_PILLAR_ROOM) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_HALLWAY) +RANDO_ENUM_ITEM(RC_WATER_TEMPLE_MQ_WONDER_GS_STORAGE_ROOM) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH) +RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_MQ_WONDER_THREE_POTS) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3) +RANDO_ENUM_ITEM(RC_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL) +// End Wonder Items + RANDO_ENUM_ITEM(RC_SFM_FAIRY_GROTTO_FAIRY_1) RANDO_ENUM_ITEM(RC_SFM_FAIRY_GROTTO_FAIRY_2) RANDO_ENUM_ITEM(RC_SFM_FAIRY_GROTTO_FAIRY_3) @@ -2191,6 +2693,25 @@ RANDO_ENUM_ITEM(RC_LW_SHORTCUT_STORMS_FAIRY) RANDO_ENUM_ITEM(RC_TH_KITCHEN_SUN_FAIRY) RANDO_ENUM_ITEM(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY) RANDO_ENUM_ITEM(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY) +RANDO_ENUM_ITEM(RC_HC_NEAR_WALL_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_HC_NEAR_STAIRS_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_HC_NEAR_BOULDER_PATH_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_HC_NEAR_ARCHWAY_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_LW_MEADOW_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_GY_NEAR_HUT_GRAVE_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_ZR_NEAR_ROCK_CIRCLE_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_ZR_WATERFALL_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_ZF_LOG_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_LH_SCARECROW_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_KF_STORMS_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_LW_TUNNEL_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_DMT_STORMS_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_DMC_UPPER_BOULDER_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_HF_NEAR_MARKET_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_HF_SOUTHEAST_BOULDER_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_HF_OPEN_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_KAK_OPEN_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RC_ZR_OPEN_GROTTO_BUTTERFLY_FAIRY) RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY) RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY) RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY) @@ -2563,6 +3084,290 @@ RANDO_ENUM_ITEM(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_7) RANDO_ENUM_ITEM(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8) // End Grass +// Overworld Signs +RANDO_ENUM_ITEM(RC_KF_DEKU_TREE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_STEPPING_STONES_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_LINKS_HOUSE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_FIRST_TRAINING_CENTER_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_SECOND_TRAINING_CENTER_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_AFTER_CRAWLSPACE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_CRAWL_RECTANGLE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_LOST_WOODS_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_HOUSE_OF_TWINS_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KF_SHOP_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KF_SARIAS_HOUSE_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KF_LOST_WOODS_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KF_MIDOS_HOUSE_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KF_TRAINING_CENTER_ENTRANCE_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KF_INNER_TRAINING_CENTER_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KF_KNOW_IT_ALL_BROTHERS_HOUSE_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KF_BOULDER_MAZE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KF_LINKS_HOUSE_SIGN) +RANDO_ENUM_ITEM(RC_LW_THEATER_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_HF_CASTLE_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_HF_WOODED_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_HF_ROCKY_PATH_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_HF_FENCED_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_HF_CENTER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_HF_RIVER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_HF_STAIRS_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_MK_SHOOTING_GALLERY_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_MK_MASK_SHOP_SIGN) +RANDO_ENUM_ITEM(RC_TOT_ALTAR) +RANDO_ENUM_ITEM(RC_HC_DEAD_END_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KAK_GUARD_GATE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KAK_WELL_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_KAK_SOUTHEAST_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KAK_FRONT_GATE_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_GY_ENTRANCE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_GY_ENTRANCE_PLINTH) +RANDO_ENUM_ITEM(RC_GY_RIGHT_OF_ROYAL_TOMB_GRAVE) +RANDO_ENUM_ITEM(RC_GY_LEFT_OF_ROYAL_TOMB_GRAVE) +RANDO_ENUM_ITEM(RC_GY_ROYAL_TOMB_GRAVE) +RANDO_ENUM_ITEM(RC_DMT_ABOVE_DODONGO_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_DMT_ADULT_CENTER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_DMT_CHILD_CENTER_EXIT_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_DMT_DODONGOS_CAVERN_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_DMT_CENTER_TRAIL_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_DMT_TO_UPPER_TRAIL_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_DMT_UPPER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_DMT_TO_CENTER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_DMT_LOWER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_GC_CHILD_ROLLING_GORON_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_DMC_BRIDGE_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_ZR_SLEEPLESS_WATERFALL_PLAQUE) +RANDO_ENUM_ITEM(RC_ZD_SHOP_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_ZD_ENTRANCE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_ZD_KING_ZORA_PATH_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_ZD_NEAR_KING_ZORA_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_ZD_NEAR_KING_ZORA_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_ZF_JABU_JABU_PLATFORM_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_ZF_ENTRANCE_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_LH_LAB_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_LH_NORTH_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_LH_FISHING_SIGN) +RANDO_ENUM_ITEM(RC_LH_ISLAND_PEDESTAL) +RANDO_ENUM_ITEM(RC_LH_FISHING_POND_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_GV_BRIDGE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_GV_EAST_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_GF_EAST_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_GF_HBA_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_GF_GATE_EXIT_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_GF_GTG_ENTRANCE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_HW_CARPET_SALESMAN_ARROW_SIGN) +RANDO_ENUM_ITEM(RC_HW_POE_ALTAR) +// Dungeon Signs +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL) +RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE) +RANDO_ENUM_ITEM(RC_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE) +// MQ Dungeon Signs +RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN) +// Beggar +RANDO_ENUM_ITEM(RC_MK_BEGGAR_BUGS) +RANDO_ENUM_ITEM(RC_MK_BEGGAR_FISH) +RANDO_ENUM_ITEM(RC_MK_BEGGAR_BLUE_FIRE) +RANDO_ENUM_ITEM(RC_KAK_BEGGAR_BUGS) +RANDO_ENUM_ITEM(RC_KAK_BEGGAR_FISH) +RANDO_ENUM_ITEM(RC_KAK_BEGGAR_BLUE_FIRE) + +// Vanilla Icicles +RANDO_ENUM_ITEM(RC_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_ENTRANCE_MIDDLE_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_ENTRANCE_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_ENTRANCE_STALACTITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_ENTRANCE_STALACTITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_LOBBY_STALACTITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_LOBBY_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_LOBBY_MIDDLE_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_LOBBY_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_AFTER_LOBBY_STALACTITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_AFTER_LOBBY_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_AFTER_LOBBY_CENTER_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_AFTER_LOBBY_CENTER_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_AFTER_LOBBY_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SPINNING_BLADE_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SPINNING_BLADE_MIDDLE_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_HALLWAY_STALACTITE_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_HALLWAY_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_HALLWAY_MIDDLE_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_HALLWAY_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_6) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_PUSH_BLOCK_HALL_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_PUSH_BLOCK_HALL_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALACTITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALACTITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALACTITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALACTITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALAGMITE_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALAGMITE_6) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALAGMITE_7) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_STALAGMITE_8) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_5) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_6) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_7) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_8) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_9) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_10) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_5) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_6) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_7) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_8) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_9) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_10) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_STALACTITE_11) +// MQ Icicles +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_LOBBY_STALACTITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_STALAGMITE_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_6) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_7) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_BEFORE_SCARECROW_STALAGMITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_SCARECROW_ROOM_STALACTITE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_3) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_5) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_1) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_2) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_3) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_4) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_LEFT_STALACTITE) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_4) +// Red Ice +RANDO_ENUM_ITEM(RC_ZD_KING_ZORA_RED_ICE) +RANDO_ENUM_ITEM(RC_ZD_ZORA_SHOP_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_ENTRANCE_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_LOBBY_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_LOBBY_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_HEART_PIECE_ROOM_CHEST_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_ROOM_POT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MAP_ROOM_CHEST_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_RUPEE_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_MIDDLE_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_DOOR_RED_ICE) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_WATER_TRIAL_RUSTED_SWITCH_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_WEST_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_WEST_MIDDLE_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_WEST_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_LEDGE_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_LEDGE_MIDDLE_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_HUB_LEDGE_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_COMPASS_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_MAP_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_RED_ICE) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_BACK_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5) + RANDO_ENUM_ITEM(RC_MAX) RANDO_ENUM_END(RandomizerCheck) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h index a57f763553..b6e8eb6c5e 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h @@ -1368,6 +1368,33 @@ RANDO_ENUM_ITEM(RHT_TREE_LON_LON_RANCH) RANDO_ENUM_ITEM(RHT_TREE_KAKARIKO) RANDO_ENUM_ITEM(RHT_BUSH_HYRULE_FIELD) RANDO_ENUM_ITEM(RHT_BUSH_ZORAS_FOUNTAIN) +// Shuffle Wonder Items +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_KOKIRI_FOREST) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_HYRULE_FIELD) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_MARKET) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_LON_LON_RANCH) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_HYRULE_CASTLE) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_CASTLE_COURTYARD_ZELDA) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_LOST_WOODS) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_SACRED_FOREST_MEADOW) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_KAKARIKO_VILLAGE) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_DAMPES_GRAVE) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_DEATH_MOUNTAIN_CRATER) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_ZORAS_RIVER) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_ZORAS_FOUNTAIN) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_GERUDO_VALLEY) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_GERUDOS_FORTRESS) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_THIEVES_HIDEOUT) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_DESERT_COLOSSUS) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_DEKU_TREE) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_JABU_JABU) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_FIRE_TEMPLE) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_WATER_TEMPLE) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_SPIRIT_TEMPLE) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_SHADOW_TEMPLE) +RANDO_ENUM_ITEM(RHT_BOTTOM_OF_THE_WELL_WONDER_ITEM) +RANDO_ENUM_ITEM(RHT_WONDER_ITEM_GERUDO_TRAINING_GROUND) +RANDO_ENUM_ITEM(RHT_GANONS_CASTLE_WONDER_ITEM) // Ganon Line RANDO_ENUM_ITEM(RHT_GANON_JOKE01) RANDO_ENUM_ITEM(RHT_GANON_JOKE02) @@ -1515,6 +1542,19 @@ RANDO_ENUM_ITEM(RHT_LW_SHORTCUT_STORMS_FAIRY) RANDO_ENUM_ITEM(RHT_TH_KITCHEN_SUN_FAIRY) RANDO_ENUM_ITEM(RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY) RANDO_ENUM_ITEM(RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_HYRULE_CASTLE) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_LOST_WOODS) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_GRAVEYARD) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_ZORAS_RIVER) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_ZORAS_FOUNTAIN) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_LAKE_HYLIA) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_KF_GROTTO) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_LW_GROTTO) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_DMT_GROTTO) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_DMC_GROTTO) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_HF_GROTTO) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_KAK_GROTTO) +RANDO_ENUM_ITEM(RHT_BUTTERFLY_FAIRY_ZR_GROTTO) RANDO_ENUM_ITEM(RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY) RANDO_ENUM_ITEM(RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY) RANDO_ENUM_ITEM(RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY) @@ -1547,6 +1587,86 @@ RANDO_ENUM_ITEM(RHT_DEKU_TREE_GRASS) RANDO_ENUM_ITEM(RHT_DODONGOS_CAVERN_GRASS) RANDO_ENUM_ITEM(RHT_BOTTOM_OF_THE_WELL_GRASS) RANDO_ENUM_ITEM(RHT_JABU_JABUS_BELLY_GRASS) +// ROCKS +RANDO_ENUM_ITEM(RHT_KF_ROCK) +RANDO_ENUM_ITEM(RHT_LW_BOULDER) +RANDO_ENUM_ITEM(RHT_HC_ROCK) +RANDO_ENUM_ITEM(RHT_HC_BOULDER) +RANDO_ENUM_ITEM(RHT_OGC_BRONZE_BOULDER) +RANDO_ENUM_ITEM(RHT_OGC_SILVER_BOULDER) +RANDO_ENUM_ITEM(RHT_DMC_ROCK) +RANDO_ENUM_ITEM(RHT_DMC_BOULDER) +RANDO_ENUM_ITEM(RHT_DMC_BRONZE_BOULDER) +RANDO_ENUM_ITEM(RHT_GV_SILVER_BOULDER) +RANDO_ENUM_ITEM(RHT_GV_ROCK) +RANDO_ENUM_ITEM(RHT_GV_BOULDER) +RANDO_ENUM_ITEM(RHT_GV_BRONZE_BOULDER) +RANDO_ENUM_ITEM(RHT_HF_SILVER_BOULDER) +RANDO_ENUM_ITEM(RHT_HF_ROCK) +RANDO_ENUM_ITEM(RHT_HF_BOULDER) +RANDO_ENUM_ITEM(RHT_HF_BRONZE_BOULDER) +RANDO_ENUM_ITEM(RHT_KAK_SILVER_BOULDER) +RANDO_ENUM_ITEM(RHT_KAK_ROCK) +RANDO_ENUM_ITEM(RHT_GY_ROCK) +RANDO_ENUM_ITEM(RHT_LH_ROCK) +RANDO_ENUM_ITEM(RHT_ZD_ROCK) +RANDO_ENUM_ITEM(RHT_ZF_BOULDER) +RANDO_ENUM_ITEM(RHT_ZF_SILVER_BOULDER) +RANDO_ENUM_ITEM(RHT_ZR_BOULDER) +RANDO_ENUM_ITEM(RHT_ZR_ROCK) +RANDO_ENUM_ITEM(RHT_DMT_ROCK) +RANDO_ENUM_ITEM(RHT_DMT_BOULDER) +RANDO_ENUM_ITEM(RHT_DMT_BRONZE_BOULDER) +RANDO_ENUM_ITEM(RHT_GC_BOULDER) +RANDO_ENUM_ITEM(RHT_GC_SILVER_BOULDER) +RANDO_ENUM_ITEM(RHT_GC_BRONZE_BOULDER) +RANDO_ENUM_ITEM(RHT_GC_ROCK) +RANDO_ENUM_ITEM(RHT_COLOSSUS_SILVER_BOULDER) +RANDO_ENUM_ITEM(RHT_COLOSSUS_ROCK) +RANDO_ENUM_ITEM(RHT_HC_STORMS_GROTTO_ROCK) +RANDO_ENUM_ITEM(RHT_BOTW_BOULDER) +RANDO_ENUM_ITEM(RHT_DEKU_BOULDER) +RANDO_ENUM_ITEM(RHT_DODONGOS_BOULDER) +RANDO_ENUM_ITEM(RHT_JABU_BOULDER) +RANDO_ENUM_ITEM(RHT_SPIRIT_TEMPLE_BOULDER) +// SIGNS +RANDO_ENUM_ITEM(RHT_SIGN_KOKIRI_FOREST) +RANDO_ENUM_ITEM(RHT_SIGN_LINKS_HOUSE) +RANDO_ENUM_ITEM(RHT_SIGN_DEKU_THEATER) +RANDO_ENUM_ITEM(RHT_SIGN_HYRULE_FIELD) +RANDO_ENUM_ITEM(RHT_SIGN_MK_SHOOTING_GALLERY) +RANDO_ENUM_ITEM(RHT_SIGN_HAPPY_MASK_SHOP) +RANDO_ENUM_ITEM(RHT_SIGN_TEMPLE_OF_TIME) +RANDO_ENUM_ITEM(RHT_SIGN_HYRULE_CASTLE) +RANDO_ENUM_ITEM(RHT_SIGN_KAKARIKO_VILLAGE) +RANDO_ENUM_ITEM(RHT_SIGN_KAK_SHOOTING_GALLERY) +RANDO_ENUM_ITEM(RHT_SIGN_GRAVEYARD) +RANDO_ENUM_ITEM(RHT_SIGN_DEATH_MOUNTAIN_TRAIL) +RANDO_ENUM_ITEM(RHT_SIGN_GORON_CITY) +RANDO_ENUM_ITEM(RHT_SIGN_DEATH_MOUNTAIN_CRATER) +RANDO_ENUM_ITEM(RHT_SIGN_ZORAS_RIVER) +RANDO_ENUM_ITEM(RHT_SIGN_ZORAS_DOMAIN) +RANDO_ENUM_ITEM(RHT_SIGN_ZORAS_FOUNTAIN) +RANDO_ENUM_ITEM(RHT_SIGN_LAKE_HYLIA) +RANDO_ENUM_ITEM(RHT_SIGN_FISHING_POND) +RANDO_ENUM_ITEM(RHT_SIGN_GERUDO_VALLEY) +RANDO_ENUM_ITEM(RHT_SIGN_GERUDO_FORTRESS) +RANDO_ENUM_ITEM(RHT_SIGN_HAUNTED_WASTELAND) +RANDO_ENUM_ITEM(RHT_SIGN_DODONGOS_CAVERN) +RANDO_ENUM_ITEM(RHT_SIGN_SHADOW_TEMPLE) +RANDO_ENUM_ITEM(RHT_SIGN_SPIRIT_TEMPLE) +// BEGGAR +RANDO_ENUM_ITEM(RHT_BEGGAR_MARKET) +RANDO_ENUM_ITEM(RHT_BEGGAR_KAKARIKO_VILLAGE) +// ICICLES +RANDO_ENUM_ITEM(RHT_ICE_CAVERN_ICICLE) +RANDO_ENUM_ITEM(RHT_GERUDO_TRAINING_GROUND_ICICLE) +RANDO_ENUM_ITEM(RHT_GANONS_CASTLE_ICICLE) +// RED ICE +RANDO_ENUM_ITEM(RHT_RED_ICE_ZORAS_DOMAIN) +RANDO_ENUM_ITEM(RHT_GERUDO_TRAINING_GROUND_RED_ICE) +RANDO_ENUM_ITEM(RHT_ICE_CAVERN_RED_ICE) +RANDO_ENUM_ITEM(RHT_GANONS_CASTLE_RED_ICE) // MAX RANDO_ENUM_ITEM(RHT_MAX) RANDO_ENUM_END(RandomizerHintTextKey) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h index d679bb2234..7f142c787b 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h @@ -1023,6 +1023,291 @@ RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3) RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4) RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE) RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE) +RANDO_ENUM_ITEM(RAND_INF_KF_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_KF_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_KF_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_KF_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_KF_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_KF_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_KF_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_KF_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_KF_ROCK_BY_SARIAS_HOUSE) +RANDO_ENUM_ITEM(RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE) +RANDO_ENUM_ITEM(RAND_INF_KF_ROCK_BY_MIDOS_HOUSE) +RANDO_ENUM_ITEM(RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE) +RANDO_ENUM_ITEM(RAND_INF_LW_BOULDER_BY_GORON_CITY) +RANDO_ENUM_ITEM(RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW) +RANDO_ENUM_ITEM(RAND_INF_LW_RUPEE_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_HC_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_HC_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_HC_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_HC_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_OGC_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_OGC_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_OGC_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_OGC_SILVER_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_OGC_SILVER_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_OGC_SILVER_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_OGC_SILVER_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_DMC_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_DMC_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_DMC_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_DMC_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_DMC_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_DMC_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_DMC_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_DMC_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1) +RANDO_ENUM_ITEM(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2) +RANDO_ENUM_ITEM(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3) +RANDO_ENUM_ITEM(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4) +RANDO_ENUM_ITEM(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5) +RANDO_ENUM_ITEM(RAND_INF_DMC_GOSSIP_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_DMC_GOSSIP_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_DMC_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DMC_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DMC_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_DMC_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DMC_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DMC_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_DMC_BRONZE_BOULDER_SHORTCUT) +RANDO_ENUM_ITEM(RAND_INF_GV_SILVER_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_GV_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_GV_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_GV_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_GV_UNDERWATER_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_GV_UNDERWATER_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_GV_UNDERWATER_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_GV_ROCK_ACROSS_BRIDGE_1) +RANDO_ENUM_ITEM(RAND_INF_GV_ROCK_ACROSS_BRIDGE_2) +RANDO_ENUM_ITEM(RAND_INF_GV_ROCK_ACROSS_BRIDGE_3) +RANDO_ENUM_ITEM(RAND_INF_GV_ROCK_ACROSS_BRIDGE_4) +RANDO_ENUM_ITEM(RAND_INF_GV_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_GV_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_GV_BOULDER_ACROSS_BRIDGE) +RANDO_ENUM_ITEM(RAND_INF_GV_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_GV_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1) +RANDO_ENUM_ITEM(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2) +RANDO_ENUM_ITEM(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3) +RANDO_ENUM_ITEM(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4) +RANDO_ENUM_ITEM(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5) +RANDO_ENUM_ITEM(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6) +RANDO_ENUM_ITEM(RAND_INF_HF_SILVER_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_HF_BOULDER_NORTH) +RANDO_ENUM_ITEM(RAND_INF_HF_BOULDER_BY_MARKET) +RANDO_ENUM_ITEM(RAND_INF_HF_BOULDER_SOUTH) +RANDO_ENUM_ITEM(RAND_INF_HF_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_HF_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_HF_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_HF_BRONZE_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_KAK_SILVER_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_KAK_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_KAK_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_GY_ROCK) +RANDO_ENUM_ITEM(RAND_INF_LH_ROCK) +RANDO_ENUM_ITEM(RAND_INF_ZD_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_ZD_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_ZD_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_ZD_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_ZD_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_ZD_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_ZD_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_ZD_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_ZF_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_ZF_SILVER_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_ZF_UNDERGROUND_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_ZR_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_ZR_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_ZR_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_ZR_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_ZR_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_ZR_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_ZR_UPPER_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_ZR_ROCK) +RANDO_ENUM_ITEM(RAND_INF_ZR_UNDERWATER_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_UNDERWATER_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_UNDERWATER_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_UNDERWATER_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_DMT_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_DMT_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_DMT_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_DMT_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_DMT_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_DMT_SUMMIT_ROCK) +RANDO_ENUM_ITEM(RAND_INF_DMT_CIRCLE_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_DMT_CIRCLE_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_DMT_CIRCLE_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_DMT_CIRCLE_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_DMT_CIRCLE_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_DMT_CIRCLE_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_DMT_CIRCLE_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_DMT_CIRCLE_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_DMT_CHILD_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_DMT_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DMT_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DMT_COW_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_5) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_6) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_7) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_8) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_9) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_10) +RANDO_ENUM_ITEM(RAND_INF_DMT_BRONZE_BOULDER_11) +RANDO_ENUM_ITEM(RAND_INF_GC_LW_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_GC_LW_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_GC_LW_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_GC_ENTRANCE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_GC_ENTRANCE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_GC_ENTRANCE_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_5) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_6) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_7) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_8) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_9) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_10) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_11) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_12) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_13) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_14) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_15) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_16) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_17) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_18) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_19) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_20) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_21) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_22) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_23) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_24) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_25) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_26) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_27) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_28) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_SILVER_BOULDER_29) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_5) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_6) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_7) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_8) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_9) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BOULDER_10) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BRONZE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BRONZE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BRONZE_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BRONZE_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_BRONZE_BOULDER_5) +RANDO_ENUM_ITEM(RAND_INF_GC_MAZE_ROCK) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_SILVER_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_ROCK) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_HC_STORMS_GROTTO_ROCK_1) +RANDO_ENUM_ITEM(RAND_INF_HC_STORMS_GROTTO_ROCK_2) +RANDO_ENUM_ITEM(RAND_INF_HC_STORMS_GROTTO_ROCK_3) +RANDO_ENUM_ITEM(RAND_INF_HC_STORMS_GROTTO_ROCK_4) +RANDO_ENUM_ITEM(RAND_INF_HC_STORMS_GROTTO_ROCK_5) +RANDO_ENUM_ITEM(RAND_INF_HC_STORMS_GROTTO_ROCK_6) +RANDO_ENUM_ITEM(RAND_INF_HC_STORMS_GROTTO_ROCK_7) +RANDO_ENUM_ITEM(RAND_INF_HC_STORMS_GROTTO_ROCK_8) +RANDO_ENUM_ITEM(RAND_INF_BOTW_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_BOTW_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_BOTW_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_BOTW_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_BOTW_BOULDER_5) +RANDO_ENUM_ITEM(RAND_INF_BOTW_BOULDER_6) +RANDO_ENUM_ITEM(RAND_INF_DEKU_TREE_MQ_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DEKU_TREE_MQ_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DEKU_TREE_MQ_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_EYE_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_CRAWLSPACE_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_LOW) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_GIBDO_BOULDER_HIGH) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER) +RANDO_ENUM_ITEM(RAND_INF_BOTW_MQ_BOULDER_1) +RANDO_ENUM_ITEM(RAND_INF_BOTW_MQ_BOULDER_2) +RANDO_ENUM_ITEM(RAND_INF_BOTW_MQ_BOULDER_3) RANDO_ENUM_ITEM(RAND_INF_MARKET_TREE) RANDO_ENUM_ITEM(RAND_INF_HC_NEAR_GUARDS_TREE_1) RANDO_ENUM_ITEM(RAND_INF_HC_NEAR_GUARDS_TREE_2) @@ -1484,6 +1769,212 @@ RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART) RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART) RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART) +// Overworld Wonder Items +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_TRAINING_1) +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_TRAINING_2) +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_TRAINING_3) +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_SHOP) +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_PLATFORMS_1) +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_PLATFORMS_2) +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_CRAWL_GRASS_1) +RANDO_ENUM_ITEM(RAND_INF_KF_WONDER_CRAWL_GRASS_2) +RANDO_ENUM_ITEM(RAND_INF_HF_WONDER_BRIDGE_1) +RANDO_ENUM_ITEM(RAND_INF_HF_WONDER_BRIDGE_2) +RANDO_ENUM_ITEM(RAND_INF_HF_WONDER_BRIDGE_3) +RANDO_ENUM_ITEM(RAND_INF_MKT_WONDER_DAY_1) +RANDO_ENUM_ITEM(RAND_INF_MKT_WONDER_DAY_2) +RANDO_ENUM_ITEM(RAND_INF_MKT_WONDER_DAY_3) +RANDO_ENUM_ITEM(RAND_INF_MKT_WONDER_DAY_4) +RANDO_ENUM_ITEM(RAND_INF_MKT_WONDER_DAY_5) +RANDO_ENUM_ITEM(RAND_INF_MKT_WONDER_NIGHT_1) +RANDO_ENUM_ITEM(RAND_INF_MKT_WONDER_NIGHT_2) +RANDO_ENUM_ITEM(RAND_INF_LLR_WONDER_BIG_FENCE) +RANDO_ENUM_ITEM(RAND_INF_LLR_WONDER_SMALL_FENCE) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_LEFT_TORCH) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_RIGHT_TORCH) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_1) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_2) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_3) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_4) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_5) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_6) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_7) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_8) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_9) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_MOAT_10) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_COURTYARD_RIGHT_WINDOW) +RANDO_ENUM_ITEM(RAND_INF_HC_WONDER_COURTYARD_LEFT_WINDOW) +RANDO_ENUM_ITEM(RAND_INF_LW_WONDER_BACK_SKULL_KIDS_GRASS_1) +RANDO_ENUM_ITEM(RAND_INF_LW_WONDER_BACK_SKULL_KIDS_GRASS_2) +RANDO_ENUM_ITEM(RAND_INF_LW_WONDER_FRONT_SKULL_KIDS_GRASS) +RANDO_ENUM_ITEM(RAND_INF_SFM_WONDER_ENTRANCE) +RANDO_ENUM_ITEM(RAND_INF_SFM_WONDER_MAZE_1) +RANDO_ENUM_ITEM(RAND_INF_SFM_WONDER_MAZE_2) +RANDO_ENUM_ITEM(RAND_INF_SFM_WONDER_MAZE_3) +RANDO_ENUM_ITEM(RAND_INF_SFM_WONDER_MAZE_4) +RANDO_ENUM_ITEM(RAND_INF_SFM_WONDER_MAZE_5) +RANDO_ENUM_ITEM(RAND_INF_KAK_WONDER_UNDER_CONSTRUCTION) +RANDO_ENUM_ITEM(RAND_INF_KAK_WONDER_ABOVE_COW) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_1) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_2) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_3) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_4) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_5) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_6) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_7) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_8) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_9) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_10) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_11) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_12) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_13) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_14) +RANDO_ENUM_ITEM(RAND_INF_GY_WONDER_DAMPE_RACE_15) +RANDO_ENUM_ITEM(RAND_INF_DMC_WONDER_BENEATH_BRIDGE_PLATFORM) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_NEAR_DOMAIN_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_NEAR_DOMAIN_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_NEAR_DOMAIN_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_NEAR_DOMAIN_4) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_BEFORE_LADDER_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_BEFORE_LADDER_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_BEFORE_LADDER_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_BEFORE_LADDER_4) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_BEFORE_LADDER_5) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_BEFORE_LADDER_6) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_AFTER_LADDER_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_AFTER_LADDER_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_AFTER_LADDER_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_FROG_BRIDGE_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_FROG_BRIDGE_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_FROG_BRIDGE_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_PILLARS_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_PILLARS_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_PILLARS_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_PILLARS_4) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_LOWER_LAND_BRIDGE_4) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_NEAR_CUCCO_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_NEAR_CUCCO_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_NEAR_CUCCO_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_LOWER_RIVER_1) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_LOWER_RIVER_2) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_LOWER_RIVER_3) +RANDO_ENUM_ITEM(RAND_INF_ZR_WONDER_LOWER_RIVER_4) +RANDO_ENUM_ITEM(RAND_INF_ZF_WONDER_ROCK) +RANDO_ENUM_ITEM(RAND_INF_GV_WONDER_LOWER_WATERFALL) +RANDO_ENUM_ITEM(RAND_INF_GV_WONDER_UPPER_WATERFALL) +RANDO_ENUM_ITEM(RAND_INF_GF_WONDER_ENTRANCE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GF_WONDER_ARCHERY_SIGN) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_1_TORCH_1) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_1_TORCH_2) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_STEEP_SLOPE_LOWER_EXIT) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_STEEP_SLOPE_UPPER_EXIT) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_DOUBLE_JAIL_LOWER_EXIT) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_DOUBLE_JAIL_UPPER_EXIT) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_KITCHEN_SKULL) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_KITCHEN_SOUP) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_DEAD_END_SKULL_ENTRANCE) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_DEAD_END_SKULL_NEAR_JAIL) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_BREAK_ROOM_BOTTOM_SKULL) +RANDO_ENUM_ITEM(RAND_INF_TH_WONDER_BREAK_ROOM_TOP_SKULL) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_WONDER_OASIS_TREE_1) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_WONDER_OASIS_TREE_2) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_WONDER_OASIS_CHILD_TREE) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_WONDER_GF_TREE_1) +RANDO_ENUM_ITEM(RAND_INF_COLOSSUS_WONDER_GF_TREE_2) +// Dungeon Wonder Items +RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_WONDER_THREE_POTS) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_WONDER_BEAMOS_ROOM) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_WONDER_EYE_STATUE_ROOM) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_WONDER_TORCH_SLUGS_ROOM) +// MQ Dungeon Wonder Items +RANDO_ENUM_ITEM(RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_1) +RANDO_ENUM_ITEM(RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_2) +RANDO_ENUM_ITEM(RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_3) +RANDO_ENUM_ITEM(RAND_INF_DEKU_TREE_MQ_WONDER_BASEMENT_GRAVE_4) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_LEFT_COW) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ENTRANCE_RIGHT_COW) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_ELEVATOR_COW) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_COW) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_2) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_RIGHT_COW_3) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_2) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BASEMENT_LEFT_COW_3) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_AFTER_BIG_OCTO) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_JIGGLIES_COW) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_2) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_RIGHT_3) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_2) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_COW_LEFT_3) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_2) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_FALLING_LIKE_LIKES_EXPLOSION_3) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_LEFT_COW) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_1) +RANDO_ENUM_ITEM(RAND_INF_JABU_JABUS_BELLY_MQ_WONDER_BEFORE_BOSS_RIGHT_COW_2) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_1) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_2) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_SHORTCUT_ROOM_3) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_BOW) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_LIZALFOS_MAZE) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_1) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_LARGE_FACE_2) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_1) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_EAST_TOWER_SMALL_FACE_2) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_TORCH_ROOM) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_FIRE_MAZE) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_AFTER_FLARE_DANCER) +RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_WONDER_STAIRCASE) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_1) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_2) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_RIGHT_3) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_1) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_2) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_HOOKSHOT_STAIRCASE_LEFT_3) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_AFTER_DARK_LINK) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_LEFT_EYE) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_RIGHT_EYE) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_DRAGON_ROOM_PORTRAIT) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_TRIPLE_TORCHES) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_1) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_WATER_SPROUTS_2) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_FREESTANDING_ROOM) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_1) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_BEFORE_BOSS_2) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_UNDER_PILLAR_ROOM) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_LIZALFOS_HALLWAY) +RANDO_ENUM_ITEM(RAND_INF_WATER_TEMPLE_MQ_WONDER_GS_STORAGE_ROOM) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_WONDER_CHEST_HAMMER) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_MQ_WONDER_CHEST_SLASH) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_MQ_WONDER_THREE_POTS) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_1) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_2) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_3) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_LEFT_4) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_1) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_2) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_3) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_MAIN_ROOM_RIGHT_4) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_1) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_2) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_3) +RANDO_ENUM_ITEM(RAND_INF_BOTTOM_OF_THE_WELL_MQ_WONDER_SIDE_ROOM_4) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL) +// End Wonder Items + RANDO_ENUM_ITEM(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1) RANDO_ENUM_ITEM(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2) RANDO_ENUM_ITEM(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3) @@ -1680,6 +2171,27 @@ RANDO_ENUM_ITEM(RAND_INF_LW_SHORTCUT_STORMS_FAIRY) RANDO_ENUM_ITEM(RAND_INF_TH_KITCHEN_SUN_FAIRY) RANDO_ENUM_ITEM(RAND_INF_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY) RANDO_ENUM_ITEM(RAND_INF_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY) + +RANDO_ENUM_ITEM(RAND_INF_HC_NEAR_WALL_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_HC_NEAR_STAIRS_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_HC_NEAR_BOULDER_PATH_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_HC_NEAR_ARCHWAY_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_LW_MEADOW_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_GY_NEAR_HUT_GRAVE_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_ZR_NEAR_ROCK_CIRCLE_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_ZR_WATERFALL_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_ZF_LOG_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_LH_SCARECROW_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_KF_STORMS_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_LW_TUNNEL_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_DMT_STORMS_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_DMC_UPPER_BOULDER_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_HF_NEAR_MARKET_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_HF_SOUTHEAST_BOULDER_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_HF_OPEN_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_KAK_OPEN_GROTTO_BUTTERFLY_FAIRY) +RANDO_ENUM_ITEM(RAND_INF_ZR_OPEN_GROTTO_BUTTERFLY_FAIRY) + RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY) RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY) RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY) @@ -2129,6 +2641,297 @@ RANDO_ENUM_ITEM(RAND_INF_OBTAINED_NAYRUS_LOVE) RANDO_ENUM_ITEM(RAND_INF_OBTAINED_ROCS_FEATHER) RANDO_ENUM_ITEM(RAND_INF_TALON_SENT_MALON_HOME) +// Overworld Signs +RANDO_ENUM_ITEM(RAND_INF_KF_DEKU_TREE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_STEPPING_STONES_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_LINKS_HOUSE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_FIRST_TRAINING_CENTER_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_SECOND_TRAINING_CENTER_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_AFTER_CRAWLSPACE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_CRAWL_RECTANGLE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_LOST_WOODS_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_HOUSE_OF_TWINS_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_SHOP_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_SARIAS_HOUSE_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_LOST_WOODS_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_MIDOS_HOUSE_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_TRAINING_CENTER_ENTRANCE_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_INNER_TRAINING_CENTER_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_KNOW_IT_ALL_BROTHERS_HOUSE_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_BOULDER_MAZE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KF_LINKS_HOUSE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_LW_THEATER_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HF_CASTLE_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HF_WOODED_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HF_ROCKY_PATH_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HF_FENCED_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HF_CENTER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HF_RIVER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HF_STAIRS_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_MK_SHOOTING_GALLERY_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_MK_MASK_SHOP_SIGN) +RANDO_ENUM_ITEM(RAND_INF_TOT_ALTAR) +RANDO_ENUM_ITEM(RAND_INF_HC_DEAD_END_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KAK_GUARD_GATE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KAK_WELL_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KAK_SOUTHEAST_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KAK_FRONT_GATE_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_KAK_SHOOTING_GALLERY_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GY_ENTRANCE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GY_ENTRANCE_PLINTH) +RANDO_ENUM_ITEM(RAND_INF_GY_RIGHT_OF_ROYAL_TOMB_GRAVE) +RANDO_ENUM_ITEM(RAND_INF_GY_LEFT_OF_ROYAL_TOMB_GRAVE) +RANDO_ENUM_ITEM(RAND_INF_GY_ROYAL_TOMB_GRAVE) +RANDO_ENUM_ITEM(RAND_INF_DMT_ABOVE_DODONGO_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMT_ADULT_CENTER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMT_CHILD_CENTER_EXIT_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMT_DODONGOS_CAVERN_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMT_CENTER_TRAIL_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMT_TO_UPPER_TRAIL_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMT_UPPER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMT_TO_CENTER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMT_LOWER_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GC_CHILD_ROLLING_GORON_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_DMC_BRIDGE_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_ZR_SLEEPLESS_WATERFALL_PLAQUE) +RANDO_ENUM_ITEM(RAND_INF_ZD_SHOP_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_ZD_ENTRANCE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_ZD_KING_ZORA_PATH_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_ZD_NEAR_KING_ZORA_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_ZD_NEAR_KING_ZORA_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_ZF_JABU_JABU_PLATFORM_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_ZF_ENTRANCE_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_LH_LAB_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_LH_NORTH_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_LH_FISHING_SIGN) +RANDO_ENUM_ITEM(RAND_INF_LH_ISLAND_PEDESTAL) +RANDO_ENUM_ITEM(RAND_INF_LH_FISHING_POND_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GV_BRIDGE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GV_EAST_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GF_EAST_EXIT_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GF_HBA_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GF_GATE_EXIT_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_GF_GTG_ENTRANCE_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HW_CARPET_SALESMAN_ARROW_SIGN) +RANDO_ENUM_ITEM(RAND_INF_HW_POE_ALTAR) +// Dungeon Signs +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_TOP_FLOOR_PEDESTAL) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE) +// MQ Dungeon Signs +RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN) +// Beggar +RANDO_ENUM_ITEM(RAND_INF_MK_BEGGAR_BUGS) +RANDO_ENUM_ITEM(RAND_INF_MK_BEGGAR_FISH) +RANDO_ENUM_ITEM(RAND_INF_MK_BEGGAR_BLUE_FIRE) +RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_BUGS) +RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_FISH) +RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_BLUE_FIRE) + +// Vanilla Icicles +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_ENTRANCE_MIDDLE_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_ENTRANCE_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_ENTRANCE_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_ENTRANCE_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_LOBBY_STALACTITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_LOBBY_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_LOBBY_MIDDLE_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_LOBBY_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_AFTER_LOBBY_STALACTITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_AFTER_LOBBY_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_AFTER_LOBBY_CENTER_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_AFTER_LOBBY_CENTER_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_AFTER_LOBBY_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SPINNING_BLADE_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SPINNING_BLADE_MIDDLE_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_HALLWAY_STALACTITE_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_HALLWAY_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_HALLWAY_MIDDLE_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_HALLWAY_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALAGMITE_6) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_LEFT_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_RIGHT_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_LEFT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_CENTER_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_RIGHT_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALACTITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_6) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_7) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_STALAGMITE_8) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_5) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_6) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_7) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_8) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_9) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALAGMITE_10) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_RIGHT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_5) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_6) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_7) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_8) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_9) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_10) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_STALACTITE_11) +// MQ Icicles +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_ENTRANCE_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_LOBBY_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_LOBBY_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_AFTER_LOBBY_STALAGMITE_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_STALAGMITE_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_6) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_7) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_COMPASS_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_COMPASS_RIGHT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_BEFORE_SCARECROW_STALAGMITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_SCARECROW_ROOM_STALACTITE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_WEST_CORRIDOR_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_5) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_RIGHT_STALACTITE_4) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_LEFT_STALACTITE) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALACTITE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_LEFT_STALAGMITE_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_RIGHT_STALAGMITE_4) +// Red Ice +RANDO_ENUM_ITEM(RAND_INF_ZD_KING_ZORA_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ZD_ZORA_SHOP_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_ENTRANCE_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_LOBBY_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_LOBBY_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_FREESTANDING_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_HEART_PIECE_ROOM_CHEST_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_ROOM_POT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MAP_ROOM_CHEST_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_RUPEE_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_MIDDLE_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_NEAR_END_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_DOOR_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_WATER_TRIAL_RUSTED_SWITCH_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_WEST_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_WEST_MIDDLE_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_WEST_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_MIDDLE_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_HUB_LEDGE_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_COMPASS_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_MAP_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_SCARECROW_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_SCARECROW_MIDDLE_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_MQ_SCARECROW_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_RIGHT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_BACK_LEFT_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_FIRST_ROOM_DOOR_RED_ICE_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SILVER_RUPEE_RED_ICE) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5) + +// Set when a non-shop shield/tunic is found, gating the matching shop copy behind it +// (RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL). +RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_DEKU_SHIELD) +RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_HYLIAN_SHIELD) +RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_GORON_TUNIC) +RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_ZORA_TUNIC) + RANDO_ENUM_ITEM(RAND_INF_MAX) RANDO_ENUM_END(RandomizerInf) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h index 78b032c38c..6eb2bb4e08 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h @@ -116,9 +116,12 @@ RANDO_ENUM_ITEM(RCTYPE_POT) // Pots RANDO_ENUM_ITEM(RCTYPE_CRATE) // Crates RANDO_ENUM_ITEM(RCTYPE_NLCRATE) // NL Crates RANDO_ENUM_ITEM(RCTYPE_SMALL_CRATE) // Small crates +RANDO_ENUM_ITEM(RCTYPE_ROCK) // Rocks +RANDO_ENUM_ITEM(RCTYPE_BOULDER) // Boulders RANDO_ENUM_ITEM(RCTYPE_TREE) // Trees RANDO_ENUM_ITEM(RCTYPE_NLTREE) // NL Trees RANDO_ENUM_ITEM(RCTYPE_BUSH) // Bushes +RANDO_ENUM_ITEM(RCTYPE_WONDER_ITEM) // Wonder Items RANDO_ENUM_ITEM(RCTYPE_DUNGEON_REWARD) // Dungeon rewards (blue warps) RANDO_ENUM_ITEM(RCTYPE_OCARINA) // Ocarina locations RANDO_ENUM_ITEM(RCTYPE_BEEHIVE) // Beehives @@ -128,7 +131,12 @@ RANDO_ENUM_ITEM(RCTYPE_FOUNTAIN_FAIRY) // Fairies in Fountains RANDO_ENUM_ITEM(RCTYPE_STONE_FAIRY) // Fairies from Gossip Stones RANDO_ENUM_ITEM(RCTYPE_BEAN_FAIRY) // Fairies from Beans RANDO_ENUM_ITEM(RCTYPE_SONG_FAIRY) // Fairies from Songs +RANDO_ENUM_ITEM(RCTYPE_BUTTERFLY_FAIRY) // Fairies from Butterflies RANDO_ENUM_ITEM(RCTYPE_GRASS) // Grass +RANDO_ENUM_ITEM(RCTYPE_SIGN) // Signs +RANDO_ENUM_ITEM(RCTYPE_BEGGAR) // Beggar +RANDO_ENUM_ITEM(RCTYPE_ICICLE) // Icicles +RANDO_ENUM_ITEM(RCTYPE_RED_ICE) // Red Ice RANDO_ENUM_END(RandomizerCheckType) RANDO_ENUM_BEGIN(RandomizerCheckQuest) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h index ac0c4dded7..e19e34a599 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h @@ -189,6 +189,7 @@ RANDO_ENUM_END(RandoOptionDungeonItemLocation) RANDO_ENUM_BEGIN(RandoOptionDungeonRewards) RANDO_ENUM_ITEM(RO_DUNGEON_REWARDS_VANILLA) RANDO_ENUM_ITEM(RO_DUNGEON_REWARDS_END_OF_DUNGEON) +RANDO_ENUM_ITEM(RO_DUNGEON_REWARDS_OWN_DUNGEON) RANDO_ENUM_ITEM(RO_DUNGEON_REWARDS_ANY_DUNGEON) RANDO_ENUM_ITEM(RO_DUNGEON_REWARDS_OVERWORLD) RANDO_ENUM_ITEM(RO_DUNGEON_REWARDS_ANYWHERE) @@ -365,6 +366,14 @@ RANDO_ENUM_ITEM(RO_SHUFFLE_FREESTANDING_OVERWORLD) RANDO_ENUM_ITEM(RO_SHUFFLE_FREESTANDING_ALL) RANDO_ENUM_END(RandoOptionFreestanding) +// Wonder Items settings (off, dungeons, overworld, all) +RANDO_ENUM_BEGIN(RandoOptionWonderItems) +RANDO_ENUM_ITEM(RO_SHUFFLE_WONDER_ITEMS_OFF) +RANDO_ENUM_ITEM(RO_SHUFFLE_WONDER_ITEMS_DUNGEONS) +RANDO_ENUM_ITEM(RO_SHUFFLE_WONDER_ITEMS_OVERWORLD) +RANDO_ENUM_ITEM(RO_SHUFFLE_WONDER_ITEMS_ALL) +RANDO_ENUM_END(RandoOptionWonderItems) + // Shuffle Pots settings (off, dungeons, overworld, all) RANDO_ENUM_BEGIN(RandoOptionShufflePots) RANDO_ENUM_ITEM(RO_SHUFFLE_POTS_OFF) @@ -389,6 +398,22 @@ RANDO_ENUM_ITEM(RO_SHUFFLE_CRATES_OVERWORLD) RANDO_ENUM_ITEM(RO_SHUFFLE_CRATES_ALL) RANDO_ENUM_END(RandoOptionShuffleCrates) +// Shuffle Boulder settings (off, dungeons, overworld, all) +RANDO_ENUM_BEGIN(RandoOptionShuffleBoulders) +RANDO_ENUM_ITEM(RO_SHUFFLE_BOULDERS_OFF) +RANDO_ENUM_ITEM(RO_SHUFFLE_BOULDERS_DUNGEONS) +RANDO_ENUM_ITEM(RO_SHUFFLE_BOULDERS_OVERWORLD) +RANDO_ENUM_ITEM(RO_SHUFFLE_BOULDERS_ALL) +RANDO_ENUM_END(RandoOptionShuffleBoulders) + +// Shuffle Signs settings (off, dungeons, overworld, all) +RANDO_ENUM_BEGIN(RandoOptionShuffleSigns) +RANDO_ENUM_ITEM(RO_SHUFFLE_SIGNS_OFF) +RANDO_ENUM_ITEM(RO_SHUFFLE_SIGNS_DUNGEONS) +RANDO_ENUM_ITEM(RO_SHUFFLE_SIGNS_OVERWORLD) +RANDO_ENUM_ITEM(RO_SHUFFLE_SIGNS_ALL) +RANDO_ENUM_END(RandoOptionShuffleSigns) + // Link's Pocket Settings (dungeon reward, advancement, anything, nothing) RANDO_ENUM_BEGIN(RandoOptionLinksPocket) RANDO_ENUM_ITEM(RO_LINKS_POCKET_DUNGEON_REWARD) @@ -399,9 +424,10 @@ RANDO_ENUM_END(RandoOptionLinksPocket) // Link's Pocket Dungeon Reward Settings (dungeon reward, stone, medallion) RANDO_ENUM_BEGIN(RandoOptionLinksPocketReward) -RANDO_ENUM_ITEM(RO_LINKS_POCKET_REWARD) -RANDO_ENUM_ITEM(RO_LINKS_POCKET_STONE) -RANDO_ENUM_ITEM(RO_LINKS_POCKET_MEDALLION) +RANDO_ENUM_ITEM(RO_LINKS_POCKET_ANY_REWARD) +RANDO_ENUM_ITEM(RO_LINKS_POCKET_ANY_STONE) +RANDO_ENUM_ITEM(RO_LINKS_POCKET_ANY_MEDALLION) +RANDO_ENUM_ITEM(RO_LINKS_POCKET_LIGHT_MEDALLION) RANDO_ENUM_END(RandoOptionLinksPocketReward) // Logic (glitchless/no logic) @@ -436,6 +462,13 @@ RANDO_ENUM_ITEM(RO_TRIFORCE_HUNT_WIN) RANDO_ENUM_ITEM(RO_TRIFORCE_HUNT_GBK) RANDO_ENUM_END(RandoOptionTriforceHunt) +// Trifoce Hunt location +RANDO_ENUM_BEGIN(RandoOptionTriforceHuntLocation) +RANDO_ENUM_ITEM(RO_TRIFORCE_HUNT_LOCATION_ANY_DUNGEON) +RANDO_ENUM_ITEM(RO_TRIFORCE_HUNT_LOCATION_OVERWORLD) +RANDO_ENUM_ITEM(RO_TRIFORCE_HUNT_LOCATION_ANYWHERE) +RANDO_ENUM_END(RandoOptionTriforceHuntLocation) + RANDO_ENUM_BEGIN(RandoOptionLocationInclusion) RANDO_ENUM_ITEM(RO_LOCATION_INCLUDE) RANDO_ENUM_ITEM(RO_LOCATION_EXCLUDE) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerRegion.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerRegion.h index 6a60f3512a..b2ad74ca67 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerRegion.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerRegion.h @@ -114,7 +114,8 @@ RANDO_ENUM_ITEM(RR_TH_KITCHEN_MAIN) RANDO_ENUM_ITEM(RR_TH_KITCHEN_BY_CORRIDOR) RANDO_ENUM_ITEM(RR_TH_KITCHEN_OPPOSITE_CORRIDOR) RANDO_ENUM_ITEM(RR_TH_BREAK_ROOM) -RANDO_ENUM_ITEM(RR_TH_BREAK_ROOM_CORRIDOR) +RANDO_ENUM_ITEM(RR_TH_BREAK_ROOM_LOWER_CORRIDOR) +RANDO_ENUM_ITEM(RR_TH_BREAK_ROOM_UPPER_CORRIDOR) RANDO_ENUM_ITEM(RR_WASTELAND_NEAR_FORTRESS) RANDO_ENUM_ITEM(RR_HAUNTED_WASTELAND) RANDO_ENUM_ITEM(RR_WASTELAND_NEAR_COLOSSUS) @@ -710,7 +711,8 @@ RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_SCARECROW_CANAL) RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_CANAL_ALCOVE) RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_BEHIND_CANAL) RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_FREESTANDING_ROOM) -RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_3_JETS_ROOM) +RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_3_JETS_ROOM_SWITCH_SIDE) +RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_3_JETS_ROOM_NO_SWITCH_SIDE) RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_DODONGO_ROOM) RANDO_ENUM_ITEM(RR_WATER_TEMPLE_MQ_CRATE_VORTEX_CAGE) @@ -943,6 +945,7 @@ RANDO_ENUM_ITEM(RR_ICE_CAVERN_MAP_ROOM) RANDO_ENUM_ITEM(RR_ICE_CAVERN_COMPASS_ROOM) RANDO_ENUM_ITEM(RR_ICE_CAVERN_BLOCK_ROOM) RANDO_ENUM_ITEM(RR_ICE_CAVERN_BLOCK_ROOM_BLUE_FIRE) +RANDO_ENUM_ITEM(RR_ICE_CAVERN_AFTER_BLOCK_ROOM) RANDO_ENUM_ITEM(RR_ICE_CAVERN_BEFORE_FINAL_ROOM) RANDO_ENUM_ITEM(RR_ICE_CAVERN_FINAL_ROOM) RANDO_ENUM_ITEM(RR_ICE_CAVERN_FINAL_ROOM_UNDERWATER) @@ -985,6 +988,7 @@ RANDO_ENUM_ITEM(RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM) RANDO_ENUM_ITEM(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM) RANDO_ENUM_ITEM(RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK) RANDO_ENUM_ITEM(RR_GERUDO_TRAINING_GROUND_MQ_ROOM_BEHIND_BLOCK) +RANDO_ENUM_ITEM(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_ALCOVE) RANDO_ENUM_ITEM(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE) RANDO_ENUM_ITEM(RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM) RANDO_ENUM_ITEM(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM) @@ -1014,6 +1018,7 @@ RANDO_ENUM_ITEM(RR_GANONS_CASTLE_FIRE_TRIAL_FINAL_ROOM) RANDO_ENUM_ITEM(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM) RANDO_ENUM_ITEM(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM_END) RANDO_ENUM_ITEM(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM) +RANDO_ENUM_ITEM(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_SWITCH) RANDO_ENUM_ITEM(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_END) RANDO_ENUM_ITEM(RR_GANONS_CASTLE_WATER_TRIAL_FINAL_ROOM) RANDO_ENUM_ITEM(RR_GANONS_CASTLE_SHADOW_TRIAL_START) @@ -1074,6 +1079,7 @@ RANDO_ENUM_ITEM(RR_GANONS_TOWER_FLOOR_2) RANDO_ENUM_ITEM(RR_GANONS_TOWER_STAIRS_3) RANDO_ENUM_ITEM(RR_GANONS_TOWER_FLOOR_3) RANDO_ENUM_ITEM(RR_GANONS_TOWER_STAIRS_4) +RANDO_ENUM_ITEM(RR_GANONS_TOWER_POT_ROOM) RANDO_ENUM_ITEM(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR) RANDO_ENUM_ITEM(RR_GANONS_TOWER_GANONDORF_LAIR) RANDO_ENUM_ITEM(RR_GANONS_CASTLE_ESCAPE) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h index 40ebb218de..3095055b55 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h @@ -76,6 +76,7 @@ RANDO_ENUM_ITEM(RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_SHOPSANITY_PRICES_AFFORDABLE) +RANDO_ENUM_ITEM(RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL) RANDO_ENUM_ITEM(RSK_SHUFFLE_SCRUBS) RANDO_ENUM_ITEM(RSK_SCRUBS_PRICES) RANDO_ENUM_ITEM(RSK_SCRUBS_PRICES_FIXED_PRICE) @@ -93,6 +94,8 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_WEIRD_EGG) RANDO_ENUM_ITEM(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) RANDO_ENUM_ITEM(RSK_SHUFFLE_POTS) RANDO_ENUM_ITEM(RSK_SHUFFLE_CRATES) +RANDO_ENUM_ITEM(RSK_SHUFFLE_ROCKS) +RANDO_ENUM_ITEM(RSK_SHUFFLE_BOULDERS) RANDO_ENUM_ITEM(RSK_SHUFFLE_TREES) RANDO_ENUM_ITEM(RSK_SHUFFLE_BUSHES) RANDO_ENUM_ITEM(RSK_SHUFFLE_FROG_SONG_RUPEES) @@ -160,6 +163,7 @@ RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_AFFORDABLE) +RANDO_ENUM_ITEM(RSK_SHUFFLE_BEGGAR) RANDO_ENUM_ITEM(RSK_BLUE_FIRE_ARROWS) RANDO_ENUM_ITEM(RSK_SUNLIGHT_ARROWS) RANDO_ENUM_ITEM(RSK_SLINGBOW_BREAK_BEEHIVES) @@ -226,6 +230,7 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_100_GS_REWARD) RANDO_ENUM_ITEM(RSK_TRIFORCE_HUNT) RANDO_ENUM_ITEM(RSK_TRIFORCE_HUNT_PIECES_TOTAL) RANDO_ENUM_ITEM(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) +RANDO_ENUM_ITEM(RSK_TRIFORCE_HUNT_PIECES_LOCATION) RANDO_ENUM_ITEM(RSK_SHUFFLE_BEAN_SOULS) RANDO_ENUM_ITEM(RSK_SHUFFLE_BOSS_SOULS) RANDO_ENUM_ITEM(RSK_FISHSANITY) @@ -237,13 +242,18 @@ RANDO_ENUM_ITEM(RSK_SKELETON_KEY) RANDO_ENUM_ITEM(RSK_SHUFFLE_DEKU_STICK_BAG) RANDO_ENUM_ITEM(RSK_SHUFFLE_DEKU_NUT_BAG) RANDO_ENUM_ITEM(RSK_SHUFFLE_FREESTANDING) +RANDO_ENUM_ITEM(RSK_SHUFFLE_WONDER_ITEMS) RANDO_ENUM_ITEM(RSK_SHUFFLE_FOUNTAIN_FAIRIES) RANDO_ENUM_ITEM(RSK_SHUFFLE_STONE_FAIRIES) RANDO_ENUM_ITEM(RSK_SHUFFLE_BEAN_FAIRIES) RANDO_ENUM_ITEM(RSK_SHUFFLE_SONG_FAIRIES) +RANDO_ENUM_ITEM(RSK_SHUFFLE_BUTTERFLY_FAIRIES) RANDO_ENUM_ITEM(RSK_LOCK_OVERWORLD_DOORS) RANDO_ENUM_ITEM(RSK_SHUFFLE_GRASS) +RANDO_ENUM_ITEM(RSK_SHUFFLE_SIGNS) RANDO_ENUM_ITEM(RSK_ROCS_FEATHER) +RANDO_ENUM_ITEM(RSK_SHUFFLE_ICICLES) +RANDO_ENUM_ITEM(RSK_SHUFFLE_RED_ICE) RANDO_ENUM_ITEM(RSK_MAX) RANDO_ENUM_END(RandomizerSettingKey) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerTrick.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerTrick.h index 42ecc2bb92..a6e829989d 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerTrick.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerTrick.h @@ -29,9 +29,11 @@ RANDO_ENUM_ITEM(RT_BOMBCHU_BEEHIVES) RANDO_ENUM_ITEM(RT_HOOKSHOT_LADDERS) RANDO_ENUM_ITEM(RT_BLUE_FIRE_MUD_WALLS) RANDO_ENUM_ITEM(RT_OPEN_UNDERWATER_CHEST) -RANDO_ENUM_ITEM(RT_DISTANT_BOULDER_COLLISION) +RANDO_ENUM_ITEM(RT_BOULDER_COLLISION) RANDO_ENUM_ITEM(RT_ITEM_EXTENSION) RANDO_ENUM_ITEM(RT_SLIDE_JUMP) +RANDO_ENUM_ITEM(RT_VOIDOUT_COLLECTION) +RANDO_ENUM_ITEM(RT_BOMB_DETONATION) RANDO_ENUM_ITEM(RT_KF_ADULT_GS) // -- location tricks RANDO_ENUM_ITEM(RT_LW_BRIDGE) RANDO_ENUM_ITEM(RT_LW_MIDO_BACKFLIP) @@ -201,6 +203,7 @@ RANDO_ENUM_ITEM(RT_LENS_GTG) RANDO_ENUM_ITEM(RT_GTG_WITHOUT_HOOKSHOT) RANDO_ENUM_ITEM(RT_GTG_FAKE_WALL) RANDO_ENUM_ITEM(RT_GTG_LAVA_JUMP) +RANDO_ENUM_ITEM(RT_GTG_STATUE_JUMP) RANDO_ENUM_ITEM(RT_LENS_GTG_MQ) RANDO_ENUM_ITEM(RT_GTG_MQ_WITH_HOOKSHOT) RANDO_ENUM_ITEM(RT_GTG_MQ_WITHOUT_HOOKSHOT) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 35aad1f383..fb9ba56b91 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -140,6 +140,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { (location.GetRCType() != RCTYPE_MERCHANT || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF) != RO_SHUFFLE_MERCHANTS_OFF) && + (location.GetRCType() != RCTYPE_BEGGAR || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeggar"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_SONG_LOCATION || (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_SONG_LOCATIONS) != RO_SONG_SHUFFLE_SONG_LOCATIONS && @@ -197,6 +199,14 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTrees"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_NLTREE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTrees"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_SIGN || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSigns"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_WONDER_ITEM || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWonderItems"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_ICICLE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleIcicles"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_RED_ICE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleRedIce"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_FISH || ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) && (location.GetRCType() != RCTYPE_ADULT_TRADE || @@ -219,6 +229,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeanFairies"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_SONG_FAIRY || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFairySpots"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_BUTTERFLY_FAIRY || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleButterflyFairies"), RO_GENERIC_NO)) && ((location.GetRCType() != RCTYPE_MAP && location.GetRCType() != RCTYPE_COMPASS) || CVarGetInteger(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != RO_DUNGEON_ITEM_LOC_VANILLA) && @@ -230,7 +242,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { RO_DUNGEON_ITEM_LOC_VANILLA) && (location.GetRCType() != RCTYPE_GANON_BOSS_KEY || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) != - RO_GANON_BOSS_KEY_VANILLA) && // vanilla ganon boss key + RO_GANON_BOSS_KEY_VANILLA || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), 0)) && (location.GetRandomizerCheck() != RC_TOT_LIGHT_ARROWS_CUTSCENE || (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) != RO_GANON_BOSS_KEY_LACS_DUNGEONS && diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 3a835bd9f7..039337a551 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -14,6 +14,9 @@ #include "location_access.h" #include "3drando/fill.hpp" #include "soh/Enhancements/debugger/performanceTimer.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/ObjectExtension/ObjectExtension.h" +#include "overlays/actors/ovl_En_GirlA/z_en_girla.h" #include #include @@ -25,7 +28,6 @@ #include "item_location.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "z64item.h" -#include "fishsanity.h" extern "C" { #include "variables.h" @@ -77,13 +79,24 @@ bool showOverworldGrass; bool showDungeonGrass; bool showOverworldCrates; bool showDungeonCrates; +bool showRocks; +bool showOverworldBoulders; +bool showDungeonBoulders; bool showTrees; bool showBushes; +bool showOverworldSigns; +bool showDungeonSigns; +bool showOverworldWonderItems; +bool showDungeonWonderItems; +bool showBeggar; +bool showIcicles; +bool showRedIce; bool showFrogSongRupees; bool showFountainFairies; bool showStoneFairies; bool showBeanFairies; bool showSongFairies; +bool showButterflyFairies; bool showStartingMapsCompasses; bool showKeysanity; bool showGerudoFortressKeys; @@ -467,14 +480,9 @@ RandomizerCheckArea GetCheckArea() { return area; } -bool vector_contains_scene(std::vector vec, const int16_t scene) { - return std::any_of(vec.begin(), vec.end(), [&](const auto& x) { return x == scene; }); -} - -std::vector skipScenes = { +std::array skipScenes = { SCENE_GANON_BOSS, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, - SCENE_GANON_BOSS, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, }; @@ -651,7 +659,8 @@ void CheckTrackerTransition(uint32_t sceneNum) { } void CheckTrackerItemReceive(GetItemEntry giEntry) { - if (!GameInteractor::IsSaveLoaded() || vector_contains_scene(skipScenes, gPlayState->sceneNum)) { + if (!GameInteractor::IsSaveLoaded() || std::find(std::begin(skipScenes), std::end(skipScenes), + (SceneID)gPlayState->sceneNum) != std::end(skipScenes)) { return; } auto scene = static_cast(gPlayState->sceneNum); @@ -858,6 +867,32 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { } } +void CheckTrackerDialogMessage() { + auto identifyCheck = [](RandomizerCheck rc) { + auto loc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); + if (loc->GetCheckStatus() == RCSHOW_UNCHECKED) { + loc->SetCheckStatus(RCSHOW_IDENTIFIED); + RecalculateAvailableChecks(); + } + }; + + if (gPlayState->msgCtx.textId == TEXT_BEAN_SALESMAN_BUY_FOR_10) { + identifyCheck(RC_ZR_MAGIC_BEAN_SALESMAN); + } else if (gPlayState->msgCtx.textId == TEXT_MEDIGORON) { + identifyCheck(RC_GC_MEDIGORON); + } else if (gPlayState->msgCtx.textId == TEXT_GRANNYS_SHOP) { + identifyCheck(RC_KAK_GRANNYS_SHOP); + } else if (gPlayState->msgCtx.textId == TEXT_CARPET_SALESMAN_1) { + identifyCheck(RC_WASTELAND_BOMBCHU_SALESMAN); + } else if (gPlayState->msgCtx.textId == TEXT_SCRUB_RANDOM) { + if (auto* actor = gPlayState->msgCtx.talkActor) { + if (auto* checkIdentity = ObjectExtension::GetInstance().Get(actor)) { + identifyCheck(checkIdentity->identity.randomizerCheck); + } + } + } +} + void InitTrackerData(bool isDebug) { TrySetAreas(); areasSpoiled = 0; @@ -995,7 +1030,8 @@ void CheckTrackerWindow::DrawElement() { int comboButton1Mask = buttons[CVarGetInteger(CVAR_TRACKER_CHECK("ComboButton1"), TRACKER_COMBO_BUTTON_L)]; int comboButton2Mask = buttons[CVarGetInteger(CVAR_TRACKER_CHECK("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; OSContPad* trackerButtonsPressed = - std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetControlDeck()) + ->GetPads(); bool comboButtonsHeld = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & comboButton1Mask && trackerButtonsPressed[0].button & comboButton2Mask; @@ -1361,6 +1397,10 @@ void LoadSettings() { showSongFairies = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SONG_FAIRIES) == RO_GENERIC_YES : false; + showButterflyFairies = + IS_RANDO + ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BUTTERFLY_FAIRIES) == RO_GENERIC_YES + : false; showStartingMapsCompasses = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue( RSK_SHUFFLE_MAPANDCOMPASS) != RO_DUNGEON_ITEM_LOC_VANILLA : false; @@ -1463,8 +1503,70 @@ void LoadSettings() { showDungeonCrates = false; break; } + + showRocks = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ROCKS); + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOULDERS)) { + case RO_SHUFFLE_BOULDERS_ALL: + showOverworldBoulders = true; + showDungeonBoulders = true; + break; + case RO_SHUFFLE_BOULDERS_OVERWORLD: + showOverworldBoulders = true; + showDungeonBoulders = false; + break; + case RO_SHUFFLE_BOULDERS_DUNGEONS: + showOverworldBoulders = false; + showDungeonBoulders = true; + break; + default: + showOverworldBoulders = false; + showDungeonBoulders = false; + break; + } + + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SIGNS)) { + case RO_SHUFFLE_SIGNS_ALL: + showOverworldSigns = true; + showDungeonSigns = true; + break; + case RO_SHUFFLE_SIGNS_OVERWORLD: + showOverworldSigns = true; + showDungeonSigns = false; + break; + case RO_SHUFFLE_SIGNS_DUNGEONS: + showOverworldSigns = false; + showDungeonSigns = true; + break; + default: + showOverworldSigns = false; + showDungeonSigns = false; + break; + } + showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); showBushes = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BUSHES); + + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WONDER_ITEMS)) { + case RO_SHUFFLE_WONDER_ITEMS_ALL: + showOverworldWonderItems = true; + showDungeonWonderItems = true; + break; + case RO_SHUFFLE_WONDER_ITEMS_OVERWORLD: + showOverworldWonderItems = true; + showDungeonWonderItems = false; + break; + case RO_SHUFFLE_WONDER_ITEMS_DUNGEONS: + showOverworldWonderItems = false; + showDungeonWonderItems = true; + break; + default: + showOverworldWonderItems = false; + showDungeonWonderItems = false; + break; + } + showBeggar = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEGGAR); + showIcicles = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ICICLES); + showRedIce = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_RED_ICE); } else { // Vanilla showOverworldTokens = true; showDungeonTokens = true; @@ -1474,8 +1576,18 @@ void LoadSettings() { showDungeonGrass = false; showOverworldCrates = false; showDungeonCrates = false; + showRocks = false; + showOverworldBoulders = false; + showDungeonBoulders = false; showTrees = false; showBushes = false; + showOverworldWonderItems = false; + showDungeonWonderItems = false; + showOverworldSigns = false; + showDungeonSigns = false; + showBeggar = false; + showIcicles = false; + showRedIce = false; } fortressFast = false; @@ -1567,6 +1679,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) && ((loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) || (rc == RC_ZR_MAGIC_BEAN_SALESMAN && showBeans)) && + (loc->GetRCType() != RCTYPE_BEGGAR || showBeggar) && (loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) && (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && @@ -1589,11 +1702,23 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_SMALL_CRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_ROCK || showRocks) && + (loc->GetRCType() != RCTYPE_BOULDER || + (showOverworldBoulders && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonBoulders && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && (loc->GetRCType() != RCTYPE_TREE || showTrees) && (loc->GetRCType() != RCTYPE_NLTREE || (showTrees && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && (loc->GetRCType() != RCTYPE_BUSH || showBushes) && (loc->GetRCType() != RCTYPE_COW || showCows) && + (loc->GetRCType() != RCTYPE_SIGN || + (showOverworldSigns && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonSigns && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_WONDER_ITEM || + (showOverworldWonderItems && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonWonderItems && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_ICICLE || showIcicles) && + (loc->GetRCType() != RCTYPE_RED_ICE || showRedIce) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && (loc->GetRCType() != RCTYPE_FREESTANDING || @@ -1611,6 +1736,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_STONE_FAIRY || showStoneFairies) && (loc->GetRCType() != RCTYPE_BEAN_FAIRY || showBeanFairies) && (loc->GetRCType() != RCTYPE_SONG_FAIRY || showSongFairies) && + (loc->GetRCType() != RCTYPE_BUTTERFLY_FAIRY || showButterflyFairies) && (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && @@ -1732,6 +1858,42 @@ bool IsHeartPiece(GetItemID giid) { return giid == GI_HEART_PIECE || giid == GI_HEART_PIECE_WIN; } +bool IsMysteryShopItem(RandomizerCheck rc) { + s32 sceneNum = 0; + u8 slotIndex = 0; + + if (rc >= RC_KF_SHOP_ITEM_1 && rc <= RC_KF_SHOP_ITEM_8) { + sceneNum = SCENE_KOKIRI_SHOP; + slotIndex = rc - RC_KF_SHOP_ITEM_1; + } else if (rc >= RC_MARKET_BAZAAR_ITEM_1 && rc <= RC_MARKET_BAZAAR_ITEM_8) { + sceneNum = SCENE_BAZAAR; + slotIndex = rc - RC_MARKET_BAZAAR_ITEM_1; + } else if (rc >= RC_MARKET_POTION_SHOP_ITEM_1 && rc <= RC_MARKET_POTION_SHOP_ITEM_8) { + sceneNum = SCENE_POTION_SHOP_MARKET; + slotIndex = rc - RC_MARKET_POTION_SHOP_ITEM_1; + } else if (rc >= RC_MARKET_BOMBCHU_SHOP_ITEM_1 && rc <= RC_MARKET_BOMBCHU_SHOP_ITEM_8) { + sceneNum = SCENE_BOMBCHU_SHOP; + slotIndex = rc - RC_MARKET_BOMBCHU_SHOP_ITEM_1; + } else if (rc >= RC_KAK_BAZAAR_ITEM_1 && rc <= RC_KAK_BAZAAR_ITEM_8) { + sceneNum = SCENE_TEST01; + slotIndex = rc - RC_KAK_BAZAAR_ITEM_1; + } else if (rc >= RC_KAK_POTION_SHOP_ITEM_1 && rc <= RC_KAK_POTION_SHOP_ITEM_8) { + sceneNum = SCENE_POTION_SHOP_KAKARIKO; + slotIndex = rc - RC_KAK_POTION_SHOP_ITEM_1; + } else if (rc >= RC_GC_SHOP_ITEM_1 && rc <= RC_GC_SHOP_ITEM_8) { + sceneNum = SCENE_GORON_SHOP; + slotIndex = rc - RC_GC_SHOP_ITEM_1; + } else if (rc >= RC_ZD_SHOP_ITEM_1 && rc <= RC_ZD_SHOP_ITEM_8) { + sceneNum = SCENE_ZORA_SHOP; + slotIndex = rc - RC_ZD_SHOP_ITEM_1; + } else { + return false; + } + + ShopItemIdentity shopItemIdentity = OTRGlobals::Instance->gRandomizer->IdentifyShopItem(sceneNum, slotIndex + 1); + return shopItemIdentity.enGirlAShopItem == SI_RANDOMIZED_ITEM; +} + void DrawLocation(RandomizerCheck rc) { Color_RGBA8 mainColor; Color_RGBA8 extraColor; @@ -1889,7 +2051,17 @@ void DrawLocation(RandomizerCheck rc) { case RCSHOW_IDENTIFIED: case RCSHOW_SEEN: if (IS_RANDO) { - if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP && !mystery) { + const auto checkType = loc->GetRCType(); + const bool hideMerchantName = + checkType == RCTYPE_MERCHANT && + (!OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MERCHANT_TEXT_HINT) || mystery); + const bool hideScrubName = + checkType == RCTYPE_SCRUB && + (!OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SCRUB_TEXT_HINT) || mystery); + const bool hideShopName = checkType == RCTYPE_SHOP && mystery && IsMysteryShopItem(rc); + const bool revealItemName = !(hideMerchantName || hideScrubName || hideShopName); + + if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP && revealItemName) { if (status == RCSHOW_IDENTIFIED) { txt = OTRGlobals::Instance->gRandoContext->overrides[rc].GetTrickName().GetForLanguage( gSaveContext.language); @@ -1899,14 +2071,12 @@ void DrawLocation(RandomizerCheck rc) { .GetName() .GetForLanguage(gSaveContext.language); } - } else if (!mystery) { + } else if (revealItemName) { txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language); } - if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery) { + if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED) { auto price = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice(); - if (price) { - txt += fmt::format(" - {}", price); - } + txt = !txt.empty() ? fmt::format("{} - {}", txt, price) : fmt::format("{}", price); } } else { if (IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID())) { @@ -2264,6 +2434,7 @@ void CheckTrackerWindow::InitElement() { GameInteractor::Instance->RegisterGameHook(CheckTrackerShopSlotChange); GameInteractor::Instance->RegisterGameHook(CheckTrackerSceneFlagSet); GameInteractor::Instance->RegisterGameHook(CheckTrackerFlagSet); + GameInteractor::Instance->RegisterGameHook(CheckTrackerDialogMessage); } void CheckTrackerWindow::UpdateElement() { diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c index f1a70ab9ce..6daf6f4768 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c @@ -77,8 +77,8 @@ static DungeonEntranceInfo dungeons[] = { // clang-format on }; -static s8 hasCopiedEntranceTable = 0; -static s8 hasModifiedEntranceTable = 0; +static bool hasCopiedEntranceTable = false; +static bool hasModifiedEntranceTable = false; void Entrance_SetEntranceDiscovered(u16 entranceIndex, u8 isReversedEntrance); @@ -130,20 +130,19 @@ static void Entrance_ReplaceChildTempleWarps() { void Entrance_CopyOriginalEntranceTable(void) { if (!hasCopiedEntranceTable) { memcpy(originalEntranceTable, gEntranceTable, sizeof(EntranceInfo) * ENTRANCE_TABLE_SIZE); - hasCopiedEntranceTable = 1; + hasCopiedEntranceTable = true; } } void Entrance_ResetEntranceTable(void) { if (hasCopiedEntranceTable && hasModifiedEntranceTable) { memcpy(gEntranceTable, originalEntranceTable, sizeof(EntranceInfo) * ENTRANCE_TABLE_SIZE); - hasModifiedEntranceTable = 0; + hasModifiedEntranceTable = false; } } void Entrance_Init(void) { EntranceOverride* entranceOverrides = Randomizer_GetEntranceOverrides(); - s32 index; Entrance_CopyOriginalEntranceTable(); @@ -156,7 +155,7 @@ void Entrance_Init(void) { } // Delete the title card and add a fade in for Hyrule Field from Ocarina of Time cutscene - for (index = ENTR_HYRULE_FIELD_16; index <= ENTR_HYRULE_FIELD_16_3; ++index) { + for (s32 index = ENTR_HYRULE_FIELD_16; index <= ENTR_HYRULE_FIELD_16_3; ++index) { gEntranceTable[index].field = ENTRANCE_INFO_FIELD(false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_INSTANT); } @@ -199,7 +198,7 @@ void Entrance_Init(void) { bossScene = dungeons[j].bossScene; } - if (index == dungeons[j].bossDoor) { + if (originalIndex == dungeons[j].bossDoor) { saveWarpEntrance = dungeons[j].entryway; } } @@ -258,7 +257,7 @@ void Entrance_Init(void) { } } - hasModifiedEntranceTable = 1; + hasModifiedEntranceTable = true; } s16 Entrance_GetOverride(s16 index) { diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 95cb71c2e9..410c0a21da 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include @@ -840,7 +841,8 @@ void EntranceTrackerWindow::DrawElement() { int comboButton2Mask = buttons[CVarGetInteger(CVAR_TRACKER_ENTRANCE("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; OSContPad* trackerButtonsPressed = - std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetControlDeck()) + ->GetPads(); bool comboButtonsHeld = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & comboButton1Mask && trackerButtonsPressed[0].button & comboButton2Mask; diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h index 036630e90d..281b6f6d99 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include "randomizerTypes.h" diff --git a/soh/soh/Enhancements/randomizer/randomizer_grotto.c b/soh/soh/Enhancements/randomizer/randomizer_grotto.c index 5fe0875273..51576725d3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_grotto.c +++ b/soh/soh/Enhancements/randomizer/randomizer_grotto.c @@ -94,7 +94,7 @@ static s16 grottoExitList[NUM_GROTTOS] = { 0 }; static s16 grottoLoadList[NUM_GROTTOS] = { 0 }; static s8 grottoId = 0xFF; static s8 lastEntranceType = NOT_GROTTO; -static u8 overridingNextEntrance = false; +static bool overridingNextEntrance = false; // Initialize both lists so that each index refers to itself. An index referring // to itself means that the entrance is not shuffled. Indices will be overwritten diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 0ccc205a6d..ddd9435e95 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -18,6 +18,9 @@ #include "soh/SohGui/SohMenu.h" #include "soh/SohGui/UIWidgets.hpp" #include "soh/util.h" +#include "soh/Enhancements/randomizer/randomizer.h" + +#include extern "C" { #include @@ -805,8 +808,8 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { void DrawEquip(ItemTrackerItem item) { bool hasEquip = HasEquipment(item); float iconSize = static_cast(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36)); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasEquip && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasEquip && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0.0f, 0.0f), ImVec2(1, 1)); Tooltip(SohUtils::GetItemName(item.id).c_str()); @@ -816,9 +819,10 @@ void DrawQuest(ItemTrackerItem item) { bool hasQuestItem = HasQuestItem(item); float iconSize = static_cast(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36)); ImGui::BeginGroup(); - ImGui::ImageWithBg(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasQuestItem && IsValidSaveFile() ? item.name : item.nameFaded), - ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); + ImGui::ImageWithBg( + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasQuestItem && IsValidSaveFile() ? item.name : item.nameFaded), + ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); if (item.id == QUEST_SKULL_TOKEN) { DrawItemCount(item, false); @@ -1215,8 +1219,8 @@ void DrawItem(ItemTrackerItem item) { ImGui::BeginGroup(); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasItem && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); DrawItemCount(item, false); @@ -1301,8 +1305,8 @@ void DrawBottle(ItemTrackerItem item) { } float iconSize = static_cast(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36)); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasItem && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); Tooltip(SohUtils::GetItemName(item.id).c_str()); @@ -1317,12 +1321,12 @@ void DrawDungeonItem(ItemTrackerItem item) { bool hasSmallKey = GameInteractor::IsSaveLoaded() ? ((gSaveContext.inventory.dungeonKeys[item.data]) >= 0) : false; ImGui::BeginGroup(); if (itemId == ITEM_KEY_SMALL) { - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasSmallKey && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasSmallKey && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); } else { - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasItem && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); } @@ -1367,8 +1371,8 @@ void DrawSong(ItemTrackerItem item) { ImVec2 p = ImGui::GetCursorScreenPos(); bool hasSong = HasSong(item); ImGui::SetCursorScreenPos(ImVec2(p.x + 6, p.y)); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( - hasSong && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(hasSong && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize / 1.5f, iconSize), ImVec2(0, 0), ImVec2(1, 1)); Tooltip(SohUtils::GetQuestItemName(item.id).c_str()); } @@ -1828,7 +1832,7 @@ void ItemTrackerWindow::DrawElement() { int comboButton1Mask = buttonMap[CVarGetInteger(CVAR_TRACKER_ITEM("ComboButton1"), TRACKER_COMBO_BUTTON_L)]; int comboButton2Mask = buttonMap[CVarGetInteger(CVAR_TRACKER_ITEM("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; OSContPad* buttonsPressed = - std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetControlDeck())->GetPads(); bool comboButtonsHeld = buttonsPressed != nullptr && buttonsPressed[0].button & comboButton1Mask && buttonsPressed[0].button & comboButton2Mask; bool isPaused = CVarGetInteger(CVAR_TRACKER_ITEM("ShowOnlyPaused"), 0) == 0 || diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h index fab47c9531..0538e9f71a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include void DrawItemAmmo(int itemId); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 064eabff64..da024d5165 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -3,6 +3,7 @@ #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/randomizer/logic.h" +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include @@ -482,6 +483,7 @@ extern "C" void Randomizer_InitSaveFile() { gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x11); gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0C); // picked up key + Flags_SetRandomizerInf(RAND_INF_TH_ITEM_FROM_LEADER_OF_FORTRESS); if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { Item_Give(NULL, ITEM_GERUDO_CARD); } diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 35a37451b9..29b028002d 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -2,12 +2,14 @@ #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "trial.h" #include "dungeon.h" +#include "soh/ShipUtils.h" #include "soh/OTRGlobals.h" #include #include +#include namespace Rando { std::shared_ptr Settings::mInstance; @@ -242,11 +244,6 @@ void Settings::CreateOptions() { OPT_U8(RSK_RAINBOW_BRIDGE_REWARD_COUNT, "Bridge Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true); OPT_U8(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT, "Bridge Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true); OPT_U8(RSK_RAINBOW_BRIDGE_TOKEN_COUNT, "Bridge Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true); - OPT_U8(RSK_RAINBOW_BRIDGE_STONE_COUNT, "Bridge Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true); - OPT_U8(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT, "Bridge Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true); - OPT_U8(RSK_RAINBOW_BRIDGE_REWARD_COUNT, "Bridge Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true); - OPT_U8(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT, "Bridge Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true); - OPT_U8(RSK_RAINBOW_BRIDGE_TOKEN_COUNT, "Bridge Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true); OPT_U8(RSK_BRIDGE_OPTIONS, "Bridge Reward Options", {"Standard Rewards", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), mOptionDescriptions[RSK_BRIDGE_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_BRIDGE_STANDARD_REWARD, false, nullptr, IMFLAG_NONE); OPT_CALLBACK(RSK_BRIDGE_OPTIONS, { const uint8_t bridgeOpt = CVarGetInteger(CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), RO_BRIDGE_STANDARD_REWARD); @@ -440,10 +437,12 @@ void Settings::CreateOptions() { if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_TRIFORCE_HUNT_OFF) == RO_TRIFORCE_HUNT_OFF) { mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Hide(); mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Hide(); + mOptions[RSK_TRIFORCE_HUNT_PIECES_LOCATION].Hide(); mOptions[RSK_GANONS_BOSS_KEY].Enable(); } else { mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Unhide(); mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Unhide(); + mOptions[RSK_TRIFORCE_HUNT_PIECES_LOCATION].Unhide(); mOptions[RSK_GANONS_BOSS_KEY].Disable( "This option is disabled because Triforce Hunt is enabled." "Ganon's Boss key\nwill instead be given to you after Triforce Hunt completion."); @@ -458,6 +457,7 @@ void Settings::CreateOptions() { } }); OPT_U8(RSK_TRIFORCE_HUNT_PIECES_REQUIRED, "Triforce Hunt Required Pieces", {NumOpts(1, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntRequiredPieces"), mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], WIDGET_CVAR_SLIDER_INT, 19); + OPT_U8(RSK_TRIFORCE_HUNT_PIECES_LOCATION, "Triforce Hunt Pieces Location", {"Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntPiecesLocation"), mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_LOCATION], WIDGET_CVAR_COMBOBOX, RO_TRIFORCE_HUNT_LOCATION_ANYWHERE); OPT_U8(RSK_MQ_DUNGEON_RANDOM, "MQ Dungeon Setting", {"None", "Set Number", "Random", "Selection Only"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeons"), mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM], WIDGET_CVAR_COMBOBOX, RO_MQ_DUNGEONS_NONE, false, nullptr, IMFLAG_NONE); OPT_CALLBACK(RSK_MQ_DUNGEON_RANDOM, { switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE)) { @@ -567,7 +567,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_MQ_ICE_CAVERN, "Ice Cavern Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE); OPT_U8(RSK_MQ_GTG, "Gerudo Training Ground Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE); OPT_U8(RSK_MQ_GANONS_CASTLE, "Ganon's Castle Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA); - OPT_U8(RSK_SHUFFLE_DUNGEON_REWARDS, "Shuffle Dungeon Rewards", {"Vanilla", "End of Dungeons", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_REWARDS_END_OF_DUNGEON); + OPT_U8(RSK_SHUFFLE_DUNGEON_REWARDS, "Shuffle Dungeon Rewards", {"Vanilla", "End of Dungeons", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_REWARDS_END_OF_DUNGEON); OPT_CALLBACK(RSK_SHUFFLE_DUNGEON_REWARDS, { // Link's Pocket - Disabled when Dungeon Rewards are shuffled to End of Dungeon if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == @@ -576,32 +576,39 @@ void Settings::CreateOptions() { "This option is disabled because \"Dungeon Rewards\" are shuffled to \"End of Dungeons\"."); mOptions[RSK_LINKS_POCKET_REWARD].Enable(); mOptions[RSK_LINKS_POCKET_REWARD].Unhide(); - } else if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == - RO_DUNGEON_REWARDS_VANILLA) { - mOptions[RSK_LINKS_POCKET_REWARD].Disable("This option is disabled because \"Dungeon Rewards\" are shuffled to \"Vanilla\"."); - mOptions[RSK_LINKS_POCKET_REWARD].Hide(); - mOptions[RSK_LINKS_POCKET].Enable(); } else { - mOptions[RSK_LINKS_POCKET].Enable(); - mOptions[RSK_LINKS_POCKET_REWARD].Enable(); + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == + RO_DUNGEON_REWARDS_OWN_DUNGEON) { + mOptions[RSK_LINKS_POCKET].Enable(); + mOptions[RSK_LINKS_POCKET_REWARD].Disable( + "As \"Link's Pocket\" is set to \"Dungeon Reward\" while \"Dungeon Rewards\" is set to \"Own Dungeon\", Link's Pocket will always have the Light Medallion"); + }else if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == + RO_DUNGEON_REWARDS_VANILLA) { + mOptions[RSK_LINKS_POCKET].Enable(); + mOptions[RSK_LINKS_POCKET_REWARD].Disable( + "As \"Link's Pocket\" is set to \"Dungeon Reward\" while \"Dungeon Rewards\" is set to \"Vanilla\", Link's Pocket will always have the Light Medallion"); + } else { + mOptions[RSK_LINKS_POCKET].Enable(); + mOptions[RSK_LINKS_POCKET_REWARD].Enable(); + } if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD) == RO_LINKS_POCKET_DUNGEON_REWARD) { mOptions[RSK_LINKS_POCKET_REWARD].Unhide(); - } + } else { + mOptions[RSK_LINKS_POCKET_REWARD].Hide(); + } } }); - OPT_U8(RSK_LINKS_POCKET, "Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocket"), "", WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_DUNGEON_REWARD); + OPT_U8(RSK_LINKS_POCKET, "Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocket"), mOptionDescriptions[RSK_LINKS_POCKET], WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_DUNGEON_REWARD); OPT_CALLBACK(RSK_LINKS_POCKET, { // Only show the dungeon reward type if Link's Pocket is set to Dungeon Reward and Dungeon Rewards are not Vanilla, OR Dungeon Rewards are end of dungeon - if ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD) == - RO_LINKS_POCKET_DUNGEON_REWARD && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) != - RO_DUNGEON_REWARDS_VANILLA) || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == - RO_DUNGEON_REWARDS_END_OF_DUNGEON) { + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD) == RO_LINKS_POCKET_DUNGEON_REWARD || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == RO_DUNGEON_REWARDS_END_OF_DUNGEON) { mOptions[RSK_LINKS_POCKET_REWARD].Unhide(); } else { mOptions[RSK_LINKS_POCKET_REWARD].Hide(); } }); - OPT_U8(RSK_LINKS_POCKET_REWARD, "Link's Pocket Reward Type", {"Dungeon Reward", "Stone", "Medallion"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocketReward"), "", WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_REWARD); + OPT_U8(RSK_LINKS_POCKET_REWARD, "Link's Pocket Reward Type", {"Any Reward", "Any Stone", "Any Medallion", "Light Medallion"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocketReward"), mOptionDescriptions[RSK_LINKS_POCKET_REWARD], WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_ANY_REWARD); OPT_U8(RSK_SHUFFLE_SONGS, "Shuffle Songs", {"Off", "Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), mOptionDescriptions[RSK_SHUFFLE_SONGS], WIDGET_CVAR_COMBOBOX, RO_SONG_SHUFFLE_SONG_LOCATIONS); OPT_U8(RSK_SHOPSANITY, "Shop Shuffle", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WIDGET_CVAR_COMBOBOX, RO_SHOPSANITY_OFF); OPT_CALLBACK(RSK_SHOPSANITY, { @@ -632,7 +639,7 @@ void Settings::CreateOptions() { break; } }); - OPT_U8(RSK_SHOPSANITY_COUNT, "Shops Item Count", {NumOpts(0, 7/*8*/)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WIDGET_CVAR_SLIDER_INT, 0, false, nullptr, IMFLAG_NONE); + OPT_U8(RSK_SHOPSANITY_COUNT, "Shops Item Count", {NumOpts(0, 8)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WIDGET_CVAR_SLIDER_INT, 0, false, nullptr, IMFLAG_NONE); OPT_U8(RSK_SHOPSANITY_PRICES, "Shops Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WIDGET_CVAR_COMBOBOX, RO_PRICE_VANILLA, false, nullptr, IMFLAG_NONE); OPT_CALLBACK(RSK_SHOPSANITY_PRICES, { HandleShopsanityPriceUI(); @@ -646,6 +653,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT, "Shops Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE); OPT_U8(RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT, "Shops Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE); OPT_BOOL(RSK_SHOPSANITY_PRICES_AFFORDABLE, "Shops Affordable Prices", CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE]); + OPT_BOOL(RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL, "Gate Shop Shields & Tunics", CVAR_RANDOMIZER_SETTING("ShopShieldsTunicsGate"), mOptionDescriptions[RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL]); OPT_U8(RSK_SHUFFLE_TOKENS, "Token Shuffle", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WIDGET_CVAR_COMBOBOX, RO_TOKENSANITY_OFF); OPT_U8(RSK_SHUFFLE_SCRUBS, "Scrubs Shuffle", {"Off", "One-Time Only", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WIDGET_CVAR_COMBOBOX, RO_SCRUBS_OFF); OPT_CALLBACK(RSK_SHUFFLE_SCRUBS, { @@ -842,8 +850,13 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_POTS_OFF); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_CRATES_OFF); + OPT_BOOL(RSK_SHUFFLE_ROCKS, "Shuffle Rocks", CVAR_RANDOMIZER_SETTING("ShuffleRocks"), mOptionDescriptions[RSK_SHUFFLE_ROCKS]); + OPT_U8(RSK_SHUFFLE_BOULDERS, "Shuffle Boulders", {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), mOptionDescriptions[RSK_SHUFFLE_BOULDERS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_BOULDERS_OFF); OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]); OPT_BOOL(RSK_SHUFFLE_BUSHES, "Shuffle Bushes", CVAR_RANDOMIZER_SETTING("ShuffleBushes"), mOptionDescriptions[RSK_SHUFFLE_BUSHES]); + OPT_BOOL(RSK_SHUFFLE_ICICLES, "Shuffle Icicles", CVAR_RANDOMIZER_SETTING("ShuffleIcicles"), mOptionDescriptions[RSK_SHUFFLE_ICICLES]); + OPT_BOOL(RSK_SHUFFLE_RED_ICE, "Shuffle Red Ice", CVAR_RANDOMIZER_SETTING("ShuffleRedIce"), mOptionDescriptions[RSK_SHUFFLE_RED_ICE]); + OPT_U8(RSK_SHUFFLE_SIGNS, "Shuffle Signs", {"Off", "Dungeons", "Overworld", "All Signs"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSigns"), mOptionDescriptions[RSK_SHUFFLE_SIGNS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_SIGNS_OFF); OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); OPT_CALLBACK(RSK_SHUFFLE_FISHING_POLE, { // Disable fishing pole hint if the fishing pole is not shuffled @@ -1011,6 +1024,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT, "Merchant Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE); OPT_U8(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, "Merchant Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE); OPT_BOOL(RSK_MERCHANT_PRICES_AFFORDABLE, "Merchant Affordable Prices", CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE]); + OPT_BOOL(RSK_SHUFFLE_BEGGAR, "Shuffle Beggar", CVAR_RANDOMIZER_SETTING("ShuffleBeggar"), mOptionDescriptions[RSK_SHUFFLE_BEGGAR]); OPT_BOOL(RSK_SHUFFLE_FROG_SONG_RUPEES, "Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]); OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, "Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]); OPT_U8(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); @@ -1041,6 +1055,7 @@ void Settings::CreateOptions() { } }); OPT_U8(RSK_SHUFFLE_FREESTANDING, "Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_FREESTANDING_OFF); + OPT_U8(RSK_SHUFFLE_WONDER_ITEMS, "Shuffle Wonder Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWonderItems"), mOptionDescriptions[RSK_SHUFFLE_WONDER_ITEMS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_WONDER_ITEMS_OFF); OPT_U8(RSK_FISHSANITY, "Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WIDGET_CVAR_COMBOBOX, RO_FISHSANITY_OFF); OPT_CALLBACK(RSK_FISHSANITY, { // Hide fishing pond settings if we aren't shuffling the fishing pond @@ -1068,6 +1083,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_STONE_FAIRIES, "Shuffle Gossip Stone Fairies", CVAR_RANDOMIZER_SETTING("ShuffleStoneFairies"), mOptionDescriptions[RSK_SHUFFLE_STONE_FAIRIES]); OPT_BOOL(RSK_SHUFFLE_BEAN_FAIRIES, "Shuffle Bean Fairies", CVAR_RANDOMIZER_SETTING("ShuffleBeanFairies"), mOptionDescriptions[RSK_SHUFFLE_BEAN_FAIRIES]); OPT_BOOL(RSK_SHUFFLE_SONG_FAIRIES, "Shuffle Fairy Spots", CVAR_RANDOMIZER_SETTING("ShuffleFairySpots"), mOptionDescriptions[RSK_SHUFFLE_SONG_FAIRIES]); + OPT_BOOL(RSK_SHUFFLE_BUTTERFLY_FAIRIES, "Shuffle Butterfly Fairies", CVAR_RANDOMIZER_SETTING("ShuffleButterflyFairies"), mOptionDescriptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES]); OPT_U8(RSK_SHUFFLE_MAPANDCOMPASS, "Maps/Compasses", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); OPT_U8(RSK_KEYSANITY, "Small Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); OPT_U8(RSK_GERUDO_KEYS, "Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WIDGET_CVAR_COMBOBOX, RO_GERUDO_KEYS_VANILLA); @@ -1324,6 +1340,10 @@ void Settings::CreateOptions() { OPT_U8(RSK_LOGIC_RULES, "Logic", {"Glitchless", "No Logic"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LogicRules"), mOptionDescriptions[RSK_LOGIC_RULES], WIDGET_CVAR_COMBOBOX, RO_LOGIC_GLITCHLESS, false, nullptr, IMFLAG_LABEL_INLINE); OPT_CALLBACK(RSK_LOGIC_RULES, { HandleStartingAgeUI(); + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC && + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), 0) > 7) { + CVarSetInteger(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), 7); + } }); OPT_BOOL(RSK_ALL_LOCATIONS_REACHABLE, "All Locations Reachable", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE], WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_SAME_LINE); OPT_BOOL(RSK_SKULLS_SUNS_SONG, "Night Skulltula's Expect Sun's Song", CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), mOptionDescriptions[RSK_SKULLS_SUNS_SONG]); @@ -1369,34 +1389,7 @@ void Settings::CreateOptions() { mExcludeLocationsOptionsAreas.reserve(RCAREA_INVALID); - // the following are glitches and are currently disabled - // OPT_TRICK(RT_ACUTE_ANGLE_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, - // Tricks::Tag::GLITCH}, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet - // at an acute angle."); OPT_TRICK(RT_ADVANCED_CLIPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, - // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Advanced clips", "Enables locations requiring clips through - // walls and objects requiring precise jumps or other tricks."); OPT_TRICK(RT_BLANK_A, RCQUEST_BOTH, RA_NONE, - // {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Blank A", "Enables locations requiring - // blank A button; NOTE: this requires the 'Quick Putaway' restoration."); OPT_TRICK(RT_DOOM_JUMP, RCQUEST_BOTH, - // RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Doom Jump", "Enables locations - // requiring doom jumps."); OPT_TRICK(RT_EPG, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, - // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "EPG", "Enables locations requiring use of the Entrance Point - // Glitch."); OPT_TRICK(RT_EQUIP_SWAP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, - // Tricks::Tag::GLITCH}, "Equip Swap", "Enables locations requiring use of equip swap; NOTE: this may expect the - // 'Allow cursor to be over any slot' enhancement to be turned off."); OPT_TRICK(RT_EQUIP_SWAP_EXPECTS_DINS, - // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Equip Swap - // Require's Din's Fire", "Enables locations requiring use of equip swap once Din's Fire is found."); - // OPT_TRICK(RT_FLAME_STORAGE, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, - // Tricks::Tag::GLITCH}, "Flame Storage", "Enables locations requiring flame storage."); OPT_TRICK(RT_GROUND_CLIP, - // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Clip", - // "Enables locations requiring ground clips."); OPT_TRICK(RT_HESS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, - // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "HESS", "Enables locations requiring a Hyper Extended Super - // Slide."); OPT_TRICK(RT_HOOKSHOT_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, - // Tricks::Tag::GLITCH}, "Hookshot Clip", "Enables locations requiring Hookshot clips."); - // OPT_TRICK(RT_HOOKSHOT_JUMP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, - // Tricks::Tag::GLITCH}, "Hookshot Jump", "Enables locations requiring Hookshot jumps."); OPT_TRICK(RT_ISG, - // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "ISG", "Enables - // locations requiring use of the infinite sword glitch."); - + // RANDOTODO sweep trick descriptions and make sure they match a post-refactor, post shuffles reality /* Common abbreviations in name tags - A: Adult - Blk: Block @@ -1423,857 +1416,292 @@ void Settings::CreateOptions() { Try to keep Name Tags less than 8 chars. */ - OPT_TRICK(RT_VISIBLE_COLLISION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Ignore Visible Collision", - "VisCol", - "Allows ignoring visible barriers and objects that do not actually stop Link from walking, climbing or " - "hitting things, without clipping.\n\n" - "This notably allows for walking through Kak's gate backwards, climb into the back of Impa's house as " - "Adult from the coop," - "and hitting Rusted Switches or boulders through Blocks, Ice and Walls.\n\n" - "This trick only applies to case where doing the thing is trivial, instances where it only works from " - "certain angles are not part of this trick," - "niether are any form of clips, including clipping Link's hitbox inside boulders with jumpslash."); - OPT_TRICK(RT_GROTTOS_WITHOUT_AGONY, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, - "Hidden Grottos without Stone of Agony", "NoSoA", - "Allows entering hidden grottos without the Stone of Agony."); - OPT_TRICK( - RT_FEWER_TUNIC_REQUIREMENTS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "Fewer Tunic Requirements", - "FTR", - "Normally the only hot area logic expects you to navigate without a Goron Tunic is Death Mountain Crater\n" - "and you are not expected to navigate underwater sections without a Zora Tunic.\n\n" - "With this trick you are expected to do any underwater area except Central Pillar,\n" - "any hot area except Volvagia and the Block lift room in Fire Temple\n" - "and the health needed to logically navigate Crater is decreased."); - OPT_TRICK(RT_UNINTUITIVE_JUMPS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Unintuitive Jumps", "UnJmp", - "Many ledges can be overcome with particular jumps which are simple to execute without items.\n" - "This includes jumping from heights to dive deeper without scales,\n" - "though this trick doesn't cover Water Temple's Dragon Room."); - OPT_TRICK(RT_FIRE_RINGS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "Fire Ring", "FlaChst", - "Fire Rings can be run into while Link is invincible from having taken damage," - "letting you interact with some objects inside them such as large chests"); + // the following are glitches and are currently disabled + + // OPT_TRICK(RT_ACUTE_ANGLE_CLIP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_ADVANCED_CLIPS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_BLANK_A, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_DOOM_JUMP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_EPG, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH}); + + // OPT_TRICK(RT_EQUIP_SWAP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_EQUIP_SWAP_EXPECTS_DINS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_FLAME_STORAGE, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_GROUND_CLIP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_HESS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH}); + + // OPT_TRICK(RT_HOOKSHOT_CLIP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_HOOKSHOT_JUMP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH }); + + // OPT_TRICK(RT_ISG, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH}); + + OPT_TRICK(RT_VISIBLE_COLLISION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "VisCol"); + OPT_TRICK(RT_GROTTOS_WITHOUT_AGONY, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "NoSoA"); + OPT_TRICK(RT_FEWER_TUNIC_REQUIREMENTS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "FTR"); + OPT_TRICK(RT_UNINTUITIVE_JUMPS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "UnJmp"); + OPT_TRICK(RT_FIRE_RINGS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "FlaChst"); + // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely - // decoupled from rando OPT_TRICK(RT_BUNNY_HOOD_JUMPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, "Bunny Hood - // Jumps", "Allows reaching locations using Bunny Hood's extended jumps."); + // decoupled from rando + + // OPT_TRICK(RT_BUNNY_HOOD_JUMPS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED }); + OPT_TRICK(RT_DAMAGE_BOOST_SIMPLE, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL }, - "Simple damage boosts", "SDmgBoo", - "Allows damage boosts in order to reach further locations. Can be combined with \"Simple hover boosts\" " - "for reaching far distances."); - OPT_TRICK(RT_HOVER_BOOST_SIMPLE, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::GLITCH }, - "Simple hover boosts", "SHovBoo", - "Allows equipping of hover boots when Link is moving at high speeds to extend distance covered, often " - "after recoil. Can be combined with \"Simple damage boosts\" for greater uses."); - OPT_TRICK(RT_BOMBCHU_BEEHIVES, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Bombchu Beehives", "ChuBee", - "Allows exploding beehives with Bombchus."); - OPT_TRICK(RT_HOOKSHOT_LADDERS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Hookshot Ladders", "HSLad", - "You can skip climb for hookshottable ladders can be skipped by hookshotting the top of the ladder from " - "the correct distance and angle.\n" - "This is more difficult for some ladders than others, and a few are not possible.\n" - "Hookshotting climbable walls in the same way is not a trick, as it is trivial to get an angle that " - "correctly ledge grabs."); - OPT_TRICK(RT_BLUE_FIRE_MUD_WALLS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Blue Fire Beyond Red Ice", - "BluFire", - "Use Blue Fire to break mud walls, detonate bomb flowers, and break floor to King Dodongo.\nDoes not " - "apply to MQ Dead Hand bomb flowers.\nUsing blue fire on bombflower to stop rolling goron also requires " - "\"Stop Link the Goron with Din's Fire\".\nUsing blue fire arrows to break floor in King Dodongo's " - "chamber also requires \"Dodongo\'s Cavern Smash the Boss Lobby Floor\"."); - OPT_TRICK(RT_OPEN_UNDERWATER_CHEST, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, - "Open Underwater Chests", "OpenUC", - "Underwater chests can be opened by wearing iron boots and hookshotting the chest."); - OPT_TRICK(RT_DISTANT_BOULDER_COLLISION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, - "Distant Boulder Collision", "BolCol", - "From afar boulder collision is disabled, allowing projectiles to pass through them."); - OPT_TRICK(RT_ITEM_EXTENSION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "Item Extension", "HSExt", - "Slightly extends the range of projectiles such as Hookshot, Bow or Slingshot. Also allows clipping " - "projectile past collision. Used for:\n" - "- Crossing Gerudo Valley with Hookshot\n" - "- Retrieving DMT Gold Skulltula beside bomb flower\n" - "- Hitting switch through wall in Spirit Temple's big mirror room with Bow, Slingshot, or Hookshot\n" - "- Hitting switch through wall in Spirit Trial with Bow or Slingshot\n" - "- Hitting switch through gate in Shadow Temple MQ with Bow or Slingshot"); + "SDmgBoo"); + OPT_TRICK(RT_HOVER_BOOST_SIMPLE, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::GLITCH }, "SHovBoo"); + OPT_TRICK(RT_BOMBCHU_BEEHIVES, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "ChuBee"); + OPT_TRICK(RT_HOOKSHOT_LADDERS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "HSLad"); + OPT_TRICK(RT_BLUE_FIRE_MUD_WALLS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "BluFire"); + OPT_TRICK(RT_OPEN_UNDERWATER_CHEST, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "OpenUC"); + OPT_TRICK(RT_BOULDER_COLLISION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "BolCol"); + OPT_TRICK(RT_ITEM_EXTENSION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "HSExt"); OPT_TRICK(RT_BIG_SKULLTULA_PAUSE_LIFT, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, - "Lift Big Skulltulas with Pausing", "SkulPaus", - "Pausing while a big skulltula is bobbing upwards slightly lifts it,\n" - "eventually allowing passage without any items."); - OPT_TRICK(RT_GROUND_JUMP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "Ground Jump", - "GrdJmp", "Enables requiring ground jumps."); + "SkulPaus"); + OPT_TRICK(RT_GROUND_JUMP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "GrdJmp"); OPT_TRICK(RT_GROUND_JUMP_HARD, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE, Tricks::Tag::GLITCH }, - "Hard Ground Jumps", "HGrdJmp", - "Enables ground jumps which require some precision outside of setting up jump,\n" - "such as needing extra height with jumpslash or jumping while running with hover boots."); - OPT_TRICK(RT_SLIDE_JUMP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Sliding Jumps", "SldJmp", - "Running forward while sliding sideways on ice can be used to jump on platforms."); - OPT_TRICK(RT_KF_ADULT_GS, RCQUEST_BOTH, RA_KOKIRI_FOREST, { Tricks::Tag::NOVICE }, - "Adult Kokiri Forest GS with Hover Boots", "KFGSHB", - "Can be obtained without Hookshot by using the Hover Boots off of one of the roots."); - OPT_TRICK(RT_LW_BRIDGE, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::EXPERT }, - "Jump onto the Lost Woods Bridge as Adult with Nothing", "LWBrgJmp", - "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, " - "Hover Boots, or Bean."); - OPT_TRICK(RT_LW_MIDO_BACKFLIP, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::NOVICE }, - "Backflip over Mido as Adult", "MidoSkip", - "With a specific position and angle, you can backflip over Mido."); + "HGrdJmp"); + OPT_TRICK(RT_SLIDE_JUMP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "SldJmp"); + OPT_TRICK(RT_VOIDOUT_COLLECTION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "VdCl"); + OPT_TRICK(RT_BOMB_DETONATION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "BmbDet"); + OPT_TRICK(RT_KF_ADULT_GS, RCQUEST_BOTH, RA_KOKIRI_FOREST, { Tricks::Tag::NOVICE }, "KFGSHB"); + OPT_TRICK(RT_LW_BRIDGE, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::EXPERT }, "LWBrgJmp"); + OPT_TRICK(RT_LW_MIDO_BACKFLIP, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::NOVICE }, "MidoSkip"); OPT_TRICK(RT_LOST_WOOD_NAVI_DIVE, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, - "Lost Woods Navi dive", "LWNaviD", - "You need Deku Sticks or Kokiri Sword to dive with Navi for entering Zora's River."); - OPT_TRICK(RT_LW_GS_BEAN, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::INTERMEDIATE }, - "Lost Woods Adult GS without Bean", "LWGSHS", - "You can collect the token with a precise Hookshot use, as long as you can kill the Skulltula somehow " - "first. It can be killed using Longshot, Bow, Bombchus or Din's Fire."); - OPT_TRICK(RT_HC_STORMS_GS, RCQUEST_BOTH, RA_HYRULE_CASTLE, { Tricks::Tag::INTERMEDIATE }, - "Hyrule Castle Storms Grotto GS with Just Boomerang", "HCGrGSRng", - "With precise throws, the Boomerang alone can kill the Skulltula and collect the token, without first " - "needing to blow up the wall."); - OPT_TRICK(RT_HF_BIG_POE_WITHOUT_EPONA, RCQUEST_BOTH, RA_HYRULE_FIELD, { Tricks::Tag::NOVICE }, - "Big Poe without Epona", "PoeDiff", - "Big Poes have a chance of appearing without Epona, you can shoot them quickly with only bow."); - OPT_TRICK(RT_KAK_TOWER_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::INTERMEDIATE }, - "Kakariko Tower GS with Jumpslash", "KakGSJS", - "Climb the tower as high as you can without touching the Gold Skulltula, then let go and jumpslash " - "immediately. By jump-slashing from as low on the ladder as possible to still hit the Skulltula, this " - "trick can be done without taking fall damage."); - OPT_TRICK(RT_KAK_CHILD_WINDMILL_POH, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::EXTREME }, - "Windmill PoH as Child with Precise Jumpslash", "WndCJS", - "Can jump up to the spinning platform from below as child with a precise jumpslash timed with the " - "platforms rotation."); - OPT_TRICK( - RT_KAK_ROOFTOP_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::ADVANCED }, - "Kakariko Rooftop GS with Hover Boots", "KakGSHB", - "Take the Hover Boots from the entrance to Impa's House over to the rooftop of Skulltula House. From there, a " - "precise Hover Boots backwalk with backflip can be used to get onto a hill above the side of the village. And " - "then from there you can Hover onto Impa's rooftop to kill the Skulltula and backflip into the token."); - OPT_TRICK(RT_GY_POH, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::INTERMEDIATE }, - "Graveyard Freestanding PoH with Boomerang", "GYPoHRng", - "Using a precise moving setup you can obtain the Piece of Heart by having the Boomerang interact with it " - "along the return path."); - OPT_TRICK( - RT_GY_CHILD_DAMPE_RACE_POH, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::NOVICE }, - "Second Dampe Race as Child", "CDmpRace", - "It is possible to complete the second dampe race as child in under a minute, but it is a strict time limit."); - OPT_TRICK(RT_GY_SHADOW_FIRE_ARROWS, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::EXPERT }, - "Shadow Temple Entry with Fire Arrows", "FAEntry", - "It is possible to light all of the torches to open the Shadow Temple entrance with just Fire Arrows, " - "but you must be very quick, precise, and strategic with how you take your shots."); - OPT_TRICK(RT_DMT_SHIELDLESS_CLIMB, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::NOVICE }, - "Death Mountain Trail Child Climb Without Shield", "DMTCWoS", - "Child can make it past the eruption to reach DMT Summit without a Hylian Shield or Nayru's Love" - "by backwalking or simply taking damage."); - OPT_TRICK(RT_DMT_SOIL_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, - "Death Mountain Trail Soil GS without Destroying Boulder", "DMTSoil", - "Bugs will go into the soft soil even while the boulder is still blocking the entrance. Then, using a " - "precise moving setup you can kill the Gold Skulltula and obtain the token by having the Boomerang " - "interact with it along the return path."); - OPT_TRICK(RT_DMT_BOMBABLE, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, - "Death Mountain Trail Chest with Strength", "DMTSTR", - "Child Link can blow up the wall using a nearby bomb flower. You must backwalk with the flower and then " - "quickly throw it toward the wall."); - OPT_TRICK(RT_DMT_HOVERS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::ADVANCED }, - "Death Mountain Trail Lower Red Rock GS with Hover Boots", "DMTGSHB", - "After killing the Skulltula, the token can be collected without needing to destroy the rock by " - "backflipping down onto it with the Hover Boots. First use the Hover Boots to stand on a nearby fence, " - "and go for the Skulltula Token from there."); - OPT_TRICK(RT_DMT_BEAN_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::EXPERT }, - "Death Mountain Trail Lower Red Rock GS with Magic Bean", "DMTGSMB", - "After killing the Skulltula, the token can be collected without needing to destroy the rock by jumping " - "down onto it from the bean plant, midflight, with precise timing and positioning."); - OPT_TRICK(RT_DMT_JS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, - "Death Mountain Trail Lower Red Rock GS with Jumpslash", "DMTGSJS", - "After killing the Skulltula, the token can be collected without needing to destroy the rock by jump " - "slashing from a precise angle."); - OPT_TRICK(RT_DMT_CLIMB_HOVERS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::ADVANCED }, - "Death Mountain Trail Climb with Hover Boots", "DMTBouHB", - "It is possible to use the Hover Boots to bypass needing to destroy the boulders blocking the path to " - "the top of Death Mountain."); - OPT_TRICK( - RT_DMT_UPPER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::NOVICE }, - "Death Mountain Trail Upper Red Rock GS with Backflip", "DMTGSBF", - "After killing the Skulltula, the token can be collected by backflipping into the rock at the correct angle."); + "LWNaviD"); + OPT_TRICK(RT_LW_GS_BEAN, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::INTERMEDIATE }, "LWGSHS"); + OPT_TRICK(RT_HC_STORMS_GS, RCQUEST_BOTH, RA_HYRULE_CASTLE, { Tricks::Tag::INTERMEDIATE }, "HCGrGSRng"); + OPT_TRICK(RT_HF_BIG_POE_WITHOUT_EPONA, RCQUEST_BOTH, RA_HYRULE_FIELD, { Tricks::Tag::NOVICE }, "PoeDiff"); + OPT_TRICK(RT_KAK_TOWER_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::INTERMEDIATE }, "KakGSJS"); + OPT_TRICK(RT_KAK_CHILD_WINDMILL_POH, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::EXTREME }, "WndCJS"); + OPT_TRICK(RT_KAK_ROOFTOP_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::ADVANCED }, "KakGSHB"); + OPT_TRICK(RT_GY_POH, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::INTERMEDIATE }, "GYPoHRng"); + OPT_TRICK(RT_GY_CHILD_DAMPE_RACE_POH, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::NOVICE }, "CDmpRace"); + OPT_TRICK(RT_GY_SHADOW_FIRE_ARROWS, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::EXPERT }, "FAEntry"); + OPT_TRICK(RT_DMT_SHIELDLESS_CLIMB, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::NOVICE }, "DMTCWoS"); + OPT_TRICK(RT_DMT_SOIL_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, "DMTSoil"); + OPT_TRICK(RT_DMT_BOMBABLE, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, "DMTSTR"); + OPT_TRICK(RT_DMT_HOVERS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::ADVANCED }, "DMTGSHB"); + OPT_TRICK(RT_DMT_BEAN_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::EXPERT }, "DMTGSMB"); + OPT_TRICK(RT_DMT_JS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, "DMTGSJS"); + OPT_TRICK(RT_DMT_CLIMB_HOVERS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::ADVANCED }, "DMTBouHB"); + OPT_TRICK(RT_DMT_UPPER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::NOVICE }, "DMTGSBF"); + // disabled for now, only applies when trade quest is not shuffled so there's a timer (currently not considered in - // logic) OPT_TRICK(RT_DMT_BOLERO_BIGGORON, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, - // "Deliver Eye Drops with Bolero of Fire", "Playing a warp song normally causes a trade item to spoil immediately, - // however, it is possible use Bolero to reach Biggoron and still deliver the Eye Drops before they spoil. If you do - // not wear the Goron Tunic, the heat timer inside the crater will override the trade item\'s timer. When you exit - // to Death Mountain Trail you will have one second to show the Eye Drops before they expire. You can get extra time - // to show the Eye Drops if you warp immediately upon receiving them. If you don't have many hearts, you may have to - // reset the heat timer by quickly dipping in and out of Darunia\'s chamber or quickly equipping and unequipping the - // Goron Tunic. This trick does not apply if \"Randomize Warp Song Destinations\" is enabled, or if the settings are - // such that trade items do not need to be delivered within a time limit."); - OPT_TRICK(RT_GC_POT, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, - "Goron City Spinning Pot PoH with Bombchu", "GorPotChu", - "A Bombchu can be used to stop the spinning pot, but it can be quite finicky to get it to work."); - OPT_TRICK(RT_GC_POT_STRENGTH, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::INTERMEDIATE }, - "Goron City Spinning Pot PoH with Strength", "GorPotStr", - "Allows for stopping the Goron City Spinning Pot using a Bomb Flower alone, requiring strength in lieu " - "of inventory explosives."); - OPT_TRICK(RT_GC_ROLLING_STRENGTH, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::INTERMEDIATE }, - "Rolling Goron (Hot Rodder Goron) as Child with Strength", "GorStrC", - "Use the Bomb Flower on the stairs or near Medigoron. Timing is tight, especially without backwalking."); - OPT_TRICK(RT_GC_LEFTMOST, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, - "Goron City Maze Left Chest with Hover Boots", "GCMazHB", - "A precise backwalk starting from on top of the crate and ending with a precisely-timed backflip can " - "reach this chest without needing either the Hammer or Silver Gauntlets."); - OPT_TRICK(RT_GC_GROTTO, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, - "Goron City Grotto with Hookshot While Taking Damage", "GorGroHS", - "It is possible to reach the Goron City Grotto by quickly using the Hookshot while in the midst of " - "taking damage from the lava floor."); - OPT_TRICK(RT_GC_LINK_GORON_DINS, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::NOVICE }, - "Stop Link the Goron with Din\'s Fire", "GorDinA", "The timing is quite awkward."); - OPT_TRICK(RT_DMC_HOVER_BEAN_POH, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::NOVICE }, - "Crater\'s Bean PoH with Hover Boots", "DMCHB", - "Hover from the base of the bridge near Goron City and walk up the very steep slope."); - OPT_TRICK(RT_DMC_BOLERO_JUMP, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::EXTREME }, - "Death Mountain Crater Jump to Bolero", "DMCBolJump", - "As Adult, using a shield to drop a pot while you have the perfect speed and position, the pot can push " - "you that little extra distance you need to jump across the gap in the bridge."); - OPT_TRICK(RT_DMC_BOULDER_JS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::NOVICE }, - "Death Mountain Crater Upper to Lower with Hammer", "DMCHam", - "With the Hammer, you can jumpslash the rock twice in the same jump in order to destroy it before you " - "fall into the lava."); - OPT_TRICK(RT_DMC_BOULDER_SKIP, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::INTERMEDIATE }, - "Death Mountain Crater Upper to Lower Boulder Skip", "DMCULJmp", - "As adult, With careful positioning, you can jump to the ledge where the boulder is, then use repeated " - "ledge grabs to shimmy to a climbable ledge. This trick supersedes \"Death Mountain Crater Upper to " - "Lower with Hammer\"."); - OPT_TRICK(RT_ZR_LOWER, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::INTERMEDIATE }, - "Zora\'s River Lower Freestanding PoH as Adult with Nothing", "ZRLJmp", - "Adult can reach this PoH with a precise jump, no Hover Boots required."); - OPT_TRICK(RT_ZR_UPPER, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::INTERMEDIATE }, - "Zora\'s River Upper Freestanding PoH as Adult with Nothing", "ZRUJmp", - "Adult can reach this PoH with a precise jump, no Hover Boots required."); - OPT_TRICK(RT_ZR_HOVERS, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::NOVICE }, - "Zora\'s Domain Entry with Hover Boots", "ZRZDHB", "Can hover behind the waterfall as adult."); - OPT_TRICK(RT_ZR_CUCCO, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::NOVICE }, "Zora\'s Domain Entry with Cucco", - "ZRZDCuc", "You can fly behind the waterfall with a Cucco as child."); - OPT_TRICK(RT_ZD_KING_ZORA_SKIP, RCQUEST_BOTH, RA_ZORAS_DOMAIN, { Tricks::Tag::INTERMEDIATE }, - "Skip King Zora as Adult with Nothing", "Mweep", - "With a precise jump as adult, it is possible to get on the fence next to King Zora from the front to " - "access Zora's Fountain."); - OPT_TRICK(RT_ZD_GS, RCQUEST_BOTH, RA_ZORAS_DOMAIN, { Tricks::Tag::INTERMEDIATE }, - "Zora\'s Domain GS with No Additional Items", "ZDGS", - "A precise jumpslash can kill the Skulltula and recoil back onto the top of the frozen waterfall. To " - "kill it, the logic normally guarantees one of Hookshot, Bow, or Magic."); + // logic) + + // OPT_TRICK(RT_DMT_BOLERO_BIGGORON, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }); + + OPT_TRICK(RT_GC_POT, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, "GorPotChu"); + OPT_TRICK(RT_GC_POT_STRENGTH, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::INTERMEDIATE }, "GorPotStr"); + OPT_TRICK(RT_GC_ROLLING_STRENGTH, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::INTERMEDIATE }, "GorStrC"); + OPT_TRICK(RT_GC_LEFTMOST, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, "GCMazHB"); + OPT_TRICK(RT_GC_GROTTO, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, "GorGroHS"); + OPT_TRICK(RT_GC_LINK_GORON_DINS, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::NOVICE }, "GorDinA"); + OPT_TRICK(RT_DMC_HOVER_BEAN_POH, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::NOVICE }, "DMCHB"); + OPT_TRICK(RT_DMC_BOLERO_JUMP, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::EXTREME }, "DMCBolJump"); + OPT_TRICK(RT_DMC_BOULDER_JS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::NOVICE }, "DMCHam"); + OPT_TRICK(RT_DMC_BOULDER_SKIP, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::INTERMEDIATE }, "DMCULJmp"); + OPT_TRICK(RT_ZR_LOWER, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::INTERMEDIATE }, "ZRLJmp"); + OPT_TRICK(RT_ZR_UPPER, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::INTERMEDIATE }, "ZRUJmp"); + OPT_TRICK(RT_ZR_HOVERS, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::NOVICE }, "ZRZDHB"); + OPT_TRICK(RT_ZR_CUCCO, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::NOVICE }, "ZRZDCuc"); + OPT_TRICK(RT_ZD_KING_ZORA_SKIP, RCQUEST_BOTH, RA_ZORAS_DOMAIN, { Tricks::Tag::INTERMEDIATE }, "Mweep"); + OPT_TRICK(RT_ZD_GS, RCQUEST_BOTH, RA_ZORAS_DOMAIN, { Tricks::Tag::INTERMEDIATE }, "ZDGS"); OPT_TRICK(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES, RCQUEST_BOTH, RA_ZORAS_FOUNTAIN, { Tricks::Tag::NOVICE }, - "Zora\'s Fountain Great Fairy without Explosives", "ZFGFStr2", - "It's possible to use silver gauntlets to pick up the silver rock and hammer to break the rock below it, " - "allowing you to ledge grab the edge of the hole and get past the breakable wall (hammer can't break the " - "wall itself)."); - OPT_TRICK(RT_LH_LAB_WALL_GS, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::NOVICE }, - "Lake Hylia Lab Wall GS with Jumpslash", "LHGSJS", - "The jumpslash to actually collect the token is somewhat precise."); - OPT_TRICK(RT_LH_LAB_DIVING, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::NOVICE }, - "Lake Hylia Lab Dive without Gold Scale", "LabHS", - "Remove the Iron Boots in the midst of Hookshotting the underwater crate."); - OPT_TRICK(RT_LH_WATER_HOOKSHOT, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::INTERMEDIATE }, - "Water Temple Entry without Iron Boots using Hookshot", "WTEntHS", - "When entering Water Temple using Gold Scale instead of Iron Boots, the Longshot is usually used to be " - "able to hit the switch and open the gate. But, by standing in a particular spot, the switch can be hit " - "with only the reach of the Hookshot."); - OPT_TRICK(RT_GV_CRATE_HOVERS, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::INTERMEDIATE }, - "Gerudo Valley Crate PoH as Adult with Hover Boots", "GVPoHHB", - "From the far side of Gerudo Valley, a precise Hover Boots movement and jump-slash recoil can allow " - "adult to reach the ledge with the crate PoH without needing Longshot. You will take fall damage."); - OPT_TRICK(RT_GV_CHILD_TENT, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::NOVICE }, - "Gerudo Valley Enter Carpenter's Tent as Child", "GVTent", - "The loading zone for Carpenter's Tent is accessible to child."); - OPT_TRICK(RT_GV_CHILD_CUCCO_JUMP, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::INTERMEDIATE }, - "Gerudo Valley Jump Fence with Cucco", "GVCUC", - "Using cucco as child, it's possible to jumpslash over the gate."); - OPT_TRICK(RT_GV_HOOKSHOT_BRIDGE, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::ADVANCED }, - "Gerudo Valley Bridge with only Hookshot", "GVHSBrg", - "Using Hookshot Extension and a precise setup, you can cross the broken bridge in Gerudo Valley with " - "only a Hookshot."); - OPT_TRICK(RT_PASS_GUARDS_WITH_NOTHING, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, - "Sneak Past Moving Gerudo Guards with No Items", "Guards", - "The logic normally guarantees Bow or Hookshot to stun them from a distance," - "but every moving guard can be passed with basic movement and AI manipulation"); - OPT_TRICK(RT_GF_WASTELAND_GATE_SIDEHOP_SKIP, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, - "Gerudo\'s Fortress Gate Skip with Sidehop", "GFHWC", - "You can sidehop out of bounds from the tower, then sidehop again on the other side of the gate.\n\n" - "This is easiest and most useful for Child, but Adult can also do this to skip the Gerudo Jabber Nut."); + "ZFGFStr2"); + OPT_TRICK(RT_LH_LAB_WALL_GS, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::NOVICE }, "LHGSJS"); + OPT_TRICK(RT_LH_LAB_DIVING, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::NOVICE }, "LabHS"); + OPT_TRICK(RT_LH_WATER_HOOKSHOT, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::INTERMEDIATE }, "WTEntHS"); + OPT_TRICK(RT_GV_CRATE_HOVERS, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::INTERMEDIATE }, "GVPoHHB"); + OPT_TRICK(RT_GV_CHILD_TENT, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::NOVICE }, "GVTent"); + OPT_TRICK(RT_GV_CHILD_CUCCO_JUMP, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::INTERMEDIATE }, "GVCUC"); + OPT_TRICK(RT_GV_HOOKSHOT_BRIDGE, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::ADVANCED }, "GVHSBrg"); + OPT_TRICK(RT_PASS_GUARDS_WITH_NOTHING, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, "Guards"); + OPT_TRICK(RT_GF_WASTELAND_GATE_SIDEHOP_SKIP, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, "GFHWC"); OPT_TRICK(RT_GF_ADULT_SKIP_WASTELAND_GATE, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::INTERMEDIATE }, - "Gerudo\'s Fortress Skip Wasteland Gate as Adult", "GFHWA", - "As adult a precise jumpslash out of bounds with hoverboots from above the jail can be used to get past " - "the gate.\n\n" - "This can also be used to reach the tower and lower the gate for child without climb."); - OPT_TRICK(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, - "Gerudo\'s Fortress Warriors with Difficult Weapons", "GWDiff", - "Warriors can be defeated with Slingshot or Bombchus."); + "GFHWA"); + OPT_TRICK(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, "GWDiff"); OPT_TRICK(RT_GF_LEDGE_CLIP_INTO_GTG, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, - "Ledge Clip into Training Ground", "GTGLdgClp", - "Adult Link can use a ledge clip to enter Gerudo Training Ground without Gerudo Card."); + "GTGLdgClp"); + // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely - // decoupled from rando OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE}, - // "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood. - // Note that jumping to the carpet merchant as child typically requires a fairly precise jumpslash."); - OPT_TRICK(RT_HW_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, - "Wasteland Crossing without Hover Boots or Longshot", "RvrSand", - "You can beat the quicksand by backwalking across it in a specific way. Note that jumping to the carpet " - "merchant as child typically requires a fairly precise jumpslash."); - OPT_TRICK(RT_LENS_HW, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, "Lensless Wasteland", - "HWNoLoT", - "By memorizing the path, you can travel through the Wasteland without using the Lens of Truth to see the " - "Poe. The equivalent trick for going in reverse through the Wasteland is \"Reverse Wasteland\"."); - OPT_TRICK( - RT_HW_REVERSE, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, "Reverse Wasteland", "RevHW", - "By memorizing the path, you can travel through the Wasteland in reverse. Note that jumping to the carpet " - "merchant as child typically requires a fairly precise jumpslash. The equivalent trick for going forward " - "through the Wasteland is \"Lensless Wasteland\". To cross the river of sand with no additional items, be sure " - "to also enable \"Wasteland Crossing without Hover Boots or Longshot\". Unless all overworld entrances are " - "randomized, Child Link will not be expected to do anything at Gerudo's Fortress."); - OPT_TRICK(RT_COLOSSUS_GS, RCQUEST_BOTH, RA_DESERT_COLOSSUS, { Tricks::Tag::NOVICE }, - "Colossus Hill GS with Hookshot", "ColGSHS", - "Somewhat precise. If you kill enough Leevers you can get enough of a break to take some time to aim " - "more carefully."); - OPT_TRICK(RT_DEKU_BASEMENT_GS, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, - "Deku Tree Basement Vines GS with Jumpslash", "DTGSJS", "Can be defeated by doing a precise jumpslash."); - OPT_TRICK(RT_DEKU_B1_SKIP, RCQUEST_BOTH, RA_DEKU_TREE, { Tricks::Tag::INTERMEDIATE }, - "Deku Tree Basement without Slingshot", "B1Skip", - "A precise jump can be used to skip needing to use the Slingshot to go around B1 of the Deku Tree. If " - "used with the \"Closed Forest\" setting, a Slingshot will not be guaranteed to exist somewhere inside " - "the Forest. This trick applies to both Vanilla and Master Quest."); - OPT_TRICK(RT_DEKU_B1_BOW_WEBS, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, - "Deku Tree Basement Web to Gohma with Bow", "DTWebBow", - "All spider web walls in the Deku Tree basement can be burnt as adult with just a bow by shooting " - "through torches. This trick only applies to the circular web leading to Gohma; the two vertical webs " - "are always in logic. Backflip onto the chest near the torch at the bottom of the vine wall. With " - "precise positioning you can shoot through the torch to the right edge of the circular web. This allows " - "completion of adult Deku Tree with no fire source."); - OPT_TRICK(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, - "Deku Tree Basement Backflip over Spiked Log", "DTLogBF", - "Allows backflipping over the spiked log in the Deku Tree basement in Vanilla. Only relevant if " - "\"Shuffle Swim\" is enabled."); - OPT_TRICK(RT_DEKU_MQ_COMPASS_GS, RCQUEST_MQ, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, - "Deku Tree MQ Compass Room GS Boulders with Just Hammer", "DTGSHam", - "Climb to the top of the vines, then let go and jumpslash immediately to destroy the boulders using the " - "Hammer, without needing to spawn a Song of Time block."); - OPT_TRICK(RT_DEKU_MQ_LOG, RCQUEST_MQ, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, - "Deku Tree MQ Roll Under the Spiked Log", "DTLogRol", - "You can get past the spiked log by rolling to briefly shrink your hitbox. As adult, the timing is a bit " - "more precise."); - OPT_TRICK(RT_DC_SCARECROW_GS, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, - "Dodongo\'s Cavern Scarecrow GS with Armos Statue", "DCArmos", - "You can jump off an Armos Statue to reach the alcove with the Gold Skulltula. It takes quite a long " - "time to pull the statue the entire way. The jump to the alcove can be a bit picky when done as child."); - OPT_TRICK(RT_DC_VINES_GS, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, - "Dodongo\'s Cavern Vines GS from Below with Longshot", "DCGSLS", - "The vines upon which this Skulltula rests are one-sided collision. You can use the Longshot to get it " - "from below, by shooting it through the vines, bypassing the need to lower the staircase."); - OPT_TRICK(RT_DC_STAIRS_WITH_BOW, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, - "Dodongo\'s Cavern Stairs with Bow", "DCStaBow", - "The Bow can be used to knock down the stairs with two well-timed shots."); - OPT_TRICK(RT_DC_SLINGSHOT_SKIP, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::EXPERT }, - "Dodongo\'s Cavern Child Slingshot Skips", "DCSliSkp", - "With precise platforming, child can cross the platforms while the flame circles are there. When " - "enabling this trick, it's recommended that you also enable the Adult variant: \"Dodongo's Cavern Spike " - "Trap Room Jump without Hover Boots\"."); - OPT_TRICK(RT_DC_SCRUB_ROOM, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, - "Dodongo\'s Cavern Two Scrub Room with Strength", "DCSrbStr", - "With help from a conveniently-positioned block, Adult can quickly carry a Bomb Flower over to destroy " - "the mud wall blocking the room with two Deku Scrubs."); - OPT_TRICK(RT_DC_HAMMER_FLOOR, RCQUEST_BOTH, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, - "Dodongo\'s Cavern Smash the Boss Lobby Floor", "KDHamFl", - "The bombable floor before King Dodongo can be destroyed with Hammer if hit in the very center. This is " - "only relevant with Shuffle Boss Entrances or if Dodongo's Cavern is MQ and either variant of " - "\"Dodongo's Cavern MQ Light the Eyes with Strength\" is on."); - OPT_TRICK(RT_DC_DODONGO_CHU, RCQUEST_BOTH, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, - "Dodongo\'s Cavern Dodongo with Only Bombchus", "KDChu", - "With precise timing you can feed King Dodongo a bombchu during a backflip"); - OPT_TRICK(RT_DC_MQ_STAIRS_WITH_ONLY_STRENGTH, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, - "Dodongo\'s Cavern MQ Stairs With Only Strength", "DCStaStr", - "Taking a bomb from the back can be used to lower stairs without using stick to drop bomb from wall."); - OPT_TRICK(RT_DC_MQ_CHILD_BOMBS, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, - "Dodongo\'s Cavern MQ Early Bomb Bag Area as Child", "DCLobyJS", - "With a precise jumpslash from above, you can reach the Bomb Bag area as only child without needing a " - "Slingshot. You will take fall damage."); - OPT_TRICK(RT_DC_MQ_CHILD_EYES, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::EXPERT }, - "Dodongo\'s Cavern MQ Light the Eyes with Strength as Child", "DCEyeStrC", - "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the " - "eyes. To perform this trick as child is significantly more difficult than adult. The player is also " - "expected to complete the DC back area without explosives, including getting past the Armos wall to the " - "switch for the boss door."); - OPT_TRICK( - RT_DC_MQ_ADULT_EYES, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, - "Dodongo\'s Cavern MQ Light the Eyes with Strength as Adult", "DCEyeStrA", - "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes."); - OPT_TRICK( - RT_DC_EYES_CHU, RCQUEST_BOTH, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, - "Dodongo\'s Cavern Light the Eyes with Bombchus", "DCEyeChu", - "You can light the dodongo head's eyes with bombchus from the main room, allowing instant access to the end " - "of the dungeon."); - OPT_TRICK(RT_JABU_BOSS_HOVER, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE }, - "Jabu Near Boss Room with Hover Boots", "JbuBoxHB", - "A box for the blue switch can be carried over by backwalking with one while the elevator is at its " - "peak. Alternatively, you can skip transporting a box by quickly rolling from the switch and opening the " - "door before it closes. However, the timing for this is very tight."); - OPT_TRICK( - RT_JABU_NEAR_BOSS_RANGED, RCQUEST_BOTH, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, - "Jabu Near Boss Ceiling Switch/GS without Boomerang or Explosives", "JbuBosPrj", - "Vanilla Jabu: From near the entrance into the room, you can hit the switch that opens the door to the boss " - "room using a precisely-aimed use of the Slingshot, Bow, or Longshot. As well, if you climb to the top of the " - "vines you can stand on the right edge of the platform and shoot around the glass. From this distance, even " - "the Hookshot can reach the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled. MQ " - "Jabu: A Gold Skulltula Token can be collected with Longshot using the same methods as hitting the switch in " - "Vanilla."); + // decoupled from rando + + // OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::NOVICE }); + + OPT_TRICK(RT_HW_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, "RvrSand"); + OPT_TRICK(RT_LENS_HW, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, "HWNoLoT"); + OPT_TRICK(RT_HW_REVERSE, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, "RevHW"); + OPT_TRICK(RT_COLOSSUS_GS, RCQUEST_BOTH, RA_DESERT_COLOSSUS, { Tricks::Tag::NOVICE }, "ColGSHS"); + OPT_TRICK(RT_DEKU_BASEMENT_GS, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, "DTGSJS"); + OPT_TRICK(RT_DEKU_B1_SKIP, RCQUEST_BOTH, RA_DEKU_TREE, { Tricks::Tag::INTERMEDIATE }, "B1Skip"); + OPT_TRICK(RT_DEKU_B1_BOW_WEBS, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, "DTWebBow"); + OPT_TRICK(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, "DTLogBF"); + OPT_TRICK(RT_DEKU_MQ_COMPASS_GS, RCQUEST_MQ, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, "DTGSHam"); + OPT_TRICK(RT_DEKU_MQ_LOG, RCQUEST_MQ, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, "DTLogRol"); + OPT_TRICK(RT_DC_SCARECROW_GS, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, "DCArmos"); + OPT_TRICK(RT_DC_VINES_GS, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, "DCGSLS"); + OPT_TRICK(RT_DC_STAIRS_WITH_BOW, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, "DCStaBow"); + OPT_TRICK(RT_DC_SLINGSHOT_SKIP, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::EXPERT }, "DCSliSkp"); + OPT_TRICK(RT_DC_SCRUB_ROOM, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, "DCSrbStr"); + OPT_TRICK(RT_DC_HAMMER_FLOOR, RCQUEST_BOTH, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, "KDHamFl"); + OPT_TRICK(RT_DC_DODONGO_CHU, RCQUEST_BOTH, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, "KDChu"); + OPT_TRICK(RT_DC_MQ_STAIRS_WITH_ONLY_STRENGTH, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, "DCStaStr"); + OPT_TRICK(RT_DC_MQ_CHILD_BOMBS, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, "DCLobyJS"); + OPT_TRICK(RT_DC_MQ_CHILD_EYES, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::EXPERT }, "DCEyeStrC"); + OPT_TRICK(RT_DC_MQ_ADULT_EYES, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, "DCEyeStrA"); + OPT_TRICK(RT_DC_EYES_CHU, RCQUEST_BOTH, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, "DCEyeChu"); + OPT_TRICK(RT_JABU_BOSS_HOVER, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE }, "JbuBoxHB"); + OPT_TRICK(RT_JABU_NEAR_BOSS_RANGED, RCQUEST_BOTH, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, "JbuBosPrj"); OPT_TRICK(RT_JABU_NEAR_BOSS_EXPLOSIVES, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE }, - "Jabu Near Boss Ceiling Switch with Explosives", "JbuBosExp", - "You can hit the switch that opens the door to the boss room using a precisely-aimed Bombchu. Also, " - "using the Hover Boots, adult can throw a Bomb at the switch. This trick is only relevant if \"Shuffle " - "Boss Entrances\" is enabled."); - OPT_TRICK(RT_JABU_B1_CUBE_HOVER, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, - "Jabu B1 Pass Cube with Hover Boots", "JbuJigHB", - "It's possible reach pots past cube with only hover boots."); - OPT_TRICK(RT_LENS_JABU_MQ, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, - "Jabu MQ without Lens of Truth", "JbuLoT", "Removes the requirements for the Lens of Truth in Jabu MQ."); - OPT_TRICK(RT_JABU_MQ_RANG_JUMP, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::ADVANCED }, - "Jabu MQ Compass Chest with Boomerang", "JbuSwtRng", - "Boomerang can reach the cow switch to spawn the chest by targeting the cow, jumping off of the ledge " - "where the chest spawns, and throwing the Boomerang in midair."); - OPT_TRICK(RT_JABU_MQ_SOT_GS, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE }, - "Jabu MQ Song of Time Block GS with Boomerang", "JbuSoTRng", - "Allow the Boomerang to return to you through the Song of Time block to grab the token."); - OPT_TRICK(RT_JABU_BARINADE_POTS, RCQUEST_BOTH, RA_JABU_JABUS_BELLY, { Tricks::Tag::ADVANCED }, - "Jabu Barinade with Pots", "BariPot", - "Barinade can be damaged with pots, requiring only boomerang to defeat."); - OPT_TRICK(RT_LENS_BOTW, RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, - "Bottom of the Well without Lens of Truth", "BWLoT", - "Removes the requirements for the Lens of Truth in Bottom of the Well."); + "JbuBosExp"); + OPT_TRICK(RT_JABU_B1_CUBE_HOVER, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, "JbuJigHB"); + OPT_TRICK(RT_LENS_JABU_MQ, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, "JbuLoT"); + OPT_TRICK(RT_JABU_MQ_RANG_JUMP, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::ADVANCED }, "JbuSwtRng"); + OPT_TRICK(RT_JABU_MQ_SOT_GS, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE }, "JbuSoTRng"); + OPT_TRICK(RT_JABU_BARINADE_POTS, RCQUEST_BOTH, RA_JABU_JABUS_BELLY, { Tricks::Tag::ADVANCED }, "BariPot"); + OPT_TRICK(RT_LENS_BOTW, RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, "BWLoT"); OPT_TRICK(RT_BOTTOM_OF_THE_WELL_NAVI_DIVE, RCQUEST_BOTH, RA_BOTTOM_OF_THE_WELL, - { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "Bottom of the Well Navi dive", "KakNviD", - "You need Deku Sticks or Kokiri Sword to dive with Navi for entering Bottom of the Well."); - OPT_TRICK(RT_BOTW_CHILD_DEADHAND, RCQUEST_BOTH, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, - "Child Dead Hand without Kokiri Sword", "DHDiff", "Requires 9 sticks or 5 jumpslashes."); - OPT_TRICK(RT_BOTW_BASEMENT, RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, - "Bottom of the Well Map Chest with Strength & Sticks", "BWBmbFl", - "The chest in the basement can be reached with strength by doing a jumpslash with a lit stick to access " - "the Bomb Flowers."); + { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "KakNviD"); + OPT_TRICK(RT_BOTW_CHILD_DEADHAND, RCQUEST_BOTH, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, "DHDiff"); + OPT_TRICK(RT_BOTW_BASEMENT, RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, "BWBmbFl"); // RANDOTODO with doorsanity, this can be relevant in Vanilla - OPT_TRICK(RT_BOTW_PITS, RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, - "Bottom of the Well MQ Jump Over the Pits", "BWPitJmp", - "While the pits in Bottom of the Well don't allow you to jump just by running straight at them, you can " - "still get over them by side-hopping or backflipping across. With explosives, this allows you to access " - "the central areas without Zelda's Lullaby. With Zelda's Lullaby, it allows you to access the west inner " - "room without explosives."); - OPT_TRICK(RT_BOTW_MQ_DEADHAND_KEY, RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, - "Bottom of the Well MQ Dead Hand Freestanding Key with Boomerang", "BWKeyRng", - "Boomerang can fish the item out of the rubble without needing explosives to blow it up."); - OPT_TRICK(RT_FOREST_FIRST_GS, RCQUEST_VANILLA, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Forest Temple First Room GS with Difficult-to-Use Weapons", "FT1stGS", - "Allows killing this Skulltula with Sword or Sticks by jumpslashing it as you let go from the vines. " - "You can avoid taking fall damage by recoiling onto the tree. Also allows killing it as Child with a " - "Bomb throw. It's much more difficult to use a Bomb as child due to Child Link's shorter height."); - OPT_TRICK(RT_FOREST_COURTYARD_EAST_GS, RCQUEST_VANILLA, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Forest Temple East Courtyard GS with Boomerang", "FTGSRng", - "Precise Boomerang throws can allow child to kill the Skulltula and collect the token."); - OPT_TRICK(RT_FOREST_VINES, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Forest Temple East Courtyard Vines with Hookshot", "FTVineHS", - "The vines in Forest Temple leading to where the well drain switch is in the standard form can be barely " - "reached with just the Hookshot. Applies to MQ also."); - OPT_TRICK(RT_FOREST_COURTYARD_LEDGE, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Forest Temple NE Courtyard Ledge with Hover Boots", "FTLdgHB", - "With precise Hover Boots movement you can fall down to this ledge from upper balconies. If done " - "precisely enough, it is not necessary to take fall damage. In MQ, this skips a Longshot requirement. In " - "Vanilla, this can skip a Hookshot requirement in entrance randomizer."); - OPT_TRICK(RT_FOREST_DOORFRAME, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::ADVANCED }, - "Forest Temple East Courtyard Door Frame with Hover Boots", "FTDoorHB", - "A precise Hover Boots movement from the upper balconies in this courtyard can be used to get on top of " - "the door frame. Applies to both Vanilla and Master Quest. In Vanilla, from on top the door frame you " - "can summon Pierre, allowing you to access the falling ceiling room early. In Master Quest, this allows " - "you to obtain the GS on the door frame as adult without Hookshot or Song of Time."); - OPT_TRICK(RT_FOREST_OUTSIDE_BACKDOOR, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::ADVANCED }, - "Forest Temple Outside Backdoor with Jumpslash", "FTBlkJS", - "A jumpslash recoil can be used to reach the ledge in the block puzzle room that leads to the west " - "courtyard. This skips a potential Hover Boots requirement in Vanilla, and it can sometimes apply in MQ " - "as well. This trick can be performed as both ages."); + OPT_TRICK(RT_BOTW_PITS, RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, "BWPitJmp"); + OPT_TRICK(RT_BOTW_MQ_DEADHAND_KEY, RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, "BWKeyRng"); + OPT_TRICK(RT_FOREST_FIRST_GS, RCQUEST_VANILLA, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, "FT1stGS"); + OPT_TRICK(RT_FOREST_COURTYARD_EAST_GS, RCQUEST_VANILLA, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, "FTGSRng"); + OPT_TRICK(RT_FOREST_VINES, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, "FTVineHS"); + OPT_TRICK(RT_FOREST_COURTYARD_LEDGE, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, "FTLdgHB"); + OPT_TRICK(RT_FOREST_DOORFRAME, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::ADVANCED }, "FTDoorHB"); + OPT_TRICK(RT_FOREST_OUTSIDE_BACKDOOR, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::ADVANCED }, "FTBlkJS"); OPT_TRICK(RT_FOREST_COURTYARD_HEARTS_BOOMERANG, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Forest Temple Courtyard Hearts with Boomerang", "FTHrtRng", - "A well aimed boomerang from the water's edge can reach the hearts from ground level. If unable to swim, " - "you can back away from the water while the boomerang is returning so the hearts land on the ground."); - OPT_TRICK(RT_FOREST_WELL_SWIM, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Swim Through Forest Temple Well with Hookshot", "FTSwim", - "Shoot the vines in the well as low and as far to the right as possible, and then immediately swim under " - "the ceiling to the right. This is usually only useful in Master Quest."); - OPT_TRICK(RT_FOREST_MQ_BLOCK_PUZZLE, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Skip Forest Temple MQ Block Puzzle with Bombchu", "FTBlkChu", - "Send the Bombchu straight up the center of the wall directly to the left upon entering the room."); + "FTHrtRng"); + OPT_TRICK(RT_FOREST_WELL_SWIM, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, "FTSwim"); + OPT_TRICK(RT_FOREST_MQ_BLOCK_PUZZLE, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, "FTBlkChu"); // Child with hovers cannot do this from the lower floor, and must go to the upper floor which needs goron bracelet. // Adult can do this with hammer and KSword, But child cannot. - OPT_TRICK(RT_FOREST_MQ_JS_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Forest Temple MQ Twisted Hallway Switch with Jumpslash", "FTTwstJS", - "The switch to twist the hallway can be hit with a jumpslash through the glass block. To get in front " - "of the switch, either use the Hover Boots or hit the shortcut switch at the top of the room and jump " - "from the glass blocks that spawn. Sticks can be used as child, but the Kokiri Sword is too short to " - "reach through the glass."); + OPT_TRICK(RT_FOREST_MQ_JS_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, "FTTwstJS"); OPT_TRICK(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Forest Temple MQ Twisted Hallway Switch with Hookshot", "FTTwstHS", - "There's a very small gap between the glass block and the wall. Through that gap you can hookshot the " - "target on the ceiling."); + "FTTwstHS"); OPT_TRICK(RT_FOREST_MQ_RANG_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Forest Temple MQ Twisted Hallway Switch with Boomerang", "FTTwstRng", - "The Boomerang can return to Link through walls, allowing child to hit the hallway switch. This can be " - "used to allow adult to pass through later, or in conjunction with \"Forest Temple Outside Backdoor with " - "Jumpslash\"."); - OPT_TRICK(RT_FOREST_MQ_CHILD_DOORFRAME, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, - "Forest Temple MQ Doorframe GS as Child without Boomerang", "FTDoorC", - "If Adult burns the courtyard webbing with Fire Arrows (which is a permanent flag in Ship Rando) " - "then Child can climb up to the balconies and jump to the SoT block from the railing, " - "and from there either roll jump or jump against the wall to reach the doorframe.\n" - "From there, The GS can be killed with a crouchstab, explosives or other ranged weapon " - "and collected by climbing down."); + "FTTwstRng"); + OPT_TRICK(RT_FOREST_MQ_CHILD_DOORFRAME, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, "FTDoorC"); // Is also used in MQ logic, but has no practical effect there as of now - OPT_TRICK(RT_FIRE_SOT, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Fire Temple Song of Time Room GS without Song of Time", "FISoTSkp", - "A precise jump can be used to reach this room."); - OPT_TRICK(RT_FIRE_STRENGTH, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Fire Temple Climb without Strength", "FIStrSkp", - "A precise jump can be used to skip pushing the block."); - OPT_TRICK(RT_FIRE_SCARECROW, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::EXPERT }, - "Fire Temple East Tower without Scarecrow\'s Song", "PixelShot", - "Also known as \"Pixelshot\". The Longshot can reach the target on the elevator itself, allowing you to " - "skip needing to spawn the scarecrow."); - OPT_TRICK(RT_FIRE_SKIP_FLAME_WALLS, RCQUEST_BOTH, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Fire Temple Skip Flame Walls", "FIRWAL", - "If you move quickly you can sneak past the edge of a flame wall before rises up to block you. To " - "do it without taking damage is more precise. Allows progress without needing either a Small Key or " - "Hover Boots. In MQ if either \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" or " - "\"with Precise Jump\" are enabled, this also allows progress deeper into the dungeon without Hookshot.\n" - "Child can sidehop past fire wall in MQ lobby."); - OPT_TRICK(RT_FIRE_MQ_NEAR_BOSS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, - "Fire Temple MQ Chest Near Boss without Breaking Crate", "FICrtTor", - "The hitbox for the torch extends a bit outside of the crate. Shoot a flaming arrow at the side of the " - "crate to light the torch without needing to get over there and break the crate."); - OPT_TRICK(RT_FIRE_MQ_BLOCKED_CHEST, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Fire Temple MQ Big Lava Room Blocked Door without Hookshot", "FIHSSkp", - "There is a gap between the hitboxes of the flame wall in the big lava room. If you know where this gap " - "is located, you can jump through it and skip needing to use the Hookshot. To do this without taking " - "damage is more precise."); - OPT_TRICK( - RT_FIRE_MQ_BK_CHEST, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Fire Temple MQ Boss Key Chest without Bow", "FIBowSkp", - "It is possible to light both of the timed torches to unbar the door to the boss key chest's room with just " - "Din's Fire if you move very quickly between the two torches. It is also possible to unbar the door with just " - "Din's Fire by abusing an oversight in the way the game counts how many torches have been lit."); - OPT_TRICK(RT_FIRE_MQ_CLIMB, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, - "Fire Temple MQ Climb without Fire Source", "FIFirSkp", - "You can use the Hover Boots to hover around to the climbable wall, skipping the need to use a fire " - "source and spawn a Hookshot target."); - OPT_TRICK(RT_FIRE_MQ_MAZE_SIDE_ROOM, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, - "Fire Temple MQ Lizalfos Maze Side Room without Box", "FIBoxSkp", - "You can walk from the blue switch to the door and quickly open the door before the bars reclose. This " - "skips needing to reach the upper sections of the maze to get a box to place on the switch."); - OPT_TRICK(RT_FIRE_MQ_MAZE_HOVERS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, - "Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots", "FIMazHB", - "Use the Hover Boots off of a crate to climb to the upper maze without needing to spawn and use the " - "Hookshot targets."); - OPT_TRICK(RT_FIRE_MQ_MAZE_JUMP, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Fire Temple MQ Lower to Upper Lizalfos Maze with Precise Jump", "FIMazJmp", - "A precise jump off of a crate can be used to climb to the upper maze without needing to spawn and use " - "the Hookshot targets. This trick supersedes both \"Fire Temple MQ Lower to Upper Lizalfos Maze with " - "Hover Boots\" and \"Fire Temple MQ Lizalfos Maze Side Room without Box\"."); - OPT_TRICK(RT_FIRE_MQ_ABOVE_MAZE_GS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Fire Temple MQ Above Flame Wall Maze GS from Below with Longshot", "FIGSLS", - "The floor of the room that contains this Skulltula is only solid from above. From the maze below, the " - "Longshot can be shot through the ceiling to obtain the token with two fewer small keys than normal."); - OPT_TRICK(RT_WATER_LONGSHOT_TORCH, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple Torch Longshot", "WTTorLS", - "Stand on the eastern side of the central pillar and longshot the torches on the bottom level. Swim " - "through the corridor and float up to the top level. This allows access to this area and lower water " - "levels without Iron Boots. The majority of the tricks that allow you to skip Iron Boots in the Water " - "Temple are not going to be relevant unless this trick is first enabled."); - OPT_TRICK(RT_WATER_CRACKED_WALL_HOVERS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple Cracked Wall with Hover Boots", "WTCrkHB", - "With a midair side-hop while wearing the Hover Boots, you can reach the cracked wall without needing to " - "raise the water up to the middle level."); - OPT_TRICK(RT_WATER_CRACKED_WALL, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Water Temple Cracked Wall with No Additional Items", "WTCrkJmp", - "A precise jumpslash (among other methods) will get you to the cracked wall without needing the Hover " - "Boots or to raise the water to the middle level. This trick supersedes \"Water Temple Cracked Wall with " - "Hover Boots\"."); - OPT_TRICK(RT_WATER_BK_REGION, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Water Temple Boss Key Region with Hover Boots", "WTBKHB", - "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing " - "the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the " - "following room can also be obtained with just the Hover Boots."); + OPT_TRICK(RT_FIRE_SOT, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FISoTSkp"); + OPT_TRICK(RT_FIRE_STRENGTH, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FIStrSkp"); + OPT_TRICK(RT_FIRE_SCARECROW, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::EXPERT }, "PixelShot"); + OPT_TRICK(RT_FIRE_SKIP_FLAME_WALLS, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FIRWAL"); + OPT_TRICK(RT_FIRE_MQ_NEAR_BOSS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, "FICrtTor"); + OPT_TRICK(RT_FIRE_MQ_BLOCKED_CHEST, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FIHSSkp"); + OPT_TRICK(RT_FIRE_MQ_BK_CHEST, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FIBowSkp"); + OPT_TRICK(RT_FIRE_MQ_CLIMB, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, "FIFirSkp"); + OPT_TRICK(RT_FIRE_MQ_MAZE_SIDE_ROOM, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, "FIBoxSkp"); + OPT_TRICK(RT_FIRE_MQ_MAZE_HOVERS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, "FIMazHB"); + OPT_TRICK(RT_FIRE_MQ_MAZE_JUMP, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FIMazJmp"); + OPT_TRICK(RT_FIRE_MQ_ABOVE_MAZE_GS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FIGSLS"); + OPT_TRICK(RT_WATER_LONGSHOT_TORCH, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTTorLS"); + OPT_TRICK(RT_WATER_CRACKED_WALL_HOVERS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTCrkHB"); + OPT_TRICK(RT_WATER_CRACKED_WALL, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "WTCrkJmp"); + OPT_TRICK(RT_WATER_BK_REGION, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "WTBKHB"); OPT_TRICK(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Water Temple North Basement Ledge with Precise Jump", "WTBolLdg", - "In the northern basement there's a ledge from where, in Vanilla Water Temple, boulders roll out into " - "the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise " - "jump, it can be done without them. This trick applies to both Vanilla and Master Quest."); + "WTBolLdg"); // Also used in MQ logic, but won't be relevent unless a way to enter tower without irons exists (likely a clip + // swim) - OPT_TRICK(RT_WATER_FW_CENTRAL_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple Central Pillar GS with Farore\'s Wind", "WTGSFW", - "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the " - "water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang."); - OPT_TRICK( - RT_WATER_IRONS_CENTRAL_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple Central Pillar GS with Iron Boots", "WTGSIB", - "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you " - "do not leave the room, even if you were to raise the water up to the highest level. With the Iron Boots to go " - "through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot."); - OPT_TRICK(RT_WATER_CENTRAL_BOW, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::ADVANCED }, - "Water Temple Central Bow Target without Longshot or Hover Boots", "WTBowJmp", - "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the " - "hallway and make through it before the gate closes. It can also be done as child, using the Slingshot " - "instead of the Bow."); - OPT_TRICK( - RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple Falling Platform Room GS with Hookshot", "WTWfalHS", - "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Hookshot."); - OPT_TRICK( - RT_WATER_RANG_FALLING_PLATFORM_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Water Temple Falling Platform Room GS with Boomerang", "WTWfalRng", - "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Boomerang."); - OPT_TRICK(RT_WATER_RIVER_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Water Temple River GS without Iron Boots", "WTRvrLS", - "Standing on the exposed ground toward the end of the river, a precise Longshot use can obtain the " - "token. The Longshot cannot normally reach far enough to kill the Skulltula, however. You'll first have " - "to find some other way of killing it."); - OPT_TRICK(RT_WATER_DRAGON_JUMP_DIVE, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple Dragon Statue Jump Dive", "WTDrgJmp", - "If you come into the dragon statue room from the serpent river, you can sidehop down from above and get " - "into the tunnel without needing either Iron Boots or a Scale. This trick applies to both Vanilla and " - "Master Quest. In Vanilla, you must shoot the switch from above with the Bow, and then quickly get " - "through the tunnel before the gate closes."); - OPT_TRICK(RT_WATER_ADULT_DRAGON, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple Dragon Statue Switch from Above the Water as Adult", "WTDrgA", - "Normally you need both Hookshot and Iron Boots to hit the switch and swim through the tunnel to get to " - "the chest. But by hitting the switch from dry land, using one of Bombchus, Hookshot, or Bow, it is " - "possible to skip one or both of those requirements. After the gate has been opened, besides just using " - "the Iron Boots, a well-timed dive with at least the Silver Scale could be used to swim through the " - "tunnel. If coming from the serpent river, a jump dive can also be used to get into the tunnel."); - OPT_TRICK(RT_WATER_CHILD_DRAGON, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::ADVANCED }, - "Water Temple Dragon Statue Switch from Above the Water as Child", "WTDrgC", - "It is possible for child to hit the switch from dry land using one of Bombchus, Slingshot or Boomerang. " - "Then, to get to the chest, child can dive through the tunnel using at least the Silver Scale. The " - "timing and positioning of this dive needs to be perfect to actually make it under the gate, and it all " - "needs to be done very quickly to be able to get through before the gate closes. Be sure to enable " - "\"Water Temple Dragon Statue Switch from Above the Water as Adult\" for adult's variant of this trick."); - OPT_TRICK(RT_WATER_MQ_CENTRAL_PILLAR, RCQUEST_MQ, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple MQ Central Pillar with Fire Arrows", "WTCntFA", - "Slanted torches have misleading hitboxes. Whenever you see a slanted torch jutting out of the wall, you " - "can expect most or all of its hitbox is actually on the other side that wall. This can make slanted " - "torches very finicky to light when using arrows. The torches in the central pillar of MQ Water Temple " - "are a particularly egregious example. Logic normally expects Din's Fire and Song of Time."); - OPT_TRICK( - RT_WATER_IRON_BOOTS_LEDGE_GRAB, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, - "Water Temple Ledge Grab While Surfacing with Iron Boots", "IBSrfLG", - "Diving in front of ledge tapping B to swim up faster, then equipping iron boots while surfacing allows you to " - "ledge grab to the higher ground. This can be used to reach ledge to boss door and vanilla compass chest, or " - "MQ storage room"); - OPT_TRICK(RT_WATER_INVISIBLE_HOOKSHOT_TARGET, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, - "Water Temple Invisible Hookshot Target", "WTTarg", - "Invisible hookshot geometry can be used in MQ to get over the gate that blocks you from going to this " - "Skulltula early, skipping a small key as well as needing Hovers or Scarecrow to reach the locked door.\n" - "In vanilla this can be used to get past without bronze scale."); - OPT_TRICK(RT_WATER_MORPHA_WITHOUT_HOOKSHOT, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::EXTREME }, - "Water Temple Morpha without Hookshot", "MorphDiff", - "It is possible to slash at Morpha without hookshot."); - OPT_TRICK(RT_LENS_SHADOW, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, - "Shadow Temple Stationary Objects without Lens of Truth", "STStLoT", - "Removes the requirements for the Lens of Truth in Shadow Temple for most areas in the dungeon except " - "for crossing the moving platform in the huge pit room and for fighting Bongo Bongo."); - OPT_TRICK(RT_LENS_SHADOW_PLATFORM, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, - "Shadow Temple Invisible Moving Platform without Lens of Truth", "STMvLot", - "Removes the requirements for the Lens of Truth in Shadow Temple to cross the invisible moving platform " - "in the huge pit room in either direction."); - OPT_TRICK(RT_LENS_BONGO, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, - "Shadow Temple Bongo Bongo without Lens of Truth", "BNGLoT", - "Bongo Bongo can be defeated without the use of Lens of Truth, as the hands give a pretty good idea of " - "where the eye is."); - OPT_TRICK(RT_SHADOW_UMBRELLA_HOVER, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, - "Shadow Temple Stone Umbrella Skip", "STUmbSkp", - "A very precise Hover Boots movement from off of the lower chest can get you on top of the falling " - "spikes without needing to pull the block. Applies to both Vanilla and Master Quest."); + OPT_TRICK(RT_WATER_FW_CENTRAL_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTGSFW"); + OPT_TRICK(RT_WATER_IRONS_CENTRAL_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTGSIB"); + OPT_TRICK(RT_WATER_CENTRAL_BOW, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::ADVANCED }, "WTBowJmp"); + OPT_TRICK(RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "WTWfalHS"); + OPT_TRICK(RT_WATER_RANG_FALLING_PLATFORM_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "WTWfalRng"); + OPT_TRICK(RT_WATER_RIVER_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "WTRvrLS"); + OPT_TRICK(RT_WATER_DRAGON_JUMP_DIVE, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTDrgJmp"); + OPT_TRICK(RT_WATER_ADULT_DRAGON, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTDrgA"); + OPT_TRICK(RT_WATER_CHILD_DRAGON, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::ADVANCED }, "WTDrgC"); + OPT_TRICK(RT_WATER_MQ_CENTRAL_PILLAR, RCQUEST_MQ, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTCntFA"); + OPT_TRICK(RT_WATER_IRON_BOOTS_LEDGE_GRAB, RCQUEST_BOTH, RA_WATER_TEMPLE, + { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "IBSrfLG"); + OPT_TRICK(RT_WATER_INVISIBLE_HOOKSHOT_TARGET, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTTarg"); + OPT_TRICK(RT_WATER_MORPHA_WITHOUT_HOOKSHOT, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::EXTREME }, "MorphDiff"); + OPT_TRICK(RT_LENS_SHADOW, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "STStLoT"); + OPT_TRICK(RT_LENS_SHADOW_PLATFORM, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "STMvLot"); + OPT_TRICK(RT_LENS_BONGO, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "BNGLoT"); + OPT_TRICK(RT_SHADOW_UMBRELLA_HOVER, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, "STUmbSkp"); OPT_TRICK(RT_SHADOW_UMBRELLA_CLIP, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, - "Shadow Temple Stone Umbrella Clip", "STUmbClp", - "Backflipping as the falling spikes fall clips above without needing any other requirements. " - "Applies to both Vanilla and Master Quest."); - OPT_TRICK(RT_SHADOW_UMBRELLA_GS, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, - "Shadow Temple Falling Spikes GS with Hover Boots", "STUmbHB", - "After killing the Skulltula, a very precise Hover Boots movement from off of the lower chest can get " - "you on top of the falling spikes without needing to pull the block. From there, another very precise " - "Hover Boots movement can be used to obtain the token without needing the Hookshot. Applies to both " - "Vanilla and Master Quest."); - OPT_TRICK(RT_SHADOW_FREESTANDING_KEY, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, - "Shadow Temple Freestanding Key with Bombchu", "STPotChu", - "Release the Bombchu with good timing so that it explodes near the bottom of the pot."); - OPT_TRICK(RT_SHADOW_STATUE, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Shadow Temple River Statue with Bombchu", "STStaChu", - "By sending a Bombchu around the edge of the gorge, you can knock down the statue without needing a Bow. " - "Applies in both Vanilla and MQ Shadow."); - OPT_TRICK(RT_SHADOW_BONGO, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Shadow Temple Bongo Bongo without projectiles", "BngNoPrg", - "Using precise sword slashes, Bongo Bongo can be defeated without using projectiles. This is only " - "relevant in conjunction with Shadow Temple dungeon shortcuts or shuffled boss entrances."); - OPT_TRICK(RT_LENS_SHADOW_MQ, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, - "Shadow Temple MQ Stationary Objects without Lens of Truth", "STMQStLoT", - "Removes the requirements for the Lens of Truth in Shadow Temple MQ for most areas in the dungeon. See " - "\"Shadow Temple MQ Invisible Moving Platform without Lens of Truth\", \"Shadow Temple MQ Invisible " - "Blades Silver Rupees without Lens of Truth\", \"Shadow Temple MQ 2nd Dead Hand without Lens of Truth\", " - "and \"Shadow Temple Bongo Bongo without Lens of Truth\" for exceptions."); - OPT_TRICK(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, - "Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth", "STBldLoT", - "Removes the requirement for the Lens of Truth or Nayru's Love in Shadow Temple MQ for the Invisible " - "Blades room Silver Rupee collection."); - OPT_TRICK(RT_LENS_SHADOW_MQ_PLATFORM, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, - "Shadow Temple MQ Invisible Moving Platform without Lens of Truth", "STMQMvLot", - "Removes the requirements for the Lens of Truth in Shadow Temple MQ to cross the invisible moving " - "platform in the huge pit room in either direction."); - OPT_TRICK(RT_LENS_SHADOW_MQ_DEADHAND, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, - "Shadow Temple MQ 2nd Dead Hand without Lens of Truth", "STDHLoT", - "Dead Hand spawns in a random spot within the room. Having Lens removes the hassle of having to comb the " - "room looking for his spawn location."); - OPT_TRICK(RT_SHADOW_MQ_GAP, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Shadow Temple MQ Truth Spinner Gap with Longshot", "STTSLS", - "You can Longshot a torch and jump-slash recoil onto the tongue. It works best if you Longshot the right " - "torch from the left side of the room."); - OPT_TRICK( - RT_SHADOW_MQ_INVISIBLE_BLADES, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Shadow Temple MQ Invisible Blades without Song of Time", "STSoTSkp", - "The Like Like can be used to boost you into the Silver Rupee or Recovery Hearts that normally require Song of " - "Time. This cannot be performed on OHKO since the Like Like does not boost you high enough if you die."); - OPT_TRICK(RT_SHADOW_MQ_HUGE_PIT, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Shadow Temple MQ Lower Huge Pit without Fire Source", "STPitJmp", - "Normally a frozen eye switch spawns some platforms that you can use to climb down, but there's actually " - "a small piece of ground that you can stand on that you can just jump down to."); - OPT_TRICK( - RT_SHADOW_MQ_WINDY_WALKWAY, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Shadow Temple MQ Windy Walkway Reverse without Hover Boots", "STWindSkp", - "It is possible to jump from the alcove in the windy hallway to the middle platform. There are two methods: " - "wait out the fan opposite the door and hold forward, or jump to the right to be pushed by the fan there " - "towards the platform ledge. Note that jumps of this distance are inconsistent, but still possible."); - OPT_TRICK(RT_LENS_SPIRIT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, - "Spirit Temple without Lens of Truth", "SPLoT", - "Removes the requirements for the Lens of Truth in Spirit Temple."); - OPT_TRICK(RT_SPIRIT_CHILD_CHU, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, - "Spirit Temple Child Side Bridge with Bombchu", "SPBrgChu", - "A carefully-timed Bombchu can hit the switch."); - OPT_TRICK(RT_SPIRIT_WEST_LEDGE, RCQUEST_BOTH, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, - "Spirit Temple Statue Room West Ledge Checks with Boomerang", "SPWeRng", - "By carefully walking onto the upper arm of the statue, it's possible to get a good angle on the " - "Gold Skulltula (In Vanilla) and the farthest pot (In MQ) to collect the checks with Boomerang. " - "The nearest pot in MQ can be reached from the forearm and is always in logic."); - OPT_TRICK(RT_SPIRIT_LOWER_ADULT_SWITCH, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::ADVANCED }, - "Spirit Temple Lower Adult Switch with Bombs", "SPSwtBmb", - "A bomb can be used to hit the switch on the ceiling, but it must be thrown from a particular distance " - "away and with precise timing."); - OPT_TRICK( - RT_SPIRIT_STATUE_JUMP, RCQUEST_BOTH, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Spirit Temple Statue Room Jump from Hands to Upper Ledges", "SPHndJmp", - "A precise jump to obtain the following as adult without needing one of Hover Boots, or Hookshot (in Vanilla) " - "or Song of Time (in MQ): - Spirit Temple Statue Room Northeast Chest - Spirit Temple GS Lobby - Spirit Temple " - "MQ Central Chamber Top Left Pot (Left) - Spirit Temple MQ Central Chamber Top Left Pot (Right)"); + "STUmbClp"); + OPT_TRICK(RT_SHADOW_UMBRELLA_GS, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, "STUmbHB"); + OPT_TRICK(RT_SHADOW_FREESTANDING_KEY, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "STPotChu"); + OPT_TRICK(RT_SHADOW_STATUE, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "STStaChu"); + OPT_TRICK(RT_SHADOW_BONGO, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "BngNoPrg"); + OPT_TRICK(RT_LENS_SHADOW_MQ, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "STMQStLoT"); + OPT_TRICK(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "STBldLoT"); + OPT_TRICK(RT_LENS_SHADOW_MQ_PLATFORM, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "STMQMvLot"); + OPT_TRICK(RT_LENS_SHADOW_MQ_DEADHAND, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "STDHLoT"); + OPT_TRICK(RT_SHADOW_MQ_GAP, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "STTSLS"); + OPT_TRICK(RT_SHADOW_MQ_INVISIBLE_BLADES, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "STSoTSkp"); + OPT_TRICK(RT_SHADOW_MQ_HUGE_PIT, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "STPitJmp"); + OPT_TRICK(RT_SHADOW_MQ_WINDY_WALKWAY, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "STWindSkp"); + OPT_TRICK(RT_LENS_SPIRIT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, "SPLoT"); + OPT_TRICK(RT_SPIRIT_CHILD_CHU, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, "SPBrgChu"); + OPT_TRICK(RT_SPIRIT_WEST_LEDGE, RCQUEST_BOTH, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, "SPWeRng"); + OPT_TRICK(RT_SPIRIT_LOWER_ADULT_SWITCH, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::ADVANCED }, "SPSwtBmb"); + OPT_TRICK(RT_SPIRIT_STATUE_JUMP, RCQUEST_BOTH, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "SPHndJmp"); + // disabled since "Spirit Temple boss shortcuts" (pre-lowers the platform where you break the statues face) isn't a - // setting in ship OPT_TRICK(RT_SPIRIT_PLATFORM_HOOKSHOT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, - // {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Main Room Hookshot to Boss Platform", "Precise hookshot aiming at the - // platform chains can be used to reach the boss platform from the middle landings. Using a jumpslash immediately - // after reaching a chain makes aiming more lenient. Relevant only when Spirit Temple boss shortcuts are on."); - OPT_TRICK(RT_SPIRIT_MAP_CHEST, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, - "Spirit Temple Map Chest with Bow", "SPMapBow", - "To get a line of sight from the upper torch to the map chest torches, you must pull an Armos statue all " - "the way up the stairs."); - OPT_TRICK(RT_SPIRIT_SUN_CHEST, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::ADVANCED }, - "Spirit Temple Sun Block Room Chest with Bow", "SPSUNBOW", - "Using the blocks in the room as platforms you can get lines of sight to all three torches. The timer on " - "the torches is quite short so you must move quickly in order to light all three.\n" - "A backflip can be used instead to light torches without pushing blocks."); - OPT_TRICK( - RT_SPIRIT_WALL, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Spirit Temple Shifting Wall with No Additional Items", "SPWall", - "Logic normally guarantees a way of dealing with both the Beamos and the Walltula before climbing the wall."); - OPT_TRICK(RT_LENS_SPIRIT_MQ, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, - "Spirit Temple MQ without Lens of Truth", "SPMQLoT", - "Removes the requirements for the Lens of Truth in Spirit Temple MQ."); - OPT_TRICK(RT_SPIRIT_MQ_SUN_BLOCK_SOT, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Spirit Temple MQ Sun Block Room as Child without Song of Time", "SPBluSkp", - "While adult can easily jump directly to the switch that unbars the door to the sun block room, child " - "Link cannot make the jump without spawning a Song of Time block to jump from. You can skip this by " - "throwing the crate down onto the switch from above, which does unbar the door, however the crate " - "immediately breaks, so you must move quickly to get through the door before it closes back up."); - OPT_TRICK(RT_SPIRIT_MQ_SUN_BLOCK_GS, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Spirit Temple MQ Sun Block Room GS with Boomerang", "SPBlkGS", - "Throw the Boomerang in such a way that it curves through the side of the glass block to hit the Gold " - "Skulltula."); - OPT_TRICK(RT_SPIRIT_MQ_LOWER_ADULT, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, - "Spirit Temple MQ Lower Adult without Fire Arrows", "SPTorDin", - "By standing in a precise position it is possible to light two of the torches with a single use of " - "Din\'s Fire. This saves enough time to be able to light all three torches with only Din\'s Fire."); - OPT_TRICK(RT_SPIRIT_MQ_FROZEN_EYE, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, - "Spirit Temple MQ Frozen Eye Switch without Fire", "SPFEBow", - "You can melt the ice by shooting an arrow through a torch. The only way to find a line of sight for " - "this shot is to first spawn a Song of Time block, and then stand on the very edge of it."); - OPT_TRICK(RT_ICE_STALAGMITE_CLIP, RCQUEST_BOTH, RA_ICE_CAVERN, { Tricks::Tag::NOVICE }, - "Ice Cavern Stalagmite Clips", "StalClp", - "Most stalagmites blocking path in Ice Cavern can be clipped past with basic movement. Also applies to " - "Water Trial."); - OPT_TRICK(RT_ICE_STALAGMITE_HOOKSHOT, RCQUEST_BOTH, RA_ICE_CAVERN, { Tricks::Tag::NOVICE }, - "Ice Cavern Stalagmites with Hookshot", "StalHS", - "Shooting stalagmites with hookshot in the right way also breaks them. Also applies to Water Trial."); - // RANDOTO sweep trick descriptions and make sure they match a post-refactor, post shuffles reality - OPT_TRICK(RT_ICE_BLOCK_GS, RCQUEST_VANILLA, RA_ICE_CAVERN, { Tricks::Tag::INTERMEDIATE }, - "Ice Cavern Block Room GS with Hover Boots", "ICBlkHB", - "The Hover Boots can be used to get in front of the Skulltula to kill it with a jumpslash. Then, the " - "Hover Boots can again be used to obtain the Token, all without Hookshot or Boomerang."); - OPT_TRICK(RT_ICE_MQ_RED_ICE_GS, RCQUEST_MQ, RA_ICE_CAVERN, { Tricks::Tag::INTERMEDIATE }, - "Ice Cavern MQ Red Ice GS without Song of Time", "ICNoSoT", - "If you side-hop into the perfect position, you can briefly stand on the platform with the red ice just " - "long enough to dump some blue fire."); - OPT_TRICK(RT_LENS_GTG, RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, - "Gerudo Training Ground without Lens of Truth", "GTGLoT", - "Removes the requirements for the Lens of Truth in Gerudo Training Ground."); + // setting in ship + + // OPT_TRICK(RT_SPIRIT_PLATFORM_HOOKSHOT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }); + + OPT_TRICK(RT_SPIRIT_MAP_CHEST, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, "SPMapBow"); + OPT_TRICK(RT_SPIRIT_SUN_CHEST, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::ADVANCED }, "SPSUNBOW"); + OPT_TRICK(RT_SPIRIT_WALL, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "SPWall"); + OPT_TRICK(RT_LENS_SPIRIT_MQ, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, "SPMQLoT"); + OPT_TRICK(RT_SPIRIT_MQ_SUN_BLOCK_SOT, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "SPBluSkp"); + OPT_TRICK(RT_SPIRIT_MQ_SUN_BLOCK_GS, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "SPBlkGS"); + OPT_TRICK(RT_SPIRIT_MQ_LOWER_ADULT, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "SPTorDin"); + OPT_TRICK(RT_SPIRIT_MQ_FROZEN_EYE, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, "SPFEBow"); + OPT_TRICK(RT_ICE_STALAGMITE_CLIP, RCQUEST_BOTH, RA_ICE_CAVERN, { Tricks::Tag::NOVICE }, "StalClp"); + OPT_TRICK(RT_ICE_STALAGMITE_HOOKSHOT, RCQUEST_BOTH, RA_ICE_CAVERN, { Tricks::Tag::NOVICE }, "StalHS"); + OPT_TRICK(RT_ICE_BLOCK_GS, RCQUEST_VANILLA, RA_ICE_CAVERN, { Tricks::Tag::INTERMEDIATE }, "ICBlkHB"); + OPT_TRICK(RT_ICE_MQ_RED_ICE_GS, RCQUEST_MQ, RA_ICE_CAVERN, { Tricks::Tag::INTERMEDIATE }, "ICNoSoT"); + OPT_TRICK(RT_LENS_GTG, RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, "GTGLoT"); OPT_TRICK(RT_GTG_WITHOUT_HOOKSHOT, RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::INTERMEDIATE }, - "Gerudo Training Ground Left Side Silver Rupees without Hookshot", "GTGNoHS", - "After collecting the rest of the Silver Rupees in the room, you can reach the final Silver Rupee on the " - "ceiling by being pulled up into it after getting grabbed by the Wallmaster. Then, you must also reach " - "the exit of the room without the use of the Hookshot. If you move quickly you can sneak past the edge " - "of a flame wall before it can rise up to block you. To do so without taking damage is more precise."); - OPT_TRICK(RT_GTG_FAKE_WALL, RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, - "Reach Gerudo Training Ground Fake Wall Ledge with Hover Boots", "GTGWallHB", - "A precise Hover Boots use from the top of the chest can allow you to grab the ledge without needing the " - "usual requirements. In Master Quest, this always skips a Song of Time requirement. In Vanilla, this " - "skips a Hookshot requirement, but is only relevant if \"Gerudo Training Ground Left Side Silver Rupees " - "without Hookshot\" is enabled."); - OPT_TRICK(RT_GTG_LAVA_JUMP, RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::INTERMEDIATE }, - "Gerudo Training Grounds Itemless Lava Room Jump", "GTGLavaJmp", - "A precise rolling jump can be used to jump between all but the furthest platforms in the lava room."); - OPT_TRICK(RT_LENS_GTG_MQ, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, - "Gerudo Training Ground MQ without Lens of Truth", "GTGMQLoT", - "Removes the requirements for the Lens of Truth in Gerudo Training Ground MQ."); - OPT_TRICK(RT_GTG_MQ_WITH_HOOKSHOT, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, - "Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot", "GTGMQHS", - "The highest Silver Rupee can be obtained by hookshooting the target and then immediately jumpslashing " - "toward the Rupee."); + "GTGNoHS"); + OPT_TRICK(RT_GTG_FAKE_WALL, RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, "GTGWallHB"); + OPT_TRICK(RT_GTG_LAVA_JUMP, RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::INTERMEDIATE }, "GTGLavaJmp"); + OPT_TRICK(RT_GTG_STATUE_JUMP, RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::INTERMEDIATE }, "GTGStJmp"); + OPT_TRICK(RT_LENS_GTG_MQ, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, "GTGMQLoT"); + OPT_TRICK(RT_GTG_MQ_WITH_HOOKSHOT, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, "GTGMQHS"); OPT_TRICK(RT_GTG_MQ_WITHOUT_HOOKSHOT, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::INTERMEDIATE }, - "Gerudo Training Ground MQ Left Side Silver Rupees without Hookshot", "GTGMQNoHS", - "After collecting the rest of the Silver Rupees in the room, you can reach the final Silver Rupee on the " - "ceiling by being pulled up into it after getting grabbed by the Wallmaster. The Wallmaster will not " - "track you to directly underneath the rupee. You should take the last step to be under the rupee after " - "the Wallmaster has begun its attempt to grab you. Also included with this trick is that fact that the " - "switch that unbars the door to the final chest of GTG can be hit without a projectile, using a precise " - "jumpslash. This trick supersedes \"Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot\"."); - OPT_TRICK(RT_LENS_GANON, RCQUEST_VANILLA, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, - "Ganon\'s Castle without Lens of Truth", "GCLoT", - "Removes the requirements for the Lens of Truth in Ganon's Castle."); - OPT_TRICK(RT_GANON_SPIRIT_TRIAL_HOOKSHOT, RCQUEST_VANILLA, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, - "Spirit Trial without Hookshot", "GCNoHS", - "The highest rupee can be obtained as adult by performing a precise jump and a well-timed jumpslash " - "off of an Armos."); - OPT_TRICK(RT_LENS_GANON_MQ, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, - "Ganon\'s Castle MQ without Lens of Truth", "GCMQLoT", - "Removes the requirements for the Lens of Truth in Ganon's Castle MQ."); - OPT_TRICK(RT_GANON_MQ_FIRE_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::ADVANCED }, - "Fire Trial MQ with Hookshot", "GCFTHS", - "It's possible to hook the target at the end of fire trial with just Hookshot, but it requires precise " - "aim and perfect positioning. The main difficulty comes from getting on the very corner of the obelisk " - "without falling into the lava."); - OPT_TRICK(RT_GANON_MQ_SHADOW_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, - "Shadow Trial MQ Torch with Bow", "GCSTBow", - "You can light the torch in this room without a fire source by shooting an arrow through the lit torch " - "at the beginning of the room. Because the room is so dark and the unlit torch is so far away, it can be " - "difficult to aim the shot correctly."); - OPT_TRICK(RT_GANON_MQ_LIGHT_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::INTERMEDIATE }, - "Light Trial MQ without Hookshot", "GCFirWal", - "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. In " - "this case to do it without taking damage is especially precise."); + "GTGMQNoHS"); + OPT_TRICK(RT_LENS_GANON, RCQUEST_VANILLA, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, "GCLoT"); + OPT_TRICK(RT_GANON_SPIRIT_TRIAL_HOOKSHOT, RCQUEST_VANILLA, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, "GCNoHS"); + OPT_TRICK(RT_LENS_GANON_MQ, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, "GCMQLoT"); + OPT_TRICK(RT_GANON_MQ_FIRE_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::ADVANCED }, "GCFTHS"); + OPT_TRICK(RT_GANON_MQ_SHADOW_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, "GCSTBow"); + OPT_TRICK(RT_GANON_MQ_LIGHT_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::INTERMEDIATE }, "GCFirWal"); for (auto trick : mTrickSettings) { if (trick.GetNameTag() != "") { @@ -2327,9 +1755,10 @@ void Settings::CreateOptions() { mOptionGroups[RSG_MENU_SECTION_WINCON] = OptionGroup::SubGroup( "Win Condition", { &mOptions[RSK_TRIFORCE_HUNT], &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], - &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], &mOptions[RSK_GANONS_BOSS_KEY], &mOptions[RSK_LACS_OPTIONS], - &mOptions[RSK_LACS_MEDALLION_COUNT], &mOptions[RSK_LACS_STONE_COUNT], &mOptions[RSK_LACS_DUNGEON_COUNT], - &mOptions[RSK_LACS_REWARD_COUNT], &mOptions[RSK_LACS_TOKEN_COUNT] }, + &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], &mOptions[RSK_TRIFORCE_HUNT_PIECES_LOCATION], + &mOptions[RSK_GANONS_BOSS_KEY], &mOptions[RSK_LACS_OPTIONS], &mOptions[RSK_LACS_MEDALLION_COUNT], + &mOptions[RSK_LACS_STONE_COUNT], &mOptions[RSK_LACS_DUNGEON_COUNT], &mOptions[RSK_LACS_REWARD_COUNT], + &mOptions[RSK_LACS_TOKEN_COUNT] }, WidgetContainerType::SECTION); mOptionGroups[RSG_MENU_COLUMN_LOGIC_WINCON] = OptionGroup::SubGroup("", std::initializer_list{ @@ -2446,13 +1875,19 @@ void Settings::CreateOptions() { &mOptions[RSK_FISHSANITY_POND_COUNT], &mOptions[RSK_FISHSANITY_AGE_SPLIT], &mOptions[RSK_SHUFFLE_FREESTANDING], + &mOptions[RSK_SHUFFLE_WONDER_ITEMS], &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_GRASS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_BOULDERS], + &mOptions[RSK_SHUFFLE_ROCKS], &mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_BUSHES], + &mOptions[RSK_SHUFFLE_ICICLES], + &mOptions[RSK_SHUFFLE_RED_ICE], + &mOptions[RSK_SHUFFLE_SIGNS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], @@ -2460,6 +1895,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_STONE_FAIRIES], &mOptions[RSK_SHUFFLE_BEAN_FAIRIES], &mOptions[RSK_SHUFFLE_SONG_FAIRIES], + &mOptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES], }, WidgetContainerType::SECTION); mOptionGroups[RSG_MENU_COLUMN_BASIC_SHUFFLES] = @@ -2479,6 +1915,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], &mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], + &mOptions[RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL], &mOptions[RSK_SHUFFLE_SCRUBS], &mOptions[RSK_SCRUBS_PRICES], &mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE], @@ -2501,6 +1938,7 @@ void Settings::CreateOptions() { &mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], + &mOptions[RSK_SHUFFLE_BEGGAR], }, WidgetContainerType::SECTION); mOptionGroups[RSG_MENU_COLUMN_SHOP_SHUFFLES] = @@ -2683,6 +2121,7 @@ void Settings::CreateOptions() { &mOptions[RSK_TRIFORCE_HUNT], &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], + &mOptions[RSK_TRIFORCE_HUNT_PIECES_LOCATION], &mOptions[RSK_MQ_DUNGEON_RANDOM], &mOptions[RSK_MQ_DUNGEON_COUNT], &mOptions[RSK_MQ_DUNGEON_SET], @@ -2710,6 +2149,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], &mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], + &mOptions[RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL], &mOptions[RSK_FISHSANITY], &mOptions[RSK_FISHSANITY_POND_COUNT], &mOptions[RSK_FISHSANITY_AGE_SPLIT], @@ -2731,8 +2171,13 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_GRASS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_BOULDERS], + &mOptions[RSK_SHUFFLE_ROCKS], &mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_BUSHES], + &mOptions[RSK_SHUFFLE_ICICLES], + &mOptions[RSK_SHUFFLE_RED_ICE], + &mOptions[RSK_SHUFFLE_SIGNS], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], @@ -2755,6 +2200,7 @@ void Settings::CreateOptions() { &mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], + &mOptions[RSK_SHUFFLE_BEGGAR], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], @@ -2765,10 +2211,12 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], + &mOptions[RSK_SHUFFLE_WONDER_ITEMS], &mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES], &mOptions[RSK_SHUFFLE_STONE_FAIRIES], &mOptions[RSK_SHUFFLE_BEAN_FAIRIES], &mOptions[RSK_SHUFFLE_SONG_FAIRIES], + &mOptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { @@ -3097,6 +2545,13 @@ void Context::FinalizeSettings(const std::set& excludedLocation if (mOptions[RSK_SHUFFLE_DUNGEON_REWARDS].Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { mOptions[RSK_LINKS_POCKET].Set(RO_LINKS_POCKET_DUNGEON_REWARD); + } else if (mOptions[RSK_SHUFFLE_DUNGEON_REWARDS].Is(RO_DUNGEON_REWARDS_OWN_DUNGEON) || + mOptions[RSK_SHUFFLE_DUNGEON_REWARDS].Is(RO_DUNGEON_REWARDS_VANILLA)) { + mOptions[RSK_LINKS_POCKET_REWARD].Set(RO_LINKS_POCKET_LIGHT_MEDALLION); + } + + if (mOptions[RSK_LINKS_POCKET].IsNot(RO_LINKS_POCKET_DUNGEON_REWARD)) { + mOptions[RSK_LINKS_POCKET_REWARD].Set(RO_LINKS_POCKET_ANY_REWARD); } for (const auto locationKey : this->everyPossibleLocation) { @@ -3164,7 +2619,7 @@ void Context::FinalizeSettings(const std::set& excludedLocation case RO_MQ_SET_RANDOM: // 50% per dungeon, rolled separatly so people can either have a linear distribtuion // or a bell curve for the number of MQ dungeons per seed. - if (Random(0, 2)) { + if (ShipUtils::Random(0, 2)) { dungeon->SetMQ(); mqSet += 1; } @@ -3231,13 +2686,13 @@ void Context::FinalizeSettings(const std::set& excludedLocation if (randMQOption.size() > 0) { // Figure out how many dungeons to select, rolling the random number if needed if (mOptions[RSK_MQ_DUNGEON_RANDOM].Is(RO_MQ_DUNGEONS_RANDOM_NUMBER)) { - mqToSet = Random(0, static_cast(randMQOption.size()) + 1); + mqToSet = ShipUtils::Random(0, static_cast(randMQOption.size()) + 1); } else if (mqCount > mqSet) { mqToSet = std::min(mqCount - mqSet, static_cast(randMQOption.size())); } // we only need to shuffle if we're not using them all if (mqToSet <= static_cast(randMQOption.size()) && mqToSet > 0) { - Shuffle(randMQOption); + ShipUtils::Shuffle(randMQOption); } for (uint8_t i = 0; i < mqToSet; i++) { dungeons[randMQOption[i]]->SetMQ(); @@ -3286,8 +2741,8 @@ void Context::FinalizeSettings(const std::set& excludedLocation if (mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_RANDOM) || mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_COUNT)) { const uint32_t keyRingCount = mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_COUNT) ? mOptions[RSK_KEYRINGS_RANDOM_COUNT].Get() - : Random(0, static_cast(keyrings.size())); - Shuffle(keyrings); + : ShipUtils::Random(0, static_cast(keyrings.size())); + ShipUtils::Shuffle(keyrings); for (size_t i = 0; i < keyRingCount; i++) { keyrings[i]->Set(RO_KEYRING_FOR_DUNGEON_ON); } @@ -3296,49 +2751,50 @@ void Context::FinalizeSettings(const std::set& excludedLocation } } if (mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { + (mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && + ShipUtils::Random(0, 2) == 0)) { this->GetDungeon(BOTTOM_OF_THE_WELL)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_FOREST_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_FOREST_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { + (mOptions[RSK_KEYRINGS_FOREST_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { this->GetDungeon(FOREST_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_FIRE_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_FIRE_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { + (mOptions[RSK_KEYRINGS_FIRE_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { this->GetDungeon(FIRE_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_WATER_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_WATER_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { + (mOptions[RSK_KEYRINGS_WATER_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { this->GetDungeon(WATER_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { + (mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { this->GetDungeon(SPIRIT_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { + (mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { this->GetDungeon(SHADOW_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_GTG].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_GTG].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { + (mOptions[RSK_KEYRINGS_GTG].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { this->GetDungeon(GERUDO_TRAINING_GROUND)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_GANONS_CASTLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_GANONS_CASTLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { + (mOptions[RSK_KEYRINGS_GANONS_CASTLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { this->GetDungeon(GANONS_CASTLE)->SetKeyRing(); } } auto trials = this->GetTrials()->GetTrialList(); - Shuffle(trials); + ShipUtils::Shuffle(trials); for (const auto trial : trials) { trial->SetAsSkipped(); } if (mOptions[RSK_GANONS_TRIALS].Is(RO_GANONS_TRIALS_SKIP)) { mOptions[RSK_TRIAL_COUNT].Set(0); } else if (mOptions[RSK_GANONS_TRIALS].Is(RO_GANONS_TRIALS_RANDOM_NUMBER)) { - mOptions[RSK_TRIAL_COUNT].Set( - Random(0, static_cast(Rando::Settings::GetInstance()->GetOption(RSK_TRIAL_COUNT).GetOptionCount()))); + mOptions[RSK_TRIAL_COUNT].Set(ShipUtils::Random( + 0, static_cast(Rando::Settings::GetInstance()->GetOption(RSK_TRIAL_COUNT).GetOptionCount()))); } for (uint8_t i = 0; i < mOptions[RSK_TRIAL_COUNT].Get(); i++) { trials[i]->SetAsRequired(); @@ -3380,7 +2836,7 @@ void Context::FinalizeSettings(const std::set& excludedLocation } if (mOptions[RSK_STARTING_AGE].Is(RO_AGE_RANDOM)) { - if (const uint32_t choice = Random(0, 2); choice == 0) { + if (const uint32_t choice = ShipUtils::Random(0, 2); choice == 0) { mOptions[RSK_SELECTED_STARTING_AGE].Set(RO_AGE_CHILD); } else { mOptions[RSK_SELECTED_STARTING_AGE].Set(RO_AGE_ADULT); @@ -3475,6 +2931,48 @@ void Settings::SetAllToContext() { } } +void Settings::RandomizeAllSettings() { + // Randomize all settings except tricks + for (int i = 0; i < RSK_MAX; i++) { + switch (static_cast(i)) { + case RSK_STARTING_SKULLTULA_TOKEN: + case RSK_STARTING_HEARTS: + case RSK_STARTING_ZELDAS_LULLABY: + case RSK_STARTING_EPONAS_SONG: + case RSK_STARTING_SARIAS_SONG: + case RSK_STARTING_SUNS_SONG: + case RSK_STARTING_SONG_OF_TIME: + case RSK_STARTING_SONG_OF_STORMS: + case RSK_STARTING_MINUET_OF_FOREST: + case RSK_STARTING_BOLERO_OF_FIRE: + case RSK_STARTING_SERENADE_OF_WATER: + case RSK_STARTING_REQUIEM_OF_SPIRIT: + case RSK_STARTING_NOCTURNE_OF_SHADOW: + case RSK_STARTING_PRELUDE_OF_LIGHT: + continue; + default: + break; + } + + auto key = static_cast(i); + Option& option = mOptions[key]; + + if (option.GetOptionCount() == 0) { + continue; + } + + uint8_t randomIndex = ShipUtils::Random(0, static_cast(option.GetOptionCount())); + + option.SetContextIndex(randomIndex); + if (!option.GetCVarName().empty()) { + CVarSetInteger(option.GetCVarName().c_str(), randomIndex); + } + option.RunCallback(); + } + + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); +} + std::shared_ptr Settings::GetInstance() { if (mInstance == nullptr) { mInstance = std::make_shared(); diff --git a/soh/soh/Enhancements/randomizer/settings.h b/soh/soh/Enhancements/randomizer/settings.h index e77d9d864f..ecef3bfa0d 100644 --- a/soh/soh/Enhancements/randomizer/settings.h +++ b/soh/soh/Enhancements/randomizer/settings.h @@ -135,6 +135,13 @@ class Settings { */ void SetAllToContext(); + /** + * @brief Randomizes all randomizer settings (excluding tricks) to random valid values. + * This function iterates through all options and sets them to a random index within + * their valid range. + */ + void RandomizeAllSettings(); + static std::shared_ptr GetInstance(); private: diff --git a/soh/soh/Enhancements/randomizer/static_data.cpp b/soh/soh/Enhancements/randomizer/static_data.cpp index ecd4a11e30..390febf5e8 100644 --- a/soh/soh/Enhancements/randomizer/static_data.cpp +++ b/soh/soh/Enhancements/randomizer/static_data.cpp @@ -192,16 +192,16 @@ std::unordered_map StaticData::staticHintInfoMap // warp song hints are special cased due to entrances not being done properly yet // Ganondorf Joke is special cased as the text is random {RH_SHEIK_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SHEIK_HINT_LA_ONLY}, RSK_SHEIK_LA_HINT, true, {}, {RG_LIGHT_ARROWS}, {RC_SHEIK_HINT_GC, RC_SHEIK_HINT_MQ_GC}, true)}, - {RH_FOREST_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_FOREST_TEMPLE_BOSS_KEY}, {}, true)}, - {RH_FIRE_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_FIRE_TEMPLE_BOSS_KEY}, {}, true)}, - {RH_WATER_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_WATER_TEMPLE_BOSS_KEY}, {}, true)}, - {RH_SPIRIT_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_SPIRIT_TEMPLE_BOSS_KEY}, {}, true)}, - {RH_SHADOW_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_SHADOW_TEMPLE_BOSS_KEY}, {}, true)}, - {RH_GANONS_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_GANONS_CASTLE_BOSS_KEY}, {}, true)}, + {RH_FOREST_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_FOREST_TEMPLE_BOSS_KEY}, {RC_FOREST_BOSS_KEY_HINT}, true)}, + {RH_FIRE_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_FIRE_TEMPLE_BOSS_KEY}, {RC_FIRE_BOSS_KEY_HINT}, true)}, + {RH_WATER_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_WATER_TEMPLE_BOSS_KEY}, {RC_WATER_BOSS_KEY_HINT}, true)}, + {RH_SPIRIT_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_SPIRIT_TEMPLE_BOSS_KEY}, {RC_SPIRIT_BOSS_KEY_HINT}, true)}, + {RH_SHADOW_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_SHADOW_TEMPLE_BOSS_KEY}, {RC_SHADOW_BOSS_KEY_HINT}, true)}, + {RH_GANONS_BOSS_KEY_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_BOSS_KEY_HINT}, RSK_BOSS_KEY_HINT, true, {}, {RG_GANONS_CASTLE_BOSS_KEY}, {RC_GANONS_BOSS_KEY_HINT}, true)}, {RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})}, {RH_GREG_RUPEE, StaticHintInfo(HINT_TYPE_AREA, {RHT_GREG_HINT}, RSK_GREG_HINT, true, {}, {RG_GREG_RUPEE}, {RC_GREG_HINT})}, {RH_SARIA_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT}, RSK_SARIA_HINT, true, {}, {RG_PROGRESSIVE_MAGIC_METER}, {RC_SARIA_SONG_HINT, RC_SONG_FROM_SARIA}, true)}, - {RH_MIDO_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_MIDO_HINT}, RSK_MIDO_HINT, true, {}, {RG_KOKIRI_SWORD}, {}, true)}, + {RH_MIDO_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_MIDO_HINT}, RSK_MIDO_HINT, true, {}, {RG_KOKIRI_SWORD}, {RC_MIDO_HINT}, true)}, {RH_LOACH_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_LOACH_HINT}, RSK_LOACH_HINT, true, {RC_LH_HYRULE_LOACH})}, {RH_FISHING_POLE, StaticHintInfo(HINT_TYPE_AREA, {RHT_FISHING_POLE_HINT}, RSK_FISHING_POLE_HINT, true, {}, {RG_FISHING_POLE}, {RC_FISHING_POLE_HINT}, true)}, {RH_HBA_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_HBA_HINT_SIGN, RHT_HBA_HINT_NOT_ON_HORSE, RHT_HBA_HINT_INITIAL, RHT_HBA_HINT_HAVE_1000}, RSK_HBA_HINT, true, {RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS})}, diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index ccc895d7bf..241f6794a0 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -61,7 +61,13 @@ class StaticData { static void RegisterFreestandingLocations(); static void RegisterGrassLocations(); static void RegisterCrateLocations(); + static void RegisterRockLocations(); static void RegisterTreeLocations(); + static void RegisterSignLocations(); + static void RegisterWonderItemLocations(); + static void RegisterBeggarLocations(); + static void RegisterIcicleLocations(); + static void RegisterRedIceLocations(); static void InitHashMaps(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; diff --git a/soh/soh/Enhancements/savestates.cpp b/soh/soh/Enhancements/savestates.cpp index 16fb98690b..795ce86e4c 100644 --- a/soh/soh/Enhancements/savestates.cpp +++ b/soh/soh/Enhancements/savestates.cpp @@ -818,8 +818,8 @@ extern "C" void ProcessSaveStateRequests(void) { } void SaveStateMgr::SetCurrentSlot(unsigned int slot) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(1.0f, true, - "slot %u set", slot); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(1.0f, true, + "slot %u set", slot); this->currentSlot = slot; } @@ -838,13 +838,13 @@ void SaveStateMgr::ProcessSaveStateRequests(void) { std::make_shared(OTRGlobals::Instance->gSaveStateMgr, request.slot); } this->states[request.slot]->Save(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( 1.0f, true, "saved state %u", request.slot); break; case RequestType::LOAD: if (this->states.contains(request.slot)) { this->states[request.slot]->Load(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( 1.0f, true, "loaded state %u", request.slot); } else { SPDLOG_ERROR("Invalid SaveState slot: {}", request.slot); @@ -861,7 +861,7 @@ void SaveStateMgr::ProcessSaveStateRequests(void) { SaveStateReturn SaveStateMgr::AddRequest(const SaveStateRequest request) { if (gPlayState == nullptr) { SPDLOG_ERROR("[SOH] Can not save or load a state outside of \"GamePlay\""); - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( 1.0f, true, "states not available here", request.slot); return SaveStateReturn::FAIL_WRONG_GAMESTATE; } @@ -876,7 +876,7 @@ SaveStateReturn SaveStateMgr::AddRequest(const SaveStateRequest request) { return SaveStateReturn::SUCCESS; } else { SPDLOG_ERROR("Invalid SaveState slot: {}", request.slot); - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( 1.0f, true, "state slot %u empty", request.slot); return SaveStateReturn::FAIL_INVALID_SLOT; } diff --git a/soh/soh/Enhancements/savestates.h b/soh/soh/Enhancements/savestates.h index 4cf0353628..0fe4a9ce52 100644 --- a/soh/soh/Enhancements/savestates.h +++ b/soh/soh/Enhancements/savestates.h @@ -1,7 +1,7 @@ #ifndef SAVE_STATES_H #define SAVE_STATES_H -#include +#include #include #include #include diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index e970b965cf..91eaa8a7a5 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -10,6 +10,10 @@ #include #include "soh/SohGui/UIWidgets.hpp" +#include + +#include + extern "C" { #include "z64item.h" #include "macros.h" @@ -435,7 +439,8 @@ void TimeSplitsPopUpContext() { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 2.0f)); ImGui::ImageButton( "QUEST_SKULL_TOKEN", - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("QUEST_SKULL_TOKEN"), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName("QUEST_SKULL_TOKEN"), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0)); ImGui::PopStyleVar(); ImGui::TableNextColumn(); @@ -488,7 +493,8 @@ void TimeSplitsPopUpContext() { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 2.0f)); auto ret = ImGui::ImageButton( popupObject.splitImage.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(popupObject.splitImage), + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(popupObject.splitImage), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), popupObject.splitTint); ImGui::PopStyleVar(); if (ret) { @@ -664,8 +670,9 @@ void TimeSplitsDrawSplitsList() { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(imagePadding, imagePadding)); auto ret = ImGui::ImageButton( split.splitImage.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(split.splitImage), imageSize, - ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), split.splitTint); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(split.splitImage), + imageSize, ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), split.splitTint); ImGui::PopStyleVar(); if (ret) { TimeSplitsSkipSplit(dragIndex); @@ -748,8 +755,9 @@ void TimeSplitsDrawItemList(uint32_t type) { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(imagePadding, imagePadding)); auto ret = ImGui::ImageButton( split.splitImage.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(split.splitImage), imageSize, - ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), split.splitTint); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(split.splitImage), + imageSize, ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), split.splitTint); ImGui::PopStyleVar(); if (ret) { if (popupList.contains(split.splitID) && (split.splitType < SPLIT_TYPE_BOSS)) { @@ -891,8 +899,9 @@ void TimeSplitsDrawManageList() { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(imagePadding, imagePadding)); auto ret = ImGui::ImageButton( data.splitImage.c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(data.splitImage), imageSize, - ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), data.splitTint); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(data.splitImage), + imageSize, ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), data.splitTint); ImGui::PopStyleVar(); if (ret) { removeIndex = index; @@ -976,10 +985,10 @@ void TimeSplitWindow::DrawElement() { void TimeSplitWindow::InitElement() { TimeSplitsUpdateWindowSize(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_TRIFORCE_PIECE_WHITE", - gWTriforcePieceTex, ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_SPLIT_ENTRANCE", gSplitEntranceTex, - ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("SPECIAL_TRIFORCE_PIECE_WHITE", gWTriforcePieceTex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("SPECIAL_SPLIT_ENTRANCE", gSplitEntranceTex, ImVec4(1, 1, 1, 1)); Color_RGBA8 defaultColour = { 0, 0, 0, 255 }; windowColor = VecFromRGBA8(CVarGetColor(CVAR_ENHANCEMENT("TimeSplits.WindowColor.Value"), defaultColour)); diff --git a/soh/soh/Enhancements/tts/tts.cpp b/soh/soh/Enhancements/tts/tts.cpp index fddcb77ce9..6b31cdfb68 100644 --- a/soh/soh/Enhancements/tts/tts.cpp +++ b/soh/soh/Enhancements/tts/tts.cpp @@ -1124,21 +1124,21 @@ void InitTTSBank() { initData->Type = static_cast(Ship::ResourceType::Json); initData->ResourceVersion = 0; - sceneMap = std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource( + sceneMap = std::static_pointer_cast(Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource( "accessibility/texts/scenes" + languageSuffix, true, initData)) ->Data; - miscMap = std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource( + miscMap = std::static_pointer_cast(Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource( "accessibility/texts/misc" + languageSuffix, true, initData)) ->Data; kaleidoMap = - std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource( + std::static_pointer_cast(Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource( "accessibility/texts/kaleidoscope" + languageSuffix, true, initData)) ->Data; fileChooseMap = - std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource( + std::static_pointer_cast(Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource( "accessibility/texts/filechoose" + languageSuffix, true, initData)) ->Data; } diff --git a/soh/soh/Extractor/FastCrc32C.c b/soh/soh/Extractor/FastCrc32C.c index 2dccda61ec..795cc42d74 100644 --- a/soh/soh/Extractor/FastCrc32C.c +++ b/soh/soh/Extractor/FastCrc32C.c @@ -12,11 +12,18 @@ #pragma GCC target("sse4.2") #endif -// Include headers for the CRC32 intrinsic and cpuid instruction on windows. No need to do any other checks because it -// assumes the target will support CRC32 +// Include headers for the CRC32 intrinsic and CPU feature checks on Windows x86/x64/ARM64. #ifdef _WIN32 -#include +#if defined(_M_X64) || defined(_M_IX86) || defined(_M_ARM64) #include +#if defined(_M_X64) || defined(_M_IX86) +#include +#elif defined(_M_ARM64) +#include +#endif +#else +#define NO_CRC_INTRIN +#endif // Same as above but these platforms use slightly different headers #elif ((defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)))) #include @@ -27,12 +34,18 @@ #define NO_CRC_INTRIN #endif -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) +#if defined(_MSC_VER) && defined(_M_ARM64) +#define INTRIN_CRC32_64(crc, data) crc = __crc32cd(crc, data) +#define INTRIN_CRC32_32(crc, data) crc = __crc32cw(crc, data) +#define INTRIN_CRC32_16(crc, data) crc = __crc32ch(crc, data) +#define INTRIN_CRC32_8(crc, data) crc = __crc32cb(crc, data) +#elif defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) #define INTRIN_CRC32_64(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]" : [c] "+r"(crc) : [v] "r"(value)) #define INTRIN_CRC32_32(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value)) #define INTRIN_CRC32_16(crc, value) __asm__("crc32ch %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value)) #define INTRIN_CRC32_8(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value)) -#elif defined(__GNUC__) || defined(_MSC_VER) +#elif ((defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(_M_X64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__))) #define INTRIN_CRC32_64(crc, data) crc = _mm_crc32_u64(crc, data) #define INTRIN_CRC32_32(crc, data) crc = _mm_crc32_u32(crc, data) #define INTRIN_CRC32_16(crc, data) crc = _mm_crc32_u16(crc, data) @@ -78,7 +91,7 @@ static uint32_t CRC32IntrinImpl(unsigned char* data, size_t dataSize) { uint32_t ret = 0xFFFFFFFF; int64_t sizeSigned = dataSize; // Only 64bit platforms support doing a CRC32 operation on a 64bit value -#if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) +#if defined(_M_X64) || defined(_M_ARM64) || defined(__x86_64__) || defined(__aarch64__) while ((sizeSigned -= sizeof(uint64_t)) >= 0) { INTRIN_CRC32_64(ret, *(uint64_t*)data); data += sizeof(uint64_t); @@ -122,6 +135,11 @@ static uint32_t CRC32TableImpl(unsigned char* data, size_t dataSize) { uint32_t CRC32C(unsigned char* data, size_t dataSize) { #ifndef NO_CRC_INTRIN // Test to make sure the CPU supports the CRC32 intrinsic +#if defined(_WIN32) && defined(_M_ARM64) + if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) { + return CRC32IntrinImpl(data, dataSize); + } +#else unsigned int cpuidData[4]; #ifdef _WIN32 __cpuid(cpuidData, 1); @@ -135,6 +153,7 @@ uint32_t CRC32C(unsigned char* data, size_t dataSize) { if (cpuidData[2] & (1 << 20)) { // bit_SSE4_2 return CRC32IntrinImpl(data, dataSize); } +#endif #endif // NO_CRC_INTRIN return CRC32TableImpl(data, dataSize); } diff --git a/soh/soh/Network/Anchor/Anchor.cpp b/soh/soh/Network/Anchor/Anchor.cpp index 2bbbf90822..d4bba613ee 100644 --- a/soh/soh/Network/Anchor/Anchor.cpp +++ b/soh/soh/Network/Anchor/Anchor.cpp @@ -4,6 +4,7 @@ #include "soh/OTRGlobals.h" #include "soh/Enhancements/nametag.h" #include "soh/ObjectExtension/ObjectExtension.h" +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "variables.h" diff --git a/soh/soh/Network/Anchor/Anchor.h b/soh/soh/Network/Anchor/Anchor.h index 8476d8c364..a7277a0a71 100644 --- a/soh/soh/Network/Anchor/Anchor.h +++ b/soh/soh/Network/Anchor/Anchor.h @@ -29,6 +29,7 @@ typedef struct { bool isSaveLoaded; bool isGameComplete; s16 sceneNum; + s8 curRoomNum; s32 entranceIndex; // Only available in PLAYER_UPDATE packets diff --git a/soh/soh/Network/Anchor/AnchorRoomWindow.cpp b/soh/soh/Network/Anchor/AnchorRoomWindow.cpp index d0d273e2cd..6163bc8939 100644 --- a/soh/soh/Network/Anchor/AnchorRoomWindow.cpp +++ b/soh/soh/Network/Anchor/AnchorRoomWindow.cpp @@ -1,5 +1,7 @@ #include "Anchor.h" #include "soh/OTRGlobals.h" +#include "soh/util.h" +#include "soh/Enhancements/randomizer/SeedContext.h" extern "C" { #include "variables.h" diff --git a/soh/soh/Network/Anchor/DummyPlayer.cpp b/soh/soh/Network/Anchor/DummyPlayer.cpp index 67bf6ac3f9..1201033e0f 100644 --- a/soh/soh/Network/Anchor/DummyPlayer.cpp +++ b/soh/soh/Network/Anchor/DummyPlayer.cpp @@ -131,7 +131,8 @@ void DummyPlayer_Update(Actor* actor, PlayState* play) { player->itemAction = client.itemAction; player->heldItemAction = client.heldItemAction; player->invincibilityTimer = client.invincibilityTimer; - player->unk_862 = client.unk_862; + player->unk_862 = + (client.unk_862 > (s16)GID_MAXIMUM) ? (s16)GID_STONE_OF_AGONY : client.unk_862; // prevent OOB, show SoA if OOB player->unk_85C = client.unk_85C; player->av1.actionVar1 = client.actionVar1; diff --git a/soh/soh/Network/Anchor/HookHandlers.cpp b/soh/soh/Network/Anchor/HookHandlers.cpp index c620ee30e1..8b2817f490 100644 --- a/soh/soh/Network/Anchor/HookHandlers.cpp +++ b/soh/soh/Network/Anchor/HookHandlers.cpp @@ -1,6 +1,9 @@ #include "Anchor.h" #include +#include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" extern "C" { #include "variables.h" @@ -28,16 +31,18 @@ extern "C" { #include "src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h" #include "src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.h" #include "src/overlays/actors/ovl_Bg_Hidan_Kowarerukabe/z_bg_hidan_kowarerukabe.h" +#include "objects/gameplay_keep/gameplay_keep.h" extern PlayState* gPlayState; +extern MapData* gMapData; void func_8086ED70(BgBombwall* bgBombwall, PlayState* play); void BgBreakwall_Wait(BgBreakwall* bgBreakwall, PlayState* play); -void func_80883000(BgHakaZou* bgHakaZou, PlayState* play); +void BgHakaZou_WaitForHit(BgHakaZou* bgHakaZou, PlayState* play); void func_808887C4(BgHidanHamstep* bgHidanHamstep, PlayState* play); void func_808896B8(BgHidanHrock* bgHidanHrock, PlayState* play); -void func_8089107C(BgIceShelter* bgIceShelter, PlayState* play); -void func_808911BC(BgIceShelter* bgIceShelter); +void BgIceShelter_Idle(BgIceShelter* bgIceShelter, PlayState* play); +void BgIceShelter_SetupMelt(BgIceShelter* bgIceShelter); void ObjBombiwa_Break(ObjBombiwa* objBombiwa, PlayState* play); void ObjHamishi_Break(ObjHamishi* objHamishi, PlayState* play); void BgJyaBombchuiwa_WaitForExplosion(BgJyaBombchuiwa* bgJyaBombchuiwa, PlayState* play); @@ -48,6 +53,8 @@ void BgYdanSp_FloorWebIdle(BgYdanSp* bgYdanSp, PlayState* play); void BgYdanSp_WallWebIdle(BgYdanSp* bgYdanSp, PlayState* play); void BgYdanSp_BurnWeb(BgYdanSp* bgYdanSp, PlayState* play); void EnDoor_Idle(EnDoor* enDoor, PlayState* play); +float OTRGetDimensionFromLeftEdge(float v); +float OTRGetDimensionFromRightEdge(float v); } void Anchor::RegisterHooks() { @@ -210,7 +217,7 @@ void Anchor::RegisterHooks() { COND_ID_HOOK(ShouldActorUpdate, ACTOR_BG_HAKA_ZOU, isConnected, [&](void* refActor, bool* should) { BgHakaZou* actor = static_cast(refActor); - if (actor->actionFunc == func_80883000 && Flags_GetSwitch(gPlayState, actor->switchFlag)) { + if (actor->actionFunc == BgHakaZou_WaitForHit && Flags_GetSwitch(gPlayState, actor->switchFlag)) { actor->collider.base.acFlags |= AC_HIT; } }); @@ -234,8 +241,8 @@ void Anchor::RegisterHooks() { COND_ID_HOOK(ShouldActorUpdate, ACTOR_BG_ICE_SHELTER, isConnected, [&](void* refActor, bool* should) { BgIceShelter* actor = static_cast(refActor); - if (actor->actionFunc == func_8089107C && Flags_GetSwitch(gPlayState, actor->dyna.actor.params & 0x3F)) { - func_808911BC(actor); + if (actor->actionFunc == BgIceShelter_Idle && Flags_GetSwitch(gPlayState, actor->dyna.actor.params & 0x3F)) { + BgIceShelter_SetupMelt(actor); Audio_PlayActorSound2(&actor->dyna.actor, NA_SE_EV_ICE_MELT); } }); @@ -315,7 +322,7 @@ void Anchor::RegisterHooks() { DoorShutter* actor = static_cast(refActor); if (Flags_GetSwitch(gPlayState, actor->dyna.actor.params & 0x3F)) { - DECR(actor->unk_16E); + DECR(actor->unlockTimer); } }); @@ -393,4 +400,149 @@ void Anchor::RegisterHooks() { }); // #endregion + + // #region Hooks for visual effects that don't affect gameplay + + struct CompassIcon { + Vec3f pos; + Vec3s rot; + float scale; + Color_RGB8 color; + }; + + COND_HOOK(OnMinimapDrawCompassIcons, isConnected, [&]() { + if (!CVarGetInteger(CVAR_REMOTE_ANCHOR("ShowOtherPlayersOnMinimap"), 1) || + Anchor::Instance->roomState.showLocationsMode == 0) { + return; + } + + std::vector compassIcons; + + bool isInDungeon = gPlayState->sceneNum == SCENE_DEKU_TREE || gPlayState->sceneNum == SCENE_DODONGOS_CAVERN || + gPlayState->sceneNum == SCENE_JABU_JABU || gPlayState->sceneNum == SCENE_FOREST_TEMPLE || + gPlayState->sceneNum == SCENE_FIRE_TEMPLE || gPlayState->sceneNum == SCENE_WATER_TEMPLE || + gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE || gPlayState->sceneNum == SCENE_SHADOW_TEMPLE || + gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL || gPlayState->sceneNum == SCENE_ICE_CAVERN; + std::string teamId = CVarGetString(CVAR_REMOTE_ANCHOR("TeamId"), "default"); + + // When transitioning to a new room via a door, curRoom.num updates immediately but the minimap still shows the + // previous room while fading out + s8 displayedRoomNum = + gPlayState->roomCtx.prevRoom.num >= 0 ? gPlayState->roomCtx.prevRoom.num : gPlayState->roomCtx.curRoom.num; + + for (auto& [clientId, client] : Anchor::Instance->clients) { + // Show compass icons for other players in the current scene. Also require them to be in the current room + // within dungeons. If showLocationsMode isn't all players (2), only show compass icons for players of the + // same team + if (!client.self && client.online && client.player && client.sceneNum == gPlayState->sceneNum && + (!isInDungeon || client.curRoomNum == displayedRoomNum) && + (Anchor::Instance->roomState.showLocationsMode == 2 || client.teamId == teamId)) { + compassIcons.push_back( + CompassIcon{ client.player->actor.world.pos, client.player->actor.shape.rot, 0.3f, client.color }); + } + } + + // The local player's compass icon is always last so it gets drawn above the others + Player* player = GET_PLAYER(gPlayState); + compassIcons.push_back(CompassIcon{ player->actor.world.pos, player->actor.shape.rot, 0.4f, + CVarGetColor24(CVAR_REMOTE_ANCHOR("Color.Value"), { 100, 255, 100 }) }); + + // Adapted internals of Minimap_DrawCompassIcons() + s16 leftMinimapMargin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.L"), 0); + s16 rightMinimapMargin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.R"), 0); + s16 bottomMinimapMargin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.B"), 0); + + s16 xMarginsMinimap; + s16 yMarginsMinimap; + if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) { + if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ORIGINAL_LOCATION) { + xMarginsMinimap = rightMinimapMargin; + } + yMarginsMinimap = bottomMinimapMargin; + } else { + xMarginsMinimap = 0; + yMarginsMinimap = 0; + } + + s16 mapWidth = isInDungeon ? R_DGN_MINIMAP_X : R_OW_MINIMAP_X; + s16 mapStartPosX = isInDungeon ? 96 : gMapData->owMinimapWidth[R_MAP_INDEX]; + + OPEN_DISPS(gPlayState->state.gfxCtx); + Gfx_SetupDL_42Overlay(gPlayState->state.gfxCtx); + + for (auto& compassIcon : compassIcons) { + gSPMatrix(OVERLAY_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, + PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); + gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); + gDPSetCombineMode(OVERLAY_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + + // The compass offset value is a factor of 10 compared to N64 screen pixels and originates in the center of + // the screen Compute the additional mirror offset value by normalizing the original offset position and + // taking it's distance to the center of the map, duplicating that result and casting back to a factor of 10 + s16 mirrorOffset = + ((mapWidth / 2) - ((R_COMPASS_OFFSET_X / 10) - (mapStartPosX - SCREEN_WIDTH / 2))) * 2 * 10; + + s16 tempX = (s16)compassIcon.pos.x; + s16 tempZ = (s16)compassIcon.pos.z; + tempX /= R_COMPASS_SCALE_X * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? -1 : 1); + tempZ /= R_COMPASS_SCALE_Y; + + s16 tempXOffset = + R_COMPASS_OFFSET_X + (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? mirrorOffset : 0); + if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) { + if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) { + if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) { + xMarginsMinimap = leftMinimapMargin; + }; + Matrix_Translate( + OTRGetDimensionFromLeftEdge((tempXOffset + (xMarginsMinimap * 10) + tempX + + (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) * 10)) / + 10.0f), + (R_COMPASS_OFFSET_Y + ((yMarginsMinimap * 10) * -1) - tempZ + + ((CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) * 10) * -1)) / + 10.0f, + 0.0f, MTXMODE_NEW); + } else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) { + if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) { + xMarginsMinimap = rightMinimapMargin; + }; + Matrix_Translate( + OTRGetDimensionFromRightEdge((tempXOffset + (xMarginsMinimap * 10) + tempX + + (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) * 10)) / + 10.0f), + (R_COMPASS_OFFSET_Y + ((yMarginsMinimap * 10) * -1) - tempZ + + ((CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) * 10) * -1)) / + 10.0f, + 0.0f, MTXMODE_NEW); + } else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) { + Matrix_Translate( + (tempXOffset + tempX + (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) * 10) / 10.0f), + (R_COMPASS_OFFSET_Y + ((yMarginsMinimap * 10) * -1) - tempZ + + ((CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) * 10) * -1)) / + 10.0f, + 0.0f, MTXMODE_NEW); + } + } else { + Matrix_Translate(OTRGetDimensionFromRightEdge((tempXOffset + (xMarginsMinimap * 10) + tempX) / 10.0f), + (R_COMPASS_OFFSET_Y + ((yMarginsMinimap * 10) * -1) - tempZ) / 10.0f, 0.0f, + MTXMODE_NEW); + } + Matrix_Scale(compassIcon.scale, compassIcon.scale, compassIcon.scale, MTXMODE_APPLY); + Matrix_RotateX(-1.6f, MTXMODE_APPLY); + s16 rotation = ((0x7FFF - compassIcon.rot.y) / 0x400) * + (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? -1 : 1); + Matrix_RotateY(rotation / 10.0f, MTXMODE_APPLY); + gSPMatrix(OVERLAY_DISP++, MATRIX_NEWMTX(gPlayState->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0xFF, compassIcon.color.r, compassIcon.color.g, compassIcon.color.b, + 255); + gSPDisplayList(OVERLAY_DISP++, (Gfx*)gCompassArrowDL); + } + + CLOSE_DISPS(gPlayState->state.gfxCtx); + }); + + // #endregion } diff --git a/soh/soh/Network/Anchor/JsonConversions.hpp b/soh/soh/Network/Anchor/JsonConversions.hpp index 0794662336..9a3e802884 100644 --- a/soh/soh/Network/Anchor/JsonConversions.hpp +++ b/soh/soh/Network/Anchor/JsonConversions.hpp @@ -62,6 +62,7 @@ inline void from_json(const json& j, AnchorClient& client) { client.isSaveLoaded = j.value("isSaveLoaded", false); client.isGameComplete = j.value("isGameComplete", false); client.sceneNum = j.value("sceneNum", (s16)SCENE_ID_MAX); + client.curRoomNum = j.value("curRoomNum", (s8)-1); client.entranceIndex = j.value("entranceIndex", (s32)0); client.self = j.value("self", false); } diff --git a/soh/soh/Network/Anchor/Menu.cpp b/soh/soh/Network/Anchor/Menu.cpp index 77b544fb3d..2930a405b2 100644 --- a/soh/soh/Network/Anchor/Menu.cpp +++ b/soh/soh/Network/Anchor/Menu.cpp @@ -34,7 +34,7 @@ void AnchorMainMenu(WidgetInfo& info) { ImVec2((ImGui::GetFontSize() * 5 + ImGui::GetStyle().ItemSpacing.x), 0)) .Color(THEME_COLOR))) { CVarSetString(CVAR_REMOTE_ANCHOR("Host"), host.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); @@ -42,7 +42,7 @@ void AnchorMainMenu(WidgetInfo& info) { ImGui::SetNextItemWidth(ImGui::GetFontSize() * 5); if (ImGui::InputScalar("##Port", ImGuiDataType_U16, &port)) { CVarSetInteger(CVAR_REMOTE_ANCHOR("Port"), port); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } UIWidgets::PopStyleInput(); @@ -53,20 +53,20 @@ void AnchorMainMenu(WidgetInfo& info) { ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); if (UIWidgets::InputString("##Name", &anchorName, UIWidgets::InputOptions().Color(THEME_COLOR))) { CVarSetString(CVAR_REMOTE_ANCHOR("Name"), anchorName.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::Text("Room ID"); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); if (UIWidgets::InputString("##RoomId", &anchorRoomId, UIWidgets::InputOptions().IsSecret(anchor->isEnabled).Color(THEME_COLOR))) { CVarSetString(CVAR_REMOTE_ANCHOR("RoomId"), anchorRoomId.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::Text("Team ID (Items & Flags Shared)"); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); if (UIWidgets::InputString("##TeamId", &anchorTeamId, UIWidgets::InputOptions().Color(THEME_COLOR))) { CVarSetString(CVAR_REMOTE_ANCHOR("TeamId"), anchorTeamId.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::Spacing(); @@ -78,7 +78,7 @@ void AnchorMainMenu(WidgetInfo& info) { CVarSetString(CVAR_REMOTE_ANCHOR("TeamId"), "default"); CVarSetString(CVAR_REMOTE_ANCHOR("RoomId"), ""); CVarSetString(CVAR_REMOTE_ANCHOR("Name"), ""); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); @@ -91,7 +91,7 @@ void AnchorMainMenu(WidgetInfo& info) { CVarSetInteger(CVAR_REMOTE_ANCHOR("Port"), 43383); CVarSetString(CVAR_REMOTE_ANCHOR("TeamId"), "default"); CVarSetString(CVAR_REMOTE_ANCHOR("RoomId"), "soh-global"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::EndDisabled(); @@ -105,11 +105,11 @@ void AnchorMainMenu(WidgetInfo& info) { if (ImGui::Button(buttonLabel, ImVec2(-1.0f, 0.0f))) { if (anchor->isEnabled) { CVarClear(CVAR_REMOTE_ANCHOR("Enabled")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); anchor->Disable(); } else { CVarSetInteger(CVAR_REMOTE_ANCHOR("Enabled"), 1); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); anchor->Enable(); } } @@ -139,6 +139,24 @@ void AnchorMainMenu(WidgetInfo& info) { ImGui::SameLine(); UIWidgets::WindowButton("Toggle Anchor Room Window", CVAR_WINDOW("AnchorRoom"), SohGui::mAnchorRoomWindow); + + ImGui::Spacing(); + + bool hideLocations = Anchor::Instance->roomState.showLocationsMode == 0; + ImGui::BeginDisabled(hideLocations); + UIWidgets::CVarCheckbox( + "Show Other Players on Minimap", CVAR_REMOTE_ANCHOR("ShowOtherPlayersOnMinimap"), + UIWidgets::CheckboxOptions() + .Color(THEME_COLOR) + .DefaultValue(true) + .Tooltip(!hideLocations + ? "Other players will appear on the minimap in areas where you have the compass. " + "Visibility is restricted according to the Show Locations mode for the room." + : "Cannot show other players because the room's Show Locations mode is set to None.")); + ImGui::EndDisabled(); + + ImGui::Spacing(); + if (!SohGui::mAnchorRoomWindow->IsVisible()) { SohGui::mAnchorRoomWindow->DrawElement(); } diff --git a/soh/soh/Network/Anchor/Packets/AllClientState.cpp b/soh/soh/Network/Anchor/Packets/AllClientState.cpp index 7de1a67ec1..8e01d1f34e 100644 --- a/soh/soh/Network/Anchor/Packets/AllClientState.cpp +++ b/soh/soh/Network/Anchor/Packets/AllClientState.cpp @@ -22,7 +22,7 @@ void Anchor::HandlePacket_AllClientState(nlohmann::json payload) { if (client.self) { ownClientId = client.clientId; CVarSetInteger(CVAR_REMOTE_ANCHOR("LastClientId"), ownClientId); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); clients[client.clientId].self = true; } else { clients[client.clientId].self = false; diff --git a/soh/soh/Network/Anchor/Packets/DamagePlayer.cpp b/soh/soh/Network/Anchor/Packets/DamagePlayer.cpp index e97abea4fa..eea1e81759 100644 --- a/soh/soh/Network/Anchor/Packets/DamagePlayer.cpp +++ b/soh/soh/Network/Anchor/Packets/DamagePlayer.cpp @@ -29,7 +29,7 @@ void Anchor::SendPacket_DamagePlayer(u32 clientId, u8 damageEffect, u8 damage) { } void Anchor::HandlePacket_DamagePlayer(nlohmann::json payload) { - uint32_t clientId = payload["clientId"].get(); + uint32_t clientId = payload.at("clientId").get(); if (!clients.contains(clientId) || clients[clientId].player == nullptr) { return; } @@ -44,8 +44,8 @@ void Anchor::HandlePacket_DamagePlayer(nlohmann::json payload) { return; } - u8 damageEffect = payload["damageEffect"].get(); - u8 damage = payload["damage"].get(); + u8 damageEffect = payload.at("damageEffect").get(); + u8 damage = payload.at("damage").get(); self->actor.colChkInfo.damage = damage * 8; // Arbitrary number currently, need to fine tune diff --git a/soh/soh/Network/Anchor/Packets/EntranceDiscovered.cpp b/soh/soh/Network/Anchor/Packets/EntranceDiscovered.cpp index 6669e28a04..85671f0ed9 100644 --- a/soh/soh/Network/Anchor/Packets/EntranceDiscovered.cpp +++ b/soh/soh/Network/Anchor/Packets/EntranceDiscovered.cpp @@ -28,6 +28,6 @@ void Anchor::HandlePacket_EntranceDiscovered(nlohmann::json payload) { return; } - u16 entranceIndex = payload["entranceIndex"].get(); + u16 entranceIndex = payload.at("entranceIndex").get(); Entrance_SetEntranceDiscovered(entranceIndex, 1); } diff --git a/soh/soh/Network/Anchor/Packets/GameComplete.cpp b/soh/soh/Network/Anchor/Packets/GameComplete.cpp index aa05a6e64f..7f41ecfeb6 100644 --- a/soh/soh/Network/Anchor/Packets/GameComplete.cpp +++ b/soh/soh/Network/Anchor/Packets/GameComplete.cpp @@ -3,7 +3,7 @@ #include #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Notification/Notification.h" -#include "soh/Enhancements/randomizer/3drando/random.hpp" +#include "soh/ShipUtils.h" const std::string gameCompleteMessages[] = { "killed Ganon", "saved Zelda", "proved their Courage", @@ -26,7 +26,7 @@ void Anchor::SendPacket_GameComplete() { } void Anchor::HandlePacket_GameComplete(nlohmann::json payload) { - uint32_t clientId = payload["clientId"].get(); + uint32_t clientId = payload.at("clientId").get(); if (!clients.contains(clientId)) { return; } @@ -37,6 +37,6 @@ void Anchor::HandlePacket_GameComplete(nlohmann::json payload) { Notification::Emit({ .prefix = isGlobalRoom ? "Someone" : anchorClient.name, - .message = RandomElement(gameCompleteMessages), + .message = ShipUtils::RandomElement(gameCompleteMessages), }); } diff --git a/soh/soh/Network/Anchor/Packets/GiveItem.cpp b/soh/soh/Network/Anchor/Packets/GiveItem.cpp index fbf048d7d2..f957eef022 100644 --- a/soh/soh/Network/Anchor/Packets/GiveItem.cpp +++ b/soh/soh/Network/Anchor/Packets/GiveItem.cpp @@ -49,10 +49,10 @@ void Anchor::HandlePacket_GiveItem(nlohmann::json payload) { return; } - uint32_t clientId = payload["clientId"].get(); + uint32_t clientId = payload.at("clientId").get(); AnchorClient& client = clients[clientId]; - u16 modId = payload["modId"].get(); - u16 getItemId = payload["getItemId"].get(); + u16 modId = payload.at("modId").get(); + u16 getItemId = payload.at("getItemId").get(); GetItemEntry getItemEntry; if (modId == MOD_NONE) { diff --git a/soh/soh/Network/Anchor/Packets/OcarinaSfx.cpp b/soh/soh/Network/Anchor/Packets/OcarinaSfx.cpp index 72eee3c5c0..c2b958102a 100644 --- a/soh/soh/Network/Anchor/Packets/OcarinaSfx.cpp +++ b/soh/soh/Network/Anchor/Packets/OcarinaSfx.cpp @@ -1,5 +1,4 @@ #include "soh/Network/Anchor/Anchor.h" -#include "soh/Network/Anchor/JsonConversions.hpp" #include #include @@ -39,10 +38,10 @@ void Anchor::SendPacket_OcarinaSfx(uint8_t note, float modulator, int8_t bend) { } void Anchor::HandlePacket_OcarinaSfx(nlohmann::json payload) { - uint32_t clientId = payload["clientId"].get(); - uint8_t note = payload["note"].get(); - float modulator = payload["modulator"].get(); - int8_t bend = payload["bend"].get(); + uint32_t clientId = payload.at("clientId").get(); + uint8_t note = payload.at("note").get(); + float modulator = payload.at("modulator").get(); + int8_t bend = payload.at("bend").get(); if (!clients.contains(clientId) || !clients[clientId].player) { return; diff --git a/soh/soh/Network/Anchor/Packets/PlayerSfx.cpp b/soh/soh/Network/Anchor/Packets/PlayerSfx.cpp index ce4755adf8..6dff899eb3 100644 --- a/soh/soh/Network/Anchor/Packets/PlayerSfx.cpp +++ b/soh/soh/Network/Anchor/Packets/PlayerSfx.cpp @@ -36,8 +36,8 @@ void Anchor::SendPacket_PlayerSfx(u16 sfxId) { } void Anchor::HandlePacket_PlayerSfx(nlohmann::json payload) { - uint32_t clientId = payload["clientId"].get(); - u16 sfxId = payload["sfxId"].get(); + uint32_t clientId = payload.at("clientId").get(); + u16 sfxId = payload.at("sfxId").get(); if (!clients.contains(clientId) || !clients[clientId].player) { return; diff --git a/soh/soh/Network/Anchor/Packets/RequestTeleport.cpp b/soh/soh/Network/Anchor/Packets/RequestTeleport.cpp index 8bcb1a3066..4d9c572638 100644 --- a/soh/soh/Network/Anchor/Packets/RequestTeleport.cpp +++ b/soh/soh/Network/Anchor/Packets/RequestTeleport.cpp @@ -27,7 +27,7 @@ void Anchor::HandlePacket_RequestTeleport(nlohmann::json payload) { return; } - uint32_t clientId = payload["clientId"].get(); + uint32_t clientId = payload.at("clientId").get(); SendPacket_TeleportTo(clientId); } diff --git a/soh/soh/Network/Anchor/Packets/ServerMessage.cpp b/soh/soh/Network/Anchor/Packets/ServerMessage.cpp index 9c1fdc1326..e7b1197311 100644 --- a/soh/soh/Network/Anchor/Packets/ServerMessage.cpp +++ b/soh/soh/Network/Anchor/Packets/ServerMessage.cpp @@ -12,6 +12,6 @@ void Anchor::HandlePacket_ServerMessage(nlohmann::json payload) { Notification::Emit({ .prefix = "Server:", .prefixColor = ImVec4(1.0f, 0.5f, 0.5f, 1.0f), - .message = payload["message"].get(), + .message = payload.at("message").get(), }); } diff --git a/soh/soh/Network/Anchor/Packets/SetCheckStatus.cpp b/soh/soh/Network/Anchor/Packets/SetCheckStatus.cpp index 171ce3d39a..86551783ad 100644 --- a/soh/soh/Network/Anchor/Packets/SetCheckStatus.cpp +++ b/soh/soh/Network/Anchor/Packets/SetCheckStatus.cpp @@ -4,6 +4,7 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/OTRGlobals.h" #include "soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h" +#include "soh/Enhancements/randomizer/randomizer.h" static bool isResultOfHandling = false; @@ -39,13 +40,13 @@ void Anchor::HandlePacket_SetCheckStatus(nlohmann::json payload) { auto randoContext = Rando::Context::GetInstance(); - RandomizerCheck rc = payload["rc"].get(); + RandomizerCheck rc = payload.at("rc").get(); if (rc < 0 || rc >= RC_MAX) { SPDLOG_ERROR("[Anchor] SET_CHECK_STATUS: rc {} out of range", (int)rc); return; } - RandomizerCheckStatus status = payload["status"].get(); - bool skipped = payload["skipped"].get(); + RandomizerCheckStatus status = payload.at("status").get(); + bool skipped = payload.at("skipped").get(); isResultOfHandling = true; diff --git a/soh/soh/Network/Anchor/Packets/SetFlag.cpp b/soh/soh/Network/Anchor/Packets/SetFlag.cpp index 8b12bf6487..c4501a0814 100644 --- a/soh/soh/Network/Anchor/Packets/SetFlag.cpp +++ b/soh/soh/Network/Anchor/Packets/SetFlag.cpp @@ -37,9 +37,9 @@ void Anchor::HandlePacket_SetFlag(nlohmann::json payload) { return; } - s16 sceneNum = payload["sceneNum"].get(); - s16 flagType = payload["flagType"].get(); - s16 flag = payload["flag"].get(); + s16 sceneNum = payload.at("sceneNum").get(); + s16 flagType = payload.at("flagType").get(); + s16 flag = payload.at("flag").get(); // sceneNum == SCENE_ID_MAX is a sentinel meaning "global flag" (handled below); only larger // values would index gSaveContext.sceneFlags out of bounds. diff --git a/soh/soh/Network/Anchor/Packets/TeleportTo.cpp b/soh/soh/Network/Anchor/Packets/TeleportTo.cpp index 2c000b1ce5..34cf074262 100644 --- a/soh/soh/Network/Anchor/Packets/TeleportTo.cpp +++ b/soh/soh/Network/Anchor/Packets/TeleportTo.cpp @@ -37,15 +37,15 @@ void Anchor::HandlePacket_TeleportTo(nlohmann::json payload) { return; } - s32 entranceIndex = payload["entranceIndex"].get(); - s8 roomIndex = payload["roomIndex"].get(); + s32 entranceIndex = payload.at("entranceIndex").get(); + s8 roomIndex = payload.at("roomIndex").get(); if (entranceIndex < 0 || roomIndex < 0) { SPDLOG_ERROR("[Anchor] TELEPORT_TO: invalid entranceIndex {} or roomIndex {}", entranceIndex, (int)roomIndex); return; } - PosRot posRot = payload["posRot"].get(); + PosRot posRot = payload.at("posRot").get(); gPlayState->nextEntranceIndex = entranceIndex; gPlayState->transitionTrigger = TRANS_TRIGGER_START; diff --git a/soh/soh/Network/Anchor/Packets/UnsetFlag.cpp b/soh/soh/Network/Anchor/Packets/UnsetFlag.cpp index e5e7de7a8b..a0609ca7f0 100644 --- a/soh/soh/Network/Anchor/Packets/UnsetFlag.cpp +++ b/soh/soh/Network/Anchor/Packets/UnsetFlag.cpp @@ -37,9 +37,9 @@ void Anchor::HandlePacket_UnsetFlag(nlohmann::json payload) { return; } - s16 sceneNum = payload["sceneNum"].get(); - s16 flagType = payload["flagType"].get(); - s16 flag = payload["flag"].get(); + s16 sceneNum = payload.at("sceneNum").get(); + s16 flagType = payload.at("flagType").get(); + s16 flag = payload.at("flag").get(); // sceneNum == SCENE_ID_MAX is a sentinel meaning "global flag" (handled below); only larger // values would index gSaveContext.sceneFlags out of bounds. diff --git a/soh/soh/Network/Anchor/Packets/UpdateBeansCount.cpp b/soh/soh/Network/Anchor/Packets/UpdateBeansCount.cpp index 976c7cc24c..c536459fbf 100644 --- a/soh/soh/Network/Anchor/Packets/UpdateBeansCount.cpp +++ b/soh/soh/Network/Anchor/Packets/UpdateBeansCount.cpp @@ -34,6 +34,6 @@ void Anchor::HandlePacket_UpdateBeansCount(nlohmann::json payload) { return; } - AMMO(ITEM_BEAN) = payload["amount"].get(); - BEANS_BOUGHT = payload["amountBought"].get(); + AMMO(ITEM_BEAN) = payload.at("amount").get(); + BEANS_BOUGHT = payload.at("amountBought").get(); } diff --git a/soh/soh/Network/Anchor/Packets/UpdateClientState.cpp b/soh/soh/Network/Anchor/Packets/UpdateClientState.cpp index 3099da84a4..67a4d3891a 100644 --- a/soh/soh/Network/Anchor/Packets/UpdateClientState.cpp +++ b/soh/soh/Network/Anchor/Packets/UpdateClientState.cpp @@ -3,6 +3,7 @@ #include #include #include "soh/OTRGlobals.h" +#include "soh/Enhancements/randomizer/SeedContext.h" extern "C" { #include "variables.h" @@ -33,12 +34,14 @@ nlohmann::json Anchor::PrepClientState() { payload["isSaveLoaded"] = true; payload["isGameComplete"] = gSaveContext.ship.stats.gameComplete; payload["sceneNum"] = gPlayState->sceneNum; + payload["curRoomNum"] = gPlayState->roomCtx.curRoom.num; payload["entranceIndex"] = gSaveContext.entranceIndex; } else { payload["seed"] = 0; payload["isSaveLoaded"] = false; payload["isGameComplete"] = false; payload["sceneNum"] = SCENE_ID_MAX; + payload["curRoomNum"] = -1; payload["entranceIndex"] = 0x00; } @@ -54,7 +57,7 @@ void Anchor::SendPacket_UpdateClientState() { } void Anchor::HandlePacket_UpdateClientState(nlohmann::json payload) { - uint32_t clientId = payload["clientId"].get(); + uint32_t clientId = payload.at("clientId").get(); if (clients.contains(clientId)) { AnchorClient client = payload["state"].get(); @@ -68,6 +71,7 @@ void Anchor::HandlePacket_UpdateClientState(nlohmann::json payload) { clients[clientId].isSaveLoaded = client.isSaveLoaded; clients[clientId].isGameComplete = client.isGameComplete; clients[clientId].sceneNum = client.sceneNum; + clients[clientId].curRoomNum = client.curRoomNum; clients[clientId].entranceIndex = client.entranceIndex; } } diff --git a/soh/soh/Network/Anchor/Packets/UpdateDungeonItems.cpp b/soh/soh/Network/Anchor/Packets/UpdateDungeonItems.cpp index ed44356e33..59f3b80c97 100644 --- a/soh/soh/Network/Anchor/Packets/UpdateDungeonItems.cpp +++ b/soh/soh/Network/Anchor/Packets/UpdateDungeonItems.cpp @@ -2,8 +2,10 @@ #include #include #include -#include "soh/Enhancements/game-interactor/GameInteractor.h" -#include "soh/OTRGlobals.h" + +extern "C" { +#include "include/macros.h" +} /** * UPDATE_DUNGEON_ITEMS @@ -33,13 +35,13 @@ void Anchor::HandlePacket_UpdateDungeonItems(nlohmann::json payload) { return; } - u16 mapIndex = payload["mapIndex"].get(); + u16 mapIndex = payload.at("mapIndex").get(); // dungeonKeys is shorter than dungeonItems (19 vs 20), so bound by the smaller of the two. if (mapIndex >= ARRAY_COUNT(gSaveContext.inventory.dungeonItems) || mapIndex >= ARRAY_COUNT(gSaveContext.inventory.dungeonKeys)) { SPDLOG_ERROR("[Anchor] UPDATE_DUNGEON_ITEMS: mapIndex {} out of range", mapIndex); return; } - gSaveContext.inventory.dungeonItems[mapIndex] = payload["dungeonItems"].get(); - gSaveContext.inventory.dungeonKeys[mapIndex] = payload["dungeonKeys"].get(); + gSaveContext.inventory.dungeonItems[mapIndex] = payload.at("dungeonItems").get(); + gSaveContext.inventory.dungeonKeys[mapIndex] = payload.at("dungeonKeys").get(); } diff --git a/soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp b/soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp index 9e9169779e..d0c4a956ad 100644 --- a/soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp +++ b/soh/soh/Network/Anchor/Packets/UpdateTeamState.cpp @@ -2,10 +2,9 @@ #include "soh/Network/Anchor/JsonConversions.hpp" #include #include -#include "soh/Enhancements/randomizer/entrance.h" -#include "soh/Enhancements/randomizer/dungeon.h" #include "soh/OTRGlobals.h" #include "soh/Notification/Notification.h" +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "variables.h" @@ -125,8 +124,9 @@ void Anchor::HandlePacket_UpdateTeamState(nlohmann::json payload) { } isHandlingUpdateTeamState = true; - // This can happen in between file select and the game starting, so we cant use this check, but we need to ensure we - // be careful to wrap PlayState usage in this check + // This can happen in between file select and the game starting, so we can't use this check, but we need to ensure + // we be careful to wrap PlayState usage in this check + // // if (!IsSaveLoaded()) { // return; // } @@ -224,24 +224,24 @@ void Anchor::HandlePacket_UpdateTeamState(nlohmann::json payload) { auto randoContext = Rando::Context::GetInstance(); for (int i = 0; i < RC_MAX; i++) { + auto itemLocation = payload["state"]["rando"].at("itemLocations").at(i); // randoContext->GetItemLocation(i)->RefPlacedItem() = - // payload["state"]["rando"]["itemLocations"][i]["rgID"].get(); + // itemLocation.at("rgID").get(); OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->SetCheckStatus( - payload["state"]["rando"]["itemLocations"][i][0].get()); - OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->SetIsSkipped( - payload["state"]["rando"]["itemLocations"][i][1].get()); + itemLocation.at(0).get()); + OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->SetIsSkipped(itemLocation.at(1).get()); - // if (payload["state"]["rando"]["itemLocations"][i].contains("fakeRgID")) { + // if (itemLocation.contains("fakeRgID")) { // randoContext->overrides.emplace(static_cast(i), // Rando::ItemOverride(static_cast(i), - // payload["state"]["rando"]["itemLocations"][i]["fakeRgID"].get())); + // itemLocation.at("fakeRgID").get())); // randoContext->GetItemOverride(i).GetTrickName().english = - // payload["state"]["rando"]["itemLocations"][i]["trickName"]["english"].get(); + // itemLocation.at("trickName").at("english").get(); // randoContext->GetItemOverride(i).GetTrickName().french = - // payload["state"]["rando"]["itemLocations"][i]["trickName"]["french"].get(); + // itemLocation.at("trickName").at("french").get(); // } - // if (payload["state"]["rando"]["itemLocations"][i].contains("price")) { - // u16 price = payload["state"]["rando"]["itemLocations"][i]["price"].get(); + // if (itemLocation.contains("price")) { + // u16 price = itemLocation.at("price"].get(); // if (price > 0) { // randoContext->GetItemLocation(i)->SetCustomPrice(price); // } diff --git a/soh/soh/Network/CrowdControl/CrowdControl.cpp b/soh/soh/Network/CrowdControl/CrowdControl.cpp index 7bbfb64b7e..a0621a4eac 100644 --- a/soh/soh/Network/CrowdControl/CrowdControl.cpp +++ b/soh/soh/Network/CrowdControl/CrowdControl.cpp @@ -130,6 +130,10 @@ void CrowdControl::EmitMessage(uint32_t eventId, long timeRemaining, EffectResul } CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) { + if (!GameInteractor::IsPlayerInControl()) { + return EffectResult::Retry; + } + GameInteractionEffectQueryResult giResult; if (effect->category == kEffectCatSpawnEnemy) { giResult = GameInteractor::RawAction::SpawnEnemyWithOffset(effect->spawnParams[0], effect->spawnParams[1], @@ -147,6 +151,10 @@ CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) { /// Checks if effect can be applied -- should not be used to check for spawn enemy effects. CrowdControl::EffectResult CrowdControl::CanApplyEffect(Effect* effect) { assert(effect->category != kEffectCatSpawnEnemy || effect->category != kEffectCatSpawnActor); + if (!GameInteractor::IsPlayerInControl()) { + return EffectResult::Retry; + } + GameInteractionEffectQueryResult giResult = GameInteractor::CanApplyEffect(*effect->giEffect.get()); return TranslateGiEnum(giResult); @@ -275,6 +283,9 @@ std::unique_ptr CrowdControl::ParseMessage(nlohmann::json break; case kEffectSpawnWolfos: effect->spawnParams[0] = ACTOR_EN_WF; + // Match EnEncount1 wolfos spawner (0xFF00): high byte must be 0xFF so EnWf_Init does not treat + // switchFlag 0; Flags_GetSwitch(play, 0) is true in many scenes and would instantly kill the actor. + effect->spawnParams[1] = (0xFF << 8) | 0x00; // normal Wolfos; high byte 0xFF = no switch (vanilla encount) effect->category = kEffectCatSpawnEnemy; break; case kEffectSpawnWallmaster: diff --git a/soh/soh/Network/Sail/Sail.cpp b/soh/soh/Network/Sail/Sail.cpp index dcfcca8aca..43de5115cf 100644 --- a/soh/soh/Network/Sail/Sail.cpp +++ b/soh/soh/Network/Sail/Sail.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "soh/ShipUtils.h" template bool IsType(const SrcType* src) { return dynamic_cast(src) != nullptr; @@ -53,7 +54,7 @@ void Sail::OnIncomingJson(nlohmann::json payload) { std::string command = payload["command"].get(); std::reinterpret_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) ->Dispatch(command); responsePayload["status"] = "success"; SendJsonToRemote(responsePayload); @@ -77,7 +78,7 @@ void Sail::OnIncomingJson(nlohmann::json payload) { std::string command = payload["effect"]["command"].get(); std::reinterpret_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) ->Dispatch(command); responsePayload["status"] = "success"; SendJsonToRemote(responsePayload); @@ -337,7 +338,7 @@ void Sail::RegisterHooks() { return; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnTransitionEnd"; payload["hook"]["sceneNum"] = sceneNum; @@ -350,7 +351,7 @@ void Sail::RegisterHooks() { return; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnLoadGame"; payload["hook"]["fileNum"] = fileNum; @@ -363,7 +364,7 @@ void Sail::RegisterHooks() { return; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnExitGame"; payload["hook"]["fileNum"] = fileNum; @@ -375,7 +376,7 @@ void Sail::RegisterHooks() { if (!isConnected || !GameInteractor::IsSaveLoaded()) return; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnItemReceive"; payload["hook"]["tableId"] = itemEntry.tableId; @@ -390,7 +391,7 @@ void Sail::RegisterHooks() { Actor* actor = (Actor*)refActor; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnEnemyDefeat"; payload["hook"]["actorId"] = actor->id; @@ -405,7 +406,7 @@ void Sail::RegisterHooks() { Actor* actor = (Actor*)refActor; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnActorInit"; payload["hook"]["actorId"] = actor->id; @@ -418,7 +419,7 @@ void Sail::RegisterHooks() { if (!isConnected || !GameInteractor::IsSaveLoaded()) return; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnFlagSet"; payload["hook"]["flagType"] = flagType; @@ -431,7 +432,7 @@ void Sail::RegisterHooks() { if (!isConnected || !GameInteractor::IsSaveLoaded()) return; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnFlagUnset"; payload["hook"]["flagType"] = flagType; @@ -444,7 +445,7 @@ void Sail::RegisterHooks() { if (!isConnected || !GameInteractor::IsSaveLoaded()) return; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnSceneFlagSet"; payload["hook"]["flagType"] = flagType; @@ -458,7 +459,7 @@ void Sail::RegisterHooks() { if (!isConnected || !GameInteractor::IsSaveLoaded()) return; nlohmann::json payload; - payload["id"] = std::rand(); + payload["id"] = ShipUtils::Random(0, UINT32_MAX); payload["type"] = "hook"; payload["hook"]["type"] = "OnSceneFlagUnset"; payload["hook"]["flagType"] = flagType; diff --git a/soh/soh/Notification/Notification.cpp b/soh/soh/Notification/Notification.cpp index 5b6039cf8c..03a7c03183 100644 --- a/soh/soh/Notification/Notification.cpp +++ b/soh/soh/Notification/Notification.cpp @@ -3,6 +3,10 @@ #include #include "soh/OTRGlobals.h" +#include + +#include + extern "C" { #include "functions.h" #include "macros.h" @@ -88,8 +92,10 @@ void Window::Draw() { ImGui::SetWindowPos(notificationPos); if (notification.itemIcon != nullptr) { - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(notification.itemIcon), - ImVec2(24, 24)); + ImGui::Image( + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetTextureByName(notification.itemIcon), + ImVec2(24, 24)); ImGui::SameLine(); } if (!notification.prefix.empty()) { diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index b5227b4113..b52beaead3 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -7,9 +7,11 @@ #include #include #include +#include #include "ResourceManagerHelpers.h" #include +#include #include #include #include @@ -30,7 +32,9 @@ #include "Enhancements/randomizer/randomizer_entrance_tracker.h" #include "Enhancements/randomizer/randomizer_check_tracker.h" #include "Enhancements/randomizer/static_data.h" +#include "soh/Enhancements/randomizer/settings.h" #include "Enhancements/gameplaystats.h" +#include "soh/Enhancements/savestates.h" #include "frame_interpolation.h" #include "SohGui/SohMenu.h" #include "SohGui/SohGui.hpp" @@ -44,6 +48,9 @@ #include "Enhancements/custom-message/CustomMessageManager.h" #include "util.h" +#include +#include + #if not defined(__SWITCH__) && not defined(__WIIU__) #include "Extractor/Extract.h" #endif @@ -65,13 +72,14 @@ #include #include "Enhancements/item-tables/ItemTableManager.h" +#include "Enhancements/Lang/Lang.h" +#include "soh/SohGui/SohGui.hpp" #include "soh/SohGui/ImGuiUtils.h" #include "ActorDB.h" #include "SaveManager.h" #include "soh/Network/CrowdControl/CrowdControl.h" #include "soh/Network/Sail/Sail.h" #include "soh/Network/Anchor/Anchor.h" -#include "Enhancements/mods.h" #include "Enhancements/game-interactor/GameInteractor.h" #include "Enhancements/randomizer/draw.h" #include @@ -121,6 +129,14 @@ #include "soh/config/ConfigUpdaters.h" #include "soh/ShipInit.hpp" +#ifdef __WIIU__ +const uint32_t defaultImGuiScale = 3; +#else +const uint32_t defaultImGuiScale = 1; +#endif + +const float imguiScaleOptionToValue[4] = { 0.75f, 1.0f, 1.5f, 2.0f }; + bool SoH_HandleConfigDrop(char* filePath); OTRGlobals* OTRGlobals::Instance; @@ -305,7 +321,7 @@ OTRGlobals::OTRGlobals() { if (sohArchiveVersionMatch) { - auto overlay = context->GetInstance()->GetWindow()->GetGui()->GetGameOverlay(); + auto overlay = context->GetRawInstance()->GetWindow()->GetGui()->GetGameOverlay(); overlay->LoadFont("Press Start 2P", 12.0f, "fonts/PressStart2P-Regular.ttf"); overlay->LoadFont("Fipps", 32.0f, "fonts/Fipps-Regular.otf"); overlay->SetCurrentFont(CVarGetString(CVAR_GAME_OVERLAY_FONT, "Press Start 2P")); @@ -763,6 +779,21 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) { #endif } +void InitGfxDebugger() { + auto dbg = + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow())->GetGfxDebugger(); + + if (dbg != nullptr) { + return; + } + + dbg = std::make_shared(); + + if (dbg != nullptr) { + SPDLOG_ERROR("Failed to initialize gfx debugger"); + } +} + void OTRGlobals::Initialize() { std::string mqPath = Ship::Context::LocateFileAcrossAppDirs("oot-mq.o2r", appShortName); if (std::filesystem::exists(mqPath)) { @@ -789,9 +820,9 @@ void OTRGlobals::Initialize() { auto logLevel = static_cast(CVarGetInteger(CVAR_DEVELOPER_TOOLS("LogLevel"), defaultLogLevel)); context->InitLogging(logLevel, logLevel); - Ship::Context::GetInstance()->GetLogger()->set_pattern("[%H:%M:%S.%e] [%s:%#] [%l] %v"); + Ship::Context::GetRawInstance()->GetLogger()->set_pattern("[%H:%M:%S.%e] [%s:%#] [%l] %v"); - context->InitGfxDebugger(); + InitGfxDebugger(); context->InitFileDropMgr(); // tell LUS to reserve 3 SoH specific threads (Game, Audio, Save) @@ -882,6 +913,8 @@ void OTRGlobals::Initialize() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Background", static_cast(SOH::ResourceType::SOH_Background), 0); + Lang::LoadLangs(); + gSaveStateMgr = std::make_shared(); gRandoContext->InitStaticData(); gRandoContext = Rando::Context::CreateInstance(); @@ -960,25 +993,6 @@ void OTRGlobals::ScaleImGui() { previousImGuiScaleIndex = imGuiScaleIndex; } -ImFont* OTRGlobals::CreateDefaultFontWithSize(float size) { - auto mImGuiIo = &ImGui::GetIO(); - ImFontConfig fontCfg = ImFontConfig(); - fontCfg.OversampleH = fontCfg.OversampleV = 1; - fontCfg.PixelSnapH = true; - fontCfg.SizePixels = size; - ImFont* font = mImGuiIo->Fonts->AddFontDefault(&fontCfg); - // FontAwesome fonts need to have their sizes reduced by 2.0f/3.0f in order to align correctly - float iconFontSize = size * 2.0f / 3.0f; - static const ImWchar sIconsRanges[] = { ICON_MIN_FA, ICON_MAX_16_FA, 0 }; - ImFontConfig iconsConfig; - iconsConfig.MergeMode = true; - iconsConfig.PixelSnapH = true; - iconsConfig.GlyphMinAdvanceX = iconFontSize; - mImGuiIo->Fonts->AddFontFromMemoryCompressedBase85TTF(fontawesome_compressed_data_base85, iconFontSize, - &iconsConfig, sIconsRanges); - return font; -} - bool OTRGlobals::HasMasterQuest() { return hasMasterQuest; } @@ -989,10 +1003,10 @@ bool OTRGlobals::HasOriginal() { uint32_t OTRGlobals::GetInterpolationFPS() { if (CVarGetInteger(CVAR_SETTING("MatchRefreshRate"), 0)) { - return Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); + return Ship::Context::GetRawInstance()->GetWindow()->GetCurrentRefreshRate(); } else if (CVarGetInteger(CVAR_VSYNC_ENABLED, 1) || - !Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) { - return std::min(Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(), + !Ship::Context::GetRawInstance()->GetWindow()->CanDisableVerticalSync()) { + return std::min(Ship::Context::GetRawInstance()->GetWindow()->GetCurrentRefreshRate(), CVarGetInteger(CVAR_SETTING("InterpolationFPS"), 20)); } return CVarGetInteger(CVAR_SETTING("InterpolationFPS"), 20); @@ -1001,7 +1015,7 @@ uint32_t OTRGlobals::GetInterpolationFPS() { extern "C" void OTRMessage_Init(); extern "C" void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples); extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len); -extern "C" int AudioPlayer_Buffered(void); +int AudioPlayer_Buffered(void); extern "C" int AudioPlayer_GetDesiredBuffered(void); std::unordered_map ExtensionCache; @@ -1045,8 +1059,7 @@ void OTRAudio_Thread() { } } -// C->C++ Bridge -extern "C" void OTRAudio_Init() { +void OTRAudio_Init() { // Precache all our samples, sequences, etc... ResourceMgr_LoadDirectory("audio"); @@ -1056,6 +1069,7 @@ extern "C" void OTRAudio_Init() { } } +// C->C++ Bridge extern "C" char** sequenceMap; extern "C" size_t sequenceMapSize; @@ -1087,7 +1101,7 @@ extern "C" void OTRAudio_Exit() { #endif } -extern "C" void VanillaItemTable_Init() { +void VanillaItemTable_Init() { static GetItemEntry getItemTable[] = { // clang-format off GET_ITEM(ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, GI_BOMBS_5), @@ -1396,7 +1410,7 @@ extern "C" RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID) { } extern "C" void OTRExtScanner() { - auto lst = *Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles().get(); + auto lst = *Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->ListFiles().get(); for (auto& rPath : lst) { std::vector raw = StringHelper::Split(rPath, "."); @@ -1497,14 +1511,13 @@ extern "C" void InitOTR(int argc, char* argv[]) { VanillaItemTable_Init(); DebugConsole_Init(); - InitMods(); ActorDB::AddBuiltInCustomActors(); // #region SOH [Randomizer] TODO: Remove these and refactor spoiler file handling for randomizer CVarClear(CVAR_GENERAL("RandomizerNewFileDropped")); CVarClear(CVAR_GENERAL("RandomizerDroppedFile")); // #endregion - Ship::Context::GetInstance()->GetFileDropMgr()->RegisterDropHandler(SoH_HandleConfigDrop); + Ship::Context::GetRawInstance()->GetFileDropMgr()->RegisterDropHandler(SoH_HandleConfigDrop); RegisterImGuiItemIcons(); @@ -1609,7 +1622,8 @@ extern "C" void Graph_StartFrame() { switch (dwScancode) { case KbScancode::LUS_KB_F1: { std::shared_ptr modal = static_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Modal Window")); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetGuiWindow("Modal Window")); if (modal->IsPopupOpen("Menu Moved")) { modal->DismissPopup(); } else { @@ -1622,8 +1636,9 @@ extern "C" void Graph_StartFrame() { } case KbScancode::LUS_KB_F5: { if (CVarGetInteger(CVAR_CHEAT("SaveStatesEnabled"), 0) == 0) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( - 6.0f, true, "Save states not enabled. Check Cheats Menu."); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetGameOverlay() + ->TextDrawNotification(6.0f, true, "Save states not enabled. Check Cheats Menu."); return; } const unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); @@ -1643,8 +1658,9 @@ extern "C" void Graph_StartFrame() { } case KbScancode::LUS_KB_F6: { if (CVarGetInteger(CVAR_CHEAT("SaveStatesEnabled"), 0) == 0) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( - 6.0f, true, "Save states not enabled. Check Cheats Menu."); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetGameOverlay() + ->TextDrawNotification(6.0f, true, "Save states not enabled. Check Cheats Menu."); return; } unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); @@ -1658,8 +1674,9 @@ extern "C" void Graph_StartFrame() { } case KbScancode::LUS_KB_F7: { if (CVarGetInteger(CVAR_CHEAT("SaveStatesEnabled"), 0) == 0) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification( - 6.0f, true, "Save states not enabled. Check Cheats Menu."); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetGameOverlay() + ->TextDrawNotification(6.0f, true, "Save states not enabled. Check Cheats Menu."); return; } const unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); @@ -1739,7 +1756,7 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { static int time; int fps = target_fps; int original_fps = 60 / R_UPDATE_RATE; - auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()); if (target_fps == 20 || original_fps > target_fps) { fps = original_fps; @@ -1788,7 +1805,7 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { bool curAltAssets = CVarGetInteger(CVAR_SETTING("AltAssets"), 1); if (prevAltAssets != curAltAssets) { prevAltAssets = curAltAssets; - Ship::Context::GetInstance()->GetResourceManager()->SetAltAssetsEnabled(curAltAssets); + Ship::Context::GetRawInstance()->GetResourceManager()->SetAltAssetsEnabled(curAltAssets); gfx_texture_cache_clear(); SOH::SkeletonPatcher::UpdateSkeletons(); GameInteractor::Instance->ExecuteHooks(); @@ -1799,10 +1816,8 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { OTRGlobals::Instance->context->lastScancode = -1;*/ } -float divisor_num = 0.0f; - extern "C" void OTRGetPixelDepthPrepare(float x, float y) { - auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()); if (wnd == nullptr) { return; } @@ -1811,7 +1826,7 @@ extern "C" void OTRGetPixelDepthPrepare(float x, float y) { } extern "C" uint16_t OTRGetPixelDepth(float x, float y) { - auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()); if (wnd == nullptr) { return 0; } @@ -1829,62 +1844,6 @@ extern "C" uint8_t GetSeedIconIndex(uint8_t index) { std::map cachedCustomSFs; -extern "C" SoundFontSample* ReadCustomSample(const char* path) { - return nullptr; - /* - if (!ExtensionCache.contains(path)) - return nullptr; - - ExtensionEntry entry = ExtensionCache[path]; - - auto sampleRaw = Ship::Context::GetInstance()->GetResourceManager()->LoadFile(entry.path); - uint32_t* strem = (uint32_t*)sampleRaw->Buffer.get(); - uint8_t* strem2 = (uint8_t*)strem; - - SoundFontSample* sampleC = new SoundFontSample; - - if (entry.ext == "wav") { - drwav_uint32 channels; - drwav_uint32 sampleRate; - drwav_uint64 totalPcm; - drmp3_int16* pcmData = - drwav_open_memory_and_read_pcm_frames_s16(strem2, sampleRaw->BufferSize, &channels, &sampleRate, &totalPcm, - NULL); sampleC->size = totalPcm; sampleC->sampleAddr = (uint8_t*)pcmData; sampleC->codec = CODEC_S16; - - sampleC->loop = new AdpcmLoop; - sampleC->loop->start = 0; - sampleC->loop->end = sampleC->size - 1; - sampleC->loop->count = 0; - sampleC->sampleRateMagicValue = 'RIFF'; - sampleC->sampleRate = sampleRate; - - cachedCustomSFs[path] = sampleC; - return sampleC; - } else if (entry.ext == "mp3") { - drmp3_config mp3Info; - drmp3_uint64 totalPcm; - drmp3_int16* pcmData = - drmp3_open_memory_and_read_pcm_frames_s16(strem2, sampleRaw->BufferSize, &mp3Info, &totalPcm, NULL); - - sampleC->size = totalPcm * mp3Info.channels * sizeof(short); - sampleC->sampleAddr = (uint8_t*)pcmData; - sampleC->codec = CODEC_S16; - - sampleC->loop = new AdpcmLoop; - sampleC->loop->start = 0; - sampleC->loop->end = sampleC->size; - sampleC->loop->count = 0; - sampleC->sampleRateMagicValue = 'RIFF'; - sampleC->sampleRate = mp3Info.sampleRate; - - cachedCustomSFs[path] = sampleC; - return sampleC; - } - - return nullptr; - */ -} - ImFont* OTRGlobals::CreateFontWithSize(float size, std::string fontPath, bool isJapaneseFont) { auto mImGuiIo = &ImGui::GetIO(); ImFont* font; @@ -1901,7 +1860,7 @@ ImFont* OTRGlobals::CreateFontWithSize(float size, std::string fontPath, bool is initData->ResourceVersion = 0; initData->Path = fontPath; std::shared_ptr fontData = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fontPath, false, initData)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(fontPath, false, initData)); ImFontConfig fontConf; fontConf.FontDataOwnedByAtlas = false; const ImWchar* glyph_ranges = isJapaneseFont ? mImGuiIo->Fonts->GetGlyphRangesJapanese() : nullptr; @@ -1937,20 +1896,6 @@ std::filesystem::path GetSaveFile() { return GetSaveFile(pConf); } -void OTRGlobals::CheckSaveFile(size_t sramSize) const { - const std::shared_ptr pConf = Instance->context->GetConfig(); - - std::filesystem::path savePath = GetSaveFile(pConf); - std::fstream saveFile(savePath, std::fstream::in | std::fstream::out | std::fstream::binary); - if (saveFile.fail()) { - saveFile.open(savePath, std::fstream::in | std::fstream::out | std::fstream::binary | std::fstream::app); - for (size_t i = 0; i < sramSize; i++) { - saveFile.write("\0", 1); - } - } - saveFile.close(); -} - extern "C" void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size) { SaveManager::ReadSaveFile(GetSaveFile(), addr, dramAddr, size); } @@ -2077,14 +2022,6 @@ extern "C" void OTRGfxPrint(const char* str, void* printer, void (*printImpl)(vo } } -extern "C" uint32_t OTRGetCurrentWidth() { - return OTRGlobals::Instance->context->GetWindow()->GetWidth(); -} - -extern "C" uint32_t OTRGetCurrentHeight() { - return OTRGlobals::Instance->context->GetWindow()->GetHeight(); -} - Color_RGB8 GetColorForControllerLED() { auto brightness = CVarGetFloat(CVAR_SETTING("LEDBrightness"), 1.0f) / 1.0f; Color_RGB8 color = { 0, 0, 0 }; @@ -2183,26 +2120,27 @@ Color_RGB8 GetColorForControllerLED() { extern "C" void OTRControllerCallback(uint8_t rumble) { // We call this every tick, SDL accounts for this use and prevents driver spam // https://github.com/libsdl-org/SDL/blob/f17058b562c8a1090c0c996b42982721ace90903/src/joystick/SDL_joystick.c#L1114-L1144 - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(0)->GetLED()->SetLEDColor( + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(0)->GetLED()->SetLEDColor( GetColorForControllerLED()); static std::shared_ptr controllerConfigWindow = nullptr; if (controllerConfigWindow == nullptr) { controllerConfigWindow = std::dynamic_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Controller Configuration")); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetGuiWindow("Controller Configuration")); } else if (controllerConfigWindow->TestingRumble()) { return; } if (rumble) { - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(0)->GetRumble()->StartRumble(); + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(0)->GetRumble()->StartRumble(); } else { - Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(0)->GetRumble()->StopRumble(); + Ship::Context::GetRawInstance()->GetControlDeck()->GetControllerByPort(0)->GetRumble()->StopRumble(); } } extern "C" float OTRGetAspectRatio() { - return Ship::Context::GetInstance()->GetWindow()->GetAspectRatio(); + return Ship::Context::GetRawInstance()->GetWindow()->GetAspectRatio(); } extern "C" float OTRGetDimensionFromLeftEdge(float v) { @@ -2215,7 +2153,7 @@ extern "C" float OTRGetDimensionFromRightEdge(float v) { // Gets the width of the current render target area extern "C" uint32_t OTRGetGameRenderWidth() { - auto fastWnd = dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + auto fastWnd = dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()); auto intP = fastWnd->GetInterpreterWeak().lock(); if (!intP) { @@ -2231,7 +2169,7 @@ extern "C" uint32_t OTRGetGameRenderWidth() { // Gets the height of the current render target area extern "C" uint32_t OTRGetGameRenderHeight() { - auto fastWnd = dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + auto fastWnd = dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()); auto intP = fastWnd->GetInterpreterWeak().lock(); if (!intP) { @@ -2256,7 +2194,7 @@ extern "C" int16_t OTRGetRectDimensionFromRightEdge(float v) { return ((int)ceilf(OTRGetDimensionFromRightEdge(v))); } -extern "C" int AudioPlayer_Buffered(void) { +int AudioPlayer_Buffered(void) { return AudioPlayerBuffered(); } @@ -2270,7 +2208,7 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) { extern "C" int Controller_ShouldRumble(size_t slot) { // don't rumble if we don't have rumble mappings - if (Ship::Context::GetInstance() + if (Ship::Context::GetRawInstance() ->GetControlDeck() ->GetControllerByPort(static_cast(slot)) ->GetRumble() @@ -2280,7 +2218,7 @@ extern "C" int Controller_ShouldRumble(size_t slot) { } // don't rumble if we don't have connected gamepads - if (Ship::Context::GetInstance() + if (Ship::Context::GetRawInstance() ->GetControlDeck() ->GetConnectedPhysicalDeviceManager() ->GetConnectedSDLGamepadsForPort(slot) @@ -2344,10 +2282,6 @@ extern "C" void Randomizer_ParseSpoiler(const char* fileLoc) { OTRGlobals::Instance->gRandoContext->ParseSpoiler(fileLoc); } -extern "C" bool Randomizer_IsTrialRequired(s32 trialFlag) { - return OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag); -} - extern "C" u32 SpoilerFileExists(const char* spoilerFileName) { return OTRGlobals::Instance->gRandomizer->SpoilerFileExists(spoilerFileName); } @@ -2376,15 +2310,6 @@ extern "C" GetItemEntry ItemTable_RetrieveEntry(s16 tableID, s16 getItemID) { return ItemTableManager::Instance->RetrieveItemEntry(tableID, getItemID); } -extern "C" GetItemEntry Randomizer_GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId) { - return OTRGlobals::Instance->gRandomizer->GetItemFromActor(actorId, sceneNum, actorParams, ogId); -} - -extern "C" GetItemEntry Randomizer_GetItemFromActorWithoutObtainabilityCheck(s16 actorId, s16 sceneNum, s16 actorParams, - GetItemID ogId) { - return OTRGlobals::Instance->gRandomizer->GetItemFromActor(actorId, sceneNum, actorParams, ogId, false); -} - extern "C" GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) { return OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(randomizerCheck, ogId); } @@ -2394,10 +2319,6 @@ extern "C" GetItemEntry Randomizer_GetItemFromKnownCheckWithoutObtainabilityChec return OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(randomizerCheck, ogId, false); } -extern "C" RandomizerInf Randomizer_GetRandomizerInfFromCheck(RandomizerCheck randomizerCheck) { - return OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(randomizerCheck); -} - extern "C" ItemObtainability Randomizer_GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck) { return OTRGlobals::Instance->gRandomizer->GetItemObtainabilityFromRandomizerCheck(randomizerCheck); } @@ -2414,10 +2335,6 @@ extern "C" uint8_t Randomizer_IsSeedGenerated() { return OTRGlobals::Instance->gRandoContext->IsSeedGenerated() ? 1 : 0; } -extern "C" void Randomizer_SetSeedGenerated(bool seedGenerated) { - OTRGlobals::Instance->gRandoContext->SetSeedGenerated(seedGenerated); -} - extern "C" uint8_t Randomizer_IsSpoilerLoaded() { return OTRGlobals::Instance->gRandoContext->IsSpoilerLoaded() ? 1 : 0; } @@ -2443,7 +2360,7 @@ extern "C" void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex) { } extern "C" void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement) { - if (auto intP = dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()) + if (auto intP = dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()) ->GetInterpreterWeak() .lock()) { intP->RegisterBlendedTexture(name, mask, replacement); @@ -2453,7 +2370,7 @@ extern "C" void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* repla } extern "C" void Gfx_UnregisterBlendedTexture(const char* name) { - if (auto intP = dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()) + if (auto intP = dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()) ->GetInterpreterWeak() .lock()) { intP->UnregisterBlendedTexture(name); @@ -2473,7 +2390,7 @@ extern "C" void Gfx_TextureCacheDelete(const uint8_t* texAddr) { texAddr = (const uint8_t*)ResourceMgr_GetResourceDataByNameHandlingMQ(imgName); } - if (auto intP = dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()) + if (auto intP = dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()) ->GetInterpreterWeak() .lock()) { intP->TextureCacheDelete(texAddr); @@ -2524,7 +2441,7 @@ bool SoH_HandleConfigDrop(char* filePath) { } } - auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); + auto gui = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()); gui->GetGuiWindow("Console")->Hide(); gui->GetGuiWindow("Actor Viewer")->Hide(); gui->GetGuiWindow("Collision Viewer")->Hide(); @@ -2532,7 +2449,8 @@ bool SoH_HandleConfigDrop(char* filePath) { gui->GetGuiWindow("Display List Viewer")->Hide(); gui->GetGuiWindow("Stats")->Hide(); std::dynamic_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->GetGuiWindow("Console")) ->ClearBindings(); Rando::Settings::GetInstance()->UpdateAllOptions(); @@ -2545,27 +2463,19 @@ bool SoH_HandleConfigDrop(char* filePath) { return true; } catch (std::exception& e) { SPDLOG_ERROR("Failed to load config file: {}", e.what()); - auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); + auto gui = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()); gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Failed to load config file"); return false; } catch (...) { SPDLOG_ERROR("Failed to load config file"); - auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); + auto gui = std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()); gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Failed to load config file"); return false; } return false; } -extern "C" void CheckTracker_RecalculateAvailableChecks() { - CheckTracker::RecalculateAvailableChecks(); -} - -extern "C" uint32_t Ship_GetInterpolationFPS() { - return OTRGlobals::Instance->GetInterpolationFPS(); -} - // Number of interpolated frames extern "C" uint32_t Ship_GetInterpolationFrameCount() { - return ceil((float)Ship_GetInterpolationFPS() / 20.0f); + return ceil((float)OTRGlobals::Instance->GetInterpolationFPS() / 20.0f); } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 424105f8cd..abd40dd4ba 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -1,6 +1,3 @@ -#ifndef OTR_GLOBALS_H -#define OTR_GLOBALS_H - #pragma once #define BTN_CUSTOM_MODIFIER1 0x0040 @@ -17,15 +14,12 @@ #define M_PIf 3.14159265358979323846f #define M_PI_2f 1.57079632679489661923f // pi/2 -#define M_SQRT2f 1.41421356237309504880f -#define M_SQRT1_2f 0.70710678118654752440f /* 1/sqrt(2) */ #ifdef __cplusplus -#include -#include "Enhancements/savestates.h" -#include "Enhancements/randomizer/randomizer.h" -#include +#include +#include #include +#include struct ExtensionEntry { std::string path; @@ -33,31 +27,31 @@ struct ExtensionEntry { }; extern std::unordered_map ExtensionCache; -#include "Enhancements/randomizer/settings.h" const std::string appShortName = "soh"; -#ifdef __WIIU__ -const uint32_t defaultImGuiScale = 3; -#else -const uint32_t defaultImGuiScale = 1; -#endif +class Randomizer; +class SaveStateMgr; -const float imguiScaleOptionToValue[4] = { 0.75f, 1.0f, 1.5f, 2.0f }; +namespace Rando { +class Context; +} + +namespace Ship { +class Context; +} + +struct ImFont; class OTRGlobals { public: static OTRGlobals* Instance; - std::shared_ptr context; + Ship::Context* context; std::shared_ptr gSaveStateMgr; std::shared_ptr gRandomizer; std::shared_ptr gRandoContext; - ImFont* defaultFontSmaller; - ImFont* defaultFontLarger; - ImFont* defaultFontLargest; - ImFont* fontMonoSmall = nullptr; ImFont* fontStandard = nullptr; ImFont* fontStandardLarger = nullptr; @@ -76,13 +70,10 @@ class OTRGlobals { bool HasMasterQuest(); bool HasOriginal(); uint32_t GetInterpolationFPS(); - std::shared_ptr> ListFiles(std::string path); private: - void CheckSaveFile(size_t sramSize) const; bool hasMasterQuest; bool hasOriginal; - ImFont* CreateDefaultFontWithSize(float size); ImFont* CreateFontWithSize(float size, std::string fontPath, bool isJapaneseFont = false); }; #endif @@ -90,19 +81,12 @@ class OTRGlobals { #ifndef __cplusplus void InitOTR(int argc, char* argv[]); void DeinitOTR(void); -void VanillaItemTable_Init(); -void OTRAudio_Init(); void OTRMessage_Init(); -void InitAudio(); void Graph_StartFrame(); void Graph_ProcessGfxCommands(Gfx* commands); -void Graph_ProcessFrame(void (*run_one_game_iter)(void)); -void OTRLogString(const char* src); void OTRGfxPrint(const char* str, void* printer, void (*printImpl)(void*, char)); void OTRGetPixelDepthPrepare(float x, float y); uint16_t OTRGetPixelDepth(float x, float y); -int32_t OTRGetLastScancode(); -char* GetResourceDataByNameHandlingMQ(const char* path); void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size); void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size); @@ -110,8 +94,6 @@ void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size); uint64_t GetPerfCounter(); uint64_t osGetTime(void); uint32_t osGetCount(void); -uint32_t OTRGetCurrentWidth(void); -uint32_t OTRGetCurrentHeight(void); float OTRGetAspectRatio(void); float OTRGetDimensionFromLeftEdge(float v); float OTRGetDimensionFromRightEdge(float v); @@ -119,13 +101,10 @@ int16_t OTRGetRectDimensionFromLeftEdge(float v); int16_t OTRGetRectDimensionFromRightEdge(float v); uint32_t OTRGetGameRenderWidth(); uint32_t OTRGetGameRenderHeight(); -int AudioPlayer_Buffered(void); int AudioPlayer_GetDesiredBuffered(void); void AudioPlayer_Play(const uint8_t* buf, uint32_t len); void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples); int Controller_ShouldRumble(size_t slot); -void Controller_BlockGameInput(); -void Controller_UnblockGameInput(); size_t GetEquipNowMessage(char* buffer, char* src, const size_t maxBufferSize); u32 SpoilerFileExists(const char* spoilerFileName); Sprite* GetSeedTexture(uint8_t index); @@ -134,18 +113,12 @@ u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams); ShopItemIdentity Randomizer_IdentifyShopItem(s32 sceneNum, u8 slotIndex); void Randomizer_ParseSpoiler(const char* fileLoc); -bool Randomizer_IsTrialRequired(s32 trialFlag); -GetItemEntry Randomizer_GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId); -GetItemEntry Randomizer_GetItemFromActorWithoutObtainabilityCheck(s16 actorId, s16 sceneNum, s16 actorParams, - GetItemID ogId); GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); GetItemEntry Randomizer_GetItemFromKnownCheckWithoutObtainabilityCheck(RandomizerCheck randomizerCheck, GetItemID ogId); -RandomizerInf Randomizer_GetRandomizerInfFromCheck(RandomizerCheck randomizerCheck); bool Randomizer_IsCheckShuffled(RandomizerCheck check); GetItemEntry GetItemMystery(); ItemObtainability Randomizer_GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck); uint8_t Randomizer_IsSeedGenerated(); -void Randomizer_SetSeedGenerated(bool seedGenerated); uint8_t Randomizer_IsSpoilerLoaded(); void Randomizer_SetSpoilerLoaded(bool spoilerLoaded); uint8_t Randomizer_GenerateRandomizer(); @@ -158,14 +131,11 @@ void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement); void Gfx_UnregisterBlendedTexture(const char* name); void Gfx_TextureCacheDelete(const uint8_t* addr); void SaveManager_ThreadPoolWait(); -void CheckTracker_OnMessageClose(); -void CheckTracker_RecalculateAvailableChecks(); GetItemID RetrieveGetItemIDFromItemID(ItemID itemID); RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID); void Messagebox_ShowErrorBox(char* title, char* body); -uint32_t Ship_GetInterpolationFPS(); uint32_t Ship_GetInterpolationFrameCount(); #endif @@ -175,6 +145,4 @@ extern "C" { uint64_t GetUnixTimestamp(); #ifdef __cplusplus }; -#endif - -#endif +#endif \ No newline at end of file diff --git a/soh/soh/ResourceManagerHelpers.cpp b/soh/soh/ResourceManagerHelpers.cpp index 4d4f912645..59dfa2084b 100644 --- a/soh/soh/ResourceManagerHelpers.cpp +++ b/soh/soh/ResourceManagerHelpers.cpp @@ -5,6 +5,7 @@ #include "cvar_prefixes.h" #include "Enhancements/enhancementTypes.h" #include "Enhancements/randomizer/dungeon.h" +#include "soh/Enhancements/randomizer/SeedContext.h" #include #include #include "resource/type/SohResourceType.h" @@ -15,19 +16,21 @@ #include #include +#include + extern "C" PlayState* gPlayState; extern "C" uint32_t ResourceMgr_GetNumGameVersions() { - return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions().size(); + return Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions().size(); } extern "C" uint32_t ResourceMgr_GetGameVersion(int index) { - return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; + return Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; } extern "C" uint32_t ResourceMgr_GetGamePlatform(int index) { uint32_t version = - Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; + Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; switch (version) { case OOT_NTSC_US_10: @@ -52,7 +55,7 @@ extern "C" uint32_t ResourceMgr_GetGamePlatform(int index) { extern "C" uint32_t ResourceMgr_GetGameRegion(int index) { uint32_t version = - Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; + Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; switch (version) { case OOT_NTSC_US_10: @@ -127,11 +130,11 @@ extern "C" uint32_t ResourceMgr_IsGameMasterQuest() { } extern "C" void ResourceMgr_LoadDirectory(const char* resName) { - Ship::Context::GetInstance()->GetResourceManager()->LoadResources(resName); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResources(resName); } extern "C" void ResourceMgr_DirtyDirectory(const char* resName) { - Ship::Context::GetInstance()->GetResourceManager()->DirtyResources(resName); + Ship::Context::GetRawInstance()->GetResourceManager()->DirtyResources(resName); } extern "C" void ResourceMgr_UnloadResource(const char* resName) { @@ -139,13 +142,13 @@ extern "C" void ResourceMgr_UnloadResource(const char* resName) { if (path.substr(0, 7) == "__OTR__") { path = path.substr(7); } - auto res = Ship::Context::GetInstance()->GetResourceManager()->UnloadResource(path); + auto res = Ship::Context::GetRawInstance()->GetResourceManager()->UnloadResource(path); } // OTRTODO: There is probably a more elegant way to go about this... // Caller must free each string and the array itself when done. extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) { - auto lst = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(searchMask); + auto lst = Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(searchMask); char** result = (char**)malloc(lst->size() * sizeof(char*)); for (size_t i = 0; i < lst->size(); i++) { @@ -182,7 +185,7 @@ extern "C" uint8_t ResourceMgr_FileAltExists(const char* filePath) { } extern "C" bool ResourceMgr_IsAltAssetsEnabled() { - return Ship::Context::GetInstance()->GetResourceManager()->IsAltAssetsEnabled(); + return Ship::Context::GetRawInstance()->GetResourceManager()->IsAltAssetsEnabled(); } // Unloads a resource if an alternate version exists when alt assets are enabled @@ -201,7 +204,7 @@ std::shared_ptr ResourceMgr_GetResourceByNameHandlingMQ(const c Path.replace(pos, 7, "/mq/"); } } - return Ship::Context::GetInstance()->GetResourceManager()->LoadResource(Path.c_str()); + return Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(Path.c_str()); } extern "C" char* ResourceMgr_GetResourceDataByNameHandlingMQ(const char* path) { @@ -325,7 +328,7 @@ std::unordered_map> origi // using OTRs instead (When that is available). Index can be found using the commented out section below. extern "C" void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction) { auto res = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(path)); if (res == nullptr || static_cast(index) >= res->Instructions.size()) { return; @@ -368,7 +371,7 @@ extern "C" void ResourceMgr_PatchGfxByName(const char* path, const char* patchNa extern "C" void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, int sourceIndex) { auto res = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(path)); if (res == nullptr || static_cast(destinationIndex) >= res->Instructions.size() || static_cast(sourceIndex) >= res->Instructions.size()) { @@ -393,7 +396,7 @@ extern "C" void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const ch extern "C" void ResourceMgr_PatchCustomGfxByName(const char* path, const char* patchName, int index, Gfx instruction) { auto res = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(path)); if (res == nullptr || static_cast(index) >= res->Instructions.size()) { return; @@ -412,7 +415,7 @@ extern "C" void ResourceMgr_PatchCustomGfxByName(const char* path, const char* p extern "C" void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName) { if (originalGfx.contains(path) && originalGfx[path].contains(patchName)) { auto res = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(path)); // If the resource is unavailable (e.g. swapped out when toggling alt assets), clean up the record and bail. if (res == nullptr) { @@ -517,7 +520,47 @@ extern "C" int ResourceMgr_OTRSigCheck(char* imgData) { return 0; } +// Load animation with explicit alt asset path checking. +// When Alt Assets is OFF: use original path directly (O2R or vanilla) +// When Alt Assets is ON: try alt/ prefix first, fall back to regular path if not found or invalid extern "C" AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path) { + bool isAlt = ResourceMgr_IsAltAssetsEnabled(); + + if (isAlt) { + std::string pathStr = std::string(path); + static const std::string sOtr = "__OTR__"; + + if (pathStr.starts_with(sOtr)) { + pathStr = pathStr.substr(sOtr.length()); + } + + // Try alt/ first + pathStr = Ship::IResource::gAltAssetPrefix + pathStr; + AnimationHeaderCommon* animHeader = (AnimationHeaderCommon*)ResourceGetDataByName(pathStr.c_str()); + + // If alt loaded successfully, verify it has valid data + if (animHeader != NULL) { + // Check for valid frame count (> 0) + if (animHeader->frameCount > 0) { + // For Normal animations: check frameData (comes after frameCount in AnimationHeader) + // For Link animations: check segment (comes after frameCount in LinkAnimationHeader) + // We check both to be safe - if either is valid, the animation is usable + AnimationHeader* normalAnim = (AnimationHeader*)animHeader; + LinkAnimationHeader* linkAnim = (LinkAnimationHeader*)animHeader; + + // Valid if Normal animation has frameData OR Link animation has segment + if (normalAnim->frameData != NULL || linkAnim->segment != NULL) { + return animHeader; + } + } + // Alt loaded but is invalid (broken), fall through to original path + } + + // Fall back to original path + return (AnimationHeaderCommon*)ResourceGetDataByName(path); + } + + // Alt OFF: use original path directly return (AnimationHeaderCommon*)ResourceGetDataByName(path); } diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 89224c0ab5..0772b93ebd 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -8,6 +8,7 @@ #include "soh/util.h" #include "Enhancements/randomizer/hint.h" #include "Enhancements/randomizer/item.h" +#include "soh/Enhancements/randomizer/settings.h" #include "ResourceManagerHelpers.h" #include "z64.h" diff --git a/soh/soh/ShipUtils.h b/soh/soh/ShipUtils.h index 9046ffb08e..f0c85adaba 100644 --- a/soh/soh/ShipUtils.h +++ b/soh/soh/ShipUtils.h @@ -4,6 +4,7 @@ #include #ifdef __cplusplus +#include void LoadGuiTextures(); diff --git a/soh/soh/SohGui/ImGuiUtils.cpp b/soh/soh/SohGui/ImGuiUtils.cpp index 3f01e6e554..8cf6579106 100644 --- a/soh/soh/SohGui/ImGuiUtils.cpp +++ b/soh/soh/SohGui/ImGuiUtils.cpp @@ -5,6 +5,10 @@ #include "soh/Enhancements/randomizer/rando_hash.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" +#include + +#include + std::map itemMapping = { ITEM_MAP_ENTRY(ITEM_STICK), ITEM_MAP_ENTRY(ITEM_NUT), @@ -215,68 +219,73 @@ const char* GetTextureForItemId(uint32_t itemId) { void RegisterImGuiItemIcons() { for (const auto& entry : itemMapping) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture( - entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } for (const auto& entry : gregMapping) { ImVec4 gregGreen = ImVec4(42.0f / 255.0f, 169.0f / 255.0f, 40.0f / 255.0f, 1.0f); ImVec4 gregFadedGreen = gregGreen; gregFadedGreen.w = 0.3f; - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, - gregGreen); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, - entry.second.texturePath, gregFadedGreen); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.name, entry.second.texturePath, gregGreen); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, gregFadedGreen); } for (const auto& entry : actionShuffleMapping) { ImVec4 aButtonBlue = ImVec4(90.f / 255.f, 90.f / 250.f, 255.f / 255.f, 255.f / 255.f); ImVec4 aButtonBlueFaded = aButtonBlue; aButtonBlueFaded.w = 0.3f; - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, - aButtonBlue); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, - entry.second.texturePath, aButtonBlueFaded); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.name, entry.second.texturePath, aButtonBlue); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, aButtonBlueFaded); } for (const auto& entry : customItemsMapping) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture( - entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } for (const auto& entry : jabbernutMapping) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture( - entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } for (const auto& entry : questMapping) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture( - entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } for (const auto& [quest, entry] : songMapping) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.name, gSongNoteTex, entry.color); ImVec4 fadedCol = entry.color; fadedCol.w = 0.3f; - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol); } for (const auto& entry : vanillaSongMapping) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.name, gSongNoteTex, entry.color); ImVec4 fadedCol = entry.color; fadedCol.w = 0.3f; - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol); } for (const auto& entry : gSeedTextures) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.tex, entry.tex, ImVec4(1, 1, 1, 1)); + std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture(entry.tex, entry.tex, ImVec4(1, 1, 1, 1)); } } \ No newline at end of file diff --git a/soh/soh/SohGui/Menu.cpp b/soh/soh/SohGui/Menu.cpp index 0147d75ab3..472d479dc6 100644 --- a/soh/soh/SohGui/Menu.cpp +++ b/soh/soh/SohGui/Menu.cpp @@ -99,17 +99,18 @@ void Menu::RemoveSidebarSearch() { } void Menu::UpdateWindowBackendObjects() { - Ship::WindowBackend runningWindowBackend = Ship::Context::GetInstance()->GetWindow()->GetWindowBackend(); - int32_t configWindowBackendId = Ship::Context::GetInstance()->GetConfig()->GetInt("Window.Backend.Id", -1); - if (Ship::Context::GetInstance()->GetWindow()->IsAvailableWindowBackend(configWindowBackendId)) { - configWindowBackend = static_cast(configWindowBackendId); + Fast::WindowBackend runningWindowBackend = + (Fast::WindowBackend)Ship::Context::GetRawInstance()->GetWindow()->GetWindowBackend(); + int32_t configWindowBackendId = Ship::Context::GetRawInstance()->GetConfig()->GetInt("Window.Backend.Id", -1); + if (Ship::Context::GetRawInstance()->GetWindow()->IsAvailableWindowBackend(configWindowBackendId)) { + configWindowBackend = static_cast(configWindowBackendId); } else { configWindowBackend = runningWindowBackend; } - availableWindowBackends = Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends(); + availableWindowBackends = Ship::Context::GetRawInstance()->GetWindow()->GetAvailableWindowBackends(); for (auto& backend : *availableWindowBackends) { - availableWindowBackendsMap[backend] = windowBackendsMap.at(backend); + availableWindowBackendsMap[(Fast::WindowBackend)backend] = windowBackendsMap.at((Fast::WindowBackend)backend); } } @@ -208,8 +209,7 @@ uint32_t Menu::DrawSearchResults(std::string& menuSearchText) { info.type == WIDGET_SEPARATOR_TEXT || info.isHidden || info.hideInSearch) { continue; } - const char* tooltip = info.options->tooltip; - std::string widgetStr = std::string(info.name) + std::string(tooltip != NULL ? tooltip : ""); + std::string widgetStr = std::string(info.name) + info.options->tooltip; std::transform(widgetStr.begin(), widgetStr.end(), widgetStr.begin(), ::tolower); widgetStr.erase(std::remove(widgetStr.begin(), widgetStr.end(), ' '), widgetStr.end()); if (widgetStr.find(menuSearchText) != std::string::npos) { @@ -337,14 +337,15 @@ void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors me }; } break; case WIDGET_AUDIO_BACKEND: { - auto currentAudioBackend = Ship::Context::GetInstance()->GetAudio()->GetCurrentAudioBackend(); + auto currentAudioBackend = Ship::Context::GetRawInstance()->GetAudio()->GetCurrentAudioBackend(); UIWidgets::ComboboxOptions options = {}; options.color = menuThemeIndex; options.tooltip = "Sets the audio API used by the game. Requires a relaunch to take effect."; - options.disabled = Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1; + options.disabled = + Ship::Context::GetRawInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1; options.disabledTooltip = "Only one audio API is available on this platform."; if (UIWidgets::Combobox("Audio API", ¤tAudioBackend, audioBackendsMap, options)) { - Ship::Context::GetInstance()->GetAudio()->SetCurrentAudioBackend(currentAudioBackend); + Ship::Context::GetRawInstance()->GetAudio()->SetCurrentAudioBackend(currentAudioBackend); } } break; case WIDGET_VIDEO_BACKEND: { @@ -355,11 +356,11 @@ void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors me options.disabledTooltip = "Only one renderer API is available on this platform."; if (UIWidgets::Combobox("Renderer API (Needs reload)", &configWindowBackend, availableWindowBackendsMap, options)) { - Ship::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", - (int32_t)(configWindowBackend)); - Ship::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name", - windowBackendsMap.at(configWindowBackend)); - Ship::Context::GetInstance()->GetConfig()->Save(); + Ship::Context::GetRawInstance()->GetConfig()->SetInt("Window.Backend.Id", + (int32_t)(configWindowBackend)); + Ship::Context::GetRawInstance()->GetConfig()->SetString("Window.Backend.Name", + windowBackendsMap.at(configWindowBackend)); + Ship::Context::GetRawInstance()->GetConfig()->Save(); UpdateWindowBackendObjects(); } } break; @@ -490,7 +491,7 @@ void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors me SPDLOG_ERROR(msg.c_str()); break; } - auto window = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow(widget.windowName); + auto window = Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow(widget.windowName); if (!window) { std::string msg = fmt::format("Error drawing window contents: windowName {} does not exist", widget.windowName); @@ -766,11 +767,11 @@ void Menu::DrawElement() { "Quit SoH", "Are you sure you want to quit SoH?", "Quit", "Cancel", []() { std::shared_ptr menu = - static_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetMenu()); + static_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetMenu()); if (!menu->IsMenuPopped()) { menu->ToggleVisibility(); } - Ship::Context::GetInstance()->GetWindow()->Close(); + Ship::Context::GetRawInstance()->GetWindow()->Close(); }, nullptr); } @@ -790,7 +791,7 @@ void Menu::DrawElement() { ; if (UIWidgets::Button(ICON_FA_UNDO, options2)) { std::reinterpret_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) ->Dispatch("reset"); } ImGui::SameLine(); @@ -803,7 +804,7 @@ void Menu::DrawElement() { // Update gamepad navigation after close based on if other menus are still visible auto mImGuiIo = &ImGui::GetIO(); if (CVarGetInteger(CVAR_IMGUI_CONTROLLER_NAV, 0) && - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetMenuOrMenubarVisible()) { + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetMenuOrMenubarVisible()) { mImGuiIo->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; } else { mImGuiIo->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; diff --git a/soh/soh/SohGui/Menu.h b/soh/soh/SohGui/Menu.h index 915403e72a..e8c3c0c274 100644 --- a/soh/soh/SohGui/Menu.h +++ b/soh/soh/SohGui/Menu.h @@ -39,9 +39,9 @@ class Menu : public GuiWindow { ImGuiTextFilter menuSearch; uint8_t searchSidebarIndex; UIWidgets::Colors defaultThemeIndex; - std::shared_ptr> availableWindowBackends; - std::map availableWindowBackendsMap; - Ship::WindowBackend configWindowBackend; + std::shared_ptr> availableWindowBackends; + std::map availableWindowBackendsMap; + Fast::WindowBackend configWindowBackend; std::unordered_map disabledMap; std::vector disabledVector; diff --git a/soh/soh/SohGui/MenuTypes.h b/soh/soh/SohGui/MenuTypes.h index b3ceea0897..192c49da30 100644 --- a/soh/soh/SohGui/MenuTypes.h +++ b/soh/soh/SohGui/MenuTypes.h @@ -2,6 +2,7 @@ #define MENUTYPES_H #include +#include #include "UIWidgets.hpp" typedef enum { @@ -271,10 +272,10 @@ static const std::map audioBackendsMap = { { Ship::AudioBackend::NUL, "Null" }, }; -static const std::map windowBackendsMap = { - { Ship::WindowBackend::FAST3D_DXGI_DX11, "DirectX" }, - { Ship::WindowBackend::FAST3D_SDL_OPENGL, "OpenGL" }, - { Ship::WindowBackend::FAST3D_SDL_METAL, "Metal" }, +static const std::map windowBackendsMap = { + { Fast::WindowBackend::FAST3D_DXGI_DX11, "DirectX" }, + { Fast::WindowBackend::FAST3D_SDL_OPENGL, "OpenGL" }, + { Fast::WindowBackend::FAST3D_SDL_METAL, "Metal" }, }; struct MenuInit { diff --git a/soh/soh/SohGui/ResolutionEditor.cpp b/soh/soh/SohGui/ResolutionEditor.cpp index db61e814cb..778504c4b0 100644 --- a/soh/soh/SohGui/ResolutionEditor.cpp +++ b/soh/soh/SohGui/ResolutionEditor.cpp @@ -121,7 +121,7 @@ void ResolutionCustomWidget(WidgetInfo& info) { CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", verticalPixelCount); CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } UIWidgets::PopStyleCombobox(); // Horizontal Resolution, if visibility is enabled for it. @@ -191,7 +191,7 @@ void ResolutionCustomWidget(WidgetInfo& info) { .Color(THEME_COLOR)); if (disabled_pixelCount && CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0)) { CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } // Integer Scaling @@ -225,7 +225,7 @@ void ResolutionCustomWidget(WidgetInfo& info) { // This is just here to update the value shown on the slider. // The function in LUS to handle this setting will ignore IntegerScaleFactor while active. CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", integerScale_maximumBounds); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } // End of integer scaling settings UIWidgets::PopStyleHeader(); @@ -255,7 +255,7 @@ void ResolutionCustomWidget(WidgetInfo& info) { " If the image is stretched and you don't know why, click this."); if (ImGui::Button("Click to reenable aspect correction.")) { CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } UIWidgets::Spacer(2); } @@ -306,7 +306,7 @@ void ResolutionCustomWidget(WidgetInfo& info) { // Initialise the (currently unused) "Exceed Bounds By" cvar if it's been changed. if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) { CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } @@ -336,7 +336,7 @@ void ResolutionCustomWidget(WidgetInfo& info) { if (UIWidgets::Button("Click to reset a console variable that may be causing this.", UIWidgets::ButtonOptions().Color(THEME_COLOR))) { CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } } else { @@ -374,12 +374,12 @@ void ResolutionCustomWidget(WidgetInfo& info) { } CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio); CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } void RegisterResolutionWidgets() { - auto fastWnd = dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + auto fastWnd = dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()); mInterpreter = fastWnd->GetInterpreterWeak(); WidgetPath path = { "Settings", "Graphics", SECTION_COLUMN_2 }; @@ -421,7 +421,7 @@ void RegisterResolutionWidgets() { .PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); }) .Callback([](WidgetInfo& info) { CVarSetInteger(CVAR_LOW_RES_MODE, 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); }); // Aspect Ratio @@ -466,7 +466,7 @@ void RegisterResolutionWidgets() { CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioY); } CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); }) .Options(ComboboxOptions().ComboMap(aspectRatioPresetLabels)); mSohMenu->AddWidget(path, "AspectRatioCustom", WIDGET_CUSTOM) @@ -543,7 +543,7 @@ void UpdateResolutionVars() { } CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio); CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } // Initialise update flags. for (uint8_t i = 0; i < sizeof(update); i++) { diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index 625c131175..2aa79b1d00 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -20,14 +20,7 @@ #include #endif #include "include/global.h" -#include "include/z64audio.h" -#include "soh/SaveManager.h" -#include "soh/OTRGlobals.h" -#include "soh/Enhancements/Presets/Presets.h" -#include "soh/resource/type/Skeleton.h" -#include "soh/Enhancements/game-interactor/GameInteractor.h" -#include "soh/Enhancements/cosmetics/authenticGfxPatches.h" #include "soh/Enhancements/debugger/MessageViewer.h" #include "soh/Notification/Notification.h" #include "soh/Enhancements/TimeDisplay/TimeDisplay.h" @@ -108,7 +101,7 @@ std::shared_ptr GetSohMenu() { } void SetupMenu() { - auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); + auto gui = Ship::Context::GetRawInstance()->GetWindow()->GetGui(); mSohMenu = std::make_shared(CVAR_WINDOW("Menu"), "Port Menu"); gui->SetMenu(mSohMenu); @@ -122,7 +115,7 @@ void SetupMenuElements() { } void SetupGuiElements() { - auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); + auto gui = Ship::Context::GetRawInstance()->GetWindow()->GetGui(); mConsoleWindow = std::make_shared(CVAR_WINDOW("SohConsole"), "Console##SoH", ImVec2(820, 630)); gui->AddGuiWindow(mConsoleWindow); @@ -207,7 +200,7 @@ void SetupGuiElements() { } void Destroy() { - auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); + auto gui = Ship::Context::GetRawInstance()->GetWindow()->GetGui(); gui->RemoveAllGuiWindows(); mNotificationWindow = nullptr; diff --git a/soh/soh/SohGui/SohMenu.cpp b/soh/soh/SohGui/SohMenu.cpp index 0e8ea5cf88..ff793deb24 100644 --- a/soh/soh/SohGui/SohMenu.cpp +++ b/soh/soh/SohGui/SohMenu.cpp @@ -108,29 +108,29 @@ void SohMenu::InitElement() { disabledMap = { { DISABLE_FOR_NO_VSYNC, { [](disabledInfo& info) -> bool { - return !Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync(); + return !Ship::Context::GetRawInstance()->GetWindow()->CanDisableVerticalSync(); }, "Disabling VSync not supported" } }, { DISABLE_FOR_NO_WINDOWED_FULLSCREEN, { [](disabledInfo& info) -> bool { - return !Ship::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen(); + return !Ship::Context::GetRawInstance()->GetWindow()->SupportsWindowedFullscreen(); }, "Windowed Fullscreen not supported" } }, { DISABLE_FOR_NO_MULTI_VIEWPORT, { [](disabledInfo& info) -> bool { - return !Ship::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports(); + return !Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SupportsViewports(); }, "Multi-viewports not supported" } }, { DISABLE_FOR_NOT_DIRECTX, { [](disabledInfo& info) -> bool { - return Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() != - Ship::WindowBackend::FAST3D_DXGI_DX11; + return Ship::Context::GetRawInstance()->GetWindow()->GetWindowBackend() != + Fast::WindowBackend::FAST3D_DXGI_DX11; }, "Available Only on DirectX" } }, { DISABLE_FOR_DIRECTX, { [](disabledInfo& info) -> bool { - return Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == - Ship::WindowBackend::FAST3D_DXGI_DX11; + return Ship::Context::GetRawInstance()->GetWindow()->GetWindowBackend() == + Fast::WindowBackend::FAST3D_DXGI_DX11; }, "Not Available on DirectX" } }, { DISABLE_FOR_MATCH_REFRESH_RATE_ON, diff --git a/soh/soh/SohGui/SohMenuDevTools.cpp b/soh/soh/SohGui/SohMenuDevTools.cpp index c5b88ce8fb..43a6a7a5d1 100644 --- a/soh/soh/SohGui/SohMenuDevTools.cpp +++ b/soh/soh/SohGui/SohMenuDevTools.cpp @@ -120,7 +120,7 @@ void SohMenu::AddMenuDevTools() { .ComboMap(logLevels) .DefaultIndex(defaultLogLevel)) .Callback([](WidgetInfo& info) { - Ship::Context::GetInstance()->GetLogger()->set_level( + Ship::Context::GetRawInstance()->GetLogger()->set_level( (spdlog::level::level_enum)CVarGetInteger(CVAR_DEVELOPER_TOOLS("LogLevel"), defaultLogLevel)); }); diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 4cf7305373..c06230a9e8 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1,10 +1,11 @@ #include "SohMenu.h" #include -#include +#include "soh/Enhancements/SwitchAge.h" #include #include #include #include +#include "soh/Enhancements/randomizer/randomizer.h" extern "C" { #include "functions.h" @@ -361,7 +362,7 @@ void SohMenu::AddMenuEnhancements() { CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), true); CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), true); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); }); AddWidget(path, "None##Skips", WIDGET_BUTTON) .SameLine(true) @@ -378,7 +379,7 @@ void SohMenu::AddMenuEnhancements() { CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), false); CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), false); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); }); AddWidget(path, "Skip Intro", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro")) @@ -1041,6 +1042,17 @@ void SohMenu::AddMenuEnhancements() { "Forces Goron City doors open if you somehow complete Fire Temple without talking to Goron Link " " and receiving the Goron Tunic.")); + AddWidget(path, "Fix MQ Water 1F Lock", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("MQWaterLockFix")) + .PreFunc([](WidgetInfo& info) { + info.options->disabled = IS_RANDO && GameInteractor::IsSaveLoaded(true); + info.options->disabledTooltip = "This setting is forcefully enabled when you are playing a Randomizer."; + }) + .Options(CheckboxOptions().Tooltip( + "The second small key lock MQ water is removed before the player can reach it by a shared flag with some " + "Stalfos on the way to Dark Link.\n" + "Enabling this will cause that lock to use a different flag, working as intended.")); + AddWidget(path, "Item-related Fixes", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Fix Deku Nut Upgrade", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("DekuNutUpgradeFix")) @@ -1349,7 +1361,6 @@ void SohMenu::AddMenuEnhancements() { AddWidget(path, "Enemies", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Hyper Bosses", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("HyperBosses")) - .Callback([](WidgetInfo& info) { UpdateHyperBossesState(); }) .Options(CheckboxOptions().Tooltip("All Major Bosses move and act twice as fast.")); AddWidget(path, "Hyper Enemies", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("HyperEnemies")) @@ -1430,6 +1441,33 @@ void SohMenu::AddMenuEnhancements() { .DefaultValue(10) .Format("%d bombchus") .Tooltip("The number of Bombchus available at the start of the Bombchu Bowling minigame.")); + AddWidget(path, "Horseback Archery", WIDGET_SEPARATOR_TEXT); + AddWidget(path, "Customize Behavior##HBA", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("CustomizeHorsebackArchery")) + .Options(CheckboxOptions().Tooltip("Turn on/off changes to the Horseback Archery minigame behavior.")); + auto hbaDisabledFunc = [](WidgetInfo& info) { + info.options->disabled = CVarGetInteger(CVAR_ENHANCEMENT("CustomizeHorsebackArchery"), 0) == 0; + info.options->disabledTooltip = "This option is disabled because \"Customize Behavior\" is turned off."; + }; + AddWidget(path, "Instant Win##HBA", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("InstantHorsebackArcheryWin")) + .PreFunc(hbaDisabledFunc) + .Options(CheckboxOptions().Tooltip("Skips the Horseback Archery minigame, automatically awarding the prize.")); + AddWidget(path, "Always Score 100##HBA", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("HorsebackArcheryAlwaysScore")) + .PreFunc(hbaDisabledFunc) + .Options(CheckboxOptions().Tooltip( + "Every arrow that hits a target scores 100 points (inner ring) regardless of where it lands.")); + AddWidget(path, "Arrow Count", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("HorsebackArcheryAmmo")) + .PreFunc(hbaDisabledFunc) + .Options(IntSliderOptions() + .Min(15) + .Max(40) + .DefaultValue(20) + .Format("%d arrows") + .Tooltip("The number of arrows available at the start of the Horseback Archery minigame.")); + AddWidget(path, "Frogs' Ocarina Game", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Customize Behavior##Frogs", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame")) @@ -1523,6 +1561,11 @@ void SohMenu::AddMenuEnhancements() { .Options(CheckboxOptions().Tooltip("Amy's block pushing puzzle instantly solved.")); path.column = SECTION_COLUMN_3; + AddWidget(path, "Rupee Diving Game", WIDGET_SEPARATOR_TEXT); + AddWidget(path, "Time Limit: %d seconds", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("DivingGame.TimeLimit")) + .Options(IntSliderOptions().Min(30).Max(120).DefaultValue(50).Format("%d seconds")); + AddWidget(path, "Fishing", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Customize Behavior##Fishing", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("CustomizeFishing")) @@ -1824,7 +1867,7 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_CHEAT("SaveStatePromise")) .Callback([](WidgetInfo& info) { CVarSetInteger(CVAR_CHEAT("SaveStatesEnabled"), 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); }); AddWidget(path, "I understand, enable save states", WIDGET_CVAR_CHECKBOX) .PreFunc([](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_CHEAT("SaveStatePromise"), 0) == 0; }) @@ -1842,9 +1885,9 @@ void SohMenu::AddMenuEnhancements() { CVarSetInteger(CVAR_CHEAT("BetaQuestWorld"), 0); } std::reinterpret_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) ->Dispatch("reset"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); }) .Options(CheckboxOptions().Tooltip("Turns on OoT Beta Quest. *WARNING*: This will reset your game!")); AddWidget(path, "Beta Quest World: %d", WIDGET_CVAR_SLIDER_INT) @@ -1854,9 +1897,9 @@ void SohMenu::AddMenuEnhancements() { }) .Callback([](WidgetInfo& info) { std::reinterpret_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) ->Dispatch("reset"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); }) .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(8).Tooltip( "Set the Beta Quest world to explore. *WARNING*: Changing this will reset your game!\n" diff --git a/soh/soh/SohGui/SohMenuNetwork.cpp b/soh/soh/SohGui/SohMenuNetwork.cpp index 716e4652cb..8e2ba18f57 100644 --- a/soh/soh/SohGui/SohMenuNetwork.cpp +++ b/soh/soh/SohGui/SohMenuNetwork.cpp @@ -3,6 +3,7 @@ #include #include "SohGui.hpp" #include "soh/OTRGlobals.h" +#include "soh/util.h" #include #include @@ -87,11 +88,11 @@ void SohMenu::AddMenuNetwork() { .Callback([](WidgetInfo& info) { if (Sail::Instance->isEnabled) { CVarClear(CVAR_REMOTE_SAIL("Enabled")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); Sail::Instance->Disable(); } else { CVarSetInteger(CVAR_REMOTE_SAIL("Enabled"), 1); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); Sail::Instance->Enable(); } }); @@ -153,11 +154,11 @@ void SohMenu::AddMenuNetwork() { .Callback([](WidgetInfo& info) { if (CrowdControl::Instance->isEnabled) { CVarClear(CVAR_REMOTE_CROWD_CONTROL("Enabled")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); CrowdControl::Instance->Disable(); } else { CVarSetInteger(CVAR_REMOTE_CROWD_CONTROL("Enabled"), 1); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); CrowdControl::Instance->Enable(); } }); diff --git a/soh/soh/SohGui/SohMenuRandomizer.cpp b/soh/soh/SohGui/SohMenuRandomizer.cpp index 5647e35910..a51a4fbca4 100644 --- a/soh/soh/SohGui/SohMenuRandomizer.cpp +++ b/soh/soh/SohGui/SohMenuRandomizer.cpp @@ -2,7 +2,9 @@ #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/randomizer/randomizer.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/Enhancements/randomizer/settings.h" #include "soh/OTRGlobals.h" +#include "soh/ShipUtils.h" #include "soh/SohGui/SohGui.hpp" extern "C" { @@ -39,7 +41,7 @@ void SaveEnabledTricks() { } else { CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str()); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); tricksDirty = false; return; } @@ -109,7 +111,7 @@ void DrawLocationsMenu(WidgetInfo& info) { } CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), excludedLocationString.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); locationsDirty = true; } UIWidgets::PopStyleButton(); @@ -160,7 +162,7 @@ void DrawLocationsMenu(WidgetInfo& info) { CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), excludedLocationString.c_str()); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); locationsDirty = true; } UIWidgets::PopStyleButton(); @@ -563,16 +565,19 @@ void SohMenu::AddMenuRandomizer() { .Color(THEME_COLOR) .Padding(ImVec2(10.f, 6.f)) .Tooltip("Creates a new random seed value to be used when generating a randomizer"))) { - SohUtils::CopyStringToCharArray(seedString, std::to_string(rand() & 0xFFFFFFFF), MAX_SEED_STRING_SIZE); + for (size_t i = 0; i < 10; i++) { + seedString[i] = '0' + ShipUtils::Random(0, 10); + } + seedString[10] = '\0'; } ImGui::SameLine(); if (UIWidgets::Button(ICON_FA_ERASER, UIWidgets::ButtonOptions() .Size(UIWidgets::Sizes::Inline) .Color(THEME_COLOR) .Padding(ImVec2(10.f, 6.f)))) { - memset(seedString, 0, MAX_SEED_STRING_SIZE); + seedString[0] = 0; } - if (strnlen(seedString, MAX_SEED_STRING_SIZE) == 0) { + if (seedString[0] == 0) { ImGui::SameLine(17.0f); ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Leave blank for random seed"); } @@ -590,15 +595,23 @@ void SohMenu::AddMenuRandomizer() { .Options(ButtonOptions() .Size(ImVec2(250.f, 0.f)) .DisabledTooltip("Must be on File Select to generate a randomizer seed.")); - AddWidget(path, "Spoiler File", WIDGET_CUSTOM) - .CustomFunction([](WidgetInfo& info) { - JoinRandoGenerationThread(); - if (!CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) { - std::string spoilerfilepath = CVarGetString(CVAR_GENERAL("SpoilerLog"), ""); - ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str()); - } + AddWidget(path, "Randomize All Settings", WIDGET_BUTTON) + .Callback([](WidgetInfo& info) { Rando::Settings::GetInstance()->RandomizeAllSettings(); }) + .PreFunc([](WidgetInfo& info) { + info.options->disabled = CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) || + CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0); }) + .Options(ButtonOptions() + .Size(ImVec2(250.f, 0.f)) + .Tooltip("Randomizes all randomizer settings to random valid values (excludes tricks).")) .SameLine(true); + AddWidget(path, "Spoiler File", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) { + JoinRandoGenerationThread(); + if (!CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) { + std::string spoilerfilepath = CVarGetString(CVAR_GENERAL("SpoilerLog"), ""); + ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str()); + } + }); // Enhancements AddWidget(path, "Enhancements", WIDGET_SEPARATOR_TEXT); diff --git a/soh/soh/SohGui/SohMenuSettings.cpp b/soh/soh/SohGui/SohMenuSettings.cpp index b806da560c..587b6a4aa6 100644 --- a/soh/soh/SohGui/SohMenuSettings.cpp +++ b/soh/soh/SohGui/SohMenuSettings.cpp @@ -167,7 +167,7 @@ void SohMenu::AddMenuSettings() { .CVar(CVAR_SETTING("CursorVisibility")) .RaceDisable(false) .Callback([](WidgetInfo& info) { - Ship::Context::GetInstance()->GetWindow()->SetForceCursorVisibility( + Ship::Context::GetRawInstance()->GetWindow()->SetForceCursorVisibility( CVarGetInteger(CVAR_SETTING("CursorVisibility"), 0)); }) .Options(CheckboxOptions().Tooltip("Makes the cursor always visible, even in full screen.")); @@ -195,7 +195,7 @@ void SohMenu::AddMenuSettings() { AddWidget(path, "Open App Files Folder", WIDGET_BUTTON) .RaceDisable(false) .Callback([](WidgetInfo& info) { - std::string filesPath = Ship::Context::GetInstance()->GetAppDirectoryPath(); + std::string filesPath = Ship::Context::GetRawInstance()->GetAppDirectoryPath(); SDL_OpenURL(std::string("file:///" + std::filesystem::absolute(filesPath).string()).c_str()); }) .Options(ButtonOptions().Tooltip("Opens the folder that contains the save and mods folders, etc.")); @@ -251,6 +251,10 @@ void SohMenu::AddMenuSettings() { .CVar(CVAR_SETTING("A11yNoJabuWobble")) .RaceDisable(false) .Options(CheckboxOptions().Tooltip("Disable the geometry wobble and camera distortion inside Jabu.")); + AddWidget(path, "Disable Heat Haze", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_SETTING("A11yNoHeatHaze")) + .RaceDisable(false) + .Options(CheckboxOptions().Tooltip("Disable the heat haze distortion effect in Death Mountain / Fire Temple.")); AddWidget(path, "EXPERIMENTAL", WIDGET_SEPARATOR_TEXT).Options(TextOptions().Color(Colors::Orange)); AddWidget(path, "ImGui Menu Scaling", WIDGET_CVAR_COMBOBOX) .CVar(CVAR_SETTING("ImGuiScale")) @@ -330,13 +334,13 @@ void SohMenu::AddMenuSettings() { AddWidget(path, "Graphics Options", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Toggle Fullscreen", WIDGET_BUTTON) .RaceDisable(false) - .Callback([](WidgetInfo& info) { Ship::Context::GetInstance()->GetWindow()->ToggleFullscreen(); }) + .Callback([](WidgetInfo& info) { Ship::Context::GetRawInstance()->GetWindow()->ToggleFullscreen(); }) .Options(ButtonOptions().Tooltip("Toggles Fullscreen On/Off.")); AddWidget(path, "Internal Resolution", WIDGET_CVAR_SLIDER_FLOAT) .CVar(CVAR_INTERNAL_RESOLUTION) .RaceDisable(false) .Callback([](WidgetInfo& info) { - Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier( + Ship::Context::GetRawInstance()->GetWindow()->SetResolutionMultiplier( CVarGetFloat(CVAR_INTERNAL_RESOLUTION, 1)); }) .PreFunc([](WidgetInfo& info) { @@ -361,7 +365,7 @@ void SohMenu::AddMenuSettings() { .CVar(CVAR_MSAA_VALUE) .RaceDisable(false) .Callback([](WidgetInfo& info) { - Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger(CVAR_MSAA_VALUE, 1)); + Ship::Context::GetRawInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger(CVAR_MSAA_VALUE, 1)); }) .Options( IntSliderOptions() @@ -437,9 +441,10 @@ void SohMenu::AddMenuSettings() { "This will completely erase the controls config, including registered devices.\nContinue?", "Clear", "Cancel", []() { - Ship::Context::GetInstance()->GetConsoleVariables()->ClearBlock(CVAR_PREFIX_SETTING ".Controllers"); + Ship::Context::GetRawInstance()->GetConsoleVariables()->ClearBlock(CVAR_PREFIX_SETTING + ".Controllers"); uint8_t bits = 0; - Ship::Context::GetInstance()->GetControlDeck()->Init(&bits); + Ship::Context::GetRawInstance()->GetControlDeck()->Init(&bits); }, nullptr); }) diff --git a/soh/soh/SohGui/UIWidgets.cpp b/soh/soh/SohGui/UIWidgets.cpp index fff4da0ef9..f97e0dd566 100644 --- a/soh/soh/SohGui/UIWidgets.cpp +++ b/soh/soh/SohGui/UIWidgets.cpp @@ -59,6 +59,12 @@ void Tooltip(const char* text) { } } +void Tooltip(std::string text) { + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("%s", WrappedText(text).c_str()); + } +} + void PushStyleMenu(const ImVec4& color) { ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(color.x, color.y, color.z, 0.5f)); ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(color.x, color.y, color.z, 1.0f)); @@ -174,9 +180,9 @@ bool Button(const char* label, const ButtonOptions& options) { PopStyleButton(); ImGui::EndDisabled(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } return dirty; @@ -365,9 +371,9 @@ bool Checkbox(const char* _label, bool* value, const CheckboxOptions& options) { PopStyleCheckbox(); ImGui::EndDisabled(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } return pressed; @@ -378,7 +384,7 @@ bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions bool value = (bool)CVarGetInteger(cvarName, options.defaultValue); if (Checkbox(label, &value, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } @@ -595,9 +601,9 @@ bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& option ImGui::EndDisabled(); ImGui::EndGroup(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } ImGui::PopID(); @@ -609,7 +615,7 @@ bool CVarSliderInt(const char* label, const char* cvarName, const IntSliderOptio int32_t value = CVarGetInteger(cvarName, options.defaultValue); if (SliderInt(label, &value, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } @@ -726,9 +732,9 @@ bool SliderFloat(const char* label, float* value, const FloatSliderOptions& opti ImGui::EndDisabled(); ImGui::EndGroup(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } ImGui::PopID(); @@ -740,7 +746,7 @@ bool CVarSliderFloat(const char* label, const char* cvarName, const FloatSliderO float value = CVarGetFloat(cvarName, options.defaultValue); if (SliderFloat(label, &value, options)) { CVarSetFloat(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } @@ -799,13 +805,12 @@ bool InputString(const char* label, std::string* value, const InputOptions& opti PopStyleInput(); ImGui::EndDisabled(); ImGui::EndGroup(); - if (options.hasError && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.errorText)) { + if (options.hasError && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.errorText.empty()) { ImGui::SetTooltip("%s", WrappedText(options.errorText).c_str()); } else if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } ImGui::PopID(); @@ -817,7 +822,7 @@ bool CVarInputString(const char* label, const char* cvarName, const InputOptions std::string value = CVarGetString(cvarName, options.defaultValue.c_str()); if (InputString(label, &value, options)) { CVarSetString(cvarName, value.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } @@ -854,9 +859,9 @@ bool InputInt(const char* label, int32_t* value, const InputOptions& options) { ImGui::EndDisabled(); ImGui::EndGroup(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } ImGui::PopID(); @@ -869,7 +874,7 @@ bool CVarInputInt(const char* label, const char* cvarName, const InputOptions& o int32_t value = CVarGetInteger(cvarName, defaultValue); if (InputInt(label, &value, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } @@ -914,7 +919,7 @@ bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaul CVarClear((std::string(cvarName) + ".A").c_str()); CVarClear((std::string(cvarName) + ".Type").c_str()); CVarClearBlock(valueCVar.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } if (showRandom) { @@ -931,7 +936,7 @@ bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaul CVarSetColor(valueCVar.c_str(), color); CVarSetInteger(rainbowCVar.c_str(), 0); // On click disable rainbow mode. ShipInit::Init(rainbowCVar.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } if (showRainbow) { @@ -959,7 +964,7 @@ bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaul color.b = (uint8_t)(colorVec.z * 255.0f); color.a = (uint8_t)(colorVec.w * 255.0f); CVarSetColor(valueCVar.c_str(), color); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(valueCVar.c_str()); changed = true; } @@ -1034,13 +1039,13 @@ bool CVarRadioButton(const char* text, const char* cvarName, int32_t id, const R PushStyleCheckbox(options.color); if (ImGui::RadioButton(make_invisible.c_str(), id == val)) { CVarSetInteger(cvarName, id); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ret = true; } ImGui::SameLine(); ImGui::Text("%s", text); PopStyleCheckbox(); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } @@ -1241,7 +1246,7 @@ bool CVarBtnSelector(const char* label, const char* cvarName, const BtnSelectorO int32_t value = CVarGetInteger(cvarName, options.defaultValue); if (BtnSelector(label, &value, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } diff --git a/soh/soh/SohGui/UIWidgets.hpp b/soh/soh/SohGui/UIWidgets.hpp index 494974f451..f9902f97d8 100644 --- a/soh/soh/SohGui/UIWidgets.hpp +++ b/soh/soh/SohGui/UIWidgets.hpp @@ -36,7 +36,7 @@ std::string WrappedText(const char* text, unsigned int charactersPerLine = 80); std::string WrappedText(const std::string& text, unsigned int charactersPerLine = 80); void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, float extraVerticalBottomPadding = 0.0f); -void Tooltip(const char* text); +void Tooltip(std::string text); typedef enum ColorPickerModifiers { ColorPickerResetButton = 1, @@ -106,11 +106,11 @@ enum ComponentAlignments { }; struct WidgetOptions { - const char* tooltip = ""; + std::string tooltip = ""; bool disabled = false; - const char* disabledTooltip = ""; + std::string disabledTooltip = ""; - WidgetOptions& Tooltip(const char* tooltip_) { + WidgetOptions& Tooltip(std::string tooltip_) { tooltip = tooltip_; return *this; } @@ -120,7 +120,7 @@ struct WidgetOptions { return *this; } - WidgetOptions& DisabledTooltip(const char* disabledTooltip_) { + WidgetOptions& DisabledTooltip(std::string disabledTooltip_) { disabledTooltip = disabledTooltip_; return *this; } @@ -150,7 +150,7 @@ struct ButtonOptions : WidgetOptions { return *this; } - ButtonOptions& Tooltip(const char* tooltip_) { + ButtonOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -182,7 +182,7 @@ struct ColorPickerOptions : WidgetOptions { return *this; } - ColorPickerOptions& Tooltip(const char* tooltip_) { + ColorPickerOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -240,7 +240,7 @@ struct WindowButtonOptions : WidgetOptions { return *this; } - WindowButtonOptions& Tooltip(const char* tooltip_) { + WindowButtonOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -283,7 +283,7 @@ struct CheckboxOptions : WidgetOptions { return *this; } - CheckboxOptions& Tooltip(const char* tooltip_) { + CheckboxOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -293,7 +293,7 @@ struct CheckboxOptions : WidgetOptions { return *this; } - CheckboxOptions& DisabledTooltip(const char* disabledTooltip_) { + CheckboxOptions& DisabledTooltip(std::string disabledTooltip_) { WidgetOptions::disabledTooltip = disabledTooltip_; return *this; } @@ -332,7 +332,7 @@ struct ComboboxOptions : WidgetOptions { return *this; } - ComboboxOptions& Tooltip(const char* tooltip_) { + ComboboxOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -397,7 +397,7 @@ struct IntSliderOptions : WidgetOptions { return *this; } - IntSliderOptions& Tooltip(const char* tooltip_) { + IntSliderOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -481,7 +481,7 @@ struct FloatSliderOptions : WidgetOptions { return *this; } - FloatSliderOptions& Tooltip(const char* tooltip_) { + FloatSliderOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -544,7 +544,7 @@ struct RadioButtonsOptions : WidgetOptions { return *this; } - RadioButtonsOptions& Tooltip(const char* tooltip_) { + RadioButtonsOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -571,9 +571,9 @@ struct InputOptions : WidgetOptions { bool secret = false; ImGuiInputFlags addedFlags = 0; bool hasError = false; - const char* errorText = ""; + std::string errorText = ""; - InputOptions& Tooltip(const char* tooltip_) { + InputOptions& Tooltip(std::string tooltip_) { WidgetOptions::tooltip = tooltip_; return *this; } @@ -628,7 +628,7 @@ struct InputOptions : WidgetOptions { return *this; } - InputOptions& ErrorText(const char* errorText_) { + InputOptions& ErrorText(std::string errorText_) { errorText = errorText_; return *this; } @@ -754,9 +754,9 @@ bool Combobox(std::string label, T* value, const std::map& combo ImGui::EndDisabled(); ImGui::EndGroup(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } ImGui::PopID(); @@ -839,9 +839,9 @@ bool Combobox(std::string label, T* value, const std::vector& combo ImGui::EndDisabled(); ImGui::EndGroup(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } ImGui::PopID(); @@ -925,9 +925,9 @@ bool Combobox(std::string label, T* value, const std::vector& combo ImGui::EndDisabled(); ImGui::EndGroup(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } ImGui::PopID(); @@ -1011,9 +1011,9 @@ bool Combobox(std::string label, T* value, const char* (&comboArray)[N], const C ImGui::EndDisabled(); ImGui::EndGroup(); if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - !Ship_IsCStringEmpty(options.disabledTooltip)) { + !options.disabledTooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) { ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } ImGui::PopID(); @@ -1027,7 +1027,7 @@ bool CVarCombobox(const char* label, const char* cvarName, const std::map(label, &value, comboMap, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } @@ -1041,7 +1041,7 @@ bool CVarCombobox(const char* label, const char* cvarName, const std::vector(label, &value, comboVector, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } @@ -1055,7 +1055,7 @@ bool CVarCombobox(const char* label, const char* cvarName, const char* (&comboAr int32_t value = CVarGetInteger(cvarName, options.defaultIndex); if (Combobox(label, &value, comboArray, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ShipInit::Init(cvarName); dirty = true; } diff --git a/soh/soh/resource/importer/AnimationFactory.cpp b/soh/soh/resource/importer/AnimationFactory.cpp index 99507e4f3a..643408c3c9 100644 --- a/soh/soh/resource/importer/AnimationFactory.cpp +++ b/soh/soh/resource/importer/AnimationFactory.cpp @@ -78,15 +78,33 @@ ResourceFactoryBinaryAnimationV0::ReadResource(std::shared_ptr file, } animation->animationData.transformUpdateIndex.copyValues = animation->copyValuesArr.data(); } else if (animType == AnimationType::Link) { + // Initialize segment to nullptr (important for alt asset fallback) + animation->animationData.linkAnimationHeader.segment = nullptr; + // Read the frame count animation->animationData.linkAnimationHeader.common.frameCount = reader->ReadInt16(); // Read the segment pointer (always 32 bit, doesn't adjust for system pointer size) std::string path = reader->ReadString(); - const auto animData = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(path.c_str())); + auto animData = std::static_pointer_cast( + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(path.c_str())); - animation->animationData.linkAnimationHeader.segment = animData->GetPointer(); + // If direct load failed and alt assets are enabled, try with alt/ prefix + if (animData == nullptr && Ship::Context::GetRawInstance()->GetResourceManager()->IsAltAssetsEnabled()) { + std::string altPath = path; + if (altPath.find("__OTR__") == 0) { + altPath = altPath.substr(7); // Strip __OTR__ + } + altPath = "alt/" + altPath; + animData = std::static_pointer_cast( + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(altPath.c_str())); + } + + if (animData != nullptr) { + animation->animationData.linkAnimationHeader.segment = animData->GetPointer(); + } else { + SPDLOG_WARN("Animation data segment not found: {}", path); + } } else if (animType == AnimationType::Legacy) { SPDLOG_DEBUG("BEYTAH ANIMATION?!"); } diff --git a/soh/soh/resource/importer/AudioSampleFactory.cpp b/soh/soh/resource/importer/AudioSampleFactory.cpp index 098efd2363..cdfe4311cc 100644 --- a/soh/soh/resource/importer/AudioSampleFactory.cpp +++ b/soh/soh/resource/importer/AudioSampleFactory.cpp @@ -290,7 +290,7 @@ ResourceFactoryXMLAudioSampleV0::ReadResource(std::shared_ptr file, const char* path = child->Attribute("Path"); - auto sampleFile = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFile(path); + auto sampleFile = Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->LoadFile(path); audioSample->sample.fileSize = sampleFile->Buffer.get()->size(); if (customFormatStr != nullptr) { // Compressed files can take a really long time to decode (~250ms per). diff --git a/soh/soh/resource/importer/AudioSequenceFactory.cpp b/soh/soh/resource/importer/AudioSequenceFactory.cpp index 313284f6a0..5052acce2e 100644 --- a/soh/soh/resource/importer/AudioSequenceFactory.cpp +++ b/soh/soh/resource/importer/AudioSequenceFactory.cpp @@ -342,7 +342,7 @@ ResourceFactoryXMLAudioSequenceV0::ReadResource(std::shared_ptr file const char* path = child->Attribute("Path"); std::shared_ptr seqFile; if (path != nullptr) { - seqFile = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFile(path); + seqFile = Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->LoadFile(path); } if (!streamed) { diff --git a/soh/soh/resource/importer/AudioSoundFontFactory.cpp b/soh/soh/resource/importer/AudioSoundFontFactory.cpp index f71f31d145..bb67ef29d9 100644 --- a/soh/soh/resource/importer/AudioSoundFontFactory.cpp +++ b/soh/soh/resource/importer/AudioSoundFontFactory.cpp @@ -65,7 +65,8 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr if (sampleFileName.empty()) { drum->sound.sample = nullptr; } else { - auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); + auto res = + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); drum->sound.sample = static_cast(res ? res->GetRawPointer() : nullptr); } @@ -109,7 +110,8 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr bool hasSampleRef = reader->ReadInt8(); std::string sampleFileName = reader->ReadString(); instrument->lowNotesSound.tuning = reader->ReadFloat(); - auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); + auto res = + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); instrument->lowNotesSound.sample = static_cast(res ? res->GetRawPointer() : nullptr); } else { instrument->lowNotesSound.sample = nullptr; @@ -122,7 +124,8 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr bool hasSampleRef = reader->ReadInt8(); std::string sampleFileName = reader->ReadString(); instrument->normalNotesSound.tuning = reader->ReadFloat(); - auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); + auto res = + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); instrument->normalNotesSound.sample = static_cast(res ? res->GetRawPointer() : nullptr); } else { instrument->normalNotesSound.sample = nullptr; @@ -134,7 +137,8 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr bool hasSampleRef = reader->ReadInt8(); std::string sampleFileName = reader->ReadString(); instrument->highNotesSound.tuning = reader->ReadFloat(); - auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); + auto res = + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); instrument->highNotesSound.sample = static_cast(res ? res->GetRawPointer() : nullptr); } else { instrument->highNotesSound.sample = nullptr; @@ -161,7 +165,8 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr bool hasSampleRef = reader->ReadInt8(); std::string sampleFileName = reader->ReadString(); soundEffect.tuning = reader->ReadFloat(); - auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); + auto res = + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str()); soundEffect.sample = static_cast(res ? res->GetRawPointer() : nullptr); } @@ -232,7 +237,7 @@ void ResourceFactoryXMLSoundFontV0::ParseDrums(AudioSoundFont* soundFont, tinyxm const char* sampleStr = element->Attribute("SampleRef"); if (sampleStr != nullptr && sampleStr[0] != 0) { - auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr); + auto res = Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleStr); drum->sound.sample = static_cast(res ? res->GetRawPointer() : nullptr); } else { drum->sound.sample = nullptr; @@ -308,7 +313,7 @@ void ResourceFactoryXMLSoundFontV0::ParseInstruments(AudioSoundFont* soundFont, const char* sampleStr = instrumentElement->Attribute("SampleRef"); if (sampleStr != nullptr && sampleStr[0] != 0) { std::shared_ptr res = static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleStr)); if (res->tuning != -1.0f) { instrument->lowNotesSound.tuning = res->tuning; } @@ -322,7 +327,7 @@ void ResourceFactoryXMLSoundFontV0::ParseInstruments(AudioSoundFont* soundFont, const char* sampleStr = instrumentElement->Attribute("SampleRef"); if (sampleStr != nullptr && sampleStr[0] != 0) { std::shared_ptr res = static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleStr)); if (res->tuning != -1.0f) { instrument->normalNotesSound.tuning = res->tuning; } @@ -336,7 +341,7 @@ void ResourceFactoryXMLSoundFontV0::ParseInstruments(AudioSoundFont* soundFont, const char* sampleStr = instrumentElement->Attribute("SampleRef"); if (sampleStr != nullptr && sampleStr[0] != 0) { std::shared_ptr res = static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleStr)); if (res->tuning != -1.0f) { instrument->highNotesSound.tuning = res->tuning; } @@ -376,7 +381,7 @@ void ResourceFactoryXMLSoundFontV0::ParseSfxTable(AudioSoundFont* soundFont, tin sound.tuning = element->FloatAttribute("Tuning"); if (sampleStr[0] != 0) { auto res = static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(sampleStr)); if (res->tuning != -1.0f) { sound.tuning = res->tuning; } @@ -431,7 +436,7 @@ ResourceFactoryXMLSoundFontV0::ReadResource(std::shared_ptr file, std::string origName = "audio/fonts/"; origName += patch; audioSoundFont = dynamic_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(origName)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(origName)); } else { audioSoundFont = std::make_shared(initData); memset(&audioSoundFont->soundFont, 0, sizeof(audioSoundFont->soundFont)); diff --git a/soh/soh/resource/importer/CutsceneFactory.cpp b/soh/soh/resource/importer/CutsceneFactory.cpp index c8d3b0e19f..1d96178b9c 100644 --- a/soh/soh/resource/importer/CutsceneFactory.cpp +++ b/soh/soh/resource/importer/CutsceneFactory.cpp @@ -2,14 +2,14 @@ #include "soh/resource/type/Cutscene.h" #include "spdlog/spdlog.h" -static inline uint32_t read_CMD_BBBB(std::shared_ptr reader) { +static uint32_t read_CMD_BBBB(Ship::BinaryReader* reader) { uint32_t v; reader->Read((char*)&v, sizeof(uint32_t)); return v; } -static inline uint32_t read_CMD_BBH(std::shared_ptr reader) { +static uint32_t read_CMD_BBH(Ship::BinaryReader* reader) { uint32_t v; reader->Read((char*)&v, sizeof(uint32_t)); @@ -24,7 +24,7 @@ static inline uint32_t read_CMD_BBH(std::shared_ptr reader) return v; } -static inline uint32_t read_CMD_HBB(std::shared_ptr reader) { +static uint32_t read_CMD_HBB(Ship::BinaryReader* reader) { uint32_t v; reader->Read((char*)&v, sizeof(uint32_t)); @@ -39,7 +39,7 @@ static inline uint32_t read_CMD_HBB(std::shared_ptr reader) return v; } -static inline uint32_t read_CMD_HH(std::shared_ptr reader) { +static uint32_t read_CMD_HH(Ship::BinaryReader* reader) { uint32_t v; reader->Read((char*)&v, sizeof(uint32_t)); @@ -66,7 +66,8 @@ ResourceFactoryBinaryCutsceneV0::ReadResource(std::shared_ptr file, } auto cutscene = std::make_shared(initData); - auto reader = std::get>(file->Reader); + const auto readerShared = std::get>(file->Reader); + const auto reader = readerShared.get(); uint32_t numEntries = reader->ReadUInt32(); cutscene->commands.reserve(numEntries); diff --git a/soh/soh/resource/importer/PathFactory.cpp b/soh/soh/resource/importer/PathFactory.cpp index 945e36c5fe..4d50c2cdec 100644 --- a/soh/soh/resource/importer/PathFactory.cpp +++ b/soh/soh/resource/importer/PathFactory.cpp @@ -3,6 +3,7 @@ #include "soh/resource/logging/PathLogger.h" #include "spdlog/spdlog.h" #include +#include namespace SOH { std::shared_ptr diff --git a/soh/soh/resource/importer/SkeletonFactory.cpp b/soh/soh/resource/importer/SkeletonFactory.cpp index f814765237..f44de85461 100644 --- a/soh/soh/resource/importer/SkeletonFactory.cpp +++ b/soh/soh/resource/importer/SkeletonFactory.cpp @@ -46,7 +46,7 @@ ResourceFactoryBinarySkeletonV0::ReadResource(std::shared_ptr file, for (size_t i = 0; i < skeleton->limbTable.size(); i++) { std::string limbStr = skeleton->limbTable[i]; - auto limb = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(limbStr.c_str()); + auto limb = Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(limbStr.c_str()); skeleton->skeletonHeaderSegments.push_back(limb ? limb->GetRawPointer() : nullptr); } @@ -116,7 +116,7 @@ ResourceFactoryXMLSkeletonV0::ReadResource(std::shared_ptr file, std::string limbName = child->Attribute("Path"); skel->limbTable.push_back(limbName); - auto limb = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(limbName.c_str()); + auto limb = Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(limbName.c_str()); skel->skeletonHeaderSegments.push_back(limb ? limb->GetRawPointer() : nullptr); } diff --git a/soh/soh/resource/importer/scenecommand/SetAlternateHeadersFactory.cpp b/soh/soh/resource/importer/scenecommand/SetAlternateHeadersFactory.cpp index 5a6d35cc22..bf339d87dd 100644 --- a/soh/soh/resource/importer/scenecommand/SetAlternateHeadersFactory.cpp +++ b/soh/soh/resource/importer/scenecommand/SetAlternateHeadersFactory.cpp @@ -19,7 +19,7 @@ SetAlternateHeadersFactory::ReadResource(std::shared_ptr auto headerName = reader->ReadString(); if (!headerName.empty()) { setAlternateHeaders->headers.push_back(std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(headerName.c_str()))); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(headerName.c_str()))); setAlternateHeaders->headerFileNames.push_back(headerName); } else { setAlternateHeaders->headers.push_back(nullptr); @@ -49,7 +49,8 @@ SetAlternateHeadersFactoryXML::ReadResource(std::shared_ptrAttribute("Path")); if (!headerName.empty()) { setAlternateHeaders->headers.push_back(std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(headerName.c_str()))); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess( + headerName.c_str()))); } else { setAlternateHeaders->headers.push_back(nullptr); } diff --git a/soh/soh/resource/importer/scenecommand/SetCollisionHeaderFactory.cpp b/soh/soh/resource/importer/scenecommand/SetCollisionHeaderFactory.cpp index cc0a7b0057..8e3a8f6d40 100644 --- a/soh/soh/resource/importer/scenecommand/SetCollisionHeaderFactory.cpp +++ b/soh/soh/resource/importer/scenecommand/SetCollisionHeaderFactory.cpp @@ -15,7 +15,8 @@ SetCollisionHeaderFactory::ReadResource(std::shared_ptr setCollisionHeader->fileName = reader->ReadString(); setCollisionHeader->collisionHeader = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(setCollisionHeader->fileName.c_str())); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess( + setCollisionHeader->fileName.c_str())); if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ResourceLogging"), 0)) { LogSetCollisionHeaderAsXML(setCollisionHeader); @@ -33,7 +34,8 @@ SetCollisionHeaderFactoryXML::ReadResource(std::shared_ptrfileName = reader->Attribute("FileName"); setCollisionHeader->collisionHeader = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(setCollisionHeader->fileName.c_str())); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess( + setCollisionHeader->fileName.c_str())); return setCollisionHeader; } diff --git a/soh/soh/resource/importer/scenecommand/SetCutscenesFactory.cpp b/soh/soh/resource/importer/scenecommand/SetCutscenesFactory.cpp index a8883b2e4e..3aee3231e1 100644 --- a/soh/soh/resource/importer/scenecommand/SetCutscenesFactory.cpp +++ b/soh/soh/resource/importer/scenecommand/SetCutscenesFactory.cpp @@ -14,7 +14,7 @@ std::shared_ptr SetCutscenesFactory::ReadResource(std::shared_p setCutscenes->fileName = reader->ReadString(); setCutscenes->cutscene = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(setCutscenes->fileName.c_str())); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(setCutscenes->fileName.c_str())); if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ResourceLogging"), 0)) { LogCutscenesAsXML(setCutscenes); @@ -31,7 +31,7 @@ std::shared_ptr SetCutscenesFactoryXML::ReadResource(std::share setCutscenes->fileName = reader->Attribute("FileName"); setCutscenes->cutscene = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(setCutscenes->fileName.c_str())); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(setCutscenes->fileName.c_str())); return setCutscenes; } diff --git a/soh/soh/resource/importer/scenecommand/SetPathwaysFactory.cpp b/soh/soh/resource/importer/scenecommand/SetPathwaysFactory.cpp index 62a3d0d7f9..36c42a2246 100644 --- a/soh/soh/resource/importer/scenecommand/SetPathwaysFactory.cpp +++ b/soh/soh/resource/importer/scenecommand/SetPathwaysFactory.cpp @@ -17,7 +17,7 @@ std::shared_ptr SetPathwaysFactory::ReadResource(std::shared_pt for (uint32_t i = 0; i < setPathways->numPaths; i++) { std::string pathFileName = reader->ReadString(); auto path = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(pathFileName.c_str())); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(pathFileName.c_str())); setPathways->paths.push_back(path->GetPointer()); setPathways->pathFileNames.push_back(pathFileName); } @@ -42,7 +42,7 @@ std::shared_ptr SetPathwaysFactoryXML::ReadResource(std::shared if (childName == "Pathway") { std::string pathFileName = child->Attribute("FilePath"); auto path = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(pathFileName.c_str())); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(pathFileName.c_str())); setPathways->paths.push_back(path->GetPointer()); setPathways->pathFileNames.push_back(pathFileName); } diff --git a/soh/soh/resource/type/AudioSample.h b/soh/soh/resource/type/AudioSample.h index eb29bc5bce..b07523bc44 100644 --- a/soh/soh/resource/type/AudioSample.h +++ b/soh/soh/resource/type/AudioSample.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/soh/soh/resource/type/AudioSequence.h b/soh/soh/resource/type/AudioSequence.h index 90d5dd15e0..96f2022807 100644 --- a/soh/soh/resource/type/AudioSequence.h +++ b/soh/soh/resource/type/AudioSequence.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include namespace SOH { diff --git a/soh/soh/resource/type/AudioSoundFont.h b/soh/soh/resource/type/AudioSoundFont.h index 0e07c03083..0f66d927a9 100644 --- a/soh/soh/resource/type/AudioSoundFont.h +++ b/soh/soh/resource/type/AudioSoundFont.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "soh/resource/type/AudioSample.h" diff --git a/soh/soh/resource/type/CollisionHeader.h b/soh/soh/resource/type/CollisionHeader.h index d6cd3c6fd8..7479de99ea 100644 --- a/soh/soh/resource/type/CollisionHeader.h +++ b/soh/soh/resource/type/CollisionHeader.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/Cutscene.h b/soh/soh/resource/type/Cutscene.h index 59475d1cf9..a8748f59b3 100644 --- a/soh/soh/resource/type/Cutscene.h +++ b/soh/soh/resource/type/Cutscene.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include namespace SOH { diff --git a/soh/soh/resource/type/Path.h b/soh/soh/resource/type/Path.h index 42fc2946fb..a5b821ebdf 100644 --- a/soh/soh/resource/type/Path.h +++ b/soh/soh/resource/type/Path.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/Scene.h b/soh/soh/resource/type/Scene.h index 371890e764..6394bff5e1 100644 --- a/soh/soh/resource/type/Scene.h +++ b/soh/soh/resource/type/Scene.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/Skeleton.cpp b/soh/soh/resource/type/Skeleton.cpp index b241209f67..35d29e0c9c 100644 --- a/soh/soh/resource/type/Skeleton.cpp +++ b/soh/soh/resource/type/Skeleton.cpp @@ -5,11 +5,11 @@ #include #include #include -#include "macros.h" extern "C" { #include "variables.h" #include "z64.h" +#include "macros.h" #include "z64player.h" extern PlayState* gPlayState; } @@ -106,7 +106,7 @@ void SkeletonPatcher::ClearSkeletons() { } void SkeletonPatcher::UpdateSkeletons() { - auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager(); + auto resourceMgr = Ship::Context::GetRawInstance()->GetResourceManager(); bool isAlt = resourceMgr->IsAltAssetsEnabled(); for (auto skel : skeletons) { Skeleton* newSkel = @@ -177,12 +177,12 @@ void SkeletonPatcher::UpdateTunicSkeletons(SkeletonPatchInfo& skel) { void SkeletonPatcher::UpdateCustomSkeletonFromPath(const std::string& skeletonPath, SkeletonPatchInfo& skel) { Skeleton* newSkel = nullptr; Skeleton* altSkel = nullptr; - auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager(); + auto resourceMgr = Ship::Context::GetRawInstance()->GetResourceManager(); bool isAlt = resourceMgr->IsAltAssetsEnabled(); // If alt assets are on, look for alt tagged skeletons if (isAlt) { - altSkel = (Skeleton*)Ship::Context::GetInstance() + altSkel = (Skeleton*)Ship::Context::GetRawInstance() ->GetResourceManager() ->LoadResource(Ship::IResource::gAltAssetPrefix + skeletonPath, true) .get(); @@ -195,7 +195,8 @@ void SkeletonPatcher::UpdateCustomSkeletonFromPath(const std::string& skeletonPa // Load new skeleton based on the custom model if it exists if (altSkel == nullptr) { - newSkel = (Skeleton*)Ship::Context::GetInstance()->GetResourceManager()->LoadResource(skeletonPath, true).get(); + newSkel = + (Skeleton*)Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(skeletonPath, true).get(); } // Change back to the original skeleton if no skeleton's were found diff --git a/soh/soh/resource/type/Skeleton.h b/soh/soh/resource/type/Skeleton.h index 3ae5d743f3..11e0995c94 100644 --- a/soh/soh/resource/type/Skeleton.h +++ b/soh/soh/resource/type/Skeleton.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include "SkeletonLimb.h" #include diff --git a/soh/soh/resource/type/Text.h b/soh/soh/resource/type/Text.h index ff921e7317..a9f00ef277 100644 --- a/soh/soh/resource/type/Text.h +++ b/soh/soh/resource/type/Text.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/EndMarker.h b/soh/soh/resource/type/scenecommand/EndMarker.h index 5d3a0f7dfb..17b3b4fff1 100644 --- a/soh/soh/resource/type/scenecommand/EndMarker.h +++ b/soh/soh/resource/type/scenecommand/EndMarker.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/RomFile.h b/soh/soh/resource/type/scenecommand/RomFile.h index 5262ce6499..78bad901ff 100644 --- a/soh/soh/resource/type/scenecommand/RomFile.h +++ b/soh/soh/resource/type/scenecommand/RomFile.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace SOH { typedef struct { diff --git a/soh/soh/resource/type/scenecommand/SceneCommand.h b/soh/soh/resource/type/scenecommand/SceneCommand.h index 1e71599dc1..8d684e1465 100644 --- a/soh/soh/resource/type/scenecommand/SceneCommand.h +++ b/soh/soh/resource/type/scenecommand/SceneCommand.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetActorList.h b/soh/soh/resource/type/scenecommand/SetActorList.h index b444aadd0b..63d218a248 100644 --- a/soh/soh/resource/type/scenecommand/SetActorList.h +++ b/soh/soh/resource/type/scenecommand/SetActorList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetAlternateHeaders.h b/soh/soh/resource/type/scenecommand/SetAlternateHeaders.h index 38817d1a6c..2d6118fe0c 100644 --- a/soh/soh/resource/type/scenecommand/SetAlternateHeaders.h +++ b/soh/soh/resource/type/scenecommand/SetAlternateHeaders.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetCameraSettings.h b/soh/soh/resource/type/scenecommand/SetCameraSettings.h index 0cc03cfd56..62bee9aaa8 100644 --- a/soh/soh/resource/type/scenecommand/SetCameraSettings.h +++ b/soh/soh/resource/type/scenecommand/SetCameraSettings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetCollisionHeader.h b/soh/soh/resource/type/scenecommand/SetCollisionHeader.h index 283a8bc0a2..17940cb133 100644 --- a/soh/soh/resource/type/scenecommand/SetCollisionHeader.h +++ b/soh/soh/resource/type/scenecommand/SetCollisionHeader.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetCsCamera.h b/soh/soh/resource/type/scenecommand/SetCsCamera.h index 42db077544..7af48b990c 100644 --- a/soh/soh/resource/type/scenecommand/SetCsCamera.h +++ b/soh/soh/resource/type/scenecommand/SetCsCamera.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetCutscenes.h b/soh/soh/resource/type/scenecommand/SetCutscenes.h index 0988b2027b..d24dddbb0c 100644 --- a/soh/soh/resource/type/scenecommand/SetCutscenes.h +++ b/soh/soh/resource/type/scenecommand/SetCutscenes.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetEchoSettings.h b/soh/soh/resource/type/scenecommand/SetEchoSettings.h index dfa0538a48..bfdbecf58e 100644 --- a/soh/soh/resource/type/scenecommand/SetEchoSettings.h +++ b/soh/soh/resource/type/scenecommand/SetEchoSettings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetEntranceList.h b/soh/soh/resource/type/scenecommand/SetEntranceList.h index 08fcf9fca0..d9fad36fb4 100644 --- a/soh/soh/resource/type/scenecommand/SetEntranceList.h +++ b/soh/soh/resource/type/scenecommand/SetEntranceList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetExitList.h b/soh/soh/resource/type/scenecommand/SetExitList.h index d9598c3cd6..958f62f7bc 100644 --- a/soh/soh/resource/type/scenecommand/SetExitList.h +++ b/soh/soh/resource/type/scenecommand/SetExitList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetLightList.h b/soh/soh/resource/type/scenecommand/SetLightList.h index 3a95a4f8fd..a9c48914b1 100644 --- a/soh/soh/resource/type/scenecommand/SetLightList.h +++ b/soh/soh/resource/type/scenecommand/SetLightList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetLightingSettings.h b/soh/soh/resource/type/scenecommand/SetLightingSettings.h index ca9282225e..6eadad1e7c 100644 --- a/soh/soh/resource/type/scenecommand/SetLightingSettings.h +++ b/soh/soh/resource/type/scenecommand/SetLightingSettings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetMesh.h b/soh/soh/resource/type/scenecommand/SetMesh.h index 1ab86530a9..baf7744f27 100644 --- a/soh/soh/resource/type/scenecommand/SetMesh.h +++ b/soh/soh/resource/type/scenecommand/SetMesh.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetObjectList.h b/soh/soh/resource/type/scenecommand/SetObjectList.h index 5650f6d947..49fc5079da 100644 --- a/soh/soh/resource/type/scenecommand/SetObjectList.h +++ b/soh/soh/resource/type/scenecommand/SetObjectList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetPathways.h b/soh/soh/resource/type/scenecommand/SetPathways.h index ec20113670..6862049bbc 100644 --- a/soh/soh/resource/type/scenecommand/SetPathways.h +++ b/soh/soh/resource/type/scenecommand/SetPathways.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetRoomBehavior.h b/soh/soh/resource/type/scenecommand/SetRoomBehavior.h index 8a1c2b832a..8114a4b625 100644 --- a/soh/soh/resource/type/scenecommand/SetRoomBehavior.h +++ b/soh/soh/resource/type/scenecommand/SetRoomBehavior.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetRoomList.h b/soh/soh/resource/type/scenecommand/SetRoomList.h index 6fe6d33ff3..f8530a1a77 100644 --- a/soh/soh/resource/type/scenecommand/SetRoomList.h +++ b/soh/soh/resource/type/scenecommand/SetRoomList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetSkyboxModifier.h b/soh/soh/resource/type/scenecommand/SetSkyboxModifier.h index 189e4ab3d7..003b8411e2 100644 --- a/soh/soh/resource/type/scenecommand/SetSkyboxModifier.h +++ b/soh/soh/resource/type/scenecommand/SetSkyboxModifier.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetSkyboxSettings.h b/soh/soh/resource/type/scenecommand/SetSkyboxSettings.h index cf3bbfbad0..d5bdc97c37 100644 --- a/soh/soh/resource/type/scenecommand/SetSkyboxSettings.h +++ b/soh/soh/resource/type/scenecommand/SetSkyboxSettings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetSoundSettings.h b/soh/soh/resource/type/scenecommand/SetSoundSettings.h index ba180d8232..184063afd3 100644 --- a/soh/soh/resource/type/scenecommand/SetSoundSettings.h +++ b/soh/soh/resource/type/scenecommand/SetSoundSettings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetSpecialObjects.h b/soh/soh/resource/type/scenecommand/SetSpecialObjects.h index 1e9e44e9f0..d2c0b93606 100644 --- a/soh/soh/resource/type/scenecommand/SetSpecialObjects.h +++ b/soh/soh/resource/type/scenecommand/SetSpecialObjects.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetStartPositionList.h b/soh/soh/resource/type/scenecommand/SetStartPositionList.h index 2b1ddce893..64b4b89b78 100644 --- a/soh/soh/resource/type/scenecommand/SetStartPositionList.h +++ b/soh/soh/resource/type/scenecommand/SetStartPositionList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetTimeSettings.h b/soh/soh/resource/type/scenecommand/SetTimeSettings.h index c5b63283ba..76eda7439a 100644 --- a/soh/soh/resource/type/scenecommand/SetTimeSettings.h +++ b/soh/soh/resource/type/scenecommand/SetTimeSettings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetTransitionActorList.h b/soh/soh/resource/type/scenecommand/SetTransitionActorList.h index 0b7149fa64..6b395d9793 100644 --- a/soh/soh/resource/type/scenecommand/SetTransitionActorList.h +++ b/soh/soh/resource/type/scenecommand/SetTransitionActorList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/resource/type/scenecommand/SetWindSettings.h b/soh/soh/resource/type/scenecommand/SetWindSettings.h index 87e0a3039a..f712488d30 100644 --- a/soh/soh/resource/type/scenecommand/SetWindSettings.h +++ b/soh/soh/resource/type/scenecommand/SetWindSettings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/soh/soh/util.cpp b/soh/soh/util.cpp index b3bc053f10..7efa4b7d16 100644 --- a/soh/soh/util.cpp +++ b/soh/soh/util.cpp @@ -796,3 +796,20 @@ uint32_t SohUtils::Hash(std::string str) { } return hval; } + +std::vector SohUtils::StringSplit(const std::string& str, const std::string& delimiter) { + std::vector tokens; + size_t pos = str.find(delimiter, 0); + size_t prevpos = 0; + + while (pos != std::string::npos) { + std::string token = str.substr(prevpos, pos - prevpos); + tokens.push_back(token); + prevpos = pos + 1; + pos = str.find(delimiter, prevpos); + } + + tokens.push_back(str.substr(prevpos)); + + return tokens; +} \ No newline at end of file diff --git a/soh/soh/util.h b/soh/soh/util.h index f704076b4d..2058a34429 100644 --- a/soh/soh/util.h +++ b/soh/soh/util.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include typedef enum FileType { FILE_TYPE_SAVE_VANILLA, FILE_TYPE_SAVE_RANDO, FILE_TYPE_PRESET, FILE_TYPE_SPOILER } FileType; @@ -25,4 +26,6 @@ size_t CopyStringToCharBuffer(char* buffer, const std::string& source, size_t ma bool IsStringEmpty(std::string str); uint32_t Hash(std::string str); + +std::vector StringSplit(const std::string& str, const std::string& delimiter); } // namespace SohUtils diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index 1a83970ffa..a693d5078f 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -23,11 +23,11 @@ static void SetMessageEntry(MessageTableEntry& entry, const SOH::MessageEntry& m } static void OTRMessage_LoadCustom(const std::string& folderPath, MessageTableEntry*& table, size_t tableSize) { - auto lst = *Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(folderPath).get(); + auto lst = *Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(folderPath).get(); for (auto& tPath : lst) { auto file = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(tPath)); + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(tPath)); for (size_t j = 0; j < file->messages.size(); ++j) { // Check if same text ID exists already @@ -44,8 +44,8 @@ static void OTRMessage_LoadCustom(const std::string& folderPath, MessageTableEnt } MessageTableEntry* OTRMessage_LoadTable(const std::string& filePath, bool isNES) { - auto file = - std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource(filePath)); + auto file = std::static_pointer_cast( + Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(filePath)); if (file == nullptr) return nullptr; @@ -95,7 +95,7 @@ extern "C" void OTRMessage_Init() { if (sStaffMessageEntryTablePtr == NULL) { auto file2 = - std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource( + std::static_pointer_cast(Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource( "text/staff_message_data_static/staff_message_data_static")); // OTRTODO: Should not be malloc'ing here. It's fine for now since we check that the message table is already // null. diff --git a/soh/soh/z_play_otr.cpp b/soh/soh/z_play_otr.cpp index f997c37284..892edd5fd0 100644 --- a/soh/soh/z_play_otr.cpp +++ b/soh/soh/z_play_otr.cpp @@ -14,7 +14,7 @@ s32 OTRScene_ExecuteCommands(PlayState* play, SOH::Scene* scene); // LUS::OTRResource* OTRPlay_LoadFile(PlayState* play, RomFile* file) { Ship::IResource* OTRPlay_LoadFile(PlayState* play, const char* fileName) { - auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fileName); + auto res = Ship::Context::GetRawInstance()->GetResourceManager()->LoadResource(fileName); return res.get(); } @@ -81,7 +81,7 @@ void OTRPlay_InitScene(PlayState* play, s32 spawn) { GameInteractor_ExecuteAfterSceneCommands(play->sceneNum); Play_InitEnvironment(play, play->skyboxId); - /* auto data = static_cast(Ship::Context::GetInstance() + /* auto data = static_cast(Ship::Context::GetRawInstance() ->GetResourceManager() ->ResourceLoad("object_link_child\\object_link_childVtx_01FE08") .get()); diff --git a/soh/src/code/game.c b/soh/src/code/game.c index a31cf64744..dbbe5e75c2 100644 --- a/soh/src/code/game.c +++ b/soh/src/code/game.c @@ -26,7 +26,7 @@ GameState* gGameState; // Forward declared, because this in a C++ header. int gfx_create_framebuffer(uint32_t width, uint32_t height, uint32_t native_width, uint32_t native_height, - uint8_t resize); + uint8_t resize, bool forceFixedAspect); void gfx_texture_cache_clear(); void GameState_FaultPrint(void) { @@ -260,7 +260,7 @@ void GameState_Update(GameState* gameState) { if (gPauseLinkFrameBuffer == -1) { gPauseLinkFrameBuffer = gfx_create_framebuffer(PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT, - PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT, true); + PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT, true, true); } GameState_SetFrameBuffer(gfxCtx); diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index f69a7ea8cc..7369727e02 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -1472,7 +1472,7 @@ s32 func_8002DEEC(Player* player) { } void func_8002DF18(PlayState* play, Player* player) { - func_8006DC68(play, player); + Horse_InitPlayerHorse(play, player); } s32 func_8002DF38(PlayState* play, Actor* actor, u8 csAction) { diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 0d30dcb2e6..f6f0a607e3 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -8,6 +8,7 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/controls/Mouse.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" s16 Camera_ChangeSettingFlags(Camera* camera, s16 setting, s16 flags); s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags); @@ -4542,9 +4543,9 @@ s32 Camera_Subj4(Camera* camera) { } anim->unk_28 = temp_f16; - // camera->player->actor.world.pos = *eyeNext; - // camera->player->actor.world.pos.y = camera->playerGroundY; - // camera->player->actor.shape.rot.y = sp64.yaw; + camera->player->actor.world.pos = *eyeNext; + camera->player->actor.world.pos.y = camera->playerGroundY; + camera->player->actor.shape.rot.y = sp64.yaw; temp_f16 = ((240.0f * temp_f16) * (anim->unk_24 * 0.416667f)); temp_a0 = temp_f16 + anim->unk_30; at->x = eye->x + (Math_SinS(temp_a0) * 10.0f); @@ -7363,7 +7364,8 @@ s32 Camera_UpdateWater(Camera* camera) { s32 Camera_UpdateHotRoom(Camera* camera) { camera->distortionFlags &= ~DISTORTION_HOT_ROOM; - if (camera->play->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_3) { + if (GameInteractor_Should(VB_HOT_ROOM_DISTORTION, + camera->play->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_3)) { camera->distortionFlags |= DISTORTION_HOT_ROOM; } diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index e8e29a19df..b2da1c40db 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -3,7 +3,6 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h" #include "textures/icon_item_static/icon_item_static.h" -#include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/OTRGlobals.h" @@ -781,11 +780,8 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { } } - if (this->unk_15A > 0) { + if (GameInteractor_Should(VB_ITEM00_TIMER_TICK, this->unk_15A > 0, this)) { this->unk_15A--; - if (CVarGetInteger(CVAR_CHEAT("DropsDontDie"), 0) && (this->unk_154 <= 0)) { - this->unk_15A++; - } } if ((this->unk_15A > 0) && (this->unk_15A < 41) && (this->unk_154 <= 0)) { diff --git a/soh/src/code/z_horse.c b/soh/src/code/z_horse.c index 68f9ba9d2d..2accaa9ac5 100644 --- a/soh/src/code/z_horse.c +++ b/soh/src/code/z_horse.c @@ -4,7 +4,7 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -s32 func_8006CFC0(s32 scene) { +s32 Horse_CanSpawn(s32 scene) { s32 validScenes[] = { SCENE_HYRULE_FIELD, SCENE_LAKE_HYLIA, SCENE_GERUDO_VALLEY, SCENE_GERUDOS_FORTRESS, SCENE_LON_LON_RANCH }; s32 i; @@ -18,7 +18,7 @@ s32 func_8006CFC0(s32 scene) { return 0; } -void func_8006D074(PlayState* play) { +void Horse_ResetHorseData(PlayState* play) { gSaveContext.horseData.scene = SCENE_HYRULE_FIELD; gSaveContext.horseData.pos.x = -1840; gSaveContext.horseData.pos.y = 72; @@ -26,7 +26,7 @@ void func_8006D074(PlayState* play) { gSaveContext.horseData.angle = -27353; } -void func_8006D0AC(PlayState* play) { +void Horse_FixLakeHyliaPosition(PlayState* play) { if (gSaveContext.horseData.scene == SCENE_LAKE_HYLIA) { gSaveContext.horseData.scene = SCENE_LAKE_HYLIA; gSaveContext.horseData.pos.x = -2065; @@ -43,7 +43,7 @@ typedef struct { /* 0x0A */ s16 type; } HorseSpawn; -void func_8006D0EC(PlayState* play, Player* player) { +void Horse_SetupInGameplay(PlayState* play, Player* player) { s32 i; HorseSpawn horseSpawns[] = { { SCENE_HYRULE_FIELD, -460, 100, 6640, 0, 2 }, { SCENE_LAKE_HYLIA, -1929, -1025, 768, 0, 2 }, @@ -87,7 +87,7 @@ void func_8006D0EC(PlayState* play, Player* player) { osSyncPrintf("馬存在によるセット %d %d %d\n", gSaveContext.horseData.scene, Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED), DREG(1)); - if (func_8006CFC0(gSaveContext.horseData.scene)) { + if (Horse_CanSpawn(gSaveContext.horseData.scene)) { Actor* horseActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, gSaveContext.horseData.pos.x, gSaveContext.horseData.pos.y, gSaveContext.horseData.pos.z, 0, gSaveContext.horseData.angle, 0, 1); @@ -100,7 +100,7 @@ void func_8006D0EC(PlayState* play, Player* player) { // "Horse_SetNormal():%d set spot is no good." osSyncPrintf("Horse_SetNormal():%d セットスポットまずいです。\n", gSaveContext.horseData.scene); osSyncPrintf(VT_RST); - func_8006D074(play); + Horse_ResetHorseData(play); } } else if ((play->sceneNum == SCENE_LON_LON_RANCH) && !Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) && (DREG(1) == 0)) { @@ -136,7 +136,7 @@ typedef struct { /* 0x10 */ s16 type; } struct_8011F9B8; -void func_8006D684(PlayState* play, Player* player) { +void Horse_SetupInCutscene(PlayState* play, Player* player) { s32 pad; s32 i; Vec3s spawnPos; @@ -247,17 +247,17 @@ void func_8006D684(PlayState* play, Player* player) { } } -void func_8006DC68(PlayState* play, Player* player) { +void Horse_InitPlayerHorse(PlayState* play, Player* player) { if (LINK_IS_ADULT) { - if (!func_8006CFC0(gSaveContext.horseData.scene)) { + if (!Horse_CanSpawn(gSaveContext.horseData.scene)) { osSyncPrintf(VT_COL(RED, WHITE)); // "Horse_Set_Check():%d set spot is no good." osSyncPrintf("Horse_Set_Check():%d セットスポットまずいです。\n", gSaveContext.horseData.scene); osSyncPrintf(VT_RST); - func_8006D074(play); + Horse_ResetHorseData(play); } - if (func_8006CFC0(play->sceneNum)) { + if (Horse_CanSpawn(play->sceneNum)) { if ((gSaveContext.sceneSetupIndex > 3) || ((gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_11 || gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_12 || @@ -266,15 +266,15 @@ void func_8006DC68(PlayState* play, Player* player) { (gSaveContext.respawnFlag == 0)) || ((play->sceneNum == SCENE_LON_LON_RANCH) && ((gSaveContext.eventInf[0] & 0xF) == 6) && !Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) && (DREG(1) == 0))) { - func_8006D684(play, player); + Horse_SetupInCutscene(play, player); } else { - func_8006D0EC(play, player); + Horse_SetupInGameplay(play, player); } } } } -void func_8006DD9C(Actor* actor, Vec3f* arg1, s16 arg2) { +void Horse_RotateToPoint(Actor* actor, Vec3f* arg1, s16 arg2) { s16 x = Math_Vec3f_Yaw(&actor->world.pos, arg1) - actor->world.rot.y; if (x > arg2) { diff --git a/soh/src/code/z_map_exp.c b/soh/src/code/z_map_exp.c index 44b5b43b5d..6d8222e5a2 100644 --- a/soh/src/code/z_map_exp.c +++ b/soh/src/code/z_map_exp.c @@ -7,6 +7,7 @@ #include #include "soh/OTRGlobals.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" MapData* gMapData; @@ -761,6 +762,10 @@ void Minimap_DrawCompassIcons(PlayState* play) { } CLOSE_DISPS(play->state.gfxCtx); + + if (play->interfaceCtx.minimapAlpha >= 0xAA) { + GameInteractor_ExecuteOnMinimapDrawCompassIcons(); + } } void Minimap_Draw(PlayState* play) { diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 4b782d9540..2064527e6e 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1711,7 +1711,9 @@ void Interface_InitHorsebackArchery(PlayState* play) { gSaveContext.minigameState = 1; interfaceCtx->unk_23C = interfaceCtx->unk_240 = interfaceCtx->unk_242 = 0; gSaveContext.minigameScore = sHBAScoreTier = 0; - interfaceCtx->hbaAmmo = 20; + if (GameInteractor_Should(VB_SET_HORSEBACK_ARCHERY_AMMO, true, interfaceCtx)) { + interfaceCtx->hbaAmmo = 20; + } } void func_800849EC(PlayState* play) { @@ -1910,7 +1912,7 @@ u8 Item_Give(PlayState* play, u8 item) { osSyncPrintf(VT_RST); if (item == ITEM_MEDALLION_WATER) { - func_8006D0AC(play); + Horse_FixLakeHyliaPosition(play); } return Return_Item(item, MOD_NONE, ITEM_NONE); diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index 89faa95ad5..f2e2b7321d 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -1598,21 +1598,28 @@ void Player_DrawGetItemIceTrap(PlayState* play, Player* this, Vec3f* refPos, s32 } else if (iceTrapScale < 0.8f) { iceTrapScale += 0.2f; } - gSPSegment(POLY_XLU_DISP++, 0x08, - Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, (0 - play->gameplayFrames) % 128, 32, 32, 1, 0, - (play->gameplayFrames * -2) % 128, 32, 32, 0, -1, 0, -2)); - Matrix_Translate(0.0f, -40.0f, 0.0f, MTXMODE_APPLY); - Matrix_Scale(iceTrapScale, iceTrapScale, iceTrapScale, MTXMODE_APPLY); - gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gDPSetEnvColor(POLY_XLU_DISP++, 0, 50, 100, 255); - gSPDisplayList(POLY_XLU_DISP++, gEffIceFragment3DL); + // Draw the ice only after a bit so it doesn't spoil the fact that it's a trap + if (iceTrapScale >= 0.01) { + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, (0 - play->gameplayFrames) % 128, 32, 32, 1, 0, + (play->gameplayFrames * -2) % 128, 32, 32, 0, -1, 0, -2)); + + Matrix_Translate(0.0f, -40.0f, 0.0f, MTXMODE_APPLY); + Matrix_Scale(iceTrapScale, iceTrapScale, iceTrapScale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 50, 100, 255); + gSPDisplayList(POLY_XLU_DISP++, gEffIceFragment3DL); + + // Reset matrix for the fake item model because we're animating the size of the ice block around it before + // this. + Matrix_Translate(refPos->x + (3.3f * Math_SinS(this->actor.shape.rot.y)), refPos->y + height, + refPos->z + ((3.3f + (IREG(90) / 10.0f)) * Math_CosS(this->actor.shape.rot.y)), + MTXMODE_NEW); + Matrix_RotateZYX(0, play->gameplayFrames * 1000, 0, MTXMODE_APPLY); + Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); + } - // Reset matrix for the fake item model because we're animating the size of the ice block around it before this. - Matrix_Translate(refPos->x + (3.3f * Math_SinS(this->actor.shape.rot.y)), refPos->y + height, - refPos->z + ((3.3f + (IREG(90) / 10.0f)) * Math_CosS(this->actor.shape.rot.y)), MTXMODE_NEW); - Matrix_RotateZYX(0, play->gameplayFrames * 1000, 0, MTXMODE_APPLY); - Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); // Draw fake item model. if (this->getItemEntry.drawFunc != NULL) { this->getItemEntry.drawFunc(play, &this->getItemEntry); diff --git a/soh/src/code/z_skelanime.c b/soh/src/code/z_skelanime.c index 4335df0c8f..3449c2ed91 100644 --- a/soh/src/code/z_skelanime.c +++ b/soh/src/code/z_skelanime.c @@ -902,6 +902,10 @@ void AnimationContext_SetLoadFrame(PlayState* play, LinkAnimationHeader* animati if (frame < 0) { frame = 0; } + // SOH [Alt Assets] Check if animData is null (can happen if animation data segment failed to load) + if (animData == NULL) { + return; + } memcpy(ram, (uintptr_t)animData + (((sizeof(Vec3s) * limbCount + 2) * frame)), sizeof(Vec3s) * limbCount + 2); } } diff --git a/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c b/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c index 6e2bf6e94f..640eaf4102 100644 --- a/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c +++ b/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c @@ -95,7 +95,7 @@ void ArmsHook_Wait(ArmsHook* this, PlayState* play) { } } -void func_80865044(ArmsHook* this) { +void ArmsHook_PullPlayer(ArmsHook* this) { this->actor.child = this->actor.parent; this->actor.parent->parent = &this->actor; } @@ -178,7 +178,7 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) { if (this->collider.info.atHitInfo->bumperFlags & BUMP_HOOKABLE) { ArmsHook_AttachHookToActor(this, touchedActor); if (CHECK_FLAG_ALL(touchedActor->flags, ACTOR_FLAG_HOOKSHOT_PULLS_PLAYER)) { - func_80865044(this); + ArmsHook_PullPlayer(this); } } } @@ -279,7 +279,7 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) { ArmsHook_AttachHookToActor(this, &dynaPolyActor->actor); } } - func_80865044(this); + ArmsHook_PullPlayer(this); Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_STICK_OBJ, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c index a30a1dcd32..d6f8250059 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c @@ -14,22 +14,22 @@ void BgBdanObjects_Destroy(Actor* thisx, PlayState* play); void BgBdanObjects_Update(Actor* thisx, PlayState* play); void BgBdanObjects_Draw(Actor* thisx, PlayState* play); -void func_8086C054(BgBdanObjects* this, PlayState* play); -void func_8086C1A0(BgBdanObjects* this, PlayState* play); -void func_8086C29C(BgBdanObjects* this, PlayState* play); -void func_8086C55C(BgBdanObjects* this, PlayState* play); -void func_8086C5BC(BgBdanObjects* this, PlayState* play); -void func_8086C618(BgBdanObjects* this, PlayState* play); -void func_8086C6EC(BgBdanObjects* this, PlayState* play); -void func_8086C76C(BgBdanObjects* this, PlayState* play); -void func_8086C7D0(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_OctoPlatform_WaitForRutoToStartCutscene(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_OctoPlatform_RaiseToUpperPosition(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_OctoPlatform_WaitForRutoToAdvanceCutscene(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_OctoPlatform_PauseBeforeDescending(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_OctoPlatform_WaitForBigOctoToStartBattle(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_OctoPlatform_BattleInProgress(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_SinkToFloorHeight(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_WaitForPlayerInRange(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_RaiseToUpperPosition(BgBdanObjects* this, PlayState* play); void BgBdanObjects_DoNothing(BgBdanObjects* this, PlayState* play); -void func_8086C874(BgBdanObjects* this, PlayState* play); -void func_8086C9A8(BgBdanObjects* this, PlayState* play); -void func_8086C9F0(BgBdanObjects* this, PlayState* play); -void func_8086CABC(BgBdanObjects* this, PlayState* play); -void func_8086CB10(BgBdanObjects* this, PlayState* play); -void func_8086CB8C(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_ElevatorOscillate(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_WaitForSwitch(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_ChangeWaterBoxLevel(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_WaitForTimerExpired(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_WaitForPlayerOnTop(BgBdanObjects* this, PlayState* play); +void BgBdanObjects_FallToLowerPos(BgBdanObjects* this, PlayState* play); const ActorInit Bg_Bdan_Objects_InitVars = { ACTOR_BG_BDAN_OBJECTS, @@ -117,7 +117,7 @@ void BgBdanObjects_Init(Actor* thisx, PlayState* play) { if (thisx->params == 2) { thisx->flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED; play->colCtx.colHeader->waterBoxes[7].ySurface = thisx->world.pos.y; - this->actionFunc = func_8086C9A8; + this->actionFunc = BgBdanObjects_WaitForSwitch; return; } if (thisx->params == 0) { @@ -127,7 +127,7 @@ void BgBdanObjects_Init(Actor* thisx, PlayState* play) { thisx->world.pos.y += -79.0f; if (Flags_GetClear(play, thisx->room)) { Flags_SetSwitch(play, this->switchFlag); - this->actionFunc = func_8086C6EC; + this->actionFunc = BgBdanObjects_SinkToFloorHeight; } else { if (BgBdanObjects_GetContactRu1(this, 4)) { if (Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_BIGOKUTA, thisx->home.pos.x, @@ -136,12 +136,12 @@ void BgBdanObjects_Init(Actor* thisx, PlayState* play) { thisx->child->world.pos.z = thisx->child->home.pos.z + 263.0f; } thisx->world.rot.y = 0; - this->actionFunc = func_8086C618; + this->actionFunc = BgBdanObjects_OctoPlatform_BattleInProgress; thisx->world.pos.y = thisx->home.pos.y + -70.0f; } else { Flags_SetSwitch(play, this->switchFlag); this->timer = 0; - this->actionFunc = func_8086C054; + this->actionFunc = BgBdanObjects_OctoPlatform_WaitForRutoToStartCutscene; } } } else { @@ -149,14 +149,14 @@ void BgBdanObjects_Init(Actor* thisx, PlayState* play) { CollisionHeader_GetVirtual(&gJabuElevatorCol, &colHeader); this->timer = 512; this->switchFlag = 0; - this->actionFunc = func_8086C874; + this->actionFunc = BgBdanObjects_ElevatorOscillate; } else { CollisionHeader_GetVirtual(&gJabuLoweringPlatformCol, &colHeader); if (Flags_GetSwitch(play, this->switchFlag)) { this->actionFunc = BgBdanObjects_DoNothing; thisx->world.pos.y = thisx->home.pos.y - 400.0f; } else { - this->actionFunc = func_8086CB10; + this->actionFunc = BgBdanObjects_WaitForPlayerOnTop; } } } @@ -172,7 +172,7 @@ void BgBdanObjects_Destroy(Actor* thisx, PlayState* play) { } } -void func_8086C054(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_OctoPlatform_WaitForRutoToStartCutscene(BgBdanObjects* this, PlayState* play) { Player* player = GET_PLAYER(play); if (BgBdanObjects_GetContactRu1(this, 0)) { @@ -190,7 +190,7 @@ void func_8086C054(BgBdanObjects* this, PlayState* play) { this->timer--; } if (this->timer == 0) { - this->actionFunc = func_8086C1A0; + this->actionFunc = BgBdanObjects_OctoPlatform_RaiseToUpperPosition; } } @@ -201,11 +201,11 @@ void func_8086C054(BgBdanObjects* this, PlayState* play) { } } -void func_8086C1A0(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_OctoPlatform_RaiseToUpperPosition(BgBdanObjects* this, PlayState* play) { if (Math_SmoothStepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 500.0f, 0.5f, 7.5f, 1.0f) < 0.1f) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYOSTAND_STOP_A); - this->actionFunc = func_8086C29C; + this->actionFunc = BgBdanObjects_OctoPlatform_WaitForRutoToAdvanceCutscene; this->timer = 30; BgBdanObjects_SetContactRu1(this, 2); func_800AA000(0.0f, 0xFF, 0x14, 0x96); @@ -221,7 +221,7 @@ void func_8086C1A0(BgBdanObjects* this, PlayState* play) { } } -void func_8086C29C(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_OctoPlatform_WaitForRutoToAdvanceCutscene(BgBdanObjects* this, PlayState* play) { s32 temp; if (this->timer != 0) { @@ -240,12 +240,12 @@ void func_8086C29C(BgBdanObjects* this, PlayState* play) { this->dyna.actor.shape.rot.y + 0x8000, 0, 0); BgBdanObjects_SetContactRu1(this, 4); this->timer = 10; - this->actionFunc = func_8086C55C; + this->actionFunc = BgBdanObjects_OctoPlatform_PauseBeforeDescending; func_8005B1A4(GET_ACTIVE_CAM(play)); } } -void func_8086C3D8(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_OctoPlatform_DescendWithBigOcto(BgBdanObjects* this, PlayState* play) { Player* player = GET_PLAYER(play); this->dyna.actor.velocity.y += 0.5f; @@ -255,7 +255,7 @@ void func_8086C3D8(BgBdanObjects* this, PlayState* play) { this->timer = 60; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYOSTAND_STOP_U); this->dyna.actor.child->world.pos.y = this->dyna.actor.world.pos.y + 140.0f; - this->actionFunc = func_8086C5BC; + this->actionFunc = BgBdanObjects_OctoPlatform_WaitForBigOctoToStartBattle; OnePointCutscene_Init(play, 3080, -99, this->dyna.actor.child, MAIN_CAM); player->actor.world.pos.x = -1130.0f; player->actor.world.pos.y = -1025.0f; @@ -278,63 +278,63 @@ void func_8086C3D8(BgBdanObjects* this, PlayState* play) { } } -void func_8086C55C(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_OctoPlatform_PauseBeforeDescending(BgBdanObjects* this, PlayState* play) { this->timer--; if (this->timer == 0) { Flags_UnsetSwitch(play, this->switchFlag); } else if (this->timer == -40) { this->timer = 0; - this->actionFunc = func_8086C3D8; + this->actionFunc = BgBdanObjects_OctoPlatform_DescendWithBigOcto; } } -void func_8086C5BC(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_OctoPlatform_WaitForBigOctoToStartBattle(BgBdanObjects* this, PlayState* play) { if (this->timer != 0) { this->timer--; } if ((this->timer == 0) && (this->dyna.actor.child != NULL)) { if (this->dyna.actor.child->params == 2) { - this->actionFunc = func_8086C618; + this->actionFunc = BgBdanObjects_OctoPlatform_BattleInProgress; } else if (this->dyna.actor.child->params == 0) { this->dyna.actor.child->params = 1; } } } -void func_8086C618(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_OctoPlatform_BattleInProgress(BgBdanObjects* this, PlayState* play) { Collider_UpdateCylinder(&this->dyna.actor, &this->collider); CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); if (Flags_GetClear(play, this->dyna.actor.room)) { Flags_SetSwitch(play, this->switchFlag); this->dyna.actor.home.rot.y = (s16)(this->dyna.actor.shape.rot.y + 0x2000) & 0xC000; - this->actionFunc = func_8086C6EC; + this->actionFunc = BgBdanObjects_SinkToFloorHeight; } else { this->dyna.actor.shape.rot.y += this->dyna.actor.world.rot.y; func_800F436C(&this->dyna.actor.projectedPos, 0x2063, ABS(this->dyna.actor.world.rot.y) / 512.0f); } } -void func_8086C6EC(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_SinkToFloorHeight(BgBdanObjects* this, PlayState* play) { s32 cond = Math_ScaledStepToS(&this->dyna.actor.shape.rot.y, this->dyna.actor.home.rot.y, 0x200); if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + -125.0f, 3.0f)) { if (cond) { - this->actionFunc = func_8086C76C; + this->actionFunc = BgBdanObjects_WaitForPlayerInRange; } } } -void func_8086C76C(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_WaitForPlayerInRange(BgBdanObjects* this, PlayState* play) { if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->dyna.actor.xzDistToPlayer < 120.0f) { - this->actionFunc = func_8086C7D0; + this->actionFunc = BgBdanObjects_RaiseToUpperPosition; OnePointCutscene_Init(play, 3090, -99, &this->dyna.actor, MAIN_CAM); } } } -void func_8086C7D0(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_RaiseToUpperPosition(BgBdanObjects* this, PlayState* play) { if (Math_SmoothStepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 965.0f, 0.5f, 15.0f, 0.2f) < 0.01f) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYOSTAND_STOP_A); @@ -347,7 +347,7 @@ void func_8086C7D0(BgBdanObjects* this, PlayState* play) { void BgBdanObjects_DoNothing(BgBdanObjects* this, PlayState* play) { } -void func_8086C874(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_ElevatorOscillate(BgBdanObjects* this, PlayState* play) { if (this->timer != 0) { this->timer--; } @@ -377,50 +377,50 @@ void func_8086C874(BgBdanObjects* this, PlayState* play) { } } -void func_8086C9A8(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_WaitForSwitch(BgBdanObjects* this, PlayState* play) { if (Flags_GetSwitch(play, this->switchFlag)) { this->timer = 100; - this->actionFunc = func_8086C9F0; + this->actionFunc = BgBdanObjects_ChangeWaterBoxLevel; } } -void func_8086C9F0(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_ChangeWaterBoxLevel(BgBdanObjects* this, PlayState* play) { if (this->timer == 0) { if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 0.5f)) { Flags_UnsetSwitch(play, this->switchFlag); - this->actionFunc = func_8086C9A8; + this->actionFunc = BgBdanObjects_WaitForSwitch; } func_8002F948(&this->dyna.actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); } else { if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 75.0f, 0.5f)) { - this->actionFunc = func_8086CABC; + this->actionFunc = BgBdanObjects_WaitForTimerExpired; } func_8002F948(&this->dyna.actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); } play->colCtx.colHeader->waterBoxes[7].ySurface = this->dyna.actor.world.pos.y; } -void func_8086CABC(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_WaitForTimerExpired(BgBdanObjects* this, PlayState* play) { if (this->timer != 0) { this->timer--; } func_8002F994(&this->dyna.actor, this->timer); if (this->timer == 0) { - this->actionFunc = func_8086C9F0; + this->actionFunc = BgBdanObjects_ChangeWaterBoxLevel; } } -void func_8086CB10(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_WaitForPlayerOnTop(BgBdanObjects* this, PlayState* play) { if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { Flags_SetSwitch(play, this->switchFlag); this->timer = 50; - this->actionFunc = func_8086CB8C; + this->actionFunc = BgBdanObjects_FallToLowerPos; this->dyna.actor.home.pos.y -= 200.0f; OnePointCutscene_Init(play, 3100, 51, &this->dyna.actor, MAIN_CAM); } } -void func_8086CB8C(BgBdanObjects* this, PlayState* play) { +void BgBdanObjects_FallToLowerPos(BgBdanObjects* this, PlayState* play) { if (this->timer != 0) { this->timer--; } @@ -447,7 +447,7 @@ void BgBdanObjects_Draw(Actor* thisx, PlayState* play) { BgBdanObjects* this = (BgBdanObjects*)thisx; if (thisx->params == 0) { - if (this->actionFunc == func_8086C054) { + if (this->actionFunc == BgBdanObjects_OctoPlatform_WaitForRutoToStartCutscene) { if (((thisx->home.pos.y + -79.0f) - 5.0f) < thisx->world.pos.y) { Matrix_Translate(0.0f, -50.0f, 0.0f, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index 3f9b424abc..988a0b6740 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -8,8 +8,6 @@ #include "scenes/dungeons/ddan/ddan_scene.h" #include "objects/object_bwall/object_bwall.h" #include "objects/object_kingdodongo/object_kingdodongo.h" -#include "soh/OTRGlobals.h" -#include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED @@ -62,27 +60,6 @@ static ColliderQuadInit sQuadInit = { { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; -// Replacement quad used for "Blue Fire Arrows" enhancement -static ColliderQuadInit sIceArrowQuadInit = { - { - COLTYPE_NONE, - AT_NONE, - AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, - OC1_NONE, - OC2_TYPE_2, - COLSHAPE_QUAD, - }, - { - ELEMTYPE_UNK0, - { 0x00000048, 0x00, 0x00 }, - { 0x00001048, 0x00, 0x00 }, - TOUCH_NONE, - BUMP_ON, - OCELEM_NONE, - }, - { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, -}; - static BombableWallInfo sBombableWallInfo[] = { { &object_bwall_Col_000118, object_bwall_DL_000040, 0 }, { &object_bwall_Col_000118, object_bwall_DL_000040, 0 }, @@ -97,8 +74,6 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), }; -bool blueFireArrowsEnabledOnMudwallLoad = false; - void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc) { this->actionFunc = actionFunc; } @@ -108,10 +83,6 @@ void BgBreakwall_Init(Actor* thisx, PlayState* play) { s32 pad; s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF; - // Initialize this with the mud wall, so it can't be affected by toggling while the actor is loaded - blueFireArrowsEnabledOnMudwallLoad = CVarGetInteger(CVAR_ENHANCEMENT("BlueFireArrows"), 0) || - (IS_RANDO && Randomizer_GetSettingValue(RSK_BLUE_FIRE_ARROWS)); - Actor_ProcessInitChain(&this->dyna.actor, sInitChain); DynaPolyActor_Init(&this->dyna, DPM_UNK); this->bombableWallDList = sBombableWallInfo[wallType].dList; @@ -129,14 +100,8 @@ void BgBreakwall_Init(Actor* thisx, PlayState* play) { ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f); - // If "Blue Fire Arrows" are enabled, set up this collider for them - if (blueFireArrowsEnabledOnMudwallLoad) { - Collider_InitQuad(play, &this->collider); - Collider_SetQuad(play, &this->collider, &this->dyna.actor, &sIceArrowQuadInit); - } else { - Collider_InitQuad(play, &this->collider); - Collider_SetQuad(play, &this->collider, &this->dyna.actor, &sQuadInit); - } + Collider_InitQuad(play, &this->collider); + Collider_SetQuad(play, &this->collider, &this->dyna.actor, &sQuadInit); } else { this->dyna.actor.world.pos.y -= 40.0f; } @@ -263,20 +228,7 @@ void BgBreakwall_WaitForObject(BgBreakwall* this, PlayState* play) { * despawn itself. */ void BgBreakwall_Wait(BgBreakwall* this, PlayState* play) { - bool blueFireArrowHit = false; - // If "Blue Fire Arrows" enabled, check this collider for a hit - if (blueFireArrowsEnabledOnMudwallLoad) { - if (this->collider.base.acFlags & AC_HIT) { - if ((this->collider.base.ac != NULL) && (this->collider.base.ac->id == ACTOR_EN_ARROW)) { - - if (this->collider.base.ac->child != NULL && this->collider.base.ac->child->id == ACTOR_ARROW_ICE) { - blueFireArrowHit = true; - } - } - } - } - - if (GameInteractor_Should(VB_BG_BREAKWALL_BREAK, this->collider.base.acFlags & 2 || blueFireArrowHit)) { + if (GameInteractor_Should(VB_BG_BREAKWALL_BREAK, this->collider.base.acFlags & AC_HIT, this)) { Vec3f effectPos; s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF; diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h index 4b78bc6c23..b0588bd69e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h @@ -21,8 +21,8 @@ typedef struct { /* 0x30 */ f32 scale; /* 0x34 */ s16 timer; // lifetime /* 0x36 */ s16 type; // 0 is general radiance, else is directed towards Player - /* 0x36 */ f32 pitch; - /* 0x36 */ f32 yaw; + /* 0x38 */ f32 pitch; + /* 0x3C */ f32 yaw; /* 0x40 */ f32 roll; /* 0x44 */ u32 epoch; } BgDyYoseizoParticle; // size = 0x48 @@ -48,7 +48,7 @@ typedef struct BgDyYoseizo { /* 0x02FA */ s16 unusedTimer; /* 0x02FC */ s16 animationChanged; /* 0x02FE */ s16 finishedSpinGrow; - /* 0x02FE */ s16 itemSpawned; + /* 0x0300 */ s16 itemSpawned; /* 0x0302 */ s16 healingTimer; /* 0x0304 */ s16 warpEffectSpawned; /* 0x0306 */ s16 refillTimer; diff --git a/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c b/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c index 732755ed3c..8f86e0cb99 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c @@ -15,11 +15,11 @@ void BgHaka_Destroy(Actor* thisx, PlayState* play); void BgHaka_Update(Actor* thisx, PlayState* play); void BgHaka_Draw(Actor* thisx, PlayState* play); -void func_8087B758(BgHaka* this, Player* player); -void func_8087B7E8(BgHaka* this, PlayState* play); -void func_8087B938(BgHaka* this, PlayState* play); -void func_8087BAAC(BgHaka* this, PlayState* play); -void func_8087BAE4(BgHaka* this, PlayState* play); +void BgHaka_CheckPlayerOnDirtPatch(BgHaka* this, Player* player); +void BgHaka_IdleClosed(BgHaka* this, PlayState* play); +void BgHaka_Pull(BgHaka* this, PlayState* play); +void BgHaka_IdleOpened(BgHaka* this, PlayState* play); +void BgHaka_IdleLockedClosed(BgHaka* this, PlayState* play); const ActorInit Bg_Haka_InitVars = { ACTOR_BG_HAKA, @@ -48,7 +48,7 @@ void BgHaka_Init(Actor* thisx, PlayState* play) { DynaPolyActor_Init(&this->dyna, DPM_UNK); CollisionHeader_GetVirtual(&gGravestoneCol, &colHeader); this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader); - this->actionFunc = func_8087B7E8; + this->actionFunc = BgHaka_IdleClosed; } void BgHaka_Destroy(Actor* thisx, PlayState* play) { @@ -57,7 +57,7 @@ void BgHaka_Destroy(Actor* thisx, PlayState* play) { DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); } -void func_8087B758(BgHaka* this, Player* player) { +void BgHaka_CheckPlayerOnDirtPatch(BgHaka* this, Player* player) { Vec3f sp1C; Actor_WorldToActorCoords(&this->dyna.actor, &sp1C, &player->actor.world.pos); @@ -66,7 +66,7 @@ void func_8087B758(BgHaka* this, Player* player) { } } -void func_8087B7E8(BgHaka* this, PlayState* play) { +void BgHaka_IdleClosed(BgHaka* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->dyna.unk_150 != 0.0f) { @@ -77,7 +77,7 @@ void func_8087B7E8(BgHaka* this, PlayState* play) { if (!Play_InCsMode(play)) { Message_StartTextbox(play, 0x5073, NULL); this->dyna.actor.params = 100; - this->actionFunc = func_8087BAE4; + this->actionFunc = BgHaka_IdleLockedClosed; } } else if (0.0f < this->dyna.unk_150 || (play->sceneNum == SCENE_LAKE_HYLIA && !LINK_IS_ADULT && !Flags_GetSwitch(play, 0x23))) { @@ -85,13 +85,13 @@ void func_8087B7E8(BgHaka* this, PlayState* play) { player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY; } else { this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y + 0x8000; - this->actionFunc = func_8087B938; + this->actionFunc = BgHaka_Pull; } } - func_8087B758(this, player); + BgHaka_CheckPlayerOnDirtPatch(this, player); } -void func_8087B938(BgHaka* this, PlayState* play) { +void BgHaka_Pull(BgHaka* this, PlayState* play) { Player* player = GET_PLAYER(play); s32 sp38; @@ -137,12 +137,12 @@ void func_8087B938(BgHaka* this, PlayState* play) { } } - this->actionFunc = func_8087BAAC; + this->actionFunc = BgHaka_IdleOpened; } func_8002F974(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); } -void func_8087BAAC(BgHaka* this, PlayState* play) { +void BgHaka_IdleOpened(BgHaka* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->dyna.unk_150 != 0.0f) { @@ -151,7 +151,7 @@ void func_8087BAAC(BgHaka* this, PlayState* play) { } } -void func_8087BAE4(BgHaka* this, PlayState* play) { +void BgHaka_IdleLockedClosed(BgHaka* this, PlayState* play) { Player* player = GET_PLAYER(play); s32 pad; @@ -163,9 +163,9 @@ void func_8087BAE4(BgHaka* this, PlayState* play) { player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY; } if (this->dyna.actor.params == 0) { - this->actionFunc = func_8087B7E8; + this->actionFunc = BgHaka_IdleClosed; } - func_8087B758(this, player); + BgHaka_CheckPlayerOnDirtPatch(this, player); } void BgHaka_Update(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c b/soh/src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c index 3bfce6c2a4..2f6bd48cea 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c @@ -15,8 +15,8 @@ void BgHakaMegane_Destroy(Actor* thisx, PlayState* play); void BgHakaMegane_Update(Actor* thisx, PlayState* play); void BgHakaMegane_Draw(Actor* thisx, PlayState* play); -void func_8087DB24(BgHakaMegane* this, PlayState* play); -void func_8087DBF0(BgHakaMegane* this, PlayState* play); +void BgHakaMegane_WaitForObject(BgHakaMegane* this, PlayState* play); +void BgHakaMegane_UpdateState(BgHakaMegane* this, PlayState* play); void BgHakaMegane_DoNothing(BgHakaMegane* this, PlayState* play); const ActorInit Bg_Haka_Megane_InitVars = { @@ -75,7 +75,7 @@ void BgHakaMegane_Init(Actor* thisx, PlayState* play) { if (this->objBankIndex < 0) { Actor_Kill(thisx); } else { - this->actionFunc = func_8087DB24; + this->actionFunc = BgHakaMegane_WaitForObject; } } @@ -85,7 +85,7 @@ void BgHakaMegane_Destroy(Actor* thisx, PlayState* play) { DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); } -void func_8087DB24(BgHakaMegane* this, PlayState* play) { +void BgHakaMegane_WaitForObject(BgHakaMegane* this, PlayState* play) { CollisionHeader* colHeader; CollisionHeader* collision; @@ -94,7 +94,7 @@ void func_8087DB24(BgHakaMegane* this, PlayState* play) { this->dyna.actor.draw = BgHakaMegane_Draw; Actor_SetObjectDependency(play, &this->dyna.actor); if (play->roomCtx.curRoom.lensMode != LENS_MODE_HIDE_ACTORS) { - this->actionFunc = func_8087DBF0; + this->actionFunc = BgHakaMegane_UpdateState; collision = sCollisionHeaders[this->dyna.actor.params]; if (collision != NULL) { CollisionHeader_GetVirtual(collision, &colHeader); @@ -106,7 +106,7 @@ void func_8087DB24(BgHakaMegane* this, PlayState* play) { } } -void func_8087DBF0(BgHakaMegane* this, PlayState* play) { +void BgHakaMegane_UpdateState(BgHakaMegane* this, PlayState* play) { Actor* thisx = &this->dyna.actor; if (play->actorCtx.lensActive) { diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.c b/soh/src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.c index 49b6e5f7c0..348c604f8c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.c @@ -14,14 +14,14 @@ void BgHakaMeganeBG_Destroy(Actor* thisx, PlayState* play); void BgHakaMeganeBG_Update(Actor* thisx, PlayState* play); void BgHakaMeganeBG_Draw(Actor* thisx, PlayState* play); -void func_8087DFF8(BgHakaMeganeBG* this, PlayState* play); -void func_8087E040(BgHakaMeganeBG* this, PlayState* play); -void func_8087E10C(BgHakaMeganeBG* this, PlayState* play); -void func_8087E1E0(BgHakaMeganeBG* this, PlayState* play); -void func_8087E258(BgHakaMeganeBG* this, PlayState* play); -void func_8087E288(BgHakaMeganeBG* this, PlayState* play); -void func_8087E2D8(BgHakaMeganeBG* this, PlayState* play); -void func_8087E34C(BgHakaMeganeBG* this, PlayState* play); +void BgHakaMeganeBG_HiddenMovingPlatform_Idle(BgHakaMeganeBG* this, PlayState* play); +void BgHakaMeganeBG_HiddenMovingPlatform_Move(BgHakaMeganeBG* this, PlayState* play); +void BgHakaMeganeBG_ElevatorPlatform_Drop(BgHakaMeganeBG* this, PlayState* play); +void BgHakaMeganeBG_ElevatorPlatform_Raise(BgHakaMeganeBG* this, PlayState* play); +void BgHakaMeganeBG_RotatingPlatform_Spin(BgHakaMeganeBG* this, PlayState* play); +void BgHakaMeganeBG_Gate_WaitForSwitchFlag(BgHakaMeganeBG* this, PlayState* play); +void BgHakaMeganeBG_Gate_Open(BgHakaMeganeBG* this, PlayState* play); +void BgHakaMeganeBG_DoNothing(BgHakaMeganeBG* this, PlayState* play); const ActorInit Bg_Haka_MeganeBG_InitVars = { ACTOR_BG_HAKA_MEGANEBG, @@ -60,37 +60,37 @@ void BgHakaMeganeBG_Init(Actor* thisx, PlayState* play) { CollisionHeader* colHeader = NULL; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - this->unk_168 = (thisx->params >> 8) & 0xFF; + this->switchFlag = (thisx->params >> 8) & 0xFF; thisx->params &= 0xFF; if (thisx->params == 2) { DynaPolyActor_Init(&this->dyna, DPM_UNK3); thisx->flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED; CollisionHeader_GetVirtual(&object_haka_objects_Col_005334, &colHeader); - this->actionFunc = func_8087E258; + this->actionFunc = BgHakaMeganeBG_RotatingPlatform_Spin; } else { DynaPolyActor_Init(&this->dyna, DPM_PLAYER); if (thisx->params == 0) { CollisionHeader_GetVirtual(&object_haka_objects_Col_009168, &colHeader); thisx->flags |= ACTOR_FLAG_REACT_TO_LENS; - this->unk_16A = 20; - this->actionFunc = func_8087DFF8; + this->timer = 20; + this->actionFunc = BgHakaMeganeBG_HiddenMovingPlatform_Idle; } else if (thisx->params == 3) { CollisionHeader_GetVirtual(&object_haka_objects_Col_000118, &colHeader); thisx->home.pos.y += 100.0f; - if (Flags_GetSwitch(play, this->unk_168)) { - this->actionFunc = func_8087E34C; + if (Flags_GetSwitch(play, this->switchFlag)) { + this->actionFunc = BgHakaMeganeBG_DoNothing; thisx->world.pos.y = thisx->home.pos.y; } else { thisx->flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED; - this->actionFunc = func_8087E288; + this->actionFunc = BgHakaMeganeBG_Gate_WaitForSwitchFlag; } } else { CollisionHeader_GetVirtual(&object_haka_objects_Col_00A7F4, &colHeader); - this->unk_16A = 80; - this->actionFunc = func_8087E10C; + this->timer = 80; + this->actionFunc = BgHakaMeganeBG_ElevatorPlatform_Drop; thisx->uncullZoneScale = 3000.0f; thisx->uncullZoneDownward = 3000.0f; } @@ -105,26 +105,26 @@ void BgHakaMeganeBG_Destroy(Actor* thisx, PlayState* play) { DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); } -void func_8087DFF8(BgHakaMeganeBG* this, PlayState* play) { - if (this->unk_16A != 0) { - this->unk_16A--; +void BgHakaMeganeBG_HiddenMovingPlatform_Idle(BgHakaMeganeBG* this, PlayState* play) { + if (this->timer != 0) { + this->timer--; } - if (this->unk_16A == 0) { - this->unk_16A = 40; + if (this->timer == 0) { + this->timer = 40; this->dyna.actor.world.rot.y += 0x8000; - this->actionFunc = func_8087E040; + this->actionFunc = BgHakaMeganeBG_HiddenMovingPlatform_Move; } } -void func_8087E040(BgHakaMeganeBG* this, PlayState* play) { +void BgHakaMeganeBG_HiddenMovingPlatform_Move(BgHakaMeganeBG* this, PlayState* play) { f32 xSub; - if (this->unk_16A != 0) { - this->unk_16A--; + if (this->timer != 0) { + this->timer--; } - xSub = (sinf(((this->unk_16A * 0.025f) + 0.5f) * M_PI) + 1.0f) * 160.0f; + xSub = (sinf(((this->timer * 0.025f) + 0.5f) * M_PI) + 1.0f) * 160.0f; if (this->dyna.actor.world.rot.y != this->dyna.actor.shape.rot.y) { xSub = 320.0f - xSub; @@ -132,13 +132,13 @@ void func_8087E040(BgHakaMeganeBG* this, PlayState* play) { this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x - xSub; - if (this->unk_16A == 0) { - this->unk_16A = 20; - this->actionFunc = func_8087DFF8; + if (this->timer == 0) { + this->timer = 20; + this->actionFunc = BgHakaMeganeBG_HiddenMovingPlatform_Idle; } } -void func_8087E10C(BgHakaMeganeBG* this, PlayState* play) { +void BgHakaMeganeBG_ElevatorPlatform_Drop(BgHakaMeganeBG* this, PlayState* play) { this->dyna.actor.velocity.y += 1.0f; if (this->dyna.actor.velocity.y > 20.0f) { @@ -147,8 +147,8 @@ void func_8087E10C(BgHakaMeganeBG* this, PlayState* play) { this->dyna.actor.velocity.y = this->dyna.actor.velocity.y; } - if (this->unk_16A != 0) { - this->unk_16A--; + if (this->timer != 0) { + this->timer--; } if (!Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y - 640.0f, @@ -156,51 +156,51 @@ void func_8087E10C(BgHakaMeganeBG* this, PlayState* play) { func_8002F974(&this->dyna.actor, NA_SE_EV_CHINETRAP_DOWN - SFX_FLAG); } - if (this->unk_16A == 0) { - this->unk_16A = 120; - this->actionFunc = func_8087E1E0; + if (this->timer == 0) { + this->timer = 120; + this->actionFunc = BgHakaMeganeBG_ElevatorPlatform_Raise; this->dyna.actor.velocity.y = 0.0f; } } -void func_8087E1E0(BgHakaMeganeBG* this, PlayState* play) { +void BgHakaMeganeBG_ElevatorPlatform_Raise(BgHakaMeganeBG* this, PlayState* play) { Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 16.0f / 3.0f); func_8002F974(&this->dyna.actor, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG); - if (this->unk_16A != 0) { - this->unk_16A--; + if (this->timer != 0) { + this->timer--; } - if (this->unk_16A == 0) { - this->unk_16A = 80; - this->actionFunc = func_8087E10C; + if (this->timer == 0) { + this->timer = 80; + this->actionFunc = BgHakaMeganeBG_ElevatorPlatform_Drop; } } -void func_8087E258(BgHakaMeganeBG* this, PlayState* play) { +void BgHakaMeganeBG_RotatingPlatform_Spin(BgHakaMeganeBG* this, PlayState* play) { this->dyna.actor.shape.rot.y += 0x180; func_8002F974(&this->dyna.actor, NA_SE_EV_ELEVATOR_MOVE - SFX_FLAG); } -void func_8087E288(BgHakaMeganeBG* this, PlayState* play) { - if (Flags_GetSwitch(play, this->unk_168)) { +void BgHakaMeganeBG_Gate_WaitForSwitchFlag(BgHakaMeganeBG* this, PlayState* play) { + if (Flags_GetSwitch(play, this->switchFlag)) { OnePointCutscene_Attention(play, &this->dyna.actor); - this->actionFunc = func_8087E2D8; + this->actionFunc = BgHakaMeganeBG_Gate_Open; } } -void func_8087E2D8(BgHakaMeganeBG* this, PlayState* play) { +void BgHakaMeganeBG_Gate_Open(BgHakaMeganeBG* this, PlayState* play) { Math_StepToF(&this->dyna.actor.speedXZ, 30.0f, 2.0f); if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, this->dyna.actor.speedXZ)) { Actor_SetFocus(&this->dyna.actor, 50.0f); - this->actionFunc = func_8087E34C; + this->actionFunc = BgHakaMeganeBG_DoNothing; } else { func_8002F974(&this->dyna.actor, NA_SE_EV_METALDOOR_OPEN); } } -void func_8087E34C(BgHakaMeganeBG* this, PlayState* play) { +void BgHakaMeganeBG_DoNothing(BgHakaMeganeBG* this, PlayState* play) { } void BgHakaMeganeBG_Update(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.h b/soh/src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.h index 999926a088..223eec565e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.h +++ b/soh/src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.h @@ -11,8 +11,8 @@ typedef void (*BgHakaMeganeBGActionFunc)(struct BgHakaMeganeBG*, PlayState*); typedef struct BgHakaMeganeBG { /* 0x0000 */ DynaPolyActor dyna; /* 0x0164 */ BgHakaMeganeBGActionFunc actionFunc; - /* 0x0168 */ u8 unk_168; - /* 0x016A */ s16 unk_16A; + /* 0x0168 */ u8 switchFlag; + /* 0x016A */ s16 timer; } BgHakaMeganeBG; // size = 0x016C #endif diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c b/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c index 2563a848a3..5cbf881b05 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c @@ -15,18 +15,18 @@ void BgHakaTrap_Update(Actor* thisx, PlayState* play); void BgHakaTrap_Draw(Actor* thisx, PlayState* play); void BgHakaTrap_Reset(void); -void func_8087FFC0(BgHakaTrap* this, PlayState* play); -void func_808801B8(BgHakaTrap* this, PlayState* play); -void func_808802D8(BgHakaTrap* this, PlayState* play); -void func_80880484(BgHakaTrap* this, PlayState* play); -void func_808805C0(BgHakaTrap* this, PlayState* play); -void func_808806BC(BgHakaTrap* this, PlayState* play); -void func_808808F4(BgHakaTrap* this, PlayState* play); -void func_808809B0(BgHakaTrap* this, PlayState* play); -void func_808809E4(BgHakaTrap* this, PlayState* play, s16 arg2); -void func_80880AE8(BgHakaTrap* this, PlayState* play); -void func_80880C0C(BgHakaTrap* this, PlayState* play); -void func_80880D68(BgHakaTrap* this); +void BgHakaTrap_UpdateBodyColliderPos(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_SpikedWall_CloseIn(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_SpikedWall_Burn(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_Guillotine_Fall(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_Guillotine_Lift(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_SpikedCrusher_Fall(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_SpikedCrusher_Lift(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_FanBlade_Idle(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_FanBlade_UpdateFanRotation(BgHakaTrap* this, PlayState* play, s16 arg2); +void BgHakaTrap_FireBarrier_Idle(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_FireBarrier_UpdateLayout(BgHakaTrap* this, PlayState* play); +void BgHakaTrap_GetSwitchFlag(BgHakaTrap* this); UNK_TYPE D_80880F30 = 0; @@ -130,7 +130,7 @@ void BgHakaTrap_Init(Actor* thisx, PlayState* play) { this->unk_16A = 1; } - this->actionFunc = func_80880484; + this->actionFunc = BgHakaTrap_Guillotine_Fall; } else { DynaPolyActor_Init(&this->dyna, DPM_PLAYER); thisx->flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED; @@ -140,11 +140,11 @@ void BgHakaTrap_Init(Actor* thisx, PlayState* play) { this->timer = 30; if (D_80881014 != 0) { - this->actionFunc = func_808808F4; + this->actionFunc = BgHakaTrap_SpikedCrusher_Lift; D_80881014 = 0; } else { D_80881014 = 1; - this->actionFunc = func_808806BC; + this->actionFunc = BgHakaTrap_SpikedCrusher_Fall; thisx->velocity.y = 0.5f; } @@ -171,14 +171,14 @@ void BgHakaTrap_Init(Actor* thisx, PlayState* play) { this->colliderCylinder.info.toucherFlags = this->colliderCylinder.info.toucherFlags; this->colliderCylinder.info.toucherFlags |= TOUCH_SFX_WOOD; - this->actionFunc = func_808801B8; + this->actionFunc = BgHakaTrap_SpikedWall_CloseIn; } this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, thisx, colHeader); } } else { this->timer = 40; - this->actionFunc = func_808809B0; + this->actionFunc = BgHakaTrap_FanBlade_Idle; thisx->uncullZoneScale = 500.0f; } @@ -200,10 +200,10 @@ void BgHakaTrap_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->colliderCylinder); } - Audio_StopSfxByPos(&this->unk_16C); + Audio_StopSfxByPos(&this->chainLiftSfxPos); } -void func_8087FFC0(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_UpdateBodyColliderPos(BgHakaTrap* this, PlayState* play) { f32 cosine; Vec3f sp28; f32 sine; @@ -229,7 +229,7 @@ void func_8087FFC0(BgHakaTrap* this, PlayState* play) { } static UNK_TYPE D_80881018 = 0; -void func_808801B8(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_SpikedWall_CloseIn(BgHakaTrap* this, PlayState* play) { Player* player = GET_PLAYER(play); if ((D_80880F30 == 0) && (!Player_InCsMode(play))) { @@ -242,19 +242,19 @@ void func_808801B8(BgHakaTrap* this, PlayState* play) { } } - func_8087FFC0(this, play); + BgHakaTrap_UpdateBodyColliderPos(this, play); if (this->colliderSpikes.base.acFlags & AC_HIT) { this->timer = 20; D_80880F30 = 1; - this->actionFunc = func_808802D8; + this->actionFunc = BgHakaTrap_SpikedWall_Burn; } else if (D_80881018 == 3) { D_80881018 = 4; player->actor.bgCheckFlags |= 0x100; } } -void func_808802D8(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_SpikedWall_Burn(BgHakaTrap* this, PlayState* play) { static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; Vec3f vector; f32 xScale; @@ -284,7 +284,7 @@ void func_808802D8(BgHakaTrap* this, PlayState* play) { } } -void func_80880484(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_Guillotine_Fall(BgHakaTrap* this, PlayState* play) { s32 sp24; s32 timer; @@ -310,17 +310,17 @@ void func_80880484(BgHakaTrap* this, PlayState* play) { this->dyna.actor.velocity.y = 0.0f; this->timer = (this->unk_16A) ? 10 : 40; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GUILLOTINE_UP); - this->actionFunc = func_808805C0; + this->actionFunc = BgHakaTrap_Guillotine_Lift; } - func_8087FFC0(this, play); + BgHakaTrap_UpdateBodyColliderPos(this, play); if (sp24 == 0) { CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderCylinder.base); } } -void func_808805C0(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_Guillotine_Lift(BgHakaTrap* this, PlayState* play) { if (this->timer != 0) { this->timer--; } @@ -343,13 +343,13 @@ void func_808805C0(BgHakaTrap* this, PlayState* play) { this->timer = 20; this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; this->dyna.actor.velocity.y = 0.1f; - this->actionFunc = func_80880484; + this->actionFunc = BgHakaTrap_Guillotine_Fall; } - func_8087FFC0(this, play); + BgHakaTrap_UpdateBodyColliderPos(this, play); } -void func_808806BC(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_SpikedCrusher_Fall(BgHakaTrap* this, PlayState* play) { Vec3f vector; f32 tempf20; f32 temp; @@ -396,40 +396,41 @@ void func_808806BC(BgHakaTrap* this, PlayState* play) { this->unk_16A = (s16)this->dyna.actor.world.pos.y + 50.0f; this->unk_16A = CLAMP_MAX(this->unk_16A, this->dyna.actor.home.pos.y); - this->actionFunc = func_808808F4; + this->actionFunc = BgHakaTrap_SpikedCrusher_Lift; } } -void func_808808F4(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_SpikedCrusher_Lift(BgHakaTrap* this, PlayState* play) { if (this->timer != 0) { this->timer--; } if (this->timer > 20) { - this->unk_169 = Math_StepToF(&this->dyna.actor.world.pos.y, this->unk_16A, 15.0f); + this->isSpikedCrusherStationary = Math_StepToF(&this->dyna.actor.world.pos.y, this->unk_16A, 15.0f); } else { - this->unk_169 = Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 20.0f); + this->isSpikedCrusherStationary = + Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 20.0f); } if (this->timer == 0) { this->timer = 30; this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; this->dyna.actor.velocity.y = 0.5f; - this->actionFunc = func_808806BC; + this->actionFunc = BgHakaTrap_SpikedCrusher_Fall; } } -void func_808809B0(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_FanBlade_Idle(BgHakaTrap* this, PlayState* play) { if (this->timer != 0) { this->timer -= 1; } if (this->timer == 0) { - this->actionFunc = func_80880AE8; + this->actionFunc = BgHakaTrap_FireBarrier_Idle; } } -void func_808809E4(BgHakaTrap* this, PlayState* play, s16 arg2) { +void BgHakaTrap_FanBlade_UpdateFanRotation(BgHakaTrap* this, PlayState* play, s16 arg2) { Player* player = GET_PLAYER(play); Vec3f sp18; @@ -442,16 +443,16 @@ void func_808809E4(BgHakaTrap* this, PlayState* play, s16 arg2) { } } -void func_80880AE8(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_FireBarrier_Idle(BgHakaTrap* this, PlayState* play) { if (this->timer != 0) { if (Math_ScaledStepToS(&this->dyna.actor.world.rot.z, 0, this->dyna.actor.world.rot.z * 0.03f + 5.0f)) { this->timer = 40; - this->actionFunc = func_808809B0; + this->actionFunc = BgHakaTrap_FanBlade_Idle; } } else { if (Math_ScaledStepToS(&this->dyna.actor.world.rot.z, 0x3A00, this->dyna.actor.world.rot.z * 0.03f + 5.0f)) { this->timer = 100; - this->actionFunc = func_80880C0C; + this->actionFunc = BgHakaTrap_FireBarrier_UpdateLayout; } } @@ -460,10 +461,10 @@ void func_80880AE8(BgHakaTrap* this, PlayState* play) { func_8002F974(&this->dyna.actor, NA_SE_EV_WIND_TRAP - SFX_FLAG); } - func_808809E4(this, play, this->dyna.actor.world.rot.z); + BgHakaTrap_FanBlade_UpdateFanRotation(this, play, this->dyna.actor.world.rot.z); } -void func_80880C0C(BgHakaTrap* this, PlayState* play) { +void BgHakaTrap_FireBarrier_UpdateLayout(BgHakaTrap* this, PlayState* play) { if (this->timer != 0) { this->timer--; } @@ -472,11 +473,11 @@ void func_80880C0C(BgHakaTrap* this, PlayState* play) { if (this->timer == 0) { this->timer = 1; - this->actionFunc = func_80880AE8; + this->actionFunc = BgHakaTrap_FireBarrier_Idle; } this->dyna.actor.shape.rot.z += this->dyna.actor.world.rot.z; - func_808809E4(this, play, this->dyna.actor.world.rot.z); + BgHakaTrap_FanBlade_UpdateFanRotation(this, play, this->dyna.actor.world.rot.z); } void BgHakaTrap_Update(Actor* thisx, PlayState* play) { @@ -492,7 +493,7 @@ void BgHakaTrap_Update(Actor* thisx, PlayState* play) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base); CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder.base); } else { - if (this->actionFunc == func_808801B8) { + if (this->actionFunc == BgHakaTrap_SpikedWall_CloseIn) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSpikes.base); } @@ -501,7 +502,7 @@ void BgHakaTrap_Update(Actor* thisx, PlayState* play) { } } -void func_80880D68(BgHakaTrap* this) { +void BgHakaTrap_GetSwitchFlag(BgHakaTrap* this) { Vec3f vec3; Vec3f vec2; Vec3f vec1; @@ -525,27 +526,27 @@ void BgHakaTrap_Draw(Actor* thisx, PlayState* play) { s32 pad; Vec3f sp2C; - if (this->actionFunc == func_808802D8) { + if (this->actionFunc == BgHakaTrap_SpikedWall_Burn) { func_80026230(play, &D_8088103C, this->timer + 20, 0x28); } Gfx_DrawDListOpa(play, sDLists[this->dyna.actor.params]); - if (this->actionFunc == func_808801B8) { - func_80880D68(this); + if (this->actionFunc == BgHakaTrap_SpikedWall_CloseIn) { + BgHakaTrap_GetSwitchFlag(this); } - if (this->actionFunc == func_808802D8) { + if (this->actionFunc == BgHakaTrap_SpikedWall_Burn) { func_80026608(play); } - if ((this->actionFunc == func_808808F4) && !this->unk_169) { + if ((this->actionFunc == BgHakaTrap_SpikedCrusher_Lift) && !this->isSpikedCrusherStationary) { sp2C.x = this->dyna.actor.world.pos.x; sp2C.z = this->dyna.actor.world.pos.z; sp2C.y = this->dyna.actor.world.pos.y + 110.0f; - SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &sp2C, &this->unk_16C); - Sfx_PlaySfxAtPos(&this->unk_16C, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG); + SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &sp2C, &this->chainLiftSfxPos); + Sfx_PlaySfxAtPos(&this->chainLiftSfxPos, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.h b/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.h index 97371df4af..24681d78d0 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.h +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.h @@ -21,9 +21,9 @@ typedef struct BgHakaTrap { /* 0x0000 */ DynaPolyActor dyna; /* 0x0164 */ BgHakaTrapActionFunc actionFunc; /* 0x0168 */ u8 timer; - /* 0x0169 */ u8 unk_169; + /* 0x0169 */ u8 isSpikedCrusherStationary; /* 0x016A */ s16 unk_16A; // used as boolean for HAKA_TRAP_GUILLOTINE_SLOW/FAST, s16 for HAKA_TRAP_SPIKED_BOX - /* 0x016C */ Vec3f unk_16C; + /* 0x016C */ Vec3f chainLiftSfxPos; /* 0x0178 */ ColliderCylinder colliderCylinder; /* 0x01C4 */ ColliderTris colliderSpikes; /* 0x01E4 */ ColliderTrisElement colliderSpikesItem[2]; diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c b/soh/src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c index c2b2c60d9d..bd101cc7d1 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c @@ -23,13 +23,13 @@ void BgHakaZou_Update(Actor* thisx, PlayState* play); void BgHakaZou_Draw(Actor* thisx, PlayState* play); void BgHakaZou_Wait(BgHakaZou* this, PlayState* play); -void func_80882BDC(BgHakaZou* this, PlayState* play); -void func_80883000(BgHakaZou* this, PlayState* play); -void func_80883104(BgHakaZou* this, PlayState* play); -void func_80883144(BgHakaZou* this, PlayState* play); -void func_80883254(BgHakaZou* this, PlayState* play); -void func_80883328(BgHakaZou* this, PlayState* play); -void func_808834D8(BgHakaZou* this, PlayState* play); +void BgHakaZou_CrumbleSkullWall(BgHakaZou* this, PlayState* play); +void BgHakaZou_WaitForHit(BgHakaZou* this, PlayState* play); +void BgHakaZou_IdleKill(BgHakaZou* this, PlayState* play); +void BgHakaZou_BirdStatueAnim_Explode(BgHakaZou* this, PlayState* play); +void BgHakaZou_BirdStatueAnim_Shear(BgHakaZou* this, PlayState* play); +void BgHakaZou_BirdStatueAnim_Topple(BgHakaZou* this, PlayState* play); +void BgHakaZou_BirdStatueAnim_Settle(BgHakaZou* this, PlayState* play); void BgHakaZou_DoNothing(BgHakaZou* this, PlayState* play); static ColliderCylinderInit sCylinderInit = { @@ -164,7 +164,7 @@ void BgHakaZou_Wait(BgHakaZou* this, PlayState* play) { this->dyna.actor.draw = BgHakaZou_Draw; if (this->dyna.actor.params == STA_UNKNOWN) { - this->actionFunc = func_80882BDC; + this->actionFunc = BgHakaZou_CrumbleSkullWall; } else { Actor_SetObjectDependency(play, &this->dyna.actor); @@ -192,12 +192,12 @@ void BgHakaZou_Wait(BgHakaZou* this, PlayState* play) { if ((this->dyna.actor.params == STA_GIANT_BIRD_STATUE) && Flags_GetSwitch(play, this->switchFlag)) { this->actionFunc = BgHakaZou_DoNothing; } else { - this->actionFunc = func_80883000; + this->actionFunc = BgHakaZou_WaitForHit; } } } } -void func_80882BDC(BgHakaZou* this, PlayState* play) { +void BgHakaZou_CrumbleSkullWall(BgHakaZou* this, PlayState* play) { if (this->timer != 0) { this->timer--; } @@ -221,7 +221,7 @@ void func_80882BDC(BgHakaZou* this, PlayState* play) { } } -void func_80882CC4(BgHakaZou* this, PlayState* play) { +void BgHakaZou_SpawnSkullWallRubble(BgHakaZou* this, PlayState* play) { s32 i; s32 j; Vec3f actorSpawnPos; @@ -245,7 +245,7 @@ void func_80882CC4(BgHakaZou* this, PlayState* play) { } } -void func_80882E54(BgHakaZou* this, PlayState* play) { +void BgHakaZou_SpawnRubbleParticles(BgHakaZou* this, PlayState* play) { Vec3f fragmentPos; s32 i; s32 j; @@ -267,32 +267,32 @@ void func_80882E54(BgHakaZou* this, PlayState* play) { } } -void func_80883000(BgHakaZou* this, PlayState* play) { +void BgHakaZou_WaitForHit(BgHakaZou* this, PlayState* play) { if (this->collider.base.acFlags & AC_HIT) { Flags_SetSwitch(play, this->switchFlag); if (this->dyna.actor.params == STA_GIANT_BIRD_STATUE) { this->timer = 20; - this->actionFunc = func_80883144; + this->actionFunc = BgHakaZou_BirdStatueAnim_Explode; OnePointCutscene_Init(play, 3400, 999, &this->dyna.actor, MAIN_CAM); } else if (this->dyna.actor.params == 2) { - func_80882E54(this, play); + BgHakaZou_SpawnRubbleParticles(this, play); this->dyna.actor.draw = NULL; this->timer = 1; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_EXPLOSION); - this->actionFunc = func_80883104; + this->actionFunc = BgHakaZou_IdleKill; } else { - func_80882CC4(this, play); + BgHakaZou_SpawnSkullWallRubble(this, play); this->timer = 1; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WALL_BROKEN); - this->actionFunc = func_80883104; + this->actionFunc = BgHakaZou_IdleKill; } } else { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); } } -void func_80883104(BgHakaZou* this, PlayState* play) { +void BgHakaZou_IdleKill(BgHakaZou* this, PlayState* play) { if (this->timer != 0) { this->timer--; } @@ -302,7 +302,7 @@ void func_80883104(BgHakaZou* this, PlayState* play) { } } -void func_80883144(BgHakaZou* this, PlayState* play) { +void BgHakaZou_BirdStatueAnim_Explode(BgHakaZou* this, PlayState* play) { Vec3f explosionPos; if (this->timer != 0) { @@ -320,11 +320,11 @@ void func_80883144(BgHakaZou* this, PlayState* play) { if (this->timer == 0) { this->timer = 20; - this->actionFunc = func_80883254; + this->actionFunc = BgHakaZou_BirdStatueAnim_Shear; } } -void func_80883254(BgHakaZou* this, PlayState* play) { +void BgHakaZou_BirdStatueAnim_Shear(BgHakaZou* this, PlayState* play) { f32 moveDist = (Rand_ZeroOne() * 0.5f) + 0.5f; Math_StepToF(&this->dyna.actor.world.pos.z, this->dyna.actor.home.pos.z - 80.0f, 2.0f * moveDist); @@ -337,14 +337,14 @@ void func_80883254(BgHakaZou* this, PlayState* play) { if (this->timer == 0) { this->timer = 60; this->dyna.actor.world.rot.x = 8; - this->actionFunc = func_80883328; + this->actionFunc = BgHakaZou_BirdStatueAnim_Topple; } } else { func_808828F4(this, play); } } -void func_80883328(BgHakaZou* this, PlayState* play) { +void BgHakaZou_BirdStatueAnim_Topple(BgHakaZou* this, PlayState* play) { Vec3f effectPos; s32 i; s32 j; @@ -368,11 +368,11 @@ void func_80883328(BgHakaZou* this, PlayState* play) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); this->timer = 25; - this->actionFunc = func_808834D8; + this->actionFunc = BgHakaZou_BirdStatueAnim_Settle; } } -void func_808834D8(BgHakaZou* this, PlayState* play) { +void BgHakaZou_BirdStatueAnim_Settle(BgHakaZou* this, PlayState* play) { f32 moveDist; if (this->timer != 0) { diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c index 40e6b5e63f..160f60ebe0 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c @@ -14,9 +14,9 @@ void BgHidanFslift_Destroy(Actor* thisx, PlayState* play); void BgHidanFslift_Update(Actor* thisx, PlayState* play); void BgHidanFslift_Draw(Actor* thisx, PlayState* play); -void func_80886FCC(BgHidanFslift* this, PlayState* play); -void func_8088706C(BgHidanFslift* this, PlayState* play); -void func_808870D8(BgHidanFslift* this, PlayState* play); +void BgHidanFslift_Idle(BgHidanFslift* this, PlayState* play); +void BgHidanFslift_Descend(BgHidanFslift* this, PlayState* play); +void BgHidanFslift_Ascend(BgHidanFslift* this, PlayState* play); const ActorInit Bg_Hidan_Fslift_InitVars = { ACTOR_BG_HIDAN_FSLIFT, @@ -54,10 +54,10 @@ void BgHidanFslift_Init(Actor* thisx, PlayState* play) { Actor_Kill(&this->dyna.actor); return; } - this->actionFunc = func_80886FCC; + this->actionFunc = BgHidanFslift_Idle; } -void func_80886F24(BgHidanFslift* this) { +void BgHidanFslift_SetHookshotTargetPos(BgHidanFslift* this) { if (this->dyna.actor.child != NULL && this->dyna.actor.child->update != NULL) { this->dyna.actor.child->world.pos.x = this->dyna.actor.world.pos.x; this->dyna.actor.child->world.pos.y = this->dyna.actor.world.pos.y + 40.0f; @@ -73,12 +73,12 @@ void BgHidanFslift_Destroy(Actor* thisx, PlayState* play) { DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); } -void func_80886FB4(BgHidanFslift* this) { +void BgHidanFslift_SetupIdle(BgHidanFslift* this) { this->timer = 40; - this->actionFunc = func_80886FCC; + this->actionFunc = BgHidanFslift_Idle; } -void func_80886FCC(BgHidanFslift* this, PlayState* play) { +void BgHidanFslift_Idle(BgHidanFslift* this, PlayState* play) { s32 heightBool; if (this->timer) { @@ -91,35 +91,35 @@ void func_80886FCC(BgHidanFslift* this, PlayState* play) { heightBool = true; } if (DynaPolyActor_IsPlayerAbove(&this->dyna) && (heightBool)) { - this->actionFunc = func_808870D8; + this->actionFunc = BgHidanFslift_Ascend; } else if (!heightBool) { - this->actionFunc = func_8088706C; + this->actionFunc = BgHidanFslift_Descend; } } } -void func_8088706C(BgHidanFslift* this, PlayState* play) { +void BgHidanFslift_Descend(BgHidanFslift* this, PlayState* play) { if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 4.0f)) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); - func_80886FB4(this); + BgHidanFslift_SetupIdle(this); } else { func_8002F974(&this->dyna.actor, NA_SE_EV_ELEVATOR_MOVE3 - SFX_FLAG); } - func_80886F24(this); + BgHidanFslift_SetHookshotTargetPos(this); } -void func_808870D8(BgHidanFslift* this, PlayState* play) { +void BgHidanFslift_Ascend(BgHidanFslift* this, PlayState* play) { if (DynaPolyActor_IsPlayerAbove(&this->dyna)) { if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 790.0f, 4.0f)) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); - func_80886FB4(this); + BgHidanFslift_SetupIdle(this); } else { func_8002F974(&this->dyna.actor, NA_SE_EV_ELEVATOR_MOVE3 - SFX_FLAG); } } else { - func_80886FB4(this); + BgHidanFslift_SetupIdle(this); } - func_80886F24(this); + BgHidanFslift_SetHookshotTargetPos(this); } void BgHidanFslift_Update(Actor* thisx, PlayState* play) { @@ -127,15 +127,15 @@ void BgHidanFslift_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { - if (this->unk_16A == 0) { - this->unk_16A = 3; + if (this->cameraSetting == 0) { + this->cameraSetting = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { - if (this->unk_16A != 0) { + if (this->cameraSetting != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } - this->unk_16A = 0; + this->cameraSetting = 0; } } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.h b/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.h index caaaacf1d6..618313dccf 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.h +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.h @@ -12,7 +12,7 @@ typedef struct BgHidanFslift { /* 0x0000 */ DynaPolyActor dyna; /* 0x0164 */ BgHidanFsliftActionFunc actionFunc; /* 0x0168 */ s16 timer; - /* 0x016A */ s16 unk_16A; + /* 0x016A */ s16 cameraSetting; } BgHidanFslift; // size = 0x016C #endif diff --git a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c index eb267edcb6..0ce95602a2 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c +++ b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c @@ -1,6 +1,6 @@ #include "z_bg_ice_shelter.h" #include "objects/object_ice_objects/object_ice_objects.h" -#include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -9,14 +9,11 @@ void BgIceShelter_Destroy(Actor* thisx, PlayState* play); void BgIceShelter_Update(Actor* thisx, PlayState* play); void BgIceShelter_Draw(Actor* thisx, PlayState* play); -void func_80891064(BgIceShelter* this); -void func_808911BC(BgIceShelter* this); +void BgIceShelter_SetupIdle(BgIceShelter* this); +void BgIceShelter_SetupMelt(BgIceShelter* this); -void func_8089107C(BgIceShelter* this, PlayState* play); -void func_808911D4(BgIceShelter* this, PlayState* play); - -// For "Blue Fire Arrows" enhancement -void MeltOnIceArrowHit(BgIceShelter* this, ColliderCylinder cylinder, s16 type, PlayState* play); +void BgIceShelter_Idle(BgIceShelter* this, PlayState* play); +void BgIceShelter_Melt(BgIceShelter* this, PlayState* play); const ActorInit Bg_Ice_Shelter_InitVars = { ACTOR_BG_ICE_SHELTER, @@ -31,10 +28,10 @@ const ActorInit Bg_Ice_Shelter_InitVars = { NULL, }; -static f32 sScales[] = { 0.1f, 0.06f, 0.1f, 0.1f, 0.25f }; +static f32 sRedIceScales[] = { 0.1f, 0.06f, 0.1f, 0.1f, 0.25f }; -static Color_RGBA8 sDustPrimColor = { 250, 250, 250, 255 }; -static Color_RGBA8 sDustEnvColor = { 180, 180, 180, 255 }; +static Color_RGBA8 sSteamPrimColor = { 250, 250, 250, 255 }; +static Color_RGBA8 sSteamEnvColor = { 180, 180, 180, 255 }; static ColliderCylinderInit sCylinder1Init = { { @@ -76,52 +73,24 @@ static ColliderCylinderInit sCylinder2Init = { { 0, 0, 0, { 0, 0, 0 } }, }; -// This cylinder only used for "Blue Fire Arrows" enhancement -static ColliderCylinderInit sIceArrowCylinderInit = { - { - COLTYPE_NONE, - AT_NONE, - AC_ON | AC_TYPE_OTHER | AC_TYPE_PLAYER, - OC1_ON | OC1_TYPE_ALL, - OC2_TYPE_2, - COLSHAPE_CYLINDER, - }, - { - ELEMTYPE_UNK0, - { 0x00000000, 0x00, 0x00 }, - { 0xFFCFFFFF, 0x00, 0x00 }, - TOUCH_NONE, - BUMP_ON, - OCELEM_ON, - }, - { 0, 0, 0, { 0, 0, 0 } }, -}; - -bool blueFireArrowsEnabledOnRedIceLoad = false; - -void func_80890740(BgIceShelter* this, PlayState* play) { +/** + * Initializes either one or both cylinder colliders, depending on the actor's type. + */ +void BgIceShelter_InitColliders(BgIceShelter* this, PlayState* play) { static s16 cylinderRadii[] = { 47, 33, 44, 41, 100 }; static s16 cylinderHeights[] = { 80, 54, 90, 60, 200 }; s32 pad; s32 type = (this->dyna.actor.params >> 8) & 7; - // Initialize this with the red ice, so it can't be affected by toggling while the actor is loaded - blueFireArrowsEnabledOnRedIceLoad = CVarGetInteger(CVAR_ENHANCEMENT("BlueFireArrows"), 0) || - (IS_RANDO && Randomizer_GetSettingValue(RSK_BLUE_FIRE_ARROWS)); - Collider_InitCylinder(play, &this->cylinder1); - // If "Blue Fire Arrows" is enabled, set up a collider on the red ice that responds to them - if (blueFireArrowsEnabledOnRedIceLoad) { - Collider_SetCylinder(play, &this->cylinder1, &this->dyna.actor, &sIceArrowCylinderInit); - } else { - Collider_SetCylinder(play, &this->cylinder1, &this->dyna.actor, &sCylinder1Init); - } + Collider_SetCylinder(play, &this->cylinder1, &this->dyna.actor, &sCylinder1Init); Collider_UpdateCylinder(&this->dyna.actor, &this->cylinder1); this->cylinder1.dim.radius = cylinderRadii[type]; this->cylinder1.dim.height = cylinderHeights[type]; - if (type == 0 || type == 1 || type == 4) { + // The wall and platform types use DynaPoly for collision, so they don't need the second collider + if (type == RED_ICE_LARGE || type == RED_ICE_SMALL || type == RED_ICE_KING_ZORA) { Collider_InitCylinder(play, &this->cylinder2); Collider_SetCylinder(play, &this->cylinder2, &this->dyna.actor, &sCylinder2Init); Collider_UpdateCylinder(&this->dyna.actor, &this->cylinder2); @@ -129,13 +98,13 @@ void func_80890740(BgIceShelter* this, PlayState* play) { this->cylinder2.dim.height = cylinderHeights[type]; } - if (type == 4) { + if (type == RED_ICE_KING_ZORA) { this->cylinder1.dim.pos.z += 30; this->cylinder2.dim.pos.z += 30; } } -void func_80890874(BgIceShelter* this, PlayState* play, CollisionHeader* collision, s32 moveFlag) { +void BgIceShelter_InitDynaPoly(BgIceShelter* this, PlayState* play, CollisionHeader* collision, s32 moveFlag) { s32 pad; CollisionHeader* colHeader = NULL; s32 pad2; @@ -151,7 +120,7 @@ void func_80890874(BgIceShelter* this, PlayState* play, CollisionHeader* collisi } } -void func_808908FC(Vec3f* dest, Vec3f* src, s16 angle) { +void BgIceShelter_RotateY(Vec3f* dest, Vec3f* src, s16 angle) { f32 sin = Math_SinS(angle); f32 cos = Math_CosS(angle); @@ -173,38 +142,42 @@ void BgIceShelter_Init(Actor* thisx, PlayState* play) { Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - if (type == 4) { + if (type == RED_ICE_KING_ZORA) { this->dyna.actor.world.rot.x += 0xBB8; this->dyna.actor.world.pos.y -= 45.0f; this->dyna.actor.shape.rot.x = this->dyna.actor.world.rot.x; this->dyna.actor.world.pos.z -= 38.0f; } - if (type == 4) { + if (type == RED_ICE_KING_ZORA) { Math_Vec3f_Copy(&this->dyna.actor.scale, &kzIceScale); } else { - Actor_SetScale(&this->dyna.actor, sScales[type]); + Actor_SetScale(&this->dyna.actor, sRedIceScales[type]); } + // Only 2 types use DynaPoly switch (type) { - case 2: - func_80890874(this, play, &gRedIcePlatformCol, 0); + case RED_ICE_PLATFORM: + BgIceShelter_InitDynaPoly(this, play, &gRedIcePlatformCol, 0); break; - case 3: - func_80890874(this, play, &gRedIceWallCol, 0); + case RED_ICE_WALL: + BgIceShelter_InitDynaPoly(this, play, &gRedIceWallCol, 0); break; } - func_80890740(this, play); + // All types use at least one collider + BgIceShelter_InitColliders(this, play); this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; - if (!((this->dyna.actor.params >> 6) & 1) && (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F))) { + if (GameInteractor_Should( + VB_RED_ICE_MELTED_FLAG, + !((this->dyna.actor.params >> 6) & 1) && (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)), this)) { Actor_Kill(&this->dyna.actor); return; } - func_80891064(this); + BgIceShelter_SetupIdle(this); osSyncPrintf("(ice shelter)(arg_data 0x%04x)\n", this->dyna.actor.params); } @@ -213,14 +186,14 @@ void BgIceShelter_Destroy(Actor* thisx, PlayState* play) { BgIceShelter* this = (BgIceShelter*)thisx; switch ((this->dyna.actor.params >> 8) & 7) { - case 2: - case 3: + case RED_ICE_PLATFORM: + case RED_ICE_WALL: DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); break; - case 0: - case 1: - case 4: + case RED_ICE_LARGE: + case RED_ICE_SMALL: + case RED_ICE_KING_ZORA: Collider_DestroyCylinder(play, &this->cylinder2); break; } @@ -228,131 +201,153 @@ void BgIceShelter_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->cylinder1); } -static s16 D_80891794[] = { 0x0000, 0x4000, 0x2000, 0x6000, 0x1000, 0x5000, 0x3000, 0x7000 }; -static s16 D_808917A4[] = { 0x0000, 0x003C, 0x0018, 0x0054, 0x0030, 0x000C, 0x0048, 0x0024 }; +/** + * Angles used to spawn steam particles in a circle. + */ +static s16 sSteamCircleAngles[] = { 0x0000, 0x4000, 0x2000, 0x6000, 0x1000, 0x5000, 0x3000, 0x7000 }; -void func_80890B8C(BgIceShelter* this, PlayState* play, f32 chance, f32 scale) { +/** + * Positions used to spawn steam particles in a straight line. + */ +static s16 sSteamLinePositions[] = { 0x0000, 0x003C, 0x0018, 0x0054, 0x0030, 0x000C, 0x0048, 0x0024 }; + +/** + * Spawns steam particle effects in a circle around the ice block. + * + * On each frame the function is called, two particles have a chance to appear, at the same distance and opposite + * sides from the center. + */ +void BgIceShelter_SpawnSteamAround(BgIceShelter* this, PlayState* play, f32 particleSpawningChance, + f32 steamEffectScale) { f32 cos; f32 sin; - f32 xzOffset; + f32 distance; Vec3f* icePos; s16 angle; - s16 frames; + s16 frameCounter; s32 i; s32 pad[2]; - Vec3f dustPos; - Vec3f dustVel; - Vec3f dustAccel; + Vec3f steamPos; + Vec3f steamVel; + Vec3f steamAccel; - frames = (s16)play->state.frames & 7; + frameCounter = (s16)play->state.frames & 7; for (i = 0; i < 2; i++) { - if (chance < Rand_ZeroOne()) { + if (particleSpawningChance < Rand_ZeroOne()) { continue; } - xzOffset = 42.0f * scale; + // The steamEffectScale is used here to make the particles appear at the edges of the red ice. + distance = 42.0f * steamEffectScale; icePos = &this->dyna.actor.world.pos; - angle = D_80891794[frames] + (i * 0x8000); + angle = sSteamCircleAngles[frameCounter] + (i * 0x8000); sin = Math_SinS(angle); cos = Math_CosS(angle); - dustPos.x = (xzOffset * sin) + icePos->x; - dustPos.y = (16.0f * scale) + icePos->y; - dustPos.z = (xzOffset * cos) + icePos->z; + steamPos.x = (distance * sin) + icePos->x; + steamPos.y = (16.0f * steamEffectScale) + icePos->y; + steamPos.z = (distance * cos) + icePos->z; - dustVel.x = ((Rand_ZeroOne() * 3.0f) - 1.0f) * sin; - dustVel.y = 0.0f; - dustVel.z = ((Rand_ZeroOne() * 3.0f) - 1.0f) * cos; + steamVel.x = ((Rand_ZeroOne() * 3.0f) - 1.0f) * sin; + steamVel.y = 0.0f; + steamVel.z = ((Rand_ZeroOne() * 3.0f) - 1.0f) * cos; - dustAccel.x = 0.07f * sin; - dustAccel.y = 0.8f; - dustAccel.z = 0.07f * cos; + steamAccel.x = 0.07f * sin; + steamAccel.y = 0.8f; + steamAccel.z = 0.07f * cos; - func_8002829C(play, &dustPos, &dustVel, &dustAccel, &sDustPrimColor, &sDustEnvColor, 450.0f * scale, - (s16)((Rand_ZeroOne() * 40.0f) + 40.0f) * scale); + func_8002829C(play, &steamPos, &steamVel, &steamAccel, &sSteamPrimColor, &sSteamEnvColor, + 450.0f * steamEffectScale, (s16)((Rand_ZeroOne() * 40.0f) + 40.0f) * steamEffectScale); } } -void func_80890E00(BgIceShelter* this, PlayState* play, f32 chance, f32 arg3) { - static f32 D_808917B4[] = { -1.0f, 1.0f }; +/** + * Spawns steam particle effects in a straight line. Only used for the ice wall type. + * + * On each frame the function is called, two particles have a chance to appear, at the same distance and opposite + * sides from the midpoint. + * + * The last argument is unused because only one red ice type can call this function, so the scale isn't needed. + */ +void BgIceShelter_SpawnSteamAlong(BgIceShelter* this, PlayState* play, f32 particleSpawningChance, f32 unusedArg) { + static f32 signs[] = { -1.0f, 1.0f }; Vec3f* icePos; - s16 frames; + s16 frameCounter; s32 pad[2]; - Vec3f dustPos; - Vec3f dustVel; - Vec3f dustAccel; + Vec3f steamPos; + Vec3f steamVel; + Vec3f steamAccel; Vec3f posOffset; s32 i; - frames = (s16)play->state.frames & 7; + frameCounter = (s16)play->state.frames & 7; for (i = 0; i < 2; i++) { icePos = &this->dyna.actor.world.pos; - if (chance < Rand_ZeroOne()) { + if (particleSpawningChance < Rand_ZeroOne()) { continue; } - posOffset.x = (D_808917A4[frames] + ((Rand_ZeroOne() * 12.0f) - 6.0f)) * D_808917B4[i]; + posOffset.x = (sSteamLinePositions[frameCounter] + ((Rand_ZeroOne() * 12.0f) - 6.0f)) * signs[i]; posOffset.y = 15.0f; posOffset.z = ((84.0f - posOffset.x) * 0.2f) + (Rand_ZeroOne() * 20.0f); - func_808908FC(&dustPos, &posOffset, this->dyna.actor.world.rot.y); - Math_Vec3f_Sum(&dustPos, icePos, &dustPos); + // Convert the position offset from relative to the ice wall to absolute. + BgIceShelter_RotateY(&steamPos, &posOffset, this->dyna.actor.world.rot.y); + Math_Vec3f_Sum(&steamPos, icePos, &steamPos); - dustVel.x = (Rand_ZeroOne() * 3.0f) - 1.5f; - dustVel.y = 0.0f; - dustVel.z = (Rand_ZeroOne() * 3.0f) - 1.5f; + steamVel.x = (Rand_ZeroOne() * 3.0f) - 1.5f; + steamVel.y = 0.0f; + steamVel.z = (Rand_ZeroOne() * 3.0f) - 1.5f; - dustAccel.x = (Rand_ZeroOne() * 0.14f) - 0.07f; - dustAccel.y = 0.8f; - dustAccel.z = (Rand_ZeroOne() * 0.14f) - 0.07f; + steamAccel.x = (Rand_ZeroOne() * 0.14f) - 0.07f; + steamAccel.y = 0.8f; + steamAccel.z = (Rand_ZeroOne() * 0.14f) - 0.07f; - func_8002829C(play, &dustPos, &dustVel, &dustAccel, &sDustPrimColor, &sDustEnvColor, 450, + func_8002829C(play, &steamPos, &steamVel, &steamAccel, &sSteamPrimColor, &sSteamEnvColor, 450, (Rand_ZeroOne() * 40.0f) + 40.0f); } } -void func_80891064(BgIceShelter* this) { - this->actionFunc = func_8089107C; +void BgIceShelter_SetupIdle(BgIceShelter* this) { + this->actionFunc = BgIceShelter_Idle; this->alpha = 255; } -void func_8089107C(BgIceShelter* this, PlayState* play) { +void BgIceShelter_Idle(BgIceShelter* this, PlayState* play) { s32 pad; s16 type = (this->dyna.actor.params >> 8) & 7; - if (type == 4) { + // Freeze King Zora + if (type == RED_ICE_KING_ZORA) { if (this->dyna.actor.parent != NULL) { this->dyna.actor.parent->freezeTimer = 10000; } } - // If we have "Blue Fire Arrows" enabled, check both cylinders for a hit - if (blueFireArrowsEnabledOnRedIceLoad) { - MeltOnIceArrowHit(this, this->cylinder1, type, play); - MeltOnIceArrowHit(this, this->cylinder2, type, play); - } - // Default blue fire check - if (this->cylinder1.base.acFlags & AC_HIT) { + + if (GameInteractor_Should(VB_BG_ICE_SHELTER_HIT, this->cylinder1.base.acFlags & AC_HIT, this)) { this->cylinder1.base.acFlags &= ~AC_HIT; - if ((this->cylinder1.base.ac != NULL) && (this->cylinder1.base.ac->id == ACTOR_EN_ICE_HONO)) { - if (type == 4) { + if (GameInteractor_Should( + VB_BG_ICE_SHELTER_MELT, + (this->cylinder1.base.ac != NULL) && (this->cylinder1.base.ac->id == ACTOR_EN_ICE_HONO), this)) { + if (type == RED_ICE_KING_ZORA) { if (this->dyna.actor.parent != NULL) { this->dyna.actor.parent->freezeTimer = 50; } } - func_808911BC(this); + BgIceShelter_SetupMelt(this); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_ICE_MELT); } } switch (type) { - case 0: - case 1: - case 4: + case RED_ICE_LARGE: + case RED_ICE_SMALL: + case RED_ICE_KING_ZORA: CollisionCheck_SetOC(play, &play->colChkCtx, &this->cylinder1.base); CollisionCheck_SetAC(play, &play->colChkCtx, &this->cylinder2.base); break; @@ -361,54 +356,50 @@ void func_8089107C(BgIceShelter* this, PlayState* play) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->cylinder1.base); } -// For "Blue Fire Arrows" enhancement: If hit by an Ice Arrow, melt the red ice (copied from the default blue fire -// function above). -void MeltOnIceArrowHit(BgIceShelter* this, ColliderCylinder cylinder, s16 type, PlayState* play) { - if (cylinder.base.acFlags & AC_HIT) { - cylinder.base.acFlags &= ~AC_HIT; - if ((cylinder.base.ac != NULL) && (cylinder.base.ac->id == ACTOR_EN_ARROW)) { - if (cylinder.base.ac->child != NULL && cylinder.base.ac->child->id == ACTOR_ARROW_ICE) { - if (type == 4) { - if (this->dyna.actor.parent != NULL) { - this->dyna.actor.parent->freezeTimer = 50; - } - } - func_808911BC(this); - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_ICE_MELT); - } - } - } -} - -void func_808911BC(BgIceShelter* this) { - this->actionFunc = func_808911D4; +void BgIceShelter_SetupMelt(BgIceShelter* this) { + this->actionFunc = BgIceShelter_Melt; this->alpha = 255; } -static f32 D_808917BC[] = { -0.0015f, -0.0009f, -0.0016f, -0.0016f, -0.00375f }; -static f32 D_808917D0[] = { 1.0f, 0.6f, 1.2f, 1.0f, 1.8f }; +/** + * Values added to the ice block's height every frame while it's melting. + */ +static f32 sMeltingRates[] = { -0.0015f, -0.0009f, -0.0016f, -0.0016f, -0.00375f }; -static void (*sEffSpawnFuncs[])(BgIceShelter* this, PlayState* play, f32 chance, f32 scale) = { - func_80890B8C, func_80890B8C, func_80890B8C, func_80890E00, func_80890B8C, +/** + * Values used to scale and position the steam effects so they match the ice block's size. + */ +static f32 sSteamEffectScales[] = { 1.0f, 0.6f, 1.2f, 1.0f, 1.8f }; + +/** + * Functions used to spawn steam effects at the base of the red ice. + */ +static void (*sSteamSpawnFuncs[])(BgIceShelter* this, PlayState* play, f32 particleSpawningChance, + f32 steamEffectScale) = { + BgIceShelter_SpawnSteamAround, BgIceShelter_SpawnSteamAround, BgIceShelter_SpawnSteamAround, + BgIceShelter_SpawnSteamAlong, BgIceShelter_SpawnSteamAround, }; -void func_808911D4(BgIceShelter* this, PlayState* play) { +/** + * Progressively reduces the height and opacity of the red ice, while spawning steam effects at its base. + */ +void BgIceShelter_Melt(BgIceShelter* this, PlayState* play) { s32 pad; s32 type = (this->dyna.actor.params >> 8) & 7; - f32 phi_f0; + f32 particleSpawningChance; this->alpha -= 5; this->alpha = CLAMP(this->alpha, 0, 255); - this->dyna.actor.scale.y += D_808917BC[type]; + this->dyna.actor.scale.y += sMeltingRates[type]; this->dyna.actor.scale.y = CLAMP_MIN(this->dyna.actor.scale.y, 0.0001f); if (this->alpha > 80) { switch (type) { - case 0: - case 1: - case 4: + case RED_ICE_LARGE: + case RED_ICE_SMALL: + case RED_ICE_KING_ZORA: CollisionCheck_SetOC(play, &play->colChkCtx, &this->cylinder1.base); CollisionCheck_SetAC(play, &play->colChkCtx, &this->cylinder2.base); break; @@ -416,16 +407,16 @@ void func_808911D4(BgIceShelter* this, PlayState* play) { } if (this->alpha > 180) { - phi_f0 = 1.0f; + particleSpawningChance = 1.0f; } else if (this->alpha > 60) { - phi_f0 = 0.5f; + particleSpawningChance = 0.5f; } else { - phi_f0 = 0.0f; + particleSpawningChance = 0.0f; } - sEffSpawnFuncs[type](this, play, phi_f0, D_808917D0[type]); + sSteamSpawnFuncs[type](this, play, particleSpawningChance, sSteamEffectScales[type]); - if (this->alpha <= 0) { + if (GameInteractor_Should(VB_RED_ICE_DROP_ITEM, this->alpha <= 0, this)) { if (!((this->dyna.actor.params >> 6) & 1)) { Flags_SetSwitch(play, this->dyna.actor.params & 0x3F); } @@ -455,10 +446,10 @@ void BgIceShelter_Draw(Actor* thisx, PlayState* play2) { gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); switch ((this->dyna.actor.params >> 8) & 7) { - case 0: - case 1: - case 2: - case 4: + case RED_ICE_LARGE: + case RED_ICE_SMALL: + case RED_ICE_PLATFORM: + case RED_ICE_KING_ZORA: func_8002ED80(&this->dyna.actor, play, 0); break; } @@ -471,9 +462,9 @@ void BgIceShelter_Draw(Actor* thisx, PlayState* play2) { } switch ((this->dyna.actor.params >> 8) & 7) { - case 0: - case 1: - case 4: + case RED_ICE_LARGE: + case RED_ICE_SMALL: + case RED_ICE_KING_ZORA: gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, -play->gameplayFrames & 0x7F, -play->gameplayFrames & 0x7F, 0x20, 0x20, 1, -play->gameplayFrames & 0x7F, @@ -481,7 +472,7 @@ void BgIceShelter_Draw(Actor* thisx, PlayState* play2) { gSPDisplayList(POLY_XLU_DISP++, gRedIceBlockDL); break; - case 2: + case RED_ICE_PLATFORM: gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0, play->gameplayFrames & 0xFF, 0x40, 0x40, 1, 0, -play->gameplayFrames & 0xFF, 0x40, 0x40, 0, 1, 0, -1)); @@ -492,7 +483,7 @@ void BgIceShelter_Draw(Actor* thisx, PlayState* play2) { gSPDisplayList(POLY_XLU_DISP++, gRedIcePlatformDL); break; - case 3: + case RED_ICE_WALL: gSPDisplayList(POLY_XLU_DISP++, gRedIceWallDL); break; } diff --git a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.h b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.h index df6976c422..4eca07050c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.h +++ b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.h @@ -8,6 +8,14 @@ struct BgIceShelter; typedef void (*BgIceShelterActionFunc)(struct BgIceShelter*, PlayState*); +typedef enum RedIceType { + /* 0 */ RED_ICE_LARGE, // Large red ice block + /* 1 */ RED_ICE_SMALL, // Small red ice block + /* 2 */ RED_ICE_PLATFORM, // Complex structure that can be climbed and walked on. Unused in vanilla OoT, used in MQ to cover the Ice Cavern Map chest + /* 3 */ RED_ICE_WALL, // Vertical ice sheets blocking corridors + /* 4 */ RED_ICE_KING_ZORA // Giant red ice block covering King Zora +} RedIceType; + typedef struct BgIceShelter { /* 0x0000 */ DynaPolyActor dyna; /* 0x0164 */ BgIceShelterActionFunc actionFunc; diff --git a/soh/src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c b/soh/src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c index db45bca9a6..efcbe4d430 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c +++ b/soh/src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c @@ -6,6 +6,7 @@ #include "z_bg_ice_turara.h" #include "objects/object_ice_objects/object_ice_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -114,7 +115,7 @@ void BgIceTurara_Break(BgIceTurara* this, PlayState* play, f32 arg2) { } void BgIceTurara_Stalagmite(BgIceTurara* this, PlayState* play) { - if (this->collider.base.acFlags & AC_HIT) { + if (GameInteractor_Should(VB_STALAGMITE_DROP_ITEM, this->collider.base.acFlags & AC_HIT, this)) { BgIceTurara_Break(this, play, 50.0f); Actor_Kill(&this->dyna.actor); return; @@ -165,7 +166,7 @@ void BgIceTurara_Fall(BgIceTurara* this, PlayState* play) { this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; } BgIceTurara_Break(this, play, 40.0f); - if (this->dyna.actor.params == TURARA_STALACTITE_REGROW) { + if (GameInteractor_Should(VB_STALACTITE_DROP_ITEM, this->dyna.actor.params == TURARA_STALACTITE_REGROW, this)) { this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 120.0f; func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId); this->actionFunc = BgIceTurara_Regrow; @@ -198,4 +199,5 @@ void BgIceTurara_Update(Actor* thisx, PlayState* play) { void BgIceTurara_Draw(Actor* thisx, PlayState* play) { Gfx_DrawDListOpa(play, object_ice_objects_DL_0023D0); + if (GameInteractor_Should(VB_ICICLE_SETUP_DRAW, true, thisx)) {} } diff --git a/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c b/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c index 74eede4f05..58a79d2b1d 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c +++ b/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c @@ -21,9 +21,9 @@ void BgMizuMovebg_Destroy(Actor* thisx, PlayState* play); void BgMizuMovebg_Update(Actor* thisx, PlayState* play); void BgMizuMovebg_Draw(Actor* thisx, PlayState* play); -void func_8089E318(BgMizuMovebg* this, PlayState* play); -void func_8089E650(BgMizuMovebg* this, PlayState* play); -s32 func_8089E108(Path* pathList, Vec3f* pos, s32 pathId, s32 pointId); +void BgMizuMovebg_UpdateMain(BgMizuMovebg* this, PlayState* play); +void BgMizuMovebg_UpdateHookshotPlatform(BgMizuMovebg* this, PlayState* play); +s32 BgMizuMovebg_SetPosFromPath(Path* pathList, Vec3f* pos, s32 pathId, s32 pointId); const ActorInit Bg_Mizu_Movebg_InitVars = { ACTOR_BG_MIZU_MOVEBG, @@ -64,7 +64,7 @@ static Vec3f D_8089EBAC = { 0.0f, 80.0f, 23.0f }; static u8 D_8089EE40; -s32 func_8089DC30(PlayState* play) { +s32 BgMizuMovebg_GetDragonStatueBossRoomOffsetIndex(PlayState* play) { s32 result; if (Flags_GetSwitch(play, WATER_TEMPLE_WATER_F1_FLAG)) { @@ -103,7 +103,7 @@ void BgMizuMovebg_Init(Actor* thisx, PlayState* play) { } else { thisx->world.pos.y = temp; } - ((BgMizuMovebg*)thisx)->actionFunc = func_8089E318; + ((BgMizuMovebg*)thisx)->actionFunc = BgMizuMovebg_UpdateMain; break; case 1: temp = waterBoxes[2].ySurface + 15.0f; @@ -112,7 +112,7 @@ void BgMizuMovebg_Init(Actor* thisx, PlayState* play) { } else { thisx->world.pos.y = temp; } - ((BgMizuMovebg*)thisx)->actionFunc = func_8089E318; + ((BgMizuMovebg*)thisx)->actionFunc = BgMizuMovebg_UpdateMain; break; case 2: temp = waterBoxes[2].ySurface + 15.0f; @@ -121,11 +121,12 @@ void BgMizuMovebg_Init(Actor* thisx, PlayState* play) { } else { thisx->world.pos.y = temp; } - ((BgMizuMovebg*)thisx)->actionFunc = func_8089E318; + ((BgMizuMovebg*)thisx)->actionFunc = BgMizuMovebg_UpdateMain; break; case 3: - thisx->world.pos.y = ((BgMizuMovebg*)thisx)->homeY + D_8089EB40[func_8089DC30(play)]; - ((BgMizuMovebg*)thisx)->actionFunc = func_8089E318; + thisx->world.pos.y = + ((BgMizuMovebg*)thisx)->homeY + D_8089EB40[BgMizuMovebg_GetDragonStatueBossRoomOffsetIndex(play)]; + ((BgMizuMovebg*)thisx)->actionFunc = BgMizuMovebg_UpdateMain; break; case 4: case 5: @@ -135,7 +136,7 @@ void BgMizuMovebg_Init(Actor* thisx, PlayState* play) { } else { thisx->world.pos.y = ((BgMizuMovebg*)thisx)->homeY; } - ((BgMizuMovebg*)thisx)->actionFunc = func_8089E318; + ((BgMizuMovebg*)thisx)->actionFunc = BgMizuMovebg_UpdateMain; break; case 7: ((BgMizuMovebg*)thisx)->scrollAlpha1 = 160; @@ -144,8 +145,9 @@ void BgMizuMovebg_Init(Actor* thisx, PlayState* play) { ((BgMizuMovebg*)thisx)->scrollAlpha4 = 160; waypointId = MOVEBG_POINT_ID(thisx->params); ((BgMizuMovebg*)thisx)->waypointId = waypointId; - func_8089E108(play->setupPathList, &thisx->world.pos, MOVEBG_PATH_ID(thisx->params), waypointId); - ((BgMizuMovebg*)thisx)->actionFunc = func_8089E650; + BgMizuMovebg_SetPosFromPath(play->setupPathList, &thisx->world.pos, MOVEBG_PATH_ID(thisx->params), + waypointId); + ((BgMizuMovebg*)thisx)->actionFunc = BgMizuMovebg_UpdateHookshotPlatform; break; } @@ -188,7 +190,7 @@ void BgMizuMovebg_Destroy(Actor* thisx, PlayState* play) { } } -s32 func_8089E108(Path* pathList, Vec3f* pos, s32 pathId, s32 pointId) { +s32 BgMizuMovebg_SetPosFromPath(Path* pathList, Vec3f* pos, s32 pathId, s32 pointId) { Path* path = pathList; Vec3s* point; @@ -202,7 +204,7 @@ s32 func_8089E108(Path* pathList, Vec3f* pos, s32 pathId, s32 pointId) { return 0; } -void func_8089E198(BgMizuMovebg* this, PlayState* play) { +void BgMizuMovebg_SetScrollAlphas(BgMizuMovebg* this, PlayState* play) { f32 waterLevel = play->colCtx.colHeader->waterBoxes[2].ySurface; if (waterLevel < WATER_TEMPLE_WATER_F1_Y) { @@ -235,13 +237,13 @@ void func_8089E198(BgMizuMovebg* this, PlayState* play) { this->scrollAlpha4 = this->scrollAlpha3; } -void func_8089E318(BgMizuMovebg* this, PlayState* play) { +void BgMizuMovebg_UpdateMain(BgMizuMovebg* this, PlayState* play) { WaterBox* waterBoxes = play->colCtx.colHeader->waterBoxes; f32 phi_f0; s32 type; Vec3f sp28; - func_8089E198(this, play); + BgMizuMovebg_SetScrollAlphas(this, play); type = MOVEBG_TYPE(this->dyna.actor.params); switch (type) { @@ -263,7 +265,7 @@ void func_8089E318(BgMizuMovebg* this, PlayState* play) { } break; case 3: - phi_f0 = this->homeY + D_8089EB40[func_8089DC30(play)]; + phi_f0 = this->homeY + D_8089EB40[BgMizuMovebg_GetDragonStatueBossRoomOffsetIndex(play)]; if (!Math_StepToF(&this->dyna.actor.world.pos.y, phi_f0, 1.0f)) { if (!(D_8089EE40 & 2) && MOVEBG_SPEED(this->dyna.actor.params) != 0) { D_8089EE40 |= 2; @@ -316,7 +318,7 @@ void func_8089E318(BgMizuMovebg* this, PlayState* play) { } } -void func_8089E650(BgMizuMovebg* this, PlayState* play) { +void BgMizuMovebg_UpdateHookshotPlatform(BgMizuMovebg* this, PlayState* play) { Vec3f waypoint; f32 dist; f32 dx; @@ -324,7 +326,8 @@ void func_8089E650(BgMizuMovebg* this, PlayState* play) { f32 dz; this->dyna.actor.speedXZ = MOVEBG_SPEED(this->dyna.actor.params) * 0.1f; - func_8089E108(play->setupPathList, &waypoint, MOVEBG_PATH_ID(this->dyna.actor.params), this->waypointId); + BgMizuMovebg_SetPosFromPath(play->setupPathList, &waypoint, MOVEBG_PATH_ID(this->dyna.actor.params), + this->waypointId); dist = Actor_WorldDistXYZToPoint(&this->dyna.actor, &waypoint); if (dist < this->dyna.actor.speedXZ) { this->dyna.actor.speedXZ = dist; @@ -338,7 +341,8 @@ void func_8089E650(BgMizuMovebg* this, PlayState* play) { this->waypointId++; if (this->waypointId >= play->setupPathList[MOVEBG_PATH_ID(this->dyna.actor.params)].count) { this->waypointId = 0; - func_8089E108(play->setupPathList, &this->dyna.actor.world.pos, MOVEBG_PATH_ID(this->dyna.actor.params), 0); + BgMizuMovebg_SetPosFromPath(play->setupPathList, &this->dyna.actor.world.pos, + MOVEBG_PATH_ID(this->dyna.actor.params), 0); } } if (!(D_8089EE40 & 1) && MOVEBG_SPEED(this->dyna.actor.params) != 0) { diff --git a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c index 7b7030ef47..eef23e1eae 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c @@ -6,7 +6,6 @@ #include "z_bg_spot06_objects.h" #include "objects/object_spot06_objects/object_spot06_objects.h" -#include "soh/Enhancements/custom-message/CustomMessageTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_HOOKSHOT_PULLS_ACTOR @@ -49,8 +48,6 @@ void BgSpot06Objects_WaterPlaneCutsceneWait(BgSpot06Objects* this, PlayState* pl void BgSpot06Objects_WaterPlaneCutsceneRise(BgSpot06Objects* this, PlayState* play); void BgSpot06Objects_WaterPlaneCutsceneLower(BgSpot06Objects* this, PlayState* play); -s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId); - const ActorInit Bg_Spot06_Objects_InitVars = { ACTOR_BG_SPOT06_OBJECTS, ACTORCAT_PROP, @@ -194,12 +191,6 @@ void BgSpot06Objects_Init(Actor* thisx, PlayState* play) { } } -static u8 actionCounter = 0; // Used to perform some actions on subsequent frames -static s8 waterMovement = 0; // Used to control the water change direction -static u8 switchPressed = 0; // Used to track when the water fill switch is pressed/depressed -static u8 prevSwitchState = 0; // Used to track the previous state of the water fill switch -static Actor* lakeControlFloorSwitch; - void BgSpot06Objects_Destroy(Actor* thisx, PlayState* play) { BgSpot06Objects* this = (BgSpot06Objects*)thisx; @@ -217,17 +208,6 @@ void BgSpot06Objects_Destroy(Actor* thisx, PlayState* play) { // Due to Ships resource caching, the water box collisions for the river have to be manually reset play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z; - - if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { - // For randomizer when leaving lake hylia while the water level is lowered, - // reset the "raise lake hylia water" flag back to on if the water temple is cleared - Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); - } - - actionCounter = 0; - waterMovement = 0; - switchPressed = 0; - prevSwitchState = 0; } /** @@ -450,72 +430,6 @@ void BgSpot06Objects_Update(Actor* thisx, PlayState* play) { if (thisx->params == LHO_WATER_TEMPLE_ENTRANCE_LOCK) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); } - - // Bail early for water control system for child or non-rando - if (LINK_IS_CHILD || !IS_RANDO) { - return; - } - - // Begin setup for Lake Hylia water control system - if (actionCounter == 0) { - // Object containing floor switch data (and ice block data) - Object_Spawn(&play->objectCtx, OBJECT_GAMEPLAY_DANGEON_KEEP); - - s16 switchParams; - if (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { - // Toggle-able floor switch, - // linked to temp_switch 0x1E (room temporary, cleared when room unloads) - switchParams = 0x3E10; - } else { - // Frozen rusty switch, same flag as above. It's glitched and can't be pressed - switchParams = 0x3E81; - } - - // Spawn a floor switch - lakeControlFloorSwitch = - Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_SWITCH, -896.0f, -1243.0f, 6953.0f, 0, 0, 0, switchParams); - // Spawn a sign - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KANBAN, -970.0f, -1242.0f, 6954.0f, 0, 0, 0, - 0x0000 | (TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN & 0xFF)); - - // Spawn a Navi check spot when Water Temple isn't cleared - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { - Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, -896.0f, -1243.0f, 6953.0f, 0, 0, 0, - 0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF)); - } - - actionCounter++; - return; - } else if (actionCounter == 1) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { - // Remove the link to ice block so melting it doesn't set the flag - lakeControlFloorSwitch->params = 0x3E01; - } - - actionCounter++; - return; - } - - // Detect when the switch is pressed - if (prevSwitchState != (Flags_GetSwitch(play, 0x3E) != 0)) { - prevSwitchState = !prevSwitchState; - switchPressed = 1; - } - - // When pressed, assign the corresponding action func to the water plane and water movement direction - if (switchPressed == 1 && thisx->params == LHO_WATER_PLANE) { - // Lower water - if (waterMovement >= 0) { - waterMovement = -1; - this->actionFunc = BgSpot06Objects_WaterPlaneCutsceneLower; - // Raise water - } else { - waterMovement = 1; - this->actionFunc = BgSpot06Objects_WaterPlaneCutsceneRise; - } - - switchPressed = 0; - } } /** diff --git a/soh/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c b/soh/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c index e082ed4ee9..34577ca753 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c @@ -71,7 +71,7 @@ void func_808B3960(BgSpot15Rrbox* this, PlayState* play, CollisionHeader* collis } } -void func_808B39E8(Vec3f* arg0, Vec3f* arg1, f32 arg2, f32 arg3) { +void BgSpot15Rrbox_RotatePoint(Vec3f* arg0, Vec3f* arg1, f32 arg2, f32 arg3) { arg0->x = (arg1->z * arg2) + (arg1->x * arg3); arg0->y = arg1->y; arg0->z = (arg1->z * arg3) - (arg1->x * arg2); @@ -141,7 +141,7 @@ void BgSpot15Rrbox_Destroy(Actor* thisx, PlayState* play) { D_808B4590 = 0; } -s32 func_808B3CA0(BgSpot15Rrbox* this, PlayState* play, s32 arg2) { +s32 BgSpot15Rrbox_TrySnapToCheckedPoint(BgSpot15Rrbox* this, PlayState* play, s32 arg2) { f32 chkDist = 0.0f; Vec3f actorPosition; Vec3f actorScale; @@ -152,7 +152,7 @@ s32 func_808B3CA0(BgSpot15Rrbox* this, PlayState* play, s32 arg2) { actorScale.y = D_808B45DC[arg2].y * (this->dyna.actor.scale.y * 10.0f); actorScale.z = D_808B45DC[arg2].z * (this->dyna.actor.scale.z * 10.0f); - func_808B39E8(&actorPosition, &actorScale, this->unk_16C, this->unk_170); + BgSpot15Rrbox_RotatePoint(&actorPosition, &actorScale, this->unk_16C, this->unk_170); actorPosition.x += this->dyna.actor.world.pos.x; actorPosition.y += this->dyna.actor.prevPos.y; @@ -168,7 +168,7 @@ s32 func_808B3CA0(BgSpot15Rrbox* this, PlayState* play, s32 arg2) { return false; } -f32 func_808B3DDC(BgSpot15Rrbox* this, PlayState* play) { +f32 BgSpot15Rrbox_GetFloorHeight(BgSpot15Rrbox* this, PlayState* play) { s32 i; Vec3f position; Vec3f scale; @@ -183,7 +183,7 @@ f32 func_808B3DDC(BgSpot15Rrbox* this, PlayState* play) { scale.y = D_808B45DC[i].y * (actor->scale.y * 10.0f); scale.z = D_808B45DC[i].z * (actor->scale.z * 10.0f); - func_808B39E8(&position, &scale, this->unk_16C, this->unk_170); + BgSpot15Rrbox_RotatePoint(&position, &scale, this->unk_16C, this->unk_170); position.x += actor->world.pos.x; position.y += actor->prevPos.y; @@ -199,20 +199,20 @@ f32 func_808B3DDC(BgSpot15Rrbox* this, PlayState* play) { return returnValue; } -s32 func_808B3F58(BgSpot15Rrbox* this, PlayState* play) { - if (func_808B3CA0(this, play, 0)) { +s32 BgSpot15Rrbox_TrySnapToFloor(BgSpot15Rrbox* this, PlayState* play) { + if (BgSpot15Rrbox_TrySnapToCheckedPoint(this, play, 0)) { return true; } - if (func_808B3CA0(this, play, 1)) { + if (BgSpot15Rrbox_TrySnapToCheckedPoint(this, play, 1)) { return true; } - if (func_808B3CA0(this, play, 2)) { + if (BgSpot15Rrbox_TrySnapToCheckedPoint(this, play, 2)) { return true; } - if (func_808B3CA0(this, play, 3)) { + if (BgSpot15Rrbox_TrySnapToCheckedPoint(this, play, 3)) { return true; } - if (func_808B3CA0(this, play, 4)) { + if (BgSpot15Rrbox_TrySnapToCheckedPoint(this, play, 4)) { return true; } return false; @@ -272,7 +272,7 @@ void func_808B4194(BgSpot15Rrbox* this, PlayState* play) { actor->world.pos.x = actor->home.pos.x + (tempUnk178 * this->unk_16C); actor->world.pos.z = actor->home.pos.z + (tempUnk178 * this->unk_170); - if (!func_808B3F58(this, play)) { + if (!BgSpot15Rrbox_TrySnapToFloor(this, play)) { actor->home.pos.x = actor->world.pos.x; actor->home.pos.z = actor->world.pos.z; player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY; @@ -305,7 +305,7 @@ void func_808B4380(BgSpot15Rrbox* this, PlayState* play) { this->dyna.actor.velocity.y = 0.0f; this->dyna.actor.velocity.z = 0.0f; this->dyna.actor.gravity = -1.0f; - this->dyna.actor.floorHeight = func_808B3DDC(this, play); + this->dyna.actor.floorHeight = BgSpot15Rrbox_GetFloorHeight(this, play); this->actionFunc = func_808B43D0; } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c b/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c index 72e59a80d5..85cafdbbdc 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c @@ -11,18 +11,18 @@ void BgSpot18Basket_Update(Actor* thisx, PlayState* play); void BgSpot18Basket_Draw(Actor* thisx, PlayState* play); void BgSpot18Basket_Reset(void); -void func_808B7BCC(BgSpot18Basket* this, PlayState* play); -void func_808B7AEC(BgSpot18Basket* this); -void func_808B7B58(BgSpot18Basket* this); -void func_808B7BB0(BgSpot18Basket* this); -void func_808B7D38(BgSpot18Basket* this); -void func_808B7F74(BgSpot18Basket* this); -void func_808B818C(BgSpot18Basket* this); -void func_808B7AFC(BgSpot18Basket* this, PlayState* play); -void func_808B7B6C(BgSpot18Basket* this, PlayState* play); -void func_808B7D50(BgSpot18Basket* this, PlayState* play); -void func_808B7FC0(BgSpot18Basket* this, PlayState* play); -void func_808B81A0(BgSpot18Basket* this, PlayState* play); +void BgSpot18Basket_Spinning(BgSpot18Basket* this, PlayState* play); +void BgSpot18Basket_SetupInactive(BgSpot18Basket* this); +void BgSpot18Basket_SetupActivation(BgSpot18Basket* this); +void BgSpot18Basket_SetupSpinning(BgSpot18Basket* this); +void BgSpot18Basket_SetupExplosionCs(BgSpot18Basket* this); +void BgSpot18Basket_SetupStopping(BgSpot18Basket* this); +void BgSpot18Basket_SetupGivingPrize(BgSpot18Basket* this); +void BgSpot18Basket_Inactive(BgSpot18Basket* this, PlayState* play); +void BgSpot18Basket_Activation(BgSpot18Basket* this, PlayState* play); +void BgSpot18Basket_ExplosionCs(BgSpot18Basket* this, PlayState* play); +void BgSpot18Basket_Stopping(BgSpot18Basket* this, PlayState* play); +void BgSpot18Basket_GivingPrize(BgSpot18Basket* this, PlayState* play); const ActorInit Bg_Spot18_Basket_InitVars = { ACTOR_BG_SPOT18_BASKET, @@ -77,7 +77,7 @@ static ColliderJntSphInit sJntSphInit = { static s16 D_808B85C8[] = { 0x8000, 0x2AAA, 0xD555, 0x0000 }; -void func_808B7710(Actor* thisx, PlayState* play) { +void BgSpot18Basket_InitColliderJntSph(Actor* thisx, PlayState* play) { BgSpot18Basket* this = (BgSpot18Basket*)thisx; Collider_InitJntSph(play, &this->colliderJntSph); @@ -86,7 +86,7 @@ void func_808B7710(Actor* thisx, PlayState* play) { } s16 D_808B85D0 = 0; -void func_808B7770(BgSpot18Basket* this, PlayState* play, f32 arg2) { +void BgSpot18Basket_SpawnDustClouds(BgSpot18Basket* this, PlayState* play, f32 arg2) { Vec3f acceleration; Vec3f velocity; Vec3f position; @@ -137,7 +137,7 @@ void BgSpot18Basket_Init(Actor* thisx, PlayState* play) { CollisionHeader* colHeader = NULL; DynaPolyActor_Init(&this->dyna, DPM_UNK3); - func_808B7710(&this->dyna.actor, play); + BgSpot18Basket_InitColliderJntSph(&this->dyna.actor, play); CollisionHeader_GetVirtual(&gGoronCityVaseCol, &colHeader); this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader); @@ -148,11 +148,11 @@ void BgSpot18Basket_Init(Actor* thisx, PlayState* play) { this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; if (Flags_GetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F)) { - func_808B7BB0(this); + BgSpot18Basket_SetupSpinning(this); return; } - func_808B7AEC(this); + BgSpot18Basket_SetupInactive(this); Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_BG_SPOT18_FUTA, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, this->dyna.actor.shape.rot.x, this->dyna.actor.shape.rot.y + 0x1555, this->dyna.actor.shape.rot.z, -1); @@ -172,50 +172,52 @@ void BgSpot18Basket_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyJntSph(play, &this->colliderJntSph); } -void func_808B7AEC(BgSpot18Basket* this) { - this->actionFunc = func_808B7AFC; +void BgSpot18Basket_SetupInactive(BgSpot18Basket* this) { + this->actionFunc = BgSpot18Basket_Inactive; } -void func_808B7AFC(BgSpot18Basket* this, PlayState* play) { +void BgSpot18Basket_Inactive(BgSpot18Basket* this, PlayState* play) { if (Flags_GetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F)) { OnePointCutscene_Init(play, 4220, 80, &this->dyna.actor, MAIN_CAM); - func_808B7B58(this); + BgSpot18Basket_SetupActivation(this); } } -void func_808B7B58(BgSpot18Basket* this) { - this->actionFunc = func_808B7B6C; - this->unk_216 = 0; +void BgSpot18Basket_SetupActivation(BgSpot18Basket* this) { + this->actionFunc = BgSpot18Basket_Activation; + this->timer = 0; } -void func_808B7B6C(BgSpot18Basket* this, PlayState* play) { - if (this->unk_216 > 20) { - func_808B7BB0(this); +void BgSpot18Basket_Activation(BgSpot18Basket* this, PlayState* play) { + if (this->timer > 20) { + BgSpot18Basket_SetupSpinning(this); this->dyna.actor.child->parent = NULL; this->dyna.actor.child = NULL; } } -void func_808B7BB0(BgSpot18Basket* this) { - this->actionFunc = func_808B7BCC; - this->unk_210 = this->unk_20C = 0; +void BgSpot18Basket_SetupSpinning(BgSpot18Basket* this) { + this->actionFunc = BgSpot18Basket_Spinning; + this->spinRate = this->circleRate = 0; } -void func_808B7BCC(BgSpot18Basket* this, PlayState* play) { +void BgSpot18Basket_Spinning(BgSpot18Basket* this, PlayState* play) { f32 positionDiff; Actor* colliderBaseAc; - Math_StepToS(&this->unk_210, 0x1F4, 0x1E); + Math_StepToS(&this->spinRate, 0x1F4, 0x1E); - this->dyna.actor.shape.rot.y += this->unk_210; + this->dyna.actor.shape.rot.y += this->spinRate; - Math_StepToF(&this->unk_208, 50.0f, 1.5f); - Math_StepToS(&this->unk_20C, 400, 15); + Math_StepToF(&this->circleRadius, 50.0f, 1.5f); + Math_StepToS(&this->circleRate, 400, 15); - this->unk_20E += this->unk_20C; + this->circleMoveAngle += this->circleRate; - this->dyna.actor.world.pos.x = (Math_SinS(this->unk_20E) * this->unk_208) + this->dyna.actor.home.pos.x; - this->dyna.actor.world.pos.z = (Math_CosS(this->unk_20E) * this->unk_208) + this->dyna.actor.home.pos.z; + this->dyna.actor.world.pos.x = + (Math_SinS(this->circleMoveAngle) * this->circleRadius) + this->dyna.actor.home.pos.x; + this->dyna.actor.world.pos.z = + (Math_CosS(this->circleMoveAngle) * this->circleRadius) + this->dyna.actor.home.pos.z; if (this->colliderJntSph.base.acFlags & AC_HIT) { colliderBaseAc = this->colliderJntSph.base.ac; @@ -227,7 +229,7 @@ void func_808B7BCC(BgSpot18Basket* this, PlayState* play) { if (Math3D_Dist2DSq(colliderBaseAc->world.pos.z, this->colliderJntSph.base.ac->world.pos.x, this->dyna.actor.world.pos.z, this->dyna.actor.world.pos.x) < SQ(32.0f)) { OnePointCutscene_Init(play, 4210, 240, &this->dyna.actor, MAIN_CAM); - func_808B7D38(this); + BgSpot18Basket_SetupExplosionCs(this); func_8003EBF8(play, &play->colCtx.dyna, this->dyna.bgId); } } @@ -236,142 +238,144 @@ void func_808B7BCC(BgSpot18Basket* this, PlayState* play) { func_8002F974(&this->dyna.actor, NA_SE_EV_ELEVATOR_MOVE - SFX_FLAG); } -void func_808B7D38(BgSpot18Basket* this) { - this->actionFunc = func_808B7D50; - this->unk_216 = 0; - this->unk_214 = 0; +void BgSpot18Basket_SetupExplosionCs(BgSpot18Basket* this) { + this->actionFunc = BgSpot18Basket_ExplosionCs; + this->timer = 0; + this->pivotAltitude = 0; } -void func_808B7D50(BgSpot18Basket* this, PlayState* play) { +void BgSpot18Basket_ExplosionCs(BgSpot18Basket* this, PlayState* play) { f32 tempValue2; f32 tempValue; - if (this->unk_216 > 120) { - Math_StepToS(&this->unk_210, 0x3E8, 0x32); + if (this->timer > 120) { + Math_StepToS(&this->spinRate, 0x3E8, 0x32); } else { - Math_StepToS(&this->unk_210, 0xBB8, 0x64); + Math_StepToS(&this->spinRate, 0xBB8, 0x64); } - this->dyna.actor.shape.rot.y = this->dyna.actor.shape.rot.y + this->unk_210; + this->dyna.actor.shape.rot.y = this->dyna.actor.shape.rot.y + this->spinRate; - if (this->unk_216 < 70) { - Math_StepToF(&this->unk_208, 100.0f, 2.0f); + if (this->timer < 70) { + Math_StepToF(&this->circleRadius, 100.0f, 2.0f); } else { - Math_StepToF(&this->unk_208, 0.0f, 2.0f); + Math_StepToF(&this->circleRadius, 0.0f, 2.0f); } - Math_StepToS(&this->unk_20C, 1000, 20); + Math_StepToS(&this->circleRate, 1000, 20); - this->unk_20E += this->unk_20C; + this->circleMoveAngle += this->circleRate; - this->dyna.actor.world.pos.x = (Math_SinS(this->unk_20E) * this->unk_208) + this->dyna.actor.home.pos.x; - this->dyna.actor.world.pos.z = (Math_CosS(this->unk_20E) * this->unk_208) + this->dyna.actor.home.pos.z; + this->dyna.actor.world.pos.x = + (Math_SinS(this->circleMoveAngle) * this->circleRadius) + this->dyna.actor.home.pos.x; + this->dyna.actor.world.pos.z = + (Math_CosS(this->circleMoveAngle) * this->circleRadius) + this->dyna.actor.home.pos.z; - this->unk_212 += 0xBB8; + this->pivotAzimuth += 0xBB8; - Math_StepToS(&this->unk_214, 0x5DC, 0x1E); + Math_StepToS(&this->pivotAltitude, 0x5DC, 0x1E); - this->dyna.actor.shape.rot.x = Math_CosS(this->unk_212) * this->unk_214; - this->dyna.actor.shape.rot.z = -Math_SinS(this->unk_212) * this->unk_214; + this->dyna.actor.shape.rot.x = Math_CosS(this->pivotAzimuth) * this->pivotAltitude; + this->dyna.actor.shape.rot.z = -Math_SinS(this->pivotAzimuth) * this->pivotAltitude; - if (this->unk_216 > 140) { - func_808B7F74(this); + if (this->timer > 140) { + BgSpot18Basket_SetupStopping(this); } - if (this->unk_216 < 80) { - func_808B7770(this, play, 1.0f); + if (this->timer < 80) { + BgSpot18Basket_SpawnDustClouds(this, play, 1.0f); } else { - func_808B7770(this, play, 0.8f); + BgSpot18Basket_SpawnDustClouds(this, play, 0.8f); } - tempValue2 = (this->unk_210 - 500) * 0.0006f; + tempValue2 = (this->spinRate - 500) * 0.0006f; tempValue = CLAMP(tempValue2, 0.0f, 1.5f); func_800F436C(&this->dyna.actor.projectedPos, NA_SE_EV_WALL_MOVE_SP - SFX_FLAG, tempValue); } -void func_808B7F74(BgSpot18Basket* this) { +void BgSpot18Basket_SetupStopping(BgSpot18Basket* this) { s16 shapeRotY; shapeRotY = this->dyna.actor.shape.rot.y; - this->actionFunc = func_808B7FC0; + this->actionFunc = BgSpot18Basket_Stopping; if (GameInteractor_Should(VB_WIN_GORON_POT, (shapeRotY < -0x2E93) || (shapeRotY >= 0x7C19))) { - this->unk_218 = 2; + this->prize = 2; } else if (shapeRotY < 0x26C2) { - this->unk_218 = 1; + this->prize = 1; } else { - this->unk_218 = 0; + this->prize = 0; } - this->unk_216 = 0; + this->timer = 0; } -void func_808B7FC0(BgSpot18Basket* this, PlayState* play) { +void BgSpot18Basket_Stopping(BgSpot18Basket* this, PlayState* play) { s32 pad; s32 tempUnk214; f32 tempUnk210; s16 arrayValue; f32 clampedTempUnk210; - this->unk_212 += 0xBB8; + this->pivotAzimuth += 0xBB8; - if (this->unk_216 >= 13) { - tempUnk214 = Math_StepToS(&this->unk_214, 0, 55); + if (this->timer >= 13) { + tempUnk214 = Math_StepToS(&this->pivotAltitude, 0, 55); } else { tempUnk214 = 0; } - this->dyna.actor.shape.rot.x = Math_CosS(this->unk_212) * this->unk_214; - this->dyna.actor.shape.rot.z = -Math_SinS(this->unk_212) * this->unk_214; + this->dyna.actor.shape.rot.x = Math_CosS(this->pivotAzimuth) * this->pivotAltitude; + this->dyna.actor.shape.rot.z = -Math_SinS(this->pivotAzimuth) * this->pivotAltitude; - Math_StepToS(&this->unk_210, 0x1F4, 0xA); - this->dyna.actor.shape.rot.y += this->unk_210; + Math_StepToS(&this->spinRate, 0x1F4, 0xA); + this->dyna.actor.shape.rot.y += this->spinRate; if (tempUnk214 != 0) { - arrayValue = D_808B85C8[this->unk_218]; + arrayValue = D_808B85C8[this->prize]; if ((s16)(this->dyna.actor.shape.rot.y - arrayValue) >= 0) { this->dyna.actor.shape.rot.y = arrayValue; - func_808B818C(this); + BgSpot18Basket_SetupGivingPrize(this); func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId); } } - if (this->unk_216 < 30) { - func_808B7770(this, play, 0.5f); + if (this->timer < 30) { + BgSpot18Basket_SpawnDustClouds(this, play, 0.5f); } else { - func_808B7770(this, play, 0.3f); + BgSpot18Basket_SpawnDustClouds(this, play, 0.3f); } - tempUnk210 = (this->unk_210 - 500) * 0.0006f; + tempUnk210 = (this->spinRate - 500) * 0.0006f; clampedTempUnk210 = CLAMP(tempUnk210, 0.0f, 1.5f); func_800F436C(&this->dyna.actor.projectedPos, NA_SE_EV_WALL_MOVE_SP - SFX_FLAG, clampedTempUnk210); } -void func_808B818C(BgSpot18Basket* this) { - this->actionFunc = func_808B81A0; - this->unk_216 = 0; +void BgSpot18Basket_SetupGivingPrize(BgSpot18Basket* this) { + this->actionFunc = BgSpot18Basket_GivingPrize; + this->timer = 0; } static s16 D_808B85E4[] = { -0x0FA0, 0x0320, 0x0FA0 }; -void func_808B81A0(BgSpot18Basket* this, PlayState* play) { +void BgSpot18Basket_GivingPrize(BgSpot18Basket* this, PlayState* play) { s32 i; Actor* actor = &this->dyna.actor; Vec3f tempVector; EnItem00* collectible; - if (this->unk_216 == 1) { + if (this->timer == 1) { tempVector.x = actor->world.pos.x; tempVector.y = actor->world.pos.y + 170.0f; tempVector.z = actor->world.pos.z; - if (this->unk_218 == 0) { + if (this->prize == 0) { for (i = 0; i < ARRAY_COUNT(D_808B85E4); i++) { collectible = Item_DropCollectible(play, &tempVector, ITEM00_BOMBS_A); if (collectible != NULL) { @@ -379,7 +383,7 @@ void func_808B81A0(BgSpot18Basket* this, PlayState* play) { collectible->actor.world.rot.y = D_808B85E4[i]; } } - } else if (this->unk_218 == 1) { + } else if (this->prize == 1) { for (i = 0; i < ARRAY_COUNT(D_808B85E4); i++) { collectible = Item_DropCollectible(play, &tempVector, ITEM00_RUPEE_GREEN); if (collectible != NULL) { @@ -387,8 +391,8 @@ void func_808B81A0(BgSpot18Basket* this, PlayState* play) { collectible->actor.world.rot.y = D_808B85E4[i]; } } - } else if (this->unk_218 == 2) { - if ((this->unk_21A != 0) || Flags_GetCollectible(play, (actor->params & 0x3F))) { + } else if (this->prize == 2) { + if ((this->isHeartPieceGiven != 0) || Flags_GetCollectible(play, (actor->params & 0x3F))) { collectible = Item_DropCollectible(play, &tempVector, ITEM00_RUPEE_PURPLE); if (collectible != NULL) { collectible->actor.velocity.y = 11.0f; @@ -400,7 +404,7 @@ void func_808B81A0(BgSpot18Basket* this, PlayState* play) { if (collectible != NULL) { collectible->actor.velocity.y = 11.0f; collectible->actor.world.rot.y = D_808B85E4[1]; - this->unk_21A = 1; + this->isHeartPieceGiven = 1; } } @@ -416,14 +420,14 @@ void func_808B81A0(BgSpot18Basket* this, PlayState* play) { collectible->actor.world.rot.y = D_808B85E4[2]; } } - } else if (this->unk_216 == 2) { - if (this->unk_218 == 2) { + } else if (this->timer == 2) { + if (this->prize == 2) { Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } else { Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } - } else if (this->unk_216 == 200) { - func_808B7BB0(this); + } else if (this->timer == 200) { + BgSpot18Basket_SetupSpinning(this); } } @@ -432,13 +436,13 @@ void BgSpot18Basket_Update(Actor* thisx, PlayState* play) { BgSpot18Basket* this = (BgSpot18Basket*)thisx; s32 bgId; - this->unk_216++; + this->timer++; this->actionFunc(this, play); this->dyna.actor.floorHeight = BgCheck_EntityRaycastFloor4(&play->colCtx, &this->dyna.actor.floorPoly, &bgId, &this->dyna.actor, &this->dyna.actor.world.pos); - if (this->actionFunc != func_808B7AFC) { + if (this->actionFunc != BgSpot18Basket_Inactive) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base); - if (this->actionFunc != func_808B7B6C) { + if (this->actionFunc != BgSpot18Basket_Activation) { this->colliderJntSph.base.acFlags &= ~AC_HIT; CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base); } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.h b/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.h index e218fc7b16..a4943750b6 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.h +++ b/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.h @@ -13,16 +13,16 @@ typedef struct BgSpot18Basket { /* 0x0164 */ ColliderJntSph colliderJntSph; /* 0x0184 */ ColliderJntSphElement ColliderJntSphElements[2]; /* 0x0204 */ BgSpot18BasketActionFunc actionFunc; - /* 0x0208 */ f32 unk_208; - /* 0x020C */ s16 unk_20C; - /* 0x020E */ s16 unk_20E; - /* 0x0210 */ s16 unk_210; - /* 0x0212 */ s16 unk_212; - /* 0x0214 */ s16 unk_214; - /* 0x0216 */ s16 unk_216; - /* 0x0218 */ s16 unk_218; - /* 0x021A */ u8 unk_21A; - /* 0x021B */ u8 unk_21B; + /* 0x0208 */ f32 circleRadius; + /* 0x020C */ s16 circleRate; + /* 0x020E */ s16 circleMoveAngle; + /* 0x0210 */ s16 spinRate; + /* 0x0212 */ s16 pivotAzimuth; + /* 0x0214 */ s16 pivotAltitude; + /* 0x0216 */ s16 timer; + /* 0x0218 */ s16 prize; + /* 0x021A */ u8 isHeartPieceGiven; + /* 0x021B */ u8 pad; } BgSpot18Basket; // size = 0x021C #endif diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h index 2a546540ed..92f5da5fc0 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h @@ -72,7 +72,7 @@ typedef struct BossDodongo { /* 0x020C */ f32 unk_20C; /* 0x0210 */ f32 colorFilterR; /* 0x0214 */ f32 colorFilterG; - /* 0x0214 */ f32 colorFilterB; + /* 0x0218 */ f32 colorFilterB; /* 0x021C */ f32 colorFilterMin; /* 0x0220 */ f32 colorFilterMax; /* 0x0224 */ f32 unk_224; diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index e463f981ad..21a849cfaa 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -36,8 +36,8 @@ void func_80900580(BossGanon2* this, PlayState* play); void func_80900650(BossGanon2* this, PlayState* play); void func_80900890(BossGanon2* this, PlayState* play); void func_8090120C(BossGanon2* this, PlayState* play); -void func_80905DA8(BossGanon2* this, PlayState* play); -void func_809060E8(PlayState* play); +void BossGanon2_UpdateEffects(BossGanon2* this, PlayState* play); +void BossGanon2_DrawEffects(PlayState* play); void BossGanon2_GenShadowTexture(void* shadowTexture, BossGanon2* this, PlayState* play); void BossGanon2_DrawShadowTexture(void* shadowTexture, BossGanon2* this, PlayState* play); @@ -233,9 +233,9 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { if (Object_IsLoaded(&play->objectCtx, objectIdx)) { func_80064520(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 8); - this->unk_39E = Play_CreateSubCamera(play); + this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); + Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); sBossGanon2Zelda = (EnZl3*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_ZL3, 970.0f, 1086.0f, -200.0f, 0, 0, 0, 1); sBossGanon2Zelda->unk_3C8 = 0; @@ -254,12 +254,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { sBossGanon2Zelda->unk_3C8 = 4; } - this->unk_3BC.x = 0.0f; - this->unk_3BC.y = 1.0f; - this->unk_3BC.z = 0.0f; - this->unk_3A4.x = 0.0f; - this->unk_3A4.y = 1400.0f; - this->unk_3A4.z = 1600.0f; + this->subCamUp.x = 0.0f; + this->subCamUp.y = 1.0f; + this->subCamUp.z = 0.0f; + this->subCamEye.x = 0.0f; + this->subCamEye.y = 1400.0f; + this->subCamEye.z = 1600.0f; player->actor.world.pos.x = 970.0f; player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -186.0f; @@ -268,7 +268,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { play->envCtx.unk_D8 = 0.0f; // fake, tricks the compiler into allocating more stack if (zero) { - this->unk_3A4.x *= 2.0; + this->subCamEye.x *= 2.0; } } else { break; @@ -278,12 +278,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { play->envCtx.unk_D8 = 0.0f; } this->unk_339 = 3; - Math_ApproachF(&this->unk_3A4.x, 1500.0f, 0.1f, this->unk_410.x * 1500.0f); - Math_ApproachF(&this->unk_3A4.z, -160.0f, 0.1f, this->unk_410.x * 1760.0f); + Math_ApproachF(&this->subCamEye.x, 1500.0f, 0.1f, this->unk_410.x * 1500.0f); + Math_ApproachF(&this->subCamEye.z, -160.0f, 0.1f, this->unk_410.x * 1760.0f); Math_ApproachF(&this->unk_410.x, 0.0075f, 1.0f, 0.0001f); - this->unk_3B0.x = -200.0f; - this->unk_3B0.y = 1086.0f; - this->unk_3B0.z = -200.0f; + this->subCamAt.x = -200.0f; + this->subCamAt.y = 1086.0f; + this->subCamAt.z = -200.0f; if (this->csTimer == 150) { Message_StartTextbox(play, 0x70D3, NULL); } @@ -316,17 +316,17 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { sBossGanon2Zelda->unk_3C8 = 2; Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4F); } - this->unk_3A4.x = 930.0f; - this->unk_3A4.y = 1129.0f; - this->unk_3A4.z = -181.0f; - this->unk_3B0.x = player->actor.world.pos.x; - this->unk_3B0.z = (player->actor.world.pos.z - 15.0f) + 5.0f; + this->subCamEye.x = 930.0f; + this->subCamEye.y = 1129.0f; + this->subCamEye.z = -181.0f; + this->subCamAt.x = player->actor.world.pos.x; + this->subCamAt.z = (player->actor.world.pos.z - 15.0f) + 5.0f; if (this->csTimer > 104) { - Math_ApproachF(&this->unk_3B0.y, player->actor.world.pos.y + 47.0f + 7.0f + 15.0f, 0.1f, + Math_ApproachF(&this->subCamAt.y, player->actor.world.pos.y + 47.0f + 7.0f + 15.0f, 0.1f, this->unk_410.x); Math_ApproachF(&this->unk_410.x, 2.0f, 1.0f, 0.1f); } else { - this->unk_3B0.y = player->actor.world.pos.y + 47.0f + 7.0f; + this->subCamAt.y = player->actor.world.pos.y + 47.0f + 7.0f; } if ((this->csTimer > 170) && (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE)) { this->csState = 3; @@ -335,7 +335,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { } break; case 3: - Math_ApproachF(&this->unk_3B0.y, player->actor.world.pos.y + 47.0f + 7.0f, 0.1f, 2.0f); + Math_ApproachF(&this->subCamAt.y, player->actor.world.pos.y + 47.0f + 7.0f, 0.1f, 2.0f); this->unk_339 = 4; if (this->csTimer == 10) { Sfx_PlaySfxAtPos(&D_80906D6C, NA_SE_EV_STONE_BOUND); @@ -355,17 +355,17 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { break; case 4: this->unk_339 = 4; - Math_ApproachF(&this->unk_3A4.x, -360.0f, 0.1f, this->unk_410.x * 1290.0f); - Math_ApproachF(&this->unk_3A4.z, -20.0f, 0.1f, this->unk_410.x * 170.0f); + Math_ApproachF(&this->subCamEye.x, -360.0f, 0.1f, this->unk_410.x * 1290.0f); + Math_ApproachF(&this->subCamEye.z, -20.0f, 0.1f, this->unk_410.x * 170.0f); Math_ApproachF(&this->unk_410.x, 0.04f, 1.0f, 0.0005f); if (this->csTimer == 100) { Camera* camera = Play_GetCamera(play, MAIN_CAM); - camera->eye = this->unk_3A4; - camera->eyeNext = this->unk_3A4; - camera->at = this->unk_3B0; - func_800C08AC(play, this->unk_39E, 0); - this->unk_39E = 0; + camera->eye = this->subCamEye; + camera->eyeNext = this->subCamEye; + camera->at = this->subCamAt; + func_800C08AC(play, this->subCamId, 0); + this->subCamId = 0; func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->csState = 5; @@ -379,9 +379,9 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->csState = 10; this->csTimer = 0; func_80064520(play, &play->csCtx); - this->unk_39E = Play_CreateSubCamera(play); + this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); + Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); } else { break; } @@ -394,12 +394,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { sBossGanon2Zelda->actor.world.pos.z = -186.0f; player->actor.shape.rot.y = -0x4000; sBossGanon2Zelda->actor.shape.rot.y = -0x5000; - this->unk_3A4.x = 410.0f; - this->unk_3A4.y = 1096.0f; - this->unk_3A4.z = -110.0f; - this->unk_3B0.x = player->actor.world.pos.x + 10.0f; - this->unk_3B0.y = (player->actor.world.pos.y + 200.0f) - 160.0f; - this->unk_3B0.z = player->actor.world.pos.z; + this->subCamEye.x = 410.0f; + this->subCamEye.y = 1096.0f; + this->subCamEye.z = -110.0f; + this->subCamAt.x = player->actor.world.pos.x + 10.0f; + this->subCamAt.y = (player->actor.world.pos.y + 200.0f) - 160.0f; + this->subCamAt.z = player->actor.world.pos.z; if (this->csTimer >= 20) { Sfx_PlaySfxCentered(NA_SE_EN_GOMA_LAST - SFX_FLAG); Math_ApproachF(&this->unk_324, 255.0f, 1.0f, 10.0f); @@ -431,12 +431,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { sBossGanon2Zelda->actor.world.pos.z = -186.0f; player->actor.shape.rot.y = -0x4000; sBossGanon2Zelda->actor.shape.rot.y = -0x5000; - this->unk_3A4.x = 450.0f; - this->unk_3A4.y = 1121.0f; - this->unk_3A4.z = -158.0f; - this->unk_3B0.x = (player->actor.world.pos.x - 20.0f) + 2.0f; - this->unk_3B0.y = ((player->actor.world.pos.y + 200.0f) - 151.0f) - 2.0f; - this->unk_3B0.z = player->actor.world.pos.z + 2.0f; + this->subCamEye.x = 450.0f; + this->subCamEye.y = 1121.0f; + this->subCamEye.z = -158.0f; + this->subCamAt.x = (player->actor.world.pos.x - 20.0f) + 2.0f; + this->subCamAt.y = ((player->actor.world.pos.y + 200.0f) - 151.0f) - 2.0f; + this->subCamAt.z = player->actor.world.pos.z + 2.0f; if (this->csTimer == 10) { Sfx_PlaySfxAtPos(&D_80906D6C, NA_SE_EV_STONE_BOUND); } @@ -455,11 +455,11 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->actor.world.pos.y = 1009.0f; this->actor.shape.yOffset = 7000.0f; this->actor.world.rot.y = 0x5000; - this->unk_3A4.x = -60.0f; - this->unk_3A4.y = 1106.0f; - this->unk_3A4.z = -200.0f; - this->unk_3B0.x = this->unk_3B0.z = -200.0f; - this->unk_3B0.y = this->actor.world.pos.y + 70.0f; + this->subCamEye.x = -60.0f; + this->subCamEye.y = 1106.0f; + this->subCamEye.z = -200.0f; + this->subCamAt.x = this->subCamAt.z = -200.0f; + this->subCamAt.y = this->actor.world.pos.y + 70.0f; play->envCtx.unk_D8 = 0.0f; play->envCtx.unk_BE = play->envCtx.unk_BD = 0; this->unk_339 = 0; @@ -479,7 +479,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { } if (this->csTimer >= 30) { Math_ApproachF(&this->actor.world.pos.y, 1289.0f, 0.1f, 10.0f); - this->unk_3B0.y = this->actor.world.pos.y + 70.0f; + this->subCamAt.y = this->actor.world.pos.y + 70.0f; } if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Animation_MorphToLoop(&this->skelAnime, &gGanondorfFloatingHeavyBreathingAnim, 0.0f); @@ -502,25 +502,25 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { sBossGanon2Zelda->actor.world.pos.x = 724.0f; sBossGanon2Zelda->actor.world.pos.y = 1086.0f; sBossGanon2Zelda->actor.world.pos.z = -186.0f; - this->unk_3A4.x = this->actor.world.pos.x + -10.0f; - this->unk_3A4.y = this->actor.world.pos.y + 80.0f; - this->unk_3A4.z = this->actor.world.pos.z + 50.0f; - this->unk_3B0.x = player->actor.world.pos.x; - this->unk_3B0.y = player->actor.world.pos.y; - this->unk_3B0.z = player->actor.world.pos.z - 200.0f; + this->subCamEye.x = this->actor.world.pos.x + -10.0f; + this->subCamEye.y = this->actor.world.pos.y + 80.0f; + this->subCamEye.z = this->actor.world.pos.z + 50.0f; + this->subCamAt.x = player->actor.world.pos.x; + this->subCamAt.y = player->actor.world.pos.y; + this->subCamAt.z = player->actor.world.pos.z - 200.0f; if (this->csTimer == 20) { Player_SetCsActionWithHaltedActors(play, &this->actor, 0x1E); } if (this->csTimer == 60) { - this->unk_3A4.x = (this->actor.world.pos.x + 200.0f) - 154.0f; - this->unk_3A4.y = this->actor.world.pos.y + 60.0f; - this->unk_3A4.z = this->actor.world.pos.z - 15.0f; + this->subCamEye.x = (this->actor.world.pos.x + 200.0f) - 154.0f; + this->subCamEye.y = this->actor.world.pos.y + 60.0f; + this->subCamEye.z = this->actor.world.pos.z - 15.0f; this->csState = 15; this->csTimer = 0; - this->unk_3B0.y = this->actor.world.pos.y + 77.0f + 100.0f; + this->subCamAt.y = this->actor.world.pos.y + 77.0f + 100.0f; this->unk_314 = 2; - this->unk_3B0.z = this->actor.world.pos.z + 5.0f; - this->unk_3B0.x = this->actor.world.pos.x; + this->subCamAt.z = this->actor.world.pos.z + 5.0f; + this->subCamAt.x = this->actor.world.pos.x; } if ((play->gameplayFrames % 32) == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BREATH); @@ -531,7 +531,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BREATH); } SkelAnime_Update(&this->skelAnime); - Math_ApproachF(&this->unk_3B0.y, this->actor.world.pos.y + 77.0f, 0.05f, 5.0f); + Math_ApproachF(&this->subCamAt.y, this->actor.world.pos.y + 77.0f, 0.05f, 5.0f); if (this->csTimer >= 50) { if (this->csTimer == 50) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanondorfShowTriforceStartAnim, 0.0f); @@ -574,9 +574,9 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanondorfTransformEndAnim, 0.0f); this->unk_194 = 1000.0f; } - Math_ApproachF(&this->unk_3A4.x, (this->actor.world.pos.x + 200.0f) - 90.0f, 0.1f, 6.3999996f); - Math_ApproachF(&this->unk_3A4.y, ((this->actor.world.pos.y + 60.0f) - 60.0f) - 70.0f, 0.1f, 13.0f); - Math_ApproachF(&this->unk_3B0.y, this->actor.world.pos.y + 40.0f, 0.1f, 3.6999998f); + Math_ApproachF(&this->subCamEye.x, (this->actor.world.pos.x + 200.0f) - 90.0f, 0.1f, 6.3999996f); + Math_ApproachF(&this->subCamEye.y, ((this->actor.world.pos.y + 60.0f) - 60.0f) - 70.0f, 0.1f, 13.0f); + Math_ApproachF(&this->subCamAt.y, this->actor.world.pos.y + 40.0f, 0.1f, 3.6999998f); if (this->csTimer == 30) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BIGMASIC); Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_THROW_BIG); @@ -587,9 +587,9 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { if (this->csTimer >= 60) { Camera* camera = Play_GetCamera(play, MAIN_CAM); - camera->eye = this->unk_3A4; - camera->eyeNext = this->unk_3A4; - camera->at = this->unk_3B0; + camera->eye = this->subCamEye; + camera->eyeNext = this->subCamEye; + camera->at = this->subCamAt; this->csState = 17; this->csTimer = 0; this->unk_337 = 2; @@ -610,29 +610,29 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { } // fake, tricks the compiler into using stack the way we need it to if (zero) { - Math_ApproachF(&this->unk_3B0.y, 0.0f, 0.0f, 0.0f); + Math_ApproachF(&this->subCamAt.y, 0.0f, 0.0f, 0.0f); } break; case 17: this->unk_339 = 6; SkelAnime_Update(&this->skelAnime); - this->unk_3A4.x = player->actor.world.pos.x - 40.0f; - this->unk_3A4.y = player->actor.world.pos.y + 40.0f; - this->unk_3A4.z = player->actor.world.pos.z + 20.0f; - this->unk_3B0.x = player->actor.world.pos.x; - this->unk_3B0.y = (player->actor.world.pos.y + 10.0f + 60.0f) - 30.0f; - this->unk_3B0.z = player->actor.world.pos.z; + this->subCamEye.x = player->actor.world.pos.x - 40.0f; + this->subCamEye.y = player->actor.world.pos.y + 40.0f; + this->subCamEye.z = player->actor.world.pos.z + 20.0f; + this->subCamAt.x = player->actor.world.pos.x; + this->subCamAt.y = (player->actor.world.pos.y + 10.0f + 60.0f) - 30.0f; + this->subCamAt.z = player->actor.world.pos.z; if (this->csTimer == 25) { this->csState = 18; this->csTimer = 0; Animation_MorphToPlayOnce(&this->skelAnime, &gGanonUncurlAndFlailAnim, 0.0f); this->skelAnime.playSpeed = 0.0f; - this->unk_3A4.x = ((this->actor.world.pos.x + 500.0f) - 350.0f) - 50.0f; - this->unk_3A4.y = this->actor.world.pos.y; - this->unk_3A4.z = this->actor.world.pos.z; - this->unk_3B0.x = this->actor.world.pos.x + 50.0f; - this->unk_3B0.y = this->actor.world.pos.y + 60.0f; - this->unk_3B0.z = this->actor.world.pos.z; + this->subCamEye.x = ((this->actor.world.pos.x + 500.0f) - 350.0f) - 50.0f; + this->subCamEye.y = this->actor.world.pos.y; + this->subCamEye.z = this->actor.world.pos.z; + this->subCamAt.x = this->actor.world.pos.x + 50.0f; + this->subCamAt.y = this->actor.world.pos.y + 60.0f; + this->subCamAt.z = this->actor.world.pos.z; this->actor.world.rot.y = 0x4000; } break; @@ -642,8 +642,8 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_GANON_BOSS); } Math_ApproachF(&this->unk_30C, 7.0f, 1.0f, 0.1f); - Math_ApproachF(&this->unk_3A4.x, (this->actor.world.pos.x + 500.0f) - 350.0f, 0.1f, 1.0f); - Math_ApproachF(&this->unk_3B0.x, this->actor.world.pos.x, 0.1f, 1.0f); + Math_ApproachF(&this->subCamEye.x, (this->actor.world.pos.x + 500.0f) - 350.0f, 0.1f, 1.0f); + Math_ApproachF(&this->subCamAt.x, this->actor.world.pos.x, 0.1f, 1.0f); Math_ApproachF(&this->unk_228, 1.0f, 0.1f, 0.02f); if (this->csTimer == 65) { this->csState = 19; @@ -675,13 +675,13 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -266.0f; player->actor.shape.rot.y = -0x4000; - this->unk_3A4.x = (player->actor.world.pos.x - 40.0f) - 200.0f; - this->unk_3A4.y = (player->actor.world.pos.y + 40.0f) - 30.0f; - this->unk_3A4.z = (player->actor.world.pos.z - 20.0f) + 100.0f; - this->unk_3B0.x = player->actor.world.pos.x; - this->unk_3B0.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) + 30.0f; - this->unk_3B0.z = player->actor.world.pos.z; - this->unk_3BC.x = 0.8f; + this->subCamEye.x = (player->actor.world.pos.x - 40.0f) - 200.0f; + this->subCamEye.y = (player->actor.world.pos.y + 40.0f) - 30.0f; + this->subCamEye.z = (player->actor.world.pos.z - 20.0f) + 100.0f; + this->subCamAt.x = player->actor.world.pos.x; + this->subCamAt.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) + 30.0f; + this->subCamAt.z = player->actor.world.pos.z; + this->subCamUp.x = 0.8f; if (this->actor.world.pos.y <= 1099.0f) { this->actor.world.pos.y = 1099.0f; this->csState = 21; @@ -708,7 +708,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { if (this->csTimer < 60) { this->unk_339 = 7; } - this->unk_3BC.x = 0.0f; + this->subCamUp.x = 0.0f; this->actor.world.pos.y = 1099.0f; SkelAnime_Update(&this->skelAnime); Math_ApproachZeroF(&this->unk_30C, 1.0f, 0.1f); @@ -724,12 +724,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { 180, 128, 40, true); // It has translation but they are all the same. they all say "GANON" only } - this->unk_3A4.x = ((this->actor.world.pos.x + 500.0f) - 350.0f) + 100.0f; - this->unk_3A4.y = this->actor.world.pos.y; - this->unk_3A4.z = this->actor.world.pos.z; - this->unk_3B0.x = this->actor.world.pos.x; - this->unk_3B0.z = this->actor.world.pos.z; - this->unk_3B0.y = (this->unk_1B8.y + 60.0f) - 40.0f; + this->subCamEye.x = ((this->actor.world.pos.x + 500.0f) - 350.0f) + 100.0f; + this->subCamEye.y = this->actor.world.pos.y; + this->subCamEye.z = this->actor.world.pos.z; + this->subCamAt.x = this->actor.world.pos.x; + this->subCamAt.z = this->actor.world.pos.z; + this->subCamAt.y = (this->unk_1B8.y + 60.0f) - 40.0f; if (this->csTimer > 166 && this->csTimer < 173) { this->unk_312 = 2; } @@ -758,12 +758,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { Sfx_PlaySfxCentered(NA_SE_EN_MGANON_SWORD); Sfx_PlaySfxCentered(NA_SE_EN_MGANON_ROAR); } - this->unk_3A4.x = (player->actor.world.pos.x - 40.0f) + 6.0f; - this->unk_3A4.y = player->actor.world.pos.y + 40.0f; - this->unk_3A4.z = (player->actor.world.pos.z + 20.0f) - 7.0f; - this->unk_3B0.x = player->actor.world.pos.x; - this->unk_3B0.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) - 2.0f; - this->unk_3B0.z = player->actor.world.pos.z; + this->subCamEye.x = (player->actor.world.pos.x - 40.0f) + 6.0f; + this->subCamEye.y = player->actor.world.pos.y + 40.0f; + this->subCamEye.z = (player->actor.world.pos.z + 20.0f) - 7.0f; + this->subCamAt.x = player->actor.world.pos.x; + this->subCamAt.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) - 2.0f; + this->subCamAt.z = player->actor.world.pos.z; if (this->csTimer == 228) { Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_REFLECT_SW); Player_SetCsActionWithHaltedActors(play, &this->actor, 0x56); @@ -794,10 +794,10 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { if (1) { BossGanon2Effect* effect = play->specialEffects; - this->unk_3B0 = effect->position; - this->unk_3A4.x = effect->position.x + 70.0f; - this->unk_3A4.y = effect->position.y - 30.0f; - this->unk_3A4.z = effect->position.z + 70.0f; + this->subCamAt = effect->position; + this->subCamEye.x = effect->position.x + 70.0f; + this->subCamEye.y = effect->position.y - 30.0f; + this->subCamEye.z = effect->position.z + 70.0f; } if ((this->csTimer & 3) == 0) { Sfx_PlaySfxCentered(NA_SE_IT_SWORD_SWING); @@ -810,12 +810,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { break; case 25: SkelAnime_Update(&this->skelAnime); - this->unk_3A4.x = (player->actor.world.pos.x - 40.0f) + 80.0f; - this->unk_3A4.y = player->actor.world.pos.y + 40.0f + 10.0f; - this->unk_3A4.z = player->actor.world.pos.z + 20.0f + 10.0f; - this->unk_3B0.x = player->actor.world.pos.x - 20.0f; - this->unk_3B0.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) - 3.0f; - this->unk_3B0.z = (player->actor.world.pos.z - 40.0f) - 10.0f; + this->subCamEye.x = (player->actor.world.pos.x - 40.0f) + 80.0f; + this->subCamEye.y = player->actor.world.pos.y + 40.0f + 10.0f; + this->subCamEye.z = player->actor.world.pos.z + 20.0f + 10.0f; + this->subCamAt.x = player->actor.world.pos.x - 20.0f; + this->subCamAt.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) - 3.0f; + this->subCamAt.z = (player->actor.world.pos.z - 40.0f) - 10.0f; if (this->csTimer == 10) { BossGanon2Effect* effect = play->specialEffects; @@ -832,13 +832,13 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { break; } case 26: - this->unk_3A4.x = sBossGanon2Zelda->actor.world.pos.x + 100.0f + 30.0f; - this->unk_3A4.y = sBossGanon2Zelda->actor.world.pos.y + 10.0f; - this->unk_3A4.z = sBossGanon2Zelda->actor.world.pos.z + 5.0f; - this->unk_3B0.x = sBossGanon2Zelda->actor.world.pos.x; - this->unk_3B0.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; - this->unk_3B0.z = sBossGanon2Zelda->actor.world.pos.z - 20.0f; - this->unk_3BC.z = -0.5f; + this->subCamEye.x = sBossGanon2Zelda->actor.world.pos.x + 100.0f + 30.0f; + this->subCamEye.y = sBossGanon2Zelda->actor.world.pos.y + 10.0f; + this->subCamEye.z = sBossGanon2Zelda->actor.world.pos.z + 5.0f; + this->subCamAt.x = sBossGanon2Zelda->actor.world.pos.x; + this->subCamAt.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; + this->subCamAt.z = sBossGanon2Zelda->actor.world.pos.z - 20.0f; + this->subCamUp.z = -0.5f; if (this->csTimer == 13) { sBossGanon2Zelda->unk_3C8 = 6; } @@ -848,26 +848,26 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { } break; case 27: - this->unk_3BC.z = 0.0f; + this->subCamUp.z = 0.0f; if (this->csTimer == 4) { Player_SetCsActionWithHaltedActors(play, &this->actor, 0x58); } - this->unk_3A4.x = player->actor.world.pos.x - 20.0f; - this->unk_3A4.y = player->actor.world.pos.y + 50.0f; - this->unk_3A4.z = player->actor.world.pos.z; - this->unk_3B0.x = player->actor.world.pos.x; - this->unk_3B0.y = player->actor.world.pos.y + 50.0f; - this->unk_3B0.z = player->actor.world.pos.z; + this->subCamEye.x = player->actor.world.pos.x - 20.0f; + this->subCamEye.y = player->actor.world.pos.y + 50.0f; + this->subCamEye.z = player->actor.world.pos.z; + this->subCamAt.x = player->actor.world.pos.x; + this->subCamAt.y = player->actor.world.pos.y + 50.0f; + this->subCamAt.z = player->actor.world.pos.z; if (this->csTimer == 26) { D_8090EB30 = play->actorCtx.actorLists[ACTORCAT_ITEMACTION].head; while (D_8090EB30 != NULL) { if (D_8090EB30->id == ACTOR_EN_ELF) { - this->unk_3A4.x = D_8090EB30->world.pos.x - 30.0f; - this->unk_3A4.y = D_8090EB30->world.pos.y; - this->unk_3A4.z = D_8090EB30->world.pos.z; - this->unk_3B0.x = D_8090EB30->world.pos.x; - this->unk_3B0.y = D_8090EB30->world.pos.y; - this->unk_3B0.z = D_8090EB30->world.pos.z; + this->subCamEye.x = D_8090EB30->world.pos.x - 30.0f; + this->subCamEye.y = D_8090EB30->world.pos.y; + this->subCamEye.z = D_8090EB30->world.pos.z; + this->subCamAt.x = D_8090EB30->world.pos.x; + this->subCamAt.y = D_8090EB30->world.pos.y; + this->subCamAt.z = D_8090EB30->world.pos.z; break; } D_8090EB30 = D_8090EB30->next; @@ -881,12 +881,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { Message_StartTextbox(play, 0x70D6, NULL); } if (D_8090EB30 != NULL) { - this->unk_3A4.x = D_8090EB30->world.pos.x - 20.0f; - this->unk_3A4.y = D_8090EB30->world.pos.y; - this->unk_3A4.z = D_8090EB30->world.pos.z; - Math_ApproachF(&this->unk_3B0.x, D_8090EB30->world.pos.x, 0.2f, 50.0f); - Math_ApproachF(&this->unk_3B0.y, D_8090EB30->world.pos.y, 0.2f, 50.0f); - Math_ApproachF(&this->unk_3B0.z, D_8090EB30->world.pos.z, 0.2f, 50.0f); + this->subCamEye.x = D_8090EB30->world.pos.x - 20.0f; + this->subCamEye.y = D_8090EB30->world.pos.y; + this->subCamEye.z = D_8090EB30->world.pos.z; + Math_ApproachF(&this->subCamAt.x, D_8090EB30->world.pos.x, 0.2f, 50.0f); + Math_ApproachF(&this->subCamAt.y, D_8090EB30->world.pos.y, 0.2f, 50.0f); + Math_ApproachF(&this->subCamAt.z, D_8090EB30->world.pos.z, 0.2f, 50.0f); if ((this->csTimer > 40) && (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE)) { this->csState = 29; this->csTimer = 0; @@ -902,12 +902,12 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { break; case 29: SkelAnime_Update(&this->skelAnime); - this->unk_3A4.x = (((this->actor.world.pos.x + 500.0f) - 350.0f) + 100.0f) - 60.0f; - this->unk_3B0.x = this->actor.world.pos.x; - this->unk_3B0.z = this->actor.world.pos.z; - this->unk_3A4.y = this->actor.world.pos.y; - this->unk_3A4.z = this->actor.world.pos.z + 10.0f; - this->unk_3B0.y = (this->unk_1B8.y + 60.0f) - 40.0f; + this->subCamEye.x = (((this->actor.world.pos.x + 500.0f) - 350.0f) + 100.0f) - 60.0f; + this->subCamAt.x = this->actor.world.pos.x; + this->subCamAt.z = this->actor.world.pos.z; + this->subCamEye.y = this->actor.world.pos.y; + this->subCamEye.z = this->actor.world.pos.z + 10.0f; + this->subCamAt.y = (this->unk_1B8.y + 60.0f) - 40.0f; player->actor.shape.rot.y = -0x4000; player->actor.world.pos.x = 140.0f; player->actor.world.pos.z = -196.0f; @@ -917,11 +917,11 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Camera* camera = Play_GetCamera(play, MAIN_CAM); - camera->eye = this->unk_3A4; - camera->eyeNext = this->unk_3A4; - camera->at = this->unk_3B0; - func_800C08AC(play, this->unk_39E, 0); - this->unk_39E = 0; + camera->eye = this->subCamEye; + camera->eyeNext = this->subCamEye; + camera->at = this->subCamAt; + func_800C08AC(play, this->subCamId, 0); + this->subCamId = 0; func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->csState = 0; @@ -938,18 +938,18 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BODY_SPARK - SFX_FLAG); } - if (this->unk_39E != 0) { + if (this->subCamId != 0) { // fake, tricks the compiler into putting some pointers on the stack if (zero) { osSyncPrintf(NULL, 0, 0); } - this->unk_3B0.y += this->unk_41C; - Play_CameraSetAtEyeUp(play, this->unk_39E, &this->unk_3B0, &this->unk_3A4, &this->unk_3BC); + this->subCamAt.y += this->unk_41C; + Play_CameraSetAtEyeUp(play, this->subCamId, &this->subCamAt, &this->subCamEye, &this->subCamUp); } } void func_808FF898(BossGanon2* this, PlayState* play) { - if ((this->unk_312 != 0) && (this->unk_39E == 0)) { + if ((this->unk_312 != 0) && (this->subCamId == 0)) { Actor* actor = play->actorCtx.actorLists[ACTORCAT_PROP].head; while (actor != NULL) { if (actor->id == ACTOR_DEMO_GJ) { @@ -1341,13 +1341,13 @@ void func_80900890(BossGanon2* this, PlayState* play) { switch (this->csState) { case 0: func_80064520(play, &play->csCtx); - this->unk_39E = Play_CreateSubCamera(play); + this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); + Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csState = 1; - this->unk_3A4 = sp4C->eye; - this->unk_3B0 = sp4C->at; + this->subCamEye = sp4C->eye; + this->subCamAt = sp4C->at; this->unk_1A2[0] = 300; this->unk_1A2[1] = 100; play->envCtx.unk_D8 = 0.0f; @@ -1360,12 +1360,12 @@ void func_80900890(BossGanon2* this, PlayState* play) { sp5C.y = 0.0f; sp5C.z = 250.0f; Matrix_MultVec3f(&sp5C, &sp50); - Math_ApproachF(&this->unk_3A4.x, this->actor.world.pos.x + sp50.x, 0.2f, 100.0f); - Math_ApproachF(&this->unk_3A4.y, 1136.0f, 0.2f, 100.0f); - Math_ApproachF(&this->unk_3A4.z, this->actor.world.pos.z + sp50.z, 0.2f, 100.0f); - Math_ApproachF(&this->unk_3B0.x, this->unk_1B8.x, 0.2f, 100.0f); - Math_ApproachF(&this->unk_3B0.y, this->unk_1B8.y, 0.2f, 100.0f); - Math_ApproachF(&this->unk_3B0.z, this->unk_1B8.z, 0.2f, 100.0f); + Math_ApproachF(&this->subCamEye.x, this->actor.world.pos.x + sp50.x, 0.2f, 100.0f); + Math_ApproachF(&this->subCamEye.y, 1136.0f, 0.2f, 100.0f); + Math_ApproachF(&this->subCamEye.z, this->actor.world.pos.z + sp50.z, 0.2f, 100.0f); + Math_ApproachF(&this->subCamAt.x, this->unk_1B8.x, 0.2f, 100.0f); + Math_ApproachF(&this->subCamAt.y, this->unk_1B8.y, 0.2f, 100.0f); + Math_ApproachF(&this->subCamAt.z, this->unk_1B8.z, 0.2f, 100.0f); if (this->unk_1A2[1] == 0) { this->csState = 2; this->unk_1A2[1] = 90; @@ -1373,12 +1373,12 @@ void func_80900890(BossGanon2* this, PlayState* play) { break; case 2: this->unk_1A2[0] = 300; - this->unk_3A4.x = sBossGanon2Zelda->actor.world.pos.x - 100.0f; - this->unk_3A4.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; - this->unk_3A4.z = (sBossGanon2Zelda->actor.world.pos.z + 30.0f) - 60.0f; - this->unk_3B0.x = sBossGanon2Zelda->actor.world.pos.x; - this->unk_3B0.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; - this->unk_3B0.z = sBossGanon2Zelda->actor.world.pos.z - 10.0f; + this->subCamEye.x = sBossGanon2Zelda->actor.world.pos.x - 100.0f; + this->subCamEye.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; + this->subCamEye.z = (sBossGanon2Zelda->actor.world.pos.z + 30.0f) - 60.0f; + this->subCamAt.x = sBossGanon2Zelda->actor.world.pos.x; + this->subCamAt.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; + this->subCamAt.z = sBossGanon2Zelda->actor.world.pos.z - 10.0f; Math_ApproachZeroF(&this->unk_324, 1.0f, 5.0f); Math_ApproachF(&play->envCtx.unk_D8, 1.0f, 1.0f, 1.0f / 51); if (this->unk_1A2[1] == 80) { @@ -1386,11 +1386,11 @@ void func_80900890(BossGanon2* this, PlayState* play) { } if ((this->unk_1A2[1] < 30) && (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE)) { temp_v0 = Play_GetCamera(play, MAIN_CAM); - temp_v0->eye = this->unk_3A4; - temp_v0->eyeNext = this->unk_3A4; - temp_v0->at = this->unk_3B0; - func_800C08AC(play, this->unk_39E, 0); - this->unk_39E = 0; + temp_v0->eye = this->subCamEye; + temp_v0->eyeNext = this->subCamEye; + temp_v0->at = this->subCamAt; + func_800C08AC(play, this->subCamId, 0); + this->subCamId = 0; func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->csState = 3; @@ -1398,9 +1398,9 @@ void func_80900890(BossGanon2* this, PlayState* play) { break; case 10: func_80064520(play, &play->csCtx); - this->unk_39E = Play_CreateSubCamera(play); + this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); + Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); this->csState = 11; this->unk_334 = 1; Player_SetCsActionWithHaltedActors(play, &this->actor, 0x60); @@ -1409,28 +1409,28 @@ void func_80900890(BossGanon2* this, PlayState* play) { player->actor.world.pos.x = sBossGanon2Zelda->actor.world.pos.x + 50.0f + 10.0f; player->actor.world.pos.z = sBossGanon2Zelda->actor.world.pos.z - 25.0f; player->actor.shape.rot.y = -0x8000; - this->unk_3A4.x = (player->actor.world.pos.x + 100.0f) - 80.0f; - this->unk_3A4.y = (player->actor.world.pos.y + 60.0f) - 40.0f; - this->unk_3A4.z = player->actor.world.pos.z - 110.0f; - this->unk_3B0.x = player->actor.world.pos.x; - this->unk_3B0.y = (player->actor.world.pos.y + 60.0f) - 25.0f; - this->unk_3B0.z = player->actor.world.pos.z; + this->subCamEye.x = (player->actor.world.pos.x + 100.0f) - 80.0f; + this->subCamEye.y = (player->actor.world.pos.y + 60.0f) - 40.0f; + this->subCamEye.z = player->actor.world.pos.z - 110.0f; + this->subCamAt.x = player->actor.world.pos.x; + this->subCamAt.y = (player->actor.world.pos.y + 60.0f) - 25.0f; + this->subCamAt.z = player->actor.world.pos.z; if (this->csTimer == 80) { temp_v0_2 = Play_GetCamera(play, MAIN_CAM); - temp_v0_2->eye = this->unk_3A4; - temp_v0_2->eyeNext = this->unk_3A4; - temp_v0_2->at = this->unk_3B0; + temp_v0_2->eye = this->subCamEye; + temp_v0_2->eyeNext = this->subCamEye; + temp_v0_2->at = this->subCamAt; this->csState = 3; - func_800C08AC(play, this->unk_39E, 0); - this->unk_39E = 0; + func_800C08AC(play, this->subCamId, 0); + this->subCamId = 0; func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); } break; } - if (this->unk_39E != 0) { - Play_CameraSetAtEye(play, this->unk_39E, &this->unk_3B0, &this->unk_3A4); + if (this->subCamId != 0) { + Play_CameraSetAtEye(play, this->subCamId, &this->subCamAt, &this->subCamEye); } switch (this->unk_1AC) { @@ -1529,16 +1529,16 @@ void func_8090120C(BossGanon2* this, PlayState* play) { this->csTimer++; SkelAnime_Update(&this->skelAnime); - this->unk_3BC.x = 0.0f; - this->unk_3BC.y = 1.0f; - this->unk_3BC.z = 0.0f; + this->subCamUp.x = 0.0f; + this->subCamUp.y = 1.0f; + this->subCamUp.z = 0.0f; switch (this->csState) { case 0: func_80064520(play, &play->csCtx); - this->unk_39E = Play_CreateSubCamera(play); + this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); + Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csState = 1; this->csTimer = 0; @@ -1585,12 +1585,12 @@ void func_8090120C(BossGanon2* this, PlayState* play) { sBossGanon2Zelda->actor.world.pos.x = 340.0f; sBossGanon2Zelda->actor.world.pos.z = -250.0f; sBossGanon2Zelda->actor.world.rot.y = sBossGanon2Zelda->actor.shape.rot.y = -0x2000; - this->unk_3A4.x = 250; - this->unk_3A4.y = 1150.0f; - this->unk_3A4.z = 0.0f; - this->unk_3B0.x = this->unk_1B8.x; - this->unk_3B0.y = this->unk_1B8.y; - this->unk_3B0.z = this->unk_1B8.z; + this->subCamEye.x = 250; + this->subCamEye.y = 1150.0f; + this->subCamEye.z = 0.0f; + this->subCamAt.x = this->unk_1B8.x; + this->subCamAt.y = this->unk_1B8.y; + this->subCamAt.z = this->unk_1B8.z; if (this->csTimer > 135) { this->csState = 2; this->csTimer = 0; @@ -1600,12 +1600,12 @@ void func_8090120C(BossGanon2* this, PlayState* play) { this->unk_339 = 22; Math_ApproachF(&play->envCtx.unk_D8, 1.0f, 1.0f, 0.1f); Sfx_PlaySfxCentered(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); - this->unk_3A4.x = 250; - this->unk_3A4.y = 1150.0f; - this->unk_3A4.z = 0.0f; - Math_ApproachF(&this->unk_3B0.x, sBossGanon2Zelda->actor.world.pos.x, 0.2f, 20.0f); - Math_ApproachF(&this->unk_3B0.y, sBossGanon2Zelda->actor.world.pos.y + 50.0f, 0.2f, 10.0f); - Math_ApproachF(&this->unk_3B0.z, sBossGanon2Zelda->actor.world.pos.z, 0.2f, 20.0f); + this->subCamEye.x = 250; + this->subCamEye.y = 1150.0f; + this->subCamEye.z = 0.0f; + Math_ApproachF(&this->subCamAt.x, sBossGanon2Zelda->actor.world.pos.x, 0.2f, 20.0f); + Math_ApproachF(&this->subCamAt.y, sBossGanon2Zelda->actor.world.pos.y + 50.0f, 0.2f, 10.0f); + Math_ApproachF(&this->subCamAt.z, sBossGanon2Zelda->actor.world.pos.z, 0.2f, 20.0f); if (this->csTimer == 50) { this->csState = 3; this->csTimer = 0; @@ -1614,12 +1614,12 @@ void func_8090120C(BossGanon2* this, PlayState* play) { case 3: this->unk_339 = 22; Sfx_PlaySfxCentered(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); - this->unk_3A4.x = 330.0f; - this->unk_3A4.y = 1120.0f; - this->unk_3A4.z = -150.0f; - this->unk_3B0.x = sBossGanon2Zelda->actor.world.pos.x; - this->unk_3B0.y = sBossGanon2Zelda->actor.world.pos.y + 40.0f; - this->unk_3B0.z = sBossGanon2Zelda->actor.world.pos.z; + this->subCamEye.x = 330.0f; + this->subCamEye.y = 1120.0f; + this->subCamEye.z = -150.0f; + this->subCamAt.x = sBossGanon2Zelda->actor.world.pos.x; + this->subCamAt.y = sBossGanon2Zelda->actor.world.pos.y + 40.0f; + this->subCamAt.z = sBossGanon2Zelda->actor.world.pos.z; if (this->csTimer == 10) { Message_StartTextbox(play, 0x70D8, NULL); } @@ -1665,19 +1665,19 @@ void func_8090120C(BossGanon2* this, PlayState* play) { this->unk_30C = 10.0f; player->actor.world.pos.x = 250.0f; player->actor.world.pos.z = 30.0f; - this->unk_3A4.x = player->actor.world.pos.x - 50.0f; - this->unk_3A4.y = player->actor.world.pos.y + 50.0f; - this->unk_3A4.z = player->actor.world.pos.z + 40.0f; - this->unk_3B0.x = player->actor.world.pos.x; - this->unk_3B0.y = player->actor.world.pos.y + 40.0f; - this->unk_3B0.z = player->actor.world.pos.z; + this->subCamEye.x = player->actor.world.pos.x - 50.0f; + this->subCamEye.y = player->actor.world.pos.y + 50.0f; + this->subCamEye.z = player->actor.world.pos.z + 40.0f; + this->subCamAt.x = player->actor.world.pos.x; + this->subCamAt.y = player->actor.world.pos.y + 40.0f; + this->subCamAt.z = player->actor.world.pos.z; if (this->csTimer == 166) { temp_v0_2 = Play_GetCamera(play, MAIN_CAM); - temp_v0_2->eye = this->unk_3A4; - temp_v0_2->eyeNext = this->unk_3A4; - temp_v0_2->at = this->unk_3B0; - func_800C08AC(play, this->unk_39E, 0); - this->unk_39E = 0; + temp_v0_2->eye = this->subCamEye; + temp_v0_2->eyeNext = this->subCamEye; + temp_v0_2->at = this->subCamAt; + func_800C08AC(play, this->subCamId, 0); + this->subCamId = 0; func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->csState = 6; @@ -1692,9 +1692,9 @@ void func_8090120C(BossGanon2* this, PlayState* play) { (player->meleeWeaponState != 0) && (player->heldItemAction == PLAYER_IA_SWORD_MASTER)) { func_80064520(play, &play->csCtx); GameInteractor_ExecuteOnBossDefeat(&this->actor); - this->unk_39E = Play_CreateSubCamera(play); + this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); + Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); this->csState = 7; this->csTimer = 0; Animation_MorphToPlayOnce(&this->skelAnime, &gGanonFinalBlowAnim, 0.0f); @@ -1722,42 +1722,42 @@ void func_8090120C(BossGanon2* this, PlayState* play) { func_8090109C(this, play); } if ((this->csTimer >= 34) && (this->csTimer < 40)) { - this->unk_3A4.x = 269.0f; - this->unk_3A4.y = 1112.0f; - this->unk_3A4.z = -28.0f; - this->unk_3B0.x = 234.0f; - this->unk_3B0.y = 1117.0f; - this->unk_3B0.z = -11.0f; + this->subCamEye.x = 269.0f; + this->subCamEye.y = 1112.0f; + this->subCamEye.z = -28.0f; + this->subCamAt.x = 234.0f; + this->subCamAt.y = 1117.0f; + this->subCamAt.z = -11.0f; } else { if (this->csTimer < 30) { phi_a1 = 0; } else if (this->csTimer < 43) { phi_a1 = 1; } else { - this->unk_3BC.z = -0.8f; + this->subCamUp.z = -0.8f; player->actor.world.pos.x = 200.0f; player->actor.world.pos.z = 10.0f; phi_a1 = 2; } - this->unk_3A4.x = D_8090702C[phi_a1].x + (player->actor.world.pos.x - 50.0f); - this->unk_3A4.y = D_8090702C[phi_a1].y + (player->actor.world.pos.y + 50.0f); - this->unk_3A4.z = D_8090702C[phi_a1].z + (player->actor.world.pos.z + 40.0f); - this->unk_3B0.x = D_80907050[phi_a1].x + player->actor.world.pos.x; - this->unk_3B0.y = D_80907050[phi_a1].y + (player->actor.world.pos.y + 40.0f); - this->unk_3B0.z = D_80907050[phi_a1].z + player->actor.world.pos.z; + this->subCamEye.x = D_8090702C[phi_a1].x + (player->actor.world.pos.x - 50.0f); + this->subCamEye.y = D_8090702C[phi_a1].y + (player->actor.world.pos.y + 50.0f); + this->subCamEye.z = D_8090702C[phi_a1].z + (player->actor.world.pos.z + 40.0f); + this->subCamAt.x = D_80907050[phi_a1].x + player->actor.world.pos.x; + this->subCamAt.y = D_80907050[phi_a1].y + (player->actor.world.pos.y + 40.0f); + this->subCamAt.z = D_80907050[phi_a1].z + player->actor.world.pos.z; } if (this->csTimer > 80) { Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); this->csState = 75; this->csTimer = 0; - this->unk_3A4.x = 112.0f; - this->unk_3A4.y = 1146.0f; - this->unk_3A4.z = 202.0f; - this->unk_3B0.x = 110.0f; - this->unk_3B0.y = 1144.0f; - this->unk_3B0.z = 177.0f; + this->subCamEye.x = 112.0f; + this->subCamEye.y = 1146.0f; + this->subCamEye.z = 202.0f; + this->subCamAt.x = 110.0f; + this->subCamAt.y = 1144.0f; + this->subCamAt.z = 177.0f; player->actor.world.pos.x = 200.0f; - this->unk_3BC.z = 0.0f; + this->subCamUp.z = 0.0f; } break; case 75: @@ -1792,12 +1792,12 @@ void func_8090120C(BossGanon2* this, PlayState* play) { this->csTimer = 0; this->unk_194 = 1000.0f; } - this->unk_3A4.x = 250; - this->unk_3A4.y = 1150.0f; - this->unk_3A4.z = 0.0f; - this->unk_3B0.x = this->unk_1B8.x; - this->unk_3B0.y = this->unk_1B8.y; - this->unk_3B0.z = this->unk_1B8.z; + this->subCamEye.x = 250; + this->subCamEye.y = 1150.0f; + this->subCamEye.z = 0.0f; + this->subCamAt.x = this->unk_1B8.x; + this->subCamAt.y = this->unk_1B8.y; + this->subCamAt.z = this->unk_1B8.z; if ((this->csTimer < 1000) && ((this->csTimer % 16) == 0)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_SWORD); } @@ -1812,12 +1812,12 @@ void func_8090120C(BossGanon2* this, PlayState* play) { break; case 9: this->unk_339 = 24; - this->unk_3A4.x = 330.0f; - this->unk_3A4.y = 1120.0f; - this->unk_3A4.z = -150.0f; - this->unk_3B0.x = sBossGanon2Zelda->actor.world.pos.x; - this->unk_3B0.y = sBossGanon2Zelda->actor.world.pos.y + 40.0f; - this->unk_3B0.z = sBossGanon2Zelda->actor.world.pos.z; + this->subCamEye.x = 330.0f; + this->subCamEye.y = 1120.0f; + this->subCamEye.z = -150.0f; + this->subCamAt.x = sBossGanon2Zelda->actor.world.pos.x; + this->subCamAt.y = sBossGanon2Zelda->actor.world.pos.y + 40.0f; + this->subCamAt.z = sBossGanon2Zelda->actor.world.pos.z; if (this->csTimer > 60) { this->csState = 10; this->csTimer = 0; @@ -1826,9 +1826,9 @@ void func_8090120C(BossGanon2* this, PlayState* play) { break; case 10: this->unk_339 = 24; - Math_ApproachF(&this->unk_3A4.x, 290.0f, 0.05f, this->unk_410.x); - Math_ApproachF(&this->unk_3A4.y, 1130.0f, 0.05f, this->unk_410.x * 0.25f); - Math_ApproachF(&this->unk_3A4.z, -260.0f, 0.05f, this->unk_410.x * 1.25f); + Math_ApproachF(&this->subCamEye.x, 290.0f, 0.05f, this->unk_410.x); + Math_ApproachF(&this->subCamEye.y, 1130.0f, 0.05f, this->unk_410.x * 0.25f); + Math_ApproachF(&this->subCamEye.z, -260.0f, 0.05f, this->unk_410.x * 1.25f); if ((this->csTimer >= 40) && (this->csTimer <= 110)) { Math_ApproachF(&play->envCtx.unk_D8, 1.0f, 1.0f, 0.02f); Math_ApproachF(&this->unk_384, 10.0f, 0.1f, 0.2f); @@ -1837,10 +1837,10 @@ void func_8090120C(BossGanon2* this, PlayState* play) { Math_ApproachZeroF(&this->unk_384, 1.0f, 0.2f); } if (this->csTimer > 130) { - Math_ApproachF(&this->unk_3B0.y, (sBossGanon2Zelda->actor.world.pos.y + 40.0f + 10.0f) - 20.0f, 0.1f, + Math_ApproachF(&this->subCamAt.y, (sBossGanon2Zelda->actor.world.pos.y + 40.0f + 10.0f) - 20.0f, 0.1f, this->unk_410.x); } else { - Math_ApproachF(&this->unk_3B0.y, sBossGanon2Zelda->actor.world.pos.y + 40.0f + 10.0f, 0.05f, + Math_ApproachF(&this->subCamAt.y, sBossGanon2Zelda->actor.world.pos.y + 40.0f + 10.0f, 0.05f, this->unk_410.x * 0.25f); } Math_ApproachF(&this->unk_410.x, 1.0f, 1.0f, 0.01f); @@ -1865,8 +1865,8 @@ void func_8090120C(BossGanon2* this, PlayState* play) { break; } - if (this->unk_39E != 0) { - Play_CameraSetAtEyeUp(play, this->unk_39E, &this->unk_3B0, &this->unk_3A4, &this->unk_3BC); + if (this->subCamId != 0) { + Play_CameraSetAtEyeUp(play, this->subCamId, &this->subCamAt, &this->subCamEye, &this->subCamUp); } switch (this->unk_1AC) { @@ -1930,7 +1930,7 @@ void func_80902348(BossGanon2* this, PlayState* play) { } } -void func_80902524(BossGanon2* this, PlayState* play) { +void BossGanon2_CollisionCheck(BossGanon2* this, PlayState* play) { s8 temp_v0_4; ColliderInfo* acHitInfo; s16 i; @@ -2117,11 +2117,11 @@ void BossGanon2_Update(Actor* thisx, PlayState* play) { func_80902348(this, play); CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk_424.base); if (this->actionFunc != func_8090120C) { - func_80902524(this, play); + BossGanon2_CollisionCheck(this, play); CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk_424.base); CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk_444.base); CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk_444.base); - if (this->unk_39E == 0) { + if (this->subCamId == 0) { CollisionCheck_SetAT(play, &play->colChkCtx, &this->unk_444.base); } } @@ -2241,7 +2241,7 @@ void BossGanon2_Update(Actor* thisx, PlayState* play) { } } this->unk_388 += 0.15f; - func_80905DA8(this, play); + BossGanon2_UpdateEffects(this, play); } void func_809034E4(Vec3f* arg0, Vec3f* arg1) { @@ -2869,10 +2869,10 @@ void BossGanon2_Draw(Actor* thisx, PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); - func_809060E8(play); + BossGanon2_DrawEffects(play); } -void func_80905DA8(BossGanon2* this, PlayState* play) { +void BossGanon2_UpdateEffects(BossGanon2* this, PlayState* play) { s32 pad[5]; Player* player = GET_PLAYER(play); BossGanon2Effect* effect = play->specialEffects; @@ -2939,7 +2939,7 @@ void func_80905DA8(BossGanon2* this, PlayState* play) { } } -void func_809060E8(PlayState* play) { +void BossGanon2_DrawEffects(PlayState* play) { s16 alpha; u8 usingObjectGEff = false; BossGanon2Effect* effect; diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.h b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.h index 43539c1e8d..b7e2c12a04 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.h +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.h @@ -93,11 +93,11 @@ typedef struct BossGanon2 { /* 0x0394 */ f32 unk_394; /* 0x0398 */ u32 csTimer; /* 0x039C */ s16 csState; - /* 0x039E */ s16 unk_39E; + /* 0x039E */ s16 subCamId; /* 0x03A0 */ char unk_3A0[0x4]; - /* 0x03A4 */ Vec3f unk_3A4; - /* 0x03B0 */ Vec3f unk_3B0; - /* 0x03BC */ Vec3f unk_3BC; + /* 0x03A4 */ Vec3f subCamEye; + /* 0x03B0 */ Vec3f subCamAt; + /* 0x03BC */ Vec3f subCamUp; /* 0x03C8 */ char unk_3C8[0x48]; /* 0x0410 */ Vec3f unk_410; /* 0x041C */ f32 unk_41C; diff --git a/soh/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c b/soh/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c index 1be26e4615..5a8719cb87 100644 --- a/soh/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c +++ b/soh/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c @@ -21,7 +21,7 @@ void Demo6K_Destroy(Actor* thisx, PlayState* play); void Demo6K_Update(Actor* thisx, PlayState* play); void Demo6K_Reset(void); -void func_80966DB0(Demo6K* this, PlayState* play); +void Demo6K_WaitForObject(Demo6K* this, PlayState* play); void func_80966E04(Demo6K* this, PlayState* play); void func_80966E98(Demo6K* this, PlayState* play); void func_80966F84(Demo6K* this, PlayState* play); @@ -93,7 +93,7 @@ void Demo6K_Init(Actor* thisx, PlayState* play) { this->objBankIndex = objBankIndex; } - Demo6K_SetupAction(this, func_80966DB0); + Demo6K_SetupAction(this, Demo6K_WaitForObject); this->timer1 = 0; this->flags = 0; this->timer2 = 0; @@ -202,7 +202,7 @@ void Demo6K_Destroy(Actor* thisx, PlayState* play) { LightContext_RemoveLight(play, &play->lightCtx, this->lightNode); } -void func_80966DB0(Demo6K* this, PlayState* play) { +void Demo6K_WaitForObject(Demo6K* this, PlayState* play) { if (Object_IsLoaded(&play->objectCtx, this->objBankIndex)) { this->actor.objBankIndex = this->objBankIndex; this->actor.draw = this->drawFunc; diff --git a/soh/src/overlays/actors/ovl_Demo_Go/z_demo_go.c b/soh/src/overlays/actors/ovl_Demo_Go/z_demo_go.c index 1ccf9f0c85..edca1fc2d6 100644 --- a/soh/src/overlays/actors/ovl_Demo_Go/z_demo_go.c +++ b/soh/src/overlays/actors/ovl_Demo_Go/z_demo_go.c @@ -50,7 +50,7 @@ const ActorInit Demo_Go_InitVars = { NULL, }; -s32 func_8097C870(DemoGo* this) { +s32 DemoGo_GetCueChannel(DemoGo* this) { s32 ret; switch (this->actor.params) { @@ -134,7 +134,7 @@ void func_8097CB0C(DemoGo* this, PlayState* play) { Vec3f endPos; if (play->csCtx.state != CS_STATE_IDLE) { - npcAction = csCtx->npcActions[func_8097C870(this)]; + npcAction = csCtx->npcActions[DemoGo_GetCueChannel(this)]; if (npcAction != NULL) { temp_ret = Environment_LerpWeight(npcAction->endFrame, npcAction->startFrame, csCtx->frames); startPos.x = npcAction->startPos.x; @@ -174,7 +174,7 @@ void func_8097CCE0(DemoGo* this, PlayState* play) { s32 thisRotY; if (play->csCtx.state != CS_STATE_IDLE) { - npcAction = play->csCtx.npcActions[func_8097C870(this)]; + npcAction = play->csCtx.npcActions[DemoGo_GetCueChannel(this)]; if (npcAction != NULL) { thisRotY = thisx->world.rot.y; rotYDelta = npcAction->rot.y - thisRotY; @@ -197,7 +197,7 @@ s32 DemoGo_UpdateSkelAnime(DemoGo* this) { s32 func_8097CDB0(DemoGo* this, PlayState* play, u16 npcAction) { CutsceneContext* csCtx = &play->csCtx; - s32 actionIdx = func_8097C870(this); + s32 actionIdx = DemoGo_GetCueChannel(this); if ((csCtx->state != CS_STATE_IDLE) && (csCtx->npcActions[actionIdx] != NULL) && (csCtx->npcActions[actionIdx]->action == npcAction)) { @@ -224,7 +224,7 @@ void func_8097CE78(DemoGo* this, PlayState* play) { CsCmdActorCue* npcAction; if (play->csCtx.state != CS_STATE_IDLE) { - npcAction = csCtx->npcActions[func_8097C870(this)]; + npcAction = csCtx->npcActions[DemoGo_GetCueChannel(this)]; if (npcAction != NULL && csCtx->frames >= npcAction->endFrame) { func_8097CA78(this, play); this->action = 3; diff --git a/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c b/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c index 82c898e489..63e20df36c 100644 --- a/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c +++ b/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c @@ -287,7 +287,7 @@ void func_8097E454(PlayState* play, Vec3f* spawnerPos, Vec3f* velocity, Vec3f* a } } -u8 func_8097E69C(PlayState* play) { +u8 DemoGt_IsCutsceneIdle(PlayState* play) { if (play->csCtx.state == CS_STATE_IDLE) { return true; } else { @@ -299,7 +299,7 @@ CsCmdActorCue* DemoGt_GetNpcAction(PlayState* play, u32 actionIdx) { s32 pad[2]; CsCmdActorCue* ret = NULL; - if (!func_8097E69C(play)) { + if (!DemoGt_IsCutsceneIdle(play)) { ret = play->csCtx.npcActions[actionIdx]; } @@ -433,7 +433,7 @@ void func_8097ED64(DemoGt* this, PlayState* play, s32 actionIdx) { func_8097E824(this, actionIdx); } -u8 func_8097ED94() { +u8 DemoGt_IsCutsceneLayer() { if (kREG(2) != 0) { return true; } else if (gSaveContext.sceneSetupIndex < 4) { @@ -462,7 +462,7 @@ void func_8097EDD8(DemoGt* this, PlayState* play, CollisionHeader* collision) { u8 func_8097EE44(DemoGt* this, PlayState* play, s32 updateMode, s32 drawConfig, CollisionHeader* colHeader) { - if (func_8097ED94()) { + if (DemoGt_IsCutsceneLayer()) { this->updateMode = updateMode; this->drawConfig = drawConfig; func_8097EDD8(this, play, colHeader); diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index 7b332bb9f0..bbcebd592a 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -618,7 +618,7 @@ void func_809861C4(DemoIm* this, PlayState* play) { if (npcAction != NULL) { u32 action = npcAction->action; - u32 unk_274 = this->unk_274; + u32 unk_274 = this->cueId; if (action != unk_274) { switch (action) { @@ -633,7 +633,7 @@ void func_809861C4(DemoIm* this, PlayState* play) { default: osSyncPrintf("Demo_Im_Ocarina_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); } - this->unk_274 = action; + this->cueId = action; } } } @@ -651,7 +651,7 @@ void func_809862E0(DemoIm* this, PlayState* play) { if (npcAction != NULL) { u32 action = npcAction->action; - u32 unk_274 = this->unk_274; + u32 unk_274 = this->cueId; if (action != unk_274) { switch (action) { @@ -673,7 +673,7 @@ void func_809862E0(DemoIm* this, PlayState* play) { default: osSyncPrintf("Demo_Im_Ocarina_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); } - this->unk_274 = action; + this->cueId = action; } } } @@ -782,7 +782,7 @@ void func_8098680C(DemoIm* this, PlayState* play) { if (npcAction != NULL) { u32 action = npcAction->action; - u32 unk_274 = this->unk_274; + u32 unk_274 = this->cueId; if (action != unk_274) { switch (action) { @@ -801,7 +801,7 @@ void func_8098680C(DemoIm* this, PlayState* play) { default: osSyncPrintf("Demo_Im_Spot00_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); } - this->unk_274 = action; + this->cueId = action; } } } @@ -1061,7 +1061,7 @@ void func_809871E8(DemoIm* this, PlayState* play) { if (npcAction != NULL) { u32 action = npcAction->action; - u32 unk_274 = this->unk_274; + u32 unk_274 = this->cueId; if (action != unk_274) { switch (action) { @@ -1074,7 +1074,7 @@ void func_809871E8(DemoIm* this, PlayState* play) { default: osSyncPrintf("Demo_Im_inEnding_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); } - this->unk_274 = action; + this->cueId = action; } } } diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h index 06d6e5d7e1..e25aee903b 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h @@ -42,7 +42,7 @@ typedef struct DemoIm { /* 0x0268 */ f32 unk_268; /* 0x026C */ s32 alpha; /* 0x0270 */ s32 unk_270; - /* 0x0274 */ s32 unk_274; + /* 0x0274 */ s32 cueId; /* 0x0278 */ f32 unk_278; /* 0x027C */ s32 unk_27C; /* 0x0280 */ s32 unk_280; diff --git a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c index 1bc15698e6..70e12441cc 100644 --- a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c +++ b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c @@ -554,7 +554,7 @@ void func_8098F654(DemoSa* this, PlayState* play) { if (npcAction != NULL) { action = npcAction->action; - unk_1AC = this->unk_1AC; + unk_1AC = this->cueId; if (action != unk_1AC) { switch (action) { case 7: @@ -569,7 +569,7 @@ void func_8098F654(DemoSa* this, PlayState* play) { default: osSyncPrintf("Demo_Sa_inEnding_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); } - this->unk_1AC = action; + this->cueId = action; } } } @@ -644,7 +644,7 @@ void func_8098F984(DemoSa* this) { } void func_8098F998(DemoSa* this, PlayState* play) { - if (this->unk_1AC == 4) { + if (this->cueId == 4) { func_8098E6EC(this, play, 1); this->action = 17; this->drawConfig = 2; @@ -699,7 +699,7 @@ void func_8098FB68(DemoSa* this, PlayState* play) { if (npcAction != NULL) { action = npcAction->action; - unk_1AC = this->unk_1AC; + unk_1AC = this->cueId; if (action != unk_1AC) { switch (action) { case 4: @@ -717,7 +717,7 @@ void func_8098FB68(DemoSa* this, PlayState* play) { default: osSyncPrintf("Demo_Sa_inPresent_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); } - this->unk_1AC = action; + this->cueId = action; } } } diff --git a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.h b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.h index 538cacbbb4..42e5caa7e1 100644 --- a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.h +++ b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.h @@ -20,7 +20,7 @@ typedef struct DemoSa { /* 0x01A0 */ f32 unk_1A0; /* 0x01A4 */ s32 alpha; /* 0x01A8 */ s32 unk_1A8; - /* 0x01AC */ s32 unk_1AC; + /* 0x01AC */ s32 cueId; /* 0x01B0 */ s32 unk_1B0; } DemoSa; // size = 0x01B4 diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 307aee785d..3f37ef1ad8 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -32,21 +32,21 @@ void DoorShutter_Destroy(Actor* thisx, PlayState* play); void DoorShutter_Update(Actor* thisx, PlayState* play); void DoorShutter_Draw(Actor* thisx, PlayState* play); -void func_8099803C(PlayState* play, s16 y, s16 countdown, s16 arg3); +void DoorShutter_RequestQuakeAndRumble(PlayState* play, s16 y, s16 countdown, s16 arg3); void DoorShutter_SetupType(DoorShutter* this, PlayState* play); -void func_80996A54(DoorShutter* this, PlayState* play); -void func_80996B00(DoorShutter* this, PlayState* play); -void func_80996B0C(DoorShutter* this, PlayState* play); -void func_80996EE8(DoorShutter* this, PlayState* play); -void func_80996F98(DoorShutter* this, PlayState* play); -void func_80997004(DoorShutter* this, PlayState* play); -void func_80997150(DoorShutter* this, PlayState* play); -void func_809973E8(DoorShutter* this, PlayState* play); -void func_80997528(DoorShutter* this, PlayState* play); -void func_80997568(DoorShutter* this, PlayState* play); -void func_809975C0(DoorShutter* this, PlayState* play); -void func_809976B8(DoorShutter* this, PlayState* play); -void func_80997744(DoorShutter* this, PlayState* play); +void DoorShutter_WaitClear(DoorShutter* this, PlayState* play); +void DoorShutter_Unopenable(DoorShutter* this, PlayState* play); +void DoorShutter_Idle(DoorShutter* this, PlayState* play); +void DoorShutter_BarAndWaitSwitchFlag(DoorShutter* this, PlayState* play); +void DoorShutter_UnbarredCheckSwitchFlag(DoorShutter* this, PlayState* play); +void DoorShutter_Open(DoorShutter* this, PlayState* play); +void DoorShutter_Unbar(DoorShutter* this, PlayState* play); +void DoorShutter_Close(DoorShutter* this, PlayState* play); +void DoorShutter_JabuDoorClose(DoorShutter* this, PlayState* play); +void DoorShutter_WaitPlayerSurprised(DoorShutter* this, PlayState* play); +void DoorShutter_GohmaBlockFall(DoorShutter* this, PlayState* play); +void DoorShutter_GohmaBlockBounce(DoorShutter* this, PlayState* play); +void DoorShutter_PhantomGanonBarsRaise(DoorShutter* this, PlayState* play); const ActorInit Door_Shutter_InitVars = { ACTOR_DOOR_SHUTTER, @@ -184,14 +184,14 @@ static void* D_809982D4[] = { void DoorShutter_SetupAction(DoorShutter* this, DoorShutterActionFunc actionFunc) { this->actionFunc = actionFunc; - this->unk_16F = 0; + this->actionTimer = 0; } s32 DoorShutter_SetupDoor(DoorShutter* this, PlayState* play) { TransitionActorEntry* transitionEntry = &play->transiActorCtx.list[(u16)this->dyna.actor.params >> 0xA]; s8 frontRoom = transitionEntry->sides[0].room; s32 doorType = this->doorType; - ShutterObjectInfo* temp_t0 = &sObjectInfo[this->unk_16B]; + ShutterObjectInfo* temp_t0 = &sObjectInfo[this->styleType]; if (doorType != SHUTTER_KEY_LOCKED) { if (frontRoom == transitionEntry->sides[1].room) { @@ -207,27 +207,27 @@ s32 DoorShutter_SetupDoor(DoorShutter* this, PlayState* play) { } } } - this->unk_16C = (doorType == SHUTTER) ? temp_t0->index1 : temp_t0->index2; + this->gfxType = (doorType == SHUTTER) ? temp_t0->index1 : temp_t0->index2; if (doorType == SHUTTER_FRONT_CLEAR) { if (!Flags_GetClear(play, this->dyna.actor.room)) { - DoorShutter_SetupAction(this, func_80996A54); - this->unk_170 = 1.0f; + DoorShutter_SetupAction(this, DoorShutter_WaitClear); + this->barsClosedAmount = 1.0f; return true; } } else if (doorType == SHUTTER_FRONT_SWITCH || doorType == SHUTTER_FRONT_SWITCH_BACK_CLEAR) { if (!Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { - DoorShutter_SetupAction(this, func_80996EE8); - this->unk_170 = 1.0f; + DoorShutter_SetupAction(this, DoorShutter_BarAndWaitSwitchFlag); + this->barsClosedAmount = 1.0f; return true; } - DoorShutter_SetupAction(this, func_80996F98); + DoorShutter_SetupAction(this, DoorShutter_UnbarredCheckSwitchFlag); return false; } else if (doorType == SHUTTER_BACK_LOCKED) { - DoorShutter_SetupAction(this, func_80996B00); + DoorShutter_SetupAction(this, DoorShutter_Unopenable); return false; } - DoorShutter_SetupAction(this, func_80996B0C); + DoorShutter_SetupAction(this, DoorShutter_Idle); return false; } @@ -261,7 +261,7 @@ void DoorShutter_Init(Actor* thisx, PlayState* play2) { break; } } - this->unk_168 = phi_v1_2->index; + this->bossDoorTexIndex = phi_v1_2->index; } else { this->dyna.actor.room = -1; } @@ -271,15 +271,15 @@ void DoorShutter_Init(Actor* thisx, PlayState* play2) { return; } DoorShutter_SetupAction(this, DoorShutter_SetupType); - this->unk_16B = phi_a3; + this->styleType = phi_a3; if (this->doorType == SHUTTER_KEY_LOCKED || this->doorType == SHUTTER_BOSS) { if (GameInteractor_Should(VB_LOCK_BOSS_DOOR, !Flags_GetSwitch(play, this->dyna.actor.params & 0x3F), this)) { - this->unk_16E = 10; + this->unlockTimer = 10; } Actor_SetFocus(&this->dyna.actor, 60.0f); } else if (phi_a3 == 4) { Actor_SetScale(&this->dyna.actor, 0.1f); - this->unk_166 = 100; + this->jabuDoorClosedAmount = 100; this->dyna.actor.uncullZoneScale = 200.0f; Actor_SetFocus(&this->dyna.actor, 0.0f); } else { @@ -306,7 +306,7 @@ void DoorShutter_SetupType(DoorShutter* this, PlayState* play) { CollisionHeader* colHeader = NULL; Actor_SetObjectDependency(play, &this->dyna.actor); - this->unk_16C = sObjectInfo[this->unk_16B].index1; + this->gfxType = sObjectInfo[this->styleType].index1; CollisionHeader_GetVirtual((this->doorType == SHUTTER_GOHMA_BLOCK) ? &gGohmaDoorCol : &gPhantomGanonBarsCol, &colHeader); this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader); @@ -314,9 +314,9 @@ void DoorShutter_SetupType(DoorShutter* this, PlayState* play) { this->dyna.actor.velocity.y = 0.0f; this->dyna.actor.gravity = -2.0f; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_CLOSE); - DoorShutter_SetupAction(this, func_809975C0); + DoorShutter_SetupAction(this, DoorShutter_GohmaBlockFall); } else { - DoorShutter_SetupAction(this, func_80997744); + DoorShutter_SetupAction(this, DoorShutter_PhantomGanonBarsRaise); this->unk_164 = 7; } } else { @@ -325,7 +325,7 @@ void DoorShutter_SetupType(DoorShutter* this, PlayState* play) { } } -f32 func_80996840(PlayState* play, DoorShutter* this, f32 arg2, f32 arg3, f32 arg4) { +f32 DoorShutter_GetPlayerDistance(PlayState* play, DoorShutter* this, f32 arg2, f32 arg3, f32 arg4) { s32 pad; Vec3f sp28; Vec3f sp1C; @@ -342,12 +342,13 @@ f32 func_80996840(PlayState* play, DoorShutter* this, f32 arg2, f32 arg3, f32 ar } } -s32 func_809968D4(DoorShutter* this, PlayState* play) { +s32 DoorShutter_GetPlayerSide(DoorShutter* this, PlayState* play) { Player* player = GET_PLAYER(play); if (!Player_InCsMode(play)) { - ShutterInfo* temp_v1 = &sShutterInfo[this->unk_16C]; - f32 temp_f2 = func_80996840(play, this, (this->unk_16C != 3) ? 0.0f : 80.0f, temp_v1->e, temp_v1->f); + ShutterInfo* temp_v1 = &sShutterInfo[this->gfxType]; + f32 temp_f2 = + DoorShutter_GetPlayerDistance(play, this, (this->gfxType != 3) ? 0.0f : 80.0f, temp_v1->e, temp_v1->f); if (fabsf(temp_f2) < 50.0f) { s16 phi_v0 = player->actor.shape.rot.y - this->dyna.actor.shape.rot.y; @@ -363,30 +364,30 @@ s32 func_809968D4(DoorShutter* this, PlayState* play) { return 0.0f; } -void func_80996A54(DoorShutter* this, PlayState* play) { +void DoorShutter_WaitClear(DoorShutter* this, PlayState* play) { if (Flags_GetClear(play, this->dyna.actor.room) || Flags_GetTempClear(play, this->dyna.actor.room)) { Flags_SetClear(play, this->dyna.actor.room); - DoorShutter_SetupAction(this, func_80997150); + DoorShutter_SetupAction(this, DoorShutter_Unbar); if (GameInteractor_Should(VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { OnePointCutscene_Attention(play, &this->dyna.actor); OnePointCutscene_Attention(play, &GET_PLAYER(play)->actor); - this->unk_16F = -100; + this->actionTimer = -100; } - } else if (func_809968D4(this, play) != 0) { + } else if (DoorShutter_GetPlayerSide(this, play) != 0) { Player* player = GET_PLAYER(play); player->naviTextId = -0x202; } } -void func_80996B00(DoorShutter* this, PlayState* play) { +void DoorShutter_Unopenable(DoorShutter* this, PlayState* play) { } -void func_80996B0C(DoorShutter* this, PlayState* play) { +void DoorShutter_Idle(DoorShutter* this, PlayState* play) { if (this->unk_164 != 0) { - DoorShutter_SetupAction(this, func_80997004); + DoorShutter_SetupAction(this, DoorShutter_Open); this->dyna.actor.velocity.y = 0.0f; - if (this->unk_16E != 0) { + if (this->unlockTimer != 0) { Flags_SetSwitch(play, this->dyna.actor.params & 0x3F); if (this->doorType != SHUTTER_BOSS) { gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]--; @@ -397,12 +398,12 @@ void func_80996B0C(DoorShutter* this, PlayState* play) { } } } else { - s32 doorDirection = func_809968D4(this, play); + s32 doorDirection = DoorShutter_GetPlayerSide(this, play); if (doorDirection != 0) { Player* player = GET_PLAYER(play); - if (this->unk_16E != 0) { + if (this->unlockTimer != 0) { if (this->doorType == SHUTTER_BOSS) { if (!CHECK_DUNGEON_ITEM(DUNGEON_KEY_BOSS, gSaveContext.mapIndex)) { player->naviTextId = -0x204; @@ -421,28 +422,28 @@ void func_80996B0C(DoorShutter* this, PlayState* play) { } } -void func_80996C60(DoorShutter* this, PlayState* play) { +void DoorShutter_InitOpeningDoorCam(DoorShutter* this, PlayState* play) { if (this->dyna.actor.category == ACTORCAT_DOOR) { Player* player = GET_PLAYER(play); - s32 sp38 = this->unk_16C; + s32 sp38 = this->gfxType; s32 sp34 = 0xF; if (DoorShutter_SetupDoor(this, play)) { sp34 = 0x20; } - DoorShutter_SetupAction(this, func_80997004); - this->unk_16C = sp38; - this->unk_170 = 0.0f; + DoorShutter_SetupAction(this, DoorShutter_Open); + this->gfxType = sp38; + this->barsClosedAmount = 0.0f; Camera_ChangeDoorCam(play->cameraPtrs[MAIN_CAM], &this->dyna.actor, player->cv.slidingDoorBgCamIndex, 0.0f, 12, sp34, 10); } } -s32 func_80996D14(DoorShutter* this, PlayState* play) { - if (this->unk_16C != 3) { +s32 DoorShutter_UpdateOpening(DoorShutter* this, PlayState* play) { + if (this->gfxType != 3) { if (this->dyna.actor.velocity.y == 0.0f) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_OPEN); - func_80996C60(this, play); + DoorShutter_InitOpeningDoorCam(this, play); } Math_StepToF(&this->dyna.actor.velocity.y, 15.0f, 3.0f); if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 200.0f, @@ -450,20 +451,20 @@ s32 func_80996D14(DoorShutter* this, PlayState* play) { return true; } } else { - if (this->unk_166 == 100) { + if (this->jabuDoorClosedAmount == 100) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYODOOR_OPEN); - func_80996C60(this, play); + DoorShutter_InitOpeningDoorCam(this, play); } - if (Math_StepToS(&this->unk_166, 0, 10)) { + if (Math_StepToS(&this->jabuDoorClosedAmount, 0, 10)) { return true; } } return false; } -s32 func_80996E08(DoorShutter* this, PlayState* play, f32 arg2) { - if (this->unk_170 == 1.0f - arg2) { - if (this->unk_16C != 3) { +s32 DoorShutter_UpdateBarsClosed(DoorShutter* this, PlayState* play, f32 arg2) { + if (this->barsClosedAmount == 1.0f - arg2) { + if (this->gfxType != 3) { if (arg2 == 1.0f) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_METALDOOR_CLOSE); } else { @@ -477,21 +478,21 @@ s32 func_80996E08(DoorShutter* this, PlayState* play, f32 arg2) { } } } - if (Math_StepToF(&this->unk_170, arg2, 0.2f)) { + if (Math_StepToF(&this->barsClosedAmount, arg2, 0.2f)) { return true; } return false; } -void func_80996EE8(DoorShutter* this, PlayState* play) { - if (func_80996E08(this, play, 1.0f)) { +void DoorShutter_BarAndWaitSwitchFlag(DoorShutter* this, PlayState* play) { + if (DoorShutter_UpdateBarsClosed(this, play, 1.0f)) { if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { - DoorShutter_SetupAction(this, func_80997150); + DoorShutter_SetupAction(this, DoorShutter_Unbar); if (GameInteractor_Should(VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { OnePointCutscene_Attention(play, &this->dyna.actor); - this->unk_16F = -100; + this->actionTimer = -100; } - } else if (func_809968D4(this, play)) { + } else if (DoorShutter_GetPlayerSide(this, play)) { Player* player = GET_PLAYER(play); // Jabu navi text for switch doors is different player->naviTextId = (play->sceneNum == SCENE_JABU_JABU) ? -0x20B : -0x202; @@ -499,58 +500,58 @@ void func_80996EE8(DoorShutter* this, PlayState* play) { } } -void func_80996F98(DoorShutter* this, PlayState* play) { +void DoorShutter_UnbarredCheckSwitchFlag(DoorShutter* this, PlayState* play) { if (this->unk_164 == 0 && !Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { - DoorShutter_SetupAction(this, func_80996EE8); + DoorShutter_SetupAction(this, DoorShutter_BarAndWaitSwitchFlag); } else { - func_80996B0C(this, play); + DoorShutter_Idle(this, play); } } -void func_80997004(DoorShutter* this, PlayState* play) { - if (DECR(this->unk_16E) == 0 && play->roomCtx.status == 0 && func_80996D14(this, play) != 0) { +void DoorShutter_Open(DoorShutter* this, PlayState* play) { + if (DECR(this->unlockTimer) == 0 && play->roomCtx.status == 0 && DoorShutter_UpdateOpening(this, play) != 0) { if (((this->doorType == SHUTTER_BOSS) ? 20.0f : 50.0f) < this->dyna.actor.xzDistToPlayer) { if (DoorShutter_SetupDoor(this, play)) { this->dyna.actor.velocity.y = 30.0f; } - if (this->unk_16C != 3) { + if (this->gfxType != 3) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_CLOSE); - DoorShutter_SetupAction(this, func_809973E8); + DoorShutter_SetupAction(this, DoorShutter_Close); } else { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYODOOR_CLOSE); if ((this->doorType == SHUTTER_FRONT_SWITCH || this->doorType == SHUTTER_FRONT_SWITCH_BACK_CLEAR) && !Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYOSHUTTER_CLOSE); } - DoorShutter_SetupAction(this, func_80997528); + DoorShutter_SetupAction(this, DoorShutter_JabuDoorClose); } } } } -void func_80997150(DoorShutter* this, PlayState* play) { - if (this->unk_16F != 0) { - if (this->unk_16F < 0) { +void DoorShutter_Unbar(DoorShutter* this, PlayState* play) { + if (this->actionTimer != 0) { + if (this->actionTimer < 0) { if (play->state.frames % 2 != 0) { - this->unk_16F++; + this->actionTimer++; } - if (this->dyna.actor.category == func_8005B198() || this->unk_16F == 0) { - this->unk_16F = 5; + if (this->dyna.actor.category == func_8005B198() || this->actionTimer == 0) { + this->actionTimer = 5; } } else { - this->unk_16F--; + this->actionTimer--; } - } else if (func_80996E08(this, play, 0.0f)) { + } else if (DoorShutter_UpdateBarsClosed(this, play, 0.0f)) { if (!(this->doorType == SHUTTER || this->doorType == SHUTTER_FRONT_CLEAR)) { - DoorShutter_SetupAction(this, func_80996F98); + DoorShutter_SetupAction(this, DoorShutter_UnbarredCheckSwitchFlag); } else { - DoorShutter_SetupAction(this, func_80996B0C); + DoorShutter_SetupAction(this, DoorShutter_Idle); } func_800F5B58(); } } -void func_80997220(DoorShutter* this, PlayState* play) { +void DoorShutter_SetupClosed(DoorShutter* this, PlayState* play) { Player* player = GET_PLAYER(play); s8 room = this->dyna.actor.room; @@ -573,12 +574,12 @@ void func_80997220(DoorShutter* this, PlayState* play) { this->unk_164 = 0; this->dyna.actor.velocity.y = 0.0f; if (DoorShutter_SetupDoor(this, play) && !(player->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR)) { - DoorShutter_SetupAction(this, func_80997568); + DoorShutter_SetupAction(this, DoorShutter_WaitPlayerSurprised); Player_SetCsActionWithHaltedActors(play, NULL, 2); } } -void func_809973E8(DoorShutter* this, PlayState* play) { +void DoorShutter_Close(DoorShutter* this, PlayState* play) { s32 quakeId; if (this->dyna.actor.velocity.y < 20.0f) { @@ -596,41 +597,41 @@ void func_809973E8(DoorShutter* this, PlayState* play) { Quake_SetQuakeValues(quakeId, 2, 0, 0, 0); Quake_SetCountdown(quakeId, 10); func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64); - func_80997220(this, play); + DoorShutter_SetupClosed(this, play); } } -void func_80997528(DoorShutter* this, PlayState* play) { - if (Math_StepToS(&this->unk_166, 0x64, 0xA)) { - func_80997220(this, play); +void DoorShutter_JabuDoorClose(DoorShutter* this, PlayState* play) { + if (Math_StepToS(&this->jabuDoorClosedAmount, 0x64, 0xA)) { + DoorShutter_SetupClosed(this, play); } } -void func_80997568(DoorShutter* this, PlayState* play) { - if (this->unk_16F++ > 30) { +void DoorShutter_WaitPlayerSurprised(DoorShutter* this, PlayState* play) { + if (this->actionTimer++ > 30) { Player_SetCsActionWithHaltedActors(play, NULL, 7); DoorShutter_SetupDoor(this, play); } } -void func_809975C0(DoorShutter* this, PlayState* play) { +void DoorShutter_GohmaBlockFall(DoorShutter* this, PlayState* play) { Actor_MoveXZGravity(&this->dyna.actor); Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 4); if (this->dyna.actor.bgCheckFlags & 1) { - DoorShutter_SetupAction(this, func_809976B8); + DoorShutter_SetupAction(this, DoorShutter_GohmaBlockBounce); if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE)) { BossGoma* parent = (BossGoma*)this->dyna.actor.parent; this->unk_164 = 10; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); - func_8099803C(play, 2, 10, parent->subCameraId); + DoorShutter_RequestQuakeAndRumble(play, 2, 10, parent->subCameraId); Actor_SpawnFloorDustRing(play, &this->dyna.actor, &this->dyna.actor.world.pos, 70.0f, 20, 8.0f, 500, 10, true); } } } -void func_809976B8(DoorShutter* this, PlayState* play) { +void DoorShutter_GohmaBlockBounce(DoorShutter* this, PlayState* play) { f32 mult; if (this->unk_164 != 0) { @@ -640,7 +641,7 @@ void func_809976B8(DoorShutter* this, PlayState* play) { } } -void func_80997744(DoorShutter* this, PlayState* play) { +void DoorShutter_PhantomGanonBarsRaise(DoorShutter* this, PlayState* play) { f32 phi_f0; osSyncPrintf("FHG SAKU START !!\n"); @@ -666,7 +667,7 @@ void DoorShutter_Update(Actor* thisx, PlayState* play) { Gfx* func_80997838(PlayState* play, DoorShutter* this, Gfx* p) { MtxF mtx; f32 angle = 0.0f; - f32 yScale = this->unk_166 * 0.01f; + f32 yScale = this->jabuDoorClosedAmount * 0.01f; s32 i; Matrix_Get(&mtx); @@ -679,7 +680,7 @@ Gfx* func_80997838(PlayState* play, DoorShutter* this, Gfx* p) { } else { Matrix_Translate(0.0f, 989.94f, 0.0f, MTXMODE_APPLY); } - if (this->unk_166 != 100) { + if (this->jabuDoorClosedAmount != 100) { Matrix_Scale(1.0f, yScale, 1.0f, MTXMODE_APPLY); } gSPMatrix(p++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -690,7 +691,7 @@ Gfx* func_80997838(PlayState* play, DoorShutter* this, Gfx* p) { return p; } -s32 func_80997A34(DoorShutter* this, PlayState* play) { +s32 DoorShutter_ShouldDraw(DoorShutter* this, PlayState* play) { s32 phi_a1; s32 phi_a0; @@ -723,18 +724,18 @@ void DoorShutter_Draw(Actor* thisx, PlayState* play) { //! the init vars for the actor, and only set draw after initialization is complete. if (this->dyna.actor.objBankIndex == this->requiredObjBankIndex && - (this->unk_16B == 0 || func_80997A34(this, play) != 0)) { + (this->styleType == 0 || DoorShutter_ShouldDraw(this, play) != 0)) { s32 pad[2]; - ShutterInfo* sp70 = &sShutterInfo[this->unk_16C]; + ShutterInfo* sp70 = &sShutterInfo[this->gfxType]; OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx); - if (this->unk_16C == 3) { + if (this->gfxType == 3) { POLY_OPA_DISP = func_80997838(play, this, POLY_OPA_DISP); - if (this->unk_170 != 0.0f) { - f32 sp58 = (this->unk_166 * 0.01f) * this->unk_170; + if (this->barsClosedAmount != 0.0f) { + f32 sp58 = (this->jabuDoorClosedAmount * 0.01f) * this->barsClosedAmount; Gfx_SetupDL_25Opa(play->state.gfxCtx); gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255.0f * sp58); @@ -759,31 +760,31 @@ void DoorShutter_Draw(Actor* thisx, PlayState* play) { Matrix_RotateY(M_PI, MTXMODE_APPLY); } } else if (this->doorType == SHUTTER_BOSS) { - gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_809982D4[this->unk_168])); + gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_809982D4[this->bossDoorTexIndex])); } gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, sp70->a); - if (this->unk_170 != 0.0f && sp70->b != NULL) { - Matrix_Translate(0, sp70->c * (1.0f - this->unk_170), sp70->translateZ, MTXMODE_APPLY); + if (this->barsClosedAmount != 0.0f && sp70->b != NULL) { + Matrix_Translate(0, sp70->c * (1.0f - this->barsClosedAmount), sp70->translateZ, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, sp70->b); } } - if (this->unk_16E != 0) { + if (this->unlockTimer != 0) { Matrix_Scale(0.01f, 0.01f, 0.025f, MTXMODE_APPLY); - Actor_DrawDoorLock(play, this->unk_16E, + Actor_DrawDoorLock(play, this->unlockTimer, (this->doorType == SHUTTER_BOSS) ? DOORLOCK_BOSS - : ((this->unk_16C == 6) ? DOORLOCK_NORMAL_SPIRIT : DOORLOCK_NORMAL)); + : ((this->gfxType == 6) ? DOORLOCK_NORMAL_SPIRIT : DOORLOCK_NORMAL)); } CLOSE_DISPS(play->state.gfxCtx); } } -void func_8099803C(PlayState* play, s16 y, s16 countdown, s16 camId) { +void DoorShutter_RequestQuakeAndRumble(PlayState* play, s16 y, s16 countdown, s16 camId) { s16 quakeId = Quake_Add(Play_GetCamera(play, camId), 3); func_800A9F6C(0.0f, 180, 20, 100); diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h index 6916f88326..b30706c783 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h @@ -46,15 +46,15 @@ typedef void (*DoorShutterActionFunc)(struct DoorShutter*, PlayState*); typedef struct DoorShutter { /* 0x0000 */ DynaPolyActor dyna; /* 0x0164 */ s16 unk_164; - /* 0x0166 */ s16 unk_166; - /* 0x0168 */ s16 unk_168; + /* 0x0166 */ s16 jabuDoorClosedAmount; + /* 0x0168 */ s16 bossDoorTexIndex; /* 0x016A */ u8 doorType; - /* 0x016B */ u8 unk_16B; - /* 0x016C */ u8 unk_16C; + /* 0x016B */ u8 styleType; + /* 0x016C */ u8 gfxType; /* 0x016D */ s8 requiredObjBankIndex; - /* 0x016E */ s8 unk_16E; - /* 0x016F */ s8 unk_16F; - /* 0x0170 */ f32 unk_170; + /* 0x016E */ s8 unlockTimer; + /* 0x016F */ s8 actionTimer; + /* 0x0170 */ f32 barsClosedAmount; /* 0x0174 */ DoorShutterActionFunc actionFunc; } DoorShutter; // size = 0x0178 diff --git a/soh/src/overlays/actors/ovl_En_Am/z_en_am.h b/soh/src/overlays/actors/ovl_En_Am/z_en_am.h index 22c40f36ce..20b20806d9 100644 --- a/soh/src/overlays/actors/ovl_En_Am/z_en_am.h +++ b/soh/src/overlays/actors/ovl_En_Am/z_en_am.h @@ -24,7 +24,7 @@ typedef struct EnAm { /* 0x0264 */ s16 unk_264; /* 0x0266 */ u8 textureBlend; // 0 = statue textures; 255 = enemy textures /* 0x0267 */ u8 damageEffect; - /* 0x0267 */ Vec3f shakeOrigin; // center point to shake around when waking up + /* 0x0268 */ Vec3f shakeOrigin; // center point to shake around when waking up /* 0x0274 */ ColliderCylinder hurtCollider; /* 0x02C0 */ ColliderCylinder blockCollider; /* 0x030C */ ColliderQuad hitCollider; diff --git a/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h b/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h index 8b18f6b478..9c2c87915e 100644 --- a/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h +++ b/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h @@ -30,7 +30,7 @@ typedef struct EnAttackNiw { /* 0x027C */ f32 unk_27C; /* 0x0280 */ f32 unk_280; /* 0x0284 */ f32 unk_284; - /* 0x0284 */ f32 unk_288; + /* 0x0288 */ f32 unk_288; /* 0x028C */ s16 unk_28C; /* 0x028E */ s16 unk_28E; /* 0x0290 */ char unk_290[0x2]; diff --git a/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c b/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c index 6b6c1f8471..2d9e268780 100644 --- a/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c +++ b/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.c @@ -14,10 +14,10 @@ void EnBird_Destroy(Actor* thisx, PlayState* play); void EnBird_Update(Actor* thisx, PlayState* play); void EnBird_Draw(Actor* thisx, PlayState* play); -void func_809C1E00(EnBird* this, s16 params); -void func_809C1E40(EnBird* this, PlayState* play); -void func_809C1D60(EnBird* this, PlayState* play); -void func_809C1CAC(EnBird* this, s16 params); +void EnBird_SetupMove(EnBird* this, s16 params); +void EnBird_Move(EnBird* this, PlayState* play); +void EnBird_Idle(EnBird* this, PlayState* play); +void EnBird_SetupIdle(EnBird* this, s16 params); const ActorInit En_Bird_InitVars = { ACTOR_EN_BIRD, @@ -48,17 +48,17 @@ void EnBird_Init(Actor* thisx, PlayState* play) { SkelAnime_Init(play, &this->skelAnime, &gBirdSkel, &gBirdFlyAnim, NULL, NULL, 0); ActorShape_Init(&this->actor.shape, 5500, ActorShadow_DrawCircle, 4); this->unk_194 = 0; - this->unk_198 = 0; - this->unk_1C0 = 0x9C4; + this->timer = 0; + this->rotYStep = 0x9C4; this->actor.colChkInfo.mass = 0; - this->unk_1A8 = 1.5f; - this->unk_1AC = 0.5f; - this->unk_1A0 = 0.0f; - this->unk_1A4 = 0.0f; - this->unk_1B8 = 0.0f; - this->unk_1B0 = 40.0f; + this->speedTarget = 1.5f; + this->speedStep = 0.5f; + this->posYMag = 0.0f; + this->rotYMag = 0.0f; + this->posYPhaseStep = 0.0f; + this->flightDistance = 40.0f; this->unk_1BC = 70.0f; - func_809C1CAC(this, this->actor.params); + EnBird_SetupIdle(this, this->actor.params); } void EnBird_Destroy(Actor* thisx, PlayState* play) { @@ -67,65 +67,65 @@ void EnBird_Destroy(Actor* thisx, PlayState* play) { SkelAnime_Free(&this->skelAnime, play); } -void func_809C1CAC(EnBird* this, s16 params) { +void EnBird_SetupIdle(EnBird* this, s16 params) { f32 frameCount = Animation_GetLastFrame(&gBirdFlyAnim); - f32 playbackSpeed = this->unk_19C ? 0.0f : 1.0f; + f32 playbackSpeed = this->scaleAnimSpeed ? 0.0f : 1.0f; AnimationHeader* anim = &gBirdFlyAnim; - this->unk_198 = Rand_S16Offset(5, 0x23); + this->timer = Rand_S16Offset(5, 0x23); Animation_Change(&this->skelAnime, anim, playbackSpeed, 0.0f, frameCount, ANIMMODE_LOOP, 0.0f); - EnBird_SetupAction(this, func_809C1D60); + EnBird_SetupAction(this, EnBird_Idle); } -void func_809C1D60(EnBird* this, PlayState* play) { - f32 fVar2 = sinf(this->unk_1B4); +void EnBird_Idle(EnBird* this, PlayState* play) { + f32 fVar2 = sinf(this->posYPhase); - this->actor.shape.yOffset = this->actor.shape.yOffset + fVar2 * this->unk_1A0; + this->actor.shape.yOffset = this->actor.shape.yOffset + fVar2 * this->posYMag; Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.1f, 0.5f, 0.0f); - if (this->unk_19C != 0) { + if (this->scaleAnimSpeed != 0) { this->skelAnime.playSpeed = this->actor.speedXZ + this->actor.speedXZ; } SkelAnime_Update(&this->skelAnime); - this->unk_198 -= 1; + this->timer -= 1; - if (this->unk_198 <= 0) { - func_809C1E00(this, this->actor.params); + if (this->timer <= 0) { + EnBird_SetupMove(this, this->actor.params); } } -void func_809C1E00(EnBird* this, s16 params) { - this->unk_198 = Rand_S16Offset(0x14, 0x2D); - EnBird_SetupAction(this, func_809C1E40); +void EnBird_SetupMove(EnBird* this, s16 params) { + this->timer = Rand_S16Offset(0x14, 0x2D); + EnBird_SetupAction(this, EnBird_Move); } -void func_809C1E40(EnBird* this, PlayState* play) { - f32 fVar4 = sinf(this->unk_1B4); +void EnBird_Move(EnBird* this, PlayState* play) { + f32 fVar4 = sinf(this->posYPhase); - this->actor.shape.yOffset += fVar4 * this->unk_1A0; - Math_SmoothStepToF(&this->actor.speedXZ, this->unk_1A8, 0.1f, this->unk_1AC, 0.0f); + this->actor.shape.yOffset += fVar4 * this->posYMag; + Math_SmoothStepToF(&this->actor.speedXZ, this->speedTarget, 0.1f, this->speedStep, 0.0f); - if (this->unk_1B0 < Math_Vec3f_DistXZ(&this->actor.world.pos, &this->actor.home.pos) || this->unk_198 < 4) { + if (this->flightDistance < Math_Vec3f_DistXZ(&this->actor.world.pos, &this->actor.home.pos) || this->timer < 4) { Math_StepToAngleS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos), - this->unk_1C0); + this->rotYStep); } else { - fVar4 = sinf(this->unk_1B4); - this->actor.world.rot.y += (s16)(fVar4 * this->unk_1A4); + fVar4 = sinf(this->posYPhase); + this->actor.world.rot.y += (s16)(fVar4 * this->rotYMag); } this->actor.shape.rot.y = this->actor.world.rot.y; SkelAnime_Update(&this->skelAnime); - this->unk_198 -= 1; - if (this->unk_198 < 0) { - func_809C1CAC(this, this->actor.params); + this->timer -= 1; + if (this->timer < 0) { + EnBird_SetupIdle(this, this->actor.params); } } void EnBird_Update(Actor* thisx, PlayState* play) { EnBird* this = (EnBird*)thisx; - this->unk_1B4 += this->unk_1B8; + this->posYPhase += this->posYPhaseStep; this->actionFunc(this, play); } diff --git a/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.h b/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.h index a3966986b5..bb904883e8 100644 --- a/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.h +++ b/soh/src/overlays/actors/ovl_En_Bird/z_en_bird.h @@ -13,18 +13,18 @@ typedef struct EnBird { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnBirdActionFunc actionFunc; /* 0x0194 */ u32 unk_194; - /* 0x0198 */ s32 unk_198; - /* 0x019C */ s16 unk_19C; + /* 0x0198 */ s32 timer; + /* 0x019C */ s16 scaleAnimSpeed; /* 0x019E */ char unk_19E[0x2]; - /* 0x01A0 */ f32 unk_1A0; - /* 0x01A4 */ f32 unk_1A4; - /* 0x01A8 */ f32 unk_1A8; - /* 0x01AC */ f32 unk_1AC; - /* 0x01B0 */ f32 unk_1B0; - /* 0x01B4 */ f32 unk_1B4; - /* 0x01B8 */ f32 unk_1B8; + /* 0x01A0 */ f32 posYMag; + /* 0x01A4 */ f32 rotYMag; + /* 0x01A8 */ f32 speedTarget; + /* 0x01AC */ f32 speedStep; + /* 0x01B0 */ f32 flightDistance; + /* 0x01B4 */ f32 posYPhase; + /* 0x01B8 */ f32 posYPhaseStep; /* 0x01BC */ f32 unk_1BC; - /* 0x01C0 */ s16 unk_1C0; + /* 0x01C0 */ s16 rotYStep; /* 0x01C2 */ char unk_1C2[0x1A]; } EnBird; // size = 0x01DC diff --git a/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c b/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c index 9fe450695e..900a869025 100644 --- a/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c +++ b/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c @@ -8,7 +8,7 @@ #include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" -#include +#include "soh/ShipUtils.h" #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) @@ -104,14 +104,13 @@ void EnBom_Init(Actor* thisx, PlayState* play) { } else { // Set random fuse timer with a minimum of 10. Do the sound and scale immediately, // otherwise the bomb is invisible until the timer hits the "normal" amount. - uint32_t randomTimer = (rand() % 150) + 10; - this->timer = randomTimer; + this->timer = 10 + (s16)(Rand_ZeroOne() * 150.0f); Audio_PlayActorSound2(thisx, NA_SE_PL_TAKE_OUT_SHIELD); Actor_SetScale(thisx, 0.01f); } if (CVarGetFloat(CVAR_CHEAT("BombTimerMultiplier"), 1.0f) != 1.0f) { - this->timer = (s32)(70 * CVarGetFloat(CVAR_CHEAT("BombTimerMultiplier"), 1.0f)); + this->timer *= CVarGetFloat(CVAR_CHEAT("BombTimerMultiplier"), 1.0f); // Do the sound and scale immediately if GameInteractor hasn't already. if (!GameInteractor_GetRandomBombFuseTimerActive()) { Audio_PlayActorSound2(thisx, NA_SE_PL_TAKE_OUT_SHIELD); diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index 3bdf701d4d..5597f8a1fc 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -86,7 +86,7 @@ void EnBomBowlMan_Init(Actor* thisx, PlayState* play2) { cuccoSpawnPos[i].y, cuccoSpawnPos[i].z, 0, 0, 0, 1); if (cucco != NULL) { - cucco->unk_2F4 = cuccoScales[i]; + cucco->scale = cuccoScales[i]; cucco->collider.dim.radius = (s16)cuccoColliderDims[i][0]; cucco->collider.dim.height = (s16)cuccoColliderDims[i][1]; } diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c index 8351d2e79d..428158c0f8 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c @@ -76,34 +76,34 @@ void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play) { Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->camId, CAM_STAT_ACTIVE); - this->unk_1C8.x = this->unk_1C8.y = this->unk_1C8.z = 0.1f; - this->unk_1A4.x = this->unk_1A4.y = this->unk_1A4.z = 0.1f; + this->subCamAtMaxVelFrac.x = this->subCamAtMaxVelFrac.y = this->subCamAtMaxVelFrac.z = 0.1f; + this->subCamEyeMaxVelFrac.x = this->subCamEyeMaxVelFrac.y = this->subCamEyeMaxVelFrac.z = 0.1f; - this->unk_180.x = this->unk_168.x = play->view.lookAt.x; - this->unk_180.y = this->unk_168.y = play->view.lookAt.y; - this->unk_180.z = this->unk_168.z = play->view.lookAt.z; + this->subCamAt.x = this->viewAt.x = play->view.lookAt.x; + this->subCamAt.y = this->viewAt.y = play->view.lookAt.y; + this->subCamAt.z = this->viewAt.z = play->view.lookAt.z; - this->unk_18C.x = this->unk_174.x = play->view.eye.x; - this->unk_18C.y = this->unk_174.y = play->view.eye.y; - this->unk_18C.z = this->unk_174.z = play->view.eye.z; + this->subCamEye.x = this->viewEye.x = play->view.eye.x; + this->subCamEye.y = this->viewEye.y = play->view.eye.y; + this->subCamEye.z = this->viewEye.z = play->view.eye.z; - this->unk_1BC.x = 20.0f; - this->unk_1BC.y = 100.0f; - this->unk_1BC.z = -800.0f; + this->subCamAtNext.x = 20.0f; + this->subCamAtNext.y = 100.0f; + this->subCamAtNext.z = -800.0f; - this->unk_198.x = 20.0f; - this->unk_198.y = 50.0f; - this->unk_198.z = -485.0f; + this->subCamEyeNext.x = 20.0f; + this->subCamEyeNext.y = 50.0f; + this->subCamEyeNext.z = -485.0f; - this->unk_1B0.x = fabsf(this->unk_18C.x - this->unk_198.x) * 0.02f; - this->unk_1B0.y = fabsf(this->unk_18C.y - this->unk_198.y) * 0.02f; - this->unk_1B0.z = fabsf(this->unk_18C.z - this->unk_198.z) * 0.02f; + this->subCamEyeVel.x = fabsf(this->subCamEye.x - this->subCamEyeNext.x) * 0.02f; + this->subCamEyeVel.y = fabsf(this->subCamEye.y - this->subCamEyeNext.y) * 0.02f; + this->subCamEyeVel.z = fabsf(this->subCamEye.z - this->subCamEyeNext.z) * 0.02f; - this->unk_1D4.x = fabsf(this->unk_180.x - this->unk_1BC.x) * 0.02f; - this->unk_1D4.y = fabsf(this->unk_180.y - this->unk_1BC.y) * 0.02f; - this->unk_1D4.z = fabsf(this->unk_180.z - this->unk_1BC.z) * 0.02f; + this->subCamAtVel.x = fabsf(this->subCamAt.x - this->subCamAtNext.x) * 0.02f; + this->subCamAtVel.y = fabsf(this->subCamAt.y - this->subCamAtNext.y) * 0.02f; + this->subCamAtVel.z = fabsf(this->subCamAt.z - this->subCamAtNext.z) * 0.02f; - Play_CameraSetAtEye(play, this->camId, &this->unk_180, &this->unk_18C); + Play_CameraSetAtEye(play, this->camId, &this->subCamAt, &this->subCamEye); this->actor.textId = 0xF; Message_StartTextbox(play, this->actor.textId, NULL); this->unk_154 = TEXT_STATE_EVENT; @@ -121,23 +121,26 @@ void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play) { void EnBomBowlPit_CameraDollyIn(EnBomBowlPit* this, PlayState* play) { if (this->camId != SUBCAM_FREE) { - Math_ApproachF(&this->unk_180.x, this->unk_1BC.x, this->unk_1C8.x, this->unk_1D4.x); - Math_ApproachF(&this->unk_180.y, this->unk_1BC.y, this->unk_1C8.y, this->unk_1D4.y); - Math_ApproachF(&this->unk_180.z, this->unk_1BC.z, this->unk_1C8.z, this->unk_1D4.z); - Math_ApproachF(&this->unk_18C.x, this->unk_198.x, this->unk_1A4.x, this->unk_1B0.x); - Math_ApproachF(&this->unk_18C.y, this->unk_198.y, this->unk_1A4.y, this->unk_1B0.y); - Math_ApproachF(&this->unk_18C.z, this->unk_198.z, this->unk_1A4.z, this->unk_1B0.z); + Math_ApproachF(&this->subCamAt.x, this->subCamAtNext.x, this->subCamAtMaxVelFrac.x, this->subCamAtVel.x); + Math_ApproachF(&this->subCamAt.y, this->subCamAtNext.y, this->subCamAtMaxVelFrac.y, this->subCamAtVel.y); + Math_ApproachF(&this->subCamAt.z, this->subCamAtNext.z, this->subCamAtMaxVelFrac.z, this->subCamAtVel.z); + Math_ApproachF(&this->subCamEye.x, this->subCamEyeNext.x, this->subCamEyeMaxVelFrac.x, this->subCamEyeVel.x); + Math_ApproachF(&this->subCamEye.y, this->subCamEyeNext.y, this->subCamEyeMaxVelFrac.y, this->subCamEyeVel.y); + Math_ApproachF(&this->subCamEye.z, this->subCamEyeNext.z, this->subCamEyeMaxVelFrac.z, this->subCamEyeVel.z); } - Play_CameraSetAtEye(play, this->camId, &this->unk_180, &this->unk_18C); + Play_CameraSetAtEye(play, this->camId, &this->subCamAt, &this->subCamEye); if ((this->unk_154 == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); } - if ((fabsf(this->unk_18C.x - this->unk_198.x) < 5.0f) && (fabsf(this->unk_18C.y - this->unk_198.y) < 5.0f) && - (fabsf(this->unk_18C.z - this->unk_198.z) < 5.0f) && (fabsf(this->unk_180.x - this->unk_1BC.x) < 5.0f) && - (fabsf(this->unk_180.y - this->unk_1BC.y) < 5.0f) && (fabsf(this->unk_180.z - this->unk_1BC.z) < 5.0f)) { + if ((fabsf(this->subCamEye.x - this->subCamEyeNext.x) < 5.0f) && + (fabsf(this->subCamEye.y - this->subCamEyeNext.y) < 5.0f) && + (fabsf(this->subCamEye.z - this->subCamEyeNext.z) < 5.0f) && + (fabsf(this->subCamAt.x - this->subCamAtNext.x) < 5.0f) && + (fabsf(this->subCamAt.y - this->subCamAtNext.y) < 5.0f) && + (fabsf(this->subCamAt.z - this->subCamAtNext.z) < 5.0f)) { Message_CloseTextbox(play); this->timer = 30; this->actionFunc = EnBomBowlPit_SpawnPrize; diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h index 48cfbd5c2a..a921c5bb77 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h @@ -21,16 +21,16 @@ typedef struct EnBomBowlPit { /* 0x015C */ s16 start; /* 0x0160 */ s32 getItemId; /* 0x0164 */ u8 status; - /* 0x0168 */ Vec3f unk_168; // set and not used? - /* 0x0174 */ Vec3f unk_174; // set and not used? - /* 0x0180 */ Vec3f unk_180; // camera at (start) - /* 0x018C */ Vec3f unk_18C; // camera eye (start) - /* 0x0198 */ Vec3f unk_198; // camera eye (end) - /* 0x01A4 */ Vec3f unk_1A4; // camera eye (scales) - /* 0x01B0 */ Vec3f unk_1B0; // camera eye (maxsteps) - /* 0x01BC */ Vec3f unk_1BC; // camera at (end) - /* 0x01C8 */ Vec3f unk_1C8; // camera at (scales) - /* 0x01D4 */ Vec3f unk_1D4; // camera eye (maxsteps) + /* 0x0168 */ Vec3f viewAt; // set and not used? + /* 0x0174 */ Vec3f viewEye; // set and not used? + /* 0x0180 */ Vec3f subCamAt; // camera at (start) + /* 0x018C */ Vec3f subCamEye; // camera eye (start) + /* 0x0198 */ Vec3f subCamEyeNext; // camera eye (end) + /* 0x01A4 */ Vec3f subCamEyeMaxVelFrac; // camera eye (scales) + /* 0x01B0 */ Vec3f subCamEyeVel; // camera eye (maxsteps) + /* 0x01BC */ Vec3f subCamAtNext; // camera at (end) + /* 0x01C8 */ Vec3f subCamAtMaxVelFrac; // camera at (scales) + /* 0x01D4 */ Vec3f subCamAtVel; // camera eye (maxsteps) /* 0x01E0 */ EnExItem* exItem; /* 0x01E4 */ char unk_1E4[0x3520]; } EnBomBowlPit; // size = 0x3704 diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index fb4f09d2b5..c178dab757 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -271,7 +271,7 @@ void EnBox_Fall(EnBox* this, PlayState* play) { this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; EnBox_SetupAction(this, EnBox_WaitOpen); if (GameInteractor_Should(VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { - OnePointCutscene_EndCutscene(play, this->unk_1AC); + OnePointCutscene_EndCutscene(play, this->subCamId); } } Audio_PlaySoundGeneral(NA_SE_EV_COFFIN_CAP_BOUND, &this->dyna.actor.projectedPos, 4, @@ -295,7 +295,7 @@ void EnBox_FallOnSwitchFlag(EnBox* this, PlayState* play) { if (this->unk_1A8 >= 0) { EnBox_SetupAction(this, EnBox_Fall); - this->unk_1AC = OnePointCutscene_Init(play, 4500, 9999, &this->dyna.actor, MAIN_CAM); + this->subCamId = OnePointCutscene_Init(play, 4500, 9999, &this->dyna.actor, MAIN_CAM); func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId); } else if (this->unk_1A8 >= -11) { this->unk_1A8++; diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h index 0168fc1a85..fdfec21bcd 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h @@ -34,7 +34,7 @@ typedef struct EnBox { /* 0x0000 */ DynaPolyActor dyna; /* 0x0164 */ SkelAnime skelanime; /* 0x01A8 */ s32 unk_1A8; // related to animation delays for types 3 and 8 - /* 0x01AC */ s32 unk_1AC; + /* 0x01AC */ s32 subCamId; /* 0x01B0 */ f32 unk_1B0; // 0-1, rotation-related, apparently unused (in z_en_box.c at least) /* 0x01B4 */ EnBoxActionFunc actionFunc; /* 0x01B8 */ Vec3s jointTable[5]; diff --git a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c index 281402e9e3..a71489ade1 100644 --- a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c +++ b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c @@ -15,13 +15,13 @@ void EnBrob_Destroy(Actor* thisx, PlayState* play); void EnBrob_Update(Actor* thisx, PlayState* play); void EnBrob_Draw(Actor* thisx, PlayState* play); -void func_809CADDC(EnBrob* this, PlayState* play); -void func_809CB054(EnBrob* this, PlayState* play); -void func_809CB114(EnBrob* this, PlayState* play); -void func_809CB218(EnBrob* this, PlayState* play); -void func_809CB2B8(EnBrob* this, PlayState* play); -void func_809CB354(EnBrob* this, PlayState* play); -void func_809CB458(EnBrob* this, PlayState* play); +void EnBrob_SetupIdle(EnBrob* this, PlayState* play); +void EnBrob_Idle(EnBrob* this, PlayState* play); +void EnBrob_MoveUp(EnBrob* this, PlayState* play); +void EnBrob_Wobble(EnBrob* this, PlayState* play); +void EnBrob_Stunned(EnBrob* this, PlayState* play); +void EnBrob_MoveDown(EnBrob* this, PlayState* play); +void EnBrob_Shock(EnBrob* this, PlayState* play); const ActorInit En_Brob_InitVars = { ACTOR_EN_BROB, @@ -94,7 +94,7 @@ void EnBrob_Init(Actor* thisx, PlayState* play) { this->colliders[1].dim.yShift *= thisx->scale.y; this->actionFunc = NULL; thisx->flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - func_809CADDC(this, play); + EnBrob_SetupIdle(this, play); } void EnBrob_Destroy(Actor* thisx, PlayState* play) { @@ -107,82 +107,82 @@ void EnBrob_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -void func_809CADDC(EnBrob* this, PlayState* play) { +void EnBrob_SetupIdle(EnBrob* this, PlayState* play) { func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId); - this->timer = this->actionFunc == func_809CB2B8 ? 200 : 0; - this->unk_1AE = 0; - this->actionFunc = func_809CB054; + this->timer = this->actionFunc == EnBrob_Stunned ? 200 : 0; + this->modelOffsetY = 0; + this->actionFunc = EnBrob_Idle; } -void func_809CAE44(EnBrob* this, PlayState* play) { +void EnBrob_SetupMoveUp(EnBrob* this, PlayState* play) { Animation_PlayOnce(&this->skelAnime, &object_brob_Anim_001750); func_8003EBF8(play, &play->colCtx.dyna, this->dyna.bgId); - this->unk_1AE = 1000; - this->actionFunc = func_809CB114; + this->modelOffsetY = 1000; + this->actionFunc = EnBrob_MoveUp; } -void func_809CAEA0(EnBrob* this) { +void EnBrob_SetupWobble(EnBrob* this) { Animation_MorphToLoop(&this->skelAnime, &object_brob_Anim_001958, -5.0f); - this->unk_1AE = 8000; + this->modelOffsetY = 8000; this->timer = 1200; - this->actionFunc = func_809CB218; + this->actionFunc = EnBrob_Wobble; } -void func_809CAEF4(EnBrob* this) { +void EnBrob_SetupStunned(EnBrob* this) { Animation_MorphToPlayOnce(&this->skelAnime, &object_brob_Anim_000290, -5.0f); - this->unk_1AE -= 125.0f; + this->modelOffsetY -= 125.0f; Actor_SetColorFilter(&this->dyna.actor, 0, 0xFF, 0, 0x50); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_GOMA_JR_FREEZE); - this->actionFunc = func_809CB2B8; + this->actionFunc = EnBrob_Stunned; } -void func_809CAF88(EnBrob* this) { +void EnBrob_SetupMoveDown(EnBrob* this) { Animation_Change(&this->skelAnime, &object_brob_Anim_001750, -1.0f, Animation_GetLastFrame(&object_brob_Anim_001750), 0.0f, ANIMMODE_ONCE, -5.0f); - this->unk_1AE = 8250; - this->actionFunc = func_809CB354; + this->modelOffsetY = 8250; + this->actionFunc = EnBrob_MoveDown; } -void func_809CB008(EnBrob* this) { +void EnBrob_SetupShock(EnBrob* this) { Animation_MorphToLoop(&this->skelAnime, &object_brob_Anim_001678, -5.0f); this->timer = 10; - this->actionFunc = func_809CB458; + this->actionFunc = EnBrob_Shock; } -void func_809CB054(EnBrob* this, PlayState* play) { +void EnBrob_Idle(EnBrob* this, PlayState* play) { if (this->timer != 0) { this->timer--; } if (this->timer == 0) { if (DynaPolyActor_IsPlayerOnTop(&this->dyna) != 0) { func_8002F71C(play, &this->dyna.actor, 5.0f, this->dyna.actor.yawTowardsPlayer, 1.0f); - func_809CAE44(this, play); + EnBrob_SetupMoveUp(this, play); } else if (this->dyna.actor.xzDistToPlayer < 300.0f) { - func_809CAE44(this, play); + EnBrob_SetupMoveUp(this, play); } } else if (this->timer >= 81) { this->dyna.actor.colorFilterTimer = 80; } } -void func_809CB114(EnBrob* this, PlayState* play) { +void EnBrob_MoveUp(EnBrob* this, PlayState* play) { f32 curFrame; if (SkelAnime_Update(&this->skelAnime)) { - func_809CAEA0(this); + EnBrob_SetupWobble(this); } else { curFrame = this->skelAnime.curFrame; if (curFrame < 8.0f) { - this->unk_1AE += 1000.0f; + this->modelOffsetY += 1000.0f; } else if (curFrame < 12.0f) { - this->unk_1AE += 250.0f; + this->modelOffsetY += 250.0f; } else { - this->unk_1AE -= 250.0f; + this->modelOffsetY -= 250.0f; } } } -void func_809CB218(EnBrob* this, PlayState* play) { +void EnBrob_Wobble(EnBrob* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 6.0f) || Animation_OnFrame(&this->skelAnime, 15.0f)) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_BROB_WAVE); @@ -191,37 +191,37 @@ void func_809CB218(EnBrob* this, PlayState* play) { this->timer--; } if ((this->timer == 0) && (this->dyna.actor.xzDistToPlayer > 500.0f)) { - func_809CAF88(this); + EnBrob_SetupMoveDown(this); } } -void func_809CB2B8(EnBrob* this, PlayState* play) { +void EnBrob_Stunned(EnBrob* this, PlayState* play) { if (SkelAnime_Update(&this->skelAnime)) { - func_809CADDC(this, play); + EnBrob_SetupIdle(this, play); } else if (this->skelAnime.curFrame < 8.0f) { - this->unk_1AE -= 1250.0f; + this->modelOffsetY -= 1250.0f; } this->dyna.actor.colorFilterTimer = 0x50; } -void func_809CB354(EnBrob* this, PlayState* play) { +void EnBrob_MoveDown(EnBrob* this, PlayState* play) { f32 curFrame; if (SkelAnime_Update(&this->skelAnime)) { - func_809CADDC(this, play); + EnBrob_SetupIdle(this, play); } else { curFrame = this->skelAnime.curFrame; if (curFrame < 8.0f) { - this->unk_1AE -= 1000.0f; + this->modelOffsetY -= 1000.0f; } else if (curFrame < 12.0f) { - this->unk_1AE -= 250.0f; + this->modelOffsetY -= 250.0f; } else { - this->unk_1AE += 250.0f; + this->modelOffsetY += 250.0f; } } } -void func_809CB458(EnBrob* this, PlayState* play) { +void EnBrob_Shock(EnBrob* this, PlayState* play) { Vec3f pos; f32 dist1; f32 dist2; @@ -254,7 +254,7 @@ void func_809CB458(EnBrob* this, PlayState* play) { } if (this->timer == 0) { - func_809CAEA0(this); + EnBrob_SetupWobble(this); } } @@ -274,16 +274,16 @@ void EnBrob_Update(Actor* thisx, PlayState* play2) { this->colliders[i].base.acFlags &= ~AC_HIT; } - func_809CAEF4(this); + EnBrob_SetupStunned(this); } else if ((this->colliders[0].base.atFlags & AT_HIT) || (this->colliders[1].base.atFlags & AT_HIT) || (acHits[0] && (this->colliders[0].info.acHitInfo->toucher.dmgFlags & 0x100)) || (acHits[1] && (this->colliders[1].info.acHitInfo->toucher.dmgFlags & 0x100))) { - if (this->actionFunc == func_809CB114 && !(this->colliders[0].base.atFlags & AT_BOUNCED) && + if (this->actionFunc == EnBrob_MoveUp && !(this->colliders[0].base.atFlags & AT_BOUNCED) && !(this->colliders[1].base.atFlags & AT_BOUNCED)) { func_8002F71C(play, &this->dyna.actor, 5.0f, this->dyna.actor.yawTowardsPlayer, 1.0f); - } else if (this->actionFunc != func_809CB114) { - func_809CB008(this); + } else if (this->actionFunc != EnBrob_MoveUp) { + EnBrob_SetupShock(this); } for (i = 0; i < 2; i++) { @@ -292,11 +292,11 @@ void EnBrob_Update(Actor* thisx, PlayState* play2) { } } this->actionFunc(this, play); - if (this->actionFunc != func_809CB054 && this->actionFunc != func_809CB354) { - if (this->actionFunc != func_809CB2B8) { + if (this->actionFunc != EnBrob_Idle && this->actionFunc != EnBrob_MoveDown) { + if (this->actionFunc != EnBrob_Stunned) { CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliders[0].base); CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliders[1].base); - if (this->actionFunc != func_809CB114) { + if (this->actionFunc != EnBrob_MoveUp) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliders[0].base); CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliders[1].base); } @@ -326,6 +326,6 @@ void EnBrob_Draw(Actor* thisx, PlayState* play) { EnBrob* this = (EnBrob*)thisx; Gfx_SetupDL_25Opa(play->state.gfxCtx); - Matrix_Translate(0.0f, this->unk_1AE, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, this->modelOffsetY, 0.0f, MTXMODE_APPLY); SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, EnBrob_PostLimbDraw, this); } diff --git a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.h b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.h index c4e256576a..5fca10407a 100644 --- a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.h +++ b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.h @@ -13,7 +13,7 @@ typedef struct EnBrob { /* 0x0164 */ SkelAnime skelAnime; /* 0x01A8 */ EnBrobActionFunc actionFunc; /* 0x01AC */ s16 timer; - /* 0x01AE */ s16 unk_1AE; + /* 0x01AE */ s16 modelOffsetY; /* 0x01B0 */ Vec3s jointTable[10]; /* 0x01EC */ Vec3s morphTable[10]; /* 0x0228 */ ColliderCylinder colliders[2]; diff --git a/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c b/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c index 4421865d2c..f7a171bd03 100644 --- a/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c +++ b/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c @@ -9,6 +9,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -363,7 +364,7 @@ void EnButte_TransformIntoFairy(EnButte* this, PlayState* play) { if (this->timer == 5) { SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 60, NA_SE_EV_BUTTERFRY_TO_FAIRY); - } else if (this->timer == 4) { + } else if (GameInteractor_Should(VB_SPAWN_BUTTERFLY_FAIRY, this->timer == 4, this)) { Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z, 0, this->actor.shape.rot.y, 0, FAIRY_HEAL_TIMED); this->drawSkelAnime = false; diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 0009c25dd0..e4994d13f0 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -15,17 +15,17 @@ void EnCow_Init(Actor* thisx, PlayState* play); void EnCow_Destroy(Actor* thisx, PlayState* play); void EnCow_Update(Actor* thisx, PlayState* play); void EnCow_Draw(Actor* thisx, PlayState* play); -void func_809DFE98(Actor* thisx, PlayState* play); -void func_809E0070(Actor* thisx, PlayState* play); +void EnCow_UpdateTail(Actor* thisx, PlayState* play); +void EnCow_DrawTail(Actor* thisx, PlayState* play); -void func_809DF494(EnCow* this, PlayState* play); -void func_809DF6BC(EnCow* this, PlayState* play); -void func_809DF778(EnCow* this, PlayState* play); -void func_809DF7D8(EnCow* this, PlayState* play); -void func_809DF870(EnCow* this, PlayState* play); -void func_809DF8FC(EnCow* this, PlayState* play); -void func_809DF96C(EnCow* this, PlayState* play); -void func_809DFA84(EnCow* this, PlayState* play); +void EnCow_UpdateAnimation(EnCow* this, PlayState* play); +void EnCow_TalkEnd(EnCow* this, PlayState* play); +void EnCow_GiveMilkWait(EnCow* this, PlayState* play); +void EnCow_GiveMilk(EnCow* this, PlayState* play); +void EnCow_CheckForEmptyBottle(EnCow* this, PlayState* play); +void EnCow_Talk(EnCow* this, PlayState* play); +void EnCow_Idle(EnCow* this, PlayState* play); +void EnCow_IdleTail(EnCow* this, PlayState* play); const ActorInit En_Cow_InitVars = { ACTOR_EN_COW, @@ -62,7 +62,7 @@ static ColliderCylinderInit sCylinderInit = { static Vec3f D_809E010C = { 0.0f, -1300.0f, 1100.0f }; -void func_809DEE00(Vec3f* vec, s16 rotY) { +void EnCow_RotateY(Vec3f* vec, s16 rotY) { f32 xCalc; f32 rotCalcTemp; @@ -73,13 +73,13 @@ void func_809DEE00(Vec3f* vec, s16 rotY) { vec->x = xCalc; } -void func_809DEE9C(EnCow* this) { +void EnCow_SetColliderPos(EnCow* this) { Vec3f vec; vec.y = 0.0f; vec.x = 0.0f; vec.z = 30.0f; - func_809DEE00(&vec, this->actor.shape.rot.y); + EnCow_RotateY(&vec, this->actor.shape.rot.y); this->colliders[0].dim.pos.x = this->actor.world.pos.x + vec.x; this->colliders[0].dim.pos.y = this->actor.world.pos.y; this->colliders[0].dim.pos.z = this->actor.world.pos.z + vec.z; @@ -87,18 +87,18 @@ void func_809DEE9C(EnCow* this) { vec.x = 0.0f; vec.y = 0.0f; vec.z = -20.0f; - func_809DEE00(&vec, this->actor.shape.rot.y); + EnCow_RotateY(&vec, this->actor.shape.rot.y); this->colliders[1].dim.pos.x = this->actor.world.pos.x + vec.x; this->colliders[1].dim.pos.y = this->actor.world.pos.y; this->colliders[1].dim.pos.z = this->actor.world.pos.z + vec.z; } -void func_809DEF94(EnCow* this) { +void EnCow_SetTailPos(EnCow* this) { Vec3f vec; VEC_SET(vec, 0.0f, 57.0f, -36.0f); - func_809DEE00(&vec, this->actor.shape.rot.y); + EnCow_RotateY(&vec, this->actor.shape.rot.y); this->actor.world.pos.x += vec.x; this->actor.world.pos.y += vec.y; this->actor.world.pos.z += vec.z; @@ -117,8 +117,8 @@ void EnCow_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->colliders[0], &this->actor, &sCylinderInit); Collider_InitCylinder(play, &this->colliders[1]); Collider_SetCylinder(play, &this->colliders[1], &this->actor, &sCylinderInit); - func_809DEE9C(this); - this->actionFunc = func_809DF96C; + EnCow_SetColliderPos(this); + this->actionFunc = EnCow_Idle; if (GameInteractor_Should(VB_DESPAWN_HORSE_RACE_COW, (play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE))), @@ -129,25 +129,25 @@ void EnCow_Init(Actor* thisx, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_COW, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 1); - this->unk_278 = Rand_ZeroFloat(1000.0f) + 40.0f; - this->unk_27A = 0; + this->animationTimer = Rand_ZeroFloat(1000.0f) + 40.0f; + this->breathTimer = 0; this->actor.targetMode = 6; DREG(53) = 0; break; case 1: SkelAnime_InitFlex(play, &this->skelAnime, &gCowTailSkel, NULL, this->jointTable, this->morphTable, 6); Animation_PlayLoop(&this->skelAnime, &gCowTailIdleAnim); - this->actor.update = func_809DFE98; - this->actor.draw = func_809E0070; - this->actionFunc = func_809DFA84; - func_809DEF94(this); + this->actor.update = EnCow_UpdateTail; + this->actor.draw = EnCow_DrawTail; + this->actionFunc = EnCow_IdleTail; + EnCow_SetTailPos(this); this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - this->unk_278 = ((u32)(Rand_ZeroFloat(1000.0f)) & 0xFFFF) + 40.0f; + this->animationTimer = ((u32)(Rand_ZeroFloat(1000.0f)) & 0xFFFF) + 40.0f; break; } this->actor.colChkInfo.mass = MASS_IMMOVABLE; Actor_SetScale(&this->actor, 0.01f); - this->unk_276 = 0; + this->cowFlags = 0; } void EnCow_Destroy(Actor* thisx, PlayState* play) { @@ -161,109 +161,109 @@ void EnCow_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -void func_809DF494(EnCow* this, PlayState* play) { - if (this->unk_278 > 0) { - this->unk_278 -= 1; +void EnCow_UpdateAnimation(EnCow* this, PlayState* play) { + if (this->animationTimer > 0) { + this->animationTimer -= 1; } else { - this->unk_278 = Rand_ZeroFloat(500.0f) + 40.0f; + this->animationTimer = Rand_ZeroFloat(500.0f) + 40.0f; Animation_Change(&this->skelAnime, &gCowBodyChewAnim, 1.0f, this->skelAnime.curFrame, Animation_GetLastFrame(&gCowBodyChewAnim), ANIMMODE_ONCE, 1.0f); } - if ((this->actor.xzDistToPlayer < 150.0f) && (!(this->unk_276 & 2))) { - this->unk_276 |= 2; + if ((this->actor.xzDistToPlayer < 150.0f) && (!(this->cowFlags & 2))) { + this->cowFlags |= 2; if (this->skelAnime.animation == &gCowBodyChewAnim) { - this->unk_278 = 0; + this->animationTimer = 0; } } - this->unk_27A += 1; - if (this->unk_27A >= 0x31) { - this->unk_27A = 0; + this->breathTimer += 1; + if (this->breathTimer >= 0x31) { + this->breathTimer = 0; } // (1.0f / 100.0f) instead of 0.01f below is necessary so 0.01f doesn't get reused mistakenly - if (this->unk_27A < 0x20) { - this->actor.scale.x = ((Math_SinS(this->unk_27A << 0xA) * (1.0f / 100.0f)) + 1.0f) * 0.01f; + if (this->breathTimer < 0x20) { + this->actor.scale.x = ((Math_SinS(this->breathTimer << 0xA) * (1.0f / 100.0f)) + 1.0f) * 0.01f; } else { this->actor.scale.x = 0.01f; } - if (this->unk_27A >= 0x11) { - this->actor.scale.y = ((Math_SinS((this->unk_27A << 0xA) - 0x4000) * (1.0f / 100.0f)) + 1.0f) * 0.01f; + if (this->breathTimer >= 0x11) { + this->actor.scale.y = ((Math_SinS((this->breathTimer << 0xA) - 0x4000) * (1.0f / 100.0f)) + 1.0f) * 0.01f; } else { this->actor.scale.y = 0.01f; } } -void func_809DF6BC(EnCow* this, PlayState* play) { +void EnCow_TalkEnd(EnCow* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; Message_CloseTextbox(play); - this->actionFunc = func_809DF96C; + this->actionFunc = EnCow_Idle; } } -void func_809DF730(EnCow* this, PlayState* play) { +void EnCow_GiveMilkEnd(EnCow* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; - this->actionFunc = func_809DF96C; + this->actionFunc = EnCow_Idle; } } -void func_809DF778(EnCow* this, PlayState* play) { +void EnCow_GiveMilkWait(EnCow* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actor.parent = NULL; - this->actionFunc = func_809DF730; + this->actionFunc = EnCow_GiveMilkEnd; } else { Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 100.0f); } } -void func_809DF7D8(EnCow* this, PlayState* play) { +void EnCow_GiveMilk(EnCow* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; Message_CloseTextbox(play); - this->actionFunc = func_809DF778; + this->actionFunc = EnCow_GiveMilkWait; Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 100.0f); } } -void func_809DF870(EnCow* this, PlayState* play) { +void EnCow_CheckForEmptyBottle(EnCow* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { if (Inventory_HasEmptyBottle()) { Message_ContinueTextbox(play, 0x2007); - this->actionFunc = func_809DF7D8; + this->actionFunc = EnCow_GiveMilk; } else { Message_ContinueTextbox(play, 0x2013); - this->actionFunc = func_809DF6BC; + this->actionFunc = EnCow_TalkEnd; } } } -void func_809DF8FC(EnCow* this, PlayState* play) { +void EnCow_Talk(EnCow* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { - this->actionFunc = func_809DF870; + this->actionFunc = EnCow_CheckForEmptyBottle; } else { this->actor.flags |= ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; func_8002F2CC(&this->actor, play, 170.0f); this->actor.textId = 0x2006; } - func_809DF494(this, play); + EnCow_UpdateAnimation(this, play); } -void func_809DF96C(EnCow* this, PlayState* play) { +void EnCow_Idle(EnCow* this, PlayState* play) { if ((play->msgCtx.ocarinaMode == OCARINA_MODE_00) || (play->msgCtx.ocarinaMode == OCARINA_MODE_04)) { if (DREG(53) != 0) { - if (this->unk_276 & 4) { - this->unk_276 &= ~0x4; + if (this->cowFlags & 4) { + this->cowFlags &= ~0x4; DREG(53) = 0; } else { if ((this->actor.xzDistToPlayer < 150.0f) && (ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x61A8)) { DREG(53) = 0; if (GameInteractor_Should(VB_GIVE_ITEM_FROM_COW, true, this)) { - this->actionFunc = func_809DF8FC; + this->actionFunc = EnCow_Talk; this->actor.flags |= ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; func_8002F2CC(&this->actor, play, 170.0f); this->actor.textId = 0x2006; @@ -271,30 +271,30 @@ void func_809DF96C(EnCow* this, PlayState* play) { return; } } else { - this->unk_276 |= 4; + this->cowFlags |= 4; } } } else { - this->unk_276 &= ~0x4; + this->cowFlags &= ~0x4; } } - func_809DF494(this, play); + EnCow_UpdateAnimation(this, play); } -void func_809DFA84(EnCow* this, PlayState* play) { - if (this->unk_278 > 0) { - this->unk_278--; +void EnCow_IdleTail(EnCow* this, PlayState* play) { + if (this->animationTimer > 0) { + this->animationTimer--; } else { - this->unk_278 = Rand_ZeroFloat(200.0f) + 40.0f; + this->animationTimer = Rand_ZeroFloat(200.0f) + 40.0f; Animation_Change(&this->skelAnime, &gCowTailIdleAnim, 1.0f, this->skelAnime.curFrame, Animation_GetLastFrame(&gCowTailIdleAnim), ANIMMODE_ONCE, 1.0f); } if ((this->actor.xzDistToPlayer < 150.0f) && - (ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) >= 0x61A9) && (!(this->unk_276 & 2))) { - this->unk_276 |= 2; + (ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) >= 0x61A9) && (!(this->cowFlags & 2))) { + this->cowFlags |= 2; if (this->skelAnime.animation == &gCowTailIdleAnim) { - this->unk_278 = 0; + this->animationTimer = 0; } } } @@ -346,7 +346,7 @@ void EnCow_Update(Actor* thisx, PlayState* play2) { Math_SmoothStepToS(&this->someRot.y, targetY, 0xA, 0xC8, 0xA); } -void func_809DFE98(Actor* thisx, PlayState* play) { +void EnCow_UpdateTail(Actor* thisx, PlayState* play) { EnCow* this = (EnCow*)thisx; s32 pad; @@ -390,7 +390,7 @@ void EnCow_Draw(Actor* thisx, PlayState* play) { SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnCow_OverrideLimbDraw, EnCow_PostLimbDraw, this); } -void func_809E0070(Actor* thisx, PlayState* play) { +void EnCow_DrawTail(Actor* thisx, PlayState* play) { EnCow* this = (EnCow*)thisx; Gfx_SetupDL_37Opa(play->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h index 3cd2443882..4d82fc2d4c 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h @@ -15,12 +15,12 @@ typedef struct EnCow { /* 0x0228 */ Vec3s jointTable[6]; /* 0x024C */ Vec3s morphTable[6]; /* 0x0270 */ Vec3s someRot; - /* 0x0276 */ u16 unk_276; - /* 0x0278 */ u16 unk_278; - /* 0x027A */ u16 unk_27A; + /* 0x0276 */ u16 cowFlags; + /* 0x0278 */ u16 animationTimer; + /* 0x027A */ u16 breathTimer; /* 0x027C */ EnCowActionFunc actionFunc; } EnCow; // size = 0x0280 -void func_809DEE9C(EnCow* enCow); +void EnCow_SetColliderPos(EnCow* enCow); #endif diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c index 6c4066f376..cd1a14f1fa 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c @@ -308,35 +308,36 @@ void EnDivingGame_SetupRupeeThrow(EnDivingGame* this, PlayState* play) { Play_ChangeCameraStatus(play, 0, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); this->spawnRuppyTimer = 10; - this->unk_2F4.x = -210.0f; - this->unk_2F4.y = -80.0f; - this->unk_2F4.z = -1020.0f; - this->unk_2D0.x = -280.0f; - this->unk_2D0.y = -20.0f; - this->unk_2D0.z = -240.0f; + this->subCamAtNext.x = -210.0f; + this->subCamAtNext.y = -80.0f; + this->subCamAtNext.z = -1020.0f; + this->subCamEyeNext.x = -280.0f; + this->subCamEyeNext.y = -20.0f; + this->subCamEyeNext.z = -240.0f; if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_SILVER_SCALE)) { this->rupeesLeftToThrow = 5; } else { this->rupeesLeftToThrow = 10; } - this->unk_2DC.x = this->unk_2DC.y = this->unk_2DC.z = this->unk_300.x = this->unk_300.y = this->unk_300.z = 0.1f; + this->subCamEyeMaxVelFrac.x = this->subCamEyeMaxVelFrac.y = this->subCamEyeMaxVelFrac.z = + this->subCamAtMaxVelFrac.x = this->subCamAtMaxVelFrac.y = this->subCamAtMaxVelFrac.z = 0.1f; this->camLookAt.x = play->view.lookAt.x; this->camLookAt.y = play->view.lookAt.y; this->camLookAt.z = play->view.lookAt.z; this->camEye.x = play->view.eye.x; this->camEye.y = play->view.eye.y + 80.0f; this->camEye.z = play->view.eye.z + 250.0f; - this->unk_2E8.x = fabsf(this->camEye.x - this->unk_2D0.x) * 0.04f; - this->unk_2E8.y = fabsf(this->camEye.y - this->unk_2D0.y) * 0.04f; - this->unk_2E8.z = fabsf(this->camEye.z - this->unk_2D0.z) * 0.04f; - this->unk_30C.x = fabsf(this->camLookAt.x - this->unk_2F4.x) * 0.04f; - this->unk_30C.y = fabsf(this->camLookAt.y - this->unk_2F4.y) * 0.04f; - this->unk_30C.z = fabsf(this->camLookAt.z - this->unk_2F4.z) * 0.04f; + this->subCamEyeVel.x = fabsf(this->camEye.x - this->subCamEyeNext.x) * 0.04f; + this->subCamEyeVel.y = fabsf(this->camEye.y - this->subCamEyeNext.y) * 0.04f; + this->subCamEyeVel.z = fabsf(this->camEye.z - this->subCamEyeNext.z) * 0.04f; + this->subCamAtVel.x = fabsf(this->camLookAt.x - this->subCamAtNext.x) * 0.04f; + this->subCamAtVel.y = fabsf(this->camLookAt.y - this->subCamAtNext.y) * 0.04f; + this->subCamAtVel.z = fabsf(this->camLookAt.z - this->subCamAtNext.z) * 0.04f; Play_CameraSetAtEye(play, this->subCamId, &this->camLookAt, &this->camEye); Play_CameraSetFov(play, this->subCamId, play->mainCamera.fov); this->csCameraTimer = 60; this->actionFunc = EnDivingGame_RupeeThrow; - this->unk_318 = 0.0f; + this->subCamVelFactor = 0.0f; } // Throws rupee when this->spawnRuppyTimer == 0 @@ -346,12 +347,17 @@ void EnDivingGame_RupeeThrow(EnDivingGame* this, PlayState* play) { Audio_SetExtraFilter(0); } if (this->subCamId != 0) { - Math_ApproachF(&this->camEye.x, this->unk_2D0.x, this->unk_2DC.x, this->unk_2E8.x * this->unk_318); - Math_ApproachF(&this->camEye.z, this->unk_2D0.z, this->unk_2DC.z, this->unk_2E8.z * this->unk_318); - Math_ApproachF(&this->camLookAt.x, this->unk_2F4.x, this->unk_300.x, this->unk_30C.x * this->unk_318); - Math_ApproachF(&this->camLookAt.y, this->unk_2F4.y, this->unk_300.y, this->unk_30C.y * this->unk_318); - Math_ApproachF(&this->camLookAt.z, this->unk_2F4.z, this->unk_300.z, this->unk_30C.z * this->unk_318); - Math_ApproachF(&this->unk_318, 1.0f, 1.0f, 0.02f); + Math_ApproachF(&this->camEye.x, this->subCamEyeNext.x, this->subCamEyeMaxVelFrac.x, + this->subCamEyeVel.x * this->subCamVelFactor); + Math_ApproachF(&this->camEye.z, this->subCamEyeNext.z, this->subCamEyeMaxVelFrac.z, + this->subCamEyeVel.z * this->subCamVelFactor); + Math_ApproachF(&this->camLookAt.x, this->subCamAtNext.x, this->subCamAtMaxVelFrac.x, + this->subCamAtVel.x * this->subCamVelFactor); + Math_ApproachF(&this->camLookAt.y, this->subCamAtNext.y, this->subCamAtMaxVelFrac.y, + this->subCamAtVel.y * this->subCamVelFactor); + Math_ApproachF(&this->camLookAt.z, this->subCamAtNext.z, this->subCamAtMaxVelFrac.z, + this->subCamAtVel.z * this->subCamVelFactor); + Math_ApproachF(&this->subCamVelFactor, 1.0f, 1.0f, 0.02f); } Play_CameraSetAtEye(play, this->subCamId, &this->camLookAt, &this->camEye); if (!this->allRupeesThrown && this->spawnRuppyTimer == 0) { @@ -368,10 +374,12 @@ void EnDivingGame_RupeeThrow(EnDivingGame* this, PlayState* play) { this->allRupeesThrown = true; } } - if (this->csCameraTimer == 0 || - ((fabsf(this->camEye.x - this->unk_2D0.x) < 2.0f) && (fabsf(this->camEye.y - this->unk_2D0.y) < 2.0f) && - (fabsf(this->camEye.z - this->unk_2D0.z) < 2.0f) && (fabsf(this->camLookAt.x - this->unk_2F4.x) < 2.0f) && - (fabsf(this->camLookAt.y - this->unk_2F4.y) < 2.0f) && (fabsf(this->camLookAt.z - this->unk_2F4.z) < 2.0f))) { + if (this->csCameraTimer == 0 || ((fabsf(this->camEye.x - this->subCamEyeNext.x) < 2.0f) && + (fabsf(this->camEye.y - this->subCamEyeNext.y) < 2.0f) && + (fabsf(this->camEye.z - this->subCamEyeNext.z) < 2.0f) && + (fabsf(this->camLookAt.x - this->subCamAtNext.x) < 2.0f) && + (fabsf(this->camLookAt.y - this->subCamAtNext.y) < 2.0f) && + (fabsf(this->camLookAt.z - this->subCamAtNext.z) < 2.0f))) { if (this->unk_2A2 != 0) { this->csCameraTimer = 70; this->unk_2A2 = 2; @@ -389,12 +397,12 @@ void EnDivingGame_SetupUnderwaterViewCs(EnDivingGame* this, PlayState* play) { this->unk_2A2 = 1; this->csCameraTimer = 100; this->actionFunc = EnDivingGame_RupeeThrow; - this->camLookAt.x = this->unk_2F4.x = -210.0f; - this->camLookAt.y = this->unk_2F4.y = -80.0f; - this->camLookAt.z = this->unk_2F4.z = -1020.0f; - this->camEye.x = this->unk_2D0.x = -280.0f; - this->camEye.y = this->unk_2D0.y = -20.0f; - this->camEye.z = this->unk_2D0.z = -240.0f; + this->camLookAt.x = this->subCamAtNext.x = -210.0f; + this->camLookAt.y = this->subCamAtNext.y = -80.0f; + this->camLookAt.z = this->subCamAtNext.z = -1020.0f; + this->camEye.x = this->subCamEyeNext.x = -280.0f; + this->camEye.y = this->subCamEyeNext.y = -20.0f; + this->camEye.z = this->subCamEyeNext.z = -240.0f; } } @@ -416,10 +424,12 @@ void func_809EE800(EnDivingGame* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (this->unk_292 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); - if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_SILVER_SCALE)) { - Interface_SetTimer(BREG(2) + 50); - } else { - Interface_SetTimer(BREG(2) + 50); + if (GameInteractor_Should(VB_SET_DIVING_GAME_TIME_LIMIT, true)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_SILVER_SCALE)) { + Interface_SetTimer(BREG(2) + 50); + } else { + Interface_SetTimer(BREG(2) + 50); + } } func_800F5ACC(NA_BGM_TIMED_MINI_GAME); Player_SetCsActionWithHaltedActors(play, NULL, 7); diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.h b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.h index 57acaafb46..744255589d 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.h +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.h @@ -33,13 +33,13 @@ typedef struct EnDivingGame { /* 0x02AC */ char unk_2AC[0xC]; // probably another Vec3f, but unused. /* 0x02B8 */ Vec3f camLookAt; /* 0x02C4 */ Vec3f camEye; - /* 0x02D0 */ Vec3f unk_2D0; - /* 0x02DC */ Vec3f unk_2DC; - /* 0x02E8 */ Vec3f unk_2E8; - /* 0x02F4 */ Vec3f unk_2F4; - /* 0x0300 */ Vec3f unk_300; - /* 0x030C */ Vec3f unk_30C; - /* 0x0318 */ f32 unk_318; + /* 0x02D0 */ Vec3f subCamEyeNext; + /* 0x02DC */ Vec3f subCamEyeMaxVelFrac; + /* 0x02E8 */ Vec3f subCamEyeVel; + /* 0x02F4 */ Vec3f subCamAtNext; + /* 0x0300 */ Vec3f subCamAtMaxVelFrac; + /* 0x030C */ Vec3f subCamAtVel; + /* 0x0318 */ f32 subCamVelFactor; /* 0x031C */ char unk_31C; // unused /* 0x031D */ u8 notPlayingMinigame; // flag /* 0x031E */ u8 allRupeesThrown; // flag diff --git a/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c b/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c index 6235d87100..4601816c0e 100644 --- a/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c +++ b/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c @@ -17,21 +17,21 @@ void EnDodojr_Destroy(Actor* thisx, PlayState* play); void EnDodojr_Update(Actor* thisx, PlayState* play); void EnDodojr_Draw(Actor* thisx, PlayState* play); -void func_809F73AC(EnDodojr* this, PlayState* play); -void func_809F7BE4(EnDodojr* this, PlayState* play); -void func_809F74C4(EnDodojr* this, PlayState* play); -void func_809F758C(EnDodojr* this, PlayState* play); -void func_809F786C(EnDodojr* this, PlayState* play); -void func_809F799C(EnDodojr* this, PlayState* play); -void func_809F78EC(EnDodojr* this, PlayState* play); -void func_809F773C(EnDodojr* this, PlayState* play); -void func_809F77AC(EnDodojr* this, PlayState* play); -void func_809F784C(EnDodojr* this, PlayState* play); -void func_809F7AB8(EnDodojr* this, PlayState* play); -void func_809F7A00(EnDodojr* this, PlayState* play); -void func_809F7B3C(EnDodojr* this, PlayState* play); -void func_809F7C48(EnDodojr* this, PlayState* play); -void func_809F768C(EnDodojr* this, PlayState* play); +void EnDodojr_WaitUnderground(EnDodojr* this, PlayState* play); +void EnDodojr_DropItem(EnDodojr* this, PlayState* play); +void EnDodojr_EmergeFromGround(EnDodojr* this, PlayState* play); +void EnDodojr_CrawlTowardsTarget(EnDodojr* this, PlayState* play); +void EnDodojr_StunnedBounce(EnDodojr* this, PlayState* play); +void EnDodojr_JumpAttackBounce(EnDodojr* this, PlayState* play); +void EnDodojr_Stunned(EnDodojr* this, PlayState* play); +void EnDodojr_SwallowBomb(EnDodojr* this, PlayState* play); +void EnDodojr_SwallowedBombDeathBounce(EnDodojr* this, PlayState* play); +void EnDodojr_SwallowedBombDeathSequence(EnDodojr* this, PlayState* play); +void EnDodojr_StandardDeathBounce(EnDodojr* this, PlayState* play); +void EnDodojr_Despawn(EnDodojr* this, PlayState* play); +void EnDodojr_DeathSequence(EnDodojr* this, PlayState* play); +void EnDodojr_WaitFreezeFrames(EnDodojr* this, PlayState* play); +void EnDodojr_EatBomb(EnDodojr* this, PlayState* play); const ActorInit En_Dodojr_InitVars = { ACTOR_EN_DODOJR, @@ -83,7 +83,7 @@ void EnDodojr_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 0.02f); - this->actionFunc = func_809F73AC; + this->actionFunc = EnDodojr_WaitUnderground; } void EnDodojr_Destroy(Actor* thisx, PlayState* play) { @@ -94,12 +94,12 @@ void EnDodojr_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -void func_809F64D0(EnDodojr* this) { +void EnDodojr_DoSwallowedBombEffects(EnDodojr* this) { Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION); Actor_SetColorFilter(&this->actor, 0x4000, 200, 0, 8); } -void func_809F6510(EnDodojr* this, PlayState* play, s32 count) { +void EnDodojr_SpawnLargeDust(EnDodojr* this, PlayState* play, s32 count) { Color_RGBA8 prim = { 170, 130, 90, 255 }; Color_RGBA8 env = { 100, 60, 20, 0 }; Vec3f velocity = { 0.0f, 0.0f, 0.0f }; @@ -121,7 +121,7 @@ void func_809F6510(EnDodojr* this, PlayState* play, s32 count) { } } -void func_809F6730(EnDodojr* this, PlayState* play, Vec3f* arg2) { +void EnDodojr_SpawnSmallDust(EnDodojr* this, PlayState* play, Vec3f* arg2) { Color_RGBA8 prim = { 170, 130, 90, 255 }; Color_RGBA8 env = { 100, 60, 20, 0 }; Vec3f velocity = { 0.0f, 0.0f, 0.0f }; @@ -140,23 +140,23 @@ void func_809F6730(EnDodojr* this, PlayState* play, Vec3f* arg2) { func_8002836C(play, &pos, &velocity, &accel, &prim, &env, 100, 60, 8); } -s32 func_809F68B0(EnDodojr* this, PlayState* play) { +s32 EnDodojr_UpdateBounces(EnDodojr* this, PlayState* play) { if (this->actor.velocity.y >= 0.0f) { return 0; } - if (this->unk_1FC == 0) { + if (this->counter == 0) { return 0; } if (this->actor.bgCheckFlags & 1) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND); this->dustPos = this->actor.world.pos; - func_809F6510(this, play, 10); - this->actor.velocity.y = 10.0f / (4 - this->unk_1FC); - this->unk_1FC--; + EnDodojr_SpawnLargeDust(this, play, 10); + this->actor.velocity.y = 10.0f / (4 - this->counter); + this->counter--; - if (this->unk_1FC == 0) { + if (this->counter == 0) { this->actor.velocity.y = 0.0f; return 1; } @@ -165,7 +165,7 @@ s32 func_809F68B0(EnDodojr* this, PlayState* play) { return 0; } -void func_809F6994(EnDodojr* this) { +void EnDodojr_SetupCrawlTowardsTarget(EnDodojr* this) { f32 lastFrame = Animation_GetLastFrame(&object_dodojr_Anim_000860); Animation_Change(&this->skelAnime, &object_dodojr_Anim_000860, 1.8f, 0.0f, lastFrame, ANIMMODE_LOOP_INTERP, -10.0f); @@ -174,7 +174,7 @@ void func_809F6994(EnDodojr* this) { this->actor.gravity = -0.8f; } -void func_809F6A20(EnDodojr* this) { +void EnDodojr_SetupFlipBounce(EnDodojr* this) { f32 lastFrame = Animation_GetLastFrame(&object_dodojr_Anim_0004A0); Animation_Change(&this->skelAnime, &object_dodojr_Anim_0004A0, 1.0f, 0.0f, lastFrame, ANIMMODE_ONCE, -10.0f); @@ -183,14 +183,14 @@ void func_809F6A20(EnDodojr* this) { this->actor.velocity.z = 0.0f; this->actor.gravity = -0.8f; - if (this->unk_1FC == 0) { - this->unk_1FC = 3; + if (this->counter == 0) { + this->counter = 3; this->actor.velocity.y = 10.0f; } GameInteractor_ExecuteOnEnemyDefeat(&this->actor); } -void func_809F6AC4(EnDodojr* this) { +void EnDodojr_SetupSwallowedBombDeathSequence(EnDodojr* this) { f32 lastFrame = Animation_GetLastFrame(&object_dodojr_Anim_0005F0); Animation_Change(&this->skelAnime, &object_dodojr_Anim_0005F0, 1.0f, 0.0f, lastFrame, ANIMMODE_LOOP, 0.0f); @@ -198,16 +198,16 @@ void func_809F6AC4(EnDodojr* this) { this->actor.gravity = -0.8f; } -void func_809F6B38(EnDodojr* this) { +void EnDodojr_SetupJumpAttackBounce(EnDodojr* this) { f32 lastFrame = Animation_GetLastFrame(&object_dodojr_Anim_000724); Animation_Change(&this->skelAnime, &object_dodojr_Anim_000724, 1.0f, 0.0f, lastFrame, ANIMMODE_LOOP, -10.0f); this->actor.gravity = -0.8f; - this->unk_1FC = 3; + this->counter = 3; this->actor.velocity.y = 10.0f; } -void func_809F6BBC(EnDodojr* this) { +void EnDodojr_SetupDespawn(EnDodojr* this) { this->actor.shape.shadowDraw = NULL; this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; this->actor.home.pos = this->actor.world.pos; @@ -217,7 +217,7 @@ void func_809F6BBC(EnDodojr* this) { this->dustPos = this->actor.world.pos; } -void func_809F6C24(EnDodojr* this) { +void EnDodojr_SetupEatBomb(EnDodojr* this) { Animation_Change(&this->skelAnime, &object_dodojr_Anim_000724, 1.0f, 8.0f, 12.0f, ANIMMODE_ONCE, 0.0f); Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_EAT); this->actor.speedXZ = 0.0f; @@ -226,7 +226,7 @@ void func_809F6C24(EnDodojr* this) { this->actor.gravity = -0.8f; } -s32 func_809F6CA4(EnDodojr* this, PlayState* play) { +s32 EnDodojr_CheckNearbyBombs(EnDodojr* this, PlayState* play) { Actor* bomb; Vec3f unkVec = { 99999.0f, 99999.0f, 99999.0f }; s32 retVar = 0; @@ -267,7 +267,7 @@ s32 func_809F6CA4(EnDodojr* this, PlayState* play) { return retVar; } -s32 func_809F6DD0(EnDodojr* this) { +s32 EnDodojr_TryEatBomb(EnDodojr* this) { if (this->bomb == NULL) { return 0; } else if (this->bomb->parent != NULL) { @@ -280,7 +280,7 @@ s32 func_809F6DD0(EnDodojr* this) { } } -void func_809F6E54(EnDodojr* this, PlayState* play) { +void EnDodojr_UpdateCrawl(EnDodojr* this, PlayState* play) { f32 angles[] = { 0.0f, 210.0f, 60.0f, 270.0f, 120.0f, 330.0f, 180.0f, 30.0f, 240.0f, 90.0f, 300.0f, 150.0f }; s32 pad; Player* player = GET_PLAYER(play); @@ -289,7 +289,7 @@ void func_809F6E54(EnDodojr* this, PlayState* play) { if ((this->bomb == NULL) || (this->bomb->update == NULL) || ((this->bomb != NULL) && (this->bomb->parent != NULL))) { - func_809F6CA4(this, play); + EnDodojr_CheckNearbyBombs(this, play); } if (this->bomb != NULL) { @@ -311,7 +311,7 @@ void func_809F6E54(EnDodojr* this, PlayState* play) { this->actor.shape.rot.y = this->actor.world.rot.y; } -s32 func_809F706C(EnDodojr* this) { +s32 EnDodojr_IsPlayerWithinAttackRange(EnDodojr* this) { if (this->actor.xzDistToPlayer > 40.0f) { return 0; } else { @@ -319,28 +319,28 @@ s32 func_809F706C(EnDodojr* this) { } } -void func_809F709C(EnDodojr* this) { +void EnDodojr_SetupStandardDeathBounce(EnDodojr* this) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_DEAD); this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - func_809F6A20(this); - this->actionFunc = func_809F7AB8; + EnDodojr_SetupFlipBounce(this); + this->actionFunc = EnDodojr_StandardDeathBounce; } -s32 func_809F70E8(EnDodojr* this, PlayState* play) { - if ((this->actionFunc == func_809F773C) || (this->actionFunc == func_809F77AC) || - (this->actionFunc == func_809F784C) || (this->actionFunc == func_809F7A00) || - (this->actionFunc == func_809F7AB8) || (this->actionFunc == func_809F7B3C) || - (this->actionFunc == func_809F7BE4)) { +s32 EnDodojr_CheckDamaged(EnDodojr* this, PlayState* play) { + if ((this->actionFunc == EnDodojr_SwallowBomb) || (this->actionFunc == EnDodojr_SwallowedBombDeathBounce) || + (this->actionFunc == EnDodojr_SwallowedBombDeathSequence) || (this->actionFunc == EnDodojr_Despawn) || + (this->actionFunc == EnDodojr_StandardDeathBounce) || (this->actionFunc == EnDodojr_DeathSequence) || + (this->actionFunc == EnDodojr_DropItem)) { return 0; } if (play->actorCtx.unk_02 != 0) { - if (this->actionFunc != func_809F73AC) { - if (this->actionFunc == func_809F74C4) { + if (this->actionFunc != EnDodojr_WaitUnderground) { + if (this->actionFunc == EnDodojr_EmergeFromGround) { this->actor.shape.shadowDraw = ActorShadow_DrawCircle; } - func_809F709C(this); + EnDodojr_SetupStandardDeathBounce(this); } return 0; } @@ -350,42 +350,42 @@ s32 func_809F70E8(EnDodojr* this, PlayState* play) { } else { this->collider.base.acFlags &= ~2; - if ((this->actionFunc == func_809F73AC) || (this->actionFunc == func_809F74C4)) { + if ((this->actionFunc == EnDodojr_WaitUnderground) || (this->actionFunc == EnDodojr_EmergeFromGround)) { this->actor.shape.shadowDraw = ActorShadow_DrawCircle; } if ((this->actor.colChkInfo.damageEffect == 0) && (this->actor.colChkInfo.damage != 0)) { Enemy_StartFinishingBlow(play, &this->actor); this->timer2 = 2; - this->actionFunc = func_809F7C48; + this->actionFunc = EnDodojr_WaitFreezeFrames; return 1; } - if ((this->actor.colChkInfo.damageEffect == 1) && (this->actionFunc != func_809F78EC) && - (this->actionFunc != func_809F786C)) { + if ((this->actor.colChkInfo.damageEffect == 1) && (this->actionFunc != EnDodojr_Stunned) && + (this->actionFunc != EnDodojr_StunnedBounce)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE); this->timer1 = 120; Actor_SetColorFilter(&this->actor, 0, 200, 0, 120); - func_809F6A20(this); - this->actionFunc = func_809F786C; + EnDodojr_SetupFlipBounce(this); + this->actionFunc = EnDodojr_StunnedBounce; } return 0; } } -void func_809F72A4(EnDodojr* this, PlayState* play) { +void EnDodojr_UpdateCollider(EnDodojr* this, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); - if ((this->actionFunc != func_809F73AC) && (this->actionFunc != func_809F7BE4)) { - if ((this->actionFunc == func_809F74C4) || (this->actionFunc == func_809F758C) || - (this->actionFunc == func_809F799C)) { + if ((this->actionFunc != EnDodojr_WaitUnderground) && (this->actionFunc != EnDodojr_DropItem)) { + if ((this->actionFunc == EnDodojr_EmergeFromGround) || (this->actionFunc == EnDodojr_CrawlTowardsTarget) || + (this->actionFunc == EnDodojr_JumpAttackBounce)) { CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); } - if ((this->actionFunc == func_809F74C4) || (this->actionFunc == func_809F758C) || - (this->actionFunc == func_809F786C) || (this->actionFunc == func_809F78EC) || - (this->actionFunc == func_809F799C)) { + if ((this->actionFunc == EnDodojr_EmergeFromGround) || (this->actionFunc == EnDodojr_CrawlTowardsTarget) || + (this->actionFunc == EnDodojr_StunnedBounce) || (this->actionFunc == EnDodojr_Stunned) || + (this->actionFunc == EnDodojr_JumpAttackBounce)) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); } @@ -393,7 +393,7 @@ void func_809F72A4(EnDodojr* this, PlayState* play) { } } -void func_809F73AC(EnDodojr* this, PlayState* play) { +void EnDodojr_WaitUnderground(EnDodojr* this, PlayState* play) { f32 lastFrame = Animation_GetLastFrame(&object_dodojr_Anim_000860); Player* player = GET_PLAYER(play); f32 dist; @@ -411,59 +411,59 @@ void func_809F73AC(EnDodojr* this, PlayState* play) { this->actor.shape.rot.x = this->actor.world.rot.x; this->dustPos = this->actor.world.pos; this->dustPos.y = this->actor.floorHeight; - this->actionFunc = func_809F74C4; + this->actionFunc = EnDodojr_EmergeFromGround; } } } -void func_809F74C4(EnDodojr* this, PlayState* play) { +void EnDodojr_EmergeFromGround(EnDodojr* this, PlayState* play) { f32 sp2C; Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 4, 0x3E8, 0x64); sp2C = this->actor.shape.rot.x; sp2C /= 16384.0f; this->actor.world.pos.y = this->actor.home.pos.y + (60.0f * sp2C); - func_809F6510(this, play, 3); + EnDodojr_SpawnLargeDust(this, play, 3); if (sp2C == 0.0f) { this->actor.shape.shadowDraw = ActorShadow_DrawCircle; this->actor.world.rot.x = this->actor.shape.rot.x; this->actor.speedXZ = 2.6f; - this->actionFunc = func_809F758C; + this->actionFunc = EnDodojr_CrawlTowardsTarget; } } -void func_809F758C(EnDodojr* this, PlayState* play) { +void EnDodojr_CrawlTowardsTarget(EnDodojr* this, PlayState* play) { Actor_UpdateVelocityXZGravity(&this->actor); - func_809F6730(this, play, &this->actor.world.pos); + EnDodojr_SpawnSmallDust(this, play, &this->actor.world.pos); if (DECR(this->timer4) == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_MOVE); this->timer4 = 5; } - if (func_809F6DD0(this) != 0) { - func_809F6C24(this); - this->actionFunc = func_809F768C; + if (EnDodojr_TryEatBomb(this) != 0) { + EnDodojr_SetupEatBomb(this); + this->actionFunc = EnDodojr_EatBomb; return; } - func_809F6E54(this, play); + EnDodojr_UpdateCrawl(this, play); - if (func_809F706C(this) != 0) { + if (EnDodojr_IsPlayerWithinAttackRange(this) != 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_CRY); - func_809F6B38(this); - this->actionFunc = func_809F799C; + EnDodojr_SetupJumpAttackBounce(this); + this->actionFunc = EnDodojr_JumpAttackBounce; } if (this->actor.bgCheckFlags & 8) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_DOWN); - func_809F6BBC(this); - this->actionFunc = func_809F7A00; + EnDodojr_SetupDespawn(this); + this->actionFunc = EnDodojr_Despawn; } } -void func_809F768C(EnDodojr* this, PlayState* play) { +void EnDodojr_EatBomb(EnDodojr* this, PlayState* play) { EnBom* bomb; if (((s16)this->skelAnime.curFrame - 8) < 4) { @@ -474,43 +474,43 @@ void func_809F768C(EnDodojr* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_K_DRINK); Actor_Kill(this->bomb); this->timer3 = 24; - this->unk_1FC = 0; - this->actionFunc = func_809F773C; + this->counter = 0; + this->actionFunc = EnDodojr_SwallowBomb; } } -void func_809F773C(EnDodojr* this, PlayState* play) { +void EnDodojr_SwallowBomb(EnDodojr* this, PlayState* play) { if (DECR(this->timer3) == 0) { - func_809F64D0(this); + EnDodojr_DoSwallowedBombEffects(this); this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - func_809F6A20(this); - this->actionFunc = func_809F77AC; + EnDodojr_SetupFlipBounce(this); + this->actionFunc = EnDodojr_SwallowedBombDeathBounce; } } -void func_809F77AC(EnDodojr* this, PlayState* play) { +void EnDodojr_SwallowedBombDeathBounce(EnDodojr* this, PlayState* play) { this->rootScale = 1.2f; this->rootScale *= ((f32)this->actor.colorFilterTimer / 8); Actor_UpdateVelocityXZGravity(&this->actor); - if (func_809F68B0(this, play) != 0) { + if (EnDodojr_UpdateBounces(this, play) != 0) { this->timer3 = 60; - func_809F6AC4(this); - this->unk_1FC = 7; - this->actionFunc = func_809F784C; + EnDodojr_SetupSwallowedBombDeathSequence(this); + this->counter = 7; + this->actionFunc = EnDodojr_SwallowedBombDeathSequence; } } -void func_809F784C(EnDodojr* this, PlayState* play) { - func_809F7B3C(this, play); +void EnDodojr_SwallowedBombDeathSequence(EnDodojr* this, PlayState* play) { + EnDodojr_DeathSequence(this, play); } -void func_809F786C(EnDodojr* this, PlayState* play) { +void EnDodojr_StunnedBounce(EnDodojr* this, PlayState* play) { Actor_UpdateVelocityXZGravity(&this->actor); - if (func_809F68B0(this, play) != 0) { - func_809F6AC4(this); - this->actionFunc = func_809F78EC; + if (EnDodojr_UpdateBounces(this, play) != 0) { + EnDodojr_SetupSwallowedBombDeathSequence(this); + this->actionFunc = EnDodojr_Stunned; } Math_SmoothStepToS(&this->actor.shape.rot.y, 0, 4, 1000, 10); @@ -518,7 +518,7 @@ void func_809F786C(EnDodojr* this, PlayState* play) { this->actor.colorFilterTimer = this->timer1; } -void func_809F78EC(EnDodojr* this, PlayState* play) { +void EnDodojr_Stunned(EnDodojr* this, PlayState* play) { if (DECR(this->timer1) != 0) { if (this->timer1 < 30) { if ((this->timer1 & 1) != 0) { @@ -532,22 +532,22 @@ void func_809F78EC(EnDodojr* this, PlayState* play) { return; } } else { - func_809F6994(this); - this->actionFunc = func_809F758C; + EnDodojr_SetupCrawlTowardsTarget(this); + this->actionFunc = EnDodojr_CrawlTowardsTarget; } } -void func_809F799C(EnDodojr* this, PlayState* play) { +void EnDodojr_JumpAttackBounce(EnDodojr* this, PlayState* play) { this->actor.flags |= ACTOR_FLAG_SFX_FOR_PLAYER_BODY_HIT; Actor_UpdateVelocityXZGravity(&this->actor); - if (func_809F68B0(this, play) != 0) { - func_809F6994(this); - this->actionFunc = func_809F758C; + if (EnDodojr_UpdateBounces(this, play) != 0) { + EnDodojr_SetupCrawlTowardsTarget(this); + this->actionFunc = EnDodojr_CrawlTowardsTarget; } } -void func_809F7A00(EnDodojr* this, PlayState* play) { +void EnDodojr_Despawn(EnDodojr* this, PlayState* play) { f32 tmp; Math_SmoothStepToS(&this->actor.shape.rot.x, 0x4000, 4, 1000, 100); @@ -559,29 +559,29 @@ void func_809F7A00(EnDodojr* this, PlayState* play) { Actor_Kill(&this->actor); } - func_809F6510(this, play, 3); + EnDodojr_SpawnLargeDust(this, play, 3); } -void func_809F7AB8(EnDodojr* this, PlayState* play) { +void EnDodojr_StandardDeathBounce(EnDodojr* this, PlayState* play) { Actor_UpdateVelocityXZGravity(&this->actor); Math_SmoothStepToS(&this->actor.shape.rot.y, 0, 4, 1000, 10); this->actor.world.rot.x = this->actor.shape.rot.x; - if (func_809F68B0(this, play) != 0) { + if (EnDodojr_UpdateBounces(this, play) != 0) { this->timer3 = 60; - func_809F6AC4(this); - this->unk_1FC = 7; - this->actionFunc = func_809F7B3C; + EnDodojr_SetupSwallowedBombDeathSequence(this); + this->counter = 7; + this->actionFunc = EnDodojr_DeathSequence; } } -void func_809F7B3C(EnDodojr* this, PlayState* play) { +void EnDodojr_DeathSequence(EnDodojr* this, PlayState* play) { EnBom* bomb; - if (this->unk_1FC != 0) { + if (this->counter != 0) { if (this->actor.colorFilterTimer == 0) { - Actor_SetColorFilter(&this->actor, 0x4000, 200, 0, this->unk_1FC); - this->unk_1FC--; + Actor_SetColorFilter(&this->actor, 0x4000, 200, 0, this->counter); + this->counter--; } } else { bomb = (EnBom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOM, this->actor.world.pos.x, @@ -592,20 +592,20 @@ void func_809F7B3C(EnDodojr* this, PlayState* play) { } this->timer3 = 8; - this->actionFunc = func_809F7BE4; + this->actionFunc = EnDodojr_DropItem; } } -void func_809F7BE4(EnDodojr* this, PlayState* play) { +void EnDodojr_DropItem(EnDodojr* this, PlayState* play) { if (DECR(this->timer3) == 0) { Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, 0x40); Actor_Kill(&this->actor); } } -void func_809F7C48(EnDodojr* this, PlayState* play) { +void EnDodojr_WaitFreezeFrames(EnDodojr* this, PlayState* play) { if (DECR(this->timer2) == 0) { - func_809F709C(this); + EnDodojr_SetupStandardDeathBounce(this); } } @@ -614,18 +614,18 @@ void EnDodojr_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); Actor_MoveXZGravity(&this->actor); - func_809F70E8(this, play); + EnDodojr_CheckDamaged(this, play); - if (this->actionFunc != func_809F73AC) { + if (this->actionFunc != EnDodojr_WaitUnderground) { Actor_UpdateBgCheckInfo(play, &this->actor, this->collider.dim.radius, this->collider.dim.height, 0.0f, 5); } this->actionFunc(this, play); Actor_SetFocus(&this->actor, 10.0f); - func_809F72A4(this, play); + EnDodojr_UpdateCollider(this, play); } -s32 func_809F7D50(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { +s32 EnDodojr_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { EnDodojr* this = (EnDodojr*)thisx; Vec3f D_809F7F64 = { 480.0f, 620.0f, 0.0f }; @@ -641,14 +641,15 @@ s32 func_809F7D50(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s return false; } -void func_809F7DFC(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { +void EnDodojr_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { } void EnDodojr_Draw(Actor* thisx, PlayState* play) { EnDodojr* this = (EnDodojr*)thisx; - if ((this->actionFunc != func_809F73AC) && (this->actionFunc != func_809F7BE4)) { + if ((this->actionFunc != EnDodojr_WaitUnderground) && (this->actionFunc != EnDodojr_DropItem)) { Gfx_SetupDL_25Opa(play->state.gfxCtx); - SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, func_809F7D50, func_809F7DFC, &this->actor); + SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnDodojr_OverrideLimbDraw, EnDodojr_PostLimbDraw, + &this->actor); } } diff --git a/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.h b/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.h index 098001772e..1f6da6a3f2 100644 --- a/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.h +++ b/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.h @@ -16,7 +16,7 @@ typedef struct EnDodojr { /* 0x01E0 */ Actor* bomb; /* 0x01E4 */ Vec3f headPos; /* 0x01F0 */ Vec3f dustPos; - /* 0x01FC */ s16 unk_1FC; + /* 0x01FC */ s16 counter; /* 0x01FE */ s16 timer1; /* 0x0200 */ s16 timer2; /* 0x0202 */ s16 timer3; diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c index 76c5238012..bcc9e397d6 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c @@ -120,7 +120,7 @@ void EnDu_SetupAction(EnDu* this, EnDuActionFunc actionFunc) { this->actionFunc = actionFunc; } -u16 func_809FDC38(PlayState* play, Actor* actor) { +u16 EnDu_GetTextId(PlayState* play, Actor* actor) { u16 reaction = Text_GetFaceReaction(play, 0x21); if (reaction != 0) { @@ -140,7 +140,7 @@ u16 func_809FDC38(PlayState* play, Actor* actor) { } } -s16 func_809FDCDC(PlayState* play, Actor* actor) { +s16 EnDu_UpdateTalkState(PlayState* play, Actor* actor) { switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_NONE: case TEXT_STATE_DONE_HAS_NEXT: @@ -623,7 +623,7 @@ void EnDu_Update(Actor* thisx, PlayState* play) { if (this->actionFunc != func_809FE4A4) { Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 116.0f, - func_809FDC38, func_809FDCDC); + EnDu_GetTextId, EnDu_UpdateTalkState); } this->actionFunc(this, play); } diff --git a/soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c b/soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c index ac36315641..577d70d990 100644 --- a/soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c +++ b/soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c @@ -144,7 +144,7 @@ void EnEncount1_SpawnLeevers(EnEncount1* this, PlayState* play) { if (leever != NULL) { this->curNumSpawn++; - leever->unk_280 = this->leeverIndex++; + leever->aimType = this->leeverIndex++; if (this->leeverIndex >= 5) { this->leeverIndex = 0; } diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h index 090d7028ca..55acc87d7e 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h @@ -14,7 +14,7 @@ typedef struct EnExItem { /* 0x014C */ EnExItemActionFunc actionFunc; /* 0x0150 */ s16 getItemObjId; /* 0x0152 */ s16 type; - /* 0x0152 */ s16 unusedParam; + /* 0x0154 */ s16 unusedParam; /* 0x0156 */ s16 giDrawId; /* 0x0158 */ s16 stopRotate; /* 0x015A */ s16 timer; diff --git a/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c b/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c index c8509aa518..7ee6432b29 100644 --- a/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c +++ b/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c @@ -8,6 +8,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "vt.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -679,7 +680,7 @@ void EnFish_UpdateCutscene(EnFish* this, PlayState* play) { // Update functions and Draw void EnFish_OrdinaryUpdate(EnFish* this, PlayState* play) { - if (this->timer > 0 && CVarGetInteger(CVAR_CHEAT("NoFishDespawn"), 0) == 0) { + if (GameInteractor_Should(VB_FISH_TIMER_TICK, this->timer > 0)) { this->timer--; } diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index 5b610e3796..ab4ec68601 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -234,7 +234,7 @@ void EnGe1_KickPlayer(EnGe1* this, PlayState* play) { if (this->cutsceneTimer > 0) { this->cutsceneTimer--; } else { - func_8006D074(play); + Horse_ResetHorseData(play); if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) { play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1; @@ -599,7 +599,7 @@ void EnGe1_BeginGame_Archery(EnGe1* this, PlayState* play) { if (gSaveContext.rupees < 20) { Message_ContinueTextbox(play, 0x85); this->actionFunc = EnGe1_TalkTooPoor_Archery; - } else { + } else if (GameInteractor_Should(VB_PLAY_HORSEBACK_ARCHERY, true, this, play)) { Rupees_ChangeBy(-20); play->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_EAST_EXIT; gSaveContext.nextCutsceneIndex = 0xFFF0; diff --git a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c index 739ddf7324..61efee28bc 100644 --- a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -243,7 +243,7 @@ void EnGe2_CaptureClose(EnGe2* this, PlayState* play) { if (this->timer > 0) { this->timer--; } else { - func_8006D074(play); + Horse_ResetHorseData(play); if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) { play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1; @@ -273,7 +273,7 @@ void EnGe2_CaptureCharge(EnGe2* this, PlayState* play) { if (this->timer > 0) { this->timer--; } else { - func_8006D074(play); + Horse_ResetHorseData(play); if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) { play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1; diff --git a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index 9576c7a82f..e73609aa3e 100644 --- a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -664,6 +664,10 @@ s32 EnGirlA_CanBuy_Longsword(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_HylianShield(PlayState* play, EnGirlA* this) { + s32 canBuy; + if (GameInteractor_Should(VB_CAN_BUY_SHOP_SHIELD_OR_TUNIC, false, &canBuy, RAND_INF_HAS_FOUND_HYLIAN_SHIELD)) { + return canBuy; + } if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_HYLIAN)) { return CANBUY_RESULT_CANT_GET_NOW; } @@ -677,6 +681,10 @@ s32 EnGirlA_CanBuy_HylianShield(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_DekuShield(PlayState* play, EnGirlA* this) { + s32 canBuy; + if (GameInteractor_Should(VB_CAN_BUY_SHOP_SHIELD_OR_TUNIC, false, &canBuy, RAND_INF_HAS_FOUND_DEKU_SHIELD)) { + return canBuy; + } if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_DEKU)) { return CANBUY_RESULT_CANT_GET_NOW; } @@ -690,6 +698,10 @@ s32 EnGirlA_CanBuy_DekuShield(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_GoronTunic(PlayState* play, EnGirlA* this) { + s32 canBuy; + if (GameInteractor_Should(VB_CAN_BUY_SHOP_SHIELD_OR_TUNIC, false, &canBuy, RAND_INF_HAS_FOUND_GORON_TUNIC)) { + return canBuy; + } if (LINK_AGE_IN_YEARS == YEARS_CHILD && (!IS_RANDO || Randomizer_GetSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF)) { return CANBUY_RESULT_CANT_GET_NOW; @@ -707,6 +719,10 @@ s32 EnGirlA_CanBuy_GoronTunic(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_ZoraTunic(PlayState* play, EnGirlA* this) { + s32 canBuy; + if (GameInteractor_Should(VB_CAN_BUY_SHOP_SHIELD_OR_TUNIC, false, &canBuy, RAND_INF_HAS_FOUND_ZORA_TUNIC)) { + return canBuy; + } if (LINK_AGE_IN_YEARS == YEARS_CHILD && (!IS_RANDO || Randomizer_GetSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF)) { return CANBUY_RESULT_CANT_GET_NOW; diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index ed409b115d..6ef04cfe7a 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -823,8 +823,8 @@ s16 EnGo2_UpdateTalkState(PlayState* play, Actor* thisx) { s32 func_80A44790(EnGo2* this, PlayState* play) { if ((this->actor.params & 0x1F) != GORON_DMT_BIGGORON && (this->actor.params & 0x1F) != GORON_CITY_ROLLING_BIG) { - return Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->unk_218, EnGo2_GetTextId, - EnGo2_UpdateTalkState); + return Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->interactRange, + EnGo2_GetTextId, EnGo2_UpdateTalkState); } else if (((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) && ((this->collider.base.ocFlags2 & 1) == 0)) { return false; } else { @@ -834,7 +834,7 @@ s32 func_80A44790(EnGo2* this, PlayState* play) { } else if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { this->interactInfo.talkState = EnGo2_UpdateTalkState(play, &this->actor); return false; - } else if (func_8002F2CC(&this->actor, play, this->unk_218)) { + } else if (func_8002F2CC(&this->actor, play, this->interactRange)) { this->actor.textId = EnGo2_GetTextId(play, &this->actor); } return false; @@ -854,8 +854,8 @@ void EnGo2_SetShape(EnGo2* this) { this->actor.shape.shadowScale = D_80A481F8[index].shape_unk_10; Actor_SetScale(&this->actor, D_80A481F8[index].scale); this->actor.targetMode = D_80A481F8[index].actor_unk_1F; - this->unk_218 = D_80A481F8[index].unk_218; - this->unk_218 += this->collider.dim.radius; + this->interactRange = D_80A481F8[index].interactRange; + this->interactRange += this->collider.dim.radius; } void EnGo2_CheckCollision(EnGo2* this, PlayState* play) { @@ -2017,7 +2017,7 @@ void EnGo2_Update(Actor* thisx, PlayState* play) { } this->actionFunc(this, play); if (this->unk_211 == true) { - func_80034F54(play, this->unk_226, this->unk_24A, 18); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 18); } func_80A45288(this, play); EnGo2_EyeMouthTexState(this); @@ -2075,9 +2075,9 @@ s32 EnGo2_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, V Matrix_RotateX(float1, MTXMODE_APPLY); } if ((limb == 10) || (limb == 11) || (limb == 14)) { - float1 = Math_SinS(this->unk_226[limb]); + float1 = Math_SinS(this->fidgetTableY[limb]); rot->y += float1 * 200.0f; - float1 = Math_CosS(this->unk_24A[limb]); + float1 = Math_CosS(this->fidgetTableZ[limb]); rot->z += float1 * 200.0f; } return 0; diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h index 185a036f49..81c53f8821 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h @@ -53,7 +53,7 @@ typedef struct { f32 shape_unk_10; f32 scale; s8 actor_unk_1F; - f32 unk_218; + f32 interactRange; } EnGo2DataStruct2; // size = 0x10 typedef struct { @@ -86,12 +86,12 @@ typedef struct EnGo2 { /* 0x0214 */ u8 eyeTexIndex; /* 0x0215 */ u8 mouthTexIndex; /* 0x0216 */ u8 unk_216; // Set to z rotation, checked by waypoint - /* 0x0218 */ f32 unk_218; + /* 0x0218 */ f32 interactRange; /* 0x021C */ char unk_21C[0x04]; /* 0x0220 */ f32 alpha; // Set to 0, used by func_80A45360, smoothed to this->actor.shape.unk_14 from either 0 or 255.0f /* 0x0224 */ s16 blinkTimer; - /* 0x0226 */ s16 unk_226[18]; // Remains unknown - /* 0x024A */ s16 unk_24A[18]; // Remains unknown + /* 0x0226 */ s16 fidgetTableY[18]; // Remains unknown + /* 0x024A */ s16 fidgetTableZ[18]; // Remains unknown /* 0x026E */ u16 trackingMode; /* 0x0270 */ EnGoEffect dustEffects[10]; /* 0x04A0 */ Vec3f eye; diff --git a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c index f8372067cb..bc73c062e9 100644 --- a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c +++ b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c @@ -163,7 +163,7 @@ void func_80A505CC(Actor* thisx, PlayState* play) { } Npc_TrackPoint(&this->actor, &this->interactInfo, 6, NPC_TRACKING_HEAD_AND_TORSO); - func_80034F54(play, this->unk_2CC, this->unk_2EC, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); gSegments[6] = VIRTUAL_TO_PHYSICAL(play->objectCtx.status[this->osAnimeBankIndex].segment); @@ -206,8 +206,8 @@ s32 EnGuest_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* } if (limbIndex == 8 || limbIndex == 9 || limbIndex == 12) { - rot->y += Math_SinS(this->unk_2CC[limbIndex]) * 200.0f; - rot->z += Math_CosS(this->unk_2EC[limbIndex]) * 200.0f; + rot->y += Math_SinS(this->fidgetTableY[limbIndex]) * 200.0f; + rot->z += Math_CosS(this->fidgetTableZ[limbIndex]) * 200.0f; } CLOSE_DISPS(play->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.h b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.h index 4cf72a26c3..77d178f4f8 100644 --- a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.h +++ b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.h @@ -18,8 +18,8 @@ typedef struct EnGuest { /* 0x02A0 */ NpcInteractInfo interactInfo; /* 0x02C8 */ s16 unk_2C8; /* 0x02CA */ s16 unk_2CA; - /* 0x02CC */ s16 unk_2CC[16]; - /* 0x02EC */ s16 unk_2EC[16]; + /* 0x02CC */ s16 fidgetTableY[16]; + /* 0x02EC */ s16 fidgetTableZ[16]; /* 0x030C */ s8 osAnimeBankIndex; /* 0x030D */ u8 unk_30D; /* 0x030E */ u8 unk_30E; diff --git a/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c b/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c index 3ca5830335..9107ed6b48 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c +++ b/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c @@ -8,6 +8,7 @@ #include "objects/object_sd/object_sd.h" #include "vt.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED @@ -124,15 +125,21 @@ void EnHeishi1_Init(Actor* thisx, PlayState* play) { (Flags_GetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY)); if (this->type != 5) { - if ((gSaveContext.dayTime < 0xB888 || IS_DAY) && - ((!IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) || (IS_RANDO && !metZelda))) { + if (GameInteractor_Should(VB_WONDER_HEISHI_PATROLLING, + (gSaveContext.dayTime < 0xB888 || IS_DAY) && + ((!IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) || + (IS_RANDO && !metZelda)), + this)) { this->actionFunc = EnHeishi1_SetupWalk; } else { Actor_Kill(&this->actor); } } else { - if ((gSaveContext.dayTime >= 0xB889) || !IS_DAY || - (!IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) || (IS_RANDO && metZelda)) { + if (GameInteractor_Should(VB_WONDER_HEISHI_PATROLLING, + (gSaveContext.dayTime >= 0xB889) || !IS_DAY || + (!IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) || + (IS_RANDO && metZelda), + this)) { this->actionFunc = EnHeishi1_SetupWaitNight; } else { Actor_Kill(&this->actor); diff --git a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c index b6c1b866bd..598c27291c 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c +++ b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c @@ -321,15 +321,15 @@ void func_80A5372C(EnHeishi2* this, PlayState* play) { this->cameraId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE); - this->unk_280.x = 947.0f; - this->unk_280.y = 1195.0f; - this->unk_280.z = 2682.0f; + this->subCamEye.x = 947.0f; + this->subCamEye.y = 1195.0f; + this->subCamEye.z = 2682.0f; - this->unk_28C.x = 1164.0f; - this->unk_28C.y = 1145.0f; - this->unk_28C.z = 3014.0f; + this->subCamAt.x = 1164.0f; + this->subCamAt.y = 1145.0f; + this->subCamAt.z = 3014.0f; - Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + Play_CameraSetAtEye(play, this->cameraId, &this->subCamEye, &this->subCamAt); } this->actionFunc = func_80A53850; } @@ -339,7 +339,7 @@ void func_80A53850(EnHeishi2* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) { - Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + Play_CameraSetAtEye(play, this->cameraId, &this->subCamEye, &this->subCamAt); } gate = (BgSpot15Saku*)this->gate; if ((this->unk_2F2[0] == 0) || (gate->unk_168 == 0)) { @@ -492,19 +492,19 @@ void func_80A53DF8(EnHeishi2* this, PlayState* play) { this->cameraId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE); - this->unk_2BC.x = -71.0f; - this->unk_280.x = -71.0f; - this->unk_2BC.y = 571.0f; - this->unk_280.y = 571.0f; - this->unk_2BC.z = -1487.0f; - this->unk_280.z = -1487.0f; - this->unk_298.x = 181.0f; - this->unk_28C.x = 181.0f; - this->unk_298.y = 417.0f; - this->unk_28C.y = 417.0f; - this->unk_298.z = -1079.0f; - this->unk_28C.z = -1079.0f; - Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + this->subCamEyeInit.x = -71.0f; + this->subCamEye.x = -71.0f; + this->subCamEyeInit.y = 571.0f; + this->subCamEye.y = 571.0f; + this->subCamEyeInit.z = -1487.0f; + this->subCamEye.z = -1487.0f; + this->subCamAtInit.x = 181.0f; + this->subCamAt.x = 181.0f; + this->subCamAtInit.y = 417.0f; + this->subCamAt.y = 417.0f; + this->subCamAtInit.z = -1079.0f; + this->subCamAt.z = -1079.0f; + Play_CameraSetAtEye(play, this->cameraId, &this->subCamEye, &this->subCamAt); } this->actionFunc = func_80A53F30; } @@ -514,7 +514,7 @@ void func_80A53F30(EnHeishi2* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) { - Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); + Play_CameraSetAtEye(play, this->cameraId, &this->subCamEye, &this->subCamAt); } gate = (BgGateShutter*)this->gate; if ((this->unk_2F2[0] == 0) || (gate->openingState == 0)) { @@ -679,10 +679,12 @@ void func_80A5455C(EnHeishi2* this, PlayState* play) { pos.y = Rand_CenteredFloat(20.0f) + (this->unk_274.y - 40.0f); pos.z = Rand_CenteredFloat(20.0f) + (this->unk_274.z - 20.0f); rotY = Rand_CenteredFloat(7000.0f) + this->actor.yawTowardsPlayer; - bomb = (EnBom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOM, pos.x, pos.y, pos.z, 0, rotY, 0, 0); - if (bomb != NULL) { - bomb->actor.speedXZ = Rand_CenteredFloat(5.0f) + 10.0f; - bomb->actor.velocity.y = Rand_CenteredFloat(5.0f) + 10.0f; + if (GameInteractor_Should(VB_WONDER_HEISHI_ITEM, true, &pos, rotY)) { + bomb = (EnBom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOM, pos.x, pos.y, pos.z, 0, rotY, 0, 0); + if (bomb != NULL) { + bomb->actor.speedXZ = Rand_CenteredFloat(5.0f) + 10.0f; + bomb->actor.velocity.y = Rand_CenteredFloat(5.0f) + 10.0f; + } } // "This is down!" diff --git a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h index f88c67314f..410cb61a02 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h +++ b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h @@ -19,11 +19,11 @@ typedef struct EnHeishi2 { /* 0x0266 */ char unk_266[0x06]; /* 0x026C */ Vec3s unk_26C; // padding inbetween these /* 0x0274 */ Vec3f unk_274; - /* 0x0280 */ Vec3f unk_280; // camera related - /* 0x028C */ Vec3f unk_28C; // camera related - /* 0x0298 */ Vec3f unk_298; // camera related + /* 0x0280 */ Vec3f subCamEye; // camera related + /* 0x028C */ Vec3f subCamAt; // camera related + /* 0x0298 */ Vec3f subCamAtInit; // camera related /* 0x02A4 */ char unk_2A4[0x18]; - /* 0x02BC */ Vec3f unk_2BC; // camera related + /* 0x02BC */ Vec3f subCamEyeInit; // camera related /* 0x02C8 */ char unk_2C8[0x18]; /* 0x02E0 */ f32 unk_2E0; /* 0x02E4 */ f32 unk_2E4; diff --git a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c index 0bc1730596..2180f71cd3 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c +++ b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c @@ -268,7 +268,7 @@ void func_80A56900(EnHeishi4* this, PlayState* play) { void func_80A56994(EnHeishi4* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - func_80038290(play, &this->actor, &this->unk_260, &this->unk_266, this->actor.focus.pos); + func_80038290(play, &this->actor, &this->headRot, &this->torsoRot, this->actor.focus.pos); if ((this->unk_282 == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); Flags_SetInfTable(INFTABLE_6C); @@ -393,8 +393,8 @@ void EnHeishi4_Update(Actor* thisx, PlayState* play) { this->interactInfo.trackPos.y = player->actor.world.pos.y - 10.0f; } Npc_TrackPoint(thisx, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); - this->unk_260 = this->interactInfo.headRot; - this->unk_266 = this->interactInfo.torsoRot; + this->headRot = this->interactInfo.headRot; + this->torsoRot = this->interactInfo.torsoRot; } this->unk_27E += 1; this->actionFunc(this, play); @@ -408,11 +408,11 @@ s32 EnHeishi_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f EnHeishi4* this = (EnHeishi4*)thisx; if (limbIndex == 9) { - rot->x += this->unk_266.y; + rot->x += this->torsoRot.y; } if (limbIndex == 16) { - rot->x += this->unk_260.y; - rot->z += this->unk_260.z; + rot->x += this->headRot.y; + rot->z += this->headRot.z; } return false; } diff --git a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h index d7c57d78dd..1cc941ab2a 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h +++ b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h @@ -21,8 +21,8 @@ typedef struct EnHeishi4 { /* 0x0190 */ Vec3s jointTable[17]; /* 0x01F6 */ Vec3s morphTable[17]; /* 0x025C */ EnHeishi4ActionFunc actionFunc; - /* 0x0260 */ Vec3s unk_260; - /* 0x0266 */ Vec3s unk_266; + /* 0x0260 */ Vec3s headRot; + /* 0x0266 */ Vec3s torsoRot; /* 0x026C */ Vec3f pos; /* 0x0278 */ f32 height; /* 0x027C */ s16 unk_27C; diff --git a/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.c b/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.c index 86030a52a9..40e0dfbad9 100644 --- a/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.c +++ b/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.c @@ -97,7 +97,7 @@ void EnHoll_Init(Actor* thisx, PlayState* play) { Actor_ProcessInitChain(&this->actor, sInitChain); EnHoll_ChooseAction(this); - this->unk_14F = 0; + this->resetBgCoverAlpha = 0; } void EnHoll_Destroy(Actor* thisx, PlayState* play) { @@ -206,13 +206,13 @@ void func_80A591C0(EnHoll* this, PlayState* play) { if (this->actor.room != play->roomCtx.curRoom.num && func_8009728C(play, &play->roomCtx, this->actor.room) != 0) { EnHoll_SetupAction(this, EnHoll_NextAction); - this->unk_14F = 1; + this->resetBgCoverAlpha = 1; player->actor.speedXZ = 0.0f; } } - } else if (this->unk_14F != 0) { + } else if (this->resetBgCoverAlpha != 0) { play->unk_11E18 = 0; - this->unk_14F = 0; + this->resetBgCoverAlpha = 0; } } @@ -235,11 +235,11 @@ void func_80A593A4(EnHoll* this, PlayState* play) { if (this->actor.room != play->roomCtx.curRoom.num && func_8009728C(play, &play->roomCtx, this->actor.room) != 0) { EnHoll_SetupAction(this, EnHoll_NextAction); - this->unk_14F = 1; + this->resetBgCoverAlpha = 1; } } - } else if (this->unk_14F != 0) { - this->unk_14F = 0; + } else if (this->resetBgCoverAlpha != 0) { + this->resetBgCoverAlpha = 0; play->unk_11E18 = 0; } } @@ -273,15 +273,15 @@ void func_80A59618(EnHoll* this, PlayState* play) { s32 transitionActorIdx; if (!Flags_GetSwitch(play, this->actor.params & 0x3F)) { - if (this->unk_14F != 0) { + if (this->resetBgCoverAlpha != 0) { play->unk_11E18 = 0; - this->unk_14F = 0; + this->resetBgCoverAlpha = 0; } } else { Actor_WorldToActorCoords(&this->actor, &vec, &player->actor.world.pos); absZ = fabsf(vec.z); if (PLANE_Y_MIN < vec.y && vec.y < PLANE_Y_MAX && fabsf(vec.x) < PLANE_HALFWIDTH_2 && absZ < 100.0f) { - this->unk_14F = 1; + this->resetBgCoverAlpha = 1; transitionActorIdx = (u16)this->actor.params >> 0xA; play->unk_11E18 = 0xFF - (s32)((absZ - 50.0f) * 5.9f); if (play->unk_11E18 >= 0x100) { @@ -297,9 +297,9 @@ void func_80A59618(EnHoll* this, PlayState* play) { EnHoll_SetupAction(this, EnHoll_NextAction); } } - } else if (this->unk_14F != 0) { + } else if (this->resetBgCoverAlpha != 0) { play->unk_11E18 = 0; - this->unk_14F = 0; + this->resetBgCoverAlpha = 0; } } } @@ -308,7 +308,7 @@ void EnHoll_NextAction(EnHoll* this, PlayState* play) { if (!EnHoll_IsKokiriSetup8() && play->roomCtx.status == 0) { func_80097534(play, &play->roomCtx); if (play->unk_11E18 == 0) { - this->unk_14F = 0; + this->resetBgCoverAlpha = 0; } EnHoll_ChooseAction(this); } diff --git a/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.h b/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.h index 950f7d094e..935c398005 100644 --- a/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.h +++ b/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.h @@ -12,7 +12,7 @@ typedef struct EnHoll { /* 0x0000 */ Actor actor; /* 0x014C */ s16 planeAlpha; /* 0x014E */ u8 side; - /* 0x014F */ u8 unk_14F; + /* 0x014F */ u8 resetBgCoverAlpha; /* 0x0150 */ EnHollActionFunc actionFunc; } EnHoll; // size = 0x0154 diff --git a/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c b/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c index 5ddb429e4a..502b07301c 100644 --- a/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c +++ b/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c @@ -532,7 +532,7 @@ void EnHorse_RaceWaypointPos(RaceWaypoint* waypoints, s32 idx, Vec3f* pos) { } void EnHorse_RotateToPoint(EnHorse* this, PlayState* play, Vec3f* pos, s16 turnAmount) { - func_8006DD9C(&this->actor, pos, turnAmount); + Horse_RotateToPoint(&this->actor, pos, turnAmount); } void EnHorse_UpdateIngoRaceInfo(EnHorse* this, PlayState* play, RaceInfo* raceInfo) { diff --git a/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c b/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c index fe3ec787a4..03aebe1c73 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c +++ b/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c @@ -231,7 +231,7 @@ s32 EnHorseGameCheck_InitGerudoArchery(EnHorseGameCheckBase* base, PlayState* pl EnHorseGameCheckGerudoArchery* this = (EnHorseGameCheckGerudoArchery*)base; this->base.type = HORSEGAME_GERUDO_ARCHERY; - this->unk_150 = 0; + this->startFlags = 0; this->startTimer = 0; return true; } @@ -261,7 +261,7 @@ s32 EnHorseGameCheck_InitType3(EnHorseGameCheckBase* base, PlayState* play) { EnHorseGameCheck3* this = (EnHorseGameCheck3*)base; this->base.type = HORSEGAME_TYPE3; - this->unk_150 = 0; + this->startFlags = 0; return true; } diff --git a/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h b/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h index 3c39cf1edb..9655d2f725 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h +++ b/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h @@ -28,13 +28,13 @@ typedef struct EnHorseGameCheckIngoRace { typedef struct EnHorseGameCheckGerudoArchery { /* 0x0000 */ EnHorseGameCheckBase base; - /* 0x0150 */ s32 unk_150; + /* 0x0150 */ s32 startFlags; /* 0x0154 */ u32 startTimer; } EnHorseGameCheckGerudoArchery; // size = 0x0158 typedef struct EnHorseGameCheck3 { /* 0x0000 */ EnHorseGameCheckBase base; - /* 0x0150 */ s32 unk_150; + /* 0x0150 */ s32 startFlags; } EnHorseGameCheck3; // size = 0x0154 typedef struct EnHorseGameCheckMalonRace { diff --git a/soh/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c b/soh/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c index 630156e84d..452f3bfa21 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c +++ b/soh/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c @@ -453,7 +453,7 @@ void func_80A6A5A4(EnHorseLinkChild* this, PlayState* play) { yawDiff = Actor_WorldYawTowardActor(&this->actor, &GET_PLAYER(play)->actor) - this->actor.world.rot.y; // 0.7071 = cos(pi/4) if ((Math_CosS(yawDiff) < 0.7071f) && (this->animationIdx == 2)) { - func_8006DD9C(&this->actor, &GET_PLAYER(play)->actor.world.pos, 300); + Horse_RotateToPoint(&this->actor, &GET_PLAYER(play)->actor.world.pos, 300); } if (SkelAnime_Update(&this->skin.skelAnime)) { @@ -490,9 +490,9 @@ void func_80A6A7D0(EnHorseLinkChild* this, PlayState* play) { if ((this->animationIdx == 4) || (this->animationIdx == 3) || (this->animationIdx == 2)) { if (!this->unk_1E8) { - func_8006DD9C(&this->actor, &player->actor.world.pos, 300); + Horse_RotateToPoint(&this->actor, &player->actor.world.pos, 300); } else { - func_8006DD9C(&this->actor, &this->actor.home.pos, 300); + Horse_RotateToPoint(&this->actor, &this->actor.home.pos, 300); } } diff --git a/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c b/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c index cddc0a8ee7..5aa674034d 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c +++ b/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c @@ -14,9 +14,9 @@ void EnHorseZelda_Destroy(Actor* thisx, PlayState* play); void EnHorseZelda_Update(Actor* thisx, PlayState* play); void EnHorseZelda_Draw(Actor* thisx, PlayState* play); -void func_80A6DCCC(EnHorseZelda* this, PlayState* play); -void func_80A6DDFC(EnHorseZelda* this, PlayState* play); -void func_80A6DC7C(EnHorseZelda* this); +void EnHorseZelda_Stop(EnHorseZelda* this, PlayState* play); +void EnHorseZelda_Gallop(EnHorseZelda* this, PlayState* play); +void EnHorseZelda_SetupStop(EnHorseZelda* this); const ActorInit En_Horse_Zelda_InitVars = { ACTOR_EN_HORSE_ZELDA, @@ -101,27 +101,27 @@ static InitChainEntry sInitChain[] = { }; static EnHorseZeldaActionFunc sActionFuncs[] = { - func_80A6DCCC, - func_80A6DDFC, + EnHorseZelda_Stop, + EnHorseZelda_Gallop, }; -void func_80A6D8D0(unknownStruct* data, s32 index, Vec3f* vec) { +void EnHorseZelda_GetFieldPosition(unknownStruct* data, s32 index, Vec3f* vec) { vec->x = data[index].unk_0.x; vec->y = data[index].unk_0.y; vec->z = data[index].unk_0.z; } -void func_80A6D918(EnHorseZelda* this, PlayState* play) { +void EnHorseZelda_Move(EnHorseZelda* this, PlayState* play) { s32 pad; Vec3f sp28; s16 yawDiff; - func_80A6D8D0(D_80A6E240, this->unk_1EC, &sp28); + EnHorseZelda_GetFieldPosition(D_80A6E240, this->fieldPosIndex, &sp28); if (Math3D_Vec3f_DistXYZ(&sp28, &this->actor.world.pos) <= 400.0f) { - this->unk_1EC++; - if (this->unk_1EC >= 14) { - this->unk_1EC = 0; - func_80A6D8D0(D_80A6E240, 0, &sp28); + this->fieldPosIndex++; + if (this->fieldPosIndex >= 14) { + this->fieldPosIndex = 0; + EnHorseZelda_GetFieldPosition(D_80A6E240, 0, &sp28); } } yawDiff = Math_Vec3f_Yaw(&this->actor.world.pos, &sp28) - this->actor.world.rot.y; @@ -140,7 +140,7 @@ void func_80A6D918(EnHorseZelda* this, PlayState* play) { } else { this->actor.speedXZ -= 1.0f; } - } else if (this->actor.speedXZ < D_80A6E240[this->unk_1EC].unk_6) { + } else if (this->actor.speedXZ < D_80A6E240[this->fieldPosIndex].unk_6) { this->actor.speedXZ += 0.5f; } else { this->actor.speedXZ -= 0.5f; @@ -167,7 +167,7 @@ void EnHorseZelda_Init(Actor* thisx, PlayState* play) { Collider_SetJntSph(play, &this->colliderSphere, &this->actor, &sJntSphInit, &this->colliderSphereItem); CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); this->animationIndex = 0; - func_80A6DC7C(this); + EnHorseZelda_SetupStop(this); } void EnHorseZelda_Destroy(Actor* thisx, PlayState* play) { @@ -178,7 +178,7 @@ void EnHorseZelda_Destroy(Actor* thisx, PlayState* play) { Skin_Free(play, &this->skin); } -void func_80A6DC7C(EnHorseZelda* this) { +void EnHorseZelda_SetupStop(EnHorseZelda* this) { this->action = 0; this->animationIndex++; if (this->animationIndex > 0) { @@ -187,14 +187,14 @@ void func_80A6DC7C(EnHorseZelda* this) { Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->animationIndex]); } -void func_80A6DCCC(EnHorseZelda* this, PlayState* play) { +void EnHorseZelda_Stop(EnHorseZelda* this, PlayState* play) { this->actor.speedXZ = 0.0f; if (SkelAnime_Update(&this->skin.skelAnime)) { - func_80A6DC7C(this); + EnHorseZelda_SetupStop(this); } } -void func_80A6DD14(EnHorseZelda* this) { +void EnHorseZelda_Spur(EnHorseZelda* this) { f32 sp34; this->action = 1; @@ -207,14 +207,14 @@ void func_80A6DD14(EnHorseZelda* this) { Animation_GetLastFrame(sAnimationHeaders[this->animationIndex]), ANIMMODE_ONCE, 0.0f); } -void func_80A6DDFC(EnHorseZelda* this, PlayState* play) { - func_80A6D918(this, play); +void EnHorseZelda_Gallop(EnHorseZelda* this, PlayState* play) { + EnHorseZelda_Move(this, play); if (SkelAnime_Update(&this->skin.skelAnime)) { - func_80A6DD14(this); + EnHorseZelda_Spur(this); } } -void func_80A6DE38(EnHorseZelda* this, PlayState* play) { +void EnHorseZelda_SetRotate(EnHorseZelda* this, PlayState* play) { s32 pad; CollisionPoly* poly; s32 pad2; @@ -224,8 +224,8 @@ void func_80A6DE38(EnHorseZelda* this, PlayState* play) { pos.x = (Math_SinS(this->actor.shape.rot.y) * 30.0f) + this->actor.world.pos.x; pos.y = this->actor.world.pos.y + 60.0f; pos.z = (Math_CosS(this->actor.shape.rot.y) * 30.0f) + this->actor.world.pos.z; - this->unk_1F4 = BgCheck_EntityRaycastFloor3(&play->colCtx, &poly, &bgId, &pos); - this->actor.shape.rot.x = Math_FAtan2F(this->actor.world.pos.y - this->unk_1F4, 30.0f) * (0x8000 / M_PI); + this->floorYForwards = BgCheck_EntityRaycastFloor3(&play->colCtx, &poly, &bgId, &pos); + this->actor.shape.rot.x = Math_FAtan2F(this->actor.world.pos.y - this->floorYForwards, 30.0f) * (0x8000 / M_PI); } void EnHorseZelda_Update(Actor* thisx, PlayState* play) { @@ -270,7 +270,7 @@ void EnHorseZelda_PostDraw(Actor* thisx, PlayState* play, Skin* skin) { void EnHorseZelda_Draw(Actor* thisx, PlayState* play) { EnHorseZelda* this = (EnHorseZelda*)thisx; - func_80A6DE38(this, play); + EnHorseZelda_SetRotate(this, play); Gfx_SetupDL_25Opa(play->state.gfxCtx); func_800A6330(&this->actor, play, &this->skin, EnHorseZelda_PostDraw, true); } diff --git a/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.h b/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.h index 1db5a54e5f..9efb0f95c7 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.h +++ b/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.h @@ -14,9 +14,9 @@ typedef struct EnHorseZelda { /* 0x0150 */ s32 animationIndex; /* 0x0154 */ Skin skin; /* 0x01E4 */ char unk_1E4[0x8]; - /* 0x01EC */ s32 unk_1EC; + /* 0x01EC */ s32 fieldPosIndex; /* 0x01F0 */ char unk_1F0[0x4]; - /* 0x01F4 */ f32 unk_1F4; + /* 0x01F4 */ f32 floorYForwards; /* 0x01F8 */ char unk_1F8[0x4]; /* 0x01FC */ ColliderCylinder colliderCylinder; /* 0x0248 */ ColliderJntSph colliderSphere; diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index bcd1f362d0..e02b4ee601 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -25,14 +25,14 @@ void EnHy_Update(Actor* thisx, PlayState* play); void EnHy_Draw(Actor* thisx, PlayState* play); void EnHy_InitImpl(EnHy* this, PlayState* play); -void func_80A7134C(EnHy* this, PlayState* play); -void func_80A71530(EnHy* this, PlayState* play); -void func_80A711B4(EnHy* this, PlayState* play); -void func_80A712C0(EnHy* this, PlayState* play); -void func_80A710F8(EnHy* this, PlayState* play); -void func_80A7127C(EnHy* this, PlayState* play); +void EnHy_Pace(EnHy* this, PlayState* play); +void EnHy_FinishGivingDogFoundReward(EnHy* this, PlayState* play); +void EnHy_Walk(EnHy* this, PlayState* play); +void EnHy_SetupPace(EnHy* this, PlayState* play); +void EnHy_WatchDog(EnHy* this, PlayState* play); +void EnHy_Fidget(EnHy* this, PlayState* play); void EnHy_DoNothing(EnHy* this, PlayState* play); -void func_80A714C4(EnHy* this, PlayState* play); +void EnHy_WaitDogFoundRewardGiven(EnHy* this, PlayState* play); const ActorInit En_Hy_InitVars = { ACTOR_EN_HY, @@ -411,13 +411,13 @@ s32 EnHy_IsOsAnimeObjectLoaded(EnHy* this, PlayState* play) { return true; } -void func_80A6F7CC(EnHy* this, PlayState* play, s32 getItemId) { +void EnHy_GiveItem(EnHy* this, PlayState* play, s32 getItemId) { this->unkGetItemId = getItemId; Actor_OfferGetItem(&this->actor, play, getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } -u16 func_80A6F810(PlayState* play, Actor* thisx) { +u16 EnHy_GetTextId(PlayState* play, Actor* thisx) { Player* player = GET_PLAYER(play); EnHy* this = (EnHy*)thisx; u16 textId = Text_GetFaceReaction(play, (this->actor.params & 0x7F) + 37); @@ -432,14 +432,14 @@ u16 func_80A6F810(PlayState* play, Actor* thisx) { switch (this->actor.params & 0x7F) { case ENHY_TYPE_AOB: if (play->sceneNum == SCENE_KAKARIKO_CENTER_GUEST_HOUSE) { - return (this->unk_330 & 0x800) ? 0x508D : ((Flags_GetInfTable(INFTABLE_CB)) ? 0x508C : 0x508B); + return (this->talonEventChkInf & 0x800) ? 0x508D : ((Flags_GetInfTable(INFTABLE_CB)) ? 0x508C : 0x508B); } else if (play->sceneNum == SCENE_MARKET_DAY) { return (gSaveContext.eventInf[3] & 1) ? 0x709B : 0x709C; } else if (gSaveContext.dogIsLost) { s16 followingDog = (gSaveContext.dogParams & 0xF00) >> 8; if (followingDog != 0) { - this->unk_215 = false; + this->playedSfx = false; return ((followingDog == 1) || (CVarGetInteger(CVAR_ENHANCEMENT("AllDogsRichard"), 0))) ? 0x709F : 0x709E; } else { @@ -557,7 +557,8 @@ u16 func_80A6F810(PlayState* play, Actor* thisx) { ? 0x505F : ((Flags_GetInfTable(INFTABLE_163)) ? 0x505E : 0x505D); } else { - return (this->unk_330 & 0x800) ? 0x5062 : ((Flags_GetInfTable(INFTABLE_164)) ? 0x5061 : 0x5060); + return (this->talonEventChkInf & 0x800) ? 0x5062 + : ((Flags_GetInfTable(INFTABLE_164)) ? 0x5061 : 0x5060); } case ENHY_TYPE_BJI_19: return 0x7120; @@ -568,7 +569,7 @@ u16 func_80A6F810(PlayState* play, Actor* thisx) { } } -s16 func_80A70058(PlayState* play, Actor* thisx) { +s16 EnHy_UpdateTalkState(PlayState* play, Actor* thisx) { EnHy* this = (EnHy*)thisx; s16 beggarItems[] = { ITEM_BLUE_FIRE, ITEM_FISH, ITEM_BUG, ITEM_FAIRY }; s16 beggarRewards[] = { 150, 100, 50, 25 }; @@ -586,11 +587,11 @@ s16 func_80A70058(PlayState* play, Actor* thisx) { switch (this->actor.textId) { case 0x709E: case 0x709F: - if (!this->unk_215) { + if (!this->playedSfx) { Audio_PlaySoundGeneral(this->actor.textId == 0x709F ? NA_SE_SY_CORRECT_CHIME : NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - this->unk_215 = true; + this->playedSfx = true; } break; case 0x70F0: @@ -610,7 +611,9 @@ s16 func_80A70058(PlayState* play, Actor* thisx) { case 0x70F1: case 0x70F2: case 0x70F3: - Rupees_ChangeBy(beggarRewards[this->actor.textId - 0x70F0]); + if (GameInteractor_Should(VB_BEGGAR_GIVE_ITEM, true, this)) { + Rupees_ChangeBy(beggarRewards[this->actor.textId - 0x70F0]); + } Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENHY_ANIM_17); Player_UpdateBottleHeld(play, GET_PLAYER(play), ITEM_BOTTLE, PLAYER_IA_BOTTLE); break; @@ -676,8 +679,8 @@ s16 func_80A70058(PlayState* play, Actor* thisx) { break; case 0x709F: if (GameInteractor_Should(VB_GIVE_ITEM_FROM_LOST_DOG, true, this)) { - func_80A6F7CC(this, play, Flags_GetInfTable(INFTABLE_191) ? GI_RUPEE_BLUE : GI_HEART_PIECE); - this->actionFunc = func_80A714C4; + EnHy_GiveItem(this, play, Flags_GetInfTable(INFTABLE_191) ? GI_RUPEE_BLUE : GI_HEART_PIECE); + this->actionFunc = EnHy_WaitDogFoundRewardGiven; } break; } @@ -737,7 +740,7 @@ void EnHy_UpdateCollider(EnHy* this, PlayState* play) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); } -void func_80A70834(EnHy* this, PlayState* play) { +void EnHy_OfferBuyBottledItem(EnHy* this, PlayState* play) { Player* player = GET_PLAYER(play); if ((this->actor.params & 0x7F) == ENHY_TYPE_BOJ_5) { @@ -778,7 +781,7 @@ void func_80A70834(EnHy* this, PlayState* play) { } } -void func_80A70978(EnHy* this, PlayState* play) { +void EnHy_UpdateNPC(EnHy* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 trackingMode; @@ -818,9 +821,9 @@ void func_80A70978(EnHy* this, PlayState* play) { Npc_TrackPoint(&this->actor, &this->interactInfo, sInit1Info[this->actor.params & 0x7F].unkPresetIndex, trackingMode); - if (Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->unkRange, func_80A6F810, - func_80A70058)) { - func_80A70834(this, play); + if (Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->unkRange, EnHy_GetTextId, + EnHy_UpdateTalkState)) { + EnHy_OfferBuyBottledItem(this, play); } } @@ -939,7 +942,7 @@ void EnHy_InitImpl(EnHy* this, PlayState* play) { } if (play->sceneNum == SCENE_KAKARIKO_CENTER_GUEST_HOUSE) { - this->unk_330 = gSaveContext.eventChkInf[6]; + this->talonEventChkInf = gSaveContext.eventChkInf[6]; } EnHy_InitSetProperties(this); @@ -950,15 +953,15 @@ void EnHy_InitImpl(EnHy* this, PlayState* play) { if (this->path != NULL) { this->actor.speedXZ = 3.0f; } - this->actionFunc = func_80A711B4; + this->actionFunc = EnHy_Walk; break; case ENHY_TYPE_BJI_7: this->pathReverse = false; - this->actionFunc = func_80A712C0; + this->actionFunc = EnHy_SetupPace; break; case ENHY_TYPE_AOB: if (play->sceneNum == SCENE_MARKET_DAY) { - this->actionFunc = func_80A710F8; + this->actionFunc = EnHy_WatchDog; break; } // fall-through @@ -975,7 +978,7 @@ void EnHy_InitImpl(EnHy* this, PlayState* play) { case ENHY_TYPE_BOB_18: case ENHY_TYPE_BJI_19: case ENHY_TYPE_AHG_20: - this->actionFunc = func_80A7127C; + this->actionFunc = EnHy_Fidget; break; case ENHY_TYPE_BOJ_5: case ENHY_TYPE_BOJ_9: @@ -991,7 +994,7 @@ void EnHy_InitImpl(EnHy* this, PlayState* play) { } } -void func_80A710F8(EnHy* this, PlayState* play) { +void EnHy_WatchDog(EnHy* this, PlayState* play) { if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if (this->skelAnime.animation != &gObjOsAnim_0BFC) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENHY_ANIM_26); @@ -1005,7 +1008,7 @@ void func_80A710F8(EnHy* this, PlayState* play) { } } -void func_80A711B4(EnHy* this, PlayState* play) { +void EnHy_Walk(EnHy* this, PlayState* play) { s16 yaw; f32 distSq; @@ -1021,24 +1024,24 @@ void func_80A711B4(EnHy* this, PlayState* play) { } } -void func_80A7127C(EnHy* this, PlayState* play) { - func_80034F54(play, this->unk_21C, this->unk_23C, 16); +void EnHy_Fidget(EnHy* this, PlayState* play) { + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); } void EnHy_DoNothing(EnHy* this, PlayState* play) { } -void func_80A712C0(EnHy* this, PlayState* play) { +void EnHy_SetupPace(EnHy* this, PlayState* play) { if ((this->actor.xzDistToPlayer <= 100.0f) && (this->path != NULL)) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENHY_ANIM_7); this->actor.speedXZ = 0.4f; - this->actionFunc = func_80A7134C; + this->actionFunc = EnHy_Pace; } - func_80034F54(play, this->unk_21C, this->unk_23C, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); } -void func_80A7134C(EnHy* this, PlayState* play) { +void EnHy_Pace(EnHy* this, PlayState* play) { s16 yaw; f32 distSq; @@ -1072,16 +1075,16 @@ void func_80A7134C(EnHy* this, PlayState* play) { } } -void func_80A714C4(EnHy* this, PlayState* play) { +void EnHy_WaitDogFoundRewardGiven(EnHy* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { - this->actionFunc = func_80A71530; + this->actionFunc = EnHy_FinishGivingDogFoundReward; } else { Actor_OfferGetItem(&this->actor, play, this->unkGetItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } } -void func_80A71530(EnHy* this, PlayState* play) { +void EnHy_FinishGivingDogFoundReward(EnHy* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { switch (this->unkGetItemId) { case GI_HEART_PIECE: @@ -1096,7 +1099,7 @@ void func_80A71530(EnHy* this, PlayState* play) { break; } - this->actionFunc = func_80A7127C; + this->actionFunc = EnHy_Fidget; } } @@ -1116,7 +1119,7 @@ void EnHy_Update(Actor* thisx, PlayState* play) { } this->actionFunc(this, play); - func_80A70978(this, play); + EnHy_UpdateNPC(this, play); EnHy_UpdateCollider(this, play); } @@ -1158,8 +1161,8 @@ s32 EnHy_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po } if ((limbIndex == 8) || (limbIndex == 9) || (limbIndex == 12)) { - rot->y += Math_SinS(this->unk_21C[limbIndex]) * 200.0f; - rot->z += Math_CosS(this->unk_23C[limbIndex]) * 200.0f; + rot->y += Math_SinS(this->fidgetTableY[limbIndex]) * 200.0f; + rot->z += Math_CosS(this->fidgetTableZ[limbIndex]) * 200.0f; } CLOSE_DISPS(play->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h index 7d94a5ca66..c307f7186b 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h @@ -47,21 +47,21 @@ typedef struct EnHy { /* 0x01E8 */ NpcInteractInfo interactInfo; /* 0x0210 */ Path* path; /* 0x0214 */ s8 waypoint; - /* 0x0215 */ s8 unk_215; + /* 0x0215 */ s8 playedSfx; /* 0x0216 */ char unk_216[2]; // unused /* 0x0218 */ s16 curEyeIndex; /* 0x021A */ s16 nextEyeIndexTimer; - /* 0x021C */ s16 unk_21C[16]; // bodyWiggleY ? - /* 0x023C */ s16 unk_23C[16]; // bodyWiggleZ ? + /* 0x021C */ s16 fidgetTableY[16]; // bodyWiggleY ? + /* 0x023C */ s16 fidgetTableZ[16]; // bodyWiggleZ ? /* 0x025C */ f32 unkRange; /* 0x0260 */ s32 unkGetItemId; /* 0x0264 */ Vec3f modelOffset; /* 0x0270 */ Vec3s jointTable[16]; /* 0x02D0 */ Vec3s morphTable[16]; - /* 0x0330 */ u16 unk_330; + /* 0x0330 */ u16 talonEventChkInf; /* */ GetItemEntry getItemEntry; } EnHy; // size = 0x0334 -void func_80A7127C(EnHy* enHy, PlayState* play); +void EnHy_Fidget(EnHy* enHy, PlayState* play); #endif diff --git a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c index c4dbe3f3af..425a80a36f 100644 --- a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c +++ b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c @@ -203,7 +203,7 @@ void func_80A74398(Actor* thisx, PlayState* play) { thisx->colChkInfo.damageTable = &sDamageTable; thisx->colChkInfo.mass = MASS_HEAVY; - this->unk_2FC = 0; + this->isBreakingProp = 0; thisx->colChkInfo.health = 30; thisx->gravity = -1.0f; this->switchFlags = (thisx->params >> 8) & 0xFF; @@ -252,7 +252,7 @@ void func_80A74398(Actor* thisx, PlayState* play) { } s32 func_80A745E4(EnIk* this, PlayState* play) { - if (((this->unk_2FB != 0) || (this->actor.params == 0)) && + if (((this->armorStatusFlag != 0) || (this->actor.params == 0)) && (func_800354B4(play, &this->actor, 100.0f, 0x2710, 0x4000, this->actor.shape.rot.y) != 0) && (play->gameplayFrames & 1)) { func_80A755F0(this); @@ -330,7 +330,7 @@ void func_80A7489C(EnIk* this) { } void func_80A7492C(EnIk* this, PlayState* play) { - s32 phi_a0 = (this->unk_2FB == 0) ? 0xAAA : 0x3FFC; + s32 phi_a0 = (this->armorStatusFlag == 0) ? 0xAAA : 0x3FFC; s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; if ((ABS(yawDiff) <= phi_a0) && (this->actor.xzDistToPlayer < 100.0f) && @@ -351,7 +351,7 @@ void func_80A7492C(EnIk* this, PlayState* play) { void func_80A74AAC(EnIk* this) { this->unk_2F8 = 5; - if (this->unk_2FB == 0) { + if (this->armorStatusFlag == 0) { Animation_Change(&this->skelAnime, &gIronKnuckleWalkAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gIronKnuckleWalkAnim), ANIMMODE_LOOP, -4.0f); this->actor.speedXZ = 0.9f; @@ -373,7 +373,7 @@ void func_80A74BA4(EnIk* this, PlayState* play) { s16 sp2E; s16 phi_a3; - if (this->unk_2FB == 0) { + if (this->armorStatusFlag == 0) { temp_t0 = 0xAAA; phi_a3 = 0x320; sp30 = 0; @@ -404,7 +404,7 @@ void func_80A74BA4(EnIk* this, PlayState* play) { } if (func_80A74674(play, &this->actor) != NULL) { func_80A751C8(this); - this->unk_2FC = 1; + this->isBreakingProp = 1; } else { temp_t0 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; if (ABS(temp_t0) > 0x4000) { @@ -451,7 +451,7 @@ void func_80A74EBC(EnIk* this, PlayState* play) { if ((this->skelAnime.curFrame > 17.0f) && (this->skelAnime.curFrame < 23.0f)) { this->unk_2FE = 1; } else { - if ((this->unk_2FB != 0) && (this->skelAnime.curFrame < 10.0f)) { + if ((this->armorStatusFlag != 0) && (this->skelAnime.curFrame < 10.0f)) { Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 0x5DC, 0); this->actor.shape.rot.y = this->actor.world.rot.y; } @@ -467,7 +467,7 @@ void func_80A7506C(EnIk* this) { f32 frames = Animation_GetLastFrame(&gIronKnuckleAxeStuckAnim); this->unk_2FE = 0; - this->unk_2F9 = (s8)frames; + this->animationTimer = (s8)frames; this->unk_2F8 = 7; this->unk_2FF = this->unk_2FE; Animation_Change(&this->skelAnime, &gIronKnuckleAxeStuckAnim, 1.0f, 0.0f, frames, ANIMMODE_LOOP, -4.0f); @@ -478,7 +478,7 @@ void func_80A7506C(EnIk* this) { void func_80A7510C(EnIk* this, PlayState* play) { f32 frames; - if (SkelAnime_Update(&this->skelAnime) || (--this->unk_2F9 == 0)) { + if (SkelAnime_Update(&this->skelAnime) || (--this->animationTimer == 0)) { if (this->unk_2F8 == 8) { func_80A7489C(this); } else { @@ -499,7 +499,7 @@ void func_80A751C8(EnIk* this) { this->actor.speedXZ = 0.0f; Animation_Change(&this->skelAnime, &gIronKnuckleHorizontalAttackAnim, 0.0f, 0.0f, frames, ANIMMODE_ONCE_INTERP, -6.0f); - this->unk_2FC = 0; + this->isBreakingProp = 0; EnIk_SetupAction(this, func_80A75260); } @@ -515,7 +515,7 @@ void func_80A75260(EnIk* this, PlayState* play) { } if (((this->skelAnime.curFrame > 1.0f) && (this->skelAnime.curFrame < 9.0f)) || ((this->skelAnime.curFrame > 13.0f) && (this->skelAnime.curFrame < 18.0f))) { - if ((this->unk_2FC == 0) && (this->unk_2FB != 0) && (this->skelAnime.curFrame < 10.0f)) { + if ((this->isBreakingProp == 0) && (this->armorStatusFlag != 0) && (this->skelAnime.curFrame < 10.0f)) { Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 0x5DC, 0); this->actor.shape.rot.y = this->actor.world.rot.y; } @@ -644,7 +644,7 @@ void func_80A7598C(EnIk* this) { this->unk_2F8 = 2; this->actor.speedXZ = 0.0f; Animation_Change(&this->skelAnime, &gIronKnuckleDeathAnim, 1.0f, 0.0f, frames, ANIMMODE_ONCE, -4.0f); - this->unk_2F9 = 0x18; + this->animationTimer = 0x18; Audio_PlayActorSound2(&this->actor, NA_SE_EN_IRONNACK_DEAD); Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_CUTBODY); EnIk_SetupAction(this, func_80A75A38); @@ -653,20 +653,20 @@ void func_80A7598C(EnIk* this) { void func_80A75A38(EnIk* this, PlayState* play) { if (SkelAnime_Update(&this->skelAnime)) { - if ((this->actor.colChkInfo.health == 0) && (this->unk_2F9 != 0)) { + if ((this->actor.colChkInfo.health == 0) && (this->animationTimer != 0)) { s32 i; Vec3f pos; Vec3f sp7C = { 0.0f, 0.5f, 0.0f }; - this->unk_2F9--; + this->animationTimer--; - for (i = 0xC - (this->unk_2F9 >> 1); i >= 0; i--) { + for (i = 0xC - (this->animationTimer >> 1); i >= 0; i--) { pos.x = this->actor.world.pos.x + Rand_CenteredFloat(120.0f); pos.z = this->actor.world.pos.z + Rand_CenteredFloat(120.0f); pos.y = this->actor.world.pos.y + 20.0f + Rand_CenteredFloat(50.0f); EffectSsDeadDb_Spawn(play, &pos, &sp7C, &sp7C, 100, 0, 255, 255, 255, 255, 0, 0, 255, 1, 9, true); } - if (this->unk_2F9 == 0) { + if (this->animationTimer == 0) { Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0xB0); // Don't set flag when Enemy Rando or CrowdControl are on. // Instead Iron Knuckles rely on the "clear room" flag. @@ -709,11 +709,12 @@ void func_80A75C38(EnIk* this, PlayState* play) { sp38.y += 50.0f; Actor_SetDropFlag(&this->actor, &this->bodyCollider.info, 1); temp_v0_3 = this->actor.colChkInfo.damageEffect; - this->unk_2FD = temp_v0_3 & 0xFF; + this->damageReaction = temp_v0_3 & 0xFF; this->bodyCollider.base.acFlags &= ~AC_HIT; - if ((this->unk_2FD == 0) || (this->unk_2FD == 0xD) || ((this->unk_2FB == 0) && (this->unk_2FD == 0xE))) { - if (this->unk_2FD != 0) { + if ((this->damageReaction == 0) || (this->damageReaction == 0xD) || + ((this->armorStatusFlag == 0) && (this->damageReaction == 0xE))) { + if (this->damageReaction != 0) { CollisionCheck_SpawnShieldParticlesMetal(play, &sp38); } return; @@ -723,7 +724,7 @@ void func_80A75C38(EnIk* this, PlayState* play) { Actor_ApplyDamage(&this->actor); if (this->actor.params != 0) { if ((prevHealth > 10) && (this->actor.colChkInfo.health <= 10)) { - this->unk_2FB = 1; + this->armorStatusFlag = 1; BodyBreak_Alloc(&this->bodyBreak, 3, play); } } else if (this->actor.colChkInfo.health <= 10) { @@ -748,7 +749,7 @@ void func_80A75C38(EnIk* this, PlayState* play) { func_80A754A0(this); } } - if ((this->actor.params != 0) && (this->unk_2FB != 0)) { + if ((this->actor.params != 0) && (this->armorStatusFlag != 0)) { if ((prevHealth > 10) && (this->actor.colChkInfo.health <= 10)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_IRONNACK_ARMOR_OFF_DEMO); } else { @@ -769,7 +770,7 @@ void func_80A75FA0(Actor* thisx, PlayState* play) { Player* player = GET_PLAYER(play); u8 prevInvincibilityTimer; - this->unk_2FA = this->unk_2FB; + this->drawArmorFlag = this->armorStatusFlag; func_80A75C38(this, play); if ((this->actor.params == 0) && (this->actor.colChkInfo.health <= 10)) { func_80A781CC(&this->actor, play); @@ -842,11 +843,11 @@ s32 EnIk_OverrideLimbDraw3(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p *dList = gIronKnuckleGerudoHeadDL; } } else if ((limbIndex == 26) || (limbIndex == 27)) { - if ((this->unk_2FA & 1)) { + if ((this->drawArmorFlag & 1)) { *dList = NULL; } } else if ((limbIndex == 28) || (limbIndex == 29)) { - if (!(this->unk_2FA & 1)) { + if (!(this->drawArmorFlag & 1)) { *dList = NULL; } } @@ -882,7 +883,7 @@ void EnIk_PostLimbDraw3(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, OPEN_DISPS(play->state.gfxCtx); - if (this->unk_2FB & 1) { + if (this->armorStatusFlag & 1) { BodyBreak_SetInfo(&this->bodyBreak, limbIndex, 26, 27, 28, dList, BODYBREAK_OBJECT_DEFAULT); } if (limbIndex == 12) { @@ -932,14 +933,14 @@ void EnIk_PostLimbDraw3(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, gSPDisplayList(POLY_XLU_DISP++, object_ik_DL_016EE8); break; case 26: - if (!(this->unk_2FA & 1)) { + if (!(this->drawArmorFlag & 1)) { gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gIronKnuckleArmorRivetAndSymbolDL); } break; case 27: - if (!(this->unk_2FA & 1)) { + if (!(this->drawArmorFlag & 1)) { gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, object_ik_DL_016CD8); @@ -1022,7 +1023,7 @@ void func_80A76E2C(EnIk* this, PlayState* play, Vec3f* pos) { { 900.0, -800.0, 2700.0 }, { 720.0f, 900.0f, 2500.0f }, }; - if (this->unk_4D4 == 0) { + if (this->isAxeSummoned == 0) { s32 pad; Vec3f effectVelocity = { 0.0f, 0.0f, 0.0f }; Vec3f effectAccel = { 0.0f, 0.3f, 0.0f }; @@ -1046,7 +1047,7 @@ void func_80A76E2C(EnIk* this, PlayState* play, Vec3f* pos) { (Rand_ZeroOne() * 60.0f) + 300.0f, 0); } - this->unk_4D4 = 1; + this->isAxeSummoned = 1; func_80A76DDC(this, play, pos); } } @@ -1104,7 +1105,7 @@ void func_80A771E4(EnIk* this) { Animation_GetLastFrame(&gIronKnuckleNabooruSummonAxeAnim), ANIMMODE_ONCE, 0.0f); this->action = 2; this->drawMode = 1; - this->unk_4D4 = 0; + this->isAxeSummoned = 0; this->actor.shape.shadowAlpha = 0xFF; } diff --git a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.h b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.h index a77db20b05..9ae5437b3d 100644 --- a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.h +++ b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.h @@ -14,11 +14,11 @@ typedef struct EnIk { /* 0x0190 */ Vec3s jointTable[30]; /* 0x0244 */ Vec3s morphTable[30]; /* 0x02F8 */ u8 unk_2F8; - /* 0x02F9 */ u8 unk_2F9; - /* 0x02FA */ u8 unk_2FA; - /* 0x02FB */ u8 unk_2FB; - /* 0x02FC */ u8 unk_2FC; - /* 0x02FD */ u8 unk_2FD; + /* 0x02F9 */ u8 animationTimer; + /* 0x02FA */ u8 drawArmorFlag; + /* 0x02FB */ u8 armorStatusFlag; + /* 0x02FC */ u8 isBreakingProp; + /* 0x02FD */ u8 damageReaction; /* 0x02FE */ s8 unk_2FE; /* 0x02FF */ s8 unk_2FF; /* 0x0300 */ s16 unk_300; @@ -33,7 +33,7 @@ typedef struct EnIk { /* 0x04C8 */ s32 action; /* 0x04CC */ s32 drawMode; /* 0x04D0 */ u32 npcAction; - /* 0x04D4 */ s32 unk_4D4; + /* 0x04D4 */ s32 isAxeSummoned; /* 0x04D8 */ char unk_4D8[0x04]; } EnIk; // size = 0x04DC diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.c b/soh/src/overlays/actors/ovl_En_In/z_en_in.c index 9777525961..6e302d2734 100644 --- a/soh/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.c @@ -11,7 +11,7 @@ void EnIn_Update(Actor* thisx, PlayState* play); void EnIn_Draw(Actor* thisx, PlayState* play); void EnIn_Reset(void); -void func_80A79FB0(EnIn* this, PlayState* play); +void EnIn_WaitForObject(EnIn* this, PlayState* play); void func_80A7A304(EnIn* this, PlayState* play); void func_80A7A4C8(EnIn* this, PlayState* play); void func_80A7A568(EnIn* this, PlayState* play); @@ -112,7 +112,7 @@ static Gfx* sAdultEraDLs[] = { gIngoAdultEraMustacheDL, }; -u16 func_80A78FB0(PlayState* play) { +u16 EnIn_GetTextIdChild(PlayState* play) { if (Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)) { if (Flags_GetInfTable(INFTABLE_97)) { return 0x2046; @@ -127,7 +127,7 @@ u16 func_80A78FB0(PlayState* play) { } } -u16 func_80A79010(PlayState* play) { +u16 EnIn_GetTextIdAdult(PlayState* play) { Player* player = GET_PLAYER(play); u16 temp_v0 = Text_GetFaceReaction(play, 25); @@ -180,20 +180,20 @@ u16 func_80A79010(PlayState* play) { } } -u16 func_80A79168(PlayState* play, Actor* thisx) { +u16 EnIn_GetTextId(PlayState* play, Actor* thisx) { u16 temp_v0 = Text_GetFaceReaction(play, 25); if (temp_v0 != 0) { return temp_v0; } if (!LINK_IS_ADULT) { - return func_80A78FB0(play); + return EnIn_GetTextIdChild(play); } else { - return func_80A79010(play); + return EnIn_GetTextIdAdult(play); } } -s16 func_80A791CC(PlayState* play, Actor* thisx) { +s16 EnIn_UpdateTalkStateOnClosing(PlayState* play, Actor* thisx) { s32 ret = NPC_TALK_STATE_IDLE; switch (thisx->textId) { @@ -211,7 +211,7 @@ s16 func_80A791CC(PlayState* play, Actor* thisx) { return ret; } -s16 func_80A7924C(PlayState* play, Actor* thisx) { +s16 EnIn_UpdateTalkStateOnChoice(PlayState* play, Actor* thisx) { EnIn* this = (EnIn*)thisx; s32 sp18 = NPC_TALK_STATE_TALKING; @@ -272,7 +272,7 @@ s16 func_80A7924C(PlayState* play, Actor* thisx) { return sp18; } -s16 func_80A7949C(PlayState* play, Actor* thisx) { +s16 EnIn_UpdateTalkStateOnEvent(PlayState* play, Actor* thisx) { s32 phi_v1 = NPC_TALK_STATE_TALKING; if (thisx->textId == 0x2035) { @@ -285,7 +285,7 @@ s16 func_80A7949C(PlayState* play, Actor* thisx) { return phi_v1; } -s16 func_80A79500(PlayState* play, Actor* thisx) { +s16 EnIn_UpdateTalkState(PlayState* play, Actor* thisx) { s16 sp1E = NPC_TALK_STATE_TALKING; osSyncPrintf("message_check->(%d[%x])\n", Message_GetState(&play->msgCtx), thisx->textId); @@ -294,18 +294,18 @@ s16 func_80A79500(PlayState* play, Actor* thisx) { case TEXT_STATE_DONE_HAS_NEXT: break; case TEXT_STATE_CLOSING: - sp1E = func_80A791CC(play, thisx); + sp1E = EnIn_UpdateTalkStateOnClosing(play, thisx); break; case TEXT_STATE_DONE_FADING: break; case TEXT_STATE_CHOICE: if (Message_ShouldAdvance(play)) { - sp1E = func_80A7924C(play, thisx); + sp1E = EnIn_UpdateTalkStateOnChoice(play, thisx); } break; case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { - sp1E = func_80A7949C(play, thisx); + sp1E = EnIn_UpdateTalkStateOnEvent(play, thisx); } break; case TEXT_STATE_DONE: @@ -365,7 +365,7 @@ s32 func_80A7975C(EnIn* this, PlayState* play) { return 1; } -s32 func_80A79830(EnIn* this, PlayState* play) { +s32 EnIn_GetStartMode(EnIn* this, PlayState* play) { if (play->sceneNum == SCENE_LON_LON_RANCH && LINK_IS_CHILD && IS_DAY && this->actor.shape.rot.z == 1 && !Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)) { return 1; @@ -496,20 +496,20 @@ void EnIn_Init(Actor* thisx, PlayState* play) { gSaveContext.eventInf[0] = 0; D_80A7B998 = 1; } - this->actionFunc = func_80A79FB0; + this->actionFunc = EnIn_WaitForObject; } void EnIn_Destroy(Actor* thisx, PlayState* play) { EnIn* this = (EnIn*)thisx; - if (this->actionFunc != NULL && this->actionFunc != func_80A79FB0) { + if (this->actionFunc != NULL && this->actionFunc != EnIn_WaitForObject) { Collider_DestroyCylinder(play, &this->collider); ResourceMgr_UnregisterSkeleton(&this->skelAnime); } } -void func_80A79FB0(EnIn* this, PlayState* play) { +void EnIn_WaitForObject(EnIn* this, PlayState* play) { s32 sp3C = 0; if (Object_IsLoaded(&play->objectCtx, this->ingoObjBankIndex) || this->actor.params <= 0) { @@ -527,7 +527,7 @@ void func_80A79FB0(EnIn* this, PlayState* play) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = func_80A7A4BC; - switch (func_80A79830(this, play)) { + switch (EnIn_GetStartMode(this, play)) { case 1: EnIn_ChangeAnim(this, ENIN_ANIM_9); this->actionFunc = func_80A7A4BC; @@ -771,21 +771,21 @@ void func_80A7AA40(EnIn* this, PlayState* play) { Play_ChangeCameraStatus(play, this->activeCamId, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->camId, CAM_STAT_ACTIVE); - this->unk_2F0 = 0.0f; + this->subCamAtOffset = 0.0f; this->unk_2F4 = 50.0f; this->unk_2F8 = 0.0f; - this->unk_2FC = 0.0f; + this->subCamEyeOffset = 0.0f; this->unk_300 = 50.0f; this->unk_304 = 50.0f; sp30 = this->actor.world.pos; sp24 = this->actor.world.pos; - sp30.x += this->unk_2F0; + sp30.x += this->subCamAtOffset; sp30.y += this->unk_2F4; sp30.z += this->unk_2F8; - sp24.x += this->unk_2FC; + sp24.x += this->subCamEyeOffset; sp24.y += this->unk_300; sp24.z += this->unk_304; @@ -837,20 +837,20 @@ void func_80A7ABD4(EnIn* this, PlayState* play) { if (play->csCtx.frames == 44) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_RONRON_DOOR_CLOSE); } - Math_SmoothStepToF(&this->unk_2F0, 0.0f, 0.06f, 10000.0f, 0.0f); + Math_SmoothStepToF(&this->subCamAtOffset, 0.0f, 0.06f, 10000.0f, 0.0f); Math_SmoothStepToF(&this->unk_2F4, 50.0f, 0.06f, 10000.0f, 0.0f); Math_SmoothStepToF(&this->unk_2F8, 0.0f, 0.06f, 10000.0f, 0.0f); - Math_SmoothStepToF(&this->unk_2FC, 0.0f, 0.06f, 10000.0f, 0.0f); + Math_SmoothStepToF(&this->subCamEyeOffset, 0.0f, 0.06f, 10000.0f, 0.0f); Math_SmoothStepToF(&this->unk_300, 150.0f, 0.06f, 10000.0f, 0.0f); Math_SmoothStepToF(&this->unk_304, 300.0f, 0.06f, 10000.0f, 0.0f); sp48 = this->actor.world.pos; sp3C = this->actor.world.pos; - sp48.x += this->unk_2F0; + sp48.x += this->subCamAtOffset; sp48.y += this->unk_2F4; sp48.z += this->unk_2F8; - sp3C.x += this->unk_2FC; + sp3C.x += this->subCamEyeOffset; sp3C.y += this->unk_300; sp3C.z += this->unk_304; Play_CameraSetAtEye(play, this->camId, &sp48, &sp3C); @@ -913,7 +913,7 @@ void EnIn_Update(Actor* thisx, PlayState* play) { ColliderCylinder* collider; EnIn* this = (EnIn*)thisx; - if (this->actionFunc == func_80A79FB0) { + if (this->actionFunc == EnIn_WaitForObject) { this->actionFunc(this, play); return; } @@ -937,7 +937,7 @@ void EnIn_Update(Actor* thisx, PlayState* play) { } else { Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, ((this->actor.targetMode == 6) ? 80.0f : 320.0f) + this->collider.dim.radius, - func_80A79168, func_80A79500); + EnIn_GetTextId, EnIn_UpdateTalkState); if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { this->unk_1FA = this->unk_1F8; this->unk_1F8 = Message_GetState(&play->msgCtx); @@ -1001,7 +1001,7 @@ void EnIn_Draw(Actor* thisx, PlayState* play) { EnIn* this = (EnIn*)thisx; OPEN_DISPS(play->state.gfxCtx); - if (this->actionFunc != func_80A79FB0) { + if (this->actionFunc != EnIn_WaitForObject) { Gfx_SetupDL_25Opa(play->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeIndex])); gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(gIngoHeadGradient2Tex)); diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.h b/soh/src/overlays/actors/ovl_En_In/z_en_in.h index e926a00eef..36f1310d6c 100644 --- a/soh/src/overlays/actors/ovl_En_In/z_en_in.h +++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.h @@ -52,10 +52,10 @@ typedef struct EnIn { /* 0x01FC */ s16 unk_1FC; /* 0x01FE */ Vec3s jointTable[INGO_LIMB_MAX]; /* 0x0276 */ Vec3s morphTable[INGO_LIMB_MAX]; - /* 0x02F0 */ f32 unk_2F0; + /* 0x02F0 */ f32 subCamAtOffset; /* 0x02F4 */ f32 unk_2F4; /* 0x02F8 */ f32 unk_2F8; - /* 0x02FC */ f32 unk_2FC; + /* 0x02FC */ f32 subCamEyeOffset; /* 0x0300 */ f32 unk_300; /* 0x0304 */ f32 unk_304; /* 0x0308 */ NpcInteractInfo interactInfo; diff --git a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c index 820ce13c52..49836eb61b 100644 --- a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c +++ b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c @@ -17,21 +17,21 @@ void EnInsect_Update(Actor* thisx, PlayState* play); void EnInsect_Draw(Actor* thisx, PlayState* play); void EnInsect_Reset(void); -void func_80A7C3A0(EnInsect* this); -void func_80A7C3F4(EnInsect* this, PlayState* play); -void func_80A7C598(EnInsect* this); -void func_80A7C5EC(EnInsect* this, PlayState* play); -void func_80A7C818(EnInsect* this); -void func_80A7C86C(EnInsect* this, PlayState* play); -void func_80A7CAD0(EnInsect* this, PlayState* play); -void func_80A7CBC8(EnInsect* this); -void func_80A7CC3C(EnInsect* this, PlayState* play); -void func_80A7CE60(EnInsect* this); -void func_80A7CEC0(EnInsect* this, PlayState* play); -void func_80A7D1F4(EnInsect* this); -void func_80A7D26C(EnInsect* this, PlayState* play); -void func_80A7D39C(EnInsect* this); -void func_80A7D460(EnInsect* this, PlayState* play); +void EnInsect_SetupSlowDown(EnInsect* this); +void EnInsect_SlowDown(EnInsect* this, PlayState* play); +void EnInsect_SetupCrawl(EnInsect* this); +void EnInsect_Crawl(EnInsect* this, PlayState* play); +void EnInsect_SetupRunFromPlayer(EnInsect* this); +void EnInsect_RunFromPlayer(EnInsect* this, PlayState* play); +void EnInsect_Caught(EnInsect* this, PlayState* play); +void EnInsect_SetupDig(EnInsect* this); +void EnInsect_Dig(EnInsect* this, PlayState* play); +void EnInsect_SetupWalkOnWater(EnInsect* this); +void EnInsect_WalkOnWater(EnInsect* this, PlayState* play); +void EnInsect_SetupDrown(EnInsect* this); +void EnInsect_Drown(EnInsect* this, PlayState* play); +void EnInsect_SetupDropped(EnInsect* this); +void EnInsect_Dropped(EnInsect* this, PlayState* play); f32 D_80A7DEB0 = 0.0f; s16 D_80A7DEB4 = 0; @@ -86,8 +86,8 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 600, ICHAIN_STOP), }; -void func_80A7BE20(EnInsect* this) { - this->unk_314 = D_80A7DF10[this->actor.params & 3]; +void EnInsect_InitFlags(EnInsect* this) { + this->insectFlags = D_80A7DF10[this->actor.params & 3]; } f32 EnInsect_XZDistanceSquared(Vec3f* v1, Vec3f* v2) { @@ -115,7 +115,7 @@ s32 EnInsect_InBottleRange(EnInsect* this, PlayState* play) { return false; } -void func_80A7BF58(EnInsect* this) { +void EnInsect_SetCrawlAnim(EnInsect* this) { Animation_Change(&this->skelAnime, &gBugCrawlAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP_INTERP, 0.0f); } @@ -151,17 +151,17 @@ s32 EnInsect_FoundNearbySoil(EnInsect* this, PlayState* play) { return ret; } -void func_80A7C058(EnInsect* this) { - if (this->unk_31E > 0) { - this->unk_31E--; +void EnInsect_UpdateCrawlSfx(EnInsect* this) { + if (this->crawlSoundDelay > 0) { + this->crawlSoundDelay--; return; } Audio_PlayActorSound2(&this->actor, NA_SE_EN_MUSI_WALK); - this->unk_31E = 3.0f / CLAMP_MIN(this->skelAnime.playSpeed, 0.1f); - if (this->unk_31E < 2) { - this->unk_31E = 2; + this->crawlSoundDelay = 3.0f / CLAMP_MIN(this->skelAnime.playSpeed, 0.1f); + if (this->crawlSoundDelay < 2) { + this->crawlSoundDelay = 2; } } @@ -173,7 +173,7 @@ void EnInsect_Init(Actor* thisx, PlayState* play2) { s32 count; Actor_ProcessInitChain(&this->actor, sInitChain); - func_80A7BE20(this); + EnInsect_InitFlags(this); temp_s2 = this->actor.params & 3; @@ -183,19 +183,19 @@ void EnInsect_Init(Actor* thisx, PlayState* play2) { this->actor.colChkInfo.mass = 30; - if (this->unk_314 & 1) { + if (this->insectFlags & 1) { this->actor.gravity = -0.2f; this->actor.minVelocityY = -2.0f; } - if (this->unk_314 & 4) { - this->unk_31C = Rand_S16Offset(200, 40); + if (this->insectFlags & 4) { + this->lifeTimer = Rand_S16Offset(200, 40); this->actor.flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED; } if (temp_s2 == 2 || temp_s2 == 3) { if (EnInsect_FoundNearbySoil(this, play)) { - this->unk_314 |= 0x10; + this->insectFlags |= 0x10; D_80A7DEB0 = 0.0f; } @@ -210,25 +210,18 @@ void EnInsect_Init(Actor* thisx, PlayState* play2) { } } - func_80A7D39C(this); - - // For bugs that aren't linked to a soil patch, we remove the "short lived" flag to prevent them from despawning - // And exit early to not increment the "bugs dropped count" - if (CVarGetInteger(CVAR_CHEAT("NoBugsDespawn"), 0) && this->soilActor == NULL) { - this->unk_314 &= ~4; - return; - } + EnInsect_SetupDropped(this); D_80A7DEB8++; } else { rand = Rand_ZeroOne(); if (rand < 0.3f) { - func_80A7C3A0(this); + EnInsect_SetupSlowDown(this); } else if (rand < 0.4f) { - func_80A7C598(this); + EnInsect_SetupCrawl(this); } else { - func_80A7C818(this); + EnInsect_SetupRunFromPlayer(this); } } } @@ -246,14 +239,14 @@ void EnInsect_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -void func_80A7C3A0(EnInsect* this) { - this->unk_31A = Rand_S16Offset(5, 35); - func_80A7BF58(this); - this->actionFunc = func_80A7C3F4; - this->unk_314 |= 0x100; +void EnInsect_SetupSlowDown(EnInsect* this) { + this->actionTimer = Rand_S16Offset(5, 35); + EnInsect_SetCrawlAnim(this); + this->actionFunc = EnInsect_SlowDown; + this->insectFlags |= 0x100; } -void func_80A7C3F4(EnInsect* this, PlayState* play) { +void EnInsect_SlowDown(EnInsect* this, PlayState* play) { s32 pad[2]; s16 sp2E; f32 playSpeed; @@ -267,28 +260,28 @@ void func_80A7C3F4(EnInsect* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); this->actor.shape.rot.y = this->actor.world.rot.y; - if (this->unk_31A <= 0) { - func_80A7C598(this); + if (this->actionTimer <= 0) { + EnInsect_SetupCrawl(this); } - if (((this->unk_314 & 4) && this->unk_31C <= 0) || - ((sp2E == 2 || sp2E == 3) && (this->unk_314 & 1) && (this->actor.bgCheckFlags & 1) && D_80A7DEB8 >= 4)) { - func_80A7CBC8(this); - } else if ((this->unk_314 & 1) && (this->actor.bgCheckFlags & 0x40)) { - func_80A7CE60(this); + if (((this->insectFlags & 4) && this->lifeTimer <= 0) || + ((sp2E == 2 || sp2E == 3) && (this->insectFlags & 1) && (this->actor.bgCheckFlags & 1) && D_80A7DEB8 >= 4)) { + EnInsect_SetupDig(this); + } else if ((this->insectFlags & 1) && (this->actor.bgCheckFlags & 0x40)) { + EnInsect_SetupWalkOnWater(this); } else if (this->actor.xzDistToPlayer < 40.0f) { - func_80A7C818(this); + EnInsect_SetupRunFromPlayer(this); } } -void func_80A7C598(EnInsect* this) { - this->unk_31A = Rand_S16Offset(10, 45); - func_80A7BF58(this); - this->actionFunc = func_80A7C5EC; - this->unk_314 |= 0x100; +void EnInsect_SetupCrawl(EnInsect* this) { + this->actionTimer = Rand_S16Offset(10, 45); + EnInsect_SetCrawlAnim(this); + this->actionFunc = EnInsect_Crawl; + this->insectFlags |= 0x100; } -void func_80A7C5EC(EnInsect* this, PlayState* play) { +void EnInsect_Crawl(EnInsect* this, PlayState* play) { s32 pad1; s32 pad2; s16 yaw; @@ -296,7 +289,8 @@ void func_80A7C5EC(EnInsect* this, PlayState* play) { Math_SmoothStepToF(&this->actor.speedXZ, 1.5f, 0.1f, 0.5f, 0.0f); - if (EnInsect_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > 1600.0f || (this->unk_31A < 4)) { + if (EnInsect_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > 1600.0f || + (this->actionTimer < 4)) { yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); Math_ScaledStepToS(&this->actor.world.rot.y, yaw, 2000); } else if (this->actor.child != NULL && &this->actor != this->actor.child) { @@ -309,28 +303,28 @@ void func_80A7C5EC(EnInsect* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (this->unk_31A <= 0) { - func_80A7C3A0(this); + if (this->actionTimer <= 0) { + EnInsect_SetupSlowDown(this); } - if (((this->unk_314 & 4) && this->unk_31C <= 0) || - ((sp34 == 2 || sp34 == 3) && (this->unk_314 & 1) && (this->actor.bgCheckFlags & 1) && D_80A7DEB8 >= 4)) { - func_80A7CBC8(this); - } else if ((this->unk_314 & 1) && (this->actor.bgCheckFlags & 0x40)) { - func_80A7CE60(this); + if (((this->insectFlags & 4) && this->lifeTimer <= 0) || + ((sp34 == 2 || sp34 == 3) && (this->insectFlags & 1) && (this->actor.bgCheckFlags & 1) && D_80A7DEB8 >= 4)) { + EnInsect_SetupDig(this); + } else if ((this->insectFlags & 1) && (this->actor.bgCheckFlags & 0x40)) { + EnInsect_SetupWalkOnWater(this); } else if (this->actor.xzDistToPlayer < 40.0f) { - func_80A7C818(this); + EnInsect_SetupRunFromPlayer(this); } } -void func_80A7C818(EnInsect* this) { - this->unk_31A = Rand_S16Offset(10, 40); - func_80A7BF58(this); - this->actionFunc = func_80A7C86C; - this->unk_314 |= 0x100; +void EnInsect_SetupRunFromPlayer(EnInsect* this) { + this->actionTimer = Rand_S16Offset(10, 40); + EnInsect_SetCrawlAnim(this); + this->actionFunc = EnInsect_RunFromPlayer; + this->insectFlags |= 0x100; } -void func_80A7C86C(EnInsect* this, PlayState* play) { +void EnInsect_RunFromPlayer(EnInsect* this, PlayState* play) { s32 pad1; s32 pad2; s16 pad3; @@ -340,7 +334,7 @@ void func_80A7C86C(EnInsect* this, PlayState* play) { Math_SmoothStepToF(&this->actor.speedXZ, 1.8f, 0.1f, 0.5f, 0.0f); - if (EnInsect_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > 25600.0f || this->unk_31A < 4) { + if (EnInsect_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > 25600.0f || this->actionTimer < 4) { yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); Math_ScaledStepToS(&this->actor.world.rot.y, yaw, 2000); } else if (sp38 != 0) { @@ -363,56 +357,56 @@ void func_80A7C86C(EnInsect* this, PlayState* play) { this->skelAnime.playSpeed = CLAMP(this->actor.speedXZ * 1.6f, 0.8f, 1.9f); SkelAnime_Update(&this->skelAnime); - if (this->unk_31A <= 0 || !sp38) { - func_80A7C3A0(this); - } else if ((this->unk_314 & 1) && (this->actor.bgCheckFlags & 0x40)) { - func_80A7CE60(this); + if (this->actionTimer <= 0 || !sp38) { + EnInsect_SetupSlowDown(this); + } else if ((this->insectFlags & 1) && (this->actor.bgCheckFlags & 0x40)) { + EnInsect_SetupWalkOnWater(this); } } -void func_80A7CA64(EnInsect* this) { - this->unk_31A = 200; +void EnInsect_SetupCaught(EnInsect* this) { + this->actionTimer = 200; Actor_SetScale(&this->actor, 0.001f); this->actor.draw = NULL; this->actor.speedXZ = 0.0f; - func_80A7BF58(this); + EnInsect_SetCrawlAnim(this); this->skelAnime.playSpeed = 0.3f; - this->actionFunc = func_80A7CAD0; - this->unk_314 &= ~0x100; + this->actionFunc = EnInsect_Caught; + this->insectFlags &= ~0x100; } -void func_80A7CAD0(EnInsect* this, PlayState* play) { - if (this->unk_31A == 20 && !(this->unk_314 & 4)) { +void EnInsect_Caught(EnInsect* this, PlayState* play) { + if (this->actionTimer == 20 && !(this->insectFlags & 4)) { this->actor.draw = EnInsect_Draw; - } else if (this->unk_31A == 0) { - if (this->unk_314 & 4) { + } else if (this->actionTimer == 0) { + if (this->insectFlags & 4) { Actor_Kill(&this->actor); } else { Actor_SetScale(&this->actor, 0.01f); - func_80A7C3A0(this); + EnInsect_SetupSlowDown(this); } - } else if (this->unk_31A < 20) { + } else if (this->actionTimer < 20) { Actor_SetScale(&this->actor, CLAMP_MAX(this->actor.scale.x + 0.001f, 0.01f)); SkelAnime_Update(&this->skelAnime); } } -void func_80A7CBC8(EnInsect* this) { - this->unk_31A = 60; - func_80A7BF58(this); +void EnInsect_SetupDig(EnInsect* this) { + this->actionTimer = 60; + EnInsect_SetCrawlAnim(this); this->skelAnime.playSpeed = 1.9f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MUSI_SINK); Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos); - this->actionFunc = func_80A7CC3C; - this->unk_314 &= ~0x100; - this->unk_314 |= 0x8; + this->actionFunc = EnInsect_Dig; + this->insectFlags &= ~0x100; + this->insectFlags |= 0x8; } -void func_80A7CC3C(EnInsect* this, PlayState* play) { +void EnInsect_Dig(EnInsect* this, PlayState* play) { static Vec3f accel = { 0.0f, 0.0f, 0.0f }; static Vec3f unused = { 0.0f, 0.0f, 0.0f }; s32 pad[2]; @@ -429,7 +423,7 @@ void func_80A7CC3C(EnInsect* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (this->unk_31A > 20 && Rand_ZeroOne() < 0.1f) { + if (this->actionTimer > 20 && Rand_ZeroOne() < 0.1f) { velocity.x = Math_SinS(this->actor.shape.rot.y) * -0.6f; velocity.y = Math_SinS(this->actor.shape.rot.x) * 0.6f; velocity.z = Math_CosS(this->actor.shape.rot.y) * -0.6f; @@ -437,8 +431,8 @@ void func_80A7CC3C(EnInsect* this, PlayState* play) { Rand_ZeroOne() * 5.0f + 8.0f); } - if (this->unk_31A <= 0) { - if ((this->unk_314 & 0x10) && this->soilActor != NULL && + if (this->actionTimer <= 0) { + if ((this->insectFlags & 0x10) && this->soilActor != NULL && Math3D_Vec3fDistSq(&this->soilActor->actor.world.pos, &this->actor.world.pos) < 64.0f) { this->soilActor->unk_152 = 1; } @@ -446,15 +440,15 @@ void func_80A7CC3C(EnInsect* this, PlayState* play) { } } -void func_80A7CE60(EnInsect* this) { - this->unk_31A = Rand_S16Offset(120, 50); - func_80A7BF58(this); +void EnInsect_SetupWalkOnWater(EnInsect* this) { + this->actionTimer = Rand_S16Offset(120, 50); + EnInsect_SetCrawlAnim(this); this->unk_316 = this->unk_318 = 0; - this->actionFunc = func_80A7CEC0; - this->unk_314 &= ~0x100; + this->actionFunc = EnInsect_WalkOnWater; + this->insectFlags &= ~0x100; } -void func_80A7CEC0(EnInsect* this, PlayState* play) { +void EnInsect_WalkOnWater(EnInsect* this, PlayState* play) { f32 temp_f0; s16 temp_v1; s16 pad; @@ -465,18 +459,18 @@ void func_80A7CEC0(EnInsect* this, PlayState* play) { sp4E = this->actor.params & 3; - if (this->unk_31A >= 81) { + if (this->actionTimer >= 81) { Math_StepToF(&this->actor.speedXZ, 0.6f, 0.08f); } else { Math_StepToF(&this->actor.speedXZ, 0.0f, 0.02f); } this->actor.velocity.y = 0.0f; this->actor.world.pos.y += this->actor.yDistToWater; - this->skelAnime.playSpeed = CLAMP(this->unk_31A * 0.018f, 0.1f, 1.9f); + this->skelAnime.playSpeed = CLAMP(this->actionTimer * 0.018f, 0.1f, 1.9f); SkelAnime_Update(&this->skelAnime); - if (this->unk_31A >= 81) { + if (this->actionTimer >= 81) { this->unk_316 += Rand_S16Offset(-50, 100); this->unk_318 += Rand_S16Offset(-300, 600); } @@ -519,32 +513,32 @@ void func_80A7CEC0(EnInsect* this, PlayState* play) { EffectSsGRipple_Spawn(play, &sp40, 40, 200, 8); } - if (this->unk_31A <= 0 || ((this->unk_314 & 4) && this->unk_31C <= 0) || - ((sp4E == 2 || sp4E == 3) && (this->unk_314 & 1) && D_80A7DEB8 >= 4)) { - func_80A7D1F4(this); + if (this->actionTimer <= 0 || ((this->insectFlags & 4) && this->lifeTimer <= 0) || + ((sp4E == 2 || sp4E == 3) && (this->insectFlags & 1) && D_80A7DEB8 >= 4)) { + EnInsect_SetupDrown(this); } else if (!(this->actor.bgCheckFlags & 0x40)) { - if (this->unk_314 & 0x10) { - func_80A7D39C(this); + if (this->insectFlags & 0x10) { + EnInsect_SetupDropped(this); } else { - func_80A7C3A0(this); + EnInsect_SetupSlowDown(this); } } } -void func_80A7D1F4(EnInsect* this) { - this->unk_31A = 100; - func_80A7BF58(this); +void EnInsect_SetupDrown(EnInsect* this) { + this->actionTimer = 100; + EnInsect_SetCrawlAnim(this); this->actor.velocity.y = 0.0f; this->actor.speedXZ = 0.0f; this->actor.minVelocityY = -0.8f; this->actor.gravity = -0.04f; - this->unk_314 &= ~0x3; - this->actionFunc = func_80A7D26C; - this->unk_314 &= ~0x100; - this->unk_314 |= 8; + this->insectFlags &= ~0x3; + this->actionFunc = EnInsect_Drown; + this->insectFlags &= ~0x100; + this->insectFlags |= 8; } -void func_80A7D26C(EnInsect* this, PlayState* play) { +void EnInsect_Drown(EnInsect* this, PlayState* play) { this->actor.shape.rot.x -= 500; this->actor.shape.rot.y += 200; Actor_SetScale(&this->actor, CLAMP_MIN(this->actor.scale.x - 0.00005f, 0.001f)); @@ -553,24 +547,24 @@ void func_80A7D26C(EnInsect* this, PlayState* play) { EffectSsBubble_Spawn(play, &this->actor.world.pos, -5.0f, 5.0f, 5.0f, (Rand_ZeroOne() * 0.04f) + 0.02f); } - if (this->unk_31A <= 0) { + if (this->actionTimer <= 0) { Actor_Kill(&this->actor); } } -void func_80A7D39C(EnInsect* this) { - func_80A7BF58(this); - this->unk_31A = 100; +void EnInsect_SetupDropped(EnInsect* this) { + EnInsect_SetCrawlAnim(this); + this->actionTimer = 100; this->unk_324 = 1.5f; this->unk_328 = Rand_ZeroOne() * (0xFFFF + 0.5f); this->unk_316 = (Rand_ZeroOne() - 0.5f) * 1500.0f; this->actor.world.rot.y = Rand_ZeroOne() * (0xFFFF + 0.5f); Actor_SetScale(&this->actor, 0.003f); - this->actionFunc = func_80A7D460; - this->unk_314 |= 0x100; + this->actionFunc = EnInsect_Dropped; + this->insectFlags |= 0x100; } -void func_80A7D460(EnInsect* this, PlayState* play) { +void EnInsect_Dropped(EnInsect* this, PlayState* play) { s32 temp_a0; s32 sp50; f32 phi_f0; @@ -588,7 +582,7 @@ void func_80A7D460(EnInsect* this, PlayState* play) { if (this->soilActor != NULL) { sp40 = Math3D_Vec3fDistSq(&this->actor.world.pos, &this->soilActor->actor.world.pos); } else { - if (this->unk_314 & 0x10) { + if (this->insectFlags & 0x10) { osSyncPrintf(VT_COL(YELLOW, BLACK)); // "warning: target Actor is NULL" osSyncPrintf("warning:目標 Actor が NULL (%s %d)\n", __FILE__, __LINE__); @@ -674,12 +668,12 @@ void func_80A7D460(EnInsect* this, PlayState* play) { } SkelAnime_Update(&this->skelAnime); - if (!(this->unk_314 & 0x40) && (this->unk_314 & 1) && (this->actor.bgCheckFlags & 1)) { + if (!(this->insectFlags & 0x40) && (this->insectFlags & 1) && (this->actor.bgCheckFlags & 1)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MUSI_LAND); - this->unk_314 |= 0x40; + this->insectFlags |= 0x40; } - if (sp3A == 2 && (this->unk_314 & 0x10) && !(this->unk_314 & 0x80)) { + if (sp3A == 2 && (this->insectFlags & 0x10) && !(this->insectFlags & 0x80)) { if (this->unk_32A >= 15) { if (this->soilActor != NULL) { if (!(GET_GS_FLAGS(((this->soilActor->actor.params >> 8) & 0x1F) - 1) & @@ -687,32 +681,32 @@ void func_80A7D460(EnInsect* this, PlayState* play) { Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } - this->unk_314 |= 0x80; + this->insectFlags |= 0x80; } else { this->unk_32A++; } } - if ((this->unk_314 & 1) && (this->actor.bgCheckFlags & 0x40)) { - func_80A7CE60(this); - } else if (this->unk_314 & 0x10) { + if ((this->insectFlags & 1) && (this->actor.bgCheckFlags & 0x40)) { + EnInsect_SetupWalkOnWater(this); + } else if (this->insectFlags & 0x10) { if (sp40 < 9.0f) { - func_80A7CBC8(this); - } else if (this->unk_31A <= 0 || this->unk_31C <= 0 || - ((this->unk_314 & 1) && (this->actor.bgCheckFlags & 1) && D_80A7DEB8 >= 4 && + EnInsect_SetupDig(this); + } else if (this->actionTimer <= 0 || this->lifeTimer <= 0 || + ((this->insectFlags & 1) && (this->actor.bgCheckFlags & 1) && D_80A7DEB8 >= 4 && (sp3A == 2 || sp3A == 3))) { - func_80A7CBC8(this); + EnInsect_SetupDig(this); } else { if (sp40 < 900.0f) { - this->unk_31C++; - this->unk_314 |= 0x20; + this->lifeTimer++; + this->insectFlags |= 0x20; } else { - this->unk_31A = 100; + this->actionTimer = 100; } } } else if (sp50 != 0) { - func_80A7C3A0(this); - } else if ((sp3A == 2 || sp3A == 3) && (this->unk_314 & 1) && this->unk_31C <= 0 && this->unk_31A <= 0 && + EnInsect_SetupSlowDown(this); + } else if ((sp3A == 2 || sp3A == 3) && (this->insectFlags & 1) && this->lifeTimer <= 0 && this->actionTimer <= 0 && this->actor.floorHeight < BGCHECK_Y_MIN + 10.0f) { osSyncPrintf(VT_COL(YELLOW, BLACK)); // "BG missing? To do Actor_delete" @@ -734,35 +728,35 @@ void EnInsect_Update(Actor* thisx, PlayState* play) { } } - if (this->unk_31A > 0) { - this->unk_31A--; + if (this->actionTimer > 0) { + this->actionTimer--; } - if (this->unk_31C > 0) { - this->unk_31C--; + if (this->lifeTimer > 0) { + this->lifeTimer--; } this->actionFunc(this, play); if (this->actor.update != NULL) { Actor_MoveXZGravity(&this->actor); - if (this->unk_314 & 0x100) { - if (this->unk_314 & 1) { + if (this->insectFlags & 0x100) { + if (this->insectFlags & 1) { if (this->actor.bgCheckFlags & 1) { - func_80A7C058(this); + EnInsect_UpdateCrawlSfx(this); } } else { - func_80A7C058(this); + EnInsect_UpdateCrawlSfx(this); } } phi_v0 = 0; - if (this->unk_314 & 1) { + if (this->insectFlags & 1) { phi_v0 = 4; } - if (this->unk_314 & 2) { + if (this->insectFlags & 2) { phi_v0 |= 1; } @@ -778,14 +772,14 @@ void EnInsect_Update(Actor* thisx, PlayState* play) { if (phi_v0 == 2 || phi_v0 == 3) { Actor_Kill(&this->actor); } else { - func_80A7CA64(this); + EnInsect_SetupCaught(this); } - } else if (this->actor.xzDistToPlayer < 50.0f && this->actionFunc != func_80A7CAD0) { - if (!(this->unk_314 & 0x20) && this->unk_31C < 180) { + } else if (this->actor.xzDistToPlayer < 50.0f && this->actionFunc != EnInsect_Caught) { + if (!(this->insectFlags & 0x20) && this->lifeTimer < 180) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); } - if (!(this->unk_314 & 8) && D_80A7DEB4 < 4 && EnInsect_InBottleRange(this, play) && + if (!(this->insectFlags & 8) && D_80A7DEB4 < 4 && EnInsect_InBottleRange(this, play) && // GI_MAX in this case allows the player to catch the actor in a bottle Actor_OfferGetItem(&this->actor, play, GI_MAX, 60.0f, 30.0f)) { D_80A7DEB4++; diff --git a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.h b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.h index c18b5aa261..c82cad97e1 100644 --- a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.h +++ b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.h @@ -17,12 +17,12 @@ typedef struct EnInsect { /* 0x01F0 */ Vec3s jointTable[24]; /* 0x0280 */ Vec3s morphTable[24]; /* 0x0310 */ EnInsectActionFunc actionFunc; - /* 0x0314 */ u16 unk_314; + /* 0x0314 */ u16 insectFlags; /* 0x0316 */ s16 unk_316; /* 0x0318 */ s16 unk_318; - /* 0x031A */ s16 unk_31A; - /* 0x031C */ s16 unk_31C; - /* 0x031E */ s16 unk_31E; + /* 0x031A */ s16 actionTimer; + /* 0x031C */ s16 lifeTimer; + /* 0x031E */ s16 crawlSoundDelay; /* 0x0320 */ ObjMakekinsuta* soilActor; /* 0x0324 */ f32 unk_324; /* 0x0328 */ s16 unk_328; diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index c88e69fdde..1f4e9adfb1 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -8,6 +8,7 @@ #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" @@ -251,7 +252,7 @@ void EnIshi_SpawnDustLarge(EnIshi* this, PlayState* play) { void EnIshi_DropCollectible(EnIshi* this, PlayState* play) { s16 dropParams; - if ((this->actor.params & 1) == ROCK_SMALL) { + if (GameInteractor_Should(VB_ROCK_DROP_ITEM, (this->actor.params & 1) == ROCK_SMALL, this)) { dropParams = (this->actor.params >> 8) & 0xF; if (dropParams >= 0xD) { diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index e818a1c2c4..cfd312c714 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -707,7 +707,7 @@ s32 func_80A97D68(EnKo* this, PlayState* play) { s32 func_80A97E18(EnKo* this, PlayState* play) { s16 trackingMode; - func_80034F54(play, this->unk_2E4, this->unk_304, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); if (EnKo_IsWithinTalkAngle(this) == true) { trackingMode = NPC_TRACKING_HEAD_AND_TORSO; } else { @@ -726,7 +726,7 @@ s32 func_80A97EB0(EnKo* this, PlayState* play) { s16 trackingMode; s32 result; - func_80034F54(play, this->unk_2E4, this->unk_304, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); result = EnKo_IsWithinTalkAngle(this); trackingMode = (result == true) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; Npc_TrackPoint(&this->actor, &this->interactInfo, 2, trackingMode); @@ -734,7 +734,7 @@ s32 func_80A97EB0(EnKo* this, PlayState* play) { } s32 func_80A97F20(EnKo* this, PlayState* play) { - func_80034F54(play, this->unk_2E4, this->unk_304, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); return 1; } @@ -746,7 +746,7 @@ s32 func_80A97F70(EnKo* this, PlayState* play) { if ((this->skelAnime.animation == &gKokiriBlockingAnim) == false) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_BLOCKING_STATIC); } - func_80034F54(play, this->unk_2E4, this->unk_304, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); trackingMode = NPC_TRACKING_HEAD_AND_TORSO; } else { if ((this->skelAnime.animation == &gKokiriCuttingGrassAnim) == false) { @@ -766,7 +766,7 @@ s32 func_80A98034(EnKo* this, PlayState* play) { if ((this->skelAnime.animation == &gKokiriBlockingAnim) == false) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_BLOCKING_STATIC); } - func_80034F54(play, this->unk_2E4, this->unk_304, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); result = EnKo_IsWithinTalkAngle(this); trackingMode = (result == true) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; } else { @@ -782,7 +782,7 @@ s32 func_80A98034(EnKo* this, PlayState* play) { // Same as func_80A97F20 s32 func_80A98124(EnKo* this, PlayState* play) { - func_80034F54(play, this->unk_2E4, this->unk_304, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); return 1; } @@ -796,7 +796,7 @@ s32 func_80A98174(EnKo* this, PlayState* play) { this->skelAnime.playSpeed = 1.0f; } if (this->skelAnime.playSpeed == 0.0f) { - func_80034F54(play, this->unk_2E4, this->unk_304, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); } Npc_TrackPoint(&this->actor, &this->interactInfo, 2, (this->skelAnime.playSpeed == 0.0f) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE); @@ -1338,8 +1338,8 @@ s32 EnKo_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po Matrix_Translate(-1200.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 8 || limbIndex == 9 || limbIndex == 12) { - rot->y += Math_SinS(this->unk_2E4[limbIndex]) * 200.0f; - rot->z += Math_CosS(this->unk_304[limbIndex]) * 200.0f; + rot->y += Math_SinS(this->fidgetTableY[limbIndex]) * 200.0f; + rot->z += Math_CosS(this->fidgetTableZ[limbIndex]) * 200.0f; } return false; } diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h index 80ecd06641..32d76764b7 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h @@ -30,8 +30,8 @@ typedef struct EnKo { /* 0x0220 */ f32 modelAlpha; /* 0x0224 */ Vec3s jointTable[16]; /* 0x0284 */ Vec3s morphTable[16]; - /* 0x02E4 */ s16 unk_2E4[16]; - /* 0x0304 */ s16 unk_304[16]; + /* 0x02E4 */ s16 fidgetTableY[16]; + /* 0x0304 */ s16 fidgetTableZ[16]; } EnKo; // size = 0x0324 typedef enum { diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 110f663331..fa4db4d59c 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -416,7 +416,7 @@ void EnKz_PreMweepWait(EnKz* this, PlayState* play) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = EnKz_SetupMweep; } else { - func_80034F54(play, this->unk_2A6, this->unk_2BE, 12); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 12); } } @@ -489,7 +489,7 @@ void EnKz_Wait(EnKz* this, PlayState* play) { this->actionFunc = EnKz_SetupGetItem; EnKz_SetupGetItem(this, play); } else { - func_80034F54(play, this->unk_2A6, this->unk_2BE, 12); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 12); } } @@ -548,8 +548,8 @@ s32 EnKz_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po EnKz* this = (EnKz*)thisx; if (limbIndex == 8 || limbIndex == 9 || limbIndex == 10) { - rot->y += Math_SinS(this->unk_2A6[limbIndex]) * 200.0f; - rot->z += Math_CosS(this->unk_2BE[limbIndex]) * 200.0f; + rot->y += Math_SinS(this->fidgetTableY[limbIndex]) * 200.0f; + rot->z += Math_CosS(this->fidgetTableZ[limbIndex]) * 200.0f; } if (limbIndex) {} return false; diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h index 0b48ff202f..b66a35ba8e 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h @@ -24,8 +24,8 @@ typedef struct EnKz { /* 0x0214 */ s16 gameplayCamera; /* 0x0216 */ Vec3s jointTable[12]; /* 0x025E */ Vec3s morphTable[12]; - /* 0x02A6 */ s16 unk_2A6[12]; - /* 0x02BE */ s16 unk_2BE[12]; + /* 0x02A6 */ s16 fidgetTableY[12]; + /* 0x02BE */ s16 fidgetTableZ[12]; } EnKz; // size = 0x02D8 diff --git a/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c b/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c index 4f838f5bbc..2731873db6 100644 --- a/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c +++ b/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c @@ -8,9 +8,9 @@ void EnMThunder_Destroy(Actor* thisx, PlayState* play); void EnMThunder_Update(Actor* thisx, PlayState* play); void EnMThunder_Draw(Actor* thisx, PlayState* play); -void func_80A9F314(PlayState* play, f32 arg1); -void func_80A9F408(EnMThunder* this, PlayState* play); -void func_80A9F9B4(EnMThunder* this, PlayState* play); +void EnMThunder_AdjustEnvLights(PlayState* play, f32 intensity); +void EnMThunder_ChargingSpinAttack(EnMThunder* this, PlayState* play); +void EnMThunder_SpinAttacking(EnMThunder* this, PlayState* play); const ActorInit En_M_Thunder_InitVars = { ACTOR_EN_M_THUNDER, @@ -25,7 +25,7 @@ const ActorInit En_M_Thunder_InitVars = { NULL, }; -static ColliderCylinderInit D_80AA0420 = { +static ColliderCylinderInit sCylinderInit = { { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, @@ -45,8 +45,8 @@ static ColliderCylinderInit D_80AA0420 = { { 200, 200, 0, { 0, 0, 0 } }, }; -static u32 D_80AA044C[] = { 0x01000000, 0x00400000, 0x00800000 }; -static u32 D_80AA0458[] = { 0x08000000, 0x02000000, 0x04000000 }; +static u32 sSpinAttackDmgFlags[] = { 0x01000000, 0x00400000, 0x00800000 }; +static u32 sJumpAttackDmgFlags[] = { 0x08000000, 0x02000000, 0x04000000 }; static u16 sSfxIds[] = { NA_SE_IT_ROLLING_CUT_LV2, @@ -55,8 +55,7 @@ static u16 sSfxIds[] = { NA_SE_IT_ROLLING_CUT_LV1, }; -// Setup action -void func_80A9EFE0(EnMThunder* this, EnMThunderActionFunc actionFunc) { +void EnMThunder_SetupAction(EnMThunder* this, EnMThunderActionFunc actionFunc) { this->actionFunc = actionFunc; } @@ -66,23 +65,23 @@ void EnMThunder_Init(Actor* thisx, PlayState* play2) { Player* player = GET_PLAYER(play); Collider_InitCylinder(play, &this->collider); - Collider_SetCylinder(play, &this->collider, &this->actor, &D_80AA0420); - this->unk_1C7 = (this->actor.params & 0xFF) - 1; + Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); + this->swordType = (this->actor.params & 0xFF) - 1; Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 255, 255, 255, 0); this->lightNode = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo); this->collider.dim.radius = 0; this->collider.dim.height = 40; this->collider.dim.yShift = -20; - this->unk_1C4 = 8; - this->unk_1B4 = 0.0f; + this->followPlayerTimer = 8; + this->spinTrailTexScroll = 0.0f; this->actor.world.pos = player->bodyPartsPos[0]; - this->unk_1AC = 0.0f; - this->unk_1BC = 0.0f; + this->spinAttackTimer = 0.0f; + this->dimmingIntensity = 0.0f; this->actor.shape.rot.y = player->actor.shape.rot.y + 0x8000; this->actor.room = -1; Actor_SetScale(&this->actor, 0.1f); - this->unk_1CA = 0; + this->isUsingMagic = 0; if (player->stateFlags2 & PLAYER_STATE2_SPIN_ATTACKING) { if (!gSaveContext.isMagicAcquired || (gSaveContext.magicState != MAGIC_STATE_IDLE) || @@ -97,17 +96,17 @@ void EnMThunder_Init(Actor* thisx, PlayState* play2) { } player->stateFlags2 &= ~PLAYER_STATE2_SPIN_ATTACKING; - this->unk_1CA = 1; - this->collider.info.toucher.dmgFlags = D_80AA044C[this->unk_1C7]; - this->unk_1C6 = 1; - this->unk_1C9 = ((this->unk_1C7 == 1) ? 2 : 4); - func_80A9EFE0(this, func_80A9F9B4); - this->unk_1C4 = 8; + this->isUsingMagic = 1; + this->collider.info.toucher.dmgFlags = sSpinAttackDmgFlags[this->swordType]; + this->attackStrength = 1; + this->targetScale = ((this->swordType == 1) ? 2 : 4); + EnMThunder_SetupAction(this, EnMThunder_SpinAttacking); + this->followPlayerTimer = 8; Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT_LV1, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - this->unk_1AC = 1.0f; + this->spinAttackTimer = 1.0f; } else { - func_80A9EFE0(this, func_80A9F408); + EnMThunder_SetupAction(this, EnMThunder_ChargingSpinAttack); } this->actor.child = NULL; } @@ -115,20 +114,20 @@ void EnMThunder_Init(Actor* thisx, PlayState* play2) { void EnMThunder_Destroy(Actor* thisx, PlayState* play) { EnMThunder* this = (EnMThunder*)thisx; - if (this->unk_1CA != 0) { + if (this->isUsingMagic != 0) { Magic_Reset(play); } Collider_DestroyCylinder(play, &this->collider); - func_80A9F314(play, 0.0f); + EnMThunder_AdjustEnvLights(play, 0.0f); LightContext_RemoveLight(play, &play->lightCtx, this->lightNode); } -void func_80A9F314(PlayState* play, f32 arg1) { - Environment_AdjustLights(play, arg1, 850.0f, 0.2f, 0.0f); +void EnMThunder_AdjustEnvLights(PlayState* play, f32 intensity) { + Environment_AdjustLights(play, intensity, 850.0f, 0.2f, 0.0f); } -void func_80A9F350(EnMThunder* this, PlayState* play) { +void EnMThunder_EmptySpinAttack(EnMThunder* this, PlayState* play) { Player* player = GET_PLAYER(play); if (player->stateFlags2 & PLAYER_STATE2_SPIN_ATTACKING) { @@ -148,28 +147,28 @@ void func_80A9F350(EnMThunder* this, PlayState* play) { } } -void func_80A9F408(EnMThunder* this, PlayState* play) { +void EnMThunder_ChargingSpinAttack(EnMThunder* this, PlayState* play) { Player* player = GET_PLAYER(play); Actor* child = this->actor.child; - this->unk_1B8 = player->unk_858; + this->spinChargePercent = player->unk_858; this->actor.world.pos = player->bodyPartsPos[0]; this->actor.shape.rot.y = player->actor.shape.rot.y + 0x8000; - if (this->unk_1CA == 0) { + if (this->isUsingMagic == 0) { if (player->unk_858 >= 0.1f) { if ((gSaveContext.magicState != MAGIC_STATE_IDLE) || (((this->actor.params & 0xFF00) >> 8) && !(Magic_RequestChange(play, (this->actor.params & 0xFF00) >> 8, MAGIC_CONSUME_WAIT_PREVIEW)))) { - func_80A9F350(this, play); - func_80A9EFE0(this, func_80A9F350); - this->unk_1C8 = 0; - this->unk_1BC = 0.0; - this->unk_1AC = 0.0f; + EnMThunder_EmptySpinAttack(this, play); + EnMThunder_SetupAction(this, EnMThunder_EmptySpinAttack); + this->chargeAlpha = 0; + this->dimmingIntensity = 0.0; + this->spinAttackTimer = 0.0f; return; } - this->unk_1CA = 1; + this->isUsingMagic = 1; } } @@ -197,20 +196,20 @@ void func_80A9F408(EnMThunder* this, PlayState* play) { gSaveContext.magicState = MAGIC_STATE_CONSUME_SETUP; } if (player->unk_858 < 0.85f) { - this->collider.info.toucher.dmgFlags = D_80AA044C[this->unk_1C7]; - this->unk_1C6 = 1; - this->unk_1C9 = ((this->unk_1C7 == 1) ? 2 : 4); + this->collider.info.toucher.dmgFlags = sSpinAttackDmgFlags[this->swordType]; + this->attackStrength = 1; + this->targetScale = ((this->swordType == 1) ? 2 : 4); } else { - this->collider.info.toucher.dmgFlags = D_80AA0458[this->unk_1C7]; - this->unk_1C6 = 0; - this->unk_1C9 = ((this->unk_1C7 == 1) ? 4 : 8); + this->collider.info.toucher.dmgFlags = sJumpAttackDmgFlags[this->swordType]; + this->attackStrength = 0; + this->targetScale = ((this->swordType == 1) ? 4 : 8); } - func_80A9EFE0(this, func_80A9F9B4); - this->unk_1C4 = 8; - Audio_PlaySoundGeneral(sSfxIds[this->unk_1C6], &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - this->unk_1AC = 1.0f; + EnMThunder_SetupAction(this, EnMThunder_SpinAttacking); + this->followPlayerTimer = 8; + Audio_PlaySoundGeneral(sSfxIds[this->attackStrength], &player->actor.projectedPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + this->spinAttackTimer = 1.0f; return; } } @@ -224,19 +223,19 @@ void func_80A9F408(EnMThunder* this, PlayState* play) { } if (player->unk_858 > 0.15f) { - this->unk_1C8 = 255; + this->chargeAlpha = 255; if (this->actor.child == NULL) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EFF_DUST, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, - this->unk_1C7 + 2); + this->swordType + 2); } - this->unk_1BC += ((((player->unk_858 - 0.15f) * 1.5f) - this->unk_1BC) * 0.5f); + this->dimmingIntensity += ((((player->unk_858 - 0.15f) * 1.5f) - this->dimmingIntensity) * 0.5f); } else if (player->unk_858 > .1f) { - this->unk_1C8 = (s32)((player->unk_858 - .1f) * 255.0f * 20.0f); - this->unk_1AC = (player->unk_858 - .1f) * 10.0f; + this->chargeAlpha = (s32)((player->unk_858 - .1f) * 255.0f * 20.0f); + this->spinAttackTimer = (player->unk_858 - .1f) * 10.0f; } else { - this->unk_1C8 = 0; + this->chargeAlpha = 0; } if (player->unk_858 > 0.85f) { @@ -252,50 +251,50 @@ void func_80A9F408(EnMThunder* this, PlayState* play) { } } -void func_80A9F938(EnMThunder* this, PlayState* play) { - if (this->unk_1C4 < 2) { - if (this->unk_1C8 < 40) { - this->unk_1C8 = 0; +void EnMThunder_UpdateSpinAttack(EnMThunder* this, PlayState* play) { + if (this->followPlayerTimer < 2) { + if (this->chargeAlpha < 40) { + this->chargeAlpha = 0; } else { - this->unk_1C8 -= 40; + this->chargeAlpha -= 40; } } - this->unk_1B4 += 2.0f * this->unk_1B0; + this->spinTrailTexScroll += 2.0f * this->spinAttackAlpha; - if (this->unk_1BC < this->unk_1AC) { - this->unk_1BC += ((this->unk_1AC - this->unk_1BC) * 0.1f); + if (this->dimmingIntensity < this->spinAttackTimer) { + this->dimmingIntensity += ((this->spinAttackTimer - this->dimmingIntensity) * 0.1f); } else { - this->unk_1BC = this->unk_1AC; + this->dimmingIntensity = this->spinAttackTimer; } } -void func_80A9F9B4(EnMThunder* this, PlayState* play) { +void EnMThunder_SpinAttacking(EnMThunder* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (Math_StepToF(&this->unk_1AC, 0.0f, 1 / 16.0f)) { + if (Math_StepToF(&this->spinAttackTimer, 0.0f, 1 / 16.0f)) { Actor_Kill(&this->actor); } else { - Math_SmoothStepToF(&this->actor.scale.x, (s32)this->unk_1C9, 0.6f, 0.8f, 0.0f); + Math_SmoothStepToF(&this->actor.scale.x, (s32)this->targetScale, 0.6f, 0.8f, 0.0f); Actor_SetScale(&this->actor, this->actor.scale.x); this->collider.dim.radius = (this->actor.scale.x * 25.0f); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); } - if (this->unk_1C4 > 0) { + if (this->followPlayerTimer > 0) { this->actor.world.pos.x = player->bodyPartsPos[0].x; this->actor.world.pos.z = player->bodyPartsPos[0].z; - this->unk_1C4--; + this->followPlayerTimer--; } - if (this->unk_1AC > 0.6f) { - this->unk_1B0 = 1.0f; + if (this->spinAttackTimer > 0.6f) { + this->spinAttackAlpha = 1.0f; } else { - this->unk_1B0 = this->unk_1AC * (5.0f / 3.0f); + this->spinAttackAlpha = this->spinAttackTimer * (5.0f / 3.0f); } - func_80A9F938(this, play); + EnMThunder_UpdateSpinAttack(this, play); if (Play_InCsMode(play)) { Actor_Kill(&this->actor); @@ -308,8 +307,8 @@ void EnMThunder_Update(Actor* thisx, PlayState* play) { s32 redGreen; this->actionFunc(this, play); - func_80A9F314(play, this->unk_1BC); - blueRadius = this->unk_1AC; + EnMThunder_AdjustEnvLights(play, this->dimmingIntensity); + blueRadius = this->spinAttackTimer; redGreen = (u32)(blueRadius * 255.0f) & 0xFF; Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, redGreen, redGreen, (u32)(blueRadius * 100.0f), @@ -317,7 +316,7 @@ void EnMThunder_Update(Actor* thisx, PlayState* play) { } void EnMThunder_Draw(Actor* thisx, PlayState* play2) { - static f32 D_80AA046C[] = { 0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.25f, 0.2f, 0.15f }; + static f32 sSpinChargeScale[] = { 0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.25f, 0.2f, 0.15f }; PlayState* play = play2; EnMThunder* this = (EnMThunder*)thisx; Player* player = GET_PLAYER(play); @@ -329,24 +328,24 @@ void EnMThunder_Draw(Actor* thisx, PlayState* play2) { Matrix_Scale(0.02f, 0.02f, 0.02f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - switch (this->unk_1C6) { + switch (this->attackStrength) { case 0: case 1: gSPSegment(POLY_XLU_DISP++, 0x08, - Gfx_TwoTexScrollEx(play->state.gfxCtx, 0, 0xFF - ((u8)(s32)(this->unk_1B4 * 30) & 0xFF), 0, 0x40, - 0x20, 1, 0xFF - ((u8)(s32)(this->unk_1B4 * 20) & 0xFF), 0, 8, 8, -30, 0, -20, - 0)); + Gfx_TwoTexScrollEx( + play->state.gfxCtx, 0, 0xFF - ((u8)(s32)(this->spinTrailTexScroll * 30) & 0xFF), 0, 0x40, + 0x20, 1, 0xFF - ((u8)(s32)(this->spinTrailTexScroll * 20) & 0xFF), 0, 8, 8, -30, 0, -20, 0)); break; } - switch (this->unk_1C6) { + switch (this->attackStrength) { case 0: if (CVarGetInteger(CVAR_COSMETIC("SpinAttack.Level2Primary.Changed"), 0)) { Color_RGB8 color = CVarGetColor24(CVAR_COSMETIC("SpinAttack.Level2Primary.Value"), (Color_RGB8){ 255, 255, 170 }); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, color.r, color.g, color.b, (u8)(this->unk_1B0 * 255)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, color.r, color.g, color.b, (u8)(this->spinAttackAlpha * 255)); } else { - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 170, (u8)(this->unk_1B0 * 255)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 170, (u8)(this->spinAttackAlpha * 255)); } gSPDisplayList(POLY_XLU_DISP++, gSpinAttack3DL); gSPDisplayList(POLY_XLU_DISP++, gSpinAttack4DL); @@ -355,9 +354,9 @@ void EnMThunder_Draw(Actor* thisx, PlayState* play2) { if (CVarGetInteger(CVAR_COSMETIC("SpinAttack.Level1Primary.Changed"), 0)) { Color_RGB8 color = CVarGetColor24(CVAR_COSMETIC("SpinAttack.Level1Primary.Value"), (Color_RGB8){ 170, 255, 255 }); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, color.r, color.g, color.b, (u8)(this->unk_1B0 * 255)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, color.r, color.g, color.b, (u8)(this->spinAttackAlpha * 255)); } else { - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, (u8)(this->unk_1B0 * 255)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, (u8)(this->spinAttackAlpha * 255)); } gSPDisplayList(POLY_XLU_DISP++, gSpinAttack1DL); gSPDisplayList(POLY_XLU_DISP++, gSpinAttack2DL); @@ -366,7 +365,7 @@ void EnMThunder_Draw(Actor* thisx, PlayState* play2) { Matrix_Mult(&player->mf_9E0, MTXMODE_NEW); - switch (this->unk_1C7) { + switch (this->swordType) { case 1: Matrix_Translate(0.0f, 220.0f, 0.0f, MTXMODE_APPLY); Matrix_Scale(-0.7f, -0.6f, -0.4f, MTXMODE_APPLY); @@ -384,14 +383,14 @@ void EnMThunder_Draw(Actor* thisx, PlayState* play2) { break; } - if (this->unk_1B8 >= 0.85f) { - phi_f14 = (D_80AA046C[(play->gameplayFrames & 7)] * 6.0f) + 1.0f; + if (this->spinChargePercent >= 0.85f) { + phi_f14 = (sSpinChargeScale[(play->gameplayFrames & 7)] * 6.0f) + 1.0f; if (CVarGetInteger(CVAR_COSMETIC("SpinAttack.Level2Primary.Changed"), 0)) { Color_RGB8 color = CVarGetColor24(CVAR_COSMETIC("SpinAttack.Level2Primary.Value"), (Color_RGB8){ 255, 255, 170 }); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, color.r, color.g, color.b, this->unk_1C8); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, color.r, color.g, color.b, this->chargeAlpha); } else { - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 170, this->unk_1C8); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 170, this->chargeAlpha); } if (CVarGetInteger(CVAR_COSMETIC("SpinAttack.Level2Secondary.Changed"), 0)) { Color_RGB8 color = @@ -402,13 +401,13 @@ void EnMThunder_Draw(Actor* thisx, PlayState* play2) { } phi_t1 = 0x28; } else { - phi_f14 = (D_80AA046C[play->gameplayFrames & 7] * 2.0f) + 1.0f; + phi_f14 = (sSpinChargeScale[play->gameplayFrames & 7] * 2.0f) + 1.0f; if (CVarGetInteger(CVAR_COSMETIC("SpinAttack.Level1Primary.Changed"), 0)) { Color_RGB8 color = CVarGetColor24(CVAR_COSMETIC("SpinAttack.Level1Primary.Value"), (Color_RGB8){ 170, 255, 255 }); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, color.r, color.g, color.b, this->unk_1C8); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, color.r, color.g, color.b, this->chargeAlpha); } else { - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, this->unk_1C8); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, this->chargeAlpha); } if (CVarGetInteger(CVAR_COSMETIC("SpinAttack.Level1Secondary.Changed"), 0)) { Color_RGB8 color = diff --git a/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h b/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h index 5b1caa993c..d83f884184 100644 --- a/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h +++ b/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h @@ -13,18 +13,18 @@ typedef struct EnMThunder { /* 0x014C */ ColliderCylinder collider; /* 0x0198 */ LightNode* lightNode; /* 0x019C */ LightInfo lightInfo; - /* 0x01AC */ f32 unk_1AC; - /* 0x01B0 */ f32 unk_1B0; - /* 0x01B0 */ f32 unk_1B4; - /* 0x01B0 */ f32 unk_1B8; - /* 0x01BC */ f32 unk_1BC; + /* 0x01AC */ f32 spinAttackTimer; + /* 0x01B0 */ f32 spinAttackAlpha; + /* 0x01B4 */ f32 spinTrailTexScroll; + /* 0x01B8 */ f32 spinChargePercent; + /* 0x01BC */ f32 dimmingIntensity; /* 0x01C0 */ EnMThunderActionFunc actionFunc; - /* 0x01C4 */ u16 unk_1C4; - /* 0x01C6 */ u8 unk_1C6; - /* 0x01C7 */ u8 unk_1C7; - /* 0x01C8 */ u8 unk_1C8; - /* 0x01C9 */ u8 unk_1C9; - /* 0x01CA */ u8 unk_1CA; + /* 0x01C4 */ u16 followPlayerTimer; + /* 0x01C6 */ u8 attackStrength; + /* 0x01C7 */ u8 swordType; + /* 0x01C8 */ u8 chargeAlpha; + /* 0x01C9 */ u8 targetScale; + /* 0x01CA */ u8 isUsingMagic; } EnMThunder; // size = 0x01CC #endif diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index 91f3c6ab74..925c90a7f9 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -18,15 +18,15 @@ void EnMa1_Update(Actor* thisx, PlayState* play); void EnMa1_Draw(Actor* thisx, PlayState* play); u16 EnMa1_GetText(PlayState* play, Actor* this); -s16 func_80AA0778(PlayState* play, Actor* this); +s16 EnMa1_UpdateTalkState(PlayState* play, Actor* this); -void func_80AA0D88(EnMa1* this, PlayState* play); -void func_80AA0EA0(EnMa1* this, PlayState* play); -void func_80AA0EFC(EnMa1* this, PlayState* play); -void func_80AA0F44(EnMa1* this, PlayState* play); -void func_80AA106C(EnMa1* this, PlayState* play); -void func_80AA10EC(EnMa1* this, PlayState* play); -void func_80AA1150(EnMa1* this, PlayState* play); +void EnMa1_Idle(EnMa1* this, PlayState* play); +void EnMa1_GiveWeirdEgg(EnMa1* this, PlayState* play); +void EnMa1_FinishGivingWeirdEgg(EnMa1* this, PlayState* play); +void EnMa1_IdleTeachSong(EnMa1* this, PlayState* play); +void EnMa1_StartTeachSong(EnMa1* this, PlayState* play); +void EnMa1_TeachSong(EnMa1* this, PlayState* play); +void EnMa1_WaitForPlayback(EnMa1* this, PlayState* play); void EnMa1_DoNothing(EnMa1* this, PlayState* play); const ActorInit En_Ma1_InitVars = { @@ -131,7 +131,7 @@ u16 EnMa1_GetText(PlayState* play, Actor* thisx) { return 0x2041; } -s16 func_80AA0778(PlayState* play, Actor* thisx) { +s16 EnMa1_UpdateTalkState(PlayState* play, Actor* thisx) { s16 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { @@ -188,7 +188,7 @@ s16 func_80AA0778(PlayState* play, Actor* thisx) { return ret; } -s32 func_80AA08C4(EnMa1* this, PlayState* play) { +s32 EnMa1_ShouldSpawn(EnMa1* this, PlayState* play) { bool malonReturnedFromCastle = GameInteractor_Should(VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)); @@ -240,7 +240,7 @@ void EnMa1_ChangeAnim(EnMa1* this, s32 index) { sAnimationInfo[index].mode, sAnimationInfo[index].morphFrames); } -void func_80AA0AF4(EnMa1* this, PlayState* play) { +void EnMa1_UpdateTracking(EnMa1* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 trackingMode; @@ -256,16 +256,16 @@ void func_80AA0AF4(EnMa1* this, PlayState* play) { Npc_TrackPoint(&this->actor, &this->interactInfo, 0, trackingMode); } -void func_80AA0B74(EnMa1* this) { +void EnMa1_UpdateSinging(EnMa1* this) { if (this->skelAnime.animation == &gMalonChildSingAnim) { if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { - if (this->unk_1E0 != 0) { - this->unk_1E0 = 0; + if (this->singingDisabled != 0) { + this->singingDisabled = 0; func_800F6584(0); } } else { - if (this->unk_1E0 == 0) { - this->unk_1E0 = 1; + if (this->singingDisabled == 0) { + this->singingDisabled = 1; func_800F6584(1); } } @@ -286,7 +286,7 @@ void EnMa1_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(22), &sColChkInfoInit); - if (!func_80AA08C4(this, play)) { + if (!EnMa1_ShouldSpawn(this, play)) { Actor_Kill(&this->actor); return; } @@ -297,10 +297,10 @@ void EnMa1_Init(Actor* thisx, PlayState* play) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; if (!malonReturnedFromCastle || malonTaughtEponasSong) { - this->actionFunc = func_80AA0D88; + this->actionFunc = EnMa1_Idle; EnMa1_ChangeAnim(this, ENMA1_ANIM_2); } else { - this->actionFunc = func_80AA0F44; + this->actionFunc = EnMa1_IdleTeachSong; EnMa1_ChangeAnim(this, ENMA1_ANIM_2); } } @@ -312,7 +312,7 @@ void EnMa1_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->collider); } -void func_80AA0D88(EnMa1* this, PlayState* play) { +void EnMa1_Idle(EnMa1* this, PlayState* play) { bool malonReturnedFromCastle = GameInteractor_Should(VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)); bool malonTaughtEponasSong = @@ -334,33 +334,33 @@ void func_80AA0D88(EnMa1* this, PlayState* play) { } } else if (!malonReturnedFromCastle || malonTaughtEponasSong) { if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { - this->actionFunc = func_80AA0EA0; + this->actionFunc = EnMa1_GiveWeirdEgg; play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; } } } -void func_80AA0EA0(EnMa1* this, PlayState* play) { +void EnMa1_GiveWeirdEgg(EnMa1* this, PlayState* play) { if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_WEIRD_EGG, true)) { this->actor.parent = NULL; - this->actionFunc = func_80AA0EFC; + this->actionFunc = EnMa1_FinishGivingWeirdEgg; } else { Actor_OfferGetItem(&this->actor, play, GI_WEIRD_EGG, 120.0f, 10.0f); } } -void func_80AA0EFC(EnMa1* this, PlayState* play) { +void EnMa1_FinishGivingWeirdEgg(EnMa1* this, PlayState* play) { if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN || !GameInteractor_Should(VB_GIVE_ITEM_WEIRD_EGG, true)) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - this->actionFunc = func_80AA0D88; + this->actionFunc = EnMa1_Idle; Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; } } -void func_80AA0F44(EnMa1* this, PlayState* play) { +void EnMa1_IdleTeachSong(EnMa1* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { @@ -381,32 +381,32 @@ void func_80AA0F44(EnMa1* this, PlayState* play) { Message_StartTextbox(play, this->actor.textId, NULL); this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actor.flags |= ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; - this->actionFunc = func_80AA106C; + this->actionFunc = EnMa1_StartTeachSong; } else if (this->actor.xzDistToPlayer < 30.0f + (f32)this->collider.dim.radius) { player->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; } } } -void func_80AA106C(EnMa1* this, PlayState* play) { +void EnMa1_StartTeachSong(EnMa1* this, PlayState* play) { GET_PLAYER(play)->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { Audio_OcaSetInstrument(2); func_8010BD58(play, OCARINA_ACTION_TEACH_EPONA); this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; - this->actionFunc = func_80AA10EC; + this->actionFunc = EnMa1_TeachSong; } } -void func_80AA10EC(EnMa1* this, PlayState* play) { +void EnMa1_TeachSong(EnMa1* this, PlayState* play) { GET_PLAYER(play)->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; if (Message_GetState(&play->msgCtx) == TEXT_STATE_SONG_DEMO_DONE) { func_8010BD58(play, OCARINA_ACTION_PLAYBACK_EPONA); - this->actionFunc = func_80AA1150; + this->actionFunc = EnMa1_WaitForPlayback; } } -void func_80AA1150(EnMa1* this, PlayState* play) { +void EnMa1_WaitForPlayback(EnMa1* this, PlayState* play) { GET_PLAYER(play)->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { @@ -433,10 +433,10 @@ void EnMa1_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->actionFunc != EnMa1_DoNothing) { Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, (f32)this->collider.dim.radius + 30.0f, - EnMa1_GetText, func_80AA0778); + EnMa1_GetText, EnMa1_UpdateTalkState); } - func_80AA0B74(this); - func_80AA0AF4(this, play); + EnMa1_UpdateSinging(this); + EnMa1_UpdateTracking(this, play); } s32 EnMa1_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h index f06f220c9d..a79e53f5d9 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h @@ -13,14 +13,14 @@ typedef struct EnMa1 { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnMa1ActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ s16 unk_1E0; + /* 0x01E0 */ s16 singingDisabled; /* 0x01E2 */ s16 blinkTimer; /* 0x01E4 */ s16 eyeIndex; /* 0x01E6 */ s16 mouthIndex; /* 0x01E8 */ NpcInteractInfo interactInfo; } EnMa1; // size = 0x0210 -void func_80AA106C(EnMa1* enMa1, PlayState* play); -void func_80AA0D88(EnMa1* enMa1, PlayState* play); +void EnMa1_StartTeachSong(EnMa1* enMa1, PlayState* play); +void EnMa1_Idle(EnMa1* enMa1, PlayState* play); #endif diff --git a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c index 23707c6c96..efd8e61b66 100644 --- a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c +++ b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c @@ -10,17 +10,17 @@ void EnMa2_Destroy(Actor* thisx, PlayState* play); void EnMa2_Update(Actor* thisx, PlayState* play); void EnMa2_Draw(Actor* thisx, PlayState* play); -u16 func_80AA19A0(PlayState* play, Actor* this); -s16 func_80AA1A38(PlayState* play, Actor* this); +u16 EnMa2_GetTextId(PlayState* play, Actor* this); +s16 EnMa2_UpdateTalkState(PlayState* play, Actor* this); -void func_80AA1AE4(EnMa2* this, PlayState* play); -s32 func_80AA1C68(EnMa2* this); +void EnMa2_UpdateTracking(EnMa2* this, PlayState* play); +s32 EnMa2_IsSinging(EnMa2* this); void EnMa2_UpdateEyes(EnMa2* this); -void func_80AA1DB4(EnMa2* this, PlayState* play); -void func_80AA2018(EnMa2* this, PlayState* play); -void func_80AA204C(EnMa2* this, PlayState* play); -void func_80AA20E4(EnMa2* this, PlayState* play); -void func_80AA21C8(EnMa2* this, PlayState* play); +void EnMa2_UpdateSinging(EnMa2* this, PlayState* play); +void EnMa2_WaitToEndTalk(EnMa2* this, PlayState* play); +void EnMa2_WaitForOcarina(EnMa2* this, PlayState* play); +void EnMa2_WaitForEponasSong(EnMa2* this, PlayState* play); +void EnMa2_ForceTalkAfterSong(EnMa2* this, PlayState* play); const ActorInit En_Ma2_InitVars = { ACTOR_EN_MA2, @@ -71,7 +71,7 @@ static AnimationFrameCountInfo sAnimationInfo[] = { { &gMalonAdultSingAnim, 1.0f, ANIMMODE_LOOP, -10.0f }, }; -u16 func_80AA19A0(PlayState* play, Actor* thisx) { +u16 EnMa2_GetTextId(PlayState* play, Actor* thisx) { u16 faceReaction = Text_GetFaceReaction(play, 23); if (faceReaction != 0) { @@ -92,7 +92,7 @@ u16 func_80AA19A0(PlayState* play, Actor* thisx) { return 0x204C; } -s16 func_80AA1A38(PlayState* play, Actor* thisx) { +s16 EnMa2_UpdateTalkState(PlayState* play, Actor* thisx) { s16 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { @@ -124,7 +124,7 @@ s16 func_80AA1A38(PlayState* play, Actor* thisx) { return ret; } -void func_80AA1AE4(EnMa2* this, PlayState* play) { +void EnMa2_UpdateTracking(EnMa2* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 trackingMode; @@ -140,7 +140,7 @@ void func_80AA1AE4(EnMa2* this, PlayState* play) { Npc_TrackPoint(&this->actor, &this->interactInfo, 0, trackingMode); } -u16 func_80AA1B58(EnMa2* this, PlayState* play) { +u16 EnMa2_GetSpawnIndex(EnMa2* this, PlayState* play) { if (LINK_IS_CHILD) { return 0; } @@ -164,7 +164,7 @@ u16 func_80AA1B58(EnMa2* this, PlayState* play) { return 0; } -s32 func_80AA1C68(EnMa2* this) { +s32 EnMa2_IsSinging(EnMa2* this) { if (this->skelAnime.animation != &gMalonAdultSingAnim) { return 0; } @@ -180,7 +180,7 @@ s32 func_80AA1C68(EnMa2* this) { } void EnMa2_UpdateEyes(EnMa2* this) { - if ((!func_80AA1C68(this)) && (DECR(this->blinkTimer) == 0)) { + if ((!EnMa2_IsSinging(this)) && (DECR(this->blinkTimer) == 0)) { this->eyeIndex += 1; if (this->eyeIndex >= 3) { this->blinkTimer = Rand_S16Offset(30, 30); @@ -196,17 +196,17 @@ void EnMa2_ChangeAnim(EnMa2* this, s32 index) { sAnimationInfo[index].mode, sAnimationInfo[index].morphFrames); } -void func_80AA1DB4(EnMa2* this, PlayState* play) { +void EnMa2_UpdateSinging(EnMa2* this, PlayState* play) { if (this->skelAnime.animation == &gMalonAdultSingAnim) { if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { - if (this->unk_20A != 0) { + if (this->singingDisabled != 0) { func_800F6584(0); - this->unk_20A = 0; + this->singingDisabled = 0; } } else { - if (this->unk_20A == 0) { + if (this->singingDisabled == 0) { func_800F6584(1); - this->unk_20A = 1; + this->singingDisabled = 1; } } } @@ -222,14 +222,14 @@ void EnMa2_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(22), &sColChkInfoInit); - switch (func_80AA1B58(this, play)) { + switch (EnMa2_GetSpawnIndex(this, play)) { case 1: EnMa2_ChangeAnim(this, ENMA2_ANIM_2); - this->actionFunc = func_80AA2018; + this->actionFunc = EnMa2_WaitToEndTalk; break; case 2: EnMa2_ChangeAnim(this, ENMA2_ANIM_3); - this->actionFunc = func_80AA204C; + this->actionFunc = EnMa2_WaitForOcarina; break; case 3: if (Flags_GetInfTable(INFTABLE_8D)) { @@ -237,7 +237,7 @@ void EnMa2_Init(Actor* thisx, PlayState* play) { } else { EnMa2_ChangeAnim(this, ENMA2_ANIM_3); } - this->actionFunc = func_80AA2018; + this->actionFunc = EnMa2_WaitToEndTalk; break; case 0: Actor_Kill(&this->actor); @@ -257,48 +257,48 @@ void EnMa2_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->collider); } -void func_80AA2018(EnMa2* this, PlayState* play) { +void EnMa2_WaitToEndTalk(EnMa2* this, PlayState* play) { if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } } -void func_80AA204C(EnMa2* this, PlayState* play) { +void EnMa2_WaitForOcarina(EnMa2* this, PlayState* play) { Player* player = GET_PLAYER(play); if (player->stateFlags2 & PLAYER_STATE2_ATTEMPT_PLAY_FOR_ACTOR) { player->unk_6A8 = &this->actor; player->stateFlags2 |= PLAYER_STATE2_PLAY_FOR_ACTOR; func_8010BD58(play, OCARINA_ACTION_CHECK_EPONA); - this->actionFunc = func_80AA20E4; + this->actionFunc = EnMa2_WaitForEponasSong; } else if (this->actor.xzDistToPlayer < 30.0f + (f32)this->collider.dim.radius) { player->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; } } -void func_80AA20E4(EnMa2* this, PlayState* play) { +void EnMa2_WaitForEponasSong(EnMa2* this, PlayState* play) { Player* player = GET_PLAYER(play); if (play->msgCtx.ocarinaMode >= OCARINA_MODE_04) { - this->actionFunc = func_80AA204C; + this->actionFunc = EnMa2_WaitForOcarina; play->msgCtx.ocarinaMode = OCARINA_MODE_04; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - this->unk_208 = 0x1E; + this->timer = 0x1E; Flags_SetInfTable(INFTABLE_8E); - this->actionFunc = func_80AA21C8; + this->actionFunc = EnMa2_ForceTalkAfterSong; play->msgCtx.ocarinaMode = OCARINA_MODE_04; } else { player->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; } } -void func_80AA21C8(EnMa2* this, PlayState* play) { +void EnMa2_ForceTalkAfterSong(EnMa2* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (DECR(this->unk_208)) { + if (DECR(this->timer)) { player->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; } else { if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { @@ -306,7 +306,7 @@ void func_80AA21C8(EnMa2* this, PlayState* play) { Message_CloseTextbox(play); } else { this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; - this->actionFunc = func_80AA2018; + this->actionFunc = EnMa2_WaitToEndTalk; } } } @@ -320,11 +320,11 @@ void EnMa2_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); EnMa2_UpdateEyes(this); this->actionFunc(this, play); - func_80AA1DB4(this, play); - func_80AA1AE4(this, play); - if (this->actionFunc != func_80AA20E4) { + EnMa2_UpdateSinging(this, play); + EnMa2_UpdateTracking(this, play); + if (this->actionFunc != EnMa2_WaitForEponasSong) { Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, (f32)this->collider.dim.radius + 30.0f, - func_80AA19A0, func_80AA1A38); + EnMa2_GetTextId, EnMa2_UpdateTalkState); } } @@ -349,8 +349,8 @@ s32 EnMa2_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p } if ((limbIndex == MALON_ADULT_CHEST_AND_NECK_LIMB) || (limbIndex == MALON_ADULT_LEFT_SHOULDER_LIMB) || (limbIndex == MALON_ADULT_RIGHT_SHOULDER_LIMB)) { - rot->y += Math_SinS(this->unk_212[limbIndex].y) * 200.0f; - rot->z += Math_CosS(this->unk_212[limbIndex].z) * 200.0f; + rot->y += Math_SinS(this->upperBodyRot[limbIndex].y) * 200.0f; + rot->z += Math_CosS(this->upperBodyRot[limbIndex].z) * 200.0f; } return false; } diff --git a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h index 20f0cd6deb..53b77613e1 100644 --- a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h +++ b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h @@ -37,12 +37,12 @@ typedef struct EnMa2 { /* 0x0190 */ EnMa2ActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; /* 0x01E0 */ NpcInteractInfo interactInfo; - /* 0x0208 */ s16 unk_208; - /* 0x020A */ s16 unk_20A; + /* 0x0208 */ s16 timer; + /* 0x020A */ s16 singingDisabled; /* 0x020C */ s16 blinkTimer; /* 0x020E */ s16 eyeIndex; /* 0x0210 */ s16 mouthIndex; - /* 0x0212 */ Vec3s unk_212[MALON_ADULT_LIMB_MAX]; + /* 0x0212 */ Vec3s upperBodyRot[MALON_ADULT_LIMB_MAX]; } EnMa2; // size = 0x0284 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c index 9238c42df4..9bc0418b4b 100644 --- a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c +++ b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c @@ -16,8 +16,8 @@ void EnMa3_Destroy(Actor* thisx, PlayState* play); void EnMa3_Update(Actor* thisx, PlayState* play); void EnMa3_Draw(Actor* thisx, PlayState* play); -u16 func_80AA2AA0(PlayState* play, Actor* this); -s16 func_80AA2BD4(PlayState* play, Actor* this); +u16 EnMa3_GetTextId(PlayState* play, Actor* this); +s16 EnMa3_UpdateTalkState(PlayState* play, Actor* this); void func_80AA2E54(EnMa3* this, PlayState* play); s32 func_80AA2EC8(EnMa3* this, PlayState* play); @@ -74,7 +74,7 @@ static AnimationFrameCountInfo sAnimationInfo[] = { { &gMalonAdultSingAnim, 1.0f, ANIMMODE_LOOP, -10.0f }, }; -u16 func_80AA2AA0(PlayState* play, Actor* thisx) { +u16 EnMa3_GetTextId(PlayState* play, Actor* thisx) { Player* player = GET_PLAYER(play); s16* timerSecondsPtr; // weirdness with this necessary to match @@ -111,7 +111,7 @@ u16 func_80AA2AA0(PlayState* play, Actor* thisx) { } } -s16 func_80AA2BD4(PlayState* play, Actor* thisx) { +s16 EnMa3_UpdateTalkState(PlayState* play, Actor* thisx) { s16 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { @@ -295,15 +295,15 @@ void EnMa3_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); func_80AA2E54(this, play); Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, (f32)this->collider.dim.radius + 150.0f, - func_80AA2AA0, func_80AA2BD4); + EnMa3_GetTextId, EnMa3_UpdateTalkState); if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { - if (this->unk_20A != 0) { + if (this->isNotSinging != 0) { func_800F6584(0); - this->unk_20A = 0; + this->isNotSinging = 0; } - } else if (this->unk_20A == 0) { + } else if (this->isNotSinging == 0) { func_800F6584(1); - this->unk_20A = 1; + this->isNotSinging = 1; } } diff --git a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h index 7500379056..1f3ec2ed81 100644 --- a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h +++ b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h @@ -38,7 +38,7 @@ typedef struct EnMa3 { /* 0x0194 */ ColliderCylinder collider; /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ s16 unk_208; - /* 0x020A */ s16 unk_20A; + /* 0x020A */ s16 isNotSinging; /* 0x020C */ s16 blinkTimer; /* 0x020E */ s16 eyeIndex; /* 0x0210 */ s16 mouthIndex; diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index 13b51a16ec..68b43078e5 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -682,7 +682,7 @@ void EnMd_Destroy(Actor* thisx, PlayState* play) { void EnMd_Idle(EnMd* this, PlayState* play) { if (this->skelAnime.animation == &gMidoHandsOnHipsIdleAnim) { - func_80034F54(play, this->unk_214, this->unk_236, 17); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 17); } else if ((this->interactInfo.talkState == NPC_TALK_STATE_IDLE) && (this->animSequence != 7)) { EnMd_SetAnimSequence(this, 7); } @@ -692,7 +692,7 @@ void EnMd_Idle(EnMd* this, PlayState* play) { void EnMd_Watch(EnMd* this, PlayState* play) { if (this->skelAnime.animation == &gMidoHandsOnHipsIdleAnim) { - func_80034F54(play, this->unk_214, this->unk_236, 17); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 17); } EnMd_UpdateAnimSequence(this); } @@ -748,7 +748,7 @@ void EnMd_BlockPath(EnMd* this, PlayState* play) { } if (this->skelAnime.animation == &gMidoHandsOnHipsIdleAnim) { - func_80034F54(play, this->unk_214, this->unk_236, 17); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 17); } if ((this->interactInfo.talkState == NPC_TALK_STATE_IDLE) && (play->sceneNum == SCENE_LOST_WOODS)) { @@ -786,7 +786,7 @@ void EnMd_ListenToOcarina(EnMd* this, PlayState* play) { } void EnMd_Walk(EnMd* this, PlayState* play) { - func_80034F54(play, this->unk_214, this->unk_236, 17); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 17); EnMd_UpdateAnimSequence(this); if (!(EnMd_FollowPath(this, play)) || (this->waypoint != 0)) { @@ -844,8 +844,8 @@ s32 EnMd_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po } if (((limbIndex == 9) || (limbIndex == 10)) || (limbIndex == 13)) { - rot->y += Math_SinS(this->unk_214[limbIndex]) * 200.0f; - rot->z += Math_CosS(this->unk_236[limbIndex]) * 200.0f; + rot->y += Math_SinS(this->fidgetTableY[limbIndex]) * 200.0f; + rot->z += Math_CosS(this->fidgetTableZ[limbIndex]) * 200.0f; } return false; diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.h b/soh/src/overlays/actors/ovl_En_Md/z_en_md.h index 4d4962acc8..8412b4a3ff 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.h +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.h @@ -22,8 +22,8 @@ typedef struct EnMd { /* 0x020E */ s16 eyeIdx; /* 0x0210 */ s16 alpha; /* 0x0212 */ s16 waypoint; - /* 0x0214 */ s16 unk_214[17]; - /* 0x0236 */ s16 unk_236[17]; + /* 0x0214 */ s16 fidgetTableY[17]; + /* 0x0236 */ s16 fidgetTableZ[17]; /* 0x0258 */ Vec3s jointTable[17]; /* 0x02BE */ Vec3s morphTable[17]; } EnMd; // size = 0x0324 diff --git a/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c b/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c index 614b88a709..86351c7dd0 100644 --- a/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c +++ b/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c @@ -149,7 +149,7 @@ void EnMu_Destroy(Actor* thisx, PlayState* play) { } void EnMu_Pose(EnMu* this, PlayState* play) { - func_80034F54(play, this->unk_20A, this->unk_22A, 16); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 16); } void EnMu_Update(Actor* thisx, PlayState* play) { @@ -181,8 +181,8 @@ s32 EnMu_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po if ((limbIndex == 5) || (limbIndex == 6) || (limbIndex == 7) || (limbIndex == 11) || (limbIndex == 12) || (limbIndex == 13) || (limbIndex == 14)) { - rot->y += Math_SinS(this->unk_20A[limbIndex]) * 200.0f; - rot->z += Math_CosS(this->unk_22A[limbIndex]) * 200.0f; + rot->y += Math_SinS(this->fidgetTableY[limbIndex]) * 200.0f; + rot->z += Math_CosS(this->fidgetTableZ[limbIndex]) * 200.0f; } return false; } diff --git a/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h b/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h index b1d7995598..e8a84566a6 100644 --- a/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h +++ b/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h @@ -15,8 +15,8 @@ typedef struct EnMu { /* 0x0194 */ ColliderCylinder collider; /* 0x01E0 */ NpcInteractInfo npcInfo; /* 0x0208 */ u16 defFaceReaction; - /* 0x020A */ s16 unk_20A[16]; - /* 0x022A */ s16 unk_22A[17]; + /* 0x020A */ s16 fidgetTableY[16]; + /* 0x022A */ s16 fidgetTableZ[17]; } EnMu; // size = 0x024C #endif diff --git a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c index 84da935d67..54ec62d96b 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c @@ -212,12 +212,12 @@ void EnNiwGirl_Update(Actor* thisx, PlayState* play) { this->interactInfo.trackPos.y = player->actor.world.pos.y - 10.0f; } Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); - this->unk_260 = this->interactInfo.headRot; - this->unk_266 = this->interactInfo.torsoRot; + this->headRot = this->interactInfo.headRot; + this->torsoRot = this->interactInfo.torsoRot; } else { - Math_SmoothStepToS(&this->unk_266.y, 0, 5, 3000, 0); - Math_SmoothStepToS(&this->unk_260.y, 0, 5, 3000, 0); - Math_SmoothStepToS(&this->unk_260.z, 0, 5, 3000, 0); + Math_SmoothStepToS(&this->torsoRot.y, 0, 5, 3000, 0); + Math_SmoothStepToS(&this->headRot.y, 0, 5, 3000, 0); + Math_SmoothStepToS(&this->headRot.z, 0, 5, 3000, 0); } if (this->blinkTimer != 0) { this->blinkTimer--; @@ -236,11 +236,11 @@ s32 EnNiwGirlOverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f EnNiwGirl* this = (EnNiwGirl*)thisx; if (limbIndex == 3) { - rot->x += this->unk_266.y; + rot->x += this->torsoRot.y; } if (limbIndex == 4) { - rot->x += this->unk_260.y; - rot->z += this->unk_260.z; + rot->x += this->headRot.y; + rot->z += this->headRot.z; } return false; } diff --git a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.h b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.h index 812f1d88ea..1facb4c385 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.h +++ b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.h @@ -15,8 +15,8 @@ typedef struct EnNiwGirl { /* 0x0190 */ Vec3s jointTable[17]; /* 0x01F6 */ Vec3s morphTable[17]; /* 0x025C */ EnNiwGirlActionFunc actionFunc; - /* 0x0260 */ Vec3s unk_260; - /* 0x0266 */ Vec3s unk_266; + /* 0x0260 */ Vec3s headRot; + /* 0x0266 */ Vec3s torsoRot; /* 0x026C */ s16 jumpTimer; // Controls how many frames she jumps for and how long until she jumps again /* 0x026E */ s16 unkUpTimer; /* 0x0270 */ s16 unk_270; diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 4e204fac5d..09ac1e057e 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -518,10 +518,10 @@ void EnNiwLady_Update(Actor* thisx, PlayState* play) { this->interactInfo.trackPos.y = player->actor.world.pos.y - 10.0f; } Npc_TrackPoint(thisx, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); - this->unk_254 = this->interactInfo.headRot; - this->unk_25A = this->interactInfo.torsoRot; + this->headRot = this->interactInfo.headRot; + this->torsoRot = this->interactInfo.torsoRot; if (this->unk_276 == 0) { - Math_SmoothStepToS(&this->unk_254.y, 0, 5, 3000, 0); + Math_SmoothStepToS(&this->headRot.y, 0, 5, 3000, 0); } gSegments[6] = VIRTUAL_TO_PHYSICAL(play->objectCtx.status[this->objectOsAnimeIndex].segment); if (this->objectOsAnimeIndex >= 0) { @@ -570,11 +570,11 @@ s32 EnNiwLady_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3 s32 pad; if (limbIndex == 15) { - rot->x += this->unk_254.y; - rot->z += this->unk_254.x; + rot->x += this->headRot.y; + rot->z += this->headRot.x; } if (limbIndex == 8) { - rot->x += this->unk_25A.y; + rot->x += this->torsoRot.y; } if (this->unk_275 != 0) { if ((limbIndex == 8) || (limbIndex == 10) || (limbIndex == 13)) { diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h index 0105605934..db1f1a3710 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h @@ -14,8 +14,8 @@ typedef struct EnNiwLady { /* 0x0190 */ Vec3s jointTable[16]; /* 0x01F0 */ Vec3s morphTable[16]; /* 0x0250 */ EnNiwLadyActionFunc actionFunc; - /* 0x0254 */ Vec3s unk_254; - /* 0x025A */ Vec3s unk_25A; + /* 0x0254 */ Vec3s headRot; + /* 0x025A */ Vec3s torsoRot; /* 0x0260 */ s16 unusedTimer; /* 0x0262 */ s16 unk_262; // "message_end_code" /* 0x0264 */ s16 unusedTimer2; diff --git a/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h b/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h index 5b608ad065..25613720f2 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h +++ b/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h @@ -33,7 +33,7 @@ typedef struct EnPoField { /* 0x019C */ Vec3s jointTable[10]; /* 0x01D8 */ Vec3s morphTable[10]; /* 0x0214 */ Color_RGBA8 lightColor; - /* 0x0214 */ Color_RGBA8 soulColor; + /* 0x0218 */ Color_RGBA8 soulColor; /* 0x021C */ f32 scaleModifier; /* 0x0220 */ f32 flameScale; /* 0x0224 */ Vec3f flamePosition; diff --git a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c index 119f10de6f..95332dd7ed 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c +++ b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c @@ -126,7 +126,7 @@ void EnPoRelay_Destroy(Actor* thisx, PlayState* play) { } void EnPoRelay_SetupIdle(EnPoRelay* this) { - this->unk_195 = 32; + this->bobTimer = 32; this->pathIndex = 0; this->actor.room = -1; this->actor.shape.rot.y = 0; @@ -149,7 +149,7 @@ void EnPoRelay_SetupRace(EnPoRelay* this) { Interface_SetTimer(0); this->hookshotSlotFull = (INV_CONTENT(ITEM_HOOKSHOT) != ITEM_NONE && !IS_RANDO) || (IS_RANDO && Flags_GetTreasure(gPlayState, 0x1E)); - this->unk_19A = Actor_WorldYawTowardPoint(&this->actor, &vec); + this->yawTowardsPathPoint = Actor_WorldYawTowardPoint(&this->actor, &vec); this->actor.flags |= ACTOR_FLAG_LOCK_ON_DISABLED; Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); this->actionFunc = EnPoRelay_Race; @@ -164,7 +164,7 @@ void EnPoRelay_SetupEndRace(EnPoRelay* this) { void EnPoRelay_CorrectY(EnPoRelay* this) { Math_StepToF(&this->actor.home.pos.y, D_80AD8C30[(this->pathIndex >= 28) ? 27 : this->pathIndex].y + 45.0f, 2.0f); - this->actor.world.pos.y = Math_SinS(this->unk_195 * 0x800) * 8.0f + this->actor.home.pos.y; + this->actor.world.pos.y = Math_SinS(this->bobTimer * 0x800) * 8.0f + this->actor.home.pos.y; } void EnPoRelay_Idle(EnPoRelay* this, PlayState* play) { @@ -213,12 +213,12 @@ void EnPoRelay_Race(EnPoRelay* this, PlayState* play) { speed = 30.0f * multiplier; Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HONOTRAP, - Math_CosS(this->unk_19A) * speed + this->actor.world.pos.x, this->actor.world.pos.y, - Math_SinS(this->unk_19A) * speed + this->actor.world.pos.z, 0, - (this->unk_19A + 0x8000) - (0x2000 * multiplier), 0, HONOTRAP_FLAME_DROP); + Math_CosS(this->yawTowardsPathPoint) * speed + this->actor.world.pos.x, this->actor.world.pos.y, + Math_SinS(this->yawTowardsPathPoint) * speed + this->actor.world.pos.z, 0, + (this->yawTowardsPathPoint + 0x8000) - (0x2000 * multiplier), 0, HONOTRAP_FLAME_DROP); } } - Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_19A, 2, 0x1000, 0x100); + Math_SmoothStepToS(&this->actor.world.rot.y, this->yawTowardsPathPoint, 2, 0x1000, 0x100); this->actor.shape.rot.y = this->actor.world.rot.y + (this->actionTimer * 0x800) + 0x8000; if (this->pathIndex < 23) { // If the player travels along a different path to Dampé that converges later @@ -264,7 +264,7 @@ void EnPoRelay_Race(EnPoRelay* this, PlayState* play) { Flags_SetSwitch(play, 0x37); } } - this->unk_19A = Actor_WorldYawTowardPoint(&this->actor, &vec); + this->yawTowardsPathPoint = Actor_WorldYawTowardPoint(&this->actor, &vec); func_8002F974(&this->actor, NA_SE_EN_PO_AWAY - SFX_FLAG); } @@ -394,11 +394,11 @@ void EnPoRelay_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); Actor_SetFocus(&this->actor, 50.0f); - if (this->unk_195 != 0) { - this->unk_195 -= 1; + if (this->bobTimer != 0) { + this->bobTimer -= 1; } - if (this->unk_195 == 0) { - this->unk_195 = 32; + if (this->bobTimer == 0) { + this->bobTimer = 32; } this->eyeTextureIdx++; if (this->eyeTextureIdx == 3) { diff --git a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h index bfc76cef98..d3478e0e70 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h +++ b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h @@ -13,10 +13,10 @@ typedef struct EnPoRelay { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnPoRelayActionFunc actionFunc; /* 0x0194 */ u8 hookshotSlotFull; - /* 0x0195 */ u8 unk_195; + /* 0x0195 */ u8 bobTimer; /* 0x0196 */ s16 actionTimer; /* 0x0198 */ s16 pathIndex; - /* 0x019A */ s16 unk_19A; + /* 0x019A */ s16 yawTowardsPathPoint; /* 0x019C */ u16 textId; /* 0x019E */ u16 eyeTextureIdx; /* 0x01A0 */ Vec3s jointTable[18]; diff --git a/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.h b/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.h index e0d2e7a8f5..33f96c929c 100644 --- a/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.h +++ b/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.h @@ -24,7 +24,7 @@ typedef struct { /* 0x0000 */ Color_RGB8 primColor; /* 0x0003 */ Color_RGB8 lightColor; /* 0x0006 */ u8 unk_6; // limb index - /* 0x0006 */ u8 unk_7; // limb index + /* 0x0007 */ u8 unk_7; // limb index /* 0x0008 */ s8 unk_8; // rate of some kind /* 0x000C */ AnimationHeader* idleAnim; /* 0x0010 */ AnimationHeader* idleAnim2; diff --git a/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c b/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c index a27b3b5b13..da1cb631de 100644 --- a/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c +++ b/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c @@ -46,7 +46,7 @@ void EnPubox_Init(Actor* thisx, PlayState* play) { default: break; } - this->unk_164 = 1; + this->unused_164 = 1; thisx->colChkInfo.cylRadius = 20; thisx->colChkInfo.cylHeight = 50; thisx->uncullZoneDownward = 1200.0f; diff --git a/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.h b/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.h index fe5c865486..f4ede4e855 100644 --- a/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.h +++ b/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.h @@ -8,7 +8,7 @@ struct EnPubox; typedef struct EnPubox { /* 0x0000 */ DynaPolyActor dyna; - /* 0x0164 */ u32 unk_164; + /* 0x0164 */ u32 unused_164; } EnPubox; // size = 0x0168 #endif diff --git a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c index 062be3268d..5482f38f69 100644 --- a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c +++ b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c @@ -12,26 +12,26 @@ void EnRd_Destroy(Actor* thisx, PlayState* play); void EnRd_Update(Actor* thisx, PlayState* play); void EnRd_Draw(Actor* thisx, PlayState* play); -void func_80AE269C(EnRd* this); -void func_80AE2744(EnRd* this, PlayState* play); -void func_80AE2970(EnRd* this); -void func_80AE2A10(EnRd* this, PlayState* play); -void func_80AE2C1C(EnRd* this, PlayState* play); -void func_80AE2F50(EnRd* this, PlayState* play); -void func_80AE2FD0(EnRd* this, PlayState* play); -void func_80AE31DC(EnRd* this); -void func_80AE3260(EnRd* this, PlayState* play); -void func_80AE33F0(EnRd* this); -void func_80AE392C(EnRd* this); -void func_80AE39D4(EnRd* this); -void func_80AE3454(EnRd* this, PlayState* play); -void func_80AE37BC(EnRd* this); -void func_80AE3834(EnRd* this, PlayState* play); -void func_80AE3978(EnRd* this, PlayState* play); -void func_80AE3A54(EnRd* this, PlayState* play); -void func_80AE3B18(EnRd* this, PlayState* play); -void func_80AE3C98(EnRd* this, PlayState* play); -void func_80AE3ECC(EnRd* this, PlayState* play); +void EnRd_SetupIdle(EnRd* this); +void EnRd_Idle(EnRd* this, PlayState* play); +void EnRd_SetupRiseFromCoffin(EnRd* this); +void EnRd_RiseFromCoffin(EnRd* this, PlayState* play); +void EnRd_WalkToPlayer(EnRd* this, PlayState* play); +void EnRd_SetupWalkToHome(EnRd* this, PlayState* play); +void EnRd_WalkToHome(EnRd* this, PlayState* play); +void EnRd_SetupWalkToParent(EnRd* this); +void EnRd_WalkToParent(EnRd* this, PlayState* play); +void EnRd_SetupGrab(EnRd* this); +void EnRd_SetupStandUp(EnRd* this); +void EnRd_SetupCrouch(EnRd* this); +void EnRd_Grab(EnRd* this, PlayState* play); +void EnRd_SetupAttemptPlayerFreeze(EnRd* this); +void EnRd_AttemptPlayerFreeze(EnRd* this, PlayState* play); +void EnRd_StandUp(EnRd* this, PlayState* play); +void EnRd_Crouch(EnRd* this, PlayState* play); +void EnRd_Damaged(EnRd* this, PlayState* play); +void EnRd_Dead(EnRd* this, PlayState* play); +void EnRd_Stunned(EnRd* this, PlayState* play); const ActorInit En_Rd_InitVars = { ACTOR_EN_RD, @@ -132,13 +132,13 @@ void EnRd_Init(Actor* thisx, PlayState* play) { thisx->targetMode = 0; thisx->colChkInfo.damageTable = &sDamageTable; ActorShape_Init(&thisx->shape, 0.0f, NULL, 0.0f); - this->unk_310 = this->unk_30E = 0; + this->upperBodyYRotation = this->headYRotation = 0; thisx->focus.pos = thisx->world.pos; thisx->focus.pos.y += 50.0f; thisx->colChkInfo.mass = MASS_HEAVY; thisx->colChkInfo.health = 8; - this->unk_314 = this->unk_31D = 0xFF; - this->unk_312 = (thisx->params & 0xFF00) >> 8; + this->alpha = this->unk_31D = 0xFF; + this->rdFlags = (thisx->params & 0xFF00) >> 8; if (thisx->params & 0x80) { thisx->params |= 0xFF00; @@ -160,9 +160,9 @@ void EnRd_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->collider, thisx, &sCylinderInit); if (thisx->params >= -2) { - func_80AE269C(this); + EnRd_SetupIdle(this); } else { - func_80AE2970(this); + EnRd_SetupRiseFromCoffin(this); } SkelAnime_Update(&this->skelAnime); @@ -183,7 +183,7 @@ void EnRd_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -void func_80AE2630(PlayState* play, Actor* thisx, s32 arg2) { +void EnRd_UpdateMourningTarget(PlayState* play, Actor* thisx, s32 arg2) { Actor* enemyIt = play->actorCtx.actorLists[ACTORCAT_ENEMY].head; while (enemyIt != NULL) { @@ -201,24 +201,24 @@ void func_80AE2630(PlayState* play, Actor* thisx, s32 arg2) { } } -void func_80AE269C(EnRd* this) { +void EnRd_SetupIdle(EnRd* this) { if (this->actor.params != 2) { Animation_MorphToLoop(&this->skelAnime, &gGibdoRedeadIdleAnim, -6.0f); } else { Animation_PlayLoop(&this->skelAnime, &gGibdoRedeadSobbingAnim); } - this->unk_31B = 0; - this->unk_30C = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->action = 0; + this->timer = (Rand_ZeroOne() * 10.0f) + 5.0f; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; - EnRd_SetupAction(this, func_80AE2744); + EnRd_SetupAction(this, EnRd_Idle); } -void func_80AE2744(EnRd* this, PlayState* play) { +void EnRd_Idle(EnRd* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - Math_SmoothStepToS(&this->unk_30E, 0, 1, 0x64, 0); - Math_SmoothStepToS(&this->unk_310, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 0x64, 0); if ((this->actor.params == 2) && (0.0f == this->skelAnime.curFrame)) { if (Rand_ZeroOne() >= 0.5f) { @@ -227,31 +227,31 @@ void func_80AE2744(EnRd* this, PlayState* play) { Animation_PlayLoop(&this->skelAnime, &gGibdoRedeadWipingTearsAnim); } } else { - this->unk_30C--; - if (this->unk_30C == 0) { - this->unk_30C = (Rand_ZeroOne() * 10.0f) + 10.0f; + this->timer--; + if (this->timer == 0) { + this->timer = (Rand_ZeroOne() * 10.0f) + 10.0f; this->skelAnime.curFrame = 0.0f; } } if (this->actor.parent != NULL) { - if (this->unk_305 == 0) { + if (this->isMourning == 0) { if (this->actor.params != 2) { - func_80AE31DC(this); + EnRd_SetupWalkToParent(this); } else { - func_80AE392C(this); + EnRd_SetupStandUp(this); } } } else { - if (this->unk_305 != 0) { + if (this->isMourning != 0) { if (this->actor.params != 2) { - func_80AE37BC(this); + EnRd_SetupAttemptPlayerFreeze(this); } else { - func_80AE392C(this); + EnRd_SetupStandUp(this); } } - this->unk_305 = 0; + this->isMourning = 0; if (this->actor.xzDistToPlayer <= 150.0f && func_8002DDE4(play)) { // Add a height check to redeads/gibdos freeze when Enemy Randomizer is on. @@ -261,10 +261,10 @@ void func_80AE2744(EnRd* this, PlayState* play) { (CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("Enabled"), 0)); if (!enemyRandoCCActive || (enemyRandoCCActive && this->actor.yDistToPlayer <= 100.0f && this->actor.yDistToPlayer >= -100.0f)) { - if ((this->actor.params != 2) && (this->unk_305 == 0)) { - func_80AE37BC(this); + if ((this->actor.params != 2) && (this->isMourning == 0)) { + EnRd_SetupAttemptPlayerFreeze(this); } else { - func_80AE392C(this); + EnRd_SetupStandUp(this); } } } @@ -275,33 +275,33 @@ void func_80AE2744(EnRd* this, PlayState* play) { } } -void func_80AE2970(EnRd* this) { +void EnRd_SetupRiseFromCoffin(EnRd* this) { Animation_Change(&this->skelAnime, &gGibdoRedeadIdleAnim, 0, 0, Animation_GetLastFrame(&gGibdoRedeadIdleAnim), ANIMMODE_LOOP, -6.0f); - this->unk_31B = 11; - this->unk_30C = 6; + this->action = 11; + this->timer = 6; this->actor.shape.rot.x = -0x4000; this->actor.gravity = 0.0f; this->actor.shape.yOffset = 0.0f; this->actor.speedXZ = 0.0f; - EnRd_SetupAction(this, func_80AE2A10); + EnRd_SetupAction(this, EnRd_RiseFromCoffin); } // Rising out of coffin -void func_80AE2A10(EnRd* this, PlayState* play) { +void EnRd_RiseFromCoffin(EnRd* this, PlayState* play) { if (this->actor.shape.rot.x != -0x4000) { Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 1, 0x7D0, 0); if (Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 0.3f, 2.0f, 0.3f) == 0.0f) { this->actor.gravity = -3.5f; - func_80AE269C(this); + EnRd_SetupIdle(this); } } else { if (this->actor.world.pos.y == this->actor.home.pos.y) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); } if (Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y + 50.0f, 0.3f, 2.0f, 0.3f) == 0.0f) { - if (this->unk_30C != 0) { - this->unk_30C--; + if (this->timer != 0) { + this->timer--; Math_SmoothStepToF(&this->actor.speedXZ, 6.0f, 0.3f, 1.0f, 0.3f); } else if (Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.3f, 1.0f, 0.3f) == 0.0f) { Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 1, 0x7D0, 0); @@ -310,31 +310,31 @@ void func_80AE2A10(EnRd* this, PlayState* play) { } } -void func_80AE2B90(EnRd* this, PlayState* play) { +void EnRd_SetupWalkToPlayer(EnRd* this, PlayState* play) { Animation_Change(&this->skelAnime, &gGibdoRedeadWalkAnim, 1.0f, 4.0f, Animation_GetLastFrame(&gGibdoRedeadWalkAnim), ANIMMODE_LOOP_INTERP, -4.0f); this->actor.speedXZ = 0.4f; - this->unk_31B = 4; - EnRd_SetupAction(this, func_80AE2C1C); + this->action = 4; + EnRd_SetupAction(this, EnRd_WalkToPlayer); } -void func_80AE2C1C(EnRd* this, PlayState* play) { +void EnRd_WalkToPlayer(EnRd* this, PlayState* play) { Vec3f sp44 = D_80AE4918; Color_RGBA8 sp40 = D_80AE4924; Color_RGBA8 sp3C = D_80AE4928; Player* player = GET_PLAYER(play); s32 pad; - s16 sp32 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y - this->unk_30E - this->unk_310; + s16 sp32 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y - this->headYRotation - this->upperBodyYRotation; this->skelAnime.playSpeed = this->actor.speedXZ; Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 0xFA, 0); - Math_SmoothStepToS(&this->unk_30E, 0, 1, 0x64, 0); - Math_SmoothStepToS(&this->unk_310, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 0x64, 0); this->actor.world.rot.y = this->actor.shape.rot.y; SkelAnime_Update(&this->skelAnime); if (Actor_WorldDistXYZToPoint(&player->actor, &this->actor.home.pos) >= 150.0f) { - func_80AE2F50(this, play); + EnRd_SetupWalkToHome(this, play); } if ((ABS(sp32) < 0x1554) && (Actor_WorldDistXYZToActor(&this->actor, &player->actor) <= 150.0f)) { @@ -342,38 +342,38 @@ void func_80AE2C1C(EnRd* this, PlayState* play) { (PLAYER_STATE1_DEAD | PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_JUMPING | PLAYER_STATE1_FREEFALL | PLAYER_STATE1_CLIMBING_LADDER)) && !(player->stateFlags2 & PLAYER_STATE2_GRABBED_BY_ENEMY)) { - if (this->unk_306 == 0) { - if (!(this->unk_312 & PLAYER_STATE2_GRABBED_BY_ENEMY) && + if (this->playerStunWaitTimer == 0) { + if (!(this->rdFlags & PLAYER_STATE2_GRABBED_BY_ENEMY) && GameInteractor_Should(VB_REDEAD_GIBDO_FREEZE_LINK, true, this)) { player->actor.freezeTimer = 40; Player_SetAutoLockOnActor(play, &this->actor); GET_PLAYER(play)->autoLockOnActor = &this->actor; func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); } - this->unk_306 = 0x3C; + this->playerStunWaitTimer = 0x3C; Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); } } else { - func_80AE2F50(this, play); + EnRd_SetupWalkToHome(this, play); } } - if (this->unk_307 != 0) { - this->unk_307--; + if (this->grabWaitTimer != 0) { + this->grabWaitTimer--; } - if (!this->unk_307 && (Actor_WorldDistXYZToActor(&this->actor, &player->actor) <= 45.0f) && + if (!this->grabWaitTimer && (Actor_WorldDistXYZToActor(&this->actor, &player->actor) <= 45.0f) && Actor_IsFacingPlayer(&this->actor, 0x38E3)) { player->actor.freezeTimer = 0; if (play->grabPlayer(play, player)) { this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - func_80AE33F0(this); + EnRd_SetupGrab(this); } } else if (this->actor.params > 0) { if (this->actor.parent != NULL) { - func_80AE31DC(this); + EnRd_SetupWalkToParent(this); } else { - this->unk_305 = 0; + this->isMourning = 0; } } @@ -384,14 +384,14 @@ void func_80AE2C1C(EnRd* this, PlayState* play) { } } -void func_80AE2F50(EnRd* this, PlayState* play) { +void EnRd_SetupWalkToHome(EnRd* this, PlayState* play) { Animation_Change(&this->skelAnime, &gGibdoRedeadWalkAnim, 0.5f, 0, Animation_GetLastFrame(&gGibdoRedeadWalkAnim), ANIMMODE_LOOP_INTERP, -4.0f); - this->unk_31B = 2; - EnRd_SetupAction(this, func_80AE2FD0); + this->action = 2; + EnRd_SetupAction(this, EnRd_WalkToHome); } -void func_80AE2FD0(EnRd* this, PlayState* play) { +void EnRd_WalkToHome(EnRd* this, PlayState* play) { Player* player = GET_PLAYER(play); s32 pad; s16 targetY = Actor_WorldYawTowardPoint(&this->actor, &this->actor.home.pos); @@ -402,15 +402,15 @@ void func_80AE2FD0(EnRd* this, PlayState* play) { this->actor.speedXZ = 0.0f; if (Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 0x1C2, 0) == 0) { if (this->actor.params != 2) { - func_80AE269C(this); + EnRd_SetupIdle(this); } else { - func_80AE39D4(this); + EnRd_SetupCrouch(this); } } } - Math_SmoothStepToS(&this->unk_30E, 0, 1, 0x64, 0); - Math_SmoothStepToS(&this->unk_310, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 0x64, 0); this->actor.world.rot.y = this->actor.shape.rot.y; SkelAnime_Update(&this->skelAnime); @@ -419,12 +419,12 @@ void func_80AE2FD0(EnRd* this, PlayState* play) { !(player->stateFlags2 & PLAYER_STATE2_GRABBED_BY_ENEMY) && (Actor_WorldDistXYZToPoint(&player->actor, &this->actor.home.pos) < 150.0f)) { this->actor.targetMode = 0; - func_80AE2B90(this, play); + EnRd_SetupWalkToPlayer(this, play); } else if (this->actor.params > 0) { if (this->actor.parent != NULL) { - func_80AE31DC(this); + EnRd_SetupWalkToParent(this); } else { - this->unk_305 = 0; + this->isMourning = 0; } } @@ -435,15 +435,15 @@ void func_80AE2FD0(EnRd* this, PlayState* play) { } } -void func_80AE31DC(EnRd* this) { +void EnRd_SetupWalkToParent(EnRd* this) { Animation_Change(&this->skelAnime, &gGibdoRedeadWalkAnim, 0.5f, 0, Animation_GetLastFrame(&gGibdoRedeadWalkAnim), ANIMMODE_LOOP_INTERP, -4.0f); - this->unk_31B = 3; - this->unk_305 = 1; - EnRd_SetupAction(this, func_80AE3260); + this->action = 3; + this->isMourning = 1; + EnRd_SetupAction(this, EnRd_WalkToParent); } -void func_80AE3260(EnRd* this, PlayState* play) { +void EnRd_WalkToParent(EnRd* this, PlayState* play) { if (this->actor.parent != NULL) { s32 pad; s16 targetY; @@ -459,16 +459,16 @@ void func_80AE3260(EnRd* this, PlayState* play) { this->actor.speedXZ = 0.0f; if (this->actor.params != 2) { - func_80AE269C(this); + EnRd_SetupIdle(this); } else { - func_80AE39D4(this); + EnRd_SetupCrouch(this); } } - Math_SmoothStepToS(&this->unk_30E, 0, 1, 0x64, 0); - Math_SmoothStepToS(&this->unk_310, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 0x64, 0); } else { - func_80AE2B90(this, play); + EnRd_SetupWalkToPlayer(this, play); } this->actor.world.rot.y = this->actor.shape.rot.y; @@ -481,39 +481,39 @@ void func_80AE3260(EnRd* this, PlayState* play) { } } -void func_80AE33F0(EnRd* this) { +void EnRd_SetupGrab(EnRd* this) { Animation_PlayOnce(&this->skelAnime, &gGibdoRedeadGrabStartAnim); - this->unk_30C = this->unk_304 = 0; - this->unk_319 = 200; - this->unk_31B = 8; + this->timer = this->grabState = 0; + this->grabDamageTimer = 200; + this->action = 8; this->actor.speedXZ = 0.0f; - EnRd_SetupAction(this, func_80AE3454); + EnRd_SetupAction(this, EnRd_Grab); } -void func_80AE3454(EnRd* this, PlayState* play) { +void EnRd_Grab(EnRd* this, PlayState* play) { s32 pad; Player* player = GET_PLAYER(play); if (SkelAnime_Update(&this->skelAnime)) { - this->unk_304++; + this->grabState++; } - switch (this->unk_304) { + switch (this->grabState) { case 1: Animation_PlayLoop(&this->skelAnime, &gGibdoRedeadGrabAttackAnim); - this->unk_304++; + this->grabState++; play->damagePlayer(play, -8); func_800AA000(this->actor.xzDistToPlayer, 0xFF, 1, 0xC); - this->unk_319 = 20; + this->grabDamageTimer = 20; case 0: - Math_SmoothStepToS(&this->unk_30E, 0, 1, 0x5DC, 0); - Math_SmoothStepToS(&this->unk_310, 0, 1, 0x5DC, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 0x5DC, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 0x5DC, 0); case 2: if (!(player->stateFlags2 & 0x80)) { Animation_Change(&this->skelAnime, &gGibdoRedeadGrabEndAnim, 0.5f, 0.0f, Animation_GetLastFrame(&gGibdoRedeadGrabEndAnim), ANIMMODE_ONCE_INTERP, 0.0f); - this->unk_304++; - this->unk_31B = 4; + this->grabState++; + this->action = 4; return; } @@ -533,12 +533,12 @@ void func_80AE3454(EnRd* this, PlayState* play) { if (this->skelAnime.curFrame == 0.0f) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_ATTACK); } - this->unk_319--; + this->grabDamageTimer--; - if (this->unk_319 == 0) { + if (this->grabDamageTimer == 0) { play->damagePlayer(play, -8); func_800AA000(this->actor.xzDistToPlayer, 0xF0, 1, 0xC); - this->unk_319 = 20; + this->grabDamageTimer = 20; Player_PlaySfx(&player->actor, NA_SE_VO_LI_DAMAGE_S + player->ageProperties->unk_92); } break; @@ -553,68 +553,69 @@ void func_80AE3454(EnRd* this, PlayState* play) { } this->actor.targetMode = 0; this->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED; - this->unk_306 = 0xA; - this->unk_307 = 0xF; - func_80AE2B90(this, play); + this->playerStunWaitTimer = 0xA; + this->grabWaitTimer = 0xF; + EnRd_SetupWalkToPlayer(this, play); break; } } -void func_80AE37BC(EnRd* this) { +void EnRd_SetupAttemptPlayerFreeze(EnRd* this) { Animation_Change(&this->skelAnime, &gGibdoRedeadLookBackAnim, 0.0f, 0.0f, Animation_GetLastFrame(&gGibdoRedeadLookBackAnim), ANIMMODE_ONCE, 0.0f); - this->unk_31B = 7; - EnRd_SetupAction(this, func_80AE3834); + this->action = 7; + EnRd_SetupAction(this, EnRd_AttemptPlayerFreeze); } -void func_80AE3834(EnRd* this, PlayState* play) { +void EnRd_AttemptPlayerFreeze(EnRd* this, PlayState* play) { Vec3f sp34 = D_80AE492C; Color_RGBA8 sp30 = D_80AE4938; Color_RGBA8 sp2C = D_80AE493C; Player* player = GET_PLAYER(play); - s16 temp_v0 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y - this->unk_30E - this->unk_310; + s16 temp_v0 = + this->actor.yawTowardsPlayer - this->actor.shape.rot.y - this->headYRotation - this->upperBodyYRotation; if (ABS(temp_v0) < 0x2008) { - if (!(this->unk_312 & 0x80) && GameInteractor_Should(VB_REDEAD_GIBDO_FREEZE_LINK, true, this)) { + if (!(this->rdFlags & 0x80) && GameInteractor_Should(VB_REDEAD_GIBDO_FREEZE_LINK, true, this)) { player->actor.freezeTimer = 60; func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); Player_SetAutoLockOnActor(play, &this->actor); } Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); - func_80AE2B90(this, play); + EnRd_SetupWalkToPlayer(this, play); } } -void func_80AE392C(EnRd* this) { +void EnRd_SetupStandUp(EnRd* this) { Animation_MorphToPlayOnce(&this->skelAnime, &gGibdoRedeadStandUpAnim, -4.0f); - this->unk_31B = 5; - EnRd_SetupAction(this, func_80AE3978); + this->action = 5; + EnRd_SetupAction(this, EnRd_StandUp); } -void func_80AE3978(EnRd* this, PlayState* play) { +void EnRd_StandUp(EnRd* this, PlayState* play) { if (SkelAnime_Update(&this->skelAnime)) { if (this->actor.parent != NULL) { - func_80AE31DC(this); + EnRd_SetupWalkToParent(this); } else { - func_80AE37BC(this); + EnRd_SetupAttemptPlayerFreeze(this); } } } -void func_80AE39D4(EnRd* this) { +void EnRd_SetupCrouch(EnRd* this) { Animation_Change(&this->skelAnime, &gGibdoRedeadStandUpAnim, -1.0f, Animation_GetLastFrame(&gGibdoRedeadStandUpAnim), 0.0f, ANIMMODE_ONCE, -4.0f); - this->unk_31B = 6; - EnRd_SetupAction(this, func_80AE3A54); + this->action = 6; + EnRd_SetupAction(this, EnRd_Crouch); } -void func_80AE3A54(EnRd* this, PlayState* play) { +void EnRd_Crouch(EnRd* this, PlayState* play) { if (SkelAnime_Update(&this->skelAnime)) { - func_80AE269C(this); + EnRd_SetupIdle(this); } } -void func_80AE3A8C(EnRd* this) { +void EnRd_SetupDamaged(EnRd* this) { Animation_MorphToPlayOnce(&this->skelAnime, &gGibdoRedeadDamageAnim, -6.0f); if (this->actor.bgCheckFlags & 1) { @@ -623,11 +624,11 @@ void func_80AE3A8C(EnRd* this) { this->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED; Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); - this->unk_31B = 9; - EnRd_SetupAction(this, func_80AE3B18); + this->action = 9; + EnRd_SetupAction(this, EnRd_Damaged); } -void func_80AE3B18(EnRd* this, PlayState* play) { +void EnRd_Damaged(EnRd* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->actor.speedXZ < 0.0f) { @@ -635,175 +636,175 @@ void func_80AE3B18(EnRd* this, PlayState* play) { } this->actor.world.rot.y = this->actor.yawTowardsPlayer; - Math_SmoothStepToS(&this->unk_30E, 0, 1, 0x12C, 0); - Math_SmoothStepToS(&this->unk_310, 0, 1, 0x12C, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 0x12C, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 0x12C, 0); if (SkelAnime_Update(&this->skelAnime)) { this->actor.world.rot.y = this->actor.shape.rot.y; if (this->actor.parent != NULL) { - func_80AE31DC(this); + EnRd_SetupWalkToParent(this); } else if (Actor_WorldDistXYZToPoint(&player->actor, &this->actor.home.pos) >= 150.0f) { - func_80AE2F50(this, play); + EnRd_SetupWalkToHome(this, play); } else { - func_80AE2B90(this, play); + EnRd_SetupWalkToPlayer(this, play); } this->unk_31D = 0xFF; } } -void func_80AE3C20(EnRd* this) { +void EnRd_SetupDead(EnRd* this) { Animation_MorphToPlayOnce(&this->skelAnime, &gGibdoRedeadDeathAnim, -1.0f); - this->unk_31B = 10; - this->unk_30C = 300; + this->action = 10; + this->timer = 300; this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; this->actor.speedXZ = 0.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DEAD); - EnRd_SetupAction(this, func_80AE3C98); + EnRd_SetupAction(this, EnRd_Dead); GameInteractor_ExecuteOnEnemyDefeat(&this->actor); } -void func_80AE3C98(EnRd* this, PlayState* play) { +void EnRd_Dead(EnRd* this, PlayState* play) { if (this->actor.category != ACTORCAT_PROP) { Actor_ChangeCategory(play, &play->actorCtx, &this->actor, ACTORCAT_PROP); } - Math_SmoothStepToS(&this->unk_30E, 0, 1, 0x7D0, 0); - Math_SmoothStepToS(&this->unk_310, 0, 1, 0x7D0, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 0x7D0, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 0x7D0, 0); if (SkelAnime_Update(&this->skelAnime)) { - if (this->unk_30C == 0) { + if (this->timer == 0) { s8 enemyRandoCCActive = CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), 0) || (CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("Enabled"), 0)); // Don't set this flag in Enemy Rando as it can overlap with other objects using the same flag. - if (!Flags_GetSwitch(play, this->unk_312 & 0x7F) && !enemyRandoCCActive) { - Flags_SetSwitch(play, this->unk_312 & 0x7F); + if (!Flags_GetSwitch(play, this->rdFlags & 0x7F) && !enemyRandoCCActive) { + Flags_SetSwitch(play, this->rdFlags & 0x7F); } - if (this->unk_314 != 0) { - if (this->unk_314 == 0xB4) { - func_80AE2630(play, &this->actor, 0); + if (this->alpha != 0) { + if (this->alpha == 0xB4) { + EnRd_UpdateMourningTarget(play, &this->actor, 0); } this->actor.scale.y -= 0.000075f; - this->unk_314 -= 5; + this->alpha -= 5; } else { Actor_Kill(&this->actor); } } else { - this->unk_30C--; + this->timer--; } } else if (((s32)this->skelAnime.curFrame == 33) || ((s32)this->skelAnime.curFrame == 40)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_DOWN); } } -void func_80AE3DE4(EnRd* this) { - this->unk_31B = 1; +void EnRd_SetupStunned(EnRd* this) { + this->action = 1; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; if (gSaveContext.sunsSongState != SUNSSONG_INACTIVE) { - this->unk_318 = 1; - this->unk_316 = 0x258; + this->stunnedBySunsSong = 1; + this->sunsSongStunTimer = 0x258; Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIGHT_ARROW_HIT); Actor_SetColorFilter(&this->actor, -0x8000, -0x7F38, 0, 0xFF); - } else if (this->unk_31C == 1) { + } else if (this->damageReaction == 1) { Actor_SetColorFilter(&this->actor, 0, 0xC8, 0, 0x50); } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIGHT_ARROW_HIT); Actor_SetColorFilter(&this->actor, -0x8000, 0xC8, 0, 0x50); } - EnRd_SetupAction(this, func_80AE3ECC); + EnRd_SetupAction(this, EnRd_Stunned); } -void func_80AE3ECC(EnRd* this, PlayState* play) { - if ((this->unk_318 != 0) && (this->unk_316 != 0)) { - this->unk_316--; - if (this->unk_316 >= 0xFF) { +void EnRd_Stunned(EnRd* this, PlayState* play) { + if ((this->stunnedBySunsSong != 0) && (this->sunsSongStunTimer != 0)) { + this->sunsSongStunTimer--; + if (this->sunsSongStunTimer >= 0xFF) { Actor_SetColorFilter(&this->actor, -0x8000, 0xC8, 0, 0xFF); } - if (this->unk_316 == 0) { - this->unk_318 = 0; + if (this->sunsSongStunTimer == 0) { + this->stunnedBySunsSong = 0; gSaveContext.sunsSongState = SUNSSONG_INACTIVE; } } if (this->actor.colorFilterTimer == 0) { if (this->actor.colChkInfo.health == 0) { - func_80AE2630(play, &this->actor, 1); - func_80AE3C20(this); + EnRd_UpdateMourningTarget(play, &this->actor, 1); + EnRd_SetupDead(this); Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0x90); } else { - func_80AE3A8C(this); + EnRd_SetupDamaged(this); } } } -void func_80AE3F9C(EnRd* this, PlayState* play) { +void EnRd_TurnTowardsPlayer(EnRd* this, PlayState* play) { s16 temp1; s16 temp2; s16 temp3; - temp1 = this->actor.yawTowardsPlayer - (s16)(this->actor.shape.rot.y + this->unk_310); + temp1 = this->actor.yawTowardsPlayer - (s16)(this->actor.shape.rot.y + this->upperBodyYRotation); temp2 = CLAMP(temp1, -500, 500); - temp1 -= this->unk_30E; + temp1 -= this->headYRotation; temp3 = CLAMP(temp1, -500, 500); if ((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y) >= 0) { - this->unk_310 += ABS(temp2); - this->unk_30E += ABS(temp3); + this->upperBodyYRotation += ABS(temp2); + this->headYRotation += ABS(temp3); } else { - this->unk_310 -= ABS(temp2); - this->unk_30E -= ABS(temp3); + this->upperBodyYRotation -= ABS(temp2); + this->headYRotation -= ABS(temp3); } - this->unk_310 = CLAMP(this->unk_310, -18783, 18783); - this->unk_30E = CLAMP(this->unk_30E, -9583, 9583); + this->upperBodyYRotation = CLAMP(this->upperBodyYRotation, -18783, 18783); + this->headYRotation = CLAMP(this->headYRotation, -9583, 9583); } -void func_80AE4114(EnRd* this, PlayState* play) { +void EnRd_UpdateDamage(EnRd* this, PlayState* play) { s32 pad; Player* player = GET_PLAYER(play); - if ((gSaveContext.sunsSongState != SUNSSONG_INACTIVE) && (this->actor.shape.rot.x == 0) && (this->unk_318 == 0) && - (this->unk_31B != 9) && (this->unk_31B != 10) && (this->unk_31B != 1)) { - func_80AE3DE4(this); + if ((gSaveContext.sunsSongState != SUNSSONG_INACTIVE) && (this->actor.shape.rot.x == 0) && + (this->stunnedBySunsSong == 0) && (this->action != 9) && (this->action != 10) && (this->action != 1)) { + EnRd_SetupStunned(this); return; } if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; - this->unk_31C = this->actor.colChkInfo.damageEffect; + this->damageReaction = this->actor.colChkInfo.damageEffect; - if (this->unk_31B != 11) { + if (this->action != 11) { Actor_SetDropFlag(&this->actor, &this->collider.info, 1); if (player->unk_844 != 0) { this->unk_31D = player->unk_845; } - if ((this->unk_31C != 0) && (this->unk_31C != 6)) { - if (((this->unk_31C == 1) || (this->unk_31C == 13)) && (this->unk_31B != 1)) { + if ((this->damageReaction != 0) && (this->damageReaction != 6)) { + if (((this->damageReaction == 1) || (this->damageReaction == 13)) && (this->action != 1)) { Actor_ApplyDamage(&this->actor); - func_80AE3DE4(this); + EnRd_SetupStunned(this); return; } - this->unk_318 = 0; - this->unk_316 = 0; + this->stunnedBySunsSong = 0; + this->sunsSongStunTimer = 0; - if (this->unk_31C == 0xE) { + if (this->damageReaction == 0xE) { Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 0x50); - this->unk_31A = 0x28; + this->fireTimer = 0x28; } else { Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); } Actor_ApplyDamage(&this->actor); if (this->actor.colChkInfo.health == 0) { - func_80AE2630(play, &this->actor, 1); - func_80AE3C20(this); + EnRd_UpdateMourningTarget(play, &this->actor, 1); + EnRd_SetupDead(this); Item_DropCollectibleRandom(play, 0, &this->actor.world.pos, 0x90); } else { - func_80AE3A8C(this); + EnRd_SetupDamaged(this); } } } @@ -816,38 +817,38 @@ void EnRd_Update(Actor* thisx, PlayState* play) { Player* player = GET_PLAYER(play); s32 pad2; - func_80AE4114(this, play); + EnRd_UpdateDamage(this, play); - if (gSaveContext.sunsSongState != SUNSSONG_INACTIVE && this->unk_318 == 0) { + if (gSaveContext.sunsSongState != SUNSSONG_INACTIVE && this->stunnedBySunsSong == 0) { gSaveContext.sunsSongState = SUNSSONG_INACTIVE; } - if (this->unk_31C != 6 && ((this->unk_31B != 11) || (this->unk_31C != 14))) { - if (this->unk_306 != 0) { - this->unk_306--; + if (this->damageReaction != 6 && ((this->action != 11) || (this->damageReaction != 14))) { + if (this->playerStunWaitTimer != 0) { + this->playerStunWaitTimer--; } this->actionFunc(this, play); - if (this->unk_31B != 8 && this->actor.speedXZ != 0.0f) { + if (this->action != 8 && this->actor.speedXZ != 0.0f) { Actor_MoveXZGravity(&this->actor); } - if ((this->actor.shape.rot.x == 0) && (this->unk_31B != 8) && (this->actor.speedXZ != 0.0f)) { + if ((this->actor.shape.rot.x == 0) && (this->action != 8) && (this->actor.speedXZ != 0.0f)) { Actor_UpdateBgCheckInfo(play, &this->actor, 30.0f, 20.0f, 35.0f, 0x1D); } - if (this->unk_31B == 7) { - func_80AE3F9C(this, play); + if (this->action == 7) { + EnRd_TurnTowardsPlayer(this, play); } } this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 50.0f; - if ((this->actor.colChkInfo.health > 0) && (this->unk_31B != 8)) { + if ((this->actor.colChkInfo.health > 0) && (this->action != 8)) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - if ((this->unk_31B != 9) || ((player->unk_844 != 0) && (player->unk_845 != this->unk_31D))) { + if ((this->action != 9) || ((player->unk_844 != 0) && (player->unk_845 != this->unk_31D))) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); } } @@ -857,9 +858,9 @@ s32 EnRd_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po EnRd* this = (EnRd*)thisx; if (limbIndex == 23) { - rot->y += this->unk_30E; + rot->y += this->headYRotation; } else if (limbIndex == 12) { - rot->y += this->unk_310; + rot->y += this->upperBodyYRotation; } return false; } @@ -870,7 +871,7 @@ void EnRd_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, s32 idx = -1; Vec3f destPos; - if ((this->unk_31A != 0) || ((this->actor.colorFilterTimer != 0) && (this->actor.colorFilterParams & 0x4000))) { + if ((this->fireTimer != 0) || ((this->actor.colorFilterTimer != 0) && (this->actor.colorFilterParams & 0x4000))) { switch (limbIndex - 1) { case 23: idx = 0; @@ -920,31 +921,31 @@ void EnRd_Draw(Actor* thisx, PlayState* play) { OPEN_DISPS(play->state.gfxCtx); - if (this->unk_314 == 0xFF) { + if (this->alpha == 0xFF) { Gfx_SetupDL_25Opa(play->state.gfxCtx); - gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->unk_314); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->alpha); gSPSegment(POLY_OPA_DISP++, 8, &D_80116280[2]); POLY_OPA_DISP = SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, EnRd_OverrideLimbDraw, EnRd_PostLimbDraw, this, POLY_OPA_DISP); func_80033C30(&thisPos, &D_80AE4958, 255, play); - if (this->unk_31A != 0) { + if (this->fireTimer != 0) { thisx->colorFilterTimer++; - this->unk_31A--; - if (this->unk_31A % 4 == 0) { - EffectSsEnFire_SpawnVec3s(play, thisx, &this->firePos[this->unk_31A >> 2], 0x4B, 0, 0, - (this->unk_31A >> 2)); + this->fireTimer--; + if (this->fireTimer % 4 == 0) { + EffectSsEnFire_SpawnVec3s(play, thisx, &this->firePos[this->fireTimer >> 2], 0x4B, 0, 0, + (this->fireTimer >> 2)); } } } else { Gfx_SetupDL_25Xlu(play->state.gfxCtx); - gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_314); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->alpha); gSPSegment(POLY_XLU_DISP++, 8, &D_80116280[0]); POLY_XLU_DISP = SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, EnRd_OverrideLimbDraw, NULL, this, POLY_XLU_DISP); - func_80033C30(&thisPos, &D_80AE4958, this->unk_314, play); + func_80033C30(&thisPos, &D_80AE4958, this->alpha, play); } CLOSE_DISPS(play->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.h b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.h index c7518f569d..729d150d1b 100644 --- a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.h +++ b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.h @@ -14,22 +14,22 @@ typedef struct EnRd { /* 0x0188 */ SkelAnime skelAnime; /* 0x01CC */ Vec3s jointTable[26]; /* 0x0268 */ Vec3s morphTable[26]; - /* 0x0304 */ u8 unk_304; - /* 0x0305 */ u8 unk_305; - /* 0x0306 */ u8 unk_306; - /* 0x0307 */ u8 unk_307; + /* 0x0304 */ u8 grabState; + /* 0x0305 */ u8 isMourning; + /* 0x0306 */ u8 playerStunWaitTimer; + /* 0x0307 */ u8 grabWaitTimer; /* 0x0308 */ EnRdActionFunc actionFunc; - /* 0x030C */ s16 unk_30C; - /* 0x030E */ s16 unk_30E; - /* 0x0310 */ s16 unk_310; - /* 0x0312 */ s16 unk_312; - /* 0x0314 */ s16 unk_314; - /* 0x0316 */ s16 unk_316; - /* 0x0318 */ u8 unk_318; - /* 0x0319 */ u8 unk_319; - /* 0x031A */ u8 unk_31A; - /* 0x031B */ u8 unk_31B; - /* 0x031C */ u8 unk_31C; + /* 0x030C */ s16 timer; + /* 0x030E */ s16 headYRotation; + /* 0x0310 */ s16 upperBodyYRotation; + /* 0x0312 */ s16 rdFlags; + /* 0x0314 */ s16 alpha; + /* 0x0316 */ s16 sunsSongStunTimer; + /* 0x0318 */ u8 stunnedBySunsSong; + /* 0x0319 */ u8 grabDamageTimer; + /* 0x031A */ u8 fireTimer; + /* 0x031B */ u8 action; + /* 0x031C */ u8 damageReaction; /* 0x031D */ u8 unk_31D; /* 0x0320 */ ColliderCylinder collider; } EnRd; // size = 0x036C diff --git a/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c b/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c index 0a9f228b65..94785b7a53 100644 --- a/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c +++ b/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c @@ -21,18 +21,18 @@ void EnReeba_Destroy(Actor* thisx, PlayState* play); void EnReeba_Update(Actor* thisx, PlayState* play); void EnReeba_Draw(Actor* thisx, PlayState* play); -void func_80AE4F40(EnReeba* this, PlayState* play); -void func_80AE5054(EnReeba* this, PlayState* play); -void func_80AE5270(EnReeba* this, PlayState* play); -void func_80AE5688(EnReeba* this, PlayState* play); -void func_80AE56E0(EnReeba* this, PlayState* play); -void func_80AE538C(EnReeba* this, PlayState* play); -void func_80AE53AC(EnReeba* this, PlayState* play); -void func_80AE5E48(EnReeba* this, PlayState* play); -void func_80AE5854(EnReeba* this, PlayState* play); -void func_80AE5C38(EnReeba* this, PlayState* play); -void func_80AE5938(EnReeba* this, PlayState* play); -void func_80AE5A9C(EnReeba* this, PlayState* play); +void EnReeba_SetupSurface(EnReeba* this, PlayState* play); +void EnReeba_Surface(EnReeba* this, PlayState* play); +void EnReeba_Move(EnReeba* this, PlayState* play); +void EnReeba_SetupSink(EnReeba* this, PlayState* play); +void EnReeba_Sink(EnReeba* this, PlayState* play); +void EnReeba_SetupMoveBig(EnReeba* this, PlayState* play); +void EnReeba_MoveBig(EnReeba* this, PlayState* play); +void EnReeba_StunRecover(EnReeba* this, PlayState* play); +void EnReeba_Damaged(EnReeba* this, PlayState* play); +void EnReeba_Die(EnReeba* this, PlayState* play); +void EnReeba_Stunned(EnReeba* this, PlayState* play); +void EnReeba_StunDie(EnReeba* this, PlayState* play); static DamageTable sDamageTable = { /* Deku nut */ DMG_ENTRY(0, 0x0), @@ -131,7 +131,7 @@ void EnReeba_Init(Actor* thisx, PlayState* play) { Actor_ChangeCategory(play, &play->actorCtx, &this->actor, ACTORCAT_ENEMY); } - this->actor.shape.yOffset = this->unk_284 = this->scale * -27500.0f; + this->actor.shape.yOffset = this->yOffsetTarget = this->scale * -27500.0f; ActorShape_Init(&this->actor.shape, this->actor.shape.yOffset, ActorShadow_DrawCircle, 0.0f); this->actor.colChkInfo.damageTable = &sDamageTable; Actor_UpdateBgCheckInfo(play, &this->actor, 35.0f, 60.0f, 60.0f, 0x1D); @@ -143,7 +143,7 @@ void EnReeba_Init(Actor* thisx, PlayState* play) { return; } - this->actionfunc = func_80AE4F40; + this->actionfunc = EnReeba_SetupSurface; } void EnReeba_Destroy(Actor* thisx, PlayState* play) { @@ -169,7 +169,7 @@ void EnReeba_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelanime); } -void func_80AE4F40(EnReeba* this, PlayState* play) { +void EnReeba_SetupSurface(EnReeba* this, PlayState* play) { f32 frames = Animation_GetLastFrame(&object_reeba_Anim_0001E4); Player* player = GET_PLAYER(play); s16 playerSpeed; @@ -177,12 +177,12 @@ void func_80AE4F40(EnReeba* this, PlayState* play) { Animation_Change(&this->skelanime, &object_reeba_Anim_0001E4, 2.0f, 0.0f, frames, ANIMMODE_LOOP, -10.0f); playerSpeed = fabsf(player->linearVelocity); - this->unk_278 = 20 - playerSpeed * 2; - if (this->unk_278 < 0) { - this->unk_278 = 2; + this->waitTimer = 20 - playerSpeed * 2; + if (this->waitTimer < 0) { + this->waitTimer = 2; } - if (this->unk_278 > 20) { - this->unk_278 = 20; + if (this->waitTimer > 20) { + this->waitTimer = 20; } this->actor.flags &= ~ACTOR_FLAG_LOCK_ON_DISABLED; @@ -194,10 +194,10 @@ void func_80AE4F40(EnReeba* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_APPEAR); } - this->actionfunc = func_80AE5054; + this->actionfunc = EnReeba_Surface; } -void func_80AE5054(EnReeba* this, PlayState* play) { +void EnReeba_Surface(EnReeba* this, PlayState* play) { Player* player = GET_PLAYER(play); f32 playerLinearVel; @@ -208,17 +208,17 @@ void func_80AE5054(EnReeba* this, PlayState* play) { 500, 10, true); } - if (this->unk_278 == 0) { + if (this->waitTimer == 0) { Math_ApproachF(&this->actor.shape.shadowScale, 12.0f, 1.0f, 1.0f); if (this->actor.shape.yOffset < 0.0f) { - Math_ApproachZeroF(&this->actor.shape.yOffset, 1.0f, this->unk_288); - Math_ApproachF(&this->unk_288, 300.0f, 1.0f, 5.0f); + Math_ApproachZeroF(&this->actor.shape.yOffset, 1.0f, this->yOffsetStep); + Math_ApproachF(&this->yOffsetStep, 300.0f, 1.0f, 5.0f); } else { - this->unk_288 = 0.0f; + this->yOffsetStep = 0.0f; this->actor.shape.yOffset = 0.0f; playerLinearVel = player->linearVelocity; - switch (this->unk_280) { + switch (this->aimType) { case 0: this->actor.world.rot.y = this->actor.yawTowardsPlayer; break; @@ -237,17 +237,17 @@ void func_80AE5054(EnReeba* this, PlayState* play) { } if (this->isBig) { - this->actionfunc = func_80AE538C; + this->actionfunc = EnReeba_SetupMoveBig; } else { - this->unk_272 = 130; + this->moveTimer = 130; this->actor.speedXZ = Rand_ZeroFloat(4.0f) + 6.0f; - this->actionfunc = func_80AE5270; + this->actionfunc = EnReeba_Move; } } } } -void func_80AE5270(EnReeba* this, PlayState* play) { +void EnReeba_Move(EnReeba* this, PlayState* play) { s32 surfaceType; SkelAnime_Update(&this->skelanime); @@ -260,22 +260,22 @@ void func_80AE5270(EnReeba* this, PlayState* play) { if ((surfaceType != 4) && (surfaceType != 7)) { this->actor.speedXZ = 0.0f; - this->actionfunc = func_80AE5688; - } else if ((this->unk_272 == 0) || (this->actor.xzDistToPlayer < 30.0f) || (this->actor.xzDistToPlayer > 400.0f) || - (this->actor.bgCheckFlags & 8)) { - this->actionfunc = func_80AE5688; - } else if (this->unk_274 == 0) { + this->actionfunc = EnReeba_SetupSink; + } else if ((this->moveTimer == 0) || (this->actor.xzDistToPlayer < 30.0f) || + (this->actor.xzDistToPlayer > 400.0f) || (this->actor.bgCheckFlags & 8)) { + this->actionfunc = EnReeba_SetupSink; + } else if (this->sfxTimer == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_MOVE); - this->unk_274 = 10; + this->sfxTimer = 10; } } -void func_80AE538C(EnReeba* this, PlayState* play) { +void EnReeba_SetupMoveBig(EnReeba* this, PlayState* play) { this->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE; - this->actionfunc = func_80AE53AC; + this->actionfunc = EnReeba_MoveBig; } -void func_80AE53AC(EnReeba* this, PlayState* play) { +void EnReeba_MoveBig(EnReeba* this, PlayState* play) { f32 speed; s16 yawDiff; s16 yaw; @@ -291,10 +291,10 @@ void func_80AE53AC(EnReeba* this, PlayState* play) { if (((surfaceType != 4) && (surfaceType != 7)) || (this->actor.xzDistToPlayer > 400.0f) || (this->actor.bgCheckFlags & 8)) { - this->actionfunc = func_80AE5688; + this->actionfunc = EnReeba_SetupSink; } else { - if ((this->actor.xzDistToPlayer < 70.0f) && (this->unk_270 == 0)) { - this->unk_270 = 30; + if ((this->actor.xzDistToPlayer < 70.0f) && (this->bigLeeverTimer == 0)) { + this->bigLeeverTimer = 30; } speed = (this->actor.xzDistToPlayer - 20.0f) / ((Rand_ZeroOne() * 50.0f) + 150.0f); @@ -306,103 +306,103 @@ void func_80AE53AC(EnReeba* this, PlayState* play) { this->actor.speedXZ = -3.0f; } - yawDiff = (this->unk_270 == 0) ? this->actor.yawTowardsPlayer : -this->actor.yawTowardsPlayer; + yawDiff = (this->bigLeeverTimer == 0) ? this->actor.yawTowardsPlayer : -this->actor.yawTowardsPlayer; yawDiff -= this->actor.world.rot.y; yaw = (yawDiff > 0) ? ((yawDiff / 31.0f) + 10.0f) : ((yawDiff / 31.0f) - 10.0f); this->actor.world.rot.y += yaw * 2.0f; - if (this->unk_274 == 0) { + if (this->sfxTimer == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_MOVE); - this->unk_274 = 20; + this->sfxTimer = 20; } } } -void func_80AE561C(EnReeba* this, PlayState* play) { +void EnReeba_Recoiled(EnReeba* this, PlayState* play) { Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.3f); - if (this->unk_272 == 0) { + if (this->moveTimer == 0) { if (this->isBig) { - this->actionfunc = func_80AE538C; + this->actionfunc = EnReeba_SetupMoveBig; } else { - this->actionfunc = func_80AE5688; + this->actionfunc = EnReeba_SetupSink; } } } -void func_80AE5688(EnReeba* this, PlayState* play) { - this->unk_27E = 0; +void EnReeba_SetupSink(EnReeba* this, PlayState* play) { + this->stunType = 0; Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); this->actor.flags |= ACTOR_FLAG_LOCK_ON_DISABLED; this->actor.flags &= ~(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE); - this->actionfunc = func_80AE56E0; + this->actionfunc = EnReeba_Sink; } -void func_80AE56E0(EnReeba* this, PlayState* play) { +void EnReeba_Sink(EnReeba* this, PlayState* play) { Math_ApproachZeroF(&this->actor.shape.shadowScale, 1.0f, 0.3f); Math_ApproachZeroF(&this->actor.speedXZ, 0.1f, 0.3f); SkelAnime_Update(&this->skelanime); - if ((this->unk_284 + 10.0f) <= this->actor.shape.yOffset) { + if ((this->yOffsetTarget + 10.0f) <= this->actor.shape.yOffset) { if ((play->gameplayFrames % 4) == 0) { Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f, 500, 10, true); } - Math_ApproachF(&this->actor.shape.yOffset, this->unk_284, 1.0f, this->unk_288); - Math_ApproachF(&this->unk_288, 300.0f, 1.0f, 5.0f); + Math_ApproachF(&this->actor.shape.yOffset, this->yOffsetTarget, 1.0f, this->yOffsetStep); + Math_ApproachF(&this->yOffsetStep, 300.0f, 1.0f, 5.0f); } else { Actor_Kill(&this->actor); } } -void func_80AE57F0(EnReeba* this, PlayState* play) { - this->unk_276 = 14; +void EnReeba_SetupDamaged(EnReeba* this, PlayState* play) { + this->damagedTimer = 14; this->actor.speedXZ = -8.0f; this->actor.world.rot.y = this->actor.yawTowardsPlayer; Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); - this->actionfunc = func_80AE5854; + this->actionfunc = EnReeba_Damaged; } -void func_80AE5854(EnReeba* this, PlayState* play) { +void EnReeba_Damaged(EnReeba* this, PlayState* play) { SkelAnime_Update(&this->skelanime); if (this->actor.speedXZ < 0.0f) { this->actor.speedXZ += 1.0f; } - if (this->unk_276 == 0) { + if (this->damagedTimer == 0) { if (this->isBig) { - this->unk_270 = 30; - this->actionfunc = func_80AE538C; + this->bigLeeverTimer = 30; + this->actionfunc = EnReeba_SetupMoveBig; } else { - this->actionfunc = func_80AE5688; + this->actionfunc = EnReeba_SetupSink; } } } -void func_80AE58EC(EnReeba* this, PlayState* play) { - this->unk_278 = 14; +void EnReeba_SetupStunned(EnReeba* this, PlayState* play) { + this->waitTimer = 14; this->actor.world.rot.y = this->actor.yawTowardsPlayer; this->actor.speedXZ = -8.0f; this->actor.flags |= ACTOR_FLAG_LOCK_ON_DISABLED; this->actor.flags &= ~(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE); - this->actionfunc = func_80AE5938; + this->actionfunc = EnReeba_Stunned; } -void func_80AE5938(EnReeba* this, PlayState* play) { +void EnReeba_Stunned(EnReeba* this, PlayState* play) { Vec3f pos; f32 scale; - if (this->unk_278 != 0) { + if (this->waitTimer != 0) { if (this->actor.speedXZ < 0.0f) { this->actor.speedXZ += 1.0f; } } else { this->actor.speedXZ = 0.0f; - if ((this->unk_27E == 4) || (this->actor.colChkInfo.health != 0)) { - if (this->unk_27E == 2) { + if ((this->stunType == 4) || (this->actor.colChkInfo.health != 0)) { + if (this->stunType == 2) { pos.x = this->actor.world.pos.x + Rand_CenteredFloat(20.0f); pos.y = this->actor.world.pos.y + Rand_CenteredFloat(20.0f); pos.z = this->actor.world.pos.z + Rand_CenteredFloat(20.0f); @@ -415,21 +415,21 @@ void func_80AE5938(EnReeba* this, PlayState* play) { EffectSsEnIce_SpawnFlyingVec3f(play, &this->actor, &pos, 150, 150, 150, 250, 235, 245, 255, scale); } - this->unk_278 = 66; - this->actionfunc = func_80AE5E48; + this->waitTimer = 66; + this->actionfunc = EnReeba_StunRecover; } else { - this->unk_278 = 30; - this->actionfunc = func_80AE5A9C; + this->waitTimer = 30; + this->actionfunc = EnReeba_StunDie; } } } -void func_80AE5A9C(EnReeba* this, PlayState* play) { +void EnReeba_StunDie(EnReeba* this, PlayState* play) { Vec3f pos; f32 scale; - if (this->unk_278 != 0) { - if ((this->unk_27E == 2) && ((this->unk_278 & 0xF) == 0)) { + if (this->waitTimer != 0) { + if ((this->stunType == 2) && ((this->waitTimer & 0xF) == 0)) { pos.x = this->actor.world.pos.x + Rand_CenteredFloat(20.0f); pos.y = this->actor.world.pos.y + Rand_CenteredFloat(20.0f); pos.z = this->actor.world.pos.z + Rand_CenteredFloat(20.0f); @@ -444,26 +444,26 @@ void func_80AE5A9C(EnReeba* this, PlayState* play) { } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_DEAD); Enemy_StartFinishingBlow(play, &this->actor); - this->actionfunc = func_80AE5C38; + this->actionfunc = EnReeba_Die; GameInteractor_ExecuteOnEnemyDefeat(&this->actor); } } -void func_80AE5BC4(EnReeba* this, PlayState* play) { +void EnReeba_SetupDie(EnReeba* this, PlayState* play) { this->actor.speedXZ = -8.0f; this->actor.world.rot.y = this->actor.yawTowardsPlayer; Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); - this->unk_278 = 14; + this->waitTimer = 14; this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - this->actionfunc = func_80AE5C38; + this->actionfunc = EnReeba_Die; } -void func_80AE5C38(EnReeba* this, PlayState* play) { +void EnReeba_Die(EnReeba* this, PlayState* play) { Vec3f pos; Vec3f accel = { 0.0f, 0.0f, 0.0f }; Vec3f velocity = { 0.0f, 0.0f, 0.0f }; - if (this->unk_278 != 0) { + if (this->waitTimer != 0) { if (this->actor.speedXZ < 0.0f) { this->actor.speedXZ += 1.0f; } @@ -506,74 +506,74 @@ void func_80AE5C38(EnReeba* this, PlayState* play) { } } -void func_80AE5E48(EnReeba* this, PlayState* play) { - if (this->unk_278 < 37) { +void EnReeba_StunRecover(EnReeba* this, PlayState* play) { + if (this->waitTimer < 37) { this->actor.shape.rot.x = Rand_CenteredFloat(3000.0f); this->actor.shape.rot.z = Rand_CenteredFloat(3000.0f); - if (this->unk_278 == 0) { + if (this->waitTimer == 0) { if (this->isBig) { - this->actionfunc = func_80AE538C; + this->actionfunc = EnReeba_SetupMoveBig; } else { - this->actionfunc = func_80AE5688; + this->actionfunc = EnReeba_SetupSink; } } } } -void func_80AE5EDC(EnReeba* this, PlayState* play) { +void EnReeba_CheckDamage(EnReeba* this, PlayState* play) { if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; - if ((this->actionfunc != func_80AE5C38) && (this->actionfunc != func_80AE5854)) { + if ((this->actionfunc != EnReeba_Die) && (this->actionfunc != EnReeba_Damaged)) { this->actor.shape.rot.x = this->actor.shape.rot.z = 0; - this->unk_27E = 0; + this->stunType = 0; switch (this->actor.colChkInfo.damageEffect) { case 11: // none case 12: // boomerang - if ((this->actor.colChkInfo.health > 1) && (this->unk_27E != 4)) { - this->unk_27E = 4; + if ((this->actor.colChkInfo.health > 1) && (this->stunType != 4)) { + this->stunType = 4; Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE); Actor_SetColorFilter(&this->actor, 0, 0xFF, 0, 0x50); - this->actionfunc = func_80AE58EC; + this->actionfunc = EnReeba_SetupStunned; break; } case 13: // hookshot/longshot - if ((this->actor.colChkInfo.health > 2) && (this->unk_27E != 4)) { - this->unk_27E = 4; + if ((this->actor.colChkInfo.health > 2) && (this->stunType != 4)) { + this->stunType = 4; Actor_SetColorFilter(&this->actor, 0, 0xFF, 0, 0x50); Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE); - this->actionfunc = func_80AE58EC; + this->actionfunc = EnReeba_SetupStunned; break; } case 14: - this->unk_27C = 6; + this->unkDamageField = 6; Actor_ApplyDamage(&this->actor); if (this->actor.colChkInfo.health == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_DEAD); Enemy_StartFinishingBlow(play, &this->actor); - this->actionfunc = func_80AE5BC4; + this->actionfunc = EnReeba_SetupDie; } else { - if (this->actionfunc == func_80AE5E48) { + if (this->actionfunc == EnReeba_StunRecover) { this->actor.shape.rot.x = this->actor.shape.rot.z = 0; } Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_DAMAGE); - this->actionfunc = func_80AE57F0; + this->actionfunc = EnReeba_SetupDamaged; } break; case 3: // ice arrows/ice magic Actor_ApplyDamage(&this->actor); - this->unk_27C = 2; - this->unk_27E = 2; + this->unkDamageField = 2; + this->stunType = 2; Actor_SetColorFilter(&this->actor, 0, 0xFF, 0, 80); - this->actionfunc = func_80AE58EC; + this->actionfunc = EnReeba_SetupStunned; break; case 1: // unknown - if (this->unk_27E != 4) { - this->unk_27E = 4; + if (this->stunType != 4) { + this->stunType = 4; Actor_SetColorFilter(&this->actor, 0, 0xFF, 0, 80); - this->actionfunc = func_80AE58EC; + this->actionfunc = EnReeba_SetupStunned; } break; } @@ -586,28 +586,28 @@ void EnReeba_Update(Actor* thisx, PlayState* play2) { EnReeba* this = (EnReeba*)thisx; Player* player = GET_PLAYER(play); - func_80AE5EDC(this, play); + EnReeba_CheckDamage(this, play); this->actionfunc(this, play); Actor_SetScale(&this->actor, this->scale); - if (this->unk_270 != 0) { - this->unk_270--; + if (this->bigLeeverTimer != 0) { + this->bigLeeverTimer--; } - if (this->unk_272 != 0) { - this->unk_272--; + if (this->moveTimer != 0) { + this->moveTimer--; } - if (this->unk_278 != 0) { - this->unk_278--; + if (this->waitTimer != 0) { + this->waitTimer--; } - if (this->unk_274 != 0) { - this->unk_274--; + if (this->sfxTimer != 0) { + this->sfxTimer--; } - if (this->unk_276 != 0) { - this->unk_276--; + if (this->damagedTimer != 0) { + this->damagedTimer--; } Actor_MoveXZGravity(&this->actor); @@ -616,19 +616,19 @@ void EnReeba_Update(Actor* thisx, PlayState* play2) { if (this->collider.base.atFlags & AT_BOUNCED) { this->collider.base.atFlags &= ~AT_BOUNCED; - if ((this->actionfunc == func_80AE5270) || (this->actionfunc == func_80AE53AC)) { + if ((this->actionfunc == EnReeba_Move) || (this->actionfunc == EnReeba_MoveBig)) { this->actor.speedXZ = 8.0f; this->actor.world.rot.y *= -1.0f; - this->unk_272 = 14; - this->actionfunc = func_80AE561C; + this->moveTimer = 14; + this->actionfunc = EnReeba_Recoiled; return; } } if (this->collider.base.atFlags & AT_HIT) { this->collider.base.atFlags &= ~AT_HIT; - if ((this->collider.base.at == &player->actor) && !this->isBig && (this->actionfunc != func_80AE56E0)) { - this->actionfunc = func_80AE5688; + if ((this->collider.base.at == &player->actor) && !this->isBig && (this->actionfunc != EnReeba_Sink)) { + this->actionfunc = EnReeba_SetupSink; } } @@ -643,13 +643,13 @@ void EnReeba_Update(Actor* thisx, PlayState* play2) { Collider_UpdateCylinder(&this->actor, &this->collider); if ((this->actor.shape.yOffset >= -700.0f) && (this->actor.colChkInfo.health > 0) && - (this->actionfunc != func_80AE56E0)) { + (this->actionfunc != EnReeba_Sink)) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); if (!(this->actor.shape.yOffset < 0.0f)) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); - if ((this->actionfunc == func_80AE5270) || (this->actionfunc == func_80AE53AC)) { + if ((this->actionfunc == EnReeba_Move) || (this->actionfunc == EnReeba_MoveBig)) { CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); } } diff --git a/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.h b/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.h index 6d31a41dc1..54d4003843 100644 --- a/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.h +++ b/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.h @@ -15,17 +15,17 @@ typedef struct EnReeba { /* 0x01FC */ Vec3s morphTable[18]; /* 0x0268 */ char unk_268[0x4]; /* 0x026C */ EnReebaActionFunc actionfunc; - /* 0x0270 */ s16 unk_270; - /* 0x0272 */ s16 unk_272; - /* 0x0274 */ s16 unk_274; - /* 0x0276 */ s16 unk_276; - /* 0x0278 */ s16 unk_278; + /* 0x0270 */ s16 bigLeeverTimer; + /* 0x0272 */ s16 moveTimer; + /* 0x0274 */ s16 sfxTimer; + /* 0x0276 */ s16 damagedTimer; + /* 0x0278 */ s16 waitTimer; /* 0x027A */ s16 isBig; - /* 0x027C */ s16 unk_27C; - /* 0x027E */ s16 unk_27E; - /* 0x0280 */ s16 unk_280; - /* 0x0284 */ f32 unk_284; - /* 0x0288 */ f32 unk_288; + /* 0x027C */ s16 unkDamageField; + /* 0x027E */ s16 stunType; + /* 0x0280 */ s16 aimType; + /* 0x0284 */ f32 yOffsetTarget; + /* 0x0288 */ f32 yOffsetStep; /* 0x028C */ f32 scale; /* 0x0290 */ ColliderCylinder collider; } EnReeba; // size = 0x02DC diff --git a/soh/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c b/soh/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c index 83107138e2..fd76bdcff0 100644 --- a/soh/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c +++ b/soh/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c @@ -58,7 +58,7 @@ void EnRiverSound_Destroy(Actor* thisx, PlayState* play) { } } -s32 func_80AE6A54(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3) { +s32 EnRiverSound_FindClosestPointOnLineSegment(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3) { Vec3f vec[3]; f32 temp; @@ -132,18 +132,18 @@ s32 EnRiverSound_GetSoundPos(Vec3s* points, s32 numPoints, Vec3f* hearPos, Vec3f vec.x = point[-1].x; vec.y = point[-1].y; vec.z = point[-1].z; - sp78[0] = func_80AE6A54(&vec, &pointLoc, hearPos, &sp54); + sp78[0] = EnRiverSound_FindClosestPointOnLineSegment(&vec, &pointLoc, hearPos, &sp54); } if (pointIdx + 1 != numPoints) { vec.x = point[1].x; vec.y = point[1].y; vec.z = point[1].z; - sp78[1] = func_80AE6A54(&pointLoc, &vec, hearPos, &sp60); + sp78[1] = EnRiverSound_FindClosestPointOnLineSegment(&pointLoc, &vec, hearPos, &sp60); } if (sp78[0] && sp78[1]) { - if (!func_80AE6A54(&sp54, &sp60, hearPos, soundPos)) { + if (!EnRiverSound_FindClosestPointOnLineSegment(&sp54, &sp60, hearPos, soundPos)) { soundPos->x = (sp54.x + sp60.x) * 0.5f; soundPos->y = (sp54.y + sp60.y) * 0.5f; soundPos->z = (sp54.z + sp60.z) * 0.5f; diff --git a/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c b/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c index ee98b08391..0f6f85aded 100644 --- a/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c +++ b/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c @@ -81,7 +81,7 @@ void func_80AE744C(EnRl* this, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 75.0f, 30.0f, 30.0f, 5); } -s32 func_80AE7494(EnRl* this) { +s32 EnRl_UpdateSkelAnime(EnRl* this) { return SkelAnime_Update(&this->skelAnime); } @@ -169,7 +169,7 @@ void func_80AE7798(EnRl* this, PlayState* play) { void func_80AE77B8(EnRl* this, PlayState* play) { func_80AE744C(this, play); - func_80AE7494(this); + EnRl_UpdateSkelAnime(this); func_80AE72D0(this); func_80AE7698(this, play); } @@ -178,14 +178,14 @@ void func_80AE77F8(EnRl* this, PlayState* play) { s32 temp; func_80AE744C(this, play); - temp = func_80AE7494(this); + temp = EnRl_UpdateSkelAnime(this); func_80AE72D0(this); func_80AE772C(this, temp); } void func_80AE7838(EnRl* this, PlayState* play) { func_80AE744C(this, play); - func_80AE7494(this); + EnRl_UpdateSkelAnime(this); func_80AE72D0(this); func_80AE7590(this, play); } @@ -274,7 +274,7 @@ void func_80AE7C64(EnRl* this, PlayState* play) { void func_80AE7C94(EnRl* this, PlayState* play) { func_80AE744C(this, play); - func_80AE7494(this); + EnRl_UpdateSkelAnime(this); func_80AE72D0(this); func_80AE79A4(this, play); func_80AE73D8(this, play); @@ -284,7 +284,7 @@ void func_80AE7CE8(EnRl* this, PlayState* play) { s32 temp; func_80AE744C(this, play); - temp = func_80AE7494(this); + temp = EnRl_UpdateSkelAnime(this); func_80AE72D0(this); func_80AE7BF8(this, temp); func_80AE73D8(this, play); @@ -292,7 +292,7 @@ void func_80AE7CE8(EnRl* this, PlayState* play) { void func_80AE7D40(EnRl* this, PlayState* play) { func_80AE744C(this, play); - func_80AE7494(this); + EnRl_UpdateSkelAnime(this); func_80AE72D0(this); func_80AE7AF8(this, play); func_80AE73D8(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c index e03a8ed201..a5dd7441e4 100644 --- a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c +++ b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c @@ -157,10 +157,10 @@ void func_80AEAC54(EnRu1* this, PlayState* play) { s32 pad[5]; Collider_UpdateCylinder(&this->actor, &this->collider2); - if (this->unk_34C != 0) { + if (this->isSittingOCActive != 0) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider2.base); } else if (this->actor.xzDistToPlayer > 32.0f) { - this->unk_34C = 1; + this->isSittingOCActive = 1; } } @@ -187,7 +187,7 @@ void EnRu1_DestroyColliders(EnRu1* this, PlayState* play) { } void func_80AEADD8(EnRu1* this) { - this->unk_34C = 0; + this->isSittingOCActive = 0; } u8 func_80AEADE0(EnRu1* this) { @@ -437,10 +437,10 @@ void EnRu1_SpawnRipple(EnRu1* this, PlayState* play, s16 radiusMax, s16 life) { } void func_80AEB50C(EnRu1* this, PlayState* play) { - this->unk_270 += 1.0f; - if (this->unk_270 >= kREG(3) + 10.0f) { + this->treadTimer += 1.0f; + if (this->treadTimer >= kREG(3) + 10.0f) { EnRu1_SpawnRipple(this, play, kREG(1) + 500, 0); - this->unk_270 = 0.0f; + this->treadTimer = 0.0f; } } @@ -548,7 +548,7 @@ void func_80AEBA0C(EnRu1* this, PlayState* play) { void func_80AEBA2C(EnRu1* this, PlayState* play) { s32 pad; - Vec3f* unk_364 = &this->unk_364; + Vec3f* unk_364 = &this->treadStartPos; Vec3f* thisPos; f32 temp_ret_2; CsCmdActorCue* csCmdNPCAction = func_80AEB438(play); @@ -670,7 +670,7 @@ void func_80AEBF60(EnRu1* this, PlayState* play) { if (func_80AEB480(play, 6)) { func_80AEB7D0(this); this->action = 5; - this->unk_364 = this->actor.world.pos; + this->treadStartPos = this->actor.world.pos; } else { func_80AEBA0C(this, play); } @@ -791,7 +791,7 @@ void func_80AEC320(EnRu1* this, PlayState* play) { } void func_80AEC40C(EnRu1* this) { - f32 unk_26C = this->unk_26C; + f32 unk_26C = this->walkingFrame; if (unk_26C < 8.0f) { this->actor.speedXZ = (((kREG(3) * 0.01f) + 2.7f) / 8.0f) * unk_26C; @@ -809,9 +809,9 @@ void func_80AEC4CC(EnRu1* this) { void func_80AEC4F4(EnRu1* this) { f32* speedXZ = &this->actor.speedXZ; - f32* unk_26C = &this->unk_26C; + f32* unk_26C = &this->walkingFrame; - if (this->unk_26C < 8.0f) { + if (this->walkingFrame < 8.0f) { *unk_26C += 1.0f; *speedXZ *= (8.0f - *unk_26C) / 8.0f; this->actor.velocity.y = -*unk_26C * (((kREG(4) * 0.01f) + 13.0f) / 8.0f); @@ -836,7 +836,7 @@ s32 func_80AEC5FC(EnRu1* this, PlayState* play) { void func_80AEC650(EnRu1* this) { s32 pad[2]; - if (this->unk_280 == 0) { + if (this->isFalling == 0) { if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 7.0f)) { Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WALK_DIRT); } @@ -849,10 +849,10 @@ void func_80AEC6B0(EnRu1* this) { } void func_80AEC6E4(EnRu1* this, PlayState* play) { - if ((func_80AEAFA0(play, 4, 3)) && (this->unk_280 == 0)) { + if ((func_80AEAFA0(play, 4, 3)) && (this->isFalling == 0)) { Animation_Change(&this->skelAnime, &gRutoChildBringArmsUpAnim, 1.0f, 0, Animation_GetLastFrame(&gRutoChildBringArmsUpAnim), ANIMMODE_ONCE, -8.0f); - this->unk_280 = 1; + this->isFalling = 1; func_80AEC6B0(this); } } @@ -907,15 +907,15 @@ void func_80AEC93C(EnRu1* this, UNK_TYPE arg1) { ANIMMODE_LOOP, -8.0f); this->actor.world.rot.y += 0x8000; this->action = 0xB; - this->unk_26C = 0.0f; + this->walkingFrame = 0.0f; } } void func_80AEC9C4(EnRu1* this) { - this->unk_26C += 1.0f; - if (this->unk_26C >= 8.0f) { + this->walkingFrame += 1.0f; + if (this->walkingFrame >= 8.0f) { this->action = 12; - this->unk_26C = 0.0f; + this->walkingFrame = 0.0f; this->actor.velocity.y = -1.0f; } } @@ -923,7 +923,7 @@ void func_80AEC9C4(EnRu1* this) { void func_80AECA18(EnRu1* this) { if (!(this->actor.bgCheckFlags & 1)) { this->action = 13; - this->unk_26C = 0.0f; + this->walkingFrame = 0.0f; this->actor.velocity.y = 0.0f; } } @@ -1030,7 +1030,7 @@ void func_80AECE20(EnRu1* this, PlayState* play) { Vec3f* playerPos = &player->actor.world.pos; s16 shapeRotY = player->actor.shape.rot.y; s32 pad; - f32 unk_27C = this->unk_27C; + f32 unk_27C = this->xzDistToPlayerInBlueWarp; Vec3f* pos = &this->actor.world.pos; pos->x = (Math_SinS(shapeRotY) * unk_27C) + playerPos->x; @@ -1058,8 +1058,8 @@ s32 func_80AECF6C(EnRu1* this, PlayState* play) { f32 temp2; s32 pad2[5]; - this->unk_26C += 1.0f; - if ((player->actor.speedXZ == 0.0f) && (this->unk_26C >= 3.0f)) { + this->walkingFrame += 1.0f; + if ((player->actor.speedXZ == 0.0f) && (this->walkingFrame >= 3.0f)) { otherPlayer = GET_PLAYER(play); player->actor.world.pos.x = otherPlayer->unk_450.x; player->actor.world.pos.y = otherPlayer->unk_450.y; @@ -1114,7 +1114,7 @@ void func_80AED110(EnRu1* this) { void func_80AED154(EnRu1* this, PlayState* play) { if (func_80AED084(this, WARP_BLUE_RUTO_STATE_ENTERED)) { this->action = 0x13; - this->unk_26C = 0.0f; + this->walkingFrame = 0.0f; func_80AECEB4(this, play); } } @@ -1139,7 +1139,7 @@ void func_80AED218(EnRu1* this, UNK_TYPE arg1) { Animation_Change(&this->skelAnime, &gRutoChildWaitInBlueWarpAnim, 1.0f, 0, Animation_GetLastFrame(&gRutoChildWaitInBlueWarpAnim), ANIMMODE_ONCE, -8.0f); this->action = 21; - this->unk_27C = this->actor.xzDistToPlayer; + this->xzDistToPlayerInBlueWarp = this->actor.xzDistToPlayer; } } @@ -1294,28 +1294,28 @@ void func_80AED83C(EnRu1* this) { void func_80AED8DC(EnRu1* this) { s32 temp_hi; - s16* unk_2AC = &this->unk_2AC; + s16* unk_2AC = &this->headRotTimer; s16* someY = &this->interactInfo.headRot.y; - s16* unk_29E = &this->unk_29E; + s16* unk_29E = &this->headTurnSpeed; s32 pad[2]; if (DECR(*unk_2AC) == 0) { *unk_2AC = Rand_S16Offset(0xA, 0x19); temp_hi = *unk_2AC % 5; if (temp_hi == 0) { - this->unk_2B0 = 1; + this->headRotDirection = 1; } else if (temp_hi == 1) { - this->unk_2B0 = 2; + this->headRotDirection = 2; } else { - this->unk_2B0 = 0; + this->headRotDirection = 0; } *unk_29E = 0; } - if (this->unk_2B0 == 0) { + if (this->headRotDirection == 0) { Math_SmoothStepToS(unk_29E, 0 - *someY, 1, 0x190, 0x190); Math_SmoothStepToS(someY, 0, 3, ABS(*unk_29E), 0x64); - } else if (this->unk_2B0 == 1) { + } else if (this->headRotDirection == 1) { Math_SmoothStepToS(unk_29E, -0x2AAA - *someY, 1, 0x190, 0x190); Math_SmoothStepToS(someY, -0x2AAA, 3, ABS(*unk_29E), 0x64); } else { @@ -1458,13 +1458,13 @@ void func_80AEE050(EnRu1* this) { f32 temp_f10; EnRu1* thisx = this; // necessary to match - if (this->unk_350 == 0) { + if (this->waterState == 0) { if ((this->actor.minVelocityY == 0.0f) && (this->actor.speedXZ == 0.0f)) { - this->unk_350 = 1; + this->waterState = 1; func_80AEE02C(this); - this->unk_35C = 0; - this->unk_358 = (this->actor.yDistToWater - 10.0f) * 0.5f; - this->unk_354 = this->actor.world.pos.y + thisx->unk_358; // thisx only used here + this->bobPhase = 0; + this->bobDepth = (this->actor.yDistToWater - 10.0f) * 0.5f; + this->sinkingStartPosY = this->actor.world.pos.y + thisx->bobDepth; // thisx only used here } else { this->actor.gravity = 0.0f; this->actor.minVelocityY *= 0.2f; @@ -1482,23 +1482,23 @@ void func_80AEE050(EnRu1* this) { Actor_UpdatePos(&this->actor); } } else { - if (this->unk_350 == 1) { - if (this->unk_358 <= 1.0f) { + if (this->waterState == 1) { + if (this->bobDepth <= 1.0f) { func_80AEE02C(this); - this->unk_350 = 2; - this->unk_360 = 0.0f; + this->waterState = 2; + this->isSinking = 0.0f; } else { - sp28 = this->unk_358; - sp24 = this->unk_354; - temp_f10 = Math_CosS(this->unk_35C) * -sp28; + sp28 = this->bobDepth; + sp24 = this->sinkingStartPosY; + temp_f10 = Math_CosS(this->bobPhase) * -sp28; this->actor.world.pos.y = temp_f10 + sp24; - this->unk_35C += 0x3E8; - this->unk_358 *= 0.95f; + this->bobPhase += 0x3E8; + this->bobDepth *= 0.95f; } } else { - this->unk_360 += 1.0f; - if (this->unk_360 > 0.0f) { - this->unk_350 = 3; + this->isSinking += 1.0f; + if (this->isSinking > 0.0f) { + this->waterState = 3; } } } @@ -1591,7 +1591,7 @@ void func_80AEE568(EnRu1* this, PlayState* play) { func_80AEADD8(this); } else if (this->actor.yDistToWater > 0.0f) { this->action = 29; - this->unk_350 = 0; + this->waterState = 0; } } } @@ -1622,7 +1622,7 @@ s32 func_80AEE6D0(EnRu1* this, PlayState* play) { Animation_GetLastFrame(&gRutoChildSquirmAnim), ANIMMODE_LOOP, -8.0f); func_80AED600(this); this->action = 34; - this->unk_26C = 0.0f; + this->walkingFrame = 0.0f; play->csCtx.segment = &D_80AF1728; gSaveContext.cutsceneTrigger = 1; } @@ -1637,7 +1637,7 @@ void func_80AEE7C4(EnRu1* this, PlayState* play) { f32 frameCount; s32 pad[13]; Player* player; - f32* unk_370 = &this->unk_370; + f32* unk_370 = &this->carryIdleTimer; if (Actor_HasNoParent(&this->actor, play)) { frameCount = Animation_GetLastFrame(&gRutoChildSittingAnim); @@ -1660,7 +1660,7 @@ void func_80AEE7C4(EnRu1* this, PlayState* play) { player = GET_PLAYER(play); if (player->stateFlags2 & PLAYER_STATE2_IDLE_FIDGET) { - this->unk_370 += 1.0f; + this->carryIdleTimer += 1.0f; if (this->action != 32) { if (*unk_370 > 30.0f) { if (Rand_S16Offset(0, 3) == 0) { @@ -1699,7 +1699,7 @@ s32 func_80AEEAC8(EnRu1* this, PlayState* play) { } void func_80AEEB24(EnRu1* this, PlayState* play) { - if ((func_80AEEAC8(this, play) == 0) && (this->unk_350 == 3)) { + if ((func_80AEEAC8(this, play) == 0) && (this->waterState == 3)) { this->action = 30; func_80AEE02C(this); this->actor.gravity = -0.1f; @@ -2295,11 +2295,12 @@ s32 EnRu1_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p Gfx** gfx) { EnRu1* this = (EnRu1*)thisx; - if ((this->unk_290 < 0) || (this->unk_290 > 0) || (*sPreLimbDrawFuncs[this->unk_290] == NULL)) { + if ((this->preLimbDrawIndex < 0) || (this->preLimbDrawIndex > 0) || + (*sPreLimbDrawFuncs[this->preLimbDrawIndex] == NULL)) { // "Neck rotation mode is improper!" osSyncPrintf(VT_FGCOL(RED) "首回しモードがおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST); } else { - sPreLimbDrawFuncs[this->unk_290](this, play, limbIndex, rot); + sPreLimbDrawFuncs[this->preLimbDrawIndex](this, play, limbIndex, rot); } return false; } diff --git a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h index 59a553baed..f0d0ffe0fc 100644 --- a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h +++ b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h @@ -23,37 +23,37 @@ typedef struct EnRu1 { /* 0x0260 */ s16 mouthIndex; /* 0x0264 */ s32 action; /* 0x0268 */ s32 drawConfig; - /* 0x026C */ f32 unk_26C; - /* 0x0270 */ f32 unk_270; + /* 0x026C */ f32 walkingFrame; + /* 0x0270 */ f32 treadTimer; /* 0x0274 */ char unk_274[0x4]; /* 0x0278 */ DoorWarp1* blueWarp; - /* 0x027C */ f32 unk_27C; - /* 0x0280 */ s32 unk_280; + /* 0x027C */ f32 xzDistToPlayerInBlueWarp; + /* 0x0280 */ s32 isFalling; /* 0x0284 */ s8 roomNum1; /* 0x0285 */ s8 roomNum2; /* 0x0286 */ s8 roomNum3; /* 0x0288 */ f32 unk_288; /* 0x028C */ BgBdanObjects* unk_28C; - /* 0x0290 */ s32 unk_290; + /* 0x0290 */ s32 preLimbDrawIndex; /* 0x0294 */ char unk_294[0x4]; /* 0x0298 */ s32 unk_298; /* 0x029C */ char unk_29C[0x2]; - /* 0x029E */ s16 unk_29E; + /* 0x029E */ s16 headTurnSpeed; /* 0x02A0 */ char unk_2A0[0x4]; /* 0x02A4 */ f32 unk_2A4; /* 0x02A8 */ s32 alpha; - /* 0x02AC */ s16 unk_2AC; - /* 0x02B0 */ s32 unk_2B0; + /* 0x02AC */ s16 headRotTimer; + /* 0x02B0 */ s32 headRotDirection; /* 0x02B4 */ ColliderCylinder collider; /* 0x0300 */ ColliderCylinder collider2; - /* 0x034C */ s32 unk_34C; - /* 0x0350 */ s32 unk_350; - /* 0x0354 */ f32 unk_354; - /* 0x0358 */ f32 unk_358; - /* 0x035C */ s16 unk_35C; - /* 0x0360 */ f32 unk_360; - /* 0x0364 */ Vec3f unk_364; - /* 0x0370 */ f32 unk_370; + /* 0x034C */ s32 isSittingOCActive; + /* 0x0350 */ s32 waterState; + /* 0x0354 */ f32 sinkingStartPosY; + /* 0x0358 */ f32 bobDepth; + /* 0x035C */ s16 bobPhase; + /* 0x0360 */ f32 isSinking; + /* 0x0364 */ Vec3f treadStartPos; + /* 0x0370 */ f32 carryIdleTimer; /* 0x0374 */ NpcInteractInfo interactInfo; } EnRu1; // size = 0x039C diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index 527768b80a..7475283b94 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -144,7 +144,7 @@ s16 func_80AF5560(EnSa* this, PlayState* play) { return textState; } -u16 func_80AF55E0(PlayState* play, Actor* thisx) { +u16 EnSa_GetTextId(PlayState* play, Actor* thisx) { EnSa* this = (EnSa*)thisx; u16 reaction = Text_GetFaceReaction(play, 0x10); @@ -187,7 +187,7 @@ u16 func_80AF55E0(PlayState* play, Actor* thisx) { return 0x1001; } -s16 func_80AF56F4(PlayState* play, Actor* thisx) { +s16 EnSa_UpdateTalkState(PlayState* play, Actor* thisx) { s16 ret = NPC_TALK_STATE_TALKING; EnSa* this = (EnSa*)thisx; @@ -230,7 +230,7 @@ void func_80AF57D8(EnSa* this, PlayState* play) { ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x1555 || this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 30.0f, - func_80AF55E0, func_80AF56F4); + EnSa_GetTextId, EnSa_UpdateTalkState); } } diff --git a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c index b7612dd917..e8dcebae7f 100644 --- a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c +++ b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c @@ -205,7 +205,7 @@ void func_80AFCD60(EnSkb* this) { void func_80AFCDF8(EnSkb* this) { Animation_PlayOnceSetSpeed(&this->skelAnime, &gStalchildUncurlingAnim, 1.0f); - this->unk_280 = 0; + this->actionState = 0; this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_APPEAR); EnSkb_SetupAction(this, func_80AFCE5C); @@ -231,8 +231,8 @@ void func_80AFCE5C(EnSkb* this, PlayState* play) { void func_80AFCF48(EnSkb* this) { Animation_Change(&this->skelAnime, &gStalchildUncurlingAnim, -1.0f, Animation_GetLastFrame(&gStalchildUncurlingAnim), 0.0f, ANIMMODE_ONCE, -4.0f); - this->unk_280 = 0; - this->unk_281 = 0; + this->actionState = 0; + this->setColliderAT = 0; this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; this->actor.speedXZ = 0.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); @@ -253,8 +253,8 @@ void func_80AFCFF0(EnSkb* this, PlayState* play) { void func_80AFD0A4(EnSkb* this) { Animation_Change(&this->skelAnime, &gStalchildWalkingAnim, 0.96000004f, 0.0f, Animation_GetLastFrame(&gStalchildWalkingAnim), ANIMMODE_LOOP, -4.0f); - this->unk_280 = 4; - this->unk_288 = 0; + this->actionState = 4; + this->headlessYawOffset = 0; this->actor.speedXZ = this->actor.scale.y * 160.0f; EnSkb_SetupAction(this, EnSkb_Advance); } @@ -265,10 +265,10 @@ void EnSkb_Advance(EnSkb* this, PlayState* play) { f32 playSpeed; Player* player = GET_PLAYER(play); - if ((this->unk_283 != 0) && ((play->gameplayFrames & 0xF) == 0)) { - this->unk_288 = Rand_CenteredFloat(50000.0f); + if ((this->breakFlags != 0) && ((play->gameplayFrames & 0xF) == 0)) { + this->headlessYawOffset = Rand_CenteredFloat(50000.0f); } - Math_SmoothStepToS(&this->actor.shape.rot.y, (this->actor.yawTowardsPlayer + this->unk_288), 1, 0x2EE, 0); + Math_SmoothStepToS(&this->actor.shape.rot.y, (this->actor.yawTowardsPlayer + this->headlessYawOffset), 1, 0x2EE, 0); this->actor.world.rot.y = this->actor.shape.rot.y; thisKeyFrame = this->skelAnime.curFrame; SkelAnime_Update(&this->skelAnime); @@ -305,7 +305,7 @@ void func_80AFD33C(EnSkb* this) { Animation_Change(&this->skelAnime, &gStalchildAttackingAnim, 0.6f, 0.0f, Animation_GetLastFrame(&gStalchildAttackingAnim), ANIMMODE_ONCE_INTERP, 4.0f); this->collider.base.atFlags &= ~4; - this->unk_280 = 3; + this->actionState = 3; this->actor.speedXZ = 0.0f; EnSkb_SetupAction(this, EnSkb_SetupAttack); } @@ -316,9 +316,9 @@ void EnSkb_SetupAttack(EnSkb* this, PlayState* play) { frameData = this->skelAnime.curFrame; if (frameData == 3) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); - this->unk_281 = 1; + this->setColliderAT = 1; } else if (frameData == 6) { - this->unk_281 = 0; + this->setColliderAT = 0; } if (this->collider.base.atFlags & 4) { this->collider.base.atFlags &= ~6; @@ -332,8 +332,8 @@ void func_80AFD47C(EnSkb* this) { Animation_Change(&this->skelAnime, &gStalchildAttackingAnim, -0.4f, this->skelAnime.curFrame - 1.0f, 0.0f, ANIMMODE_ONCE_INTERP, 0.0f); this->collider.base.atFlags &= ~4; - this->unk_280 = 5; - this->unk_281 = 0; + this->actionState = 5; + this->setColliderAT = 0; EnSkb_SetupAction(this, func_80AFD508); } @@ -348,8 +348,8 @@ void EnSkb_SetupStunned(EnSkb* this) { this->actor.speedXZ = 0.0f; } Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE); - this->unk_281 = 0; - this->unk_280 = 6; + this->setColliderAT = 0; + this->actionState = 6; EnSkb_SetupAction(this, func_80AFD59C); } @@ -378,7 +378,7 @@ void func_80AFD644(EnSkb* this) { } this->actor.world.rot.y = this->actor.yawTowardsPlayer; Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); - this->unk_280 = 2; + this->actionState = 2; EnSkb_SetupAction(this, func_80AFD6CC); } @@ -386,10 +386,10 @@ void func_80AFD6CC(EnSkb* this, PlayState* play) { // this cast is likely not real, but allows for a match u8* new_var; - new_var = &this->unk_283; - if ((this->unk_283 != 1) || BodyBreak_SpawnParts(&this->actor, &this->bodyBreak, play, 1)) { + new_var = &this->breakFlags; + if ((this->breakFlags != 1) || BodyBreak_SpawnParts(&this->actor, &this->bodyBreak, play, 1)) { if ((*new_var) != 0) { - this->unk_283 = (*new_var) | 2; + this->breakFlags = (*new_var) | 2; } if (this->actor.bgCheckFlags & 2) { this->actor.speedXZ = 0; @@ -414,10 +414,10 @@ void func_80AFD7B4(EnSkb* this, PlayState* play) { if (this->actor.bgCheckFlags & 1) { this->actor.speedXZ = -6.0f; } - this->unk_280 = 1; + this->actionState = 1; this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; BodyBreak_Alloc(&this->bodyBreak, 18, play); - this->unk_283 |= 4; + this->breakFlags |= 4; EffectSsDeadSound_SpawnStationary(play, &this->actor.projectedPos, NA_SE_EN_STALKID_DEAD, 1, 1, 0x28); EnSkb_SetupAction(this, func_80AFD880); GameInteractor_ExecuteOnEnemyDefeat(&this->actor); @@ -435,7 +435,7 @@ void func_80AFD880(EnSkb* this, PlayState* play) { Item_DropCollectible(play, &this->actor.world.pos, ITEM00_RUPEE_RED); } - this->unk_283 |= 8; + this->breakFlags |= 8; Actor_Kill(&this->actor); } } @@ -448,19 +448,19 @@ void func_80AFD968(EnSkb* this, PlayState* play) { s16 phi_v1; Player* player; - if ((this->unk_280 != 1) && (this->actor.bgCheckFlags & 0x60) && (this->actor.yDistToWater >= 40.0f)) { + if ((this->actionState != 1) && (this->actor.bgCheckFlags & 0x60) && (this->actor.yDistToWater >= 40.0f)) { this->actor.colChkInfo.health = 0; - this->unk_281 = 0; + this->setColliderAT = 0; func_80AFD7B4(this, play); - } else if (this->unk_280 >= 3) { + } else if (this->actionState >= 3) { if ((this->collider.base.acFlags & 2) != 0) { this->collider.base.acFlags &= ~2; if (this->actor.colChkInfo.damageEffect != 6) { - this->unk_282 = this->actor.colChkInfo.damageEffect; + this->lastDamageReaction = this->actor.colChkInfo.damageEffect; Actor_SetDropFlag(&this->actor, &this->collider.elements[1].info, 1); - this->unk_281 = 0; + this->setColliderAT = 0; if (this->actor.colChkInfo.damageEffect == 1) { - if (this->unk_280 != 6) { + if (this->actionState != 6) { Actor_SetColorFilter(&this->actor, 0, 0x78, 0, 0x50); Actor_ApplyDamage(&this->actor); EnSkb_SetupStunned(this); @@ -484,13 +484,13 @@ void func_80AFD968(EnSkb* this, PlayState* play) { return; } player = GET_PLAYER(play); - if (this->unk_283 == 0) { + if (this->breakFlags == 0) { if ((this->actor.colChkInfo.damageEffect == 0xD) || ((this->actor.colChkInfo.damageEffect == 0xE) && ((player->meleeWeaponAnimation >= 4 && player->meleeWeaponAnimation <= 11) || (player->meleeWeaponAnimation == 20 || player->meleeWeaponAnimation == 21)))) { BodyBreak_Alloc(&this->bodyBreak, 2, play); - this->unk_283 = 1; + this->breakFlags = 1; } } func_80AFD644(this); @@ -510,11 +510,11 @@ void EnSkb_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += (3000.0f * this->actor.scale.y); - if (this->unk_281 != 0) { + if (this->setColliderAT != 0) { CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); } - if (this->unk_280 >= 3) { + if (this->actionState >= 3) { if ((this->actor.colorFilterTimer == 0) || ((this->actor.colorFilterParams & 0x4000) == 0)) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); @@ -529,7 +529,7 @@ s32 EnSkb_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p s16 pad[2]; if (limbIndex == 11) { - if ((this->unk_283 & 2) == 0) { + if ((this->breakFlags & 2) == 0) { OPEN_DISPS(play->state.gfxCtx); color = ABS((s16)(Math_SinS((play->gameplayFrames * 0x1770)) * 95.0f)) + 160; gDPPipeSync(POLY_OPA_DISP++); @@ -538,7 +538,7 @@ s32 EnSkb_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p } else { *dList = NULL; } - } else if ((limbIndex == 12) && ((this->unk_283 & 2) != 0)) { + } else if ((limbIndex == 12) && ((this->breakFlags & 2) != 0)) { *dList = NULL; } return 0; @@ -549,9 +549,9 @@ void EnSkb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Collider_UpdateSpheres(limbIndex, &this->collider); - if ((this->unk_283 ^ 1) == 0) { + if ((this->breakFlags ^ 1) == 0) { BodyBreak_SetInfo(&this->bodyBreak, limbIndex, 11, 12, 18, dList, BODYBREAK_OBJECT_DEFAULT); - } else if ((this->unk_283 ^ (this->unk_283 | 4)) == 0) { + } else if ((this->breakFlags ^ (this->breakFlags | 4)) == 0) { BodyBreak_SetInfo(&this->bodyBreak, limbIndex, 0, 18, 18, dList, BODYBREAK_OBJECT_DEFAULT); } } diff --git a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.h b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.h index 002ff0a187..d8d21a3730 100644 --- a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.h +++ b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.h @@ -13,12 +13,12 @@ typedef struct EnSkb { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ Vec3s jointTable[20]; /* 0x0208 */ Vec3s morphTable[20]; - /* 0x0280 */ u8 unk_280; - /* 0x0281 */ u8 unk_281; - /* 0x0282 */ u8 unk_282; - /* 0x0283 */ u8 unk_283; + /* 0x0280 */ u8 actionState; + /* 0x0281 */ u8 setColliderAT; + /* 0x0282 */ u8 lastDamageReaction; + /* 0x0283 */ u8 breakFlags; /* 0x0284 */ EnSkbActionFunc actionFunc; - /* 0x0288 */ s16 unk_288; + /* 0x0288 */ s16 headlessYawOffset; /* 0x028C */ BodyBreak bodyBreak; /* 0x02A4 */ ColliderJntSph collider; /* 0x02C4 */ ColliderJntSphElement colliderItem[2]; diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c b/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c index 25e25339c1..69c1c2f2e5 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c @@ -17,16 +17,16 @@ void EnSyatekiNiw_Destroy(Actor* thisx, PlayState* play); void EnSyatekiNiw_Update(Actor* thisx, PlayState* play); void EnSyatekiNiw_Draw(Actor* thisx, PlayState* play); -void func_80B11DEC(EnSyatekiNiw* this, PlayState* play); -void func_80B132A8(EnSyatekiNiw* this, PlayState* play); -void func_80B129EC(EnSyatekiNiw* this, PlayState* play); -void func_80B13464(EnSyatekiNiw* this, PlayState* play); -void func_80B123A8(EnSyatekiNiw* this, PlayState* play); -void func_80B11E78(EnSyatekiNiw* this, PlayState* play); -void func_80B12460(EnSyatekiNiw* this, PlayState* play); -void func_80B128D8(EnSyatekiNiw* this, PlayState* play); +void EnSyatekiNiw_SetupDefault(EnSyatekiNiw* this, PlayState* play); +void EnSyatekiNiw_UpdateEffects(EnSyatekiNiw* this, PlayState* play); +void EnSyatekiNiw_Remove(EnSyatekiNiw* this, PlayState* play); +void EnSyatekiNiw_DrawEffects(EnSyatekiNiw* this, PlayState* play); +void EnSyatekiNiw_SetupArchery(EnSyatekiNiw* this, PlayState* play); +void EnSyatekiNiw_Default(EnSyatekiNiw* this, PlayState* play); +void EnSyatekiNiw_Archery(EnSyatekiNiw* this, PlayState* play); +void EnSyatekiNiw_ExitArchery(EnSyatekiNiw* this, PlayState* play); -void func_80B131B8(EnSyatekiNiw* this, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4); +void EnSyatekiNiw_SpawnFeather(EnSyatekiNiw* this, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4); const ActorInit En_Syateki_Niw_InitVars = { ACTOR_EN_SYATEKI_NIW, @@ -75,14 +75,14 @@ void EnSyatekiNiw_Init(Actor* thisx, PlayState* play) { ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); SkelAnime_InitFlex(play, &this->skelAnime, &gCuccoSkel, &gCuccoAnim, this->jointTable, this->morphTable, 16); - this->unk_29E = this->actor.params; - if (this->unk_29E < 0) { - this->unk_29E = 0; + this->minigameType = this->actor.params; + if (this->minigameType < 0) { + this->minigameType = 0; } Collider_InitCylinder(play, &this->collider); Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); - if (this->unk_29E == 0) { + if (this->minigameType == 0) { osSyncPrintf("\n\n"); // "Archery range chicken" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 射的場鶏 ☆☆☆☆☆ \n" VT_RST); @@ -95,9 +95,9 @@ void EnSyatekiNiw_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 0.01f); } - this->unk_2DC = this->actor.world.pos; - this->unk_2E8 = this->actor.world.pos; - this->actionFunc = func_80B11DEC; + this->initPos = this->actor.world.pos; + this->targetPos = this->actor.world.pos; + this->actionFunc = EnSyatekiNiw_SetupDefault; } void EnSyatekiNiw_Destroy(Actor* thisx, PlayState* play) { @@ -108,120 +108,120 @@ void EnSyatekiNiw_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -void func_80B11A94(EnSyatekiNiw* this, PlayState* play, s16 arg2) { - if (this->unk_254 == 0) { +void EnSyatekiNiw_UpdateRotations(EnSyatekiNiw* this, PlayState* play, s16 arg2) { + if (this->peckTimer == 0) { if (arg2 == 0) { - this->unk_264 = 0.0f; + this->headRotXTarget = 0.0f; } else { - this->unk_264 = -10000.0f; + this->headRotXTarget = -10000.0f; } - this->unk_28E += 1; - this->unk_254 = 3; - if (!(this->unk_28E & 1)) { - this->unk_264 = 0.0f; + this->headRotXState += 1; + this->peckTimer = 3; + if (!(this->headRotXState & 1)) { + this->headRotXTarget = 0.0f; if (arg2 == 0) { - this->unk_254 = Rand_ZeroFloat(30.0f); + this->peckTimer = Rand_ZeroFloat(30.0f); } } } - if (this->unk_258 == 0) { - this->unk_292++; - this->unk_292 &= 1; + if (this->flapTimer == 0) { + this->wingsRotState++; + this->wingsRotState &= 1; switch (arg2) { case 0: - this->unk_26C = 0.0f; - this->unk_268 = 0.0f; + this->leftWingRotXTarget = 0.0f; + this->rightWingRotXTarget = 0.0f; break; case 1: - this->unk_258 = 3; - this->unk_26C = 7000.0f; - this->unk_268 = 7000.0f; - if (this->unk_292 == 0) { - this->unk_26C = 0.0f; - this->unk_268 = 0.0f; + this->flapTimer = 3; + this->leftWingRotXTarget = 7000.0f; + this->rightWingRotXTarget = 7000.0f; + if (this->wingsRotState == 0) { + this->leftWingRotXTarget = 0.0f; + this->rightWingRotXTarget = 0.0f; } break; case 2: - this->unk_258 = 2; - this->unk_268 = this->unk_26C = -10000.0f; - this->unk_280 = this->unk_278 = 25000.0f; - this->unk_284 = this->unk_27C = 6000.0f; - if (this->unk_292 == 0) { - this->unk_278 = 8000.0f; - this->unk_280 = 8000.0f; + this->flapTimer = 2; + this->rightWingRotXTarget = this->leftWingRotXTarget = -10000.0f; + this->leftWingRotYTarget = this->rightWingRotYTarget = 25000.0f; + this->leftWingRotZTarget = this->rightWingRotZTarget = 6000.0f; + if (this->wingsRotState == 0) { + this->rightWingRotYTarget = 8000.0f; + this->leftWingRotYTarget = 8000.0f; } break; case 3: - this->unk_258 = 2; - this->unk_278 = 10000.0f; - this->unk_280 = 10000.0f; - if (this->unk_292 == 0) { - this->unk_278 = 3000.0f; - this->unk_280 = 3000.0f; + this->flapTimer = 2; + this->rightWingRotYTarget = 10000.0f; + this->leftWingRotYTarget = 10000.0f; + if (this->wingsRotState == 0) { + this->rightWingRotYTarget = 3000.0f; + this->leftWingRotYTarget = 3000.0f; } break; case 4: - this->unk_254 = this->unk_256 = 5; + this->peckTimer = this->timer1 = 5; break; case 5: - this->unk_258 = 5; - this->unk_278 = 14000.0f; - this->unk_280 = 14000.0f; - if (this->unk_292 == 0) { - this->unk_278 = 10000.0f; - this->unk_280 = 10000.0f; + this->flapTimer = 5; + this->rightWingRotYTarget = 14000.0f; + this->leftWingRotYTarget = 14000.0f; + if (this->wingsRotState == 0) { + this->rightWingRotYTarget = 10000.0f; + this->leftWingRotYTarget = 10000.0f; } break; } } - if (this->unk_264 != this->unk_2BC.x) { - Math_ApproachF(&this->unk_2BC.x, this->unk_264, 0.5f, 4000.0f); + if (this->headRotXTarget != this->headRot.x) { + Math_ApproachF(&this->headRot.x, this->headRotXTarget, 0.5f, 4000.0f); } - if (this->unk_26C != this->unk_2A4.x) { - Math_ApproachF(&this->unk_2A4.x, this->unk_26C, 0.8f, 7000.0f); + if (this->leftWingRotXTarget != this->leftWingRot.x) { + Math_ApproachF(&this->leftWingRot.x, this->leftWingRotXTarget, 0.8f, 7000.0f); } - if (this->unk_280 != this->unk_2A4.y) { - Math_ApproachF(&this->unk_2A4.y, this->unk_280, 0.8f, 7000.0f); + if (this->leftWingRotYTarget != this->leftWingRot.y) { + Math_ApproachF(&this->leftWingRot.y, this->leftWingRotYTarget, 0.8f, 7000.0f); } - if (this->unk_284 != this->unk_2A4.z) { - Math_ApproachF(&this->unk_2A4.z, this->unk_284, 0.8f, 7000.0f); + if (this->leftWingRotZTarget != this->leftWingRot.z) { + Math_ApproachF(&this->leftWingRot.z, this->leftWingRotZTarget, 0.8f, 7000.0f); } - if (this->unk_268 != this->unk_2B0.x) { - Math_ApproachF(&this->unk_2B0.x, this->unk_268, 0.8f, 7000.0f); + if (this->rightWingRotXTarget != this->rightWingRot.x) { + Math_ApproachF(&this->rightWingRot.x, this->rightWingRotXTarget, 0.8f, 7000.0f); } - if (this->unk_278 != this->unk_2B0.y) { - Math_ApproachF(&this->unk_2B0.y, this->unk_278, 0.8f, 7000.0f); + if (this->rightWingRotYTarget != this->rightWingRot.y) { + Math_ApproachF(&this->rightWingRot.y, this->rightWingRotYTarget, 0.8f, 7000.0f); } - if (this->unk_27C != this->unk_2B0.z) { - Math_ApproachF(&this->unk_2B0.z, this->unk_27C, 0.8f, 7000.0f); + if (this->rightWingRotZTarget != this->rightWingRot.z) { + Math_ApproachF(&this->rightWingRot.z, this->rightWingRotZTarget, 0.8f, 7000.0f); } } -void func_80B11DEC(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_SetupDefault(EnSyatekiNiw* this, PlayState* play) { Animation_Change(&this->skelAnime, &gCuccoAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gCuccoAnim), ANIMMODE_LOOP, -10.0f); - if (this->unk_29E != 0) { - Actor_SetScale(&this->actor, this->unk_2F4); + if (this->minigameType != 0) { + Actor_SetScale(&this->actor, this->scale); } - this->actionFunc = func_80B11E78; + this->actionFunc = EnSyatekiNiw_Default; } -void func_80B11E78(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_Default(EnSyatekiNiw* this, PlayState* play) { Vec3f dustVelocity = { 0.0f, 0.0f, 0.0f }; Vec3f dustAccel = { 0.0f, 0.2f, 0.0f }; Color_RGBA8 dustPrimColor = { 0, 0, 0, 255 }; @@ -233,20 +233,20 @@ void func_80B11E78(EnSyatekiNiw* this, PlayState* play) { f32 tmpf1; s16 sp4A; - if ((this->unk_29C != 0) && (this->unk_29E == 0) && (this->actor.bgCheckFlags & 1)) { - this->unk_29C = 0; - this->actionFunc = func_80B123A8; + if ((this->archeryState != 0) && (this->minigameType == 0) && (this->actor.bgCheckFlags & 1)) { + this->archeryState = 0; + this->actionFunc = EnSyatekiNiw_SetupArchery; return; } sp4A = 0; - if ((this->unk_25E == 0) && (this->unk_25C == 0)) { - this->unk_294++; - if (this->unk_294 >= 8) { - this->unk_25E = Rand_ZeroFloat(30.0f); - this->unk_294 = Rand_ZeroFloat(3.99f); + if ((this->movementTimer == 0) && (this->hopTimer == 0)) { + this->targetPosTimer++; + if (this->targetPosTimer >= 8) { + this->movementTimer = Rand_ZeroFloat(30.0f); + this->targetPosTimer = Rand_ZeroFloat(3.99f); - switch (this->unk_29E) { + switch (this->minigameType) { case 0: sp50 = Rand_CenteredFloat(100.0f); if (sp50 < 0.0f) { @@ -262,23 +262,23 @@ void func_80B11E78(EnSyatekiNiw* this, PlayState* play) { sp4C += 100.0f; } - this->unk_2E8.x = this->unk_2DC.x + sp50; - this->unk_2E8.z = this->unk_2DC.z + sp4C; + this->targetPos.x = this->initPos.x + sp50; + this->targetPos.z = this->initPos.z + sp4C; - if (this->unk_2E8.x < -150.0f) { - this->unk_2E8.x = -150.0f; + if (this->targetPos.x < -150.0f) { + this->targetPos.x = -150.0f; } - if (this->unk_2E8.x > 150.0f) { - this->unk_2E8.x = 150.0f; + if (this->targetPos.x > 150.0f) { + this->targetPos.x = 150.0f; } - if (this->unk_2E8.z < -60.0f) { - this->unk_2E8.z = -60.0f; + if (this->targetPos.z < -60.0f) { + this->targetPos.z = -60.0f; } - if (this->unk_2E8.z > -40.0f) { - this->unk_2E8.z = -40.0f; + if (this->targetPos.z > -40.0f) { + this->targetPos.z = -40.0f; } break; @@ -297,28 +297,28 @@ void func_80B11E78(EnSyatekiNiw* this, PlayState* play) { sp4C += 30.0f; } - this->unk_2E8.x = this->unk_2DC.x + sp50; - this->unk_2E8.z = this->unk_2DC.z + sp4C; + this->targetPos.x = this->initPos.x + sp50; + this->targetPos.z = this->initPos.z + sp4C; break; } } else { - this->unk_25C = 4; + this->hopTimer = 4; if (this->actor.bgCheckFlags & 1) { this->actor.velocity.y = 2.5f; - if ((Rand_ZeroFloat(10.0f) < 1.0f) && (this->unk_29E == 0)) { - this->unk_25C = 0xC; + if ((Rand_ZeroFloat(10.0f) < 1.0f) && (this->minigameType == 0)) { + this->hopTimer = 0xC; this->actor.velocity.y = 10.0f; } } } } - if (this->unk_25C != 0) { + if (this->hopTimer != 0) { sp4A = 1; - Math_ApproachF(&this->actor.world.pos.x, this->unk_2E8.x, 1.0f, this->unk_2C8.y); - Math_ApproachF(&this->actor.world.pos.z, this->unk_2E8.z, 1.0f, this->unk_2C8.y); - Math_ApproachF(&this->unk_2C8.y, 3.0f, 1.0f, 0.3f); - tmpf1 = this->unk_2E8.x - this->actor.world.pos.x; - tmpf2 = this->unk_2E8.z - this->actor.world.pos.z; + Math_ApproachF(&this->actor.world.pos.x, this->targetPos.x, 1.0f, this->posRotStep.y); + Math_ApproachF(&this->actor.world.pos.z, this->targetPos.z, 1.0f, this->posRotStep.y); + Math_ApproachF(&this->posRotStep.y, 3.0f, 1.0f, 0.3f); + tmpf1 = this->targetPos.x - this->actor.world.pos.x; + tmpf2 = this->targetPos.z - this->actor.world.pos.z; if (fabsf(tmpf1) < 10.0f) { tmpf1 = 0; @@ -329,17 +329,17 @@ void func_80B11E78(EnSyatekiNiw* this, PlayState* play) { } if ((tmpf1 == 0.0f) && (tmpf2 == 0.0f)) { - this->unk_25C = 0; - this->unk_294 = 7; + this->hopTimer = 0; + this->targetPosTimer = 7; } - Math_SmoothStepToS(&this->actor.world.rot.y, Math_FAtan2F(tmpf1, tmpf2) * (0x8000 / M_PI), 3, this->unk_2C8.z, - 0); - Math_ApproachF(&this->unk_2C8.z, 10000.0f, 1.0f, 1000.0f); + Math_SmoothStepToS(&this->actor.world.rot.y, Math_FAtan2F(tmpf1, tmpf2) * (0x8000 / M_PI), 3, + this->posRotStep.z, 0); + Math_ApproachF(&this->posRotStep.z, 10000.0f, 1.0f, 1000.0f); } - if (this->unk_260 == 0) { - func_80B11A94(this, play, sp4A); + if (this->sootTimer == 0) { + EnSyatekiNiw_UpdateRotations(this, play, sp4A); return; } @@ -351,54 +351,54 @@ void func_80B11E78(EnSyatekiNiw* this, PlayState* play) { } } -void func_80B123A8(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_SetupArchery(EnSyatekiNiw* this, PlayState* play) { Animation_Change(&this->skelAnime, &gCuccoAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gCuccoAnim), ANIMMODE_LOOP, -10.0f); - this->unk_27C = 6000.0f; - this->unk_288 = -10000.0f; - this->unk_2B0.z = 6000.0f; - this->unk_2B0.y = 10000.0f; - this->actionFunc = func_80B12460; - this->unk_2A4.z = 6000.0f; - this->unk_284 = 6000.0f; - this->unk_2B0.x = -10000.0f; - this->unk_268 = -10000.0f; - this->unk_2A4.y = -10000.0f; - this->unk_2A4.x = -10000.0f; - this->unk_26C = -10000.0f; + this->rightWingRotZTarget = 6000.0f; + this->unkArcheryFloat = -10000.0f; + this->rightWingRot.z = 6000.0f; + this->rightWingRot.y = 10000.0f; + this->actionFunc = EnSyatekiNiw_Archery; + this->leftWingRot.z = 6000.0f; + this->leftWingRotZTarget = 6000.0f; + this->rightWingRot.x = -10000.0f; + this->rightWingRotXTarget = -10000.0f; + this->leftWingRot.y = -10000.0f; + this->leftWingRot.x = -10000.0f; + this->leftWingRotXTarget = -10000.0f; } -void func_80B12460(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_Archery(EnSyatekiNiw* this, PlayState* play) { Player* player = GET_PLAYER(play); f32 phi_f16 = 0.0f; player->actor.freezeTimer = 10; - switch (this->unk_29A) { + switch (this->archeryState) { case 0: - this->unk_296 = 2; - this->unk_2C8.y = 0.0f; - this->unk_29A = 1; + this->archeryAnimationType = 2; + this->posRotStep.y = 0.0f; + this->archeryState = 1; break; case 1: this->actor.speedXZ = 2.0f; - if (this->unk_25C == 0) { - this->unk_25C = 3; + if (this->hopTimer == 0) { + this->hopTimer = 3; this->actor.velocity.y = 3.5f; } - if (this->unk_25A == 0) { - this->unk_298++; - this->unk_298 &= 1; - this->unk_25A = 5; + if (this->archeryTimer == 0) { + this->rotYFlip++; + this->rotYFlip &= 1; + this->archeryTimer = 5; } - phi_f16 = (this->unk_298 == 0) ? 5000.0f : -5000.0f; + phi_f16 = (this->rotYFlip == 0) ? 5000.0f : -5000.0f; if (this->actor.world.pos.z > 100.0f) { this->actor.speedXZ = 2.0f; this->actor.gravity = -0.3f; this->actor.velocity.y = 5.0f; - this->unk_29A = 2; + this->archeryState = 2; } break; @@ -410,71 +410,71 @@ void func_80B12460(EnSyatekiNiw* this, PlayState* play) { if ((this->actor.bgCheckFlags & 1) && (this->actor.world.pos.z > 110.0f)) { this->actor.velocity.y = 0.0f; this->actor.gravity = 0.0f; - this->unk_284 = 0.0f; - this->unk_27C = 0.0f; - this->unk_278 = 0.0f; - this->unk_280 = 0.0f; - this->unk_288 = 0.0f; + this->leftWingRotZTarget = 0.0f; + this->rightWingRotZTarget = 0.0f; + this->rightWingRotYTarget = 0.0f; + this->leftWingRotYTarget = 0.0f; + this->unkArcheryFloat = 0.0f; this->actor.speedXZ = 0.5f; - this->unk_254 = this->unk_256 = 0; - this->unk_28E = this->unk_290 = 0; - this->unk_296 = 1; - this->unk_29A = 3; + this->peckTimer = this->timer1 = 0; + this->headRotXState = this->unk_290 = 0; + this->archeryAnimationType = 1; + this->archeryState = 3; } break; case 3: if ((player->actor.world.pos.z - 50.0f) < this->actor.world.pos.z) { this->actor.speedXZ = 0.0f; - this->unk_262 = 0x3C; - this->unk_25A = 0x14; - this->unk_264 = 10000.0f; - this->unk_29A = 4; + this->cluckTimer = 0x3C; + this->archeryTimer = 0x14; + this->headRotXTarget = 10000.0f; + this->archeryState = 4; } break; case 4: - if (this->unk_25A == 0) { - this->unk_296 = 4; - this->unk_264 = 5000.0f; - this->unk_26C = 0.0f; - this->unk_268 = 0.0f; - this->unk_284 = 0.0f; - this->unk_27C = 0.0f; - this->unk_280 = 14000.0f; - this->unk_278 = 14000.0f; + if (this->archeryTimer == 0) { + this->archeryAnimationType = 4; + this->headRotXTarget = 5000.0f; + this->leftWingRotXTarget = 0.0f; + this->rightWingRotXTarget = 0.0f; + this->leftWingRotZTarget = 0.0f; + this->rightWingRotZTarget = 0.0f; + this->leftWingRotYTarget = 14000.0f; + this->rightWingRotYTarget = 14000.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_M); - this->unk_254 = this->unk_256 = this->unk_25A = 0x1E; - this->unk_29A = 5; + this->peckTimer = this->timer1 = this->archeryTimer = 0x1E; + this->archeryState = 5; } break; case 5: - if (this->unk_25A == 1) { - this->unk_258 = 0; - this->unk_296 = 5; - this->unk_256 = this->unk_258; - this->unk_254 = this->unk_258; + if (this->archeryTimer == 1) { + this->flapTimer = 0; + this->archeryAnimationType = 5; + this->timer1 = this->flapTimer; + this->peckTimer = this->flapTimer; this->actor.speedXZ = 1.0f; } - if ((this->unk_25A == 0) && ((player->actor.world.pos.z - 30.0f) < this->actor.world.pos.z)) { + if ((this->archeryTimer == 0) && ((player->actor.world.pos.z - 30.0f) < this->actor.world.pos.z)) { Audio_PlaySoundGeneral(NA_SE_VO_LI_DOWN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - this->unk_25E = 0x14; - this->unk_29A = 6; + this->movementTimer = 0x14; + this->archeryState = 6; this->actor.speedXZ = 0.0f; } break; case 6: - if (this->unk_25E == 1) { + if (this->movementTimer == 1) { play->transitionTrigger = TRANS_TRIGGER_START; play->nextEntranceIndex = gSaveContext.entranceIndex; play->shootingGalleryStatus = 0; player->actor.freezeTimer = 20; - this->unk_25E = 0x14; - this->actionFunc = func_80B128D8; + this->movementTimer = 0x14; + this->actionFunc = EnSyatekiNiw_ExitArchery; } break; } @@ -484,93 +484,93 @@ void func_80B12460(EnSyatekiNiw* this, PlayState* play) { player->actor.world.pos.z - this->actor.world.pos.z) * (0x8000 / M_PI)) + phi_f16, - 5, this->unk_2C8.y, 0); - Math_ApproachF(&this->unk_2C8.y, 3000.0f, 1.0f, 500.0f); - if (this->unk_296 == 2) { - this->unk_256 = 10; - this->unk_254 = this->unk_256; + 5, this->posRotStep.y, 0); + Math_ApproachF(&this->posRotStep.y, 3000.0f, 1.0f, 500.0f); + if (this->archeryAnimationType == 2) { + this->timer1 = 10; + this->peckTimer = this->timer1; } - func_80B11A94(this, play, this->unk_296); + EnSyatekiNiw_UpdateRotations(this, play, this->archeryAnimationType); } -void func_80B128D8(EnSyatekiNiw* this, PlayState* play) { - if (this->unk_25E == 1) { +void EnSyatekiNiw_ExitArchery(EnSyatekiNiw* this, PlayState* play) { + if (this->movementTimer == 1) { gSaveContext.timerState = TIMER_STATE_OFF; } } -void func_80B128F8(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_SetupRemove(EnSyatekiNiw* this, PlayState* play) { s16 sp26; s16 sp24; - Actor_SetFocus(&this->actor, this->unk_2D4); + Actor_SetFocus(&this->actor, this->focusYOffset); Actor_GetScreenPos(play, &this->actor, &sp26, &sp24); if ((this->actor.projectedPos.z > 200.0f) && (this->actor.projectedPos.z < 800.0f) && (sp26 > 0) && (sp26 < SCREEN_WIDTH) && (sp24 > 0) && (sp24 < SCREEN_HEIGHT)) { this->actor.speedXZ = 5.0f; - this->unk_298 = Rand_ZeroFloat(1.99f); - this->unk_2D8 = Rand_CenteredFloat(8000.0f) + -10000.0f; - this->unk_262 = 0x1E; - this->unk_25E = 0x64; - this->actionFunc = func_80B129EC; + this->rotYFlip = Rand_ZeroFloat(1.99f); + this->removeStateYaw = Rand_CenteredFloat(8000.0f) + -10000.0f; + this->cluckTimer = 0x1E; + this->movementTimer = 0x64; + this->actionFunc = EnSyatekiNiw_Remove; } } -void func_80B129EC(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_Remove(EnSyatekiNiw* this, PlayState* play) { s32 pad; f32 phi_f2; s16 sp2E; s16 sp2C; f32 tmpf2; - Actor_SetFocus(&this->actor, this->unk_2D4); + Actor_SetFocus(&this->actor, this->focusYOffset); Actor_GetScreenPos(play, &this->actor, &sp2E, &sp2C); - if ((this->unk_25E == 0) || (this->actor.projectedPos.z < -70.0f) || (sp2E < 0) || (sp2E > SCREEN_WIDTH) || + if ((this->movementTimer == 0) || (this->actor.projectedPos.z < -70.0f) || (sp2E < 0) || (sp2E > SCREEN_WIDTH) || (sp2C < 0) || (sp2C > SCREEN_HEIGHT)) { Actor_Kill(&this->actor); return; } - this->unk_2A0 = 1; - if (this->unk_25C == 0) { - this->unk_298++; - this->unk_298 &= 1; - this->unk_25C = (s16)Rand_CenteredFloat(4.0f) + 5; + this->spawnFeathers = 1; + if (this->hopTimer == 0) { + this->rotYFlip++; + this->rotYFlip &= 1; + this->hopTimer = (s16)Rand_CenteredFloat(4.0f) + 5; if ((Rand_ZeroFloat(5.0f) < 1.0f) && (this->actor.bgCheckFlags & 1)) { this->actor.velocity.y = 4.0f; } } - phi_f2 = (this->unk_298 == 0) ? 5000.0f : -5000.0f; - tmpf2 = this->unk_2D8 + phi_f2; - Math_SmoothStepToS(&this->actor.world.rot.y, tmpf2, 3, this->unk_2C8.y, 0); - Math_ApproachF(&this->unk_2C8.y, 3000.0f, 1.0f, 500.0f); - func_80B11A94(this, play, 2); + phi_f2 = (this->rotYFlip == 0) ? 5000.0f : -5000.0f; + tmpf2 = this->removeStateYaw + phi_f2; + Math_SmoothStepToS(&this->actor.world.rot.y, tmpf2, 3, this->posRotStep.y, 0); + Math_ApproachF(&this->posRotStep.y, 3000.0f, 1.0f, 500.0f); + EnSyatekiNiw_UpdateRotations(this, play, 2); } -void func_80B12BA4(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_CheckHit(EnSyatekiNiw* this, PlayState* play) { if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; - switch (this->unk_29E) { + switch (this->minigameType) { case 0: - if (this->unk_29C == 0) { - this->unk_262 = 0x1E; + if (this->archeryState == 0) { + this->cluckTimer = 0x1E; Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_A); - this->unk_29C = 1; - this->unk_2A0 = 1; - this->actionFunc = func_80B123A8; + this->archeryState = 1; + this->spawnFeathers = 1; + this->actionFunc = EnSyatekiNiw_SetupArchery; this->actor.gravity = -3.0f; } break; case 1: - this->unk_262 = 0x1E; - this->unk_2F8 = 1; + this->cluckTimer = 0x1E; + this->unkAlleyHitByte = 1; Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_A); - this->unk_260 = 100; - this->unk_2A0 = 1; - this->unk_25E = this->unk_260; + this->sootTimer = 100; + this->spawnFeathers = 1; + this->movementTimer = this->sootTimer; break; } } @@ -586,34 +586,34 @@ void EnSyatekiNiw_Update(Actor* thisx, PlayState* play) { Vec3f sp6C; Vec3f sp60; - func_80B132A8(this, play); - this->unk_28C++; - if (this->unk_254 != 0) { - this->unk_254--; + EnSyatekiNiw_UpdateEffects(this, play); + this->lifetime++; + if (this->peckTimer != 0) { + this->peckTimer--; } - if (this->unk_258 != 0) { - this->unk_258--; + if (this->flapTimer != 0) { + this->flapTimer--; } - if (this->unk_25A != 0) { - this->unk_25A--; + if (this->archeryTimer != 0) { + this->archeryTimer--; } - if (this->unk_25C != 0) { - this->unk_25C--; + if (this->hopTimer != 0) { + this->hopTimer--; } - if (this->unk_25E != 0) { - this->unk_25E--; + if (this->movementTimer != 0) { + this->movementTimer--; } - if (this->unk_262 != 0) { - this->unk_262--; + if (this->cluckTimer != 0) { + this->cluckTimer--; } - if (this->unk_260 != 0) { - this->unk_260--; + if (this->sootTimer != 0) { + this->sootTimer--; } this->actor.shape.rot = this->actor.world.rot; @@ -623,7 +623,7 @@ void EnSyatekiNiw_Update(Actor* thisx, PlayState* play) { Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D); - if (this->unk_2A0 != 0) { + if (this->spawnFeathers != 0) { for (i = 0; i < 20; i++) { sp78.x = Rand_CenteredFloat(10.0f) + this->actor.world.pos.x; sp78.y = Rand_CenteredFloat(10.0f) + (this->actor.world.pos.y + 20.0f); @@ -633,25 +633,25 @@ void EnSyatekiNiw_Update(Actor* thisx, PlayState* play) { sp6C.z = Rand_CenteredFloat(3.0f); sp60.z = sp60.x = 0.0f; sp60.y = -0.15f; - func_80B131B8(this, &sp78, &sp6C, &sp60, Rand_ZeroFloat(8.0f) + 8.0f); + EnSyatekiNiw_SpawnFeather(this, &sp78, &sp6C, &sp60, Rand_ZeroFloat(8.0f) + 8.0f); } - this->unk_2A0 = 0; + this->spawnFeathers = 0; } - func_80B12BA4(this, play); - if (this->unk_262 == 0) { - if (this->actionFunc == func_80B11E78) { - this->unk_262 = 0x12C; + EnSyatekiNiw_CheckHit(this, play); + if (this->cluckTimer == 0) { + if (this->actionFunc == EnSyatekiNiw_Default) { + this->cluckTimer = 0x12C; Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_N); } else { - this->unk_262 = 0x1E; + this->cluckTimer = 0x1E; Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_A); } } i = 0; - switch (this->unk_29E) { + switch (this->minigameType) { case 0: if (play->shootingGalleryStatus != 0) { i = 1; @@ -675,19 +675,19 @@ s32 SyatekiNiw_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec Vec3f sp0 = { 0.0f, 0.0f, 0.0f }; if (limbIndex == 13) { - rot->y += (s16)this->unk_2BC.x; + rot->y += (s16)this->headRot.x; } if (limbIndex == 11) { - rot->x += (s16)this->unk_2B0.z; - rot->y += (s16)this->unk_2B0.y; - rot->z += (s16)this->unk_2B0.x; + rot->x += (s16)this->rightWingRot.z; + rot->y += (s16)this->rightWingRot.y; + rot->z += (s16)this->rightWingRot.x; } if (limbIndex == 7) { - rot->x += (s16)this->unk_2A4.z; - rot->y += (s16)this->unk_2A4.y; - rot->z += (s16)this->unk_2A4.x; + rot->x += (s16)this->leftWingRot.z; + rot->y += (s16)this->leftWingRot.y; + rot->z += (s16)this->leftWingRot.x; } return false; @@ -697,72 +697,72 @@ void EnSyatekiNiw_Draw(Actor* thisx, PlayState* play) { EnSyatekiNiw* this = (EnSyatekiNiw*)thisx; Color_RGBA8 sp30 = { 0, 0, 0, 255 }; - if (this->actionFunc != func_80B128F8) { + if (this->actionFunc != EnSyatekiNiw_SetupRemove) { Gfx_SetupDL_25Opa(play->state.gfxCtx); - if (this->unk_260 != 0) { + if (this->sootTimer != 0) { func_80026230(play, &sp30, 0, 0x14); } SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, SyatekiNiw_OverrideLimbDraw, NULL, this); func_80026608(play); - func_80B13464(this, play); + EnSyatekiNiw_DrawEffects(this, play); } } -void func_80B131B8(EnSyatekiNiw* this, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4) { +void EnSyatekiNiw_SpawnFeather(EnSyatekiNiw* this, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4) { s16 i; - EnSyatekiNiw_1* ptr = &this->unk_348[0]; + EnSyatekiNiw_1* ptr = &this->effects[0]; for (i = 0; i < 5; i++, ptr++) { - if (ptr->unk_00 == 0) { + if (ptr->state == 0) { ptr->epoch++; - ptr->unk_00 = 1; - ptr->unk_04 = *arg1; - ptr->unk_10 = *arg2; - ptr->unk_1C = *arg3; - ptr->unk_34 = 0; - ptr->unk_2C = (arg4 / 1000.0f); - ptr->unk_28 = (s16)Rand_ZeroFloat(20.0f) + 0x28; - ptr->unk_2A = Rand_ZeroFloat(1000.0f); + ptr->state = 1; + ptr->pos = *arg1; + ptr->vel = *arg2; + ptr->accel = *arg3; + ptr->timer = 0; + ptr->scale = (arg4 / 1000.0f); + ptr->lifespan = (s16)Rand_ZeroFloat(20.0f) + 0x28; + ptr->rotPulse = Rand_ZeroFloat(1000.0f); return; } } } -void func_80B132A8(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_UpdateEffects(EnSyatekiNiw* this, PlayState* play) { s16 i; - EnSyatekiNiw_1* ptr = &this->unk_348[0]; + EnSyatekiNiw_1* ptr = &this->effects[0]; for (i = 0; i < 5; i++, ptr++) { - if (ptr->unk_00 != 0) { - ptr->unk_04.x += ptr->unk_10.x; - ptr->unk_04.y += ptr->unk_10.y; - ptr->unk_04.z += ptr->unk_10.z; - ptr->unk_34++; - ptr->unk_10.x += ptr->unk_1C.x; - ptr->unk_10.y += ptr->unk_1C.y; - ptr->unk_10.z += ptr->unk_1C.z; - if (ptr->unk_00 == 1) { - ptr->unk_2A++; - Math_ApproachF(&ptr->unk_10.x, 0.0f, 1.0f, 0.05f); - Math_ApproachF(&ptr->unk_10.z, 0.0f, 1.0f, 0.05f); - if (ptr->unk_10.y < -0.5f) { - ptr->unk_10.y = 0.5f; + if (ptr->state != 0) { + ptr->pos.x += ptr->vel.x; + ptr->pos.y += ptr->vel.y; + ptr->pos.z += ptr->vel.z; + ptr->timer++; + ptr->vel.x += ptr->accel.x; + ptr->vel.y += ptr->accel.y; + ptr->vel.z += ptr->accel.z; + if (ptr->state == 1) { + ptr->rotPulse++; + Math_ApproachF(&ptr->vel.x, 0.0f, 1.0f, 0.05f); + Math_ApproachF(&ptr->vel.z, 0.0f, 1.0f, 0.05f); + if (ptr->vel.y < -0.5f) { + ptr->vel.y = 0.5f; } - ptr->unk_30 = (Math_SinS(ptr->unk_2A * 3000) * M_PI) * 0.2f; - if (ptr->unk_28 < ptr->unk_34) { - ptr->unk_00 = 0; + ptr->rot = (Math_SinS(ptr->rotPulse * 3000) * M_PI) * 0.2f; + if (ptr->lifespan < ptr->timer) { + ptr->state = 0; } } } } } -void func_80B13464(EnSyatekiNiw* this, PlayState* play) { +void EnSyatekiNiw_DrawEffects(EnSyatekiNiw* this, PlayState* play) { GraphicsContext* gfxCtx = play->state.gfxCtx; s16 i; - EnSyatekiNiw_1* ptr = &this->unk_348[0]; + EnSyatekiNiw_1* ptr = &this->effects[0]; u8 flag = 0; OPEN_DISPS(gfxCtx); @@ -770,17 +770,17 @@ void func_80B13464(EnSyatekiNiw* this, PlayState* play) { Gfx_SetupDL_25Xlu(play->state.gfxCtx); for (i = 0; i < 5; i++, ptr++) { - if (ptr->unk_00 == 1) { + if (ptr->state == 1) { if (flag == 0) { gSPDisplayList(POLY_XLU_DISP++, gCuccoEffectFeatherMaterialDL); flag++; } FrameInterpolation_RecordOpenChild(ptr, ptr->epoch); - Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + Matrix_Translate(ptr->pos.x, ptr->pos.y, ptr->pos.z, MTXMODE_NEW); Matrix_ReplaceRotation(&play->billboardMtxF); - Matrix_Scale(ptr->unk_2C, ptr->unk_2C, 1.0f, MTXMODE_APPLY); - Matrix_RotateZ(ptr->unk_30, MTXMODE_APPLY); + Matrix_Scale(ptr->scale, ptr->scale, 1.0f, MTXMODE_APPLY); + Matrix_RotateZ(ptr->rot, MTXMODE_APPLY); Matrix_Translate(0.0f, -1000.0f, 0.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h b/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h index 609b89f1c3..0f98eef1ef 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h +++ b/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h @@ -9,15 +9,15 @@ struct EnSyatekiNiw; typedef void (*EnSyatekiNiwActionFunc)(struct EnSyatekiNiw*, PlayState*); typedef struct { - /* 0x00 */ u8 unk_00; - /* 0x0C */ Vec3f unk_04; - /* 0x10 */ Vec3f unk_10; - /* 0x1C */ Vec3f unk_1C; - /* 0x28 */ s16 unk_28; - /* 0x2A */ s16 unk_2A; - /* 0x2C */ f32 unk_2C; - /* 0x30 */ f32 unk_30; - /* 0x34 */ u8 unk_34; + /* 0x00 */ u8 state; + /* 0x0C */ Vec3f pos; + /* 0x10 */ Vec3f vel; + /* 0x1C */ Vec3f accel; + /* 0x28 */ s16 lifespan; + /* 0x2A */ s16 rotPulse; + /* 0x2C */ f32 scale; + /* 0x30 */ f32 rot; + /* 0x34 */ u8 timer; u32 epoch; } EnSyatekiNiw_1; // size = 0x38 @@ -27,46 +27,45 @@ typedef struct EnSyatekiNiw { /* 0x0190 */ Vec3s jointTable[16]; /* 0x01F0 */ Vec3s morphTable[16]; /* 0x0250 */ EnSyatekiNiwActionFunc actionFunc; - /* 0x0254 */ s16 unk_254; - /* 0x0256 */ s16 unk_256; - /* 0x0258 */ s16 unk_258; - /* 0x025A */ s16 unk_25A; - /* 0x025C */ s16 unk_25C; - /* 0x025E */ s16 unk_25E; - /* 0x0260 */ s16 unk_260; - /* 0x0262 */ s16 unk_262; - /* 0x0264 */ f32 unk_264; - /* 0x0268 */ f32 unk_268; - /* 0x026C */ f32 unk_26C; + /* 0x0254 */ s16 peckTimer; + /* 0x0256 */ s16 timer1; + /* 0x0258 */ s16 flapTimer; + /* 0x025A */ s16 archeryTimer; + /* 0x025C */ s16 hopTimer; + /* 0x025E */ s16 movementTimer; + /* 0x0260 */ s16 sootTimer; + /* 0x0262 */ s16 cluckTimer; + /* 0x0264 */ f32 headRotXTarget; + /* 0x0268 */ f32 rightWingRotXTarget; + /* 0x026C */ f32 leftWingRotXTarget; /* 0x0270 */ char unk_270[0x8]; - /* 0x0278 */ f32 unk_278; - /* 0x027C */ f32 unk_27C; - /* 0x0284 */ f32 unk_280; - /* 0x0280 */ f32 unk_284; - /* 0x0288 */ f32 unk_288; - /* 0x028C */ s16 unk_28C; - /* 0x028E */ s16 unk_28E; + /* 0x0278 */ f32 rightWingRotYTarget; + /* 0x027C */ f32 rightWingRotZTarget; + /* 0x0284 */ f32 leftWingRotYTarget; + /* 0x0280 */ f32 leftWingRotZTarget; + /* 0x0288 */ f32 unkArcheryFloat; + /* 0x028C */ s16 lifetime; + /* 0x028E */ s16 headRotXState; /* 0x0290 */ s16 unk_290; - /* 0x0292 */ s16 unk_292; - /* 0x0294 */ s16 unk_294; - /* 0x0296 */ s16 unk_296; - /* 0x0298 */ s16 unk_298; - /* 0x029C */ s16 unk_29A; - /* 0x029C */ s16 unk_29C; - /* 0x029E */ s16 unk_29E; - /* 0x02A0 */ s16 unk_2A0; - /* 0x02A4 */ Vec3f unk_2A4; - /* 0x02B0 */ Vec3f unk_2B0; - /* 0x02BC */ Vec3f unk_2BC; - /* 0x02C8 */ Vec3f unk_2C8; - /* 0x02D4 */ f32 unk_2D4; - /* 0x02D8 */ f32 unk_2D8; - /* 0x02DC */ Vec3f unk_2DC; - /* 0x02E8 */ Vec3f unk_2E8; - /* 0x02F4 */ f32 unk_2F4; - /* 0x02F8 */ u8 unk_2F8; + /* 0x0292 */ s16 wingsRotState; + /* 0x0294 */ s16 targetPosTimer; + /* 0x0296 */ s16 archeryAnimationType; + /* 0x0298 */ s16 rotYFlip; + /* 0x029C */ s16 archeryState; + /* 0x029E */ s16 minigameType; + /* 0x02A0 */ s16 spawnFeathers; + /* 0x02A4 */ Vec3f leftWingRot; + /* 0x02B0 */ Vec3f rightWingRot; + /* 0x02BC */ Vec3f headRot; + /* 0x02C8 */ Vec3f posRotStep; + /* 0x02D4 */ f32 focusYOffset; + /* 0x02D8 */ f32 removeStateYaw; + /* 0x02DC */ Vec3f initPos; + /* 0x02E8 */ Vec3f targetPos; + /* 0x02F4 */ f32 scale; + /* 0x02F8 */ u8 unkAlleyHitByte; /* 0x02FC */ ColliderCylinder collider; - /* 0x0348 */ EnSyatekiNiw_1 unk_348[5]; + /* 0x0348 */ EnSyatekiNiw_1 effects[5]; } EnSyatekiNiw; // size = 0x0460 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index caddf8ad90..032c1cf27c 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -69,10 +69,10 @@ static ColliderCylinderInit sCylinderInit = { void EnTa_SetupAction(EnTa* this, EnTaActionFunc arg1, EnTaUnkFunc arg2) { this->actionFunc = arg1; - this->unk_260 = arg2; + this->animFunc = arg2; } -void func_80B13AAC(EnTa* this, PlayState* play) { +void EnTa_SetTextForTalkInLonLonHouse(EnTa* this, PlayState* play) { u16 faceReaction = Text_GetFaceReaction(play, 24); if (gSaveContext.eventInf[0] & 0x400) { @@ -111,11 +111,11 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); this->actor.colChkInfo.mass = MASS_IMMOVABLE; - this->unk_2E0 = 0; - this->unk_2CE = 0; - this->unk_2E2 = 0; + this->stateFlags = 0; + this->rapidBlinks = 0; + this->nodOffTimer = 0; this->blinkTimer = 20; - this->unk_2B0 = EnTa_BlinkWaitUntilNext; + this->blinkFunc = EnTa_BlinkWaitUntilNext; Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; this->actor.velocity.y = -4.0f; @@ -184,7 +184,7 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { } else { if (IS_DAY) { this->actor.flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED; - this->unk_2C4[0] = this->unk_2C4[1] = this->unk_2C4[2] = 7; + this->superCuccoTimers[0] = this->superCuccoTimers[1] = this->superCuccoTimers[2] = 7; this->superCuccos[0] = (EnNiw*)Actor_Spawn( &play->actorCtx, play, ACTOR_EN_NIW, this->actor.world.pos.x + 5.0f, this->actor.world.pos.y + 3.0f, this->actor.world.pos.z + 26.0f, 0, 0, 0, 0xD); @@ -194,7 +194,7 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { this->superCuccos[2] = (EnNiw*)Actor_Spawn( &play->actorCtx, play, ACTOR_EN_NIW, this->actor.world.pos.x + 20.0f, this->actor.world.pos.y + 40.0f, this->actor.world.pos.z - 30.0f, 0, 0, 0, 0xD); - func_80B13AAC(this, play); + EnTa_SetTextForTalkInLonLonHouse(this, play); if (gSaveContext.eventInf[0] & 0x400) { EnTa_SetupAction(this, EnTa_IdleAfterCuccoGameFinished, EnTa_AnimRunToEnd); @@ -227,7 +227,7 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { } } -void func_80B14248(EnTa* this) { +void EnTa_DecreaseShadowSize(EnTa* this) { if (this->actor.shape.shadowScale > 36.0f) { this->actor.shape.shadowScale -= 0.8f; } @@ -242,14 +242,14 @@ void EnTa_Destroy(Actor* thisx, PlayState* play) { gSaveContext.timerState = TIMER_STATE_OFF; } - if (this->unk_2E0 & 0x200) { + if (this->stateFlags & 0x200) { func_800F5B58(); } ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -s32 func_80B142F4(EnTa* this, PlayState* play, u16 textId) { +s32 EnTa_RequestTalk(EnTa* this, PlayState* play, u16 textId) { if (Actor_ProcessTalkRequest(&this->actor, play)) { return true; } @@ -258,25 +258,25 @@ s32 func_80B142F4(EnTa* this, PlayState* play, u16 textId) { if ((ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) <= 0x4300) && (this->actor.xzDistToPlayer < 100.0f)) { - this->unk_2E0 |= 1; + this->stateFlags |= 1; func_8002F2CC(&this->actor, play, 100.0f); } return false; } -void func_80B14398(EnTa* this, PlayState* play) { +void EnTa_SleepTalkInKakariko(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { EnTa_SetupAction(this, EnTa_IdleAsleepInKakariko, EnTa_AnimSleeping); } } -void func_80B143D4(EnTa* this, PlayState* play) { +void EnTa_SleepTalkInLonLonHouse(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { EnTa_SetupAction(this, EnTa_IdleAsleepInLonLonHouse, EnTa_AnimSleeping); } } -void func_80B14410(EnTa* this) { +void EnTa_SetupAwake(EnTa* this) { if (!LINK_IS_ADULT) { EnTa_SetupAction(this, EnTa_IdleAwakeInCastle, EnTa_AnimRepeatCurrent); Flags_SetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_CASTLE); @@ -286,43 +286,43 @@ void func_80B14410(EnTa* this) { } } -void func_80B1448C(EnTa* this, PlayState* play) { +void EnTa_TalkWakingUp2(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B14410(this); + EnTa_SetupAwake(this); } - func_80B14248(this); - this->unk_2E0 |= 0x4; + EnTa_DecreaseShadowSize(this); + this->stateFlags |= 0x4; } -void func_80B144D8(EnTa* this, PlayState* play) { +void EnTa_TalkWakingUp1(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B14410(this); + EnTa_SetupAwake(this); this->blinkTimer = 1; - this->unk_2B0 = EnTa_BlinkAdvanceState; + this->blinkFunc = EnTa_BlinkAdvanceState; } if (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) { this->eyeIndex = 1; - EnTa_SetupAction(this, func_80B1448C, EnTa_AnimRepeatCurrent); + EnTa_SetupAction(this, EnTa_TalkWakingUp2, EnTa_AnimRepeatCurrent); } - func_80B14248(this); - this->unk_2E0 |= 4; + EnTa_DecreaseShadowSize(this); + this->stateFlags |= 4; } -void func_80B14570(EnTa* this, PlayState* play) { - this->unk_2E0 |= 4; +void EnTa_WakeUp(EnTa* this, PlayState* play) { + this->stateFlags |= 4; - if (this->unk_2CC == 0) { - EnTa_SetupAction(this, func_80B144D8, EnTa_AnimRepeatCurrent); - this->unk_2CE = 3; - this->unk_2CC = 60; + if (this->timer == 0) { + EnTa_SetupAction(this, EnTa_TalkWakingUp1, EnTa_AnimRepeatCurrent); + this->rapidBlinks = 3; + this->timer = 60; Animation_PlayOnce(&this->skelAnime, &gTalonWakeUpAnim); this->currentAnimation = &gTalonStandAnim; Audio_PlayActorSound2(&this->actor, NA_SE_VO_TA_SURPRISE); } } -void func_80B145F8(EnTa* this, PlayState* play) { +void EnTa_SleepTalkInCastle(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { EnTa_SetupAction(this, EnTa_IdleAsleepInCastle, EnTa_AnimSleeping); } @@ -337,14 +337,14 @@ void EnTa_IdleAsleepInCastle(EnTa* this, PlayState* play) { switch (exchangeItemId) { case EXCH_ITEM_CHICKEN: player->actor.textId = 0x702B; - EnTa_SetupAction(this, func_80B14570, EnTa_AnimRepeatCurrent); - this->unk_2CC = 40; + EnTa_SetupAction(this, EnTa_WakeUp, EnTa_AnimRepeatCurrent); + this->timer = 40; break; default: if (exchangeItemId != EXCH_ITEM_NONE) { player->actor.textId = 0x702A; } - EnTa_SetupAction(this, func_80B145F8, EnTa_AnimSleeping); + EnTa_SetupAction(this, EnTa_SleepTalkInCastle, EnTa_AnimSleeping); break; } } else { @@ -355,7 +355,7 @@ void EnTa_IdleAsleepInCastle(EnTa* this, PlayState* play) { void EnTa_IdleAsleepInLonLonHouse(EnTa* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { - EnTa_SetupAction(this, func_80B143D4, EnTa_AnimSleeping); + EnTa_SetupAction(this, EnTa_SleepTalkInLonLonHouse, EnTa_AnimSleeping); } this->actor.textId = 0x204B; func_8002F2CC(&this->actor, play, 100.0f); @@ -370,14 +370,14 @@ void EnTa_IdleAsleepInKakariko(EnTa* this, PlayState* play) { switch (exchangeItemId) { case EXCH_ITEM_POCKET_CUCCO: player->actor.textId = 0x702B; - EnTa_SetupAction(this, func_80B14570, EnTa_AnimRepeatCurrent); - this->unk_2CC = 40; + EnTa_SetupAction(this, EnTa_WakeUp, EnTa_AnimRepeatCurrent); + this->timer = 40; break; default: if (exchangeItemId != EXCH_ITEM_NONE) { player->actor.textId = 0x5015; } - EnTa_SetupAction(this, func_80B14398, EnTa_AnimSleeping); + EnTa_SetupAction(this, EnTa_SleepTalkInKakariko, EnTa_AnimSleeping); break; } } else { @@ -386,7 +386,7 @@ void EnTa_IdleAsleepInKakariko(EnTa* this, PlayState* play) { } } -void func_80B14818(EnTa* this, PlayState* play) { +void EnTa_RunWithAccelerationAndSfx(EnTa* this, PlayState* play) { s32 framesMod12 = (s32)play->state.frames % 12; if (framesMod12 == 0 || framesMod12 == 6) { @@ -398,75 +398,75 @@ void func_80B14818(EnTa* this, PlayState* play) { Actor_MoveXZGravity(&this->actor); } -void func_80B14898(EnTa* this, PlayState* play) { +void EnTa_RunAwayRunOutOfGate(EnTa* this, PlayState* play) { func_80033480(play, &this->actor.world.pos, 50.0f, 2, 250, 20, 1); - func_80B14818(this, play); + EnTa_RunWithAccelerationAndSfx(this, play); - if (this->unk_2CC == 0) { + if (this->timer == 0) { Actor_Kill(&this->actor); } } -void func_80B1490C(EnTa* this, PlayState* play) { +void EnTa_RunAwayTurnTowardsGate(EnTa* this, PlayState* play) { this->actor.world.rot.y += 0xC00; this->actor.shape.rot.y += 0xC00; - if (this->unk_2CC == 0) { - EnTa_SetupAction(this, func_80B14898, EnTa_AnimRepeatCurrent); - this->unk_2CC = 60; + if (this->timer == 0) { + EnTa_SetupAction(this, EnTa_RunAwayRunOutOfGate, EnTa_AnimRepeatCurrent); + this->timer = 60; } } -void func_80B1496C(EnTa* this, PlayState* play) { +void EnTa_RunAwayRunWest(EnTa* this, PlayState* play) { func_80033480(play, &this->actor.world.pos, 50.0f, 2, 250, 20, 1); - func_80B14818(this, play); + EnTa_RunWithAccelerationAndSfx(this, play); - if (this->unk_2CC == 0) { - EnTa_SetupAction(this, func_80B1490C, EnTa_AnimRepeatCurrent); - this->unk_2CC = 5; + if (this->timer == 0) { + EnTa_SetupAction(this, EnTa_RunAwayTurnTowardsGate, EnTa_AnimRepeatCurrent); + this->timer = 5; } } -void func_80B149F4(EnTa* this, PlayState* play) { +void EnTa_RunAwayTurnWest(EnTa* this, PlayState* play) { this->actor.world.rot.y -= 0xD00; this->actor.shape.rot.y -= 0xD00; - if (this->unk_2CC == 0) { - EnTa_SetupAction(this, func_80B1496C, EnTa_AnimRepeatCurrent); - this->unk_2CC = 65; + if (this->timer == 0) { + EnTa_SetupAction(this, EnTa_RunAwayRunWest, EnTa_AnimRepeatCurrent); + this->timer = 65; } } -void func_80B14A54(EnTa* this, PlayState* play) { +void EnTa_RunAwayRunSouth(EnTa* this, PlayState* play) { func_80033480(play, &this->actor.world.pos, 50.0f, 2, 250, 20, 1); - func_80B14818(this, play); + EnTa_RunWithAccelerationAndSfx(this, play); - if (this->unk_2CC == 20) { + if (this->timer == 20) { Message_CloseTextbox(play); } - if (this->unk_2CC == 0) { - this->unk_2CC = 5; - EnTa_SetupAction(this, func_80B149F4, EnTa_AnimRepeatCurrent); + if (this->timer == 0) { + this->timer = 5; + EnTa_SetupAction(this, EnTa_RunAwayTurnWest, EnTa_AnimRepeatCurrent); } } -void func_80B14AF4(EnTa* this, PlayState* play) { +void EnTa_RunAwayStart(EnTa* this, PlayState* play) { this->actor.world.rot.y -= 0xC00; this->actor.shape.rot.y -= 0xC00; - if (this->unk_2CC == 0) { + if (this->timer == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_VO_TA_CRY_1); - EnTa_SetupAction(this, func_80B14A54, EnTa_AnimRepeatCurrent); - this->unk_2CC = 65; + EnTa_SetupAction(this, EnTa_RunAwayRunSouth, EnTa_AnimRepeatCurrent); + this->timer = 65; this->actor.flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED; } } -void func_80B14B6C(EnTa* this, PlayState* play) { +void EnTa_TalkAwakeInCastle(EnTa* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) { s16 csCamIdx = OnePointCutscene_Init(play, 4175, -99, &this->actor, MAIN_CAM); - EnTa_SetupAction(this, func_80B14AF4, EnTa_AnimRepeatCurrent); - this->unk_2CC = 5; + EnTa_SetupAction(this, EnTa_RunAwayStart, EnTa_AnimRepeatCurrent); + this->timer = 5; Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE); if (GameInteractor_Should(VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { OnePointCutscene_EndCutscene(play, csCamIdx); @@ -474,49 +474,49 @@ void func_80B14B6C(EnTa* this, PlayState* play) { Animation_PlayOnce(&this->skelAnime, &gTalonRunTransitionAnim); this->currentAnimation = &gTalonRunAnim; } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } void EnTa_IdleAwakeInCastle(EnTa* this, PlayState* play) { - if (func_80B142F4(this, play, 0x702C)) { - EnTa_SetupAction(this, func_80B14B6C, EnTa_AnimRepeatCurrent); + if (EnTa_RequestTalk(this, play, 0x702C)) { + EnTa_SetupAction(this, EnTa_TalkAwakeInCastle, EnTa_AnimRepeatCurrent); } - func_80B14248(this); + EnTa_DecreaseShadowSize(this); } -void func_80B14C60(EnTa* this, PlayState* play) { +void EnTa_TalkAwakeInKakariko(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { EnTa_SetupAction(this, EnTa_IdleAwakeInKakariko, EnTa_AnimRepeatCurrent); } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } void EnTa_IdleAwakeInKakariko(EnTa* this, PlayState* play) { if (Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED)) { - if (func_80B142F4(this, play, 0x5017)) { - EnTa_SetupAction(this, func_80B14C60, EnTa_AnimRepeatCurrent); + if (EnTa_RequestTalk(this, play, 0x5017)) { + EnTa_SetupAction(this, EnTa_TalkAwakeInKakariko, EnTa_AnimRepeatCurrent); Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_KAKARIKO); } - } else if (func_80B142F4(this, play, 0x5016)) { - EnTa_SetupAction(this, func_80B14C60, EnTa_AnimRepeatCurrent); + } else if (EnTa_RequestTalk(this, play, 0x5016)) { + EnTa_SetupAction(this, EnTa_TalkAwakeInKakariko, EnTa_AnimRepeatCurrent); } - func_80B14248(this); + EnTa_DecreaseShadowSize(this); } -void func_80B14D4C(EnTa* this, PlayState* play) { +void EnTa_TalkAtRanch(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { EnTa_SetupAction(this, EnTa_IdleAtRanch, EnTa_AnimRepeatCurrent); } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } void EnTa_IdleAtRanch(EnTa* this, PlayState* play) { - if (func_80B142F4(this, play, 0x2055)) { - EnTa_SetupAction(this, func_80B14D4C, EnTa_AnimRepeatCurrent); + if (EnTa_RequestTalk(this, play, 0x2055)) { + EnTa_SetupAction(this, EnTa_TalkAtRanch, EnTa_AnimRepeatCurrent); } } -s32 func_80B14DD8(void) { +s32 EnTa_CheckCanBuyMilk(void) { if (gSaveContext.rupees < 30) { return 0; } else if (!Inventory_HasEmptyBottle()) { @@ -526,14 +526,14 @@ s32 func_80B14DD8(void) { } } -void func_80B14E28(EnTa* this, PlayState* play) { +void EnTa_CreateFloorCamera(EnTa* this, PlayState* play) { Vec3f b; Vec3f a; - this->unk_2D0 = Play_CreateSubCamera(play); - this->unk_2D2 = play->activeCamera; - Play_ChangeCameraStatus(play, this->unk_2D2, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->unk_2D0, CAM_STAT_ACTIVE); + this->subCamId = Play_CreateSubCamera(play); + this->returnToCamId = play->activeCamera; + Play_ChangeCameraStatus(play, this->returnToCamId, CAM_STAT_WAIT); + Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); b.x = 1053.0f; b.y = 11.0f; @@ -543,41 +543,41 @@ void func_80B14E28(EnTa* this, PlayState* play) { a.y = 45.0f; a.z = -40.0f; - Play_CameraSetAtEye(play, this->unk_2D0, &a, &b); + Play_CameraSetAtEye(play, this->subCamId, &a, &b); } -void func_80B14EDC(EnTa* this, PlayState* play) { - Play_ChangeCameraStatus(play, this->unk_2D2, CAM_STAT_ACTIVE); - Play_ClearCamera(play, this->unk_2D0); +void EnTa_RemoveFloorCamera(EnTa* this, PlayState* play) { + Play_ChangeCameraStatus(play, this->returnToCamId, CAM_STAT_ACTIVE); + Play_ClearCamera(play, this->subCamId); } -void func_80B14F20(EnTa* this, EnTaActionFunc arg1) { +void EnTa_SetupActionWithSleepAnimation(EnTa* this, EnTaActionFunc arg1) { EnTa_SetupAction(this, arg1, EnTa_AnimSitSleeping); this->eyeIndex = 2; Animation_Change(&this->skelAnime, &gTalonSitSleepingAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gTalonSitSleepingAnim), ANIMMODE_ONCE, -5.0f); - this->unk_2E2 = 0; + this->nodOffTimer = 0; this->currentAnimation = &gTalonSitSleepingAnim; } -void func_80B14FAC(EnTa* this, EnTaActionFunc arg1) { +void EnTa_SetupActionWithWakeUpAnimation(EnTa* this, EnTaActionFunc arg1) { this->eyeIndex = 1; EnTa_SetupAction(this, arg1, EnTa_AnimRunToEnd); - this->unk_2E0 &= ~0x10; + this->stateFlags &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitWakeUpAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim), ANIMMODE_ONCE, -5.0f); } -void func_80B15034(EnTa* this, PlayState* play) { +void EnTa_TalkNotEnoughRupees(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); - func_80B14F20(this, EnTa_IdleSittingInLonLonHouse); - func_80B13AAC(this, play); + EnTa_SetupActionWithSleepAnimation(this, EnTa_IdleSittingInLonLonHouse); + EnTa_SetTextForTalkInLonLonHouse(this, play); } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } -s32 func_80B150AC(EnTa* this, PlayState* play, s32 idx) { +s32 EnTa_IsPlayerHoldingSuperCucco(EnTa* this, PlayState* play, s32 idx) { Player* player = GET_PLAYER(play); Actor* interactRangeActor; @@ -591,7 +591,7 @@ s32 func_80B150AC(EnTa* this, PlayState* play, s32 idx) { return false; } -void func_80B15100(EnTa* this, PlayState* play) { +void EnTa_TalkFoundSuperCucco(EnTa* this, PlayState* play) { Player* player = GET_PLAYER(play); if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { @@ -600,9 +600,9 @@ void func_80B15100(EnTa* this, PlayState* play) { Animation_Change(&this->skelAnime, &gTalonSitWakeUpAnim, 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim) - 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim), ANIMMODE_ONCE, 10.0f); - this->unk_2E0 &= ~0x10; + this->stateFlags &= ~0x10; Message_CloseTextbox(play); - unk_2CA = this->unk_2CA; + unk_2CA = this->lastFoundSuperCuccoIdx; this->actionFunc = EnTa_RunCuccoGame; this->superCuccos[unk_2CA]->actor.gravity = 0.1f; this->superCuccos[unk_2CA]->actor.velocity.y = 0.0f; @@ -618,17 +618,17 @@ void func_80B15100(EnTa* this, PlayState* play) { player->stateFlags1 &= ~PLAYER_STATE1_CARRYING_ACTOR; this->superCuccos[unk_2CA] = NULL; } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } -void func_80B15260(EnTa* this, PlayState* play) { +void EnTa_IdleFoundSuperCucco(EnTa* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { - this->actionFunc = func_80B15100; + this->actionFunc = EnTa_TalkFoundSuperCucco; this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; } else { func_8002F2CC(&this->actor, play, 1000.0f); } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } s32 EnTa_GetSuperCuccosCount(EnTa* this, PlayState* play) { @@ -643,32 +643,32 @@ s32 EnTa_GetSuperCuccosCount(EnTa* this, PlayState* play) { return count; } -void func_80B15308(EnTa* this) { - if (this->unk_2E0 & 0x10) { - if (this->unk_2E0 & 0x100) { +void EnTa_AnimateHandsUpDown(EnTa* this) { + if (this->stateFlags & 0x10) { + if (this->stateFlags & 0x100) { Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 17.0f, 22.0f, ANIMMODE_ONCE, 0.0f); - this->unk_2E0 &= ~0x100; + this->stateFlags &= ~0x100; } else { Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, -1.0f, 21.0f, 16.0f, ANIMMODE_ONCE, 3.0f); - this->unk_2E0 |= 0x100; + this->stateFlags |= 0x100; } - this->unk_2E0 &= ~0x10; + this->stateFlags &= ~0x10; } } -void func_80B153D4(EnTa* this, PlayState* play) { - func_80B15308(this); +void EnTa_TransitionToPostCuccoGame(EnTa* this, PlayState* play) { + EnTa_AnimateHandsUpDown(this); - if (this->unk_2CC == 0) { - if (this->unk_2E0 & 0x80) { - this->unk_2E0 &= ~0x80; - func_80B14EDC(this, play); + if (this->timer == 0) { + if (this->stateFlags & 0x80) { + this->stateFlags &= ~0x80; + EnTa_RemoveFloorCamera(this, play); } } } -void func_80B15424(EnTa* this, PlayState* play) { - func_80B15308(this); +void EnTa_TalkCuccoGameEnd(EnTa* this, PlayState* play) { + EnTa_AnimateHandsUpDown(this); if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { play->nextEntranceIndex = ENTR_LON_LON_BUILDINGS_2; @@ -683,8 +683,8 @@ void func_80B15424(EnTa* this, PlayState* play) { play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.eventInf[0] |= 0x400; - this->actionFunc = func_80B153D4; - this->unk_2CC = 22; + this->actionFunc = EnTa_TransitionToPostCuccoGame; + this->timer = 22; } } @@ -697,13 +697,13 @@ void EnTa_RunCuccoGame(EnTa* this, PlayState* play) { this->superCuccos[i]->actor.gravity -= 0.03f; } - if (!GameInteractor_Should(VB_PREVENT_STRENGTH, !func_80B150AC(this, play, i))) { - if (this->unk_2C4[i] > 0) { - this->unk_2C4[i]--; + if (!GameInteractor_Should(VB_PREVENT_STRENGTH, !EnTa_IsPlayerHoldingSuperCucco(this, play, i))) { + if (this->superCuccoTimers[i] > 0) { + this->superCuccoTimers[i]--; } else { - this->unk_2CA = i; + this->lastFoundSuperCuccoIdx = i; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 8.0f, 29.0f, ANIMMODE_ONCE, -10.0f); - this->unk_2E0 &= ~0x10; + this->stateFlags &= ~0x10; switch (EnTa_GetSuperCuccosCount(this, play)) { case 1: @@ -711,14 +711,14 @@ void EnTa_RunCuccoGame(EnTa* this, PlayState* play) { Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Message_StartTextbox(play, 0x2084, &this->actor); - this->actionFunc = func_80B15424; + this->actionFunc = EnTa_TalkCuccoGameEnd; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 8.0f, 29.0f, ANIMMODE_ONCE, -10.0f); - this->unk_2E0 &= ~0x10; - this->unk_2E0 &= ~0x100; + this->stateFlags &= ~0x10; + this->stateFlags &= ~0x100; gSaveContext.eventInf[0] |= 0x100; Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP); - this->unk_2E0 &= ~0x200; + this->stateFlags &= ~0x200; Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); return; case 2: @@ -730,13 +730,13 @@ void EnTa_RunCuccoGame(EnTa* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_VO_TA_SURPRISE); break; } - this->actionFunc = func_80B15260; + this->actionFunc = EnTa_IdleFoundSuperCucco; this->actor.flags |= ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; func_8002F2CC(&this->actor, play, 1000.0f); return; } } else { - this->unk_2C4[i] = 7; + this->superCuccoTimers[i] = 7; } } } @@ -747,36 +747,36 @@ void EnTa_RunCuccoGame(EnTa* this, PlayState* play) { if (gSaveContext.timerSeconds == 0 && !Play_InCsMode(play)) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP); - this->unk_2E0 &= ~0x200; + this->stateFlags &= ~0x200; Sfx_PlaySfxCentered(NA_SE_SY_FOUND); gSaveContext.timerState = TIMER_STATE_OFF; Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Message_StartTextbox(play, 0x2081, &this->actor); - this->actionFunc = func_80B15424; - func_80B14E28(this, play); + this->actionFunc = EnTa_TalkCuccoGameEnd; + EnTa_CreateFloorCamera(this, play); gSaveContext.eventInf[0] &= ~0x100; - this->unk_2E0 |= 0x80; + this->stateFlags |= 0x80; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 8.0f, 29.0f, ANIMMODE_ONCE, -10.0f); - this->unk_2E0 &= ~0x10; - this->unk_2E0 &= ~0x100; + this->stateFlags &= ~0x10; + this->stateFlags &= ~0x100; } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } -void func_80B1585C(EnTa* this, PlayState* play) { +void EnTa_ThrowSuperCuccos(EnTa* this, PlayState* play) { s32 i; - if (this->unk_2CC > 35) { + if (this->timer > 35) { for (i = 1; i < ARRAY_COUNT(this->superCuccos); i++) { if (this->superCuccos[i] != NULL) { Math_SmoothStepToS(&this->superCuccos[i]->actor.world.rot.y, i * -10000 - 3000, 2, 0x800, 0x100); this->superCuccos[i]->actor.shape.rot.y = this->superCuccos[i]->actor.world.rot.y; } } - } else if (this->unk_2CC == 35) { + } else if (this->timer == 35) { for (i = 0; i < ARRAY_COUNT(this->superCuccos); i++) { - this->unk_2C4[i] = (s32)(Rand_CenteredFloat(6.0f) + 10.0f); + this->superCuccoTimers[i] = (s32)(Rand_CenteredFloat(6.0f) + 10.0f); if (this->superCuccos[i] != NULL) { EnNiw* niw = this->superCuccos[i]; @@ -787,7 +787,7 @@ void func_80B1585C(EnTa* this, PlayState* play) { } } else { for (i = 0; i < ARRAY_COUNT(this->superCuccos); i++) { - if (this->unk_2CC < 35 - this->unk_2C4[i]) { + if (this->timer < 35 - this->superCuccoTimers[i]) { if (this->superCuccos[i] != NULL) { if (this->superCuccos[i]->actor.gravity > -2.0f) { this->superCuccos[i]->actor.gravity -= 0.03f; @@ -797,9 +797,9 @@ void func_80B1585C(EnTa* this, PlayState* play) { } } - if (this->unk_2CC == 0) { + if (this->timer == 0) { EnTa_SetupAction(this, EnTa_RunCuccoGame, EnTa_AnimRunToEnd); - this->unk_2E0 &= ~0x10; + this->stateFlags &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitWakeUpAnim, 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim) - 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim), ANIMMODE_ONCE, 10.0f); @@ -807,66 +807,66 @@ void func_80B1585C(EnTa* this, PlayState* play) { } } -void func_80B15AD4(EnTa* this, PlayState* play) { - if (this->unk_2CC == 0 && this->unk_2E0 & 0x20) { - EnTa_SetupAction(this, func_80B1585C, EnTa_AnimRunToEnd); - this->unk_2E0 &= ~0x10; +void EnTa_StartingCuccoGame3(EnTa* this, PlayState* play) { + if (this->timer == 0 && this->stateFlags & 0x20) { + EnTa_SetupAction(this, EnTa_ThrowSuperCuccos, EnTa_AnimRunToEnd); + this->stateFlags &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 1.0f, Animation_GetLastFrame(&gTalonSitHandsUpAnim), ANIMMODE_ONCE, 0.0f); - this->unk_2CC = 50; + this->timer = 50; Interface_SetTimer(0x1E); func_800F5ACC(NA_BGM_TIMED_MINI_GAME); - this->unk_2E0 |= 0x200; + this->stateFlags |= 0x200; Message_CloseTextbox(play); Player_SetCsActionWithHaltedActors(play, &this->actor, 1); } if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { - this->unk_2E0 |= 0x20; + this->stateFlags |= 0x20; } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } -void func_80B15BF8(EnTa* this, PlayState* play) { - if (this->unk_2E0 & 0x10) { - EnTa_SetupAction(this, func_80B15AD4, EnTa_AnimRunToEnd); - this->unk_2E0 &= ~0x10; +void EnTa_StartingCuccoGame2(EnTa* this, PlayState* play) { + if (this->stateFlags & 0x10) { + EnTa_SetupAction(this, EnTa_StartingCuccoGame3, EnTa_AnimRunToEnd); + this->stateFlags &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 0.0f, 1.0f, ANIMMODE_ONCE, 0.0f); - this->unk_2CC = 5; + this->timer = 5; } if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { - this->unk_2E0 |= 0x20; + this->stateFlags |= 0x20; } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } -void func_80B15CC8(EnTa* this, PlayState* play) { - if (this->unk_2E0 & 0x10) { - EnTa_SetupAction(this, func_80B15BF8, EnTa_AnimRunToEnd); - this->unk_2E0 &= ~0x10; +void EnTa_StartingCuccoGame1(EnTa* this, PlayState* play) { + if (this->stateFlags & 0x10) { + EnTa_SetupAction(this, EnTa_StartingCuccoGame2, EnTa_AnimRunToEnd); + this->stateFlags &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, -1.0f, 29.0f, 0.0f, ANIMMODE_ONCE, 10.0f); } if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { - this->unk_2E0 |= 0x20; + this->stateFlags |= 0x20; } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } -void func_80B15D90(EnTa* this, PlayState* play) { - EnTa_SetupAction(this, func_80B15CC8, EnTa_AnimRunToEnd); - this->unk_2E0 &= ~0x10; +void EnTa_StartCuccoGame(EnTa* this, PlayState* play) { + EnTa_SetupAction(this, EnTa_StartingCuccoGame1, EnTa_AnimRunToEnd); + this->stateFlags &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 8.0f, 29.0f, ANIMMODE_ONCE, -10.0f); Message_ContinueTextbox(play, 0x2080); - this->unk_2E0 &= ~0x20; + this->stateFlags &= ~0x20; } void EnTa_TalkGeneralInLonLonHouse(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B14F20(this, EnTa_IdleSittingInLonLonHouse); - func_80B13AAC(this, play); + EnTa_SetupActionWithSleepAnimation(this, EnTa_IdleSittingInLonLonHouse); + EnTa_SetTextForTalkInLonLonHouse(this, play); } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } void EnTa_GiveItemInLonLonHouse(EnTa* this, PlayState* play) { @@ -874,24 +874,24 @@ void EnTa_GiveItemInLonLonHouse(EnTa* this, PlayState* play) { !GameInteractor_Should(VB_GIVE_ITEM_FROM_TALONS_CHICKENS, true, &this->actor)) { this->actor.parent = NULL; this->actionFunc = EnTa_TalkGeneralInLonLonHouse; - if (!(this->unk_2E0 & 0x2)) { + if (!(this->stateFlags & 0x2)) { Flags_SetItemGetInf(ITEMGETINF_TALON_BOTTLE); } - this->unk_2E0 &= ~0x2; - } else if (this->unk_2E0 & 2) { + this->stateFlags &= ~0x2; + } else if (this->stateFlags & 2) { Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 50.0f); } else { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_TALONS_CHICKENS, true, &this->actor)) { Actor_OfferGetItem(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); } } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } void EnTa_TalkAfterCuccoGameFirstWon(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); - this->unk_2E0 &= ~0x2; + this->stateFlags &= ~0x2; EnTa_SetupAction(this, EnTa_GiveItemInLonLonHouse, EnTa_AnimRunToEnd); if (GameInteractor_Should(VB_GIVE_ITEM_FROM_TALONS_CHICKENS, true, &this->actor)) { Actor_OfferGetItem(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); @@ -899,21 +899,21 @@ void EnTa_TalkAfterCuccoGameFirstWon(EnTa* this, PlayState* play) { } } -void func_80B15FE8(EnTa* this, PlayState* play) { +void EnTa_WaitBuyMilkOrPlayCuccoGameResponse(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { switch (play->msgCtx.choiceIndex) { case 0: - switch (func_80B14DD8()) { + switch (EnTa_CheckCanBuyMilk()) { case 0: Message_ContinueTextbox(play, 0x85); - EnTa_SetupAction(this, func_80B15034, EnTa_AnimRunToEnd); + EnTa_SetupAction(this, EnTa_TalkNotEnoughRupees, EnTa_AnimRunToEnd); break; case 1: Message_ContinueTextbox(play, 0x208A); EnTa_SetupAction(this, EnTa_TalkGeneralInLonLonHouse, EnTa_AnimRunToEnd); break; case 2: - this->unk_2E0 |= 2; + this->stateFlags |= 2; EnTa_SetupAction(this, EnTa_GiveItemInLonLonHouse, EnTa_AnimRunToEnd); Rupees_ChangeBy(-30); GetItemEntry itemEntry = ItemTable_Retrieve(GI_MILK); @@ -926,25 +926,25 @@ void func_80B15FE8(EnTa* this, PlayState* play) { case 1: if (gSaveContext.rupees < 10) { Message_ContinueTextbox(play, 0x85); - EnTa_SetupAction(this, func_80B15034, EnTa_AnimRunToEnd); + EnTa_SetupAction(this, EnTa_TalkNotEnoughRupees, EnTa_AnimRunToEnd); } else { Rupees_ChangeBy(-10); - func_80B15D90(this, play); + EnTa_StartCuccoGame(this, play); } break; case 2: - func_80B14F20(this, EnTa_IdleSittingInLonLonHouse); - func_80B13AAC(this, play); + EnTa_SetupActionWithSleepAnimation(this, EnTa_IdleSittingInLonLonHouse); + EnTa_SetTextForTalkInLonLonHouse(this, play); break; } } - if (this->unk_2E0 & 0x10) { - this->unk_2E0 |= 1; + if (this->stateFlags & 0x10) { + this->stateFlags |= 1; } } -void func_80B161C0(EnTa* this, PlayState* play) { +void EnTa_WaitForPlayCuccoGameResponse(EnTa* this, PlayState* play) { s32 price; if (this->actor.textId == 0x2085) { @@ -958,57 +958,57 @@ void func_80B161C0(EnTa* this, PlayState* play) { case 0: if (gSaveContext.rupees < price) { Message_ContinueTextbox(play, 0x85); - EnTa_SetupAction(this, func_80B15034, EnTa_AnimRunToEnd); + EnTa_SetupAction(this, EnTa_TalkNotEnoughRupees, EnTa_AnimRunToEnd); } else { Rupees_ChangeBy(-price); - func_80B15D90(this, play); + EnTa_StartCuccoGame(this, play); } break; case 1: - func_80B14F20(this, EnTa_IdleSittingInLonLonHouse); - func_80B13AAC(this, play); + EnTa_SetupActionWithSleepAnimation(this, EnTa_IdleSittingInLonLonHouse); + EnTa_SetTextForTalkInLonLonHouse(this, play); break; } } - if (this->unk_2E0 & 0x10) { - this->unk_2E0 |= 1; + if (this->stateFlags & 0x10) { + this->stateFlags |= 1; } } -void func_80B162E8(EnTa* this, PlayState* play) { +void EnTa_WaitForMarryMalonResponse(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { Message_ContinueTextbox(play, 0x2087); EnTa_SetupAction(this, EnTa_TalkAfterCuccoGameFirstWon, EnTa_AnimRunToEnd); } - if (this->unk_2E0 & 0x10) { - this->unk_2E0 |= 1; + if (this->stateFlags & 0x10) { + this->stateFlags |= 1; } } -void func_80B16364(EnTa* this, PlayState* play) { +void EnTa_ContinueTalkInLonLonHouse(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Flags_SetInfTable(INFTABLE_TALKED_TO_TALON_IN_RANCH_HOUSE); if (Flags_GetItemGetInf(ITEMGETINF_TALON_BOTTLE)) { Message_ContinueTextbox(play, 0x208B); - EnTa_SetupAction(this, func_80B15FE8, EnTa_AnimRunToEnd); + EnTa_SetupAction(this, EnTa_WaitBuyMilkOrPlayCuccoGameResponse, EnTa_AnimRunToEnd); } else { Message_ContinueTextbox(play, 0x207F); - EnTa_SetupAction(this, func_80B161C0, EnTa_AnimRunToEnd); + EnTa_SetupAction(this, EnTa_WaitForPlayCuccoGameResponse, EnTa_AnimRunToEnd); } } - if (this->unk_2E0 & 0x10) { - this->unk_2E0 |= 1; + if (this->stateFlags & 0x10) { + this->stateFlags |= 1; } } -void func_80B1642C(EnTa* this, PlayState* play) { +void EnTa_TalkAfterCuccoGameWon(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { if (Inventory_HasEmptyBottle()) { Message_CloseTextbox(play); - this->unk_2E0 |= 2; + this->stateFlags |= 2; EnTa_SetupAction(this, EnTa_GiveItemInLonLonHouse, EnTa_AnimRunToEnd); Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 50.0f); } else { @@ -1021,44 +1021,44 @@ void func_80B1642C(EnTa* this, PlayState* play) { void EnTa_IdleSittingInLonLonHouse(EnTa* this, PlayState* play) { u16 faceReaction = Text_GetFaceReaction(play, 0x18); - func_80B13AAC(this, play); + EnTa_SetTextForTalkInLonLonHouse(this, play); - if (func_80B142F4(this, play, this->actor.textId)) { + if (EnTa_RequestTalk(this, play, this->actor.textId)) { Audio_PlayActorSound2(&this->actor, NA_SE_VO_TA_SURPRISE); if (faceReaction != 0) { - func_80B14FAC(this, EnTa_TalkGeneralInLonLonHouse); + EnTa_SetupActionWithWakeUpAnimation(this, EnTa_TalkGeneralInLonLonHouse); } else { Flags_SetInfTable(INFTABLE_TALKED_TO_TALON_IN_RANCH_HOUSE); switch (this->actor.textId) { case 0x207E: case 0x207F: - func_80B14FAC(this, func_80B161C0); + EnTa_SetupActionWithWakeUpAnimation(this, EnTa_WaitForPlayCuccoGameResponse); break; case 0x208B: - func_80B14FAC(this, func_80B15FE8); + EnTa_SetupActionWithWakeUpAnimation(this, EnTa_WaitBuyMilkOrPlayCuccoGameResponse); break; default: - func_80B14FAC(this, func_80B16364); + EnTa_SetupActionWithWakeUpAnimation(this, EnTa_ContinueTalkInLonLonHouse); break; } } } - this->unk_2E0 &= ~1; + this->stateFlags &= ~1; } void EnTa_IdleAfterCuccoGameFinished(EnTa* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { switch (this->actor.textId) { case 0x2085: - this->actionFunc = func_80B161C0; + this->actionFunc = EnTa_WaitForPlayCuccoGameResponse; break; case 0x2086: - this->actionFunc = func_80B162E8; + this->actionFunc = EnTa_WaitForMarryMalonResponse; break; case 0x2088: - this->actionFunc = func_80B1642C; + this->actionFunc = EnTa_TalkAfterCuccoGameWon; break; } this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; @@ -1066,7 +1066,7 @@ void EnTa_IdleAfterCuccoGameFinished(EnTa* this, PlayState* play) { this->actor.flags |= ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; func_8002F2CC(&this->actor, play, 1000.0f); } - this->unk_2E0 |= 1; + this->stateFlags |= 1; } void EnTa_BlinkWaitUntilNext(EnTa* this) { @@ -1075,7 +1075,7 @@ void EnTa_BlinkWaitUntilNext(EnTa* this) { if (temp_v0 != 0) { this->blinkTimer = temp_v0; } else { - this->unk_2B0 = EnTa_BlinkAdvanceState; + this->blinkFunc = EnTa_BlinkAdvanceState; } } @@ -1090,14 +1090,14 @@ void EnTa_BlinkAdvanceState(EnTa* this) { if (nextEyeIndex >= blinkTimer) { this->eyeIndex = 0; - if (this->unk_2CE > 0) { - this->unk_2CE--; + if (this->rapidBlinks > 0) { + this->rapidBlinks--; blinkTimer = 1; } else { blinkTimer = (s32)(Rand_ZeroOne() * 60.0f) + 20; } this->blinkTimer = blinkTimer; - this->unk_2B0 = EnTa_BlinkWaitUntilNext; + this->blinkFunc = EnTa_BlinkWaitUntilNext; } else { this->eyeIndex = nextEyeIndex; this->blinkTimer = 1; @@ -1116,16 +1116,16 @@ void EnTa_AnimSleeping(EnTa* this) { Animation_PlayOnce(&this->skelAnime, this->currentAnimation); Audio_PlayActorSound2(&this->actor, NA_SE_VO_TA_SLEEP); } - this->unk_2E0 |= 0xC; + this->stateFlags |= 0xC; } void EnTa_AnimSitSleeping(EnTa* this) { - if (this->unk_2E2 > 0) { - this->unk_2E2--; + if (this->nodOffTimer > 0) { + this->nodOffTimer--; } else { if (SkelAnime_Update(&this->skelAnime)) { Animation_PlayOnce(&this->skelAnime, this->currentAnimation); - this->unk_2E2 = Rand_ZeroFloat(100.0f) + 100.0f; + this->nodOffTimer = Rand_ZeroFloat(100.0f) + 100.0f; } if (this->skelAnime.curFrame < 96.0f && this->skelAnime.curFrame >= 53.0f) { @@ -1133,17 +1133,17 @@ void EnTa_AnimSitSleeping(EnTa* this) { } else { this->eyeIndex = 2; } - this->unk_2E0 |= 8; + this->stateFlags |= 8; } - this->unk_2E0 |= 4; + this->stateFlags |= 4; } void EnTa_AnimRunToEnd(EnTa* this) { - if (!(this->unk_2E0 & 0x10)) { + if (!(this->stateFlags & 0x10)) { if (SkelAnime_Update(&this->skelAnime)) { - this->unk_2E0 |= 0x10; + this->stateFlags |= 0x10; } - this->unk_2E0 |= 8; + this->stateFlags |= 8; } } @@ -1155,26 +1155,26 @@ void EnTa_Update(Actor* thisx, PlayState* play) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); - this->unk_260(this); + this->animFunc(this); this->actionFunc(this, play); - if (!(this->unk_2E0 & 4)) { - this->unk_2B0(this); + if (!(this->stateFlags & 4)) { + this->blinkFunc(this); } - if (this->unk_2E0 & 1) { - func_80038290(play, &this->actor, &this->unk_2D4, &this->unk_2DA, this->actor.focus.pos); + if (this->stateFlags & 1) { + func_80038290(play, &this->actor, &this->headRot, &this->torsoRot, this->actor.focus.pos); } else { - Math_SmoothStepToS(&this->unk_2D4.x, 0, 6, 6200, 100); - Math_SmoothStepToS(&this->unk_2D4.y, 0, 6, 6200, 100); - Math_SmoothStepToS(&this->unk_2DA.x, 0, 6, 6200, 100); - Math_SmoothStepToS(&this->unk_2DA.y, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->headRot.x, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->headRot.y, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->torsoRot.x, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->torsoRot.y, 0, 6, 6200, 100); } - this->unk_2E0 &= ~0x5; + this->stateFlags &= ~0x5; - if (this->unk_2CC > 0) { - this->unk_2CC--; + if (this->timer > 0) { + this->timer--; } } @@ -1183,17 +1183,17 @@ s32 EnTa_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po switch (limbIndex) { case 8: - rot->x += this->unk_2DA.y; - rot->y -= this->unk_2DA.x; + rot->x += this->torsoRot.y; + rot->y -= this->torsoRot.x; break; case 15: - rot->x += this->unk_2D4.y; - rot->z += this->unk_2D4.x; + rot->x += this->headRot.y; + rot->z += this->headRot.x; break; } - if (this->unk_2E0 & 0x8) { - this->unk_2E0 &= ~0x8; + if (this->stateFlags & 0x8) { + this->stateFlags &= ~0x8; } else if ((limbIndex == 8) || (limbIndex == 10) || (limbIndex == 13)) { s32 limbIdx50 = limbIndex * 50; diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.h b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.h index 1d07dbd963..69b391001e 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.h +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.h @@ -17,22 +17,22 @@ typedef struct EnTa { /* 0x0190 */ Vec3s jointTable[17]; /* 0x01F6 */ Vec3s morphTable[17]; /* 0x025C */ EnTaActionFunc actionFunc; - /* 0x0260 */ EnTaUnkFunc unk_260; + /* 0x0260 */ EnTaUnkFunc animFunc; /* 0x0264 */ ColliderCylinder collider; - /* 0x02B0 */ EnTaUnkFunc unk_2B0; + /* 0x02B0 */ EnTaUnkFunc blinkFunc; /* 0x02B4 */ s16 eyeIndex; /* 0x02B6 */ s16 blinkTimer; /* 0x02B8 */ EnNiw* superCuccos[3]; - /* 0x02C4 */ s16 unk_2C4[3]; - /* 0x02CA */ u8 unk_2CA; - /* 0x02CC */ s16 unk_2CC; - /* 0x02CE */ s16 unk_2CE; - /* 0x02D0 */ s16 unk_2D0; - /* 0x02D2 */ s16 unk_2D2; - /* 0x02D4 */ Vec3s unk_2D4; - /* 0x02DA */ Vec3s unk_2DA; - /* 0x02E0 */ u16 unk_2E0; - /* 0x02E2 */ s16 unk_2E2; + /* 0x02C4 */ s16 superCuccoTimers[3]; + /* 0x02CA */ u8 lastFoundSuperCuccoIdx; + /* 0x02CC */ s16 timer; + /* 0x02CE */ s16 rapidBlinks; + /* 0x02D0 */ s16 subCamId; + /* 0x02D2 */ s16 returnToCamId; + /* 0x02D4 */ Vec3s headRot; + /* 0x02DA */ Vec3s torsoRot; + /* 0x02E0 */ u16 stateFlags; + /* 0x02E2 */ s16 nodOffTimer; /* 0x02E4 */ AnimationHeader* currentAnimation; } EnTa; // size = 0x02E8 diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 96ce945e48..edfb614eea 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -334,7 +334,7 @@ s32 EnTk_Orient(EnTk* this, PlayState* play) { } } -u16 func_80B1C54C(PlayState* play, Actor* thisx) { +u16 EnTk_GetTextId(PlayState* play, Actor* thisx) { u16 ret; ret = Text_GetFaceReaction(play, 14); @@ -351,7 +351,7 @@ u16 func_80B1C54C(PlayState* play, Actor* thisx) { } } -s16 func_80B1C5A0(PlayState* play, Actor* thisx) { +s16 EnTk_UpdateTalkState(PlayState* play, Actor* thisx) { s32 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { @@ -537,7 +537,7 @@ void EnTk_Rest(EnTk* this, PlayState* play) { } Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 30.0f, - func_80B1C54C, func_80B1C5A0); + EnTk_GetTextId, EnTk_UpdateTalkState); } else if (EnTk_CheckFacingPlayer(this)) { v1 = this->actor.shape.rot.y; v1 -= this->h_21E; @@ -545,7 +545,7 @@ void EnTk_Rest(EnTk* this, PlayState* play) { this->actionCountdown = 0; Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 30.0f, - func_80B1C54C, func_80B1C5A0); + EnTk_GetTextId, EnTk_UpdateTalkState); } else if (Actor_ProcessTalkRequest(&this->actor, play)) { v1 = this->actor.shape.rot.y; v1 -= this->h_21E; diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index b7f35742c6..aab4323281 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -16,7 +16,7 @@ void EnToryo_Destroy(Actor* thisx, PlayState* play); void EnToryo_Update(Actor* thisx, PlayState* play); void EnToryo_Draw(Actor* thisx, PlayState* play); -void func_80B20914(EnToryo* this, PlayState* play); +void EnToryo_Idle(EnToryo* this, PlayState* play); s32 EnToryo_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx); void EnToryo_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx); @@ -131,7 +131,7 @@ void EnToryo_Init(Actor* thisx, PlayState* play) { sEnToryoAnimation.morphFrames); this->stateFlags |= 8; this->actor.targetMode = 6; - this->actionFunc = func_80B20914; + this->actionFunc = EnToryo_Idle; } void EnToryo_Destroy(Actor* thisx, PlayState* play) { @@ -142,7 +142,7 @@ void EnToryo_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -s32 func_80B203D8(EnToryo* this, PlayState* play) { +s32 EnToryo_TalkRespond(EnToryo* this, PlayState* play) { s32 pad; Player* player = GET_PLAYER(play); s32 ret = 1; @@ -215,7 +215,7 @@ s32 func_80B203D8(EnToryo* this, PlayState* play) { return ret; } -s32 func_80B205CC(EnToryo* this, PlayState* play) { +s32 EnToryo_DoneTalking(EnToryo* this, PlayState* play) { s32 pad; Player* player = GET_PLAYER(play); s32 ret = 5; @@ -238,11 +238,11 @@ s32 func_80B205CC(EnToryo* this, PlayState* play) { return ret; } -u32 func_80B20634(EnToryo* this, PlayState* play) { +u32 EnToryo_ReactToExchangeItem(EnToryo* this, PlayState* play) { u32 ret; - if (this->unk_1E0 != 0) { - if (this->unk_1E0 == 10) { + if (this->exchangeItemId != 0) { + if (this->exchangeItemId == 10) { Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); if (Flags_GetInfTable(INFTABLE_171)) { ret = 0x606E; @@ -257,7 +257,7 @@ u32 func_80B20634(EnToryo* this, PlayState* play) { return ret; } -s32 func_80B206A0(EnToryo* this, PlayState* play) { +s32 EnToryo_GetTextId(EnToryo* this, PlayState* play) { s32 textId = Text_GetFaceReaction(play, 0); s32 ret = textId; @@ -286,35 +286,35 @@ s32 func_80B206A0(EnToryo* this, PlayState* play) { return ret; } -void func_80B20768(EnToryo* this, PlayState* play) { +void EnToryo_HandleTalking(EnToryo* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 sp32; s16 sp30; - if (this->unk_1E4 == 3 && !GameInteractor_Should(VB_FIX_SAW_SOFTLOCK, false)) { + if (this->messageState == 3 && !GameInteractor_Should(VB_FIX_SAW_SOFTLOCK, false)) { Actor_ProcessTalkRequest(&this->actor, play); Message_ContinueTextbox(play, this->actor.textId); - this->unk_1E4 = 1; + this->messageState = 1; } - if (this->unk_1E4 == 1) { - this->unk_1E4 = func_80B203D8(this, play); + if (this->messageState == 1) { + this->messageState = EnToryo_TalkRespond(this, play); } - if (this->unk_1E4 == 5) { - this->unk_1E4 = func_80B205CC(this, play); + if (this->messageState == 5) { + this->messageState = EnToryo_DoneTalking(this, play); return; } - if (this->unk_1E4 == 2) { + if (this->messageState == 2) { Message_ContinueTextbox(play, this->actor.textId); - this->unk_1E4 = 1; + this->messageState = 1; } - if (this->unk_1E4 == 4) { + if (this->messageState == 4) { if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_TRADE_SAW, true, this)) { this->actor.parent = NULL; - this->unk_1E4 = 5; + this->messageState = 5; Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW); } else { Actor_OfferGetItem(&this->actor, play, GI_SWORD_BROKEN, 100.0f, 10.0f); @@ -322,29 +322,29 @@ void func_80B20768(EnToryo* this, PlayState* play) { return; } - if (this->unk_1E4 == 0) { + if (this->messageState == 0) { if (Actor_ProcessTalkRequest(&this->actor, play)) { - this->unk_1E0 = func_8002F368(play); - if (this->unk_1E0 != 0) { - player->actor.textId = func_80B20634(this, play); + this->exchangeItemId = func_8002F368(play); + if (this->exchangeItemId != 0) { + player->actor.textId = EnToryo_ReactToExchangeItem(this, play); this->actor.textId = player->actor.textId; } - this->unk_1E4 = 1; + this->messageState = 1; return; } Actor_GetScreenPos(play, &this->actor, &sp32, &sp30); if ((sp32 >= 0) && (sp32 < 0x141) && (sp30 >= 0) && (sp30 < 0xF1)) { - this->actor.textId = func_80B206A0(this, play); + this->actor.textId = EnToryo_GetTextId(this, play); func_8002F298(&this->actor, play, 100.0f, 10); } } } -void func_80B20914(EnToryo* this, PlayState* play) { +void EnToryo_Idle(EnToryo* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - func_80B20768(this, play); - if (this->unk_1E4 != 0) { + EnToryo_HandleTalking(this, play); + if (this->messageState != 0) { this->stateFlags |= 0x10; } else { this->stateFlags &= ~0x10; diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h index 8e44ed0a91..25d7f0c090 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h @@ -13,8 +13,8 @@ typedef struct EnToryo { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnToryoActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ s32 unk_1E0; - /* 0x01E4 */ s32 unk_1E4; + /* 0x01E0 */ s32 exchangeItemId; + /* 0x01E4 */ s32 messageState; /* 0x01E8 */ u16 stateFlags; /* 0x01EA */ s16 unk_1EA; /* 0x01EC */ NpcInteractInfo interactInfo; diff --git a/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c b/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c index fe771b892a..f14bee8e57 100644 --- a/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c +++ b/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c @@ -16,17 +16,17 @@ void EnWeiyer_Destroy(Actor* thisx, PlayState* play); void EnWeiyer_Update(Actor* thisx, PlayState* play); void EnWeiyer_Draw(Actor* thisx, PlayState* play); -void func_80B32804(EnWeiyer* this, PlayState* play); -void func_80B328E8(EnWeiyer* this, PlayState* play); -void func_80B32C2C(EnWeiyer* this, PlayState* play); -void func_80B32D30(EnWeiyer* this, PlayState* play); -void func_80B32E34(EnWeiyer* this, PlayState* play); -void func_80B33018(EnWeiyer* this, PlayState* play); -void func_80B331CC(EnWeiyer* this, PlayState* play); -void func_80B333B8(EnWeiyer* this, PlayState* play); -void func_80B332B4(EnWeiyer* this, PlayState* play); -void func_80B33338(EnWeiyer* this, PlayState* play); -void func_80B3349C(EnWeiyer* this, PlayState* play); +void EnWeiyer_InitInsideWaterBox(EnWeiyer* this, PlayState* play); +void EnWeiyer_FreeSwim(EnWeiyer* this, PlayState* play); +void EnWeiyer_TurnAround(EnWeiyer* this, PlayState* play); +void EnWeiyer_StuckOnFloor(EnWeiyer* this, PlayState* play); +void EnWeiyer_Attack(EnWeiyer* this, PlayState* play); +void EnWeiyer_Inactive(EnWeiyer* this, PlayState* play); +void EnWeiyer_Hurt(EnWeiyer* this, PlayState* play); +void EnWeiyer_Stunned(EnWeiyer* this, PlayState* play); +void EnWeiyer_Die(EnWeiyer* this, PlayState* play); +void EnWeiyer_Dead(EnWeiyer* this, PlayState* play); +void EnWeiyer_OutOfWater(EnWeiyer* this, PlayState* play); const ActorInit En_Weiyer_InitVars = { ACTOR_EN_WEIYER, @@ -112,7 +112,7 @@ void EnWeiyer_Init(Actor* thisx, PlayState* play) { Collider_InitCylinder(play, &this->collider); Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); - this->actionFunc = func_80B32804; + this->actionFunc = EnWeiyer_InitInsideWaterBox; } void EnWeiyer_Destroy(Actor* thisx, PlayState* play) { @@ -123,52 +123,52 @@ void EnWeiyer_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -void func_80B32384(EnWeiyer* this) { - this->unk_196 = this->actor.shape.rot.y; - this->unk_27C = (cosf(-M_PI / 8) * 3.0f) + this->actor.world.pos.y; +void EnWeiyer_SetupFreeSwim(EnWeiyer* this) { + this->targetYaw = this->actor.shape.rot.y; + this->swimHeight = (cosf(-M_PI / 8) * 3.0f) + this->actor.world.pos.y; Animation_MorphToLoop(&this->skelAnime, &gStingerHitAnim, -5.0f); - this->unk_194 = 30; + this->timer = 30; this->actor.speedXZ = CLAMP_MAX(this->actor.speedXZ, 2.5f); this->collider.base.atFlags &= ~AT_ON; - this->unk_280 = this->actor.floorHeight; - this->actionFunc = func_80B328E8; + this->targetSwimHeight = this->actor.floorHeight; + this->actionFunc = EnWeiyer_FreeSwim; } -void func_80B32434(EnWeiyer* this) { +void EnWeiyer_SetupTurnAround(EnWeiyer* this) { Animation_MorphToLoop(&this->skelAnime, &gStingerHitAnim, -5.0f); this->collider.base.atFlags |= AT_ON; - this->unk_194 = 0; + this->timer = 0; this->actor.speedXZ = 5.0f; - this->actionFunc = func_80B32C2C; + this->actionFunc = EnWeiyer_TurnAround; } -void func_80B32494(EnWeiyer* this) { +void EnWeiyer_SetupStuckOnFloor(EnWeiyer* this) { Animation_Change(&this->skelAnime, &gStingerPopOutAnim, 2.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f); - this->unk_194 = 40; + this->timer = 40; this->collider.base.atFlags |= AT_ON; - this->actionFunc = func_80B32D30; + this->actionFunc = EnWeiyer_StuckOnFloor; } -void func_80B32508(EnWeiyer* this) { - this->unk_194 = 200; +void EnWeiyer_SetupAttack(EnWeiyer* this) { + this->timer = 200; this->collider.base.atFlags |= AT_ON; this->skelAnime.playSpeed = 3.0f; - this->actionFunc = func_80B32E34; + this->actionFunc = EnWeiyer_Attack; } -void func_80B32538(EnWeiyer* this) { - this->unk_194 = 200; - this->unk_196 = this->actor.yawTowardsPlayer + 0x8000; - this->unk_27C = this->actor.world.pos.y; +void EnWeiyer_SetupInactive(EnWeiyer* this) { + this->timer = 200; + this->targetYaw = this->actor.yawTowardsPlayer + 0x8000; + this->swimHeight = this->actor.world.pos.y; this->actor.speedXZ = CLAMP_MAX(this->actor.speedXZ, 4.0f); this->collider.base.atFlags &= ~AT_ON; this->skelAnime.playSpeed = 1.0f; - this->actionFunc = func_80B33018; + this->actionFunc = EnWeiyer_Inactive; } -void func_80B325A0(EnWeiyer* this) { +void EnWeiyer_SetupHurt(EnWeiyer* this) { Animation_Change(&this->skelAnime, &gStingerHitAnim, 2.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -3.0f); - this->unk_194 = 40; + this->timer = 40; this->collider.base.atFlags &= ~AT_ON; this->collider.base.acFlags &= ~AC_ON; this->actor.gravity = 0.0f; @@ -176,12 +176,12 @@ void func_80B325A0(EnWeiyer* this) { this->actor.speedXZ = 3.0f; Actor_SetColorFilter(&this->actor, 0x4000, 0xC8, 0, 0x28); this->collider.dim.height = sCylinderInit.dim.height; - this->actionFunc = func_80B331CC; + this->actionFunc = EnWeiyer_Hurt; } -void func_80B32660(EnWeiyer* this) { +void EnWeiyer_SetupStunned(EnWeiyer* this) { Animation_Change(&this->skelAnime, &gStingerPopOutAnim, 2.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f); - this->unk_194 = 80; + this->timer = 80; this->actor.speedXZ = 0.0f; this->actor.velocity.y = 0.0f; this->actor.gravity = -1.0f; @@ -189,34 +189,34 @@ void func_80B32660(EnWeiyer* this) { Actor_SetColorFilter(&this->actor, 0, 0xC8, 0, 0x50); this->collider.base.atFlags &= ~AT_ON; Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE); - this->actionFunc = func_80B333B8; + this->actionFunc = EnWeiyer_Stunned; } -void func_80B32724(EnWeiyer* this) { +void EnWeiyer_SetupDie(EnWeiyer* this) { Animation_MorphToLoop(&this->skelAnime, &gStingerHitAnim, -5.0f); - this->unk_194 = 20; + this->timer = 20; Actor_SetColorFilter(&this->actor, 0x4000, 0xC8, 0, 0x28); this->collider.base.atFlags &= ~AT_ON; this->collider.base.acFlags &= ~AC_ON; this->actor.speedXZ = 3.0f; - this->actionFunc = func_80B332B4; + this->actionFunc = EnWeiyer_Die; } -void func_80B327B0(EnWeiyer* this) { +void EnWeiyer_SetupDead(EnWeiyer* this) { this->actor.colorFilterParams |= 0x2000; this->actor.speedXZ = 0.0f; this->actor.velocity.y = 0.0f; - this->actionFunc = func_80B33338; + this->actionFunc = EnWeiyer_Dead; } -void func_80B327D8(EnWeiyer* this) { +void EnWeiyer_SetupOutOfWater(EnWeiyer* this) { this->actor.shape.rot.x = -0x2000; - this->unk_194 = -1; + this->timer = -1; this->actor.speedXZ = 5.0f; - this->actionFunc = func_80B3349C; + this->actionFunc = EnWeiyer_OutOfWater; } -void func_80B32804(EnWeiyer* this, PlayState* play) { +void EnWeiyer_InitInsideWaterBox(EnWeiyer* this, PlayState* play) { WaterBox* waterBox; s32 bgId; @@ -231,11 +231,11 @@ void func_80B32804(EnWeiyer* this, PlayState* play) { } else { this->actor.home.pos.y -= 5.0f; this->actor.world.pos.y = (this->actor.home.pos.y + this->actor.floorHeight) / 2.0f; - func_80B32384(this); + EnWeiyer_SetupFreeSwim(this); } } -void func_80B328E8(EnWeiyer* this, PlayState* play) { +void EnWeiyer_FreeSwim(EnWeiyer* this, PlayState* play) { s32 sp34; f32 curFrame; @@ -243,8 +243,8 @@ void func_80B328E8(EnWeiyer* this, PlayState* play) { Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x800); sp34 = Animation_OnFrame(&this->skelAnime, 0.0f); curFrame = this->skelAnime.curFrame; - Math_StepToF(&this->unk_27C, this->unk_280, 0.5f); - this->actor.world.pos.y = this->unk_27C - cosf((curFrame - 5.0f) * (M_PI / 40)) * 3.0f; + Math_StepToF(&this->swimHeight, this->targetSwimHeight, 0.5f); + this->actor.world.pos.y = this->swimHeight - cosf((curFrame - 5.0f) * (M_PI / 40)) * 3.0f; if (curFrame <= 45.0f) { Math_StepToF(&this->actor.speedXZ, 1.0f, 0.03f); @@ -253,19 +253,19 @@ void func_80B328E8(EnWeiyer* this, PlayState* play) { } if (this->actor.bgCheckFlags & 8) { - this->unk_196 = this->actor.wallYaw; - this->unk_194 = 30; + this->targetYaw = this->actor.wallYaw; + this->timer = 30; } - if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_196, 182)) { - if (this->unk_194 != 0) { - this->unk_194--; + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->targetYaw, 182)) { + if (this->timer != 0) { + this->timer--; } - if (this->unk_194 == 0) { - this->unk_196 = + if (this->timer == 0) { + this->targetYaw = Rand_S16Offset(0x2000, 0x2000) * ((Rand_ZeroOne() < 0.5f) ? -1 : 1) + this->actor.shape.rot.y; - this->unk_194 = 30; + this->timer = 30; if (Rand_ZeroOne() < 0.3333f) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_EIER_CRY); @@ -275,38 +275,38 @@ void func_80B328E8(EnWeiyer* this, PlayState* play) { if (this->actor.home.pos.y < this->actor.world.pos.y) { if (this->actor.home.pos.y < this->actor.floorHeight) { - func_80B32434(this); + EnWeiyer_SetupTurnAround(this); } else { this->actor.world.pos.y = this->actor.home.pos.y; - this->unk_280 = + this->targetSwimHeight = Rand_ZeroOne() * ((this->actor.home.pos.y - this->actor.floorHeight) / 2.0f) + this->actor.floorHeight; } } else { Player* player = GET_PLAYER(play); if (this->actor.bgCheckFlags & 1) { - this->unk_280 = + this->targetSwimHeight = this->actor.home.pos.y - Rand_ZeroOne() * ((this->actor.home.pos.y - this->actor.floorHeight) / 2.0f); } else if (sp34 && (Rand_ZeroOne() < 0.1f)) { - this->unk_280 = + this->targetSwimHeight = Rand_ZeroOne() * (this->actor.home.pos.y - this->actor.floorHeight) + this->actor.floorHeight; } if ((this->actor.xzDistToPlayer < 400.0f) && (fabsf(this->actor.yDistToPlayer) < 250.0f) && (player->actor.world.pos.y < (this->actor.home.pos.y + 20.0f))) { - func_80B32508(this); + EnWeiyer_SetupAttack(this); } } } -void func_80B32C2C(EnWeiyer* this, PlayState* play) { +void EnWeiyer_TurnAround(EnWeiyer* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (this->unk_194 == 0) { + if (this->timer == 0) { if (Math_ScaledStepToS(&this->actor.shape.rot.x, -0x4000, 0x800)) { this->actor.shape.rot.z = 0; this->actor.shape.rot.y += 0x8000; - this->unk_194 = 1; + this->timer = 1; } else { this->actor.shape.rot.z = this->actor.shape.rot.x * 2; } @@ -319,14 +319,14 @@ void func_80B32C2C(EnWeiyer* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_OCTAROCK_SINK); } - func_80B32538(this); + EnWeiyer_SetupInactive(this); } else if (this->actor.bgCheckFlags & 1) { - func_80B32494(this); + EnWeiyer_SetupStuckOnFloor(this); } } } -void func_80B32D30(EnWeiyer* this, PlayState* play) { +void EnWeiyer_StuckOnFloor(EnWeiyer* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 0.0f)) { @@ -336,18 +336,18 @@ void func_80B32D30(EnWeiyer* this, PlayState* play) { Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x800); Math_StepToF(&this->actor.speedXZ, 0.0f, 1.0f); - if (this->unk_194 != 0) { - this->unk_194--; + if (this->timer != 0) { + this->timer--; } - if (this->unk_194 == 0) { - func_80B32434(this); + if (this->timer == 0) { + EnWeiyer_SetupTurnAround(this); } else if (this->actor.world.pos.y < this->actor.home.pos.y) { - func_80B32384(this); + EnWeiyer_SetupFreeSwim(this); } } -s16 func_80B32DEC(EnWeiyer* this, PlayState* play) { +s16 EnWeiyer_PitchTowardPlayer(EnWeiyer* this, PlayState* play) { Player* player = GET_PLAYER(play); Vec3f vec; @@ -358,18 +358,18 @@ s16 func_80B32DEC(EnWeiyer* this, PlayState* play) { return Actor_WorldPitchTowardPoint(&this->actor, &vec); } -void func_80B32E34(EnWeiyer* this, PlayState* play) { +void EnWeiyer_Attack(EnWeiyer* this, PlayState* play) { Player* player = GET_PLAYER(play); SkelAnime_Update(&this->skelAnime); - if (this->unk_194 != 0) { - this->unk_194--; + if (this->timer != 0) { + this->timer--; } - if ((this->unk_194 == 0) || ((this->actor.home.pos.y + 20.0f) <= player->actor.world.pos.y) || + if ((this->timer == 0) || ((this->actor.home.pos.y + 20.0f) <= player->actor.world.pos.y) || (this->collider.base.atFlags & AT_HIT)) { - func_80B32538(this); + EnWeiyer_SetupInactive(this); } else { if (Actor_IsFacingPlayer(&this->actor, 0x2800)) { Math_StepToF(&this->actor.speedXZ, 4.0f, 0.2f); @@ -380,34 +380,34 @@ void func_80B32E34(EnWeiyer* this, PlayState* play) { if (this->actor.home.pos.y < this->actor.world.pos.y) { if (this->actor.home.pos.y < this->actor.floorHeight) { this->actor.shape.rot.x = 0; - func_80B32434(this); + EnWeiyer_SetupTurnAround(this); return; } this->actor.world.pos.y = this->actor.home.pos.y; Math_SmoothStepToS(&this->actor.shape.rot.x, 0x1000, 2, 0x100, 0x40); } else { - Math_SmoothStepToS(&this->actor.shape.rot.x, func_80B32DEC(this, play), 2, 0x100, 0x40); + Math_SmoothStepToS(&this->actor.shape.rot.x, EnWeiyer_PitchTowardPlayer(this, play), 2, 0x100, 0x40); } Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x200, 0x80); if ((player->actor.yDistToWater < 50.0f) && (this->actor.yDistToWater < 20.0f) && Actor_IsFacingPlayer(&this->actor, 0x2000)) { - func_80B327D8(this); + EnWeiyer_SetupOutOfWater(this); } } } -void func_80B33018(EnWeiyer* this, PlayState* play) { +void EnWeiyer_Inactive(EnWeiyer* this, PlayState* play) { f32 curFrame; SkelAnime_Update(&this->skelAnime); Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x800); curFrame = this->skelAnime.curFrame; - Math_StepToF(&this->unk_27C, (this->actor.home.pos.y - this->actor.floorHeight) / 4.0f + this->actor.floorHeight, + Math_StepToF(&this->swimHeight, (this->actor.home.pos.y - this->actor.floorHeight) / 4.0f + this->actor.floorHeight, 1.0f); - this->actor.world.pos.y = this->unk_27C - cosf((curFrame - 5.0f) * (M_PI / 40)) * 3.0f; + this->actor.world.pos.y = this->swimHeight - cosf((curFrame - 5.0f) * (M_PI / 40)) * 3.0f; if (curFrame <= 45.0f) { Math_StepToF(&this->actor.speedXZ, 1.0f, 0.03f); @@ -415,70 +415,70 @@ void func_80B33018(EnWeiyer* this, PlayState* play) { Math_StepToF(&this->actor.speedXZ, 1.3f, 0.03f); } - if (this->unk_194 != 0) { - this->unk_194--; + if (this->timer != 0) { + this->timer--; } if (this->actor.bgCheckFlags & 8) { - this->unk_196 = this->actor.wallYaw; + this->targetYaw = this->actor.wallYaw; } - if (Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_196, 2, 0x200, 0x80) == 0) { - this->unk_196 = this->actor.yawTowardsPlayer + 0x8000; + if (Math_SmoothStepToS(&this->actor.shape.rot.y, this->targetYaw, 2, 0x200, 0x80) == 0) { + this->targetYaw = this->actor.yawTowardsPlayer + 0x8000; } if (this->actor.home.pos.y < this->actor.world.pos.y) { if (this->actor.home.pos.y < this->actor.floorHeight) { - func_80B32434(this); + EnWeiyer_SetupTurnAround(this); } else { this->actor.world.pos.y = this->actor.home.pos.y; } } - if (this->unk_194 == 0) { - func_80B32384(this); + if (this->timer == 0) { + EnWeiyer_SetupFreeSwim(this); } } -void func_80B331CC(EnWeiyer* this, PlayState* play) { +void EnWeiyer_Hurt(EnWeiyer* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (this->unk_194 != 0) { - this->unk_194--; + if (this->timer != 0) { + this->timer--; } if (this->actor.bgCheckFlags & 8) { - this->unk_196 = this->actor.wallYaw; + this->targetYaw = this->actor.wallYaw; } else { - this->unk_196 = this->actor.yawTowardsPlayer + 0x8000; + this->targetYaw = this->actor.yawTowardsPlayer + 0x8000; } - Math_ScaledStepToS(&this->actor.world.rot.y, this->unk_196, 0x38E); + Math_ScaledStepToS(&this->actor.world.rot.y, this->targetYaw, 0x38E); Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x200); - this->actor.shape.rot.z = sinf(this->unk_194 * (M_PI / 5)) * 5120.0f; + this->actor.shape.rot.z = sinf(this->timer * (M_PI / 5)) * 5120.0f; - if (this->unk_194 == 0) { + if (this->timer == 0) { this->actor.shape.rot.z = 0; this->collider.base.acFlags |= AC_ON; - func_80B32384(this); + EnWeiyer_SetupFreeSwim(this); } } -void func_80B332B4(EnWeiyer* this, PlayState* play) { +void EnWeiyer_Die(EnWeiyer* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); Math_ScaledStepToS(&this->actor.shape.rot.x, -0x4000, 0x400); this->actor.shape.rot.z += 0x1000; - if (this->unk_194 != 0) { - this->unk_194--; + if (this->timer != 0) { + this->timer--; } - if ((this->unk_194 == 0) || (this->actor.bgCheckFlags & 0x10)) { - func_80B327B0(this); + if ((this->timer == 0) || (this->actor.bgCheckFlags & 0x10)) { + EnWeiyer_SetupDead(this); } } -void func_80B33338(EnWeiyer* this, PlayState* play) { +void EnWeiyer_Dead(EnWeiyer* this, PlayState* play) { this->actor.shape.shadowAlpha = CLAMP_MIN((s16)(this->actor.shape.shadowAlpha - 5), 0); this->actor.world.pos.y -= 2.0f; @@ -488,9 +488,9 @@ void func_80B33338(EnWeiyer* this, PlayState* play) { } } -void func_80B333B8(EnWeiyer* this, PlayState* play) { - if (this->unk_194 != 0) { - this->unk_194--; +void EnWeiyer_Stunned(EnWeiyer* this, PlayState* play) { + if (this->timer != 0) { + this->timer--; } Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x200); @@ -507,15 +507,15 @@ void func_80B333B8(EnWeiyer* this, PlayState* play) { } } - if (this->unk_194 == 0) { + if (this->timer == 0) { this->actor.gravity = 0.0f; this->actor.velocity.y = 0.0f; this->collider.dim.height = sCylinderInit.dim.height; - func_80B32384(this); + EnWeiyer_SetupFreeSwim(this); } } -void func_80B3349C(EnWeiyer* this, PlayState* play) { +void EnWeiyer_OutOfWater(EnWeiyer* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 phi_a1; s32 phi_a0; @@ -524,25 +524,25 @@ void func_80B3349C(EnWeiyer* this, PlayState* play) { phi_a0 = ((this->actor.home.pos.y + 20.0f) <= player->actor.world.pos.y); - if (this->unk_194 == -1) { + if (this->timer == -1) { if (phi_a0 || (this->collider.base.atFlags & AT_HIT)) { - func_80B32538(this); + EnWeiyer_SetupInactive(this); } else if (this->actor.yDistToWater < 0.0f) { - this->unk_194 = 10; + this->timer = 10; EffectSsGSplash_Spawn(play, &this->actor.world.pos, NULL, NULL, 1, 400); Audio_PlayActorSound2(&this->actor, NA_SE_EN_OCTAROCK_JUMP); } } else { if (phi_a0 || (this->collider.base.atFlags & AT_HIT)) { - this->unk_194 = 0; - } else if (this->unk_194 != 0) { - this->unk_194--; + this->timer = 0; + } else if (this->timer != 0) { + this->timer--; } - if (this->unk_194 == 0) { + if (this->timer == 0) { phi_a1 = 0x1800; } else { - phi_a1 = func_80B32DEC(this, play); + phi_a1 = EnWeiyer_PitchTowardPlayer(this, play); phi_a1 = CLAMP_MIN(phi_a1, 0); } @@ -551,35 +551,35 @@ void func_80B3349C(EnWeiyer* this, PlayState* play) { } if (this->actor.bgCheckFlags & 1) { - func_80B32434(this); + EnWeiyer_SetupTurnAround(this); } else if ((this->actor.bgCheckFlags & 0x20) && (this->actor.shape.rot.x > 0)) { EffectSsGSplash_Spawn(play, &this->actor.world.pos, NULL, NULL, 1, 400); Audio_PlayActorSound2(&this->actor, NA_SE_EN_OCTAROCK_SINK); - func_80B32538(this); + EnWeiyer_SetupInactive(this); } else { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 8, 0x100, 0x80); } } } -void func_80B3368C(EnWeiyer* this, PlayState* play) { +void EnWeiyer_UpdateDamage(EnWeiyer* this, PlayState* play) { if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; Actor_SetDropFlag(&this->actor, &this->collider.info, 1); if ((this->actor.colChkInfo.damageEffect != 0) || (this->actor.colChkInfo.damage != 0)) { if (this->actor.colChkInfo.damageEffect == 1) { - if (this->actionFunc != func_80B333B8) { - func_80B32660(this); + if (this->actionFunc != EnWeiyer_Stunned) { + EnWeiyer_SetupStunned(this); } } else if (Actor_ApplyDamage(&this->actor) == 0) { Enemy_StartFinishingBlow(play, &this->actor); Audio_PlayActorSound2(&this->actor, NA_SE_EN_EIER_DEAD); this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - func_80B32724(this); + EnWeiyer_SetupDie(this); GameInteractor_ExecuteOnEnemyDefeat(&this->actor); } else { - func_80B325A0(this); + EnWeiyer_SetupHurt(this); } } } @@ -590,12 +590,12 @@ void EnWeiyer_Update(Actor* thisx, PlayState* play) { s32 pad; this->actor.home.pos.y = this->actor.yDistToWater + this->actor.world.pos.y - 5.0f; - func_80B3368C(this, play); + EnWeiyer_UpdateDamage(this, play); this->actionFunc(this, play); this->actor.world.rot.y = this->actor.shape.rot.y; this->actor.world.rot.x = -this->actor.shape.rot.x; - if ((this->actor.world.rot.x == 0) || (this->actionFunc == func_80B333B8)) { + if ((this->actor.world.rot.x == 0) || (this->actionFunc == EnWeiyer_Stunned)) { Actor_MoveXZGravity(&this->actor); } else { Actor_MoveXYZ(&this->actor); @@ -636,7 +636,7 @@ void EnWeiyer_Draw(Actor* thisx, PlayState* play) { OPEN_DISPS(play->state.gfxCtx); - if (this->actionFunc != func_80B33338) { + if (this->actionFunc != EnWeiyer_Dead) { Gfx_SetupDL_25Opa(play->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x08, &D_80116280[2]); gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); diff --git a/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.h b/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.h index ab61af5bca..22447b0690 100644 --- a/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.h +++ b/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.h @@ -12,12 +12,12 @@ typedef struct EnWeiyer { /* 0x0000 */ Actor actor; /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnWeiyerActionFunc actionFunc; - /* 0x0194 */ s16 unk_194; - /* 0x0196 */ s16 unk_196; + /* 0x0194 */ s16 timer; + /* 0x0196 */ s16 targetYaw; /* 0x0198 */ Vec3s jointTable[19]; /* 0x020A */ Vec3s morphTable[19]; - /* 0x027C */ f32 unk_27C; - /* 0x0280 */ f32 unk_280; + /* 0x027C */ f32 swimHeight; + /* 0x0280 */ f32 targetSwimHeight; /* 0x0284 */ ColliderCylinder collider; } EnWeiyer; // size = 0x02D0 diff --git a/soh/src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c b/soh/src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c index d7c0ddf702..4003ab624f 100644 --- a/soh/src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c +++ b/soh/src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c @@ -6,6 +6,7 @@ #include "z_en_wonder_item.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -54,8 +55,8 @@ const ActorInit En_Wonder_Item_InitVars = { NULL, }; -static Vec3f sTagPointsFree[9]; -static Vec3f sTagPointsOrdered[9]; +Vec3f sTagPointsFree[9]; // SOH [Randomizer] remove static to use in ShuffleWonderItems +Vec3f sTagPointsOrdered[9]; // SOH [Randomizer] remove static to use in ShuffleWonderItems void EnWonderItem_Destroy(Actor* thisx, PlayState* play) { s32 pad; @@ -75,24 +76,26 @@ void EnWonderItem_DropCollectible(EnWonderItem* this, PlayState* play, s32 autoC s32 i; s32 randomDrop; - Sfx_PlaySfxCentered(NA_SE_SY_GET_ITEM); + if (GameInteractor_Should(VB_WONDER_DROP_ITEM, true, this)) { + Sfx_PlaySfxCentered(NA_SE_SY_GET_ITEM); - if (this->dropCount == 0) { - this->dropCount++; - } - for (i = this->dropCount; i > 0; i--) { - if (this->itemDrop < WONDERITEM_DROP_RANDOM) { - if ((this->itemDrop == WONDERITEM_DROP_FLEXIBLE) || !autoCollect) { - Item_DropCollectible(play, &this->actor.world.pos, dropTable[this->itemDrop]); + if (this->dropCount == 0) { + this->dropCount++; + } + for (i = this->dropCount; i > 0; i--) { + if (this->itemDrop < WONDERITEM_DROP_RANDOM) { + if ((this->itemDrop == WONDERITEM_DROP_FLEXIBLE) || !autoCollect) { + Item_DropCollectible(play, &this->actor.world.pos, dropTable[this->itemDrop]); + } else { + Item_DropCollectible(play, &this->actor.world.pos, dropTable[this->itemDrop] | 0x8000); + } } else { - Item_DropCollectible(play, &this->actor.world.pos, dropTable[this->itemDrop] | 0x8000); - } - } else { - randomDrop = this->itemDrop - WONDERITEM_DROP_RANDOM; - if (!autoCollect) { - Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, randomDrop); - } else { - Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, randomDrop | 0x8000); + randomDrop = this->itemDrop - WONDERITEM_DROP_RANDOM; + if (!autoCollect) { + Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, randomDrop); + } else { + Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, randomDrop | 0x8000); + } } } } @@ -104,9 +107,10 @@ void EnWonderItem_DropCollectible(EnWonderItem* this, PlayState* play, s32 autoC void EnWonderItem_Init(Actor* thisx, PlayState* play) { static u32 collisionTypes[] = { - 0x00000702 /* sword slash */, 0x0001F820 /* arrow */, 0x00000040 /* hammer */, 0x00000008 /* bomb */, - 0x00000004 /* slingshot */, 0x00000010 /* boomerang */, 0x00000080 /* hookshot */, - }; + 0x00000702 /* sword slash */, 0x0001F820 /* arrow */, 0x00000040 /* hammer */, + 0x00000008 /* bomb */, 0x00000004 /* slingshot */, 0x00000010 /* boomerang */, + 0x00000080 /* hookshot */, 0x0001F820 | 0x00000080 /* arrow or hookshot */ + }; // SOH [Port] add final array entry to avoid OOB behavior on Water MQ Torches room wonder item s32 pad; s16 colTypeIndex; EnWonderItem* this = (EnWonderItem*)thisx; @@ -125,7 +129,7 @@ void EnWonderItem_Init(Actor* thisx, PlayState* play) { this->switchFlag = -1; } this->actor.targetMode = 1; - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if (GameInteractor_Should(VB_WONDER_SPAWN, (this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag))) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ You are Shock! ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag); Actor_Kill(&this->actor); return; @@ -312,7 +316,7 @@ void EnWonderItem_BombSoldier(EnWonderItem* this, PlayState* play) { // "Careless soldier spawned" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ うっかり兵セット完了 ☆☆☆☆☆ \n" VT_RST); } - if (this->switchFlag >= 0) { + if (GameInteractor_Should(VB_WONDER_DROP_ITEM, this->switchFlag >= 0, this)) { Flags_SetSwitch(play, this->switchFlag); } Actor_Kill(&this->actor); diff --git a/soh/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.h b/soh/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.h index 423b5302f8..f8d6063c6f 100644 --- a/soh/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.h +++ b/soh/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.h @@ -16,7 +16,7 @@ typedef struct EnWonderTalk { /* 0x0154 */ s16 switchFlag; /* 0x0156 */ s16 unk_156; /* 0x0158 */ s16 unk_158; - /* 0x0160 */ s16 unk_15A; + /* 0x015A */ s16 unk_15A; /* 0x015C */ f32 unk_15C; /* 0x0160 */ f32 height; /* 0x0164 */ u8 unk_164; diff --git a/soh/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c b/soh/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c index 683e601a0c..10df16846c 100644 --- a/soh/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c +++ b/soh/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c @@ -6,6 +6,7 @@ #include "z_en_yabusame_mark.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -160,6 +161,8 @@ void func_80B42F74(EnYabusameMark* this, PlayState* play) { } } + GameInteractor_Should(VB_SCORE_HORSEBACK_ARCHERY_TARGET, true, &scoreIndex); + osSyncPrintf("\n\n"); osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ posX ☆☆☆☆☆ %f\n" VT_RST, arrowHitPos.x); osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ posY ☆☆☆☆☆ %f\n" VT_RST, arrowHitPos.y); diff --git a/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c b/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c index c027449590..b7178a89a3 100644 --- a/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c +++ b/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c @@ -173,17 +173,17 @@ void func_80B4B010(EnZl1* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { Animation_Change(&this->skelAnime, &gChildZelda1Anim_10B38, 1.0f, 0.0f, Animation_GetLastFrame(&gChildZelda1Anim_10B38), ANIMMODE_ONCE_INTERP, -10.0f); - this->unk_1E8 = Play_CreateSubCamera(play); + this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->unk_1E8, CAM_STAT_ACTIVE); - func_800C0808(play, this->unk_1E8, player, CAM_SET_FREE0); + Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); + func_800C0808(play, this->subCamId, player, CAM_SET_FREE0); play->envCtx.screenFillColor[0] = 255; play->envCtx.screenFillColor[1] = 255; play->envCtx.screenFillColor[2] = 255; play->envCtx.screenFillColor[3] = 24; play->envCtx.fillScreen = true; - Play_CameraSetAtEye(play, this->unk_1E8, &vec1, &vec2); - Play_CameraSetFov(play, this->unk_1E8, 30.0f); + Play_CameraSetAtEye(play, this->subCamId, &vec1, &vec2); + Play_CameraSetFov(play, this->subCamId, 30.0f); ShrinkWindow_SetVal(0x20); Interface_ChangeAlpha(2); player->actor.world.pos = playerPos; @@ -235,8 +235,8 @@ void func_80B4B240(EnZl1* this, PlayState* play) { case 1: if ((Message_GetState(msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { play->envCtx.fillScreen = false; - Play_CameraSetAtEye(play, this->unk_1E8, &sp74, &sp68); - Play_CameraSetFov(play, this->unk_1E8, 25.0f); + Play_CameraSetAtEye(play, this->subCamId, &sp74, &sp68); + Play_CameraSetFov(play, this->subCamId, 25.0f); player->actor.world.pos = sp58; this->actor.textId = 0x702F; Message_ContinueTextbox(play, this->actor.textId); @@ -414,8 +414,8 @@ void func_80B4B8B4(EnZl1* this, PlayState* play) { this->actor.velocity.z = (sp68.z - sp74.z) / actionLength; } func_80038290(play, &this->actor, &this->unk_200, &this->unk_206, this->actor.focus.pos); - Play_CameraSetAtEye(play, this->unk_1E8, &sp98, &sp8C); - Play_CameraSetFov(play, this->unk_1E8, 70.0f); + Play_CameraSetAtEye(play, this->subCamId, &sp98, &sp8C); + Play_CameraSetFov(play, this->subCamId, 70.0f); } } @@ -523,9 +523,9 @@ void func_80B4BF2C(EnZl1* this, PlayState* play) { } case 2: if (Actor_HasParent(&this->actor, play)) { - Play_CopyCamera(play, MAIN_CAM, this->unk_1E8); + Play_CopyCamera(play, MAIN_CAM, this->subCamId); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); - Play_ClearCamera(play, this->unk_1E8); + Play_ClearCamera(play, this->subCamId); this->actor.parent = NULL; this->unk_1E2++; } else { diff --git a/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.h b/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.h index 4b99e10f83..b4435d6b4f 100644 --- a/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.h +++ b/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.h @@ -17,7 +17,7 @@ typedef struct EnZl1 { /* 0x01E2 */ s16 unk_1E2; /* 0x01E4 */ s16 unk_1E4; /* 0x01E6 */ s16 unk_1E6; - /* 0x01E8 */ s16 unk_1E8; + /* 0x01E8 */ s16 subCamId; /* 0x01EA */ char unk_1EA[0x2]; /* 0x01EC */ void* unk_1EC; /* 0x01F0 */ char unk_1F0[0x2]; diff --git a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c index 0879e8b7b3..1c8a531fab 100644 --- a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c +++ b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c @@ -559,7 +559,7 @@ void EnZl2_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, } void func_80B4FCCC(EnZl2* this, PlayState* play) { - s32 unk_274 = this->unk_274; + s32 unk_274 = this->zl2Anime1ObjectSlot; gSegments[6] = VIRTUAL_TO_PHYSICAL(play->objectCtx.status[unk_274].segment); } @@ -921,7 +921,7 @@ void func_80B50A04(EnZl2* this, PlayState* play) { if (npcAction != NULL) { newAction = npcAction->action; - unk_240 = this->unk_240; + unk_240 = this->cueId; if (newAction != unk_240) { switch (newAction) { case 1: @@ -972,7 +972,7 @@ void func_80B50A04(EnZl2* this, PlayState* play) { default: osSyncPrintf("En_Zl2_inAgain_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); } - this->unk_240 = newAction; + this->cueId = newAction; } } } @@ -1332,7 +1332,7 @@ void func_80B51948(EnZl2* this, PlayState* play) { if (npcAction != NULL) { newAction = npcAction->action; - unk_240 = this->unk_240; + unk_240 = this->cueId; if (newAction != unk_240) { switch (newAction) { case 1: @@ -1362,7 +1362,7 @@ void func_80B51948(EnZl2* this, PlayState* play) { default: osSyncPrintf("En_Zl2_inEnding_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); } - this->unk_240 = newAction; + this->cueId = newAction; } } } @@ -1511,7 +1511,7 @@ void func_80B51FA8(EnZl2* this, PlayState* play) { if (npcAction != NULL) { action = npcAction->action; - unk_240 = this->unk_240; + unk_240 = this->cueId; if (action != unk_240) { switch (action) { case 1: @@ -1527,7 +1527,7 @@ void func_80B51FA8(EnZl2* this, PlayState* play) { osSyncPrintf("En_Zl2_inRunning_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); break; } - this->unk_240 = action; + this->cueId = action; } } } @@ -1579,7 +1579,7 @@ void func_80B521A0(EnZl2* this, PlayState* play) { } if (Object_IsLoaded(objectCtx, bankIndex)) { - this->unk_274 = bankIndex; + this->zl2Anime1ObjectSlot = bankIndex; func_80B4FCCC(this, play); this->unk_278 = Animation_GetLastFrame(&gZelda2Anime1Anim_0022D0); func_80B52114(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.h b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.h index ec519365a1..74ab71bb1b 100644 --- a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.h +++ b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.h @@ -26,7 +26,7 @@ typedef struct EnZl2 { /* 0x01DC */ s16 unk_1DC[0x18]; // ??? /* 0x020C */ s16 unk_20C[0x18]; // ??? /* 0x023C */ f32 unk_23C; - /* 0x0240 */ s32 unk_240; + /* 0x0240 */ s32 cueId; /* 0x0244 */ s32 unk_244; /* 0x0248 */ s32 unk_248; /* 0x024C */ s32 unk_24C; @@ -35,7 +35,7 @@ typedef struct EnZl2 { /* 0x0258 */ char unk_258[0xC]; /* 0x0264 */ s32 overrideLimbDrawConfig; /* 0x0268 */ char unk_268[0xC]; - /* 0x0274 */ s32 unk_274; + /* 0x0274 */ s32 zl2Anime1ObjectSlot; /* 0x0278 */ f32 unk_278; /* 0x027C */ f32 unk_27C; } EnZl2; // size = 0x0280 diff --git a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c index eb715658a3..a672df2663 100644 --- a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c +++ b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c @@ -744,7 +744,7 @@ s32 func_80B54DD4(EnZl3* this) { } void func_80B54DE0(EnZl3* this, PlayState* play) { - s32 idx = this->unk_318; + s32 idx = this->zl2Anime2ObjectSlot; gSegments[6] = VIRTUAL_TO_PHYSICAL(play->objectCtx.status[idx].segment); } @@ -2634,7 +2634,7 @@ void func_80B59DB8(EnZl3* this, PlayState* play) { } if (Object_IsLoaded(objCtx, objIndex)) { - this->unk_318 = objIndex; + this->zl2Anime2ObjectSlot = objIndex; func_80B54DE0(this, play); func_80B59B6C(this, play); } diff --git a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h index 085225b070..5077e9f712 100644 --- a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h +++ b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h @@ -36,7 +36,7 @@ typedef struct EnZl3 { /* 0x030C */ Path* unk_30C; /* 0x0310 */ s32 unk_310; /* 0x0314 */ s32 unk_314; - /* 0x0318 */ s32 unk_318; + /* 0x0318 */ s32 zl2Anime2ObjectSlot; /* 0x031C */ Vec3f unk_31C; /* 0x0328 */ s32 unk_328; /* 0x032C */ Vec3f unk_32C; diff --git a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c index 372a69ffa0..e2a2ad3109 100644 --- a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c +++ b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c @@ -622,7 +622,7 @@ void EnZo_Destroy(Actor* thisx, PlayState* play) { void EnZo_Standing(EnZo* this, PlayState* play) { s16 angle; - func_80034F54(play, this->unk_656, this->unk_67E, 20); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 20); EnZo_SetAnimation(this); if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { this->trackingMode = NPC_TRACKING_FULL_BODY; @@ -664,7 +664,7 @@ void EnZo_Surface(EnZo* this, PlayState* play) { } void EnZo_TreadWater(EnZo* this, PlayState* play) { - func_80034F54(play, this->unk_656, this->unk_67E, 20); + func_80034F54(play, this->fidgetTableY, this->fidgetTableZ, 20); if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->canSpeak = true; this->trackingMode = NPC_TRACKING_FULL_BODY; @@ -779,8 +779,8 @@ s32 EnZo_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po } if ((limbIndex == 8) || (limbIndex == 9) || (limbIndex == 12)) { - rot->y += (Math_SinS(this->unk_656[limbIndex]) * 200.0f); - rot->z += (Math_CosS(this->unk_67E[limbIndex]) * 200.0f); + rot->y += (Math_SinS(this->fidgetTableY[limbIndex]) * 200.0f); + rot->z += (Math_CosS(this->fidgetTableZ[limbIndex]) * 200.0f); } return 0; diff --git a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h index c99177fad8..85fe4cc6ea 100644 --- a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h +++ b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h @@ -37,8 +37,8 @@ typedef struct EnZo { /* 0x0650 */ s16 timeToDive; /* 0x0652 */ s16 blinkTimer; /* 0x0654 */ s16 eyeTexture; - /* 0x0656 */ s16 unk_656[20]; - /* 0x067E */ s16 unk_67E[20]; + /* 0x0656 */ s16 fidgetTableY[20]; + /* 0x067E */ s16 fidgetTableZ[20]; } EnZo; // size = 0x06A8 #endif diff --git a/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.h b/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.h index 524c25c1ea..5bea0fb737 100644 --- a/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.h +++ b/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.h @@ -34,7 +34,7 @@ typedef struct EnfHG { /* 0x018C */ Vec3f inPaintingPos; /* 0x0198 */ f32 inPaintingVelX; /* 0x019C */ f32 inPaintingVelZ; - /* 0x0198 */ f32 damageSpeedMod; + /* 0x01A0 */ f32 damageSpeedMod; /* 0x01A4 */ f32 approachRate; /* 0x01A8 */ f32 cameraSpeedMod; /* 0x01AC */ f32 cameraPanZ; diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index ba925f8cf1..7edfb5a0f9 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -15,7 +15,7 @@ void ItemEtcetera_Update(Actor* thisx, PlayState* play); void ItemEtcetera_DrawThroughLens(Actor* thisx, PlayState* play); void ItemEtcetera_Draw(Actor* thisx, PlayState* play); -void func_80B857D0(ItemEtcetera* this, PlayState* play); +void ItemEtcetera_WaitForObject(ItemEtcetera* this, PlayState* play); void func_80B85824(ItemEtcetera* this, PlayState* play); void func_80B858B4(ItemEtcetera* this, PlayState* play); void ItemEtcetera_SpawnSparkles(ItemEtcetera* this, PlayState* play); @@ -78,7 +78,7 @@ void ItemEtcetera_Init(Actor* thisx, PlayState* play) { this->futureActionFunc = func_80B85824; this->drawFunc = ItemEtcetera_Draw; Actor_SetScale(&this->actor, 0.25f); - ItemEtcetera_SetupAction(this, func_80B857D0); + ItemEtcetera_SetupAction(this, ItemEtcetera_WaitForObject); switch (type) { case ITEM_ETC_LETTER: Actor_SetScale(&this->actor, 0.5f); @@ -110,7 +110,7 @@ void ItemEtcetera_Init(Actor* thisx, PlayState* play) { void ItemEtcetera_Destroy(Actor* thisx, PlayState* play) { } -void func_80B857D0(ItemEtcetera* this, PlayState* play) { +void ItemEtcetera_WaitForObject(ItemEtcetera* this, PlayState* play) { if (Object_IsLoaded(&play->objectCtx, this->objBankIndex)) { this->actor.objBankIndex = this->objBankIndex; this->actor.draw = this->drawFunc; diff --git a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c index 602236816e..2854963750 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c +++ b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c @@ -7,6 +7,7 @@ #include "z_obj_bombiwa.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/object_bombiwa/object_bombiwa.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -75,7 +76,7 @@ void ObjBombiwa_InitCollision(Actor* thisx, PlayState* play) { void ObjBombiwa_Init(Actor* thisx, PlayState* play) { Actor_ProcessInitChain(thisx, sInitChain); ObjBombiwa_InitCollision(thisx, play); - if ((Flags_GetSwitch(play, thisx->params & 0x3F) != 0)) { + if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, thisx->params & 0x3F), thisx)) { Actor_Kill(thisx); } else { CollisionCheck_SetInfo(&thisx->colChkInfo, NULL, &sColChkInfoInit); @@ -133,6 +134,7 @@ void ObjBombiwa_Update(Actor* thisx, PlayState* play) { if (((this->actor.params >> 0xF) & 1) != 0) { Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } + GameInteractor_Should(VB_ROCK_DROP_ITEM, false, this); Actor_Kill(&this->actor); } else { this->collider.base.acFlags &= ~AC_HIT; diff --git a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c index d4d952cc0b..26d6ce6eef 100644 --- a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c +++ b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c @@ -6,6 +6,7 @@ #include "z_obj_hamishi.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -150,7 +151,7 @@ void ObjHamishi_Init(Actor* thisx, PlayState* play) { ObjHamishi_InitCollision(&this->actor, play); CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - if (Flags_GetSwitch(play, this->actor.params & 0x3F)) { + if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, this->actor.params & 0x3F), this)) { Actor_Kill(&this->actor); return; } @@ -182,6 +183,7 @@ void ObjHamishi_Update(Actor* thisx, PlayState* play) { ObjHamishi_Break(this, play); SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 40, NA_SE_EV_WALL_BROKEN); Flags_SetSwitch(play, this->actor.params & 0x3F); + GameInteractor_Should(VB_ROCK_DROP_ITEM, false, this); Actor_Kill(&this->actor); } } else { diff --git a/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c b/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c index 424d669a24..9800fcf20a 100644 --- a/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c +++ b/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c @@ -15,13 +15,13 @@ void ObjLift_Destroy(Actor* thisx, PlayState* play); void ObjLift_Update(Actor* thisx, PlayState* play); void ObjLift_Draw(Actor* thisx, PlayState* play); -void func_80B9651C(ObjLift* this); -void func_80B9664C(ObjLift* this); -void func_80B967C0(ObjLift* this); +void ObjLift_SetupWait(ObjLift* this); +void ObjLift_SetupShake(ObjLift* this); +void ObjLift_SetupFall(ObjLift* this); -void func_80B96560(ObjLift* this, PlayState* play); -void func_80B96678(ObjLift* this, PlayState* play); -void func_80B96840(ObjLift* this, PlayState* play); +void ObjLift_Wait(ObjLift* this, PlayState* play); +void ObjLift_Shake(ObjLift* this, PlayState* play); +void ObjLift_Fall(ObjLift* this, PlayState* play); const ActorInit Obj_Lift_InitVars = { ACTOR_OBJ_LIFT, @@ -76,7 +76,7 @@ void ObjLift_InitDynaPoly(ObjLift* this, PlayState* play, CollisionHeader* colli } } -void func_80B96160(ObjLift* this, PlayState* play) { +void ObjLift_SpawnFragments(ObjLift* this, PlayState* play) { Vec3f pos; Vec3f velocity; Vec3f* temp_s3; @@ -116,10 +116,10 @@ void ObjLift_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->dyna.actor, sScales[(this->dyna.actor.params >> 1) & 1]); Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - this->unk_168.x = Rand_ZeroOne() * 65535.5f; - this->unk_168.y = Rand_ZeroOne() * 65535.5f; - this->unk_168.z = Rand_ZeroOne() * 65535.5f; - func_80B9651C(this); + this->shakeOrientation.x = Rand_ZeroOne() * 65535.5f; + this->shakeOrientation.y = Rand_ZeroOne() * 65535.5f; + this->shakeOrientation.z = Rand_ZeroOne() * 65535.5f; + ObjLift_SetupWait(this); osSyncPrintf("(Dungeon Lift)(arg_data 0x%04x)\n", this->dyna.actor.params); } @@ -129,25 +129,25 @@ void ObjLift_Destroy(Actor* thisx, PlayState* play) { DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); } -void func_80B9651C(ObjLift* this) { +void ObjLift_SetupWait(ObjLift* this) { this->timer = sFallTimerDurations[(this->dyna.actor.params >> 8) & 7]; - ObjLift_SetupAction(this, func_80B96560); + ObjLift_SetupAction(this, ObjLift_Wait); } -void func_80B96560(ObjLift* this, PlayState* play) { +void ObjLift_Wait(ObjLift* this, PlayState* play) { s32 pad; s32 quakeIndex; if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->timer <= 0) { if (((this->dyna.actor.params >> 8) & 7) == 7) { - func_80B967C0(this); + ObjLift_SetupFall(this); } else { quakeIndex = Quake_Add(GET_ACTIVE_CAM(play), 1); Quake_SetSpeed(quakeIndex, 10000); Quake_SetQuakeValues(quakeIndex, 2, 0, 0, 0); Quake_SetCountdown(quakeIndex, 20); - func_80B9664C(this); + ObjLift_SetupShake(this); } } } else { @@ -155,25 +155,27 @@ void func_80B96560(ObjLift* this, PlayState* play) { } } -void func_80B9664C(ObjLift* this) { +void ObjLift_SetupShake(ObjLift* this) { this->timer = 20; - ObjLift_SetupAction(this, func_80B96678); + ObjLift_SetupAction(this, ObjLift_Shake); } -void func_80B96678(ObjLift* this, PlayState* play) { +void ObjLift_Shake(ObjLift* this, PlayState* play) { if (this->timer <= 0) { - func_80B967C0(this); + ObjLift_SetupFall(this); } else { - this->unk_168.x += 10000; - this->dyna.actor.world.rot.x = (s16)(Math_SinS(this->unk_168.x) * 300.0f) + this->dyna.actor.home.rot.x; - this->dyna.actor.world.rot.z = (s16)(Math_CosS(this->unk_168.x) * 300.0f) + this->dyna.actor.home.rot.z; + this->shakeOrientation.x += 10000; + this->dyna.actor.world.rot.x = + (s16)(Math_SinS(this->shakeOrientation.x) * 300.0f) + this->dyna.actor.home.rot.x; + this->dyna.actor.world.rot.z = + (s16)(Math_CosS(this->shakeOrientation.x) * 300.0f) + this->dyna.actor.home.rot.z; this->dyna.actor.shape.rot.x = this->dyna.actor.world.rot.x; this->dyna.actor.shape.rot.z = this->dyna.actor.world.rot.z; - this->unk_168.y += 18000; - this->dyna.actor.world.pos.y = Math_SinS(this->unk_168.y) + this->dyna.actor.home.pos.y; - this->unk_168.z += 18000; - this->dyna.actor.world.pos.x = Math_SinS(this->unk_168.z) * 3.0f + this->dyna.actor.home.pos.x; - this->dyna.actor.world.pos.z = Math_CosS(this->unk_168.z) * 3.0f + this->dyna.actor.home.pos.z; + this->shakeOrientation.y += 18000; + this->dyna.actor.world.pos.y = Math_SinS(this->shakeOrientation.y) + this->dyna.actor.home.pos.y; + this->shakeOrientation.z += 18000; + this->dyna.actor.world.pos.x = Math_SinS(this->shakeOrientation.z) * 3.0f + this->dyna.actor.home.pos.x; + this->dyna.actor.world.pos.z = Math_CosS(this->shakeOrientation.z) * 3.0f + this->dyna.actor.home.pos.z; } if ((this->timer & 3) == 3) { @@ -181,13 +183,13 @@ void func_80B96678(ObjLift* this, PlayState* play) { } } -void func_80B967C0(ObjLift* this) { - ObjLift_SetupAction(this, func_80B96840); +void ObjLift_SetupFall(ObjLift* this) { + ObjLift_SetupAction(this, ObjLift_Fall); Math_Vec3f_Copy(&this->dyna.actor.world.pos, &this->dyna.actor.home.pos); this->dyna.actor.shape.rot = this->dyna.actor.world.rot = this->dyna.actor.home.rot; } -void func_80B96840(ObjLift* this, PlayState* play) { +void ObjLift_Fall(ObjLift* this, PlayState* play) { s32 pad; s32 bgId; Vec3f sp2C; @@ -200,7 +202,7 @@ void func_80B96840(ObjLift* this, PlayState* play) { if ((this->dyna.actor.floorHeight - this->dyna.actor.world.pos.y) >= (sMaxFallDistances[(this->dyna.actor.params >> 1) & 1] - 0.001f)) { - func_80B96160(this, play); + ObjLift_SpawnFragments(this, play); SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 20, NA_SE_EV_BOX_BREAK); Flags_SetSwitch(play, (this->dyna.actor.params >> 2) & 0x3F); Actor_Kill(&this->dyna.actor); diff --git a/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.h b/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.h index 0c364513e8..c9e0db6707 100644 --- a/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.h +++ b/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.h @@ -11,7 +11,7 @@ typedef void (*ObjLiftActionFunc)(struct ObjLift*, PlayState*); typedef struct ObjLift { /* 0x0000 */ DynaPolyActor dyna; /* 0x0164 */ ObjLiftActionFunc actionFunc; - /* 0x0168 */ Vec3s unk_168; + /* 0x0168 */ Vec3s shakeOrientation; /* 0x016E */ s16 timer; } ObjLift; // size = 0x0170 diff --git a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c index 26c1d5a406..cba8feb08a 100644 --- a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c +++ b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c @@ -396,7 +396,7 @@ void ObjSwitch_FloorUp(ObjSwitch* this, PlayState* play) { break; case OBJSWITCH_SUBTYPE_FLOOR_1: if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && - !(this->unk_17F & DYNA_INTERACT_PLAYER_ON_TOP)) { + !(this->prevColFlags & DYNA_INTERACT_PLAYER_ON_TOP)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOn(this, play); } @@ -449,7 +449,7 @@ void ObjSwitch_FloorDown(ObjSwitch* this, PlayState* play) { break; case OBJSWITCH_SUBTYPE_FLOOR_1: if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && - !(this->unk_17F & DYNA_INTERACT_PLAYER_ON_TOP)) { + !(this->prevColFlags & DYNA_INTERACT_PLAYER_ON_TOP)) { ObjSwitch_FloorReleaseInit(this); ObjSwitch_SetOff(this, play); } @@ -497,7 +497,7 @@ s32 ObjSwitch_EyeIsHit(ObjSwitch* this) { Actor* collidingActor; s16 yawDiff; - if ((this->tris.col.base.acFlags & AC_HIT) && !(this->unk_17F & 2)) { + if ((this->tris.col.base.acFlags & AC_HIT) && !(this->prevColFlags & 2)) { collidingActor = this->tris.col.base.ac; if (collidingActor != NULL) { yawDiff = collidingActor->world.rot.y - this->dyna.actor.shape.rot.y; @@ -614,7 +614,7 @@ void ObjSwitch_CrystalOff(ObjSwitch* this, PlayState* play) { } break; case OBJSWITCH_SUBTYPE_CRYSTAL_1: - if ((this->jntSph.col.base.acFlags & AC_HIT) && !(this->unk_17F & 2) && this->disableAcTimer <= 0) { + if ((this->jntSph.col.base.acFlags & AC_HIT) && !(this->prevColFlags & 2) && this->disableAcTimer <= 0) { this->disableAcTimer = 10; ObjSwitch_SetOn(this, play); ObjSwitch_CrystalTurnOnInit(this); @@ -656,7 +656,7 @@ void ObjSwitch_CrystalOn(ObjSwitch* this, PlayState* play) { } break; case OBJSWITCH_SUBTYPE_CRYSTAL_1: - if ((this->jntSph.col.base.acFlags & AC_HIT) && !(this->unk_17F & 2) && this->disableAcTimer <= 0) { + if ((this->jntSph.col.base.acFlags & AC_HIT) && !(this->prevColFlags & 2) && this->disableAcTimer <= 0) { this->disableAcTimer = 10; play = play; ObjSwitch_CrystalTurnOffInit(this); @@ -696,10 +696,10 @@ void ObjSwitch_Update(Actor* thisx, PlayState* play) { switch ((this->dyna.actor.params & 7)) { case OBJSWITCH_TYPE_FLOOR: case OBJSWITCH_TYPE_FLOOR_RUSTY: - this->unk_17F = this->dyna.interactFlags; + this->prevColFlags = this->dyna.interactFlags; break; case OBJSWITCH_TYPE_EYE: - this->unk_17F = this->tris.col.base.acFlags; + this->prevColFlags = this->tris.col.base.acFlags; this->tris.col.base.acFlags &= ~AC_HIT; CollisionCheck_SetAC(play, &play->colChkCtx, &this->tris.col.base); break; @@ -708,7 +708,7 @@ void ObjSwitch_Update(Actor* thisx, PlayState* play) { if (!Player_InCsMode(play) && this->disableAcTimer > 0) { this->disableAcTimer--; } - this->unk_17F = this->jntSph.col.base.acFlags; + this->prevColFlags = this->jntSph.col.base.acFlags; this->jntSph.col.base.acFlags &= ~AC_HIT; if (this->disableAcTimer <= 0) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->jntSph.col.base); diff --git a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h index b2eaa51629..72f963ad58 100644 --- a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h +++ b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h @@ -58,7 +58,7 @@ typedef struct ObjSwitch { /* 0x017A */ u8 x2TexScroll; /* 0x017B */ u8 y2TexScroll; /* 0x017C */ Color_RGB8 crystalColor; - /* 0x017F */ u8 unk_17F; // used for different purposes between floor and eye switch + /* 0x017F */ u8 prevColFlags; // used for different purposes between floor and eye switch union { /* 0x0180 */ ObjSwitchJntSph jntSph; /* 0x0180 */ ObjSwitchTris tris; diff --git a/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c b/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c index e5e7206662..9d37bea71f 100644 --- a/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c +++ b/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c @@ -18,7 +18,7 @@ void ShotSun_Update(Actor* thisx, PlayState* play); void ShotSun_SpawnFairy(ShotSun* this, PlayState* play); void ShotSun_TriggerFairy(ShotSun* this, PlayState* play); -void func_80BADF0C(ShotSun* this, PlayState* play); +void ShotSun_UpdateFairySpawner(ShotSun* this, PlayState* play); void ShotSun_UpdateHyliaSun(ShotSun* this, PlayState* play); const ActorInit Shot_Sun_InitVars = { @@ -62,10 +62,10 @@ void ShotSun_Init(Actor* thisx, PlayState* play) { osSyncPrintf("%d ---- オカリナの秘密発生!!!!!!!!!!!!!\n", this->actor.params); params = this->actor.params & 0xFF; if (params == 0x40 || params == 0x41) { - this->unk_1A4 = 0; + this->fairySpawnerState = 0; this->actor.flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED; this->actor.flags |= ACTOR_FLAG_UPDATE_DURING_OCARINA; - this->actionFunc = func_80BADF0C; + this->actionFunc = ShotSun_UpdateFairySpawner; this->actor.flags |= ACTOR_FLAG_LOCK_ON_DISABLED; } else { Collider_InitCylinder(play, &this->collider); @@ -122,35 +122,35 @@ void ShotSun_TriggerFairy(ShotSun* this, PlayState* play) { } } -void func_80BADF0C(ShotSun* this, PlayState* play) { +void ShotSun_UpdateFairySpawner(ShotSun* this, PlayState* play) { Player* player = GET_PLAYER(play); s32 pad; s32 params = this->actor.params & 0xFF; if (Math3D_Vec3fDistSq(&this->actor.world.pos, &player->actor.world.pos) > 22500.0f) { - this->unk_1A4 = 0; + this->fairySpawnerState = 0; } else { - if (this->unk_1A4 == 0) { + if (this->fairySpawnerState == 0) { if (!(player->stateFlags2 & PLAYER_STATE2_ATTEMPT_PLAY_FOR_ACTOR)) { player->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; return; } else { - this->unk_1A4 = 1; + this->fairySpawnerState = 1; } } - if (this->unk_1A4 == 1) { + if (this->fairySpawnerState == 1) { func_8010BD58(play, OCARINA_ACTION_FREE_PLAY); - this->unk_1A4 = 2; - } else if (this->unk_1A4 == 2 && play->msgCtx.ocarinaMode == OCARINA_MODE_04) { + this->fairySpawnerState = 2; + } else if (this->fairySpawnerState == 2 && play->msgCtx.ocarinaMode == OCARINA_MODE_04) { if ((params == 0x40 && play->msgCtx.lastPlayedSong == OCARINA_SONG_SUNS) || (params == 0x41 && play->msgCtx.lastPlayedSong == OCARINA_SONG_STORMS)) { this->actionFunc = ShotSun_TriggerFairy; OnePointCutscene_Attention(play, &this->actor); this->timer = 0; } else { - this->unk_1A4 = 0; + this->fairySpawnerState = 0; } - this->unk_1A4 = 0; + this->fairySpawnerState = 0; } } } diff --git a/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h b/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h index c346defd65..3896095813 100644 --- a/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h +++ b/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h @@ -14,7 +14,7 @@ typedef struct ShotSun { /* 0x0198 */ ShotSunActionFunc actionFunc; /* 0x019C */ Vec3s hitboxPos; /* 0x01A2 */ s16 timer; // Frames until fairy spawns - /* 0x01A4 */ u8 unk_1A4; + /* 0x01A4 */ u8 fairySpawnerState; } ShotSun; // size = 0x01A8 #endif diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 804292a786..bb18a2da13 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -116,7 +116,7 @@ typedef struct struct_80854190 { typedef struct struct_80854578 { /* 0x00 */ LinkAnimationHeader* anim; /* 0x04 */ f32 unk_04; - /* 0x04 */ f32 unk_08; + /* 0x08 */ f32 unk_08; } struct_80854578; // size = 0x0C typedef struct struct_80854B18 { @@ -5606,7 +5606,6 @@ void func_8083A0F4(PlayState* play, Player* this) { void Player_SetupTalk(PlayState* play, Player* this) { Player_SetupActionPreserveAnimMovement(play, this, Player_Action_Talk, 0); - this->stateFlags1 |= PLAYER_STATE1_TALKING | PLAYER_STATE1_IN_CUTSCENE; if (this->actor.textId != 0) { @@ -6229,7 +6228,9 @@ s32 Player_ActionHandler_Talk(Player* this, PlayState* play) { // text will be used. This is especially important to prevent unwanted behavior with regards to mask // trading. this->currentMask = sSavedCurrentMask; - Player_StartTalking(play, talkOfferActor); + if (GameInteractor_Should(VB_SKIP_TALKING, true)) { + Player_StartTalking(play, talkOfferActor); + } return true; } } @@ -12449,8 +12450,10 @@ void Player_DrawGameplay(PlayState* play, Player* this, s32 lod, Gfx* cullDList, MATRIX_TOMTX(bunnyEarMtx); } - if (this->currentMask != PLAYER_MASK_BUNNY || !CVarGetInteger(CVAR_ENHANCEMENT("HideBunnyHood"), 0)) { - gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]); + if (GameInteractor_Should(VB_DRAW_PLAYER_MASK, true, this->currentMask, play)) { + if (this->currentMask != PLAYER_MASK_BUNNY || !CVarGetInteger(CVAR_ENHANCEMENT("HideBunnyHood"), 0)) { + gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]); + } } if (CVarGetInteger(CVAR_GENERAL("FixIceTrapWithBunnyHood"), 1)) diff --git a/soh/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.h b/soh/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.h index c3b16ae358..306ad8e91b 100644 --- a/soh/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.h +++ b/soh/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.h @@ -6,7 +6,7 @@ typedef struct { /* 0x00 */ Vec3f pos; - /* 0x00 */ s32 unk_C; + /* 0x0C */ s32 unk_C; } EffectSsStone1InitParams; // size = 0x #endif