Fairysanity (#4744)

* Define VB for fairy group spawning

* Add skeleton of new files for fairy shuffle

* Add option to enable/disable fairy shuffle

* Add field to fairy entities to hold randomizer data

* Expose the current grotto id, or find it if not shuffled

This is necessary since, unlike chest or scrub grottos,
fairy fountains, lacking any elements that would normally
differ between grottos, often have identical respawn data.
This change enables fairy shuffle to correctly identify
which fairy fountain was entered so it could load the right
checks.

* Initialise fairy groups if detected

* Randomize first set of fairies

* Make randomized fairies collectible

* VBify fairy healing customization

* Add remaining grotto fairies

* Add remaining fairy group spawns

* Override bean sprouts spawning fairies

* Define bean sprout fairy checks

* Add HasItem and CanUse entries for magic beans.

* Define logic for bean sprout fairies

* Enabling looking up fairies by z coordinate

* Add Temple of Time Gossip Stones

Logic might look a little weird. While the Gossip Stones
respond to Sun's Song, the scene transition takes priority,
so the fairies aren't actually obtainable. Adult does not have
day and night versions and is fully capable of acquiring the
fairies with Sun's Song.

Song of Time is similar, but rather than being dependant on
age, it's dependant on the timesaver to switch ages anywhere
with Song of Time. In this case, the fairies still spawn,
but the age transition deletes them before giving the chance
to collect them. While I could've chosen to ignore this and
simply require the player to disable the enhancement before
playing if it's their only option, I instead decided to
accomodate the enhancement and require one of the other songs
in order for the check to be in logic.

* Disable quick age change around gossip stones to simplify logic

* Add remaining gossip stone fairies

* Finish gossip stone fairies

* Add Desert Colossus Oasis

* Restrict fairy type

Somehow, it was previously possible for Navi to get detected
as a randomized fairy and rendered as an item. I was not
able to reproduce the behavior, but this should prevent it
from happening again.

* Add overworld special fairy spots

* Add mini-dungeon fairy song spots

* Add remaining dungeons except Shadow

* Add Shadow Temple fairies

* Add fairy check flags to the save editor

* Filter fairy checks from check tracker

* Add hints for fairy checks

* get fairysanity as far as I can for now

* fix a few obvious issues

* now builds

* try to convert FairyOnVanillaBehaviorHandler to vardic args

* convert RegisterFairyCustomization to REGISTER_VB_SHOULD

* fix some generation issues

* remove the list of fairy locations

* fix up logic

* more logic changes for gossip stones

* try silly thing for windows

* more stupid

* more dumb testing

* more testing

* small fixes

* implement inside fence storms fairy

* add inside fence storms fairy to logic

* remove duplicate hints (stupid conflicts)

* oops

* Rewrite game interfacing code of fairy shuffle

* Better function names

---------

Co-authored-by: Angel Bulfone <mbulfone@gmail.com>
Co-authored-by: aMannus <mannusmenting@gmail.com>
This commit is contained in:
Pepper0ni 2025-01-05 13:52:27 +00:00 committed by GitHub
parent 7021230fd5
commit 55e1af9e81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 2724 additions and 633 deletions

View File

@ -1338,6 +1338,219 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART" }, { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART" },
{ RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART" }, { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART" },
{ RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART" }, { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART" },
{ RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1" },
{ RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2" },
{ RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3" },
{ RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4" },
{ RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5" },
{ RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6" },
{ RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7" },
{ RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8" },
{ RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1" },
{ RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2" },
{ RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3" },
{ RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4" },
{ RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5" },
{ RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6" },
{ RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7" },
{ RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8" },
{ RAND_INF_HF_FAIRY_GROTTO_FAIRY_1, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_1" },
{ RAND_INF_HF_FAIRY_GROTTO_FAIRY_2, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_2" },
{ RAND_INF_HF_FAIRY_GROTTO_FAIRY_3, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_3" },
{ RAND_INF_HF_FAIRY_GROTTO_FAIRY_4, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_4" },
{ RAND_INF_HF_FAIRY_GROTTO_FAIRY_5, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_5" },
{ RAND_INF_HF_FAIRY_GROTTO_FAIRY_6, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_6" },
{ RAND_INF_HF_FAIRY_GROTTO_FAIRY_7, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_7" },
{ RAND_INF_HF_FAIRY_GROTTO_FAIRY_8, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_8" },
{ RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1" },
{ RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2" },
{ RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3" },
{ RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4" },
{ RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5" },
{ RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6" },
{ RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7" },
{ RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8" },
{ RAND_INF_GF_FAIRY_GROTTO_FAIRY_1, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_1" },
{ RAND_INF_GF_FAIRY_GROTTO_FAIRY_2, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_2" },
{ RAND_INF_GF_FAIRY_GROTTO_FAIRY_3, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_3" },
{ RAND_INF_GF_FAIRY_GROTTO_FAIRY_4, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_4" },
{ RAND_INF_GF_FAIRY_GROTTO_FAIRY_5, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_5" },
{ RAND_INF_GF_FAIRY_GROTTO_FAIRY_6, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_6" },
{ RAND_INF_GF_FAIRY_GROTTO_FAIRY_7, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_7" },
{ RAND_INF_GF_FAIRY_GROTTO_FAIRY_8, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_8" },
{ RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1" },
{ RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2" },
{ RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3" },
{ RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4" },
{ RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5" },
{ RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6" },
{ RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7" },
{ RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8" },
{ RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1" },
{ RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2" },
{ RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3" },
{ RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4" },
{ RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5" },
{ RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6" },
{ RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7" },
{ RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8" },
{ RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1" },
{ RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2" },
{ RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3" },
{ RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4" },
{ RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5" },
{ RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6" },
{ RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7" },
{ RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8" },
{ RAND_INF_COLOSSUS_OASIS_FAIRY_1, "RAND_INF_COLOSSUS_OASIS_FAIRY_1" },
{ RAND_INF_COLOSSUS_OASIS_FAIRY_2, "RAND_INF_COLOSSUS_OASIS_FAIRY_2" },
{ RAND_INF_COLOSSUS_OASIS_FAIRY_3, "RAND_INF_COLOSSUS_OASIS_FAIRY_3" },
{ RAND_INF_COLOSSUS_OASIS_FAIRY_4, "RAND_INF_COLOSSUS_OASIS_FAIRY_4" },
{ RAND_INF_COLOSSUS_OASIS_FAIRY_5, "RAND_INF_COLOSSUS_OASIS_FAIRY_5" },
{ RAND_INF_COLOSSUS_OASIS_FAIRY_6, "RAND_INF_COLOSSUS_OASIS_FAIRY_6" },
{ RAND_INF_COLOSSUS_OASIS_FAIRY_7, "RAND_INF_COLOSSUS_OASIS_FAIRY_7" },
{ RAND_INF_COLOSSUS_OASIS_FAIRY_8, "RAND_INF_COLOSSUS_OASIS_FAIRY_8" },
{ RAND_INF_ZR_BEAN_SPROUT_FAIRY_1, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_1" },
{ RAND_INF_ZR_BEAN_SPROUT_FAIRY_2, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_2" },
{ RAND_INF_ZR_BEAN_SPROUT_FAIRY_3, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_3" },
{ RAND_INF_KF_BEAN_SPROUT_FAIRY_1, "RAND_INF_KF_BEAN_SPROUT_FAIRY_1" },
{ RAND_INF_KF_BEAN_SPROUT_FAIRY_2, "RAND_INF_KF_BEAN_SPROUT_FAIRY_2" },
{ RAND_INF_KF_BEAN_SPROUT_FAIRY_3, "RAND_INF_KF_BEAN_SPROUT_FAIRY_3" },
{ RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1" },
{ RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2" },
{ RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3" },
{ RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1" },
{ RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2" },
{ RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3" },
{ RAND_INF_LH_BEAN_SPROUT_FAIRY_1, "RAND_INF_LH_BEAN_SPROUT_FAIRY_1" },
{ RAND_INF_LH_BEAN_SPROUT_FAIRY_2, "RAND_INF_LH_BEAN_SPROUT_FAIRY_2" },
{ RAND_INF_LH_BEAN_SPROUT_FAIRY_3, "RAND_INF_LH_BEAN_SPROUT_FAIRY_3" },
{ RAND_INF_GV_BEAN_SPROUT_FAIRY_1, "RAND_INF_GV_BEAN_SPROUT_FAIRY_1" },
{ RAND_INF_GV_BEAN_SPROUT_FAIRY_2, "RAND_INF_GV_BEAN_SPROUT_FAIRY_2" },
{ RAND_INF_GV_BEAN_SPROUT_FAIRY_3, "RAND_INF_GV_BEAN_SPROUT_FAIRY_3" },
{ RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1" },
{ RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2" },
{ RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3" },
{ RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1" },
{ RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2" },
{ RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3" },
{ RAND_INF_DMC_BEAN_SPROUT_FAIRY_1, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_1" },
{ RAND_INF_DMC_BEAN_SPROUT_FAIRY_2, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_2" },
{ RAND_INF_DMC_BEAN_SPROUT_FAIRY_3, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_3" },
{ RAND_INF_DMT_BEAN_SPROUT_FAIRY_1, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_1" },
{ RAND_INF_DMT_BEAN_SPROUT_FAIRY_2, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_2" },
{ RAND_INF_DMT_BEAN_SPROUT_FAIRY_3, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_3" },
{ RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY" },
{ RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY" },
{ RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY" },
{ RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY" },
{ RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_DMC_GOSSIP_STONE_FAIRY, "RAND_INF_DMC_GOSSIP_STONE_FAIRY" },
{ RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_DMT_GOSSIP_STONE_FAIRY, "RAND_INF_DMT_GOSSIP_STONE_FAIRY" },
{ RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY, "RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY" },
{ RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, "RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY" },
{ RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, "RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY" },
{ RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_GV_GOSSIP_STONE_FAIRY, "RAND_INF_GV_GOSSIP_STONE_FAIRY" },
{ RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY, "RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY" },
{ RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY, "RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY" },
{ RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY, "RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY" },
{ RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY, "RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY" },
{ RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, "RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY" },
{ RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, "RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY" },
{ RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, "RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY" },
{ RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_KF_GOSSIP_STONE_FAIRY, "RAND_INF_KF_GOSSIP_STONE_FAIRY" },
{ RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY, "RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY" },
{ RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, "RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY" },
{ RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, "RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY" },
{ RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_LW_GOSSIP_STONE_FAIRY, "RAND_INF_LW_GOSSIP_STONE_FAIRY" },
{ RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY" },
{ RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY" },
{ RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY" },
{ RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_ZD_GOSSIP_STONE_FAIRY, "RAND_INF_ZD_GOSSIP_STONE_FAIRY" },
{ RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY, "RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY" },
{ RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY, "RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY" },
{ RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY" },
{ RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY" },
{ RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY" },
{ RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG" },
{ RAND_INF_LH_ISLAND_SUN_FAIRY, "RAND_INF_LH_ISLAND_SUN_FAIRY" },
{ RAND_INF_HF_POND_STORMS_FAIRY, "RAND_INF_HF_POND_STORMS_FAIRY" },
{ RAND_INF_DMT_FLAG_SUN_FAIRY, "RAND_INF_DMT_FLAG_SUN_FAIRY" },
{ RAND_INF_LW_SHORTCUT_STORMS_FAIRY, "RAND_INF_LW_SHORTCUT_STORMS_FAIRY" },
{ RAND_INF_GF_KITCHEN_SUN_FAIRY, "RAND_INF_GF_KITCHEN_SUN_FAIRY" },
{ RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY" },
{ RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY" },
{ RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY" },
{ RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY" },
{ RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY" },
{ RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY" },
{ RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, "RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY" },
{ RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, "RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY" },
{ RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY" },
{ RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, "RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY" },
{ RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, "RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY" },
{ RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY" },
{ RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY" },
{ RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY" },
{ RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY" },
{ RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY" },
{ RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY" },
{ RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY" },
{ RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY" },
{ RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY" },
} }, } },
}; };

View File

@ -510,6 +510,15 @@ typedef enum {
// Vanilla condition: Actor is ACTOR_EN_ELF, ACTOR_EN_FISH, ACTOR_EN_ICE_HONO, or ACTOR_EN_INSECT // Vanilla condition: Actor is ACTOR_EN_ELF, ACTOR_EN_FISH, ACTOR_EN_ICE_HONO, or ACTOR_EN_INSECT
// Opt: *Actor // Opt: *Actor
VB_BOTTLE_ACTOR, VB_BOTTLE_ACTOR,
/*** Shuffle Fairies ***/
// Opt: *EnElf
VB_SPAWN_FOUNTAIN_FAIRIES,
VB_FAIRY_HEAL,
// Opt: *ObjBean
VB_SPAWN_BEAN_STALK_FAIRIES,
// Opt: *EnGs
VB_SPAWN_GOSSIP_STONE_FAIRY,
} GIVanillaBehavior; } GIVanillaBehavior;
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,3 +1,5 @@
#pragma once
#include "GameInteractor.h" #include "GameInteractor.h"
#include <stdarg.h> #include <stdarg.h>

View File

@ -37,6 +37,7 @@
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
#include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h" #include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h"
#include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "src/overlays/actors/ovl_En_Door/z_en_door.h"
#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_boy/object_link_boy.h"
#include "objects/object_link_child/object_link_child.h" #include "objects/object_link_child/object_link_child.h"
#include "soh_assets.h" #include "soh_assets.h"
@ -252,8 +253,9 @@ void RegisterOcarinaTimeTravel() {
Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.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* 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* 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 justPlayedSoT = gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME;
bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && !nearbyFrogs; bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && !nearbyFrogs && !nearbyGossipStone;
bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2; bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2;
bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
@ -1446,6 +1448,30 @@ void RegisterCustomSkeletons() {
}); });
} }
#define FAIRY_FLAG_BIG (1 << 9)
void RegisterFairyCustomization() {
REGISTER_VB_SHOULD(VB_FAIRY_HEAL, {
EnElf* enElf = va_arg(args, EnElf*);
// Don't trigger if fairy is shuffled
if (!IS_RANDO || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FAIRIES) || enElf->sohFairyIdentity.randomizerInf == RAND_INF_MAX) {
if (CVarGetInteger(CVAR_ENHANCEMENT("FairyEffect"), 0) && !(enElf->fairyFlags & FAIRY_FLAG_BIG))
{
if (CVarGetInteger(CVAR_ENHANCEMENT("FairyPercentRestore"), 0))
{
Health_ChangeBy(gPlayState, (gSaveContext.healthCapacity * CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 100) / 100 + 15) / 16 * 16);
}
else
{
Health_ChangeBy(gPlayState, CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 8) * 16);
}
*should = false;
}
}
});
}
void InitMods() { void InitMods() {
BossRush_RegisterHooks(); BossRush_RegisterHooks();
RandomizerRegisterHooks(); RandomizerRegisterHooks();
@ -1489,5 +1515,6 @@ void InitMods() {
RegisterHurtContainerModeHandler(); RegisterHurtContainerModeHandler();
RegisterPauseMenuHooks(); RegisterPauseMenuHooks();
RandoKaleido_RegisterHooks(); RandoKaleido_RegisterHooks();
RegisterFairyCustomization();
RegisterCustomSkeletons(); RegisterCustomSkeletons();
} }

View File

@ -287,6 +287,15 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone in Dodongo's Cavern# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone in Dodongo's Cavern# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
/*-------------------------- /*--------------------------
| JABU JABUS BELLY | | JABU JABUS BELLY |
---------------------------*/ ---------------------------*/
@ -673,7 +682,6 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FOREST_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Forest Temple# hides #[[1]]#.", hintTextTable[RHT_FOREST_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Forest Temple# hides #[[1]]#.",
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
@ -874,6 +882,14 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a hot arena# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun behind a knight's throne in a volcano# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
/*-------------------------- /*--------------------------
| WATER TEMPLE | | WATER TEMPLE |
---------------------------*/ ---------------------------*/
@ -1009,6 +1025,22 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RHT_WATER_TEMPLE_HEART] = HintText(CustomMessage("They say that in a #river in the Water Temple# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun atop a small pillar before a duel with one's shadow# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY] = HintText(CustomMessage("They say that #calling the rain before a duel with one's shadow# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun before a duel with one's shadow# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
/*-------------------------- /*--------------------------
| SPIRIT TEMPLE | | SPIRIT TEMPLE |
---------------------------*/ ---------------------------*/
@ -1505,6 +1537,18 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY] = HintText(CustomMessage("They say that an #calling the rain for a sentry guarding a house of the dead# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY] = HintText(CustomMessage("They say that an #calling the rain on a platform suspended above a bottomless pit# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY] = HintText(CustomMessage("They say that an #calling the sun near an invisible chest guarded by the dead# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!.", {QM_RED, QM_GREEN}));
/*-------------------------- /*--------------------------
| BOTTOM OF THE WELL | | BOTTOM OF THE WELL |
---------------------------*/ ---------------------------*/
@ -1635,6 +1679,19 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY] = HintText(CustomMessage("They say that an #calling the sun a dead end# within the well reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY] = HintText(CustomMessage("They say that an #calling the sun in an empty cell# within the well reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY] = HintText(CustomMessage("They say that an #calling the sun a dead end# within the well reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!.", {QM_RED, QM_GREEN}));
/*-------------------------- /*--------------------------
| ICE CAVERN | | ICE CAVERN |
---------------------------*/ ---------------------------*/
@ -1720,6 +1777,11 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY] = HintText(CustomMessage("They say that #calling the rain near the entrance to a frozen cave# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
// /*spanish*/ Según dicen, una #Skulltula tras un ardiente hielo# otorga #[[1]]#.
/*-------------------------- /*--------------------------
| Gerudo Training Ground | | Gerudo Training Ground |
---------------------------*/ ---------------------------*/
@ -1818,6 +1880,10 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); /*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN}));
// /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#. // /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#.
hintTextTable[RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY] = HintText(CustomMessage("They say that #calling the rain near the entrance to the Gerudo Training Grounds# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = HintText(CustomMessage("They say that the #Song of Time# in the Gerudo Training Ground leads to #[[1]]#.", hintTextTable[RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = HintText(CustomMessage("They say that the #Song of Time# in the Gerudo Training Ground leads to #[[1]]#.",
/*german*/ "Man erzählt sich, daß die #Hymne der Zeit# in der Gerudo-Trainingsarena zu #[[1]]# führe.", /*german*/ "Man erzählt sich, daß die #Hymne der Zeit# in der Gerudo-Trainingsarena zu #[[1]]# führe.",
/*french*/ "Selon moi, le #chant du temps# révèle dans le Gymnase Gerudo #[[1]]#.", {QM_RED, QM_GREEN})); /*french*/ "Selon moi, le #chant du temps# révèle dans le Gymnase Gerudo #[[1]]#.", {QM_RED, QM_GREEN}));
@ -1985,6 +2051,14 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*french*/ "Selon moi, la #musique dans l'épreuve du ciel# révèle #[[1]]#.", {QM_RED, QM_GREEN})); /*french*/ "Selon moi, la #musique dans l'épreuve du ciel# révèle #[[1]]#.", {QM_RED, QM_GREEN}));
// /*spanish*/ Según dicen, la #música en la prueba del resplandor# revela #[[1]]#. // /*spanish*/ Según dicen, la #música en la prueba del resplandor# revela #[[1]]#.
hintTextTable[RHT_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun for a sentry in the test of the sands# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GANONS_CASTLE_SCRUBS_FAIRY] = HintText(CustomMessage("They say that within a #sanctuary before the final trial# rests #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = HintText(CustomMessage("They say that the #test of the seas# holds #[[1]]#.", hintTextTable[RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = HintText(CustomMessage("They say that the #test of the seas# holds #[[1]]#.",
/*german*/ "Man erzählt sich, daß die #Prüfung der Meere# #[[1]]# enthielte.", /*german*/ "Man erzählt sich, daß die #Prüfung der Meere# #[[1]]# enthielte.",
/*french*/ "Selon moi, l'#épreuve des mers# contient #[[1]]#.", {QM_RED, QM_GREEN})); /*french*/ "Selon moi, l'#épreuve des mers# contient #[[1]]#.", {QM_RED, QM_GREEN}));

View File

@ -1602,5 +1602,338 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
/*german*/ "", /*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN})); /*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/ // /*spanish*/
hintTextTable[RHT_SFM_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath a forest meadow# rests #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZR_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath a river# rests #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath a a few trees bordering a wide field# rests #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZD_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath the home of the Zoras# rests #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GF_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath the home of thieves# rests #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY] = HintText(CustomMessage("They say that within #a fountain behind a wall within a grave# rests #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_COLOSSUS_OASIS_FAIRY] = HintText(CustomMessage("They say that #restoring water to a dried oasis# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZR_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout on the riverside# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KF_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout near a forest shop# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout near the entrance to the forest# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout above a sylvan theatre# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LH_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout on the lakeside# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GV_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout on the side of a canyon# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_COLOSSUS_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout near a temple of the sand# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GRAVEYARD_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout within a graveyard# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMC_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout within a volcano# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMT_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout on the moutainside# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_TOT_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone in the ouskirts of the market# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_TOT_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone in the ouskirts of the market# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMC_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within a volcano# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMC_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within a volcano# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMT_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone on a mountain cliff face# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMT_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone on a mountain cliff face# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_COLOSSUS_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near the temple of the sane# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near the temple of the sane# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GV_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near a canyon waterfall# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GV_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near a canyon waterfall# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GC_MAZE_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone behind a maze of rock# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone behind a maze of rock# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near a blacksmith# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near a blacksmith# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GRAVEYARD_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking the graveyard# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking the graveyard# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HC_MALON_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking the path to the castle# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking the path to the castle# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near a secret path to the castle# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near a secret path to the castle# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath the castle# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the castle# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near an ancient tree# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near an ancient tree# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KF_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking a forest village# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KF_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking a forest village# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a forest village# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a forest village# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LH_LAB_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking the river feeding a lake# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking the river feeding a lake# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone at the back of a lake# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone at the back of a lake# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone at the back of a lake# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone at the back of a lake# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LW_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within a perplexing wood# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LW_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within a perplexing wood# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_SFM_MAZE_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking a forest maze# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking a forest maze# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_SFM_SARIA_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone watching a hiding place in the woods# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone watching a hiding place in the woods# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZD_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone listening to an aquatic king# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZD_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone listening to an aquatic king# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone in the ouskirts of a deap fountain# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone in the ouskirts of a deap fountain# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZF_JABU_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone watching a guardian of the sea# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone watching a guardian of the sea# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overwatching a river# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overwatching a river# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a waterfall# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a waterfall# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone hiding near a cow# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone hiding near a cow# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath the entrance to the market# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the entrance to the market# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath trees guarded by a Peahat# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath trees guarded by a Peahat# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a village at the base of a mountain# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a village at the base of a mountain# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within a plateau by a river# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within a plateau by a river# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath an escape from the forest# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath an escape from the forest# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath the entrance to a village within a mountain# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the entrance to a village within a mountain# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within the side of a crater# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within the side of a crater# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "!!!", {QM_RED, QM_GREEN}));
} }
} }

View File

@ -622,6 +622,78 @@ static void PlaceVanillaOverworldFish() {
} }
} }
static void PlaceVanillaFairies() {
auto ctx = Rando::Context::GetInstance();
for (auto rc : Rando::StaticData::GetOverworldFairyLocations()) {
ctx->PlaceItemInLocation(rc, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) {
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::WATER_TEMPLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ()) {
ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::ICE_CAVERN)->IsVanilla()) {
ctx->PlaceItemInLocation(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla()) {
ctx->PlaceItemInLocation(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla()) {
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, GetJunkItem(), false, true);
}
}
static void PlaceItemsForType(RandomizerCheckType rctype, bool overworldActive, bool dungeonActive, bool placeVanilla) { static void PlaceItemsForType(RandomizerCheckType rctype, bool overworldActive, bool dungeonActive, bool placeVanilla) {
for (RandomizerCheck rc : ctx->GetLocations(ctx->allLocations, rctype)) { for (RandomizerCheck rc : ctx->GetLocations(ctx->allLocations, rctype)) {
auto loc = Rando::StaticData::GetLocation(rc); auto loc = Rando::StaticData::GetLocation(rc);
@ -1217,6 +1289,27 @@ void GenerateItemPool() {
AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees
} }
// Shuffle Fairies
if (ctx->GetOption(RSK_SHUFFLE_FAIRIES)) {
for (auto rc : Rando::StaticData::GetOverworldFairyLocations()) {
AddItemToMainPool(GetJunkItem());
}
// 8 extra for Ganon's Castle + 2 Dodongo's Cavern Gossip Stone + 3 Shadow Temple
int extra = 13;
extra += ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla() ? 0 : 2;
extra += ctx->GetDungeon(Rando::WATER_TEMPLE)->IsVanilla() ? 0 : 3;
extra += ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsVanilla() ? 2 : 1;
extra += ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() ? 1 : 2;
extra += ctx->GetDungeon(Rando::ICE_CAVERN)->IsVanilla() ? 1 : 0;
extra += ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla() ? 1 : 0;
extra += ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla() ? 1 : 0;
for (int i = 0; i < extra; i++) {
AddItemToMainPool(GetJunkItem());
}
} else {
PlaceVanillaFairies();
}
//Scrubsanity //Scrubsanity
if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) { if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) {
//Deku Tree //Deku Tree

View File

@ -134,19 +134,20 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT] = Region("Bottom of the Well Basement", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT] = Region("Bottom of the Well Basement", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->BlastOrSmash()), LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->BlastOrSmash()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, {[]{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, {[]{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}}),
@ -158,7 +159,7 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT_USEFUL_BOMB_FLOWERS] = Region("Bottom of the Well Basement Useful Bomb Flowers", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT_USEFUL_BOMB_FLOWERS] = Region("Bottom of the Well Basement Useful Bomb Flowers", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
//Assumes RR_BOTTOM_OF_THE_WELL_BASEMENT access //Assumes RR_BOTTOM_OF_THE_WELL_BASEMENT access
LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasItem(RG_GORONS_BRACELET)),
}, { }, {
//Exits //Exits
Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, {[]{return logic->CanDetonateUprightBombFlower();}}), Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, {[]{return logic->CanDetonateUprightBombFlower();}}),
@ -195,7 +196,6 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()),
}, { }, {
//Exits //Exits
Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->IsChild;}}), Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->IsChild;}}),
@ -257,13 +257,14 @@ void RegionTable_Init_BottomOfTheWell() {
//Also you get cheap shotted on entry sometimes. //Also you get cheap shotted on entry sometimes.
//An MQ lens trick is recommended here, and a review of this room for OHKO logic what that is added is advised. //An MQ lens trick is recommended here, and a review of this room for OHKO logic what that is added is advised.
//In the meantime I assume damage taken or the easy answer (nuts) //In the meantime I assume damage taken or the easy answer (nuts)
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->OpenedWestRoomMQBotw && (logic->TakeDamage() || logic->CanUse(RG_NUTS)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->OpenedWestRoomMQBotw && (logic->TakeDamage() || logic->CanUse(RG_NUTS)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_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_2, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
//If a relevant trick causes you to be able to warp into here without going through PERIMETER, a new eventAccess will be needed for lowering the gates with ZL //If a relevant trick causes you to be able to warp into here without going through PERIMETER, a new eventAccess will be needed for lowering the gates with ZL
@ -278,6 +279,7 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, true), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, true),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, true), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, true),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, true), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, true),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return true;}}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return true;}}),

View File

@ -38,10 +38,18 @@ void RegionTable_Init_CastleTown() {
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
}, { }, {
//Locations //Locations
LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE, true), LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)),
LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE, true), LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, true), LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)),
LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE, true), LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)),
LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)),
LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE, true),
LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE, true),
LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, true),
LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
Entrance(RR_THE_MARKET, {[]{return true;}}), Entrance(RR_THE_MARKET, {[]{return true;}}),
@ -89,10 +97,14 @@ void RegionTable_Init_CastleTown() {
EventAccess(&logic->BugRock, {[]{return true;}}), EventAccess(&logic->BugRock, {[]{return true;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_HC_MALON_EGG, true), LOCATION(RC_HC_MALON_EGG, true),
LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanAttack()), LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanAttack()),
LOCATION(RC_HC_MALON_GOSSIP_STONE, true), LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true), LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_MALON_GOSSIP_STONE, true),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}),
@ -120,19 +132,30 @@ void RegionTable_Init_CastleTown() {
Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}),
}); });
areaTable[RR_HC_STORMS_GROTTO] = Region("HC Storms Grotto", "HC Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_HC_STORMS_GROTTO] = Region("HC Storms Grotto", "HC Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_HC_GS_STORMS_GROTTO, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_HC_STORMS_GS)),
}, {
//Exits
Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}),
Entrance(RR_HC_STORMS_GROTTO_BEHIND_WALLS, {[]{return logic->CanBreakMudWalls();}}),
});
areaTable[RR_HC_STORMS_GROTTO_BEHIND_WALLS] = Region("HC Storms Grotto Behind Walls", "HC Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->NutPot, {[]{return logic->NutPot || logic->BlastOrSmash();}}), EventAccess(&logic->NutPot, {[]{return true;}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CanBreakMudWalls() && logic->CallGossipFairy();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->WanderingBugs, {[]{return logic->WanderingBugs || logic->BlastOrSmash();}}), EventAccess(&logic->WanderingBugs, {[]{return true;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_HC_GS_STORMS_GROTTO, (logic->BlastOrSmash() && logic->HookshotOrBoomerang()) || (logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_HC_STORMS_GS))), LOCATION(RC_HC_GS_STORMS_GROTTO, logic->HookshotOrBoomerang()),
LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE, logic->BlastOrSmash()), LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HC_STORMS_GROTTO_POT_1, logic->BlastOrSmash() && logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->BlastOrSmash() && logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_HC_STORMS_GROTTO_POT_3, logic->BlastOrSmash() && logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_1, logic->CanBreakPots()),
LOCATION(RC_HC_STORMS_GROTTO_POT_4, logic->BlastOrSmash() && logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->CanBreakPots()),
LOCATION(RC_HC_STORMS_GROTTO_POT_3, logic->CanBreakPots()),
LOCATION(RC_HC_STORMS_GROTTO_POT_4, logic->CanBreakPots()),
}, { }, {
//Exits //Exits
Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}),

View File

@ -6,7 +6,7 @@ using namespace Rando;
void RegionTable_Init_DeathMountain() { void RegionTable_Init_DeathMountain() {
areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain", "Death Mountain", {RA_DEATH_MOUNTAIN_TRAIL}, DAY_NIGHT_CYCLE, { areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain", "Death Mountain", {RA_DEATH_MOUNTAIN_TRAIL}, DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)));}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))),
@ -16,6 +16,10 @@ void RegionTable_Init_DeathMountain() {
LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DMT_HOOKSHOT_LOWER_GS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_DMT_JS_LOWER_GS)) && logic->CanGetNightTimeGS()), LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DMT_HOOKSHOT_LOWER_GS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_DMT_JS_LOWER_GS)) && logic->CanGetNightTimeGS()),
LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()),
LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_KAK_BEHIND_GATE, {[]{return true;}}), Entrance(RR_KAK_BEHIND_GATE, {[]{return true;}}),
@ -31,11 +35,13 @@ void RegionTable_Init_DeathMountain() {
EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}), EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)), LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)),
LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->CanUse(RG_EYEDROPS)), LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->CanUse(RG_EYEDROPS)),
LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)), LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)),
LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || ctx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS()), LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || ctx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS()),
LOCATION(RC_DMT_GOSSIP_STONE, true), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_DMT_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}),
@ -73,11 +79,13 @@ void RegionTable_Init_DeathMountain() {
areaTable[RR_DMT_STORMS_GROTTO] = Region("DMT Storms Grotto", "DMT Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { areaTable[RR_DMT_STORMS_GROTTO] = Region("DMT Storms Grotto", "DMT Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, {
//Locations //Locations
LOCATION(RC_DMT_STORMS_GROTTO_CHEST, true), LOCATION(RC_DMT_STORMS_GROTTO_CHEST, true),
LOCATION(RC_DMT_STORMS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_DMT_STORMS_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, true), LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
}, { }, {
//Exits //Exits
Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}),
@ -102,33 +110,45 @@ void RegionTable_Init_DeathMountain() {
EventAccess(&logic->StopGCRollingGoronAsAdult, {[]{return logic->StopGCRollingGoronAsAdult || (logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE))));}}), EventAccess(&logic->StopGCRollingGoronAsAdult, {[]{return logic->StopGCRollingGoronAsAdult || (logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE))));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))), LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))),
LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)),
LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)),
LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))),
LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))),
LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult), LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult),
LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()),
LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()), LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()),
LOCATION(RC_GC_MEDIGORON, logic->IsAdult && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_GC_MEDIGORON, logic->IsAdult && (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CallGossipFairyExceptSuns()),
LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GC_LOWER_STAIRCASE_POT_1, logic->CanBreakPots()), LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)),
LOCATION(RC_GC_LOWER_STAIRCASE_POT_2, logic->CanBreakPots()), LOCATION(RC_GC_LOWER_STAIRCASE_POT_1, logic->CanBreakPots()),
LOCATION(RC_GC_UPPER_STAIRCASE_POT_1, logic->CanBreakPots()), LOCATION(RC_GC_LOWER_STAIRCASE_POT_2, logic->CanBreakPots()),
LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()), LOCATION(RC_GC_UPPER_STAIRCASE_POT_1, logic->CanBreakPots()),
LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()), LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()),
// Implied CanBreakPots as when we shuffle strength 0 in the future, the GORONS_BRACELET check will have to check for specifically strength 1 anyway. LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()),
LOCATION(RC_GC_MEDIGORON_POT_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)),
}, { }, {
//Exits //Exits
Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}),
Entrance(RR_GC_MEDIGORON, {[]{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}}),
Entrance(RR_GC_WOODS_WARP, {[]{return logic->GCWoodsWarpOpen;}}), Entrance(RR_GC_WOODS_WARP, {[]{return logic->GCWoodsWarpOpen;}}),
Entrance(RR_GC_SHOP, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire || logic->CanUse(RG_FAIRY_BOW)));}}), Entrance(RR_GC_SHOP, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire || logic->CanUse(RG_FAIRY_BOW)));}}),
Entrance(RR_GC_DARUNIAS_CHAMBER, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && logic->GCDaruniasDoorOpenChild);}}), Entrance(RR_GC_DARUNIAS_CHAMBER, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && logic->GCDaruniasDoorOpenChild);}}),
Entrance(RR_GC_GROTTO_PLATFORM, {[]{return logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && ((logic->EffectiveHealth() > 2) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_NAYRUS_LOVE))) || (logic->EffectiveHealth() > 1 && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_HOOKSHOT)) || (logic->EffectiveHealth() > 2 && logic->CanUse(RG_HOOKSHOT) && ctx->GetTrickOption(RT_GC_GROTTO)));}}), Entrance(RR_GC_GROTTO_PLATFORM, {[]{return logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && ((logic->EffectiveHealth() > 2) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_NAYRUS_LOVE))) || (logic->EffectiveHealth() > 1 && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_HOOKSHOT)) || (logic->EffectiveHealth() > 2 && logic->CanUse(RG_HOOKSHOT) && ctx->GetTrickOption(RT_GC_GROTTO)));}}),
}); });
areaTable[RR_GC_MEDIGORON] = Region("GC Medigoron", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, true),
LOCATION(RC_GC_MEDIGORON_POT_1, logic->CanBreakPots()),
}, {
//Exits
Entrance(RR_GORON_CITY, {[]{return true;}}),
});
areaTable[RR_GC_WOODS_WARP] = Region("GC Woods Warp", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_GC_WOODS_WARP] = Region("GC Woods Warp", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE));}}), EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE));}}),
@ -197,9 +217,11 @@ void RegionTable_Init_DeathMountain() {
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3));}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3), LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3),
LOCATION(RC_DMC_GS_CRATE, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->IsChild && logic->CanAttack()), LOCATION(RC_DMC_GS_CRATE, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->IsChild && logic->CanAttack()),
LOCATION(RC_DMC_GOSSIP_STONE, logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), LOCATION(RC_DMC_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() && logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS) && logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_GOSSIP_STONE, logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)),
}, { }, {
//Exits //Exits
Entrance(RR_DMC_UPPER_NEARBY, {[]{return true;}}), Entrance(RR_DMC_UPPER_NEARBY, {[]{return true;}}),
@ -251,18 +273,21 @@ void RegionTable_Init_DeathMountain() {
areaTable[RR_DMC_CENTRAL_LOCAL] = Region("DMC Central Local", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_DMC_CENTRAL_LOCAL] = Region("DMC Central Local", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DMC_CENTRAL_LOCAL) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}}),
}, { }, {
//Locations //Locations
LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_DMC_GS_BEAN_PATCH, ( logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_DMC_NEAR_PLATFORM_RED_RUPEE, logic->IsChild), LOCATION(RC_DMC_NEAR_PLATFORM_RED_RUPEE, logic->IsChild),
LOCATION(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
}, { }, {
//Exits //Exits
Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return true;}}), Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return true;}}),
@ -282,11 +307,13 @@ void RegionTable_Init_DeathMountain() {
areaTable[RR_DMC_UPPER_GROTTO] = Region("DMC Upper Grotto", "DMC Upper Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { areaTable[RR_DMC_UPPER_GROTTO] = Region("DMC Upper Grotto", "DMC Upper Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, {
//Locations //Locations
LOCATION(RC_DMC_UPPER_GROTTO_CHEST, true), LOCATION(RC_DMC_UPPER_GROTTO_CHEST, true),
LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, true), LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
}, { }, {
//Exits //Exits
Entrance(RR_DMC_UPPER_LOCAL, {[]{return true;}}), Entrance(RR_DMC_UPPER_LOCAL, {[]{return true;}}),

View File

@ -30,9 +30,11 @@ void RegionTable_Init_DodongosCavern() {
EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}),
}, { }, {
//Locations //Locations
LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})),
LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, logic->CanStunDeku() || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, logic->CanStunDeku() || logic->HasItem(RG_GORONS_BRACELET)),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CallGossipFairy()),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})),
}, { }, {
//Exits //Exits
Entrance(RR_DODONGOS_CAVERN_BEGINNING, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_BEGINNING, {[]{return true;}}),
@ -260,17 +262,14 @@ void RegionTable_Init_DodongosCavern() {
Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}),
}); });
areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Region("Dodongos Cavern MQ Lobby", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Region("Dodongos Cavern MQ Lobby", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}),
}, {
//Locations //Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)),
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku()),
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), }, {
}, {
//Exits //Exits
Entrance(RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}}),
Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}),
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}),
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) ||
@ -281,6 +280,19 @@ void RegionTable_Init_DodongosCavern() {
(logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));});}}), (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));});}}),
}); });
areaTable[RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE] = Region("Dodongos Cavern MQ Gossip Stone", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, true),
LOCATION(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE] = Region("Dodongos Cavern MQ Mouth Side Bridge", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE] = Region("Dodongos Cavern MQ Mouth Side Bridge", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}}), EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}}),

View File

@ -379,7 +379,10 @@ void RegionTable_Init_FireTemple() {
Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, {[]{return logic->OpenedLowestGoronCage;}}), Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, {[]{return logic->OpenedLowestGoronCage;}}),
}); });
areaTable[RR_FIRE_TEMPLE_MQ_STALFOS_ROOM] = Region("Fire Temple MQ Stalfos Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_FIRE_TEMPLE_MQ_STALFOS_ROOM] = Region("Fire Temple MQ Stalfos Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, {
//Exits //Exits
Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, {[]{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}), Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, {[]{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}),
@ -390,6 +393,7 @@ void RegionTable_Init_FireTemple() {
EventAccess(&logic->FairyPot, {[]{return true;}}), EventAccess(&logic->FairyPot, {[]{return true;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, logic->CanBreakPots()),
LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, logic->CanBreakPots()),
LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, logic->CanBreakPots()),

View File

@ -50,6 +50,14 @@ void RegionTable_Init_GanonsCastle() {
LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()),
LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, logic->CanStunDeku()),
LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, logic->CanStunDeku()),
LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, true),
LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, true),
LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, true),
LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, true),
LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, true),
LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, true),
LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, true),
LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, true),
}, {}); }, {});
areaTable[RR_GANONS_CASTLE_FOREST_TRIAL] = Region("Ganon's Castle Forest Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_GANONS_CASTLE_FOREST_TRIAL] = Region("Ganon's Castle Forest Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {
@ -112,6 +120,7 @@ void RegionTable_Init_GanonsCastle() {
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, true), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, true),
}, {}); }, {});
@ -178,6 +187,14 @@ void RegionTable_Init_GanonsCastle() {
LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()),
LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, logic->CanStunDeku()),
LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, logic->CanStunDeku()),
LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, true),
LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, true),
LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, true),
LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, true),
LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, true),
LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, true),
LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, true),
LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, true),
}, { }, {
//Exits //Exits
Entrance(RR_GANONS_CASTLE_MQ_MAIN, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_MAIN, {[]{return true;}}),
@ -404,6 +421,7 @@ void RegionTable_Init_GanonsCastle() {
Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT, {[]{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL);}}), Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT, {[]{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL);}}),
Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, {[]{return logic->SmallKeys(RR_GANONS_CASTLE, 3) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, {[]{return logic->SmallKeys(RR_GANONS_CASTLE, 3) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
(logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanJumpslash() || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG));}}), (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanJumpslash() || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG));}}),
}); });
areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Light Trial Final Room", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Light Trial Final Room", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {

View File

@ -21,12 +21,13 @@ void RegionTable_Init_GerudoTrainingGrounds() {
if (ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsVanilla()) { if (ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsVanilla()) {
areaTable[RR_GERUDO_TRAINING_GROUND_LOBBY] = Region("Gerudo Training Ground Lobby", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_GERUDO_TRAINING_GROUND_LOBBY] = Region("Gerudo Training Ground Lobby", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)),
LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))),
LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, true), LOCATION(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, true), LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, true),
LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, true),
}, { }, {
//Exits //Exits
Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, {[]{return true;}}), Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, {[]{return true;}}),

View File

@ -22,12 +22,17 @@ void RegionTable_Init_GerudoValley() {
areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, { areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_GV_UPPER_STREAM) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}),
}, { }, {
//Locations //Locations
LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child
LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_GV_COW, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), LOCATION(RC_GV_COW, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_GV_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_GOSSIP_STONE, true), LOCATION(RC_GV_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
@ -134,6 +139,8 @@ void RegionTable_Init_GerudoValley() {
LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, logic->CanBreakPots()), LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, logic->CanBreakPots()),
LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, logic->CanBreakPots()), LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, logic->CanBreakPots()),
LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, logic->CanBreakPots()), LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, logic->CanBreakPots()),
//RANDOTODO doublecheck when GF isn't a blob
LOCATION(RC_GF_KITCHEN_SUN_FAIRY, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}),
@ -154,7 +161,17 @@ void RegionTable_Init_GerudoValley() {
areaTable[RR_GF_STORMS_GROTTO] = Region("GF Storms Grotto", "GF Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_GF_STORMS_GROTTO] = Region("GF Storms Grotto", "GF Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->FreeFairies, {[]{return true;}}), EventAccess(&logic->FreeFairies, {[]{return true;}}),
}, {}, { }, {
//Locations
LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_1, true),
LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_2, true),
LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_3, true),
LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_4, true),
LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_5, true),
LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_6, true),
LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_7, true),
LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_8, true),
}, {
//Exits //Exits
Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}),
}); });
@ -197,19 +214,45 @@ void RegionTable_Init_GerudoValley() {
EventAccess(&logic->BugRock, {[]{return true;}}), EventAccess(&logic->BugRock, {[]{return true;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS)), LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS)),
LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()),
LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
//You can kinda get the fairies without entering the water, but it relies on them cooperating and leevers are jerks. should be a trick
Entrance(RR_DESERT_COLOSSUS_OASIS, {[]{return logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}),
Entrance(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives();}}), Entrance(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives();}}),
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}),
Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return true;}}), Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return true;}}),
Entrance(RR_COLOSSUS_GROTTO, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS);}}), Entrance(RR_COLOSSUS_GROTTO, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS);}}),
}); });
//specifically the full oasis, after the fairies have spawned
areaTable[RR_DESERT_COLOSSUS_OASIS] = Region("Desert Colossus Oasis", "Desert Colossus", {RA_DESERT_COLOSSUS}, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FairyPond, {[]{return true;}}),
}, {
//Locations
LOCATION(RC_COLOSSUS_OASIS_FAIRY_1, true),
LOCATION(RC_COLOSSUS_OASIS_FAIRY_2, true),
LOCATION(RC_COLOSSUS_OASIS_FAIRY_3, true),
LOCATION(RC_COLOSSUS_OASIS_FAIRY_4, true),
LOCATION(RC_COLOSSUS_OASIS_FAIRY_5, true),
LOCATION(RC_COLOSSUS_OASIS_FAIRY_6, true),
LOCATION(RC_COLOSSUS_OASIS_FAIRY_7, true),
LOCATION(RC_COLOSSUS_OASIS_FAIRY_8, true),
}, {
//Exits
Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}),
});
areaTable[RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE] = Region("Desert Colossus From Spirit Entryway", "Desert Colossus", {RA_DESERT_COLOSSUS}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE] = Region("Desert Colossus From Spirit Entryway", "Desert Colossus", {RA_DESERT_COLOSSUS}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SHEIK_AT_COLOSSUS, true), LOCATION(RC_SHEIK_AT_COLOSSUS, true),

View File

@ -9,8 +9,9 @@ void RegionTable_Init_HyruleField() {
EventAccess(&logic->BigPoeKill, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_EPONA) && logic->HasBottle();}}), EventAccess(&logic->BigPoeKill, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_EPONA) && logic->HasBottle();}}),
}, { }, {
//Locations //Locations
LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3), LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)),
LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3), LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)),
LOCATION(RC_HF_POND_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //Exits
Entrance(RR_LW_BRIDGE, {[]{return true;}}), Entrance(RR_LW_BRIDGE, {[]{return true;}}),
@ -32,11 +33,13 @@ void RegionTable_Init_HyruleField() {
areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", "HF Southeast Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", "HF Southeast Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, {
//Locations //Locations
LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, true), LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, true),
LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, true), LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
}, { }, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}),
@ -44,11 +47,13 @@ void RegionTable_Init_HyruleField() {
areaTable[RR_HF_OPEN_GROTTO] = Region("HF Open Grotto", "HF Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { areaTable[RR_HF_OPEN_GROTTO] = Region("HF Open Grotto", "HF Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, {
//Locations //Locations
LOCATION(RC_HF_OPEN_GROTTO_CHEST, true), LOCATION(RC_HF_OPEN_GROTTO_CHEST, true),
LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE, true), LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
}, { }, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}),
@ -58,30 +63,45 @@ void RegionTable_Init_HyruleField() {
//Locations //Locations
LOCATION(RC_HF_DEKU_SCRUB_GROTTO, logic->CanStunDeku()), LOCATION(RC_HF_DEKU_SCRUB_GROTTO, logic->CanStunDeku()),
LOCATION(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), LOCATION(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()),
LOCATION(RC_HF_FENCE_GROTTO_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}),
}); });
areaTable[RR_HF_COW_GROTTO] = Region("HF Cow Grotto", "HF Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { areaTable[RR_HF_COW_GROTTO] = Region("HF Cow Grotto", "HF Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}),
Entrance(RR_HF_COW_GROTTO_BEHIND_WEBS, {[]{return logic->HasFireSource();}}),
});
areaTable[RR_HF_COW_GROTTO_BEHIND_WEBS] = Region("HF Cow Grotto Behind Webs", "HF Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->BugShrub, {[]{return logic->CanCutShrubs();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
}, {
//Locations //Locations
LOCATION(RC_HF_GS_COW_GROTTO, logic->HasFireSource() && logic->HookshotOrBoomerang()), LOCATION(RC_HF_GS_COW_GROTTO, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
LOCATION(RC_HF_COW_GROTTO_COW, logic->HasFireSource() && logic->CanUse(RG_EPONAS_SONG)), LOCATION(RC_HF_COW_GROTTO_COW, logic->CanUse(RG_EPONAS_SONG)),
LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE, logic->HasFireSource()), LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HF_COW_GROTTO_POT_1, logic->HasFireSource() && logic->CanBreakPots()), LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HF_COW_GROTTO_POT_2, logic->HasFireSource() && logic->CanBreakPots()), LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_HF_COW_GROTTO_POT_1, logic->CanBreakPots()),
LOCATION(RC_HF_COW_GROTTO_POT_2, logic->CanBreakPots()),
}, { }, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_HF_COW_GROTTO, {[]{return true;}}),
}); });
areaTable[RR_HF_NEAR_MARKET_GROTTO] = Region("HF Near Market Grotto", "HF Near Market Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { areaTable[RR_HF_NEAR_MARKET_GROTTO] = Region("HF Near Market Grotto", "HF Near Market Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, {
//Locations //Locations
LOCATION(RC_HF_NEAR_MARKET_GROTTO_CHEST, true), LOCATION(RC_HF_NEAR_MARKET_GROTTO_CHEST, true),
LOCATION(RC_HF_NEAR_MARKET_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_NEAR_MARKET_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, true), LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
}, { }, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}),
@ -90,7 +110,17 @@ void RegionTable_Init_HyruleField() {
areaTable[RR_HF_FAIRY_GROTTO] = Region("HF Fairy Grotto", "HF Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_HF_FAIRY_GROTTO] = Region("HF Fairy Grotto", "HF Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->FreeFairies, {[]{return true;}}), EventAccess(&logic->FreeFairies, {[]{return true;}}),
}, {}, { }, {
//Locations
LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_1, true),
LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_2, true),
LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_3, true),
LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_4, true),
LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_5, true),
LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_6, true),
LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_7, true),
LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_8, true),
}, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}),
}); });
@ -114,26 +144,37 @@ void RegionTable_Init_HyruleField() {
areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", "Lake Hylia", {RA_LAKE_HYLIA}, DAY_NIGHT_CYCLE, { areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", "Lake Hylia", {RA_LAKE_HYLIA}, DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_LAKE_HYLIA) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}),
EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}),
EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || (logic->IsChild && logic->CanCutShrubs());}}), EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || (logic->IsChild && logic->CanCutShrubs());}}),
EventAccess(&logic->ChildScarecrow, {[]{return logic->ChildScarecrow || (logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}}), EventAccess(&logic->ChildScarecrow, {[]{return logic->ChildScarecrow || (logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}}),
EventAccess(&logic->AdultScarecrow, {[]{return logic->AdultScarecrow || (logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}}), EventAccess(&logic->AdultScarecrow, {[]{return logic->AdultScarecrow || (logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}}),
}, { }, {
//Locations //Locations
LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)),
LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->WaterTempleClear && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)), LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->WaterTempleClear && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)),
LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))), LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))),
LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()),
LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->CanGetNightTimeGS() && logic->HasItem(RG_BRONZE_SCALE)), LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->CanGetNightTimeGS() && logic->HasItem(RG_BRONZE_SCALE)),
LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanGetNightTimeGS()), LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanGetNightTimeGS()),
LOCATION(RC_LH_FRONT_RUPEE, logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)), LOCATION(RC_LH_FRONT_RUPEE, logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)),
LOCATION(RC_LH_MIDDLE_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LH_MIDDLE_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LH_BACK_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LH_BACK_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LH_LAB_GOSSIP_STONE, true), LOCATION(RC_LH_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE, true), LOCATION(RC_LH_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE, true), LOCATION(RC_LH_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_LAB_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
//You can walk along the edge of the lake to get these without swimming, the fairy is created going backwards, which is convenient here,
LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_ISLAND_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && ((logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->WaterTempleClear)) || logic->CanUse(RG_DISTANT_SCARECROW))),
LOCATION(RC_LH_LAB_GOSSIP_STONE, true),
LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE, true),
LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}),

View File

@ -19,7 +19,10 @@ void RegionTable_Init_IceCavern() {
| VANILLA DUNGEON | | VANILLA DUNGEON |
---------------------------*/ ---------------------------*/
if (ctx->GetDungeon(ICE_CAVERN)->IsVanilla()) { if (ctx->GetDungeon(ICE_CAVERN)->IsVanilla()) {
areaTable[RR_ICE_CAVERN_BEGINNING] = Region("Ice Cavern Beginning", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_ICE_CAVERN_BEGINNING] = Region("Ice Cavern Beginning", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, {
//Exits //Exits
Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return true;}}), Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return true;}}),
Entrance(RR_ICE_CAVERN_MAIN, {[]{return Here(RR_ICE_CAVERN_BEGINNING, []{return (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE);});}}), Entrance(RR_ICE_CAVERN_MAIN, {[]{return Here(RR_ICE_CAVERN_BEGINNING, []{return (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE);});}}),

View File

@ -216,11 +216,13 @@ void RegionTable_Init_Kakariko() {
areaTable[RR_KAK_OPEN_GROTTO] = Region("Kak Open Grotto", "Kak Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { areaTable[RR_KAK_OPEN_GROTTO] = Region("Kak Open Grotto", "Kak Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, {
//Locations //Locations
LOCATION(RC_KAK_OPEN_GROTTO_CHEST, true), LOCATION(RC_KAK_OPEN_GROTTO_CHEST, true),
LOCATION(RC_KAK_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_KAK_OPEN_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, true), LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
}, { }, {
//Exits //Exits
Entrance(RR_KAK_BACKYARD, {[]{return true;}}), Entrance(RR_KAK_BACKYARD, {[]{return true;}}),
@ -241,7 +243,7 @@ void RegionTable_Init_Kakariko() {
areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", "The Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", "The Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_THE_GRAVEYARD) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}),
EventAccess(&logic->BugRock, {[]{return true;}}), EventAccess(&logic->BugRock, {[]{return true;}}),
}, { }, {
//Locations //Locations
@ -249,6 +251,9 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change
LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //Exits
Entrance(RR_GRAVEYARD_SHIELD_GRAVE, {[]{return logic->IsAdult || logic->AtNight;}}), Entrance(RR_GRAVEYARD_SHIELD_GRAVE, {[]{return logic->IsAdult || logic->AtNight;}}),
@ -263,7 +268,22 @@ void RegionTable_Init_Kakariko() {
areaTable[RR_GRAVEYARD_SHIELD_GRAVE] = Region("Graveyard Shield Grave", "Graveyard Shield Grave", {}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_GRAVEYARD_SHIELD_GRAVE] = Region("Graveyard Shield Grave", "Graveyard Shield Grave", {}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, true), LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, true),
//Free Fairies }, {
//Exits
Entrance(RR_THE_GRAVEYARD, {[]{return true;}}),
Entrance(RR_GRAVEYARD_SHIELD_GRAVE_BACK, {[]{return Here(RR_GRAVEYARD_SHIELD_GRAVE, []{return logic->CanBreakMudWalls();});}}),
});
areaTable[RR_GRAVEYARD_SHIELD_GRAVE_BACK] = Region("Graveyard Shield Grave Back", "Graveyard Shield Grave", {}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, true),
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, true),
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, true),
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, true),
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, true),
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, true),
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, true),
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, true),
}, { }, {
//Exits //Exits
Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), Entrance(RR_THE_GRAVEYARD, {[]{return true;}}),
@ -327,11 +347,13 @@ void RegionTable_Init_Kakariko() {
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
}, { }, {
//Locations //Locations
LOCATION(RC_GRAVEYARD_GOSSIP_STONE, true), LOCATION(RC_GRAVEYARD_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GRAVEYARD_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), Entrance(RR_THE_GRAVEYARD, {[]{return true;}}),
Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_GY_SHADOW_FIRE_ARROWS) && logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS));}}), Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_GY_SHADOW_FIRE_ARROWS) && logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS));}}),
}); });
} }

View File

@ -6,7 +6,7 @@ using namespace Rando;
void RegionTable_Init_LostWoods() { void RegionTable_Init_LostWoods() {
areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", "Kokiri Forest", {RA_KOKIRI_FOREST}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", "Kokiri Forest", {RA_KOKIRI_FOREST}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_KOKIRI_FOREST) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}),
}, { }, {
@ -15,6 +15,11 @@ void RegionTable_Init_LostWoods() {
LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && (/*TODO: HasNightStart ||*/ logic->CanLeaveForest() || logic->CanUse(RG_SUNS_SONG)) && logic->CanGetNightTimeGS()), LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && (/*TODO: HasNightStart ||*/ logic->CanLeaveForest() || logic->CanUse(RG_SUNS_SONG)) && logic->CanGetNightTimeGS()),
LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_KF_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild), LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild),
LOCATION(RC_KF_BEHIND_MIDOS_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_WEST_RUPEE, logic->IsChild),
@ -55,8 +60,12 @@ void RegionTable_Init_LostWoods() {
EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, true), LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, true), LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, true),
LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return logic->IsChild || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield));}}), Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return logic->IsChild || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield));}}),
@ -131,6 +140,8 @@ void RegionTable_Init_LostWoods() {
//Locations //Locations
LOCATION(RC_KF_STORMS_GROTTO_CHEST, true), LOCATION(RC_KF_STORMS_GROTTO_CHEST, true),
LOCATION(RC_KF_STORMS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_KF_STORMS_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE, true), LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
@ -147,14 +158,14 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", "Lost Woods", {RA_THE_LOST_WOODS}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", "Lost Woods", {RA_THE_LOST_WOODS}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || logic->CanUse(RG_SONG_OF_STORMS);}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}),
EventAccess(&logic->BugShrub, {[]{return logic->IsChild && logic->CanCutShrubs();}}), EventAccess(&logic->BugShrub, {[]{return logic->IsChild && logic->CanCutShrubs();}}),
}, { }, {
//Locations //Locations
LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)),
LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->CanUse(RG_COJIRO)), LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->CanUse(RG_COJIRO)),
//I cannot think of a case where you can use Odd pot but not Cojiro to reset the quadrant should you have both. If one exists, add it to logic //I cannot think of a case where you can use Odd pot but not Cojiro to reset the quadrant should you have both. If one exists, add it to logic
LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->CanUse(RG_ODD_POTION)), LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->CanUse(RG_ODD_POTION)),
//all 5 buttons are logically required for memory game //all 5 buttons are logically required for memory game
//because the chances of being able to beat it //because the chances of being able to beat it
//every time you attempt it are as follows: //every time you attempt it are as follows:
@ -163,20 +174,26 @@ void RegionTable_Init_LostWoods() {
//3 buttons => 3.75% //3 buttons => 3.75%
//4 buttons => 25.3125% //4 buttons => 25.3125%
//5 buttons => 100% //5 buttons => 100%
LOCATION(RC_LW_OCARINA_MEMORY_GAME, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 5), LOCATION(RC_LW_OCARINA_MEMORY_GAME, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 5),
LOCATION(RC_LW_TARGET_IN_WOODS, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_LW_TARGET_IN_WOODS, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, logic->IsChild && logic->CanStunDeku()), LOCATION(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, logic->IsChild && logic->CanStunDeku()),
LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull() && logic->CanAttack()),
//RANDOTODO handle collecting some of these as you leave the shortcut from the other side //RANDOTODO handle collecting some of these as you leave the shortcut from the other side
LOCATION(RC_LW_SHORTCUT_RUPEE_1, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_SHORTCUT_RUPEE_1, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_2, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_SHORTCUT_RUPEE_2, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_3, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_SHORTCUT_RUPEE_3, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_4, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_SHORTCUT_RUPEE_4, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_5, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_SHORTCUT_RUPEE_5, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_6, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_SHORTCUT_RUPEE_6, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_7, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_SHORTCUT_RUPEE_7, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_8, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_SHORTCUT_RUPEE_8, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_GOSSIP_STONE, true), LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_LW_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}),
@ -197,6 +214,9 @@ void RegionTable_Init_LostWoods() {
LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAttack()) || (ctx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS()), LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAttack()) || (ctx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS()),
LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanSpawnSoilSkull() && (logic->CanAttack() || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))), LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanSpawnSoilSkull() && (logic->CanAttack() || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))),
LOCATION(RC_LW_BOULDER_RUPEE, logic->BlastOrSmash()), LOCATION(RC_LW_BOULDER_RUPEE, logic->BlastOrSmash()),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //Exits
Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}),
@ -208,11 +228,13 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_LW_NEAR_SHORTCUTS_GROTTO] = Region("LW Near Shortcuts Grotto", "LW Near Shortcuts Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { areaTable[RR_LW_NEAR_SHORTCUTS_GROTTO] = Region("LW Near Shortcuts Grotto", "LW Near Shortcuts Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, {
//Locations //Locations
LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, true), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, true),
LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, true), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
}, { }, {
//Exits //Exits
Entrance(RR_THE_LOST_WOODS, {[]{return true;}}), Entrance(RR_THE_LOST_WOODS, {[]{return true;}}),
@ -249,12 +271,18 @@ void RegionTable_Init_LostWoods() {
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
}, { }, {
//Locations //Locations
LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)), LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)),
LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult), LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult),
LOCATION(RC_SFM_GS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_SFM_GS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE, true), LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE, true), LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE, true), LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE, true),
LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE, true),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE, true),
}, { }, {
//Exits //Exits
Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}),
@ -266,7 +294,17 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_SFM_FAIRY_GROTTO] = Region("SFM Fairy Grotto", "SFM Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_SFM_FAIRY_GROTTO] = Region("SFM Fairy Grotto", "SFM Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->FreeFairies, {[]{return true;}}), EventAccess(&logic->FreeFairies, {[]{return true;}}),
}, {}, { }, {
//Locations
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_1, true),
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_2, true),
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_3, true),
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_4, true),
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_5, true),
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_6, true),
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_7, true),
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_8, true),
}, {
//Exits //Exits
Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}),
}); });

View File

@ -24,8 +24,8 @@ void RegionTable_Init_ShadowTemple() {
EventAccess(&logic->NutPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslashExceptHammer()), LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslashExceptHammer()),
LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))),
LOCATION(RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, logic->CanBreakPots()),
@ -48,6 +48,7 @@ void RegionTable_Init_ShadowTemple() {
LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslashExceptHammer()), LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslashExceptHammer()),
LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)),
LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, false), LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, false),
LOCATION(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, {[]{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1, 2);}}), Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, {[]{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1, 2);}}),
@ -73,6 +74,7 @@ void RegionTable_Init_ShadowTemple() {
//We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared //We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared
LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, {[]{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3, 4);}}), Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, {[]{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3, 4);}}),
@ -84,6 +86,7 @@ void RegionTable_Init_ShadowTemple() {
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslashExceptHammer()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslashExceptHammer()),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, true), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, true),
LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)),
LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)),
@ -155,6 +158,7 @@ void RegionTable_Init_ShadowTemple() {
//Locations //Locations
//Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, but doesn't seem to affect the chest //Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, but doesn't seem to affect the chest
LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))),
LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}), Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}),
@ -188,7 +192,10 @@ void RegionTable_Init_ShadowTemple() {
//bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily //bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily
}); });
areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Region("Shadow Temple MQ Upper Huge Pit", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Region("Shadow Temple MQ Upper Huge Pit", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return (logic->HasFireSource() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))) || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}), Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return (logic->HasFireSource() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))) || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}),
Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}), Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
@ -286,8 +293,9 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM] = Region("Shadow Temple MQ Wind Hint Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM] = Region("Shadow Temple MQ Wind Hint Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_REDEAD)), LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_REDEAD)),
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return true;}}), Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return true;}}),
@ -358,7 +366,7 @@ void RegionTable_Init_ShadowTemple() {
//Locations //Locations
//you can drop onto this and the respawn is reasonable //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_TEMPLE_MQ_GS_NEAR_BOSS, (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}),
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}), Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}),

View File

@ -68,6 +68,7 @@ void RegionTable_Init_SpiritTemple() {
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)),
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)),
LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))), LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))),
LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}),
@ -128,6 +129,7 @@ void RegionTable_Init_SpiritTemple() {
LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()),
LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()),
LOCATION(RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, logic->CanBreakPots()),
LOCATION(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, logic->HasExplosives() && logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && (ctx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || ((logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_NUTS) || logic->CanUse(RG_DINS_FIRE)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_MEGATON_HAMMER))));}}), Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && (ctx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || ((logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_NUTS) || logic->CanUse(RG_DINS_FIRE)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_MEGATON_HAMMER))));}}),
@ -440,7 +442,8 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM] = Region("Spirit Temple MQ SoT Sun Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM] = Region("Spirit Temple MQ SoT Sun Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, true), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, true),
LOCATION(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return true;}}), Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return true;}}),

View File

@ -403,7 +403,7 @@ void RegionTable_Init_WaterTemple() {
//Raising the targets by clearing this room achieves nothing logically because it requires WL_LOW to do and hookshot to use, which implies access to WL_MID and WL_HIGH already //Raising the targets by clearing this room achieves nothing logically because it requires WL_LOW to do and hookshot to use, which implies access to WL_MID and WL_HIGH already
areaTable[RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM] = Region("Water Temple MQ East Tower 1F Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM] = Region("Water Temple MQ East Tower 1F Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE)), LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE)),
}, { }, {
Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER, {[]{return true;}}), Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER, {[]{return true;}}),
}); });
@ -549,9 +549,11 @@ void RegionTable_Init_WaterTemple() {
EventAccess(&logic->NutPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, logic->CanBreakPots()),
LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, logic->CanBreakPots()),
LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, logic->CanBreakPots()),
LOCATION(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->MQWaterStalfosPit && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}}), Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->MQWaterStalfosPit && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}}),
@ -562,8 +564,10 @@ void RegionTable_Init_WaterTemple() {
//specifically the area past the spikes //specifically the area past the spikes
areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER] = Region("Water Temple MQ Stalfos Pit Upper", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER] = Region("Water Temple MQ Stalfos Pit Upper", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, logic->CanBreakPots()),
LOCATION(RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, logic->CanBreakPots()),
LOCATION(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //Exits
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, {[]{return logic->IsAdult || logic->TakeDamage();}}), Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, {[]{return logic->IsAdult || logic->TakeDamage();}}),

View File

@ -16,7 +16,7 @@ void RegionTable_Init_ZorasDomain() {
areaTable[RR_ZORAS_RIVER] = Region("Zora River", "Zora River", {RA_ZORAS_RIVER}, DAY_NIGHT_CYCLE, { areaTable[RR_ZORAS_RIVER] = Region("Zora River", "Zora River", {RA_ZORAS_RIVER}, DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_ZORAS_RIVER) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}),
EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}),
EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || logic->CanCutShrubs();}}), EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || logic->CanCutShrubs();}}),
}, { }, {
@ -34,6 +34,13 @@ void RegionTable_Init_ZorasDomain() {
LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->CanAttack() && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->CanAttack() && logic->CanGetNightTimeGS()),
LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->CanGetNightTimeGS()),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_ZR_BENEATH_WATERFALL_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_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_MIDDLE_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))),
@ -65,6 +72,8 @@ void RegionTable_Init_ZorasDomain() {
//Locations //Locations
LOCATION(RC_ZR_OPEN_GROTTO_CHEST, true), LOCATION(RC_ZR_OPEN_GROTTO_CHEST, true),
LOCATION(RC_ZR_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_ZR_OPEN_GROTTO_FISH, logic->HasBottle()),
LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, true), LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, true),
LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()),
LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()),
@ -76,7 +85,17 @@ void RegionTable_Init_ZorasDomain() {
areaTable[RR_ZR_FAIRY_GROTTO] = Region("ZR Fairy Grotto", "ZR Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_ZR_FAIRY_GROTTO] = Region("ZR Fairy Grotto", "ZR Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, {
//Event //Event
EventAccess(&logic->FreeFairies, {[]{return true;}}), EventAccess(&logic->FreeFairies, {[]{return true;}}),
}, {}, { }, {
//Locations
LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_1, true),
LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_2, true),
LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_3, true),
LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_4, true),
LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_5, true),
LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_6, true),
LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_7, true),
LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_8, true),
}, {
//Exits //Exits
Entrance(RR_ZORAS_RIVER, {[]{return true;}}), Entrance(RR_ZORAS_RIVER, {[]{return true;}}),
}); });
@ -111,6 +130,8 @@ void RegionTable_Init_ZorasDomain() {
LOCATION(RC_ZD_FISH_3, logic->IsChild && logic->HasBottle()), LOCATION(RC_ZD_FISH_3, logic->IsChild && logic->HasBottle()),
LOCATION(RC_ZD_FISH_4, logic->IsChild && logic->HasBottle()), LOCATION(RC_ZD_FISH_4, logic->IsChild && logic->HasBottle()),
LOCATION(RC_ZD_FISH_5, logic->IsChild && logic->HasBottle()), LOCATION(RC_ZD_FISH_5, logic->IsChild && logic->HasBottle()),
LOCATION(RC_ZD_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_ZD_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZD_GOSSIP_STONE, true), LOCATION(RC_ZD_GOSSIP_STONE, true),
LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->CanBreakUpperBeehives()), LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->CanBreakUpperBeehives()),
LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->CanBreakUpperBeehives()), LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->CanBreakUpperBeehives()),
@ -125,7 +146,13 @@ void RegionTable_Init_ZorasDomain() {
Entrance(RR_LAKE_HYLIA, {[]{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), Entrance(RR_LAKE_HYLIA, {[]{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}),
Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (ctx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}}), Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (ctx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}}),
Entrance(RR_ZD_SHOP, {[]{return logic->IsChild || logic->BlueFire();}}), Entrance(RR_ZD_SHOP, {[]{return logic->IsChild || logic->BlueFire();}}),
Entrance(RR_ZD_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), Entrance(RR_ZORAS_DOMAIN_ISLAND, {[]{return true;}}),
});
areaTable[RR_ZORAS_DOMAIN_ISLAND] = Region("Zoras Domain Island", "Zoras Domain", {RA_ZORAS_DOMAIN}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_ZORAS_DOMAIN, {[]{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}}),
Entrance(RR_ZD_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}),
}); });
areaTable[RR_ZD_BEHIND_KING_ZORA] = Region("ZD Behind King Zora", "Zoras Domain", {RA_ZORAS_DOMAIN}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_ZD_BEHIND_KING_ZORA] = Region("ZD Behind King Zora", "Zoras Domain", {RA_ZORAS_DOMAIN}, NO_DAY_NIGHT_CYCLE, {}, {
@ -155,9 +182,19 @@ void RegionTable_Init_ZorasDomain() {
areaTable[RR_ZD_STORMS_GROTTO] = Region("ZD Storms Grotto", "ZD Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_ZD_STORMS_GROTTO] = Region("ZD Storms Grotto", "ZD Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->FreeFairies, {[]{return true;}}), EventAccess(&logic->FreeFairies, {[]{return true;}}),
}, {}, { }, {
//Locations
LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_1, true),
LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_2, true),
LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_3, true),
LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_4, true),
LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_5, true),
LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_6, true),
LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_7, true),
LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_8, true),
}, {
//Exits //Exits
Entrance(RR_ZORAS_DOMAIN, {[]{return true;}}), Entrance(RR_ZORAS_DOMAIN_ISLAND, {[]{return true;}}),
}); });
areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {
@ -174,6 +211,10 @@ void RegionTable_Init_ZorasDomain() {
LOCATION(RC_ZF_HIDDEN_CAVE_POT_1, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), LOCATION(RC_ZF_HIDDEN_CAVE_POT_1, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()),
LOCATION(RC_ZF_HIDDEN_CAVE_POT_2, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), LOCATION(RC_ZF_HIDDEN_CAVE_POT_2, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()),
LOCATION(RC_ZF_HIDDEN_CAVE_POT_3, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), LOCATION(RC_ZF_HIDDEN_CAVE_POT_3, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()),
LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZF_BOTTOM_NORTH_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), LOCATION(RC_ZF_BOTTOM_NORTH_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16),
LOCATION(RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), LOCATION(RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16),
LOCATION(RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), LOCATION(RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16),

View File

@ -0,0 +1,178 @@
#include "ShuffleFairies.h"
#include "randomizer_grotto.h"
#include "draw.h"
#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h"
#include "src/overlays/actors/ovl_En_Gs/z_en_gs.h"
#include "../../OTRGlobals.h"
#include "../../cvar_prefixes.h"
#define FAIRY_FLAG_TIMED (1 << 8)
void ShuffleFairies_DrawRandomizedItem(EnElf* enElf, PlayState* play) {
GetItemEntry randoGetItem = enElf->sohFairyIdentity.itemEntry;
if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) {
randoGetItem = GET_ITEM_MYSTERY;
}
Matrix_Push();
Matrix_Scale(37.5, 37.5, 37.5, MTXMODE_APPLY);
EnItem00_CustomItemsParticles(&enElf->actor, play, randoGetItem);
GetItemEntry_Draw(play, randoGetItem);
Matrix_Pop();
}
bool ShuffleFairies_FairyExists(FairyIdentity fairyIdentity) {
Actor* actor = gPlayState->actorCtx.actorLists[ACTORCAT_ITEMACTION].head;
while (actor != NULL) {
if (actor->id != ACTOR_EN_ELF) {
actor = actor->next;
} else {
EnElf* enElf = (EnElf*)(actor);
if (fairyIdentity.randomizerInf == enElf->sohFairyIdentity.randomizerInf) {
return true;
}
actor = actor->next;
}
}
return false;
}
FairyIdentity ShuffleFairies_GetFairyIdentity(int32_t params) {
FairyIdentity fairyIdentity;
s16 sceneNum = gPlayState->sceneNum;
fairyIdentity.randomizerInf = RAND_INF_MAX;
if (sceneNum == SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT || sceneNum == SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS) {
sceneNum = SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY;
}
Rando::Location* location = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_ELF, sceneNum, params);
if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) {
LUSLOG_WARN("FairyGetIdentity did not receive a valid RC value (%d).", location->GetRandomizerCheck());
assert(false);
} else {
fairyIdentity.randomizerInf = static_cast<RandomizerInf>(location->GetCollectionCheck().flag);
fairyIdentity.itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(location->GetRandomizerCheck(), true, GI_FAIRY);
}
return fairyIdentity;
}
bool ShuffleFairies_SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params) {
FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params);
if (!Flags_GetRandomizerInf(fairyIdentity.randomizerInf)) {
EnElf* fairy = (EnElf*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0,
0, 0, FAIRY_HEAL, true);
fairy->sohFairyIdentity = fairyIdentity;
fairy->actor.draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem;
fairy->fairyFlags |= FAIRY_FLAG_TIMED;
return true;
}
return false;
}
void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) {
va_list args;
va_copy(args, originalArgs);
Actor* actor = va_arg(args, Actor*);
va_end(args);
// Grant item when picking up fairy. If randomized, disable healing effect.
if (id == VB_FAIRY_HEAL) {
EnElf* enElf = (EnElf*)(actor);
if (enElf->sohFairyIdentity.randomizerInf && enElf->sohFairyIdentity.randomizerInf != RAND_INF_MAX) {
Flags_SetRandomizerInf(enElf->sohFairyIdentity.randomizerInf);
}
// Spawn fairies in fairy fountains
} else if (id == VB_SPAWN_FOUNTAIN_FAIRIES) {
bool fairySpawned = false;
s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0;
for (s16 index = 0; index < 8; index++) {
int32_t params = (grottoId << 8) | index;
if (ShuffleFairies_SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z,
params)) {
fairySpawned = true;
}
}
if (fairySpawned) {
*should = false;
}
// Spawn 3 fairies when playing Song of Storms next to a planted bean
} else if (id == VB_SPAWN_BEAN_STALK_FAIRIES) {
ObjBean* objBean = (ObjBean*)(actor);
bool fairySpawned = false;
for (s16 index = 0; index < 3; index++) {
int32_t params = ((objBean->dyna.actor.params & 0x3F) << 8) | index;
if (ShuffleFairies_SpawnFairy(objBean->dyna.actor.world.pos.x, objBean->dyna.actor.world.pos.y,
objBean->dyna.actor.world.pos.z,
params)) {
fairySpawned = true;
}
}
if (fairySpawned) {
*should = false;
}
// Handle playing both misc songs and song of storms in front of a gossip stone.
} else if (id == VB_SPAWN_GOSSIP_STONE_FAIRY) {
EnGs* gossipStone = (EnGs*)(actor);
// If not any of the songs that normally spawn a fairy, mimic vanilla behaviour.
if (gPlayState->msgCtx.ocarinaMode == OCARINA_MODE_01) {
Player* player = GET_PLAYER(gPlayState);
player->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR;
return;
} else if (gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_LULLABY &&
gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_SARIAS &&
gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_EPONAS &&
gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_SUNS &&
gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_TIME &&
gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_STORMS &&
gPlayState->msgCtx.ocarinaMode != OCARINA_MODE_04) {
return;
}
int32_t params = (gPlayState->sceneNum == SCENE_GROTTOS) ? Grotto_CurrentGrotto() : 0;
// Distinguish storms fairies from the normal song fairies
if (gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_STORMS) {
params |= 0x1000;
}
// Combine actor + song params with position to get the right randomizer check
params = TWO_ACTOR_PARAMS(params, (int32_t)gossipStone->actor.world.pos.z);
// Check if a fairy already exists with the same identity as the stone is trying to spawn.
// Because the gossip stone code runs several times after playing the song, we need to
// stop spawning the vanilla fairy as well when these fairies exist, otherwise both
// the randomized and the vanilla fairy will spawn. When the randomized fairy is already
// collected, the vanilla code will handle that part automatically.
FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params);
if (!ShuffleFairies_FairyExists(fairyIdentity)) {
if (ShuffleFairies_SpawnFairy(gossipStone->actor.world.pos.x, gossipStone->actor.world.pos.y,
gossipStone->actor.world.pos.z, params)) {
Audio_PlayActorSound2(&gossipStone->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY);
// Set vanilla check for fairy spawned so it doesn't spawn the vanilla fairy afterwards as well.
gossipStone->unk_19D = 0;
*should = false;
}
} else {
*should = false;
}
}
}
uint32_t onVanillaBehaviorHook = 0;
void ShuffleFairies_RegisterHooks() {
onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(ShuffleFairies_OnVanillaBehaviorHandler);
}
void ShuffleFairies_UnregisterHooks() {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(onVanillaBehaviorHook);
onVanillaBehaviorHook = 0;
}

View File

@ -0,0 +1,13 @@
#pragma once
#include <z64.h>
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include "randomizer_inf.h"
typedef struct FairyIdentity {
RandomizerInf randomizerInf;
GetItemEntry itemEntry;
} FairyIdentity;
void ShuffleFairies_RegisterHooks();
void ShuffleFairies_UnregisterHooks();

View File

@ -240,6 +240,8 @@ Dungeons::Dungeons() {
RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, RC_DODONGOS_CAVERN_BLADE_ROOM_HEART,
RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART,
RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART,
RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY,
RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG,
}, },
{ {
// MQ Locations // MQ Locations
@ -260,6 +262,8 @@ Dungeons::Dungeons() {
RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA,
RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART,
RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART,
RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY,
RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG,
}, },
{ {
// Vanilla Pots // Vanilla Pots
@ -579,6 +583,8 @@ Dungeons::Dungeons() {
RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART,
RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART,
RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART,
RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY,
RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY,
}, },
{ {
// Vanilla Pots // Vanilla Pots
@ -673,6 +679,9 @@ Dungeons::Dungeons() {
RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY,
RC_WATER_TEMPLE_MQ_GS_RIVER, RC_WATER_TEMPLE_MQ_GS_RIVER,
RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH,
RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY,
RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY,
RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY,
}, },
{ {
// Vanilla Pots // Vanilla Pots
@ -769,6 +778,8 @@ Dungeons::Dungeons() {
RC_SPIRIT_TEMPLE_GS_METAL_FENCE, RC_SPIRIT_TEMPLE_GS_METAL_FENCE,
RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART,
RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART,
RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY,
RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY,
}, },
{ {
// MQ Locations // MQ Locations
@ -799,6 +810,7 @@ Dungeons::Dungeons() {
RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM,
RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART,
RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART,
RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY,
}, },
{ {
// Vanilla Pots // Vanilla Pots
@ -895,6 +907,9 @@ Dungeons::Dungeons() {
RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART,
RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART,
RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART,
RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY,
RC_SHADOW_TEMPLE_PIT_STORM_FAIRY,
RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY,
}, },
{ {
// MQ Locations // MQ Locations
@ -930,6 +945,9 @@ Dungeons::Dungeons() {
RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART,
RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART,
RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART,
RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY,
RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY,
RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY,
}, },
{ {
// Vanilla Pots // Vanilla Pots
@ -1010,6 +1028,7 @@ Dungeons::Dungeons() {
RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE,
RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART,
RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART,
RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY,
}, },
{ {
// MQ Locations // MQ Locations
@ -1028,6 +1047,8 @@ Dungeons::Dungeons() {
RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART,
RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART,
RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART,
RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY,
RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY,
}, },
{ {
// Vanilla Pots // Vanilla Pots
@ -1080,6 +1101,7 @@ Dungeons::Dungeons() {
RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1,
RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2,
RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3,
RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY,
}, },
{ {
// MQ Locations // MQ Locations
@ -1150,6 +1172,7 @@ Dungeons::Dungeons() {
RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY,
RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART,
RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART,
RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY,
}, },
{ {
// MQ Locations // MQ Locations
@ -1208,6 +1231,15 @@ Dungeons::Dungeons() {
RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3,
RC_GANONS_CASTLE_FIRE_TRIAL_HEART, RC_GANONS_CASTLE_FIRE_TRIAL_HEART,
RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART,
RC_GANONS_CASTLE_SCRUBS_FAIRY_1,
RC_GANONS_CASTLE_SCRUBS_FAIRY_2,
RC_GANONS_CASTLE_SCRUBS_FAIRY_3,
RC_GANONS_CASTLE_SCRUBS_FAIRY_4,
RC_GANONS_CASTLE_SCRUBS_FAIRY_5,
RC_GANONS_CASTLE_SCRUBS_FAIRY_6,
RC_GANONS_CASTLE_SCRUBS_FAIRY_7,
RC_GANONS_CASTLE_SCRUBS_FAIRY_8,
RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY,
}, },
{ {
// MQ Locations // MQ Locations
@ -1232,6 +1264,14 @@ Dungeons::Dungeons() {
RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART,
RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART,
RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8,
}, },
{ {
// Vanilla Pots // Vanilla Pots

View File

@ -1040,8 +1040,8 @@ int EntranceShuffler::ShuffleAllEntrances() {
{ EntranceType::GrottoGrave, RR_LW_NEAR_SHORTCUTS_GROTTO, RR_THE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) } }, { EntranceType::GrottoGrave, RR_LW_NEAR_SHORTCUTS_GROTTO, RR_THE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_KOKIRI_FOREST, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) }, { { EntranceType::GrottoGrave, RR_KOKIRI_FOREST, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KOKIRI_FOREST, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } }, { EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KOKIRI_FOREST, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_ZORAS_DOMAIN, RR_ZD_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET) }, { { EntranceType::GrottoGrave, RR_ZORAS_DOMAIN_ISLAND, RR_ZD_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_ZD_STORMS_GROTTO, RR_ZORAS_DOMAIN, ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET) } }, { EntranceType::GrottoGrave, RR_ZD_STORMS_GROTTO, RR_ZORAS_DOMAIN_ISLAND, ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_GERUDO_FORTRESS, RR_GF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET) }, { { EntranceType::GrottoGrave, RR_GERUDO_FORTRESS, RR_GF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_GF_STORMS_GROTTO, RR_GERUDO_FORTRESS, ENTRANCE_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET) } }, { EntranceType::GrottoGrave, RR_GF_STORMS_GROTTO, RR_GERUDO_FORTRESS, ENTRANCE_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_GV_FORTRESS_SIDE, RR_GV_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET) }, { { EntranceType::GrottoGrave, RR_GV_FORTRESS_SIDE, RR_GV_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET) },

View File

@ -14,6 +14,7 @@
#include "soh/ImGuiUtils.h" #include "soh/ImGuiUtils.h"
#include "soh/Notification/Notification.h" #include "soh/Notification/Notification.h"
#include "soh/SaveManager.h" #include "soh/SaveManager.h"
#include "soh/Enhancements/randomizer/ShuffleFairies.h"
extern "C" { extern "C" {
#include "macros.h" #include "macros.h"
@ -2420,6 +2421,8 @@ void RandomizerRegisterHooks() {
shufflePotsOnActorInitHook = 0; shufflePotsOnActorInitHook = 0;
shufflePotsOnVanillaBehaviorHook = 0; shufflePotsOnVanillaBehaviorHook = 0;
ShuffleFairies_UnregisterHooks();
if (!IS_RANDO) return; if (!IS_RANDO) return;
// ENTRTODO: Move all entrance rando handling to a dedicated file // ENTRTODO: Move all entrance rando handling to a dedicated file
@ -2462,5 +2465,9 @@ void RandomizerRegisterHooks() {
shufflePotsOnActorInitHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>(ObjTsubo_RandomizerInit); shufflePotsOnActorInitHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>(ObjTsubo_RandomizerInit);
shufflePotsOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(ShufflePots_OnVanillaBehaviorHandler); shufflePotsOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(ShufflePots_OnVanillaBehaviorHandler);
} }
if (RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES)) {
ShuffleFairies_RegisterHooks();
}
}); });
} }

View File

@ -381,3 +381,10 @@ Rando::Location Rando::Location::Pot(RandomizerCheck rc, RandomizerCheckQuest qu
Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) { Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) {
return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS, scene_, actorParams_, std::move(shortName_), RHT_NONE, RG_NONE, false }; return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS, scene_, actorParams_, std::move(shortName_), RHT_NONE, RG_NONE, false };
} }
Rando::Location Rando::Location::Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_,
RandomizerCheckArea area_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) {
return {rc, quest_, RCTYPE_FAIRY, area_, ACTOR_EN_ELF, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, RG_NONE, false, collectionCheck};
}

View File

@ -182,6 +182,8 @@ class Location {
static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_); static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_);
static Location Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck);
static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, std::string&& shortName_);
static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_);

File diff suppressed because it is too large Load Diff

View File

@ -64,6 +64,8 @@ namespace Rando {
return ScarecrowsSong() && CanUse(RG_HOOKSHOT); return ScarecrowsSong() && CanUse(RG_HOOKSHOT);
case RG_DISTANT_SCARECROW: case RG_DISTANT_SCARECROW:
return ScarecrowsSong() && CanUse(RG_LONGSHOT); return ScarecrowsSong() && CanUse(RG_LONGSHOT);
case RG_MAGIC_BEAN:
return GetAmmo(ITEM_BEAN) > 0;
case RG_KOKIRI_SWORD: case RG_KOKIRI_SWORD:
case RG_DEKU_SHIELD: case RG_DEKU_SHIELD:
case RG_GORON_TUNIC: case RG_GORON_TUNIC:
@ -304,6 +306,8 @@ namespace Rando {
case RG_WEIRD_EGG: case RG_WEIRD_EGG:
case RG_RUTOS_LETTER: case RG_RUTOS_LETTER:
return IsChild; return IsChild;
case RG_MAGIC_BEAN:
return IsChild;
// Songs // Songs
case RG_ZELDAS_LULLABY: case RG_ZELDAS_LULLABY:

View File

@ -446,6 +446,8 @@ void Settings::CreateOptionDescriptions() {
"Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n" "Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n"
"\n" "\n"
"All Items - Shuffle all freestanding rupees & hearts."; "All Items - Shuffle all freestanding rupees & hearts.";
mOptionDescriptions[RSK_SHUFFLE_FAIRIES] =
"Shuffle fairy locations.";
mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] = mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] =
"Shuffles the location of Spiritual Stones and medallions.\n" "Shuffles the location of Spiritual Stones and medallions.\n"
"\n" "\n"

View File

@ -269,6 +269,7 @@ typedef enum {
RCTYPE_BEEHIVE, // Beehives RCTYPE_BEEHIVE, // Beehives
RCTYPE_FISH, // Fishes RCTYPE_FISH, // Fishes
RCTYPE_FREESTANDING, // Freestanding rupees and hearts RCTYPE_FREESTANDING, // Freestanding rupees and hearts
RCTYPE_FAIRY, // Fairies
} RandomizerCheckType; } RandomizerCheckType;
typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest; typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest;
@ -359,6 +360,7 @@ typedef enum {
RR_HF_OPEN_GROTTO, RR_HF_OPEN_GROTTO,
RR_HF_INSIDE_FENCE_GROTTO, RR_HF_INSIDE_FENCE_GROTTO,
RR_HF_COW_GROTTO, RR_HF_COW_GROTTO,
RR_HF_COW_GROTTO_BEHIND_WEBS,
RR_HF_NEAR_MARKET_GROTTO, RR_HF_NEAR_MARKET_GROTTO,
RR_HF_FAIRY_GROTTO, RR_HF_FAIRY_GROTTO,
RR_HF_NEAR_KAK_GROTTO, RR_HF_NEAR_KAK_GROTTO,
@ -385,6 +387,7 @@ typedef enum {
RR_HAUNTED_WASTELAND, RR_HAUNTED_WASTELAND,
RR_WASTELAND_NEAR_COLOSSUS, RR_WASTELAND_NEAR_COLOSSUS,
RR_DESERT_COLOSSUS, RR_DESERT_COLOSSUS,
RR_DESERT_COLOSSUS_OASIS,
RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE,
RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN,
RR_COLOSSUS_GROTTO, RR_COLOSSUS_GROTTO,
@ -410,6 +413,7 @@ typedef enum {
RR_HC_GARDEN, RR_HC_GARDEN,
RR_HC_GREAT_FAIRY_FOUNTAIN, RR_HC_GREAT_FAIRY_FOUNTAIN,
RR_HC_STORMS_GROTTO, RR_HC_STORMS_GROTTO,
RR_HC_STORMS_GROTTO_BEHIND_WALLS,
RR_GANONS_CASTLE_GROUNDS, RR_GANONS_CASTLE_GROUNDS,
RR_OGC_GREAT_FAIRY_FOUNTAIN, RR_OGC_GREAT_FAIRY_FOUNTAIN,
RR_GANONS_CASTLE_LEDGE, RR_GANONS_CASTLE_LEDGE,
@ -437,6 +441,7 @@ typedef enum {
RR_GRAVEYARD_DAMPES_GRAVE, RR_GRAVEYARD_DAMPES_GRAVE,
RR_GRAVEYARD_DAMPES_HOUSE, RR_GRAVEYARD_DAMPES_HOUSE,
RR_GRAVEYARD_SHIELD_GRAVE, RR_GRAVEYARD_SHIELD_GRAVE,
RR_GRAVEYARD_SHIELD_GRAVE_BACK,
RR_GRAVEYARD_COMPOSERS_GRAVE, RR_GRAVEYARD_COMPOSERS_GRAVE,
RR_GRAVEYARD_HEART_PIECE_GRAVE, RR_GRAVEYARD_HEART_PIECE_GRAVE,
RR_GRAVEYARD_WARP_PAD_REGION, RR_GRAVEYARD_WARP_PAD_REGION,
@ -447,6 +452,7 @@ typedef enum {
RR_DMT_COW_GROTTO, RR_DMT_COW_GROTTO,
RR_DMT_STORMS_GROTTO, RR_DMT_STORMS_GROTTO,
RR_GORON_CITY, RR_GORON_CITY,
RR_GC_MEDIGORON,
RR_GC_WOODS_WARP, RR_GC_WOODS_WARP,
RR_GC_DARUNIAS_CHAMBER, RR_GC_DARUNIAS_CHAMBER,
RR_GC_GROTTO_PLATFORM, RR_GC_GROTTO_PLATFORM,
@ -470,6 +476,7 @@ typedef enum {
RR_ZR_FAIRY_GROTTO, RR_ZR_FAIRY_GROTTO,
RR_ZR_STORMS_GROTTO, RR_ZR_STORMS_GROTTO,
RR_ZORAS_DOMAIN, RR_ZORAS_DOMAIN,
RR_ZORAS_DOMAIN_ISLAND,
RR_ZD_BEHIND_KING_ZORA, RR_ZD_BEHIND_KING_ZORA,
RR_ZD_SHOP, RR_ZD_SHOP,
RR_ZD_STORMS_GROTTO, RR_ZD_STORMS_GROTTO,
@ -552,6 +559,7 @@ typedef enum {
RR_DODONGOS_CAVERN_MQ_BEGINNING, RR_DODONGOS_CAVERN_MQ_BEGINNING,
RR_DODONGOS_CAVERN_MQ_LOBBY, RR_DODONGOS_CAVERN_MQ_LOBBY,
RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE,
RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE,
RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL, RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL,
RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER,
@ -2603,6 +2611,216 @@ typedef enum {
RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART,
RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART,
RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART,
RC_SFM_FAIRY_GROTTO_FAIRY_1,
RC_SFM_FAIRY_GROTTO_FAIRY_2,
RC_SFM_FAIRY_GROTTO_FAIRY_3,
RC_SFM_FAIRY_GROTTO_FAIRY_4,
RC_SFM_FAIRY_GROTTO_FAIRY_5,
RC_SFM_FAIRY_GROTTO_FAIRY_6,
RC_SFM_FAIRY_GROTTO_FAIRY_7,
RC_SFM_FAIRY_GROTTO_FAIRY_8,
RC_ZR_FAIRY_GROTTO_FAIRY_1,
RC_ZR_FAIRY_GROTTO_FAIRY_2,
RC_ZR_FAIRY_GROTTO_FAIRY_3,
RC_ZR_FAIRY_GROTTO_FAIRY_4,
RC_ZR_FAIRY_GROTTO_FAIRY_5,
RC_ZR_FAIRY_GROTTO_FAIRY_6,
RC_ZR_FAIRY_GROTTO_FAIRY_7,
RC_ZR_FAIRY_GROTTO_FAIRY_8,
RC_HF_FAIRY_GROTTO_FAIRY_1,
RC_HF_FAIRY_GROTTO_FAIRY_2,
RC_HF_FAIRY_GROTTO_FAIRY_3,
RC_HF_FAIRY_GROTTO_FAIRY_4,
RC_HF_FAIRY_GROTTO_FAIRY_5,
RC_HF_FAIRY_GROTTO_FAIRY_6,
RC_HF_FAIRY_GROTTO_FAIRY_7,
RC_HF_FAIRY_GROTTO_FAIRY_8,
RC_ZD_FAIRY_GROTTO_FAIRY_1,
RC_ZD_FAIRY_GROTTO_FAIRY_2,
RC_ZD_FAIRY_GROTTO_FAIRY_3,
RC_ZD_FAIRY_GROTTO_FAIRY_4,
RC_ZD_FAIRY_GROTTO_FAIRY_5,
RC_ZD_FAIRY_GROTTO_FAIRY_6,
RC_ZD_FAIRY_GROTTO_FAIRY_7,
RC_ZD_FAIRY_GROTTO_FAIRY_8,
RC_GF_FAIRY_GROTTO_FAIRY_1,
RC_GF_FAIRY_GROTTO_FAIRY_2,
RC_GF_FAIRY_GROTTO_FAIRY_3,
RC_GF_FAIRY_GROTTO_FAIRY_4,
RC_GF_FAIRY_GROTTO_FAIRY_5,
RC_GF_FAIRY_GROTTO_FAIRY_6,
RC_GF_FAIRY_GROTTO_FAIRY_7,
RC_GF_FAIRY_GROTTO_FAIRY_8,
RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1,
RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2,
RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3,
RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4,
RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5,
RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6,
RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7,
RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8,
RC_GANONS_CASTLE_SCRUBS_FAIRY_1,
RC_GANONS_CASTLE_SCRUBS_FAIRY_2,
RC_GANONS_CASTLE_SCRUBS_FAIRY_3,
RC_GANONS_CASTLE_SCRUBS_FAIRY_4,
RC_GANONS_CASTLE_SCRUBS_FAIRY_5,
RC_GANONS_CASTLE_SCRUBS_FAIRY_6,
RC_GANONS_CASTLE_SCRUBS_FAIRY_7,
RC_GANONS_CASTLE_SCRUBS_FAIRY_8,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7,
RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8,
RC_COLOSSUS_OASIS_FAIRY_1,
RC_COLOSSUS_OASIS_FAIRY_2,
RC_COLOSSUS_OASIS_FAIRY_3,
RC_COLOSSUS_OASIS_FAIRY_4,
RC_COLOSSUS_OASIS_FAIRY_5,
RC_COLOSSUS_OASIS_FAIRY_6,
RC_COLOSSUS_OASIS_FAIRY_7,
RC_COLOSSUS_OASIS_FAIRY_8,
RC_ZR_BEAN_SPROUT_FAIRY_1,
RC_ZR_BEAN_SPROUT_FAIRY_2,
RC_ZR_BEAN_SPROUT_FAIRY_3,
RC_KF_BEAN_SPROUT_FAIRY_1,
RC_KF_BEAN_SPROUT_FAIRY_2,
RC_KF_BEAN_SPROUT_FAIRY_3,
RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1,
RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2,
RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3,
RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1,
RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2,
RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3,
RC_LH_BEAN_SPROUT_FAIRY_1,
RC_LH_BEAN_SPROUT_FAIRY_2,
RC_LH_BEAN_SPROUT_FAIRY_3,
RC_GV_BEAN_SPROUT_FAIRY_1,
RC_GV_BEAN_SPROUT_FAIRY_2,
RC_GV_BEAN_SPROUT_FAIRY_3,
RC_COLOSSUS_BEAN_SPROUT_FAIRY_1,
RC_COLOSSUS_BEAN_SPROUT_FAIRY_2,
RC_COLOSSUS_BEAN_SPROUT_FAIRY_3,
RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1,
RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2,
RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3,
RC_DMC_BEAN_SPROUT_FAIRY_1,
RC_DMC_BEAN_SPROUT_FAIRY_2,
RC_DMC_BEAN_SPROUT_FAIRY_3,
RC_DMT_BEAN_SPROUT_FAIRY_1,
RC_DMT_BEAN_SPROUT_FAIRY_2,
RC_DMT_BEAN_SPROUT_FAIRY_3,
RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY,
RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG,
RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY,
RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG,
RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY,
RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG,
RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY,
RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG,
RC_DMC_GOSSIP_STONE_FAIRY,
RC_DMC_GOSSIP_STONE_FAIRY_BIG,
RC_DMT_GOSSIP_STONE_FAIRY,
RC_DMT_GOSSIP_STONE_FAIRY_BIG,
RC_COLOSSUS_GOSSIP_STONE_FAIRY,
RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG,
RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY,
RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG,
RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY,
RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG,
RC_GV_GOSSIP_STONE_FAIRY,
RC_GV_GOSSIP_STONE_FAIRY_BIG,
RC_GC_MAZE_GOSSIP_STONE_FAIRY,
RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG,
RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY,
RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG,
RC_GRAVEYARD_GOSSIP_STONE_FAIRY,
RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG,
RC_HC_MALON_GOSSIP_STONE_FAIRY,
RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG,
RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY,
RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG,
RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY,
RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG,
RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY,
RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG,
RC_KF_GOSSIP_STONE_FAIRY,
RC_KF_GOSSIP_STONE_FAIRY_BIG,
RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_LH_LAB_GOSSIP_STONE_FAIRY,
RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG,
RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY,
RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG,
RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY,
RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG,
RC_LW_GOSSIP_STONE_FAIRY,
RC_LW_GOSSIP_STONE_FAIRY_BIG,
RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY,
RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG,
RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY,
RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG,
RC_SFM_SARIA_GOSSIP_STONE_FAIRY,
RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG,
RC_ZD_GOSSIP_STONE_FAIRY,
RC_ZD_GOSSIP_STONE_FAIRY_BIG,
RC_ZF_FAIRY_GOSSIP_STONE_FAIRY,
RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG,
RC_ZF_JABU_GOSSIP_STONE_FAIRY,
RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG,
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY,
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG,
RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY,
RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG,
RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY,
RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY,
RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY,
RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY,
RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY,
RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RC_LH_ISLAND_SUN_FAIRY,
RC_HF_POND_STORMS_FAIRY,
RC_HF_FENCE_GROTTO_STORMS_FAIRY,
RC_DMT_FLAG_SUN_FAIRY,
RC_LW_SHORTCUT_STORMS_FAIRY,
RC_GF_KITCHEN_SUN_FAIRY,
RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY,
RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY,
RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY,
RC_SHADOW_TEMPLE_PIT_STORM_FAIRY,
RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY,
RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY,
RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY,
RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY,
RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY,
RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY,
RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY,
RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY,
RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY,
RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY,
RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY,
RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY,
RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY,
RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY,
RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY,
RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY,
RC_MAX RC_MAX
} RandomizerCheck; } RandomizerCheck;
@ -4672,6 +4890,118 @@ typedef enum {
RHT_ICE_CAVERN_RUPEE, RHT_ICE_CAVERN_RUPEE,
RHT_GERUDO_TRAINING_GROUNDS_HEART, RHT_GERUDO_TRAINING_GROUNDS_HEART,
RHT_GANONS_CASTLE_HEART, RHT_GANONS_CASTLE_HEART,
// Fairy Shuffle
RHT_SFM_FAIRY_GROTTO_FAIRY,
RHT_ZR_FAIRY_GROTTO_FAIRY,
RHT_HF_FAIRY_GROTTO_FAIRY,
RHT_ZD_FAIRY_GROTTO_FAIRY,
RHT_GF_FAIRY_GROTTO_FAIRY,
RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY,
RHT_GANONS_CASTLE_SCRUBS_FAIRY,
RHT_COLOSSUS_OASIS_FAIRY,
RHT_ZR_BEAN_SPROUT_FAIRY,
RHT_KF_BEAN_SPROUT_FAIRY,
RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY,
RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY,
RHT_LH_BEAN_SPROUT_FAIRY,
RHT_GV_BEAN_SPROUT_FAIRY,
RHT_COLOSSUS_BEAN_SPROUT_FAIRY,
RHT_GRAVEYARD_BEAN_SPROUT_FAIRY,
RHT_DMC_BEAN_SPROUT_FAIRY,
RHT_DMT_BEAN_SPROUT_FAIRY,
RHT_TOT_GOSSIP_STONE_FAIRY,
RHT_TOT_GOSSIP_STONE_FAIRY_BIG,
RHT_DMC_GOSSIP_STONE_FAIRY,
RHT_DMC_GOSSIP_STONE_FAIRY_BIG,
RHT_DMT_GOSSIP_STONE_FAIRY,
RHT_DMT_GOSSIP_STONE_FAIRY_BIG,
RHT_COLOSSUS_GOSSIP_STONE_FAIRY,
RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG,
RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY,
RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG,
RHT_GV_GOSSIP_STONE_FAIRY,
RHT_GV_GOSSIP_STONE_FAIRY_BIG,
RHT_GC_MAZE_GOSSIP_STONE_FAIRY,
RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG,
RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY,
RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG,
RHT_GRAVEYARD_GOSSIP_STONE_FAIRY,
RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG,
RHT_HC_MALON_GOSSIP_STONE_FAIRY,
RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG,
RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY,
RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG,
RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY,
RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG,
RHT_KF_GOSSIP_STONE_FAIRY,
RHT_KF_GOSSIP_STONE_FAIRY_BIG,
RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_LH_LAB_GOSSIP_STONE_FAIRY,
RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG,
RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY,
RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG,
RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY,
RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG,
RHT_LW_GOSSIP_STONE_FAIRY,
RHT_LW_GOSSIP_STONE_FAIRY_BIG,
RHT_SFM_MAZE_GOSSIP_STONE_FAIRY,
RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG,
RHT_SFM_SARIA_GOSSIP_STONE_FAIRY,
RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG,
RHT_ZD_GOSSIP_STONE_FAIRY,
RHT_ZD_GOSSIP_STONE_FAIRY_BIG,
RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY,
RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG,
RHT_ZF_JABU_GOSSIP_STONE_FAIRY,
RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG,
RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY,
RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG,
RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY,
RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG,
RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY,
RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY,
RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY,
RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY,
RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY,
RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RHT_LH_ISLAND_SUN_FAIRY,
RHT_HF_POND_STORMS_FAIRY,
RHT_HF_FENCE_GROTTO_STORMS_FAIRY,
RHT_DMT_FLAG_SUN_FAIRY,
RHT_LW_SHORTCUT_STORMS_FAIRY,
RHT_GF_KITCHEN_SUN_FAIRY,
RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY,
RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY,
RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY,
RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY,
RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY,
RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY,
RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY,
RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY,
RHT_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY,
RHT_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY,
RHT_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY,
RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY,
RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY,
RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY,
RHT_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY,
RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY,
RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY,
// MAX // MAX
RHT_MAX RHT_MAX
} RandomizerHintTextKey; } RandomizerHintTextKey;
@ -4962,6 +5292,7 @@ typedef enum {
RSK_SHUFFLE_DEKU_STICK_BAG, RSK_SHUFFLE_DEKU_STICK_BAG,
RSK_SHUFFLE_DEKU_NUT_BAG, RSK_SHUFFLE_DEKU_NUT_BAG,
RSK_SHUFFLE_FREESTANDING, RSK_SHUFFLE_FREESTANDING,
RSK_SHUFFLE_FAIRIES,
RSK_MAX RSK_MAX
} RandomizerSettingKey; } RandomizerSettingKey;

View File

@ -185,6 +185,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), RO_GENERIC_NO)) && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_FROG_SONG || (location.GetRCType() != RCTYPE_FROG_SONG ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), RO_GENERIC_NO)) && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_FAIRY ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFairies"), RO_GENERIC_NO)) &&
((location.GetRCType() != RCTYPE_MAP && location.GetRCType() != RCTYPE_COMPASS) || ((location.GetRCType() != RCTYPE_MAP && location.GetRCType() != RCTYPE_COMPASS) ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != CVarGetInteger(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) !=
RO_DUNGEON_ITEM_LOC_VANILLA) && RO_DUNGEON_ITEM_LOC_VANILLA) &&

View File

@ -59,6 +59,7 @@ bool showGerudoCard;
bool showOverworldPots; bool showOverworldPots;
bool showDungeonPots; bool showDungeonPots;
bool showFrogSongRupees; bool showFrogSongRupees;
bool showFairies;
bool showStartingMapsCompasses; bool showStartingMapsCompasses;
bool showKeysanity; bool showKeysanity;
bool showGerudoFortressKeys; bool showGerudoFortressKeys;
@ -1164,6 +1165,9 @@ void LoadSettings() {
showFrogSongRupees = IS_RANDO ? showFrogSongRupees = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES
: false; : false;
showFairies = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FAIRIES) == RO_GENERIC_YES
: false;
showStartingMapsCompasses = IS_RANDO ? showStartingMapsCompasses = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAPANDCOMPASS) != RO_DUNGEON_ITEM_LOC_VANILLA OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAPANDCOMPASS) != RO_DUNGEON_ITEM_LOC_VANILLA
: false; : false;
@ -1335,6 +1339,7 @@ bool IsCheckShuffled(RandomizerCheck rc) {
(rc != RC_HC_MALON_EGG || showWeirdEgg) && (rc != RC_HC_MALON_EGG || showWeirdEgg) &&
(loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) &&
((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) && ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) &&
(loc->GetRCType() != RCTYPE_FAIRY || showFairies) &&
(loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) &&
(loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) &&
(loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) &&

View File

@ -337,3 +337,14 @@ s16 Grotto_GetRenamedGrottoIndexFromOriginal(s8 content, s8 scene) {
return ENTRANCE_GROTTO_LOAD_START; return ENTRANCE_GROTTO_LOAD_START;
} }
s8 Grotto_CurrentGrotto() {
if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) {
return grottoId;
} else {
s16 entrance = gSaveContext.respawn[RESPAWN_MODE_RETURN].entranceIndex;
s8 scene = gEntranceTable[entrance].scene;
s8 data = gSaveContext.respawn[RESPAWN_MODE_RETURN].data;
return Grotto_GetRenamedGrottoIndexFromOriginal(data, scene) & 0xFF;
}
}

View File

@ -22,6 +22,9 @@ typedef struct {
Vec3f pos; Vec3f pos;
} GrottoReturnInfo; } GrottoReturnInfo;
#ifdef __cplusplus
extern "C" {
#endif
void Grotto_InitExitAndLoadLists(void); void Grotto_InitExitAndLoadLists(void);
void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex); void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex);
void Grotto_SetLoadOverride(s16 originalIndex, s16 overrideIndex); void Grotto_SetLoadOverride(s16 originalIndex, s16 overrideIndex);
@ -33,5 +36,9 @@ void Grotto_ForceGrottoReturn(void);
void Grotto_ForceRegularVoidOut(void); void Grotto_ForceRegularVoidOut(void);
void Grotto_SanitizeEntranceType(void); void Grotto_SanitizeEntranceType(void);
s16 Grotto_GetRenamedGrottoIndexFromOriginal(s8 content, s8 scene); s16 Grotto_GetRenamedGrottoIndexFromOriginal(s8 content, s8 scene);
s8 Grotto_CurrentGrotto();
#ifdef __cplusplus
};
#endif
#endif //_RANDO_GROTTO_H_ #endif //_RANDO_GROTTO_H_

View File

@ -1032,6 +1032,219 @@ typedef enum {
RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART,
RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART,
RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART,
RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1,
RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2,
RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3,
RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4,
RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5,
RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6,
RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7,
RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8,
RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1,
RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2,
RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3,
RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4,
RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5,
RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6,
RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7,
RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8,
RAND_INF_HF_FAIRY_GROTTO_FAIRY_1,
RAND_INF_HF_FAIRY_GROTTO_FAIRY_2,
RAND_INF_HF_FAIRY_GROTTO_FAIRY_3,
RAND_INF_HF_FAIRY_GROTTO_FAIRY_4,
RAND_INF_HF_FAIRY_GROTTO_FAIRY_5,
RAND_INF_HF_FAIRY_GROTTO_FAIRY_6,
RAND_INF_HF_FAIRY_GROTTO_FAIRY_7,
RAND_INF_HF_FAIRY_GROTTO_FAIRY_8,
RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1,
RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2,
RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3,
RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4,
RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5,
RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6,
RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7,
RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8,
RAND_INF_GF_FAIRY_GROTTO_FAIRY_1,
RAND_INF_GF_FAIRY_GROTTO_FAIRY_2,
RAND_INF_GF_FAIRY_GROTTO_FAIRY_3,
RAND_INF_GF_FAIRY_GROTTO_FAIRY_4,
RAND_INF_GF_FAIRY_GROTTO_FAIRY_5,
RAND_INF_GF_FAIRY_GROTTO_FAIRY_6,
RAND_INF_GF_FAIRY_GROTTO_FAIRY_7,
RAND_INF_GF_FAIRY_GROTTO_FAIRY_8,
RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1,
RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2,
RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3,
RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4,
RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5,
RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6,
RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7,
RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8,
RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1,
RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2,
RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3,
RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4,
RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5,
RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6,
RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7,
RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8,
RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1,
RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2,
RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3,
RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4,
RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5,
RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6,
RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7,
RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8,
RAND_INF_COLOSSUS_OASIS_FAIRY_1,
RAND_INF_COLOSSUS_OASIS_FAIRY_2,
RAND_INF_COLOSSUS_OASIS_FAIRY_3,
RAND_INF_COLOSSUS_OASIS_FAIRY_4,
RAND_INF_COLOSSUS_OASIS_FAIRY_5,
RAND_INF_COLOSSUS_OASIS_FAIRY_6,
RAND_INF_COLOSSUS_OASIS_FAIRY_7,
RAND_INF_COLOSSUS_OASIS_FAIRY_8,
RAND_INF_ZR_BEAN_SPROUT_FAIRY_1,
RAND_INF_ZR_BEAN_SPROUT_FAIRY_2,
RAND_INF_ZR_BEAN_SPROUT_FAIRY_3,
RAND_INF_KF_BEAN_SPROUT_FAIRY_1,
RAND_INF_KF_BEAN_SPROUT_FAIRY_2,
RAND_INF_KF_BEAN_SPROUT_FAIRY_3,
RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1,
RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2,
RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3,
RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1,
RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2,
RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3,
RAND_INF_LH_BEAN_SPROUT_FAIRY_1,
RAND_INF_LH_BEAN_SPROUT_FAIRY_2,
RAND_INF_LH_BEAN_SPROUT_FAIRY_3,
RAND_INF_GV_BEAN_SPROUT_FAIRY_1,
RAND_INF_GV_BEAN_SPROUT_FAIRY_2,
RAND_INF_GV_BEAN_SPROUT_FAIRY_3,
RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1,
RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2,
RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3,
RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1,
RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2,
RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3,
RAND_INF_DMC_BEAN_SPROUT_FAIRY_1,
RAND_INF_DMC_BEAN_SPROUT_FAIRY_2,
RAND_INF_DMC_BEAN_SPROUT_FAIRY_3,
RAND_INF_DMT_BEAN_SPROUT_FAIRY_1,
RAND_INF_DMT_BEAN_SPROUT_FAIRY_2,
RAND_INF_DMT_BEAN_SPROUT_FAIRY_3,
RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY,
RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY,
RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY,
RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY,
RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_DMC_GOSSIP_STONE_FAIRY,
RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_DMT_GOSSIP_STONE_FAIRY,
RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY,
RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY,
RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY,
RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_GV_GOSSIP_STONE_FAIRY,
RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY,
RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY,
RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY,
RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY,
RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY,
RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY,
RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY,
RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_KF_GOSSIP_STONE_FAIRY,
RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY,
RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY,
RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY,
RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_LW_GOSSIP_STONE_FAIRY,
RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY,
RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY,
RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY,
RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_ZD_GOSSIP_STONE_FAIRY,
RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY,
RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY,
RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY,
RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY,
RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY,
RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG,
RAND_INF_LH_ISLAND_SUN_FAIRY,
RAND_INF_HF_POND_STORMS_FAIRY,
RAND_INF_DMT_FLAG_SUN_FAIRY,
RAND_INF_LW_SHORTCUT_STORMS_FAIRY,
RAND_INF_GF_KITCHEN_SUN_FAIRY,
RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY,
RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY,
RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY,
RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY,
RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY,
RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY,
RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY,
RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY,
RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY,
RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY,
RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY,
RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY,
RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY,
RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY,
RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY,
RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY,
RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY,
RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY,
RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY,
RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY,
// If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16)
RAND_INF_MAX, RAND_INF_MAX,

View File

@ -225,6 +225,7 @@ void Settings::CreateOptions() {
mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF); mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF);
mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE); mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE);
mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]); mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]);
mOptions[RSK_SHUFFLE_FAIRIES] = Option::Bool("Shuffle Fairies", CVAR_RANDOMIZER_SETTING("ShuffleFairies"), mOptionDescriptions[RSK_SHUFFLE_FAIRIES]);
mOptions[RSK_SHUFFLE_MAPANDCOMPASS] = Option::U8("Maps/Compasses", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); mOptions[RSK_SHUFFLE_MAPANDCOMPASS] = Option::U8("Maps/Compasses", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
mOptions[RSK_KEYSANITY] = Option::U8("Small Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); mOptions[RSK_KEYSANITY] = Option::U8("Small Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
mOptions[RSK_GERUDO_KEYS] = Option::U8("Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WidgetType::Combobox, RO_GERUDO_KEYS_VANILLA); mOptions[RSK_GERUDO_KEYS] = Option::U8("Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WidgetType::Combobox, RO_GERUDO_KEYS_VANILLA);
@ -835,6 +836,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_100_GS_REWARD],
&mOptions[RSK_SHUFFLE_BOSS_SOULS], &mOptions[RSK_SHUFFLE_BOSS_SOULS],
&mOptions[RSK_SHUFFLE_FAIRIES],
}, WidgetContainerType::COLUMN); }, WidgetContainerType::COLUMN);
mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Dungeon Items", { mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Dungeon Items", {
&mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS],
@ -1083,6 +1085,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG],
&mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG],
&mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_FREESTANDING],
&mOptions[RSK_SHUFFLE_FAIRIES],
}); });
mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", {
&mOptions[RSK_SHUFFLE_MAPANDCOMPASS], &mOptions[RSK_SHUFFLE_MAPANDCOMPASS],
@ -1283,6 +1286,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_100_GS_REWARD],
&mOptions[RSK_SHUFFLE_FAIRIES],
&mOptions[RSK_GOSSIP_STONE_HINTS], &mOptions[RSK_GOSSIP_STONE_HINTS],
}; };
} }

View File

@ -47,6 +47,7 @@ class StaticData {
static std::vector<RandomizerCheck> GetPondFishLocations(); static std::vector<RandomizerCheck> GetPondFishLocations();
static std::vector<RandomizerCheck> GetOverworldFishLocations(); static std::vector<RandomizerCheck> GetOverworldFishLocations();
static std::vector<RandomizerCheck> GetOverworldPotLocations(); static std::vector<RandomizerCheck> GetOverworldPotLocations();
static std::vector<RandomizerCheck> GetOverworldFairyLocations();
static std::array<std::pair<RandomizerCheck, RandomizerCheck>, 17> randomizerFishingPondFish; static std::array<std::pair<RandomizerCheck, RandomizerCheck>, 17> randomizerFishingPondFish;
static std::unordered_map<int8_t, RandomizerCheck> randomizerGrottoFishMap; static std::unordered_map<int8_t, RandomizerCheck> randomizerGrottoFishMap;
static std::vector<RandomizerHint> oldVerHintOrder; static std::vector<RandomizerHint> oldVerHintOrder;

View File

@ -7,6 +7,7 @@
#include "z_en_elf.h" #include "z_en_elf.h"
#include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_keep/gameplay_keep.h"
#include <assert.h> #include <assert.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA)
@ -400,9 +401,11 @@ void EnElf_Init(Actor* thisx, PlayState* play) {
EnElf_SetupAction(this, func_80A03604); EnElf_SetupAction(this, func_80A03604);
func_80A01C38(this, 8); func_80A01C38(this, 8);
for (i = 0; i < 8; i++) { if (GameInteractor_Should(VB_SPAWN_FOUNTAIN_FAIRIES, true, this)) {
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, thisx->world.pos.x, for (i = 0; i < 8; i++) {
thisx->world.pos.y - 30.0f, thisx->world.pos.z, 0, 0, 0, FAIRY_HEAL, true); Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, thisx->world.pos.x,
thisx->world.pos.y - 30.0f, thisx->world.pos.z, 0, 0, 0, FAIRY_HEAL, true);
}
} }
break; break;
default: default:
@ -632,19 +635,7 @@ void func_80A0329C(EnElf* this, PlayState* play) {
if ((heightDiff > 0.0f) && (heightDiff < 60.0f)) { if ((heightDiff > 0.0f) && (heightDiff < 60.0f)) {
if (!func_80A01F90(&this->actor.world.pos, &refActor->actor.world.pos, 10.0f)) { if (!func_80A01F90(&this->actor.world.pos, &refActor->actor.world.pos, 10.0f)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("FairyEffect"), 0) && !(this->fairyFlags & FAIRY_FLAG_BIG)) if (GameInteractor_Should(VB_FAIRY_HEAL, true, this)) {
{
if (CVarGetInteger(CVAR_ENHANCEMENT("FairyPercentRestore"), 0))
{
Health_ChangeBy(play, (gSaveContext.healthCapacity * CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 100) / 100 + 15) / 16 * 16);
}
else
{
Health_ChangeBy(play, CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 8) * 16);
}
}
else
{
Health_ChangeBy(play, 128); Health_ChangeBy(play, 128);
} }
if (this->fairyFlags & FAIRY_FLAG_BIG) { if (this->fairyFlags & FAIRY_FLAG_BIG) {

View File

@ -4,6 +4,7 @@
#include <libultraship/libultra.h> #include <libultraship/libultra.h>
#include "global.h" #include "global.h"
#include "overlays/actors/ovl_Elf_Msg/z_elf_msg.h" #include "overlays/actors/ovl_Elf_Msg/z_elf_msg.h"
#include "soh/Enhancements/randomizer/ShuffleFairies.h"
struct EnElf; struct EnElf;
@ -42,6 +43,9 @@ typedef struct EnElf {
/* 0x02C7 */ u8 unk_2C7; /* 0x02C7 */ u8 unk_2C7;
/* 0x02C8 */ EnElfUnkFunc func_2C8; /* 0x02C8 */ EnElfUnkFunc func_2C8;
/* 0x02CC */ EnElfActionFunc actionFunc; /* 0x02CC */ EnElfActionFunc actionFunc;
// #region SOH [Randomizer]
/* */ FairyIdentity sohFairyIdentity;
// #endregion
} EnElf; // size = 0x02D0 } EnElf; // size = 0x02D0
typedef enum { typedef enum {

View File

@ -8,6 +8,7 @@
#include "objects/object_gs/object_gs.h" #include "objects/object_gs/object_gs.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_FREEZE_OCARINA) #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_FREEZE_OCARINA)
@ -149,8 +150,7 @@ void func_80A4E470(EnGs* this, PlayState* play) {
func_8010BD58(play, OCARINA_ACTION_FREE_PLAY); func_8010BD58(play, OCARINA_ACTION_FREE_PLAY);
this->unk_19D |= 1; this->unk_19D |= 1;
} }
} else if (GameInteractor_Should(VB_SPAWN_GOSSIP_STONE_FAIRY, this->unk_19D & 1, this)) {
} else if (this->unk_19D & 1) {
if (play->msgCtx.ocarinaMode == OCARINA_MODE_04) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_04) {
if ((play->msgCtx.unk_E3F2 == OCARINA_SONG_SARIAS) || if ((play->msgCtx.unk_E3F2 == OCARINA_SONG_SARIAS) ||
(play->msgCtx.unk_E3F2 == OCARINA_SONG_EPONAS) || (play->msgCtx.unk_E3F2 == OCARINA_SONG_EPONAS) ||

View File

@ -8,6 +8,7 @@
#include "objects/object_mamenoki/object_mamenoki.h" #include "objects/object_mamenoki/object_mamenoki.h"
#include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_keep/gameplay_keep.h"
#include "vt.h" #include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_IGNORE_POINTLIGHTS #define FLAGS ACTOR_FLAG_IGNORE_POINTLIGHTS
@ -701,8 +702,10 @@ void ObjBean_GrowWaterPhase3(ObjBean* this, PlayState* play) {
itemDropPos.x = this->dyna.actor.world.pos.x; itemDropPos.x = this->dyna.actor.world.pos.x;
itemDropPos.y = this->dyna.actor.world.pos.y - 25.0f; itemDropPos.y = this->dyna.actor.world.pos.y - 25.0f;
itemDropPos.z = this->dyna.actor.world.pos.z; itemDropPos.z = this->dyna.actor.world.pos.z;
for (i = 0; i < 3; i++) { if (GameInteractor_Should(VB_SPAWN_BEAN_STALK_FAIRIES, true, this)) {
Item_DropCollectible(play, &itemDropPos, ITEM00_FLEXIBLE); for (i = 0; i < 3; i++) {
Item_DropCollectible(play, &itemDropPos, ITEM00_FLEXIBLE);
}
} }
this->stateFlags |= BEAN_STATE_BEEN_WATERED; this->stateFlags |= BEAN_STATE_BEEN_WATERED;
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUTTERFRY_TO_FAIRY);