From 596ea5ebbb3e5a5dfab72fb7bee6d4802d8b13d4 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 8 Jan 2024 09:25:47 -0600 Subject: [PATCH 01/52] Vanilla Behavior Overhaul Co-authored-by: jordanpg --- soh/include/functions.h | 4 + soh/include/z64actor.h | 12 +- .../Enhancements/debugger/debugSaveEditor.h | 8 +- soh/soh/Enhancements/debugger/valueViewer.cpp | 2 + soh/soh/Enhancements/enhancementTypes.h | 7 + .../game-interactor/GameInteractor.h | 294 ++- .../game-interactor/GameInteractor_Hooks.cpp | 5 + .../game-interactor/GameInteractor_Hooks.h | 1 + soh/soh/Enhancements/mods.cpp | 4 + .../Enhancements/randomizer/3drando/fill.cpp | 14 +- .../randomizer/3drando/spoiler_log.hpp | 4 - .../Enhancements/randomizer/hook_handlers.cpp | 975 ++++++++++ .../Enhancements/randomizer/hook_handlers.h | 6 + .../Enhancements/randomizer/item_location.cpp | 13 + .../Enhancements/randomizer/item_location.h | 4 + soh/soh/Enhancements/randomizer/location.h | 20 +- .../Enhancements/randomizer/location_list.cpp | 1690 ++++++++--------- .../randomizer/randomizer_check_tracker.cpp | 21 +- .../randomizer/randomizer_entrance.c | 51 +- .../Enhancements/randomizer/randomizer_inf.h | 10 + soh/soh/Enhancements/randomizer/savefile.cpp | 142 +- .../Enhancements/timesaver_hook_handlers.cpp | 788 ++++++++ .../Enhancements/timesaver_hook_handlers.h | 6 + soh/soh/OTRGlobals.cpp | 10 +- soh/soh/SaveManager.cpp | 11 + soh/soh/SohMenuBar.cpp | 114 +- soh/src/code/z_demo.c | 171 +- soh/src/code/z_en_item00.c | 120 +- soh/src/code/z_message_PAL.c | 19 +- soh/src/code/z_onepointdemo.c | 18 +- soh/src/code/z_parameter.c | 8 +- soh/src/code/z_play.c | 126 -- soh/src/code/z_player_lib.c | 4 +- .../ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c | 15 +- .../actors/ovl_Bg_Breakwall/z_bg_breakwall.c | 10 +- .../ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c | 11 +- .../actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c | 10 +- .../actors/ovl_Bg_Treemouth/z_bg_treemouth.c | 15 +- .../actors/ovl_Bg_Treemouth/z_bg_treemouth.h | 3 + .../overlays/actors/ovl_Demo_Du/z_demo_du.c | 9 +- .../actors/ovl_Demo_Effect/z_demo_effect.c | 53 +- .../overlays/actors/ovl_Demo_Im/z_demo_im.c | 44 +- .../overlays/actors/ovl_Demo_Im/z_demo_im.h | 2 + .../overlays/actors/ovl_Demo_Sa/z_demo_sa.c | 9 +- .../actors/ovl_Door_Shutter/z_door_shutter.c | 15 +- .../actors/ovl_Door_Warp1/z_door_warp1.c | 176 +- .../overlays/actors/ovl_Elf_Msg/z_elf_msg.c | 15 +- soh/src/overlays/actors/ovl_En_Box/z_en_box.c | 84 +- soh/src/overlays/actors/ovl_En_Box/z_en_box.h | 3 +- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 85 +- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h | 2 + soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c | 85 +- soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h | 5 +- soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c | 71 +- soh/src/overlays/actors/ovl_En_Du/z_en_du.c | 27 +- soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c | 50 +- soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h | 4 +- soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c | 43 +- soh/src/overlays/actors/ovl_En_Go/z_en_go.c | 219 +-- soh/src/overlays/actors/ovl_En_Go/z_en_go.h | 7 +- soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 185 +- soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h | 5 + soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c | 49 +- soh/src/overlays/actors/ovl_En_Js/z_en_js.c | 21 +- soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c | 46 +- soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h | 4 + soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 90 +- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h | 2 + soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c | 169 +- soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h | 3 + soh/src/overlays/actors/ovl_En_Md/z_en_md.c | 46 +- soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c | 54 +- soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c | 36 +- soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h | 3 + soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c | 9 +- .../actors/ovl_En_Niw_Lady/z_en_niw_lady.c | 46 +- soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c | 8 +- soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h | 2 + soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c | 5 +- soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c | 9 +- soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c | 35 +- soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h | 2 + .../actors/ovl_En_Shopnuts/z_en_shopnuts.c | 16 +- soh/src/overlays/actors/ovl_En_Si/z_en_si.c | 113 +- soh/src/overlays/actors/ovl_En_Si/z_en_si.h | 3 + soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c | 3 +- soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c | 68 +- soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h | 2 + .../overlays/actors/ovl_En_Toryo/z_en_toryo.c | 20 +- .../ovl_En_Wonder_Talk2/z_en_wonder_talk2.c | 41 +- soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c | 110 +- soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c | 5 +- soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c | 34 +- soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h | 5 + .../actors/ovl_Item_B_Heart/z_item_b_heart.c | 34 +- .../actors/ovl_Item_B_Heart/z_item_b_heart.h | 5 + .../actors/ovl_Item_Ocarina/z_item_ocarina.c | 27 +- .../actors/ovl_Obj_Switch/z_obj_switch.c | 15 +- .../actors/ovl_player_actor/z_player.c | 19 +- 99 files changed, 4191 insertions(+), 2912 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/hook_handlers.cpp create mode 100644 soh/soh/Enhancements/randomizer/hook_handlers.h create mode 100644 soh/soh/Enhancements/timesaver_hook_handlers.cpp create mode 100644 soh/soh/Enhancements/timesaver_hook_handlers.h diff --git a/soh/include/functions.h b/soh/include/functions.h index 49a8a0a93..698487621 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -183,6 +183,8 @@ void __osSetWatchLo(u32); EnItem00* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, s16 params); EnItem00* Item_DropCollectible2(PlayState* play, Vec3f* spawnPos, s16 params); void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry giEntry); +void EnItem00_SetupAction(EnItem00* this, EnItem00ActionFunc actionFunc); +void func_8001E5C8(EnItem00* this, PlayState* play); void Item_DropCollectibleRandom(PlayState* play, Actor* fromActor, Vec3f* spawnPos, s16 params); void EffectBlure_ChangeType(EffectBlure* this, int type); void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2); @@ -415,6 +417,7 @@ f32 Actor_WorldDistXZToPoint(Actor* actor, Vec3f* refPoint); void func_8002DBD0(Actor* actor, Vec3f* result, Vec3f* arg2); f32 Actor_HeightDiff(Actor* actorA, Actor* actorB); f32 Player_GetHeight(Player* player); +s32 func_8083E5A8(Player* player, PlayState* play); f32 func_8002DCE4(Player* player); s32 func_8002DD6C(Player* player); s32 func_8002DD78(Player* player); @@ -1106,6 +1109,7 @@ s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input); u8 PlayerGrounded(Player* player); void Player_SetBootData(PlayState* play, Player* player); s32 Player_InBlockingCsMode(PlayState* play, Player* player); +s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction); s32 Player_InCsMode(PlayState* play); s32 func_8008E9C4(Player* player); s32 Player_IsChildWithHylianShield(Player* player); diff --git a/soh/include/z64actor.h b/soh/include/z64actor.h index 0a8ac9297..156f1d679 100644 --- a/soh/include/z64actor.h +++ b/soh/include/z64actor.h @@ -266,7 +266,12 @@ typedef enum { /* 0x17 */ ITEM00_TUNIC_ZORA, /* 0x18 */ ITEM00_TUNIC_GORON, /* 0x19 */ ITEM00_BOMBS_SPECIAL, - /* 0x20 */ ITEM00_BOMBCHU, + /* 0x1A */ ITEM00_BOMBCHU, + /* 0x1B */ ITEM00_SOH_DUMMY, + /* 0x1C */ ITEM00_SOH_GIVE_ITEM_ENTRY, + /* 0x1D */ ITEM00_SOH_GIVE_ITEM_ENTRY_GI, + /* 0x1E */ ITEM00_MAX, + /* 0xFF */ ITEM00_NONE = 0xFF } Item00Type; struct EnItem00; @@ -284,10 +289,13 @@ typedef struct EnItem00 { /* 0x15A */ s16 unk_15A; /* 0x15C */ f32 scale; /* 0x160 */ ColliderCylinder collider; - s16 ogParams; + // #region SOH [Randomizer] GetItemEntry randoGiEntry; RandomizerCheck randoCheck; RandomizerInf randoInf; + /* */ s16 ogParams; + /* */ GetItemEntry itemEntry; + // #endregion } EnItem00; // size = 0x1AC // Only A_OBJ_SIGNPOST_OBLONG and A_OBJ_SIGNPOST_ARROW are used in room files. diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index b0650bfa0..5a4618dac 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -505,6 +505,7 @@ const std::vector flagTables = { { RAND_INF_CHILD_FISHING, "RAND_INF_CHILD_FISHING" }, { RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" }, { RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" }, + { RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" }, { RAND_INF_GOHMA_SOUL, "RAND_INF_GOHMA_SOUL" }, { RAND_INF_KING_DODONGO_SOUL, "RAND_INF_KING_DODONGO_SOUL" }, @@ -515,7 +516,6 @@ const std::vector flagTables = { { RAND_INF_BONGO_BONGO_SOUL, "RAND_INF_BONGO_BONGO_SOUL" }, { RAND_INF_TWINROVA_SOUL, "RAND_INF_TWINROVA_SOUL" }, { RAND_INF_GANON_SOUL, "RAND_INF_GANON_SOUL" }, - { RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" }, { RAND_INF_HAS_OCARINA_A, "RAND_INF_HAS_OCARINA_A"}, { RAND_INF_HAS_OCARINA_C_UP, "RAND_INF_HAS_OCARINA_C_UP" }, @@ -607,7 +607,11 @@ const std::vector flagTables = { { RAND_INF_ZD_FISH_2, "RAND_INF_ZD_FISH_2" }, { RAND_INF_ZD_FISH_3, "RAND_INF_ZD_FISH_3" }, { RAND_INF_ZD_FISH_4, "RAND_INF_ZD_FISH_4" }, - { RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" } + { RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" }, + + { RAND_INF_LINKS_POCKET, "RAND_INF_LINKS_POCKET" }, + { RAND_INF_LEARNED_EPONA_SONG, "RAND_INF_LEARNED_EPONA_SONG" }, + { RAND_INF_DARUNIAS_JOY, "RAND_INF_DARUNIAS_JOY" }, } }, }; diff --git a/soh/soh/Enhancements/debugger/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp index 14a571dac..213c81cfa 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.cpp +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -34,6 +34,8 @@ std::vector valueTable = { { "Text ID", "play->msgCtx.textId", "TEXTID:", TYPE_U16, true, []() -> void* { return &gPlayState->msgCtx.textId; }, WHITE }, { "Analog Stick X", "play->state.input->cur.stick_x", "AX:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_x; }, WHITE }, { "Analog Stick Y", "play->state.input->cur.stick_y", "AY:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_y; }, WHITE }, + { "getItemID", "Player->getItemId", "ITEM:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemId; }, WHITE }, + { "getItemEntry", "Player->getItemEntry", "IE:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemEntry.itemId; }, WHITE }, /* TODO: Find these (from GZ) "XZ Units Traveled (Camera based speed variable)" f32 0x801C9018 "Movement Angle" x16 0x801DBB1C diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index c8461bbf1..f3b8ac029 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -14,6 +14,13 @@ typedef enum { CSMC_SIZE } ChestStyleMatchesContentsType; +typedef enum { + SGIA_DISABLED, + SGIA_JUNK, + SGIA_ALL, + SGIA_SIZE +} SkipGetItemAnimationType; + typedef enum { BUNNY_HOOD_VANILLA, BUNNY_HOOD_FAST_AND_JUMP, diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index be27e74a2..c6fb7c721 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -3,6 +3,7 @@ #ifndef GameInteractor_h #define GameInteractor_h +#include "libultraship/libultraship.h" #include "GameInteractionEffect.h" #include "soh/Enhancements/item-tables/ItemTableTypes.h" #include @@ -67,6 +68,272 @@ typedef enum { /* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_7, } GITeleportDestinations; +typedef enum { + // Vanilla condition: gSaveContext.showTitleCard + GI_VB_SHOW_TITLE_CARD, + // Opt: *EnWonderTalk2 + GI_VB_WONDER_TALK, + // Opt: *ElfMsg + GI_VB_NAVI_TALK, + // Vanilla condition: INFTABLE_GREETED_BY_SARIA + GI_VB_NOT_BE_GREETED_BY_SARIA, + // Opt: *EnMd + // Vanilla condition: EnMd->interactInfo.talkState == NPC_TALK_STATE_ACTION + GI_VB_MOVE_MIDO_IN_KOKIRI_FOREST, + // Opt: *EnMd + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) + GI_VB_MIDO_CONSIDER_DEKU_TREE_DEAD, + // Opt: *EnKo + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) + GI_VB_OPEN_KOKIRI_FOREST, + // Opt: *EnOwl + // Vanilla condition: EnOwl->actor.xzDistToPlayer < targetDist + GI_VB_OWL_INTERACTION, + // Vanilla condition: EVENTCHKINF_TALON_RETURNED_FROM_CASTLE + GI_VB_MALON_RETURN_FROM_CASTLE, + // Vanilla condition: CUR_UPG_VALUE(UPG_STRENGTH) <= 0 + GI_VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD, + /* Vanilla condition: + ``` + LINK_IS_ADULT && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && + !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + ``` + */ + GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, + // Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SARIA) + GI_VB_BE_ELIGIBLE_FOR_SARIAS_SONG, + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_SONG_EPONA) + GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG, + // Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) + GI_VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER, + // Vanilla condition: (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT + GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER, + // Vanilla condition: !EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT and EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP + GI_VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT, + /* Vanilla Condition: + ``` + LINK_IS_ADULT && + gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && + Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) && + !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); + ``` + */ + GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, + // Opt: *EnGo2 + // Vanilla condition: CUR_CAPACITY(UPG_BOMB_BAG) >= 20 && this->waypoint > 7 && this->waypoint < 12 + GI_VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD, + // Vanilla condition: !CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON) + GI_VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE, + // Opt: *EnMs + // Vanilla condition: gSaveContext.rupees >= sPrices[BEANS_BOUGHT] + GI_VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE, + // Opt: *EnItem00 + // Vanilla condition: Flags_GetCollectible(play, this->collectibleFlag) + GI_VB_ITEM00_DESPAWN, + // Opt: *EnTk + // Vanilla condition: gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD + GI_VB_DAMPE_IN_GRAVEYARD_DESPAWN, + // Opt: *EnTk + // Vanilla condition: this->validDigHere == 1 + GI_VB_BE_VALID_GRAVEDIGGING_SPOT, + // Opt: *EnTk + // Vanilla condition: this->currentReward == 3 + GI_VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE, + // Opt: *EnTk + // Vanilla condition: !Flags_GetItemGetInf(ITEMGETINF_1C) + GI_VB_DAMPE_GRAVEDIGGING_GRAND_PRIZE_BE_HEART_PIECE, + // Opt: *EnShopnuts + /* Vanilla Condition: + ``` + ((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) || + ((this->actor.params == 0x0009) && (Flags_GetInfTable(INFTABLE_192))) || + ((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193))) + ``` + */ + GI_VB_BUSINESS_SCRUB_DESPAWN, + // Opt: *EnCow + // Vanilla condition: play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE)) + GI_VB_DESPAWN_HORSE_RACE_COW, + // Opt: *EnHs + // Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30) + GI_VB_DESPAWN_GROG, + // Opt: *EnKo + // Vanilla condition: (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false; + GI_VB_SPAWN_LW_FADO, + // Opt: *EnMk + GI_VB_PLAY_EYEDROP_CREATION_ANIM, + // Opt: *EnDs + GI_VB_PLAY_ODD_POTION_ANIM, + // Opt: *EnMk + // Vanilla condition: INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS + GI_VB_USE_EYEDROP_DIALOGUE, + // Opt: *EnMk + // Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30) + GI_VB_OFFER_BLUE_POTION, + // Vanilla condition: Inventory_HasEmptyBottle() == 0 + GI_VB_NEED_BOTTLE_FOR_GRANNYS_ITEM, + // Opt: *EnNiwLady + GI_VB_SET_CUCCO_COUNT, + // Opt: *EnKz + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) + GI_VB_KING_ZORA_THANK_CHILD, + // Opt: *EnKz + // Vanilla condition: this->actor.textId == 0x401A + GI_VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER, + // Opt: *EnKz + // Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED) + GI_VB_KING_ZORA_BE_MOVED, + // Vanilla condition: gSaveState.bgsFlag + GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE, + // Vanilla condition: gSaveState.bgsFlag + GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED, + // Vanilla condition: Environment_GetBgsDayCount() >= 3 + GI_VB_BIGGORON_CONSIDER_SWORD_FORGED, + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) + GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_GORON_RUBY) + GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, + // Opt: *uint16_t + // Vanilla condition: false + GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE, + // Opt: *EnGo2 + GI_VB_EN_GO2_RESET_AFTER_GET_ITEM, + + /*** Play Cutscenes ***/ + + GI_VB_PLAY_TRANSITION_CS, + // Opt: *EventChkInf flag + GI_VB_PLAY_ENTRANCE_CS, + // Opt: *cutsceneId + GI_VB_PLAY_ONEPOINT_CS, + // Opt: *actor + GI_VB_PLAY_ONEPOINT_ACTOR_CS, + // Opt: *BgTreemouth + GI_VB_PLAY_DEKU_TREE_INTRO_CS, + // Vanilla condition: !EventChkInf except for spirit & shadow temple which are !medallion, and Jabu which always is true + GI_VB_PLAY_BLUE_WARP_CS, + GI_VB_PLAY_DARUNIAS_JOY_CS, + GI_VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS, + // Vanilla condition: !EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL + GI_VB_PLAY_PULL_MASTER_SWORD_CS, + GI_VB_PLAY_DROP_FISH_FOR_JABU_CS, + // Vanilla condition: player->getItemId == GI_GAUNTLETS_SILVER + GI_VB_PLAY_NABOORU_CAPTURED_CS, + GI_VB_PLAY_ZELDAS_LULLABY_CS, + // Opt: *EnSa + GI_VB_PLAY_SARIAS_SONG_CS, + GI_VB_PLAY_PRELUDE_OF_LIGHT_CS, + GI_VB_PLAY_MINUET_OF_FOREST_CS, + GI_VB_PLAY_BOLERO_OF_FIRE_CS, + GI_VB_PLAY_SERENADE_OF_WATER_CS, + GI_VB_PLAY_EYEDROPS_CS, + + /*** Give Items ***/ + + GI_VB_GIVE_ITEM_FROM_CHEST, + GI_VB_GIVE_ITEM_FROM_BLUE_WARP, + // Opt: *EnItem00 + GI_VB_GIVE_ITEM_FROM_ITEM_00, + // Opt: *EnSi + GI_VB_GIVE_ITEM_SKULL_TOKEN, + // Opt: *EnCow + GI_VB_GIVE_ITEM_FROM_COW, + // Opt: *EnDns + GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB, + // Opt: *EnMk + GI_VB_GIVE_ITEM_FROM_LAB_DIVE, + // Opt: *EnDs + GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP, + // Opt: *EnNiwLady + GI_VB_GIVE_ITEM_FROM_ANJU_AS_CHILD, + // Opt: *EnNiwLady + GI_VB_GIVE_ITEM_FROM_ANJU_AS_ADULT, + // Opt: *EnKz + // Vanilla condition: !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) + GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, + // Opt: *EnGo2 + GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD, + // Opt: *EnGo2 + GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_ADULT, + // Opt: *EnJs + GI_VB_GIVE_ITEM_FROM_CARPET_SALESMAN, + // Opt: *EnGm + GI_VB_GIVE_ITEM_FROM_MEDIGORON, + // Opt: *EnMs + GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN, + // Opt: *EnFr + GI_VB_GIVE_ITEM_FROM_FROGS, + + GI_VB_GIVE_ITEM_FAIRY_OCARINA, + GI_VB_GIVE_ITEM_WEIRD_EGG, + GI_VB_GIVE_ITEM_LIGHT_ARROW, + GI_VB_GIVE_ITEM_STRENGTH_1, + GI_VB_GIVE_ITEM_ZELDAS_LETTER, + GI_VB_GIVE_ITEM_MASTER_SWORD, + GI_VB_GIVE_ITEM_OCARINA_OF_TIME, + GI_VB_GIVE_ITEM_KOKIRI_EMERALD, + GI_VB_GIVE_ITEM_GORON_RUBY, + GI_VB_GIVE_ITEM_ZORA_SAPPHIRE, + GI_VB_GIVE_ITEM_LIGHT_MEDALLION, + GI_VB_GIVE_ITEM_FOREST_MEDALLION, + GI_VB_GIVE_ITEM_FIRE_MEDALLION, + GI_VB_GIVE_ITEM_WATER_MEDALLION, + GI_VB_GIVE_ITEM_SPIRIT_MEDALLION, + GI_VB_GIVE_ITEM_SHADOW_MEDALLION, + + /*** Give Songs ***/ + + GI_VB_GIVE_ITEM_ZELDAS_LULLABY, + GI_VB_GIVE_ITEM_SARIAS_SONG, + GI_VB_GIVE_ITEM_EPONAS_SONG, + GI_VB_GIVE_ITEM_SUNS_SONG, + GI_VB_GIVE_ITEM_SONG_OF_TIME, + GI_VB_GIVE_ITEM_SONG_OF_STORMS, + GI_VB_GIVE_ITEM_MINUET_OF_FOREST, + GI_VB_GIVE_ITEM_BOLERO_OF_FIRE, + GI_VB_GIVE_ITEM_SERENADE_OF_WATER, + GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, + GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, + GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT, + + /*** Adult Trade ***/ + // Opt: *EnNiwLady + GI_VB_TRADE_POCKET_CUCCO, + // Opt: *EnHs + GI_VB_TRADE_COJIRO, + // Opt: *EnDs + GI_VB_TRADE_ODD_MUSHROOM, + // Opt: *EnKo + GI_VB_TRADE_ODD_POTION, + // Opt: *EnToryo + GI_VB_TRADE_SAW, + // Opt: *EnGo2 + GI_VB_TRADE_BROKEN_SWORD, + // Opt: *EnKz, + GI_VB_TRADE_PRESCRIPTION, + // Opt: *EnMk + GI_VB_TRADE_FROG, + // Opt: *EnGo2 + GI_VB_TRADE_EYEDROPS, + // Opt: *EnGo2 + GI_VB_TRADE_CLAIM_CHECK, + + GI_VB_TRADE_TIMER_ODD_MUSHROOM, + GI_VB_TRADE_TIMER_EYEDROPS, + GI_VB_TRADE_TIMER_FROG, + // Opt: *EnNiwLady + GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM, + + /*** Fixes ***/ + // Vanilla condition: false + GI_VB_FIX_SAW_SOFTLOCK, +} GIVanillaBehavior; + #ifdef __cplusplus extern "C" { #endif @@ -163,11 +430,28 @@ public: static GameInteractionEffectQueryResult RemoveEffect(RemovableGameInteractionEffect* effect); // Game Hooks - template struct RegisteredGameHooks { inline static std::vector functions; }; - template void RegisterGameHook(typename H::fn h) { RegisteredGameHooks::functions.push_back(h); } + uint32_t nextHookId = 0; + template struct RegisteredGameHooks { inline static std::unordered_map functions; }; + template struct HooksToUnregister { inline static std::vector hooks; }; + template uint32_t RegisterGameHook(typename H::fn h) { + // Ensure hook id is unique + while (RegisteredGameHooks::functions.find(this->nextHookId) != RegisteredGameHooks::functions.end()) { + this->nextHookId++; + } + RegisteredGameHooks::functions[this->nextHookId] = h; + return this->nextHookId++; + } + template void UnregisterGameHook(uint32_t id) { + HooksToUnregister::hooks.push_back(id); + } + template void ExecuteHooks(Args&&... args) { - for (auto& fn : RegisteredGameHooks::functions) { - fn(std::forward(args)...); + for (auto& hookId : HooksToUnregister::hooks) { + RegisteredGameHooks::functions.erase(hookId); + } + HooksToUnregister::hooks.clear(); + for (auto& hook : RegisteredGameHooks::functions) { + hook.second(std::forward(args)...); } } @@ -194,6 +478,8 @@ public: DEFINE_HOOK(OnPlayDestroy, void()); DEFINE_HOOK(OnPlayDrawEnd, void()); + DEFINE_HOOK(OnVanillaBehavior, void(GIVanillaBehavior flag, bool* result, void* opt)); + DEFINE_HOOK(OnSaveFile, void(int32_t fileNum)); DEFINE_HOOK(OnLoadFile, void(int32_t fileNum)); DEFINE_HOOK(OnDeleteFile, void(int32_t fileNum)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 4bd5354a6..95728c075 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -90,6 +90,11 @@ void GameInteractor_ExecuteOnPlayDrawEnd() { GameInteractor::Instance->ExecuteHooks(); } +bool GameInteractor_Should(GIVanillaBehavior flag, bool result, void* opt) { + GameInteractor::Instance->ExecuteHooks(flag, &result, opt); + return result; +} + // MARK: - Save Files void GameInteractor_ExecuteOnSaveFile(int32_t fileNum) { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 7b7b226fa..d89b95381 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -27,6 +27,7 @@ void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price); void GameInteractor_ExecuteOnPlayDestroy(); void GameInteractor_ExecuteOnPlayDrawEnd(); +bool GameInteractor_Should(GIVanillaBehavior flag, bool result, void* opt); // MARK: - Save Files void GameInteractor_ExecuteOnSaveFile(int32_t fileNum); diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 26adf611d..4aabf04d6 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -10,6 +10,8 @@ #include "soh/Enhancements/cosmetics/authenticGfxPatches.h" #include #include "soh/Enhancements/nametag.h" +#include "soh/Enhancements/timesaver_hook_handlers.h" +#include "soh/Enhancements/randomizer/hook_handlers.h" #include "src/overlays/actors/ovl_En_Bb/z_en_bb.h" #include "src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.h" @@ -1596,6 +1598,8 @@ void RegisterFishsanity() { } void InitMods() { + RandomizerRegisterHooks(); + TimeSaverRegisterHooks(); RegisterTTS(); RegisterInfiniteMoney(); RegisterInfiniteHealth(); diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 8536c1d17..92799a5db 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -1122,7 +1122,19 @@ int Fill() { std::vector remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; }); FastFill(remainingPool, GetAllEmptyLocations(), false); - //Add prices for scrubsanity, this is unique to SoH because we write/read scrub prices to/from the spoilerfile. + //Add default prices to scrubs + for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) { + if (Rando::StaticData::scrubLocations[i] == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || Rando::StaticData::scrubLocations[i] == RC_LW_DEKU_SCRUB_GROTTO_FRONT) { + ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(40); + } else if (Rando::StaticData::scrubLocations[i] == RC_HF_DEKU_SCRUB_GROTTO) { + ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(10); + } else { + auto loc = Rando::StaticData::GetLocation(Rando::StaticData::scrubLocations[i]); + auto item = Rando::StaticData::RetrieveItem(loc->GetVanillaItem()); + ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(item.GetPrice()); + } + } + if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_AFFORDABLE)) { for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) { ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(10); diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp index 51fc51941..7e20b176a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp @@ -18,16 +18,12 @@ typedef enum { SPOILER_CHK_ITEM_GET_INF, SPOILER_CHK_EVENT_CHK_INF, SPOILER_CHK_INF_TABLE, - SPOILER_CHK_COW, SPOILER_CHK_FISH, SPOILER_CHK_MINIGAME, - SPOILER_CHK_SCRUB, SPOILER_CHK_GERUDO_MEMBERSHIP_CARD, SPOILER_CHK_POE_POINTS, SPOILER_CHK_SHOP_ITEM, - SPOILER_CHK_MAGIC_BEANS, SPOILER_CHK_MASTER_SWORD, - SPOILER_CHK_MERCHANT, SPOILER_CHK_GRAVEDIGGER, SPOILER_CHK_RANDOMIZER_INF, } SpoilerCollectionCheckType; diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp new file mode 100644 index 000000000..bf236a3ba --- /dev/null +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -0,0 +1,975 @@ +#include +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/enhancementTypes.h" +#include "soh/Enhancements/custom-message/CustomMessageTypes.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" + +extern "C" { +#include "macros.h" +#include "functions.h" +#include "variables.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "src/overlays/actors/ovl_En_Si/z_en_si.h" +#include "src/overlays/actors/ovl_En_Cow/z_en_cow.h" +#include "src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.h" +#include "src/overlays/actors/ovl_En_Dns/z_en_dns.h" +#include "src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h" +#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h" +#include "src/overlays/actors/ovl_En_Mk/z_en_mk.h" +#include "src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h" +#include "src/overlays/actors/ovl_En_Kz/z_en_kz.h" +#include "src/overlays/actors/ovl_En_Go2/z_en_go2.h" +#include "src/overlays/actors/ovl_En_Ms/z_en_ms.h" +#include "src/overlays/actors/ovl_En_Fr/z_en_fr.h" +#include "adult_trade_shuffle.h" +extern SaveContext gSaveContext; +extern PlayState* gPlayState; +} + +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() + +RandomizerCheck GetRandomizerCheckFromFlag(int16_t flagType, int16_t flag) { + for (auto& loc : Rando::StaticData::GetLocationTable()) { + if (loc.GetCollectionCheck().flag == flag && ( + (flagType == FLAG_EVENT_CHECK_INF && loc.GetCollectionCheck().type == SPOILER_CHK_EVENT_CHK_INF) || + (flagType == FLAG_ITEM_GET_INF && loc.GetCollectionCheck().type == SPOILER_CHK_ITEM_GET_INF) || + (flagType == FLAG_RANDOMIZER_INF && loc.GetCollectionCheck().type == SPOILER_CHK_RANDOMIZER_INF) + ) || + (loc.GetActorParams() == flag && flagType == FLAG_GS_TOKEN && loc.GetCollectionCheck().type == SPOILER_CHK_GOLD_SKULLTULA) + ) { + return loc.GetRandomizerCheck(); + } + } + + return RC_UNKNOWN_CHECK; +} + +RandomizerCheck GetRandomizerCheckFromSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag) { + for (auto& loc : Rando::StaticData::GetLocationTable()) { + if (loc.GetCollectionCheck().scene == sceneNum && loc.GetCollectionCheck().flag == flag && ( + (flagType == FLAG_SCENE_TREASURE && loc.GetCollectionCheck().type == SPOILER_CHK_CHEST) || + (flagType == FLAG_SCENE_COLLECTIBLE && loc.GetCollectionCheck().type == SPOILER_CHK_COLLECTABLE) || + (flagType == FLAG_GS_TOKEN && loc.GetCollectionCheck().type == SPOILER_CHK_GOLD_SKULLTULA) + )) { + return loc.GetRandomizerCheck(); + } + } + + return RC_UNKNOWN_CHECK; +} + +bool MeetsLACSRequirements() { + switch (RAND_GET_OPTION(RSK_GANONS_BOSS_KEY)) { + case RO_GANON_BOSS_KEY_LACS_STONES: + if ((CheckStoneCount() + CheckLACSRewardCount()) >= RAND_GET_OPTION(RSK_LACS_STONE_COUNT)) { + return true; + } + break; + case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: + if ((CheckMedallionCount() + CheckLACSRewardCount()) >= RAND_GET_OPTION(RSK_LACS_MEDALLION_COUNT)) { + return true; + } + break; + case RO_GANON_BOSS_KEY_LACS_REWARDS: + if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >= RAND_GET_OPTION(RSK_LACS_REWARD_COUNT)) { + return true; + } + break; + case RO_GANON_BOSS_KEY_LACS_DUNGEONS: + if ((CheckDungeonCount() + CheckLACSRewardCount()) >= RAND_GET_OPTION(RSK_LACS_DUNGEON_COUNT)) { + return true; + } + break; + case RO_GANON_BOSS_KEY_LACS_TOKENS: + if (gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_LACS_TOKEN_COUNT)) { + return true; + } + break; + default: + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) { + return true; + } + break; + } + + return false; +} + +// Todo Move this to randomizer context, clear it out on save load etc +static std::queue randomizerQueuedChecks; +static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK; +static GetItemEntry randomizerQueuedItemEntry = GET_ITEM_NONE; + +void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { + RandomizerCheck rc = GetRandomizerCheckFromFlag(flagType, flag); + if (rc == RC_UNKNOWN_CHECK) return; + + auto loc = Rando::Context::GetInstance()->GetItemLocation(rc); + if (loc == nullptr || loc->HasObtained()) return; + + SPDLOG_INFO("Queuing RC: {}", rc); + randomizerQueuedChecks.push(rc); +} + +void RandomizerOnSceneFlagSetHandler(int16_t sceneNum, int16_t flagType, int16_t flag) { + RandomizerCheck rc = GetRandomizerCheckFromSceneFlag(sceneNum, flagType, flag); + if (rc == RC_UNKNOWN_CHECK) return; + + auto loc = Rando::Context::GetInstance()->GetItemLocation(rc); + if (loc == nullptr || loc->HasObtained()) return; + + SPDLOG_INFO("Queuing RC: {}", rc); + randomizerQueuedChecks.push(rc); +} + +static Vec3f spawnPos = { 0.0f, -999.0f, 0.0f }; + +void RandomizerOnPlayerUpdateForRCQueueHandler() { + // If we're already queued, don't queue again + if (randomizerQueuedCheck != RC_UNKNOWN_CHECK) return; + + // If there's nothing to queue, don't queue + if (randomizerQueuedChecks.size() < 1) return; + + // If we're in a cutscene, don't queue + Player* player = GET_PLAYER(gPlayState); + if (Player_InBlockingCsMode(gPlayState, player) || player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) { + return; + } + + RandomizerCheck rc = randomizerQueuedChecks.front(); + auto loc = Rando::Context::GetInstance()->GetItemLocation(rc); + GetItemEntry getItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + + if (loc->HasObtained()) { + SPDLOG_INFO("RC {} already obtained, skipping", rc); + } else { + randomizerQueuedCheck = rc; + randomizerQueuedItemEntry = getItemEntry; + SPDLOG_INFO("Queueing Item mod {} item {} from RC {}", getItemEntry.modIndex, getItemEntry.itemId, rc); + if ( + // Skipping ItemGet animation incompatible with checks that require closing a text box to finish + rc != RC_HF_OCARINA_OF_TIME_ITEM && + rc != RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && + // Always show ItemGet animation for ice traps + !(getItemEntry.modIndex == MOD_RANDOMIZER && getItemEntry.getItemId == RG_ICE_TRAP) && + ( + CVarGetInteger("gTimeSavers.SkipGetItemAnimation", SGIA_DISABLED) == SGIA_ALL || + ( + CVarGetInteger("gTimeSavers.SkipGetItemAnimation", SGIA_DISABLED) == SGIA_JUNK && + ( + getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK || + getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN || + getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER + ) + ) + ) + ) { + Item_DropCollectible(gPlayState, &spawnPos, ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000); + } + } + + randomizerQueuedChecks.pop(); +} + +void RandomizerOnPlayerUpdateForItemQueueHandler() { + if (randomizerQueuedCheck == RC_UNKNOWN_CHECK) return; + + Player* player = GET_PLAYER(gPlayState); + if (player == NULL || Player_InBlockingCsMode(gPlayState, player) || player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) { + return; + } + + SPDLOG_INFO("Attempting to give Item mod {} item {} from RC {}", randomizerQueuedItemEntry.modIndex, randomizerQueuedItemEntry.itemId, randomizerQueuedCheck); + GiveItemEntryWithoutActor(gPlayState, randomizerQueuedItemEntry); + if (player->stateFlags1 & PLAYER_STATE1_IN_WATER) { + // Allow the player to receive the item while swimming + player->stateFlags2 |= PLAYER_STATE2_UNDERWATER; + func_8083E5A8(player, gPlayState); + } +} + +void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { + if (randomizerQueuedCheck == RC_UNKNOWN_CHECK) return; + + auto loc = Rando::Context::GetInstance()->GetItemLocation(randomizerQueuedCheck); + if (randomizerQueuedItemEntry.modIndex == receivedItemEntry.modIndex && randomizerQueuedItemEntry.itemId == receivedItemEntry.itemId) { + SPDLOG_INFO("Item received mod {} item {} from RC {}", receivedItemEntry.modIndex, receivedItemEntry.itemId, randomizerQueuedCheck); + loc->MarkAsObtained(); + randomizerQueuedCheck = RC_UNKNOWN_CHECK; + randomizerQueuedItemEntry = GET_ITEM_NONE; + } + + if ( + receivedItemEntry.modIndex == MOD_NONE && ( + receivedItemEntry.itemId == ITEM_HEART_PIECE || + receivedItemEntry.itemId == ITEM_HEART_PIECE_2 || + receivedItemEntry.itemId == ITEM_HEART_CONTAINER + ) + ) { + gSaveContext.healthAccumulator = 0x140; // Refill 20 hearts + if ((s32)(gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000) { + gSaveContext.inventory.questItems ^= 0x40000000; + gSaveContext.healthCapacity += 0x10; + gSaveContext.health += 0x10; + } + } + + if (loc->GetRandomizerCheck() == RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && !CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + static uint32_t updateHook; + updateHook = GameInteractor::Instance->RegisterGameHook([]() { + Player* player = GET_PLAYER(gPlayState); + if (player == NULL || Player_InBlockingCsMode(gPlayState, player) || player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) { + return; + } + + gPlayState->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gSaveContext.nextCutsceneIndex = 0xFFF1; + gPlayState->transitionType = TRANS_TYPE_SANDSTORM_END; + GET_PLAYER(gPlayState)->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; + Player_TryCsAction(gPlayState, NULL, 8); + GameInteractor::Instance->UnregisterGameHook(updateHook); + }); + } +} + +void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play) { + f32 mtxScale = CVarGetFloat("gTimeSavers.SkipGetItemAnimationScale", 10.0f); + Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); + EnItem00_CustomItemsParticles(&enItem00->actor, play, enItem00->itemEntry); + GetItemEntry_Draw(play, enItem00->itemEntry); +} + +void ItemBHeart_DrawRandomizedItem(ItemBHeart* itemBHeart, PlayState* play) { + EnItem00_CustomItemsParticles(&itemBHeart->actor, play, itemBHeart->sohItemEntry); + GetItemEntry_Draw(play, itemBHeart->sohItemEntry); +} + +void ItemBHeart_UpdateRandomizedItem(Actor* actor, PlayState* play) { + ItemBHeart* itemBHeart = (ItemBHeart*)actor; + + func_80B85264(itemBHeart, play); + Actor_UpdateBgCheckInfo(play, &itemBHeart->actor, 0.0f, 0.0f, 0.0f, 4); + if ((itemBHeart->actor.xzDistToPlayer < 30.0f) && (fabsf(itemBHeart->actor.yDistToPlayer) < 40.0f)) { + Flags_SetCollectible(play, 0x1F); + Actor_Kill(&itemBHeart->actor); + } +} + +void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) { + bool moved = false; + + // Don't reposition the tail + if (enCow->actor.params != 0) { + return; + } + + // Move left cow in lon lon tower + if (play->sceneNum == SCENE_LON_LON_BUILDINGS && enCow->actor.world.pos.x == -108 && + enCow->actor.world.pos.z == -65) { + enCow->actor.world.pos.x = -229.0f; + enCow->actor.world.pos.z = 157.0f; + enCow->actor.shape.rot.y = 15783.0f; + moved = true; + // Move right cow in lon lon stable + } else if (play->sceneNum == SCENE_STABLE && enCow->actor.world.pos.x == -3 && enCow->actor.world.pos.z == -254) { + enCow->actor.world.pos.x += 119.0f; + moved = true; + } + + if (moved) { + // Reposition collider + func_809DEE9C(enCow); + } +} + +u8 EnDs_RandoCanGetGrannyItem() { + return RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && + !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) && + // Traded odd mushroom when adult trade is on + ((RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && Flags_GetItemGetInf(ITEMGETINF_30)) || + // Found claim check when adult trade is off + (!RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && + INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)); +} + +RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex) { + switch (songIndex) { + case FROG_ZL: + return RC_ZR_FROGS_ZELDAS_LULLABY; + case FROG_EPONA: + return RC_ZR_FROGS_EPONAS_SONG; + case FROG_SARIA: + return RC_ZR_FROGS_SARIAS_SONG; + case FROG_SUNS: + return RC_ZR_FROGS_SUNS_SONG; + case FROG_SOT: + return RC_ZR_FROGS_SONG_OF_TIME; + case FROG_STORMS: + return RC_ZR_FROGS_IN_THE_RAIN; + case FROG_CHOIR_SONG: + return RC_ZR_FROGS_OCARINA_GAME; + default: + return RC_UNKNOWN_CHECK; + } +} + +void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { + switch (id) { + case GI_VB_GIVE_ITEM_FROM_CHEST: { + Player* player = GET_PLAYER(gPlayState); + player->unk_850 = 1; + player->getItemId = GI_NONE; + player->getItemEntry = GetItemEntry(GET_ITEM_NONE); + *should = false; + break; + } + case GI_VB_PLAY_NABOORU_CAPTURED_CS: + // This behavior is replicated for randomizer in RandomizerOnItemReceiveHandler + *should = false; + break; + case GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER: { + *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && !Flags_GetTreasure(gPlayState, 0x2); + break; + } + case GI_VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER: + *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && Flags_GetTreasure(gPlayState, 0x2); + break; + case GI_VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT: + *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); + break; + case GI_VB_MOVE_MIDO_IN_KOKIRI_FOREST: + if (RAND_GET_OPTION(RSK_FOREST) == RO_FOREST_OPEN) { + *should = true; + } + break; + case GI_VB_MIDO_CONSIDER_DEKU_TREE_DEAD: + *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); + break; + case GI_VB_OPEN_KOKIRI_FOREST: + *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || RAND_GET_OPTION(RSK_FOREST) != RO_FOREST_CLOSED; + break; + case GI_VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD: + *should = !Flags_GetRandomizerInf(RAND_INF_DARUNIAS_JOY); + break; + case GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS: + *should = !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && MeetsLACSRequirements(); + break; + case GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW: + *should = + !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && + LINK_IS_ADULT && + gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE && + CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER); + break; + case GI_VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD: { + // Don't require a bomb bag to get prize in rando + *should = true; + break; + } + case GI_VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE: { + if (RAND_GET_OPTION(RSK_SHUFFLE_MAGIC_BEANS)) { + *should = gSaveContext.rupees >= 60; + } + break; + } + case GI_VB_GIVE_ITEM_MASTER_SWORD: + if (RAND_GET_OPTION(RSK_SHUFFLE_MASTER_SWORD)) { + *should = false; + } else { + *should = true; + Rando::Context::GetInstance()->GetItemLocation(RC_TOT_MASTER_SWORD)->MarkAsObtained(); + } + break; + case GI_VB_ITEM00_DESPAWN: { + EnItem00* item00 = static_cast(optionalArg); + if (item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY) { + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(item00->actor.id, gPlayState->sceneNum, item00->ogParams); + if (rc != RC_UNKNOWN_CHECK) { + item00->actor.params = ITEM00_SOH_DUMMY; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + *should = Rando::Context::GetInstance()->GetItemLocation(rc)->HasObtained(); + } + } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY || item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) { + GetItemEntry itemEntry = randomizerQueuedItemEntry; + item00->itemEntry = itemEntry; + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + } + break; + } + case GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG: { + *should = Flags_GetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG); + break; + } + case GI_VB_SET_CUCCO_COUNT: { + EnNiwLady* enNiwLady = static_cast(optionalArg); + // Override starting Cucco count using setting value + enNiwLady->cuccosInPen = 7 - RAND_GET_OPTION(RSK_CUCCO_COUNT); + *should = false; + break; + } + case GI_VB_KING_ZORA_THANK_CHILD: { + // Allow turning in Ruto's letter even if you have already rescued her + if (!Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { + GET_PLAYER(gPlayState)->exchangeItemId = EXCH_ITEM_LETTER_RUTO; + } + *should = Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY); + break; + } + case GI_VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER: { + *should = LINK_IS_CHILD; + break; + } + case GI_VB_KING_ZORA_BE_MOVED: { + *should = false; + switch (RAND_GET_OPTION(RSK_ZORAS_FOUNTAIN)) { + case RO_ZF_CLOSED: + if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { + *should = true; + } + break; + case RO_ZF_CLOSED_CHILD: + if (LINK_IS_ADULT) { + *should = true; + } else if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { + *should = true; + } + break; + case RO_ZF_OPEN: + *should = true; + break; + } + break; + } + case GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED: { + *should = Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); + break; + } + case GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE: { + + *should = INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK && Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); + break; + } + case GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED: { + *should = Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP); + break; + } + case GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED: { + *should = Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP); + break; + } + case GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE: { + u16* textId = static_cast(optionalArg); + *should = true; + + // For rando, prioritize opening the doors in GC when Link the goron has been stopped when + // the doors are not opened, otherwise let him talk about the DMC exit or that gorons are saved + if (!Flags_GetInfTable(INFTABLE_STOPPED_GORON_LINKS_ROLLING)) { + *textId = 0x3030; + } else if (!Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED)) { + *textId = 0x3036; + } else if (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { + *textId = 0x3041; + } else { + *textId = Flags_GetInfTable(INFTABLE_SPOKE_TO_GORON_LINK) ? 0x3038 : 0x3037; + } + break; + } + case GI_VB_EN_GO2_RESET_AFTER_GET_ITEM: { + EnGo2* enGo2 = static_cast(optionalArg); + // For randomizer, handle updating the states for the gorons after receiving the item based on + // the goron type rather then the item being received + switch (enGo2->actor.params & 0x1F) { + case GORON_DMT_BIGGORON: + // Resolves #1301. unk_13EE is used to set the opacity of the HUD. The trade sequence discussion + // with Biggoron sets the HUD to transparent, and it is restored at z_message_PAL:3549, but by + // specifically watching for trade sequence items, this leaves it transparent for non-trade sequence + // items (in rando) so we fix that here + gSaveContext.unk_13EE = 0x32; + break; + case GORON_CITY_LINK: + EnGo2_GetItemAnimation(enGo2, gPlayState); + break; + case GORON_CITY_ROLLING_BIG: + EnGo2_RollingAnimation(enGo2, gPlayState); + enGo2->actionFunc = (EnGo2ActionFunc)EnGo2_GoronRollingBigContinueRolling; + break; + default: + enGo2->actionFunc = func_80A46B40; + break; + } + break; + } + case GI_VB_GIVE_ITEM_FROM_ITEM_00: { + EnItem00* item00 = static_cast(optionalArg); + if (item00->actor.params == ITEM00_SOH_DUMMY) { + Flags_SetCollectible(gPlayState, item00->collectibleFlag); + Actor_Kill(&item00->actor); + *should = false; + } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY) { + Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + if (item00->itemEntry.modIndex == MOD_NONE) { + if (item00->itemEntry.getItemId == GI_SWORD_BGS) { + gSaveContext.bgsFlag = true; + } + Item_Give(gPlayState, item00->itemEntry.itemId); + } else if (item00->itemEntry.modIndex == MOD_RANDOMIZER) { + if (item00->itemEntry.getItemId == RG_ICE_TRAP) { + gSaveContext.pendingIceTrapCount++; + } else { + Randomizer_Item_Give(gPlayState, item00->itemEntry); + } + } + // EnItem00_SetupAction(item00, func_8001E5C8); + // *should = false; + } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) { + if (!Actor_HasParent(&item00->actor, gPlayState)) { + GiveItemEntryFromActorWithFixedRange(&item00->actor, gPlayState, item00->itemEntry); + } + EnItem00_SetupAction(item00, func_8001E5C8); + *should = false; + } + break; + } + case GI_VB_BE_ELIGIBLE_FOR_SARIAS_SONG: { + *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SARIAS_SONG); + break; + } + case GI_VB_GIVE_ITEM_FROM_COW: { + if (!RAND_GET_OPTION(RSK_SHUFFLE_COWS)) { + break; + } + EnCow* enCow = static_cast(optionalArg); + CowIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow(gPlayState->sceneNum, enCow->actor.world.pos.x, enCow->actor.world.pos.z); + // Has this cow already rewarded an item? + if (Flags_GetRandomizerInf(cowIdentity.randomizerInf)) { + break; + } + Flags_SetRandomizerInf(cowIdentity.randomizerInf); + // setting the ocarina mode here prevents intermittent issues + // with the item get not triggering until walking away + gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_00; + *should = false; + break; + } + case GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP: { + if (!EnDs_RandoCanGetGrannyItem()) { + break; + } + // Only setting the inf if we've actually gotten the rando item and not the vanilla blue potion + Flags_SetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP); + *should = false; + break; + } + case GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA: { + EnKz* enKz = static_cast(optionalArg); + // If we aren't setting up the item offer, then we're just checking if it should be possible. + if (enKz->actionFunc != (EnKzActionFunc)EnKz_SetupGetItem) { + // Always give the reward in rando + *should = true; + break; + } + *should = false; + break; + } + case GI_VB_GIVE_ITEM_FROM_ANJU_AS_CHILD: { + Flags_SetItemGetInf(ITEMGETINF_0C); + *should = false; + break; + } + case GI_VB_GIVE_ITEM_FROM_ANJU_AS_ADULT: { + Flags_SetItemGetInf(ITEMGETINF_2C); + *should = false; + break; + } + case GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_ADULT: { + EnGo2* enGo2 = static_cast(optionalArg); + *should = false; + if (!Flags_GetRandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT)) { + Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); + enGo2->interactInfo.talkState = NPC_TALK_STATE_ACTION; + } + break; + } + case GI_VB_GIVE_ITEM_FROM_CARPET_SALESMAN: { + *should = RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_OFF || + // If the rando check has already been awarded, use vanilla behavior. + Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); + break; + } + case GI_VB_GIVE_ITEM_FROM_MEDIGORON: { + // fallthrough + case GI_VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE: + if (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && + !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { + if (id == GI_VB_GIVE_ITEM_FROM_MEDIGORON) { + Flags_SetInfTable(INFTABLE_B1); + *should = false; + } else { + // Resets "Talked to Medigoron" flag in infTable to restore initial conversation state + Flags_UnsetInfTable(INFTABLE_B1); + *should = true; + } + } + break; + } + case GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN: { + EnMs* enMs = static_cast(optionalArg); + if (RAND_GET_OPTION(RSK_SHUFFLE_MAGIC_BEANS)) { + Rupees_ChangeBy(-60); + BEANS_BOUGHT = 10; + // Only set inf for buying rando check + Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN); + enMs->actionFunc = (EnMsActionFunc)EnMs_Wait; + *should = false; + } + break; + } + case GI_VB_GIVE_ITEM_FROM_FROGS: { + EnFr* enFr = static_cast(optionalArg); + + // Skip GiveReward+SetIdle action func if the reward is an ice trap + if (enFr->actionFunc == (EnFrActionFunc)EnFr_GiveReward) { + RandomizerCheck rc = EnFr_RandomizerCheckFromSongIndex(enFr->songIndex); + GetItemEntry gi = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + if (gi.getItemId == RG_ICE_TRAP) { + enFr->actionFunc = (EnFrActionFunc)EnFr_Idle; + } + } + + *should = false; + break; + } + case GI_VB_TRADE_POCKET_CUCCO: { + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_POCKET_CUCCO); + // Trigger the reward now + Flags_SetItemGetInf(ITEMGETINF_2E); + *should = false; + break; + } + case GI_VB_TRADE_COJIRO: { + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_COJIRO); + *should = false; + break; + } + case GI_VB_TRADE_ODD_MUSHROOM: { + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_ODD_MUSHROOM); + // Trigger the reward now + Flags_SetItemGetInf(ITEMGETINF_30); + *should = false; + break; + } + case GI_VB_TRADE_ODD_POTION: { + EnKo* enKo = static_cast(optionalArg); + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_ODD_POTION); + // Trigger the reward now + Flags_SetItemGetInf(ITEMGETINF_31); + *should = false; + break; + } + case GI_VB_TRADE_SAW: { + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_SAW); + *should = false; + break; + } + case GI_VB_TRADE_PRESCRIPTION: { + EnKz* enKz = static_cast(optionalArg); + // If we aren't setting up the item offer, then we're just checking if it should be possible. + if (enKz->actionFunc != (EnKzActionFunc)EnKz_SetupGetItem) { + *should = !Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); + break; + } + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); + *should = false; + break; + } + case GI_VB_TRADE_FROG: { + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_FROG); + *should = false; + break; + } + case GI_VB_TRADE_BROKEN_SWORD: { + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_SWORD_BROKEN); + *should = false; + break; + } + case GI_VB_TRADE_EYEDROPS: { + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_EYEDROPS); + *should = false; + break; + } + case GI_VB_DESPAWN_HORSE_RACE_COW: { + if (!RAND_GET_OPTION(RSK_SHUFFLE_COWS)) { + break; + } + EnCow* enCow = static_cast(optionalArg); + // If this is a cow we have to move, then move it now. + EnCow_MoveForRandomizer(enCow, gPlayState); + break; + } + case GI_VB_BUSINESS_SCRUB_DESPAWN: { + EnShopnuts* enShopnuts = static_cast(optionalArg); + s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); + ScrubIdentity scrubIdentity = OTRGlobals::Instance->gRandomizer->IdentifyScrub(gPlayState->sceneNum, enShopnuts->actor.params, respawnData); + + if (scrubIdentity.isShuffled) { + *should = Flags_GetRandomizerInf(scrubIdentity.randomizerInf); + } + break; + } + case GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB: { + EnDns* enDns = static_cast(optionalArg); + *should = !enDns->sohScrubIdentity.isShuffled; + break; + } + // To explain the logic because Fado and Grog are linked: + // - If you have Cojiro, then spawn Grog and not Fado. + // - If you don't have Cojiro but do have Odd Potion, spawn Fado and not Grog. + // - If you don't have either, spawn Grog if you haven't traded the Odd Mushroom. + // - If you don't have either but have traded the mushroom, don't spawn either. + case GI_VB_DESPAWN_GROG: { + if (!RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE)) { + break; + } + if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { + *should = false; + } else if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION)) { + *should = true; + } else { + *should = Flags_GetItemGetInf(ITEMGETINF_30); // Traded odd mushroom + } + break; + } + case GI_VB_SPAWN_LW_FADO: { + if (!RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE)) { + break; + } + + if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { + *should = false; + } else { + *should = PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION); + } + + break; + } + case GI_VB_USE_EYEDROP_DIALOGUE: { + // Skip eye drop text on rando if Link went in the water, so you can still receive the dive check + EnMk* enMk = static_cast(optionalArg); + *should &= enMk->swimFlag == 0; + break; + } + case GI_VB_OFFER_BLUE_POTION: { + // Always offer blue potion when adult trade is off + *should |= RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF; + break; + } + case GI_VB_NEED_BOTTLE_FOR_GRANNYS_ITEM: { + // Allow buying the rando item regardless of having a bottle + *should &= !EnDs_RandoCanGetGrannyItem(); + break; + } + case GI_VB_TRADE_CLAIM_CHECK: + case GI_VB_TRADE_TIMER_ODD_MUSHROOM: + case GI_VB_TRADE_TIMER_EYEDROPS: + case GI_VB_TRADE_TIMER_FROG: + case GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM: + case GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD: + case GI_VB_GIVE_ITEM_FROM_LAB_DIVE: + case GI_VB_GIVE_ITEM_SKULL_TOKEN: + case GI_VB_GIVE_ITEM_FROM_BLUE_WARP: + case GI_VB_GIVE_ITEM_FAIRY_OCARINA: + case GI_VB_GIVE_ITEM_WEIRD_EGG: + case GI_VB_GIVE_ITEM_LIGHT_ARROW: + case GI_VB_GIVE_ITEM_STRENGTH_1: + case GI_VB_GIVE_ITEM_ZELDAS_LETTER: + case GI_VB_GIVE_ITEM_OCARINA_OF_TIME: + case GI_VB_GIVE_ITEM_KOKIRI_EMERALD: + case GI_VB_GIVE_ITEM_GORON_RUBY: + case GI_VB_GIVE_ITEM_ZORA_SAPPHIRE: + case GI_VB_GIVE_ITEM_LIGHT_MEDALLION: + case GI_VB_GIVE_ITEM_FOREST_MEDALLION: + case GI_VB_GIVE_ITEM_FIRE_MEDALLION: + case GI_VB_GIVE_ITEM_WATER_MEDALLION: + case GI_VB_GIVE_ITEM_SPIRIT_MEDALLION: + case GI_VB_GIVE_ITEM_SHADOW_MEDALLION: + *should = false; + break; + } +} + +void RandomizerOnSceneInitHandler(int16_t sceneNum) { + // LACs & Prelude checks + static uint32_t updateHook = 0; + + if (updateHook) { + GameInteractor::Instance->UnregisterGameHook(updateHook); + updateHook = 0; + } + + if ( + sceneNum != SCENE_TEMPLE_OF_TIME || + ( + Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && + Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) + ) + ) return; + + updateHook = GameInteractor::Instance->RegisterGameHook([]() { + if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && gPlayState->roomCtx.curRoom.num == 0) { + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); + } + + if (!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && MeetsLACSRequirements()) { + Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + } + + if ( + Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && + Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) + ) { + GameInteractor::Instance->UnregisterGameHook(updateHook); + } + }); +} + +void EnSi_DrawRandomizedItem(EnSi* enSi, PlayState* play) { + func_8002ED80(&enSi->actor, play, 0); + func_8002EBCC(&enSi->actor, play, 0); + EnItem00_CustomItemsParticles(&enSi->actor, play, enSi->sohGetItemEntry); + GetItemEntry_Draw(play, enSi->sohGetItemEntry); +} + +u32 EnDns_RandomizerPurchaseableCheck(EnDns* enDns) { + if (Flags_GetRandomizerInf(enDns->sohScrubIdentity.randomizerInf)) { + return 3; // Can't get this now + } + if (gSaveContext.rupees < enDns->dnsItemEntry->itemPrice) { + return 0; // Not enough rupees + } + return 4; +} + +void EnDns_RandomizerPurchase(EnDns* enDns) { + Rupees_ChangeBy(-enDns->dnsItemEntry->itemPrice); + Flags_SetRandomizerInf(enDns->sohScrubIdentity.randomizerInf); +} + +void RandomizerOnActorInitHandler(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id == ACTOR_EN_SI) { + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(actor->id, gPlayState->sceneNum, actor->params); + if (rc != RC_UNKNOWN_CHECK) { + EnSi* enSi = static_cast(actorRef); + enSi->sohGetItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + actor->draw = (ActorFunc)EnSi_DrawRandomizedItem; + } + } + + if (actor->id == ACTOR_ITEM_B_HEART) { + ItemBHeart* itemBHeart = static_cast(actorRef); + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(itemBHeart->actor.id, gPlayState->sceneNum, itemBHeart->actor.params); + if (rc != RC_UNKNOWN_CHECK) { + itemBHeart->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + itemBHeart->actor.draw = (ActorFunc)ItemBHeart_DrawRandomizedItem; + itemBHeart->actor.update = (ActorFunc)ItemBHeart_UpdateRandomizedItem; + } + } + + if (actor->id == ACTOR_EN_DNS) { + EnDns* enDns = static_cast(actorRef); + s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); + enDns->sohScrubIdentity = OTRGlobals::Instance->gRandomizer->IdentifyScrub(gPlayState->sceneNum, enDns->actor.params, respawnData); + + if (enDns->sohScrubIdentity.isShuffled) { + // DNS uses pointers so we're creating our own entry instead of modifying the original + enDns->sohDnsItemEntry = { + enDns->dnsItemEntry->itemPrice, + 1, + enDns->sohScrubIdentity.getItemId, + EnDns_RandomizerPurchaseableCheck, + EnDns_RandomizerPurchase, + }; + enDns->dnsItemEntry = &enDns->sohDnsItemEntry; + + if (enDns->sohScrubIdentity.itemPrice != -1) { + enDns->dnsItemEntry->itemPrice = enDns->sohScrubIdentity.itemPrice; + } + + enDns->actor.textId = TEXT_SCRUB_RANDOM; + + static uint32_t enDnsUpdateHook = 0; + static uint32_t enDnsKillHook = 0; + if (!enDnsUpdateHook) { + enDnsUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_EN_DNS) { + EnDns* innerEnDns = static_cast(innerActorRef); + if (innerEnDns->sohScrubIdentity.isShuffled) { + innerActor->textId = TEXT_SCRUB_RANDOM; + } + } + }); + enDnsKillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + GameInteractor::Instance->UnregisterGameHook(enDnsUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enDnsKillHook); + enDnsUpdateHook = 0; + enDnsKillHook = 0; + }); + } + } + } +} + +void RandomizerRegisterHooks() { + static uint32_t onFlagSetHook = 0; + static uint32_t onSceneFlagSetHook = 0; + static uint32_t onPlayerUpdateForRCQueueHook = 0; + static uint32_t onPlayerUpdateForItemQueueHook = 0; + static uint32_t onItemReceiveHook = 0; + static uint32_t onVanillaBehaviorHook = 0; + static uint32_t onSceneInitHook = 0; + static uint32_t onActorInitHook = 0; + + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + randomizerQueuedChecks = std::queue(); + randomizerQueuedCheck = RC_UNKNOWN_CHECK; + randomizerQueuedItemEntry = GET_ITEM_NONE; + + GameInteractor::Instance->UnregisterGameHook(onFlagSetHook); + GameInteractor::Instance->UnregisterGameHook(onSceneFlagSetHook); + GameInteractor::Instance->UnregisterGameHook(onPlayerUpdateForRCQueueHook); + GameInteractor::Instance->UnregisterGameHook(onPlayerUpdateForItemQueueHook); + GameInteractor::Instance->UnregisterGameHook(onItemReceiveHook); + GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); + GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); + GameInteractor::Instance->UnregisterGameHook(onActorInitHook); + + onFlagSetHook = 0; + onSceneFlagSetHook = 0; + onPlayerUpdateForRCQueueHook = 0; + onPlayerUpdateForItemQueueHook = 0; + onItemReceiveHook = 0; + onVanillaBehaviorHook = 0; + onSceneInitHook = 0; + onActorInitHook = 0; + + if (!IS_RANDO) return; + + onFlagSetHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnFlagSetHandler); + onSceneFlagSetHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneFlagSetHandler); + onPlayerUpdateForRCQueueHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateForRCQueueHandler); + onPlayerUpdateForItemQueueHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateForItemQueueHandler); + onItemReceiveHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnItemReceiveHandler); + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnVanillaBehaviorHandler); + onSceneInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); + onActorInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); + }); +} diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.h b/soh/soh/Enhancements/randomizer/hook_handlers.h new file mode 100644 index 000000000..46abb30b7 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/hook_handlers.h @@ -0,0 +1,6 @@ +#ifndef RANDOMIZER_HOOK_HANDLERS_H +#define RANDOMIZER_HOOK_HANDLERS_H + +void RandomizerRegisterHooks(); + +#endif // RANDOMIZER_HOOK_HANDLERS_H \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/item_location.cpp b/soh/soh/Enhancements/randomizer/item_location.cpp index 736778786..adc805550 100644 --- a/soh/soh/Enhancements/randomizer/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/item_location.cpp @@ -101,6 +101,18 @@ void ItemLocation::SetCustomPrice(const uint16_t price_) { hasCustomPrice = true; } +bool ItemLocation::HasObtained() const { + return obtained; +} + +void ItemLocation::MarkAsObtained() { + obtained = true; +} + +void ItemLocation::MarkAsNotObtained() { + obtained = false; +} + bool ItemLocation::IsHintable() const { return isHintable; } @@ -201,5 +213,6 @@ void ItemLocation::ResetVariables() { wothCandidate = false; barrenCandidate = false; area = RA_NONE; + obtained = false; } } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/item_location.h b/soh/soh/Enhancements/randomizer/item_location.h index a4b60a5d3..ab74b2d77 100644 --- a/soh/soh/Enhancements/randomizer/item_location.h +++ b/soh/soh/Enhancements/randomizer/item_location.h @@ -31,6 +31,9 @@ class ItemLocation { void SetPrice(uint16_t price_); bool HasCustomPrice() const; void SetCustomPrice(uint16_t price_); + bool HasObtained() const; + void MarkAsObtained(); + void MarkAsNotObtained(); bool IsHintable() const; void SetAsHintable(); bool IsHintedAt() const; @@ -67,5 +70,6 @@ class ItemLocation { bool visibleInImGui = false; bool wothCandidate = false; bool barrenCandidate = false; + bool obtained = false; }; } // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index 993e8c184..fcea02eb4 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -51,10 +51,6 @@ class SpoilerCollectionCheck { return SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene, flag); } - static auto Cow(const uint8_t scene, const uint8_t flag) { - return SpoilerCollectionCheck(SPOILER_CHK_COW, scene, flag); - } - static auto Fish(const uint8_t flag, const uint8_t scene = SCENE_FISHING_POND) { return SpoilerCollectionCheck(SPOILER_CHK_FISH, scene, flag); } @@ -63,10 +59,6 @@ class SpoilerCollectionCheck { return SpoilerCollectionCheck(SPOILER_CHK_MINIGAME, 0x00, bit); } - static auto Scrub(const uint8_t scene, const uint8_t bit) { - return SpoilerCollectionCheck(SPOILER_CHK_SCRUB, scene, bit); - } - static auto GerudoToken() { return SpoilerCollectionCheck(SPOILER_CHK_GERUDO_MEMBERSHIP_CARD, 0x00, 0x00); } @@ -83,20 +75,12 @@ class SpoilerCollectionCheck { return SpoilerCollectionCheck(SPOILER_CHK_SHOP_ITEM, scene, itemSlot); } - static auto MagicBeans(const uint8_t scene, const uint8_t flag) { - return SpoilerCollectionCheck(SPOILER_CHK_MAGIC_BEANS, scene, flag); - } - static auto MasterSword() { return SpoilerCollectionCheck(SPOILER_CHK_MASTER_SWORD, 0x00, 0x00); } - static auto Merchant(const int8_t scene, const uint8_t flag) { - return SpoilerCollectionCheck(SPOILER_CHK_MERCHANT, scene, flag); - } - - static auto RandomizerInf(const int8_t scene, const uint8_t flag) { - return SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, scene, flag); + static auto RandomizerInf(const uint8_t flag) { + return SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, 0x00, flag); } }; diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index ea4775d46..28ca3b85a 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -245,6 +245,7 @@ std::vector Rando::StaticData::overworldLocations = { RC_TOT_MASTER_SWORD, RC_SHEIK_AT_TEMPLE, RC_TOT_LIGHT_ARROWS_CUTSCENE, + RC_GIFT_FROM_SAGES, // Kakariko RC_SHEIK_IN_KAKARIKO, @@ -595,786 +596,773 @@ typedef enum { using namespace Rando; -void Rando::StaticData::InitLocationTable() { +void Rando::StaticData::InitLocationTable() { // Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression // clang-format off - locationTable[RC_UNKNOWN_CHECK] = Location::Base(RC_UNKNOWN_CHECK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_INVALID, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Invalid Location", "Invalid Location", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None()); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression + locationTable[RC_UNKNOWN_CHECK] = Location::Base(RC_UNKNOWN_CHECK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_INVALID, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Invalid Location", "Invalid Location", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None()); // Kokiri Forest - locationTable[RC_KF_KOKIRI_SWORD_CHEST] = Location::Chest(RC_KF_KOKIRI_SWORD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_KOKIRI_FOREST, 1248, 0x00, "Kokiri Sword Chest", "KF Kokiri Sword Chest", RHT_KF_KOKIRI_SWORD_CHEST, RG_KOKIRI_SWORD, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, true); - locationTable[RC_KF_MIDOS_TOP_LEFT_CHEST] = Location::Chest(RC_KF_MIDOS_TOP_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22944, 0x00, "Mido Top Left Chest", "KF Mido Top Left Chest", RHT_KF_MIDOS_TOP_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_MIDOS_TOP_RIGHT_CHEST] = Location::Chest(RC_KF_MIDOS_TOP_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22945, 0x01, "Mido Top Right Chest", "KF Mido Top Right Chest", RHT_KF_MIDOS_TOP_RIGHT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_MIDOS_BOTTOM_LEFT_CHEST] = Location::Chest(RC_KF_MIDOS_BOTTOM_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22914, 0x02, "Mido Bottom Left Chest", "KF Mido Bottom Left Chest", RHT_KF_MIDOS_BOTTOM_LEFT_CHEST, RG_GREG_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_MIDOS_BOTTOM_RIGHT_CHEST] = Location::Chest(RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22787, 0x03, "Mido Bottom Right Chest", "KF Mido Bottom Right Chest", RHT_KF_MIDOS_BOTTOM_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_STORMS_GROTTO_CHEST] = Location::Chest(RC_KF_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_GROTTOS, 22988, 0x0C, "Storms Grotto Chest", "KF Storms Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_KOKIRI_SWORD_CHEST] = Location::Chest(RC_KF_KOKIRI_SWORD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_KOKIRI_FOREST, 1248, 0x00, "Kokiri Sword Chest", "KF Kokiri Sword Chest", RHT_KF_KOKIRI_SWORD_CHEST, RG_KOKIRI_SWORD, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, true); + locationTable[RC_KF_MIDOS_TOP_LEFT_CHEST] = Location::Chest(RC_KF_MIDOS_TOP_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22944, 0x00, "Mido Top Left Chest", "KF Mido Top Left Chest", RHT_KF_MIDOS_TOP_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_MIDOS_TOP_RIGHT_CHEST] = Location::Chest(RC_KF_MIDOS_TOP_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22945, 0x01, "Mido Top Right Chest", "KF Mido Top Right Chest", RHT_KF_MIDOS_TOP_RIGHT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_MIDOS_BOTTOM_LEFT_CHEST] = Location::Chest(RC_KF_MIDOS_BOTTOM_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22914, 0x02, "Mido Bottom Left Chest", "KF Mido Bottom Left Chest", RHT_KF_MIDOS_BOTTOM_LEFT_CHEST, RG_GREG_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_MIDOS_BOTTOM_RIGHT_CHEST] = Location::Chest(RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22787, 0x03, "Mido Bottom Right Chest", "KF Mido Bottom Right Chest", RHT_KF_MIDOS_BOTTOM_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_STORMS_GROTTO_CHEST] = Location::Chest(RC_KF_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_GROTTOS, 22988, 0x0C, "Storms Grotto Chest", "KF Storms Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); // Lost Woods - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST] = Location::Chest(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_EN_BOX, SCENE_GROTTOS, 22964, 0x14, "Near Shortcuts Grotto Chest", "LW Near Shortcuts Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_LW_SKULL_KID] = Location::Base(RC_LW_SKULL_KID, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x3E, "Skull Kid", "LW Skull Kid", RHT_LW_SKULL_KID, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(30), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_TRADE_COJIRO] = Location::Base(RC_LW_TRADE_COJIRO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x1F, "Trade Cojiro", "LW Trade Cojiro", RHT_LW_TRADE_COJIRO, RG_ODD_MUSHROOM, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(0x5B, 0x1F), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_TRADE_ODD_POTION] = Location::Base(RC_LW_TRADE_ODD_POTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x21, "Trade Odd Potion", "LW Trade Odd Potion", RHT_LW_TRADE_COJIRO, RG_POACHERS_SAW, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(57), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_OCARINA_MEMORY_GAME] = Location::Base(RC_LW_OCARINA_MEMORY_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x21, "Ocarina Memory Game", "LW Ocarina Memory Game", RHT_LW_OCARINA_MEMORY_GAME, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(31), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_TARGET_IN_WOODS] = Location::Base(RC_LW_TARGET_IN_WOODS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x60, "Target in Woods", "LW Target in Woods", RHT_LW_TARGET_IN_WOODS, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT,RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x00, 0x30, "Deku Scrub Near Deku Theater Right","LW Deku Scrub Near Deku Theater Right",RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT,RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x5B, 0x01), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, 0x31, "Deku Scrub Near Deku Theater Left", "LW Deku Scrub Near Deku Theater Left", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x5B, 0x02), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, 0x77, "Deku Scrub Near Bridge", "LW Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE,{ Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::Scrub(0x5B, 0x0A), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), 0x33, "Deku Scrub Grotto Rear", "LW Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x1F, 0x04), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), 0x79, "Deku Scrub Grotto Front", "LW Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::Scrub(0x1F, 0x0B), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x77, "Deku Theater Skull Mask", "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE,{}, SpoilerCollectionCheck::Chest(0x3E, 0x1F), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x7A, "Deku Theater Mask of Truth", "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, {}, SpoilerCollectionCheck::Chest(0x3E, 0x1E), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST] = Location::Chest(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_EN_BOX, SCENE_GROTTOS, 22964, 0x14, "Near Shortcuts Grotto Chest", "LW Near Shortcuts Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_LW_SKULL_KID] = Location::Base(RC_LW_SKULL_KID, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x3E, "Skull Kid", "LW Skull Kid", RHT_LW_SKULL_KID, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(22), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_LW_TRADE_COJIRO] = Location::Base(RC_LW_TRADE_COJIRO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x1F, "Trade Cojiro", "LW Trade Cojiro", RHT_LW_TRADE_COJIRO, RG_ODD_MUSHROOM, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_LW_TRADE_ODD_POTION] = Location::Base(RC_LW_TRADE_ODD_POTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x21, "Trade Odd Potion", "LW Trade Odd Potion", RHT_LW_TRADE_COJIRO, RG_POACHERS_SAW, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(49), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_LW_OCARINA_MEMORY_GAME] = Location::Base(RC_LW_OCARINA_MEMORY_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x21, "Ocarina Memory Game", "LW Ocarina Memory Game", RHT_LW_OCARINA_MEMORY_GAME, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(23), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_LW_TARGET_IN_WOODS] = Location::Base(RC_LW_TARGET_IN_WOODS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x60, "Target in Woods", "LW Target in Woods", RHT_LW_TARGET_IN_WOODS, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x00, 0x30, "Deku Scrub Near Deku Theater Right", "LW Deku Scrub Near Deku Theater Right", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, 0x31, "Deku Scrub Near Deku Theater Left", "LW Deku Scrub Near Deku Theater Left", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, 0x77, "Deku Scrub Near Bridge", "LW Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), 0x33, "Deku Scrub Grotto Rear", "LW Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), 0x79, "Deku Scrub Grotto Front", "LW Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x77, "Deku Theater Skull Mask", "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, {}, SpoilerCollectionCheck::Chest(0x3E, 0x1F), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x7A, "Deku Theater Mask of Truth", "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, {}, SpoilerCollectionCheck::Chest(0x3E, 0x1E), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); // Sacred Forest Meadow - locationTable[RC_SFM_WOLFOS_GROTTO_CHEST] = Location::Chest(RC_SFM_WOLFOS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, 0x11, "Wolfos Grotto Chest", "SFM Wolfos Grotto Chest", RHT_SFM_WOLFOS_GROTTO_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), 0x39, "Deku Scrub Grotto Rear", "SFM Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x18, 0x08), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_SFM_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEE), 0x3A, "Deku Scrub Grotto Front", "SFM Deku Scrub Grotto Front", RHT_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x18, 0x09), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_SFM_WOLFOS_GROTTO_CHEST] = Location::Chest(RC_SFM_WOLFOS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, 0x11, "Wolfos Grotto Chest", "SFM Wolfos Grotto Chest", RHT_SFM_WOLFOS_GROTTO_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), 0x39, "Deku Scrub Grotto Rear", "SFM Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_SFM_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEE), 0x3A, "Deku Scrub Grotto Front", "SFM Deku Scrub Grotto Front", RHT_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); // Hyrule Field - locationTable[RC_HF_SOUTHEAST_GROTTO_CHEST] = Location::Chest(RC_HF_SOUTHEAST_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22978, 0x02, "Southeast Grotto Chest", "HF Southeast Grotto Chest", RHT_HF_SOUTHEAST_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_OPEN_GROTTO_CHEST] = Location::Chest(RC_HF_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22947, 0x03, "Open Grotto Chest", "HF Open Grotto Chest", RHT_HF_OPEN_GROTTO_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_NEAR_MARKET_GROTTO_CHEST] = Location::Chest(RC_HF_NEAR_MARKET_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22944, 0x00, "Near Market Grotto Chest", "HF Near Market Grotto Chest", RHT_HF_NEAR_MARKET_GROTTO_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_OCARINA_OF_TIME_ITEM] = Location::Base(RC_HF_OCARINA_OF_TIME_ITEM, RCQUEST_BOTH, RCTYPE_OCARINA, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, 0x0C, "Ocarina of Time Item", "HF Ocarina of Time Item", RHT_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0x43), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_TEKTITE_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_ITEM00, SCENE_GROTTOS, 262, 0x01, "Tektite Grotto Freestanding PoH", "HF Tektite Grotto Freestanding PoH", RHT_HF_TEKTITE_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); - locationTable[RC_HF_DEKU_SCRUB_GROTTO] = Location::GrottoScrub(RC_HF_DEKU_SCRUB_GROTTO, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_HYRULE_FIELD, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x02, 0xE6), 0x3E, "Deku Scrub Grotto", "HF Deku Scrub Grotto", RHT_HF_DEKU_SCRUB_GROTTO, RG_PIECE_OF_HEART, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::Scrub(0x10, 0x03), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); + locationTable[RC_HF_SOUTHEAST_GROTTO_CHEST] = Location::Chest(RC_HF_SOUTHEAST_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22978, 0x02, "Southeast Grotto Chest", "HF Southeast Grotto Chest", RHT_HF_SOUTHEAST_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_OPEN_GROTTO_CHEST] = Location::Chest(RC_HF_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22947, 0x03, "Open Grotto Chest", "HF Open Grotto Chest", RHT_HF_OPEN_GROTTO_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_NEAR_MARKET_GROTTO_CHEST] = Location::Chest(RC_HF_NEAR_MARKET_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22944, 0x00, "Near Market Grotto Chest", "HF Near Market Grotto Chest", RHT_HF_NEAR_MARKET_GROTTO_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_OCARINA_OF_TIME_ITEM] = Location::Base(RC_HF_OCARINA_OF_TIME_ITEM, RCQUEST_BOTH, RCTYPE_OCARINA, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, 0x0C, "Ocarina of Time Item", "HF Ocarina of Time Item", RHT_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0x43), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_TEKTITE_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_ITEM00, SCENE_GROTTOS, 262, 0x01, "Tektite Grotto Freestanding PoH", "HF Tektite Grotto Freestanding PoH", RHT_HF_TEKTITE_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); + locationTable[RC_HF_DEKU_SCRUB_GROTTO] = Location::GrottoScrub(RC_HF_DEKU_SCRUB_GROTTO, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_HYRULE_FIELD, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x02, 0xE6), 0x3E, "Deku Scrub Grotto", "HF Deku Scrub Grotto", RHT_HF_DEKU_SCRUB_GROTTO, RG_PIECE_OF_HEART, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); // Lake Hylia - locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x3E, "Child Fishing", "LH Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::RandomizerInf(SCENE_FISHING_POND, RAND_INF_CHILD_FISHING), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x38, "Adult Fishing", "LH Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(SCENE_FISHING_POND, RAND_INF_ADULT_FISHING), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_LAB_DIVE] = Location::Base(RC_LH_LAB_DIVE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, 0x3E, "Lab Dive", "LH Lab Dive", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(24), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_TRADE_FROG] = Location::Base(RC_LH_TRADE_FROG, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, 0x25, "Lab Trade Eyeball Frog", "LH Lab Trade Eyeball Frog", RHT_LH_TRADE_FROG, RG_EYEDROPS, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(0x38, 0x1F), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, 0x15, "Underwater Item", "LH Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x31), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_SUN] = Location::Base(RC_LH_SUN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, 0x58, "Sun", "LH Sun", RHT_LH_SUN, RG_FIRE_ARROWS, {}, SpoilerCollectionCheck::Chest(0x57, 0x1F), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_FREESTANDING_POH] = Location::Collectable(RC_LH_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, 7686, 0x1E, "Freestanding PoH", "LH Freestanding PoH", RHT_LH_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xEF), 0x30, "Deku Scrub Grotto Left", "LH Deku Scrub Grotto Left", RHT_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x19, 0x01), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xEF), 0x37, "Deku Scrub Grotto Right", "LH Deku Scrub Grotto Right", RHT_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x19, 0x06), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xEF), 0x33, "Deku Scrub Grotto Center", "LH Deku Scrub Grotto Center", RHT_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x19, 0x04), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x3E, "Child Fishing", "LH Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CHILD_FISHING), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); + locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x38, "Adult Fishing", "LH Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_FISHING), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); + locationTable[RC_LH_LAB_DIVE] = Location::Base(RC_LH_LAB_DIVE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, 0x3E, "Lab Dive", "LH Lab Dive", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(16), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); + locationTable[RC_LH_TRADE_FROG] = Location::Base(RC_LH_TRADE_FROG, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, 0x25, "Lab Trade Eyeball Frog", "LH Lab Trade Eyeball Frog", RHT_LH_TRADE_FROG, RG_EYEDROPS, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); + locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, 0x15, "Underwater Item", "LH Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x31), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); + locationTable[RC_LH_SUN] = Location::Base(RC_LH_SUN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, 0x58, "Sun", "LH Sun", RHT_LH_SUN, RG_FIRE_ARROWS, {}, SpoilerCollectionCheck::Chest(0x57, 0x1F), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); + locationTable[RC_LH_FREESTANDING_POH] = Location::Collectable(RC_LH_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, 7686, 0x1E, "Freestanding PoH", "LH Freestanding PoH", RHT_LH_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xEF), 0x30, "Deku Scrub Grotto Left", "LH Deku Scrub Grotto Left", RHT_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xEF), 0x37, "Deku Scrub Grotto Right", "LH Deku Scrub Grotto Right", RHT_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xEF), 0x33, "Deku Scrub Grotto Center", "LH Deku Scrub Grotto Center", RHT_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); // Gerudo Valley - locationTable[RC_GV_CHEST] = Location::Chest(RC_GV_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_BOX, SCENE_GERUDO_VALLEY, 23200, 0x00, "Chest", "GV Chest", RHT_GV_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_TRADE_SAW] = Location::Base(RC_GV_TRADE_SAW, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_GERUDO_VALLEY, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, 0x22, "Trade Saw", "GV Trade Saw", RHT_GV_TRADE_SAW, RG_BROKEN_SWORD, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(0x5A, 0x1F), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GV_WATERFALL_FREESTANDING_POH] = Location::Collectable(RC_GV_WATERFALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 262, 0x01, "Waterfall Freestanding PoH", "GV Waterfall Freestanding PoH", RHT_GV_WATERFALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GV_CRATE_FREESTANDING_POH] = Location::Collectable(RC_GV_CRATE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 518, 0x02, "Crate Freestanding PoH", "GV Crate Freestanding PoH", RHT_GV_CRATE_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xF0), 0x39, "Deku Scrub Grotto Rear", "GV Deku Scrub Grotto Rear", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x1A, 0x09), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), 0x3A, "Deku Scrub Grotto Front", "GV Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x1A, 0x09), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_CHEST] = Location::Chest(RC_GV_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_BOX, SCENE_GERUDO_VALLEY, 23200, 0x00, "Chest", "GV Chest", RHT_GV_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_TRADE_SAW] = Location::Base(RC_GV_TRADE_SAW, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_GERUDO_VALLEY, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, 0x22, "Trade Saw", "GV Trade Saw", RHT_GV_TRADE_SAW, RG_BROKEN_SWORD, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GV_WATERFALL_FREESTANDING_POH] = Location::Collectable(RC_GV_WATERFALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 262, 0x01, "Waterfall Freestanding PoH", "GV Waterfall Freestanding PoH", RHT_GV_WATERFALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GV_CRATE_FREESTANDING_POH] = Location::Collectable(RC_GV_CRATE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 518, 0x02, "Crate Freestanding PoH", "GV Crate Freestanding PoH", RHT_GV_CRATE_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xF0), 0x39, "Deku Scrub Grotto Rear", "GV Deku Scrub Grotto Rear", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), 0x3A, "Deku Scrub Grotto Front", "GV Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); // Gerudo Fortress - locationTable[RC_GF_CHEST] = Location::Chest(RC_GF_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, 0x00, "Chest", "GF Chest", RHT_GF_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x3E, "GF HBA 1000 Points", "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x08), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_HBA_1500_POINTS] = Location::Base(RC_GF_HBA_1500_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x30, "GF HBA 1500 Points", "GF HBA 1500 Points", RHT_GF_HBA_1500_POINTS, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(7), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_CHEST] = Location::Chest(RC_GF_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, 0x00, "Chest", "GF Chest", RHT_GF_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x3E, "GF HBA 1000 Points", "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x08), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_HBA_1500_POINTS] = Location::Base(RC_GF_HBA_1500_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x30, "GF HBA 1500 Points", "GF HBA 1500 Points", RHT_GF_HBA_1500_POINTS, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(15), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); // RandoTodo: Do we replace these with the RC_HIDEOUT keys or keep these? - locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, 0x3A, "GF Gerudo Membership Card", "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::GerudoToken(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_NORTH_F1_CARPENTER] = Location::Collectable(RC_GF_NORTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3089, 0x0C, "GF North F1 Carpenter", "GF North F1 Carpenter", RHT_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY,{ Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_NORTH_F2_CARPENTER] = Location::Collectable(RC_GF_NORTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 2577, 0x0A, "GF North F2 Carpenter", "GF North F2 Carpenter", RHT_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY,{ Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_SOUTH_F1_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3601, 0x0E, "GF South F1 Carpenter", "GF South F1 Carpenter", RHT_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY,{ Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_SOUTH_F2_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3857, 0x0F, "GF South F2 Carpenter", "GF South F2 Carpenter", RHT_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY,{ Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, 0x3A, "GF Gerudo Membership Card", "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::GerudoToken(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_NORTH_F1_CARPENTER] = Location::Collectable(RC_GF_NORTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3089, 0x0C, "GF North F1 Carpenter", "GF North F1 Carpenter", RHT_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_NORTH_F2_CARPENTER] = Location::Collectable(RC_GF_NORTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 2577, 0x0A, "GF North F2 Carpenter", "GF North F2 Carpenter", RHT_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_SOUTH_F1_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3601, 0x0E, "GF South F1 Carpenter", "GF South F1 Carpenter", RHT_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_SOUTH_F2_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3857, 0x0F, "GF South F2 Carpenter", "GF South F2 Carpenter", RHT_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); // Haunted Wasteland - locationTable[RC_WASTELAND_CHEST] = Location::Chest(RC_WASTELAND_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_WASTELAND, ACTOR_EN_BOX, SCENE_HAUNTED_WASTELAND, -30048, 0x00, "Chest", "Wasteland Chest", RHT_WASTELAND_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, 0x03, "Carpet Salesman", "Wasteland Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, { Category::cMerchant }, SpoilerCollectionCheck::Merchant(0x5E, 0x86), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_WASTELAND_CHEST] = Location::Chest(RC_WASTELAND_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_WASTELAND, ACTOR_EN_BOX, SCENE_HAUNTED_WASTELAND, -30048, 0x00, "Chest", "Wasteland Chest", RHT_WASTELAND_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, 0x03, "Carpet Salesman", "Wasteland Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, { Category::cMerchant }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); // Desert Colossus - locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", "Colossus Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), 0x39, "Deku Scrub Grotto Rear", "Colossus Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x27, 0x08), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xFD), 0x3A, "Deku Scrub Grotto Front", "Colossus Deku Scrub Grotto Front", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x27, 0x09), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", "Colossus Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), 0x39, "Deku Scrub Grotto Rear", "Colossus Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xFD), 0x3A, "Deku Scrub Grotto Front", "Colossus Deku Scrub Grotto Front", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); // Market - locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x0A, "Treasure Chest Game Reward", "MK Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(19), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x33, "Bombchu Bowling First Prize", "MK Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(25), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x3E, "Bombchu Bowling Second Prize", "MK Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(26), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x00, "Bombchu Bowling Bombchus", "MK Bombchu Bowling Bombchus", RHT_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RG_BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", "MK Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x09), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", "MK Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", "MK 10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(SCENE_MARKET_GUARD_HOUSE, RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x01, "Chest Game First Room Chest", "MK Chest Game First Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x03, "Chest Game Second Room Chest", "MK Chest Game Second Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x05, "Chest Game Third Room Chest", "MK Chest Game Third Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x07, "Chest Game Fourth Room Chest", "MK Chest Game Fourth Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x09, "Chest Game Fifth Room Chest", "MK Chest Game Fifth Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x0A, "Treasure Chest Game Reward", "MK Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(27), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x33, "Bombchu Bowling First Prize", "MK Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(17), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x3E, "Bombchu Bowling Second Prize", "MK Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x00, "Bombchu Bowling Bombchus", "MK Bombchu Bowling Bombchus", RHT_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RG_BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", "MK Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x09), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", "MK Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(13), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", "MK 10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x01, "Chest Game First Room Chest", "MK Chest Game First Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x03, "Chest Game Second Room Chest", "MK Chest Game Second Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x05, "Chest Game Third Room Chest", "MK Chest Game Third Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x07, "Chest Game Fourth Room Chest", "MK Chest Game Fourth Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x09, "Chest Game Fifth Room Chest", "MK Chest Game Fifth Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); // Hyrule Castle - locationTable[RC_HC_MALON_EGG] = Location::Base(RC_HC_MALON_EGG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, 0x47, "Malon Egg", "HC Malon Egg", RHT_HC_MALON_EGG, RG_WEIRD_EGG, {}, SpoilerCollectionCheck::EventChkInf(0x12), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_HC_ZELDAS_LETTER] = Location::Base(RC_HC_ZELDAS_LETTER, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, 0x0B, "Zeldas Letter", "HC Zeldas Letter", RHT_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x40), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_HC_MALON_EGG] = Location::Base(RC_HC_MALON_EGG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, 0x47, "Malon Egg", "HC Malon Egg", RHT_HC_MALON_EGG, RG_WEIRD_EGG, {}, SpoilerCollectionCheck::EventChkInf(0x12), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_HC_ZELDAS_LETTER] = Location::Base(RC_HC_ZELDAS_LETTER, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, 0x0B, "Zeldas Letter", "HC Zeldas Letter", RHT_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x40), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); // Kakariko - locationTable[RC_KAK_REDEAD_GROTTO_CHEST] = Location::Chest(RC_KAK_REDEAD_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 31434, 0x0A, "Redead Grotto Chest", "Kak Redead Grotto Chest", RHT_KAK_REDEAD_GROTTO_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_OPEN_GROTTO_CHEST] = Location::Chest(RC_KAK_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 22984, 0x08, "Open Grotto Chest", "Kak Open Grotto Chest", RHT_KAK_OPEN_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_10_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_10_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x45, "10 Gold Skulltula Reward", "Kak 10 Gold Skulltula Reward", RHT_KAK_10_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDA), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_20_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_20_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x39, "20 Gold Skulltula Reward", "Kak 20 Gold Skulltula Reward", RHT_KAK_20_GOLD_SKULLTULA_REWARD, RG_STONE_OF_AGONY, {}, SpoilerCollectionCheck::EventChkInf(0xDB), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_30_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_30_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x46, "30 Gold Skulltula Reward", "Kak 30 Gold Skulltula Reward", RHT_KAK_30_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDC), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_40_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_40_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x03, "40 Gold Skulltula Reward", "Kak 40 Gold Skulltula Reward", RHT_KAK_40_GOLD_SKULLTULA_REWARD, RG_BOMBCHU_10, {}, SpoilerCollectionCheck::EventChkInf(0xDD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_50_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_50_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "50 Gold Skulltula Reward", "Kak 50 Gold Skulltula Reward", RHT_KAK_50_GOLD_SKULLTULA_REWARD, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_100_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_100_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "100 Gold Skulltula Reward", "Kak 100 Gold Skulltula Reward", RHT_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(SCENE_HOUSE_OF_SKULLTULA, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x3E, "Man on Roof", "Kak Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x30, "Shooting Gallery Reward", "Kak Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x20, "Trade Odd Mushroom", "Kak Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(56), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x4E, "Granny's Shop", "Kak Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, {}, SpoilerCollectionCheck::RandomizerInf(SCENE_POTION_SHOP_GRANNY, RAND_INF_MERCHANTS_GRANNYS_SHOP), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x1D, "Anju as Adult", "Kak Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(36), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_ANJU_AS_CHILD] = Location::Base(RC_KAK_ANJU_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x0F, "Anju as Child", "Kak Anju as Child", RHT_KAK_ANJU_AS_CHILD, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_TRADE_POCKET_CUCCO] = Location::Base(RC_KAK_TRADE_POCKET_CUCCO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x0E, "Trade Pocket Cucco", "Kak Trade Pocket Cucco", RHT_KAK_TRADE_POCKET_CUCCO, RG_COJIRO, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(38), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_IMPAS_HOUSE_FREESTANDING_POH] = Location::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_ITEM00, SCENE_IMPAS_HOUSE, 262, 0x01, "Impas House Freestanding PoH", "Kak Impas House Freestanding PoH", RHT_KAK_IMPAS_HOUSE_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_WINDMILL_FREESTANDING_POH] = Location::Collectable(RC_KAK_WINDMILL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 262, 0x01, "Windmill Freestanding PoH", "Kak Windmill Freestanding PoH", RHT_KAK_WINDMILL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_REDEAD_GROTTO_CHEST] = Location::Chest(RC_KAK_REDEAD_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 31434, 0x0A, "Redead Grotto Chest", "Kak Redead Grotto Chest", RHT_KAK_REDEAD_GROTTO_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_OPEN_GROTTO_CHEST] = Location::Chest(RC_KAK_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 22984, 0x08, "Open Grotto Chest", "Kak Open Grotto Chest", RHT_KAK_OPEN_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_10_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_10_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x45, "10 Gold Skulltula Reward", "Kak 10 Gold Skulltula Reward", RHT_KAK_10_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDA), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_20_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_20_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x39, "20 Gold Skulltula Reward", "Kak 20 Gold Skulltula Reward", RHT_KAK_20_GOLD_SKULLTULA_REWARD, RG_STONE_OF_AGONY, {}, SpoilerCollectionCheck::EventChkInf(0xDB), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_30_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_30_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x46, "30 Gold Skulltula Reward", "Kak 30 Gold Skulltula Reward", RHT_KAK_30_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDC), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_40_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_40_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x03, "40 Gold Skulltula Reward", "Kak 40 Gold Skulltula Reward", RHT_KAK_40_GOLD_SKULLTULA_REWARD, RG_BOMBCHU_10, {}, SpoilerCollectionCheck::EventChkInf(0xDD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_50_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_50_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "50 Gold Skulltula Reward", "Kak 50 Gold Skulltula Reward", RHT_KAK_50_GOLD_SKULLTULA_REWARD, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_100_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_100_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "100 Gold Skulltula Reward", "Kak 100 Gold Skulltula Reward", RHT_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x3E, "Man on Roof", "Kak Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x30, "Shooting Gallery Reward", "Kak Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x20, "Trade Odd Mushroom", "Kak Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(48), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x4E, "Granny's Shop", "Kak Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x1D, "Anju as Adult", "Kak Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_ANJU_AS_CHILD] = Location::Base(RC_KAK_ANJU_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x0F, "Anju as Child", "Kak Anju as Child", RHT_KAK_ANJU_AS_CHILD, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(12), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_TRADE_POCKET_CUCCO] = Location::Base(RC_KAK_TRADE_POCKET_CUCCO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x0E, "Trade Pocket Cucco", "Kak Trade Pocket Cucco", RHT_KAK_TRADE_POCKET_CUCCO, RG_COJIRO, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(46), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_IMPAS_HOUSE_FREESTANDING_POH] = Location::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_ITEM00, SCENE_IMPAS_HOUSE, 262, 0x01, "Impas House Freestanding PoH", "Kak Impas House Freestanding PoH", RHT_KAK_IMPAS_HOUSE_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_WINDMILL_FREESTANDING_POH] = Location::Collectable(RC_KAK_WINDMILL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 262, 0x01, "Windmill Freestanding PoH", "Kak Windmill Freestanding PoH", RHT_KAK_WINDMILL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); // Graveyard - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_CHEST] = Location::Chest(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN,21824, 0x00, "Shield Grave Chest", "GY Shield Grave Chest", RHT_GRAVEYARD_SHIELD_GRAVE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST] = Location::Chest(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_REDEAD_GRAVE, -22592, 0x00, "Heart Piece Grave Chest", "GY Heart Piece Grave Chest", RHT_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST] = Location::Chest(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_ROYAL_FAMILYS_TOMB, -32736, 0x00, "Composers Grave Chest", "GY Composers Grave Chest", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_GRAVEYARD_HOOKSHOT_CHEST] = Location::Chest(RC_GRAVEYARD_HOOKSHOT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 4352, 0x00, "Hookshot Chest", "GY Hookshot Chest", RHT_GRAVEYARD_HOOKSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_GRAVEYARD_FREESTANDING_POH] = Location::Collectable(RC_GRAVEYARD_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 1030, 0x04, "Freestanding PoH", "GY Freestanding PoH", RHT_GRAVEYARD_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] =Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH,RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1798, 0x07, "Dampe Race Freestanding PoH", "GY Dampe Race Freestanding PoH", RHT_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH,RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = Location::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 6406, 0x08, "Dampe Gravedigging Tour", "GY Dampe Gravedigging Tour", RHT_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::Gravedigger(0x53, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_CHEST] = Location::Chest(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 21824, 0x00, "Shield Grave Chest", "GY Shield Grave Chest", RHT_GRAVEYARD_SHIELD_GRAVE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST] = Location::Chest(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_REDEAD_GRAVE, -22592, 0x00, "Heart Piece Grave Chest", "GY Heart Piece Grave Chest", RHT_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST] = Location::Chest(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_ROYAL_FAMILYS_TOMB, -32736, 0x00, "Composers Grave Chest", "GY Composers Grave Chest", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_GRAVEYARD_HOOKSHOT_CHEST] = Location::Chest(RC_GRAVEYARD_HOOKSHOT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 4352, 0x00, "Hookshot Chest", "GY Hookshot Chest", RHT_GRAVEYARD_HOOKSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_GRAVEYARD_FREESTANDING_POH] = Location::Collectable(RC_GRAVEYARD_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 1030, 0x04, "Freestanding PoH", "GY Freestanding PoH", RHT_GRAVEYARD_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1798, 0x07, "Dampe Race Freestanding PoH", "GY Dampe Race Freestanding PoH", RHT_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = Location::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 6406, 0x19, "Dampe Gravedigging Tour", "GY Dampe Gravedigging Tour", RHT_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); // Death Mountain - locationTable[RC_DMT_CHEST] = Location::Chest(RC_DMT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_DEATH_MOUNTAIN_TRAIL, 23201, 0x01, "Chest", "DMT Chest", RHT_DMT_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_STORMS_GROTTO_CHEST] = Location::Chest(RC_DMT_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_GROTTOS, 23255, 0x17, "Storms Grotto Chest", "DMT Storms Grotto Chest", RHT_DMT_STORMS_GROTTO_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_TRADE_BROKEN_SWORD] = Location::Base(RC_DMT_TRADE_BROKEN_SWORD, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x23, "Trade Broken Sword", "DMT Trade Broken Sword", RHT_DMT_TRADE_BROKEN_SWORD, RG_PRESCRIPTION, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(0x60, 0x1D), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMT_TRADE_EYEDROPS] = Location::Base(RC_DMT_TRADE_EYEDROPS, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x26, "Trade Eyedrops", "DMT Trade Eyedrops", RHT_DMT_TRADE_EYEDROPS, RG_CLAIM_CHECK, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(0x60, 0x1E), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMT_TRADE_CLAIM_CHECK] = Location::Base(RC_DMT_TRADE_CLAIM_CHECK, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x57, "Trade Claim Check", "DMT Trade Claim Check", RHT_DMT_TRADE_CLAIM_CHECK, RG_BIGGORON_SWORD, {}, SpoilerCollectionCheck::Chest(0x60, 0x1F), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMT_FREESTANDING_POH] = Location::Collectable(RC_DMT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, 7686, 0x1E, "Freestanding PoH", "DMT Freestanding PoH", RHT_DMT_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMT_CHEST] = Location::Chest(RC_DMT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_DEATH_MOUNTAIN_TRAIL, 23201, 0x01, "Chest", "DMT Chest", RHT_DMT_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMT_STORMS_GROTTO_CHEST] = Location::Chest(RC_DMT_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_GROTTOS, 23255, 0x17, "Storms Grotto Chest", "DMT Storms Grotto Chest", RHT_DMT_STORMS_GROTTO_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMT_TRADE_BROKEN_SWORD] = Location::Base(RC_DMT_TRADE_BROKEN_SWORD, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x23, "Trade Broken Sword", "DMT Trade Broken Sword", RHT_DMT_TRADE_BROKEN_SWORD, RG_PRESCRIPTION, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMT_TRADE_EYEDROPS] = Location::Base(RC_DMT_TRADE_EYEDROPS, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x26, "Trade Eyedrops", "DMT Trade Eyedrops", RHT_DMT_TRADE_EYEDROPS, RG_CLAIM_CHECK, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMT_TRADE_CLAIM_CHECK] = Location::Base(RC_DMT_TRADE_CLAIM_CHECK, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x57, "Trade Claim Check", "DMT Trade Claim Check", RHT_DMT_TRADE_CLAIM_CHECK, RG_BIGGORON_SWORD, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMT_FREESTANDING_POH] = Location::Collectable(RC_DMT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, 7686, 0x1E, "Freestanding PoH", "DMT Freestanding PoH", RHT_DMT_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); // Goron City - locationTable[RC_GC_MAZE_LEFT_CHEST] = Location::Chest(RC_GC_MAZE_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23232, 0x00, "Maze Left Chest", "GC Maze Left Chest", RHT_GC_MAZE_LEFT_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_MAZE_RIGHT_CHEST] = Location::Chest(RC_GC_MAZE_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23201, 0x01, "Maze Right Chest", "GC Maze Right Chest", RHT_GC_MAZE_RIGHT_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_MAZE_CENTER_CHEST] = Location::Chest(RC_GC_MAZE_CENTER_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23202, 0x02, "Maze Center Chest", "GC Maze Center Chest", RHT_GC_MAZE_CENTER_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_ROLLING_GORON_AS_CHILD] = Location::Base(RC_GC_ROLLING_GORON_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x34, "Rolling Goron as Child", "GC Rolling Goron as Child", RHT_GC_ROLLING_GORON_AS_CHILD, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::InfTable(0x11, 0x06), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x2C, "Rolling Goron as Adult", "GC Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, {}, SpoilerCollectionCheck::InfTable(0x10, 0x01), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x54, "Darunias Joy", "GC Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheck::Chest(0x62, 0x1E), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_POT_FREESTANDING_POH] = Location::Collectable(RC_GC_POT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_ITEM00, SCENE_GORON_CITY, 7942, 0x1F, "Pot Freestanding PoH", "GC Pot Freestanding PoH", RHT_GC_POT_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), 0x30, "Deku Scrub Grotto Left", "GC Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x25, 0x01), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFB), 0x37, "Deku Scrub Grotto Right", "GC Deku Scrub Grotto Right", RHT_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x25, 0x06), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFB), 0x33, "Deku Scrub Grotto Center", "GC Deku Scrub Grotto Center", RHT_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x25, 0x04), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_MEDIGORON] = Location::Base(RC_GC_MEDIGORON, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x51, "Medigoron", "GC Medigoron", RHT_GC_MEDIGORON, RG_GIANTS_KNIFE, { Category::cMerchant }, SpoilerCollectionCheck::Merchant(0x62, 0x87), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_MAZE_LEFT_CHEST] = Location::Chest(RC_GC_MAZE_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23232, 0x00, "Maze Left Chest", "GC Maze Left Chest", RHT_GC_MAZE_LEFT_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_MAZE_RIGHT_CHEST] = Location::Chest(RC_GC_MAZE_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23201, 0x01, "Maze Right Chest", "GC Maze Right Chest", RHT_GC_MAZE_RIGHT_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_MAZE_CENTER_CHEST] = Location::Chest(RC_GC_MAZE_CENTER_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23202, 0x02, "Maze Center Chest", "GC Maze Center Chest", RHT_GC_MAZE_CENTER_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_ROLLING_GORON_AS_CHILD] = Location::Base(RC_GC_ROLLING_GORON_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x34, "Rolling Goron as Child", "GC Rolling Goron as Child", RHT_GC_ROLLING_GORON_AS_CHILD, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ROLLING_GORON_AS_CHILD), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); + locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x2C, "Rolling Goron as Adult", "GC Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); + locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x54, "Darunias Joy", "GC Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DARUNIAS_JOY), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); + locationTable[RC_GC_POT_FREESTANDING_POH] = Location::Collectable(RC_GC_POT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_ITEM00, SCENE_GORON_CITY, 7942, 0x1F, "Pot Freestanding PoH", "GC Pot Freestanding PoH", RHT_GC_POT_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), 0x30, "Deku Scrub Grotto Left", "GC Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFB), 0x37, "Deku Scrub Grotto Right", "GC Deku Scrub Grotto Right", RHT_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFB), 0x33, "Deku Scrub Grotto Center", "GC Deku Scrub Grotto Center", RHT_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_MEDIGORON] = Location::Base(RC_GC_MEDIGORON, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x51, "Medigoron", "GC Medigoron", RHT_GC_MEDIGORON, RG_GIANTS_KNIFE, { Category::cMerchant }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MEDIGORON), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); // Death Mountain Crater - locationTable[RC_DMC_UPPER_GROTTO_CHEST] = Location::Chest(RC_DMC_UPPER_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_BOX, SCENE_GROTTOS, 23802, 0x1A, "Upper Grotto Chest", "DMC Upper Grotto Chest", RHT_DMC_UPPER_GROTTO_CHEST, RG_BOMBS_20, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_WALL_FREESTANDING_POH] = Location::Collectable(RC_DMC_WALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 518, 0x02, "Wall Freestanding PoH", "DMC Wall Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMC_VOLCANO_FREESTANDING_POH] = Location::Collectable(RC_DMC_VOLCANO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 2054, 0x08, "Volcano Freestanding PoH", "DMC Volcano Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMC_DEKU_SCRUB] = Location::Base(RC_DMC_DEKU_SCRUB, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_DEATH_MOUNTAIN_CRATER, 0x05, 0x37, "Deku Scrub", "DMC Deku Scrub", RHT_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x61, 0x06), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xF9), 0x30, "Deku Scrub Grotto Left", "DMC Deku Scrub Grotto Left", RHT_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x23, 0x01), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xF9), 0x37, "Deku Scrub Grotto Right", "DMC Deku Scrub Grotto Right", RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x23, 0x06), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF9), 0x33, "Deku Scrub Grotto Center", "DMC Deku Scrub Grotto Center", RHT_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x23, 0x04), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_UPPER_GROTTO_CHEST] = Location::Chest(RC_DMC_UPPER_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_BOX, SCENE_GROTTOS, 23802, 0x1A, "Upper Grotto Chest", "DMC Upper Grotto Chest", RHT_DMC_UPPER_GROTTO_CHEST, RG_BOMBS_20, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_WALL_FREESTANDING_POH] = Location::Collectable(RC_DMC_WALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 518, 0x02, "Wall Freestanding PoH", "DMC Wall Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMC_VOLCANO_FREESTANDING_POH] = Location::Collectable(RC_DMC_VOLCANO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 2054, 0x08, "Volcano Freestanding PoH", "DMC Volcano Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMC_DEKU_SCRUB] = Location::Base(RC_DMC_DEKU_SCRUB, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_DEATH_MOUNTAIN_CRATER, 0x05, 0x37, "Deku Scrub", "DMC Deku Scrub", RHT_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xF9), 0x30, "Deku Scrub Grotto Left", "DMC Deku Scrub Grotto Left", RHT_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xF9), 0x37, "Deku Scrub Grotto Right", "DMC Deku Scrub Grotto Right", RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF9), 0x33, "Deku Scrub Grotto Center", "DMC Deku Scrub Grotto Center", RHT_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); // Zoras River - locationTable[RC_ZR_OPEN_GROTTO_CHEST] = Location::Chest(RC_ZR_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_BOX, SCENE_GROTTOS, 22985, 0x09, "Open Grotto Chest", "ZR Open Grotto Chest", RHT_ZR_OPEN_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_MAGIC_BEAN_SALESMAN] = Location::Base(RC_ZR_MAGIC_BEAN_SALESMAN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, 0x16, "Magic Bean Salesman", "ZR Magic Bean Salesman", RHT_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, {}, SpoilerCollectionCheck::MagicBeans(0x54, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_FROGS_ZELDAS_LULLABY] = Location::Base(RC_ZR_FROGS_ZELDAS_LULLABY, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Zelda's Lullaby", "ZR Frogs Zelda's Lullaby", RHT_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD1), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_EPONAS_SONG] = Location::Base(RC_ZR_FROGS_EPONAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Epona's Song", "ZR Frogs Epona's Song", RHT_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD2), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_SARIAS_SONG] = Location::Base(RC_ZR_FROGS_SARIAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Saria's Song", "ZR Frogs Saria's Song", RHT_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD4), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_SUNS_SONG] = Location::Base(RC_ZR_FROGS_SUNS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Sun's Song", "ZR Frogs Sun's Song", RHT_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD3), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_SONG_OF_TIME] = Location::Base(RC_ZR_FROGS_SONG_OF_TIME, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Song of Time", "ZR Frogs Song of Time", RHT_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD5), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_IN_THE_RAIN] = Location::Base(RC_ZR_FROGS_IN_THE_RAIN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs in the Rain", "ZR Frogs in the Rain", RHT_ZR_FROGS_IN_THE_RAIN, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_FROGS_OCARINA_GAME] = Location::Base(RC_ZR_FROGS_OCARINA_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x76, "Frogs Ocarina Game", "ZR Frogs Ocarina Game", RHT_ZR_FROGS_OCARINA_GAME, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xD0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 1030, 0x04, "Near Open Grotto Freestanding PoH", "ZR Near Open Grotto Freestanding PoH", RHT_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_NEAR_DOMAIN_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 2822, 0x0B, "Near Domain Freestanding PoH", "ZR Near Domain Freestanding PoH", RHT_ZR_NEAR_DOMAIN_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEB), 0x39, "Deku Scrub Grotto Rear", "ZR Deku Scrub Grotto Rear", RHT_ZR_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x15, 0x08), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEB), 0x3A, "Deku Scrub Grotto Front", "ZR Deku Scrub Grotto Front", RHT_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x15, 0x09), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_OPEN_GROTTO_CHEST] = Location::Chest(RC_ZR_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_BOX, SCENE_GROTTOS, 22985, 0x09, "Open Grotto Chest", "ZR Open Grotto Chest", RHT_ZR_OPEN_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_MAGIC_BEAN_SALESMAN] = Location::Base(RC_ZR_MAGIC_BEAN_SALESMAN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, 0x16, "Magic Bean Salesman", "ZR Magic Bean Salesman", RHT_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); + locationTable[RC_ZR_FROGS_ZELDAS_LULLABY] = Location::Base(RC_ZR_FROGS_ZELDAS_LULLABY, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Zelda's Lullaby", "ZR Frogs Zelda's Lullaby", RHT_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD1), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_FROGS_EPONAS_SONG] = Location::Base(RC_ZR_FROGS_EPONAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Epona's Song", "ZR Frogs Epona's Song", RHT_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD2), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_FROGS_SARIAS_SONG] = Location::Base(RC_ZR_FROGS_SARIAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Saria's Song", "ZR Frogs Saria's Song", RHT_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD4), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_FROGS_SUNS_SONG] = Location::Base(RC_ZR_FROGS_SUNS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Sun's Song", "ZR Frogs Sun's Song", RHT_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD3), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_FROGS_SONG_OF_TIME] = Location::Base(RC_ZR_FROGS_SONG_OF_TIME, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Song of Time", "ZR Frogs Song of Time", RHT_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD5), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_FROGS_IN_THE_RAIN] = Location::Base(RC_ZR_FROGS_IN_THE_RAIN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs in the Rain", "ZR Frogs in the Rain", RHT_ZR_FROGS_IN_THE_RAIN, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); + locationTable[RC_ZR_FROGS_OCARINA_GAME] = Location::Base(RC_ZR_FROGS_OCARINA_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x76, "Frogs Ocarina Game", "ZR Frogs Ocarina Game", RHT_ZR_FROGS_OCARINA_GAME, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xD0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); + locationTable[RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 1030, 0x04, "Near Open Grotto Freestanding PoH", "ZR Near Open Grotto Freestanding PoH", RHT_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); + locationTable[RC_ZR_NEAR_DOMAIN_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 2822, 0x0B, "Near Domain Freestanding PoH", "ZR Near Domain Freestanding PoH", RHT_ZR_NEAR_DOMAIN_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); + locationTable[RC_ZR_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEB), 0x39, "Deku Scrub Grotto Rear", "ZR Deku Scrub Grotto Rear", RHT_ZR_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEB), 0x3A, "Deku Scrub Grotto Front", "ZR Deku Scrub Grotto Front", RHT_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); // Zoras Domain - locationTable[RC_ZD_CHEST] = Location::Chest(RC_ZD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_EN_BOX, SCENE_ZORAS_DOMAIN, -18496, 0x00, "Chest", "ZD Chest", RHT_ZD_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_ZD_DIVING_MINIGAME] = Location::Base(RC_ZD_DIVING_MINIGAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x37, "Diving Minigame", "ZD Diving Minigame", RHT_ZD_DIVING_MINIGAME, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::EventChkInf(0x38), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_ZD_KING_ZORA_THAWED] = Location::Base(RC_ZD_KING_ZORA_THAWED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x2D, "King Zora Thawed", "ZD King Zora Thawed", RHT_ZD_KING_ZORA_THAWED, RG_ZORA_TUNIC, {}, SpoilerCollectionCheck::InfTable(0x13, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_ZD_TRADE_PRESCRIPTION] = Location::Base(RC_ZD_TRADE_PRESCRIPTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x24, "Trade Prescription", "ZD Trade Prescription", RHT_ZD_TRADE_PRESCRIPTION, RG_EYEBALL_FROG, { Category::cAdultTrade }, SpoilerCollectionCheck::Chest(0x58, 0x1F), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_ZD_CHEST] = Location::Chest(RC_ZD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_EN_BOX, SCENE_ZORAS_DOMAIN, -18496, 0x00, "Chest", "ZD Chest", RHT_ZD_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_ZD_DIVING_MINIGAME] = Location::Base(RC_ZD_DIVING_MINIGAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x37, "Diving Minigame", "ZD Diving Minigame", RHT_ZD_DIVING_MINIGAME, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::EventChkInf(0x38), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_ZD_KING_ZORA_THAWED] = Location::Base(RC_ZD_KING_ZORA_THAWED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x2D, "King Zora Thawed", "ZD King Zora Thawed", RHT_ZD_KING_ZORA_THAWED, RG_ZORA_TUNIC, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KING_ZORA_THAWED), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_ZD_TRADE_PRESCRIPTION] = Location::Base(RC_ZD_TRADE_PRESCRIPTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x24, "Trade Prescription", "ZD Trade Prescription", RHT_ZD_TRADE_PRESCRIPTION, RG_EYEBALL_FROG, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); // Zora's Fountain - locationTable[RC_ZF_ICEBERC_FREESTANDING_POH] = Location::Collectable(RC_ZF_ICEBERC_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, 0x01, "Iceberg Freestanding PoH", "ZF Iceberg Freestanding PoH", RHT_ZF_ICEBERG_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_ZF_BOTTOM_FREESTANDING_POH] = Location::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 5126, 0x14, "Bottom Freestanding PoH", "ZF Bottom Freestanding PoH", RHT_ZF_BOTTOM_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_ZF_ICEBERC_FREESTANDING_POH] = Location::Collectable(RC_ZF_ICEBERC_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, 0x01, "Iceberg Freestanding PoH", "ZF Iceberg Freestanding PoH", RHT_ZF_ICEBERG_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_ZF_BOTTOM_FREESTANDING_POH] = Location::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 5126, 0x14, "Bottom Freestanding PoH", "ZF Bottom Freestanding PoH", RHT_ZF_BOTTOM_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); // Lon Lon Ranch - locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, 0x14, "Talons Chickens", "LLR Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, {}, SpoilerCollectionCheck::ItemGetInf(10), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); - locationTable[RC_LLR_FREESTANDING_POH] = Location::Collectable(RC_LLR_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LON_LON_RANCH, ACTOR_EN_ITEM00, SCENE_LON_LON_BUILDINGS, 262, 0x01, "Freestanding PoH", "LLR Freestanding PoH", RHT_LLR_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFC), 0x30, "Deku Scrub Grotto Left", "LLR Deku Scrub Grotto Left", RHT_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x26, 0x01), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFC), 0x37, "Deku Scrub Grotto Right", "LLR Deku Scrub Grotto Right", RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x26, 0x06), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFC), 0x33, "Deku Scrub Grotto Center", "LLR Deku Scrub Grotto Center", RHT_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x26, 0x04), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, 0x14, "Talons Chickens", "LLR Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, {}, SpoilerCollectionCheck::ItemGetInf(2), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); + locationTable[RC_LLR_FREESTANDING_POH] = Location::Collectable(RC_LLR_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LON_LON_RANCH, ACTOR_EN_ITEM00, SCENE_LON_LON_BUILDINGS, 262, 0x01, "Freestanding PoH", "LLR Freestanding PoH", RHT_LLR_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFC), 0x30, "Deku Scrub Grotto Left", "LLR Deku Scrub Grotto Left", RHT_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFC), 0x37, "Deku Scrub Grotto Right", "LLR Deku Scrub Grotto Right", RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFC), 0x33, "Deku Scrub Grotto Center", "LLR Deku Scrub Grotto Center", RHT_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); // Dungeons - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression // Deku Tree Vanilla - locationTable[RC_DEKU_TREE_MAP_CHEST] = Location::Chest(RC_DEKU_TREE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, 0x03, "Map Chest", "Deku Tree Map Chest", RHT_DEKU_TREE_MAP_CHEST, RG_DEKU_TREE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_COMPASS_CHEST] = Location::Chest(RC_DEKU_TREE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2050, 0x02, "Compass Chest", "Deku Tree Compass Chest", RHT_DEKU_TREE_COMPASS_CHEST, RG_DEKU_TREE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST] = Location::Chest(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22790, 0x06, "Compass Room Side Chest", "Deku Tree Compass Room Side Chest", RHT_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_BASEMENT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22788, 0x04, "Basement Chest", "Deku Tree Basement Chest", RHT_DEKU_TREE_BASEMENT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_SLINGSHOT_CHEST] = Location::Chest(RC_DEKU_TREE_SLINGSHOT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 161, 0x01, "Slingshot Chest", "Deku Tree Slingshot Chest", RHT_DEKU_TREE_SLINGSHOT_CHEST, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST] = Location::Chest(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "Slingshot Room Side Chest", "Deku Tree Slingshot Room Side Chest", RHT_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MAP_CHEST] = Location::Chest(RC_DEKU_TREE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, 0x03, "Map Chest", "Deku Tree Map Chest", RHT_DEKU_TREE_MAP_CHEST, RG_DEKU_TREE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_DEKU_TREE_COMPASS_CHEST] = Location::Chest(RC_DEKU_TREE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2050, 0x02, "Compass Chest", "Deku Tree Compass Chest", RHT_DEKU_TREE_COMPASS_CHEST, RG_DEKU_TREE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST] = Location::Chest(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22790, 0x06, "Compass Room Side Chest", "Deku Tree Compass Room Side Chest", RHT_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_BASEMENT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22788, 0x04, "Basement Chest", "Deku Tree Basement Chest", RHT_DEKU_TREE_BASEMENT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_SLINGSHOT_CHEST] = Location::Chest(RC_DEKU_TREE_SLINGSHOT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 161, 0x01, "Slingshot Chest", "Deku Tree Slingshot Chest", RHT_DEKU_TREE_SLINGSHOT_CHEST, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST] = Location::Chest(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "Slingshot Room Side Chest", "Deku Tree Slingshot Room Side Chest", RHT_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); // Deku Tree MQ - locationTable[RC_DEKU_TREE_MQ_MAP_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, 0x03, "MQ Map Chest", "Deku Tree MQ Map Chest", RHT_DEKU_TREE_MQ_MAP_CHEST, RG_DEKU_TREE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_MQ_COMPASS_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2049, 0x01, "MQ Compass Chest", "Deku Tree MQ Compass Chest", RHT_DEKU_TREE_MQ_COMPASS_CHEST, RG_DEKU_TREE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 4262, 0x06, "MQ Slingshot Chest", "Deku Tree MQ Slingshot Chest", RHT_DEKU_TREE_MQ_SLINGSHOT_CHEST, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31454, 0x02, "MQ Slingshot Room Back Chest", "Deku Tree MQ Slingshot Room Back Chest", RHT_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31452, 0x04, "MQ Basement Chest", "Deku Tree MQ Basement Chest", RHT_DEKU_TREE_MQ_BASEMENT_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "MQ Before Spinning Log Chest", "Deku Tree MQ Before Spinning Log Chest", RHT_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 23200, 0x00, "MQ After Spinning Log Chest", "Deku Tree MQ After Spinning Log Chest", RHT_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_DEKU_SCRUB] = Location::Base(RC_DEKU_TREE_MQ_DEKU_SCRUB, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DEKU_TREE, ACTOR_EN_DNS, SCENE_DEKU_TREE, 0x04, 0x34, "MQ Deku Scrub", "Deku Tree MQ Deku Scrub", RHT_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x00, 0x05), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_MAP_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, 0x03, "MQ Map Chest", "Deku Tree MQ Map Chest", RHT_DEKU_TREE_MQ_MAP_CHEST, RG_DEKU_TREE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_DEKU_TREE_MQ_COMPASS_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2049, 0x01, "MQ Compass Chest", "Deku Tree MQ Compass Chest", RHT_DEKU_TREE_MQ_COMPASS_CHEST, RG_DEKU_TREE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 4262, 0x06, "MQ Slingshot Chest", "Deku Tree MQ Slingshot Chest", RHT_DEKU_TREE_MQ_SLINGSHOT_CHEST, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31454, 0x02, "MQ Slingshot Room Back Chest", "Deku Tree MQ Slingshot Room Back Chest", RHT_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31452, 0x04, "MQ Basement Chest", "Deku Tree MQ Basement Chest", RHT_DEKU_TREE_MQ_BASEMENT_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "MQ Before Spinning Log Chest", "Deku Tree MQ Before Spinning Log Chest", RHT_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 23200, 0x00, "MQ After Spinning Log Chest", "Deku Tree MQ After Spinning Log Chest", RHT_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_DEKU_SCRUB] = Location::Base(RC_DEKU_TREE_MQ_DEKU_SCRUB, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DEKU_TREE, ACTOR_EN_DNS, SCENE_DEKU_TREE, 0x04, 0x34, "MQ Deku Scrub", "Deku Tree MQ Deku Scrub", RHT_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression // Dodongo's Cavern Shared - locationTable[RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN_BOSS, 20512, 0x00, "Boss Room Chest", "Dodongos Cavern Boss Room Chest", RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN_BOSS, 20512, 0x00, "Boss Room Chest", "Dodongos Cavern Boss Room Chest", RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); // Dodongo's Cavern Vanilla - locationTable[RC_DODONGOS_CAVERN_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2088, 0x08, "Map Chest", "Dodongos Cavern Map Chest", RHT_DODONGOS_CAVERN_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_COMPASS_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2053, 0x05, "Compass Chest", "Dodongos Cavern Compass Chest", RHT_DODONGOS_CAVERN_COMPASS_CHEST, RG_DODONGOS_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22982, 0x06, "Bomb Flower Platform Chest", "Dodongos Cavern Bomb Flower Platform Chest", RHT_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "Bomb Bag Chest", "Dodongos Cavern Bomb Bag Chest", RHT_DODONGOS_CAVERN_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21802, 0x0A, "End Of Bridge Chest", "Dodongos Cavern End Of Bridge Chest", RHT_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x00, 0x30, "Deku Scrub Near Bomb Bag Left", "Dodongos Cavern Deku Scrub Near Bomb Bag Left", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x01, 0x01), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, 0x31, "Deku Scrub Side Room Near Dodongos", "Dodongos Cavern Deku Scrub Side Room Near Dodongos", RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x01, 0x02), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, 0x33, "Deku Scrub Near Bomb Bag Right", "Dodongos Cavern Deku Scrub Near Bomb Bag Right", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x01, 0x04), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, 0x34, "Deku Scrub Lobby", "Dodongos Cavern Deku Scrub Lobby", RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x01, 0x05), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2088, 0x08, "Map Chest", "Dodongos Cavern Map Chest", RHT_DODONGOS_CAVERN_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_DODONGOS_CAVERN_COMPASS_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2053, 0x05, "Compass Chest", "Dodongos Cavern Compass Chest", RHT_DODONGOS_CAVERN_COMPASS_CHEST, RG_DODONGOS_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22982, 0x06, "Bomb Flower Platform Chest", "Dodongos Cavern Bomb Flower Platform Chest", RHT_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "Bomb Bag Chest", "Dodongos Cavern Bomb Bag Chest", RHT_DODONGOS_CAVERN_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21802, 0x0A, "End Of Bridge Chest", "Dodongos Cavern End Of Bridge Chest", RHT_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x00, 0x30, "Deku Scrub Near Bomb Bag Left", "Dodongos Cavern Deku Scrub Near Bomb Bag Left", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, 0x31, "Deku Scrub Side Room Near Dodongos", "Dodongos Cavern Deku Scrub Side Room Near Dodongos", RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, 0x33, "Deku Scrub Near Bomb Bag Right", "Dodongos Cavern Deku Scrub Near Bomb Bag Right", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, 0x34, "Deku Scrub Lobby", "Dodongos Cavern Deku Scrub Lobby", RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); // Dodongo's Cavern MQ - locationTable[RC_DODONGOS_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2080, 0x00, "MQ Map Chest", "Dodongos Cavern MQ Map Chest", RHT_DODONGOS_CAVERN_MQ_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "MQ Bomb Bag Chest", "Dodongos Cavern MQ Bomb Bag Chest", RHT_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 6149, 0x05, "MQ Compass Chest", "Dodongos Cavern MQ Compass Chest", RHT_DODONGOS_CAVERN_MQ_COMPASS_CHEST, RG_DODONGOS_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 29986, 0x02, "MQ Larvae Room Chest", "Dodongos Cavern MQ Larvae Room Chest", RHT_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22947, 0x03, "MQ Torch Puzzle Room Chest", "Dodongos Cavern MQ Torch Puzzle Room Chest", RHT_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21825, 0x01, "MQ Under Grave Chest", "Dodongos Cavern MQ Under Grave Chest", RHT_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, 0x31, "MQ Deku Scrub Lobby Rear", "Dodongos Cavern Deku Scrub Lobby Rear", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x01, 0x02), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, 0x33, "MQ Deku Scrub Lobby Front", "Dodongos Cavern Deku Scrub Lobby Front", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x01, 0x04), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, 0x34, "MQ Deku Scrub Staircase", "Dodongos Cavern Deku Scrub Staircase", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x01, 0x05), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x07, 0x39, "MQ Deku Scrub Side Room Near Lower Lizalfos", "Dodongos Cavern Deku Scrub Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x01, 0x08), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2080, 0x00, "MQ Map Chest", "Dodongos Cavern MQ Map Chest", RHT_DODONGOS_CAVERN_MQ_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "MQ Bomb Bag Chest", "Dodongos Cavern MQ Bomb Bag Chest", RHT_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 6149, 0x05, "MQ Compass Chest", "Dodongos Cavern MQ Compass Chest", RHT_DODONGOS_CAVERN_MQ_COMPASS_CHEST, RG_DODONGOS_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 29986, 0x02, "MQ Larvae Room Chest", "Dodongos Cavern MQ Larvae Room Chest", RHT_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22947, 0x03, "MQ Torch Puzzle Room Chest", "Dodongos Cavern MQ Torch Puzzle Room Chest", RHT_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21825, 0x01, "MQ Under Grave Chest", "Dodongos Cavern MQ Under Grave Chest", RHT_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, 0x31, "MQ Deku Scrub Lobby Rear", "Dodongos Cavern Deku Scrub Lobby Rear", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, 0x33, "MQ Deku Scrub Lobby Front", "Dodongos Cavern Deku Scrub Lobby Front", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, 0x34, "MQ Deku Scrub Staircase", "Dodongos Cavern Deku Scrub Staircase", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x07, 0x39, "MQ Deku Scrub Side Room Near Lower Lizalfos", "Dodongos Cavern Deku Scrub Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression // Jabu-Jabu's Belly Vanilla - locationTable[RC_JABU_JABUS_BELLY_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 6178, 0x02, "Map Chest", "Jabu Jabus Belly Map Chest", RHT_JABU_JABUS_BELLY_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18428, 0x04, "Compass Chest", "Jabu Jabus Belly Compass Chest", RHT_JABU_JABUS_BELLY_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 4289, 0x01, "Boomerang Chest", "Jabu Jabus Belly Boomerang Chest", RHT_JABU_JABUS_BELLY_BOOMERANG_CHEST, RG_BOOMERANG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_DEKU_SCRUB] = Location::Base(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_DNS, SCENE_JABU_JABU, 0x00, 0x30, "Deku Scrub", "Jabu Jabus Belly Deku Scrub", RHT_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x02, 0x01), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 6178, 0x02, "Map Chest", "Jabu Jabus Belly Map Chest", RHT_JABU_JABUS_BELLY_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_JABU_JABUS_BELLY_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18428, 0x04, "Compass Chest", "Jabu Jabus Belly Compass Chest", RHT_JABU_JABUS_BELLY_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_JABU_JABUS_BELLY_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 4289, 0x01, "Boomerang Chest", "Jabu Jabus Belly Boomerang Chest", RHT_JABU_JABUS_BELLY_BOOMERANG_CHEST, RG_BOOMERANG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_JABU_JABUS_BELLY_DEKU_SCRUB] = Location::Base(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_DNS, SCENE_JABU_JABU, 0x00, 0x30, "Deku Scrub", "Jabu Jabus Belly Deku Scrub", RHT_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); // Jabu-Jabu's Belly MQ - locationTable[RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32699, 0x05, "MQ First Room Side Chest", "Jabu Jabus Belly MQ First Room Side Chest", RHT_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18397, 0x03, "MQ Map Chest", "Jabu Jabus Belly MQ Map Chest", RHT_JABU_JABUS_BELLY_MQ_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 20546, 0x02, "MQ Second Room Lower Chest", "Jabu Jabus Belly MQ Second Room Lower Chest", RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18432, 0x00, "MQ Compass Chest", "Jabu Jabus Belly MQ Compass Chest", RHT_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -30457, 0x07, "MQ Second Room Upper Chest", "Jabu Jabus Belly MQ Second Room Upper Chest", RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32696, 0x08, "MQ Basement Near Switches Chest", "Jabu Jabus Belly MQ Basement Near Switches Chest", RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32668, 0x04, "MQ Basement Near Vines Chest", "Jabu Jabus Belly MQ Basement Near Vines Chest", RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -31446, 0x0A, "MQ Near Boss Chest", "Jabu Jabus Belly MQ Near Boss Chest", RHT_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 28905, 0x09, "MQ Falling Like Like Room Chest", "Jabu Jabus Belly MQ Falling Like Like Room Chest", RHT_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, RG_DEKU_STICK_1, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 20545, 0x01, "MQ Boomerang Room Small Chest", "Jabu Jabus Belly MQ Boomerang Room Small Chest", RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 4294, 0x06, "MQ Boomerang Chest", "Jabu Jabus Belly MQ Boomerang Chest", RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, RG_BOOMERANG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32699, 0x05, "MQ First Room Side Chest", "Jabu Jabus Belly MQ First Room Side Chest", RHT_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18397, 0x03, "MQ Map Chest", "Jabu Jabus Belly MQ Map Chest", RHT_JABU_JABUS_BELLY_MQ_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 20546, 0x02, "MQ Second Room Lower Chest", "Jabu Jabus Belly MQ Second Room Lower Chest", RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18432, 0x00, "MQ Compass Chest", "Jabu Jabus Belly MQ Compass Chest", RHT_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -30457, 0x07, "MQ Second Room Upper Chest", "Jabu Jabus Belly MQ Second Room Upper Chest", RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32696, 0x08, "MQ Basement Near Switches Chest", "Jabu Jabus Belly MQ Basement Near Switches Chest", RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32668, 0x04, "MQ Basement Near Vines Chest", "Jabu Jabus Belly MQ Basement Near Vines Chest", RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -31446, 0x0A, "MQ Near Boss Chest", "Jabu Jabus Belly MQ Near Boss Chest", RHT_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 28905, 0x09, "MQ Falling Like Like Room Chest", "Jabu Jabus Belly MQ Falling Like Like Room Chest", RHT_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, RG_DEKU_STICK_1, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 20545, 0x01, "MQ Boomerang Room Small Chest", "Jabu Jabus Belly MQ Boomerang Room Small Chest", RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 4294, 0x06, "MQ Boomerang Chest", "Jabu Jabus Belly MQ Boomerang Chest", RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, RG_BOOMERANG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Collection Check Group Vanilla Progression // Forest Temple Vanilla - locationTable[RC_FOREST_TEMPLE_FIRST_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22595, 0x03, "First Room Chest", "Forest Temple First Room Chest", RHT_FOREST_TEMPLE_FIRST_ROOM_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, 0x00, "First Stalfos Chest", "Forest Temple First Stalfos Chest", RHT_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST] = Location::Chest(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22789, 0x05, "Raised Island Courtyard Chest", "Forest Temple Raised Island Courtyard Chest", RHT_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MAP_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6177, 0x01, "Map Chest", "Forest Temple Map Chest", RHT_FOREST_TEMPLE_MAP_CHEST, RG_FOREST_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_WELL_CHEST] = Location::Chest(RC_FOREST_TEMPLE_WELL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22601, 0x09, "Well Chest", "Forest Temple Well Chest", RHT_FOREST_TEMPLE_WELL_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22855, 0x07, "Falling Ceiling Room Chest", "Forest Temple Falling Ceiling Room Chest", RHT_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_EYE_SWITCH_CHEST] = Location::Chest(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30364, 0x04, "Eye Switch Chest", "Forest Temple Eye Switch Chest", RHT_FOREST_TEMPLE_EYE_SWITCH_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 10222, 0x0E, "Boss Key Chest", "Forest Temple Boss Key Chest", RHT_FOREST_TEMPLE_BOSS_KEY_CHEST, RG_FOREST_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_FLOORMASTER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30786, 0x02, "Floormaster Chest", "Forest Temple Floormaster Chest", RHT_FOREST_TEMPLE_FLOORMASTER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_BOW_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BOW_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -20340, 0x0C, "Bow Chest", "Forest Temple Bow Chest", RHT_FOREST_TEMPLE_BOW_CHEST, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_RED_POE_CHEST] = Location::Chest(RC_FOREST_TEMPLE_RED_POE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30797, 0x0D, "Red Poe Chest", "Forest Temple Red Poe Chest", RHT_FOREST_TEMPLE_RED_POE_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_BLUE_POE_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BLUE_POE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6159, 0x0F, "Blue Poe Chest", "Forest Temple Blue Poe Chest", RHT_FOREST_TEMPLE_BLUE_POE_CHEST, RG_FOREST_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_BASEMENT_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BASEMENT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22827, 0x0B, "Basement Chest", "Forest Temple Basement Chest", RHT_FOREST_TEMPLE_BASEMENT_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_FIRST_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22595, 0x03, "First Room Chest", "Forest Temple First Room Chest", RHT_FOREST_TEMPLE_FIRST_ROOM_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, 0x00, "First Stalfos Chest", "Forest Temple First Stalfos Chest", RHT_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST] = Location::Chest(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22789, 0x05, "Raised Island Courtyard Chest", "Forest Temple Raised Island Courtyard Chest", RHT_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MAP_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6177, 0x01, "Map Chest", "Forest Temple Map Chest", RHT_FOREST_TEMPLE_MAP_CHEST, RG_FOREST_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_WELL_CHEST] = Location::Chest(RC_FOREST_TEMPLE_WELL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22601, 0x09, "Well Chest", "Forest Temple Well Chest", RHT_FOREST_TEMPLE_WELL_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22855, 0x07, "Falling Ceiling Room Chest", "Forest Temple Falling Ceiling Room Chest", RHT_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_EYE_SWITCH_CHEST] = Location::Chest(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30364, 0x04, "Eye Switch Chest", "Forest Temple Eye Switch Chest", RHT_FOREST_TEMPLE_EYE_SWITCH_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 10222, 0x0E, "Boss Key Chest", "Forest Temple Boss Key Chest", RHT_FOREST_TEMPLE_BOSS_KEY_CHEST, RG_FOREST_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_FLOORMASTER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30786, 0x02, "Floormaster Chest", "Forest Temple Floormaster Chest", RHT_FOREST_TEMPLE_FLOORMASTER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_BOW_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BOW_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -20340, 0x0C, "Bow Chest", "Forest Temple Bow Chest", RHT_FOREST_TEMPLE_BOW_CHEST, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_RED_POE_CHEST] = Location::Chest(RC_FOREST_TEMPLE_RED_POE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30797, 0x0D, "Red Poe Chest", "Forest Temple Red Poe Chest", RHT_FOREST_TEMPLE_RED_POE_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_BLUE_POE_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BLUE_POE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6159, 0x0F, "Blue Poe Chest", "Forest Temple Blue Poe Chest", RHT_FOREST_TEMPLE_BLUE_POE_CHEST, RG_FOREST_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_BASEMENT_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BASEMENT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22827, 0x0B, "Basement Chest", "Forest Temple Basement Chest", RHT_FOREST_TEMPLE_BASEMENT_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); // Forest Temple MQ - locationTable[RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30653, 0x03, "MQ First Room Chest", "Forest Temple MQ First Room Chest", RHT_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, 0x00, "MQ Wolfos Chest", "Forest Temple MQ Wolfos Chest", RHT_FOREST_TEMPLE_MQ_WOLFOS_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_BOW_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BOW_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -20340, 0x0C, "MQ Bow Chest", "Forest Temple MQ Bow Chest", RHT_FOREST_TEMPLE_MQ_BOW_CHEST, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22593, 0x01, "MQ Raised Island Courtyard Lower Chest", "Forest Temple MQ Raised Island Courtyard Lower Chest", RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22597, 0x05, "MQ Raised Island Courtyard Upper Chest", "Forest Temple MQ Raised Island Courtyard Upper Chest", RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_WELL_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_WELL_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22601, 0x09, "MQ Well Chest", "Forest Temple MQ Well Chest", RHT_FOREST_TEMPLE_MQ_WELL_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6189, 0x0D, "MQ Map Chest", "Forest Temple MQ Map Chest", RHT_FOREST_TEMPLE_MQ_MAP_CHEST, RG_FOREST_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6159, 0x0F, "MQ Compass Chest", "Forest Temple MQ Compass Chest", RHT_FOREST_TEMPLE_MQ_COMPASS_CHEST, RG_FOREST_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30426, 0x06, "MQ Falling Ceiling Room Chest", "Forest Temple MQ Falling Ceiling Room Chest", RHT_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22827, 0x0B, "MQ Basement Chest", "Forest Temple MQ Basement Chest", RHT_FOREST_TEMPLE_MQ_BASEMENT_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_REDEAD_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30786, 0x02, "MQ Redead Chest", "Forest Temple MQ Redead Chest", RHT_FOREST_TEMPLE_MQ_REDEAD_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 10222, 0x0E, "MQ Boss Key Chest", "Forest Temple MQ Boss Key Chest", RHT_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, RG_FOREST_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30653, 0x03, "MQ First Room Chest", "Forest Temple MQ First Room Chest", RHT_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, 0x00, "MQ Wolfos Chest", "Forest Temple MQ Wolfos Chest", RHT_FOREST_TEMPLE_MQ_WOLFOS_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_BOW_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BOW_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -20340, 0x0C, "MQ Bow Chest", "Forest Temple MQ Bow Chest", RHT_FOREST_TEMPLE_MQ_BOW_CHEST, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22593, 0x01, "MQ Raised Island Courtyard Lower Chest", "Forest Temple MQ Raised Island Courtyard Lower Chest", RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22597, 0x05, "MQ Raised Island Courtyard Upper Chest", "Forest Temple MQ Raised Island Courtyard Upper Chest", RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_WELL_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_WELL_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22601, 0x09, "MQ Well Chest", "Forest Temple MQ Well Chest", RHT_FOREST_TEMPLE_MQ_WELL_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6189, 0x0D, "MQ Map Chest", "Forest Temple MQ Map Chest", RHT_FOREST_TEMPLE_MQ_MAP_CHEST, RG_FOREST_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6159, 0x0F, "MQ Compass Chest", "Forest Temple MQ Compass Chest", RHT_FOREST_TEMPLE_MQ_COMPASS_CHEST, RG_FOREST_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30426, 0x06, "MQ Falling Ceiling Room Chest", "Forest Temple MQ Falling Ceiling Room Chest", RHT_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22827, 0x0B, "MQ Basement Chest", "Forest Temple MQ Basement Chest", RHT_FOREST_TEMPLE_MQ_BASEMENT_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MQ_REDEAD_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30786, 0x02, "MQ Redead Chest", "Forest Temple MQ Redead Chest", RHT_FOREST_TEMPLE_MQ_REDEAD_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 10222, 0x0E, "MQ Boss Key Chest", "Forest Temple MQ Boss Key Chest", RHT_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, RG_FOREST_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Collection Check Group Vanilla Progression // Fire Temple Vanilla - locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, 0x01, "Near Boss Chest", "Fire Temple Near Boss Chest", RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_FLARE_DANCER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 31936, 0x00, "Flare Dancer Chest", "Fire Temple Flare Dancer Chest", RHT_FIRE_TEMPLE_FLARE_DANCER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10220, 0x0C, "Boss Key Chest", "Fire Temple Boss Key Chest", RHT_FIRE_TEMPLE_BOSS_KEY_CHEST, RG_FIRE_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22594, 0x02, "Big Lava Room Blocked Door Chest", "Fire Temple Big Lava Room Blocked Door Chest", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22596, 0x04, "Big Lava Room Lower Open Door Chest", "Fire Temple Big Lava Room Lower Open Door Chest", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22595, 0x03, "Boulder Maze Lower Chest", "Fire Temple Boulder Maze Lower Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22598, 0x06, "Boulder Maze Upper Chest", "Fire Temple Boulder Maze Upper Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22600, 0x08, "Boulder Maze Side Room Chest", "Fire Temple Boulder Maze Side Room Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22603, 0x0B, "Boulder Maze Shortcut Chest", "Fire Temple Boulder Maze Shortcut Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_SCARECROW_CHEST] = Location::Chest(RC_FIRE_TEMPLE_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23245, 0x0D, "Scarecrow Chest", "Fire Temple Scarecrow Chest", RHT_FIRE_TEMPLE_SCARECROW_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MAP_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2090, 0x0A, "Map Chest", "Fire Temple Map Chest", RHT_FIRE_TEMPLE_MAP_CHEST, RG_FIRE_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2055, 0x07, "Compass Chest", "Fire Temple Compass Chest", RHT_FIRE_TEMPLE_COMPASS_CHEST, RG_FIRE_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST] = Location::Chest(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22601, 0x09, "Highest Goron Chest", "Fire Temple Highest Goron Chest", RHT_FIRE_TEMPLE_HIGHEST_GORON_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 421, 0x05, "Megaton Hammer Chest", "Fire Temple Megaton Hammer Chest", RHT_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, RG_MEGATON_HAMMER, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, 0x01, "Near Boss Chest", "Fire Temple Near Boss Chest", RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_FLARE_DANCER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 31936, 0x00, "Flare Dancer Chest", "Fire Temple Flare Dancer Chest", RHT_FIRE_TEMPLE_FLARE_DANCER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10220, 0x0C, "Boss Key Chest", "Fire Temple Boss Key Chest", RHT_FIRE_TEMPLE_BOSS_KEY_CHEST, RG_FIRE_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22594, 0x02, "Big Lava Room Blocked Door Chest", "Fire Temple Big Lava Room Blocked Door Chest", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22596, 0x04, "Big Lava Room Lower Open Door Chest", "Fire Temple Big Lava Room Lower Open Door Chest", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22595, 0x03, "Boulder Maze Lower Chest", "Fire Temple Boulder Maze Lower Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22598, 0x06, "Boulder Maze Upper Chest", "Fire Temple Boulder Maze Upper Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22600, 0x08, "Boulder Maze Side Room Chest", "Fire Temple Boulder Maze Side Room Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22603, 0x0B, "Boulder Maze Shortcut Chest", "Fire Temple Boulder Maze Shortcut Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_SCARECROW_CHEST] = Location::Chest(RC_FIRE_TEMPLE_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23245, 0x0D, "Scarecrow Chest", "Fire Temple Scarecrow Chest", RHT_FIRE_TEMPLE_SCARECROW_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MAP_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2090, 0x0A, "Map Chest", "Fire Temple Map Chest", RHT_FIRE_TEMPLE_MAP_CHEST, RG_FIRE_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2055, 0x07, "Compass Chest", "Fire Temple Compass Chest", RHT_FIRE_TEMPLE_COMPASS_CHEST, RG_FIRE_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST] = Location::Chest(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22601, 0x09, "Highest Goron Chest", "Fire Temple Highest Goron Chest", RHT_FIRE_TEMPLE_HIGHEST_GORON_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 421, 0x05, "Megaton Hammer Chest", "Fire Temple Megaton Hammer Chest", RHT_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, RG_MEGATON_HAMMER, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); // Fire Temple MQ - locationTable[RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22599, 0x07, "MQ Near Boss Chest", "Fire Temple MQ Near Boss Chest", RHT_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 4512, 0x00, "MQ Megaton Hammer Chest", "Fire Temple MQ Megaton Hammer Chest", RHT_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, RG_MEGATON_HAMMER, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2059, 0x0B, "MQ Compass Chest", "Fire Temple MQ Compass Chest", RHT_FIRE_TEMPLE_MQ_COMPASS_CHEST, RG_FIRE_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23747, 0x03, "MQ Lizalfos Maze Lower Chest", "Fire Temple MQ Lizalfos Maze Lower Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23782, 0x06, "MQ Lizalfos Maze Upper Chest", "Fire Temple MQ Lizalfos Maze Upper Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE] = Location::Chest(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22597, 0x05, "MQ Chest on Fire", "Fire Temple MQ Chest on Fire", RHT_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 30018, 0x02, "MQ Map Room Side Chest", "Fire Temple MQ Map Room Side Chest", RHT_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2092, 0x0C, "MQ Map Chest", "Fire Temple MQ Map Chest", RHT_FIRE_TEMPLE_MQ_MAP_CHEST, RG_FIRE_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10212, 0x04, "MQ Boss Key Chest", "Fire Temple MQ Boss Key Chest", RHT_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, RG_FIRE_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, 0x01, "MQ Big Lava Room Blocked Door Chest", "Fire Temple MQ Big Lava Room Blocked Door Chest", RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22600, 0x08, "MQ Lizalfos Maze Side Room Chest", "Fire Temple MQ Lizalfos Maze Side Room Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, 7185, 0x1C, "MQ Freestanding Key", "Fire Temple MQ Freestanding Key", RHT_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22599, 0x07, "MQ Near Boss Chest", "Fire Temple MQ Near Boss Chest", RHT_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 4512, 0x00, "MQ Megaton Hammer Chest", "Fire Temple MQ Megaton Hammer Chest", RHT_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, RG_MEGATON_HAMMER, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2059, 0x0B, "MQ Compass Chest", "Fire Temple MQ Compass Chest", RHT_FIRE_TEMPLE_MQ_COMPASS_CHEST, RG_FIRE_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23747, 0x03, "MQ Lizalfos Maze Lower Chest", "Fire Temple MQ Lizalfos Maze Lower Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23782, 0x06, "MQ Lizalfos Maze Upper Chest", "Fire Temple MQ Lizalfos Maze Upper Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE] = Location::Chest(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22597, 0x05, "MQ Chest on Fire", "Fire Temple MQ Chest on Fire", RHT_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 30018, 0x02, "MQ Map Room Side Chest", "Fire Temple MQ Map Room Side Chest", RHT_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2092, 0x0C, "MQ Map Chest", "Fire Temple MQ Map Chest", RHT_FIRE_TEMPLE_MQ_MAP_CHEST, RG_FIRE_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10212, 0x04, "MQ Boss Key Chest", "Fire Temple MQ Boss Key Chest", RHT_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, RG_FIRE_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, 0x01, "MQ Big Lava Room Blocked Door Chest", "Fire Temple MQ Big Lava Room Blocked Door Chest", RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22600, 0x08, "MQ Lizalfos Maze Side Room Chest", "Fire Temple MQ Lizalfos Maze Side Room Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, 7185, 0x1C, "MQ Freestanding Key", "Fire Temple MQ Freestanding Key", RHT_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Randomizer Get Categories Collection Check Group Vanilla Progression // Water Temple Vanilla - locationTable[RC_WATER_TEMPLE_MAP_CHEST] = Location::Chest(RC_WATER_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6178, 0x02, "Map Chest", "Water Temple Map Chest", RHT_WATER_TEMPLE_MAP_CHEST, RG_WATER_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_WATER_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 2057, 0x09, "Compass Chest", "Water Temple Compass Chest", RHT_WATER_TEMPLE_COMPASS_CHEST, RG_WATER_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_TORCHES_CHEST] = Location::Chest(RC_WATER_TEMPLE_TORCHES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 30785, 0x01, "Torches Chest", "Water Temple Torches Chest", RHT_WATER_TEMPLE_TORCHES_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_DRAGON_CHEST] = Location::Chest(RC_WATER_TEMPLE_DRAGON_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22602, 0x0A, "Dragon Chest", "Water Temple Dragon Chest", RHT_WATER_TEMPLE_DRAGON_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST] = Location::Chest(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22600, 0x08, "Central Bow Target Chest", "Water Temple Central Bow Target Chest", RHT_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST] = Location::Chest(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22598, 0x06, "Central Pillar Chest", "Water Temple Central Pillar Chest", RHT_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_CRACKED_WALL_CHEST] = Location::Chest(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22592, 0x00, "Cracked Wall Chest", "Water Temple Cracked Wall Chest", RHT_WATER_TEMPLE_CRACKED_WALL_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_WATER_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 10213, 0x05, "Boss Key Chest", "Water Temple Boss Key Chest", RHT_WATER_TEMPLE_BOSS_KEY_CHEST, RG_WATER_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_LONGSHOT_CHEST] = Location::Chest(RC_WATER_TEMPLE_LONGSHOT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 295, 0x07, "Longshot Chest", "Water Temple Longshot Chest", RHT_WATER_TEMPLE_LONGSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_RIVER_CHEST] = Location::Chest(RC_WATER_TEMPLE_RIVER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22595, 0x03, "River Chest", "Water Temple River Chest", RHT_WATER_TEMPLE_RIVER_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MAP_CHEST] = Location::Chest(RC_WATER_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6178, 0x02, "Map Chest", "Water Temple Map Chest", RHT_WATER_TEMPLE_MAP_CHEST, RG_WATER_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_WATER_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 2057, 0x09, "Compass Chest", "Water Temple Compass Chest", RHT_WATER_TEMPLE_COMPASS_CHEST, RG_WATER_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_TORCHES_CHEST] = Location::Chest(RC_WATER_TEMPLE_TORCHES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 30785, 0x01, "Torches Chest", "Water Temple Torches Chest", RHT_WATER_TEMPLE_TORCHES_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_DRAGON_CHEST] = Location::Chest(RC_WATER_TEMPLE_DRAGON_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22602, 0x0A, "Dragon Chest", "Water Temple Dragon Chest", RHT_WATER_TEMPLE_DRAGON_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST] = Location::Chest(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22600, 0x08, "Central Bow Target Chest", "Water Temple Central Bow Target Chest", RHT_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST] = Location::Chest(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22598, 0x06, "Central Pillar Chest", "Water Temple Central Pillar Chest", RHT_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_CRACKED_WALL_CHEST] = Location::Chest(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22592, 0x00, "Cracked Wall Chest", "Water Temple Cracked Wall Chest", RHT_WATER_TEMPLE_CRACKED_WALL_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_WATER_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 10213, 0x05, "Boss Key Chest", "Water Temple Boss Key Chest", RHT_WATER_TEMPLE_BOSS_KEY_CHEST, RG_WATER_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_LONGSHOT_CHEST] = Location::Chest(RC_WATER_TEMPLE_LONGSHOT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 295, 0x07, "Longshot Chest", "Water Temple Longshot Chest", RHT_WATER_TEMPLE_LONGSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_RIVER_CHEST] = Location::Chest(RC_WATER_TEMPLE_RIVER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22595, 0x03, "River Chest", "Water Temple River Chest", RHT_WATER_TEMPLE_RIVER_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); // Water Temple MQ - locationTable[RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -30650, 0x06, "MQ Central Pillar Chest", "Water Temple MQ Central Pillar Chest", RHT_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 10213, 0x05, "MQ Boss Key Chest", "Water Temple MQ Boss Key Chest", RHT_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, RG_WATER_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -20192, 0x00, "MQ Longshot Chest", "Water Temple MQ Longshot Chest", RHT_WATER_TEMPLE_MQ_LONGSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6145, 0x01, "MQ Compass Chest", "Water Temple MQ Compass Chest", RHT_WATER_TEMPLE_MQ_COMPASS_CHEST, RG_WATER_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -18398, 0x02, "MQ Map Chest", "Water Temple MQ Map Chest", RHT_WATER_TEMPLE_MQ_MAP_CHEST, RG_WATER_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, 273, 0x01, "MQ Freestanding Key", "Water Temple MQ Freestanding Key", RHT_WATER_TEMPLE_MQ_FREESTANDING_KEY, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -30650, 0x06, "MQ Central Pillar Chest", "Water Temple MQ Central Pillar Chest", RHT_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 10213, 0x05, "MQ Boss Key Chest", "Water Temple MQ Boss Key Chest", RHT_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, RG_WATER_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -20192, 0x00, "MQ Longshot Chest", "Water Temple MQ Longshot Chest", RHT_WATER_TEMPLE_MQ_LONGSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6145, 0x01, "MQ Compass Chest", "Water Temple MQ Compass Chest", RHT_WATER_TEMPLE_MQ_COMPASS_CHEST, RG_WATER_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -18398, 0x02, "MQ Map Chest", "Water Temple MQ Map Chest", RHT_WATER_TEMPLE_MQ_MAP_CHEST, RG_WATER_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, 273, 0x01, "MQ Freestanding Key", "Water Temple MQ Freestanding Key", RHT_WATER_TEMPLE_MQ_FREESTANDING_KEY, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Collection Check Group Vanilla Progression // Spirit Temple Shared - locationTable[RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 1707, 0x0B, "Silver Gauntlets Chest", "Spirit Temple Silver Gauntlets Chest", RHT_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 13673, 0x09, "Mirror Shield Chest", "Spirit Temple Mirror Shield Chest", RHT_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RG_MIRROR_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 1707, 0x0B, "Silver Gauntlets Chest", "Spirit Temple Silver Gauntlets Chest", RHT_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 13673, 0x09, "Mirror Shield Chest", "Spirit Temple Mirror Shield Chest", RHT_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RG_MIRROR_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); // Spirit Temple Vanilla - locationTable[RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 21800, 0x08, "Child Bridge Chest", "Spirit Temple Child Bridge Chest", RHT_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30656, 0x00, "Child Early Torches Chest", "Spirit Temple Child Early Torches Chest", RHT_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 14340, 0x04, "Compass Chest", "Spirit Temple Compass Chest", RHT_SPIRIT_TEMPLE_COMPASS_CHEST, RG_SPIRIT_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 22599, 0x07, "Early Adult Right Chest", "Spirit Temple Early Adult Right Chest", RHT_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30451, 0x0D, "First Mirror Left Chest", "Spirit Temple First Mirror Left Chest", RHT_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -28786, 0x0E, "First Mirror Right Chest", "Spirit Temple First Mirror Right Chest", RHT_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MAP_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -18397, 0x03, "Map Chest", "Spirit Temple Map Chest", RHT_SPIRIT_TEMPLE_MAP_CHEST, RG_SPIRIT_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -32666, 0x06, "Child Climb North Chest", "Spirit Temple Child Climb North Chest", RHT_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -31444, 0x0C, "Child Climb East Chest", "Spirit Temple Child Climb East Chest", RHT_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30655, 0x01, "Sun Block Room Chest", "Spirit Temple Sun Block Room Chest", RHT_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30654, 0x02, "Statue Room Hand Chest", "Spirit Temple Statue Room Hand Chest", RHT_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30577, 0x0F, "Statue Room Northeast Chest", "Spirit Temple Statue Room Northeast Chest", RHT_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 22597, 0x05, "Near Four Armos Chest", "Spirit Temple Near Four Armos Chest", RHT_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26900, 0x14, "Hallway Right Invisible Chest", "Spirit Temple Hallway Right Invisible Chest", RHT_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26901, 0x15, "Hallway Left Invisible Chest", "Spirit Temple Hallway Left Invisible Chest", RHT_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 10218, 0x0A, "Boss Key Chest", "Spirit Temple Boss Key Chest", RHT_SPIRIT_TEMPLE_BOSS_KEY_CHEST, RG_SPIRIT_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_TOPMOST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -29454, 0x12, "Topmost Chest", "Spirit Temple Topmost Chest", RHT_SPIRIT_TEMPLE_TOPMOST_CHEST, RG_BOMBS_20, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 21800, 0x08, "Child Bridge Chest", "Spirit Temple Child Bridge Chest", RHT_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30656, 0x00, "Child Early Torches Chest", "Spirit Temple Child Early Torches Chest", RHT_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 14340, 0x04, "Compass Chest", "Spirit Temple Compass Chest", RHT_SPIRIT_TEMPLE_COMPASS_CHEST, RG_SPIRIT_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 22599, 0x07, "Early Adult Right Chest", "Spirit Temple Early Adult Right Chest", RHT_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30451, 0x0D, "First Mirror Left Chest", "Spirit Temple First Mirror Left Chest", RHT_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -28786, 0x0E, "First Mirror Right Chest", "Spirit Temple First Mirror Right Chest", RHT_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MAP_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -18397, 0x03, "Map Chest", "Spirit Temple Map Chest", RHT_SPIRIT_TEMPLE_MAP_CHEST, RG_SPIRIT_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -32666, 0x06, "Child Climb North Chest", "Spirit Temple Child Climb North Chest", RHT_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -31444, 0x0C, "Child Climb East Chest", "Spirit Temple Child Climb East Chest", RHT_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30655, 0x01, "Sun Block Room Chest", "Spirit Temple Sun Block Room Chest", RHT_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30654, 0x02, "Statue Room Hand Chest", "Spirit Temple Statue Room Hand Chest", RHT_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30577, 0x0F, "Statue Room Northeast Chest", "Spirit Temple Statue Room Northeast Chest", RHT_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 22597, 0x05, "Near Four Armos Chest", "Spirit Temple Near Four Armos Chest", RHT_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26900, 0x14, "Hallway Right Invisible Chest", "Spirit Temple Hallway Right Invisible Chest", RHT_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26901, 0x15, "Hallway Left Invisible Chest", "Spirit Temple Hallway Left Invisible Chest", RHT_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 10218, 0x0A, "Boss Key Chest", "Spirit Temple Boss Key Chest", RHT_SPIRIT_TEMPLE_BOSS_KEY_CHEST, RG_SPIRIT_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_TOPMOST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -29454, 0x12, "Topmost Chest", "Spirit Temple Topmost Chest", RHT_SPIRIT_TEMPLE_TOPMOST_CHEST, RG_BOMBS_20, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); // Spirit Temple MQ - locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 20602, 0x1A, "MQ Entrance Front Left Chest", "Spirit Temple MQ Entrance Front Left Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -32641, 0x1F, "MQ Entrance Back Right Chest", "Spirit Temple MQ Entrance Back Right Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30629, 0x1B, "MQ Entrance Front Right Chest", "Spirit Temple MQ Entrance Front Right Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30626, 0x1E, "MQ Entrance Back Left Chest", "Spirit Temple MQ Entrance Back Left Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30627, 0x1D, "MQ Child Hammer Switch Chest", "Spirit Temple MQ Child Hammer Switch Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 2080, 0x00, "MQ Map Chest", "Spirit Temple MQ Map Chest", RHT_SPIRIT_TEMPLE_MQ_MAP_CHEST, RG_SPIRIT_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 30792, 0x08, "MQ Map Room Enemy Chest", "Spirit Temple MQ Map Room Enemy Chest", RHT_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 28774, 0x06, "MQ Child Climb North Chest", "Spirit Temple MQ Child Climb North Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30644, 0x0C, "MQ Child Climb South Chest", "Spirit Temple MQ Child Climb South Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -18429, 0x03, "MQ Compass Chest", "Spirit Temple MQ Compass Chest", RHT_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, RG_SPIRIT_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30577, 0x0F, "MQ Statue Room Lullaby Chest", "Spirit Temple MQ Statue Room Lullaby Chest", RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26882, 0x02, "MQ Statue Room Invisible Chest", "Spirit Temple MQ Statue Room Invisible Chest", RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30628, 0x1C, "MQ Silver Block Hallway Chest", "Spirit Temple MQ Silver Block Hallway Chest", RHT_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30463, 0x01, "MQ Sun Block Room Chest", "Spirit Temple MQ Sun Block Room Chest", RHT_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 23207, 0x07, "MQ Symphony Room Chest", "Spirit Temple MQ Symphony Room Chest", RHT_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 31396, 0x04, "MQ Leever Room Chest", "Spirit Temple MQ Leever Room Chest", RHT_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 24472, 0x19, "MQ Beamos Room Chest", "Spirit Temple MQ Beamos Room Chest", RHT_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 31097, 0x18, "MQ Chest Switch Chest", "Spirit Temple MQ Chest Switch Chest", RHT_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 10213, 0x05, "MQ Boss Key Chest", "Spirit Temple MQ Boss Key Chest", RHT_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, RG_SPIRIT_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26706, 0x12, "MQ Mirror Puzzle Invisible Chest", "Spirit Temple MQ Mirror Puzzle Invisible Chest", RHT_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 20602, 0x1A, "MQ Entrance Front Left Chest", "Spirit Temple MQ Entrance Front Left Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -32641, 0x1F, "MQ Entrance Back Right Chest", "Spirit Temple MQ Entrance Back Right Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30629, 0x1B, "MQ Entrance Front Right Chest", "Spirit Temple MQ Entrance Front Right Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30626, 0x1E, "MQ Entrance Back Left Chest", "Spirit Temple MQ Entrance Back Left Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30627, 0x1D, "MQ Child Hammer Switch Chest", "Spirit Temple MQ Child Hammer Switch Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 2080, 0x00, "MQ Map Chest", "Spirit Temple MQ Map Chest", RHT_SPIRIT_TEMPLE_MQ_MAP_CHEST, RG_SPIRIT_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 30792, 0x08, "MQ Map Room Enemy Chest", "Spirit Temple MQ Map Room Enemy Chest", RHT_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 28774, 0x06, "MQ Child Climb North Chest", "Spirit Temple MQ Child Climb North Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30644, 0x0C, "MQ Child Climb South Chest", "Spirit Temple MQ Child Climb South Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -18429, 0x03, "MQ Compass Chest", "Spirit Temple MQ Compass Chest", RHT_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, RG_SPIRIT_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30577, 0x0F, "MQ Statue Room Lullaby Chest", "Spirit Temple MQ Statue Room Lullaby Chest", RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26882, 0x02, "MQ Statue Room Invisible Chest", "Spirit Temple MQ Statue Room Invisible Chest", RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30628, 0x1C, "MQ Silver Block Hallway Chest", "Spirit Temple MQ Silver Block Hallway Chest", RHT_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30463, 0x01, "MQ Sun Block Room Chest", "Spirit Temple MQ Sun Block Room Chest", RHT_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 23207, 0x07, "MQ Symphony Room Chest", "Spirit Temple MQ Symphony Room Chest", RHT_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 31396, 0x04, "MQ Leever Room Chest", "Spirit Temple MQ Leever Room Chest", RHT_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 24472, 0x19, "MQ Beamos Room Chest", "Spirit Temple MQ Beamos Room Chest", RHT_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 31097, 0x18, "MQ Chest Switch Chest", "Spirit Temple MQ Chest Switch Chest", RHT_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 10213, 0x05, "MQ Boss Key Chest", "Spirit Temple MQ Boss Key Chest", RHT_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, RG_SPIRIT_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26706, 0x12, "MQ Mirror Puzzle Invisible Chest", "Spirit Temple MQ Mirror Puzzle Invisible Chest", RHT_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Collection Check Group Vanilla Progression // Shadow Temple Vanilla - locationTable[RC_SHADOW_TEMPLE_MAP_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6177, 0x01, "Map Chest", "Shadow Temple Map Chest", RHT_SHADOW_TEMPLE_MAP_CHEST, RG_SHADOW_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, 0x07, "Hover Boots Chest", "Shadow Temple Hover Boots Chest", RHT_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RG_HOVER_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6147, 0x03, "Compass Chest", "Shadow Temple Compass Chest", RHT_SHADOW_TEMPLE_COMPASS_CHEST, RG_SHADOW_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22594, 0x02, "Early Silver Rupee Chest", "Shadow Temple Early Silver Rupee Chest", RHT_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22668, 0x0C, "Invisible Blades Visible Chest", "Shadow Temple Invisible Blades Visible Chest", RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26998, 0x16, "Invisible Blades Invisible Chest", "Shadow Temple Invisible Blades Invisible Chest", RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22853, 0x05, "Falling Spikes Lower Chest", "Shadow Temple Falling Spikes Lower Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22662, 0x06, "Falling Spikes Upper Chest", "Shadow Temple Falling Spikes Upper Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30652, 0x04, "Falling Spikes Switch Chest", "Shadow Temple Falling Spikes Switch Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30857, 0x09, "Invisible Spikes Chest", "Shadow Temple Invisible Spikes Chest", RHT_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_WIND_HINT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26965, 0x15, "Wind Hint Chest", "Shadow Temple Wind Hint Chest", RHT_SHADOW_TEMPLE_WIND_HINT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30856, 0x08, "After Wind Enemy Chest", "Shadow Temple After Wind Enemy Chest", RHT_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26708, 0x14, "After Wind Hidden Chest", "Shadow Temple After Wind Hidden Chest", RHT_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22666, 0x0A, "Spike Walls Left Chest", "Shadow Temple Spike Walls Left Chest", RHT_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 10219, 0x0B, "Boss Key Chest", "Shadow Temple Boss Key Chest", RHT_SHADOW_TEMPLE_BOSS_KEY_CHEST, RG_SHADOW_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30797, 0x0D, "Invisible Floormaster Chest", "Shadow Temple Invisible Floormaster Chest", RHT_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_FREESTANDING_KEY] = Location::Collectable(RC_SHADOW_TEMPLE_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, 273, 0x01, "Freestanding Key", "Shadow Temple Freestanding Key", RHT_SHADOW_TEMPLE_FREESTANDING_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MAP_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6177, 0x01, "Map Chest", "Shadow Temple Map Chest", RHT_SHADOW_TEMPLE_MAP_CHEST, RG_SHADOW_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, 0x07, "Hover Boots Chest", "Shadow Temple Hover Boots Chest", RHT_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RG_HOVER_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6147, 0x03, "Compass Chest", "Shadow Temple Compass Chest", RHT_SHADOW_TEMPLE_COMPASS_CHEST, RG_SHADOW_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22594, 0x02, "Early Silver Rupee Chest", "Shadow Temple Early Silver Rupee Chest", RHT_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22668, 0x0C, "Invisible Blades Visible Chest", "Shadow Temple Invisible Blades Visible Chest", RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26998, 0x16, "Invisible Blades Invisible Chest", "Shadow Temple Invisible Blades Invisible Chest", RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22853, 0x05, "Falling Spikes Lower Chest", "Shadow Temple Falling Spikes Lower Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22662, 0x06, "Falling Spikes Upper Chest", "Shadow Temple Falling Spikes Upper Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30652, 0x04, "Falling Spikes Switch Chest", "Shadow Temple Falling Spikes Switch Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30857, 0x09, "Invisible Spikes Chest", "Shadow Temple Invisible Spikes Chest", RHT_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_WIND_HINT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26965, 0x15, "Wind Hint Chest", "Shadow Temple Wind Hint Chest", RHT_SHADOW_TEMPLE_WIND_HINT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30856, 0x08, "After Wind Enemy Chest", "Shadow Temple After Wind Enemy Chest", RHT_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26708, 0x14, "After Wind Hidden Chest", "Shadow Temple After Wind Hidden Chest", RHT_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22666, 0x0A, "Spike Walls Left Chest", "Shadow Temple Spike Walls Left Chest", RHT_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 10219, 0x0B, "Boss Key Chest", "Shadow Temple Boss Key Chest", RHT_SHADOW_TEMPLE_BOSS_KEY_CHEST, RG_SHADOW_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30797, 0x0D, "Invisible Floormaster Chest", "Shadow Temple Invisible Floormaster Chest", RHT_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_FREESTANDING_KEY] = Location::Collectable(RC_SHADOW_TEMPLE_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, 273, 0x01, "Freestanding Key", "Shadow Temple Freestanding Key", RHT_SHADOW_TEMPLE_FREESTANDING_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); // Shadow Temple MQ - locationTable[RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6145, 0x01, "MQ Compass Chest", "Shadow Temple MQ Compass Chest", RHT_SHADOW_TEMPLE_MQ_COMPASS_CHEST, RG_SHADOW_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, 0x07, "MQ Hover Boots Chest", "Shadow Temple MQ Hover Boots Chest", RHT_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, RG_HOVER_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30787, 0x03, "MQ Early Gibdos Chest", "Shadow Temple MQ Early Gibdos Chest", RHT_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 2082, 0x02, "MQ Map Chest", "Shadow Temple MQ Map Chest", RHT_SHADOW_TEMPLE_MQ_MAP_CHEST, RG_SHADOW_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30417, 0x0F, "MQ Beamos Silver Rupees Chest", "Shadow Temple MQ Beamos Silver Rupees Chest", RHT_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22662, 0x04, "MQ Falling Spikes Switch Chest", "Shadow Temple MQ Falling Spikes Switch Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22853, 0x05, "MQ Falling Spikes Lower Chest", "Shadow Temple MQ Falling Spikes Lower Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30652, 0x06, "MQ Falling Spikes Upper Chest", "Shadow Temple MQ Falling Spikes Upper Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30857, 0x09, "MQ Invisible Spikes Chest", "Shadow Temple MQ Invisible Spikes Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 10219, 0x0B, "MQ Boss Key Chest", "Shadow Temple MQ Boss Key Chest", RHT_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, RG_SHADOW_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22666, 0x0A, "MQ Spike Walls Left Chest", "Shadow Temple MQ Spike Walls Left Chest", RHT_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 31184, 0x10, "MQ Stalfos Room Chest", "Shadow Temple MQ Stalfos Room Chest", RHT_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26710, 0x16, "MQ Invisible Blades Invisible Chest", "Shadow Temple MQ Invisible Blades Invisible Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22668, 0x0C, "MQ Invisible Blades Visible Chest", "Shadow Temple MQ Invisible Blades Visible Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 31053, 0x0D, "MQ Bomb Flower Chest", "Shadow Temple MQ Bomb Flower Chest", RHT_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26709, 0x15, "MQ Wind Hint Chest", "Shadow Temple MQ Wind Hint Chest", RHT_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26932, 0x14, "MQ After Wind Hidden Chest", "Shadow Temple MQ After Wind Hidden Chest", RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30856, 0x08, "MQ After Wind Enemy Chest", "Shadow Temple MQ After Wind Enemy Chest", RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26702, 0x0E, "MQ Near Ship Invisible Chest", "Shadow Temple MQ Near Ship Invisible Chest", RHT_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, 1553, 0x06, "MQ Freestanding Key", "Shadow Temple MQ Freestanding Key", RHT_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6145, 0x01, "MQ Compass Chest", "Shadow Temple MQ Compass Chest", RHT_SHADOW_TEMPLE_MQ_COMPASS_CHEST, RG_SHADOW_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, 0x07, "MQ Hover Boots Chest", "Shadow Temple MQ Hover Boots Chest", RHT_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, RG_HOVER_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30787, 0x03, "MQ Early Gibdos Chest", "Shadow Temple MQ Early Gibdos Chest", RHT_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 2082, 0x02, "MQ Map Chest", "Shadow Temple MQ Map Chest", RHT_SHADOW_TEMPLE_MQ_MAP_CHEST, RG_SHADOW_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30417, 0x0F, "MQ Beamos Silver Rupees Chest", "Shadow Temple MQ Beamos Silver Rupees Chest", RHT_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22662, 0x04, "MQ Falling Spikes Switch Chest", "Shadow Temple MQ Falling Spikes Switch Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22853, 0x05, "MQ Falling Spikes Lower Chest", "Shadow Temple MQ Falling Spikes Lower Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30652, 0x06, "MQ Falling Spikes Upper Chest", "Shadow Temple MQ Falling Spikes Upper Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30857, 0x09, "MQ Invisible Spikes Chest", "Shadow Temple MQ Invisible Spikes Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 10219, 0x0B, "MQ Boss Key Chest", "Shadow Temple MQ Boss Key Chest", RHT_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, RG_SHADOW_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22666, 0x0A, "MQ Spike Walls Left Chest", "Shadow Temple MQ Spike Walls Left Chest", RHT_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 31184, 0x10, "MQ Stalfos Room Chest", "Shadow Temple MQ Stalfos Room Chest", RHT_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26710, 0x16, "MQ Invisible Blades Invisible Chest", "Shadow Temple MQ Invisible Blades Invisible Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22668, 0x0C, "MQ Invisible Blades Visible Chest", "Shadow Temple MQ Invisible Blades Visible Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 31053, 0x0D, "MQ Bomb Flower Chest", "Shadow Temple MQ Bomb Flower Chest", RHT_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26709, 0x15, "MQ Wind Hint Chest", "Shadow Temple MQ Wind Hint Chest", RHT_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26932, 0x14, "MQ After Wind Hidden Chest", "Shadow Temple MQ After Wind Hidden Chest", RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30856, 0x08, "MQ After Wind Enemy Chest", "Shadow Temple MQ After Wind Enemy Chest", RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26702, 0x0E, "MQ Near Ship Invisible Chest", "Shadow Temple MQ Near Ship Invisible Chest", RHT_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, 1553, 0x06, "MQ Freestanding Key", "Shadow Temple MQ Freestanding Key", RHT_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Collection Check Group Vanilla Progression // Bottom of the Well Vanilla - locationTable[RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22600, 0x08, "Front Left Fake Wall Chest", "Bottom of the Well Front Left Fake Wall Chest", RHT_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20578, 0x02, "Front Center Bombable Chest", "Bottom of the Well Front Center Bombable Chest", RHT_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22597, 0x05, "Right Bottom Fake Wall Chest", "Bottom of the Well Right Bottom Fake Wall Chest", RHT_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2049, 0x01, "Compass Chest", "Bottom of the Well Compass Chest", RHT_BOTTOM_OF_THE_WELL_COMPASS_CHEST, RG_BOTTOM_OF_THE_WELL_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20558, 0x0E, "Center Skulltula Chest", "Bottom of the Well Center Skulltula Chest", RHT_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 23684, 0x04, "Back Left Bombable Chest", "Bottom of the Well Back Left Bombable Chest", RHT_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, RG_DEKU_NUTS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 4419, 0x03, "Lens of Truth Chest", "Bottom of the Well Lens of Truth Chest", RHT_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, RG_LENS_OF_TRUTH, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 27348, 0x14, "Invisible Chest", "Bottom of the Well Invisible Chest", RHT_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 23760, 0x10, "Underwater Front Chest", "Bottom of the Well Underwater Front Chest", RHT_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22793, 0x09, "Underwater Left Chest", "Bottom of the Well Underwater Left Chest", RHT_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_MAP_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2087, 0x07, "Map Chest", "Bottom of the Well Map Chest", RHT_BOTTOM_OF_THE_WELL_MAP_CHEST, RG_BOTTOM_OF_THE_WELL_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 21802, 0x0A, "Fire Keese Chest", "Bottom of the Well Fire Keese Chest", RHT_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 21836, 0x0C, "Like Like Chest", "Bottom of the Well Like Like Chest", RHT_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY] = Location::Chest( RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 273, 0x01, "Freestanding Key", "Bottom of the Well Freestanding Key", RHT_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22600, 0x08, "Front Left Fake Wall Chest", "Bottom of the Well Front Left Fake Wall Chest", RHT_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20578, 0x02, "Front Center Bombable Chest", "Bottom of the Well Front Center Bombable Chest", RHT_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22597, 0x05, "Right Bottom Fake Wall Chest", "Bottom of the Well Right Bottom Fake Wall Chest", RHT_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2049, 0x01, "Compass Chest", "Bottom of the Well Compass Chest", RHT_BOTTOM_OF_THE_WELL_COMPASS_CHEST, RG_BOTTOM_OF_THE_WELL_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20558, 0x0E, "Center Skulltula Chest", "Bottom of the Well Center Skulltula Chest", RHT_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 23684, 0x04, "Back Left Bombable Chest", "Bottom of the Well Back Left Bombable Chest", RHT_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, RG_DEKU_NUTS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 4419, 0x03, "Lens of Truth Chest", "Bottom of the Well Lens of Truth Chest", RHT_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, RG_LENS_OF_TRUTH, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 27348, 0x14, "Invisible Chest", "Bottom of the Well Invisible Chest", RHT_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 23760, 0x10, "Underwater Front Chest", "Bottom of the Well Underwater Front Chest", RHT_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22793, 0x09, "Underwater Left Chest", "Bottom of the Well Underwater Left Chest", RHT_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_MAP_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2087, 0x07, "Map Chest", "Bottom of the Well Map Chest", RHT_BOTTOM_OF_THE_WELL_MAP_CHEST, RG_BOTTOM_OF_THE_WELL_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 21802, 0x0A, "Fire Keese Chest", "Bottom of the Well Fire Keese Chest", RHT_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 21836, 0x0C, "Like Like Chest", "Bottom of the Well Like Like Chest", RHT_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 273, 0x01, "Freestanding Key", "Bottom of the Well Freestanding Key", RHT_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); // Bottom of the Well Master Quest - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2083, 0x03, "MQ Map Chest", "Bottom of the Well MQ Map Chest", RHT_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, RG_BOTTOM_OF_THE_WELL_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, -20159, 0x01, "MQ Lens of Truth Chest", "Bottom of the Well MQ Lens of Truth Chest", RHT_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, RG_LENS_OF_TRUTH, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST] = Location::Chest( RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 6146, 0x02, "MQ Compass Chest", "Bottom of the Well MQ Compass Chest", RHT_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, RG_BOTTOM_OF_THE_WELL_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 529, 0x02, "MQ Dead Hand Freestanding Key", "Bottom of the Well MQ Dead Hand Freestanding Key", RHT_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 273, 0x01, "MQ East Inner Room Freestanding Key", "Bottom of the Well MQ East Inner Room Freestanding Key", RHT_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2083, 0x03, "MQ Map Chest", "Bottom of the Well MQ Map Chest", RHT_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, RG_BOTTOM_OF_THE_WELL_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, -20159, 0x01, "MQ Lens of Truth Chest", "Bottom of the Well MQ Lens of Truth Chest", RHT_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, RG_LENS_OF_TRUTH, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 6146, 0x02, "MQ Compass Chest", "Bottom of the Well MQ Compass Chest", RHT_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, RG_BOTTOM_OF_THE_WELL_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 529, 0x02, "MQ Dead Hand Freestanding Key", "Bottom of the Well MQ Dead Hand Freestanding Key", RHT_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 273, 0x01, "MQ East Inner Room Freestanding Key", "Bottom of the Well MQ East Inner Room Freestanding Key", RHT_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flag Short Name Spoiler Name Hint Text Key Vanilla Item Categories Collection Check Group Vanilla Progression // Ice Cavern Vanilla - locationTable[RC_ICE_CAVERN_MAP_CHEST] = Location::Chest( RC_ICE_CAVERN_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2080, 0x00, "Map Chest", "Ice Cavern Map Chest", RHT_ICE_CAVERN_MAP_CHEST, RG_ICE_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_COMPASS_CHEST] = Location::Chest( RC_ICE_CAVERN_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2049, 0x01, "Compass Chest", "Ice Cavern Compass Chest", RHT_ICE_CAVERN_COMPASS_CHEST, RG_ICE_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_IRON_BOOTS_CHEST] = Location::Chest( RC_ICE_CAVERN_IRON_BOOTS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, 0x02, "Iron Boots Chest", "Ice Cavern Iron Boots Chest", RHT_ICE_CAVERN_IRON_BOOTS_CHEST, RG_IRON_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_FREESTANDING_POH, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "Freestanding PoH", "Ice Cavern Freestanding PoH", RHT_ICE_CAVERN_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_MAP_CHEST] = Location::Chest(RC_ICE_CAVERN_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2080, 0x00, "Map Chest", "Ice Cavern Map Chest", RHT_ICE_CAVERN_MAP_CHEST, RG_ICE_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_COMPASS_CHEST] = Location::Chest(RC_ICE_CAVERN_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2049, 0x01, "Compass Chest", "Ice Cavern Compass Chest", RHT_ICE_CAVERN_COMPASS_CHEST, RG_ICE_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_IRON_BOOTS_CHEST] = Location::Chest(RC_ICE_CAVERN_IRON_BOOTS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, 0x02, "Iron Boots Chest", "Ice Cavern Iron Boots Chest", RHT_ICE_CAVERN_IRON_BOOTS_CHEST, RG_IRON_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_FREESTANDING_POH, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "Freestanding PoH", "Ice Cavern Freestanding PoH", RHT_ICE_CAVERN_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); // Ice Cavern Master Quest - locationTable[RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST] = Location::Chest( RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, 0x02, "MQ Iron Boots Chest", "Ice Cavern MQ Iron Boots Chest", RHT_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, RG_IRON_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_MQ_COMPASS_CHEST] = Location::Chest( RC_ICE_CAVERN_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2048, 0x00, "MQ Compass Chest", "Ice Cavern MQ Compass Chest", RHT_ICE_CAVERN_MQ_COMPASS_CHEST, RG_ICE_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_MQ_MAP_CHEST] = Location::Chest( RC_ICE_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, -18399, 0x01, "MQ Map Chest", "Ice Cavern MQ Map Chest", RHT_ICE_CAVERN_MQ_MAP_CHEST, RG_ICE_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_MQ_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_MQ_FREESTANDING_POH, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "MQ Freestanding PoH", "Ice Cavern MQ Freestanding PoH", RHT_ICE_CAVERN_MQ_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, 0x02, "MQ Iron Boots Chest", "Ice Cavern MQ Iron Boots Chest", RHT_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, RG_IRON_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2048, 0x00, "MQ Compass Chest", "Ice Cavern MQ Compass Chest", RHT_ICE_CAVERN_MQ_COMPASS_CHEST, RG_ICE_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, -18399, 0x01, "MQ Map Chest", "Ice Cavern MQ Map Chest", RHT_ICE_CAVERN_MQ_MAP_CHEST, RG_ICE_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_MQ_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_MQ_FREESTANDING_POH, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "MQ Freestanding PoH", "Ice Cavern MQ Freestanding PoH", RHT_ICE_CAVERN_MQ_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flag Short Name Spoiler Name Hint Text Key Vanilla Item Categories Collection Check Group Vanilla Progression // Gerudo Training Grounds Vanilla - locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30573, 0x13, "Lobby Left Chest", "Gerudo Training Grounds Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30393, 0x07, "Lobby Right Chest", "Gerudo Training Grounds Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30656, 0x00, "Stalfos Chest", "Gerudo Training Grounds Stalfos Chest", RHT_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "Beamos Chest", "Gerudo Training Grounds Beamos Chest", RHT_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22603, 0x0B, "Hidden Ceiling Chest", "Gerudo Training Grounds Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23206, 0x06, "Maze Path First Chest", "Gerudo Training Grounds Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "Maze Path Second Chest", "Gerudo Training Grounds Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22889, 0x09, "Maze Path Third Chest", "Gerudo Training Grounds Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 2860, 0x0C, "Maze Path Final Chest", "Gerudo Training Grounds Maze Path Final Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RG_ICE_ARROWS, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23877, 0x05, "Maze Right Central Chest", "Gerudo Training Grounds Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RG_BOMBCHU_5, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22888, 0x08, "Maze Right Side Chest", "Gerudo Training Grounds Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "Underwater Silver Rupee Chest", "Gerudo Training Grounds Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "Hammer Room Clear Chest", "Gerudo Training Grounds Hammer Room Clear Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22608, 0x10, "Hammer Room Switch Chest", "Gerudo Training Grounds Hammer Room Switch Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30653, 0x03, "Eye Statue Chest", "Gerudo Training Grounds Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22596, 0x04, "Near Scarecrow Chest", "Gerudo Training Grounds Near Scarecrow Chest", RHT_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31089, 0x11, "Before Heavy Block Chest", "Gerudo Training Grounds Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31439, 0x0F, "Heavy Block First Chest", "Gerudo Training Grounds Heavy Block First Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 30862, 0x0E, "Heavy Block Second Chest", "Gerudo Training Grounds Heavy Block Second Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 26708, 0x14, "Heavy Block Third Chest", "Gerudo Training Grounds Heavy Block Third Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24450, 0x02, "Heavy Block Fourth Chest", "Gerudo Training Grounds Heavy Block Fourth Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, 273, 0x01, "Freestanding Key", "Gerudo Training Grounds Freestanding Key", RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30573, 0x13, "Lobby Left Chest", "Gerudo Training Grounds Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30393, 0x07, "Lobby Right Chest", "Gerudo Training Grounds Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30656, 0x00, "Stalfos Chest", "Gerudo Training Grounds Stalfos Chest", RHT_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "Beamos Chest", "Gerudo Training Grounds Beamos Chest", RHT_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22603, 0x0B, "Hidden Ceiling Chest", "Gerudo Training Grounds Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23206, 0x06, "Maze Path First Chest", "Gerudo Training Grounds Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "Maze Path Second Chest", "Gerudo Training Grounds Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22889, 0x09, "Maze Path Third Chest", "Gerudo Training Grounds Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 2860, 0x0C, "Maze Path Final Chest", "Gerudo Training Grounds Maze Path Final Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RG_ICE_ARROWS, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23877, 0x05, "Maze Right Central Chest", "Gerudo Training Grounds Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RG_BOMBCHU_5, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22888, 0x08, "Maze Right Side Chest", "Gerudo Training Grounds Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "Underwater Silver Rupee Chest", "Gerudo Training Grounds Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "Hammer Room Clear Chest", "Gerudo Training Grounds Hammer Room Clear Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22608, 0x10, "Hammer Room Switch Chest", "Gerudo Training Grounds Hammer Room Switch Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30653, 0x03, "Eye Statue Chest", "Gerudo Training Grounds Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22596, 0x04, "Near Scarecrow Chest", "Gerudo Training Grounds Near Scarecrow Chest", RHT_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31089, 0x11, "Before Heavy Block Chest", "Gerudo Training Grounds Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31439, 0x0F, "Heavy Block First Chest", "Gerudo Training Grounds Heavy Block First Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 30862, 0x0E, "Heavy Block Second Chest", "Gerudo Training Grounds Heavy Block Second Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 26708, 0x14, "Heavy Block Third Chest", "Gerudo Training Grounds Heavy Block Third Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24450, 0x02, "Heavy Block Fourth Chest", "Gerudo Training Grounds Heavy Block Fourth Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, 273, 0x01, "Freestanding Key", "Gerudo Training Grounds Freestanding Key", RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); // Gerudo Training Grounds Master Quest - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23879, 0x07, "MQ Lobby Right Chest", "Gerudo Training Grounds MQ Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RG_BOMBCHU_5, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22867, 0x13, "MQ Lobby Left Chest", "Gerudo Training Grounds MQ Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30304, 0x00, "MQ First Iron Knuckle Chest", "Gerudo Training Grounds MQ First Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31057, 0x11, "MQ Before Heavy Block Chest", "Gerudo Training Grounds MQ Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -32669, 0x03, "MQ Eye Statue Chest", "Gerudo Training Grounds MQ Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30642, 0x0E, "MQ Flame Circle Chest", "Gerudo Training Grounds MQ Flame Circle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "MQ Second Iron Knuckle Chest", "Gerudo Training Grounds MQ Second Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "MQ Dinolfos Chest", "Gerudo Training Grounds MQ Dinolfos Chest", RHT_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -17628, 0x04, "MQ Ice Arrows Chest", "Gerudo Training Grounds MQ Ice Arrows Chest", RHT_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RG_ICE_ARROWS, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22661, 0x05, "MQ Maze Right Central Chest", "Gerudo Training Grounds MQ Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22918, 0x06, "MQ Maze Path First Chest", "Gerudo Training Grounds MQ Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RG_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24136, 0x08, "MQ Maze Right Side Chest", "Gerudo Training Grounds MQ Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST] = Location::Chest( RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24137, 0x09, "MQ Maze Path Third Chest", "Gerudo Training Grounds MQ Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "MQ Maze Path Second Chest", "Gerudo Training Grounds MQ Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23211, 0x0B, "MQ Hidden Ceiling Chest", "Gerudo Training Grounds MQ Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "MQ Underwater Silver Rupee Chest", "Gerudo Training Grounds MQ Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31394, 0x02, "MQ Heavy Block Chest", "Gerudo Training Grounds MQ Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23879, 0x07, "MQ Lobby Right Chest", "Gerudo Training Grounds MQ Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RG_BOMBCHU_5, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22867, 0x13, "MQ Lobby Left Chest", "Gerudo Training Grounds MQ Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30304, 0x00, "MQ First Iron Knuckle Chest", "Gerudo Training Grounds MQ First Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31057, 0x11, "MQ Before Heavy Block Chest", "Gerudo Training Grounds MQ Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -32669, 0x03, "MQ Eye Statue Chest", "Gerudo Training Grounds MQ Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30642, 0x0E, "MQ Flame Circle Chest", "Gerudo Training Grounds MQ Flame Circle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "MQ Second Iron Knuckle Chest", "Gerudo Training Grounds MQ Second Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "MQ Dinolfos Chest", "Gerudo Training Grounds MQ Dinolfos Chest", RHT_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -17628, 0x04, "MQ Ice Arrows Chest", "Gerudo Training Grounds MQ Ice Arrows Chest", RHT_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RG_ICE_ARROWS, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22661, 0x05, "MQ Maze Right Central Chest", "Gerudo Training Grounds MQ Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22918, 0x06, "MQ Maze Path First Chest", "Gerudo Training Grounds MQ Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RG_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24136, 0x08, "MQ Maze Right Side Chest", "Gerudo Training Grounds MQ Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24137, 0x09, "MQ Maze Path Third Chest", "Gerudo Training Grounds MQ Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "MQ Maze Path Second Chest", "Gerudo Training Grounds MQ Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23211, 0x0B, "MQ Hidden Ceiling Chest", "Gerudo Training Grounds MQ Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "MQ Underwater Silver Rupee Chest", "Gerudo Training Grounds MQ Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31394, 0x02, "MQ Heavy Block Chest", "Gerudo Training Grounds MQ Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flag Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression // Ganon's Castle Shared - locationTable[RC_GANONS_TOWER_BOSS_KEY_CHEST] = Location::Chest(RC_GANONS_TOWER_BOSS_KEY_CHEST, RCQUEST_BOTH, RCTYPE_GANON_BOSS_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANONS_TOWER, 10219, 0x0B, "Boss Key Chest", "Ganon's Tower Boss Key Chest", RHT_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_GANONS_TOWER_BOSS_KEY_CHEST] = Location::Chest(RC_GANONS_TOWER_BOSS_KEY_CHEST, RCQUEST_BOTH, RCTYPE_GANON_BOSS_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANONS_TOWER, 10219, 0x0B, "Boss Key Chest", "Ganon's Tower Boss Key Chest", RHT_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); // Ganon's Castle Vanilla - locationTable[RC_GANONS_CASTLE_FOREST_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30857, 0x09, "Forest Trial Chest", "Ganon's Castle Forest Trial Chest", RHT_GANONS_CASTLE_FOREST_TRIAL_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24455, 0x07, "Water Trial Left Chest", "Ganon's Castle Water Trial Left Chest", RHT_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22790, 0x06, "Water Trial Right Chest", "Ganon's Castle Water Trial Right Chest", RHT_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST] = Location::Chest(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22664, 0x08, "Shadow Trial Front Chest", "Ganon's Castle Shadow Trial Front Chest", RHT_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST] = Location::Chest(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 14021, 0x05, "Shadow Trial Golden Gauntlets Chest", "Ganon's Castle Shadow Trial Golden Gauntlets Chest", RHT_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -29326, 0x12, "Spirit Trial Crystal Switch Chest", "Ganon's Castle Spirit Trial Crystal Switch Chest", RHT_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, RG_BOMBCHU_20, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "Spirit Trial Invisible Chest", "Ganon's Castle Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22668, 0x0C, "Light Trial First Left Chest", "Ganon's Castle Light Trial First Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24459, 0x0B, "Light Trial Second Left Chest", "Ganon's Castle Light Trial Second Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22797, 0x0D, "Light Trial Third Left Chest", "Ganon's Castle Light Trial Third Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24462, 0x0E, "Light Trial First Right Chest", "Ganon's Castle Light Trial First Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22890, 0x0A, "Light Trial Second Right Chest", "Ganon's Castle Light Trial Second Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24463, 0x0F, "Light Trial Third Right Chest", "Ganon's Castle Light Trial Third Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30800, 0x10, "Light Trial Invisible Enemies Chest", "Ganon's Castle Light Trial Invisible Enemies Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30639, 0x11, "Light Trial Lullaby Chest", "Ganon's Castle Light Trial Lullaby Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, 0x37, "Deku Scrub Center-Left", "Ganon's Castle Deku Scrub Center-Left", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x06), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, 0x33, "Deku Scrub Center-Right", "Ganon's Castle Deku Scrub Center-Right", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x04), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, 0x39, "Deku Scrub Right", "Ganon's Castle Deku Scrub Right", RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x08), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, 0x3A, "Deku Scrub Left", "Ganon's Castle Deku Scrub Left", RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x09), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_FOREST_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30857, 0x09, "Forest Trial Chest", "Ganon's Castle Forest Trial Chest", RHT_GANONS_CASTLE_FOREST_TRIAL_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24455, 0x07, "Water Trial Left Chest", "Ganon's Castle Water Trial Left Chest", RHT_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22790, 0x06, "Water Trial Right Chest", "Ganon's Castle Water Trial Right Chest", RHT_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST] = Location::Chest(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22664, 0x08, "Shadow Trial Front Chest", "Ganon's Castle Shadow Trial Front Chest", RHT_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST] = Location::Chest(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 14021, 0x05, "Shadow Trial Golden Gauntlets Chest", "Ganon's Castle Shadow Trial Golden Gauntlets Chest", RHT_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -29326, 0x12, "Spirit Trial Crystal Switch Chest", "Ganon's Castle Spirit Trial Crystal Switch Chest", RHT_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, RG_BOMBCHU_20, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "Spirit Trial Invisible Chest", "Ganon's Castle Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22668, 0x0C, "Light Trial First Left Chest", "Ganon's Castle Light Trial First Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24459, 0x0B, "Light Trial Second Left Chest", "Ganon's Castle Light Trial Second Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22797, 0x0D, "Light Trial Third Left Chest", "Ganon's Castle Light Trial Third Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24462, 0x0E, "Light Trial First Right Chest", "Ganon's Castle Light Trial First Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22890, 0x0A, "Light Trial Second Right Chest", "Ganon's Castle Light Trial Second Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24463, 0x0F, "Light Trial Third Right Chest", "Ganon's Castle Light Trial Third Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30800, 0x10, "Light Trial Invisible Enemies Chest", "Ganon's Castle Light Trial Invisible Enemies Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30639, 0x11, "Light Trial Lullaby Chest", "Ganon's Castle Light Trial Lullaby Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, 0x37, "Deku Scrub Center-Left", "Ganon's Castle Deku Scrub Center-Left", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, 0x33, "Deku Scrub Center-Right", "Ganon's Castle Deku Scrub Center-Right", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, 0x39, "Deku Scrub Right", "Ganon's Castle Deku Scrub Right", RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, 0x3A, "Deku Scrub Left", "Ganon's Castle Deku Scrub Left", RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); // Ganon's Castle MQ - locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22977, 0x01, "MQ Water Trial Chest", "Ganon's Castle MQ Water Trial Chest", RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30398, 0x02, "MQ Forest Trial Eye Switch Chest", "Ganon's Castle MQ Forest Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -32733, 0x03, "MQ Forest Trial Frozen Eye Switch Chest", "Ganon's Castle MQ Forest Trial Frozen Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30460, 0x04, "MQ Light Trial Lullaby Chest", "Ganon's Castle MQ Light Trial Lullaby Chest", RHT_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30400, 0x00, "MQ Shadow Trial Bomb Flower Chest", "Ganon's Castle MQ Shadow Trial Bomb Flower Chest", RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30651, 0x05, "MQ Shadow Trial Eye Switch Chest", "Ganon's Castle MQ Shadow Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -18746, 0x06, "MQ Spirit Trial Golden Gauntlets Chest", "Ganon's Castle MQ Spirit Trial Golden Gauntlets Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30457, 0x07, "MQ Spirit Trial Sun Back Right Chest", "Ganon's Castle MQ Spirit Trial Sun Back Right Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30648, 0x08, "MQ Spirit Trial Sun Back Left Chest", "Ganon's Castle MQ Spirit Trial Sun Back Left Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30455, 0x09, "MQ Spirit Trial Sun Front Left Chest", "Ganon's Castle MQ Spirit Trial Sun Front Left Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 20586, 0x0A, "MQ Spirit Trial First Chest", "Ganon's Castle MQ Spirit Trial First Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "MQ Spirit Trial Invisible Chest", "Ganon's Castle MQ Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = Location::Collectable(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, 273, 0x01, "MQ Forest Trial Freestanding Key", "Ganon's Castle MQ Forest Trial Freestanding Key", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x00, 0x30, "MQ Deku Scrub Right", "Ganon's Castle MQ Deku Scrub Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x01), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, 0x37, "MQ Deku Scrub Center-Left", "Ganon's Castle MQ Deku Scrub Center-Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x06), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, 0x33, "MQ Deku Scrub Center", "Ganon's Castle MQ Deku Scrub Center", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x04), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, 0x39, "MQ Deku Scrub Center-Right", "Ganon's Castle MQ Deku Scrub Center-Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x08), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, 0x3A, "MQ Deku Scrub Left", "Ganon's Castle MQ Deku Scrub Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::Scrub(0x0D, 0x09), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22977, 0x01, "MQ Water Trial Chest", "Ganon's Castle MQ Water Trial Chest", RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30398, 0x02, "MQ Forest Trial Eye Switch Chest", "Ganon's Castle MQ Forest Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -32733, 0x03, "MQ Forest Trial Frozen Eye Switch Chest", "Ganon's Castle MQ Forest Trial Frozen Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30460, 0x04, "MQ Light Trial Lullaby Chest", "Ganon's Castle MQ Light Trial Lullaby Chest", RHT_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30400, 0x00, "MQ Shadow Trial Bomb Flower Chest", "Ganon's Castle MQ Shadow Trial Bomb Flower Chest", RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30651, 0x05, "MQ Shadow Trial Eye Switch Chest", "Ganon's Castle MQ Shadow Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -18746, 0x06, "MQ Spirit Trial Golden Gauntlets Chest", "Ganon's Castle MQ Spirit Trial Golden Gauntlets Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30457, 0x07, "MQ Spirit Trial Sun Back Right Chest", "Ganon's Castle MQ Spirit Trial Sun Back Right Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30648, 0x08, "MQ Spirit Trial Sun Back Left Chest", "Ganon's Castle MQ Spirit Trial Sun Back Left Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30455, 0x09, "MQ Spirit Trial Sun Front Left Chest", "Ganon's Castle MQ Spirit Trial Sun Front Left Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 20586, 0x0A, "MQ Spirit Trial First Chest", "Ganon's Castle MQ Spirit Trial First Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "MQ Spirit Trial Invisible Chest", "Ganon's Castle MQ Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = Location::Collectable(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, 273, 0x01, "MQ Forest Trial Freestanding Key", "Ganon's Castle MQ Forest Trial Freestanding Key", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x00, 0x30, "MQ Deku Scrub Right", "Ganon's Castle MQ Deku Scrub Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, 0x37, "MQ Deku Scrub Center-Left", "Ganon's Castle MQ Deku Scrub Center-Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, 0x33, "MQ Deku Scrub Center", "Ganon's Castle MQ Deku Scrub Center", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, 0x39, "MQ Deku Scrub Center-Right", "Ganon's Castle MQ Deku Scrub Center-Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, 0x3A, "MQ Deku Scrub Left", "Ganon's Castle MQ Deku Scrub Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); // Gold Skulltula Tokens // Dungeons - // Deku Tree RandomizerCheck RandomizerCheck Quest Area Scene ID params Flag Short Name Spoiler Name Hint Text Key Categories Collection Check Group - locationTable[RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8193, 0x01, "GS Basement Back Room", "Deku Tree GS Basement Back Room", RHT_DEKU_TREE_GS_BASEMENT_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_GS_BASEMENT_GATE] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_GATE, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8194, 0x02, "GS Basement Gate", "Deku Tree GS Basement Gate", RHT_DEKU_TREE_GS_BASEMENT_GATE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_GS_BASEMENT_VINES] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_VINES, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8196, 0x04, "GS Basement Vines", "Deku Tree GS Basement Vines", RHT_DEKU_TREE_GS_BASEMENT_VINES, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_COMPASS_ROOM, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8200, 0x08, "GS Compass Room", "Deku Tree GS Compass Room", RHT_DEKU_TREE_GS_COMPASS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_GS_LOBBY] = Location::GSToken(RC_DEKU_TREE_MQ_GS_LOBBY, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8194, 0x02, "MQ GS Lobby", "Deku Tree MQ GS Lobby", RHT_DEKU_TREE_MQ_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8200, 0x08, "MQ GS Compass Room", "Deku Tree MQ GS Compass Room", RHT_DEKU_TREE_MQ_GS_COMPASS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8196, 0x04, "MQ GS Basement Graves Room", "Deku Tree MQ GS Basement Graves Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8193, 0x01, "MQ GS Basement Back Room", "Deku Tree MQ GS Basement Back Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + // Deku Tree + locationTable[RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8193, 0x01, "GS Basement Back Room", "Deku Tree GS Basement Back Room", RHT_DEKU_TREE_GS_BASEMENT_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_GS_BASEMENT_GATE] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_GATE, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8194, 0x02, "GS Basement Gate", "Deku Tree GS Basement Gate", RHT_DEKU_TREE_GS_BASEMENT_GATE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_GS_BASEMENT_VINES] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_VINES, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8196, 0x04, "GS Basement Vines", "Deku Tree GS Basement Vines", RHT_DEKU_TREE_GS_BASEMENT_VINES, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_COMPASS_ROOM, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8200, 0x08, "GS Compass Room", "Deku Tree GS Compass Room", RHT_DEKU_TREE_GS_COMPASS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_GS_LOBBY] = Location::GSToken(RC_DEKU_TREE_MQ_GS_LOBBY, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8194, 0x02, "MQ GS Lobby", "Deku Tree MQ GS Lobby", RHT_DEKU_TREE_MQ_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8200, 0x08, "MQ GS Compass Room", "Deku Tree MQ GS Compass Room", RHT_DEKU_TREE_MQ_GS_COMPASS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8196, 0x04, "MQ GS Basement Graves Room", "Deku Tree MQ GS Basement Graves Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8193, 0x01, "MQ GS Basement Back Room", "Deku Tree MQ GS Basement Back Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); // Dodongo's Cavern - locationTable[RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8449, 0x01, "GS Vines Above Stairs", "Dodongos Cavern GS Vines Above Stairs", RHT_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_GS_SCARECROW] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SCARECROW, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8450, 0x02, "GS Scarecrow", "Dodongos Cavern GS Scarecrow", RHT_DODONGOS_CAVERN_GS_SCARECROW, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8452, 0x04, "GS Alcove Above Stairs", "Dodongos Cavern GS Alcove Above Stairs", RHT_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_GS_BACK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_GS_BACK_ROOM, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8456, 0x08, "GS Back Room", "Dodongos Cavern GS Back Room", RHT_DODONGOS_CAVERN_GS_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8464, 0x10, "GS Side Room Near Lower Lizalfos", "Dodongos Cavern GS Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8450, 0x02, "MQ GS Scrub Room", "Dodongos Cavern MQ GS Scrub Room", RHT_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8456, 0x08, "MQ GS Song of Time Block Room", "Dodongos Cavern MQ GS Song of Time Block Room", RHT_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8452, 0x04, "MQ GS Lizalfos Room", "Dodongos Cavern MQ GS Lizalfos Room", RHT_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8464, 0x10, "MQ GS Larvae Room", "Dodongos Cavern MQ GS Larvae Room", RHT_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8449, 0x01, "MQ GS Back Room", "Dodongos Cavern MQ GS Back Room", RHT_DODONGOS_CAVERN_MQ_GS_BACK_AREA, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8705, 0x01, "GS Lobby Basement Lower", "Jabu Jabus Belly GS Lobby Basement Lower", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8706, 0x02, "GS Lobby Basement Upper", "Jabu Jabus Belly GS Lobby Basement Upper", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8708, 0x04, "GS Near Boss", "Jabu Jabus Belly GS Near Boss", RHT_JABU_JABUS_BELLY_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8712, 0x08, "GS Water Switch Room", "Jabu Jabus Belly GS Water Switch Room", RHT_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8708, 0x04, "MQ GS Tail Parasan Room", "Jabu Jabus Belly MQ GS Tail Parasan Room", RHT_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8712, 0x08, "MQ GS Invisible Enemies Room", "Jabu Jabus Belly MQ GS Invisible Enemies Room", RHT_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8705, 0x01, "MQ GS Boomerang Chest Room", "Jabu Jabus Belly MQ GS Boomerang Chest Room", RHT_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8706, 0x02, "MQ GS Near Boss", "Jabu Jabus Belly MQ GS Near Boss", RHT_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8961, 0x01, "GS Raised Island Courtyard", "Forest Temple GS Raised Island Courtyard", RHT_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_GS_FIRST_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_GS_FIRST_ROOM, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8962, 0x02, "GS First Room", "Forest Temple GS First Room", RHT_FOREST_TEMPLE_GS_FIRST_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8964, 0x04, "GS Level Island Courtyard", "Forest Temple GS Level Island Courtyard", RHT_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_GS_LOBBY] = Location::GSToken(RC_FOREST_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8968, 0x08, "GS Lobby", "Forest Temple GS Lobby", RHT_FOREST_TEMPLE_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_GS_BASEMENT] = Location::GSToken(RC_FOREST_TEMPLE_GS_BASEMENT, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8976, 0x10, "GS Basement", "Forest Temple GS Basement", RHT_FOREST_TEMPLE_GS_BASEMENT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8962, 0x02, "MQ GS First Hallway", "Forest Temple MQ GS First Hallway", RHT_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8976, 0x10, "MQ GS Block Push Room", "Forest Temple MQ GS Block Push Room", RHT_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8961, 0x01, "MQ GS Raised Island Courtyard", "Forest Temple MQ GS Raised Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8964, 0x04, "MQ GS Level Island Courtyard", "Forest Temple MQ GS Level Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_WELL] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_WELL, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8968, 0x08, "MQ GS Well", "Forest Temple MQ GS Well", RHT_FOREST_TEMPLE_MQ_GS_WELL, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8449, 0x01, "GS Vines Above Stairs", "Dodongos Cavern GS Vines Above Stairs", RHT_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_GS_SCARECROW] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SCARECROW, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8450, 0x02, "GS Scarecrow", "Dodongos Cavern GS Scarecrow", RHT_DODONGOS_CAVERN_GS_SCARECROW, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8452, 0x04, "GS Alcove Above Stairs", "Dodongos Cavern GS Alcove Above Stairs", RHT_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_GS_BACK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_GS_BACK_ROOM, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8456, 0x08, "GS Back Room", "Dodongos Cavern GS Back Room", RHT_DODONGOS_CAVERN_GS_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8464, 0x10, "GS Side Room Near Lower Lizalfos", "Dodongos Cavern GS Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8450, 0x02, "MQ GS Scrub Room", "Dodongos Cavern MQ GS Scrub Room", RHT_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8456, 0x08, "MQ GS Song of Time Block Room", "Dodongos Cavern MQ GS Song of Time Block Room", RHT_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8452, 0x04, "MQ GS Lizalfos Room", "Dodongos Cavern MQ GS Lizalfos Room", RHT_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8464, 0x10, "MQ GS Larvae Room", "Dodongos Cavern MQ GS Larvae Room", RHT_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8449, 0x01, "MQ GS Back Room", "Dodongos Cavern MQ GS Back Room", RHT_DODONGOS_CAVERN_MQ_GS_BACK_AREA, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8705, 0x01, "GS Lobby Basement Lower", "Jabu Jabus Belly GS Lobby Basement Lower", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8706, 0x02, "GS Lobby Basement Upper", "Jabu Jabus Belly GS Lobby Basement Upper", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8708, 0x04, "GS Near Boss", "Jabu Jabus Belly GS Near Boss", RHT_JABU_JABUS_BELLY_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8712, 0x08, "GS Water Switch Room", "Jabu Jabus Belly GS Water Switch Room", RHT_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8708, 0x04, "MQ GS Tail Parasan Room", "Jabu Jabus Belly MQ GS Tail Parasan Room", RHT_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8712, 0x08, "MQ GS Invisible Enemies Room", "Jabu Jabus Belly MQ GS Invisible Enemies Room", RHT_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8705, 0x01, "MQ GS Boomerang Chest Room", "Jabu Jabus Belly MQ GS Boomerang Chest Room", RHT_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8706, 0x02, "MQ GS Near Boss", "Jabu Jabus Belly MQ GS Near Boss", RHT_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8961, 0x01, "GS Raised Island Courtyard", "Forest Temple GS Raised Island Courtyard", RHT_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_GS_FIRST_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_GS_FIRST_ROOM, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8962, 0x02, "GS First Room", "Forest Temple GS First Room", RHT_FOREST_TEMPLE_GS_FIRST_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8964, 0x04, "GS Level Island Courtyard", "Forest Temple GS Level Island Courtyard", RHT_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_GS_LOBBY] = Location::GSToken(RC_FOREST_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8968, 0x08, "GS Lobby", "Forest Temple GS Lobby", RHT_FOREST_TEMPLE_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_GS_BASEMENT] = Location::GSToken(RC_FOREST_TEMPLE_GS_BASEMENT, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8976, 0x10, "GS Basement", "Forest Temple GS Basement", RHT_FOREST_TEMPLE_GS_BASEMENT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8962, 0x02, "MQ GS First Hallway", "Forest Temple MQ GS First Hallway", RHT_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8976, 0x10, "MQ GS Block Push Room", "Forest Temple MQ GS Block Push Room", RHT_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8961, 0x01, "MQ GS Raised Island Courtyard", "Forest Temple MQ GS Raised Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8964, 0x04, "MQ GS Level Island Courtyard", "Forest Temple MQ GS Level Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_MQ_GS_WELL] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_WELL, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8968, 0x08, "MQ GS Well", "Forest Temple MQ GS Well", RHT_FOREST_TEMPLE_MQ_GS_WELL, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); // Fire Temple - locationTable[RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9217, 0x01, "GS Song of Time Room", "Fire Temple GS Song of Time Room", RHT_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9218, 0x02, "GS Boss Key Loop", "Fire Temple GS Boss Key Loop", RHT_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_GS_BOULDER_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9220, 0x04, "GS Boulder Maze", "Fire Temple GS Boulder Maze", RHT_FIRE_TEMPLE_GS_BOULDER_MAZE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_TOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9224, 0x08, "GS Scarecrow Top", "Fire Temple GS Scarecrow Top", RHT_FIRE_TEMPLE_GS_SCARECROW_TOP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9232, 0x10, "GS Scarecrow Climb", "Fire Temple GS Scarecrow Climb", RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9218, 0x02, "MQ GS Above Fire Wall Maze", "Fire Temple MQ GS Above Fire Wall Maze", RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9224, 0x08, "MQ GS Fire Wall Maze Center", "Fire Temple MQ GS Fire Wall Maze Center", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9217, 0x01, "MQ GS Big Lava Room Open Door", "Fire Temple MQ GS Big Lava Room Open Door", RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9232, 0x10, "MQ GS Fire Wall Maze Side Room", "Fire Temple MQ GS Fire Wall Maze Side Room", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9220, 0x04, "MQ GS Skull on Fire", "Fire Temple MQ GS Skull on Fire", RHT_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9217, 0x01, "GS Song of Time Room", "Fire Temple GS Song of Time Room", RHT_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9218, 0x02, "GS Boss Key Loop", "Fire Temple GS Boss Key Loop", RHT_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_GS_BOULDER_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9220, 0x04, "GS Boulder Maze", "Fire Temple GS Boulder Maze", RHT_FIRE_TEMPLE_GS_BOULDER_MAZE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_TOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9224, 0x08, "GS Scarecrow Top", "Fire Temple GS Scarecrow Top", RHT_FIRE_TEMPLE_GS_SCARECROW_TOP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9232, 0x10, "GS Scarecrow Climb", "Fire Temple GS Scarecrow Climb", RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9218, 0x02, "MQ GS Above Fire Wall Maze", "Fire Temple MQ GS Above Fire Wall Maze", RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9224, 0x08, "MQ GS Fire Wall Maze Center", "Fire Temple MQ GS Fire Wall Maze Center", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9217, 0x01, "MQ GS Big Lava Room Open Door", "Fire Temple MQ GS Big Lava Room Open Door", RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9232, 0x10, "MQ GS Fire Wall Maze Side Room", "Fire Temple MQ GS Fire Wall Maze Side Room", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9220, 0x04, "MQ GS Skull on Fire", "Fire Temple MQ GS Skull on Fire", RHT_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); // Water Temple - locationTable[RC_WATER_TEMPLE_GS_BEHIND_GATE] = Location::GSToken(RC_WATER_TEMPLE_GS_BEHIND_GATE, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9473, 0x01, "GS Behind Gate", "Water Temple GS Behind Gate", RHT_WATER_TEMPLE_GS_BEHIND_GATE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = Location::GSToken(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9474, 0x02, "GS Falling Platform Room", "Water Temple GS Falling Platform Room", RHT_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_GS_CENTRAL_PILLAR] = Location::GSToken(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9476, 0x04, "GS Central Pillar", "Water Temple GS Central Pillar", RHT_WATER_TEMPLE_GS_CENTRAL_PILLAR, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = Location::GSToken(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9480, 0x08, "GS Near Boss Key Chest", "Water Temple GS Near Boss Key Chest", RHT_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_GS_RIVER, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9488, 0x10, "GS River", "Water Temple GS River", RHT_WATER_TEMPLE_GS_RIVER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9476, 0x04, "MQ GS Before Upper Water Switch", "Water Temple MQ GS Before Upper Water Switch", RHT_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9480, 0x08, "MQ GS Freestanding Key Area", "Water Temple MQ GS Freestanding Key Area", RHT_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9473, 0x01, "MQ GS Lizalfos Hallway", "Water Temple MQ GS Lizalfos Hallway", RHT_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_RIVER, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9474, 0x02, "MQ GS River", "Water Temple MQ GS River", RHT_WATER_TEMPLE_MQ_GS_RIVER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9488, 0x10, "MQ GS Triple Wall Torch", "Water Temple MQ GS Triple Wall Torch", RHT_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_GS_BEHIND_GATE] = Location::GSToken(RC_WATER_TEMPLE_GS_BEHIND_GATE, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9473, 0x01, "GS Behind Gate", "Water Temple GS Behind Gate", RHT_WATER_TEMPLE_GS_BEHIND_GATE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = Location::GSToken(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9474, 0x02, "GS Falling Platform Room", "Water Temple GS Falling Platform Room", RHT_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_GS_CENTRAL_PILLAR] = Location::GSToken(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9476, 0x04, "GS Central Pillar", "Water Temple GS Central Pillar", RHT_WATER_TEMPLE_GS_CENTRAL_PILLAR, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = Location::GSToken(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9480, 0x08, "GS Near Boss Key Chest", "Water Temple GS Near Boss Key Chest", RHT_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_GS_RIVER, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9488, 0x10, "GS River", "Water Temple GS River", RHT_WATER_TEMPLE_GS_RIVER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9476, 0x04, "MQ GS Before Upper Water Switch", "Water Temple MQ GS Before Upper Water Switch", RHT_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9480, 0x08, "MQ GS Freestanding Key Area", "Water Temple MQ GS Freestanding Key Area", RHT_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9473, 0x01, "MQ GS Lizalfos Hallway", "Water Temple MQ GS Lizalfos Hallway", RHT_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_MQ_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_RIVER, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9474, 0x02, "MQ GS River", "Water Temple MQ GS River", RHT_WATER_TEMPLE_MQ_GS_RIVER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9488, 0x10, "MQ GS Triple Wall Torch", "Water Temple MQ GS Triple Wall Torch", RHT_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); // Spirit Temple - locationTable[RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "GS Hall After Sun Block Room", "Spirit Temple GS Hall After Sun Block Room", RHT_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "GS Boulder Room", "Spirit Temple GS Boulder Room", RHT_SPIRIT_TEMPLE_GS_BOULDER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_GS_LOBBY] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "GS Lobby", "Spirit Temple GS Lobby", RHT_SPIRIT_TEMPLE_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "GS Sun on Floor Room", "Spirit Temple GS Sun on Floor Room", RHT_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_GS_METAL_FENCE] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "GS Metal Fence", "Spirit Temple GS Metal Fence", RHT_SPIRIT_TEMPLE_GS_METAL_FENCE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "MQ GS Symphony Room", "Spirit Temple MQ GS Symphony Room", RHT_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "MQ GS Leever Room", "Spirit Temple MQ GS Leever Room", RHT_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "MQ GS Nine Thrones Room West", "Spirit Temple MQ GS Nine Thrones Room West", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "MQ GS Nine Thrones Room North", "Spirit Temple MQ GS Nine Thrones Room North", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "MQ GS Sun Block Room", "Spirit Temple MQ GS Sun Block Room", RHT_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "GS Hall After Sun Block Room", "Spirit Temple GS Hall After Sun Block Room", RHT_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "GS Boulder Room", "Spirit Temple GS Boulder Room", RHT_SPIRIT_TEMPLE_GS_BOULDER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_GS_LOBBY] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "GS Lobby", "Spirit Temple GS Lobby", RHT_SPIRIT_TEMPLE_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "GS Sun on Floor Room", "Spirit Temple GS Sun on Floor Room", RHT_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_GS_METAL_FENCE] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "GS Metal Fence", "Spirit Temple GS Metal Fence", RHT_SPIRIT_TEMPLE_GS_METAL_FENCE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "MQ GS Symphony Room", "Spirit Temple MQ GS Symphony Room", RHT_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "MQ GS Leever Room", "Spirit Temple MQ GS Leever Room", RHT_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "MQ GS Nine Thrones Room West", "Spirit Temple MQ GS Nine Thrones Room West", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "MQ GS Nine Thrones Room North", "Spirit Temple MQ GS Nine Thrones Room North", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "MQ GS Sun Block Room", "Spirit Temple MQ GS Sun Block Room", RHT_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); // Shadow Temple - locationTable[RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9985, 0x01, "GS Single Giant Pot", "Shadow Temple GS Single Giant Pot", RHT_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9986, 0x02, "GS Falling Spikes Room", "Shadow Temple GS Falling Spikes Room", RHT_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9988, 0x04, "GS Triple Giant Pot", "Shadow Temple GS Triple Giant Pot", RHT_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9992, 0x08, "GS Like Like Room", "Shadow Temple GS Like Like Room", RHT_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_GS_NEAR_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 10000, 0x10, "GS Near Ship", "Shadow Temple GS Near Ship", RHT_SHADOW_TEMPLE_GS_NEAR_SHIP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9986, 0x02, "MQ GS Falling Spikes Room", "Shadow Temple MQ GS Falling Spikes Room", RHT_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9985, 0x01, "MQ GS Wind Hint Room", "Shadow Temple MQ GS Wind Hint Room", RHT_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9992, 0x08, "MQ GS After Wind", "Shadow Temple MQ GS After Wind", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 10000, 0x10, "MQ GS After Ship", "Shadow Temple MQ GS After Ship", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9988, 0x04, "MQ GS Near Boss", "Shadow Temple MQ GS Near Boss", RHT_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9985, 0x01, "GS Single Giant Pot", "Shadow Temple GS Single Giant Pot", RHT_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9986, 0x02, "GS Falling Spikes Room", "Shadow Temple GS Falling Spikes Room", RHT_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9988, 0x04, "GS Triple Giant Pot", "Shadow Temple GS Triple Giant Pot", RHT_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9992, 0x08, "GS Like Like Room", "Shadow Temple GS Like Like Room", RHT_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_GS_NEAR_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 10000, 0x10, "GS Near Ship", "Shadow Temple GS Near Ship", RHT_SHADOW_TEMPLE_GS_NEAR_SHIP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9986, 0x02, "MQ GS Falling Spikes Room", "Shadow Temple MQ GS Falling Spikes Room", RHT_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9985, 0x01, "MQ GS Wind Hint Room", "Shadow Temple MQ GS Wind Hint Room", RHT_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9992, 0x08, "MQ GS After Wind", "Shadow Temple MQ GS After Wind", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 10000, 0x10, "MQ GS After Ship", "Shadow Temple MQ GS After Ship", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9988, 0x04, "MQ GS Near Boss", "Shadow Temple MQ GS Near Boss", RHT_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); // Bottom of the Well - locationTable[RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "GS Like Like Cage", "Bottom of the Well GS Like Like Cage", RHT_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "GS East Inner Room", "Bottom of the Well GS East Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "GS West Inner Room", "Bottom of the Well GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "MQ GS Basement", "Bottom of the Well MQ GS Basement", RHT_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "MQ GS Coffin Room", "Bottom of the Well MQ GS Coffin Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "MQ GS West Inner Room", "Bottom of the Well MQ GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "GS Like Like Cage", "Bottom of the Well GS Like Like Cage", RHT_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "GS East Inner Room", "Bottom of the Well GS East Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "GS West Inner Room", "Bottom of the Well GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "MQ GS Basement", "Bottom of the Well MQ GS Basement", RHT_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "MQ GS Coffin Room", "Bottom of the Well MQ GS Coffin Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "MQ GS West Inner Room", "Bottom of the Well MQ GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); // Ice Cavern - locationTable[RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10497, 0x01, "GS Push Block Room", "Ice Cavern GS Push Block Room", RHT_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10498, 0x02, "GS Spinning Scythe Room", "Ice Cavern GS Spinning Scythe Room", RHT_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_GS_HEART_PIECE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10500, 0x04, "GS Heart Piece Room", "Ice Cavern GS Heart Piece Room", RHT_ICE_CAVERN_GS_HEART_PIECE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_MQ_GS_SCARECROW] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_SCARECROW, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10497, 0x01, "MQ GS Scarecrow", "Ice Cavern MQ GS Scarecrow", RHT_ICE_CAVERN_MQ_GS_SCARECROW, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_MQ_GS_ICE_BLOCK] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10500, 0x04, "MQ GS Ice Block", "Ice Cavern MQ GS Ice Block", RHT_ICE_CAVERN_MQ_GS_ICE_BLOCK, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_MQ_GS_RED_ICE] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10498, 0x02, "MQ GS Red Ice", "Ice Cavern MQ GS Red Ice", RHT_ICE_CAVERN_MQ_GS_RED_ICE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); + locationTable[RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10497, 0x01, "GS Push Block Room", "Ice Cavern GS Push Block Room", RHT_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); + locationTable[RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10498, 0x02, "GS Spinning Scythe Room", "Ice Cavern GS Spinning Scythe Room", RHT_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); + locationTable[RC_ICE_CAVERN_GS_HEART_PIECE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10500, 0x04, "GS Heart Piece Room", "Ice Cavern GS Heart Piece Room", RHT_ICE_CAVERN_GS_HEART_PIECE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); + locationTable[RC_ICE_CAVERN_MQ_GS_SCARECROW] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_SCARECROW, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10497, 0x01, "MQ GS Scarecrow", "Ice Cavern MQ GS Scarecrow", RHT_ICE_CAVERN_MQ_GS_SCARECROW, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); + locationTable[RC_ICE_CAVERN_MQ_GS_ICE_BLOCK] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10500, 0x04, "MQ GS Ice Block", "Ice Cavern MQ GS Ice Block", RHT_ICE_CAVERN_MQ_GS_ICE_BLOCK, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); + locationTable[RC_ICE_CAVERN_MQ_GS_RED_ICE] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10498, 0x02, "MQ GS Red Ice", "Ice Cavern MQ GS Red Ice", RHT_ICE_CAVERN_MQ_GS_RED_ICE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); // Overworld - // Kokiri Forest RandomizerCheck RandomizerCheck Quest Area Scene ID params Flag Short Name Spoiler Name Hint Text Key Categories Map Index Collection Check Group - locationTable[RC_KF_GS_BEAN_PATCH] = Location::GSToken(RC_KF_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 27649, 0x01, "GS Bean Patch", "KF GS Bean Patch", RHT_KF_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_GS_KNOW_IT_ALL_HOUSE] = Location::GSToken(RC_KF_GS_KNOW_IT_ALL_HOUSE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 19458, 0x02, "GS Know It All House", "KF GS Know It All House", RHT_KF_GS_KNOW_IT_ALL_HOUSE, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_GS_HOUSE_OF_TWINS] = Location::GSToken(RC_KF_GS_HOUSE_OF_TWINS, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 19460, 0x04, "GS House of Twins", "KF GS House of Twins", RHT_KF_GS_HOUSE_OF_TWINS, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + // Kokiri Forest + locationTable[RC_KF_GS_BEAN_PATCH] = Location::GSToken(RC_KF_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 27649, 0x01, "GS Bean Patch", "KF GS Bean Patch", RHT_KF_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_GS_KNOW_IT_ALL_HOUSE] = Location::GSToken(RC_KF_GS_KNOW_IT_ALL_HOUSE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 19458, 0x02, "GS Know It All House", "KF GS Know It All House", RHT_KF_GS_KNOW_IT_ALL_HOUSE, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_GS_HOUSE_OF_TWINS] = Location::GSToken(RC_KF_GS_HOUSE_OF_TWINS, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 19460, 0x04, "GS House of Twins", "KF GS House of Twins", RHT_KF_GS_HOUSE_OF_TWINS, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); // Lost Woods - locationTable[RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 27905, 0x01, "GS Bean Patch Near Bridge", "LW GS Bean Patch Near Bridge", RHT_LW_GS_BEAN_PATCH_NEAR_BRIDGE, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_GS_BEAN_PATCH_NEAR_THEATER] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 27906, 0x02, "GS Bean Patch Near Theater", "LW GS Bean Patch Near Theater", RHT_LW_GS_BEAN_PATCH_NEAR_THEATER, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_GS_ABOVE_THEATER] = Location::GSToken(RC_LW_GS_ABOVE_THEATER, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 19716, 0x04, "GS Above Theater", "LW GS Above Theater", RHT_LW_GS_ABOVE_THEATER, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_SFM_GS] = Location::GSToken(RC_SFM_GS, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 19720, 0x08, "GS", "SFM GS", RHT_SFM_GS, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 27905, 0x01, "GS Bean Patch Near Bridge", "LW GS Bean Patch Near Bridge", RHT_LW_GS_BEAN_PATCH_NEAR_BRIDGE, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_GS_BEAN_PATCH_NEAR_THEATER] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 27906, 0x02, "GS Bean Patch Near Theater", "LW GS Bean Patch Near Theater", RHT_LW_GS_BEAN_PATCH_NEAR_THEATER, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_GS_ABOVE_THEATER] = Location::GSToken(RC_LW_GS_ABOVE_THEATER, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 19716, 0x04, "GS Above Theater", "LW GS Above Theater", RHT_LW_GS_ABOVE_THEATER, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_SFM_GS] = Location::GSToken(RC_SFM_GS, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 19720, 0x08, "GS", "SFM GS", RHT_SFM_GS, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); // Hyrule Field - locationTable[RC_HF_GS_COW_GROTTO] = Location::GSToken(RC_HF_GS_COW_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10753, 0x01, "GS Cow Grotto", "HF GS Cow Grotto", RHT_HF_GS_COW_GROTTO, { Category::cSkulltula }, 0x0A, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_GS_NEAR_KAK_GROTTO] = Location::GSToken(RC_HF_GS_NEAR_KAK_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10754, 0x02, "GS Near Kak Grotto", "HF GS Near Kak Grotto", RHT_HF_GS_NEAR_KAK_GROTTO, { Category::cSkulltula }, 0x0A, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_GS_COW_GROTTO] = Location::GSToken(RC_HF_GS_COW_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10753, 0x01, "GS Cow Grotto", "HF GS Cow Grotto", RHT_HF_GS_COW_GROTTO, { Category::cSkulltula }, 0x0A, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_GS_NEAR_KAK_GROTTO] = Location::GSToken(RC_HF_GS_NEAR_KAK_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10754, 0x02, "GS Near Kak Grotto", "HF GS Near Kak Grotto", RHT_HF_GS_NEAR_KAK_GROTTO, { Category::cSkulltula }, 0x0A, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); // Lake Hylia - locationTable[RC_LH_GS_BEAN_PATCH] = Location::GSToken(RC_LH_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 29185, 0x01, "GS Bean Patch", "LH GS Bean Patch", RHT_LH_GS_BEAN_PATCH, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_GS_SMALL_ISLAND] = Location::GSToken(RC_LH_GS_SMALL_ISLAND, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 20994, 0x02, "GS Small Island", "LH GS Small Island", RHT_LH_GS_SMALL_ISLAND, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_GS_LAB_WALL] = Location::GSToken(RC_LH_GS_LAB_WALL, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 20996, 0x04, "GS Lab Wall", "LH GS Lab Wall", RHT_LH_GS_LAB_WALL, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_GS_LAB_CRATE] = Location::GSToken(RC_LH_GS_LAB_CRATE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKESIDE_LABORATORY, -28152, 0x08, "GS Lab Crate", "LH GS Lab Crate", RHT_LH_GS_LAB_CRATE, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_GS_TREE] = Location::GSToken(RC_LH_GS_TREE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 21008, 0x10, "GS Tree", "LH GS Tree", RHT_LH_GS_TREE, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_GS_BEAN_PATCH] = Location::GSToken(RC_LH_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 29185, 0x01, "GS Bean Patch", "LH GS Bean Patch", RHT_LH_GS_BEAN_PATCH, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_GS_SMALL_ISLAND] = Location::GSToken(RC_LH_GS_SMALL_ISLAND, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 20994, 0x02, "GS Small Island", "LH GS Small Island", RHT_LH_GS_SMALL_ISLAND, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_GS_LAB_WALL] = Location::GSToken(RC_LH_GS_LAB_WALL, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 20996, 0x04, "GS Lab Wall", "LH GS Lab Wall", RHT_LH_GS_LAB_WALL, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_GS_LAB_CRATE] = Location::GSToken(RC_LH_GS_LAB_CRATE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKESIDE_LABORATORY, -28152, 0x08, "GS Lab Crate", "LH GS Lab Crate", RHT_LH_GS_LAB_CRATE, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_GS_TREE] = Location::GSToken(RC_LH_GS_TREE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 21008, 0x10, "GS Tree", "LH GS Tree", RHT_LH_GS_TREE, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); // Gerudo Valley - locationTable[RC_GV_GS_BEAN_PATCH] = Location::GSToken(RC_GV_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 29441, 0x01, "GS Bean Patch", "GV GS Bean Patch", RHT_GV_GS_BEAN_PATCH, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_GS_SMALL_BRIDGE] = Location::GSToken(RC_GV_GS_SMALL_BRIDGE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21250, 0x02, "GS Small Bridge", "GV GS Small Bridge", RHT_GV_GS_SMALL_BRIDGE, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_GS_PILLAR] = Location::GSToken(RC_GV_GS_PILLAR, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21252, 0x04, "GS Pillar", "GV GS Pillar", RHT_GV_GS_PILLAR, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_GS_BEHIND_TENT] = Location::GSToken(RC_GV_GS_BEHIND_TENT, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21256, 0x08, "GS Behind Tent", "GV GS Behind Tent", RHT_GV_GS_BEHIND_TENT, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_GS_BEAN_PATCH] = Location::GSToken(RC_GV_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 29441, 0x01, "GS Bean Patch", "GV GS Bean Patch", RHT_GV_GS_BEAN_PATCH, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_GS_SMALL_BRIDGE] = Location::GSToken(RC_GV_GS_SMALL_BRIDGE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21250, 0x02, "GS Small Bridge", "GV GS Small Bridge", RHT_GV_GS_SMALL_BRIDGE, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_GS_PILLAR] = Location::GSToken(RC_GV_GS_PILLAR, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21252, 0x04, "GS Pillar", "GV GS Pillar", RHT_GV_GS_PILLAR, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_GS_BEHIND_TENT] = Location::GSToken(RC_GV_GS_BEHIND_TENT, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21256, 0x08, "GS Behind Tent", "GV GS Behind Tent", RHT_GV_GS_BEHIND_TENT, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); // Gerudo Fortress - locationTable[RC_GF_GS_ARCHERY_RANGE] = Location::GSToken(RC_GF_GS_ARCHERY_RANGE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, 21505, 0x01, "GS Archery Range", "GF GS Archery Range", RHT_GF_GS_ARCHERY_RANGE, { Category::cSkulltula }, 0x14, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GF_GS_TOP_FLOOR] = Location::GSToken(RC_GF_GS_TOP_FLOOR, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, 21506, 0x02, "GS Top Floor", "GF GS Top Floor", RHT_GF_GS_TOP_FLOOR, { Category::cSkulltula }, 0x14, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GF_GS_ARCHERY_RANGE] = Location::GSToken(RC_GF_GS_ARCHERY_RANGE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, 21505, 0x01, "GS Archery Range", "GF GS Archery Range", RHT_GF_GS_ARCHERY_RANGE, { Category::cSkulltula }, 0x14, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GF_GS_TOP_FLOOR] = Location::GSToken(RC_GF_GS_TOP_FLOOR, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, 21506, 0x02, "GS Top Floor", "GF GS Top Floor", RHT_GF_GS_TOP_FLOOR, { Category::cSkulltula }, 0x14, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); // Wasteland & Desert Colossus - locationTable[RC_WASTELAND_GS] = Location::GSToken(RC_WASTELAND_GS, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, 13570, 0x02, "GS", "Wasteland GS", RHT_WASTELAND_GS, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_GS_BEAN_PATCH] = Location::GSToken(RC_COLOSSUS_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 29953, 0x01, "GS Bean Patch", "Colossus GS Bean Patch", RHT_COLOSSUS_GS_BEAN_PATCH, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_GS_HILL] = Location::GSToken(RC_COLOSSUS_GS_HILL, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 21764, 0x04, "GS Hill", "Colossus GS Hill", RHT_COLOSSUS_GS_HILL, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_GS_TREE] = Location::GSToken(RC_COLOSSUS_GS_TREE, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 21768, 0x08, "GS Tree", "Colossus GS Tree", RHT_COLOSSUS_GS_TREE, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_WASTELAND_GS] = Location::GSToken(RC_WASTELAND_GS, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, 13570, 0x02, "GS", "Wasteland GS", RHT_WASTELAND_GS, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_COLOSSUS_GS_BEAN_PATCH] = Location::GSToken(RC_COLOSSUS_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 29953, 0x01, "GS Bean Patch", "Colossus GS Bean Patch", RHT_COLOSSUS_GS_BEAN_PATCH, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_COLOSSUS_GS_HILL] = Location::GSToken(RC_COLOSSUS_GS_HILL, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 21764, 0x04, "GS Hill", "Colossus GS Hill", RHT_COLOSSUS_GS_HILL, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_COLOSSUS_GS_TREE] = Location::GSToken(RC_COLOSSUS_GS_TREE, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 21768, 0x08, "GS Tree", "Colossus GS Tree", RHT_COLOSSUS_GS_TREE, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); // Hyrule Castle, Market, and Outside Ganon's Castle - locationTable[RC_OGC_GS] = Location::GSToken(RC_OGC_GS, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE,11777, 0x01, "OGC GS", "OGC GS", RHT_OGC_GS, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_HC_GS_STORMS_GROTTO] = Location::GSToken(RC_HC_GS_STORMS_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 11778, 0x02, "GS Storms Grotto", "HC GS Storms Grotto", RHT_HC_GS_STORMS_GROTTO, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_HC_GS_TREE] = Location::GSToken(RC_HC_GS_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, -29180, 0x04, "GS Tree", "HC GS Tree", RHT_HC_GS_TREE, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_GS_GUARD_HOUSE] = Location::GSToken(RC_MARKET_GS_GUARD_HOUSE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, -29176, 0x08, "Market GS Guard House", "Market GS Guard House", RHT_MARKET_GS_GUARD_HOUSE, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_OGC_GS] = Location::GSToken(RC_OGC_GS, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, 11777, 0x01, "OGC GS", "OGC GS", RHT_OGC_GS, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_HC_GS_STORMS_GROTTO] = Location::GSToken(RC_HC_GS_STORMS_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 11778, 0x02, "GS Storms Grotto", "HC GS Storms Grotto", RHT_HC_GS_STORMS_GROTTO, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_HC_GS_TREE] = Location::GSToken(RC_HC_GS_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, -29180, 0x04, "GS Tree", "HC GS Tree", RHT_HC_GS_TREE, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_GS_GUARD_HOUSE] = Location::GSToken(RC_MARKET_GS_GUARD_HOUSE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, -29176, 0x08, "Market GS Guard House", "Market GS Guard House", RHT_MARKET_GS_GUARD_HOUSE, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); // Kakariko - locationTable[RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION] = Location::GSToken(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20488, 0x08, "GS House Under Construction", "Kak GS House Under Construction", RHT_KAK_GS_HOUSE_UNDER_CONSTRUCTION, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_SKULLTULA_HOUSE] = Location::GSToken(RC_KAK_GS_SKULLTULA_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20496, 0x10, "GS Skulltula House", "Kak GS Skulltula House", RHT_KAK_GS_SKULLTULA_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_GUARDS_HOUSE] = Location::GSToken(RC_KAK_GS_GUARDS_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20482, 0x02, "GS Guards House", "Kak GS Guards House", RHT_KAK_GS_GUARDS_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_TREE] = Location::GSToken(RC_KAK_GS_TREE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, -28640, 0x20, "GS Tree", "Kak GS Tree", RHT_KAK_GS_TREE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_WATCHTOWER] = Location::GSToken(RC_KAK_GS_WATCHTOWER, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20484, 0x04, "GS Watchtower", "Kak GS Watchtower", RHT_KAK_GS_WATCHTOWER, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_ABOVE_IMPAS_HOUSE] = Location::GSToken(RC_KAK_GS_ABOVE_IMPAS_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20544, 0x40, "GS Above Impas House", "Kak GS Above Impas House", RHT_KAK_GS_ABOVE_IMPAS_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION] = Location::GSToken(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20488, 0x08, "GS House Under Construction", "Kak GS House Under Construction", RHT_KAK_GS_HOUSE_UNDER_CONSTRUCTION, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_GS_SKULLTULA_HOUSE] = Location::GSToken(RC_KAK_GS_SKULLTULA_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20496, 0x10, "GS Skulltula House", "Kak GS Skulltula House", RHT_KAK_GS_SKULLTULA_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_GS_GUARDS_HOUSE] = Location::GSToken(RC_KAK_GS_GUARDS_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20482, 0x02, "GS Guards House", "Kak GS Guards House", RHT_KAK_GS_GUARDS_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_GS_TREE] = Location::GSToken(RC_KAK_GS_TREE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, -28640, 0x20, "GS Tree", "Kak GS Tree", RHT_KAK_GS_TREE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_GS_WATCHTOWER] = Location::GSToken(RC_KAK_GS_WATCHTOWER, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20484, 0x04, "GS Watchtower", "Kak GS Watchtower", RHT_KAK_GS_WATCHTOWER, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_GS_ABOVE_IMPAS_HOUSE] = Location::GSToken(RC_KAK_GS_ABOVE_IMPAS_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20544, 0x40, "GS Above Impas House", "Kak GS Above Impas House", RHT_KAK_GS_ABOVE_IMPAS_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); // Graveyard - locationTable[RC_GRAVEYARD_GS_WALL] = Location::GSToken(RC_GRAVEYARD_GS_WALL, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 20608, 0x80, "GS Wall", "Graveyard GS Wall", RHT_GRAVEYARD_GS_WALL, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_GRAVEYARD_GS_BEAN_PATCH] = Location::GSToken(RC_GRAVEYARD_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 28673, 0x01, "GS Bean Patch", "Graveyard GS Bean Patch", RHT_GRAVEYARD_GS_BEAN_PATCH, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_GRAVEYARD_GS_WALL] = Location::GSToken(RC_GRAVEYARD_GS_WALL, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 20608, 0x80, "GS Wall", "Graveyard GS Wall", RHT_GRAVEYARD_GS_WALL, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_GRAVEYARD_GS_BEAN_PATCH] = Location::GSToken(RC_GRAVEYARD_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 28673, 0x01, "GS Bean Patch", "Graveyard GS Bean Patch", RHT_GRAVEYARD_GS_BEAN_PATCH, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); // Death Mountain - locationTable[RC_DMC_GS_BEAN_PATCH] = Location::GSToken(RC_DMC_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER,28417, 0x01, "GS Bean Patch", "DMC GS Bean Patch", RHT_DMC_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_GS_CRATE] = Location::GSToken(RC_DMC_GS_CRATE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER,-28800, 0x80, "GS Crate", "DMC GS Crate", RHT_DMC_GS_CRATE, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_GS_BEAN_PATCH] = Location::GSToken(RC_DMT_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 28418, 0x02, "GS Bean Patch", "DMT GS Bean Patch", RHT_DMT_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_GS_NEAR_KAK] = Location::GSToken(RC_DMT_GS_NEAR_KAK, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 12036, 0x04, "GS Near Kak", "DMT GS Near Kak", RHT_DMT_GS_NEAR_KAK, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_GS_ABOVE_DODONGOS_CAVERN] = Location::GSToken(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 20232, 0x08, "GS Above Dodongos Cavern", "DMT GS Above Dodongos Cavern", RHT_DMT_GS_ABOVE_DODONGOS_CAVERN, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_GS_FALLING_ROCKS_PATH] = Location::GSToken(RC_DMT_GS_FALLING_ROCKS_PATH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 20240, 0x10, "GS Falling Rocks Path", "DMT GS Falling Rocks Path", RHT_DMT_GS_FALLING_ROCKS_PATH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_GC_GS_CENTER_PLATFORM] = Location::GSToken(RC_GC_GS_CENTER_PLATFORM, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 12064, 0x20, "GS Center Platform", "GC GS Center Platform", RHT_GC_GS_CENTER_PLATFORM, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_GS_BOULDER_MAZE] = Location::GSToken(RC_GC_GS_BOULDER_MAZE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, -28864, 0x40, "GS Boulder Maze", "GC GS Boulder Maze", RHT_GC_GS_BOULDER_MAZE, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_DMC_GS_BEAN_PATCH] = Location::GSToken(RC_DMC_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 28417, 0x01, "GS Bean Patch", "DMC GS Bean Patch", RHT_DMC_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_GS_CRATE] = Location::GSToken(RC_DMC_GS_CRATE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, -28800, 0x80, "GS Crate", "DMC GS Crate", RHT_DMC_GS_CRATE, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMT_GS_BEAN_PATCH] = Location::GSToken(RC_DMT_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 28418, 0x02, "GS Bean Patch", "DMT GS Bean Patch", RHT_DMT_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMT_GS_NEAR_KAK] = Location::GSToken(RC_DMT_GS_NEAR_KAK, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 12036, 0x04, "GS Near Kak", "DMT GS Near Kak", RHT_DMT_GS_NEAR_KAK, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMT_GS_ABOVE_DODONGOS_CAVERN] = Location::GSToken(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 20232, 0x08, "GS Above Dodongos Cavern", "DMT GS Above Dodongos Cavern", RHT_DMT_GS_ABOVE_DODONGOS_CAVERN, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMT_GS_FALLING_ROCKS_PATH] = Location::GSToken(RC_DMT_GS_FALLING_ROCKS_PATH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 20240, 0x10, "GS Falling Rocks Path", "DMT GS Falling Rocks Path", RHT_DMT_GS_FALLING_ROCKS_PATH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_GC_GS_CENTER_PLATFORM] = Location::GSToken(RC_GC_GS_CENTER_PLATFORM, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 12064, 0x20, "GS Center Platform", "GC GS Center Platform", RHT_GC_GS_CENTER_PLATFORM, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_GS_BOULDER_MAZE] = Location::GSToken(RC_GC_GS_BOULDER_MAZE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, -28864, 0x40, "GS Boulder Maze", "GC GS Boulder Maze", RHT_GC_GS_BOULDER_MAZE, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); // Zora's River, Domain, and Fountain - locationTable[RC_ZR_GS_LADDER] = Location::GSToken(RC_ZR_GS_LADDER, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20737, 0x01, "GS Ladder", "ZR GS Ladder", RHT_ZR_GS_LADDER, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_GS_TREE] = Location::GSToken(RC_ZR_GS_TREE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, -28414, 0x02, "GS Tree", "ZR GS Tree", RHT_ZR_GS_TREE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_GS_ABOVE_BRIDGE] = Location::GSToken(RC_ZR_GS_ABOVE_BRIDGE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20744, 0x08, "GS Above Bridge", "ZR GS Above Bridge", RHT_ZR_GS_ABOVE_BRIDGE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_GS_NEAR_RAISED_GROTTOS] = Location::GSToken(RC_ZR_GS_NEAR_RAISED_GROTTOS, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20752, 0x10, "GS Near Raised Grottos", "ZR GS Near Raised Grottos", RHT_ZR_GS_NEAR_RAISED_GROTTOS, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZD_GS_FROZEN_WATERFALL] = Location::GSToken(RC_ZD_GS_FROZEN_WATERFALL, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, 20800, 0x40, "GS Frozen Waterfall", "ZD GS Frozen Waterfall", RHT_ZD_GS_FROZEN_WATERFALL, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZF_GS_ABOVE_THE_LOG] = Location::GSToken(RC_ZF_GS_ABOVE_THE_LOG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 20740, 0x04, "GS Above The Log", "ZF GS Above The Log", RHT_ZF_GS_ABOVE_THE_LOG, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZF_GS_HIDDEN_CAVE] = Location::GSToken(RC_ZF_GS_HIDDEN_CAVE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 20768, 0x20, "GS Hidden Cave", "ZF GS Hidden Cave", RHT_ZF_GS_HIDDEN_CAVE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZF_GS_TREE] = Location::GSToken(RC_ZF_GS_TREE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, -28288, 0x80, "GS Tree", "ZF GS Tree", RHT_ZF_GS_TREE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZR_GS_LADDER] = Location::GSToken(RC_ZR_GS_LADDER, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20737, 0x01, "GS Ladder", "ZR GS Ladder", RHT_ZR_GS_LADDER, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_GS_TREE] = Location::GSToken(RC_ZR_GS_TREE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, -28414, 0x02, "GS Tree", "ZR GS Tree", RHT_ZR_GS_TREE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_GS_ABOVE_BRIDGE] = Location::GSToken(RC_ZR_GS_ABOVE_BRIDGE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20744, 0x08, "GS Above Bridge", "ZR GS Above Bridge", RHT_ZR_GS_ABOVE_BRIDGE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_GS_NEAR_RAISED_GROTTOS] = Location::GSToken(RC_ZR_GS_NEAR_RAISED_GROTTOS, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20752, 0x10, "GS Near Raised Grottos", "ZR GS Near Raised Grottos", RHT_ZR_GS_NEAR_RAISED_GROTTOS, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZD_GS_FROZEN_WATERFALL] = Location::GSToken(RC_ZD_GS_FROZEN_WATERFALL, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, 20800, 0x40, "GS Frozen Waterfall", "ZD GS Frozen Waterfall", RHT_ZD_GS_FROZEN_WATERFALL, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZF_GS_ABOVE_THE_LOG] = Location::GSToken(RC_ZF_GS_ABOVE_THE_LOG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 20740, 0x04, "GS Above The Log", "ZF GS Above The Log", RHT_ZF_GS_ABOVE_THE_LOG, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZF_GS_HIDDEN_CAVE] = Location::GSToken(RC_ZF_GS_HIDDEN_CAVE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 20768, 0x20, "GS Hidden Cave", "ZF GS Hidden Cave", RHT_ZF_GS_HIDDEN_CAVE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZF_GS_TREE] = Location::GSToken(RC_ZF_GS_TREE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, -28288, 0x80, "GS Tree", "ZF GS Tree", RHT_ZF_GS_TREE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); // Lon Lon Ranch - locationTable[RC_LLR_GS_BACK_WALL] = Location::GSToken(RC_LLR_GS_BACK_WALL, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11009, 0x01, "GS Back Wall", "LLR GS Back Wall", RHT_LLR_GS_BACK_WALL, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_GS_RAIN_SHED] = Location::GSToken(RC_LLR_GS_RAIN_SHED, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11010, 0x02, "GS Rain Shed", "LLR GS Rain Shed", RHT_LLR_GS_RAIN_SHED, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_GS_HOUSE_WINDOW] = Location::GSToken(RC_LLR_GS_HOUSE_WINDOW, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11012, 0x04, "GS House Window", "LLR GS House Window", RHT_LLR_GS_HOUSE_WINDOW, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_GS_TREE] = Location::GSToken(RC_LLR_GS_TREE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, -29944, 0x08, "GS Tree", "LLR GS Tree", RHT_LLR_GS_TREE, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_GS_BACK_WALL] = Location::GSToken(RC_LLR_GS_BACK_WALL, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11009, 0x01, "GS Back Wall", "LLR GS Back Wall", RHT_LLR_GS_BACK_WALL, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_GS_RAIN_SHED] = Location::GSToken(RC_LLR_GS_RAIN_SHED, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11010, 0x02, "GS Rain Shed", "LLR GS Rain Shed", RHT_LLR_GS_RAIN_SHED, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_GS_HOUSE_WINDOW] = Location::GSToken(RC_LLR_GS_HOUSE_WINDOW, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11012, 0x04, "GS House Window", "LLR GS House Window", RHT_LLR_GS_HOUSE_WINDOW, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_GS_TREE] = Location::GSToken(RC_LLR_GS_TREE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, -29944, 0x08, "GS Tree", "LLR GS Tree", RHT_LLR_GS_TREE, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - // Bosses Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression - locationTable[RC_LINKS_POCKET] = Location::Reward(RC_LINKS_POCKET, RCQUEST_BOTH, RCTYPE_LINKS_POCKET, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Link's Pocket", "Link's Pocket", RHT_LINKS_POCKET, RG_LIGHT_MEDALLION, {}, SpoilerCollectionCheck::AlwaysCollected(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, true); - locationTable[RC_QUEEN_GOHMA] = Location::Reward(RC_QUEEN_GOHMA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DEKU_TREE, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, DungeonId::DUNGEON_DEKU_TREE, "Queen Gohma", "Queen Gohma", RHT_QUEEN_GOHMA, RG_KOKIRI_EMERALD, {}, SpoilerCollectionCheck::Chest(0x11, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_KING_DODONGO] = Location::Reward(RC_KING_DODONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_DOOR_WARP1, SCENE_DODONGOS_CAVERN_BOSS, 0x00, DungeonId::DUNGEON_DODONGOS_CAVERN, "King Dodongo", "King Dodongo", RHT_KING_DODONGO, RG_GORON_RUBY, {}, SpoilerCollectionCheck::Chest(0x12, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_BARINADE] = Location::Reward(RC_BARINADE, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, DungeonId::DUNGEON_JABUJABUS_BELLY, "Barinade", "Barinade", RHT_BARINADE, RG_ZORA_SAPPHIRE, {}, SpoilerCollectionCheck::Chest(0x13, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_PHANTOM_GANON] = Location::Reward(RC_PHANTOM_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FOREST_TEMPLE, "Phantom Ganon", "Phantom Ganon", RHT_PHANTOM_GANON, RG_FOREST_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x14, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_VOLVAGIA] = Location::Reward(RC_VOLVAGIA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FIRE_TEMPLE, "Volvagia", "Volvagia", RHT_VOLVAGIA, RG_FIRE_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x15, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_MORPHA] = Location::Reward(RC_MORPHA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_WATER_TEMPLE, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_WATER_TEMPLE, "Morpha", "Morpha", RHT_MORPHA, RG_WATER_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x16, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_TWINROVA] = Location::Reward(RC_TWINROVA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_SPIRIT_TEMPLE, "Twinrova", "Twinrova", RHT_TWINROVA, RG_SPIRIT_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x17, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_BONGO_BONGO] = Location::Reward(RC_BONGO_BONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_SHADOW_TEMPLE, "Bongo Bongo", "Bongo Bongo", RHT_BONGO_BONGO, RG_SHADOW_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x18, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_GANON] = Location::Reward(RC_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_GANONS_CASTLE, ACTOR_DOOR_WARP1, SCENE_GANON_BOSS, 0x00, DungeonId::DUNGEON_GANONS_CASTLE_CRUMBLING, "Ganon", "Ganon", RHT_NONE, RG_TRIFORCE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GIFT_FROM_SAGES] = Location::Reward(RC_GIFT_FROM_SAGES, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Gift from Raoru", "Gift from Raoru", RHT_NONE, RG_LIGHT_MEDALLION, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP, true); + // Bosses + locationTable[RC_LINKS_POCKET] = Location::Reward(RC_LINKS_POCKET, RCQUEST_BOTH, RCTYPE_LINKS_POCKET, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Link's Pocket", "Link's Pocket", RHT_LINKS_POCKET, RG_NONE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LINKS_POCKET), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, true); + locationTable[RC_QUEEN_GOHMA] = Location::Reward(RC_QUEEN_GOHMA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DEKU_TREE, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, DungeonId::DUNGEON_DEKU_TREE, "Queen Gohma", "Queen Gohma", RHT_QUEEN_GOHMA, RG_KOKIRI_EMERALD, {}, SpoilerCollectionCheck::EventChkInf(0x07), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_KING_DODONGO] = Location::Reward(RC_KING_DODONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_DOOR_WARP1, SCENE_DODONGOS_CAVERN_BOSS, 0x00, DungeonId::DUNGEON_DODONGOS_CAVERN, "King Dodongo", "King Dodongo", RHT_KING_DODONGO, RG_GORON_RUBY, {}, SpoilerCollectionCheck::EventChkInf(0x25), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_BARINADE] = Location::Reward(RC_BARINADE, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, DungeonId::DUNGEON_JABUJABUS_BELLY, "Barinade", "Barinade", RHT_BARINADE, RG_ZORA_SAPPHIRE, {}, SpoilerCollectionCheck::EventChkInf(0x37), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_PHANTOM_GANON] = Location::Reward(RC_PHANTOM_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FOREST_TEMPLE, "Phantom Ganon", "Phantom Ganon", RHT_PHANTOM_GANON, RG_FOREST_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(0x48), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_VOLVAGIA] = Location::Reward(RC_VOLVAGIA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FIRE_TEMPLE, "Volvagia", "Volvagia", RHT_VOLVAGIA, RG_FIRE_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(0x49), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_MORPHA] = Location::Reward(RC_MORPHA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_WATER_TEMPLE, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_WATER_TEMPLE, "Morpha", "Morpha", RHT_MORPHA, RG_WATER_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(0x4A), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_TWINROVA] = Location::Reward(RC_TWINROVA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_SPIRIT_TEMPLE, "Twinrova", "Twinrova", RHT_TWINROVA, RG_SPIRIT_MEDALLION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_BONGO_BONGO] = Location::Reward(RC_BONGO_BONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_SHADOW_TEMPLE, "Bongo Bongo", "Bongo Bongo", RHT_BONGO_BONGO, RG_SHADOW_MEDALLION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_GANON] = Location::Reward(RC_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_GANONS_CASTLE, ACTOR_DOOR_WARP1, SCENE_GANON_BOSS, 0x00, DungeonId::DUNGEON_GANONS_CASTLE_CRUMBLING, "Ganon", "Ganon", RHT_NONE, RG_TRIFORCE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GIFT_FROM_SAGES] = Location::Reward(RC_GIFT_FROM_SAGES, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Gift from Raoru", "Gift from Raoru", RHT_NONE, RG_LIGHT_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(0xC9), SpoilerCollectionCheckGroup::GROUP_NO_GROUP, true); - // Heart Containers Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression - locationTable[RC_DEKU_TREE_QUEEN_GOHMA_HEART] = Location::Base(RC_DEKU_TREE_QUEEN_GOHMA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_DEKU_TREE, ACTOR_ITEM_B_HEART, SCENE_DEKU_TREE_BOSS, 0x00, 0x4F, "Queen Gohma Heart Container", "Deku Tree Queen Gohma Heart Container", RHT_DEKU_TREE_QUEEN_GOHMA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x11, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DODONGOS_CAVERN_KING_DODONGO_HEART] = Location::Base(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_ITEM_B_HEART, SCENE_DODONGOS_CAVERN_BOSS, 0x00, 0x4F, "King Dodongo Heart Container", "Dodongos Cavern King Dodongo Heart Container", RHT_DODONGOS_CAVERN_KING_DODONGO_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x12, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_JABU_JABUS_BELLY_BARINADE_HEART] = Location::Base(RC_JABU_JABUS_BELLY_BARINADE_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_ITEM_B_HEART, SCENE_JABU_JABU_BOSS, 0x00, 0x4F, "Barinade Heart Container", "Jabu Jabus Belly Barinade Heart Container", RHT_JABU_JABUS_BELLY_BARINADE_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x13, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_FOREST_TEMPLE_PHANTOM_GANON_HEART] = Location::Base(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_FOREST_TEMPLE_BOSS, 0x00, 0x4F, "Phantom Ganon Heart Container", "Forest Temple Phantom Ganon Heart Container", RHT_FOREST_TEMPLE_PHANTOM_GANON_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x14, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_VOLVAGIA_HEART] = Location::Base(RC_FIRE_TEMPLE_VOLVAGIA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_FIRE_TEMPLE_BOSS, 0x00, 0x4F, "Volvagia Heart Container", "Fire Temple Volvagia Heart Container", RHT_FIRE_TEMPLE_VOLVAGIA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x15, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MORPHA_HEART] = Location::Base(RC_WATER_TEMPLE_MORPHA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_WATER_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_WATER_TEMPLE_BOSS, 0x00, 0x4F, "Morpha Heart Container", "Water Temple Morpha Heart Container", RHT_WATER_TEMPLE_MORPHA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x16, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_TWINROVA_HEART] = Location::Base(RC_SPIRIT_TEMPLE_TWINROVA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, 0x4F, "Twinrova Heart Container", "Spirit Temple Twinrova Heart Container", RHT_SPIRIT_TEMPLE_TWINROVA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x17, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_BONGO_BONGO_HEART] = Location::Base(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_SHADOW_TEMPLE_BOSS, 0x00, 0x4F, "Bongo Bongo Heart Container", "Shadow Temple Bongo Bongo Heart Container", RHT_SHADOW_TEMPLE_BONGO_BONGO_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x18, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + // Heart Containers + locationTable[RC_DEKU_TREE_QUEEN_GOHMA_HEART] = Location::Base(RC_DEKU_TREE_QUEEN_GOHMA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_DEKU_TREE, ACTOR_ITEM_B_HEART, SCENE_DEKU_TREE_BOSS, 0x00, 0x4F, "Queen Gohma Heart Container", "Deku Tree Queen Gohma Heart Container", RHT_DEKU_TREE_QUEEN_GOHMA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x11, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_DODONGOS_CAVERN_KING_DODONGO_HEART] = Location::Base(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_ITEM_B_HEART, SCENE_DODONGOS_CAVERN_BOSS, 0x00, 0x4F, "King Dodongo Heart Container", "Dodongos Cavern King Dodongo Heart Container", RHT_DODONGOS_CAVERN_KING_DODONGO_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x12, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_HEART] = Location::Base(RC_JABU_JABUS_BELLY_BARINADE_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_ITEM_B_HEART, SCENE_JABU_JABU_BOSS, 0x00, 0x4F, "Barinade Heart Container", "Jabu Jabus Belly Barinade Heart Container", RHT_JABU_JABUS_BELLY_BARINADE_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x13, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_FOREST_TEMPLE_PHANTOM_GANON_HEART] = Location::Base(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_FOREST_TEMPLE_BOSS, 0x00, 0x4F, "Phantom Ganon Heart Container", "Forest Temple Phantom Ganon Heart Container", RHT_FOREST_TEMPLE_PHANTOM_GANON_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x14, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_VOLVAGIA_HEART] = Location::Base(RC_FIRE_TEMPLE_VOLVAGIA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_FIRE_TEMPLE_BOSS, 0x00, 0x4F, "Volvagia Heart Container", "Fire Temple Volvagia Heart Container", RHT_FIRE_TEMPLE_VOLVAGIA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x15, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MORPHA_HEART] = Location::Base(RC_WATER_TEMPLE_MORPHA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_WATER_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_WATER_TEMPLE_BOSS, 0x00, 0x4F, "Morpha Heart Container", "Water Temple Morpha Heart Container", RHT_WATER_TEMPLE_MORPHA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x16, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_TWINROVA_HEART] = Location::Base(RC_SPIRIT_TEMPLE_TWINROVA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, 0x4F, "Twinrova Heart Container", "Spirit Temple Twinrova Heart Container", RHT_SPIRIT_TEMPLE_TWINROVA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x17, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_BONGO_BONGO_HEART] = Location::Base(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_SHADOW_TEMPLE_BOSS, 0x00, 0x4F, "Bongo Bongo Heart Container", "Shadow Temple Bongo Bongo Heart Container", RHT_SHADOW_TEMPLE_BONGO_BONGO_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x18, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - // Cutscenes Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression - locationTable[RC_TOT_MASTER_SWORD] = Location::Delayed(RC_TOT_MASTER_SWORD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "ToT Master Sword", "ToT Master Sword", RHT_TOT_MASTER_SWORD, RG_MASTER_SWORD, {}, SpoilerCollectionCheck::MasterSword(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_TOT_LIGHT_ARROWS_CUTSCENE] = Location::Delayed(RC_TOT_LIGHT_ARROWS_CUTSCENE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x01, "ToT Light Arrow Cutscene", "ToT Light Arrow Cutscene", RHT_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS, {}, SpoilerCollectionCheck::Chest(0x43, 0x1E), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_LW_GIFT_FROM_SARIA] = Location::Delayed(RC_LW_GIFT_FROM_SARIA, RCQUEST_BOTH, RCTYPE_OCARINA, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x02, "Gift From Saria", "LW Gift From Saria", RHT_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0xC1), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_ZF_GREAT_FAIRY_REWARD] = Location::Delayed(RC_ZF_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, 0x10, "Great Fairy Reward", "ZF Great Fairy Reward", RHT_ZF_GREAT_FAIRY_REWARD, RG_FARORES_WIND, {}, SpoilerCollectionCheck::Chest(0x3D, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_HC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_HC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, 0x11, "Great Fairy Reward", "HC Great Fairy Reward", RHT_HC_GREAT_FAIRY_REWARD, RG_DINS_FIRE, {}, SpoilerCollectionCheck::Chest(0x3D, 0x02), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_COLOSSUS_GREAT_FAIRY_REWARD] = Location::Delayed(RC_COLOSSUS_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 3, 0x12, "Great Fairy Reward", "Colossus Great Fairy Reward", RHT_COLOSSUS_GREAT_FAIRY_REWARD, RG_NAYRUS_LOVE, {}, SpoilerCollectionCheck::Chest(0x3D, 0x03), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_DMT_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMT_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, 0x13, "Great Fairy Reward", "DMT Great Fairy Reward", RHT_DMT_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::Chest(0x3B, 0x01), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, 0x14, "Great Fairy Reward", "DMC Great Fairy Reward", RHT_DMC_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::Chest(0x3B, 0x02), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_OGC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_OGC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, 0x15, "OGC Great Fairy Reward", "OGC Great Fairy Reward", RHT_OGC_GREAT_FAIRY_REWARD, RG_DOUBLE_DEFENSE, {}, SpoilerCollectionCheck::Chest(0x3B, 0x03), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + // Cutscenes + locationTable[RC_TOT_MASTER_SWORD] = Location::Delayed(RC_TOT_MASTER_SWORD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "ToT Master Sword", "ToT Master Sword", RHT_TOT_MASTER_SWORD, RG_MASTER_SWORD, {}, SpoilerCollectionCheck::EventChkInf(0x45), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_TOT_LIGHT_ARROWS_CUTSCENE] = Location::Delayed(RC_TOT_LIGHT_ARROWS_CUTSCENE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x01, "ToT Light Arrow Cutscene", "ToT Light Arrow Cutscene", RHT_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS, {}, SpoilerCollectionCheck::EventChkInf(0xC4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_LW_GIFT_FROM_SARIA] = Location::Delayed(RC_LW_GIFT_FROM_SARIA, RCQUEST_BOTH, RCTYPE_OCARINA, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x02, "Gift From Saria", "LW Gift From Saria", RHT_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0xC1), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_ZF_GREAT_FAIRY_REWARD] = Location::Delayed(RC_ZF_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, 0x10, "Great Fairy Reward", "ZF Great Fairy Reward", RHT_ZF_GREAT_FAIRY_REWARD, RG_FARORES_WIND, {}, SpoilerCollectionCheck::Chest(0x3D, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_HC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_HC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, 0x11, "Great Fairy Reward", "HC Great Fairy Reward", RHT_HC_GREAT_FAIRY_REWARD, RG_DINS_FIRE, {}, SpoilerCollectionCheck::Chest(0x3D, 0x02), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_COLOSSUS_GREAT_FAIRY_REWARD] = Location::Delayed(RC_COLOSSUS_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 3, 0x12, "Great Fairy Reward", "Colossus Great Fairy Reward", RHT_COLOSSUS_GREAT_FAIRY_REWARD, RG_NAYRUS_LOVE, {}, SpoilerCollectionCheck::Chest(0x3D, 0x03), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_DMT_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMT_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, 0x13, "Great Fairy Reward", "DMT Great Fairy Reward", RHT_DMT_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::Chest(0x3B, 0x01), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, 0x14, "Great Fairy Reward", "DMC Great Fairy Reward", RHT_DMC_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::Chest(0x3B, 0x02), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_OGC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_OGC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, 0x15, "OGC Great Fairy Reward", "OGC Great Fairy Reward", RHT_OGC_GREAT_FAIRY_REWARD, RG_DOUBLE_DEFENSE, {}, SpoilerCollectionCheck::Chest(0x3B, 0x03), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - // Songs Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression - locationTable[RC_SHEIK_IN_FOREST] = Location::Delayed(RC_SHEIK_IN_FOREST, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x20, "Sheik in Forest", "Sheik in Forest", RHT_SHEIK_IN_FOREST, RG_MINUET_OF_FOREST, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x50), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_SHEIK_IN_CRATER] = Location::Delayed(RC_SHEIK_IN_CRATER, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x21, "Sheik in Crater", "Sheik in Crater", RHT_SHEIK_IN_CRATER, RG_BOLERO_OF_FIRE, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x51), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_SHEIK_IN_ICE_CAVERN] = Location::Delayed(RC_SHEIK_IN_ICE_CAVERN, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_ICE_CAVERN, ACTOR_ID_MAX, SCENE_ICE_CAVERN, 0x00, 0x22, "Sheik in Ice Cavern", "Sheik in Ice Cavern", RHT_SHEIK_IN_ICE_CAVERN, RG_SERENADE_OF_WATER, { Category::cSong, Category::cSongDungeonReward }, SpoilerCollectionCheck::EventChkInf(0x52), SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_SHEIK_AT_COLOSSUS] = Location::Delayed(RC_SHEIK_AT_COLOSSUS, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_DESERT_COLOSSUS, ACTOR_ID_MAX, SCENE_DESERT_COLOSSUS, 0x00, 0x23, "Sheik at Colossus", "Sheik at Colossus", RHT_SHEIK_AT_COLOSSUS, RG_REQUIEM_OF_SPIRIT, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xAC), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_SHEIK_IN_KAKARIKO] = Location::Delayed(RC_SHEIK_IN_KAKARIKO, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x24, "Sheik in Kakariko", "Sheik in Kakariko", RHT_SHEIK_IN_KAKARIKO, RG_NOCTURNE_OF_SHADOW, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xAA), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_SHEIK_AT_TEMPLE] = Location::Delayed(RC_SHEIK_AT_TEMPLE, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x25, "Sheik at Temple", "Sheik at Temple", RHT_SHEIK_AT_TEMPLE, RG_PRELUDE_OF_LIGHT, { Category::cSong }, SpoilerCollectionCheck::Chest(0x43, 0x1F), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_SONG_FROM_IMPA] = Location::Delayed(RC_SONG_FROM_IMPA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x26, "Song from Impa", "Song from Impa", RHT_SONG_FROM_IMPA, RG_ZELDAS_LULLABY, { Category::cSong, Category::cSongDungeonReward }, SpoilerCollectionCheck::EventChkInf(0x59), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_SONG_FROM_MALON] = Location::Delayed(RC_SONG_FROM_MALON, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x27, "Song from Malon", "Song from Malon", RHT_SONG_FROM_MALON, RG_EPONAS_SONG, { Category::cSong }, SpoilerCollectionCheck::Chest(0x63, 0x1F), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); - locationTable[RC_SONG_FROM_SARIA] = Location::Delayed(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x28, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, { Category::cSong }, SpoilerCollectionCheck::Chest(0x56, 0x1F), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Delayed(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x29, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, { Category::cSong }, SpoilerCollectionCheck::Chest(0x41, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Delayed(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2A, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, { Category::cSong }, SpoilerCollectionCheck::Chest(0x51, 0x1F), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); - locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x5B), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + // Songs + locationTable[RC_SHEIK_IN_FOREST] = Location::Delayed(RC_SHEIK_IN_FOREST, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x20, "Sheik in Forest", "Sheik in Forest", RHT_SHEIK_IN_FOREST, RG_MINUET_OF_FOREST, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x50), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_SHEIK_IN_CRATER] = Location::Delayed(RC_SHEIK_IN_CRATER, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x21, "Sheik in Crater", "Sheik in Crater", RHT_SHEIK_IN_CRATER, RG_BOLERO_OF_FIRE, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x51), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_SHEIK_IN_ICE_CAVERN] = Location::Delayed(RC_SHEIK_IN_ICE_CAVERN, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_ICE_CAVERN, ACTOR_ID_MAX, SCENE_ICE_CAVERN, 0x00, 0x22, "Sheik in Ice Cavern", "Sheik in Ice Cavern", RHT_SHEIK_IN_ICE_CAVERN, RG_SERENADE_OF_WATER, { Category::cSong, Category::cSongDungeonReward }, SpoilerCollectionCheck::EventChkInf(0x52), SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_SHEIK_AT_COLOSSUS] = Location::Delayed(RC_SHEIK_AT_COLOSSUS, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_DESERT_COLOSSUS, ACTOR_ID_MAX, SCENE_DESERT_COLOSSUS, 0x00, 0x23, "Sheik at Colossus", "Sheik at Colossus", RHT_SHEIK_AT_COLOSSUS, RG_REQUIEM_OF_SPIRIT, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xAC), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_SHEIK_IN_KAKARIKO] = Location::Delayed(RC_SHEIK_IN_KAKARIKO, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x24, "Sheik in Kakariko", "Sheik in Kakariko", RHT_SHEIK_IN_KAKARIKO, RG_NOCTURNE_OF_SHADOW, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xAA), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_SHEIK_AT_TEMPLE] = Location::Delayed(RC_SHEIK_AT_TEMPLE, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x25, "Sheik at Temple", "Sheik at Temple", RHT_SHEIK_AT_TEMPLE, RG_PRELUDE_OF_LIGHT, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x55), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_SONG_FROM_IMPA] = Location::Delayed(RC_SONG_FROM_IMPA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x26, "Song from Impa", "Song from Impa", RHT_SONG_FROM_IMPA, RG_ZELDAS_LULLABY, { Category::cSong, Category::cSongDungeonReward }, SpoilerCollectionCheck::EventChkInf(0x59), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_SONG_FROM_MALON] = Location::Delayed(RC_SONG_FROM_MALON, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x27, "Song from Malon", "Song from Malon", RHT_SONG_FROM_MALON, RG_EPONAS_SONG, { Category::cSong }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LEARNED_EPONA_SONG), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); + locationTable[RC_SONG_FROM_SARIA] = Location::Delayed(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x28, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x57), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Delayed(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x29, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x00), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Delayed(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2A, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xA9), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); + locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x5B), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - //Beehives Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression - locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), 0x00, "Storms Grotto Beehive Left", "KF Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, false); - locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), 0x00, "Storms Grotto Beehive Right", "KF Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, false); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), 0x00, "Near Shortcuts Grotto Beehive Left", "LW Near Shortcuts Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, false); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), 0x00, "Near Shortcuts Grotto Beehive Right", "LW Near Shortcuts Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, false); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), 0x00, "Deku Scrub Grotto Beehive", "LW Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, false); - locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), 0x00, "Storms Grotto Beehive", "SFM Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, false); - locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), 0x00, "Near Market Grotto Beehive Left", "HF Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); - locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), 0x00, "Near Market Grotto Beehive Right", "HF Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); - locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), 0x00, "Open Grotto Beehive Left", "HF Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); - locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), 0x00, "Open Grotto Beehive Right", "HF Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); - locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), 0x00, "Southeast Grotto Beehive Left", "HF Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); - locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), 0x00, "Southeast Grotto Beehive Right", "HF Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); - locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), 0x00, "Inside Fence Grotto Beehive", "HF Inside Fence Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); - locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), 0x00, "Grotto Beehive", "LLR Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, false); - locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), 0x00, "Open Grotto Beehive Left", "Kak Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, false); - locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), 0x00, "Open Grotto Beehive Right", "Kak Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, false); - locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), 0x00, "Cow Grotto Beehive", "DMT Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); - locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), 0x00, "Storms Grotto Beehive Left", "DMT Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); - locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), 0x00, "Storms Grotto Beehive Right", "DMT Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); - locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), 0x00, "Grotto Beehive", "GC Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, false); - locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), 0x00, "Upper Grotto Beehive Left", "DMC Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); - locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), 0x00, "Upper Grotto Beehive Right", "DMC Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); - locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), 0x00, "Hammer Grotto Beehive", "DMC Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); - locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), 0x00, "Open Grotto Beehive Left", "ZR Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, false); - locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), 0x00, "Open Grotto Beehive Right", "ZR Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, false); - locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), 0x00, "Storms Grotto Beehive", "ZR Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, false); - locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), 0x00, "In Front of King Zora Beehive Left", "ZD In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, false); - locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), 0x00, "In Front of King Zora Beehive Right", "ZD In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, false); - locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), 0x00, "Behind King Zora Beehive", "ZD Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, false); - locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), 0x00, "Grotto Beehive", "LH Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, false); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), 0x00, "Deku Scrub Grotto Beehive", "GV Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, false); - locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), 0x00, "Grotto Beehive", "Colossus Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, false); + //Beehives + locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), 0x00, "Storms Grotto Beehive Left", "KF Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), 0x00, "Storms Grotto Beehive Right", "KF Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), 0x00, "Near Shortcuts Grotto Beehive Left", "LW Near Shortcuts Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), 0x00, "Near Shortcuts Grotto Beehive Right", "LW Near Shortcuts Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), 0x00, "Deku Scrub Grotto Beehive", "LW Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), 0x00, "Storms Grotto Beehive", "SFM Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_SFM_STORMS_GROTTO), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), 0x00, "Near Market Grotto Beehive Left", "HF Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), 0x00, "Near Market Grotto Beehive Right", "HF Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), 0x00, "Open Grotto Beehive Left", "HF Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), 0x00, "Open Grotto Beehive Right", "HF Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), 0x00, "Southeast Grotto Beehive Left", "HF Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), 0x00, "Southeast Grotto Beehive Right", "HF Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), 0x00, "Inside Fence Grotto Beehive", "HF Inside Fence Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), 0x00, "Grotto Beehive", "LLR Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LLR_GROTTO), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), 0x00, "Open Grotto Beehive Left", "Kak Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), 0x00, "Open Grotto Beehive Right", "Kak Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), 0x00, "Cow Grotto Beehive", "DMT Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_COW_GROTTO), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), 0x00, "Storms Grotto Beehive Left", "DMT Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), 0x00, "Storms Grotto Beehive Right", "DMT Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), 0x00, "Grotto Beehive", "GC Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GC_GROTTO), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), 0x00, "Upper Grotto Beehive Left", "DMC Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), 0x00, "Upper Grotto Beehive Right", "DMC Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), 0x00, "Hammer Grotto Beehive", "DMC Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), 0x00, "Open Grotto Beehive Left", "ZR Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), 0x00, "Open Grotto Beehive Right", "ZR Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), 0x00, "Storms Grotto Beehive", "ZR Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_STORMS_GROTTO), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), 0x00, "In Front of King Zora Beehive Left", "ZD In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), 0x00, "In Front of King Zora Beehive Right", "ZD In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), 0x00, "Behind King Zora Beehive", "ZD Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), 0x00, "Grotto Beehive", "LH Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LH_GROTTO), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), 0x00, "Deku Scrub Grotto Beehive", "GV Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), 0x00, "Grotto Beehive", "Colossus Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - // Cows Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group - locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_KOKIRI_FOREST, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, 0x15, "Links House Cow", "KF Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x34, 0x15), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), 0x16, "Cow Grotto Cow", "HF Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x3E, 0x16), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), 0x16, "Stables Left Cow", "LLR Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x36, 0x16), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), 0x15, "Stables Right Cow", "LLR Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x36, 0x15), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), 0x15, "Tower Left Cow", "LLR Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x4C, 0x16), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), 0x16, "Tower Right Cow", "LLR Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x4C, 0x15), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, 0x15, "Impas House Cow", "Kak Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x37, 0x15), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), 0x15, "Cow Grotto Cow", "DMT Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x3E, 0x15), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_GERUDO_VALLEY, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, 0x15, "Cow", "GV Cow", RHT_GV_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x5A, 0x15), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, 0x15, "MQ Cow", "Jabu Jabus Belly MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x02, 0x15), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + // Cows + locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_KOKIRI_FOREST, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, 0x15, "Links House Cow", "KF Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), 0x16, "Cow Grotto Cow", "HF Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), 0x16, "Stables Left Cow", "LLR Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), 0x15, "Stables Right Cow", "LLR Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), 0x15, "Tower Left Cow", "LLR Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), 0x16, "Tower Right Cow", "LLR Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, 0x15, "Impas House Cow", "Kak Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), 0x15, "Cow Grotto Cow", "DMT Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_GERUDO_VALLEY, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, 0x15, "Cow", "GV Cow", RHT_GV_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, 0x15, "MQ Cow", "Jabu Jabus Belly MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); /*------------------------------- --- SHOPS --- @@ -1382,192 +1370,190 @@ void Rando::StaticData::InitLocationTable() { 7 5 1 3 -------------------------------*/ - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Spoiler Collection Check Group // Kokiri Forest - locationTable[RC_KF_SHOP_ITEM_1] = Location::Base(RC_KF_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x00, 0x00, "Shop Item 1", "KF Shop Item 1", RHT_KF_SHOP_ITEM_1, RG_BUY_DEKU_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 0), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_2] = Location::Base(RC_KF_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x01, 0x01, "Shop Item 2", "KF Shop Item 2", RHT_KF_SHOP_ITEM_2, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 1), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_3] = Location::Base(RC_KF_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x02, 0x02, "Shop Item 3", "KF Shop Item 3", RHT_KF_SHOP_ITEM_3, RG_BUY_DEKU_NUTS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 2), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_4] = Location::Base(RC_KF_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x03, 0x03, "Shop Item 4", "KF Shop Item 4", RHT_KF_SHOP_ITEM_4, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 3), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_5] = Location::Base(RC_KF_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x04, 0x04, "Shop Item 5", "KF Shop Item 5", RHT_KF_SHOP_ITEM_5, RG_BUY_DEKU_SEEDS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 4), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_6] = Location::Base(RC_KF_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x05, 0x05, "Shop Item 6", "KF Shop Item 6", RHT_KF_SHOP_ITEM_6, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 5), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_7] = Location::Base(RC_KF_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x06, 0x06, "Shop Item 7", "KF Shop Item 7", RHT_KF_SHOP_ITEM_7, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 6), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_8] = Location::Base(RC_KF_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x07, 0x07, "Shop Item 8", "KF Shop Item 8", RHT_KF_SHOP_ITEM_8, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 7), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_1] = Location::Base(RC_KF_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x00, 0x00, "Shop Item 1", "KF Shop Item 1", RHT_KF_SHOP_ITEM_1, RG_BUY_DEKU_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 0), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_2] = Location::Base(RC_KF_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x01, 0x01, "Shop Item 2", "KF Shop Item 2", RHT_KF_SHOP_ITEM_2, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 1), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_3] = Location::Base(RC_KF_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x02, 0x02, "Shop Item 3", "KF Shop Item 3", RHT_KF_SHOP_ITEM_3, RG_BUY_DEKU_NUTS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 2), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_4] = Location::Base(RC_KF_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x03, 0x03, "Shop Item 4", "KF Shop Item 4", RHT_KF_SHOP_ITEM_4, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 3), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_5] = Location::Base(RC_KF_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x04, 0x04, "Shop Item 5", "KF Shop Item 5", RHT_KF_SHOP_ITEM_5, RG_BUY_DEKU_SEEDS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 4), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_6] = Location::Base(RC_KF_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x05, 0x05, "Shop Item 6", "KF Shop Item 6", RHT_KF_SHOP_ITEM_6, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 5), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_7] = Location::Base(RC_KF_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x06, 0x06, "Shop Item 7", "KF Shop Item 7", RHT_KF_SHOP_ITEM_7, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 6), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_8] = Location::Base(RC_KF_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x07, 0x07, "Shop Item 8", "KF Shop Item 8", RHT_KF_SHOP_ITEM_8, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 7), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); // Kakariko Village - locationTable[RC_KAK_POTION_SHOP_ITEM_1] = Location::Base(RC_KAK_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x00, 0x30, "Potion Shop Item 1", "Kak Potion Shop Item 1", RHT_KAK_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_2] = Location::Base(RC_KAK_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x01, 0x31, "Potion Shop Item 2", "Kak Potion Shop Item 2", RHT_KAK_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_3] = Location::Base(RC_KAK_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x02, 0x32, "Potion Shop Item 3", "Kak Potion Shop Item 3", RHT_KAK_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 2), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_4] = Location::Base(RC_KAK_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x03, 0x33, "Potion Shop Item 4", "Kak Potion Shop Item 4", RHT_KAK_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_5] = Location::Base(RC_KAK_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x04, 0x34, "Potion Shop Item 5", "Kak Potion Shop Item 5", RHT_KAK_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_6] = Location::Base(RC_KAK_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x05, 0x35, "Potion Shop Item 6", "Kak Potion Shop Item 6", RHT_KAK_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 5), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_7] = Location::Base(RC_KAK_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x06, 0x36, "Potion Shop Item 7", "Kak Potion Shop Item 7", RHT_KAK_POTION_SHOP_ITEM_7, RG_BUY_POE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 6), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_8] = Location::Base(RC_KAK_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x07, 0x37, "Potion Shop Item 8", "Kak Potion Shop Item 8", RHT_KAK_POTION_SHOP_ITEM_8, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_1] = Location::Base(RC_KAK_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x00, 0x38, "Bazaar Item 1", "Kak Bazaar Item 1", RHT_KAK_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_2] = Location::Base(RC_KAK_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x01, 0x39, "Bazaar Item 2", "Kak Bazaar Item 2", RHT_KAK_BAZAAR_ITEM_2, RG_BUY_BOMBS_535, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_3] = Location::Base(RC_KAK_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x02, 0x3A, "Bazaar Item 3", "Kak Bazaar Item 3", RHT_KAK_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 2), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_4] = Location::Base(RC_KAK_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x03, 0x3B, "Bazaar Item 4", "Kak Bazaar Item 4", RHT_KAK_BAZAAR_ITEM_4, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_5] = Location::Base(RC_KAK_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x04, 0x3C, "Bazaar Item 5", "Kak Bazaar Item 5", RHT_KAK_BAZAAR_ITEM_5, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_6] = Location::Base(RC_KAK_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x05, 0x3D, "Bazaar Item 6", "Kak Bazaar Item 6", RHT_KAK_BAZAAR_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 5), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_7] = Location::Base(RC_KAK_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x06, 0x3E, "Bazaar Item 7", "Kak Bazaar Item 7", RHT_KAK_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 6), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_8] = Location::Base(RC_KAK_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, 0x3F, "Bazaar Item 8", "Kak Bazaar Item 8", RHT_KAK_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_1] = Location::Base(RC_KAK_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x00, 0x30, "Potion Shop Item 1", "Kak Potion Shop Item 1", RHT_KAK_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_2] = Location::Base(RC_KAK_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x01, 0x31, "Potion Shop Item 2", "Kak Potion Shop Item 2", RHT_KAK_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_3] = Location::Base(RC_KAK_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x02, 0x32, "Potion Shop Item 3", "Kak Potion Shop Item 3", RHT_KAK_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 2), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_4] = Location::Base(RC_KAK_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x03, 0x33, "Potion Shop Item 4", "Kak Potion Shop Item 4", RHT_KAK_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_5] = Location::Base(RC_KAK_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x04, 0x34, "Potion Shop Item 5", "Kak Potion Shop Item 5", RHT_KAK_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_6] = Location::Base(RC_KAK_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x05, 0x35, "Potion Shop Item 6", "Kak Potion Shop Item 6", RHT_KAK_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 5), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_7] = Location::Base(RC_KAK_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x06, 0x36, "Potion Shop Item 7", "Kak Potion Shop Item 7", RHT_KAK_POTION_SHOP_ITEM_7, RG_BUY_POE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 6), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_8] = Location::Base(RC_KAK_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x07, 0x37, "Potion Shop Item 8", "Kak Potion Shop Item 8", RHT_KAK_POTION_SHOP_ITEM_8, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_BAZAAR_ITEM_1] = Location::Base(RC_KAK_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x00, 0x38, "Bazaar Item 1", "Kak Bazaar Item 1", RHT_KAK_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_BAZAAR_ITEM_2] = Location::Base(RC_KAK_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x01, 0x39, "Bazaar Item 2", "Kak Bazaar Item 2", RHT_KAK_BAZAAR_ITEM_2, RG_BUY_BOMBS_535, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_BAZAAR_ITEM_3] = Location::Base(RC_KAK_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x02, 0x3A, "Bazaar Item 3", "Kak Bazaar Item 3", RHT_KAK_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 2), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_BAZAAR_ITEM_4] = Location::Base(RC_KAK_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x03, 0x3B, "Bazaar Item 4", "Kak Bazaar Item 4", RHT_KAK_BAZAAR_ITEM_4, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_BAZAAR_ITEM_5] = Location::Base(RC_KAK_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x04, 0x3C, "Bazaar Item 5", "Kak Bazaar Item 5", RHT_KAK_BAZAAR_ITEM_5, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_BAZAAR_ITEM_6] = Location::Base(RC_KAK_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x05, 0x3D, "Bazaar Item 6", "Kak Bazaar Item 6", RHT_KAK_BAZAAR_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 5), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_BAZAAR_ITEM_7] = Location::Base(RC_KAK_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x06, 0x3E, "Bazaar Item 7", "Kak Bazaar Item 7", RHT_KAK_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 6), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_BAZAAR_ITEM_8] = Location::Base(RC_KAK_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, 0x3F, "Bazaar Item 8", "Kak Bazaar Item 8", RHT_KAK_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); // Market - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_1] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, 0x30, "Bombchu Shop Item 1", "MK Bombchu Shop Item 1", RHT_MARKET_BOMBCHU_SHOP_ITEM_1, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_2] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, 0x31, "Bombchu Shop Item 2", "MK Bombchu Shop Item 2", RHT_MARKET_BOMBCHU_SHOP_ITEM_2, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_3] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x02, 0x32, "Bombchu Shop Item 3", "MK Bombchu Shop Item 3", RHT_MARKET_BOMBCHU_SHOP_ITEM_3, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_4] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x03, 0x33, "Bombchu Shop Item 4", "MK Bombchu Shop Item 4", RHT_MARKET_BOMBCHU_SHOP_ITEM_4, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_5] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x04, 0x34, "Bombchu Shop Item 5", "MK Bombchu Shop Item 5", RHT_MARKET_BOMBCHU_SHOP_ITEM_5, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_6] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x05, 0x35, "Bombchu Shop Item 6", "MK Bombchu Shop Item 6", RHT_MARKET_BOMBCHU_SHOP_ITEM_6, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_7] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x06, 0x36, "Bombchu Shop Item 7", "MK Bombchu Shop Item 7", RHT_MARKET_BOMBCHU_SHOP_ITEM_7, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_8] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x07, 0x37, "Bombchu Shop Item 8", "MK Bombchu Shop Item 8", RHT_MARKET_BOMBCHU_SHOP_ITEM_8, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_1] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x00, 0x30, "Potion Shop Item 1", "MK Potion Shop Item 1", RHT_MARKET_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_2] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x01, 0x31, "Potion Shop Item 2", "MK Potion Shop Item 2", RHT_MARKET_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_3] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x02, 0x32, "Potion Shop Item 3", "MK Potion Shop Item 3", RHT_MARKET_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_4] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x03, 0x33, "Potion Shop Item 4", "MK Potion Shop Item 4", RHT_MARKET_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_5] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x04, 0x34, "Potion Shop Item 5", "MK Potion Shop Item 5", RHT_MARKET_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_6] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x05, 0x35, "Potion Shop Item 6", "MK Potion Shop Item 6", RHT_MARKET_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_7] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x06, 0x36, "Potion Shop Item 7", "MK Potion Shop Item 7", RHT_MARKET_POTION_SHOP_ITEM_7, RG_BUY_POE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_8] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x07, 0x37, "Potion Shop Item 8", "MK Potion Shop Item 8", RHT_MARKET_POTION_SHOP_ITEM_8, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_1] = Location::Base(RC_MARKET_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x00, 0x30, "Bazaar Item 1", "MK Bazaar Item 1", RHT_MARKET_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_2] = Location::Base(RC_MARKET_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x01, 0x31, "Bazaar Item 2", "MK Bazaar Item 2", RHT_MARKET_BAZAAR_ITEM_2, RG_BUY_BOMBS_535, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_3] = Location::Base(RC_MARKET_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x02, 0x32, "Bazaar Item 3", "MK Bazaar Item 3", RHT_MARKET_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_4] = Location::Base(RC_MARKET_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x03, 0x33, "Bazaar Item 4", "MK Bazaar Item 4", RHT_MARKET_BAZAAR_ITEM_4, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_5] = Location::Base(RC_MARKET_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x04, 0x34, "Bazaar Item 5", "MK Bazaar Item 5", RHT_MARKET_BAZAAR_ITEM_5, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_6] = Location::Base(RC_MARKET_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x05, 0x35, "Bazaar Item 6", "MK Bazaar Item 6", RHT_MARKET_BAZAAR_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_7] = Location::Base(RC_MARKET_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x06, 0x36, "Bazaar Item 7", "MK Bazaar Item 7", RHT_MARKET_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_8] = Location::Base(RC_MARKET_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x07, 0x37, "Bazaar Item 8", "MK Bazaar Item 8", RHT_MARKET_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_1] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, 0x30, "Bombchu Shop Item 1", "MK Bombchu Shop Item 1", RHT_MARKET_BOMBCHU_SHOP_ITEM_1, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_2] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, 0x31, "Bombchu Shop Item 2", "MK Bombchu Shop Item 2", RHT_MARKET_BOMBCHU_SHOP_ITEM_2, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_3] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x02, 0x32, "Bombchu Shop Item 3", "MK Bombchu Shop Item 3", RHT_MARKET_BOMBCHU_SHOP_ITEM_3, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_4] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x03, 0x33, "Bombchu Shop Item 4", "MK Bombchu Shop Item 4", RHT_MARKET_BOMBCHU_SHOP_ITEM_4, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_5] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x04, 0x34, "Bombchu Shop Item 5", "MK Bombchu Shop Item 5", RHT_MARKET_BOMBCHU_SHOP_ITEM_5, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_6] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x05, 0x35, "Bombchu Shop Item 6", "MK Bombchu Shop Item 6", RHT_MARKET_BOMBCHU_SHOP_ITEM_6, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_7] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x06, 0x36, "Bombchu Shop Item 7", "MK Bombchu Shop Item 7", RHT_MARKET_BOMBCHU_SHOP_ITEM_7, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_8] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x07, 0x37, "Bombchu Shop Item 8", "MK Bombchu Shop Item 8", RHT_MARKET_BOMBCHU_SHOP_ITEM_8, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_1] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x00, 0x30, "Potion Shop Item 1", "MK Potion Shop Item 1", RHT_MARKET_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_2] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x01, 0x31, "Potion Shop Item 2", "MK Potion Shop Item 2", RHT_MARKET_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_3] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x02, 0x32, "Potion Shop Item 3", "MK Potion Shop Item 3", RHT_MARKET_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_4] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x03, 0x33, "Potion Shop Item 4", "MK Potion Shop Item 4", RHT_MARKET_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_5] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x04, 0x34, "Potion Shop Item 5", "MK Potion Shop Item 5", RHT_MARKET_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_6] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x05, 0x35, "Potion Shop Item 6", "MK Potion Shop Item 6", RHT_MARKET_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_7] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x06, 0x36, "Potion Shop Item 7", "MK Potion Shop Item 7", RHT_MARKET_POTION_SHOP_ITEM_7, RG_BUY_POE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_8] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x07, 0x37, "Potion Shop Item 8", "MK Potion Shop Item 8", RHT_MARKET_POTION_SHOP_ITEM_8, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BAZAAR_ITEM_1] = Location::Base(RC_MARKET_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x00, 0x30, "Bazaar Item 1", "MK Bazaar Item 1", RHT_MARKET_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BAZAAR_ITEM_2] = Location::Base(RC_MARKET_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x01, 0x31, "Bazaar Item 2", "MK Bazaar Item 2", RHT_MARKET_BAZAAR_ITEM_2, RG_BUY_BOMBS_535, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BAZAAR_ITEM_3] = Location::Base(RC_MARKET_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x02, 0x32, "Bazaar Item 3", "MK Bazaar Item 3", RHT_MARKET_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BAZAAR_ITEM_4] = Location::Base(RC_MARKET_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x03, 0x33, "Bazaar Item 4", "MK Bazaar Item 4", RHT_MARKET_BAZAAR_ITEM_4, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BAZAAR_ITEM_5] = Location::Base(RC_MARKET_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x04, 0x34, "Bazaar Item 5", "MK Bazaar Item 5", RHT_MARKET_BAZAAR_ITEM_5, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BAZAAR_ITEM_6] = Location::Base(RC_MARKET_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x05, 0x35, "Bazaar Item 6", "MK Bazaar Item 6", RHT_MARKET_BAZAAR_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BAZAAR_ITEM_7] = Location::Base(RC_MARKET_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x06, 0x36, "Bazaar Item 7", "MK Bazaar Item 7", RHT_MARKET_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BAZAAR_ITEM_8] = Location::Base(RC_MARKET_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x07, 0x37, "Bazaar Item 8", "MK Bazaar Item 8", RHT_MARKET_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); // Zora's Domain - locationTable[RC_ZD_SHOP_ITEM_1] = Location::Base(RC_ZD_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x00, 0x30, "Shop Item 1", "ZD Shop Item 1", RHT_ZD_SHOP_ITEM_1, RG_BUY_ZORA_TUNIC, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_2] = Location::Base(RC_ZD_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x01, 0x31, "Shop Item 2", "ZD Shop Item 2", RHT_ZD_SHOP_ITEM_2, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 1), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_3] = Location::Base(RC_ZD_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x02, 0x32, "Shop Item 3", "ZD Shop Item 3", RHT_ZD_SHOP_ITEM_3, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 2), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_4] = Location::Base(RC_ZD_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x03, 0x33, "Shop Item 4", "ZD Shop Item 4", RHT_ZD_SHOP_ITEM_4, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 3), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_5] = Location::Base(RC_ZD_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x04, 0x34, "Shop Item 5", "ZD Shop Item 5", RHT_ZD_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 4), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_6] = Location::Base(RC_ZD_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x05, 0x35, "Shop Item 6", "ZD Shop Item 6", RHT_ZD_SHOP_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 5), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_7] = Location::Base(RC_ZD_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x06, 0x36, "Shop Item 7", "ZD Shop Item 7", RHT_ZD_SHOP_ITEM_7, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 6), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_8] = Location::Base(RC_ZD_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x07, 0x37, "Shop Item 8", "ZD Shop Item 8", RHT_ZD_SHOP_ITEM_8, RG_BUY_RED_POTION_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 7), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_1] = Location::Base(RC_ZD_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x00, 0x30, "Shop Item 1", "ZD Shop Item 1", RHT_ZD_SHOP_ITEM_1, RG_BUY_ZORA_TUNIC, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_2] = Location::Base(RC_ZD_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x01, 0x31, "Shop Item 2", "ZD Shop Item 2", RHT_ZD_SHOP_ITEM_2, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 1), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_3] = Location::Base(RC_ZD_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x02, 0x32, "Shop Item 3", "ZD Shop Item 3", RHT_ZD_SHOP_ITEM_3, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 2), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_4] = Location::Base(RC_ZD_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x03, 0x33, "Shop Item 4", "ZD Shop Item 4", RHT_ZD_SHOP_ITEM_4, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 3), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_5] = Location::Base(RC_ZD_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x04, 0x34, "Shop Item 5", "ZD Shop Item 5", RHT_ZD_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 4), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_6] = Location::Base(RC_ZD_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x05, 0x35, "Shop Item 6", "ZD Shop Item 6", RHT_ZD_SHOP_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 5), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_7] = Location::Base(RC_ZD_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x06, 0x36, "Shop Item 7", "ZD Shop Item 7", RHT_ZD_SHOP_ITEM_7, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 6), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_8] = Location::Base(RC_ZD_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x07, 0x37, "Shop Item 8", "ZD Shop Item 8", RHT_ZD_SHOP_ITEM_8, RG_BUY_RED_POTION_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 7), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); // Goron City - locationTable[RC_GC_SHOP_ITEM_1] = Location::Base(RC_GC_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x00, 0x30, "Shop Item 1", "GC Shop Item 1", RHT_GC_SHOP_ITEM_1, RG_BUY_BOMBS_525, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 0), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_2] = Location::Base(RC_GC_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x01, 0x31, "Shop Item 2", "GC Shop Item 2", RHT_GC_SHOP_ITEM_2, RG_BUY_BOMBS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 1), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_3] = Location::Base(RC_GC_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x02, 0x32, "Shop Item 3", "GC Shop Item 3", RHT_GC_SHOP_ITEM_3, RG_BUY_BOMBS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 2), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_4] = Location::Base(RC_GC_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x03, 0x33, "Shop Item 4", "GC Shop Item 4", RHT_GC_SHOP_ITEM_4, RG_BUY_BOMBS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 3), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_5] = Location::Base(RC_GC_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x04, 0x34, "Shop Item 5", "GC Shop Item 5", RHT_GC_SHOP_ITEM_5, RG_BUY_GORON_TUNIC, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 4), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_6] = Location::Base(RC_GC_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x05, 0x35, "Shop Item 6", "GC Shop Item 6", RHT_GC_SHOP_ITEM_6, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 5), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_7] = Location::Base(RC_GC_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x06, 0x36, "Shop Item 7", "GC Shop Item 7", RHT_GC_SHOP_ITEM_7, RG_BUY_RED_POTION_40, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 6), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_8] = Location::Base(RC_GC_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x07, 0x37, "Shop Item 8", "GC Shop Item 8", RHT_GC_SHOP_ITEM_8, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 7), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_1] = Location::Base(RC_GC_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x00, 0x30, "Shop Item 1", "GC Shop Item 1", RHT_GC_SHOP_ITEM_1, RG_BUY_BOMBS_525, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 0), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_2] = Location::Base(RC_GC_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x01, 0x31, "Shop Item 2", "GC Shop Item 2", RHT_GC_SHOP_ITEM_2, RG_BUY_BOMBS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 1), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_3] = Location::Base(RC_GC_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x02, 0x32, "Shop Item 3", "GC Shop Item 3", RHT_GC_SHOP_ITEM_3, RG_BUY_BOMBS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 2), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_4] = Location::Base(RC_GC_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x03, 0x33, "Shop Item 4", "GC Shop Item 4", RHT_GC_SHOP_ITEM_4, RG_BUY_BOMBS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 3), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_5] = Location::Base(RC_GC_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x04, 0x34, "Shop Item 5", "GC Shop Item 5", RHT_GC_SHOP_ITEM_5, RG_BUY_GORON_TUNIC, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 4), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_6] = Location::Base(RC_GC_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x05, 0x35, "Shop Item 6", "GC Shop Item 6", RHT_GC_SHOP_ITEM_6, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 5), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_7] = Location::Base(RC_GC_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x06, 0x36, "Shop Item 7", "GC Shop Item 7", RHT_GC_SHOP_ITEM_7, RG_BUY_RED_POTION_40, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 6), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_8] = Location::Base(RC_GC_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x07, 0x37, "Shop Item 8", "GC Shop Item 8", RHT_GC_SHOP_ITEM_8, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 7), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); /* +--------------+ | FISHSANITY | +--------------+ */ - // Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group - locationTable[RC_LH_CHILD_FISH_1] = Location::Base(RC_LH_CHILD_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 100, 0x00, "Child Pond Fish 1", "LH Child Pond Fish 1", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_2] = Location::Base(RC_LH_CHILD_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 101, 0x00, "Child Pond Fish 2", "LH Child Pond Fish 2", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_3] = Location::Base(RC_LH_CHILD_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 102, 0x00, "Child Pond Fish 3", "LH Child Pond Fish 3", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_4] = Location::Base(RC_LH_CHILD_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 103, 0x00, "Child Pond Fish 4", "LH Child Pond Fish 4", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_5] = Location::Base(RC_LH_CHILD_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 104, 0x00, "Child Pond Fish 5", "LH Child Pond Fish 5", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_6] = Location::Base(RC_LH_CHILD_FISH_6, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 105, 0x00, "Child Pond Fish 6", "LH Child Pond Fish 6", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_7] = Location::Base(RC_LH_CHILD_FISH_7, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 106, 0x00, "Child Pond Fish 7", "LH Child Pond Fish 7", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_8] = Location::Base(RC_LH_CHILD_FISH_8, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 107, 0x00, "Child Pond Fish 8", "LH Child Pond Fish 8", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_9] = Location::Base(RC_LH_CHILD_FISH_9, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 108, 0x00, "Child Pond Fish 9", "LH Child Pond Fish 9", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_10] = Location::Base(RC_LH_CHILD_FISH_10, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 109, 0x00, "Child Pond Fish 10", "LH Child Pond Fish 10", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_11] = Location::Base(RC_LH_CHILD_FISH_11, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 110, 0x00, "Child Pond Fish 11", "LH Child Pond Fish 11", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_12] = Location::Base(RC_LH_CHILD_FISH_12, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 111, 0x00, "Child Pond Fish 12", "LH Child Pond Fish 12", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_13] = Location::Base(RC_LH_CHILD_FISH_13, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 112, 0x00, "Child Pond Fish 13", "LH Child Pond Fish 13", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_14] = Location::Base(RC_LH_CHILD_FISH_14, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 113, 0x00, "Child Pond Fish 14", "LH Child Pond Fish 14", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_15] = Location::Base(RC_LH_CHILD_FISH_15, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 114, 0x00, "Child Pond Fish 15", "LH Child Pond Fish 15", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_LOACH_1] = Location::Base(RC_LH_CHILD_LOACH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 115, 0x00, "Child Pond Loach 1", "LH Child Pond Loach 1", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_LOACH_2] = Location::Base(RC_LH_CHILD_LOACH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 116, 0x00, "Child Pond Loach 2", "LH Child Pond Loach 2", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_1] = Location::Base(RC_LH_ADULT_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 100, 0x00, "Adult Pond Fish 1", "LH Adult Pond Fish 1", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_2] = Location::Base(RC_LH_ADULT_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 101, 0x00, "Adult Pond Fish 2", "LH Adult Pond Fish 2", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_3] = Location::Base(RC_LH_ADULT_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 102, 0x00, "Adult Pond Fish 3", "LH Adult Pond Fish 3", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_4] = Location::Base(RC_LH_ADULT_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 103, 0x00, "Adult Pond Fish 4", "LH Adult Pond Fish 4", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_5] = Location::Base(RC_LH_ADULT_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 104, 0x00, "Adult Pond Fish 5", "LH Adult Pond Fish 5", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_6] = Location::Base(RC_LH_ADULT_FISH_6, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 105, 0x00, "Adult Pond Fish 6", "LH Adult Pond Fish 6", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_7] = Location::Base(RC_LH_ADULT_FISH_7, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 106, 0x00, "Adult Pond Fish 7", "LH Adult Pond Fish 7", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_8] = Location::Base(RC_LH_ADULT_FISH_8, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 107, 0x00, "Adult Pond Fish 8", "LH Adult Pond Fish 8", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_9] = Location::Base(RC_LH_ADULT_FISH_9, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 108, 0x00, "Adult Pond Fish 9", "LH Adult Pond Fish 9", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_10] = Location::Base(RC_LH_ADULT_FISH_10, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 109, 0x00, "Adult Pond Fish 10", "LH Adult Pond Fish 10", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_11] = Location::Base(RC_LH_ADULT_FISH_11, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 110, 0x00, "Adult Pond Fish 11", "LH Adult Pond Fish 11", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_12] = Location::Base(RC_LH_ADULT_FISH_12, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 111, 0x00, "Adult Pond Fish 12", "LH Adult Pond Fish 12", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_13] = Location::Base(RC_LH_ADULT_FISH_13, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 112, 0x00, "Adult Pond Fish 13", "LH Adult Pond Fish 13", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_14] = Location::Base(RC_LH_ADULT_FISH_14, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 113, 0x00, "Adult Pond Fish 14", "LH Adult Pond Fish 14", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_15] = Location::Base(RC_LH_ADULT_FISH_15, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 114, 0x00, "Adult Pond Fish 15", "LH Adult Pond Fish 15", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_LOACH] = Location::Base(RC_LH_ADULT_LOACH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 115, 0x00, "Adult Pond Loach", "LH Adult Pond Loach", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + // Fishing Pond + locationTable[RC_LH_CHILD_FISH_1] = Location::Base(RC_LH_CHILD_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 100, 0x00, "Child Pond Fish 1", "LH Child Pond Fish 1", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_2] = Location::Base(RC_LH_CHILD_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 101, 0x00, "Child Pond Fish 2", "LH Child Pond Fish 2", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_3] = Location::Base(RC_LH_CHILD_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 102, 0x00, "Child Pond Fish 3", "LH Child Pond Fish 3", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_4] = Location::Base(RC_LH_CHILD_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 103, 0x00, "Child Pond Fish 4", "LH Child Pond Fish 4", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_5] = Location::Base(RC_LH_CHILD_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 104, 0x00, "Child Pond Fish 5", "LH Child Pond Fish 5", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_6] = Location::Base(RC_LH_CHILD_FISH_6, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 105, 0x00, "Child Pond Fish 6", "LH Child Pond Fish 6", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_7] = Location::Base(RC_LH_CHILD_FISH_7, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 106, 0x00, "Child Pond Fish 7", "LH Child Pond Fish 7", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_8] = Location::Base(RC_LH_CHILD_FISH_8, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 107, 0x00, "Child Pond Fish 8", "LH Child Pond Fish 8", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_9] = Location::Base(RC_LH_CHILD_FISH_9, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 108, 0x00, "Child Pond Fish 9", "LH Child Pond Fish 9", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_10] = Location::Base(RC_LH_CHILD_FISH_10, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 109, 0x00, "Child Pond Fish 10", "LH Child Pond Fish 10", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_11] = Location::Base(RC_LH_CHILD_FISH_11, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 110, 0x00, "Child Pond Fish 11", "LH Child Pond Fish 11", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_12] = Location::Base(RC_LH_CHILD_FISH_12, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 111, 0x00, "Child Pond Fish 12", "LH Child Pond Fish 12", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_13] = Location::Base(RC_LH_CHILD_FISH_13, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 112, 0x00, "Child Pond Fish 13", "LH Child Pond Fish 13", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_14] = Location::Base(RC_LH_CHILD_FISH_14, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 113, 0x00, "Child Pond Fish 14", "LH Child Pond Fish 14", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_15] = Location::Base(RC_LH_CHILD_FISH_15, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 114, 0x00, "Child Pond Fish 15", "LH Child Pond Fish 15", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_LOACH_1] = Location::Base(RC_LH_CHILD_LOACH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 115, 0x00, "Child Pond Loach 1", "LH Child Pond Loach 1", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_LOACH_2] = Location::Base(RC_LH_CHILD_LOACH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 116, 0x00, "Child Pond Loach 2", "LH Child Pond Loach 2", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_1] = Location::Base(RC_LH_ADULT_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 100, 0x00, "Adult Pond Fish 1", "LH Adult Pond Fish 1", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_2] = Location::Base(RC_LH_ADULT_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 101, 0x00, "Adult Pond Fish 2", "LH Adult Pond Fish 2", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_3] = Location::Base(RC_LH_ADULT_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 102, 0x00, "Adult Pond Fish 3", "LH Adult Pond Fish 3", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_4] = Location::Base(RC_LH_ADULT_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 103, 0x00, "Adult Pond Fish 4", "LH Adult Pond Fish 4", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_5] = Location::Base(RC_LH_ADULT_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 104, 0x00, "Adult Pond Fish 5", "LH Adult Pond Fish 5", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_6] = Location::Base(RC_LH_ADULT_FISH_6, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 105, 0x00, "Adult Pond Fish 6", "LH Adult Pond Fish 6", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_7] = Location::Base(RC_LH_ADULT_FISH_7, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 106, 0x00, "Adult Pond Fish 7", "LH Adult Pond Fish 7", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_8] = Location::Base(RC_LH_ADULT_FISH_8, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 107, 0x00, "Adult Pond Fish 8", "LH Adult Pond Fish 8", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_9] = Location::Base(RC_LH_ADULT_FISH_9, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 108, 0x00, "Adult Pond Fish 9", "LH Adult Pond Fish 9", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_10] = Location::Base(RC_LH_ADULT_FISH_10, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 109, 0x00, "Adult Pond Fish 10", "LH Adult Pond Fish 10", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_11] = Location::Base(RC_LH_ADULT_FISH_11, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 110, 0x00, "Adult Pond Fish 11", "LH Adult Pond Fish 11", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_12] = Location::Base(RC_LH_ADULT_FISH_12, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 111, 0x00, "Adult Pond Fish 12", "LH Adult Pond Fish 12", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_13] = Location::Base(RC_LH_ADULT_FISH_13, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 112, 0x00, "Adult Pond Fish 13", "LH Adult Pond Fish 13", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_14] = Location::Base(RC_LH_ADULT_FISH_14, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 113, 0x00, "Adult Pond Fish 14", "LH Adult Pond Fish 14", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_FISH_15] = Location::Base(RC_LH_ADULT_FISH_15, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 114, 0x00, "Adult Pond Fish 15", "LH Adult Pond Fish 15", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_ADULT_LOACH] = Location::Base(RC_LH_ADULT_LOACH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 115, 0x00, "Adult Pond Loach", "LH Adult Pond Loach", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); // Grotto fish - locationTable[RC_KF_STORMS_GROTTO_FISH] = Location::Base(RC_KF_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_KOKIRI_FOREST, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Storms Grotto Fish", "KF Storms Grotto Fish", RHT_KF_STORMS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x2C, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_FISH] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LOST_WOODS, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Near Shortcuts Grotto Fish", "LW Near Shortcuts Grotto Fish", RHT_LW_NEAR_SHORTCUTS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x14, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_HF_SOUTHEAST_GROTTO_FISH] = Location::Base(RC_HF_SOUTHEAST_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Southeast Grotto Fish", "HF Southeast Grotto Fish", RHT_HF_SOUTHEAST_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x22, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_OPEN_GROTTO_FISH] = Location::Base(RC_HF_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", "HF Open Grotto Fish", RHT_HF_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x03, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_NEAR_MARKET_GROTTO_FISH] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Near Market Grotto Fish", "HF Near Market Grotto Fish", RHT_HF_NEAR_MARKET_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x00, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_KAK_OPEN_GROTTO_FISH] = Location::Base(RC_KAK_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", "Kak Open Grotto Fish", RHT_KAK_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x28, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_DMT_STORMS_GROTTO_FISH] = Location::Base(RC_DMT_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Storms Grotto Fish", "DMT Storms Grotto Fish", RHT_DMT_STORMS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x57, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_UPPER_GROTTO_FISH] = Location::Base(RC_DMC_UPPER_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_DEATH_MOUNTAIN_CRATER,ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Upper Grotto Fish", "DMC Upper Grotto Fish", RHT_DMC_UPPER_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x7A, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_ZR_OPEN_GROTTO_FISH] = Location::Base(RC_ZR_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_RIVER, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", "ZR Open Grotto Fish", RHT_ZR_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x29, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_KF_STORMS_GROTTO_FISH] = Location::Base(RC_KF_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_KOKIRI_FOREST, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Storms Grotto Fish", "KF Storms Grotto Fish", RHT_KF_STORMS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x2C, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_FISH] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LOST_WOODS, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Near Shortcuts Grotto Fish", "LW Near Shortcuts Grotto Fish", RHT_LW_NEAR_SHORTCUTS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x14, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_HF_SOUTHEAST_GROTTO_FISH] = Location::Base(RC_HF_SOUTHEAST_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Southeast Grotto Fish", "HF Southeast Grotto Fish", RHT_HF_SOUTHEAST_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x22, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_OPEN_GROTTO_FISH] = Location::Base(RC_HF_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", "HF Open Grotto Fish", RHT_HF_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x03, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_NEAR_MARKET_GROTTO_FISH] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Near Market Grotto Fish", "HF Near Market Grotto Fish", RHT_HF_NEAR_MARKET_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x00, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_KAK_OPEN_GROTTO_FISH] = Location::Base(RC_KAK_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", "Kak Open Grotto Fish", RHT_KAK_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x28, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_DMT_STORMS_GROTTO_FISH] = Location::Base(RC_DMT_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Storms Grotto Fish", "DMT Storms Grotto Fish", RHT_DMT_STORMS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x57, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_UPPER_GROTTO_FISH] = Location::Base(RC_DMC_UPPER_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Upper Grotto Fish", "DMC Upper Grotto Fish", RHT_DMC_UPPER_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x7A, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_ZR_OPEN_GROTTO_FISH] = Location::Base(RC_ZR_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_RIVER, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", "ZR Open Grotto Fish", RHT_ZR_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x29, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); // Zora's Domain fish - locationTable[RC_ZD_FISH_1] = Location::Base(RC_ZD_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 0, 0x00, "Fish 1", "ZD Fish 1", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_FISH_2] = Location::Base(RC_ZD_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 1, 0x00, "Fish 2", "ZD Fish 2", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_FISH_3] = Location::Base(RC_ZD_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 2, 0x00, "Fish 3", "ZD Fish 3", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_FISH_4] = Location::Base(RC_ZD_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 3, 0x00, "Fish 4", "ZD Fish 4", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_FISH_5] = Location::Base(RC_ZD_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 4, 0x00, "Fish 5", "ZD Fish 5", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_FISH_1] = Location::Base(RC_ZD_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 0, 0x00, "Fish 1", "ZD Fish 1", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_FISH_2] = Location::Base(RC_ZD_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 1, 0x00, "Fish 2", "ZD Fish 2", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_FISH_3] = Location::Base(RC_ZD_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 2, 0x00, "Fish 3", "ZD Fish 3", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_FISH_4] = Location::Base(RC_ZD_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 3, 0x00, "Fish 4", "ZD Fish 4", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_FISH_5] = Location::Base(RC_ZD_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 4, 0x00, "Fish 5", "ZD Fish 5", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); // Gossip Stones - // RandomizerCheck Randomizer Check Quest Area Scene Params Flag Short Name Spoiler name Categories - locationTable[RC_DMC_GOSSIP_STONE] = Location::HintStone(RC_DMC_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 14341, 0x05, "Gossip Stone", "DMC Gossip Stone", {}); - locationTable[RC_DMT_GOSSIP_STONE] = Location::HintStone(RC_DMT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 14340, 0x04, "Gossip Stone", "DMT Gossip Stone", {}); - locationTable[RC_COLOSSUS_GOSSIP_STONE] = Location::HintStone(RC_COLOSSUS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 14362, 0x1A, "Gossip Stone", "Colossus Gossip Stone", {}); - locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE] = Location::HintStone(RC_DODONGOS_CAVERN_GOSSIP_STONE, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 4372, 0x14, "Gossip Stone", "Dodongo's Cavern Gossip Stone", {}); - locationTable[RC_GV_GOSSIP_STONE] = Location::HintStone(RC_GV_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 14353, 0x11, "Gossip Stone", "GV Gossip Stone", {}); - locationTable[RC_GC_MAZE_GOSSIP_STONE] = Location::HintStone(RC_GC_MAZE_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14357, 0x15, "Maze Gossip Stone", "GC Maze Gossip Stone", {}); - locationTable[RC_GC_MEDIGORON_GOSSIP_STONE] = Location::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14873, 0x19, "Medigoron Gossip Stone", "GC Medigoron Gossip Stone", {}); - locationTable[RC_GY_GOSSIP_STONE] = Location::HintStone(RC_GY_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 14346, 0x0A, "Gossip Stone", "GY Gossip Stone", {}); - locationTable[RC_HC_MALON_GOSSIP_STONE] = Location::HintStone(RC_HC_MALON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14610, 0x12, "Malon Gossip Stone", "HC Malon Gossip Stone", {}); - locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE] = Location::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14347, 0x0B, "Rock Wall Gossip Stone", "HC Rock Wall Gossip Stone", {}); - locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 14355, 0x13, "Storms Grotto Gossip Stone", "HC Storms Grotto Gossip Stone", {}); - locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14623, 0x1F, "Deku Tree Left Gossip Stone", "KF Deku Tree Left Gossip Stone", {}); - locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14880, 0x20, "Deku Tree Right Gossip Stone", "KF Deku Tree Right Gossip Stone", {}); - locationTable[RC_KF_GOSSIP_STONE] = Location::HintStone(RC_KF_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14366, 0x1E, "Gossip Stone", "KF Gossip Stone", {}); - locationTable[RC_KF_STORMS_GOSSIP_STONE] = Location::HintStone(RC_KF_STORMS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, -22988, 0x3C, "Storms Gossip Stone", "KF Storms Gossip Stone", {}); - locationTable[RC_LH_LAB_GOSSIP_STONE] = Location::HintStone(RC_LH_LAB_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14339, 0x03, "Lab Gossip Stone", "LH Lab Gossip Stone", {}); - locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14863, 0x0F, "Southeast Gossip Stone", "LH Southeast Gossip Stone", {}); - locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14600, 0x08, "Southwest Gossip Stone", "LH Southwest Gossip Stone", {}); - locationTable[RC_LW_GOSSIP_STONE] = Location::HintStone(RC_LW_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 14365, 0x1D, "Gossip Stone", "LW Gossip Stone", {}); - locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14358, 0x16, "Maze Lower Gossip Stone", "SFM Maze Lower Gossip Stone", {}); - locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14615, 0x17, "Maze Upper Gossip Stone", "SFM Maze Upper Gossip Stone", {}); - locationTable[RC_SFM_SARIA_GOSSIP_STONE] = Location::HintStone(RC_SFM_SARIA_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14876, 0x1C, "Saria Gossip Stone", "SFM Saria Gossip Stone", {}); - locationTable[RC_TOT_LEFT_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x06, "ToT Left Gossip Stone", "ToT Left Gossip Stone", {}); - locationTable[RC_TOT_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x07, "ToT Right Gossip Stone", "ToT Right Gossip Stone", {}); - locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x10, "ToT Right Center Gossip Stone", "ToT Right Center Gossip Stone", {}); - locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x0E, "ToT Left Center Gossip Stone", "ToT Left Center Gossip Stone", {}); - locationTable[RC_ZD_GOSSIP_STONE] = Location::HintStone(RC_ZD_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, 14345, 0x09, "Gossip Stone", "ZD Gossip Stone", {}); - locationTable[RC_FAIRY_GOSSIP_STONE] = Location::HintStone(RC_FAIRY_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x01, "Fairy Gossip Stone", "Fairy Gossip Stone", {}); - locationTable[RC_JABU_GOSSIP_STONE] = Location::HintStone(RC_JABU_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x02, "Jabu Gossip Stone", "Jabu Gossip Stone", {}); - locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14605, 0x0D, "Near Grottos Gossip Stone", "ZR Near Grottos Gossip Stone", {}); - locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14860, 0x0C, "Near Domain Gossip Stone", "ZR Near Domain Gossip Stone", {}); - locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 14363, 0x1B, "Cow Grotto Gossip Stone", "HF Cow Grotto Gossip Stone", {}); - locationTable[RC_HF_NEAR_MARKET_GOSSIP_STONE] = Location::HintStone(RC_HF_NEAR_MARKET_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22944, 0x30, "Near Market Gossip Stone", "HF Near Market Gossip Stone", {}); - locationTable[RC_HF_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_HF_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22978, 0x32, "Southeast Gossip Stone", "HF Southeast Gossip Stone", {}); - locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, 0x33, "Open Grotto Gossip Stone", "HF Open Grotto Gossip Stone", {}); - locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, 0x38, "Open Grotto Gossip Stone", "Kak Open Grotto Gossip Stone", {}); - locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, 0x39, "Open Grotto Gossip Stone", "ZR Open Grotto Gossip Stone", {}); - locationTable[RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, 0x34, "Near Shortcuts Gossip Stone", "LW Near Shortcuts Gossip Stone", {}); - locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, 0x37, "Storms Grotto Gossip Stone", "DMT Storms Grotto Gossip Stone", {}); - locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, 0x3A, "Upper Grotto Gossip Stone", "DMC Upper Grotto Gossip Stone", {}); + locationTable[RC_DMC_GOSSIP_STONE] = Location::HintStone(RC_DMC_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 14341, 0x05, "Gossip Stone", "DMC Gossip Stone", {}); + locationTable[RC_DMT_GOSSIP_STONE] = Location::HintStone(RC_DMT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 14340, 0x04, "Gossip Stone", "DMT Gossip Stone", {}); + locationTable[RC_COLOSSUS_GOSSIP_STONE] = Location::HintStone(RC_COLOSSUS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 14362, 0x1A, "Gossip Stone", "Colossus Gossip Stone", {}); + locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE] = Location::HintStone(RC_DODONGOS_CAVERN_GOSSIP_STONE, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 4372, 0x14, "Gossip Stone", "Dodongo's Cavern Gossip Stone", {}); + locationTable[RC_GV_GOSSIP_STONE] = Location::HintStone(RC_GV_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 14353, 0x11, "Gossip Stone", "GV Gossip Stone", {}); + locationTable[RC_GC_MAZE_GOSSIP_STONE] = Location::HintStone(RC_GC_MAZE_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14357, 0x15, "Maze Gossip Stone", "GC Maze Gossip Stone", {}); + locationTable[RC_GC_MEDIGORON_GOSSIP_STONE] = Location::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14873, 0x19, "Medigoron Gossip Stone", "GC Medigoron Gossip Stone", {}); + locationTable[RC_GY_GOSSIP_STONE] = Location::HintStone(RC_GY_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 14346, 0x0A, "Gossip Stone", "GY Gossip Stone", {}); + locationTable[RC_HC_MALON_GOSSIP_STONE] = Location::HintStone(RC_HC_MALON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14610, 0x12, "Malon Gossip Stone", "HC Malon Gossip Stone", {}); + locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE] = Location::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14347, 0x0B, "Rock Wall Gossip Stone", "HC Rock Wall Gossip Stone", {}); + locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 14355, 0x13, "Storms Grotto Gossip Stone", "HC Storms Grotto Gossip Stone", {}); + locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14623, 0x1F, "Deku Tree Left Gossip Stone", "KF Deku Tree Left Gossip Stone", {}); + locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14880, 0x20, "Deku Tree Right Gossip Stone", "KF Deku Tree Right Gossip Stone", {}); + locationTable[RC_KF_GOSSIP_STONE] = Location::HintStone(RC_KF_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14366, 0x1E, "Gossip Stone", "KF Gossip Stone", {}); + locationTable[RC_KF_STORMS_GOSSIP_STONE] = Location::HintStone(RC_KF_STORMS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, -22988, 0x3C, "Storms Gossip Stone", "KF Storms Gossip Stone", {}); + locationTable[RC_LH_LAB_GOSSIP_STONE] = Location::HintStone(RC_LH_LAB_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14339, 0x03, "Lab Gossip Stone", "LH Lab Gossip Stone", {}); + locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14863, 0x0F, "Southeast Gossip Stone", "LH Southeast Gossip Stone", {}); + locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14600, 0x08, "Southwest Gossip Stone", "LH Southwest Gossip Stone", {}); + locationTable[RC_LW_GOSSIP_STONE] = Location::HintStone(RC_LW_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 14365, 0x1D, "Gossip Stone", "LW Gossip Stone", {}); + locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14358, 0x16, "Maze Lower Gossip Stone", "SFM Maze Lower Gossip Stone", {}); + locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14615, 0x17, "Maze Upper Gossip Stone", "SFM Maze Upper Gossip Stone", {}); + locationTable[RC_SFM_SARIA_GOSSIP_STONE] = Location::HintStone(RC_SFM_SARIA_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14876, 0x1C, "Saria Gossip Stone", "SFM Saria Gossip Stone", {}); + locationTable[RC_TOT_LEFT_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x06, "ToT Left Gossip Stone", "ToT Left Gossip Stone", {}); + locationTable[RC_TOT_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x07, "ToT Right Gossip Stone", "ToT Right Gossip Stone", {}); + locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x10, "ToT Right Center Gossip Stone", "ToT Right Center Gossip Stone", {}); + locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x0E, "ToT Left Center Gossip Stone", "ToT Left Center Gossip Stone", {}); + locationTable[RC_ZD_GOSSIP_STONE] = Location::HintStone(RC_ZD_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, 14345, 0x09, "Gossip Stone", "ZD Gossip Stone", {}); + locationTable[RC_FAIRY_GOSSIP_STONE] = Location::HintStone(RC_FAIRY_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x01, "Fairy Gossip Stone", "Fairy Gossip Stone", {}); + locationTable[RC_JABU_GOSSIP_STONE] = Location::HintStone(RC_JABU_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x02, "Jabu Gossip Stone", "Jabu Gossip Stone", {}); + locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14605, 0x0D, "Near Grottos Gossip Stone", "ZR Near Grottos Gossip Stone", {}); + locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14860, 0x0C, "Near Domain Gossip Stone", "ZR Near Domain Gossip Stone", {}); + locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 14363, 0x1B, "Cow Grotto Gossip Stone", "HF Cow Grotto Gossip Stone", {}); + locationTable[RC_HF_NEAR_MARKET_GOSSIP_STONE] = Location::HintStone(RC_HF_NEAR_MARKET_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22944, 0x30, "Near Market Gossip Stone", "HF Near Market Gossip Stone", {}); + locationTable[RC_HF_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_HF_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22978, 0x32, "Southeast Gossip Stone", "HF Southeast Gossip Stone", {}); + locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, 0x33, "Open Grotto Gossip Stone", "HF Open Grotto Gossip Stone", {}); + locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, 0x38, "Open Grotto Gossip Stone", "Kak Open Grotto Gossip Stone", {}); + locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, 0x39, "Open Grotto Gossip Stone", "ZR Open Grotto Gossip Stone", {}); + locationTable[RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, 0x34, "Near Shortcuts Gossip Stone", "LW Near Shortcuts Gossip Stone", {}); + locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, 0x37, "Storms Grotto Gossip Stone", "DMT Storms Grotto Gossip Stone", {}); + locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, 0x3A, "Upper Grotto Gossip Stone", "DMC Upper Grotto Gossip Stone", {}); // Other Hints - locationTable[RC_GANONDORF_HINT] = Location::OtherHint(RC_GANONDORF_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_GANON_MANT, SCENE_GANON_BOSS, "Ganondorf Hint", "Ganondorf Hint"); - locationTable[RC_SHEIK_HINT_GC] = Location::OtherHint(RC_SHEIK_HINT_GC, RCQUEST_VANILLA, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint", "Sheik Hint in Ganons Castle"); - locationTable[RC_SHEIK_HINT_MQ_GC] = Location::OtherHint(RC_SHEIK_HINT_MQ_GC, RCQUEST_MQ, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint", "Sheik Hint in MQ Ganons Castle"); - locationTable[RC_DAMPE_HINT] = Location::OtherHint(RC_DAMPE_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_GRAVEKEEPERS_HUT, "Diary Hint", "Dampe's Diary Hint"); - locationTable[RC_GREG_HINT] = Location::OtherHint(RC_GREG_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_EN_TAKARA_MAN, SCENE_TREASURE_BOX_SHOP, "Greg Hint", "Greg Hint"); - locationTable[RC_SARIA_SONG_HINT] = Location::OtherHint(RC_SARIA_SONG_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, "Sarias Song Hint", "Magic Hint Via Saria's Song"); - locationTable[RC_ALTAR_HINT_CHILD] = Location::OtherHint(RC_ALTAR_HINT_CHILD, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "Child Altar Hint", "ToT Child Altar Text"); - locationTable[RC_ALTAR_HINT_ADULT] = Location::OtherHint(RC_ALTAR_HINT_ADULT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "Adult Altar Hint", "ToT Adult Altar Text"); - locationTable[RC_FISHING_POLE_HINT] = Location::OtherHint(RC_FISHING_POLE_HINT,RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, "Fishing Pole Hint","Fishing Pole Hint"); + locationTable[RC_GANONDORF_HINT] = Location::OtherHint(RC_GANONDORF_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_GANON_MANT, SCENE_GANON_BOSS, "Ganondorf Hint", "Ganondorf Hint"); + locationTable[RC_SHEIK_HINT_GC] = Location::OtherHint(RC_SHEIK_HINT_GC, RCQUEST_VANILLA, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint", "Sheik Hint in Ganons Castle"); + locationTable[RC_SHEIK_HINT_MQ_GC] = Location::OtherHint(RC_SHEIK_HINT_MQ_GC, RCQUEST_MQ, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint", "Sheik Hint in MQ Ganons Castle"); + locationTable[RC_DAMPE_HINT] = Location::OtherHint(RC_DAMPE_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_GRAVEKEEPERS_HUT, "Diary Hint", "Dampe's Diary Hint"); + locationTable[RC_GREG_HINT] = Location::OtherHint(RC_GREG_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_EN_TAKARA_MAN, SCENE_TREASURE_BOX_SHOP, "Greg Hint", "Greg Hint"); + locationTable[RC_SARIA_SONG_HINT] = Location::OtherHint(RC_SARIA_SONG_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, "Sarias Song Hint", "Magic Hint Via Saria's Song"); + locationTable[RC_ALTAR_HINT_CHILD] = Location::OtherHint(RC_ALTAR_HINT_CHILD, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "Child Altar Hint", "ToT Child Altar Text"); + locationTable[RC_ALTAR_HINT_ADULT] = Location::OtherHint(RC_ALTAR_HINT_ADULT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "Adult Altar Hint", "ToT Adult Altar Text"); + locationTable[RC_FISHING_POLE_HINT] = Location::OtherHint(RC_FISHING_POLE_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, "Fishing Pole Hint", "Fishing Pole Hint"); - locationTable[RC_TRIFORCE_COMPLETED] = Location::Reward(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP); + locationTable[RC_TRIFORCE_COMPLETED] = Location::Reward(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP); // clang-format on } diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 2dc6d2271..8bf50387f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -419,11 +419,8 @@ bool HasItemBeenCollected(RandomizerCheck rc) { case SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE: return (gPlayState->sceneNum == scene && gPlayState->actorCtx.flags.collect & (1 << flag)) || gSaveContext.sceneFlags[scene].collect & (1 << flag); - case SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT: case SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM: - case SpoilerCollectionCheckType::SPOILER_CHK_COW: case SpoilerCollectionCheckType::SPOILER_CHK_FISH: - case SpoilerCollectionCheckType::SPOILER_CHK_SCRUB: case SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF: case SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD: return Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc)); @@ -437,8 +434,6 @@ bool HasItemBeenCollected(RandomizerCheck rc) { return gSaveContext.infTable[scene] & INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(flag); case SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF: return gSaveContext.itemGetInf[flag / 16] & INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(flag); - case SpoilerCollectionCheckType::SPOILER_CHK_MAGIC_BEANS: - return BEANS_BOUGHT >= 10; case SpoilerCollectionCheckType::SPOILER_CHK_NONE: return false; case SpoilerCollectionCheckType::SPOILER_CHK_GRAVEDIGGER: @@ -749,11 +744,8 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { Rando::SpoilerCollectionCheck scCheck = loc.GetCollectionCheck(); SpoilerCollectionCheckType scCheckType = scCheck.type; if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF && - (scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT || - scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM || - scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_COW || + (scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM || scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_FISH || - scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SCRUB || scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD || scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF)) { if (flag == OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(loc.GetRandomizerCheck())) { @@ -1343,6 +1335,11 @@ void DrawLocation(RandomizerCheck rc) { Rando::ItemLocation* itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); RandomizerCheckTrackerData checkData = gSaveContext.checkTrackerData[rc]; RandomizerCheckStatus status = checkData.status; + + if (itemLoc->HasObtained()) { + status = RCSHOW_COLLECTED; + } + bool skipped = checkData.skipped; if (status == RCSHOW_COLLECTED) { if (!showHidden && CVarGetInteger("gCheckTrackerCollectedHide", 0)) { @@ -1677,12 +1674,12 @@ void CheckTrackerWindow::InitElement() { GameInteractor::Instance->RegisterGameHook([](uint32_t fileNum) { Teardown(); }); - GameInteractor::Instance->RegisterGameHook(CheckTrackerItemReceive); + // GameInteractor::Instance->RegisterGameHook(CheckTrackerItemReceive); GameInteractor::Instance->RegisterGameHook(CheckTrackerFrame); GameInteractor::Instance->RegisterGameHook(CheckTrackerTransition); GameInteractor::Instance->RegisterGameHook(CheckTrackerShopSlotChange); - GameInteractor::Instance->RegisterGameHook(CheckTrackerSceneFlagSet); - GameInteractor::Instance->RegisterGameHook(CheckTrackerFlagSet); + // GameInteractor::Instance->RegisterGameHook(CheckTrackerSceneFlagSet); + // GameInteractor::Instance->RegisterGameHook(CheckTrackerFlagSet); hideShopRightChecks = CVarGetInteger("gCheckTrackerOptionHideRightShopChecks", 1); alwaysShowGS = CVarGetInteger("gCheckTrackerOptionAlwaysShowGSLocs", 0); diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c index fc2c651af..84e60bb23 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c @@ -461,34 +461,31 @@ void Entrance_SetWarpSongEntrance(void) { } void Entrance_OverrideBlueWarp(void) { - // Set nextEntranceIndex as a flag so that Grotto_CheckSpecialEntrance - // won't return index 0x7FFF, which can't work to override blue warps. - gPlayState->nextEntranceIndex = 0; + // Handles first time entering bluewarp (with item give) + switch (gSaveContext.entranceIndex) { + case ENTR_KOKIRI_FOREST_11: // Gohma blue warp + case ENTR_DEATH_MOUNTAIN_TRAIL_5: // KD blue warp + case ENTR_ZORAS_FOUNTAIN_0: // Barinade blue warp + case ENTR_SACRED_FOREST_MEADOW_3: // Phantom Ganon blue warp + case ENTR_DEATH_MOUNTAIN_CRATER_5: // Volvagia blue warp + case ENTR_LAKE_HYLIA_9: // Morpha blue warp + case ENTR_DESERT_COLOSSUS_8: // Bongo-Bongo blue warp + case ENTR_GRAVEYARD_8: // Twinrova blue warp + gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex); + return; + } - switch (gPlayState->sceneNum) { - case SCENE_DEKU_TREE_BOSS: // Ghoma boss room - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_KOKIRI_FOREST_11); - return; - case SCENE_DODONGOS_CAVERN_BOSS: // King Dodongo boss room - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DEATH_MOUNTAIN_TRAIL_5); - return; - case SCENE_JABU_JABU_BOSS: // Barinade boss room - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_ZORAS_FOUNTAIN_0); - return; - case SCENE_FOREST_TEMPLE_BOSS: // Phantom Ganon boss room - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_SACRED_FOREST_MEADOW_3); - return; - case SCENE_FIRE_TEMPLE_BOSS: // Volvagia boss room - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DEATH_MOUNTAIN_CRATER_5); - return; - case SCENE_WATER_TEMPLE_BOSS: // Morpha boss room - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_9); - return; - case SCENE_SPIRIT_TEMPLE_BOSS: // Twinrova boss room - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DESERT_COLOSSUS_8); - return; - case SCENE_SHADOW_TEMPLE_BOSS: // Bongo-Bongo boss room - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_GRAVEYARD_8); + // Handles second+ times entering bluewarp + switch (gPlayState->nextEntranceIndex) { + case ENTR_KOKIRI_FOREST_11: // Gohma blue warp + case ENTR_DEATH_MOUNTAIN_TRAIL_5: // KD blue warp + case ENTR_ZORAS_FOUNTAIN_0: // Barinade blue warp + case ENTR_SACRED_FOREST_MEADOW_3: // Phantom Ganon blue warp + case ENTR_DEATH_MOUNTAIN_CRATER_5: // Volvagia blue warp + case ENTR_LAKE_HYLIA_9: // Morpha blue warp + case ENTR_DESERT_COLOSSUS_8: // Bongo-Bongo blue warp + case ENTR_GRAVEYARD_8: // Twinrova blue warp + gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(gPlayState->nextEntranceIndex); return; } } diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index c61f933bf..31ca0a805 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -143,12 +143,15 @@ typedef enum { RAND_INF_MERCHANTS_CARPET_SALESMAN, RAND_INF_MERCHANTS_MEDIGORON, RAND_INF_MERCHANTS_GRANNYS_SHOP, + RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN, RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO, RAND_INF_ADULT_TRADES_GV_TRADE_SAW, RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD, + RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION, RAND_INF_ADULT_TRADES_LH_TRADE_FROG, RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS, + RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD, @@ -267,6 +270,13 @@ typedef enum { RAND_INF_ZD_FISH_4, RAND_INF_ZD_FISH_5, + RAND_INF_LINKS_POCKET, + RAND_INF_LEARNED_EPONA_SONG, + RAND_INF_DARUNIAS_JOY, + RAND_INF_KING_ZORA_THAWED, + RAND_INF_ROLLING_GORON_AS_CHILD, + RAND_INF_ROLLING_GORON_AS_ADULT, + // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) RAND_INF_MAX, diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index d3c2d535b..19ef26ac0 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -97,6 +97,9 @@ void GiveLinksPocketItem() { if (Randomizer_GetSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, (GetItemID)RG_NONE); StartingItemGive(getItemEntry); + Rando::Context::GetInstance()->GetItemLocation(RC_LINKS_POCKET)->MarkAsObtained(); + // If we re-add the above, we'll get the item on save creation, now it's given on first load + Flags_SetRandomizerInf(RAND_INF_LINKS_POCKET); } } @@ -202,40 +205,42 @@ void SetStartingItems() { } extern "C" void Randomizer_InitSaveFile() { - // Sets all rando flags to false - for (s32 i = 0; i < ARRAY_COUNT(gSaveContext.randomizerInf); i++) { - gSaveContext.randomizerInf[i] = 0; - } + // Now handled by cutscene skips + // gSaveContext.cutsceneIndex = 0; // no intro cutscene + // Starts pending ice traps out at 0 before potentially incrementing them down the line. + gSaveContext.pendingIceTrapCount = 0; // Reset triforce pieces collected gSaveContext.triforcePiecesCollected = 0; - gSaveContext.cutsceneIndex = 0; // no intro cutscene - // Starts pending ice traps out at 0 before potentially incrementing them down the line. - gSaveContext.pendingIceTrapCount = 0; - // Set Cutscene flags and texts to skip them - Flags_SetInfTable(INFTABLE_GREETED_BY_SARIA); + // Now handled by cutscene skips + // Flags_SetInfTable(INFTABLE_GREETED_BY_SARIA); Flags_SetEventChkInf(EVENTCHKINF_FIRST_SPOKE_TO_MIDO); - Flags_SetEventChkInf(EVENTCHKINF_MET_DEKU_TREE); - Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH); + // Now handled by cutscene skips + // Flags_SetEventChkInf(EVENTCHKINF_MET_DEKU_TREE); + // Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH); Flags_SetInfTable(INFTABLE_SPOKE_TO_KAEPORA_IN_LAKE_HYLIA); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER); - Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); + // Now handled by cutscene skips + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER); + // Now using this to grant master sword check + // Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); Flags_SetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL); - Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + // Now used to give player LACS rewards + // Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); Flags_SetEventChkInf(EVENTCHKINF_RENTED_HORSE_FROM_INGO); Flags_SetInfTable(INFTABLE_SPOKE_TO_POE_COLLECTOR_IN_RUINED_MARKET); Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_NABOORU_IN_SPIRIT_TEMPLE); - Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET); - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET); - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_INGO_AT_RANCH_BEFORE_TALON_RETURNS); - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_RANCH); - Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON); - Flags_SetInfTable(INFTABLE_CHILD_MALON_SAID_EPONA_WAS_AFRAID_OF_YOU); - Flags_SetInfTable(INFTABLE_SPOKE_TO_INGO_ONCE_AS_ADULT); + // Now handled by cutscene skips + // Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET); + // Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET); + // Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_INGO_AT_RANCH_BEFORE_TALON_RETURNS); + // Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_RANCH); + // Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON); + // Flags_SetInfTable(INFTABLE_CHILD_MALON_SAID_EPONA_WAS_AFRAID_OF_YOU); + // Flags_SetInfTable(INFTABLE_SPOKE_TO_INGO_ONCE_AS_ADULT); // Ruto already met in jabu and spawns down the hole immediately Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO); @@ -246,51 +251,55 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_NABOORU_BATTLE); Flags_SetEventChkInf(EVENTCHKINF_NABOORU_ORDERED_TO_FIGHT_BY_TWINROVA); + // Now handled by cutscene skips // Skip boss cutscenes - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE); - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE); - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE); - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE); - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE); - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE); - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE); - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE); - // Entered areas - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_FIELD); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_TRAIL); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_KAKARIKO_VILLAGE); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_DOMAIN); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_CASTLE); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GORON_CITY); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_TEMPLE_OF_TIME); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEKU_TREE); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LAKE_HYLIA); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDO_VALLEY); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDOS_FORTRESS); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LON_LON_RANCH); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_JABU_JABUS_BELLY); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GRAVEYARD); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_FOUNTAIN); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DESERT_COLOSSUS); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_CRATER); - Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GANONS_CASTLE_EXTERIOR); - Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); + // Now handled by cutscene skips + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_FIELD); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_TRAIL); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_KAKARIKO_VILLAGE); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_DOMAIN); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_CASTLE); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GORON_CITY); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_TEMPLE_OF_TIME); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEKU_TREE); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LAKE_HYLIA); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDO_VALLEY); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDOS_FORTRESS); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LON_LON_RANCH); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_JABU_JABUS_BELLY); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GRAVEYARD); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_FOUNTAIN); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DESERT_COLOSSUS); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_CRATER); + // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GANONS_CASTLE_EXTERIOR); + // Ensure Malon appears at castle first time you enter + // Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); // skip the z target talk instructions by the kokiri shop - gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 0x1F); + // Now handled by cutscene skips + // gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 0x1F); // Go away ruto (water temple first cutscene) gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10); + // Now handled by cutscene skips // no more kaepora - gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xC); // hyrule field kaepora outside kokiri forest - gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xB); // hyrule field kaepora outside lake hylia - gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x7); // lost woods kaepora pre-saria - gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x8); // lost woods kaepora post-saria - gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 0x1F); // desert colossus kaepora - gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= (1 << 0x5); // hyrule castle kaepora + // gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xC); // hyrule field kaepora outside kokiri forest + // gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xB); // hyrule field kaepora outside lake hylia + // gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x7); // lost woods kaepora pre-saria + // gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x8); // lost woods kaepora post-saria + // gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 0x1F); // desert colossus kaepora + // gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= (1 << 0x5); // hyrule castle kaepora if (!Randomizer_GetSettingValue(RSK_ENABLE_GLITCH_CUTSCENES)) { Flags_SetInfTable(INFTABLE_SPOKE_TO_DARUNIA_IN_FIRE_TEMPLE); // Darunia in Fire Temple @@ -398,15 +407,16 @@ extern "C" void Randomizer_InitSaveFile() { gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x15); } - int openForest = Randomizer_GetSettingValue(RSK_FOREST); - switch (openForest) { - case RO_FOREST_OPEN: - Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); - // Fallthrough - case RO_FOREST_CLOSED_DEKU: - Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); - break; - } + // Now handled on the fly + // int openForest = Randomizer_GetSettingValue(RSK_FOREST); + // switch (openForest) { + // case RO_FOREST_OPEN: + // Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); + // // Fallthrough + // case RO_FOREST_CLOSED_DEKU: + // Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); + // break; + // } int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME); switch (doorOfTime) { diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp new file mode 100644 index 000000000..cd34e5608 --- /dev/null +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -0,0 +1,788 @@ +#include +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" + +extern "C" { +#include "src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.h" +#include "src/overlays/actors/ovl_Elf_Msg/z_elf_msg.h" +#include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h" +#include "src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.h" +#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" +#include "src/overlays/actors/ovl_En_Owl/z_en_owl.h" +#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h" +#include "src/overlays/actors/ovl_En_Ma1/z_en_ma1.h" +#include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h" +#include "src/overlays/actors/ovl_Demo_Im/z_demo_im.h" +#include "src/overlays/actors/ovl_En_Sa/z_en_sa.h" +#include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h" +#include "src/overlays/actors/ovl_En_Tk/z_en_tk.h" +extern SaveContext gSaveContext; +extern PlayState* gPlayState; +} + +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() + +void EnKo_MoveWhenReady(EnKo* enKo, PlayState* play) { + func_80A995CC(enKo, play); + + if ((enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3) { + // Typically this doesn't get get live updated in vanilla, but we need to + // live update it if we're skipping a certain cutscene or in randomizer + if (GameInteractor_Should(GI_VB_OPEN_KOKIRI_FOREST, CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD), NULL)) { + enKo->collider.dim.height -= 200; + Path_CopyLastPoint(enKo->path, &enKo->actor.world.pos); + enKo->actionFunc = func_80A99384; + } + } +} + +void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) { + if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) { + Flags_SetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG); + func_80078884(NA_SE_SY_CORRECT_CHIME); + enMa1->actor.flags &= ~ACTOR_FLAG_WILL_TALK; + play->msgCtx.ocarinaMode = OCARINA_MODE_04; + enMa1->actionFunc = func_80AA0D88; + enMa1->unk_1E0 = 1; + enMa1->interactInfo.talkState = NPC_TALK_STATE_IDLE; + return; + } +} + +u16 EnZl4_GiveItemTextId(PlayState* play, Actor* actor) { + return 0x207D; +} + +void EnZl4_SkipToGivingZeldasLetter(EnZl4* enZl4, PlayState* play) { + if (enZl4->csState == 0 && enZl4->actor.xzDistToPlayer < 600.0f && EnZl4_SetNextAnim(enZl4, 3)) { + Audio_PlayFanfare(NA_BGM_APPEAR); + enZl4->csState = 8; // ZL4_CS_PLAN + } else { + Npc_UpdateTalking(play, &enZl4->actor, &enZl4->interactInfo.talkState, enZl4->collider.dim.radius + 60.0f, EnZl4_GiveItemTextId, func_80B5B9B0); + func_80B5BB78(enZl4, play); + + if (enZl4->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + enZl4->talkState = 6; + enZl4->actionFunc = EnZl4_Cutscene; + } + } +} + +static int successChimeCooldown = 0; +void RateLimitedSuccessChime() { + if (successChimeCooldown == 0) { + func_80078884(NA_SE_SY_CORRECT_CHIME); + successChimeCooldown = 120; + } +} + +void TimeSaverOnGameFrameUpdateHandler() { + if (successChimeCooldown > 0) { + successChimeCooldown--; + } +} + +void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* opt) { + switch (id) { + case GI_VB_PLAY_TRANSITION_CS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.Intro", 0) && gSaveContext.entranceIndex == ENTR_LINKS_HOUSE_0 && gSaveContext.cutsceneIndex == 0xFFF1) { + gSaveContext.cutsceneIndex = 0; + *should = false; + } + + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + // Song of Time + if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 && gSaveContext.cutsceneIndex == 0xFFF7) { + gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_16; + gSaveContext.cutsceneIndex = 0; + gSaveContext.nextTransitionType = 3; + *should = false; + } + + // Requiem of Spirit + if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); + // Normally happens in the cutscene + if (GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) { + Item_Give(gPlayState, ITEM_SONG_REQUIEM); + } + *should = false; + } + + u8 meetsBurningKakRequirements = + LINK_IS_ADULT && + gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && + Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) && + !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); + if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, meetsBurningKakRequirements, NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); + // Normally happens in the cutscene + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_NOCTURNE_OF_SHADOW); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) { + Item_Give(gPlayState, ITEM_SONG_NOCTURNE); + } + *should = false; + } + } + + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + uint8_t isBlueWarp = 0; + // Deku Tree Blue warp + if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) { + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; + + gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_11; + isBlueWarp = 1; + // Dodongo's Cavern Blue warp + } else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_0 && gSaveContext.cutsceneIndex == 0xFFF1) { + gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; + isBlueWarp = 1; + // Jabu Jabu's Blue warp + } else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_0 && gSaveContext.cutsceneIndex == 0xFFF0) { + gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_0; + isBlueWarp = 1; + // Forest Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) { + // Normally set in the blue warp cutscene + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT); + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; + + gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + isBlueWarp = 1; + // Fire Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && gSaveContext.cutsceneIndex == 0xFFF3) { + gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; + isBlueWarp = 1; + // Water Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) { + gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_9; + isBlueWarp = 1; + // Spirit Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) { + gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_8; + isBlueWarp = 1; + // Shadow Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) { + gSaveContext.entranceIndex = ENTR_GRAVEYARD_8; + isBlueWarp = 1; + } + + if (isBlueWarp) { + *should = false; + gSaveContext.cutsceneIndex = 0; + + if (IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { + Entrance_OverrideBlueWarp(); + } + } + + // Flee hyrule castle cutscene + if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_0 && gSaveContext.cutsceneIndex == 0xFFF1) { + gSaveContext.cutsceneIndex = 0; + *should = false; + } + + // Lost Woods Bridge + if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FAIRY_OCARINA, true, NULL)) { + Item_Give(gPlayState, ITEM_OCARINA_FAIRY); + } + *should = false; + } + + // LACS + u8 meetsLACSRequirements = + LINK_IS_ADULT && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && + !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, meetsLACSRequirements, NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_LIGHT_ARROW, true, NULL)) { + Item_Give(gPlayState, ITEM_ARROW_LIGHT); + } + *should = false; + } + } + break; + case GI_VB_PLAY_ENTRANCE_CS: { + s32* entranceFlag = static_cast(opt); + if (CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", 0) && (*entranceFlag != EVENTCHKINF_EPONA_OBTAINED)) { + *should = false; + } + break; + } + case GI_VB_PLAY_ONEPOINT_CS: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", 0)) { + s16* csId = static_cast(opt); + switch (*csId) { + case 4180: + case 4100: + *should = false; + RateLimitedSuccessChime(); + break; + default: + SPDLOG_INFO("GI_VB_PLAY_ONEPOINT_CS {}", *csId); + break; + } + } + break; + } + case GI_VB_PLAY_ONEPOINT_ACTOR_CS: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", 0)) { + Actor* actor = static_cast(opt); + switch (actor->category) { + case ACTORCAT_BG: + if (actor->id == ACTOR_BG_DDAN_KD) { + BgDdanKd* ddanKd = static_cast(opt); + Flags_SetSwitch(gPlayState, ddanKd->dyna.actor.params); + } + if (actor->id == ACTOR_BG_MORI_HINERI) { + break; + } + + RateLimitedSuccessChime(); + *should = false; + break; + } + switch (actor->id) { + case ACTOR_OBJ_SWITCH: { + ObjSwitch *switchActor = static_cast(opt); + switchActor->cooldownTimer = 0; + *should = false; + RateLimitedSuccessChime(); + break; + } + case ACTOR_BG_BDAN_SWITCH: { + BgBdanSwitch* switchActor = static_cast(opt); + switchActor->unk_1D8 = 0; + switchActor->unk_1DA = 0; + *should = false; + RateLimitedSuccessChime(); + break; + } + // case ACTOR_PLAYER: // This might cause issues + case ACTOR_EN_TA: + case ACTOR_DOOR_SHUTTER: + case ACTOR_EN_BOX: + case ACTOR_OBJ_SYOKUDAI: + case ACTOR_OBJ_TIMEBLOCK: + case ACTOR_EN_PO_SISTERS: + // Prop + case ACTOR_OBJ_ICE_POLY: + case ACTOR_BG_YDAN_MARUTA: + case ACTOR_BG_SPOT18_SHUTTER: + case ACTOR_BG_SPOT05_SOKO: + case ACTOR_BG_SPOT18_BASKET: + // BG + // case ACTOR_BG_YDAN_SP: + // case ACTOR_BG_YDAN_HASI: + // case ACTOR_BG_DODOAGO: + // case ACTOR_BG_DDAN_KD: + // case ACTOR_BG_DDAN_JD: + *should = false; + RateLimitedSuccessChime(); + break; + } + if (*should) { + SPDLOG_INFO("GI_VB_PLAY_ONEPOINT_ACTOR_CS ID:{} Cat:{}", actor->id, actor->category); + } + } + break; + } + case GI_VB_SHOW_TITLE_CARD: + if (CVarGetInteger("gTimeSavers.DisableTitleCard", 0)) { + *should = false; + } + break; + case GI_VB_WONDER_TALK: { + if (CVarGetInteger("gTimeSavers.NoForcedDialog", 0)) { + *should = false; + } + break; + } + case GI_VB_NAVI_TALK: { + if (CVarGetInteger("gTimeSavers.NoForcedDialog", 0)) { + ElfMsg* naviTalk = static_cast(opt); + Flags_SetSwitch(gPlayState, (naviTalk->actor.params >> 8) & 0x3F); + Actor_Kill(&naviTalk->actor); + *should = false; + } + break; + } + case GI_VB_NOT_BE_GREETED_BY_SARIA: + if (CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", 0) && !Flags_GetInfTable(INFTABLE_GREETED_BY_SARIA)) { + Flags_SetInfTable(INFTABLE_GREETED_BY_SARIA); + *should = true; + } + break; + case GI_VB_MOVE_MIDO_IN_KOKIRI_FOREST: + if ( + CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) && + !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && + (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) && + (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) + ) { + Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); + *should = true; + } + break; + case GI_VB_PLAY_DEKU_TREE_INTRO_CS: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + BgTreemouth* treeMouth = static_cast(opt); + Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH); + Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + BgTreemouth_SetupAction(treeMouth, func_808BC6F8); + *should = false; + } + break; + } + case GI_VB_GIVE_ITEM_FROM_BLUE_WARP: + case GI_VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS: + case GI_VB_GIVE_ITEM_FAIRY_OCARINA: + case GI_VB_GIVE_ITEM_LIGHT_ARROW: + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + *should = false; + } + break; + case GI_VB_PLAY_NABOORU_CAPTURED_CS: + if (*should == true && CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + Flags_SetEventChkInf(EVENTCHKINF_NABOORU_CAPTURED_BY_TWINROVA); + *should = false; + } + break; + case GI_VB_PLAY_PULL_MASTER_SWORD_CS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL)) { + // Normally, these would be done in the cutscene, but we're skipping it + Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); + Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER); + Flags_SetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL); + Flags_SetEventChkInf(EVENTCHKINF_TIME_TRAVELED_TO_ADULT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_LIGHT_MEDALLION, true, NULL)) { + Item_Give(gPlayState, ITEM_MEDALLION_LIGHT); + } + } + *should = false; + } + break; + case GI_VB_OWL_INTERACTION: { + if (CVarGetInteger("gTimeSavers.SkipOwlInteractions", 0) && *should) { + EnOwl* enOwl = static_cast(opt); + s32 owlType = (enOwl->actor.params & 0xFC0) >> 6; + + if (((enOwl->actor.params & 0xFC0) >> 6) == 1) { + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_KAEPORA_BY_LOST_WOODS); + } + + func_80ACA62C(enOwl, gPlayState); + *should = false; + } + break; + } + case GI_VB_PLAY_EYEDROP_CREATION_ANIM: + case GI_VB_PLAY_EYEDROPS_CS: + case GI_VB_PLAY_DROP_FISH_FOR_JABU_CS: + case GI_VB_PLAY_DARUNIAS_JOY_CS: + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + *should = false; + } + break; + case GI_VB_PLAY_ZELDAS_LULLABY_CS: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + DemoIm* demoIm = static_cast(opt); + Player* player = GET_PLAYER(gPlayState); + player->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; + player->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM; + func_80986794(demoIm); + + static uint32_t demoImUpdateHook = 0; + static uint32_t demoImKillHook = 0; + demoImUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* actorRef) mutable { + Actor* actor = static_cast(actorRef); + if (actor->id == ACTOR_DEMO_IM && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) { + DemoIm* demoIm = static_cast(actorRef); + Player* player = GET_PLAYER(gPlayState); + player->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; + player->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM; + + if (Animation_OnFrame(&demoIm->skelAnime, 25.0f)) { + Audio_PlaySoundGeneral(NA_SE_IT_DEKU, &demoIm->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + GameInteractor::Instance->UnregisterGameHook(demoImUpdateHook); + GameInteractor::Instance->UnregisterGameHook(demoImKillHook); + demoImUpdateHook = 0; + demoImKillHook = 0; + } else if (Animation_OnFrame(&demoIm->skelAnime, 15.0f)) { + Player* player = GET_PLAYER(gPlayState); + // SOH [Randomizer] In entrance rando have impa bring link back to the front of castle grounds + if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) { + gPlayState->nextEntranceIndex = ENTR_HYRULE_CASTLE_0; + } else { + gPlayState->nextEntranceIndex = ENTR_HYRULE_FIELD_17; + } + gPlayState->transitionType = TRANS_TYPE_FADE_WHITE; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gSaveContext.nextTransitionType = 2; + func_8002DF54(gPlayState, &player->actor, 8); + } + } + }); + demoImKillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(demoImUpdateHook); + GameInteractor::Instance->UnregisterGameHook(demoImKillHook); + demoImUpdateHook = 0; + demoImKillHook = 0; + }); + *should = false; + } + break; + } + case GI_VB_PLAY_SARIAS_SONG_CS: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + EnSa* enSa = static_cast(opt); + enSa->actionFunc = func_80AF6B20; + *should = false; + } + break; + } + case GI_VB_DESPAWN_HORSE_RACE_COW: { + if (Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE) && CVarGetInteger("gCowOfTime", 0)) { + *should = false; + } + break; + } + case GI_VB_GIVE_ITEM_MINUET_OF_FOREST: + case GI_VB_GIVE_ITEM_BOLERO_OF_FIRE: + case GI_VB_GIVE_ITEM_SERENADE_OF_WATER: + case GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT: + case GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW: + case GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT: + case GI_VB_GIVE_ITEM_ZELDAS_LULLABY: + case GI_VB_GIVE_ITEM_EPONAS_SONG: + case GI_VB_GIVE_ITEM_SARIAS_SONG: + case GI_VB_GIVE_ITEM_SUNS_SONG: + case GI_VB_GIVE_ITEM_SONG_OF_TIME: + case GI_VB_GIVE_ITEM_SONG_OF_STORMS: + case GI_VB_PLAY_MINUET_OF_FOREST_CS: + case GI_VB_PLAY_BOLERO_OF_FIRE_CS: + case GI_VB_PLAY_SERENADE_OF_WATER_CS: + case GI_VB_PLAY_PRELUDE_OF_LIGHT_CS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + *should = false; + } + break; + case GI_VB_DAMPE_IN_GRAVEYARD_DESPAWN: + if (CVarGetInteger("gDampeAllNight", 0)) { + *should = LINK_IS_ADULT || gPlayState->sceneNum != SCENE_GRAVEYARD; + } + break; + case GI_VB_BE_VALID_GRAVEDIGGING_SPOT: + if (CVarGetInteger("gDampeWin", 0)) { + EnTk *enTk = static_cast(opt); + enTk->validDigHere = true; + *should = true; + } + break; + case GI_VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE: + if (CVarGetInteger("gDampeWin", 0)) { + EnTk *enTk = static_cast(opt); + enTk->currentReward = 3; + *should = true; + } + break; + case GI_VB_DAMPE_GRAVEDIGGING_GRAND_PRIZE_BE_HEART_PIECE: + if (CVarGetInteger("gGravediggingTourFix", 0) || IS_RANDO) { + *should = !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE); + } + break; + case GI_VB_FIX_SAW_SOFTLOCK: + // Animation Count should be no more than 1 to guarantee putaway is complete after giving the saw + // As this is vanilla behavior, it only applies with the Fix toggle or Skip Text enabled. + *should = (CVarGetInteger("gFixSawSoftlock", 0) != 0 || CVarGetInteger("gSkipText", 0) != 0) ? gPlayState->animationCtx.animationCount > 1 : *should; + break; + case GI_VB_BIGGORON_CONSIDER_SWORD_FORGED: + *should = Environment_GetBgsDayCount() >= CVarGetInteger("gForgeTime", 3); + break; + } +} + +static uint32_t enKoUpdateHook = 0; +static uint32_t enKoKillHook = 0; +static uint32_t itemOcarinaUpdateHook = 0; +static uint32_t itemOcarinaframesSinceSpawn = 0; +static uint32_t enMa1UpdateHook = 0; +static uint32_t enMa1KillHook = 0; +void TimeSaverOnActorInitHandler(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id == ACTOR_EN_KO && (actor->params & 0xFF) == ENKO_TYPE_CHILD_3) { + enKoUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_EN_KO && (innerActor->params & 0xFF) == ENKO_TYPE_CHILD_3 && (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0) || IS_RANDO)) { + EnKo* enKo = static_cast(innerActorRef); + // They haven't moved yet, wrap their update function so we check every frame + if (enKo->actionFunc == func_80A995CC) { + enKo->actionFunc = EnKo_MoveWhenReady; + GameInteractor::Instance->UnregisterGameHook(enKoUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enKoKillHook); + enKoUpdateHook = 0; + enKoKillHook = 0; + // They have already moved + } else if (enKo->actionFunc == func_80A99384) { + GameInteractor::Instance->UnregisterGameHook(enKoUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enKoKillHook); + enKoUpdateHook = 0; + enKoKillHook = 0; + } + } + }); + enKoKillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(enKoUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enKoKillHook); + enKoUpdateHook = 0; + enKoKillHook = 0; + }); + } + + if (actor->id == ACTOR_ITEM_OCARINA && actor->params == 3 && CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + itemOcarinaframesSinceSpawn = 0; + itemOcarinaUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id != ACTOR_ITEM_OCARINA || innerActor->params != 3) return; + itemOcarinaframesSinceSpawn++; + if (itemOcarinaframesSinceSpawn > 20) { + Audio_PlayActorSound2(innerActor, NA_SE_EV_BOMB_DROP_WATER); + + GameInteractor::Instance->UnregisterGameHook(itemOcarinaUpdateHook); + itemOcarinaUpdateHook = 0; + } + }); + } + + if (actor->id == ACTOR_EN_MA1 && gPlayState->sceneNum == SCENE_LON_LON_RANCH) { + enMa1UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_EN_MA1 && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) { + EnMa1* enMa1 = static_cast(innerActorRef); + if (enMa1->actionFunc == func_80AA106C) { + enMa1->actionFunc = EnMa1_EndTeachSong; + GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); + GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); + enMa1UpdateHook = 0; + enMa1KillHook = 0; + // They've already learned the song + } else if (enMa1->actionFunc == func_80AA0D88) { + GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); + GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); + enMa1UpdateHook = 0; + enMa1KillHook = 0; + } + } + }); + enMa1KillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); + GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); + enMa1UpdateHook = 0; + enMa1KillHook = 0; + }); + } + + if (actor->id == ACTOR_EN_ZL4 && CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + EnZl4* enZl4 = static_cast(actorRef); + if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0) return; + + enZl4->actionFunc = EnZl4_SkipToGivingZeldasLetter; + } +} + +void TimeSaverOnSceneInitHandler(int16_t sceneNum) { + switch (sceneNum) { + case SCENE_HYRULE_CASTLE: + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) && !Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { + Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); + Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET); + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET); + } + break; + case SCENE_LON_LON_RANCH: + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) && GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_RANCH); + Flags_SetInfTable(INFTABLE_CHILD_MALON_SAID_EPONA_WAS_AFRAID_OF_YOU); + Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON); + } + break; + case SCENE_DEKU_TREE_BOSS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE); + } + } + break; + case SCENE_DODONGOS_CAVERN_BOSS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE); + } + } + break; + case SCENE_JABU_JABU_BOSS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE); + } + } + break; + } +} + +static GetItemEntry vanillaQueuedItemEntry = GET_ITEM_NONE; + +void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { + if (!CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) return; + + switch (flagType) { + case FLAG_EVENT_CHECK_INF: + switch (flag) { + case EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FAIRY_OCARINA).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_ZELDAS_LULLABY: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_ZELDAS_LULLABY).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_MINUET_OF_FOREST: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MINUET_OF_FOREST).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_BOLERO_OF_FIRE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_BOLERO_OF_FIRE).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_SERENADE_OF_WATER: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SERENADE_OF_WATER).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_REQUIEM_OF_SPIRIT).GetGIEntry_Copy(); + break; + case EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_NOCTURNE_OF_SHADOW).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_PRELUDE_OF_LIGHT).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_SARIAS_SONG: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SARIAS_SONG).GetGIEntry_Copy(); + break; + case EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_KOKIRI_EMERALD).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_GORON_RUBY).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_ZORA_SAPPHIRE).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FOREST_MEDALLION).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FIRE_MEDALLION).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_WATER_MEDALLION).GetGIEntry_Copy(); + break; + case EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_LIGHT_ARROWS).GetGIEntry_Copy(); + break; + case EVENTCHKINF_TIME_TRAVELED_TO_ADULT: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_LIGHT_MEDALLION).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_SONG_OF_TIME: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_TIME).GetGIEntry_Copy(); + break; + } + break; + case FLAG_RANDOMIZER_INF: + switch (flag) { + case RAND_INF_LEARNED_EPONA_SONG: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_EPONAS_SONG).GetGIEntry_Copy(); + break; + case RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SHADOW_MEDALLION).GetGIEntry_Copy(); + break; + case RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SPIRIT_MEDALLION).GetGIEntry_Copy(); + break; + } + break; + } +} + +void TimeSaverOnPlayerUpdateHandler() { + if (vanillaQueuedItemEntry.itemId == ITEM_NONE) return; + + Player* player = GET_PLAYER(gPlayState); + if (player == NULL || Player_InBlockingCsMode(gPlayState, player) || player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) { + return; + } + + SPDLOG_INFO("Attempting to give Item: mod {} item {}", vanillaQueuedItemEntry.modIndex, vanillaQueuedItemEntry.itemId); + GiveItemEntryWithoutActor(gPlayState, vanillaQueuedItemEntry); + if (player->stateFlags1 & PLAYER_STATE1_IN_WATER) { + // Allow the player to receive the item while swimming + player->stateFlags2 |= PLAYER_STATE2_UNDERWATER; + func_8083E5A8(player, gPlayState); + } +} + +void TimeSaverOnItemReceiveHandler(GetItemEntry receivedItemEntry) { + if (vanillaQueuedItemEntry.itemId == ITEM_NONE) return; + + if (vanillaQueuedItemEntry.modIndex == receivedItemEntry.modIndex && vanillaQueuedItemEntry.itemId == receivedItemEntry.itemId) { + SPDLOG_INFO("Item received: mod {} item {}", receivedItemEntry.modIndex, receivedItemEntry.itemId); + vanillaQueuedItemEntry = GET_ITEM_NONE; + } +} + +static uint32_t onSceneInitHook = 0; +static uint32_t onVanillaBehaviorHook = 0; +static uint32_t onActorInitHook = 0; +static uint32_t onGameFrameUpdate = 0; +static uint32_t onFlagSetHook = 0; +static uint32_t onPlayerUpdateHook = 0; +static uint32_t onItemReceiveHook = 0; +void TimeSaverRegisterHooks() { + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) mutable { + vanillaQueuedItemEntry = GET_ITEM_NONE; + + GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); + GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); + GameInteractor::Instance->UnregisterGameHook(onActorInitHook); + GameInteractor::Instance->UnregisterGameHook(onGameFrameUpdate); + GameInteractor::Instance->UnregisterGameHook(onFlagSetHook); + GameInteractor::Instance->UnregisterGameHook(onPlayerUpdateHook); + GameInteractor::Instance->UnregisterGameHook(onItemReceiveHook); + + onSceneInitHook = 0; + onVanillaBehaviorHook = 0; + onActorInitHook = 0; + onGameFrameUpdate = 0; + onFlagSetHook = 0; + onPlayerUpdateHook = 0; + onItemReceiveHook = 0; + + onSceneInitHook = GameInteractor::Instance->RegisterGameHook(TimeSaverOnSceneInitHandler); + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(TimeSaverOnVanillaBehaviorHandler); + onActorInitHook = GameInteractor::Instance->RegisterGameHook(TimeSaverOnActorInitHandler); + onGameFrameUpdate = GameInteractor::Instance->RegisterGameHook(TimeSaverOnGameFrameUpdateHandler); + + if (IS_RANDO) return; + + onFlagSetHook = GameInteractor::Instance->RegisterGameHook(TimeSaverOnFlagSetHandler); + onPlayerUpdateHook = GameInteractor::Instance->RegisterGameHook(TimeSaverOnPlayerUpdateHandler); + onItemReceiveHook = GameInteractor::Instance->RegisterGameHook(TimeSaverOnItemReceiveHandler); + }); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.h b/soh/soh/Enhancements/timesaver_hook_handlers.h new file mode 100644 index 000000000..41bccd8d9 --- /dev/null +++ b/soh/soh/Enhancements/timesaver_hook_handlers.h @@ -0,0 +1,6 @@ +#ifndef TIMESAVER_HOOK_HANDLERS_H +#define TIMESAVER_HOOK_HANDLERS_H + +void TimeSaverRegisterHooks(); + +#endif // TIMESAVER_HOOK_HANDLERS_H \ No newline at end of file diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 38da2015b..334b99949 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -122,6 +122,10 @@ GameInteractorSail* GameInteractorSail::Instance; #include "soh/config/ConfigUpdaters.h" +extern "C" { +#include "src/overlays/actors/ovl_En_Dns/z_en_dns.h" +} + void SoH_ProcessDroppedFiles(std::string filePath); OTRGlobals* OTRGlobals::Instance; @@ -2567,9 +2571,9 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { } else if (textId == TEXT_SHEIK_NEED_HOOK || textId == TEXT_SHEIK_HAVE_HOOK) { messageEntry = OTRGlobals::Instance->gRandomizer->GetSheikMessage(gPlayState->sceneNum, textId); // textId: TEXT_SCRUB_RANDOM + (randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT) - } else if (textId >= TEXT_SCRUB_RANDOM && textId <= TEXT_SCRUB_RANDOM + NUM_SCRUBS) { - RandomizerInf randoInf = (RandomizerInf)((textId - TEXT_SCRUB_RANDOM) + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT); - messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, TEXT_SCRUB_RANDOM, Randomizer_GetSettingValue(RSK_SCRUB_TEXT_HINT) == RO_GENERIC_OFF); + } else if (textId == TEXT_SCRUB_RANDOM) { + EnDns* enDns = (EnDns*)GET_PLAYER(play)->targetActor; + messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(enDns->sohScrubIdentity.randomizerInf, TEXT_SCRUB_RANDOM, Randomizer_GetSettingValue(RSK_SCRUB_TEXT_HINT) == RO_GENERIC_OFF); // Shop items each have two message entries, second one offset by NUM_SHOP_ITEMS // textId: TEXT_SHOP_ITEM_RANDOM + (randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) // textId: TEXT_SHOP_ITEM_RANDOM + ((randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) + NUM_SHOP_ITEMS) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index daae87146..e42e16b3f 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -351,6 +351,13 @@ void SaveManager::LoadRandomizerVersion3() { // all ItemLocations is 0 anyway. randoContext->GetItemLocation(i)->SetCustomPrice(price); } + uint16_t obtained = 0; + SaveManager::Instance->LoadData("obtained", obtained, (uint16_t)0); + if (obtained) { + randoContext->GetItemLocation(i)->MarkAsObtained(); + } else { + randoContext->GetItemLocation(i)->MarkAsNotObtained(); + } }); }); @@ -449,6 +456,7 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f if (randoContext->GetItemLocation(i)->HasCustomPrice()) { SaveManager::Instance->SaveData("price", randoContext->GetItemLocation(i)->GetPrice()); } + SaveManager::Instance->SaveData("obtained", randoContext->GetItemLocation(i)->HasObtained()); }); }); @@ -727,6 +735,9 @@ void SaveManager::InitFileNormal() { for (int flag = 0; flag < ARRAY_COUNT(gSaveContext.infTable); flag++) { gSaveContext.infTable[flag] = 0; } + for (int flag = 0; flag < ARRAY_COUNT(gSaveContext.randomizerInf); flag++) { + gSaveContext.randomizerInf[flag] = 0; + } gSaveContext.worldMapAreaData = 0; gSaveContext.scarecrowLongSongSet = 0; for (int i = 0; i < ARRAY_COUNT(gSaveContext.scarecrowLongSong); i++) { diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 56e12e53e..2ec571e26 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -69,6 +69,7 @@ static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large }; static const char* chestStyleMatchesContentsOptions[4] = { "Disabled", "Both", "Texture Only", "Size Only" }; + static const char* skipGetItemAnimationOptions[3] = { "Disabled", "Junk Items", "All Items" }; static const char* bunnyHoodOptions[3] = { "Disabled", "Faster Run & Longer Jump", "Faster Run" }; static const char* mirroredWorldModes[9] = { "Disabled", "Always", "Random", "Random (Seeded)", "Dungeons", @@ -555,6 +556,83 @@ void DrawEnhancementsMenu() { UIWidgets::Spacer(0); ImGui::Text("Speed-ups:"); UIWidgets::PaddedSeparator(); + bool allChecked = + CVarGetInteger("gTimeSavers.SkipCutscene.Intro", 0) && + CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", 0) && + CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0) && + CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) && + CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0) && + CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0) && + CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", 0) && + CVarGetInteger("gTimeSavers.NoForcedDialog", 0) && + CVarGetInteger("gTimeSavers.SkipOwlInteractions", 0) && + CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) && + CVarGetInteger("gTimeSavers.DisableTitleCard", 0); + bool someChecked = + CVarGetInteger("gTimeSavers.SkipCutscene.Intro", 0) || + CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", 0) || + CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0) || + CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || + CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0) || + CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0) || + CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", 0) || + CVarGetInteger("gTimeSavers.NoForcedDialog", 0) || + CVarGetInteger("gTimeSavers.SkipOwlInteractions", 0) || + CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) || + CVarGetInteger("gTimeSavers.DisableTitleCard", 0); + + ImGuiContext* g = ImGui::GetCurrentContext(); + ImGuiItemFlags backup_item_flags = g->CurrentItemFlags; + if (!allChecked && someChecked) g->CurrentItemFlags |= ImGuiItemFlags_MixedValue; + if (ImGui::Checkbox("All", &allChecked)) { + if (allChecked) { + CVarSetInteger("gTimeSavers.SkipCutscene.Intro", 1); + CVarSetInteger("gTimeSavers.SkipCutscene.Entrances", 1); + CVarSetInteger("gTimeSavers.SkipCutscene.Story", 1); + CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 1); + CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 1); + CVarSetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 1); + CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 1); + CVarSetInteger("gTimeSavers.NoForcedDialog", 1); + CVarSetInteger("gTimeSavers.SkipOwlInteractions", 1); + CVarSetInteger("gTimeSavers.SkipMiscInteractions", 1); + CVarSetInteger("gTimeSavers.DisableTitleCard", 1); + } else { + CVarSetInteger("gTimeSavers.SkipCutscene.Intro", 0); + CVarSetInteger("gTimeSavers.SkipCutscene.Entrances", 0); + CVarSetInteger("gTimeSavers.SkipCutscene.Story", 0); + CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 0); + CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 0); + CVarSetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0); + CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 0); + CVarSetInteger("gTimeSavers.NoForcedDialog", 0); + CVarSetInteger("gTimeSavers.SkipOwlInteractions", 0); + CVarSetInteger("gTimeSavers.SkipMiscInteractions", 0); + CVarSetInteger("gTimeSavers.DisableTitleCard", 0); + } + LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } + g->CurrentItemFlags = backup_item_flags; + UIWidgets::PaddedEnhancementCheckbox("Skip Intro", "gTimeSavers.SkipCutscene.Intro"); + UIWidgets::PaddedEnhancementCheckbox("Skip Entrance Cutscenes", "gTimeSavers.SkipCutscene.Entrances"); + UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story"); + UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong"); + UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro"); + UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding"); + UIWidgets::Tooltip("Skip cutscenes that are associated with useful glitches, currently this is only the Fire Temple Darunia CS and Forest Temple Poe Sisters CS"); + UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint"); + UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog"); + UIWidgets::Tooltip("Prevent forced conversations with Navi or other NPCs"); + UIWidgets::PaddedEnhancementCheckbox("Skip Owl Interactions", "gTimeSavers.SkipOwlInteractions"); + UIWidgets::PaddedEnhancementCheckbox("Skip Misc Interactions", "gTimeSavers.SkipMiscInteractions"); + UIWidgets::PaddedEnhancementCheckbox("Disable Title Card", "gTimeSavers.DisableTitleCard"); + + UIWidgets::PaddedText("Skip Get Item Animations", true, false); + UIWidgets::EnhancementCombobox("gTimeSavers.SkipGetItemAnimation", skipGetItemAnimationOptions, SGIA_DISABLED); + if (CVarGetInteger("gTimeSavers.SkipGetItemAnimation", SGIA_DISABLED) != SGIA_DISABLED) { + UIWidgets::EnhancementSliderFloat("Item Scale: %f", "##ItemScale", "gTimeSavers.SkipGetItemAnimationScale", 5.0f, 15.0f, "", 10.0f, false); + UIWidgets::Tooltip("The size of the item when it is picked up"); + } UIWidgets::PaddedEnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "", 1, true, false, true); UIWidgets::PaddedEnhancementCheckbox("Skip Text", "gSkipText", false, true); @@ -565,37 +643,8 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementSliderInt("Crawl speed %dx", "##CRAWLSPEED", "gCrawlSpeed", 1, 5, "", 1, true, false, true); UIWidgets::PaddedEnhancementCheckbox("Faster Heavy Block Lift", "gFasterHeavyBlockLift", false, false); UIWidgets::Tooltip("Speeds up lifting silver rocks and obelisks"); - UIWidgets::PaddedEnhancementCheckbox("Skip Pickup Messages", "gFastDrops", true, false); - UIWidgets::Tooltip("Skip pickup messages for new consumable items and bottle swipes"); - UIWidgets::PaddedEnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback", true, false); - UIWidgets::Tooltip("Skip the part where the Ocarina playback is called when you play a song"); - bool forceSkipScarecrow = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_SCARECROWS_SONG); - static const char* forceSkipScarecrowText = "This setting is forcefully enabled because a savefile\nwith \"Skip Scarecrow Song\" is loaded"; - UIWidgets::PaddedEnhancementCheckbox("Skip Scarecrow Song", "gSkipScarecrow", true, false, - forceSkipScarecrow, forceSkipScarecrowText, UIWidgets::CheckboxGraphics::Checkmark); - UIWidgets::Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song."); - UIWidgets::PaddedEnhancementCheckbox("Skip Magic Arrow Equip Animation", "gSkipArrowAnimation", true, false); - UIWidgets::PaddedEnhancementCheckbox("Skip save confirmation", "gSkipSaveConfirmation", true, false); - UIWidgets::Tooltip("Skip the \"Game saved.\" confirmation screen"); - UIWidgets::PaddedEnhancementCheckbox("Faster Farore's Wind", "gFastFarores", true, false); - UIWidgets::Tooltip("Greatly decreases cast time of Farore's Wind magic spell."); - UIWidgets::PaddedEnhancementCheckbox("Skip water take breath animation", "gSkipSwimDeepEndAnim", true, false); - UIWidgets::Tooltip("Skips Link's taking breath animation after coming up from water. This setting does not interfere with getting items from underwater."); - - ImGui::TableNextColumn(); - UIWidgets::Spacer(0); - ImGui::Text("Changes:"); - UIWidgets::PaddedSeparator(); - - UIWidgets::PaddedEnhancementSliderInt("Biggoron Forge Time: %d days", "##FORGETIME", "gForgeTime", 0, 3, "", 3, true, false, true); - UIWidgets::Tooltip("Allows you to change the number of days it takes for Biggoron to forge the Biggoron Sword"); - UIWidgets::PaddedEnhancementCheckbox("Remember Save Location", "gRememberSaveLocation", false, false); - UIWidgets::Tooltip("When loading a save, places Link at the last entrance he went through.\n" - "This doesn't work if the save was made in a grotto."); - UIWidgets::PaddedEnhancementCheckbox("No Forced Navi", "gNoForcedNavi", true, false); - UIWidgets::Tooltip("Prevent forced Navi conversations"); - UIWidgets::PaddedEnhancementCheckbox("Navi Timer Resets", "gEnhancements.ResetNaviTimer", true, false); - UIWidgets::Tooltip("Resets the Navi timer on scene change. If you have already talked to her, she will try and talk to you again, instead of needing a save warp or death. "); + UIWidgets::PaddedEnhancementCheckbox("Link as default file name", "gLinkDefaultName", true, false); + UIWidgets::Tooltip("Allows you to have \"Link\" as a premade file name"); UIWidgets::PaddedEnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze", true, false); UIWidgets::Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas"); UIWidgets::PaddedEnhancementCheckbox("Nighttime GS Always Spawn", "gNightGSAlwaysSpawn", true, false); @@ -1164,7 +1213,8 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("Removes the dungeon entrance icon on the top-left corner of the screen when no dungeon is present on the current map"); UIWidgets::PaddedEnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle", true, false); UIWidgets::Tooltip("Re-enables the two-handed idle animation, a seemingly finished animation that was disabled on accident in the original game"); - UIWidgets::PaddedEnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix", true, false); + UIWidgets::PaddedEnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix", true, false, SaveManager::Instance->IsRandoFile(), + "This setting is always enabled in randomizer files", UIWidgets::CheckboxGraphics::Checkmark); UIWidgets::Tooltip("Fixes a bug where the Gravedigging Tour Heart Piece disappears if the area reloads"); UIWidgets::PaddedEnhancementCheckbox("Fix Deku Nut upgrade", "gDekuNutUpgradeFix", true, false); UIWidgets::Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw"); diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index 9c0dd9b05..94b04580f 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -32,6 +32,7 @@ #include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" u16 D_8011E1C0 = 0; u16 D_8011E1C4 = 0; @@ -485,6 +486,7 @@ void func_80065134(PlayState* play, CutsceneContext* csCtx, CsCmdDayTime* cmd) { gSaveContext.dayTime = temp1 + temp2; gSaveContext.skyboxTime = temp1 + temp2; + LUSLOG_INFO("SET TIME %d", gSaveContext.dayTime); } } @@ -493,11 +495,16 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB Player* player = GET_PLAYER(play); s32 temp = 0; - // Automatically skip certain cutscenes when in rando - // cmd->base == 8: Traveling back/forward in time cutscene - // cmd->base == 24: Dropping a fish for Jabu Jabu - // cmd->base == 33: Zelda escaping with impa cutscene - bool randoCsSkip = (IS_RANDO && (cmd->base == 8 || cmd->base == 24 || cmd->base == 33)); + bool shouldSkipCommand = false; + + if (cmd->base == 8 && !GameInteractor_Should(GI_VB_PLAY_PULL_MASTER_SWORD_CS, true, NULL)) { + shouldSkipCommand = true; + } + + if (cmd->base == 24 && !GameInteractor_Should(GI_VB_PLAY_DROP_FISH_FOR_JABU_CS, true, NULL)) { + shouldSkipCommand = true; + } + bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) && (gSaveContext.fileNum != 0xFEDC) && CVarGetInteger("gDebugEnabled", 0)); @@ -558,7 +565,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB } } - if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (randoCsSkip || debugCsSkip))) { + if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (shouldSkipCommand || debugCsSkip))) { csCtx->state = CS_STATE_UNSKIPPABLE_EXEC; Audio_SetCutsceneFlag(0); @@ -624,7 +631,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.fw.set = 0; gSaveContext.respawn[RESPAWN_MODE_TOP].data = 0; } - if (!Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL)) { + if (GameInteractor_Should(GI_VB_PLAY_PULL_MASTER_SWORD_CS, !Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL), NULL)) { Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); play->nextEntranceIndex = ENTR_CUTSCENE_MAP_0; play->transitionTrigger = TRANS_TRIGGER_START; @@ -716,7 +723,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 22: - Item_Give(play, ITEM_SONG_REQUIEM); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) { + Item_Give(play, ITEM_SONG_REQUIEM); + } play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF0; @@ -768,7 +777,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; - Item_Give(play, ITEM_MEDALLION_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FIRE); + } gSaveContext.chamberCutsceneNum = 1; break; case 31: @@ -848,7 +859,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; break; case 47: - Item_Give(play, ITEM_SONG_NOCTURNE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) { + Item_Give(play, ITEM_SONG_NOCTURNE); + } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_NOCTURNE_OF_SHADOW); play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; play->transitionTrigger = TRANS_TRIGGER_START; @@ -1292,7 +1305,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB break; } - if (randoCsSkip) { + if (shouldSkipCommand && IS_RANDO) { Entrance_OverrideCutsceneEntrance(cmd->base); } } @@ -1561,7 +1574,49 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText } else if ((cmd->type == 4) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { Message_StartTextbox(play, cmd->textId1, NULL); } else { + GetItemEntry getItemEntry = GET_ITEM_NONE; + if (IS_RANDO) { + switch (cmd->base) { + case 0x80: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_QUEEN_GOHMA, RG_KOKIRI_EMERALD); + break; + case 0x81: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KING_DODONGO, RG_GORON_RUBY); + break; + case 0x82: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); + break; + case 0x3E: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_PHANTOM_GANON, RG_FOREST_MEDALLION); + break; + case 0x3C: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_VOLVAGIA, RG_FIRE_MEDALLION); + break; + case 0x3D: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MORPHA, RG_WATER_MEDALLION); + break; + case 0x3F: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TWINROVA, RG_SPIRIT_MEDALLION); + break; + case 0x41: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BONGO_BONGO, RG_SHADOW_MEDALLION); + break; + case 0x40: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION); + break; + case 0x72: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS); + break; + } + if (getItemEntry.getItemId != GI_NONE) { + // cmd->base = getItemEntry.textId; + // GET_PLAYER(play)->getItemEntry = getItemEntry; + } + } Message_StartTextbox(play, cmd->base, NULL); + if (IS_RANDO && getItemEntry.getItemId != GI_NONE) { + // GET_PLAYER(play)->getItemEntry = (GetItemEntry)GET_ITEM_NONE; + } } return; } @@ -1584,12 +1639,14 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText if ((dialogState == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { if (play->msgCtx.choiceIndex == 0) { if (cmd->textId1 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox D: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId1); } else { csCtx->frames++; } } else { if (cmd->textId2 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox E: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId2); } else { csCtx->frames++; @@ -1599,6 +1656,7 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText if (dialogState == TEXT_STATE_9) { if (cmd->textId1 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox F: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId1); } else { csCtx->frames++; @@ -2113,34 +2171,23 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) { u8 requiredAge; s16 i; - if (IS_RANDO && - // don't skip epona escape cutscenes - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_11 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_12 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_13 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_15 && - // don't skip nabooru iron knuckle cs - gSaveContext.entranceIndex != ENTR_SPIRIT_TEMPLE_BOSS_0) { - gSaveContext.showTitleCard = false; - return; - } - for (i = 0; i < ARRAY_COUNT(sEntranceCutsceneTable); i++) { entranceCutscene = &sEntranceCutsceneTable[i]; - requiredAge = entranceCutscene->ageRestriction; if (requiredAge == 2) { requiredAge = gSaveContext.linkAge; } if ((gSaveContext.entranceIndex == entranceCutscene->entrance) && - (!Flags_GetEventChkInf(entranceCutscene->flag) || (entranceCutscene->flag == 0x18)) && + (!Flags_GetEventChkInf(entranceCutscene->flag) || (entranceCutscene->flag == EVENTCHKINF_EPONA_OBTAINED)) && (gSaveContext.cutsceneIndex < 0xFFF0) && ((u8)gSaveContext.linkAge == requiredAge) && (gSaveContext.respawnFlag <= 0)) { Flags_SetEventChkInf(entranceCutscene->flag); - Cutscene_SetSegment(play, entranceCutscene->segAddr); - gSaveContext.cutsceneTrigger = 2; - gSaveContext.showTitleCard = false; + if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &entranceCutscene->flag)) { + Cutscene_SetSegment(play, entranceCutscene->segAddr); + gSaveContext.cutsceneTrigger = 2; + gSaveContext.showTitleCard = false; + } break; } } @@ -2148,48 +2195,48 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) { void Cutscene_HandleConditionalTriggers(PlayState* play) { osSyncPrintf("\ngame_info.mode=[%d] restart_flag", ((void)0, gSaveContext.respawnFlag)); + LUSLOG_INFO("Cutscene_HandleConditionalTriggers - entranceIndex: %#x cutsceneIndex: %#x", gSaveContext.entranceIndex, gSaveContext.cutsceneIndex); + + if (!GameInteractor_Should(GI_VB_PLAY_TRANSITION_CS, true, NULL)) { + return; + } if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { - const bool bShouldTowerRandoSkip = - (IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE)); if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); - gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0; - gSaveContext.cutsceneIndex = 0xFFF0; - } - } else if ((gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) && LINK_IS_ADULT && (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) && - (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) && - !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); - gSaveContext.cutsceneIndex = 0xFFF0; - } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); + gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0; + gSaveContext.cutsceneIndex = 0xFFF0; + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, ( + (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) && + LINK_IS_ADULT && + Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) && + !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) + ), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); + gSaveContext.cutsceneIndex = 0xFFF0; } else if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FAIRY_OCARINA, true, NULL)) { Item_Give(play, ITEM_OCARINA_FAIRY); - gSaveContext.entranceIndex = ENTR_LOST_WOODS_0; - gSaveContext.cutsceneIndex = 0xFFF0; } - } else if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && - LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && - (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); - gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0; - gSaveContext.cutsceneIndex = 0xFFF8; - } - } else if ((!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) && - gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS) || - (bShouldTowerRandoSkip && - gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR)) { + gSaveContext.entranceIndex = ENTR_LOST_WOODS_0; + gSaveContext.cutsceneIndex = 0xFFF0; + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, ( + CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && + LINK_IS_ADULT && + !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) + ), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0; + gSaveContext.cutsceneIndex = 0xFFF8; + } else if (!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS)) { Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); gSaveContext.entranceIndex = ENTR_GANON_BOSS_0; - // In rando, skip the cutscene for the tower falling down after the escape. - if (IS_RANDO) { - return; - } gSaveContext.cutsceneIndex = 0xFFF0; } } diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 77f42aebd..da7454961 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -3,6 +3,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h" #include "textures/icon_item_static/icon_item_static.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -349,6 +350,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { s32 getItemId = GI_NONE; this->randoGiEntry = (GetItemEntry)GET_ITEM_NONE; this->randoCheck = (RandomizerCheck)RC_UNKNOWN_CHECK; + this->itemEntry = (GetItemEntry)GET_ITEM_NONE; s16 spawnParam8000 = this->actor.params & 0x8000; s32 pad1; @@ -358,7 +360,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.params &= 0xFF; - if (Flags_GetCollectible(play, this->collectibleFlag)) { + if (GameInteractor_Should(GI_VB_ITEM00_DESPAWN, Flags_GetCollectible(play, this->collectibleFlag), this)) { Actor_Kill(&this->actor); return; } @@ -381,12 +383,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->unk_158 = 0; Actor_SetScale(&this->actor, 0.03f); this->scale = 0.03f; - // Offset keys in randomizer slightly higher for their GID replacement - if (!IS_RANDO) { - yOffset = 350.0f; - } else { - yOffset = 430.0f; - } + yOffset = 350.0f; break; case ITEM00_HEART_PIECE: this->unk_158 = 0; @@ -479,6 +476,14 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 0.03f); this->scale = 0.03f; break; + case ITEM00_SOH_GIVE_ITEM_ENTRY: + case ITEM00_SOH_GIVE_ITEM_ENTRY_GI: + case ITEM00_SOH_DUMMY: + this->unk_158 = 0; + Actor_SetScale(&this->actor, 0.03f); + this->scale = 0.03f; + yOffset = 430.0f; + break; } this->unk_156 = 0; @@ -507,6 +512,10 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.velocity.y = 0.0f; this->actor.gravity = 0.0f; + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ITEM_00, true, this)) { + return; + } + switch (this->actor.params) { case ITEM00_RUPEE_GREEN: Item_Give(play, ITEM_RUPEE_GREEN); @@ -576,16 +585,8 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { break; } - if (!Actor_HasParent(&this->actor, play)) { - if (getItemId != GI_NONE) { - if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) { - func_8002F554(&this->actor, play, getItemId); - } else { - if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } - } + if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { + func_8002F554(&this->actor, play, getItemId); } EnItem00_SetupAction(this, func_8001E5C8); @@ -603,8 +604,7 @@ void func_8001DFC8(EnItem00* this, PlayState* play) { (this->actor.params == ITEM00_HEART_PIECE)) { this->actor.shape.rot.y += 960; } else { - if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params != ITEM00_BOMBS_SPECIAL) && - (this->actor.params != ITEM00_BOMBCHU)) { + if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params < ITEM00_BOMBS_SPECIAL)) { if (this->unk_15A == -1) { if (Math_SmoothStepToS(&this->actor.shape.rot.x, this->actor.world.rot.x - 0x4000, 2, 3000, 1500) == 0) { @@ -697,8 +697,7 @@ void func_8001E304(EnItem00* this, PlayState* play) { if (this->actor.params <= ITEM00_RUPEE_RED) { this->actor.shape.rot.y += 960; - } else if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params != ITEM00_BOMBS_SPECIAL) && - (this->actor.params != ITEM00_BOMBCHU)) { + } else if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params < ITEM00_BOMBS_SPECIAL)) { this->actor.world.rot.x -= 700; this->actor.shape.rot.y += 400; this->actor.shape.rot.x = this->actor.world.rot.x - 0x4000; @@ -733,13 +732,7 @@ void func_8001E5C8(EnItem00* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->getItemId != GI_NONE) { if (!Actor_HasParent(&this->actor, play)) { - if (!IS_RANDO) { - func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); - } else { - if (GiveItemEntryFromActor(&this->actor, play, this->randoGiEntry, 50.0f, 80.0f) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } + func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); this->unk_15A++; } else { this->getItemId = GI_NONE; @@ -781,13 +774,15 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { s32 pad; // Rotate some drops when 3D drops are on, otherwise reset rotation back to 0 for billboard effect - if ((this->actor.params == ITEM00_HEART && this->unk_15A >= 0) || + if ( + (this->actor.params == ITEM00_HEART && this->unk_15A >= 0) || (this->actor.params >= ITEM00_ARROWS_SMALL && this->actor.params <= ITEM00_SMALL_KEY) || - this->actor.params == ITEM00_BOMBS_A || this->actor.params == ITEM00_ARROWS_SINGLE || - this->actor.params == ITEM00_BOMBS_SPECIAL || this->actor.params == ITEM00_BOMBCHU) { - if (CVarGetInteger("gNewDrops", 0) || - // Keys in randomizer need to always rotate for their GID replacement - (IS_RANDO && this->actor.params == ITEM00_SMALL_KEY)) { + this->actor.params == ITEM00_BOMBS_A || + this->actor.params == ITEM00_ARROWS_SINGLE || + this->actor.params == ITEM00_BOMBS_SPECIAL || + (this->actor.params >= ITEM00_BOMBCHU && this->actor.params <= ITEM00_SOH_GIVE_ITEM_ENTRY_GI) + ) { + if (CVarGetInteger("gNewDrops", 0) || (this->actor.params >= ITEM00_SOH_DUMMY && this->actor.params <= ITEM00_SOH_GIVE_ITEM_ENTRY_GI)) { this->actor.shape.rot.y += 960; } else { this->actor.shape.rot.y = 0; @@ -871,6 +866,10 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { return; } + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ITEM_00, true, this)) { + return; + } + switch (this->actor.params) { case ITEM00_RUPEE_GREEN: Item_Give(play, ITEM_RUPEE_GREEN); @@ -955,14 +954,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { params = &this->actor.params; if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { - if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) { - func_8002F554(&this->actor, play, getItemId); - } else { - getItemId = this->randoGiEntry.getItemId; - if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } + func_8002F554(&this->actor, play, getItemId); } switch (*params) { @@ -1052,7 +1044,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) { } break; case ITEM00_HEART_PIECE: - if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) { + if (CVarGetInteger("gNewDrops", 0)) { mtxScale = 21.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); GetItem_Draw(play, GID_HEART_PIECE); @@ -1162,7 +1154,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) { break; } case ITEM00_SMALL_KEY: - if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) { + if (CVarGetInteger("gNewDrops", 0)) { mtxScale = 8.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); GetItem_Draw(play, GID_KEY_SMALL); @@ -1368,17 +1360,7 @@ static const Vtx customDropVtx[] = { * Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...). */ void EnItem00_DrawCollectible(EnItem00* this, PlayState* play) { - if (IS_RANDO && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) { - if (this->randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE); - this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - } - - f32 mtxScale = 10.67f; - Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry); - GetItemEntry_Draw(play, this->randoGiEntry); - } else if (this->actor.params == ITEM00_BOMBCHU) { + if (this->actor.params == ITEM00_BOMBCHU) { OPEN_DISPS(play->state.gfxCtx); Matrix_ReplaceRotation(&play->billboardMtxF); @@ -1458,29 +1440,17 @@ void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play) { * Draw Function used for the Piece of Heart type of En_Item00. */ void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) { - if (IS_RANDO) { - if (this->randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE); - this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - } + s32 pad; - f32 mtxScale = 16.0f; - Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry); - GetItemEntry_Draw(play, this->randoGiEntry); - } else { - s32 pad; + OPEN_DISPS(play->state.gfxCtx); - OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + func_8002ED80(&this->actor, play, 0); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), + G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL); - Gfx_SetupDL_25Xlu(play->state.gfxCtx); - func_8002ED80(&this->actor, play, 0); - gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), - G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL); - - CLOSE_DISPS(play->state.gfxCtx); - } + CLOSE_DISPS(play->state.gfxCtx); } /** diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 4c661aad7..1d00f73bb 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -2603,8 +2603,23 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->lastPlayedSong = msgCtx->ocarinaStaff->state; msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_SUCCESS; - if (!IS_RANDO) { - Item_Give(play, ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]); + u8 songItemId = ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]; + + if ( + (songItemId == ITEM_SONG_MINUET && GameInteractor_Should(GI_VB_GIVE_ITEM_MINUET_OF_FOREST, true, NULL)) || + (songItemId == ITEM_SONG_BOLERO && GameInteractor_Should(GI_VB_GIVE_ITEM_BOLERO_OF_FIRE, true, NULL)) || + (songItemId == ITEM_SONG_SERENADE && GameInteractor_Should(GI_VB_GIVE_ITEM_SERENADE_OF_WATER, true, NULL)) || + (songItemId == ITEM_SONG_REQUIEM && GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) || + (songItemId == ITEM_SONG_NOCTURNE && GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) || + (songItemId == ITEM_SONG_PRELUDE && GameInteractor_Should(GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT, true, NULL)) || + (songItemId == ITEM_SONG_LULLABY && GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LULLABY, true, NULL)) || + (songItemId == ITEM_SONG_EPONA && GameInteractor_Should(GI_VB_GIVE_ITEM_EPONAS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_SARIA && GameInteractor_Should(GI_VB_GIVE_ITEM_SARIAS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_SUN && GameInteractor_Should(GI_VB_GIVE_ITEM_SUNS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_TIME && GameInteractor_Should(GI_VB_GIVE_ITEM_SONG_OF_TIME, true, NULL)) || + (songItemId == ITEM_SONG_STORMS && GameInteractor_Should(GI_VB_GIVE_ITEM_SONG_OF_STORMS, true, NULL)) + ) { + Item_Give(play, songItemId); } osSyncPrintf(VT_FGCOL(YELLOW)); diff --git a/soh/src/code/z_onepointdemo.c b/soh/src/code/z_onepointdemo.c index 9489eefcd..ad5df65bd 100644 --- a/soh/src/code/z_onepointdemo.c +++ b/soh/src/code/z_onepointdemo.c @@ -1,6 +1,7 @@ #include "global.h" #include "vt.h" #include "overlays/actors/ovl_En_Sw/z_en_sw.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" static s16 sDisableAttention = false; static s16 sUnused = -1; @@ -810,12 +811,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor break; case 4100: csInfo->keyFrames = D_801225D4; - // RANDO: Waterfall opening cutscene skips to the end of the cutscene data earlier by doing this - if (!(IS_RANDO)) { - csInfo->keyFrameCnt = 5; - } else { - csInfo->keyFrameCnt = 2; - } + csInfo->keyFrameCnt = ARRAY_COUNT(D_801225D4); player->actor.shape.rot.y = player->actor.world.rot.y = player->currentYaw = 0x3FFC; func_800C0808(play, camIdx, player, CAM_SET_CS_C); @@ -1176,6 +1172,16 @@ s16 OnePointCutscene_Init(PlayState* play, s16 csId, s16 timer, Actor* actor, s1 s16 csCamIdx; Camera* csCam; + if (actor != NULL && actor->id != ACTOR_PLAYER) { + if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, actor)) { + return; + } + } else { + if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_CS, true, &csId)) { + return; + } + } + if (parentCamIdx == SUBCAM_ACTIVE) { parentCamIdx = play->activeCamera; } diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 828e98368..bc253ef3a 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2128,7 +2128,9 @@ u8 Item_Give(PlayState* play, u8 item) { AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); } } - item = ITEM_STICK; + // [SOH] This results in the same behavior as the original code, but also allows us to get an accurate ReceivedItemEntry hook + INV_CONTENT(ITEM_STICK) = ITEM_STICK; + return Return_Item(item, MOD_NONE, returnItem); } else if (item == ITEM_NUT) { if (gSaveContext.inventory.items[slot] == ITEM_NONE) { Inventory_ChangeUpgrade(UPG_NUTS, 1); @@ -2152,7 +2154,9 @@ u8 Item_Give(PlayState* play, u8 item) { AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); } } - item = ITEM_NUT; + // [SOH] This results in the same behavior as the original code, but also allows us to get an accurate ReceivedItemEntry hook + INV_CONTENT(ITEM_NUT) = ITEM_NUT; + return Return_Item(item, MOD_NONE, returnItem); } else if (item == ITEM_BOMB) { // "Bomb Bomb Bomb Bomb Bomb Bomb Bomb" osSyncPrintf(" 爆弾 爆弾 爆弾 爆弾 爆弾 爆弾 爆弾 \n"); diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index f9b3e7cf4..3ce5eeefc 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -226,60 +226,6 @@ void Play_Destroy(GameState* thisx) { gPlayState = NULL; } -void GivePlayerRandoRewardSongOfTime(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_16 && player != NULL && !Player_InBlockingCsMode(play, player) && - !Flags_GetTreasure(play, 0x1F) && gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT && !gSaveContext.pendingIceTrapCount) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0x1F; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } -} - -void GivePlayerRandoRewardNocturne(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if ((gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 || - gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_1 || - gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_2) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && - CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && player != NULL && - !Player_InBlockingCsMode(play, player) && !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_NOCTURNE_OF_SHADOW); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0xAA; - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - } -} - -void GivePlayerRandoRewardRequiem(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { - if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT) && player != NULL && - !Player_InBlockingCsMode(play, player)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0xAC; - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - } - } -} - -void GivePlayerRandoRewardMasterSword(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_2 && LINK_IS_ADULT && player != NULL && - !Player_InBlockingCsMode(play, player) && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && - !Flags_GetRandomizerInf(RAND_INF_TOT_MASTER_SWORD)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_MASTER_SWORD); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = RAND_INF_TOT_MASTER_SWORD; - player->pendingFlag.flagType = FLAG_RANDOMIZER_INF; - } -} - u8 CheckStoneCount() { u8 stoneCount = 0; @@ -402,69 +348,6 @@ u8 CheckLACSRewardCount() { return lacsRewardCount; } -void GivePlayerRandoRewardZeldaLightArrowsGift(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - u8 meetsRequirements = 0; - - switch (Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY)) { - case RO_GANON_BOSS_KEY_LACS_STONES: - if ((CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_STONE_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: - if ((CheckMedallionCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_MEDALLION_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_REWARDS: - if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_REWARD_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_DUNGEONS: - if ((CheckDungeonCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_DUNGEON_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_TOKENS: - if (gSaveContext.inventory.gsTokens >= Randomizer_GetSettingValue(RSK_LACS_TOKEN_COUNT)) { - meetsRequirements = true; - } - break; - default: - if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) { - meetsRequirements = true; - } - break; - } - - if (meetsRequirements && LINK_IS_ADULT && - (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) && - !Flags_GetTreasure(play, 0x1E) && player != NULL && !Player_InBlockingCsMode(play, player) && - play->transitionTrigger == TRANS_TRIGGER_OFF) { - GetItemEntry getItem = Randomizer_GetItemFromKnownCheck(check, GI_ARROW_LIGHT); - if (GiveItemEntryWithoutActor(play, getItem)) { - player->pendingFlag.flagID = 0x1E; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } - } -} - -void GivePlayerRandoRewardSariaGift(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - if (gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY); - - if (!Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE) && player != NULL && !Player_InBlockingCsMode(play, player)) { - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - player->pendingFlag.flagID = 0xC1; - } - } -} - void Play_Init(GameState* thisx) { PlayState* play = (PlayState*)thisx; GraphicsContext* gfxCtx = play->state.gfxCtx; @@ -1448,15 +1331,6 @@ skip: Environment_Update(play, &play->envCtx, &play->lightCtx, &play->pauseCtx, &play->msgCtx, &play->gameOverCtx, play->state.gfxCtx); - - if (IS_RANDO) { - GivePlayerRandoRewardSariaGift(play, RC_LW_GIFT_FROM_SARIA); - GivePlayerRandoRewardSongOfTime(play, RC_SONG_FROM_OCARINA_OF_TIME); - GivePlayerRandoRewardZeldaLightArrowsGift(play, RC_TOT_LIGHT_ARROWS_CUTSCENE); - GivePlayerRandoRewardNocturne(play, RC_SHEIK_IN_KAKARIKO); - GivePlayerRandoRewardRequiem(play, RC_SHEIK_AT_COLOSSUS); - GivePlayerRandoRewardMasterSword(play, RC_TOT_MASTER_SWORD); - } } void Play_DrawOverlayElements(PlayState* play) { diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index dfffa7729..1f136674b 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -564,8 +564,8 @@ uint8_t Player_IsCustomLinkModel() { } s32 Player_InBlockingCsMode(PlayState* play, Player* this) { - return (this->stateFlags1 & 0x20000080) || (this->csAction != 0) || (play->transitionTrigger == TRANS_TRIGGER_START) || - (this->stateFlags1 & 1) || (this->stateFlags3 & 0x80) || + return (this->stateFlags1 & (PLAYER_STATE1_DEAD | PLAYER_STATE1_IN_CUTSCENE)) || (this->csAction != 0) || (play->transitionTrigger == TRANS_TRIGGER_START) || + (this->stateFlags1 & PLAYER_STATE1_LOADING) || (this->stateFlags3 & PLAYER_STATE3_HOOKSHOT_TRAVELLING) || ((gSaveContext.magicState != MAGIC_STATE_IDLE) && (Player_ActionToMagicSpell(this, this->itemAction) >= 0)); } diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c index 86d23c45b..e05c171f0 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c @@ -6,6 +6,7 @@ #include "z_bg_bdan_switch.h" #include "objects/object_bdan_objects/object_bdan_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -224,10 +225,12 @@ void func_8086D4B4(BgBdanSwitch* this, PlayState* play) { if (!Flags_GetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F)) { type = this->dyna.actor.params & 0xFF; Flags_SetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F); - if (type == BLUE || type == YELLOW_TALL_2) { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); - } else { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + if (type == BLUE || type == YELLOW_TALL_2) { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + } else { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME); + } } } } @@ -236,7 +239,9 @@ void func_8086D548(BgBdanSwitch* this, PlayState* play) { if (Flags_GetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F)) { Flags_UnsetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F); if ((this->dyna.actor.params & 0xFF) == YELLOW_TALL_2) { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + } } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index 58f11a7f3..d0fc8864f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -8,6 +8,7 @@ #include "scenes/dungeons/ddan/ddan_scene.h" #include "objects/object_bwall/object_bwall.h" #include "objects/object_kingdodongo/object_kingdodongo.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -300,10 +301,13 @@ void BgBreakwall_Wait(BgBreakwall* this, PlayState* play) { if ((wallType == BWALL_DC_ENTRANCE) && (!Flags_GetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN))) { Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN); - Cutscene_SetSegment(play, gDcOpeningCs); - gSaveContext.cutsceneTrigger = 1; + s32 flag = EVENTCHKINF_ENTERED_DODONGOS_CAVERN; + if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &flag)) { + Cutscene_SetSegment(play, gDcOpeningCs); + gSaveContext.cutsceneTrigger = 1; + func_8002DF54(play, NULL, 0x31); + } Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - func_8002DF54(play, NULL, 0x31); } if (this->dyna.actor.params < 0) { diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c b/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c index eeecfabcb..51b7dc622 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c @@ -6,6 +6,7 @@ #include "z_bg_mori_bigst.h" #include "objects/object_mori_objects/object_mori_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -149,7 +150,9 @@ void BgMoriBigst_StalfosFight(BgMoriBigst* this, PlayState* play) { if ((this->dyna.actor.home.rot.z == 0) && ((this->dyna.actor.home.pos.y - 5.0f) <= GET_PLAYER(play)->actor.world.pos.y)) { BgMoriBigst_SetupFall(this, play); - OnePointCutscene_Init(play, 3220, 72, &this->dyna.actor, MAIN_CAM); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_Init(play, 3220, 72, &this->dyna.actor, MAIN_CAM); + } } } @@ -163,8 +166,10 @@ void BgMoriBigst_Fall(BgMoriBigst* this, PlayState* play) { this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; BgMoriBigst_SetupLanding(this, play); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); - OnePointCutscene_Init(play, 1020, 8, &this->dyna.actor, MAIN_CAM); - func_8002DF38(play, NULL, 0x3C); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_Init(play, 1020, 8, &this->dyna.actor, MAIN_CAM); + func_8002DF38(play, NULL, 0x3C); + } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c index 26a02aa96..b6d5ed15a 100644 --- a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c +++ b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c @@ -6,6 +6,7 @@ #include "z_bg_toki_swd.h" #include "objects/object_toki_objects/object_toki_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -115,14 +116,17 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) { if (((Flags_GetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER)) == 0) && (gSaveContext.sceneSetupIndex < 4) && Actor_IsFacingAndNearPlayer(&this->actor, 800.0f, 0x7530) && !Play_InCsMode(play)) { Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER); - play->csCtx.segment = D_808BBD90; - gSaveContext.cutsceneTrigger = 1; + s32 flag = EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER; + if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &flag)) { + play->csCtx.segment = D_808BBD90; + gSaveContext.cutsceneTrigger = 1; + } } if (!LINK_IS_ADULT || (Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && !IS_RANDO) || IS_RANDO) { if (Actor_HasParent(&this->actor, play)) { if (!LINK_IS_ADULT) { - if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_MASTER_SWORD, true, NULL)) { Item_Give(play, ITEM_SWORD_MASTER); } play->csCtx.segment = D_808BB2F0; diff --git a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c index 75e920b29..04d1d6c72 100644 --- a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c +++ b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c @@ -7,6 +7,7 @@ #include "z_bg_treemouth.h" #include "objects/object_spot04_objects/object_spot04_objects.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -73,11 +74,7 @@ void BgTreemouth_Init(Actor* thisx, PlayState* play) { if ((gSaveContext.sceneSetupIndex < 4) && !LINK_IS_ADULT) { BgTreemouth_SetupAction(this, func_808BC8B8); - // If dungeon entrance randomizer is on, keep the tree mouth open - // when Link is adult and sword & shield have been shown to Mido - } else if ((LINK_IS_ADULT && (!IS_RANDO || - Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) == RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) || - !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) || (gSaveContext.sceneSetupIndex == 7)) { + } else if (LINK_IS_ADULT || (gSaveContext.sceneSetupIndex == 7)) { this->unk_168 = 0.0f; BgTreemouth_SetupAction(this, BgTreemouth_DoNothing); } else { @@ -157,9 +154,11 @@ void func_808BC8B8(BgTreemouth* this, PlayState* play) { } } else if (Actor_IsFacingAndNearPlayer(&this->dyna.actor, 1658.0f, 0x4E20)) { Flags_SetEventChkInf(EVENTCHKINF_MET_DEKU_TREE); - play->csCtx.segment = D_808BCE20; - gSaveContext.cutsceneTrigger = 1; - BgTreemouth_SetupAction(this, func_808BC9EC); + if (GameInteractor_Should(GI_VB_PLAY_DEKU_TREE_INTRO_CS, true, this)) { + play->csCtx.segment = D_808BCE20; + gSaveContext.cutsceneTrigger = 1; + BgTreemouth_SetupAction(this, func_808BC9EC); + } } } } else { diff --git a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h index 7fe96cfa1..daa33bfee 100644 --- a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h +++ b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h @@ -15,4 +15,7 @@ typedef struct BgTreemouth { /* 0x016C */ BgTreemouthActionFunc actionFunc; } BgTreemouth; // size = 0x0170 +void BgTreemouth_SetupAction(BgTreemouth* actor, BgTreemouthActionFunc actionFunc); +void func_808BC6F8(BgTreemouth* actor, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c b/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c index 1c2f4c16b..cffdbea38 100644 --- a/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c +++ b/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c @@ -3,6 +3,7 @@ #include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -184,7 +185,9 @@ void func_80969F38(DemoDu* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, DEMO_EFFECT_MEDAL_FIRE); - Item_Give(play, ITEM_MEDALLION_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FIRE); + } } void func_80969FB4(DemoDu* this, PlayState* play) { @@ -201,7 +204,9 @@ void DemoDu_CsFireMedallion_AdvanceTo01(DemoDu* this, PlayState* play) { this->updateIndex = CS_FIREMEDALLION_SUBSCENE(1); play->csCtx.segment = D_8096C1A4; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FIRE); + } player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } diff --git a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c index 9e4dd6119..4af2e9f87 100644 --- a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c +++ b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c @@ -142,7 +142,7 @@ f32 DemoEffect_InterpolateCsFrames(PlayState* play, s32 csActionId) { */ void DemoEffect_InitJewel(PlayState* play, DemoEffect* this) { this->initDrawFunc = DemoEffect_DrawJewel; - if (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) { + if (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) { this->initDrawFunc = DemoEffect_DrawGetItem; } if (!LINK_IS_ADULT) { @@ -156,7 +156,7 @@ void DemoEffect_InitJewel(PlayState* play, DemoEffect* this) { Actor_SetScale(&this->actor, 0.10f); } this->csActionId = 1; - this->actor.shape.rot.x = (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) ? 0 : 16384; + this->actor.shape.rot.x = (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) ? 0 : 16384; DemoEffect_InitJewelColor(this); this->jewel.alpha = 0; this->jewelCsRotation.x = this->jewelCsRotation.y = this->jewelCsRotation.z = 0; @@ -2087,13 +2087,48 @@ void DemoEffect_DrawGetItem(Actor* thisx, PlayState* play) { this->getItem.isLoaded = 1; return; } - if (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); - this->getItem.drawId = getItemEntry.gid; - func_8002EBCC(thisx, play, 0); - func_8002ED80(thisx, play, 0); - GetItemEntry_Draw(play, getItemEntry); - return; + if (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) { + GetItemEntry getItemEntry = GET_ITEM_NONE; + + switch (this->actor.params) { + case DEMO_EFFECT_JEWEL_KOKIRI: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_QUEEN_GOHMA, RG_KOKIRI_EMERALD); + break; + case DEMO_EFFECT_JEWEL_GORON: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KING_DODONGO, RG_GORON_RUBY); + break; + case DEMO_EFFECT_JEWEL_ZORA: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); + break; + case DEMO_EFFECT_MEDAL_FOREST: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_PHANTOM_GANON, RG_FOREST_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_FIRE: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_VOLVAGIA, RG_FIRE_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_WATER: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MORPHA, RG_WATER_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_SPIRIT: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TWINROVA, RG_SPIRIT_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_SHADOW: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BONGO_BONGO, RG_SHADOW_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_LIGHT: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION); + break; + case DEMO_EFFECT_LIGHTARROW: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS); + break; + } + if (getItemEntry.getItemId != GI_NONE) { + this->getItem.drawId = getItemEntry.gid; + func_8002EBCC(thisx, play, 0); + func_8002ED80(thisx, play, 0); + GetItemEntry_Draw(play, getItemEntry); + return; + } } func_8002EBCC(thisx, play, 0); func_8002ED80(thisx, play, 0); diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index 4ddeec155..a06786b2d 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -10,6 +10,7 @@ #include "scenes/indoors/nakaniwa/nakaniwa_scene.h" #include "objects/object_im/object_im.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -318,7 +319,9 @@ void func_809853B4(DemoIm* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, playerX, playerY, playerZ, 0, 0, 0, 0xD); - Item_Give(play, ITEM_MEDALLION_SHADOW); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SHADOW_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_SHADOW); + } } void func_80985430(DemoIm* this, PlayState* play) { @@ -334,7 +337,9 @@ void func_8098544C(DemoIm* this, PlayState* play) { this->action = 1; play->csCtx.segment = D_8098786C; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_SHADOW); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SHADOW_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_SHADOW); + } player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } } @@ -903,40 +908,17 @@ void func_80986BF8(DemoIm* this, PlayState* play) { } } -void GivePlayerRandoRewardImpa(Actor* impa, PlayState* play, RandomizerCheck check) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY); - - if (impa->parent != NULL && impa->parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1F)) { - Flags_SetTreasure(play, 0x1F); - } else if (!Flags_GetTreasure(play, 0x1F) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { - GiveItemEntryFromActor(impa, play, getItemEntry, 75.0f, 50.0f); - } else if (!Player_InBlockingCsMode(play, GET_PLAYER(play))) { - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; - // In entrance rando have impa bring link back to the front of castle grounds - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) { - play->nextEntranceIndex = ENTR_HYRULE_CASTLE_0; - } else { - play->nextEntranceIndex = ENTR_HYRULE_FIELD_17; - } - gSaveContext.nextCutsceneIndex = 0; - } -} - void func_80986C30(DemoIm* this, PlayState* play) { if (func_80986A5C(this, play)) { - if (IS_RANDO) { - GivePlayerRandoRewardImpa(this, play, RC_SONG_FROM_IMPA); - } else { + if (GameInteractor_Should(GI_VB_PLAY_ZELDAS_LULLABY_CS, true, this)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gZeldasCourtyardLullabyCs); gSaveContext.cutsceneTrigger = 1; - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); - Item_Give(play, ITEM_SONG_LULLABY); func_80985F54(this); } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LULLABY, true, NULL)) { + Item_Give(play, ITEM_SONG_LULLABY); + } } } @@ -960,7 +942,7 @@ void func_80986D40(DemoIm* this, PlayState* play) { if (gSaveContext.sceneSetupIndex == 6) { this->action = 19; this->drawConfig = 1; - } else if ((Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) && !IS_RANDO) { + } else if ((Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) && !IS_RANDO) { // SoH [Randomizer] Not sure why we're not killing impa here. Actor_Kill(&this->actor); } else if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY)) { this->action = 23; diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h index 3697733e1..06d6e5d7e 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h @@ -51,4 +51,6 @@ typedef struct DemoIm { /* 0x02D4 */ NpcInteractInfo interactInfo; } DemoIm; // size = 0x02FC +void func_80986794(DemoIm* demoIm); + #endif diff --git a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c index 6da87ab3c..85dcb4ebe 100644 --- a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c +++ b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "objects/object_sa/object_sa.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" @@ -241,7 +242,9 @@ void func_8098E8C8(DemoSa* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 0xB); - Item_Give(play, ITEM_MEDALLION_FOREST); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FOREST_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FOREST); + } } void func_8098E944(DemoSa* this, PlayState* play) { @@ -258,7 +261,9 @@ void func_8098E960(DemoSa* this, PlayState* play) { this->action = 1; play->csCtx.segment = D_8099010C; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_FOREST); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FOREST_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FOREST); + } player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } else { this->action = 1; diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 290e809f6..eeb0df2d2 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -23,6 +23,7 @@ #include "objects/object_menkuri_objects/object_menkuri_objects.h" #include "objects/object_demo_kekkai/object_demo_kekkai.h" #include "objects/object_ouke_haka/object_ouke_haka.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -354,9 +355,11 @@ void func_80996A54(DoorShutter* this, PlayState* play) { if (Flags_GetClear(play, this->dyna.actor.room) || Flags_GetTempClear(play, this->dyna.actor.room)) { Flags_SetClear(play, this->dyna.actor.room); DoorShutter_SetupAction(this, func_80997150); - OnePointCutscene_Attention(play, &this->dyna.actor); - OnePointCutscene_Attention(play, &GET_PLAYER(play)->actor); - this->unk_16F = -100; + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_Attention(play, &this->dyna.actor); + OnePointCutscene_Attention(play, &GET_PLAYER(play)->actor); + this->unk_16F = -100; + } } else if (func_809968D4(this, play) != 0) { Player* player = GET_PLAYER(play); @@ -470,8 +473,10 @@ void func_80996EE8(DoorShutter* this, PlayState* play) { if (func_80996E08(this, play, 1.0f)) { if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { DoorShutter_SetupAction(this, func_80997150); - OnePointCutscene_Attention(play, &this->dyna.actor); - this->unk_16F = -100; + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_Attention(play, &this->dyna.actor); + this->unk_16F = -100; + } } else if (func_809968D4(this, play)) { Player* player = GET_PLAYER(play); // Jabu navi text for switch doors is different diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 5ea64e232..bdb154a92 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -2,6 +2,7 @@ #include "objects/object_warp1/object_warp1.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -487,44 +488,6 @@ s32 DoorWarp1_PlayerInRange(DoorWarp1* this, PlayState* play) { return ret; } -void GivePlayerRandoReward(DoorWarp1* this, Player* player, PlayState* play, u8 ruto, u8 adult) { - GetItemEntry getItemEntry = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, 0x00, GI_NONE); - - if (this->actor.parent != NULL && this->actor.parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1F)) { - Flags_SetTreasure(play, 0x1F); - } else if (!Flags_GetTreasure(play, 0x1F)) { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 100.0f); - } else if (!Player_InBlockingCsMode(play, GET_PLAYER(play))) { - if (adult) { - OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM); - func_8002DF54(play, &this->actor, 10); - player->unk_450.x = this->actor.world.pos.x; - player->unk_450.z = this->actor.world.pos.z; - this->unk_1B2 = 20; - DoorWarp1_SetupAction(this, func_8099A508); - } else { - if (ruto) { - this->rutoWarpState = WARP_BLUE_RUTO_STATE_ENTERED; - func_8002DF54(play, &this->actor, 10); - this->unk_1B2 = 1; - DoorWarp1_SetupAction(this, func_80999EE0); - } else { - Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - OnePointCutscene_Init(play, 0x25E7, 999, &this->actor, MAIN_CAM); - func_8002DF54(play, &this->actor, 10); - - player->unk_450.x = this->actor.world.pos.x; - player->unk_450.z = this->actor.world.pos.z; - this->unk_1B2 = 1; - - DoorWarp1_SetupAction(this, DoorWarp1_ChildWarpOut); - } - } - } -} - void DoorWarp1_ChildWarpIdle(DoorWarp1* this, PlayState* play) { Player* player; @@ -532,11 +495,6 @@ void DoorWarp1_ChildWarpIdle(DoorWarp1* this, PlayState* play) { if (DoorWarp1_PlayerInRange(this, play)) { player = GET_PLAYER(play); - - if (IS_RANDO) { - GivePlayerRandoReward(this, player, play, 0, 0); - return; - } Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); @@ -570,36 +528,26 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { osSyncPrintf("\n\n\nじかんがきたからおーしまい fade_direction=[%d]", play->transitionTrigger, TRANS_TRIGGER_START); if (play->sceneNum == SCENE_DODONGOS_CAVERN_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP), EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN); - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; - gSaveContext.nextCutsceneIndex = 0; - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_GORON_RUBY)) { Item_Give(play, ITEM_GORON_RUBY); - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; } + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; } else { play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_DEKU_TREE_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD), EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD)) { Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE); - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; - gSaveContext.nextCutsceneIndex = 0; - // Skip Mido complaining about dead Deku tree - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH); - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_KOKIRI_EMERALD)) { Item_Give(play, ITEM_KOKIRI_EMERALD); - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; } + play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; } else { play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; gSaveContext.nextCutsceneIndex = 0; @@ -635,12 +583,6 @@ void DoorWarp1_RutoWarpIdle(DoorWarp1* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); if (this->rutoWarpState != WARP_BLUE_RUTO_STATE_INITIAL && DoorWarp1_PlayerInRange(this, play)) { - - if (IS_RANDO) { - GivePlayerRandoReward(this, GET_PLAYER(play), play, 1, 0); - return; - } - this->rutoWarpState = WARP_BLUE_RUTO_STATE_ENTERED; func_8002DF54(play, &this->actor, 10); this->unk_1B2 = 1; @@ -670,9 +612,8 @@ void func_80999EE0(DoorWarp1* this, PlayState* play) { Play_CameraSetAtEye(play, sRutoWarpSubCamId, &at, &eye); Play_CameraSetFov(play, sRutoWarpSubCamId, 90.0f); this->rutoWarpState = WARP_BLUE_RUTO_STATE_TALKING; - if (!IS_RANDO) { - Message_StartTextbox(play, 0x4022, NULL); - } + // TODO: Why was this disabled in rando? + Message_StartTextbox(play, 0x4022, NULL); DoorWarp1_SetupAction(this, func_80999FE4); } } @@ -704,17 +645,14 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) { this->warpTimer++; if (this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF) { - Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; - gSaveContext.nextCutsceneIndex = 0; - } else { - Item_Give(play, ITEM_ZORA_SAPPHIRE); - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, true, EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) { + Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_ZORA_SAPPHIRE)) { + Item_Give(play, ITEM_ZORA_SAPPHIRE); + } gSaveContext.nextCutsceneIndex = 0xFFF0; } + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { @@ -767,11 +705,6 @@ void DoorWarp1_AdultWarpIdle(DoorWarp1* this, PlayState* play) { player = GET_PLAYER(play); - if (IS_RANDO) { - GivePlayerRandoReward(this, player, play, 0, 1); - return; - } - OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM); func_8002DF54(play, &this->actor, 10); player->unk_450.x = this->actor.world.pos.x; @@ -829,19 +762,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (IS_BOSS_RUSH) { BossRush_HandleBlueWarp(play, this->actor.world.pos.x, this->actor.world.pos.z); } else if (play->sceneNum == SCENE_FOREST_TEMPLE_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3; - gSaveContext.nextCutsceneIndex = 0; - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FOREST)) { Item_Give(play, ITEM_MEDALLION_FOREST); - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_2; @@ -851,20 +779,13 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_FIRE_TEMPLE_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; - gSaveContext.nextCutsceneIndex = 0; - // Change Death Mountain cloud since we aren't warping to the cutscene - Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED); - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FIRE)) { Item_Give(play, ITEM_MEDALLION_FIRE); - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; - gSaveContext.nextCutsceneIndex = 0xFFF3; } + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; + gSaveContext.nextCutsceneIndex = 0xFFF3; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_4; @@ -874,21 +795,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_WATER_TEMPLE_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_LAKE_HYLIA_9; - gSaveContext.nextCutsceneIndex = 0; - // Fill Lake Hylia since we aren't warping to the cutscene - Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_WATER)) { Item_Give(play, ITEM_MEDALLION_WATER); - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_LAKE_HYLIA_8; @@ -898,18 +812,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { - if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) || IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT), RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE)) { Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; - gSaveContext.nextCutsceneIndex = 0; - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SPIRIT)) { Item_Give(play, ITEM_MEDALLION_SPIRIT); - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_5; @@ -919,18 +829,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { - if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) || IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW), RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)) { Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_GRAVEYARD_8; - gSaveContext.nextCutsceneIndex = 0; - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SHADOW)) { Item_Give(play, ITEM_MEDALLION_SHADOW); - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_GRAVEYARD_7; diff --git a/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c b/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c index 3fe7fc689..495ef96b8 100644 --- a/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c +++ b/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c @@ -7,6 +7,7 @@ #include "z_elf_msg.h" #include "vt.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -110,7 +111,7 @@ void ElfMsg_Destroy(Actor* thisx, PlayState* play) { s32 ElfMsg_GetMessageId(ElfMsg* this) { // Negative message ID forces link to talk to Navi - if (this->actor.params & 0x8000 || CVarGetInteger("gNoForcedNavi", 0) != 0) { + if (this->actor.params & 0x8000) { return (this->actor.params & 0xFF) + 0x100; } else { return -((this->actor.params & 0xFF) + 0x100); @@ -125,8 +126,10 @@ void ElfMsg_CallNaviCuboid(ElfMsg* this, PlayState* play) { (this->actor.world.pos.y <= player->actor.world.pos.y) && ((player->actor.world.pos.y - this->actor.world.pos.y) < (100.0f * this->actor.scale.y)) && (fabsf(player->actor.world.pos.z - this->actor.world.pos.z) < (100.0f * this->actor.scale.z))) { - player->naviTextId = ElfMsg_GetMessageId(this); - navi->elfMsg = this; + if (GameInteractor_Should(GI_VB_NAVI_TALK, true, this)) { + player->naviTextId = ElfMsg_GetMessageId(this); + navi->elfMsg = this; + } } } @@ -145,8 +148,10 @@ void ElfMsg_CallNaviCylinder(ElfMsg* this, PlayState* play) { if (ElfMsg_WithinXZDistance(&player->actor.world.pos, &this->actor.world.pos, this->actor.scale.x * 100.0f) && (this->actor.world.pos.y <= player->actor.world.pos.y) && ((player->actor.world.pos.y - this->actor.world.pos.y) < (100.0f * this->actor.scale.y))) { - player->naviTextId = ElfMsg_GetMessageId(this); - navi->elfMsg = this; + if (GameInteractor_Should(GI_VB_NAVI_TALK, true, this)) { + player->naviTextId = ElfMsg_GetMessageId(this); + navi->elfMsg = this; + } } } diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index a4d86ff61..e01573c9b 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -3,6 +3,7 @@ #include "soh_assets.h" #include "soh/Enhancements/enhancementTypes.h" #include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -192,10 +193,12 @@ void EnBox_Init(Actor* thisx, PlayState* play2) { SkelAnime_Init(play, &this->skelanime, &gTreasureChestSkel, anim, this->jointTable, this->morphTable, 5); Animation_Change(&this->skelanime, anim, 1.5f, animFrameStart, endFrame, ANIMMODE_ONCE, 0.0f); + this->getItemEntry = ItemTable_RetrieveEntry(MOD_NONE, this->dyna.actor.params >> 5 & 0x7F); if (IS_RANDO) { - this->getItemEntry = Randomizer_GetItemFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params, this->dyna.actor.params >> 5 & 0x7F); - } else { - this->getItemEntry = ItemTable_RetrieveEntry(MOD_NONE, this->dyna.actor.params >> 5 & 0x7F); + RandomizerCheck rc = Randomizer_GetCheckFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params); + if (rc != RC_UNKNOWN_CHECK) { + this->getItemEntry = Randomizer_GetItemFromKnownCheck(rc, this->dyna.actor.params >> 5 & 0x7F); + } } EnBox_UpdateSizeAndTexture(this, play); @@ -275,7 +278,9 @@ void EnBox_Fall(EnBox* this, PlayState* play) { this->dyna.actor.shape.rot.z = 0; this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; EnBox_SetupAction(this, EnBox_WaitOpen); - OnePointCutscene_EndCutscene(play, this->unk_1AC); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_EndCutscene(play, this->unk_1AC); + } } Audio_PlaySoundGeneral(NA_SE_EV_COFFIN_CAP_BOUND, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); @@ -445,74 +450,12 @@ void EnBox_WaitOpen(EnBox* this, PlayState* play) { } osSyncPrintf("Actor_Environment_Tbox_On() %d\n", this->dyna.actor.params & 0x1F); Flags_SetTreasure(play, this->dyna.actor.params & 0x1F); - - // treasure chest game rando - if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { - if (IS_RANDO && play->sceneNum == SCENE_TREASURE_BOX_SHOP && (this->dyna.actor.params & 0x60) != 0x20) { - if((this->dyna.actor.params & 0xF) < 2) { - Flags_SetCollectible(play, 0x1B); - } - if((this->dyna.actor.params & 0xF) >= 2 && (this->dyna.actor.params & 0xF) < 4) { - Flags_SetCollectible(play, 0x1C); - } - if((this->dyna.actor.params & 0xF) >= 4 && (this->dyna.actor.params & 0xF) < 6) { - Flags_SetCollectible(play, 0x1D); - } - if((this->dyna.actor.params & 0xF) >= 6 && (this->dyna.actor.params & 0xF) < 8) { - Flags_SetCollectible(play, 0x1E); - } - if((this->dyna.actor.params & 0xF) >= 8 && (this->dyna.actor.params & 0xF) < 10) { - Flags_SetCollectible(play, 0x1F); - } - } - } } else { player = GET_PLAYER(play); func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos); if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f && Player_IsFacingActor(&this->dyna.actor, 0x3000, play)) { - GetItemEntry sItem = Randomizer_GetItemFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params, this->dyna.actor.params >> 5 & 0x7F); - GetItemEntry blueRupee = ItemTable_RetrieveEntry(MOD_NONE, GI_RUPEE_BLUE); - - // RANDOTODO treasure chest game rando - if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { - if (IS_RANDO && play->sceneNum == SCENE_TREASURE_BOX_SHOP && (this->dyna.actor.params & 0x60) != 0x20) { - if((this->dyna.actor.params & 0xF) < 2) { - if(Flags_GetCollectible(play, 0x1B)) { - sItem = blueRupee; - } - } - if((this->dyna.actor.params & 0xF) >= 2 && (this->dyna.actor.params & 0xF) < 4) { - if(Flags_GetCollectible(play, 0x1C)) { - sItem = blueRupee; - } - } - if((this->dyna.actor.params & 0xF) >= 4 && (this->dyna.actor.params & 0xF) < 6) { - if(Flags_GetCollectible(play, 0x1D)) { - sItem = blueRupee; - } - } - if((this->dyna.actor.params & 0xF) >= 6 && (this->dyna.actor.params & 0xF) < 8) { - if(Flags_GetCollectible(play, 0x1E)) { - sItem = blueRupee; - } - } - if((this->dyna.actor.params & 0xF) >= 8 && (this->dyna.actor.params & 0xF) < 10) { - if(Flags_GetCollectible(play, 0x1F)) { - sItem = blueRupee; - } - } - } - } - // Chests need to have a negative getItemId in order to not immediately give their item - // when approaching. - if (IS_RANDO) { - sItem.getItemId = 0 - sItem.getItemId; - sItem.getItemFrom = ITEM_FROM_CHEST; - GiveItemEntryFromActorWithFixedRange(&this->dyna.actor, play, sItem); - } else { func_8002F554(&this->dyna.actor, play, -(this->dyna.actor.params >> 5 & 0x7F)); - } } if (Flags_GetTreasure(play, this->dyna.actor.params & 0x1F)) { EnBox_SetupAction(this, EnBox_Open); @@ -626,12 +569,9 @@ void EnBox_Update(Actor* thisx, PlayState* play) { Actor_SetFocus(&this->dyna.actor, 40.0f); } - if (((!IS_RANDO && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) || - (IS_RANDO && this->getItemEntry.getItemId == RG_ICE_TRAP)) && - this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) { - if (!CVarGetInteger("gAddTraps.enabled", 0)) { - EnBox_SpawnIceSmoke(this, play); - } + if ((this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && + this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) { + EnBox_SpawnIceSmoke(this, play); } } diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h index 765779367..0168fc1a8 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h @@ -4,6 +4,7 @@ #include #include "global.h" +#define ENBOX_PARAMS(type, itemId, treasureFlag) ((type) << 12 | (itemId) << 5 | (treasureFlag)) #define ENBOX_TREASURE_FLAG_UNK_MIN 20 #define ENBOX_TREASURE_FLAG_UNK_MAX 32 @@ -45,7 +46,7 @@ typedef struct EnBox { /* 0x01F9 */ u8 type; /* 0x01FA */ u8 iceSmokeTimer; /* 0x01FB */ u8 unk_1FB; - /* */ GetItemEntry getItemEntry; + /* */ GetItemEntry getItemEntry; // This is only to determine the Chest Style, randomzier item gives are handled elsewhere /* */ Gfx* boxLidDL; /* */ Gfx* boxBodyDL; } EnBox; // size = 0x01FC diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 04123c7b3..b2bd6d65c 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -6,6 +6,7 @@ #include "z_en_cow.h" #include "objects/object_cow/object_cow.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -18,7 +19,6 @@ void func_809E0070(Actor* thisx, PlayState* play); void func_809DF494(EnCow* this, PlayState* play); void func_809DF6BC(EnCow* this, PlayState* play); -void EnCow_MoveForRandomizer(EnCow* this, PlayState* play); void func_809DF778(EnCow* this, PlayState* play); void func_809DF7D8(EnCow* this, PlayState* play); void func_809DF870(EnCow* this, PlayState* play); @@ -107,10 +107,6 @@ void EnCow_Init(Actor* thisx, PlayState* play) { EnCow* this = (EnCow*)thisx; s32 pad; - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_COWS)) { - EnCow_MoveForRandomizer(thisx, play); - } - ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f); switch (this->actor.params) { case 0: @@ -122,18 +118,15 @@ void EnCow_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->colliders[1], &this->actor, &sCylinderInit); func_809DEE9C(this); this->actionFunc = func_809DF96C; - if (play->sceneNum == SCENE_LINKS_HOUSE) { - if (!LINK_IS_ADULT && !CVarGetInteger("gCowOfTime", 0)) { - Actor_Kill(&this->actor); - return; - } - if (!Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE)) { - Actor_Kill(&this->actor); - return; - } + if (GameInteractor_Should(GI_VB_DESPAWN_HORSE_RACE_COW, ( + play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE)) + ), this)) { + Actor_Kill(&this->actor); + return; } + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_COW, this->actor.world.pos.x, - this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 1); + this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 1); this->unk_278 = Rand_ZeroFloat(1000.0f) + 40.0f; this->unk_27A = 0; this->actor.targetMode = 6; @@ -216,30 +209,6 @@ void func_809DF730(EnCow* this, PlayState* play) { } } -void EnCow_MoveForRandomizer(EnCow* this, PlayState* play) { - // Only move the cow body (the tail will be moved with the body) - if (this->actor.params != 0) { - return; - } - - // Move left cow in lon lon tower - if (play->sceneNum == SCENE_LON_LON_BUILDINGS && this->actor.world.pos.x == -108 && this->actor.world.pos.z == -65) { - this->actor.world.pos.x = -229.0f; - this->actor.world.pos.z = 157.0f; - this->actor.shape.rot.y = 15783.0f; - // Move right cow in lon lon stable - } else if (play->sceneNum == SCENE_STABLE && this->actor.world.pos.x == -3 && this->actor.world.pos.z == -254) { - this->actor.world.pos.x += 119.0f; - } -} - -void EnCow_SetCowMilked(EnCow* this, PlayState* play) { - CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z); - Player* player = GET_PLAYER(play); - player->pendingFlag.flagID = cowIdentity.randomizerInf; - player->pendingFlag.flagType = FLAG_RANDOMIZER_INF; -} - void func_809DF778(EnCow* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actor.parent = NULL; @@ -281,23 +250,6 @@ void func_809DF8FC(EnCow* this, PlayState* play) { func_809DF494(this, play); } -bool EnCow_HasBeenMilked(EnCow* this, PlayState* play) { - CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z); - return Flags_GetRandomizerInf(cowIdentity.randomizerInf); -} - -void EnCow_GivePlayerRandomizedItem(EnCow* this, PlayState* play) { - if (!EnCow_HasBeenMilked(this, play)) { - CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z); - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(cowIdentity.randomizerCheck, GI_MILK); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 100.0f); - } else { - // once we've gotten the rando reward from the cow, - // return them to the their default action function - this->actionFunc = func_809DF96C; - } -} - void func_809DF96C(EnCow* this, PlayState* play) { if ((play->msgCtx.ocarinaMode == OCARINA_MODE_00) || (play->msgCtx.ocarinaMode == OCARINA_MODE_04)) { if (DREG(53) != 0) { @@ -308,23 +260,14 @@ void func_809DF96C(EnCow* this, PlayState* play) { if ((this->actor.xzDistToPlayer < 150.0f) && (ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x61A8)) { DREG(53) = 0; - // when randomized with cowsanity, if we haven't gotten the - // reward from this cow yet, give that, otherwise use the - // vanilla cow behavior - if (IS_RANDO && - Randomizer_GetSettingValue(RSK_SHUFFLE_COWS) && - !EnCow_HasBeenMilked(this, play)) { - EnCow_SetCowMilked(this, play); - // setting the ocarina mode here prevents intermittent issues - // with the item get not triggering until walking away - play->msgCtx.ocarinaMode = OCARINA_MODE_00; - this->actionFunc = EnCow_GivePlayerRandomizedItem; + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_COW, true, this)) { + this->actionFunc = func_809DF8FC; + this->actor.flags |= ACTOR_FLAG_WILL_TALK; + func_8002F2CC(&this->actor, play, 170.0f); + this->actor.textId = 0x2006; + } else { return; } - this->actionFunc = func_809DF8FC; - this->actor.flags |= ACTOR_FLAG_WILL_TALK; - func_8002F2CC(&this->actor, play, 170.0f); - this->actor.textId = 0x2006; } else { this->unk_276 |= 4; } diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h index 63dbbddd3..3cd244388 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h @@ -21,4 +21,6 @@ typedef struct EnCow { /* 0x027C */ EnCowActionFunc actionFunc; } EnCow; // size = 0x0280 +void func_809DEE9C(EnCow* enCow); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index 0dd33a8ac..09a5e6cd1 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -16,7 +16,6 @@ void EnDns_Destroy(Actor* thisx, PlayState* play); void EnDns_Update(Actor* thisx, PlayState* play); void EnDns_Draw(Actor* thisx, PlayState* play); -u32 EnDns_RandomizerPurchaseableCheck(EnDns* this); u32 func_809EF5A4(EnDns* this); u32 func_809EF658(EnDns* this); u32 func_809EF70C(EnDns* this); @@ -26,7 +25,6 @@ u32 func_809EF854(EnDns* this); u32 func_809EF8F4(EnDns* this); u32 func_809EF9A4(EnDns* this); -void EnDns_RandomizerPurchase(EnDns* this); void func_809EF9F8(EnDns* this); void func_809EFA28(EnDns* this); void func_809EFA58(EnDns* this); @@ -168,32 +166,6 @@ void EnDns_Init(Actor* thisx, PlayState* play) { this->actor.gravity = -1.0f; this->actor.textId = D_809F040C[this->actor.params]; this->dnsItemEntry = sItemEntries[this->actor.params]; - if (IS_RANDO) { - // Ugly, but the best way we can identify which grotto we are in, same method 3DRando uses, but we'll need to account for entrance rando - s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - this->scrubIdentity = Randomizer_IdentifyScrub(play->sceneNum, this->actor.params, respawnData); - - if ((Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_AFFORDABLE || - Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_RANDOM) && - this->scrubIdentity.itemPrice != -1) { - this->dnsItemEntry->itemPrice = this->scrubIdentity.itemPrice; - } - - if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_EXPENSIVE) { - // temporary workaround: always use 40 rupees as price instead of 70 - if (this->actor.params == 0x0006) { - this->dnsItemEntry->itemPrice = 40; - } - } - - if (this->scrubIdentity.isShuffled) { - this->dnsItemEntry->getItemId = this->scrubIdentity.getItemId; - this->dnsItemEntry->purchaseableCheck = EnDns_RandomizerPurchaseableCheck; - this->dnsItemEntry->setRupeesAndFlags = EnDns_RandomizerPurchase; - this->dnsItemEntry->itemAmount = 1; - this->actor.textId = 0x9000 + (this->scrubIdentity.randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT); - } - } this->actionFunc = EnDns_SetupWait; } @@ -216,13 +188,6 @@ void EnDns_ChangeAnim(EnDns* this, u8 index) { /* Item give checking functions */ -u32 EnDns_RandomizerPurchaseableCheck(EnDns* this) { - if (gSaveContext.rupees < this->dnsItemEntry->itemPrice || Flags_GetRandomizerInf(this->scrubIdentity.randomizerInf)) { - return 0; - } - return 4; -} - u32 func_809EF5A4(EnDns* this) { if ((CUR_CAPACITY(UPG_NUTS) != 0) && (AMMO(ITEM_NUT) >= CUR_CAPACITY(UPG_NUTS))) { return 1; @@ -319,10 +284,6 @@ u32 func_809EF9A4(EnDns* this) { } /* Paying and flagging functions */ -void EnDns_RandomizerPurchase(EnDns* this) { - Rupees_ChangeBy(-this->dnsItemEntry->itemPrice); - Flags_SetRandomizerInf(this->scrubIdentity.randomizerInf); -} void func_809EF9F8(EnDns* this) { Rupees_ChangeBy(-this->dnsItemEntry->itemPrice); @@ -412,44 +373,39 @@ void EnDns_Talk(EnDns* this, PlayState* play) { void func_809EFDD0(EnDns* this, PlayState* play) { u16 pendingGetItemId; - if (!IS_RANDO || !this->scrubIdentity.isShuffled) { - if (this->actor.params == 0x9) { - if (CUR_UPG_VALUE(UPG_STICKS) < 2) { - pendingGetItemId = GI_STICK_UPGRADE_20; - } else { - pendingGetItemId = GI_STICK_UPGRADE_30; - } - } else if (this->actor.params == 0xA) { - if (CUR_UPG_VALUE(UPG_NUTS) < 2) { - pendingGetItemId = GI_NUT_UPGRADE_30; - } else { - pendingGetItemId = GI_NUT_UPGRADE_40; - } + if (this->actor.params == 0x9) { + if (CUR_UPG_VALUE(UPG_STICKS) < 2) { + pendingGetItemId = GI_STICK_UPGRADE_20; } else { - pendingGetItemId = this->dnsItemEntry->getItemId; + pendingGetItemId = GI_STICK_UPGRADE_30; + } + } else if (this->actor.params == 0xA) { + if (CUR_UPG_VALUE(UPG_NUTS) < 2) { + pendingGetItemId = GI_NUT_UPGRADE_30; + } else { + pendingGetItemId = GI_NUT_UPGRADE_40; } - GetItemEntry itemEntry = ItemTable_Retrieve(pendingGetItemId); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - func_8002F434(&this->actor, play, pendingGetItemId, 130.0f, 100.0f); } else { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(this->scrubIdentity.randomizerCheck, this->scrubIdentity.getItemId); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - GiveItemEntryFromActor(&this->actor, play, itemEntry, 130.0f, 100.0f); + pendingGetItemId = this->dnsItemEntry->getItemId; } + GetItemEntry itemEntry = ItemTable_Retrieve(pendingGetItemId); + gSaveContext.pendingSale = itemEntry.itemId; + gSaveContext.pendingSaleMod = itemEntry.modIndex; + func_8002F434(&this->actor, play, pendingGetItemId, 130.0f, 100.0f); } void func_809EFEE8(EnDns* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); - func_809EFDD0(this, play); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB, true, this)) { + func_809EFDD0(this, play); + } this->actionFunc = func_809EFF50; } } void func_809EFF50(EnDns* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB, true, this)) { this->actor.parent = NULL; this->actionFunc = func_809EFF98; } else { @@ -533,9 +489,6 @@ void EnDns_Update(Actor* thisx, PlayState* play) { this->dustTimer++; this->actor.textId = D_809F040C[this->actor.params]; - if (IS_RANDO && this->scrubIdentity.isShuffled) { - this->actor.textId = 0x9000 + (this->scrubIdentity.randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT); - } Actor_SetFocus(&this->actor, 60.0f); Actor_SetScale(&this->actor, 0.01f); SkelAnime_Update(&this->skelAnime); diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h index bf0a3a167..0e3e50c9b 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h @@ -32,7 +32,10 @@ typedef struct EnDns { /* 0x02BD */ u8 dropCollectible; /* 0x02C0 */ DnsItemEntry* dnsItemEntry; /* 0x02C4 */ f32 yInitPos; - /* */ ScrubIdentity scrubIdentity; + // #region SOH [Randomizer] + /* */ DnsItemEntry sohDnsItemEntry; + /* */ ScrubIdentity sohScrubIdentity; + // #endregion } EnDns; // size = 0x02C8 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c index 6da75b1e7..d3a0eadea 100644 --- a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c +++ b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c @@ -6,7 +6,7 @@ #include "z_en_ds.h" #include "objects/object_ds/object_ds.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -90,19 +90,12 @@ void EnDs_DisplayOddPotionText(EnDs* this, PlayState* play) { } void EnDs_GiveOddPotion(EnDs* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_ODD_MUSHROOM, true, this)) { this->actor.parent = NULL; this->actionFunc = EnDs_DisplayOddPotionText; gSaveContext.timer2State = 0; } else { - u32 itemId = GI_ODD_POTION; - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Randomizer_ConsumeAdultTradeItem(play, ITEM_ODD_MUSHROOM); - return; - } - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); + func_8002F434(&this->actor, play, GI_ODD_POTION, 10000.0f, 50.0f); } } @@ -111,13 +104,9 @@ void EnDs_TalkAfterBrewOddPotion(EnDs* this, PlayState* play) { Message_CloseTextbox(play); this->actionFunc = EnDs_GiveOddPotion; u32 itemId = GI_ODD_POTION; - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Randomizer_ConsumeAdultTradeItem(play, ITEM_ODD_MUSHROOM); - return; + if (GameInteractor_Should(GI_VB_TRADE_ODD_MUSHROOM, true, this)) { + func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); } - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); } } @@ -138,7 +127,7 @@ void EnDs_BrewOddPotion2(EnDs* this, PlayState* play) { this->brewTimer -= 1; } else { this->actionFunc = EnDs_BrewOddPotion3; - this->brewTimer = IS_RANDO ? 0 : 60; + this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 60 : 0; Flags_UnsetSwitch(play, 0x3F); } } @@ -148,7 +137,7 @@ void EnDs_BrewOddPotion1(EnDs* this, PlayState* play) { this->brewTimer -= 1; } else { this->actionFunc = EnDs_BrewOddPotion2; - this->brewTimer = IS_RANDO ? 0 : 20; + this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 20 : 0; } Math_StepToF(&this->unk_1E4, 1.0f, 0.01f); @@ -162,7 +151,7 @@ void EnDs_OfferOddPotion(EnDs* this, PlayState* play) { switch (play->msgCtx.choiceIndex) { case 0: // yes this->actionFunc = EnDs_BrewOddPotion1; - this->brewTimer = IS_RANDO ? 0 : 60; + this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 60 : 0; Flags_SetSwitch(play, 0x3F); play->msgCtx.msgMode = MSGMODE_PAUSED; player->exchangeItemId = EXCH_ITEM_NONE; @@ -174,22 +163,10 @@ void EnDs_OfferOddPotion(EnDs* this, PlayState* play) { } } -u8 EnDs_RandoCanGetGrannyItem() { - return IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) && - // Traded odd mushroom when adult trade is on - ((Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) && Flags_GetItemGetInf(ITEMGETINF_30)) || - // Found claim check when adult trade is off - (!Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) && - INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)); -} - s32 EnDs_CheckRupeesAndBottle() { if (gSaveContext.rupees < 100) { return 0; - } else if (EnDs_RandoCanGetGrannyItem()) { // Allow buying the rando item regardless of having a bottle - return 2; - } else if (Inventory_HasEmptyBottle() == 0) { + } else if (GameInteractor_Should(GI_VB_NEED_BOTTLE_FOR_GRANNYS_ITEM, Inventory_HasEmptyBottle() == 0, NULL)) { return 1; } else { return 2; @@ -197,20 +174,11 @@ s32 EnDs_CheckRupeesAndBottle() { } void EnDs_GiveBluePotion(EnDs* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { - if (EnDs_RandoCanGetGrannyItem()) { - Flags_SetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP); - } - + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) { this->actor.parent = NULL; this->actionFunc = EnDs_Talk; } else { - if (EnDs_RandoCanGetGrannyItem()) { - GetItemEntry entry = Randomizer_GetItemFromKnownCheck(RC_KAK_GRANNYS_SHOP, GI_POTION_BLUE); - GiveItemEntryFromActor(&this->actor, play, entry, 10000.0f, 50.0f); - } else { - func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); - } + func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); } } @@ -229,18 +197,14 @@ void EnDs_OfferBluePotion(EnDs* this, PlayState* play) { case 2: // have 100 rupees and empty bottle Rupees_ChangeBy(-100); this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; - GetItemEntry itemEntry; - if (EnDs_RandoCanGetGrannyItem()) { - itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_GRANNYS_SHOP, GI_POTION_BLUE); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - } else { - itemEntry = ItemTable_Retrieve(GI_POTION_BLUE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) { + GetItemEntry itemEntry = ItemTable_Retrieve(GI_POTION_BLUE); func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); + gSaveContext.pendingSale = itemEntry.itemId; + gSaveContext.pendingSaleMod = itemEntry.modIndex; } - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; this->actionFunc = EnDs_GiveBluePotion; return; } @@ -261,10 +225,7 @@ void EnDs_Wait(EnDs* this, PlayState* play) { Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); player->actor.textId = 0x504A; this->actionFunc = EnDs_OfferOddPotion; - } else if ( - // Always offer blue potion when adult trade is off - (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF) || - Flags_GetItemGetInf(ITEMGETINF_30)) { // Traded odd mushroom + } else if (GameInteractor_Should(GI_VB_OFFER_BLUE_POTION, Flags_GetItemGetInf(ITEMGETINF_30), this)) { // Traded odd mushroom player->actor.textId = 0x500C; this->actionFunc = EnDs_OfferBluePotion; } else { diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c index db13ecc54..6f99f070f 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c @@ -1,6 +1,7 @@ #include "z_en_du.h" #include "objects/object_du/object_du.h" #include "scenes/overworld/spot18/spot18_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -376,7 +377,7 @@ void func_809FE4A4(EnDu* this, PlayState* play) { play->msgCtx.ocarinaMode = OCARINA_MODE_00; EnDu_SetupAction(this, func_809FE3C0); } else if (play->msgCtx.ocarinaMode >= OCARINA_MODE_06) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_DARUNIAS_JOY_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gGoronCityDaruniaWrongCs); gSaveContext.cutsceneTrigger = 1; } @@ -385,7 +386,7 @@ void func_809FE4A4(EnDu* this, PlayState* play) { play->msgCtx.ocarinaMode = OCARINA_MODE_04; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_DARUNIAS_JOY_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gGoronCityDaruniaCorrectCs); gSaveContext.cutsceneTrigger = 1; } @@ -474,10 +475,7 @@ void func_809FE890(EnDu* this, PlayState* play) { Vec3f velocity = { 0.0f, 0.0f, 0.0f }; CsCmdActorAction* csAction; - if (play->csCtx.state == CS_STATE_IDLE || IS_RANDO) { - if (IS_RANDO) { - play->csCtx.state = CS_STATE_IDLE; - } + if (play->csCtx.state == CS_STATE_IDLE) { func_8002DF54(play, &this->actor, 1); EnDu_SetupAction(this, func_809FEB08); return; @@ -556,11 +554,8 @@ void func_809FEB08(EnDu* this, PlayState* play) { EnDu_SetupAction(this, func_809FE3C0); return; } - if ((!IS_RANDO && CUR_UPG_VALUE(UPG_STRENGTH) <= 0) || - (IS_RANDO && !Flags_GetTreasure(play, 0x1E))) { - if (IS_RANDO) { - Flags_SetTreasure(play, 0x1E); - } + if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD, CUR_UPG_VALUE(UPG_STRENGTH) <= 0, NULL)) { + Flags_SetRandomizerInf(RAND_INF_DARUNIAS_JOY); this->actor.textId = 0x301C; EnDu_SetupAction(this, func_809FEC14); } else { @@ -581,17 +576,13 @@ void func_809FEC14(EnDu* this, PlayState* play) { } void func_809FEC70(EnDu* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_STRENGTH_1, true, NULL)) { this->actor.parent = NULL; EnDu_SetupAction(this, func_809FECE4); } else { f32 xzRange = this->actor.xzDistToPlayer + 1.0f; - if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); - } + + func_8002F434(&this->actor, play, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c index 11a7eb026..1c16a0eb0 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -45,7 +45,6 @@ void EnFr_OcarinaMistake(EnFr* this, PlayState* play); void EnFr_SetupReward(EnFr* this, PlayState* play, u8 unkCondition); void EnFr_PrintTextBox(EnFr* this, PlayState* play); void EnFr_TalkBeforeReward(EnFr* this, PlayState* play); -RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex); void EnFr_SetReward(EnFr* this, PlayState* play); // Deactivate @@ -618,7 +617,6 @@ void EnFr_Idle(EnFr* this, PlayState* play) { player->actor.world.pos.z = this->actor.world.pos.z; // z = -1220.0f player->currentYaw = player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y; this->reward = GI_NONE; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = EnFr_Activate; } else if (EnFr_IsAboveAndWithin30DistXZ(player, this)) { player->unk_6A8 = &this->actor; @@ -854,7 +852,6 @@ s32 EnFr_IsFrogSongComplete(EnFr* this, PlayState* play) { void EnFr_OcarinaMistake(EnFr* this, PlayState* play) { Message_CloseTextbox(play); this->reward = GI_NONE; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; func_80078884(NA_SE_SY_OCARINA_ERROR); Audio_OcaSetInstrument(0); sEnFrPointers.flags = 12; @@ -939,23 +936,6 @@ void EnFr_TalkBeforeReward(EnFr* this, PlayState* play) { } } -RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex) { - switch (songIndex) { - case FROG_ZL: - return RC_ZR_FROGS_ZELDAS_LULLABY; - case FROG_EPONA: - return RC_ZR_FROGS_EPONAS_SONG; - case FROG_SARIA: - return RC_ZR_FROGS_SARIAS_SONG; - case FROG_SUNS: - return RC_ZR_FROGS_SUNS_SONG; - case FROG_SOT: - return RC_ZR_FROGS_SONG_OF_TIME; - default: - return RC_UNKNOWN_CHECK; - } -} - void EnFr_SetReward(EnFr* this, PlayState* play) { u16 songIndex; @@ -963,16 +943,12 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { songIndex = this->songIndex; this->actionFunc = EnFr_Deactivate; this->reward = GI_NONE; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; if ((songIndex >= FROG_ZL) && (songIndex <= FROG_SOT)) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { this->reward = GI_RUPEE_PURPLE; - } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(EnFr_RandomizerCheckFromSongIndex(songIndex), GI_RUPEE_PURPLE); - this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_BLUE; @@ -981,11 +957,8 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { this->reward = GI_HEART_PIECE; - } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_FROGS_IN_THE_RAIN, GI_HEART_PIECE); - this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_BLUE; @@ -994,11 +967,8 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { this->reward = GI_HEART_PIECE; - } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_FROGS_OCARINA_GAME, GI_HEART_PIECE); - this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_PURPLE; @@ -1049,29 +1019,23 @@ void EnFr_Deactivate(EnFr* this, PlayState* play) { this->actionFunc = EnFr_Idle; } else { this->actionFunc = EnFr_GiveReward; - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 30.0f, 100.0f); } } } void EnFr_GiveReward(EnFr* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { this->actor.parent = NULL; this->actionFunc = EnFr_SetIdle; } else { - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 30.0f, 100.0f); - } + func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f); } } void EnFr_SetIdle(EnFr* this, PlayState* play) { - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play) || (IS_RANDO && this->reward == RG_ICE_TRAP)) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { this->actionFunc = EnFr_Idle; } } diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h index 19d612fdd..17b8b162e 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h @@ -73,7 +73,6 @@ typedef struct EnFr { /* 0x03AA */ s16 xyAngleButterfly; // Butterfly Travels along random angles in the x-y plane /* 0x03AC */ Vec3f posButterfly; // Position/Coordinates of the Butterfly /* 0x03B8 */ Vec3f posButterflyLight; // Used in Lights_PointNoGlowSetInfo() - /* */ GetItemEntry getItemEntry; } EnFr; // size = 0x03C4 typedef struct { @@ -81,4 +80,7 @@ typedef struct { EnFr* frogs[5]; } EnFrPointers; +void EnFr_Idle(EnFr* enFr, PlayState* play); +void EnFr_GiveReward(EnFr* enFr, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c index 4986f24f6..22754a87a 100644 --- a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -8,6 +8,7 @@ #include "objects/object_oF1d_map/object_oF1d_map.h" #include "objects/object_gm/object_gm.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -96,10 +97,9 @@ void EnGm_Destroy(Actor* thisx, PlayState* play) { s32 func_80A3D7C8(void) { if (LINK_AGE_IN_YEARS == YEARS_CHILD) { return 0; - } else if ((IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF) && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - return 1; - } else if (!CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON)) { // Don't have giant's knife + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE, ( + !CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON) // Don't have giant's knife + ), NULL)) { return 1; } else if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) { // Have broken giant's knife return 2; @@ -215,11 +215,6 @@ void func_80A3DC44(EnGm* this, PlayState* play) { return; case 1: Flags_SetInfTable(INFTABLE_B1); - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - //Resets "Talked to Medigoron" flag in infTable to restore initial conversation state - Flags_UnsetInfTable(INFTABLE_B1); - } case 2: this->actionFunc = EnGm_ProcessChoiceIndex; default: @@ -254,20 +249,10 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) { Message_ContinueTextbox(play, 0xC8); this->actionFunc = func_80A3DD7C; } else { - GetItemEntry itemEntry; - - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 415.0f, 10.0f); - Flags_SetInfTable(INFTABLE_B1); - } else { - itemEntry = ItemTable_Retrieve(GI_SWORD_KNIFE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MEDIGORON, true, this)) { func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); } - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; this->actionFunc = func_80A3DF00; } break; @@ -280,24 +265,12 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) { } void func_80A3DF00(EnGm* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON); - } - + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MEDIGORON, true, this)) { + Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON); this->actor.parent = NULL; this->actionFunc = func_80A3DF60; } else { - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 415.0f, 10.0f); - Flags_SetInfTable(INFTABLE_B1); - } - else { - func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); - } + func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index 3094f2171..7dc67f427 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -3,7 +3,6 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_oF1d_map/object_oF1d_map.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -31,9 +30,11 @@ void func_80A40C78(EnGo* this, PlayState* play); void EnGo_Eyedrops(EnGo* this, PlayState* play); void func_80A40DCC(EnGo* this, PlayState* play); -void EnGo_AddDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep); -void EnGo_UpdateDust(EnGo* this); -void EnGo_DrawDust(EnGo* this, PlayState* play); + +void EnGo_SpawnEffectDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, + f32 scaleStep); +void EnGo_UpdateEffects(EnGo* this); +void EnGo_DrawEffects(EnGo* this, PlayState* play); const ActorInit En_Go_InitVars = { ACTOR_EN_GO, @@ -95,10 +96,10 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { switch (thisx->params & 0xF0) { case 0x90: - if (!IS_RANDO && gSaveContext.bgsFlag) { + if (gSaveContext.bgsFlag) { return 0x305E; } else if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_CLAIM_CHECK) { - if (Environment_GetBgsDayCount() >= CVarGetInteger("gForgeTime", 3)) { + if (Environment_GetBgsDayCount() >= 3) { return 0x305E; } else { return 0x305D; @@ -113,8 +114,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { return 0x3053; } case 0x00: - if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) { + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { if (Flags_GetInfTable(INFTABLE_10F)) { return 0x3042; } else { @@ -199,7 +199,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { - s16 unkState = NPC_TALK_STATE_TALKING; + s16 talkState = NPC_TALK_STATE_TALKING; f32 xzRange; f32 yRange = fabsf(thisx->yDistToPlayer) + 1.0f; @@ -210,51 +210,51 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { switch (thisx->textId) { case 0x3008: Flags_SetInfTable(INFTABLE_E0); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x300B: Flags_SetInfTable(INFTABLE_EB); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3014: Flags_SetInfTable(INFTABLE_F0); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3016: Flags_SetInfTable(INFTABLE_F4); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3018: Flags_SetInfTable(INFTABLE_F8); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3036: func_8002F434(thisx, play, GI_TUNIC_GORON, xzRange, yRange); Flags_SetInfTable(INFTABLE_10D); // EnGo exclusive flag - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; case 0x3037: Flags_SetInfTable(INFTABLE_SPOKE_TO_GORON_LINK); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3041: Flags_SetInfTable(INFTABLE_10F); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3059: - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; case 0x3052: case 0x3054: case 0x3055: case 0x305A: - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; case 0x305E: - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; default: - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; } break; @@ -272,7 +272,7 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { thisx->textId = 0x300D; } Message_ContinueTextbox(play, thisx->textId); - unkState = NPC_TALK_STATE_TALKING; + talkState = NPC_TALK_STATE_TALKING; break; case 0x3034: if (play->msgCtx.choiceIndex == 0) { @@ -287,16 +287,16 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { thisx->textId = 0x3033; } Message_ContinueTextbox(play, thisx->textId); - unkState = NPC_TALK_STATE_TALKING; + talkState = NPC_TALK_STATE_TALKING; break; case 0x3054: case 0x3055: if (play->msgCtx.choiceIndex == 0) { - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; } else { thisx->textId = 0x3056; Message_ContinueTextbox(play, thisx->textId); - unkState = NPC_TALK_STATE_TALKING; + talkState = NPC_TALK_STATE_TALKING; } Flags_SetInfTable(INFTABLE_B4); break; @@ -312,17 +312,17 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { case 0x3033: thisx->textId = 0x3034; Message_ContinueTextbox(play, thisx->textId); - unkState = NPC_TALK_STATE_TALKING; + talkState = NPC_TALK_STATE_TALKING; break; default: - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; } } break; case TEXT_STATE_DONE: if (Message_ShouldAdvance(play)) { - unkState = NPC_TALK_STATE_ITEM_GIVEN; + talkState = NPC_TALK_STATE_ITEM_GIVEN; } break; case TEXT_STATE_NONE: @@ -332,21 +332,21 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { case TEXT_STATE_9: break; } - return unkState; + return talkState; } -s32 func_80A3ED24(PlayState* play, EnGo* this, NpcInteractInfo* interactInfo, f32 arg3, NpcGetTextIdFunc getTextId, +s32 EnGo_UpdateTalking(PlayState* play, Actor* thisx, s16* talkState, f32 interactRange, NpcGetTextIdFunc getTextId, NpcUpdateTalkStateFunc updateTalkState) { - if (interactInfo->talkState != NPC_TALK_STATE_IDLE) { - interactInfo->talkState = updateTalkState(play, &this->actor); + if (*talkState != NPC_TALK_STATE_IDLE) { + *talkState = updateTalkState(play, thisx); return false; - } else if (Actor_ProcessTalkRequest(&this->actor, play)) { - interactInfo->talkState = NPC_TALK_STATE_TALKING; + } else if (Actor_ProcessTalkRequest(thisx, play)) { + *talkState = NPC_TALK_STATE_TALKING; return true; - } else if (!func_8002F2CC(&this->actor, play, arg3)) { + } else if (!func_8002F2CC(thisx, play, interactRange)) { return false; } else { - this->actor.textId = getTextId(play, &this->actor); + thisx->textId = getTextId(play, thisx); return false; } } @@ -379,7 +379,7 @@ s32 EnGo_IsActorSpawned(EnGo* this, PlayState* play) { } } -f32 EnGo_GetGoronSize(EnGo* this) { +f32 EnGo_GetPlayerTrackingYOffset(EnGo* this) { switch (this->actor.params & 0xF0) { case 0x00: return 10.0f; @@ -398,16 +398,16 @@ f32 EnGo_GetGoronSize(EnGo* this) { void func_80A3F060(EnGo* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 npcTrackingMode; + s16 trackingMode; if (this->actionFunc != EnGo_BiggoronActionFunc && this->actionFunc != EnGo_FireGenericActionFunc && this->actionFunc != func_80A40B1C) { - npcTrackingMode = NPC_TRACKING_NONE; + trackingMode = NPC_TRACKING_NONE; } this->interactInfo.trackPos = player->actor.world.pos; - this->interactInfo.yOffset = EnGo_GetGoronSize(this); - Npc_TrackPoint(&this->actor, &this->interactInfo, 4, npcTrackingMode); + this->interactInfo.yOffset = EnGo_GetPlayerTrackingYOffset(this); + Npc_TrackPoint(&this->actor, &this->interactInfo, 4, trackingMode); } void func_80A3F0E4(EnGo* this) { @@ -421,23 +421,23 @@ void func_80A3F0E4(EnGo* this) { } s32 EnGo_IsCameraModified(EnGo* this, PlayState* play) { - f32 xyzDist; + f32 xyzDistSq; s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - Camera* camera = play->cameraPtrs[MAIN_CAM]; + Camera* mainCam = play->cameraPtrs[MAIN_CAM]; if (fabsf(yawDiff) > 10920.0f) { return 0; } - xyzDist = (this->actor.scale.x / 0.01f) * 10000.0f; + xyzDistSq = (this->actor.scale.x / 0.01f) * SQ(100.0f); if ((this->actor.params & 0xF0) == 0x90) { - Camera_ChangeSetting(camera, CAM_SET_DIRECTED_YAW); - xyzDist *= 4.8f; + Camera_ChangeSetting(mainCam, CAM_SET_DIRECTED_YAW); + xyzDistSq *= 4.8f; } - if (fabsf(this->actor.xyzDistToPlayerSq) > xyzDist) { - if (camera->setting == CAM_SET_DIRECTED_YAW) { - Camera_ChangeSetting(camera, CAM_SET_NORMAL0); + if (fabsf(this->actor.xyzDistToPlayerSq) > xyzDistSq) { + if (mainCam->setting == CAM_SET_DIRECTED_YAW) { + Camera_ChangeSetting(mainCam, CAM_SET_NORMAL0); } return 0; } else { @@ -480,7 +480,7 @@ s32 EnGo_FollowPath(EnGo* this, PlayState* play) { pointPos += this->unk_218; xDist = pointPos->x - this->actor.world.pos.x; zDist = pointPos->z - this->actor.world.pos.z; - Math_SmoothStepToS(&this->actor.world.rot.y, (s16)(Math_FAtan2F(xDist, zDist) * ((f32)0x8000 / M_PI)), 10, 1000, 1); + Math_SmoothStepToS(&this->actor.world.rot.y, RADF_TO_BINANG(Math_FAtan2F(xDist, zDist)), 10, 1000, 1); if ((SQ(xDist) + SQ(zDist)) < 600.0f) { this->unk_218++; @@ -536,7 +536,7 @@ s32 EnGo_SpawnDust(EnGo* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 nu accel.z = (Rand_ZeroOne() - 0.5f) * xzAccel; pos.x = (Math_SinS(angle) * radius) + this->actor.world.pos.x; pos.z = (Math_CosS(angle) * radius) + this->actor.world.pos.z; - EnGo_AddDust(this, &pos, &velocity, &accel, initialTimer, scale, scaleStep); + EnGo_SpawnEffectDust(this, &pos, &velocity, &accel, initialTimer, scale, scaleStep); angle += (s16)(0x10000 / numDustEffects); i--; } @@ -549,7 +549,7 @@ s32 EnGo_IsRollingOnGround(EnGo* this, s16 unkArg1, f32 unkArg2) { } else if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { return true; } else if (DECR(this->unk_21C)) { - if ((this->unk_21C & 1)) { + if (this->unk_21C & 1) { this->actor.world.pos.y += 1.5f; } else { this->actor.world.pos.y -= 1.5f; @@ -573,29 +573,29 @@ s32 EnGo_IsRollingOnGround(EnGo* this, s16 unkArg1, f32 unkArg2) { void func_80A3F908(EnGo* this, PlayState* play) { Player* player = GET_PLAYER(play); - f32 float1; - s32 isUnkCondition; + f32 interactRange; + s32 dialogStarted; if (this->actionFunc == EnGo_BiggoronActionFunc || this->actionFunc == EnGo_GoronLinkRolling || this->actionFunc == EnGo_FireGenericActionFunc || this->actionFunc == EnGo_Eyedrops || this->actionFunc == func_80A40DCC || this->actionFunc == EnGo_GetItem || this->actionFunc == func_80A40C78 || this->actionFunc == func_80A40B1C) { - float1 = (this->collider.dim.radius + 30.0f); - float1 *= (this->actor.scale.x / 0.01f); + interactRange = (this->collider.dim.radius + 30.0f); + interactRange *= (this->actor.scale.x / 0.01f); if ((this->actor.params & 0xF0) == 0x90) { - float1 *= 4.8f; + interactRange *= 4.8f; } if ((this->actor.params & 0xF0) == 0x90) { - isUnkCondition = - func_80A3ED24(play, this, &this->interactInfo, float1, EnGo_GetTextID, EnGo_UpdateTalkState); + dialogStarted = + EnGo_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, interactRange, EnGo_GetTextID, EnGo_UpdateTalkState); } else { - isUnkCondition = Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, float1, + dialogStarted = Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, interactRange, EnGo_GetTextID, EnGo_UpdateTalkState); } - if (((this->actor.params & 0xF0) == 0x90) && (isUnkCondition == true)) { + if (((this->actor.params & 0xF0) == 0x90) && (dialogStarted == true)) { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_SWORD_BROKEN) { if (func_8002F368(play) == EXCH_ITEM_SWORD_BROKEN) { if (Flags_GetInfTable(INFTABLE_B4)) { @@ -628,7 +628,7 @@ void EnGo_Init(Actor* thisx, PlayState* play) { Vec3f D_80A41BA8 = { 0.0f, 0.0f, 0.0f }; // unused ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); - SkelAnime_InitFlex(play, &this->skelAnime, &gGoronSkel, NULL, 0, 0, 0); + SkelAnime_InitFlex(play, &this->skelAnime, &gGoronSkel, NULL, NULL, NULL, 0); Collider_InitCylinder(play, &this->collider); Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); @@ -711,8 +711,8 @@ void EnGo_StopRolling(EnGo* this, PlayState* play) { EnBom* bomb; if (DECR(this->unk_20E) == 0) { - if (this->collider.base.ocFlags2 & 1) { - this->collider.base.ocFlags2 &= ~1; + if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { + this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; play->damagePlayer(play, -4); func_8002F71C(play, &this->actor, 4.0f, this->actor.yawTowardsPlayer, 6.0f); this->unk_20E = 0x10; @@ -859,7 +859,7 @@ void func_80A405CC(EnGo* this, PlayState* play) { void EnGo_BiggoronActionFunc(EnGo* this, PlayState* play) { if (((this->actor.params & 0xF0) == 0x90) && (this->interactInfo.talkState == NPC_TALK_STATE_ACTION)) { - if (!IS_RANDO && gSaveContext.bgsFlag) { + if (gSaveContext.bgsFlag) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } else { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) { @@ -958,45 +958,25 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { this->unk_20C = 0; if ((this->actor.params & 0xF0) == 0x90) { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { - if (!IS_RANDO) { - getItemId = GI_SWORD_BGS; - } else { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS); - getItemId = getItemEntry.getItemId; - } + getItemId = GI_SWORD_BGS; this->unk_20C = 1; } if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) { - if (IS_RANDO) { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK); - getItemId = getItemEntry.getItemId; - Randomizer_ConsumeAdultTradeItem(play, ITEM_EYEDROPS); - } else { - getItemId = GI_CLAIM_CHECK; - } + getItemId = GI_CLAIM_CHECK; } if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_SWORD_BROKEN) { - if (IS_RANDO) { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION); - Randomizer_ConsumeAdultTradeItem(play, ITEM_SWORD_BROKEN); - getItemId = getItemEntry.getItemId; - } else { - getItemId = GI_PRESCRIPTION; - } + getItemId = GI_PRESCRIPTION; } } if ((this->actor.params & 0xF0) == 0) { getItemId = GI_TUNIC_GORON; + Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT); } yDist = fabsf(this->actor.yDistToPlayer) + 1.0f; xzDist = this->actor.xzDistToPlayer + 1.0f; - if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, xzDist, yDist); - } else { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, xzDist, yDist); - } + func_8002F434(&this->actor, play, getItemId, xzDist, yDist); } } @@ -1105,32 +1085,30 @@ void EnGo_DrawRolling(EnGo* this, PlayState* play) { s32 EnGo_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { EnGo* this = (EnGo*)thisx; - Vec3s vec1; + Vec3s limbRot; f32 float1; if (limb == 17) { Matrix_Translate(2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); - vec1 = this->interactInfo.headRot; - float1 = (vec1.y / (f32)0x8000) * M_PI; + limbRot = this->interactInfo.headRot; + float1 = (limbRot.y / (f32)0x8000) * M_PI; Matrix_RotateX(float1, MTXMODE_APPLY); - float1 = (vec1.x / (f32)0x8000) * M_PI; + float1 = (limbRot.x / (f32)0x8000) * M_PI; Matrix_RotateZ(float1, MTXMODE_APPLY); Matrix_Translate(-2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limb == 10) { - vec1 = this->interactInfo.torsoRot; - float1 = (vec1.y / (f32)0x8000) * M_PI; + limbRot = this->interactInfo.torsoRot; + float1 = (limbRot.y / (f32)0x8000) * M_PI; Matrix_RotateY(float1, MTXMODE_APPLY); - float1 = (vec1.x / (f32)0x8000) * M_PI; + float1 = (limbRot.x / (f32)0x8000) * M_PI; Matrix_RotateX(float1, MTXMODE_APPLY); } if ((limb == 10) || (limb == 11) || (limb == 14)) { - float1 = Math_SinS(this->jointTable[limb]); - rot->y += float1 * 200.0f; - float1 = Math_CosS(this->morphTable[limb]); - rot->z += float1 * 200.0f; + rot->y += Math_SinS(this->jointTable[limb]) * 200.0f; + rot->z += Math_CosS(this->morphTable[limb]) * 200.0f; } return 0; @@ -1150,9 +1128,9 @@ void EnGo_Draw(Actor* thisx, PlayState* play) { OPEN_DISPS(play->state.gfxCtx); - EnGo_UpdateDust(this); + EnGo_UpdateEffects(this); Matrix_Push(); - EnGo_DrawDust(this, play); + EnGo_DrawEffects(this, play); Matrix_Pop(); if (this->actionFunc == EnGo_CurledUp) { @@ -1167,39 +1145,36 @@ void EnGo_Draw(Actor* thisx, PlayState* play) { gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(gGoronCsMouthNeutralTex)); SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnGo_OverrideLimbDraw, EnGo_PostLimbDraw, &this->actor); - EnGo_DrawDust(this, play); + EnGo_DrawEffects(this, play); } CLOSE_DISPS(play->state.gfxCtx); } -void EnGo_AddDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep) { - EnGoEffect* dustEffect = this->dustEffects; +void EnGo_SpawnEffectDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep) { + EnGoEffect* dustEffect = this->effects; s16 i; - s16 timer; - for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) { + for (i = 0; i < EN_GO_EFFECT_COUNT; i++, dustEffect++) { if (dustEffect->type != 1) { dustEffect->epoch++; dustEffect->scale = scale; dustEffect->scaleStep = scaleStep; - timer = initialTimer; - dustEffect->timer = timer; + dustEffect->initialTimer = dustEffect->timer = initialTimer; dustEffect->type = 1; - dustEffect->initialTimer = initialTimer; dustEffect->pos = *pos; dustEffect->accel = *accel; dustEffect->velocity = *velocity; - return; + break; } } } -void EnGo_UpdateDust(EnGo* this) { - EnGoEffect* dustEffect = this->dustEffects; +void EnGo_UpdateEffects(EnGo* this) { + EnGoEffect* dustEffect = this->effects; f32 randomNumber; s16 i; - for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) { + for (i = 0; i < EN_GO_EFFECT_COUNT; i++, dustEffect++) { if (dustEffect->type) { dustEffect->timer--; if (dustEffect->timer == 0) { @@ -1220,24 +1195,24 @@ void EnGo_UpdateDust(EnGo* this) { } } -void EnGo_DrawDust(EnGo* this, PlayState* play) { +void EnGo_DrawEffects(EnGo* this, PlayState* play) { static void* dustTex[] = { gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex }; - EnGoEffect* dustEffect = this->dustEffects; + EnGoEffect* dustEffect = this->effects; s16 alpha; - s16 firstDone; + s16 materialFlag; s16 index; s16 i; OPEN_DISPS(play->state.gfxCtx); - firstDone = false; + materialFlag = false; Gfx_SetupDL_25Xlu(play->state.gfxCtx); - for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) { + for (i = 0; i < EN_GO_EFFECT_COUNT; i++, dustEffect++) { if (dustEffect->type) { - if (!firstDone) { + if (!materialFlag) { POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, 0); gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD40); gDPSetEnvColor(POLY_XLU_DISP++, 100, 60, 20, 0); - firstDone = true; + materialFlag = true; } FrameInterpolation_RecordOpenChild(dustEffect, dustEffect->epoch); diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.h b/soh/src/overlays/actors/ovl_En_Go/z_en_go.h index 7b3224aec..1b1320988 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.h +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.h @@ -16,12 +16,13 @@ typedef s16 (*callback2_80A3ED24)(PlayState*, struct EnGo*); // /* 0x20 */ GORON1_DMT_DC_ENTRANCE, // /* 0x30 */ GORON1_DMT_ROLLING_SMALL, // /* 0x40 */ GORON1_DMT_BOMB_FLOWER, -// /* 0x50 */ GORON1_CITY_ENTRANCE, +// /* 0x50 */ GORON1_CITY_ENTRANCE, // /* 0x60 */ GORON1_CITY_ISLAND, -// /* 0x70 */ GORON1_CITY_LOST_WOODS, +// /* 0x70 */ GORON1_CITY_LOST_WOODS, // /* 0x80 */ // Not Used // /* 0x90 */ GORON1_DMT_BIGGORON, +#define EN_GO_EFFECT_COUNT 20 typedef struct { /* 0x0000 */ u8 type; @@ -56,7 +57,7 @@ typedef struct EnGo { /* 0x021E */ s16 unk_21E; /* 0x0220 */ s16 jointTable[18]; /* 0x0244 */ s16 morphTable[18]; - /* 0x0268 */ EnGoEffect dustEffects[20]; + /* 0x0268 */ EnGoEffect effects[EN_GO_EFFECT_COUNT]; } EnGo; // size = 0x06C8 #endif diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index a4aede2e5..86d1b488a 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -3,7 +3,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_oF1d_map/object_oF1d_map.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -335,7 +335,8 @@ u16 EnGo2_GoronFireGenericGetTextId(EnGo2* this) { u16 EnGo2_GetTextIdGoronCityRollingBig(PlayState* play, EnGo2* this) { if (Flags_GetInfTable(INFTABLE_11E)) { return 0x3013; - } else if ((CUR_CAPACITY(UPG_BOMB_BAG) >= 20 || IS_RANDO) && this->waypoint > 7 && this->waypoint < 12) { + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD, CUR_CAPACITY(UPG_BOMB_BAG) >= 2, this) + && this->waypoint > 7 && this->waypoint < 12) { return 0x3012; } else { return 0x3011; @@ -350,13 +351,14 @@ s16 EnGo2_UpdateTalkStateGoronCityRollingBig(PlayState* play, EnGo2* this) { if (Message_ShouldAdvance(play)) { if (this->actor.textId == 0x3012) { this->actionFunc = EnGo2_SetupGetItem; - if(!IS_RANDO) { + if(GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD, true, this)) { EnGo2_GetItem(this, play, CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30); } else { - EnGo2_GetItemEntry(this, play, Randomizer_GetItemFromKnownCheck(RC_GC_ROLLING_GORON_AS_CHILD, GI_BOMB_BAG_40)); + this->actionFunc = EnGo2_SetGetItem; } Message_CloseTextbox(play); Flags_SetInfTable(INFTABLE_11E); + Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_CHILD); return NPC_TALK_STATE_ACTION; } else { return NPC_TALK_STATE_ACTION; @@ -416,11 +418,9 @@ s16 EnGo2_UpdateTalkStateGoronDmtRollingSmall(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronDmtDcEntrance(PlayState* play, EnGo2* this) { - if (((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { return 0x3043; - } else if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN))) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, CHECK_QUEST_ITEM(QUEST_GORON_RUBY), NULL)) { return 0x3027; } else { return Flags_GetEventChkInf(EVENTCHKINF_BOMBED_DODONGOS_CAVERN_ENTRANCE) ? 0x3021 : Flags_GetInfTable(INFTABLE_E0) ? 0x302A : 0x3008; @@ -439,11 +439,9 @@ s16 EnGo2_UpdateTalkStateGoronDmtDcEntrance(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronCityEntrance(PlayState* play, EnGo2* this) { - if (((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { return 0x3043; - } else if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN))) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, CHECK_QUEST_ITEM(QUEST_GORON_RUBY), NULL)) { return 0x3027; } else { return Flags_GetInfTable(INFTABLE_F0) ? 0x3015 : 0x3014; @@ -462,11 +460,9 @@ s16 EnGo2_UpdateTalkStateGoronCityEntrance(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronCityIsland(PlayState* play, EnGo2* this) { - if (((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { return 0x3043; - } else if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN))) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, CHECK_QUEST_ITEM(QUEST_GORON_RUBY), NULL)) { return 0x3027; } else { return Flags_GetInfTable(INFTABLE_F4) ? 0x3017 : 0x3016; @@ -485,11 +481,9 @@ s16 EnGo2_UpdateTalkStateGoronCityIsland(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronCityLowestFloor(PlayState* play, EnGo2* this) { - if (((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { return 0x3043; - } else if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN))) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, CHECK_QUEST_ITEM(QUEST_GORON_RUBY), NULL)) { return 0x3027; } else { return CUR_UPG_VALUE(UPG_STRENGTH) != 0 ? 0x302C @@ -511,18 +505,10 @@ s16 EnGo2_UpdateTalkStateGoronCityLowestFloor(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronCityLink(PlayState* play, EnGo2* this) { - // For rando, prioritize opening the doors in GC when Link the goron has been stopped when - // the doors are not opened, otherwise let him talk about the DMC exit or that gorons are saved - if (IS_RANDO) { - if (!Flags_GetInfTable(INFTABLE_STOPPED_GORON_LINKS_ROLLING)) { - return 0x3030; - } else if (!Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED)) { - return 0x3036; - } else if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE)) { - return 0x3041; - } else { - return Flags_GetInfTable(INFTABLE_SPOKE_TO_GORON_LINK) ? 0x3038 : 0x3037; - } + // In case a hook neglects to set the override, fall back to the first dialogue + u16 overrideTextId = 0x3030; + if (GameInteractor_Should(GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE, false, &overrideTextId)) { + return overrideTextId; } if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { @@ -543,20 +529,15 @@ s16 EnGo2_UpdateTalkStateGoronCityLink(PlayState* play, EnGo2* this) { case TEXT_STATE_CLOSING: switch (this->actor.textId) { case 0x3036: - if (!IS_RANDO) { + Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT); + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_ADULT, true, this)) { EnGo2_GetItem(this, play, GI_TUNIC_GORON); this->actionFunc = EnGo2_SetupGetItem; return NPC_TALK_STATE_ACTION; } else { - if (Flags_GetTreasure(play, 0x1F)) { - return NPC_TALK_STATE_IDLE; - } - - Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); - EnGo2_GetItemEntry(this, play, Randomizer_GetItemFromKnownCheck(RC_GC_ROLLING_GORON_AS_ADULT, GI_TUNIC_GORON)); - this->actionFunc = EnGo2_SetupGetItem; - Flags_SetTreasure(play, 0x1F); - return NPC_TALK_STATE_ACTION; + this->actionFunc = EnGo2_SetGetItem; + return this->interactInfo.talkState; } case 0x3037: Flags_SetInfTable(INFTABLE_SPOKE_TO_GORON_LINK); @@ -605,7 +586,7 @@ s16 EnGo2_UpdateTalkStateGoronCityLink(PlayState* play, EnGo2* this) { u16 EnGo2_GetTextIdGoronDmtBiggoron(PlayState* play, EnGo2* this) { Player* player = GET_PLAYER(play); - if (!IS_RANDO && gSaveContext.bgsFlag) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE, gSaveContext.bgsFlag, NULL)) { player->exchangeItemId = EXCH_ITEM_CLAIM_CHECK; return 0x305E; } else if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_CLAIM_CHECK) { @@ -627,17 +608,17 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { switch (EnGo2_GetDialogState(this, play)) { case TEXT_STATE_DONE: if (this->actor.textId == 0x305E) { - if((!IS_RANDO && gSaveContext.bgsFlag) || (IS_RANDO && Flags_GetTreasure(play, 0x1F))) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED, gSaveContext.bgsFlag, NULL)) { return NPC_TALK_STATE_IDLE; } - - if(IS_RANDO) { - EnGo2_GetItemEntry(this, play, Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS)); - Flags_SetTreasure(play, 0x1F); - } else { + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); + if (GameInteractor_Should(GI_VB_TRADE_CLAIM_CHECK, true, this)) { EnGo2_GetItem(this, play, GI_SWORD_BGS); + this->actionFunc = EnGo2_SetupGetItem; + } else { + this->actionFunc = EnGo2_SetGetItem; } - this->actionFunc = EnGo2_SetupGetItem; + return NPC_TALK_STATE_ACTION; } else { return NPC_TALK_STATE_IDLE; @@ -663,16 +644,13 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { if (Message_ShouldAdvance(play)) { if ((this->actor.textId == 0x3054) || (this->actor.textId == 0x3055)) { if (play->msgCtx.choiceIndex == 0) { - if (IS_RANDO) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION); - Randomizer_ConsumeAdultTradeItem(play, ITEM_SWORD_BROKEN); - EnGo2_GetItemEntry(this, play, getItemEntry); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD); + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD); + if (GameInteractor_Should(GI_VB_TRADE_BROKEN_SWORD, true, this)) { + EnGo2_GetItem(this, play, GI_PRESCRIPTION); + this->actionFunc = EnGo2_SetupGetItem; } else { - u32 getItemId = GI_PRESCRIPTION; - EnGo2_GetItem(this, play, getItemId); + this->actionFunc = EnGo2_SetGetItem; } - this->actionFunc = EnGo2_SetupGetItem; return NPC_TALK_STATE_ACTION; } this->actor.textId = 0x3056; @@ -1070,7 +1048,7 @@ void EnGo2_BiggoronSetTextId(EnGo2* this, PlayState* play, Player* player) { u16 textId; if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) { - if ((!IS_RANDO && gSaveContext.bgsFlag)) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE, gSaveContext.bgsFlag, NULL)) { if (func_8002F368(play) == EXCH_ITEM_CLAIM_CHECK) { this->actor.textId = 0x3003; } else { @@ -1080,18 +1058,14 @@ void EnGo2_BiggoronSetTextId(EnGo2* this, PlayState* play, Player* player) { } else if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { if (func_8002F368(play) == EXCH_ITEM_CLAIM_CHECK) { - if (IS_RANDO && Flags_GetTreasure(play, 0x1F)) { - textId = 0x3003; - } else if (Environment_GetBgsDayCount() >= CVarGetInteger("gForgeTime", 3)) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_FORGED, Environment_GetBgsDayCount() >= 3, NULL)) { textId = 0x305E; } else { textId = 0x305D; } this->actor.textId = textId; } else { - if (IS_RANDO && Flags_GetTreasure(play, 0x1F)) { - textId = 0x305E; - } else if (Environment_GetBgsDayCount() >= CVarGetInteger("gForgeTime", 3)) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_FORGED, Environment_GetBgsDayCount() >= 3, NULL)) { textId = 0x3002; } else { textId = 0x305D; @@ -1219,8 +1193,7 @@ s32 EnGo2_IsCameraModified(EnGo2* this, PlayState* play) { (this->actor.params & 0x1F) == GORON_CITY_STAIRWELL || (this->actor.params & 0x1F) == GORON_DMT_BIGGORON || (this->actor.params & 0x1F) == GORON_MARKET_BAZAAR) { return true; - } else if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { return true; } else { @@ -1278,8 +1251,7 @@ void EnGo2_SelectGoronWakingUp(EnGo2* this) { EnGo2_BiggoronWakingUp(this); break; case GORON_CITY_LINK: - if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { EnGo2_WakingUp(this); break; @@ -1624,8 +1596,7 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { case GORON_CITY_LOWEST_FLOOR: case GORON_CITY_STAIRWELL: case GORON_CITY_LOST_WOODS: - if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { Actor_Kill(&this->actor); } this->actionFunc = EnGo2_CurledUp; @@ -1640,8 +1611,7 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { if ((Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED))) { Path_CopyLastPoint(this->path, &this->actor.world.pos); this->actor.home.pos = this->actor.world.pos; - if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { EnGo2_GetItemAnimation(this, play); } else { @@ -1862,11 +1832,7 @@ void EnGo2_SetupGetItem(EnGo2* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = EnGo2_SetGetItem; } else { - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, this->getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); - } + func_8002F434(&this->actor, play, this->getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } } @@ -1874,47 +1840,27 @@ void EnGo2_SetGetItem(EnGo2* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - // For randomizer, handle updating the states for the gorons after receiving the item based on - // the goron type rather then the item being received - if (IS_RANDO) { - switch (this->actor.params & 0x1F) { - case GORON_DMT_BIGGORON: - // Resolves #1301. unk_13EE is used to set the opacity of the HUD. The trade sequence discussion with Biggoron - // sets the HUD to transparent, and it is restored at z_message_PAL:3549, but by specifically watching for - // trade sequence items, this leaves it transparent for non-trade sequence items (in rando) so we fix that here - gSaveContext.unk_13EE = 0x32; - return; - case GORON_CITY_LINK: + if (GameInteractor_Should(GI_VB_EN_GO2_RESET_AFTER_GET_ITEM, true, this)) { + switch (this->getItemId) { + case GI_CLAIM_CHECK: + Environment_ClearBgsDayCount(); EnGo2_GetItemAnimation(this, play); return; - case GORON_CITY_ROLLING_BIG: + case GI_TUNIC_GORON: + Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); + EnGo2_GetItemAnimation(this, play); + return; + case GI_SWORD_BGS: + gSaveContext.bgsFlag = true; + break; + case GI_BOMB_BAG_30: + case GI_BOMB_BAG_40: EnGo2_RollingAnimation(this, play); this->actionFunc = EnGo2_GoronRollingBigContinueRolling; return; } this->actionFunc = func_80A46B40; - return; } - - switch (this->getItemId) { - case GI_CLAIM_CHECK: - Environment_ClearBgsDayCount(); - EnGo2_GetItemAnimation(this, play); - return; - case GI_TUNIC_GORON: - Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); - EnGo2_GetItemAnimation(this, play); - return; - case GI_SWORD_BGS: - gSaveContext.bgsFlag = true; - break; - case GI_BOMB_BAG_30: - case GI_BOMB_BAG_40: - EnGo2_RollingAnimation(this, play); - this->actionFunc = EnGo2_GoronRollingBigContinueRolling; - return; - } - this->actionFunc = func_80A46B40; } } @@ -1925,12 +1871,12 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; this->actor.shape.rot.y += 0x5B0; this->trackingMode = NPC_TRACKING_NONE; - this->animTimer = IS_RANDO ? 0 : (this->skelAnime.endFrame + 60.0f + 60.0f); // eyeDrops animation timer + this->animTimer = !GameInteractor_Should(GI_VB_PLAY_EYEDROPS_CS, true, NULL) ? 0 : (this->skelAnime.endFrame + 60.0f + 60.0f); // eyeDrops animation timer this->eyeMouthTexState = 2; this->unk_20C = 0; this->goronState++; func_800F483C(0x28, 5); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_EYEDROPS_CS, true, NULL)) { OnePointCutscene_Init(play, 4190, -99, &this->actor, MAIN_CAM); } break; @@ -1959,16 +1905,15 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; this->skelAnime.playSpeed = 0.0f; this->skelAnime.curFrame = this->skelAnime.endFrame; - if (IS_RANDO) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK); - Randomizer_ConsumeAdultTradeItem(play, ITEM_EYEDROPS); - EnGo2_GetItemEntry(this, play, getItemEntry); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS); - } else { + + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS); + if(GameInteractor_Should(GI_VB_TRADE_EYEDROPS, true, this)) { u32 getItemId = GI_CLAIM_CHECK; EnGo2_GetItem(this, play, getItemId); + this->actionFunc = EnGo2_SetupGetItem; + } else { + this->actionFunc = EnGo2_SetGetItem; } - this->actionFunc = EnGo2_SetupGetItem; this->goronState = 0; } break; diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h index 86ac0c32e..185a036f4 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h @@ -107,4 +107,9 @@ typedef struct EnGo2 { /* */ GetItemEntry getItemEntry; } EnGo2; // size = 0x05A0 +void EnGo2_GetItemAnimation(EnGo2* enGo2, PlayState* play); +void EnGo2_RollingAnimation(EnGo2* enGo2, PlayState* play); +void EnGo2_GoronRollingBigContinueRolling(EnGo2* enGo2, PlayState* play); +void func_80A46B40(EnGo2* enGo2, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c index 14b3703b8..c8d70fe1f 100644 --- a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c +++ b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c @@ -7,7 +7,7 @@ #include "z_en_hs.h" #include "vt.h" #include "objects/object_hs/object_hs.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -79,25 +79,7 @@ void EnHs_Init(Actor* thisx, PlayState* play) { // "chicken shop (adult era)" osSyncPrintf(VT_FGCOL(CYAN) " ヒヨコの店(大人の時) \n" VT_RST); func_80A6E3A0(this, func_80A6E9AC); - bool shouldSpawn; - bool tradedMushroom = Flags_GetItemGetInf(ITEMGETINF_30); - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) { - // To explain the logic because Fado and Grog are linked: - // - If you have Cojiro, then spawn Grog and not Fado. - // - If you don't have Cojiro but do have Odd Potion, spawn Fado and not Grog. - // - If you don't have either, spawn Grog if you haven't traded the Odd Mushroom. - // - If you don't have either but have traded the mushroom, don't spawn either. - if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { - shouldSpawn = true; - } else if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION)) { - shouldSpawn = false; - } else { - shouldSpawn = !tradedMushroom; - } - } else { - shouldSpawn = !tradedMushroom; - } - if (!shouldSpawn) { + if (GameInteractor_Should(GI_VB_DESPAWN_GROG, Flags_GetItemGetInf(ITEMGETINF_30), this)) { // "chicken shop closed" osSyncPrintf(VT_FGCOL(CYAN) " ヒヨコ屋閉店 \n" VT_RST); Actor_Kill(&this->actor); @@ -148,11 +130,11 @@ void func_80A6E5EC(EnHs* this, PlayState* play) { void func_80A6E630(EnHs* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_TRADE_TIMER_ODD_MUSHROOM, true, NULL)) { func_80088AA0(180); + gSaveContext.eventInf[1] &= ~1; } func_80A6E3A0(this, func_80A6E6B0); - gSaveContext.eventInf[1] &= ~1; } this->unk_2A8 |= 1; @@ -175,19 +157,12 @@ void func_80A6E70C(EnHs* this, PlayState* play) { } void func_80A6E740(EnHs* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_COJIRO, true, this)) { this->actor.parent = NULL; + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO); func_80A6E3A0(this, func_80A6E630); } else { - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM); - Randomizer_ConsumeAdultTradeItem(play, ITEM_COJIRO); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO); - } else { - s32 itemId = GI_ODD_MUSHROOM; - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); - } + func_8002F434(&this->actor, play, GI_ODD_MUSHROOM, 10000.0f, 50.0f); } this->unk_2A8 |= 1; @@ -198,14 +173,8 @@ void func_80A6E7BC(EnHs* this, PlayState* play) { switch (play->msgCtx.choiceIndex) { case 0: func_80A6E3A0(this, func_80A6E740); - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM); - Randomizer_ConsumeAdultTradeItem(play, ITEM_COJIRO); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO); - } else { - s32 itemId = GI_ODD_MUSHROOM; - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); + if (GameInteractor_Should(GI_VB_TRADE_COJIRO, true, this)) { + func_8002F434(&this->actor, play, GI_ODD_MUSHROOM, 10000.0f, 50.0f); } break; case 1: diff --git a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c index 50be2e458..793017d3d 100644 --- a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c +++ b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c @@ -6,6 +6,7 @@ #include "z_en_js.h" #include "objects/object_js/object_js.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -127,23 +128,15 @@ void func_80A8910C(EnJs* this, PlayState* play) { } void func_80A89160(EnJs* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_CARPET_SALESMAN, true, this)) { this->actor.parent = NULL; En_Js_SetupAction(this, func_80A8910C); + Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); } else { - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_WASTELAND_BOMBCHU_SALESMAN, GI_BOMBCHUS_10); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); - } else { - GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - func_8002F434(&this->actor, play, GI_BOMBCHUS_10, 10000.0f, 50.0f); - } + GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10); + gSaveContext.pendingSale = itemEntry.itemId; + gSaveContext.pendingSaleMod = itemEntry.modIndex; + func_8002F434(&this->actor, play, GI_BOMBCHUS_10, 10000.0f, 50.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index 25299f5b0..c801356c9 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -10,7 +10,7 @@ #include "objects/object_km1/object_km1.h" #include "objects/object_kw1/object_kw1.h" #include "vt.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -1027,20 +1027,9 @@ s32 EnKo_CanSpawn(EnKo* this, PlayState* play) { } case SCENE_LOST_WOODS: - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) { - // To explain the logic because Fado and Grog are linked: - // - If you have Cojiro, then spawn Grog and not Fado. - // - If you don't have Cojiro but do have Odd Potion, spawn Fado and not Grog. - // - If you don't have either, spawn Grog if you haven't traded the Odd Mushroom. - // - If you don't have either but have traded the mushroom, don't spawn either. - if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { - return false; - } else { - return PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION); - } - } else { - return (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false; - } + return GameInteractor_Should(GI_VB_SPAWN_LW_FADO, ( + (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false + ), this); default: return false; } @@ -1186,18 +1175,10 @@ void func_80A99048(EnKo* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_ELF, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 3); if (ENKO_TYPE == ENKO_TYPE_CHILD_3) { - if (!IS_RANDO) { - if (!CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) { - this->collider.dim.height += 200; - this->actionFunc = func_80A995CC; - return; - } - } else { - if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD)) { - this->collider.dim.height += 200; - this->actionFunc = func_80A995CC; - return; - } + if (!GameInteractor_Should(GI_VB_OPEN_KOKIRI_FOREST, CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD), this)) { + this->collider.dim.height += 200; + this->actionFunc = func_80A995CC; + return; } Path_CopyLastPoint(this->path, &this->actor.world.pos); } @@ -1230,18 +1211,11 @@ void func_80A99438(EnKo* this, PlayState* play) { } void func_80A99504(EnKo* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_ODD_POTION, true, this)) { this->actor.parent = NULL; this->actionFunc = func_80A99560; } else { - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_ODD_POTION, GI_SAW); - Randomizer_ConsumeAdultTradeItem(play, ITEM_ODD_POTION); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 120.0f, 10.0f); - } else { - s32 itemId = GI_SAW; - func_8002F434(&this->actor, play, itemId, 120.0f, 10.0f); - } + func_8002F434(&this->actor, play, GI_SAW, 120.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h index c247f53b9..5deeef465 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h @@ -57,4 +57,8 @@ typedef enum { ENKO_FQS_ADULT_SAVED } KokiriForestQuestState; +void func_80A995CC(EnKo* actor, PlayState* play); +void func_80A99384(EnKo* actor, PlayState* play); +void func_80A99560(EnKo* actor, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index ad3bd0ab5..3d5c2c354 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -6,7 +6,7 @@ #include "z_en_kz.h" #include "objects/object_kz/object_kz.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -73,12 +73,9 @@ static AnimationInfo sAnimationInfo[] = { u16 EnKz_GetTextNoMaskChild(PlayState* play, EnKz* this) { Player* player = GET_PLAYER(play); - if ((IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY)) || - (!IS_RANDO && CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE))) { - // Allow turning in Ruto's letter even if you have already rescued her - if (IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { - player->exchangeItemId = EXCH_ITEM_LETTER_RUTO; - } + if (GameInteractor_Should(GI_VB_KING_ZORA_THANK_CHILD, ( + CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) + ), this)) { return 0x402B; } else if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { return 0x401C; @@ -94,8 +91,10 @@ u16 EnKz_GetTextNoMaskAdult(PlayState* play, EnKz* this) { // this works because both ITEM_NONE and later trade items are > ITEM_FROG if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_FROG) { if (!Flags_GetInfTable(INFTABLE_139)) { - if (!IS_RANDO) { - return CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) ? 0x401F : 0x4012; + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, ( + !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) + ), this)) { + return 0x401F; } else { return 0x4012; } @@ -243,7 +242,9 @@ void func_80A9CB18(EnKz* this, PlayState* play) { Player* player = GET_PLAYER(play); if (func_80A9C95C(play, this, &this->interactInfo.talkState, 340.0f, EnKz_GetText, func_80A9C6C0)) { - if (((IS_RANDO && LINK_IS_CHILD) || this->actor.textId == 0x401A) && !Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { + if (GameInteractor_Should(GI_VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER, (this->actor.textId == 0x401A), this) && + !Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) + { if (func_8002F368(play) == EXCH_ITEM_LETTER_RUTO) { this->actor.textId = 0x401B; this->sfxPlayed = false; @@ -257,7 +258,7 @@ void func_80A9CB18(EnKz* this, PlayState* play) { if (LINK_IS_ADULT) { if ((INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_PRESCRIPTION) && (func_8002F368(play) == EXCH_ITEM_PRESCRIPTION)) { - if (!IS_RANDO || !Flags_GetTreasure(play, 0x1F)) { + if (GameInteractor_Should(GI_VB_TRADE_PRESCRIPTION, true, this)) { this->actor.textId = 0x4014; this->sfxPlayed = false; player->actor.textId = this->actor.textId; @@ -271,11 +272,11 @@ void func_80A9CB18(EnKz* this, PlayState* play) { this->actor.textId = CHECK_QUEST_ITEM(QUEST_SONG_SERENADE) ? 0x4045 : 0x401A; player->actor.textId = this->actor.textId; } else { - if (!IS_RANDO) { - this->actor.textId = CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) ? 0x401F : 0x4012; - } else { - this->actor.textId = 0x4012; - } + this->actor.textId = + !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, + (!CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA)), this) + ? 0x401F + : 0x4012; player->actor.textId = this->actor.textId; } @@ -344,29 +345,10 @@ void EnKz_Init(Actor* thisx, PlayState* play) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; Animation_ChangeByInfo(&this->skelanime, sAnimationInfo, ENKZ_ANIM_0); - if (!IS_RANDO) { - if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { - EnKz_SetMovedPos(this, play); - } - } else { - int zorasFountain = Randomizer_GetSettingValue(RSK_ZORAS_FOUNTAIN); - switch (zorasFountain) { - case 0: - if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { - EnKz_SetMovedPos(this, play); - } - break; - case 1: - if (LINK_IS_ADULT) { - EnKz_SetMovedPos(this, play); - } else if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { - EnKz_SetMovedPos(this, play); - } - break; - case 2: - EnKz_SetMovedPos(this, play); - break; - } + if (GameInteractor_Should(GI_VB_KING_ZORA_BE_MOVED, ( + Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED) + ), this)) { + EnKz_SetMovedPos(this, play); } if (LINK_IS_ADULT) { @@ -465,37 +447,29 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { f32 xzRange; f32 yRange; - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || ( + (this->isTrading && !GameInteractor_Should(GI_VB_TRADE_PRESCRIPTION, true, this)) || + (!this->isTrading && !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, true, this)) + )) { this->actor.parent = NULL; this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actionFunc = EnKz_StartTimer; - } else { - if (IS_RANDO) { - if (this->isTrading) { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_TRADE_PRESCRIPTION, GI_FROG); - getItemId = getItemEntry.getItemId; - Randomizer_ConsumeAdultTradeItem(play, ITEM_PRESCRIPTION); - Flags_SetTreasure(play, 0x1F); - } else { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_KING_ZORA_THAWED, GI_TUNIC_ZORA); - getItemId = getItemEntry.getItemId; - } + if (!this->isTrading) { + Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); } else { - getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); } + } else { + getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; yRange = fabsf(this->actor.yDistToPlayer) + 1.0f; xzRange = this->actor.xzDistToPlayer + 1.0f; - if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, xzRange, yRange); - } else { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, xzRange, yRange); - } + func_8002F434(&this->actor, play, getItemId, xzRange, yRange); } } void EnKz_StartTimer(EnKz* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG && !IS_RANDO) { + if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG && GameInteractor_Should(GI_VB_TRADE_TIMER_FROG, true, NULL)) { func_80088AA0(180); // start timer2 with 3 minutes gSaveContext.eventInf[1] &= ~1; } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h index 37feb841a..c97732356 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h @@ -28,4 +28,6 @@ typedef struct EnKz { /* 0x02BE */ s16 unk_2BE[12]; } EnKz; // size = 0x02D8 +void EnKz_SetupGetItem(EnKz* enKz, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index 8a11eb668..75db192cf 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -6,6 +6,7 @@ #include "z_en_ma1.h" #include "objects/object_ma1/object_ma1.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -25,7 +26,6 @@ void func_80AA106C(EnMa1* this, PlayState* play); void func_80AA10EC(EnMa1* this, PlayState* play); void func_80AA1150(EnMa1* this, PlayState* play); void EnMa1_DoNothing(EnMa1* this, PlayState* play); -void EnMa1_WaitForSongGive(EnMa1* this, PlayState* play); const ActorInit En_Ma1_InitVars = { ACTOR_EN_MA1, @@ -90,25 +90,16 @@ static void* sEyeTextures[] = { gMalonChildEyeClosedTex, }; -bool Randomizer_ObtainedMalonHCReward() { - return Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); -} - u16 EnMa1_GetText(PlayState* play, Actor* thisx) { - // Special case for Malon Hyrule Castle Text. Placing it here at the beginning - // has the added benefit of circumventing mask text if wearing bunny hood. - if (IS_RANDO && play->sceneNum == SCENE_HYRULE_CASTLE) { - return Randomizer_ObtainedMalonHCReward() ? 0x2044 : 0x2043; - } + bool malonReturnedFromCastle = GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL); + bool malonTaughtEponasSong = GameInteractor_Should(GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG, CHECK_QUEST_ITEM(QUEST_SONG_EPONA), NULL); u16 faceReaction = Text_GetFaceReaction(play, 0x17); if (faceReaction != 0) { return faceReaction; } - if (!IS_RANDO) { - if (CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) { - return 0x204A; - } + if (malonTaughtEponasSong) { + return 0x204A; } if (Flags_GetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON)) { return 0x2049; @@ -120,7 +111,7 @@ u16 EnMa1_GetText(PlayState* play, Actor* thisx) { return 0x2048; } } - if (Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)) { + if (malonReturnedFromCastle) { return 0x2047; } if (Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG)) { @@ -194,6 +185,8 @@ s16 func_80AA0778(PlayState* play, Actor* thisx) { } s32 func_80AA08C4(EnMa1* this, PlayState* play) { + bool malonReturnedFromCastle = GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL); + if ((this->actor.shape.rot.z == 3) && (gSaveContext.sceneSetupIndex == 5)) { return 1; } @@ -202,32 +195,24 @@ s32 func_80AA08C4(EnMa1* this, PlayState* play) { } // Causes Malon to appear in the market if you haven't met her yet. if (((play->sceneNum == SCENE_MARKET_NIGHT) || (play->sceneNum == SCENE_MARKET_DAY)) && - !Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE) && !Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { + !malonReturnedFromCastle && !Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { return 1; } - if ((play->sceneNum == SCENE_HYRULE_CASTLE) && // if we're at hyrule castle - (!Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE) || // and talon hasn't left - (IS_RANDO && - !Randomizer_ObtainedMalonHCReward()))) { // or we're rando'd and haven't gotten malon's HC check - if (Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { // if we've met malon - return 1; // make her appear at the castle - } else { // if we haven't met malon - Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); // set the flag for meeting malon - return 0; // don't make her appear at the castle + if ((play->sceneNum == SCENE_HYRULE_CASTLE) && !malonReturnedFromCastle) { + if (Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { + return 1; + } else { + Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); + return 0; } } - // Malon asleep in her bed if Talon has left Hyrule Castle and it is nighttime. - if ((play->sceneNum == SCENE_LON_LON_BUILDINGS) && IS_NIGHT && (Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE))) { + if ((play->sceneNum == SCENE_LON_LON_BUILDINGS) && IS_NIGHT && malonReturnedFromCastle) { return 1; } - // Don't spawn Malon if none of the above are true and we are not in Lon Lon Ranch. if (play->sceneNum != SCENE_LON_LON_RANCH) { return 0; } - // If we've gotten this far, we're in Lon Lon Ranch. Spawn Malon if it is daytime, Talon has left Hyrule Castle, and - // either we are not randomized, or we are and we have received Malon's item at Hyrule Castle. - if ((this->actor.shape.rot.z == 3) && IS_DAY && (Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)) && - ((IS_RANDO && Randomizer_ObtainedMalonHCReward()) || !IS_RANDO)) { + if ((this->actor.shape.rot.z == 3) && IS_DAY && malonReturnedFromCastle) { return 1; } return 0; @@ -284,6 +269,8 @@ void func_80AA0B74(EnMa1* this) { void EnMa1_Init(Actor* thisx, PlayState* play) { EnMa1* this = (EnMa1*)thisx; + bool malonReturnedFromCastle = GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL); + bool malonTaughtEponasSong = GameInteractor_Should(GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG, CHECK_QUEST_ITEM(QUEST_SONG_EPONA), NULL); s32 pad; ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 18.0f); @@ -292,12 +279,6 @@ void EnMa1_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(22), &sColChkInfoInit); - if (IS_RANDO) { // Skip Malon's multiple textboxes before getting an item - Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); - Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET); - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET); - } - if (!func_80AA08C4(this, play)) { Actor_Kill(&this->actor); return; @@ -308,21 +289,10 @@ void EnMa1_Init(Actor* thisx, PlayState* play) { this->actor.targetMode = 6; this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - // To avoid missing a check, we want Malon to have the actionFunc for singing, but not reacting to Ocarina, if any of - // the following are true. - // 1. Talon has not left Hyrule Castle. - // 2. We are Randomized and have not obtained Malon's Weird Egg Check. - // 3. We are not Randomized and have obtained Epona's Song - if (!Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE) || (IS_RANDO && !Randomizer_ObtainedMalonHCReward()) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !IS_RANDO) || - (IS_RANDO && Flags_GetTreasure(play, 0x1F))) { + if (!malonReturnedFromCastle || malonTaughtEponasSong) { this->actionFunc = func_80AA0D88; EnMa1_ChangeAnim(this, ENMA1_ANIM_2); - // If none of the above conditions were true, set Malon up to teach Epona's Song. } else { - if (IS_RANDO) { // Skip straight to "let's sing it together" textbox in the ranch - Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON); - } - this->actionFunc = func_80AA0F44; EnMa1_ChangeAnim(this, ENMA1_ANIM_2); } @@ -336,6 +306,9 @@ void EnMa1_Destroy(Actor* thisx, PlayState* play) { } void func_80AA0D88(EnMa1* this, PlayState* play) { + bool malonReturnedFromCastle = GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL); + bool malonTaughtEponasSong = GameInteractor_Should(GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG, CHECK_QUEST_ITEM(QUEST_SONG_EPONA), NULL); + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if (this->skelAnime.animation != &gMalonChildIdleAnim) { EnMa1_ChangeAnim(this, ENMA1_ANIM_1); @@ -346,16 +319,9 @@ void func_80AA0D88(EnMa1* this, PlayState* play) { } } - // We want to Kill Malon's Actor outside of randomizer when Talon is freed. In Randomizer we don't kill Malon's - // Actor here, otherwise if we wake up Talon first and then get her check she will spontaneously - // disappear. - if ((play->sceneNum == SCENE_HYRULE_CASTLE) && (!IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE))) { + if ((play->sceneNum == SCENE_HYRULE_CASTLE) && malonReturnedFromCastle) { Actor_Kill(&this->actor); - // We want Malon to give the Weird Egg Check (see function below) in the following situations: - // 1. Talon as not left Hyrule Castle (Vanilla) OR - // 2. We haven't obtained Malon's Weird Egg Check (Randomizer only) OR - // 3. We have Epona's Song? (Vanilla only, not sure why it's here but I didn't write that one) - } else if ((!Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE) || (IS_RANDO && !Randomizer_ObtainedMalonHCReward())) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !IS_RANDO)) { + } else if (!malonReturnedFromCastle || malonTaughtEponasSong) { if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actionFunc = func_80AA0EA0; play->msgCtx.stateTimer = 4; @@ -365,21 +331,16 @@ void func_80AA0D88(EnMa1* this, PlayState* play) { } void func_80AA0EA0(EnMa1* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_WEIRD_EGG, true, NULL)) { this->actor.parent = NULL; this->actionFunc = func_80AA0EFC; } else { - if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_WEIRD_EGG, 120.0f, 10.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_MALON_EGG, GI_WEIRD_EGG); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 120.0f, 10.0f); - } + func_8002F434(&this->actor, play, GI_WEIRD_EGG, 120.0f, 10.0f); } } void func_80AA0EFC(EnMa1* this, PlayState* play) { - if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN || !GameInteractor_Should(GI_VB_GIVE_ITEM_WEIRD_EGG, true, NULL)) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = func_80AA0D88; Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); @@ -387,24 +348,6 @@ void func_80AA0EFC(EnMa1* this, PlayState* play) { } } -void GivePlayerRandoRewardMalon(EnMa1* malon, PlayState* play, RandomizerCheck check) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_EPONAS_SONG); - // Prevents flag from getting set if we weren't able to get the item (i.e. Player is holding shield - // when closing the textbox). - if (malon->actor.parent != NULL && malon->actor.parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1F)) { - Flags_SetTreasure(play, 0x1F); - // puts malon in the action that vanilla has her in after learning the song - // (confirmed via breakpoints in a vanilla save). - malon->actionFunc = func_80AA0D88; - } else if (!Flags_GetTreasure(play, 0x1F)) { - GiveItemEntryFromActor(&malon->actor, play, getItemEntry, 10000.0f, 100.0f); - } - // make malon sing again after giving the item. - malon->interactInfo.talkState = NPC_TALK_STATE_IDLE; - malon->unk_1E0 = 1; -} - void func_80AA0F44(EnMa1* this, PlayState* play) { Player* player = GET_PLAYER(play); @@ -419,7 +362,6 @@ void func_80AA0F44(EnMa1* this, PlayState* play) { } if (Flags_GetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON)) { - // When the player pulls out the Ocarina while close to Malon if (player->stateFlags2 & 0x1000000) { player->stateFlags2 |= 0x2000000; player->unk_6A8 = &this->actor; @@ -427,19 +369,10 @@ void func_80AA0F44(EnMa1* this, PlayState* play) { Message_StartTextbox(play, this->actor.textId, NULL); this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actor.flags |= ACTOR_FLAG_WILL_TALK; - // when rando'ed, skip to the Item Giving. Otherwise go to the song teaching code. - this->actionFunc = IS_RANDO ? func_80AA1150 : func_80AA106C; + this->actionFunc = func_80AA106C; } else if (this->actor.xzDistToPlayer < 30.0f + (f32)this->collider.dim.radius) { - // somehow flags that the player is close to malon so that pulling out the Ocarina - // triggers the code above this. player->stateFlags2 |= 0x800000; } - // If rando'ed, a textbox is closing, it's malon's 'my mom wrote this song' text, AND we do have an ocarina - // in our inventory. This allows us to grant the check when talking to malon with the ocarina in our inventory. - if (IS_RANDO && (Actor_TextboxIsClosing(&this->actor, play) && play->msgCtx.textId == 0x2049) && - (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE || INV_CONTENT(ITEM_OCARINA_TIME) != ITEM_NONE)) { - this->actionFunc = EnMa1_WaitForSongGive; - } } } @@ -461,48 +394,16 @@ void func_80AA10EC(EnMa1* this, PlayState* play) { } } -void EnMa1_WaitForSongGive(EnMa1* this, PlayState* play) { - // Actually give the song check. - GivePlayerRandoRewardMalon(this, play, RC_SONG_FROM_MALON); -} - -// Sets an Ocarina State necessary to not softlock in rando. -// This function should only be called in rando. -void EnMa1_EndTeachSong(EnMa1* this, PlayState* play) { - if (play->csCtx.state == CS_STATE_IDLE) { - this->actionFunc = func_80AA0F44; - play->msgCtx.ocarinaMode = OCARINA_MODE_04; - } - - if (IS_RANDO) { - // Transition to the giving the song check on the next update run. - this->actionFunc = EnMa1_WaitForSongGive; - } -} - void func_80AA1150(EnMa1* this, PlayState* play) { GET_PLAYER(play)->stateFlags2 |= 0x800000; - // When rando'ed, trigger the "song learned" Ocarina mode. - if (IS_RANDO && (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING)) { - play->msgCtx.ocarinaMode = OCARINA_MODE_03; - } - if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - if (!IS_RANDO) { - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; - play->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); - play->transitionTrigger = TRANS_TRIGGER_START; - this->actionFunc = EnMa1_DoNothing; - } else { - // When rando'ed, skip the cutscene, play the chime, reset some flags, - // and give the song on next update. - func_80078884(NA_SE_SY_CORRECT_CHIME); - this->actionFunc = EnMa1_EndTeachSong; - this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; - play->msgCtx.ocarinaMode = OCARINA_MODE_00; - } + Flags_SetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG); + play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; + play->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); + play->transitionTrigger = TRANS_TRIGGER_START; + this->actionFunc = EnMa1_DoNothing; } } diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h index 55b53bd72..f06f220c9 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h @@ -20,4 +20,7 @@ typedef struct EnMa1 { /* 0x01E8 */ NpcInteractInfo interactInfo; } EnMa1; // size = 0x0210 +void func_80AA106C(EnMa1* enMa1, PlayState* play); +void func_80AA0D88(EnMa1* enMa1, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index 14d9cbb7b..6fb9119bf 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -7,6 +7,7 @@ #include "z_en_md.h" #include "objects/object_md/object_md.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -372,11 +373,7 @@ u16 EnMd_GetTextKokiriForest(PlayState* play, EnMd* this) { this->unk_208 = 0; this->unk_209 = TEXT_STATE_NONE; - // In rando, skip talking about the tree being dead so we can have the prompt for sword and shield instead - if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) || - (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && - Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE) && - !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH))) { + if (GameInteractor_Should(GI_VB_MIDO_CONSIDER_DEKU_TREE_DEAD, CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD), this)) { return 0x1045; } @@ -486,25 +483,6 @@ s16 func_80AAAF04(PlayState* play, Actor* thisx) { } u8 EnMd_ShouldSpawn(EnMd* this, PlayState* play) { - // In rando, Mido's spawn logic is adjusted to support closed deku/forest options - // He will spawn in the forest if you haven't showed the sword and shield, and will remain - // in the forest until you've obtained Zelda's letter or Deku Tree dies - // This is to ensure Deku Tree can still be opened in dungeon entrance rando even if Ghoma is defeated - if (IS_RANDO) { - if (play->sceneNum == SCENE_LOST_WOODS) { - return 1; - } - - if (Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && - Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && - (Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER) || - Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD))) { - return play->sceneNum == SCENE_MIDOS_HOUSE && !LINK_IS_ADULT; - } - - return play->sceneNum == SCENE_KOKIRI_FOREST; - } - if (play->sceneNum == SCENE_KOKIRI_FOREST) { if (!Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && !Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER)) { return 1; @@ -512,7 +490,7 @@ u8 EnMd_ShouldSpawn(EnMd* this, PlayState* play) { } if (play->sceneNum == SCENE_MIDOS_HOUSE) { - if (((Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH)) != 0) || ((Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER)) != 0)) { + if (Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) || Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER)) { if (!LINK_IS_ADULT) { return 1; } @@ -681,9 +659,8 @@ void EnMd_Init(Actor* thisx, PlayState* play) { this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, FAIRY_KOKIRI); if (((play->sceneNum == SCENE_KOKIRI_FOREST) && !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) || - ((play->sceneNum == SCENE_KOKIRI_FOREST) && (Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) && - ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE)))) || + ((play->sceneNum == SCENE_KOKIRI_FOREST) && Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && + CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) || ((play->sceneNum == SCENE_LOST_WOODS) && !Flags_GetEventChkInf(EVENTCHKINF_PLAYED_SARIAS_SONG_FOR_MIDO_AS_ADULT))) { this->actor.home.pos = this->actor.world.pos; this->actionFunc = func_80AAB948; @@ -745,10 +722,11 @@ void func_80AAB948(EnMd* this, PlayState* play) { this->skelAnime.playSpeed = CLAMP(temp, 1.0f, 3.0f); } - if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { - if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) || - IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE) && - Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && + if ( + (GameInteractor_Should(GI_VB_MOVE_MIDO_IN_KOKIRI_FOREST, this->interactInfo.talkState == NPC_TALK_STATE_ACTION, this) && play->sceneNum == SCENE_KOKIRI_FOREST) || + this->interactInfo.talkState == NPC_TALK_STATE_ACTION + ) { + if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && (play->sceneNum == SCENE_KOKIRI_FOREST)) { play->msgCtx.msgMode = MSGMODE_PAUSED; } @@ -815,9 +793,7 @@ void func_80AABD0C(EnMd* this, PlayState* play) { return; } - if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) || - IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE) && - Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && + if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && (play->sceneNum == SCENE_KOKIRI_FOREST)) { Message_CloseTextbox(play); Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH); diff --git a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c index e5501858c..54e48bfc2 100644 --- a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -6,7 +6,7 @@ #include "z_en_mk.h" #include "objects/object_mk/object_mk.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -93,37 +93,24 @@ void func_80AACA40(EnMk* this, PlayState* play) { } void func_80AACA94(EnMk* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play) != 0) { + if (Actor_HasParent(&this->actor, play) != 0 || !GameInteractor_Should(GI_VB_TRADE_FROG, true, this)) { this->actor.parent = NULL; this->actionFunc = func_80AACA40; - if (!IS_RANDO) { + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); + if (GameInteractor_Should(GI_VB_TRADE_TIMER_EYEDROPS, true, NULL)) { func_80088AA0(240); gSaveContext.eventInf[1] &= ~1; } } else { - if (IS_RANDO) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS); - Randomizer_ConsumeAdultTradeItem(play, ITEM_FROG); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); - } else { - s32 getItemID = GI_EYEDROPS; - func_8002F434(&this->actor, play, getItemID, 10000.0f, 50.0f); - } + func_8002F434(&this->actor, play, GI_EYEDROPS, 10000.0f, 50.0f); } } void func_80AACB14(EnMk* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { this->actionFunc = func_80AACA94; - if (IS_RANDO) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS); - Randomizer_ConsumeAdultTradeItem(play, ITEM_FROG); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); - } else { - s32 getItemID = GI_EYEDROPS; - func_8002F434(&this->actor, play, getItemID, 10000.0f, 50.0f); + if (GameInteractor_Should(GI_VB_TRADE_FROG, true, this)) { + func_8002F434(&this->actor, play, GI_EYEDROPS, 10000.0f, 50.0f); } } } @@ -150,7 +137,7 @@ void func_80AACC04(EnMk* this, PlayState* play) { if (this->timer > 0) { this->timer--; } else { - this->timer = IS_RANDO ? 0 : 16; + this->timer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 16 : 0; this->actionFunc = func_80AACBAC; Animation_Change(&this->skelAnime, &object_mk_Anim_000D88, 1.0f, 0.0f, Animation_GetLastFrame(&object_mk_Anim_000D88), ANIMMODE_LOOP, -4.0f); @@ -163,7 +150,7 @@ void func_80AACCA0(EnMk* this, PlayState* play) { this->timer--; this->actor.shape.rot.y += 0x800; } else { - this->timer = IS_RANDO ? 0 : 120; + this->timer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 120 : 0; this->actionFunc = func_80AACC04; Animation_Change(&this->skelAnime, &object_mk_Anim_000724, 1.0f, 0.0f, Animation_GetLastFrame(&object_mk_Anim_000724), ANIMMODE_LOOP, -4.0f); @@ -179,7 +166,7 @@ void func_80AACD48(EnMk* this, PlayState* play) { this->actionFunc = func_80AACCA0; play->msgCtx.msgMode = MSGMODE_PAUSED; player->exchangeItemId = EXCH_ITEM_NONE; - this->timer = IS_RANDO ? 0 : 16; + this->timer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 16 : 0; Animation_Change(&this->skelAnime, &object_mk_Anim_000D88, 1.0f, 0.0f, Animation_GetLastFrame(&object_mk_Anim_000D88), ANIMMODE_LOOP, -4.0f); this->flags &= ~2; @@ -213,29 +200,20 @@ void func_80AACEE8(EnMk* this, PlayState* play) { } void func_80AACFA0(EnMk* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_LAB_DIVE, true, this)) { this->actor.parent = NULL; this->actionFunc = func_80AACA40; Flags_SetItemGetInf(ITEMGETINF_10); } else { - // not sure when/how/if this is getting called - if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - } + func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); } } void func_80AAD014(EnMk* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { this->actionFunc = func_80AACFA0; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_LAB_DIVE, true, this)) { func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } } @@ -255,9 +233,9 @@ void EnMk_Wait(EnMk* this, PlayState* play) { player->actor.textId = this->actor.textId; this->actionFunc = func_80AACA40; } else { - // Skip eye drop text on rando if Link went in the water, so you can still receive the dive check - if (INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS && - (!IS_RANDO || this->swimFlag == 0)) { + if (GameInteractor_Should(GI_VB_USE_EYEDROP_DIALOGUE, ( + INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS + ), this)) { player->actor.textId = 0x4032; this->actionFunc = func_80AACA40; } else { diff --git a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c index b1d453f00..04b8166f7 100644 --- a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c +++ b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c @@ -6,6 +6,7 @@ #include "z_en_ms.h" #include "objects/object_ms/object_ms.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -127,20 +128,16 @@ void EnMs_Talk(EnMs* this, PlayState* play) { } else if (Message_ShouldAdvance(play)) { switch (play->msgCtx.choiceIndex) { case 0: // yes - if (gSaveContext.rupees < - ((IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) - ? 60 - : sPrices[BEANS_BOUGHT])) { + if (!GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE, ( + gSaveContext.rupees >= sPrices[BEANS_BOUGHT]), this)) { Message_ContinueTextbox(play, 0x4069); // not enough rupees text return; } - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) { - GiveItemEntryFromActor(&this->actor, play, - Randomizer_GetItemFromKnownCheck(RC_ZR_MAGIC_BEAN_SALESMAN, GI_BEAN), 90.0f, 10.0f); - } else { + + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN, true, this)) { func_8002F434(&this->actor, play, GI_BEAN, 90.0f, 10.0f); + this->actionFunc = EnMs_Sell; } - this->actionFunc = EnMs_Sell; return; case 1: // no Message_ContinueTextbox(play, 0x4068); @@ -152,23 +149,14 @@ void EnMs_Talk(EnMs* this, PlayState* play) { void EnMs_Sell(EnMs* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { - Rupees_ChangeBy((IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) ? -60 : -sPrices[BEANS_BOUGHT]); + Rupees_ChangeBy(-sPrices[BEANS_BOUGHT]); this->actor.parent = NULL; - this->actionFunc = - (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) ? EnMs_Wait : EnMs_TalkAfterPurchase; + this->actionFunc = EnMs_TalkAfterPurchase; } else { - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_MAGIC_BEAN_SALESMAN, GI_BEAN); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - GiveItemEntryFromActor(&this->actor, play, itemEntry, 90.0f, 10.0f); - BEANS_BOUGHT = 10; - } else { - GetItemEntry entry = ItemTable_Retrieve(GI_BEAN); - gSaveContext.pendingSaleMod = entry.modIndex; - gSaveContext.pendingSale = entry.itemId; - func_8002F434(&this->actor, play, GI_BEAN, 90.0f, 10.0f); - } + GetItemEntry entry = ItemTable_Retrieve(GI_BEAN); + gSaveContext.pendingSaleMod = entry.modIndex; + gSaveContext.pendingSale = entry.itemId; + func_8002F434(&this->actor, play, GI_BEAN, 90.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h index 70b105073..e626056f0 100644 --- a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h +++ b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h @@ -18,4 +18,7 @@ typedef struct EnMs { /* 0x024C */ s16 activeTimer; } EnMs; // size = 0x0250 +void EnMs_TalkAfterPurchase(EnMs* enMs, PlayState* play); +void EnMs_Wait(EnMs* enMs, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c index a519209aa..9a3990cf8 100644 --- a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c +++ b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c @@ -8,6 +8,7 @@ #include "vt.h" #include "objects/object_nb/object_nb.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -326,7 +327,9 @@ void EnNb_GiveMedallion(EnNb* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 0xC); - Item_Give(play, ITEM_MEDALLION_SPIRIT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SPIRIT_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_SPIRIT); + } } void EnNb_ComeUpImpl(EnNb* this, PlayState* play) { @@ -342,7 +345,9 @@ void EnNb_SetupChamberCsImpl(EnNb* this, PlayState* play) { this->action = NB_CHAMBER_UNDERGROUND; play->csCtx.segment = &D_80AB431C; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_SPIRIT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SPIRIT_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_SPIRIT); + } player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } } diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 8ddf52fad..b4e6d8892 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -3,7 +3,7 @@ #include "objects/object_os_anime/object_os_anime.h" #include "overlays/actors/ovl_En_Niw/z_en_niw.h" #include "vt.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -204,7 +204,9 @@ void func_80ABA244(EnNiwLady* this, PlayState* play) { EnNiw* currentCucco; s32 phi_s1; - this->cuccosInPen = IS_RANDO ? (7 - Randomizer_GetSettingValue(RSK_CUCCO_COUNT)) : 0; + if (GameInteractor_Should(GI_VB_SET_CUCCO_COUNT, true, this)) { + this->cuccosInPen = 0; + } currentCucco = (EnNiw*)play->actorCtx.actorLists[ACTORCAT_PROP].head; while (currentCucco != NULL) { if (currentCucco->actor.id == ACTOR_EN_NIW) { @@ -239,9 +241,11 @@ void func_80ABA244(EnNiwLady* this, PlayState* play) { phi_s1 = 7; } } + // Completed minigame and then threw Cucco(s) out of the pen if ((this->unk_26C != 0) && (phi_s1 < 7)) { phi_s1 = 9; } + this->actor.textId = sMissingCuccoTextIds[phi_s1]; if (Text_GetFaceReaction(play, 8) != 0) { this->actor.textId = Text_GetFaceReaction(play, 8); @@ -308,16 +312,18 @@ void func_80ABA654(EnNiwLady* this, PlayState* play) { if (!Flags_GetItemGetInf(ITEMGETINF_0C)) { this->actor.parent = NULL; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ANJU_AS_CHILD, true, this)) { this->getItemId = GI_BOTTLE; func_8002F434(&this->actor, play, GI_BOTTLE, 100.0f, 50.0f); } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_ANJU_AS_CHILD, GI_BOTTLE); - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 100.0f, 50.0f); + // Circumvent the item offer action + this->actionFunc = func_80ABAC84; + return; } this->actionFunc = func_80ABAC00; return; + } if (this->unk_26C == 1) { this->getItemId = GI_RUPEE_PURPLE; @@ -398,15 +404,15 @@ void func_80ABA9B8(EnNiwLady* this, PlayState* play) { Message_CloseTextbox(play); this->actor.parent = NULL; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ANJU_AS_ADULT, true, this)) { func_8002F434(&this->actor, play, GI_POCKET_EGG, 200.0f, 100.0f); + this->actionFunc = func_80ABAC00; } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 200.0f, 100.0f); - Flags_SetItemGetInf(ITEMGETINF_2C); + // Circumvent the item offer action + this->actionFunc = func_80ABAC84; + return; } - this->actionFunc = func_80ABAC00; break; case 1: this->actor.textId = sTradeItemTextIds[3]; @@ -433,15 +439,14 @@ void func_80ABAB08(EnNiwLady* this, PlayState* play) { case 0: Message_CloseTextbox(play); this->actor.parent = NULL; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_TRADE_POCKET_CUCCO, true, this)) { func_8002F434(&this->actor, play, GI_COJIRO, 200.0f, 100.0f); + this->actionFunc = func_80ABAC00; } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_POCKET_CUCCO, GI_COJIRO); - Randomizer_ConsumeAdultTradeItem(play, ITEM_POCKET_CUCCO); - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 200.0f, 100.0f); - Flags_SetItemGetInf(ITEMGETINF_2E); + // Circumvent the item offer action + this->actionFunc = func_80ABAC84; + return; } - this->actionFunc = func_80ABAC00; break; case 1: Message_CloseTextbox(play); @@ -462,12 +467,6 @@ void func_80ABAC00(EnNiwLady* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actionFunc = func_80ABAC84; } else { - if (IS_RANDO) { - getItemId = this->getItemEntry.getItemId; - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 200.0f, 100.0f); - return; - } - getItemId = this->getItemId; if (LINK_IS_ADULT) { getItemId = !Flags_GetItemGetInf(ITEMGETINF_2C) ? GI_POCKET_EGG : GI_COJIRO; @@ -482,8 +481,7 @@ void func_80ABAC84(EnNiwLady* this, PlayState* play) { } osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST); if (LINK_IS_ADULT) { - // Flags for randomizer gives are set in the original message prompt choice handling - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM, true, this)) { if (!Flags_GetItemGetInf(ITEMGETINF_2C)) { Flags_SetItemGetInf(ITEMGETINF_2C); } else { diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 303c58819..4ae7d366f 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -10,6 +10,7 @@ #include "scenes/overworld/spot16/spot16_scene.h" #include "vt.h" #include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -42,6 +43,7 @@ void func_80ACAF74(EnOwl* this, PlayState* play); void func_80ACC30C(EnOwl* this, PlayState* play); void func_80ACB4FC(EnOwl* this, PlayState* play); void func_80ACB680(EnOwl* this, PlayState* play); +void func_80ACA62C(EnOwl* this, PlayState* play); void func_80ACC460(EnOwl* this); void func_80ACBEA0(EnOwl*, PlayState*); @@ -137,9 +139,7 @@ void EnOwl_Init(Actor* thisx, PlayState* play) { // "conversation owl %4x no = %d, sv = %d" osSyncPrintf(VT_FGCOL(CYAN) " 会話フクロウ %4x no = %d, sv = %d\n" VT_RST, this->actor.params, owlType, switchFlag); - if (((owlType != OWL_DEFAULT) && (switchFlag < 0x20) && Flags_GetSwitch(play, switchFlag)) || - // Owl shortcuts at SPOT06: Lake Hylia and SPOT16: Death Mountain Trail - (IS_RANDO && !(play->sceneNum == SCENE_LAKE_HYLIA || play->sceneNum == SCENE_DEATH_MOUNTAIN_TRAIL))) { + if ((owlType != OWL_DEFAULT) && (switchFlag < 0x20) && Flags_GetSwitch(play, switchFlag)) { osSyncPrintf("savebitでフクロウ退避\n"); // "Save owl with savebit" Actor_Kill(&this->actor); return; @@ -283,7 +283,7 @@ s32 EnOwl_CheckInitTalk(EnOwl* this, PlayState* play, u16 textId, f32 targetDist } else { this->actor.textId = textId; distCheck = (flags & 2) ? 200.0f : 1000.0f; - if (this->actor.xzDistToPlayer < targetDist) { + if (GameInteractor_Should(GI_VB_OWL_INTERACTION, this->actor.xzDistToPlayer < targetDist, this)) { this->actor.flags |= ACTOR_FLAG_WILL_TALK; func_8002F1C4(&this->actor, play, targetDist, distCheck, 0); } diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h index 7a20eaa3a..a898dce2a 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h @@ -43,4 +43,6 @@ typedef struct EnOwl { /* 0x0410 */ OwlFunc unk_410; } EnOwl; // size = 0x0414 +void func_80ACA62C(EnOwl* enOwl, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c b/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c index 73996d58f..eafa8b82e 100644 --- a/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c +++ b/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c @@ -7,6 +7,7 @@ #include "z_en_rl.h" #include "vt.h" #include "objects/object_rl/object_rl.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -126,7 +127,9 @@ void func_80AE7590(EnRl* this, PlayState* play) { pos.y = player->actor.world.pos.y + 80.0f; pos.z = player->actor.world.pos.z; Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, pos.x, pos.y, pos.z, 0, 0, 0, 0xE, true); - Item_Give(play, ITEM_MEDALLION_LIGHT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_LIGHT_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_LIGHT); + } this->lightMedallionGiven = 1; } } diff --git a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c index fe4a77724..93d1fd99c 100644 --- a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c +++ b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c @@ -8,6 +8,7 @@ #include "objects/object_ru2/object_ru2.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -260,7 +261,9 @@ void func_80AF2A38(EnRu2* this, PlayState* play) { f32 posZ = player->actor.world.pos.z; Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 10); - Item_Give(play, ITEM_MEDALLION_WATER); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_WATER_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_WATER); + } } void func_80AF2AB4(EnRu2* this, PlayState* play) { @@ -273,7 +276,9 @@ void func_80AF2AB4(EnRu2* this, PlayState* play) { this->action = 1; play->csCtx.segment = &D_80AF411C; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_WATER); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_WATER_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_WATER); + } temp = this->actor.world.rot.y + 0x8000; player->actor.shape.rot.y = temp; player->actor.world.rot.y = temp; diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index 9e09a705c..f2b2db3f9 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -3,6 +3,7 @@ #include "objects/object_sa/object_sa.h" #include "scenes/overworld/spot04/spot04_scene.h" #include "scenes/overworld/spot05/spot05_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -390,13 +391,10 @@ s32 func_80AF5DFC(EnSa* this, PlayState* play) { return 1; } if (play->sceneNum == SCENE_SACRED_FOREST_MEADOW && (Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER))) { - if (IS_RANDO) { - return 5; - } - return CHECK_QUEST_ITEM(QUEST_SONG_SARIA) ? 2 : 5; + return GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_SARIAS_SONG, !CHECK_QUEST_ITEM(QUEST_SONG_SARIA), NULL) ? 5 : 2; } if (play->sceneNum == SCENE_KOKIRI_FOREST && !CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) { - if (Flags_GetInfTable(INFTABLE_GREETED_BY_SARIA)) { + if (GameInteractor_Should(GI_VB_NOT_BE_GREETED_BY_SARIA, Flags_GetInfTable(INFTABLE_GREETED_BY_SARIA), NULL)) { return 1; } return 4; @@ -622,28 +620,17 @@ void func_80AF67D0(EnSa* this, PlayState* play) { } } -void GivePlayerRandoRewardSaria(EnSa* saria, PlayState* play, RandomizerCheck check) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SARIAS_SONG); - if (saria->actor.parent != NULL && saria->actor.parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1F)) { - Flags_SetTreasure(play, 0x1F); - } else if (!Flags_GetTreasure(play, 0x1F)) { - GiveItemEntryFromActor(&saria->actor, play, getItemEntry, 10000.0f, 100.0f); - } -} - void func_80AF683C(EnSa* this, PlayState* play) { Player* player = GET_PLAYER(play); if (!(player->actor.world.pos.z >= -2220.0f) && !Play_InCsMode(play)) { - if (IS_RANDO) { - GivePlayerRandoRewardSaria(this, play, RC_SONG_FROM_SARIA); - return; + // SOH [General] This flag was previously unused, but was named accordingly so we will make use of it. (Normally we should opt for soh_inf) + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SARIAS_SONG); + if (GameInteractor_Should(GI_VB_PLAY_SARIAS_SONG_CS, true, this)) { + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(spot05_scene_Cs_005730); + gSaveContext.cutsceneTrigger = 1; + this->actionFunc = func_80AF68E4; } - - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(spot05_scene_Cs_005730); - gSaveContext.cutsceneTrigger = 1; - this->actionFunc = func_80AF68E4; } } @@ -721,7 +708,9 @@ void func_80AF68E4(EnSa* this, PlayState* play) { void func_80AF6B20(EnSa* this, PlayState* play) { if (play->sceneNum == SCENE_SACRED_FOREST_MEADOW) { - Item_Give(play, ITEM_SONG_SARIA); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SARIAS_SONG, true, NULL)) { + Item_Give(play, ITEM_SONG_SARIA); + } EnSa_ChangeAnim(this, ENSA_ANIM1_6); } diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h index 2965f04ab..56d368f13 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h @@ -30,4 +30,6 @@ typedef struct EnSa { /* 0x0286 */ Vec3s morphTable[17]; } EnSa; // size = 0x02EC +void func_80AF6B20(EnSa* enSa, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c index 6f48314ff..0f300d16f 100644 --- a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c +++ b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c @@ -1,5 +1,6 @@ #include "z_en_shopnuts.h" #include "objects/object_shopnuts/object_shopnuts.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -69,18 +70,11 @@ void EnShopnuts_Init(Actor* thisx, PlayState* play) { CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); Collider_UpdateCylinder(&this->actor, &this->collider); - if (IS_RANDO) { - s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - ScrubIdentity scrubIdentity = Randomizer_IdentifyScrub(play->sceneNum, this->actor.params, respawnData); - - if (scrubIdentity.isShuffled && Flags_GetRandomizerInf(scrubIdentity.randomizerInf)) { - Actor_Kill(&this->actor); - } - } - - if (((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) || + if (GameInteractor_Should(GI_VB_BUSINESS_SCRUB_DESPAWN, + ((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) || ((this->actor.params == 0x0009) && (Flags_GetInfTable(INFTABLE_192))) || - ((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193)))) { + ((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193))), + this)) { Actor_Kill(&this->actor); } else { EnShopnuts_SetupWait(this); diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c index 49e88f903..8eb669d2d 100644 --- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c +++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c @@ -7,9 +7,6 @@ #include "z_en_si.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -extern void func_8083C148(Player*, PlayState*); -extern void func_80078884(uint16_t); - #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOOKSHOT_DRAGS) void EnSi_Init(Actor* thisx, PlayState* play); @@ -21,13 +18,6 @@ s32 func_80AFB748(EnSi* this, PlayState* play); void func_80AFB768(EnSi* this, PlayState* play); void func_80AFB89C(EnSi* this, PlayState* play); void func_80AFB950(EnSi* this, PlayState* play); -void Randomizer_UpdateSkullReward(EnSi* this, PlayState* play); -void Randomizer_GiveSkullReward(EnSi* this, PlayState* play); - -s32 textId = 0xB4; -s32 giveItemId = ITEM_SKULL_TOKEN; -s32 getItemId; -GetItemEntry getItem; static ColliderCylinderInit sCylinderInit = { { @@ -104,36 +94,12 @@ void func_80AFB768(EnSi* this, PlayState* play) { if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; - - if (IS_RANDO) { - Randomizer_UpdateSkullReward(this, play); - } else { - Item_Give(play, giveItemId); - } - if ((!CVarGetInteger("gSkulltulaFreeze", 0) || giveItemId != ITEM_SKULL_TOKEN) && - getItemId != RG_ICE_TRAP) { - player->actor.freezeTimer = 20; - } - - if (getItemId == RG_ICE_TRAP && Message_GetState(&play->msgCtx) != TEXT_STATE_CLOSING) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SKULL_TOKEN, true, this)) { + Item_Give(play, ITEM_SKULL_TOKEN); player->actor.freezeTimer = 10; - } - - Message_StartTextbox(play, textId, NULL); - - if (IS_RANDO) { - if (getItemId != RG_ICE_TRAP) { - Randomizer_GiveSkullReward(this, play); - Audio_PlayFanfare_Rando(getItem); - } else { - gSaveContext.pendingIceTrapCount++; - Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); - } - } else { + Message_StartTextbox(play, 0xB4, NULL); Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); } - - player->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = func_80AFB950; } else { Collider_UpdateCylinder(&this->actor, &this->collider); @@ -146,32 +112,18 @@ void func_80AFB768(EnSi* this, PlayState* play) { void func_80AFB89C(EnSi* this, PlayState* play) { Player* player = GET_PLAYER(play); + Math_SmoothStepToF(&this->actor.scale.x, 0.25f, 0.4f, 1.0f, 0.0f); Actor_SetScale(&this->actor, this->actor.scale.x); this->actor.shape.rot.y += 0x400; if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) { - if (IS_RANDO) { - Randomizer_UpdateSkullReward(this, play); - } else { - Item_Give(play, giveItemId); - } - - Message_StartTextbox(play, textId, NULL); - - if (IS_RANDO) { - if (getItemId != RG_ICE_TRAP) { - Randomizer_GiveSkullReward(this, play); - Audio_PlayFanfare_Rando(getItem); - } else { - gSaveContext.pendingIceTrapCount++; - Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); - } - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SKULL_TOKEN, true, this)) { + Item_Give(play, ITEM_SKULL_TOKEN); + player->actor.freezeTimer = 10; + Message_StartTextbox(play, 0xB4, NULL); Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); } - - player->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = func_80AFB950; } } @@ -179,19 +131,12 @@ void func_80AFB89C(EnSi* this, PlayState* play) { void func_80AFB950(EnSi* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (Message_GetState(&play->msgCtx) != TEXT_STATE_CLOSING && - (!CVarGetInteger("gSkulltulaFreeze", 0) || getItemId == RG_ICE_TRAP || giveItemId != ITEM_SKULL_TOKEN)) { + if (Message_GetState(&play->msgCtx) != TEXT_STATE_CLOSING && GameInteractor_Should(GI_VB_GIVE_ITEM_SKULL_TOKEN, true, this)) { player->actor.freezeTimer = 10; } else { SET_GS_FLAGS((this->actor.params & 0x1F00) >> 8, this->actor.params & 0xFF); GameInteractor_ExecuteOnFlagSet(FLAG_GS_TOKEN, this->actor.params); Actor_Kill(&this->actor); - if (gSaveContext.pendingIceTrapCount > 0 && player->heldItemId == 11) { - player->actor.freezeTimer = 0; - func_8083C148(GET_PLAYER(play), play); - func_80078884(NA_SE_SY_CAMERA_ZOOM_UP); - player->currentYaw = player->actor.shape.rot.y; - } } } @@ -210,44 +155,6 @@ void EnSi_Draw(Actor* thisx, PlayState* play) { if (this->actionFunc != func_80AFB950) { func_8002ED80(&this->actor, play, 0); func_8002EBCC(&this->actor, play, 0); - if (!IS_RANDO) { - GetItem_Draw(play, GID_SKULL_TOKEN_2); - } else { - getItem = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->actor.params, GI_SKULL_TOKEN); - EnItem00_CustomItemsParticles(&this->actor, play, getItem); - if (getItem.itemId != ITEM_SKULL_TOKEN) { - f32 mtxScale = 1.5f; - Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - } - GetItemEntry_Draw(play, getItem); - } - } -} - -void Randomizer_UpdateSkullReward(EnSi* this, PlayState* play) { - Player* player = GET_PLAYER(play); - - getItem = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->actor.params, GI_SKULL_TOKEN); - getItemId = getItem.getItemId; - if (getItemId == RG_ICE_TRAP) { - textId = 0xF8; - } else { - textId = getItem.textId; - giveItemId = getItem.itemId; - } - player->getItemEntry = getItem; -} - -void Randomizer_GiveSkullReward(EnSi* this, PlayState* play) { - Player* player = GET_PLAYER(play); - - if (getItem.modIndex == MOD_NONE) { - // RANDOTOD: Move this into Item_Give() or some other more central location - if (getItem.getItemId == GI_SWORD_BGS) { - gSaveContext.bgsFlag = true; - } - Item_Give(play, giveItemId); - } else if (getItem.modIndex == MOD_RANDOMIZER) { - Randomizer_Item_Give(play, getItem); + GetItem_Draw(play, GID_SKULL_TOKEN_2); } } diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.h b/soh/src/overlays/actors/ovl_En_Si/z_en_si.h index dc0a3b400..318876289 100644 --- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.h +++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.h @@ -13,6 +13,9 @@ typedef struct EnSi { /* 0x014C */ EnSiActionFunc actionFunc; /* 0x0150 */ ColliderCylinder collider; /* 0x019C */ u8 unk_19C; + // #region SOH [Randomizer] Caching the get item entry for the draw function for performance + /* */ GetItemEntry sohGetItemEntry; + // #endregion } EnSi; // size = 0x01A0 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index 0eb3e9095..2f47f7c2a 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -7,6 +7,7 @@ #include "z_en_ta.h" #include "vt.h" #include "objects/object_ta/object_ta.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -466,7 +467,7 @@ void func_80B14B6C(EnTa* this, PlayState* play) { func_80B13AA0(this, func_80B14AF4, func_80B167C0); this->unk_2CC = 5; Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE); - if (IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { OnePointCutscene_EndCutscene(play, csCamIdx); } Animation_PlayOnce(&this->skelAnime, &gTalonRunTransitionAnim); diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 55fbed824..342eed149 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -8,12 +8,9 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_tk/object_tk.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) -#define COLLECTFLAG_GRAVEDIGGING_HEART_PIECE 0x19 -#define ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE 0x1000 - -bool heartPieceSpawned; void EnTk_Init(Actor* thisx, PlayState* play); void EnTk_Destroy(Actor* thisx, PlayState* play); @@ -408,10 +405,6 @@ s32 EnTk_ChooseReward(EnTk* this) { f32 luck; s32 reward; - if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE) && this->heartPieceSpawned == 0) { - return 3; - } - luck = Rand_ZeroOne(); if (luck < 0.4f) { @@ -502,12 +495,7 @@ void EnTk_Init(Actor* thisx, PlayState* play) { CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - if (CVarGetInteger("gDampeAllNight", 0)) { - if (!!LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD) { - Actor_Kill(&this->actor); - return; - } - } else if (gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || !!LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD) { + if (GameInteractor_Should(GI_VB_DAMPE_IN_GRAVEYARD_DESPAWN, gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD, this)) { Actor_Kill(&this->actor); return; } @@ -519,7 +507,6 @@ void EnTk_Init(Actor* thisx, PlayState* play) { this->currentReward = -1; this->currentSpot = NULL; this->actionFunc = EnTk_Rest; - heartPieceSpawned = false; } void EnTk_Destroy(Actor* thisx, PlayState* play) { @@ -599,7 +586,11 @@ void EnTk_Dig(EnTk* this, PlayState* play) { Vec3f rewardOrigin; Vec3f rewardPos; s32 rewardParams[] = { - ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_RED, ITEM00_RUPEE_PURPLE, ITEM00_HEART_PIECE, + ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_RED, ITEM00_RUPEE_PURPLE, + // #region SOH [General] Typically this heart piece would have no collectible flag set when it's picked up, but for both randomizer + // and gGravediggingTourFix we want to set one, and rely on it instead of the ItemGetInf flag that is set when the heart is spawned + ((COLLECTFLAG_GRAVEDIGGING_HEART_PIECE & 0x3F) << 8) | ITEM00_HEART_PIECE, + // #endregion }; EnTk_DigEff(this); @@ -610,7 +601,7 @@ void EnTk_Dig(EnTk* this, PlayState* play) { this->rewardTimer = 0; - if (this->validDigHere == 1 || IS_RANDO || CVarGetInteger("gDampeWin", 0)) { + if (GameInteractor_Should(GI_VB_BE_VALID_GRAVEDIGGING_SPOT, this->validDigHere == 1, this)) { rewardOrigin.x = 0.0f; rewardOrigin.y = 0.0f; rewardOrigin.z = -40.0f; @@ -624,51 +615,24 @@ void EnTk_Dig(EnTk* this, PlayState* play) { this->currentReward = EnTk_ChooseReward(this); - if (this->currentReward == 3) { - if (IS_RANDO || CVarGetInteger("gDampeWin", 0)) { - /* - * Upgrade the purple rupee reward to the heart piece if this - * is the first grand prize dig. - */ - if (!Flags_GetItemGetInf(ITEMGETINF_1C) && !(IS_RANDO || CVarGetInteger("gDampeWin", 0))) { - Flags_SetItemGetInf(ITEMGETINF_1C); - this->currentReward = 4; - } else if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE) && this->heartPieceSpawned == 0) { - this->currentReward = 4; - } - } + if (GameInteractor_Should(GI_VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE, this->currentReward == 3, this)) { /* - * Upgrade the purple rupee reward to the heart piece if this - * is the first grand prize dig. - */ - // If vanilla itemGetInf flag is not set, it's impossible for the new flag to be set, so return true. - // Otherwise if the gGravediggingTourFix is enabled and the new flag hasn't been set, return true. - // If true, spawn the heart piece and set the vanilla itemGetInf flag and new temp clear flag. - if (!heartPieceSpawned && - (!(gSaveContext.itemGetInf[1] & ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE) || - CVarGetInteger("gGravediggingTourFix", 0) && - !Flags_GetCollectible(play, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE))) { + * Upgrade the purple rupee reward to the heart piece if this + * is the first grand prize dig. + */ + if (GameInteractor_Should(GI_VB_DAMPE_GRAVEDIGGING_GRAND_PRIZE_BE_HEART_PIECE, !Flags_GetItemGetInf(ITEMGETINF_1C), this)) { + Flags_SetItemGetInf(ITEMGETINF_1C); this->currentReward = 4; - gSaveContext.itemGetInf[1] |= ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE; - heartPieceSpawned = true; } } - if (IS_RANDO && this->currentReward == 4) { - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, rewardPos.x, rewardPos.y, rewardPos.z, 0, 0, 0, 0x1906, true); - this->heartPieceSpawned = 1; - } else { - EnItem00* reward = Item_DropCollectible(play, &rewardPos, rewardParams[this->currentReward]); - if (this->currentReward == 4) { - reward->collectibleFlag = COLLECTFLAG_GRAVEDIGGING_HEART_PIECE; - } - } + Item_DropCollectible(play, &rewardPos, rewardParams[this->currentReward]); } } if (this->skelAnime.curFrame >= 32.0f && this->rewardTimer == 10) { /* Play a reward sound shortly after digging */ - if (!(IS_RANDO || CVarGetInteger("gDampeWin", 0)) && this->validDigHere == 0) { + if (this->validDigHere == 0) { /* Bad dig spot */ Audio_PlayActorSound2(&this->actor, NA_SE_SY_ERROR); } else if (this->currentReward == 4) { diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h index c60cb5200..c2dee0fce 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h @@ -8,6 +8,8 @@ /* Dirt particle effect */ struct EnTkEff; +#define COLLECTFLAG_GRAVEDIGGING_HEART_PIECE 0x19 + typedef struct EnTkEff { /* 0x0000 */ u8 active; /* 0x0001 */ u8 timeLeft; diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index d52b82d8d..c2ac2861b 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -6,7 +6,7 @@ #include "z_en_toryo.h" #include "objects/object_toryo/object_toryo.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -291,10 +291,7 @@ void func_80B20768(EnToryo* this, PlayState* play) { s16 sp32; s16 sp30; - // Animation Count should be no more than 1 to guarantee putaway is complete after giving the saw - // As this is vanilla behavior, it only applies with the Fix toggle or Skip Text enabled. - bool checkAnim = (CVarGetInteger("gFixSawSoftlock", 0) != 0 || CVarGetInteger("gSkipText", 0) != 0) ? play->animationCtx.animationCount <= 1 : true; - if (this->unk_1E4 == 3 && checkAnim) { + if (this->unk_1E4 == 3 && !GameInteractor_Should(GI_VB_FIX_SAW_SOFTLOCK, false, NULL)) { Actor_ProcessTalkRequest(&this->actor, play); Message_ContinueTextbox(play, this->actor.textId); this->unk_1E4 = 1; @@ -315,19 +312,12 @@ void func_80B20768(EnToryo* this, PlayState* play) { } if (this->unk_1E4 == 4) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_SAW, true, this)) { this->actor.parent = NULL; this->unk_1E4 = 5; + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW); } else { - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GV_TRADE_SAW, GI_SWORD_BROKEN); - Randomizer_ConsumeAdultTradeItem(play, ITEM_SAW); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 100.0f, 10.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW); - } else { - s32 itemId = GI_SWORD_BROKEN; - func_8002F434(&this->actor, play, itemId, 100.0f, 10.0f); - } + func_8002F434(&this->actor, play, GI_SWORD_BROKEN, 100.0f, 10.0f); } return; } diff --git a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c index 2b90e1ff7..658dd63f8 100644 --- a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c +++ b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c @@ -6,6 +6,7 @@ #include "z_en_wonder_talk2.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_LOCKON) @@ -194,7 +195,9 @@ void func_80B3A3D4(EnWonderTalk2* this, PlayState* play) { this->unk_15A = true; } this->actor.flags &= ~(ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED); - func_8002DF54(play, NULL, 7); + if (GameInteractor_Should(GI_VB_WONDER_TALK, true, this)) { + func_8002DF54(play, NULL, 7); + } this->unk_156 = true; this->actionFunc = func_80B3A4F8; break; @@ -252,42 +255,12 @@ void func_80B3A4F8(EnWonderTalk2* this, PlayState* play) { } this->unk_158 = 0; if (!this->unk_156) { - // Whether or not to skip the text in rando - bool randoSkipText = false; - if (IS_RANDO) { - // Scenes for which all of this type of wonder talk should be skipped. - switch (play->sceneNum) { - case SCENE_SHADOW_TEMPLE: // Shadow Temple - randoSkipText = true; - break; - case SCENE_GERUDO_TRAINING_GROUND: // Gerudo Training Grounds - randoSkipText = true; - break; - case SCENE_THIEVES_HIDEOUT: // Inside Gerudo Fortress - randoSkipText = true; - break; - default: - break; - } - // individual textIds that should be skipped, or that should be preserved - // in a scene that otherwise has all wonder talk skipped. - //switch (this->actor.textId) { - // case: 0x023c //textId we want to skip - // randoSkipText = true; - // break; - // case 0x023c: // textId in a skipped scene that we don't want to skip - // randoSkipText = false; - // break; - // default: - // break; - //} - } - if (!(randoSkipText)) { + if (GameInteractor_Should(GI_VB_WONDER_TALK, true, this)) { Message_StartTextbox(play, this->actor.textId, NULL); func_8002DF54(play, NULL, 8); - this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED; - this->actionFunc = func_80B3A3D4; } + this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED; + this->actionFunc = func_80B3A3D4; } } else { diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index 83f799877..6436df29f 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -13,6 +13,7 @@ #include "scenes/indoors/tokinoma/tokinoma_scene.h" #include "scenes/dungeons/ice_doukutu/ice_doukutu_scene.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -277,6 +278,7 @@ void func_80B3C9EC(EnXc* this) { this->action = SHEIK_ACTION_BLOCK_PEDESTAL; this->drawMode = SHEIK_DRAW_DEFAULT; this->unk_30C = 1; + // SOH [Randomizer] We don't want sheik blocking the pedestal in randomizer if (IS_RANDO) { Actor_Kill(&this->actor); } @@ -292,24 +294,6 @@ void func_80B3CA38(EnXc* this, PlayState* play) { } } -void GivePlayerRandoRewardSheikSong(EnXc* sheik, PlayState* play, RandomizerCheck check, int sheikType, GetItemID ogSongId) { - Player* player = GET_PLAYER(play); - if (!(gSaveContext.eventChkInf[5] & sheikType)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, ogSongId); - if (check == RC_SHEIK_AT_TEMPLE && !Flags_GetTreasure(play, 0x1F)) { - if (GiveItemEntryFromActor(&sheik->actor, play, getItemEntry, 10000.0f, 100.0f)) { - player->pendingFlag.flagID = 0x1F; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } - } else if (check != RC_SHEIK_AT_TEMPLE) { - if (GiveItemEntryFromActor(&sheik->actor, play, getItemEntry, 10000.0f, 100.0f)) { - player->pendingFlag.flagID = (0x5 << 4) | (sheikType & 0xF) >> 1; - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - } - } - } -} - s32 EnXc_MinuetCS(EnXc* this, PlayState* play) { if (this->actor.params == SHEIK_TYPE_MINUET) { Player* player = GET_PLAYER(play); @@ -317,16 +301,17 @@ s32 EnXc_MinuetCS(EnXc* this, PlayState* play) { if (z < -2225.0f) { if (!Play_InCsMode(play)) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_MINUET_OF_FOREST_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(&gMinuetCs); gSaveContext.cutsceneTrigger = 1; - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_MINUET_OF_FOREST); - Item_Give(play, ITEM_SONG_MINUET); - } else { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_IN_FOREST, 1, RG_MINUET_OF_FOREST); - return false; } - return true; + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_MINUET_OF_FOREST); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_MINUET_OF_FOREST, true, NULL)) { + Item_Give(play, ITEM_SONG_MINUET); + } + if (GameInteractor_Should(GI_VB_PLAY_MINUET_OF_FOREST_CS, true, NULL)) { + return true; + } } } return false; @@ -353,16 +338,17 @@ s32 EnXc_BoleroCS(EnXc* this, PlayState* play) { if ((posRot->pos.x > -784.0f) && (posRot->pos.x < -584.0f) && (posRot->pos.y > 447.0f) && (posRot->pos.y < 647.0f) && (posRot->pos.z > -446.0f) && (posRot->pos.z < -246.0f) && !Play_InCsMode(play)) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_BOLERO_OF_FIRE_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(&gDeathMountainCraterBoleroCs); gSaveContext.cutsceneTrigger = 1; - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_BOLERO_OF_FIRE); - Item_Give(play, ITEM_SONG_BOLERO); - } else { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_IN_CRATER, 2, RG_BOLERO_OF_FIRE); - return false; } - return true; + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_BOLERO_OF_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_BOLERO_OF_FIRE, true, NULL)) { + Item_Give(play, ITEM_SONG_BOLERO); + } + if (GameInteractor_Should(GI_VB_PLAY_BOLERO_OF_FIRE_CS, true, NULL)) { + return true; + } } return false; } @@ -370,13 +356,8 @@ s32 EnXc_BoleroCS(EnXc* this, PlayState* play) { } void EnXc_SetupSerenadeAction(EnXc* this, PlayState* play) { - if (IS_RANDO) { - this->action = SHEIK_ACTION_SERENADE; - return; - } - // Player is adult and does not have iron boots and has not learned Serenade - if ((!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER, (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT, NULL)) { this->action = SHEIK_ACTION_SERENADE; osSyncPrintf("水のセレナーデ シーク誕生!!!!!!!!!!!!!!!!!!\n"); } else { @@ -389,22 +370,20 @@ s32 EnXc_SerenadeCS(EnXc* this, PlayState* play) { if (this->actor.params == SHEIK_TYPE_SERENADE) { Player* player = GET_PLAYER(play); s32 stateFlags = player->stateFlags1; - - if (((CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !IS_RANDO) || - (Flags_GetTreasure(play, 2) && IS_RANDO)) && - !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && !(stateFlags & 0x20000000) && - !Play_InCsMode(play)) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER, CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER), NULL) && + !(stateFlags & PLAYER_STATE1_IN_CUTSCENE) && !Play_InCsMode(play)) { + if (GameInteractor_Should(GI_VB_PLAY_SERENADE_OF_WATER_CS, true, NULL)) { Cutscene_SetSegment(play, &gIceCavernSerenadeCs); gSaveContext.cutsceneTrigger = 1; - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER); // Learned Serenade of Water Flag + } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER); // Learned Serenade of Water Flag + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SERENADE_OF_WATER, true, NULL)) { Item_Give(play, ITEM_SONG_SERENADE); - } else { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_IN_ICE_CAVERN, 4, RG_SERENADE_OF_WATER); - return false; } osSyncPrintf("ブーツを取った!!!!!!!!!!!!!!!!!!\n"); - return true; + if (GameInteractor_Should(GI_VB_PLAY_SERENADE_OF_WATER_CS, true, NULL)) { + return true; + } } osSyncPrintf("はやくブーツを取るべし!!!!!!!!!!!!!!!!!!\n"); return false; @@ -415,7 +394,7 @@ s32 EnXc_SerenadeCS(EnXc* this, PlayState* play) { void EnXc_DoNothing(EnXc* this, PlayState* play) { } -void EnXc_RandoStand(EnXc* this, PlayState* play) { +void SoH_EnXc_RandoStand(EnXc* this, PlayState* play) { //Replaces Ganondorf Light Arrow hint. also stands in ToT if (play->sceneNum == SCENE_TEMPLE_OF_TIME) { EnXc_ChangeAnimation(this, &gSheikArmsCrossedIdleAnim, ANIMMODE_LOOP, 0.0f, false); @@ -2209,22 +2188,21 @@ void EnXc_InitTempleOfTime(EnXc* this, PlayState* play) { if (LINK_IS_ADULT) { if (!Flags_GetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL)) { Flags_SetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL); - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gTempleOfTimeFirstAdultCs); - gSaveContext.cutsceneTrigger = 1; + if (GameInteractor_Should(GI_VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS, true, NULL)) { + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gTempleOfTimeFirstAdultCs); + gSaveContext.cutsceneTrigger = 1; + } func_80B3EBF0(this, play); - } else if ((!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) && - !IS_RANDO) || - (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && - IS_RANDO)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT, !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT, true, NULL)) { Item_Give(play, ITEM_SONG_PRELUDE); + } + if (GameInteractor_Should(GI_VB_PLAY_PRELUDE_OF_LIGHT_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gTempleOfTimePreludeCs); gSaveContext.cutsceneTrigger = 1; - this->action = SHEIK_ACTION_30; - } else { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_AT_TEMPLE, 0x20, RG_PRELUDE_OF_LIGHT); } + this->action = SHEIK_ACTION_30; // Not sure what this does exactly } else if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT)) { func_80B3C9EC(this); } else { @@ -2378,14 +2356,6 @@ void EnXc_Update(Actor* thisx, PlayState* play) { EnXc* this = (EnXc*)thisx; s32 action = this->action; - if (this->actor.params == SHEIK_TYPE_9) { - if (IS_RANDO && LINK_IS_ADULT) { - if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT)) { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_AT_TEMPLE, 0x20, RG_PRELUDE_OF_LIGHT); - } - } - } - if ((action < 0) || (action >= ARRAY_COUNT(sActionFuncs)) || (sActionFuncs[action] == NULL)) { osSyncPrintf(VT_FGCOL(RED) "メインモードがおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST); } else { @@ -2433,7 +2403,7 @@ void EnXc_Init(Actor* thisx, PlayState* play) { EnXc_DoNothing(this, play); break; case SHEIK_TYPE_RANDO: - EnXc_RandoStand(this, play); + SoH_EnXc_RandoStand(this, play); break; default: osSyncPrintf(VT_FGCOL(RED) " En_Oa2 の arg_data がおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST); diff --git a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c index 4a47b456e..9bc53169b 100644 --- a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c +++ b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c @@ -10,6 +10,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "objects/object_zl2/object_zl2.h" #include "objects/object_zl2_anime1/object_zl2_anime1.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -633,7 +634,9 @@ void EnZl2_GiveLightArrows(EnZl2* this, PlayState* play) { posY = player->actor.world.pos.y + 80.0f; posZ = player->actor.world.pos.z; Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 0x17, true); - Item_Give(play, ITEM_ARROW_LIGHT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_LIGHT_ARROW, true, NULL)) { + Item_Give(play, ITEM_ARROW_LIGHT); + } this->unk_244 = 1; } } diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index 08c3857e0..f805e2fb5 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -7,6 +7,7 @@ #include "z_en_zl4.h" #include "objects/object_zl4/object_zl4.h" #include "scenes/indoors/nakaniwa/nakaniwa_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -227,20 +228,6 @@ u16 EnZl4_GetText(PlayState* play, Actor* thisx) { return ret; } -void GivePlayerRandoRewardZeldaChild(EnZl4* zelda, PlayState* play, RandomizerCheck check) { - if (zelda->actor.parent != NULL && zelda->actor.parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1E)) { - Flags_SetTreasure(play, 0x1E); - } else if (!Flags_GetTreasure(play, 0x1E) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA) && Actor_TextboxIsClosing(&zelda->actor, play) && - (play->msgCtx.textId == 0x703C || play->msgCtx.textId == 0x703D)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, GI_LETTER_ZELDA); - GiveItemEntryFromActor(&zelda->actor, play, getItemEntry, 10000.0f, 100.0f); - } else if (Flags_GetTreasure(play, 0x1E) && !Player_InBlockingCsMode(play, GET_PLAYER(play))) { - gSaveContext.unk_13EE = 0x32; - Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); - } -} - s16 func_80B5B9B0(PlayState* play, Actor* thisx) { EnZl4* this = (EnZl4*)thisx; @@ -389,12 +376,6 @@ void EnZl4_Init(Actor* thisx, PlayState* play) { this->actor.textId = -1; this->eyeExpression = this->mouthExpression = ZL4_MOUTH_NEUTRAL; - if (IS_RANDO) { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_0); - this->actionFunc = EnZl4_Idle; - return; - } - if (gSaveContext.sceneSetupIndex >= 4) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_0); this->actionFunc = EnZl4_TheEnd; @@ -1127,14 +1108,16 @@ s32 EnZl4_CsMakePlan(EnZl4* this, PlayState* play) { Camera_ChangeSetting(GET_ACTIVE_CAM(play), 1); this->talkState = 7; play->talkWithPlayer(play, &this->actor); - func_8002F434(&this->actor, play, GI_LETTER_ZELDA, fabsf(this->actor.xzDistToPlayer) + 1.0f, - fabsf(this->actor.yDistToPlayer) + 1.0f); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LETTER, true, NULL)) { + func_8002F434(&this->actor, play, GI_LETTER_ZELDA, fabsf(this->actor.xzDistToPlayer) + 1.0f, + fabsf(this->actor.yDistToPlayer) + 1.0f); + } play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; } break; case 7: - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LETTER, true, NULL)) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_0); this->talkState++; } else { @@ -1225,11 +1208,6 @@ void EnZl4_Idle(EnZl4* this, PlayState* play) { Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 60.0f, EnZl4_GetText, func_80B5B9B0); func_80B5BB78(this, play); - - if (IS_RANDO) { - GivePlayerRandoRewardZeldaChild(this, play, RC_HC_ZELDAS_LETTER); - return; - } } void EnZl4_TheEnd(EnZl4* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h index 601ed6905..4b14121c6 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h @@ -31,4 +31,9 @@ typedef struct EnZl4 { /* 0x0284 */ Vec3s morphTable[18]; } EnZl4; // size = 0x02F0 +s16 func_80B5B9B0(PlayState* play, Actor* actor); +void func_80B5BB78(EnZl4* enZl4, PlayState* play); +void EnZl4_Cutscene(EnZl4* enZl4, PlayState* play); +s32 EnZl4_SetNextAnim(EnZl4* enZl4, s32 nextAnim); + #endif diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index abb65c191..f511d5bbf 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -59,12 +59,7 @@ void ItemBHeart_Update(Actor* thisx, PlayState* play) { Flags_SetCollectible(play, 0x1F); Actor_Kill(&this->actor); } else { - if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_HEART_CONTAINER_2, 30.0f, 40.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->actor.params, GI_HEART_CONTAINER_2); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 30.0f, 40.0f); - } + func_8002F434(&this->actor, play, GI_HEART_CONTAINER_2, 30.0f, 40.0f); } } @@ -98,23 +93,18 @@ void ItemBHeart_Draw(Actor* thisx, PlayState* play) { actorIt = actorIt->next; } - if (IS_RANDO) { - GetItemEntry_Draw(play, Randomizer_GetItemFromActor(this->actor.id, - play->sceneNum,this->actor.params, GI_HEART_CONTAINER_2)); + if (flag) { + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL); + gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL); } else { - if (flag) { - Gfx_SetupDL_25Xlu(play->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL); - gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL); - } else { - Gfx_SetupDL_25Opa(play->state.gfxCtx); - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL); - gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL); - } + Gfx_SetupDL_25Opa(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL); + gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL); } CLOSE_DISPS(play->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h index d9483b48c..434aa775b 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h @@ -13,6 +13,11 @@ typedef struct ItemBHeart { /* 0x015C */ char unk_15C[0x8]; /* 0x0164 */ s16 unk_164; /* 0x0166 */ char unk_166[0x6]; + // #region SOH [Randomizer] Cached for drawing for performance + /* */ GetItemEntry sohItemEntry; + // #endregion } ItemBHeart; // size = 0x016C +void func_80B85264(ItemBHeart* itemBHeart, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c index a9cd36446..dba879115 100644 --- a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c +++ b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c @@ -6,6 +6,7 @@ #include "z_item_ocarina.h" #include "scenes/overworld/spot00/spot00_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -169,31 +170,27 @@ void ItemOcarina_DoNothing(ItemOcarina* this, PlayState* play) { void ItemOcarina_StartSoTCutscene(ItemOcarina* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - if (!IS_RANDO) { - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gHyruleFieldZeldaSongOfTimeCs); - gSaveContext.cutsceneTrigger = 1; - } else { - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; - play->nextEntranceIndex = ENTR_HYRULE_FIELD_16; - gSaveContext.nextCutsceneIndex = 0; - } + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gHyruleFieldZeldaSongOfTimeCs); + gSaveContext.cutsceneTrigger = 1; } } void ItemOcarina_WaitInWater(ItemOcarina* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if ( + Actor_HasParent(&this->actor, play) || + ( + !GameInteractor_Should(GI_VB_GIVE_ITEM_OCARINA_OF_TIME, true, NULL) && + (this->actor.xzDistToPlayer < 20.0f) && (fabsf(this->actor.yDistToPlayer) < 10.0f) && + GET_PLAYER(play)->stateFlags2 & PLAYER_STATE2_DIVING + ) + ) { Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_OCARINA_OF_TIME); Flags_SetSwitch(play, 3); this->actionFunc = ItemOcarina_StartSoTCutscene; this->actor.draw = NULL; } else { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_OCARINA_OF_TIME, true, NULL)) { func_8002F434(&this->actor, play, GI_OCARINA_OOT, 30.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 30.0f, 50.0f); } if ((play->gameplayFrames & 13) == 0) { diff --git a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c index 34defede5..9220c6be4 100644 --- a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c +++ b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c @@ -7,6 +7,7 @@ #include "z_obj_switch.h" #include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -249,10 +250,12 @@ void ObjSwitch_SetOn(ObjSwitch* this, PlayState* play) { subType = (this->dyna.actor.params >> 4 & 7); Flags_SetSwitch(play, (this->dyna.actor.params >> 8 & 0x3F)); - if (subType == 0 || subType == 4) { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME); - } else { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + if (subType == 0 || subType == 4) { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME); + } else { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + } } this->cooldownOn = true; @@ -266,7 +269,9 @@ void ObjSwitch_SetOff(ObjSwitch* this, PlayState* play) { Flags_UnsetSwitch(play, (this->dyna.actor.params >> 8 & 0x3F)); if ((this->dyna.actor.params >> 4 & 7) == 1) { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + } this->cooldownOn = true; } } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 7489fa8fa..456955956 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -31,6 +31,7 @@ #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "soh/Enhancements/randomizer/fishsanity.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include #include @@ -6658,7 +6659,14 @@ s32 func_8083E5A8(Player* this, PlayState* play) { uint8_t showItemCutscene = play->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY || Item_CheckObtainability(giEntry.itemId) == ITEM_NONE || IS_RANDO; // Only skip cutscenes for drops when they're items/consumables from bushes/rocks/enemies. - uint8_t isDropToSkip = (interactedActor->id == ACTOR_EN_ITEM00 && interactedActor->params != 6 && interactedActor->params != 17) || + uint8_t isDropToSkip = + ( + interactedActor->id == ACTOR_EN_ITEM00 && + interactedActor->params != ITEM00_HEART_PIECE && + interactedActor->params != ITEM00_SMALL_KEY && + interactedActor->params != ITEM00_SOH_GIVE_ITEM_ENTRY && + interactedActor->params != ITEM00_SOH_GIVE_ITEM_ENTRY_GI + ) || interactedActor->id == ACTOR_EN_KAREBABA || interactedActor->id == ACTOR_EN_DEKUBABA; @@ -6716,8 +6724,10 @@ s32 func_8083E5A8(Player* this, PlayState* play) { } func_80836898(play, this, func_8083A434); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_CHEST, true, &giEntry)) { this->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE; func_8083AE40(this, giEntry.objectId); + } this->actor.world.pos.x = chest->dyna.actor.world.pos.x - (Math_SinS(chest->dyna.actor.shape.rot.y) * 29.4343f); this->actor.world.pos.z = @@ -10087,7 +10097,7 @@ void Player_Init(Actor* thisx, PlayState* play2) { if ((sp50 == 0) || (sp50 < -1)) { titleFileSize = scene->titleFile.vromEnd - scene->titleFile.vromStart; - if (gSaveContext.showTitleCard) { + if (GameInteractor_Should(GI_VB_SHOW_TITLE_CARD, gSaveContext.showTitleCard, NULL)) { if ((gSaveContext.sceneSetupIndex < 4) && (gEntranceTable[((void)0, gSaveContext.entranceIndex) + ((void)0, gSaveContext.sceneSetupIndex)].field & ENTRANCE_INFO_DISPLAY_TITLE_CARD_FLAG) && @@ -13393,7 +13403,7 @@ s32 func_8084DFF4(PlayState* play, Player* this) { play->msgCtx.msgMode = MSGMODE_TEXT_DONE; } else { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - if (this->getItemId == GI_GAUNTLETS_SILVER && !IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_NABOORU_CAPTURED_CS, this->getItemId == GI_GAUNTLETS_SILVER, NULL)) { play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.nextCutsceneIndex = 0xFFF1; @@ -13409,11 +13419,13 @@ s32 func_8084DFF4(PlayState* play, Player* this) { this->unk_862 = 0; } + // #region SOH [Randomizer] TODO Better Ice trap handling? if (this->getItemEntry.itemId == RG_ICE_TRAP && this->getItemEntry.modIndex == MOD_RANDOMIZER) { this->unk_862 = 0; gSaveContext.pendingIceTrapCount++; Player_SetPendingFlag(this, play); } + // #endregion this->getItemId = GI_NONE; this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; @@ -15675,6 +15687,7 @@ void func_8085283C(PlayState* play, Player* this, CsCmdActorAction* arg2) { if (LinkAnimation_Update(play, &this->skelAnime)) { func_80852944(play, this, arg2); } else if (this->unk_850 == 0) { + // This is when link picks up the sword in the Ganon fight Item_Give(play, ITEM_SWORD_MASTER); func_80846720(play, this, 0); } else { From bea3c6dae04b92b0c10991ccaf387051adec396b Mon Sep 17 00:00:00 2001 From: Taw Date: Fri, 9 Feb 2024 14:17:17 -0800 Subject: [PATCH 02/52] GameInteractor hooks for adult and child shooting gallery --- .../game-interactor/GameInteractor.h | 6 +++ .../Enhancements/randomizer/hook_handlers.cpp | 21 ++++++++++ .../Enhancements/randomizer/location_list.cpp | 4 +- .../ovl_En_Syateki_Man/z_en_syateki_man.c | 39 +++++-------------- .../ovl_En_Syateki_Man/z_en_syateki_man.h | 1 - 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index c6fb7c721..bffed5458 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -203,6 +203,9 @@ typedef enum { GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE, // Opt: *EnGo2 GI_VB_EN_GO2_RESET_AFTER_GET_ITEM, + // Opt: *EnSyatekiMan + // Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50) + GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD, /*** Play Cutscenes ***/ @@ -269,6 +272,9 @@ typedef enum { // Opt: *EnFr GI_VB_GIVE_ITEM_FROM_FROGS, + // Opt: *EnSyatekiMan + GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, + GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, GI_VB_GIVE_ITEM_LIGHT_ARROW, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index bf236a3ba..6e9a6809a 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -23,6 +23,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Go2/z_en_go2.h" #include "src/overlays/actors/ovl_En_Ms/z_en_ms.h" #include "src/overlays/actors/ovl_En_Fr/z_en_fr.h" +#include "src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -775,6 +776,26 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should &= !EnDs_RandoCanGetGrannyItem(); break; } + case GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY: { + EnSyatekiMan* enSyatekiMan = static_cast(optionalArg); + enSyatekiMan->getItemId = GI_RUPEE_PURPLE; + if (LINK_IS_ADULT) { + // Give purple rupee if we've already obtained the reward OR we don't have a bow + *should = Flags_GetItemGetInf(ITEMGETINF_0E) || CUR_UPG_VALUE(UPG_QUIVER) == 0; + } else { + // Give purple rupee if we've already obtained the reward + *should = Flags_GetItemGetInf(ITEMGETINF_0D); + } + break; + } + case GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD: { + *should = CUR_UPG_VALUE(UPG_QUIVER) > 0; + if (!*should) { + // In Rando without a quiver, display a message reminding the player to come back with a bow + Message_StartTextbox(gPlayState, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW, NULL); + } + break; + } case GI_VB_TRADE_CLAIM_CHECK: case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 28ca3b85a..67b2b35ed 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -672,7 +672,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x3E, "Bombchu Bowling Second Prize", "MK Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x00, "Bombchu Bowling Bombchus", "MK Bombchu Bowling Bombchus", RHT_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RG_BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", "MK Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x09), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", "MK Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(13), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", "MK Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", "MK 10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x01, "Chest Game First Room Chest", "MK Chest Game First Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x03, "Chest Game Second Room Chest", "MK Chest Game Second Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); @@ -692,7 +692,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_KAK_50_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_50_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "50 Gold Skulltula Reward", "Kak 50 Gold Skulltula Reward", RHT_KAK_50_GOLD_SKULLTULA_REWARD, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); locationTable[RC_KAK_100_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_100_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "100 Gold Skulltula Reward", "Kak 100 Gold Skulltula Reward", RHT_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x3E, "Man on Roof", "Kak Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x30, "Shooting Gallery Reward", "Kak Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x30, "Shooting Gallery Reward", "Kak Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0E), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x20, "Trade Odd Mushroom", "Kak Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(48), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x4E, "Granny's Shop", "Kak Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x1D, "Anju as Adult", "Kak Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index 6ab91ddc0..d84298800 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -4,6 +4,7 @@ #include "objects/object_ossan/object_ossan.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/custom-message/CustomMessageTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_LOCKON) @@ -180,7 +181,6 @@ void EnSyatekiMan_Init(Actor* thisx, PlayState* play) { this->blinkFunc = EnSyatekiMan_BlinkWait; this->actor.colChkInfo.cylRadius = 100; this->actionFunc = EnSyatekiMan_Start; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; } void EnSyatekiMan_Destroy(Actor* thisx, PlayState* play) { @@ -355,11 +355,7 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) { this->tempGallery = this->actor.parent; this->actor.parent = NULL; if (!LINK_IS_ADULT) { - if(IS_RANDO && !Flags_GetTreasure(play, 0x1E)) { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_SHOOTING_GALLERY_REWARD, GI_BULLET_BAG_50); - this->getItemId = this->getItemEntry.getItemId; - Flags_SetTreasure(play, 0x1E); - } else if (!IS_RANDO && !Flags_GetItemGetInf(ITEMGETINF_0D)) { + if (!Flags_GetItemGetInf(ITEMGETINF_0D)) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Pachinko ☆☆☆☆☆ %d\n" VT_RST, CUR_UPG_VALUE(UPG_BULLET_BAG)); if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) { @@ -368,16 +364,11 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) { this->getItemId = GI_BULLET_BAG_50; } } else { - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->getItemId = GI_RUPEE_PURPLE; } } else { // Only give the adult rando reward when the player has a quiver - if (IS_RANDO && !Flags_GetTreasure(play, 0x1F) && CUR_UPG_VALUE(UPG_QUIVER) > 0) { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_SHOOTING_GALLERY_REWARD, GI_QUIVER_50); - this->getItemId = this->getItemEntry.getItemId; - Flags_SetTreasure(play, 0x1F); - } else if (!IS_RANDO && !Flags_GetItemGetInf(ITEMGETINF_0E)) { + if (!Flags_GetItemGetInf(ITEMGETINF_0E)) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Bow ☆☆☆☆☆ %d\n" VT_RST, CUR_UPG_VALUE(UPG_QUIVER)); switch (CUR_UPG_VALUE(UPG_QUIVER)) { @@ -392,14 +383,11 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) { break; } } else { - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->getItemId = GI_RUPEE_PURPLE; } } - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, true, this)) { func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f); } this->actionFunc = EnSyatekiMan_GivePrize; break; @@ -426,33 +414,26 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) { } } } -} +} void EnSyatekiMan_GivePrize(EnSyatekiMan* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, true, this)) { this->actionFunc = EnSyatekiMan_FinishPrize; - } else { - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f); - } + } else { + func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); } } void EnSyatekiMan_FinishPrize(EnSyatekiMan* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { + if (((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, true, this)) { // "Successful completion" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST); if (!LINK_IS_ADULT) { Flags_SetItemGetInf(ITEMGETINF_0D); - } else if ((this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50)) { + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD, (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50), this)) { Flags_SetItemGetInf(ITEMGETINF_0E); - } else if (IS_RANDO && LINK_IS_ADULT && CUR_UPG_VALUE(UPG_QUIVER) == 0) { - // In Rando without a quiver, display a message reminding the player to come back with a bow - Message_StartTextbox(play, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW, NULL); } this->gameResult = SYATEKI_RESULT_NONE; this->actor.parent = this->tempGallery; diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h index eaeec0429..b65364ae4 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h @@ -28,7 +28,6 @@ typedef struct EnSyatekiMan { /* 0x0220 */ Actor* tempGallery; /* 0x0224 */ EnSyatekiManOtherFunc blinkFunc; // Seems to be part of a blink system with unk_20C and unk_20E, but it's unused. /* 0x0228 */ s16 csCam; - /* */ GetItemEntry getItemEntry; } EnSyatekiMan; // size = 0x022C #endif From 4e5b92fdf385e34da94049071233dbe9c872cbca Mon Sep 17 00:00:00 2001 From: Taw Date: Sat, 10 Feb 2024 09:06:34 -0800 Subject: [PATCH 03/52] Man On Roof --- .../Enhancements/game-interactor/GameInteractor.h | 1 + soh/soh/Enhancements/randomizer/hook_handlers.cpp | 1 + soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c | 13 ++++--------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index c6fb7c721..e615e5954 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -268,6 +268,7 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN, // Opt: *EnFr GI_VB_GIVE_ITEM_FROM_FROGS, + GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index bf236a3ba..6b29ac567 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -782,6 +782,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void case GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM: case GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD: case GI_VB_GIVE_ITEM_FROM_LAB_DIVE: + case GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF: case GI_VB_GIVE_ITEM_SKULL_TOKEN: case GI_VB_GIVE_ITEM_FROM_BLUE_WARP: case GI_VB_GIVE_ITEM_FAIRY_OCARINA: diff --git a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c index 15ebd759c..5093d47d2 100644 --- a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -6,6 +6,7 @@ #include "z_en_ani.h" #include "objects/object_ani/object_ani.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -119,7 +120,7 @@ void func_809B0524(EnAni* this, PlayState* play) { } void func_809B0558(EnAni* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, true, NULL)) { this->actor.parent = NULL; if (!LINK_IS_ADULT) { EnAni_SetupAction(this, func_809B04F0); @@ -128,11 +129,8 @@ void func_809B0558(EnAni* this, PlayState* play) { } Flags_SetItemGetInf(ITEMGETINF_15); } else { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, true, NULL)) { func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 200.0f); } } } @@ -142,11 +140,8 @@ void func_809B05F0(EnAni* this, PlayState* play) { EnAni_SetupAction(this, func_809B0558); } - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, true, NULL)) { func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 200.0f); } } From ceb5b740b5af02862b778591b3bfe852c8a992f5 Mon Sep 17 00:00:00 2001 From: Taw Date: Mon, 12 Feb 2024 14:26:10 -0800 Subject: [PATCH 04/52] fix include --- soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c index 5093d47d2..3fe4e2a22 100644 --- a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -6,7 +6,7 @@ #include "z_en_ani.h" #include "objects/object_ani/object_ani.h" -#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) From 30ff3e9585eccaddae10058b2c773202b9aeab32 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Fri, 16 Feb 2024 02:03:22 -0500 Subject: [PATCH 05/52] fix the torch --- soh/src/code/z_onepointdemo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/src/code/z_onepointdemo.c b/soh/src/code/z_onepointdemo.c index ad5df65bd..68c0a4dff 100644 --- a/soh/src/code/z_onepointdemo.c +++ b/soh/src/code/z_onepointdemo.c @@ -1174,11 +1174,11 @@ s16 OnePointCutscene_Init(PlayState* play, s16 csId, s16 timer, Actor* actor, s1 if (actor != NULL && actor->id != ACTOR_PLAYER) { if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, actor)) { - return; + return SUBCAM_NONE; } } else { if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_CS, true, &csId)) { - return; + return SUBCAM_NONE; } } From 00b358115196648cb50bcff4cce08694ce759000 Mon Sep 17 00:00:00 2001 From: Ted Newman Date: Tue, 20 Feb 2024 18:15:10 -0800 Subject: [PATCH 06/52] Skull Kid (#86) Co-authored-by: Garrett Cox --- .../Enhancements/game-interactor/GameInteractor.h | 3 ++- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 1 + soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c | 14 ++++---------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 2cac52637..f27342c3e 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -271,8 +271,9 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN, // Opt: *EnFr GI_VB_GIVE_ITEM_FROM_FROGS, + // Opt: *EnSkj + GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, - // Opt: *EnSyatekiMan GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 87c7f5b3c..511c0d7e6 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -803,6 +803,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void case GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM: case GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD: case GI_VB_GIVE_ITEM_FROM_LAB_DIVE: + case GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG: case GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF: case GI_VB_GIVE_ITEM_SKULL_TOKEN: case GI_VB_GIVE_ITEM_FROM_BLUE_WARP: diff --git a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c index 207d9612b..8b6545f76 100644 --- a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c +++ b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c @@ -1039,11 +1039,8 @@ void EnSkj_SariaSongTalk(EnSkj* this, PlayState* play) { EnSkj_SetupWaitInRange(this); } else { func_80AFFE24(this); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, true, this)) { func_8002F434(&this->actor, play, GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); } } } @@ -1054,15 +1051,12 @@ void func_80AFFE24(EnSkj* this) { } void func_80AFFE44(EnSkj* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, true, this)) { this->actor.parent = NULL; EnSkj_SetupPostSariasSong(this); } else { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, true, this)) { func_8002F434(&this->actor, play, GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); } } } @@ -1072,7 +1066,7 @@ void EnSkj_SetupPostSariasSong(EnSkj* this) { } void EnSkj_ChangeModeAfterSong(EnSkj* this, PlayState* play) { - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, true, this)) { Flags_SetItemGetInf(ITEMGETINF_16); EnSkj_SetNaviId(this); EnSkj_SetupWaitInRange(this); From 0dda3a6c298af5481e967de0fd9ae1ba21547e24 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 20 Feb 2024 21:00:10 -0600 Subject: [PATCH 07/52] More boss intro skips --- soh/soh/Enhancements/randomizer/savefile.cpp | 5 ++- .../Enhancements/timesaver_hook_handlers.cpp | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 19ef26ac0..95840b15c 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -247,9 +247,10 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME); Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE); + // Now handled by cutscene skips // Skip cutscenes before Nabooru fight - Flags_SetEventChkInf(EVENTCHKINF_BEGAN_NABOORU_BATTLE); - Flags_SetEventChkInf(EVENTCHKINF_NABOORU_ORDERED_TO_FIGHT_BY_TWINROVA); + // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_NABOORU_BATTLE); + // Flags_SetEventChkInf(EVENTCHKINF_NABOORU_ORDERED_TO_FIGHT_BY_TWINROVA); // Now handled by cutscene skips // Skip boss cutscenes diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index cd34e5608..1a349805f 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -638,6 +638,43 @@ void TimeSaverOnSceneInitHandler(int16_t sceneNum) { } } break; + case SCENE_FOREST_TEMPLE_BOSS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE); + } + } + break; + case SCENE_FIRE_TEMPLE_BOSS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE); + } + } + break; + case SCENE_WATER_TEMPLE_BOSS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE); + } + } + break; + case SCENE_SPIRIT_TEMPLE_BOSS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE); + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_NABOORU_BATTLE); + Flags_SetEventChkInf(EVENTCHKINF_NABOORU_ORDERED_TO_FIGHT_BY_TWINROVA); + } + } + break; + case SCENE_SHADOW_TEMPLE_BOSS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE); + } + } + break; } } From 72581f74827ef5cc16dcde42f77671bcc372015b Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 20 Feb 2024 21:04:16 -0600 Subject: [PATCH 08/52] Re-add some UI I accidentally removed --- soh/soh/SohMenuBar.cpp | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 2ec571e26..15f67f763 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -643,8 +643,37 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementSliderInt("Crawl speed %dx", "##CRAWLSPEED", "gCrawlSpeed", 1, 5, "", 1, true, false, true); UIWidgets::PaddedEnhancementCheckbox("Faster Heavy Block Lift", "gFasterHeavyBlockLift", false, false); UIWidgets::Tooltip("Speeds up lifting silver rocks and obelisks"); - UIWidgets::PaddedEnhancementCheckbox("Link as default file name", "gLinkDefaultName", true, false); - UIWidgets::Tooltip("Allows you to have \"Link\" as a premade file name"); + UIWidgets::PaddedEnhancementCheckbox("Skip Pickup Messages", "gFastDrops", true, false); + UIWidgets::Tooltip("Skip pickup messages for new consumable items and bottle swipes"); + UIWidgets::PaddedEnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback", true, false); + UIWidgets::Tooltip("Skip the part where the Ocarina playback is called when you play a song"); + bool forceSkipScarecrow = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_SCARECROWS_SONG); + static const char* forceSkipScarecrowText = "This setting is forcefully enabled because a savefile\nwith \"Skip Scarecrow Song\" is loaded"; + UIWidgets::PaddedEnhancementCheckbox("Skip Scarecrow Song", "gSkipScarecrow", true, false, + forceSkipScarecrow, forceSkipScarecrowText, UIWidgets::CheckboxGraphics::Checkmark); + UIWidgets::Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song."); + UIWidgets::PaddedEnhancementCheckbox("Skip Magic Arrow Equip Animation", "gSkipArrowAnimation", true, false); + UIWidgets::PaddedEnhancementCheckbox("Skip save confirmation", "gSkipSaveConfirmation", true, false); + UIWidgets::Tooltip("Skip the \"Game saved.\" confirmation screen"); + UIWidgets::PaddedEnhancementCheckbox("Faster Farore's Wind", "gFastFarores", true, false); + UIWidgets::Tooltip("Greatly decreases cast time of Farore's Wind magic spell."); + UIWidgets::PaddedEnhancementCheckbox("Skip water take breath animation", "gSkipSwimDeepEndAnim", true, false); + UIWidgets::Tooltip("Skips Link's taking breath animation after coming up from water. This setting does not interfere with getting items from underwater."); + + ImGui::TableNextColumn(); + UIWidgets::Spacer(0); + ImGui::Text("Changes:"); + UIWidgets::PaddedSeparator(); + + UIWidgets::PaddedEnhancementSliderInt("Biggoron Forge Time: %d days", "##FORGETIME", "gForgeTime", 0, 3, "", 3, true, false, true); + UIWidgets::Tooltip("Allows you to change the number of days it takes for Biggoron to forge the Biggoron Sword"); + UIWidgets::PaddedEnhancementCheckbox("Remember Save Location", "gRememberSaveLocation", false, false); + UIWidgets::Tooltip("When loading a save, places Link at the last entrance he went through.\n" + "This doesn't work if the save was made in a grotto."); + UIWidgets::PaddedEnhancementCheckbox("No Forced Navi", "gNoForcedNavi", true, false); + UIWidgets::Tooltip("Prevent forced Navi conversations"); + UIWidgets::PaddedEnhancementCheckbox("Navi Timer Resets", "gEnhancements.ResetNaviTimer", true, false); + UIWidgets::Tooltip("Resets the Navi timer on scene change. If you have already talked to her, she will try and talk to you again, instead of needing a save warp or death. "); UIWidgets::PaddedEnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze", true, false); UIWidgets::Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas"); UIWidgets::PaddedEnhancementCheckbox("Nighttime GS Always Spawn", "gNightGSAlwaysSpawn", true, false); From 37e89c0c7c9f8cf060ff2499ba5ec324aa73a2b2 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 20 Feb 2024 21:49:07 -0600 Subject: [PATCH 09/52] Migrate song of storms check --- .../Enhancements/randomizer/location_list.cpp | 2 +- .../Enhancements/timesaver_hook_handlers.cpp | 41 +++++++++++++++++++ soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c | 20 +-------- soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h | 3 ++ 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 67b2b35ed..faebd65c9 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1316,7 +1316,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_SONG_FROM_SARIA] = Location::Delayed(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x28, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x57), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Delayed(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x29, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x00), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Delayed(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2A, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xA9), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); - locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x5B), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); //Beehives locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), 0x00, "Storms Grotto Beehive Left", "KF Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 1a349805f..58cdfb6fe 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -18,6 +18,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Sa/z_en_sa.h" #include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h" #include "src/overlays/actors/ovl_En_Tk/z_en_tk.h" +#include "src/overlays/actors/ovl_En_Fu/z_en_fu.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -51,6 +52,19 @@ void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) { } } +void EnFu_EndTeachSong(EnFu* enFu, PlayState* play) { + if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) { + func_80078884(NA_SE_SY_CORRECT_CHIME); + enFu->actionFunc = EnFu_WaitAdult; + enFu->actor.flags &= ~ACTOR_FLAG_WILL_TALK; + + play->msgCtx.ocarinaMode = OCARINA_MODE_04; + Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS); + return; + } +} + u16 EnZl4_GiveItemTextId(PlayState* play, Actor* actor) { return 0x207D; } @@ -518,6 +532,8 @@ static uint32_t itemOcarinaUpdateHook = 0; static uint32_t itemOcarinaframesSinceSpawn = 0; static uint32_t enMa1UpdateHook = 0; static uint32_t enMa1KillHook = 0; +static uint32_t enFuUpdateHook = 0; +static uint32_t enFuKillHook = 0; void TimeSaverOnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); @@ -593,6 +609,28 @@ void TimeSaverOnActorInitHandler(void* actorRef) { }); } + if (actor->id == ACTOR_EN_FU) { + enMa1UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_EN_FU && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) { + EnFu* enFu = static_cast(innerActorRef); + if (enFu->actionFunc == EnFu_TeachSong) { + enFu->actionFunc = EnFu_EndTeachSong; + GameInteractor::Instance->UnregisterGameHook(enFuUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enFuKillHook); + enFuUpdateHook = 0; + enFuKillHook = 0; + } + } + }); + enMa1KillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); + GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); + enMa1UpdateHook = 0; + enMa1KillHook = 0; + }); + } + if (actor->id == ACTOR_EN_ZL4 && CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { EnZl4* enZl4 = static_cast(actorRef); if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0) return; @@ -740,6 +778,9 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { case EVENTCHKINF_LEARNED_SONG_OF_TIME: vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_TIME).GetGIEntry_Copy(); break; + case EVENTCHKINF_LEARNED_SONG_OF_STORMS: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_STORMS).GetGIEntry_Copy(); + break; } break; case FLAG_RANDOMIZER_INF: diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c index 278fb18e2..ad1d6f12a 100644 --- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -161,20 +161,12 @@ void GivePlayerRandoRewardSongOfStorms(EnFu* windmillGuy, PlayState* play, Rando } } -void func_WaitForSongGive(EnFu* this, PlayState* play) { - GivePlayerRandoRewardSongOfStorms(this, play, RC_SONG_FROM_WINDMILL); -} - void func_80A1DB60(EnFu* this, PlayState* play) { if (play->csCtx.state == CS_STATE_IDLE) { this->actionFunc = EnFu_WaitAdult; Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS); play->msgCtx.ocarinaMode = OCARINA_MODE_04; } - - if (IS_RANDO) { - this->actionFunc = func_WaitForSongGive; - } } void func_80A1DBA0(EnFu* this, PlayState* play) { @@ -186,10 +178,6 @@ void func_80A1DBA0(EnFu* this, PlayState* play) { void func_80A1DBD4(EnFu* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (IS_RANDO && (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING)) { - play->msgCtx.ocarinaMode = OCARINA_MODE_03; - } - if (play->msgCtx.ocarinaMode >= OCARINA_MODE_04) { this->actionFunc = EnFu_WaitAdult; play->msgCtx.ocarinaMode = OCARINA_MODE_04; @@ -199,12 +187,6 @@ void func_80A1DBD4(EnFu* this, PlayState* play) { this->actionFunc = func_80A1DB60; this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; - if (!IS_RANDO) { - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gSongOfStormsCs); - gSaveContext.cutsceneTrigger = 1; - Item_Give(play, ITEM_SONG_STORMS); - } - play->msgCtx.ocarinaMode = OCARINA_MODE_00; Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_02) { @@ -249,7 +231,7 @@ void EnFu_WaitAdult(EnFu* this, PlayState* play) { } else if (player->stateFlags2 & 0x1000000) { this->actor.textId = 0x5035; Message_StartTextbox(play, this->actor.textId, NULL); - this->actionFunc = IS_RANDO ? func_80A1DBD4 : EnFu_TeachSong; + this->actionFunc = EnFu_TeachSong; this->behaviorFlags |= FU_WAIT; } else if (Actor_ProcessTalkRequest(&this->actor, play)) { this->actionFunc = func_80A1DBA0; diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h index 7fddd6543..fd371000d 100644 --- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h +++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h @@ -41,4 +41,7 @@ typedef struct EnFu { /* 0x02AC */ EnFuActionFunc actionFunc; } EnFu; // size = 0x02B0 +void EnFu_TeachSong(EnFu* enFu, PlayState* play); +void EnFu_WaitAdult(EnFu* enFu, PlayState* play); + #endif From 7bebe7a5738f355278b8e0d512958678aeeae442 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 21 Feb 2024 14:01:49 -0600 Subject: [PATCH 10/52] Migrate okarina_tag changes --- .../game-interactor/GameInteractor.h | 13 +++ .../Enhancements/randomizer/hook_handlers.cpp | 10 +++ .../Enhancements/randomizer/location_list.cpp | 2 +- .../Enhancements/timesaver_hook_handlers.cpp | 81 +++++++++++++++++-- .../z_bg_spot02_objects.c | 26 +----- .../z_bg_spot02_objects.h | 3 + .../ovl_En_Okarina_Tag/z_en_okarina_tag.c | 48 +++-------- 7 files changed, 117 insertions(+), 66 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index f27342c3e..940e49cae 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -206,6 +206,9 @@ typedef enum { // Opt: *EnSyatekiMan // Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50) GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD, + // Opt: *EnOkarinaTag + // Vanilla condition: !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME) + GI_VB_BE_ELIGIBLE_TO_OPEN_DOT, /*** Play Cutscenes ***/ @@ -235,6 +238,16 @@ typedef enum { GI_VB_PLAY_BOLERO_OF_FIRE_CS, GI_VB_PLAY_SERENADE_OF_WATER_CS, GI_VB_PLAY_EYEDROPS_CS, + // Opt: *EnOkarinaTag + GI_VB_PLAY_DRAIN_WELL_CS, + // Opt: *EnOkarinaTag + // Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SUN) + GI_VB_PLAY_SUNS_SONG_CS, + // Opt: *EnOkarinaTag + GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS, + GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE, + // Opt: *EnOkarinaTag + GI_VB_PLAY_DOOR_OF_TIME_CS, /*** Give Items ***/ diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 511c0d7e6..c55331edf 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -796,6 +796,16 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } break; } + case GI_VB_BE_ELIGIBLE_TO_OPEN_DOT: { + bool eligible = RAND_GET_OPTION(RSK_DOOR_OF_TIME) != RO_DOOROFTIME_CLOSED || ( + INV_CONTENT(ITEM_OCARINA_FAIRY) == ITEM_OCARINA_TIME && + CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && + CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && + CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) + ); + *should = eligible; + break; + } case GI_VB_TRADE_CLAIM_CHECK: case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index faebd65c9..8deeab8c8 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1314,7 +1314,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_SONG_FROM_IMPA] = Location::Delayed(RC_SONG_FROM_IMPA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x26, "Song from Impa", "Song from Impa", RHT_SONG_FROM_IMPA, RG_ZELDAS_LULLABY, { Category::cSong, Category::cSongDungeonReward }, SpoilerCollectionCheck::EventChkInf(0x59), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_SONG_FROM_MALON] = Location::Delayed(RC_SONG_FROM_MALON, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x27, "Song from Malon", "Song from Malon", RHT_SONG_FROM_MALON, RG_EPONAS_SONG, { Category::cSong }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LEARNED_EPONA_SONG), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); locationTable[RC_SONG_FROM_SARIA] = Location::Delayed(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x28, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x57), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Delayed(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x29, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x00), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Delayed(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x29, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SUNS_SONG), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Delayed(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2A, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xA9), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 58cdfb6fe..44102f944 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -19,6 +19,7 @@ extern "C" { #include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h" #include "src/overlays/actors/ovl_En_Tk/z_en_tk.h" #include "src/overlays/actors/ovl_En_Fu/z_en_fu.h" +#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -471,6 +472,44 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case GI_VB_PLAY_DRAIN_WELL_CS: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + *should = false; + Flags_SetSwitch(gPlayState, 0x2); + Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); + Flags_SetEventChkInf(EVENTCHKINF_DRAINED_WELL_IN_KAKARIKO); + } + break; + } + case GI_VB_PLAY_SUNS_SONG_CS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + *should = false; + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SUNS_SONG); + // SoH [Randomizer] TODO: Increment time X amount (find out X) + // When time is 0, it's changed to 0x46A7 + // When it's 0x8000, it's changed to 0xC090 + } + break; + case GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS: { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + *should = false; + } + break; + } + case GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE: { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + *should = Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB); + } + break; + } + case GI_VB_PLAY_DOOR_OF_TIME_CS: { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + *should = false; + Flags_SetEnv(gPlayState, 2); + func_80078884(NA_SE_SY_CORRECT_CHIME); + } + break; + } case GI_VB_GIVE_ITEM_MINUET_OF_FOREST: case GI_VB_GIVE_ITEM_BOLERO_OF_FIRE: case GI_VB_GIVE_ITEM_SERENADE_OF_WATER: @@ -534,6 +573,8 @@ static uint32_t enMa1UpdateHook = 0; static uint32_t enMa1KillHook = 0; static uint32_t enFuUpdateHook = 0; static uint32_t enFuKillHook = 0; +static uint32_t bgSpot02UpdateHook = 0; +static uint32_t bgSpot02KillHook = 0; void TimeSaverOnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); @@ -610,7 +651,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { } if (actor->id == ACTOR_EN_FU) { - enMa1UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + enFuUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); if (innerActor->id == ACTOR_EN_FU && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) { EnFu* enFu = static_cast(innerActorRef); @@ -623,11 +664,36 @@ void TimeSaverOnActorInitHandler(void* actorRef) { } } }); - enMa1KillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { - GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); - GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); - enMa1UpdateHook = 0; - enMa1KillHook = 0; + enFuKillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(enFuUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enFuKillHook); + enFuUpdateHook = 0; + enFuKillHook = 0; + }); + } + + if (actor->id == ACTOR_BG_SPOT02_OBJECTS && actor->params == 2) { + SPDLOG_INFO("Registering BG_SPOT02 hook"); + bgSpot02UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_BG_SPOT02_OBJECTS && innerActor->params == 2 && (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0))) { + SPDLOG_INFO("on update BG_SPOT02 hook"); + BgSpot02Objects* bgSpot02 = static_cast(innerActorRef); + if (bgSpot02->actionFunc == func_808ACC34) { + SPDLOG_INFO("BGspot02 OVERRIDDEN"); + bgSpot02->actionFunc = func_808AC908; + GameInteractor::Instance->UnregisterGameHook(bgSpot02UpdateHook); + GameInteractor::Instance->UnregisterGameHook(bgSpot02KillHook); + bgSpot02UpdateHook = 0; + bgSpot02KillHook = 0; + } + } + }); + bgSpot02KillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(bgSpot02UpdateHook); + GameInteractor::Instance->UnregisterGameHook(bgSpot02KillHook); + bgSpot02UpdateHook = 0; + bgSpot02KillHook = 0; }); } @@ -781,6 +847,9 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { case EVENTCHKINF_LEARNED_SONG_OF_STORMS: vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_STORMS).GetGIEntry_Copy(); break; + case EVENTCHKINF_LEARNED_SUNS_SONG: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SUNS_SONG).GetGIEntry_Copy(); + break; } break; case FLAG_RANDOMIZER_INF: diff --git a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c index 2eb3faeda..cc7d4c854 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c @@ -6,6 +6,7 @@ #include "z_bg_spot02_objects.h" #include "objects/object_spot02_objects/object_spot02_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -129,20 +130,7 @@ void func_808AC908(BgSpot02Objects* this, PlayState* play) { static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; Vec3f pos; - // We want to do most of the same things in rando, but we're not in a cutscene and the flag for - // destroying the royal tombstone is already set. - if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) { - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GRAVE_EXPLOSION); - this->timer = 25; - pos.x = (Math_SinS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.x; - pos.y = this->dyna.actor.world.pos.y + 30.0f; - pos.z = (Math_CosS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.z; - EffectSsBomb2_SpawnLayered(play, &pos, &zeroVec, &zeroVec, 70, 30); - this->actionFunc = func_808ACA08; - } - - if (play->csCtx.state != 0) { - if (play->csCtx.npcActions[3] != NULL && play->csCtx.npcActions[3]->action == 2) { + if (GameInteractor_Should(GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE, play->csCtx.state != 0 && play->csCtx.npcActions[3] != NULL && play->csCtx.npcActions[3]->action == 2, this)) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GRAVE_EXPLOSION); Flags_SetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB); this->timer = 25; @@ -151,7 +139,6 @@ void func_808AC908(BgSpot02Objects* this, PlayState* play) { pos.z = (Math_CosS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.z; EffectSsBomb2_SpawnLayered(play, &pos, &zeroVec, &zeroVec, 70, 30); this->actionFunc = func_808ACA08; - } } } @@ -174,7 +161,7 @@ void func_808ACA08(BgSpot02Objects* this, PlayState* play) { // This shouldn't execute in rando even without the check since we never // enter the cutscene context. - if (play->csCtx.frames == 402 && !(IS_RANDO)) { + if (play->csCtx.frames == 402) { if (!LINK_IS_ADULT) { Player_PlaySfx(&player->actor, NA_SE_VO_LI_DEMO_DAMAGE_KID); } else { @@ -217,13 +204,6 @@ void BgSpot02Objects_Draw(Actor* thisx, PlayState* play) { } void func_808ACC34(BgSpot02Objects* this, PlayState* play) { - // This is the actionFunc that the game settles on when you load the Graveyard - // When we're in rando and the flag for the gravestone being destroyed gets set, - // set the actionFunc to the function where the gravestone explodes. - if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) { - this->actionFunc = func_808AC908; - } - if (play->csCtx.state != 0 && play->csCtx.npcActions[0] != NULL && play->csCtx.npcActions[0]->action == 2) { this->unk_16A++; diff --git a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h index 0b54fa617..cf5152a7e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h +++ b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h @@ -19,4 +19,7 @@ typedef struct BgSpot02Objects { /* 0x0172 */ u16 unk_172; } BgSpot02Objects; // size = 0x0174 +void func_808ACC34(BgSpot02Objects* bgSpot02Objects, PlayState* play); +void func_808AC908(BgSpot02Objects* bgSpot02Objects, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index 74afaacff..34c094320 100644 --- a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -8,6 +8,7 @@ #include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h" #include "scenes/overworld/spot02/spot02_scene.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -192,7 +193,7 @@ void func_80ABF28C(EnOkarinaTag* this, PlayState* play) { if ((this->ocarinaSong != 6) || (gSaveContext.scarecrowSpawnSongSet)) { if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; - } else if (((this->type != 4) || !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME)) && + } else if (((this->type != 4) || GameInteractor_Should(GI_VB_BE_ELIGIBLE_TO_OPEN_DOT, !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME), this)) && ((this->type != 6) || !Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) && (this->actor.xzDistToPlayer < (90.0f + this->interactRange)) && (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 80.0f)) { @@ -234,47 +235,30 @@ void func_80ABF4C8(EnOkarinaTag* this, PlayState* play) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_04) { this->actionFunc = func_80ABF28C; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - if (!IS_RANDO || (IS_RANDO && Randomizer_GetSettingValue(RSK_DOOR_OF_TIME) != RO_DOOROFTIME_CLOSED)) { - func_80078884(NA_SE_SY_CORRECT_CHIME); - } + func_80078884(NA_SE_SY_CORRECT_CHIME); if (this->switchFlag >= 0) { Flags_SetSwitch(play, this->switchFlag); } switch (this->type) { - case 1: + case 1: // Zora's River Waterfall Flags_SetSwitch(play, this->switchFlag); Flags_SetEventChkInf(EVENTCHKINF_OPENED_ZORAS_DOMAIN); break; - case 2: - if (!IS_RANDO) { + case 2: // Kakariko Windmill + if (GameInteractor_Should(GI_VB_PLAY_DRAIN_WELL_CS, true, this)) { play->csCtx.segment = D_80ABF9D0; gSaveContext.cutsceneTrigger = 1; - } else { - Flags_SetEventChkInf(EVENTCHKINF_DRAINED_WELL_IN_KAKARIKO); - Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); } func_800F574C(1.18921f, 0x5A); break; - case 4: - if (IS_RANDO) { - if (Randomizer_GetSettingValue(RSK_DOOR_OF_TIME) == RO_DOOROFTIME_CLOSED && - (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_OCARINA_TIME || - !CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) || !CHECK_QUEST_ITEM(QUEST_GORON_RUBY) || - !CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE))) { - func_80078884(NA_SE_SY_OCARINA_ERROR); - break; - } else { - Flags_SetEnv(play, 2); - func_80078884(NA_SE_SY_CORRECT_CHIME); - } - } else { + case 4: // Door of Time + if (GameInteractor_Should(GI_VB_PLAY_DOOR_OF_TIME_CS, true, this)) { play->csCtx.segment = D_80ABFB40; gSaveContext.cutsceneTrigger = 1; } break; - case 6: - // Don't start the cutscene in a rando save. - if (!(IS_RANDO)) { + case 6: // Royal Family Tomb + if (GameInteractor_Should(GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS, true, this)) { play->csCtx.segment = LINK_IS_ADULT ? SEGMENTED_TO_VIRTUAL(&spot02_scene_Cs_003C80) : SEGMENTED_TO_VIRTUAL(&spot02_scene_Cs_005020); gSaveContext.cutsceneTrigger = 1; @@ -311,7 +295,7 @@ void func_80ABF708(EnOkarinaTag* this, PlayState* play) { yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; this->unk_15A++; if (!(this->actor.xzDistToPlayer > 120.0f)) { - if (CHECK_QUEST_ITEM(QUEST_SONG_SUN) || IS_RANDO) { + if (CHECK_QUEST_ITEM(QUEST_SONG_SUN)) { this->actor.textId = 0x5021; } yawDiffNew = ABS(yawDiff); @@ -323,23 +307,15 @@ void func_80ABF708(EnOkarinaTag* this, PlayState* play) { } } -void GivePlayerRandoRewardSunSong(EnOkarinaTag* song, PlayState* play, RandomizerCheck check) { - Flags_SetTreasure(play, 0x1F); - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, GI_LETTER_ZELDA); - GiveItemEntryFromActor(&song->actor, play, getItemEntry, 10000.0f, 100.0f); -} - void func_80ABF7CC(EnOkarinaTag* this, PlayState* play) { // "Open sesame sesame!" osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 開けゴマゴマゴマ! ☆☆☆☆☆ %d\n" VT_RST, Message_GetState(&play->msgCtx)); if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); - if (!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_SONG_SUN)) { + if (GameInteractor_Should(GI_VB_PLAY_SUNS_SONG_CS, !CHECK_QUEST_ITEM(QUEST_SONG_SUN), this)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(&gSunSongGraveSunSongTeachCs); gSaveContext.cutsceneTrigger = 1; - } else if (IS_RANDO && !Flags_GetTreasure(play, 0x1F)) { - GivePlayerRandoRewardSunSong(this, play, RC_SONG_FROM_ROYAL_FAMILYS_TOMB); } this->actionFunc = func_80ABF708; } From b293cac51c756c0718c14b2869359a17049c5441 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 21 Feb 2024 15:26:11 -0600 Subject: [PATCH 11/52] Enable timesaver enhancements by default on rando --- soh/soh/Enhancements/presets.h | 12 +++ .../Enhancements/randomizer/hook_handlers.cpp | 2 +- .../Enhancements/timesaver_hook_handlers.cpp | 86 +++++++++---------- soh/soh/SohMenuBar.cpp | 66 +++++++------- 4 files changed, 89 insertions(+), 77 deletions(-) diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index 822b61c75..3cce3dd74 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -280,6 +280,18 @@ const std::vector enhancementsCvars = { "gPermanentHeartLoss", "gRemoveExplosiveLimit", "gToggleStrength", + "gTimeSavers.SkipCutscene.Intro", + "gTimeSavers.SkipCutscene.Entrances", + "gTimeSavers.SkipCutscene.Story", + "gTimeSavers.SkipCutscene.LearnSong", + "gTimeSavers.SkipCutscene.BossIntro", + "gTimeSavers.SkipCutscene.GlitchAiding", + "gTimeSavers.SkipCutscene.OnePoint", + "gTimeSavers.NoForcedDialog", + "gTimeSavers.SkipOwlInteractions", + "gTimeSavers.SkipMiscInteractions", + "gTimeSavers.DisableTitleCard", + "gTimeSavers.SkipGetItemAnimation", }; const std::vector cheatCvars = { diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index c77e537f3..9f2e2633a 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -218,7 +218,7 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { } } - if (loc->GetRandomizerCheck() == RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && !CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (loc->GetRandomizerCheck() == RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && !CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { static uint32_t updateHook; updateHook = GameInteractor::Instance->RegisterGameHook([]() { Player* player = GET_PLAYER(gPlayState); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 08608b8ed..27d10c00e 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -102,12 +102,12 @@ void TimeSaverOnGameFrameUpdateHandler() { void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* opt) { switch (id) { case GI_VB_PLAY_TRANSITION_CS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.Intro", 0) && gSaveContext.entranceIndex == ENTR_LINKS_HOUSE_0 && gSaveContext.cutsceneIndex == 0xFFF1) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Intro", IS_RANDO) && gSaveContext.entranceIndex == ENTR_LINKS_HOUSE_0 && gSaveContext.cutsceneIndex == 0xFFF1) { gSaveContext.cutsceneIndex = 0; *should = false; } - if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || IS_RANDO) { // Song of Time if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 && gSaveContext.cutsceneIndex == 0xFFF7) { gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_16; @@ -144,7 +144,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } } - if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { uint8_t isBlueWarp = 0; // Deku Tree Blue warp if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) { @@ -228,13 +228,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; case GI_VB_PLAY_ENTRANCE_CS: { s32* entranceFlag = static_cast(opt); - if (CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", 0) && (*entranceFlag != EVENTCHKINF_EPONA_OBTAINED)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) && (*entranceFlag != EVENTCHKINF_EPONA_OBTAINED)) { *should = false; } break; } case GI_VB_PLAY_ONEPOINT_CS: { - if (CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO)) { s16* csId = static_cast(opt); switch (*csId) { case 4180: @@ -250,7 +250,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; } case GI_VB_PLAY_ONEPOINT_ACTOR_CS: { - if (CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO)) { Actor* actor = static_cast(opt); switch (actor->category) { case ACTORCAT_BG: @@ -312,18 +312,18 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; } case GI_VB_SHOW_TITLE_CARD: - if (CVarGetInteger("gTimeSavers.DisableTitleCard", 0)) { + if (CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO)) { *should = false; } break; case GI_VB_WONDER_TALK: { - if (CVarGetInteger("gTimeSavers.NoForcedDialog", 0)) { + if (CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO)) { *should = false; } break; } case GI_VB_NAVI_TALK: { - if (CVarGetInteger("gTimeSavers.NoForcedDialog", 0)) { + if (CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO)) { ElfMsg* naviTalk = static_cast(opt); Flags_SetSwitch(gPlayState, (naviTalk->actor.params >> 8) & 0x3F); Actor_Kill(&naviTalk->actor); @@ -332,14 +332,14 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; } case GI_VB_NOT_BE_GREETED_BY_SARIA: - if (CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", 0) && !Flags_GetInfTable(INFTABLE_GREETED_BY_SARIA)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) && !Flags_GetInfTable(INFTABLE_GREETED_BY_SARIA)) { Flags_SetInfTable(INFTABLE_GREETED_BY_SARIA); *should = true; } break; case GI_VB_MOVE_MIDO_IN_KOKIRI_FOREST: if ( - CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) && + CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) && !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) && (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) @@ -349,7 +349,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; case GI_VB_PLAY_DEKU_TREE_INTRO_CS: { - if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { BgTreemouth* treeMouth = static_cast(opt); Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH); Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); @@ -362,18 +362,18 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* case GI_VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS: case GI_VB_GIVE_ITEM_FAIRY_OCARINA: case GI_VB_GIVE_ITEM_LIGHT_ARROW: - if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { *should = false; } break; case GI_VB_PLAY_NABOORU_CAPTURED_CS: - if (*should == true && CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (*should == true && CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { Flags_SetEventChkInf(EVENTCHKINF_NABOORU_CAPTURED_BY_TWINROVA); *should = false; } break; case GI_VB_PLAY_PULL_MASTER_SWORD_CS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL)) { // Normally, these would be done in the cutscene, but we're skipping it Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); @@ -388,7 +388,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; case GI_VB_OWL_INTERACTION: { - if (CVarGetInteger("gTimeSavers.SkipOwlInteractions", 0) && *should) { + if (CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) && *should) { EnOwl* enOwl = static_cast(opt); s32 owlType = (enOwl->actor.params & 0xFC0) >> 6; @@ -405,12 +405,12 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* case GI_VB_PLAY_EYEDROPS_CS: case GI_VB_PLAY_DROP_FISH_FOR_JABU_CS: case GI_VB_PLAY_DARUNIAS_JOY_CS: - if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO)) { *should = false; } break; case GI_VB_PLAY_ZELDAS_LULLABY_CS: { - if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || IS_RANDO) { DemoIm* demoIm = static_cast(opt); Player* player = GET_PLAYER(gPlayState); player->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; @@ -421,7 +421,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* static uint32_t demoImKillHook = 0; demoImUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* actorRef) mutable { Actor* actor = static_cast(actorRef); - if (actor->id == ACTOR_DEMO_IM && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) { + if (actor->id == ACTOR_DEMO_IM && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || IS_RANDO)) { DemoIm* demoIm = static_cast(actorRef); Player* player = GET_PLAYER(gPlayState); player->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; @@ -459,7 +459,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; } case GI_VB_PLAY_SARIAS_SONG_CS: { - if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || IS_RANDO) { EnSa* enSa = static_cast(opt); enSa->actionFunc = func_80AF6B20; *should = false; @@ -473,7 +473,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; } case GI_VB_PLAY_DRAIN_WELL_CS: { - if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { *should = false; Flags_SetSwitch(gPlayState, 0x2); Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); @@ -482,7 +482,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; } case GI_VB_PLAY_SUNS_SONG_CS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || IS_RANDO) { *should = false; Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SUNS_SONG); // SoH [Randomizer] TODO: Increment time X amount (find out X) @@ -491,19 +491,19 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; case GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS: { - if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO)) { *should = false; } break; } case GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE: { - if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO)) { *should = Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB); } break; } case GI_VB_PLAY_DOOR_OF_TIME_CS: { - if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO)) { *should = false; Flags_SetEnv(gPlayState, 2); func_80078884(NA_SE_SY_CORRECT_CHIME); @@ -526,7 +526,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* case GI_VB_PLAY_BOLERO_OF_FIRE_CS: case GI_VB_PLAY_SERENADE_OF_WATER_CS: case GI_VB_PLAY_PRELUDE_OF_LIGHT_CS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || IS_RANDO) { *should = false; } break; @@ -581,7 +581,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_EN_KO && (actor->params & 0xFF) == ENKO_TYPE_CHILD_3) { enKoUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); - if (innerActor->id == ACTOR_EN_KO && (innerActor->params & 0xFF) == ENKO_TYPE_CHILD_3 && (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0) || IS_RANDO)) { + if (innerActor->id == ACTOR_EN_KO && (innerActor->params & 0xFF) == ENKO_TYPE_CHILD_3 && (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) || IS_RANDO)) { EnKo* enKo = static_cast(innerActorRef); // They haven't moved yet, wrap their update function so we check every frame if (enKo->actionFunc == func_80A995CC) { @@ -607,7 +607,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { }); } - if (actor->id == ACTOR_ITEM_OCARINA && actor->params == 3 && CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (actor->id == ACTOR_ITEM_OCARINA && actor->params == 3 && CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { itemOcarinaframesSinceSpawn = 0; itemOcarinaUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); @@ -625,7 +625,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_EN_MA1 && gPlayState->sceneNum == SCENE_LON_LON_RANCH) { enMa1UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); - if (innerActor->id == ACTOR_EN_MA1 && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) { + if (innerActor->id == ACTOR_EN_MA1 && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || IS_RANDO)) { EnMa1* enMa1 = static_cast(innerActorRef); if (enMa1->actionFunc == func_80AA106C) { enMa1->actionFunc = EnMa1_EndTeachSong; @@ -653,7 +653,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_EN_FU) { enFuUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); - if (innerActor->id == ACTOR_EN_FU && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) { + if (innerActor->id == ACTOR_EN_FU && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || IS_RANDO)) { EnFu* enFu = static_cast(innerActorRef); if (enFu->actionFunc == EnFu_TeachSong) { enFu->actionFunc = EnFu_EndTeachSong; @@ -676,7 +676,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { SPDLOG_INFO("Registering BG_SPOT02 hook"); bgSpot02UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); - if (innerActor->id == ACTOR_BG_SPOT02_OBJECTS && innerActor->params == 2 && (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0))) { + if (innerActor->id == ACTOR_BG_SPOT02_OBJECTS && innerActor->params == 2 && (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO))) { SPDLOG_INFO("on update BG_SPOT02 hook"); BgSpot02Objects* bgSpot02 = static_cast(innerActorRef); if (bgSpot02->actionFunc == func_808ACC34) { @@ -697,7 +697,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { }); } - if (actor->id == ACTOR_EN_ZL4 && CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + if (actor->id == ACTOR_EN_ZL4 && CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { EnZl4* enZl4 = static_cast(actorRef); if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0) return; @@ -708,63 +708,63 @@ void TimeSaverOnActorInitHandler(void* actorRef) { void TimeSaverOnSceneInitHandler(int16_t sceneNum) { switch (sceneNum) { case SCENE_HYRULE_CASTLE: - if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) && !Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) && !Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET); Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET); } break; case SCENE_LON_LON_RANCH: - if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) && GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL)) { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) && GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL)) { Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_RANCH); Flags_SetInfTable(INFTABLE_CHILD_MALON_SAID_EPONA_WAS_AFRAID_OF_YOU); Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON); } break; case SCENE_DEKU_TREE_BOSS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE)) { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE); } } break; case SCENE_DODONGOS_CAVERN_BOSS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE)) { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE); } } break; case SCENE_JABU_JABU_BOSS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE)) { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE); } } break; case SCENE_FOREST_TEMPLE_BOSS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE)) { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE); } } break; case SCENE_FIRE_TEMPLE_BOSS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE)) { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE); } } break; case SCENE_WATER_TEMPLE_BOSS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE)) { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE); } } break; case SCENE_SPIRIT_TEMPLE_BOSS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE)) { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE); Flags_SetEventChkInf(EVENTCHKINF_BEGAN_NABOORU_BATTLE); @@ -773,7 +773,7 @@ void TimeSaverOnSceneInitHandler(int16_t sceneNum) { } break; case SCENE_SHADOW_TEMPLE_BOSS: - if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0)) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO)) { if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE)) { Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE); } @@ -785,7 +785,7 @@ void TimeSaverOnSceneInitHandler(int16_t sceneNum) { static GetItemEntry vanillaQueuedItemEntry = GET_ITEM_NONE; void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { - if (!CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) return; + if (!CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) return; switch (flagType) { case FLAG_EVENT_CHECK_INF: diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index e133a1bb0..44aa38cbe 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -576,29 +576,29 @@ void DrawEnhancementsMenu() { ImGui::Text("Speed-ups:"); UIWidgets::PaddedSeparator(); bool allChecked = - CVarGetInteger("gTimeSavers.SkipCutscene.Intro", 0) && - CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", 0) && - CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0) && - CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) && - CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0) && - CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0) && - CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", 0) && - CVarGetInteger("gTimeSavers.NoForcedDialog", 0) && - CVarGetInteger("gTimeSavers.SkipOwlInteractions", 0) && - CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) && - CVarGetInteger("gTimeSavers.DisableTitleCard", 0); + CVarGetInteger("gTimeSavers.SkipCutscene.Intro", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) && + CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) && + CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO); bool someChecked = - CVarGetInteger("gTimeSavers.SkipCutscene.Intro", 0) || - CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", 0) || - CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0) || - CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || - CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", 0) || - CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0) || - CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", 0) || - CVarGetInteger("gTimeSavers.NoForcedDialog", 0) || - CVarGetInteger("gTimeSavers.SkipOwlInteractions", 0) || - CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0) || - CVarGetInteger("gTimeSavers.DisableTitleCard", 0); + CVarGetInteger("gTimeSavers.SkipCutscene.Intro", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) || + CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) || + CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO); ImGuiContext* g = ImGui::GetCurrentContext(); ImGuiItemFlags backup_item_flags = g->CurrentItemFlags; @@ -632,19 +632,19 @@ void DrawEnhancementsMenu() { LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } g->CurrentItemFlags = backup_item_flags; - UIWidgets::PaddedEnhancementCheckbox("Skip Intro", "gTimeSavers.SkipCutscene.Intro"); - UIWidgets::PaddedEnhancementCheckbox("Skip Entrance Cutscenes", "gTimeSavers.SkipCutscene.Entrances"); - UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story"); - UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong"); - UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro"); - UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding"); + UIWidgets::PaddedEnhancementCheckbox("Skip Intro", "gTimeSavers.SkipCutscene.Intro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Entrance Cutscenes", "gTimeSavers.SkipCutscene.Entrances", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::Tooltip("Skip cutscenes that are associated with useful glitches, currently this is only the Fire Temple Darunia CS and Forest Temple Poe Sisters CS"); - UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint"); - UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog"); + UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::Tooltip("Prevent forced conversations with Navi or other NPCs"); - UIWidgets::PaddedEnhancementCheckbox("Skip Owl Interactions", "gTimeSavers.SkipOwlInteractions"); - UIWidgets::PaddedEnhancementCheckbox("Skip Misc Interactions", "gTimeSavers.SkipMiscInteractions"); - UIWidgets::PaddedEnhancementCheckbox("Disable Title Card", "gTimeSavers.DisableTitleCard"); + UIWidgets::PaddedEnhancementCheckbox("Skip Owl Interactions", "gTimeSavers.SkipOwlInteractions", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Misc Interactions", "gTimeSavers.SkipMiscInteractions", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Disable Title Card", "gTimeSavers.DisableTitleCard", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedText("Skip Get Item Animations", true, false); UIWidgets::EnhancementCombobox("gTimeSavers.SkipGetItemAnimation", skipGetItemAnimationOptions, SGIA_DISABLED); From 13a113c36233e61554b297736b3df88885e739b7 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 23 Feb 2024 12:43:27 -0600 Subject: [PATCH 12/52] Various adjustments to goron related vanilla behavior hooks --- .../game-interactor/GameInteractor.h | 14 +- .../Enhancements/randomizer/hook_handlers.cpp | 82 +++------ soh/soh/Enhancements/randomizer/location.h | 8 +- .../Enhancements/randomizer/location_list.cpp | 8 +- .../Enhancements/randomizer/randomizer_inf.h | 2 - .../Enhancements/timesaver_hook_handlers.cpp | 11 ++ soh/src/overlays/actors/ovl_En_Go/z_en_go.c | 1 - soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 160 +++++++----------- 8 files changed, 101 insertions(+), 185 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 453055da4..380454e01 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -201,8 +201,8 @@ typedef enum { // Opt: *uint16_t // Vanilla condition: false GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE, - // Opt: *EnGo2 - GI_VB_EN_GO2_RESET_AFTER_GET_ITEM, + // Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON) + GI_VB_GORONS_CONSIDER_TUNIC_COLLECTED, // Opt: *EnSyatekiMan // Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50) GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD, @@ -273,9 +273,7 @@ typedef enum { // Vanilla condition: !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, // Opt: *EnGo2 - GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD, - // Opt: *EnGo2 - GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_ADULT, + GI_VB_GIVE_ITEM_FROM_GORON, // Opt: *EnJs GI_VB_GIVE_ITEM_FROM_CARPET_SALESMAN, // Opt: *EnGm @@ -333,16 +331,10 @@ typedef enum { GI_VB_TRADE_ODD_POTION, // Opt: *EnToryo GI_VB_TRADE_SAW, - // Opt: *EnGo2 - GI_VB_TRADE_BROKEN_SWORD, // Opt: *EnKz, GI_VB_TRADE_PRESCRIPTION, // Opt: *EnMk GI_VB_TRADE_FROG, - // Opt: *EnGo2 - GI_VB_TRADE_EYEDROPS, - // Opt: *EnGo2 - GI_VB_TRADE_CLAIM_CHECK, GI_VB_TRADE_TIMER_ODD_MUSHROOM, GI_VB_TRADE_TIMER_EYEDROPS, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 9f2e2633a..35031690e 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -34,6 +34,7 @@ extern PlayState* gPlayState; RandomizerCheck GetRandomizerCheckFromFlag(int16_t flagType, int16_t flag) { for (auto& loc : Rando::StaticData::GetLocationTable()) { if (loc.GetCollectionCheck().flag == flag && ( + (flagType == FLAG_INF_TABLE && loc.GetCollectionCheck().type == SPOILER_CHK_INF_TABLE) || (flagType == FLAG_EVENT_CHECK_INF && loc.GetCollectionCheck().type == SPOILER_CHK_EVENT_CHK_INF) || (flagType == FLAG_ITEM_GET_INF && loc.GetCollectionCheck().type == SPOILER_CHK_ITEM_GET_INF) || (flagType == FLAG_RANDOMIZER_INF && loc.GetCollectionCheck().type == SPOILER_CHK_RANDOMIZER_INF) @@ -104,6 +105,18 @@ static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK; static GetItemEntry randomizerQueuedItemEntry = GET_ITEM_NONE; void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { + // Consume adult trade items + if (RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && flagType == FLAG_RANDOMIZER_INF) { + switch (flag) { + case RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD: + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_SWORD_BROKEN); + break; + case RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS: + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_EYEDROPS); + break; + } + } + RandomizerCheck rc = GetRandomizerCheckFromFlag(flagType, flag); if (rc == RC_UNKNOWN_CHECK) return; @@ -453,8 +466,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void break; } case GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE: { - - *should = INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK && Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); + // This being true will prevent other biggoron trades, there are already safegaurds in place to prevent + // claim check from being traded multiple times, so we don't really need the quest to ever be considered "complete" + *should = false; break; } case GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED: { @@ -465,46 +479,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP); break; } - case GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE: { - u16* textId = static_cast(optionalArg); - *should = true; - - // For rando, prioritize opening the doors in GC when Link the goron has been stopped when - // the doors are not opened, otherwise let him talk about the DMC exit or that gorons are saved - if (!Flags_GetInfTable(INFTABLE_STOPPED_GORON_LINKS_ROLLING)) { - *textId = 0x3030; - } else if (!Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED)) { - *textId = 0x3036; - } else if (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { - *textId = 0x3041; - } else { - *textId = Flags_GetInfTable(INFTABLE_SPOKE_TO_GORON_LINK) ? 0x3038 : 0x3037; - } - break; - } - case GI_VB_EN_GO2_RESET_AFTER_GET_ITEM: { - EnGo2* enGo2 = static_cast(optionalArg); - // For randomizer, handle updating the states for the gorons after receiving the item based on - // the goron type rather then the item being received - switch (enGo2->actor.params & 0x1F) { - case GORON_DMT_BIGGORON: - // Resolves #1301. unk_13EE is used to set the opacity of the HUD. The trade sequence discussion - // with Biggoron sets the HUD to transparent, and it is restored at z_message_PAL:3549, but by - // specifically watching for trade sequence items, this leaves it transparent for non-trade sequence - // items (in rando) so we fix that here - gSaveContext.unk_13EE = 0x32; - break; - case GORON_CITY_LINK: - EnGo2_GetItemAnimation(enGo2, gPlayState); - break; - case GORON_CITY_ROLLING_BIG: - EnGo2_RollingAnimation(enGo2, gPlayState); - enGo2->actionFunc = (EnGo2ActionFunc)EnGo2_GoronRollingBigContinueRolling; - break; - default: - enGo2->actionFunc = func_80A46B40; - break; - } + case GI_VB_GORONS_CONSIDER_TUNIC_COLLECTED: { + *should = Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); break; } case GI_VB_GIVE_ITEM_FROM_ITEM_00: { @@ -589,15 +565,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; break; } - case GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_ADULT: { - EnGo2* enGo2 = static_cast(optionalArg); - *should = false; - if (!Flags_GetRandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT)) { - Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); - enGo2->interactInfo.talkState = NPC_TALK_STATE_ACTION; - } - break; - } case GI_VB_GIVE_ITEM_FROM_CARPET_SALESMAN: { *should = RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_OFF || // If the rando check has already been awarded, use vanilla behavior. @@ -695,16 +662,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; break; } - case GI_VB_TRADE_BROKEN_SWORD: { - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_SWORD_BROKEN); - *should = false; - break; - } - case GI_VB_TRADE_EYEDROPS: { - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_EYEDROPS); - *should = false; - break; - } case GI_VB_DESPAWN_HORSE_RACE_COW: { if (!RAND_GET_OPTION(RSK_SHUFFLE_COWS)) { break; @@ -806,12 +763,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = eligible; break; } - case GI_VB_TRADE_CLAIM_CHECK: case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: case GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM: - case GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD: + case GI_VB_GIVE_ITEM_FROM_GORON: case GI_VB_GIVE_ITEM_FROM_LAB_DIVE: case GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG: case GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF: diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index fcea02eb4..ad3142cae 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -16,10 +16,10 @@ class SpoilerCollectionCheck { public: SpoilerCollectionCheckType type = SPOILER_CHK_NONE; uint8_t scene = 0; - uint8_t flag = 0; + uint16_t flag = 0; SpoilerCollectionCheck() = default; - SpoilerCollectionCheck(const SpoilerCollectionCheckType type_, const uint8_t scene_, const uint8_t flag_) + SpoilerCollectionCheck(const SpoilerCollectionCheckType type_, const uint8_t scene_, const uint16_t flag_) : type(type_), scene(scene_), flag(flag_) { } @@ -39,8 +39,8 @@ class SpoilerCollectionCheck { return SpoilerCollectionCheck(SPOILER_CHK_EVENT_CHK_INF, 0xFF, flag); } - static auto InfTable(const uint8_t offset, const uint8_t bit) { - return SpoilerCollectionCheck(SPOILER_CHK_INF_TABLE, offset, bit); + static auto InfTable(const uint16_t flag) { + return SpoilerCollectionCheck(SPOILER_CHK_INF_TABLE, 0xFF, flag); } static auto Collectable(const uint8_t scene, const uint8_t flag) { diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 8deeab8c8..c375f6bea 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -651,7 +651,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), 0x3A, "Deku Scrub Grotto Front", "GV Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); // Gerudo Fortress locationTable[RC_GF_CHEST] = Location::Chest(RC_GF_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, 0x00, "Chest", "GF Chest", RHT_GF_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x3E, "GF HBA 1000 Points", "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x08), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x3E, "GF HBA 1000 Points", "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(INFTABLE_190), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); locationTable[RC_GF_HBA_1500_POINTS] = Location::Base(RC_GF_HBA_1500_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x30, "GF HBA 1500 Points", "GF HBA 1500 Points", RHT_GF_HBA_1500_POINTS, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(15), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); // RandoTodo: Do we replace these with the RC_HIDEOUT keys or keep these? locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, 0x3A, "GF Gerudo Membership Card", "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::GerudoToken(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); @@ -671,7 +671,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x33, "Bombchu Bowling First Prize", "MK Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(17), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x3E, "Bombchu Bowling Second Prize", "MK Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x00, "Bombchu Bowling Bombchus", "MK Bombchu Bowling Bombchus", RHT_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RG_BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", "MK Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x09), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", "MK Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(INFTABLE_191), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", "MK Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", "MK 10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x01, "Chest Game First Room Chest", "MK Chest Game First Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); @@ -719,8 +719,8 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_GC_MAZE_LEFT_CHEST] = Location::Chest(RC_GC_MAZE_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23232, 0x00, "Maze Left Chest", "GC Maze Left Chest", RHT_GC_MAZE_LEFT_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); locationTable[RC_GC_MAZE_RIGHT_CHEST] = Location::Chest(RC_GC_MAZE_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23201, 0x01, "Maze Right Chest", "GC Maze Right Chest", RHT_GC_MAZE_RIGHT_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); locationTable[RC_GC_MAZE_CENTER_CHEST] = Location::Chest(RC_GC_MAZE_CENTER_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23202, 0x02, "Maze Center Chest", "GC Maze Center Chest", RHT_GC_MAZE_CENTER_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_ROLLING_GORON_AS_CHILD] = Location::Base(RC_GC_ROLLING_GORON_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x34, "Rolling Goron as Child", "GC Rolling Goron as Child", RHT_GC_ROLLING_GORON_AS_CHILD, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ROLLING_GORON_AS_CHILD), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x2C, "Rolling Goron as Adult", "GC Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); + locationTable[RC_GC_ROLLING_GORON_AS_CHILD] = Location::Base(RC_GC_ROLLING_GORON_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x34, "Rolling Goron as Child", "GC Rolling Goron as Child", RHT_GC_ROLLING_GORON_AS_CHILD, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::InfTable(INFTABLE_11E), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); + locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x2C, "Rolling Goron as Adult", "GC Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, {}, SpoilerCollectionCheck::InfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x54, "Darunias Joy", "GC Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DARUNIAS_JOY), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); locationTable[RC_GC_POT_FREESTANDING_POH] = Location::Collectable(RC_GC_POT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_ITEM00, SCENE_GORON_CITY, 7942, 0x1F, "Pot Freestanding PoH", "GC Pot Freestanding PoH", RHT_GC_POT_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), 0x30, "Deku Scrub Grotto Left", "GC Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 31ca0a805..a66827de6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -274,8 +274,6 @@ typedef enum { RAND_INF_LEARNED_EPONA_SONG, RAND_INF_DARUNIAS_JOY, RAND_INF_KING_ZORA_THAWED, - RAND_INF_ROLLING_GORON_AS_CHILD, - RAND_INF_ROLLING_GORON_AS_ADULT, // 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) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 27d10c00e..84b619ebe 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -401,6 +401,17 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE: { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO)) { + u16* textId = static_cast(opt); + // If the doors are not open yet, prioritize opening them + if (!Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED)) { + *textId = 0x3036; + *should = true; + } + } + break; + } case GI_VB_PLAY_EYEDROP_CREATION_ANIM: case GI_VB_PLAY_EYEDROPS_CS: case GI_VB_PLAY_DROP_FISH_FOR_JABU_CS: diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index 7dc67f427..3ec88fb74 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -971,7 +971,6 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { if ((this->actor.params & 0xF0) == 0) { getItemId = GI_TUNIC_GORON; - Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT); } yDist = fabsf(this->actor.yDistToPlayer) + 1.0f; diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 86d1b488a..783ada21a 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -142,7 +142,6 @@ typedef enum { /* 10 */ ENGO2_ANIM_10, /* 11 */ ENGO2_ANIM_11, /* 12 */ ENGO2_ANIM_12, - /* 13 */ ENGO2_ANIM_13, // Added to fix spinning goron issue for biggoron } EnGo2Animation; static AnimationInfo sAnimationInfo[] = { @@ -152,7 +151,7 @@ static AnimationInfo sAnimationInfo[] = { { &gGoronAnim_002D80, 1.0f, 0.0f, -1.0f, 0x02, -8.0f }, { &gGoronAnim_00161C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_001A00, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_0021D0, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x01, -8.0f }, { &gGoronAnim_000750, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, - { &gGoronAnim_000D5C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_004930, 0.0f, 1.0f, -1.0f, 0x01, 0.0f }, + { &gGoronAnim_000D5C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, }; static EnGo2DustEffectData sDustEffectData[2][4] = { @@ -284,15 +283,10 @@ s32 EnGo2_SpawnDust(EnGo2* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 void EnGo2_GetItem(EnGo2* this, PlayState* play, s32 getItemId) { this->getItemId = getItemId; - func_8002F434(&this->actor, play, getItemId, this->actor.xzDistToPlayer + 1.0f, - fabsf(this->actor.yDistToPlayer) + 1.0f); -} - -void EnGo2_GetItemEntry(EnGo2* this, PlayState* play, GetItemEntry getItemEntry) { - this->getItemId = getItemEntry.getItemId; - this->getItemEntry = getItemEntry; - GiveItemEntryFromActor(&this->actor, play, getItemEntry, this->actor.xzDistToPlayer + 1.0f, - fabsf(this->actor.yDistToPlayer) + 1.0f); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GORON, true, this)) { + func_8002F434(&this->actor, play, getItemId, this->actor.xzDistToPlayer + 1.0f, + fabsf(this->actor.yDistToPlayer) + 1.0f); + } } s32 EnGo2_GetDialogState(EnGo2* this, PlayState* play) { @@ -335,7 +329,7 @@ u16 EnGo2_GoronFireGenericGetTextId(EnGo2* this) { u16 EnGo2_GetTextIdGoronCityRollingBig(PlayState* play, EnGo2* this) { if (Flags_GetInfTable(INFTABLE_11E)) { return 0x3013; - } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD, CUR_CAPACITY(UPG_BOMB_BAG) >= 2, this) + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD, CUR_CAPACITY(UPG_BOMB_BAG) >= 20, this) && this->waypoint > 7 && this->waypoint < 12) { return 0x3012; } else { @@ -351,14 +345,9 @@ s16 EnGo2_UpdateTalkStateGoronCityRollingBig(PlayState* play, EnGo2* this) { if (Message_ShouldAdvance(play)) { if (this->actor.textId == 0x3012) { this->actionFunc = EnGo2_SetupGetItem; - if(GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD, true, this)) { - EnGo2_GetItem(this, play, CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30); - } else { - this->actionFunc = EnGo2_SetGetItem; - } + EnGo2_GetItem(this, play, CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30); Message_CloseTextbox(play); Flags_SetInfTable(INFTABLE_11E); - Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_CHILD); return NPC_TALK_STATE_ACTION; } else { return NPC_TALK_STATE_ACTION; @@ -511,9 +500,9 @@ u16 EnGo2_GetTextIdGoronCityLink(PlayState* play, EnGo2* this) { return overrideTextId; } - if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL)) { return Flags_GetInfTable(INFTABLE_10F) ? 0x3042 : 0x3041; - } else if (CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_TUNIC_COLLECTED, CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON), NULL)) { return Flags_GetInfTable(INFTABLE_SPOKE_TO_GORON_LINK) ? 0x3038 : 0x3037; } else if (Flags_GetInfTable(INFTABLE_STOPPED_GORON_LINKS_ROLLING)) { this->unk_20C = 0; @@ -529,16 +518,9 @@ s16 EnGo2_UpdateTalkStateGoronCityLink(PlayState* play, EnGo2* this) { case TEXT_STATE_CLOSING: switch (this->actor.textId) { case 0x3036: - Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT); - this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_ADULT, true, this)) { - EnGo2_GetItem(this, play, GI_TUNIC_GORON); - this->actionFunc = EnGo2_SetupGetItem; - return NPC_TALK_STATE_ACTION; - } else { - this->actionFunc = EnGo2_SetGetItem; - return this->interactInfo.talkState; - } + EnGo2_GetItem(this, play, GI_TUNIC_GORON); + this->actionFunc = EnGo2_SetupGetItem; + return NPC_TALK_STATE_ACTION; case 0x3037: Flags_SetInfTable(INFTABLE_SPOKE_TO_GORON_LINK); default: @@ -608,18 +590,14 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { switch (EnGo2_GetDialogState(this, play)) { case TEXT_STATE_DONE: if (this->actor.textId == 0x305E) { - if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED, gSaveContext.bgsFlag, NULL)) { - return NPC_TALK_STATE_IDLE; - } - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); - if (GameInteractor_Should(GI_VB_TRADE_CLAIM_CHECK, true, this)) { + if (!GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED, gSaveContext.bgsFlag, NULL)) { + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); EnGo2_GetItem(this, play, GI_SWORD_BGS); this->actionFunc = EnGo2_SetupGetItem; + return NPC_TALK_STATE_ACTION; } else { - this->actionFunc = EnGo2_SetGetItem; + return NPC_TALK_STATE_IDLE; } - - return NPC_TALK_STATE_ACTION; } else { return NPC_TALK_STATE_IDLE; } @@ -645,12 +623,8 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { if ((this->actor.textId == 0x3054) || (this->actor.textId == 0x3055)) { if (play->msgCtx.choiceIndex == 0) { Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD); - if (GameInteractor_Should(GI_VB_TRADE_BROKEN_SWORD, true, this)) { - EnGo2_GetItem(this, play, GI_PRESCRIPTION); - this->actionFunc = EnGo2_SetupGetItem; - } else { - this->actionFunc = EnGo2_SetGetItem; - } + EnGo2_GetItem(this, play, GI_PRESCRIPTION); + this->actionFunc = EnGo2_SetupGetItem; return NPC_TALK_STATE_ACTION; } this->actor.textId = 0x3056; @@ -1056,7 +1030,10 @@ void EnGo2_BiggoronSetTextId(EnGo2* this, PlayState* play, Player* player) { } player->actor.textId = this->actor.textId; - } else if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { + } else if ( + !GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED, gSaveContext.bgsFlag, NULL) && + (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) + ) { if (func_8002F368(play) == EXCH_ITEM_CLAIM_CHECK) { if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_FORGED, Environment_GetBgsDayCount() >= 3, NULL)) { textId = 0x305E; @@ -1193,8 +1170,10 @@ s32 EnGo2_IsCameraModified(EnGo2* this, PlayState* play) { (this->actor.params & 0x1F) == GORON_CITY_STAIRWELL || (this->actor.params & 0x1F) == GORON_DMT_BIGGORON || (this->actor.params & 0x1F) == GORON_MARKET_BAZAAR) { return true; - } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && - CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { + } else if ( + !GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && + GameInteractor_Should(GI_VB_GORONS_CONSIDER_TUNIC_COLLECTED, CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON), NULL) + ) { return true; } else { return false; @@ -1251,8 +1230,10 @@ void EnGo2_SelectGoronWakingUp(EnGo2* this) { EnGo2_BiggoronWakingUp(this); break; case GORON_CITY_LINK: - if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && - CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { + if ( + !GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && + GameInteractor_Should(GI_VB_GORONS_CONSIDER_TUNIC_COLLECTED, CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON), NULL) + ) { EnGo2_WakingUp(this); break; } @@ -1349,25 +1330,10 @@ void EnGo2_WakeUp(EnGo2* this, PlayState* play) { } if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) { OnePointCutscene_Init(play, 4200, -99, &this->actor, MAIN_CAM); - // There is an issue interpolating between ENGO2_ANIM_0 and ENGO2_ANIM_1/10, the goron - // is technically in the same position at the end of ANIM_0 and beginning of ANIM_1/10 - // but something isn't getting translated correctly causing the 360 degree spin before - // then continuing the wake up animation like normal. One solution is to use ANIM_0 - // which uses the same frame data as ANIM_1/10 but no morph frames, but only when the - // current animation frame is at 0, meaning no morphing is necessary anyway. - // ANIM_13 is ANIM_0 but with the startFrame and mode adjusted for biggoron. - if (this->skelAnime.curFrame == 0.0f && !CVarGetInteger("gUnfixGoronSpin", 0)) { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_13); - } else { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_10); - } + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_10); this->skelAnime.playSpeed = 0.5f; } else { - if (this->skelAnime.curFrame == 0.0f && !CVarGetInteger("gUnfixGoronSpin", 0)) { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_0); - } else { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1); - } + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1); this->skelAnime.playSpeed = 1.0f; } this->actionFunc = func_80A46B40; @@ -1589,14 +1555,13 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { this->unk_216 = this->actor.shape.rot.z; this->trackingMode = NPC_TRACKING_NONE; this->path = Path_GetByIndex(play, (this->actor.params & 0x3E0) >> 5, 0x1F); - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; switch (this->actor.params & 0x1F) { case GORON_CITY_ENTRANCE: case GORON_CITY_ISLAND: case GORON_CITY_LOWEST_FLOOR: case GORON_CITY_STAIRWELL: case GORON_CITY_LOST_WOODS: - if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { + if (!GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { Actor_Kill(&this->actor); } this->actionFunc = EnGo2_CurledUp; @@ -1611,8 +1576,10 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { if ((Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED))) { Path_CopyLastPoint(this->path, &this->actor.world.pos); this->actor.home.pos = this->actor.world.pos; - if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && - CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { + if ( + !GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && + GameInteractor_Should(GI_VB_GORONS_CONSIDER_TUNIC_COLLECTED, CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON), NULL) + ) { EnGo2_GetItemAnimation(this, play); } else { this->actionFunc = EnGo2_CurledUp; @@ -1828,7 +1795,7 @@ void EnGo2_ReverseRolling(EnGo2* this, PlayState* play) { } void EnGo2_SetupGetItem(EnGo2* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GORON, true, NULL)) { this->actor.parent = NULL; this->actionFunc = EnGo2_SetGetItem; } else { @@ -1837,30 +1804,29 @@ void EnGo2_SetupGetItem(EnGo2* this, PlayState* play) { } void EnGo2_SetGetItem(EnGo2* this, PlayState* play) { - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GORON, true, NULL)) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - - if (GameInteractor_Should(GI_VB_EN_GO2_RESET_AFTER_GET_ITEM, true, this)) { - switch (this->getItemId) { - case GI_CLAIM_CHECK: - Environment_ClearBgsDayCount(); - EnGo2_GetItemAnimation(this, play); - return; - case GI_TUNIC_GORON: - Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); - EnGo2_GetItemAnimation(this, play); - return; - case GI_SWORD_BGS: + switch (this->getItemId) { + case GI_CLAIM_CHECK: + Environment_ClearBgsDayCount(); + EnGo2_GetItemAnimation(this, play); + return; + case GI_TUNIC_GORON: + Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); + EnGo2_GetItemAnimation(this, play); + return; + case GI_SWORD_BGS: + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GORON, true, NULL)) { gSaveContext.bgsFlag = true; - break; - case GI_BOMB_BAG_30: - case GI_BOMB_BAG_40: - EnGo2_RollingAnimation(this, play); - this->actionFunc = EnGo2_GoronRollingBigContinueRolling; - return; - } - this->actionFunc = func_80A46B40; + } + break; + case GI_BOMB_BAG_30: + case GI_BOMB_BAG_40: + EnGo2_RollingAnimation(this, play); + this->actionFunc = EnGo2_GoronRollingBigContinueRolling; + return; } + this->actionFunc = func_80A46B40; } } @@ -1905,15 +1871,9 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; this->skelAnime.playSpeed = 0.0f; this->skelAnime.curFrame = this->skelAnime.endFrame; - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS); - if(GameInteractor_Should(GI_VB_TRADE_EYEDROPS, true, this)) { - u32 getItemId = GI_CLAIM_CHECK; - EnGo2_GetItem(this, play, getItemId); - this->actionFunc = EnGo2_SetupGetItem; - } else { - this->actionFunc = EnGo2_SetGetItem; - } + EnGo2_GetItem(this, play, GI_CLAIM_CHECK); + this->actionFunc = EnGo2_SetupGetItem; this->goronState = 0; } break; From 09c967249f8c49cfae85dbafa5778e2226a9d94a Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 23 Feb 2024 14:06:27 -0600 Subject: [PATCH 13/52] More 1PC skips --- .../Enhancements/timesaver_hook_handlers.cpp | 29 +++++++++++-------- .../ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h | 3 ++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 84b619ebe..84d95d7f0 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -20,6 +20,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Tk/z_en_tk.h" #include "src/overlays/actors/ovl_En_Fu/z_en_fu.h" #include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h" +#include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -88,7 +89,8 @@ void EnZl4_SkipToGivingZeldasLetter(EnZl4* enZl4, PlayState* play) { static int successChimeCooldown = 0; void RateLimitedSuccessChime() { if (successChimeCooldown == 0) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + // Currently disabled, need to find a better way to do this, while being consistent with vanilla + // func_80078884(NA_SE_SY_CORRECT_CHIME); successChimeCooldown = 120; } } @@ -282,25 +284,31 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* RateLimitedSuccessChime(); break; } - // case ACTOR_PLAYER: // This might cause issues + case ACTOR_BG_HIDAN_KOUSI: { + BgHidanKousi* switchActor = static_cast(opt); + BgHidanKousi_SetupAction(switchActor, func_80889C18); + *should = false; + RateLimitedSuccessChime(); + break; + } + case ACTOR_BG_HIDAN_FWBIG: { + *should = false; + break; + } case ACTOR_EN_TA: case ACTOR_DOOR_SHUTTER: + case ACTOR_BG_ICE_SHUTTER: + case ACTOR_OBJ_LIGHTSWITCH: case ACTOR_EN_BOX: case ACTOR_OBJ_SYOKUDAI: case ACTOR_OBJ_TIMEBLOCK: case ACTOR_EN_PO_SISTERS: - // Prop case ACTOR_OBJ_ICE_POLY: case ACTOR_BG_YDAN_MARUTA: case ACTOR_BG_SPOT18_SHUTTER: case ACTOR_BG_SPOT05_SOKO: case ACTOR_BG_SPOT18_BASKET: - // BG - // case ACTOR_BG_YDAN_SP: - // case ACTOR_BG_YDAN_HASI: - // case ACTOR_BG_DODOAGO: - // case ACTOR_BG_DDAN_KD: - // case ACTOR_BG_DDAN_JD: + case ACTOR_BG_HIDAN_CURTAIN: *should = false; RateLimitedSuccessChime(); break; @@ -684,14 +692,11 @@ void TimeSaverOnActorInitHandler(void* actorRef) { } if (actor->id == ACTOR_BG_SPOT02_OBJECTS && actor->params == 2) { - SPDLOG_INFO("Registering BG_SPOT02 hook"); bgSpot02UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); if (innerActor->id == ACTOR_BG_SPOT02_OBJECTS && innerActor->params == 2 && (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO))) { - SPDLOG_INFO("on update BG_SPOT02 hook"); BgSpot02Objects* bgSpot02 = static_cast(innerActorRef); if (bgSpot02->actionFunc == func_808ACC34) { - SPDLOG_INFO("BGspot02 OVERRIDDEN"); bgSpot02->actionFunc = func_808AC908; GameInteractor::Instance->UnregisterGameHook(bgSpot02UpdateHook); GameInteractor::Instance->UnregisterGameHook(bgSpot02KillHook); diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h b/soh/src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h index fff8c4c53..1f3eb4161 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h @@ -14,4 +14,7 @@ typedef struct BgHidanKousi { /* 0x0168 */ s16 unk_168; } BgHidanKousi; // size = 0x016C +void BgHidanKousi_SetupAction(BgHidanKousi* bgHidanKousi, BgHidanKousiActionFunc actionFunc); +void func_80889C18(BgHidanKousi* bgHidanKousi, PlayState* play); + #endif From 416ed84bc689fecc1e1b2e62cf7b3353a9711977 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sat, 24 Feb 2024 09:17:48 -0600 Subject: [PATCH 14/52] Migrate great fairy checks --- soh/include/z64save.h | 2 +- .../Enhancements/debugger/debugSaveEditor.h | 8 +++ .../game-interactor/GameInteractor.h | 3 + soh/soh/Enhancements/randomizer/location.h | 2 +- .../Enhancements/randomizer/location_list.cpp | 12 ++-- .../Enhancements/randomizer/randomizer_inf.h | 7 +++ .../Enhancements/timesaver_hook_handlers.cpp | 60 +++++++++++++++++++ .../ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c | 38 ++++-------- .../actors/ovl_En_Ex_Item/z_en_ex_item.h | 2 +- 9 files changed, 97 insertions(+), 37 deletions(-) diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 0f527925d..617c2acf5 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -283,7 +283,7 @@ typedef struct { // #endregion // #region SOH [Randomizer] // Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer - /* */ u16 randomizerInf[16]; + /* */ u16 randomizerInf[17]; /* */ u8 mqDungeonCount; /* */ u16 adultTradeItems; /* */ u8 triforcePiecesCollected; diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 5a4618dac..ff9f9bf8f 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -612,6 +612,14 @@ const std::vector flagTables = { { RAND_INF_LINKS_POCKET, "RAND_INF_LINKS_POCKET" }, { RAND_INF_LEARNED_EPONA_SONG, "RAND_INF_LEARNED_EPONA_SONG" }, { RAND_INF_DARUNIAS_JOY, "RAND_INF_DARUNIAS_JOY" }, + { RAND_INF_KING_ZORA_THAWED, "RAND_INF_KING_ZORA_THAWED" }, + + { RAND_INF_HC_GREAT_FAIRY_REWARD, "RAND_INF_HC_GREAT_FAIRY_REWARD" }, + { RAND_INF_DMT_GREAT_FAIRY_REWARD, "RAND_INF_DMT_GREAT_FAIRY_REWARD" }, + { RAND_INF_DMC_GREAT_FAIRY_REWARD, "RAND_INF_DMC_GREAT_FAIRY_REWARD" }, + { RAND_INF_ZF_GREAT_FAIRY_REWARD, "RAND_INF_ZF_GREAT_FAIRY_REWARD" }, + { RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, "RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD" }, + { RAND_INF_OGC_GREAT_FAIRY_REWARD, "RAND_INF_OGC_GREAT_FAIRY_REWARD" }, } }, }; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 380454e01..478f82712 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -209,6 +209,9 @@ typedef enum { // Opt: *EnOkarinaTag // Vanilla condition: !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME) GI_VB_BE_ELIGIBLE_TO_OPEN_DOT, + // Opt: *BgDyYoseizo + // Vanilla condition: see soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c + GI_VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD, /*** Play Cutscenes ***/ diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index ad3142cae..a962e4501 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -79,7 +79,7 @@ class SpoilerCollectionCheck { return SpoilerCollectionCheck(SPOILER_CHK_MASTER_SWORD, 0x00, 0x00); } - static auto RandomizerInf(const uint8_t flag) { + static auto RandomizerInf(const uint16_t flag) { return SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, 0x00, flag); } }; diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index c375f6bea..c58674bae 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1297,12 +1297,12 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_TOT_MASTER_SWORD] = Location::Delayed(RC_TOT_MASTER_SWORD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "ToT Master Sword", "ToT Master Sword", RHT_TOT_MASTER_SWORD, RG_MASTER_SWORD, {}, SpoilerCollectionCheck::EventChkInf(0x45), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_TOT_LIGHT_ARROWS_CUTSCENE] = Location::Delayed(RC_TOT_LIGHT_ARROWS_CUTSCENE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x01, "ToT Light Arrow Cutscene", "ToT Light Arrow Cutscene", RHT_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS, {}, SpoilerCollectionCheck::EventChkInf(0xC4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_LW_GIFT_FROM_SARIA] = Location::Delayed(RC_LW_GIFT_FROM_SARIA, RCQUEST_BOTH, RCTYPE_OCARINA, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x02, "Gift From Saria", "LW Gift From Saria", RHT_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0xC1), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_ZF_GREAT_FAIRY_REWARD] = Location::Delayed(RC_ZF_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, 0x10, "Great Fairy Reward", "ZF Great Fairy Reward", RHT_ZF_GREAT_FAIRY_REWARD, RG_FARORES_WIND, {}, SpoilerCollectionCheck::Chest(0x3D, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_HC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_HC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, 0x11, "Great Fairy Reward", "HC Great Fairy Reward", RHT_HC_GREAT_FAIRY_REWARD, RG_DINS_FIRE, {}, SpoilerCollectionCheck::Chest(0x3D, 0x02), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_COLOSSUS_GREAT_FAIRY_REWARD] = Location::Delayed(RC_COLOSSUS_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 3, 0x12, "Great Fairy Reward", "Colossus Great Fairy Reward", RHT_COLOSSUS_GREAT_FAIRY_REWARD, RG_NAYRUS_LOVE, {}, SpoilerCollectionCheck::Chest(0x3D, 0x03), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_DMT_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMT_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, 0x13, "Great Fairy Reward", "DMT Great Fairy Reward", RHT_DMT_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::Chest(0x3B, 0x01), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, 0x14, "Great Fairy Reward", "DMC Great Fairy Reward", RHT_DMC_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::Chest(0x3B, 0x02), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_OGC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_OGC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, 0x15, "OGC Great Fairy Reward", "OGC Great Fairy Reward", RHT_OGC_GREAT_FAIRY_REWARD, RG_DOUBLE_DEFENSE, {}, SpoilerCollectionCheck::Chest(0x3B, 0x03), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_ZF_GREAT_FAIRY_REWARD] = Location::Delayed(RC_ZF_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, 0x10, "Great Fairy Reward", "ZF Great Fairy Reward", RHT_ZF_GREAT_FAIRY_REWARD, RG_FARORES_WIND, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_HC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_HC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, 0x11, "Great Fairy Reward", "HC Great Fairy Reward", RHT_HC_GREAT_FAIRY_REWARD, RG_DINS_FIRE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_COLOSSUS_GREAT_FAIRY_REWARD] = Location::Delayed(RC_COLOSSUS_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 3, 0x12, "Great Fairy Reward", "Colossus Great Fairy Reward", RHT_COLOSSUS_GREAT_FAIRY_REWARD, RG_NAYRUS_LOVE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_DMT_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMT_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, 0x13, "Great Fairy Reward", "DMT Great Fairy Reward", RHT_DMT_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, 0x14, "Great Fairy Reward", "DMC Great Fairy Reward", RHT_DMC_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_OGC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_OGC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, 0x15, "OGC Great Fairy Reward", "OGC Great Fairy Reward", RHT_OGC_GREAT_FAIRY_REWARD, RG_DOUBLE_DEFENSE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); // Songs locationTable[RC_SHEIK_IN_FOREST] = Location::Delayed(RC_SHEIK_IN_FOREST, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x20, "Sheik in Forest", "Sheik in Forest", RHT_SHEIK_IN_FOREST, RG_MINUET_OF_FOREST, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x50), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index a66827de6..67b396d74 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -274,6 +274,13 @@ typedef enum { RAND_INF_LEARNED_EPONA_SONG, RAND_INF_DARUNIAS_JOY, RAND_INF_KING_ZORA_THAWED, + + RAND_INF_HC_GREAT_FAIRY_REWARD, + RAND_INF_DMT_GREAT_FAIRY_REWARD, + RAND_INF_DMC_GREAT_FAIRY_REWARD, + RAND_INF_ZF_GREAT_FAIRY_REWARD, + RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, + RAND_INF_OGC_GREAT_FAIRY_REWARD, // 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) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 84d95d7f0..ba432796b 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -21,6 +21,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Fu/z_en_fu.h" #include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h" #include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h" +#include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -581,6 +582,47 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* case GI_VB_BIGGORON_CONSIDER_SWORD_FORGED: *should = Environment_GetBgsDayCount() >= CVarGetInteger("gForgeTime", 3); break; + case GI_VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD: { + BgDyYoseizo* bgDyYoseizo = static_cast(opt); + RandomizerInf flag = RAND_INF_MAX; + + if (gPlayState->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS) { + switch (bgDyYoseizo->fountainType) { + case 0: + flag = RAND_INF_ZF_GREAT_FAIRY_REWARD; + break; + case 1: + flag = RAND_INF_HC_GREAT_FAIRY_REWARD; + break; + case 2: + flag = RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD; + break; + } + } else { + switch (bgDyYoseizo->fountainType) { + case 0: + flag = RAND_INF_DMT_GREAT_FAIRY_REWARD; + break; + case 1: + flag = RAND_INF_DMC_GREAT_FAIRY_REWARD; + break; + case 2: + flag = RAND_INF_OGC_GREAT_FAIRY_REWARD; + break; + } + } + + if (flag != RAND_INF_MAX && (IS_RANDO || CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO))) { + if (IS_RANDO || *should) { + Flags_SetRandomizerInf(flag); + gSaveContext.healthAccumulator = 0x140; + Magic_Fill(gPlayState); + } + *should = false; + } + + break; + } } } @@ -879,6 +921,24 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { case RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE: vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SPIRIT_MEDALLION).GetGIEntry_Copy(); break; + case RAND_INF_ZF_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FARORES_WIND).GetGIEntry_Copy(); + break; + case RAND_INF_HC_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DINS_FIRE).GetGIEntry_Copy(); + break; + case RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_NAYRUS_LOVE).GetGIEntry_Copy(); + break; + case RAND_INF_DMT_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MAGIC_SINGLE).GetGIEntry_Copy(); + break; + case RAND_INF_DMC_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MAGIC_DOUBLE).GetGIEntry_Copy(); + break; + case RAND_INF_OGC_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DOUBLE_DEFENSE).GetGIEntry_Copy(); + break; } break; } diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index e8b2be4df..542711f81 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -11,6 +11,7 @@ #include "scenes/indoors/yousei_izumi_yoko/yousei_izumi_yoko_scene.h" #include "scenes/indoors/daiyousei_izumi/daiyousei_izumi_scene.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -68,19 +69,6 @@ const ActorInit Bg_Dy_Yoseizo_InitVars = { NULL, }; -void GivePlayerRandoRewardGreatFairy(BgDyYoseizo* this, PlayState* play) { - Player* player = GET_PLAYER(play); - GetItemEntry getItemEntry = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->fountainType + 1, GI_NONE); - - if (this->actor.parent == GET_PLAYER(play) && !Flags_GetTreasure(play, this->fountainType + 1) && - !Player_InBlockingCsMode(play, GET_PLAYER(play))) { - Flags_SetTreasure(play, this->fountainType + 1); - Actor_Kill(&this->actor); - } else if (!Flags_GetTreasure(play, this->fountainType + 1)) { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 100.0f); - } -} - void BgDyYoseizo_Init(Actor* thisx, PlayState* play2) { PlayState* play = play2; BgDyYoseizo* this = (BgDyYoseizo*)thisx; @@ -196,31 +184,25 @@ void BgDyYoseizo_Bob(BgDyYoseizo* this, PlayState* play) { } void BgDyYoseizo_CheckMagicAcquired(BgDyYoseizo* this, PlayState* play) { + u8 isEligible = true; if (Flags_GetSwitch(play, 0x38)) { play->msgCtx.ocarinaMode = OCARINA_MODE_04; - if(IS_RANDO) { - gSaveContext.healthAccumulator = 0x140; - Magic_Fill(play); - if(Flags_GetTreasure(play, this->fountainType + 1)) { - Actor_Kill(&this->actor); - } else { - GivePlayerRandoRewardGreatFairy(this, play); - } - return; - } - if (play->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC) { if (!gSaveContext.isMagicAcquired && (this->fountainType != FAIRY_UPGRADE_MAGIC)) { - Actor_Kill(&this->actor); - return; + isEligible = false; } } else { if (!gSaveContext.isMagicAcquired) { - Actor_Kill(&this->actor); - return; + isEligible = false; } } + + if (!GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD, isEligible, this)) { + Actor_Kill(&this->actor); + return; + } + func_8002DF54(play, &this->actor, 1); this->actionFunc = BgDyYoseizo_ChooseType; } diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h index 34a880c22..d014e19be 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h @@ -6,7 +6,7 @@ struct EnExItem; -typedef void (*EnExItemActionFunc)(struct EnExItem* this, PlayState* play); +typedef void (*EnExItemActionFunc)(struct EnExItem* enExItem, PlayState* play); typedef void (*EnExItemLightFunc)(Actor*, PlayState*, s32); typedef struct EnExItem { From 0334c4e35484882c09225b29a0f7dfc5642bcae8 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 3 Apr 2024 21:07:42 -0400 Subject: [PATCH 15/52] pull in docs (#97) * rename `func_8002DF54` to `Player_SetCsActionWithHaltedActors` * rename `func_8002F434` to `Actor_OfferGetItem` --- soh/include/functions.h | 6 +- .../Enhancements/timesaver_hook_handlers.cpp | 2 +- soh/src/code/z_actor.c | 7 +- soh/src/code/z_camera.c | 12 ++-- soh/src/code/z_en_item00.c | 2 +- soh/src/code/z_onepointdemo.c | 66 +++++++++---------- soh/src/code/z_parameter.c | 2 +- .../actors/ovl_Bg_Breakwall/z_bg_breakwall.c | 2 +- .../ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c | 18 ++--- .../ovl_Bg_Gnd_Iceblock/z_bg_gnd_iceblock.c | 8 +-- .../ovl_Bg_Heavy_Block/z_bg_heavy_block.c | 2 +- .../ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c | 4 +- .../ovl_Bg_Ice_Objects/z_bg_ice_objects.c | 6 +- .../z_bg_mori_kaitenkabe.c | 4 +- .../actors/ovl_Bg_Po_Event/z_bg_po_event.c | 4 +- .../z_bg_spot00_hanebasi.c | 2 +- .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 12 ++-- .../overlays/actors/ovl_Boss_Fd/z_boss_fd.c | 12 ++-- .../overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 6 +- .../actors/ovl_Boss_Ganon/z_boss_ganon.c | 32 ++++----- .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 54 +++++++-------- .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 4 +- .../actors/ovl_Boss_Goma/z_boss_goma.c | 14 ++-- .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 12 ++-- .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 8 +-- .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 18 ++--- .../overlays/actors/ovl_Boss_Va/z_boss_va.c | 20 +++--- .../overlays/actors/ovl_Demo_Im/z_demo_im.c | 2 +- .../actors/ovl_Door_Shutter/z_door_shutter.c | 4 +- .../actors/ovl_Door_Warp1/z_door_warp1.c | 6 +- soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c | 4 +- .../ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 10 +-- .../ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c | 12 ++-- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 4 +- .../overlays/actors/ovl_En_Daiku/z_en_daiku.c | 4 +- .../ovl_En_Diving_Game/z_en_diving_game.c | 20 +++--- soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c | 2 +- .../actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c | 8 +-- .../actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c | 6 +- soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c | 8 +-- soh/src/overlays/actors/ovl_En_Du/z_en_du.c | 10 +-- soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c | 2 +- .../actors/ovl_En_Ex_Item/z_en_ex_item.c | 6 +- .../overlays/actors/ovl_En_Fish/z_en_fish.c | 2 +- soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c | 4 +- soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c | 4 +- soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c | 8 +-- soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c | 6 +- soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c | 6 +- .../overlays/actors/ovl_En_GeldB/z_en_geldb.c | 2 +- soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c | 4 +- soh/src/overlays/actors/ovl_En_Go/z_en_go.c | 4 +- soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 8 +-- .../actors/ovl_En_Heishi1/z_en_heishi1.c | 4 +- .../actors/ovl_En_Heishi2/z_en_heishi2.c | 14 ++-- .../actors/ovl_En_Heishi3/z_en_heishi3.c | 4 +- .../actors/ovl_En_Heishi4/z_en_heishi4.c | 4 +- soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c | 4 +- soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c | 4 +- .../actors/ovl_En_Ice_Hono/z_en_ice_hono.c | 2 +- soh/src/overlays/actors/ovl_En_In/z_en_in.c | 4 +- .../actors/ovl_En_Insect/z_en_insect.c | 2 +- .../overlays/actors/ovl_En_Ishi/z_en_ishi.c | 4 +- soh/src/overlays/actors/ovl_En_Js/z_en_js.c | 2 +- .../actors/ovl_En_Kakasi/z_en_kakasi.c | 6 +- .../actors/ovl_En_Kakasi3/z_en_kakasi3.c | 10 +-- soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c | 2 +- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 6 +- soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c | 2 +- soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c | 8 +-- soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c | 4 +- soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c | 2 +- .../actors/ovl_En_Niw_Lady/z_en_niw_lady.c | 10 +-- .../overlays/actors/ovl_En_Ossan/z_en_ossan.c | 8 +-- soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c | 6 +- soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c | 12 ++-- soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c | 2 +- .../ovl_En_Syateki_Man/z_en_syateki_man.c | 4 +- soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c | 18 ++--- .../ovl_En_Takara_Man/z_en_takara_man.c | 4 +- .../overlays/actors/ovl_En_Toryo/z_en_toryo.c | 2 +- .../ovl_En_Wonder_Talk2/z_en_wonder_talk2.c | 4 +- soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c | 8 +-- soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c | 12 ++-- soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c | 8 +-- .../overlays/actors/ovl_Fishing/z_fishing.c | 14 ++-- .../actors/ovl_Item_B_Heart/z_item_b_heart.c | 2 +- .../ovl_Item_Etcetera/z_item_etcetera.c | 4 +- .../actors/ovl_Item_Ocarina/z_item_ocarina.c | 2 +- .../actors/ovl_Item_Shield/z_item_shield.c | 4 +- .../actors/ovl_Obj_Tsubo/z_obj_tsubo.c | 2 +- .../actors/ovl_player_actor/z_player.c | 10 +-- 92 files changed, 359 insertions(+), 360 deletions(-) diff --git a/soh/include/functions.h b/soh/include/functions.h index a0df5ba72..13c755cfe 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -429,7 +429,7 @@ void Actor_MountHorse(PlayState* play, Player* player, Actor* horse); s32 func_8002DEEC(Player* player); void func_8002DF18(PlayState* play, Player* player); s32 func_8002DF38(PlayState* play, Actor* actor, u8 csMode); -s32 func_8002DF54(PlayState* play, Actor* actor, u8 arg2); +s32 Player_SetCsActionWithHaltedActors(PlayState* play, Actor* actor, u8 arg2); void func_8002DF90(DynaPolyActor* dynaActor); void func_8002DFA4(DynaPolyActor* dynaActor, f32 arg1, s16 arg2); s32 Player_IsFacingActor(Actor* actor, s16 angle, PlayState* play); @@ -457,11 +457,11 @@ u32 Actor_TextboxIsClosing(Actor* actor, PlayState* play); s8 func_8002F368(PlayState* play); void Actor_GetScreenPos(PlayState* play, Actor* actor, s16* x, s16* y); u32 Actor_HasParent(Actor* actor, PlayState* play); -// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename func_8002F434 and func_8002F554. +// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename Actor_OfferGetItem and func_8002F554. s32 GiveItemEntryWithoutActor(PlayState* play, GetItemEntry getItemEntry); s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEntry, f32 xzRange, f32 yRange); s32 GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry); -s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange); +s32 Actor_OfferGetItem(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange); void func_8002F554(Actor* actor, PlayState* play, s32 getItemId); void func_8002F580(Actor* actor, PlayState* play); u32 Actor_HasNoParent(Actor* actor, PlayState* play); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index ba432796b..02decd7ba 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -464,7 +464,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* gPlayState->transitionType = TRANS_TYPE_FADE_WHITE; gPlayState->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.nextTransitionType = 2; - func_8002DF54(gPlayState, &player->actor, 8); + Player_SetCsActionWithHaltedActors(gPlayState, &player->actor, 8); } } }); diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index fed5ec639..e4edcc1d3 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -1462,7 +1462,7 @@ s32 func_8002DF38(PlayState* play, Actor* actor, u8 csAction) { return true; } -s32 func_8002DF54(PlayState* play, Actor* actor, u8 csAction) { +s32 Player_SetCsActionWithHaltedActors(PlayState* play, Actor* actor, u8 csAction) { Player* player = GET_PLAYER(play); func_8002DF38(play, actor, csAction); @@ -2084,9 +2084,8 @@ s32 GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemE return GiveItemEntryFromActor(actor, play, getItemEntry, 50.0f, 10.0f); } -// TODO: Rename to GiveItemIdFromActor or similar // If you're doing something for randomizer, you're probably looking for GiveItemEntryFromActor -s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange) { +s32 Actor_OfferGetItem(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange) { Player* player = GET_PLAYER(play); if (!(player->stateFlags1 & @@ -2116,7 +2115,7 @@ s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 // TODO: Rename to GiveItemIdFromActorWithFixedRange or similar // If you're doing something for randomizer, you're probably looking for GiveItemEntryFromActorWithFixedRange void func_8002F554(Actor* actor, PlayState* play, s32 getItemId) { - func_8002F434(actor, play, getItemId, 50.0f, 10.0f); + Actor_OfferGetItem(actor, play, getItemId, 50.0f, 10.0f); } void func_8002F580(Actor* actor, PlayState* play) { diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 90634ea31..b5719d48c 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -6184,14 +6184,14 @@ s32 Camera_Demo5(Camera* camera) { pad = camera->play->state.frames - sDemo5PrevAction12Frame; if (player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) { // holding object over head. - func_8002DF54(camera->play, camera->target, 8); + Player_SetCsActionWithHaltedActors(camera->play, camera->target, 8); } else if (ABS(pad) > 3000) { - func_8002DF54(camera->play, camera->target, 12); + Player_SetCsActionWithHaltedActors(camera->play, camera->target, 12); } else { - func_8002DF54(camera->play, camera->target, 69); + Player_SetCsActionWithHaltedActors(camera->play, camera->target, 69); } } else { - func_8002DF54(camera->play, camera->target, 1); + Player_SetCsActionWithHaltedActors(camera->play, camera->target, 1); } } @@ -6250,7 +6250,7 @@ s32 Camera_Demo6(Camera* camera) { camera->animState++; case 1: if (stateTimers[camera->animState] < anim->animTimer) { - func_8002DF54(camera->play, &camera->player->actor, 8); + Player_SetCsActionWithHaltedActors(camera->play, &camera->player->actor, 8); Actor_GetWorld(&focusPosRot, camFocus); anim->atTarget.x = focusPosRot.pos.x; anim->atTarget.y = focusPosRot.pos.y - 20.0f; @@ -7735,7 +7735,7 @@ void Camera_Finish(Camera* camera) { player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; if (player->csAction != 0) { - func_8002DF54(camera->play, &player->actor, 7); + Player_SetCsActionWithHaltedActors(camera->play, &player->actor, 7); osSyncPrintf("camera: player demo end!!\n"); } diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index da7454961..873a91ec9 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -732,7 +732,7 @@ void func_8001E5C8(EnItem00* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->getItemId != GI_NONE) { if (!Actor_HasParent(&this->actor, play)) { - func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 50.0f, 80.0f); this->unk_15A++; } else { this->getItemId = GI_NONE; diff --git a/soh/src/code/z_onepointdemo.c b/soh/src/code/z_onepointdemo.c index 4224066c1..24a8820af 100644 --- a/soh/src/code/z_onepointdemo.c +++ b/soh/src/code/z_onepointdemo.c @@ -268,7 +268,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor case 2290: { Actor* rideActor = player->rideActor; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); if (rideActor != NULL) { rideActor->freezeTimer = 180; } @@ -279,7 +279,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor func_800C0808(play, camIdx, player, CAM_SET_CS_C); } break; case 5120: - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); csInfo->keyFrames = D_80121314; csInfo->keyFrameCnt = 1; @@ -289,7 +289,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor case 4510: D_8012133C[0].eyeTargetInit = actor->world.pos; D_8012133C[0].eyeTargetInit.y = player->actor.world.pos.y + 40.0f; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); csInfo->keyFrames = D_8012133C; csInfo->keyFrameCnt = 3; @@ -307,7 +307,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor OnePointCutscene_AddVecSphToVec3f(&spB4, &spC0, &spD0); Play_CameraChangeSetting(play, camIdx, CAM_SET_FREE2); Play_CameraSetAtEye(play, camIdx, &spC0, &spB4); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); csCam->roll = 0; csCam->fov = 50.0f; if (csCam->childCamIdx != SUBCAM_FREE) { @@ -321,7 +321,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor if (Rand_ZeroOne() < 0.0f) { D_801213B4[3].eyeTargetInit.x = -D_801213B4[3].eyeTargetInit.x; } - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); csInfo->keyFrames = D_801213B4; csInfo->keyFrameCnt = 5; @@ -374,10 +374,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor Play_CameraSetAtEye(play, camIdx, &spC0, &spB4); csCam->roll = 6; csCam->fov = 75.0f; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); break; case 3040: - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); D_8012151C[0].timerInit = timer - 1; csInfo->keyFrames = D_8012151C; @@ -401,7 +401,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrameCnt = 2; func_800C0808(play, camIdx, player, CAM_SET_CS_C); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); break; case 3010: D_801215BC[0].timerInit = timer; @@ -429,7 +429,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; case 3090: - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); csInfo->keyFrames = D_80121814; csInfo->keyFrameCnt = 4; @@ -445,14 +445,14 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor Play_CameraSetAtEye(play, camIdx, &spC0, &spB4); csCam->roll = 0; csCam->fov = 70.0f; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); break; case 3380: case 3065: csInfo->keyFrames = D_801218B4; csInfo->keyFrameCnt = 2; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); i = Quake_Add(csCam, 1); @@ -464,12 +464,12 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_80121904; csInfo->keyFrameCnt = 2; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; case 3050: Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3); - func_8002DF54(play, &player->actor, 5); + Player_SetCsActionWithHaltedActors(play, &player->actor, 5); OnePointCutscene_SetCsCamPoints(csCam, D_80120304 | 0x2000, D_80120300, D_8012013C, D_8012021C); func_80078884(NA_SE_SY_CORRECT_CHIME); OnePointCutscene_Vec3sToVec3f(&mainCam->at, &D_8012013C[D_801202FC - 2].pos); @@ -498,14 +498,14 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csCam->unk_14C |= 2; csInfo->keyFrameCnt = 2; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; case 3130: csInfo->keyFrames = D_80121A44; csInfo->keyFrameCnt = 12; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); csCam->unk_14C |= 2; break; @@ -636,7 +636,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csCam->roll = 0; csCam->fov = 75.0f; player->actor.shape.rot.y = player->actor.world.rot.y = player->yaw = spD0.yaw + 0x7FFF; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); break; case 3240: D_80121D3C[2].timerInit = timer - 5; @@ -644,12 +644,12 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_80121D3C; csInfo->keyFrameCnt = 3; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; case 6001: Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); Actor_GetWorld(&spA0, actor); if (spA0.pos.z > -750.0f) { OnePointCutscene_SetCsCamPoints(csCam, D_801208E8, D_801208E4, D_801206A0, D_80120820); @@ -680,12 +680,12 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_80121DB4; csInfo->keyFrameCnt = 9; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; case 3310: Play_CameraChangeSetting(play, camIdx, CAM_SET_FIRE_STAIRCASE); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); Play_CopyCamera(play, camIdx, MAIN_CAM); i = Quake_Add(csCam, 1); @@ -718,7 +718,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_80121FBC; csInfo->keyFrameCnt = 4; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); i = Quake_Add(csCam, 3); @@ -745,7 +745,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor D_801220D4[1].eyeTargetInit.y = 80.0f; D_801220D4[1].eyeTargetInit.x = -D_801220D4[1].eyeTargetInit.x; } - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); csInfo->keyFrames = D_801220D4; csInfo->keyFrameCnt = 5; @@ -763,7 +763,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_801222B4; csInfo->keyFrameCnt = 5; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); i = Quake_Add(csCam, 1); @@ -787,7 +787,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_801223CC; csInfo->keyFrameCnt = 6; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); player->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; player->actor.freezeTimer = 90; @@ -801,7 +801,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_801224BC; csInfo->keyFrameCnt = 7; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); i = Quake_Add(csCam, 1); @@ -815,7 +815,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor player->actor.shape.rot.y = player->actor.world.rot.y = player->yaw = 0x3FFC; func_800C0808(play, camIdx, player, CAM_SET_CS_C); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); break; case 4110: csInfo->keyFrames = D_8012269C; @@ -825,7 +825,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; case 4120: - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); D_80122714[1].timerInit = 80; csInfo->keyFrames = D_80122714; csInfo->keyFrameCnt = 4; @@ -843,7 +843,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_801228A4; csInfo->keyFrameCnt = 5; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); Camera_ChangeMode(mainCam, CAM_MODE_NORMAL); func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; @@ -851,7 +851,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_8012296C; csInfo->keyFrameCnt = 4; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); Camera_ChangeMode(mainCam, CAM_MODE_NORMAL); func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; @@ -859,7 +859,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_80122A0C; csInfo->keyFrameCnt = 2; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); Camera_ChangeMode(mainCam, CAM_MODE_NORMAL); func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; @@ -908,11 +908,11 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor csInfo->keyFrames = D_80122C8C; csInfo->keyFrameCnt = 1; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; case 3260: - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); D_80122CB4[1].timerInit = timer - 5; csInfo->keyFrames = D_80122CB4; @@ -921,7 +921,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor func_800C0808(play, camIdx, player, CAM_SET_CS_C); break; case 3261: - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); D_80122D04[1].timerInit = timer - 10; csInfo->keyFrames = D_80122D04; diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 21c45a1ae..cb665999e 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -6159,7 +6159,7 @@ void Interface_Draw(PlayState* play) { gSaveContext.timer2State = 5; gSaveContext.cutsceneIndex = 0; Message_StartTextbox(play, 0x71B0, NULL); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); } else { D_8015FFE6 = 40; gSaveContext.timer2State = 6; diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index d0fc8864f..8b901339f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -305,7 +305,7 @@ void BgBreakwall_Wait(BgBreakwall* this, PlayState* play) { if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &flag)) { Cutscene_SetSegment(play, gDcOpeningCs); gSaveContext.cutsceneTrigger = 1; - func_8002DF54(play, NULL, 0x31); + Player_SetCsActionWithHaltedActors(play, NULL, 0x31); } Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index 542711f81..8e2139aed 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -203,7 +203,7 @@ void BgDyYoseizo_CheckMagicAcquired(BgDyYoseizo* this, PlayState* play) { return; } - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->actionFunc = BgDyYoseizo_ChooseType; } } @@ -211,7 +211,7 @@ void BgDyYoseizo_CheckMagicAcquired(BgDyYoseizo* this, PlayState* play) { void BgDyYoseizo_ChooseType(BgDyYoseizo* this, PlayState* play) { s32 givingReward; - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); // "Mode" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ もうど ☆☆☆☆☆ %d\n" VT_RST, play->msgCtx.ocarinaMode); givingReward = false; @@ -327,12 +327,12 @@ void BgDyYoseizo_SetupSpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) { } Audio_PlayActorSound2(&this->actor, NA_SE_VO_FR_LAUGH_0); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->actionFunc = BgDyYoseizo_SpinGrow_NoReward; } void BgDyYoseizo_SpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) { - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Math_ApproachF(&this->actor.world.pos.y, this->grownHeight, this->heightFraction, 100.0f); Math_ApproachF(&this->scale, 0.035f, this->scaleFraction, 0.005f); Math_ApproachF(&this->heightFraction, 0.8f, 0.1f, 0.02f); @@ -358,7 +358,7 @@ void BgDyYoseizo_SpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) { void BgDyYoseizo_CompleteSpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) { f32 curFrame = this->skelAnime.curFrame; - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); if ((this->frameCount * 1273.0f) <= this->bobTimer) { this->bobTimer = 0.0f; @@ -372,7 +372,7 @@ void BgDyYoseizo_CompleteSpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) { } void BgDyYoseizo_SetupGreetPlayer_NoReward(BgDyYoseizo* this, PlayState* play) { - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); if (play->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC) { this->frameCount = Animation_GetLastFrame(&gGreatFairySittingAnim); @@ -392,7 +392,7 @@ void BgDyYoseizo_SetupGreetPlayer_NoReward(BgDyYoseizo* this, PlayState* play) { } void BgDyYoseizo_GreetPlayer_NoReward(BgDyYoseizo* this, PlayState* play) { - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->bobTimer = this->skelAnime.curFrame * 1273.0f; if ((this->frameCount * 1273.0f) <= this->bobTimer) { @@ -560,7 +560,7 @@ void BgDyYoseizo_Vanish(BgDyYoseizo* this, PlayState* play) { Actor* findOcarinaSpot; if (this->vanishTimer == 0) { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); play->envCtx.unk_BF = 0; findOcarinaSpot = play->actorCtx.actorLists[ACTORCAT_PROP].head; @@ -582,7 +582,7 @@ void BgDyYoseizo_SetupSpinGrow_Reward(BgDyYoseizo* this, PlayState* play) { if (play->csCtx.state != CS_STATE_IDLE) { if ((play->csCtx.npcActions[0] != NULL) && (play->csCtx.npcActions[0]->action == 2)) { this->actor.draw = BgDyYoseizo_Draw; - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->finishedSpinGrow = false; if (play->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC) { diff --git a/soh/src/overlays/actors/ovl_Bg_Gnd_Iceblock/z_bg_gnd_iceblock.c b/soh/src/overlays/actors/ovl_Bg_Gnd_Iceblock/z_bg_gnd_iceblock.c index ae8f9cd05..37ff09efc 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gnd_Iceblock/z_bg_gnd_iceblock.c +++ b/soh/src/overlays/actors/ovl_Bg_Gnd_Iceblock/z_bg_gnd_iceblock.c @@ -241,7 +241,7 @@ void BgGndIceblock_Idle(BgGndIceblock* this, PlayState* play) { if (this->dyna.unk_150 > 0.0f) { BgGndIceblock_SetNextPosition(this); if (Actor_WorldDistXZToPoint(&this->dyna.actor, &this->targetPos) > 1.0f) { - func_8002DF54(play, &this->dyna.actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8); this->actionFunc = BgGndIceblock_Slide; } } @@ -282,7 +282,7 @@ void BgGndIceblock_Fall(BgGndIceblock* this, PlayState* play) { thisx->world.pos.y = thisx->home.pos.y - 100.0f; thisx->world.pos.z = thisx->home.pos.z; if (Player_InCsMode(play)) { - func_8002DF54(play, thisx, 7); + Player_SetCsActionWithHaltedActors(play, thisx, 7); } this->actionFunc = BgGndIceblock_Reset; } @@ -295,7 +295,7 @@ void BgGndIceblock_Hole(BgGndIceblock* this, PlayState* play) { if (Math_StepToF(&thisx->world.pos.y, thisx->home.pos.y - 100.0f, thisx->velocity.y)) { thisx->velocity.y = 0.0f; if (Player_InCsMode(play)) { - func_8002DF54(play, thisx, 7); + Player_SetCsActionWithHaltedActors(play, thisx, 7); } this->actionFunc = BgGndIceblock_Idle; } @@ -319,7 +319,7 @@ void BgGndIceblock_Slide(BgGndIceblock* this, PlayState* play) { switch (BgGndIceblock_NextAction(this)) { case GNDICE_IDLE: this->actionFunc = BgGndIceblock_Idle; - func_8002DF54(play, thisx, 7); + Player_SetCsActionWithHaltedActors(play, thisx, 7); break; case GNDICE_FALL: this->actionFunc = BgGndIceblock_Fall; diff --git a/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c b/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c index 3b2524e79..97ed090a8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c +++ b/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c @@ -370,7 +370,7 @@ void BgHeavyBlock_LiftedUp(BgHeavyBlock* this, PlayState* play) { this->timer++; if (!CVarGetInteger("gFasterHeavyBlockLift", 0)) { - func_8002DF54(play, &player->actor, 8); + Player_SetCsActionWithHaltedActors(play, &player->actor, 8); } // if parent is NULL, link threw it diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c index cae8037c6..3e1fd9d78 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c @@ -138,7 +138,7 @@ void BgHidanDalm_Wait(BgHidanDalm* this, PlayState* play) { this->dyna.actor.world.pos.x += 32.5f * Math_SinS(this->dyna.actor.world.rot.y); this->dyna.actor.world.pos.z += 32.5f * Math_CosS(this->dyna.actor.world.rot.y); - func_8002DF54(play, &this->dyna.actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8); this->dyna.actor.flags |= ACTOR_FLAG_UPDATE_WHILE_CULLED; this->actionFunc = BgHidanDalm_Shrink; this->dyna.actor.bgCheckFlags &= ~2; @@ -159,7 +159,7 @@ void BgHidanDalm_Shrink(BgHidanDalm* this, PlayState* play) { Vec3f pos; if (Math_StepToF(&this->dyna.actor.scale.x, 0.0f, 0.004f)) { - func_8002DF54(play, &this->dyna.actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 7); Actor_Kill(&this->dyna.actor); } diff --git a/soh/src/overlays/actors/ovl_Bg_Ice_Objects/z_bg_ice_objects.c b/soh/src/overlays/actors/ovl_Bg_Ice_Objects/z_bg_ice_objects.c index 1cd91d468..7193d3659 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ice_Objects/z_bg_ice_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Ice_Objects/z_bg_ice_objects.c @@ -126,7 +126,7 @@ void BgIceObjects_CheckPits(BgIceObjects* this, PlayState* play) { thisx->world.pos.y = thisx->home.pos.y - 60.0f; thisx->world.pos.z = thisx->home.pos.z; if (thisx->params != 0) { - func_8002DF54(play, thisx, 7); + Player_SetCsActionWithHaltedActors(play, thisx, 7); } this->actionFunc = BgIceObjects_Reset; } @@ -143,7 +143,7 @@ void BgIceObjects_Idle(BgIceObjects* this, PlayState* play) { BgIceObjects_SetNextTarget(this, play); if (Actor_WorldDistXZToPoint(thisx, &this->targetPos) > 1.0f) { thisx->flags |= ACTOR_FLAG_UPDATE_WHILE_CULLED; - func_8002DF54(play, thisx, 8); + Player_SetCsActionWithHaltedActors(play, thisx, 8); thisx->params = 1; this->actionFunc = BgIceObjects_Slide; } @@ -173,7 +173,7 @@ void BgIceObjects_Slide(BgIceObjects* this, PlayState* play) { thisx->flags &= ~ACTOR_FLAG_UPDATE_WHILE_CULLED; } thisx->params = 0; - func_8002DF54(play, thisx, 7); + Player_SetCsActionWithHaltedActors(play, thisx, 7); Audio_PlayActorSound2(thisx, NA_SE_EV_BLOCK_BOUND); if ((fabsf(thisx->world.pos.x + 1387.0f) < 1.0f) && (fabsf(thisx->world.pos.z + 260.0f) < 1.0f)) { this->actionFunc = BgIceObjects_Stuck; diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c b/soh/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c index 8392e7224..f020a462a 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c @@ -96,7 +96,7 @@ void BgMoriKaitenkabe_Wait(BgMoriKaitenkabe* this, PlayState* play) { this->timer++; if ((this->timer > (28 - CVarGetInteger("gFasterBlockPush", 0) * 4)) && !Player_InCsMode(play)) { BgMoriKaitenkabe_SetupRotate(this); - func_8002DF54(play, &this->dyna.actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8); Math_Vec3f_Copy(&this->lockedPlayerPos, &player->actor.world.pos); push.x = Math_SinS(this->dyna.unk_158); push.y = 0.0f; @@ -130,7 +130,7 @@ void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, PlayState* play) { Math_StepToF(&this->rotSpeed, 0.6f, 0.02f); if (Math_StepToF(&this->rotYdeg, this->rotDirection * 45.0f, this->rotSpeed)) { BgMoriKaitenkabe_SetupWait(this); - func_8002DF54(play, thisx, 7); + Player_SetCsActionWithHaltedActors(play, thisx, 7); if (this->rotDirection > 0.0f) { thisx->home.rot.y += 0x2000; } else { diff --git a/soh/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c b/soh/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c index a2fca0db7..08d4fc773 100644 --- a/soh/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c +++ b/soh/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c @@ -321,7 +321,7 @@ void BgPoEvent_BlockFall(BgPoEvent* this, PlayState* play) { if (firstFall == 0) { firstFall = 1; } else { - func_8002DF54(play, &GET_PLAYER(play)->actor, 7); + Player_SetCsActionWithHaltedActors(play, &GET_PLAYER(play)->actor, 7); } } this->direction = 0; @@ -358,7 +358,7 @@ void BgPoEvent_BlockIdle(BgPoEvent* this, PlayState* play) { if (sBgPoEventPuzzleState == 0x10) { sBgPoEventPuzzleState = 0x40; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_RISING); - func_8002DF54(play, &player->actor, 8); + Player_SetCsActionWithHaltedActors(play, &player->actor, 8); } } else if (this->dyna.unk_150 != 0.0f) { if (this->direction == 0) { diff --git a/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c b/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c index 0fb728661..675bbb3ed 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c @@ -223,7 +223,7 @@ void BgSpot00Hanebasi_Update(Actor* thisx, PlayState* play) { Flags_SetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE); Flags_SetEventChkInf(EVENTCHKINF_DRAWBRIDGE_OPENED_AFTER_ZELDA_FLED); this->actionFunc = BgSpot00Hanebasi_DoNothing; - func_8002DF54(play, &player->actor, 8); + Player_SetCsActionWithHaltedActors(play, &player->actor, 8); play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; gSaveContext.nextCutsceneIndex = 0xFFF1; play->transitionTrigger = TRANS_TRIGGER_START; diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index 30455e8e5..a825f67d7 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -443,7 +443,7 @@ void BossDodongo_IntroCutscene(BossDodongo* this, PlayState* play) { break; case 1: func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Play_ClearAllSubCameras(play); this->cutsceneCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, 0, 1); @@ -470,11 +470,11 @@ void BossDodongo_IntroCutscene(BossDodongo* this, PlayState* play) { } if (this->unk_198 == 110) { - func_8002DF54(play, &this->actor, 9); + Player_SetCsActionWithHaltedActors(play, &this->actor, 9); } if (this->unk_198 == 5) { - func_8002DF54(play, &this->actor, 12); + Player_SetCsActionWithHaltedActors(play, &this->actor, 12); } if (this->unk_198 < 6) { @@ -589,7 +589,7 @@ void BossDodongo_IntroCutscene(BossDodongo* this, PlayState* play) { func_800C08AC(play, this->cutsceneCamera, 0); this->cutsceneCamera = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); BossDodongo_SetupWalk(this); this->unk_1DA = 50; this->unk_1BC = 0; @@ -1535,7 +1535,7 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) { case 0: this->csState = 5; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->cutsceneCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_UNK3); Play_ChangeCameraStatus(play, this->cutsceneCamera, CAM_STAT_ACTIVE); @@ -1850,7 +1850,7 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) { this->csState = 100; Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); if (!IS_BOSS_RUSH) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_CHILD); } else { diff --git a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c index 0d33533ae..72908fd2f 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c @@ -323,7 +323,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) { this->introState = BFD_CS_START; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->introCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->introCamera, CAM_STAT_ACTIVE); @@ -399,7 +399,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) { Math_ApproachF(&this->camData.shake, 2.0f, 1.0f, 0.8 * 0.01f); } if (this->timers[0] == 40) { - func_8002DF54(play, &this->actor, 0x13); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x13); } if (this->timers[0] == 0) { this->introState = BFD_CS_LOOK_GROUND; @@ -428,7 +428,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) { this->timers[0] = 170; this->camData.speedMod = 0.0f; this->camData.accel = 0.0f; - func_8002DF54(play, &this->actor, 0x14); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x14); } break; case BFD_CS_COLLAPSE: @@ -478,7 +478,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) { if (this->timers[3] == 190) { this->camData.atMaxVel.x = this->camData.atMaxVel.y = this->camData.atMaxVel.z = 0.05f; this->platformSignal = VBSIMA_KILL; - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); } if (this->actor.world.pos.y > 120.0f) { this->camData.nextAt = this->actor.world.pos; @@ -546,7 +546,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) { func_800C08AC(play, this->introCamera, 0); this->introState = this->introFlyState = this->introCamera = BFD_CS_NONE; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->actionFunc = BossFd_Wait; this->handoffSignal = FD2_SIGNAL_GROUND; Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE); @@ -854,7 +854,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) { this->work[BFD_CAM_SHAKE_TIMER] = 20; Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_LAND2, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); - func_8002DF54(play, &this->actor, 5); + Player_SetCsActionWithHaltedActors(play, &this->actor, 5); for (i1 = 0; i1 < 15; i1++) { Vec3f sp144 = { 0.0f, 0.0f, 0.0f }; Vec3f sp138 = { 0.0f, 0.0f, 0.0f }; diff --git a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c index fb14c5ebe..2a03f1839 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c @@ -661,7 +661,7 @@ void BossFd2_Death(BossFd2* this, PlayState* play) { case DEATH_START: this->deathState = DEATH_RETREAT; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->deathCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->deathCamera, CAM_STAT_ACTIVE); @@ -754,7 +754,7 @@ void BossFd2_Death(BossFd2* this, PlayState* play) { this->work[FD2_ACTION_STATE]++; this->camData.speedMod = 0.0f; this->camData.accel = 0.02f; - func_8002DF54(play, &bossFd->actor, 1); + Player_SetCsActionWithHaltedActors(play, &bossFd->actor, 1); } } if ((bossFd->work[BFD_ACTION_STATE] == BOSSFD_BONES_FALL) && (bossFd->timers[0] == 5)) { @@ -788,7 +788,7 @@ void BossFd2_Death(BossFd2* this, PlayState* play) { func_800C08AC(play, this->deathCamera, 0); this->deathCamera = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); if (!IS_BOSS_RUSH) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index 97551ca46..b1c45feed 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -564,7 +564,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { this->actor.shape.rot.y = 0; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csCamIndex = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->csCamIndex, CAM_STAT_ACTIVE); @@ -609,7 +609,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { BossGanon_SetIntroCsCamera(this, 1); if (this->csTimer == 10) { - func_8002DF54(play, &this->actor, 5); + Player_SetCsActionWithHaltedActors(play, &this->actor, 5); } if (this->csTimer == 13) { @@ -642,7 +642,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { break; } - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csState = 4; BossGanon_SetIntroCsCamera(this, 2); this->csTimer = 0; @@ -674,7 +674,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { } if (this->csTimer == 10) { - func_8002DF54(play, &this->actor, 0x4B); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4B); } if (this->csTimer == 70) { @@ -740,7 +740,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { this->csState = 9; this->csTimer = 0; - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); sBossGanonZelda->unk_3C8 = 0; this->triforceType = GDF_TRIFORCE_ZELDA; this->fwork[GDF_TRIFORCE_SCALE] = 10.0f; @@ -794,7 +794,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { player->actor.world.pos.z = 20.0f; if (this->csTimer == 20) { - func_8002DF54(play, &this->actor, 0x17); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x17); Interface_ChangeAlpha(11); // show hearts only } @@ -1031,7 +1031,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { } if (this->csTimer == 30) { - func_8002DF54(play, &this->actor, 0x4A); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4A); } if (this->csTimer <= 50) { @@ -1154,7 +1154,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { func_800C08AC(play, this->csCamIndex, 0); this->csState = this->csCamIndex = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); BossGanon_SetupWait(this, play); } @@ -1267,7 +1267,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { switch (this->csState) { case 0: func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csCamIndex = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->csCamIndex, CAM_STAT_ACTIVE); @@ -1510,7 +1510,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BODY_SPARK - SFX_FLAG); if (this->csTimer == 2) { - func_8002DF54(play, &this->actor, 0x39); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39); } if (this->csTimer > 50) { @@ -1552,7 +1552,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { case 100: func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csCamIndex = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->csCamIndex, CAM_STAT_ACTIVE); @@ -1651,11 +1651,11 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { this->csCamAt.z = -135.0f; if (this->csTimer == 5) { - func_8002DF54(play, &this->actor, 0x4C); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4C); } if (this->csTimer == 70) { - func_8002DF54(play, &this->actor, 0x4D); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4D); } if (this->csTimer == 90) { @@ -1754,7 +1754,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { if (this->csTimer == 20) { sBossGanonZelda->unk_3C8 = 5; - func_8002DF54(play, &this->actor, 0x39); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39); } if (this->csTimer == 40) { @@ -1821,7 +1821,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { this->csState = 107; this->csTimer = 0; Message_StartTextbox(play, 0x70D2, NULL); - func_8002DF54(play, &this->actor, 0x39); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39); } break; @@ -1863,7 +1863,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { this->csState = 109; this->csCamIndex = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); Flags_SetSwitch(play, 0x37); } break; diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index ba4a4fbc6..28febacd4 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -228,7 +228,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { objectIdx = Object_GetIndex(&play->objectCtx, OBJECT_GANON_ANIME3); if (Object_IsLoaded(&play->objectCtx, objectIdx)) { func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->unk_39E = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); @@ -306,11 +306,11 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { } if (this->csTimer == 40) { sBossGanon2Zelda->unk_3C8 = 1; - func_8002DF54(play, &this->actor, 0x4E); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4E); } if (this->csTimer == 85) { sBossGanon2Zelda->unk_3C8 = 2; - func_8002DF54(play, &this->actor, 0x4F); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4F); } this->unk_3A4.x = 930.0f; this->unk_3A4.y = 1129.0f; @@ -339,14 +339,14 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { } if (this->csTimer == 20) { sBossGanon2Zelda->unk_3C8 = 3; - func_8002DF54(play, &this->actor, 0x50); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x50); } if (this->csTimer == 55) { this->csState = 4; this->csTimer = 0; this->unk_410.x = 0.0f; sBossGanon2Zelda->unk_3C8 = 4; - func_8002DF54(play, &this->actor, 0x50); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x50); } break; case 4: @@ -363,7 +363,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { func_800C08AC(play, this->unk_39E, 0); this->unk_39E = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->csState = 5; this->csTimer = 0; } @@ -409,7 +409,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { } if (this->csTimer == 30) { sBossGanon2Zelda->unk_3C8 = 5; - func_8002DF54(play, &this->actor, 0x51); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x51); } if (this->csTimer == 50) { this->csTimer = 0; @@ -440,7 +440,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { func_80078884(NA_SE_EV_STONE_BOUND); } if (this->csTimer == 30) { - func_8002DF54(play, &this->actor, 0x52); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x52); } if (this->csTimer == 50) { this->csTimer = 0; @@ -505,7 +505,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->unk_3B0.y = player->actor.world.pos.y; this->unk_3B0.z = player->actor.world.pos.z - 200.0f; if (this->csTimer == 20) { - func_8002DF54(play, &this->actor, 0x1E); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x1E); } if (this->csTimer == 60) { this->unk_3A4.x = (this->actor.world.pos.x + 200.0f) - 154.0f; @@ -593,7 +593,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { SkelAnime_Free(&this->skelAnime, play); SkelAnime_InitFlex(play, &this->skelAnime, &gGanonSkel, NULL, NULL, NULL, 0); BossGanon2_SetObjectSegment(this, play, OBJECT_GANON_ANIME3, false); - func_8002DF54(play, &this->actor, 0x54); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x54); this->unk_314 = 3; // At this point, the actor has Ganon's skeleton but is still playing an animation for Ganondorf. This @@ -657,7 +657,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->actor.world.pos.x += 250; this->actor.world.pos.y = 1886.0f; this->unk_394 = 0.0f; - func_8002DF54(play, &this->actor, 0x53); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x53); this->unk_30C = 5.0f; this->unk_228 = 1.0f; } @@ -742,7 +742,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { if (this->csTimer == 215) { this->csState = 23; this->unk_224 = 0.0f; - func_8002DF54(play, &this->actor, 0x55); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x55); } break; case 23: @@ -762,7 +762,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->unk_3B0.z = player->actor.world.pos.z; if (this->csTimer == 228) { func_80078884(NA_SE_IT_SHIELD_REFLECT_SW); - func_8002DF54(play, &this->actor, 0x56); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x56); func_800A9F6C(0.0f, 0xFF, 0xA, 0x32); } if (this->csTimer >= 229) { @@ -799,7 +799,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { func_80078884(NA_SE_IT_SWORD_SWING); } if (this->csTimer == 25) { - func_8002DF54(play, &this->actor, 0x57); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x57); this->csState = 25; this->csTimer = 0; } @@ -846,7 +846,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { case 27: this->unk_3BC.z = 0.0f; if (this->csTimer == 4) { - func_8002DF54(play, &this->actor, 0x58); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x58); } this->unk_3A4.x = player->actor.world.pos.x - 20.0f; this->unk_3A4.y = player->actor.world.pos.y + 50.0f; @@ -919,7 +919,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { func_800C08AC(play, this->unk_39E, 0); this->unk_39E = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->csState = 0; this->unk_337 = 1; func_808FFDB0(this, play); @@ -1340,7 +1340,7 @@ void func_80900890(BossGanon2* this, PlayState* play) { this->unk_39E = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csState = 1; this->unk_3A4 = sp4C->eye; this->unk_3B0 = sp4C->at; @@ -1388,7 +1388,7 @@ void func_80900890(BossGanon2* this, PlayState* play) { func_800C08AC(play, this->unk_39E, 0); this->unk_39E = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->csState = 3; } break; @@ -1399,7 +1399,7 @@ void func_80900890(BossGanon2* this, PlayState* play) { Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); this->csState = 11; this->unk_334 = 1; - func_8002DF54(play, &this->actor, 0x60); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x60); this->csTimer = 0; case 11: player->actor.world.pos.x = sBossGanon2Zelda->actor.world.pos.x + 50.0f + 10.0f; @@ -1420,7 +1420,7 @@ void func_80900890(BossGanon2* this, PlayState* play) { func_800C08AC(play, this->unk_39E, 0); this->unk_39E = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); } break; } @@ -1536,7 +1536,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { this->unk_39E = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csState = 1; this->csTimer = 0; sBossGanon2Zelda->unk_3C8 = 9; @@ -1572,7 +1572,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { this->skelAnime.playSpeed = 3.0f; } if (this->csTimer == 120) { - func_8002DF54(play, &this->actor, 0x63); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x63); } this->actor.world.rot.y = 0x4000; this->actor.world.pos.x = this->actor.world.pos.z = 0.0f; @@ -1640,7 +1640,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { this->csState = 5; this->csTimer = 40; this->skelAnime.playSpeed = 1.0f; - func_8002DF54(play, &this->actor, 0x64); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x64); } break; case 5: @@ -1654,10 +1654,10 @@ void func_8090120C(BossGanon2* this, PlayState* play) { Math_ApproachZeroF(&this->unk_38C, 1.0f, 8.0f); } if (this->csTimer == 70) { - func_8002DF54(play, &this->actor, 0x65); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x65); } if (this->csTimer == 150) { - func_8002DF54(play, &this->actor, 0x66); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x66); } this->unk_30C = 10.0f; player->actor.world.pos.x = 250.0f; @@ -1676,7 +1676,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { func_800C08AC(play, this->unk_39E, 0); this->unk_39E = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->csState = 6; } break; @@ -1764,7 +1764,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { if (this->csTimer == 55) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonDeadStartAnim, 0.0f); this->unk_194 = Animation_GetLastFrame(&gGanonDeadStartAnim); - func_8002DF54(play, &this->actor, 0x62); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x62); this->csState = 8; this->csTimer = 1000; } diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index 111380f0b..82fe2c131 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -926,7 +926,7 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) { switch (this->deathState) { case DEATH_START: func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->deathCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); osSyncPrintf("7\n"); @@ -1104,7 +1104,7 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) { func_800C08AC(play, this->deathCamera, 0); this->deathCamera = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); if (!IS_BOSS_RUSH) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y, GND_BOSSROOM_CENTER_Z + 200.0f, 0, 0, 0, 0, true); diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index 6de72fd2d..489350ad0 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -628,7 +628,7 @@ void BossGoma_SetupEncounterState4(BossGoma* this, PlayState* play) { this->actionState = 4; this->actor.flags |= ACTOR_FLAG_TARGETABLE; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->subCameraId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, 0, 3); Play_ChangeCameraStatus(play, this->subCameraId, 7); @@ -685,7 +685,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_SHUTTER, 164.72f, -480.0f, 397.68002f, 0, -0x705C, 0, 0x180); } else { - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->actionState = 1; } } @@ -756,7 +756,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) { } if (this->frameCount == 190) { - func_8002DF54(play, &this->actor, 2); + Player_SetCsActionWithHaltedActors(play, &this->actor, 2); } if (this->frameCount >= 228) { @@ -767,7 +767,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) { func_800C08AC(play, this->subCameraId, 0); this->subCameraId = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->actionState = 3; } break; @@ -964,7 +964,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) { this->disableGameplayLogic = false; this->patienceTimer = 200; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); } break; } @@ -1054,7 +1054,7 @@ void BossGoma_Defeated(BossGoma* this, PlayState* play) { case 0: this->actionState = 1; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->subCameraId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, 0, 3); Play_ChangeCameraStatus(play, this->subCameraId, 7); @@ -1189,7 +1189,7 @@ void BossGoma_Defeated(BossGoma* this, PlayState* play) { func_800C08AC(play, this->subCameraId, 0); this->subCameraId = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); Actor_Kill(&this->actor); } diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index 74684df71..7d82b93a4 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -1249,7 +1249,7 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) { (fabsf(player->actor.world.pos.x - -180.0f) < 40.0f))) { // checks if Link is on one of the four platforms func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->csCamera, CAM_STAT_ACTIVE); @@ -1357,11 +1357,11 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) { Math_ApproachF(&this->actor.speedXZ, sp80, 1.0f, sp78); Math_ApproachF(&this->cameraYawRate, sp7C, 1.0f, 128.0f); if (this->work[MO_TENT_MOVE_TIMER] == 525) { - func_8002DF54(play, &this->actor, 2); + Player_SetCsActionWithHaltedActors(play, &this->actor, 2); } if (this->work[MO_TENT_MOVE_TIMER] > 540) { this->csState = MO_INTRO_REVEAL; - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); sMorphaTent1->drawActor = true; player->actor.world.pos.x = 180.0f; player->actor.world.pos.z = -210.0f; @@ -1468,7 +1468,7 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) { func_800C08AC(play, this->csCamera, 0); this->csState = this->csCamera = MO_BATTLE; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); } break; } @@ -1533,7 +1533,7 @@ void BossMo_DeathCs(BossMo* this, PlayState* play) { switch (this->csState) { case MO_DEATH_START: func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->csCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->csCamera, CAM_STAT_ACTIVE); @@ -1700,7 +1700,7 @@ void BossMo_DeathCs(BossMo* this, PlayState* play) { func_800C08AC(play, this->csCamera, 0); this->csCamera = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); sMorphaTent1->actor.world.pos.y = -1000.0f; } } else { diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index b9f5c6f2c..5b8eef344 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -390,7 +390,7 @@ void BossSst_HeadSetupIntro(BossSst* this, PlayState* play) { player->stateFlags1 |= PLAYER_STATE1_INPUT_DISABLED; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); sCutsceneCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, sCutsceneCamera, CAM_STAT_ACTIVE); @@ -423,7 +423,7 @@ void BossSst_HeadIntro(BossSst* this, PlayState* play) { sHands[LEFT]->actor.flags |= ACTOR_FLAG_TARGETABLE; player->stateFlags1 &= ~PLAYER_STATE1_INPUT_DISABLED; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); sCameraAt.y += 30.0f; sCameraAt.z += 300.0f; Play_CameraSetAtEye(play, sCutsceneCamera, &sCameraAt, &sCameraEye); @@ -1032,7 +1032,7 @@ void BossSst_HeadSetupDeath(BossSst* this, PlayState* play) { Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, sCutsceneCamera, CAM_STAT_ACTIVE); Play_CopyCamera(play, sCutsceneCamera, MAIN_CAM); - func_8002DF54(play, &player->actor, 8); + Player_SetCsActionWithHaltedActors(play, &player->actor, 8); func_80064520(play, &play->csCtx); Math_Vec3f_Copy(&sCameraEye, &GET_ACTIVE_CAM(play)->eye); this->actionFunc = BossSst_HeadDeath; @@ -1194,7 +1194,7 @@ void BossSst_HeadFinish(BossSst* this, PlayState* play) { Play_ChangeCameraStatus(play, sCutsceneCamera, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); Play_ClearCamera(play, sCutsceneCamera); - func_8002DF54(play, &GET_PLAYER(play)->actor, 7); + Player_SetCsActionWithHaltedActors(play, &GET_PLAYER(play)->actor, 7); func_80064534(play, &play->csCtx); Actor_Kill(&this->actor); Actor_Kill(&sHands[LEFT]->actor); diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 9d0a68c38..40f8127cd 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -1466,7 +1466,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) { case 0: this->csState2 = 1; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 0x39); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39); this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, 0, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); @@ -1606,7 +1606,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) { Animation_MorphToPlayOnce(&this->skelAnime, &gTwinrovaIntroAnim, 0.0f); this->workf[ANIM_SW_TGT] = Animation_GetLastFrame(&gTwinrovaIntroAnim); this->timers[0] = 50; - func_8002DF54(play, &this->actor, 2); + Player_SetCsActionWithHaltedActors(play, &this->actor, 2); Audio_PlayActorSound2(&this->actor, NA_SE_EN_TWINROBA_TRANSFORM); Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS); } @@ -1649,7 +1649,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) { } if (this->timers[3] == 19) { - func_8002DF54(play, &this->actor, 5); + Player_SetCsActionWithHaltedActors(play, &this->actor, 5); } if (this->timers[3] == 16) { @@ -1682,7 +1682,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) { this->subCamId = 0; this->csState2 = this->subCamId; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->work[TW_PLLR_IDX] = 0; this->targetPos = sTwinrovaPillarPos[0]; BossTw_TwinrovaSetupFly(this, play); @@ -1762,7 +1762,7 @@ void BossTw_TwinrovaIntroCS(BossTw* this, PlayState* play) { player->actor.world.pos.x = player->actor.world.pos.z = .0f; this->csState2 = 1; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 0x39); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39); this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, 0, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); @@ -2245,7 +2245,7 @@ void BossTw_TwinrovaIntroCS(BossTw* this, PlayState* play) { this->subCamId = 0; this->csState2 = this->subCamId; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); BossTw_SetupWait(this, play); } break; @@ -2666,7 +2666,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) { case 0: this->csState2 = 1; func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, 0, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); @@ -2705,7 +2705,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) { sKoumePtr->actor.world.pos.z = sKotakePtr->actor.world.pos.z; sKoumePtr->work[YAW_TGT] = sKotakePtr->work[YAW_TGT] = sKoumePtr->actor.shape.rot.x = sKotakePtr->actor.shape.rot.x = sKoumePtr->actor.shape.rot.y = sKotakePtr->actor.shape.rot.y = 0; - func_8002DF54(play, &sKoumePtr->actor, 1); + Player_SetCsActionWithHaltedActors(play, &sKoumePtr->actor, 1); sKoumePtr->actor.flags |= ACTOR_FLAG_TARGETABLE; } break; @@ -2793,7 +2793,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) { this->csState2 = 4; this->subCamId = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS_CLEAR); if (!IS_BOSS_RUSH) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index 0e5a95608..77a497e7a 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -657,7 +657,7 @@ void BossVa_Init(Actor* thisx, PlayState* play2) { } else { sCsState = INTRO_CALL_BARI; sDoorState = 100; - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); play->envCtx.screenFillColor[0] = 0xDC; play->envCtx.screenFillColor[1] = 0xDC; play->envCtx.screenFillColor[2] = 0xBE; @@ -799,7 +799,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) { play->envCtx.screenFillColor[1] = 0xDC; play->envCtx.screenFillColor[2] = 0xBE; play->envCtx.screenFillColor[3] = 0xD2; - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); player->actor.world.rot.y = player->actor.shape.rot.y = 0x7FFF; sCsState++; break; @@ -827,7 +827,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) { case INTRO_CLOSE_DOOR: this->timer--; if (this->timer == 0) { - func_8002DF54(play, &this->actor, 2); + Player_SetCsActionWithHaltedActors(play, &this->actor, 2); sCsState++; this->timer = 30; } @@ -842,7 +842,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) { } break; case INTRO_CRACKLE: - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); sCsState++; break; case INTRO_SPAWN_BARI: @@ -973,7 +973,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) { sCameraAtMaxVel = sCameraEyeMaxVel; if (this->timer >= 45000) { play->envCtx.unk_BF = 1; - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); } else if (this->timer >= 35000) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS); } @@ -1030,7 +1030,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) { sCsCamera = 0; func_80064534(play, &play->csCtx); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); sCsState++; Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE); player->actor.shape.rot.y = player->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000; @@ -1550,7 +1550,7 @@ void BossVa_BodyDeath(BossVa* this, PlayState* play) { switch (sCsState) { case DEATH_START: - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); func_80064520(play, &play->csCtx); sCsCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); @@ -1613,7 +1613,7 @@ void BossVa_BodyDeath(BossVa* this, PlayState* play) { 0x28); this->onCeiling = 2; // Not used by body BossVa_SetDeathEnv(play); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); } break; case DEATH_CORE_BURST: @@ -1654,7 +1654,7 @@ void BossVa_BodyDeath(BossVa* this, PlayState* play) { camera->at = sCameraAt; - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); sCsState++; if (!IS_BOSS_RUSH) { @@ -2444,7 +2444,7 @@ void BossVa_BariIntro(BossVa* this, PlayState* play) { switch (sCsState) { case INTRO_LOOK_BARI: if (this->actor.params == BOSSVA_BARI_UPPER_1) { - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); if (Math_SmoothStepToF(&this->actor.world.pos.y, 60.0f, 0.3f, 1.0f, 0.15f) == 0.0f) { this->timer--; if (this->timer == 0) { diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index a06786b2d..1df2325e8 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -880,7 +880,7 @@ void func_80986B2C(PlayState* play) { } play->transitionType = TRANS_TYPE_CIRCLE(TCA_STARBURST, TCC_BLACK, TCS_FAST); play->transitionTrigger = TRANS_TRIGGER_START; - func_8002DF54(play, &player->actor, 8); + Player_SetCsActionWithHaltedActors(play, &player->actor, 8); } } diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index b43089d9e..34c0a0f20 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -560,7 +560,7 @@ void func_80997220(DoorShutter* this, PlayState* play) { this->dyna.actor.velocity.y = 0.0f; if (DoorShutter_SetupDoor(this, play) && !(player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) { DoorShutter_SetupAction(this, func_80997568); - func_8002DF54(play, NULL, 2); + Player_SetCsActionWithHaltedActors(play, NULL, 2); } } @@ -594,7 +594,7 @@ void func_80997528(DoorShutter* this, PlayState* play) { void func_80997568(DoorShutter* this, PlayState* play) { if (this->unk_16F++ > 30) { - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); DoorShutter_SetupDoor(this, play); } } diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index bdb154a92..710c138e2 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -499,7 +499,7 @@ void DoorWarp1_ChildWarpIdle(DoorWarp1* this, PlayState* play) { Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); OnePointCutscene_Init(play, 0x25E7, 999, &this->actor, MAIN_CAM); - func_8002DF54(play, &this->actor, 10); + Player_SetCsActionWithHaltedActors(play, &this->actor, 10); player->unk_450.x = this->actor.world.pos.x; player->unk_450.z = this->actor.world.pos.z; @@ -584,7 +584,7 @@ void DoorWarp1_RutoWarpIdle(DoorWarp1* this, PlayState* play) { if (this->rutoWarpState != WARP_BLUE_RUTO_STATE_INITIAL && DoorWarp1_PlayerInRange(this, play)) { this->rutoWarpState = WARP_BLUE_RUTO_STATE_ENTERED; - func_8002DF54(play, &this->actor, 10); + Player_SetCsActionWithHaltedActors(play, &this->actor, 10); this->unk_1B2 = 1; DoorWarp1_SetupAction(this, func_80999EE0); } @@ -706,7 +706,7 @@ void DoorWarp1_AdultWarpIdle(DoorWarp1* this, PlayState* play) { player = GET_PLAYER(play); OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM); - func_8002DF54(play, &this->actor, 10); + Player_SetCsActionWithHaltedActors(play, &this->actor, 10); player->unk_450.x = this->actor.world.pos.x; player->unk_450.z = this->actor.world.pos.z; this->unk_1B2 = 20; diff --git a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c index 3fe4e2a22..57cb6045e 100644 --- a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -130,7 +130,7 @@ void func_809B0558(EnAni* this, PlayState* play) { Flags_SetItemGetInf(ITEMGETINF_15); } else { if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, true, NULL)) { - func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f); + Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f); } } } @@ -141,7 +141,7 @@ void func_809B05F0(EnAni* this, PlayState* play) { } if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, true, NULL)) { - func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f); + Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index 76c0feac3..2110383a4 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -295,7 +295,7 @@ void EnBomBowMan_RunGame(EnBomBowlMan* this, PlayState* play) { Message_StartTextbox(play, this->actor.textId, NULL); if (this->gameResult == 2) { - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); } this->actionFunc = EnBomBowlMan_HandlePlayChoice; } else { @@ -345,7 +345,7 @@ void EnBomBowlMan_HandlePlayChoice(EnBomBowlMan* this, PlayState* play) { Message_ContinueTextbox(play, this->actor.textId); this->dialogState = TEXT_STATE_EVENT; OnePointCutscene_Init(play, 8010, -99, NULL, MAIN_CAM); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = EnBomBowMan_SetupChooseShowPrize; } } else { @@ -381,11 +381,11 @@ void func_809C41FC(EnBomBowlMan* this, PlayState* play) { Message_ContinueTextbox(play, this->actor.textId); this->dialogState = TEXT_STATE_EVENT; OnePointCutscene_Init(play, 8010, -99, NULL, MAIN_CAM); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = EnBomBowMan_SetupChooseShowPrize; } else { if (this->gameResult == 2) { - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); } this->actionFunc = EnBomBowMan_SetupRunGame; } @@ -509,7 +509,7 @@ void EnBomBowlMan_BeginPlayGame(EnBomBowlMan* this, PlayState* play) { // "Wow" osSyncPrintf(VT_FGCOL(YELLOW) "☆ わー ☆ %d\n" VT_RST, play->bombchuBowlingStatus); - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actionFunc = EnBomBowMan_SetupRunGame; } } diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c index 5c18c52fa..232b096f9 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c @@ -68,7 +68,7 @@ void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play) { if (((fabsf(chuPosDiff.x) < 40.0f) || (BREG(2))) && ((fabsf(chuPosDiff.y) < 40.0f) || (BREG(2))) && ((fabsf(chuPosDiff.z) < 40.0f) || (BREG(2)))) { - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); chu->timer = 1; this->camId = Play_CreateSubCamera(play); @@ -107,7 +107,7 @@ void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play) { Message_StartTextbox(play, this->actor.textId, NULL); this->unk_154 = TEXT_STATE_EVENT; func_80078884(NA_SE_EV_HIT_SOUND); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->status = 1; this->actionFunc = EnBomBowlPit_CameraDollyIn; break; @@ -167,7 +167,7 @@ void EnBomBowlPit_SetupGivePrize(EnBomBowlPit* this, PlayState* play) { Play_ClearCamera(play, this->camId); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = EnBomBowlPit_GivePrize; } } @@ -175,7 +175,7 @@ void EnBomBowlPit_SetupGivePrize(EnBomBowlPit* this, PlayState* play) { void EnBomBowlPit_GivePrize(EnBomBowlPit* this, PlayState* play) { Player* player = GET_PLAYER(play); - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->getItemId = sGetItemIds[this->prizeIndex]; this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; @@ -203,7 +203,7 @@ void EnBomBowlPit_GivePrize(EnBomBowlPit* this, PlayState* play) { player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; this->actor.parent = NULL; if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); } else { GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f); } @@ -216,7 +216,7 @@ void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, PlayState* play) { this->actionFunc = EnBomBowlPit_Reset; } else { if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); } else { GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f); } diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index b2bd6d65c..9869a0621 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -214,7 +214,7 @@ void func_809DF778(EnCow* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = func_809DF730; } else { - func_8002F434(&this->actor, play, GI_MILK, 10000.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 100.0f); } } @@ -223,7 +223,7 @@ void func_809DF7D8(EnCow* this, PlayState* play) { this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; Message_CloseTextbox(play); this->actionFunc = func_809DF778; - func_8002F434(&this->actor, play, GI_MILK, 10000.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index 8df2f8c0b..715a48c37 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -470,7 +470,7 @@ void EnDaiku_InitSubCamera(EnDaiku* this, PlayState* play) { Play_CameraSetAtEye(play, this->subCamId, &this->subCamAt, &this->subCamEye); Play_CameraSetFov(play, this->subCamId, play->mainCamera.fov); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); } void EnDaiku_UpdateSubCamera(EnDaiku* this, PlayState* play) { @@ -507,7 +507,7 @@ void EnDaiku_EscapeSuccess(EnDaiku* this, PlayState* play) { Actor_Kill(&this->actor); } } else { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); } } diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c index df00c3cf5..84ac2749d 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c @@ -138,7 +138,7 @@ s32 EnDivingGame_HasMinigameFinished(EnDivingGame* this, PlayState* play) { Message_StartTextbox(play, this->actor.textId, NULL); this->unk_292 = TEXT_STATE_EVENT; this->allRupeesThrown = this->state = this->phase = this->unk_2A2 = this->grabbedRupeesCounter = 0; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = func_809EE048; return true; } else { @@ -163,7 +163,7 @@ s32 EnDivingGame_HasMinigameFinished(EnDivingGame* this, PlayState* play) { this->unk_292 = TEXT_STATE_EVENT; func_800F5B58(); Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_SILVER_SCALE)) { this->actionFunc = func_809EE96C; } else { @@ -191,7 +191,7 @@ void EnDivingGame_Talk(EnDivingGame* this, PlayState* play) { if (this->unk_292 != TEXT_STATE_DONE) { switch (this->state) { case ENDIVINGGAME_STATE_NOTPLAYING: - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = EnDivingGame_HandlePlayChoice; break; case ENDIVINGGAME_STATE_AWARDPRIZE: @@ -258,7 +258,7 @@ void EnDivingGame_HandlePlayChoice(EnDivingGame* this, PlayState* play) { this->actionFunc = func_809EE048; } else { play->msgCtx.msgMode = MSGMODE_PAUSED; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = func_809EE0FC; } } @@ -270,11 +270,11 @@ void func_809EE048(EnDivingGame* this, PlayState* play) { if (this->unk_292 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play)) { if (this->phase == ENDIVINGGAME_PHASE_ENDED) { Message_CloseTextbox(play); - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actionFunc = func_809EDCB0; } else { play->msgCtx.msgMode = MSGMODE_PAUSED; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = func_809EE0FC; } } @@ -419,7 +419,7 @@ void func_809EE800(EnDivingGame* this, PlayState* play) { func_80088B34(BREG(2) + 50); } func_800F5ACC(NA_BGM_TIMED_MINI_GAME); - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actor.textId = 0x405B; this->unk_292 = TEXT_STATE_EVENT; this->state = ENDIVINGGAME_STATE_PLAYING; @@ -442,7 +442,7 @@ void func_809EE96C(EnDivingGame* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if ((this->unk_292 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play))) { Message_CloseTextbox(play); - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actor.textId = 0x4056; this->unk_292 = TEXT_STATE_EVENT; this->state = ENDIVINGGAME_STATE_AWARDPRIZE; @@ -456,7 +456,7 @@ void func_809EEA00(EnDivingGame* this, PlayState* play) { Message_CloseTextbox(play); this->actor.parent = NULL; if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 90.0f, 10.0f); @@ -471,7 +471,7 @@ void func_809EEA90(EnDivingGame* this, PlayState* play) { this->actionFunc = func_809EEAF8; } else { if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 90.0f, 10.0f); diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index 933f5be2e..6ea9c26e1 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -391,7 +391,7 @@ void func_809EFDD0(EnDns* this, PlayState* play) { GetItemEntry itemEntry = ItemTable_Retrieve(pendingGetItemId); gSaveContext.pendingSale = itemEntry.itemId; gSaveContext.pendingSaleMod = itemEntry.modIndex; - func_8002F434(&this->actor, play, pendingGetItemId, 130.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, pendingGetItemId, 130.0f, 100.0f); } void func_809EFEE8(EnDns* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c b/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c index 2864544c5..401ffbef4 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c @@ -126,7 +126,7 @@ void EnDntJiji_Wait(EnDntJiji* this, PlayState* play) { !(player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) { OnePointCutscene_Init(play, 2230, -99, &this->actor, MAIN_CAM); this->timer = 0; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = EnDntJiji_SetupUnburrow; } } @@ -260,9 +260,9 @@ void EnDntJiji_Talk(EnDntJiji* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { func_8005B1A4(GET_ACTIVE_CAM(play)); Message_CloseTextbox(play); - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actor.parent = NULL; - func_8002F434(&this->actor, play, this->getItemId, 400.0f, 200.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 400.0f, 200.0f); this->actionFunc = EnDntJiji_SetupGivePrize; } } @@ -272,7 +272,7 @@ void EnDntJiji_SetupGivePrize(EnDntJiji* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actionFunc = EnDntJiji_GivePrize; } else { - func_8002F434(&this->actor, play, this->getItemId, 400.0f, 200.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 400.0f, 200.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c b/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c index f3dff79fe..f96c93695 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c @@ -256,7 +256,7 @@ void EnDntNomal_TargetWait(EnDntNomal* this, PlayState* play) { this->actionFunc = EnDntNomal_TargetGivePrize; } else { OnePointCutscene_Init(play, 4140, -99, &this->actor, MAIN_CAM); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->timer4 = 50; this->actionFunc = EnDntNomal_SetupTargetUnburrow; } @@ -346,7 +346,7 @@ void EnDntNomal_TargetTalk(EnDntNomal* this, PlayState* play) { Message_CloseTextbox(play); func_8005B1A4(GET_ACTIVE_CAM(play)); GET_ACTIVE_CAM(play)->csId = 0; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = EnDntNomal_SetupTargetGivePrize; } } @@ -368,7 +368,7 @@ void EnDntNomal_TargetGivePrize(EnDntNomal* this, PlayState* play) { if (Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_EX_ITEM, itemX, itemY, itemZ, 0, 0, 0, EXITEM_BULLET_BAG) == NULL) { - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); Actor_Kill(&this->actor); } this->spawnedItem = true; diff --git a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c index d3a0eadea..e94ff9039 100644 --- a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c +++ b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c @@ -95,7 +95,7 @@ void EnDs_GiveOddPotion(EnDs* this, PlayState* play) { this->actionFunc = EnDs_DisplayOddPotionText; gSaveContext.timer2State = 0; } else { - func_8002F434(&this->actor, play, GI_ODD_POTION, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_ODD_POTION, 10000.0f, 50.0f); } } @@ -105,7 +105,7 @@ void EnDs_TalkAfterBrewOddPotion(EnDs* this, PlayState* play) { this->actionFunc = EnDs_GiveOddPotion; u32 itemId = GI_ODD_POTION; if (GameInteractor_Should(GI_VB_TRADE_ODD_MUSHROOM, true, this)) { - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, itemId, 10000.0f, 50.0f); } } } @@ -178,7 +178,7 @@ void EnDs_GiveBluePotion(EnDs* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = EnDs_Talk; } else { - func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); } } @@ -200,7 +200,7 @@ void EnDs_OfferBluePotion(EnDs* this, PlayState* play) { if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) { GetItemEntry itemEntry = ItemTable_Retrieve(GI_POTION_BLUE); - func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); gSaveContext.pendingSale = itemEntry.itemId; gSaveContext.pendingSaleMod = itemEntry.modIndex; } diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c index 9f5ba2b0a..781c09f79 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c @@ -362,7 +362,7 @@ void func_809FE3C0(EnDu* this, PlayState* play) { return; } if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } if (this->actor.xzDistToPlayer < 116.0f + this->collider.dim.radius) { @@ -476,7 +476,7 @@ void func_809FE890(EnDu* this, PlayState* play) { CsCmdActorAction* csAction; if (play->csCtx.state == CS_STATE_IDLE) { - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); EnDu_SetupAction(this, func_809FEB08); return; } @@ -549,7 +549,7 @@ void func_809FEB08(EnDu* this, PlayState* play) { this->unk_1EE = 0; if (this->unk_1E8 == 1) { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENDU_ANIM_1); EnDu_SetupAction(this, func_809FE3C0); return; @@ -569,7 +569,7 @@ void func_809FEB08(EnDu* this, PlayState* play) { void func_809FEC14(EnDu* this, PlayState* play) { if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); EnDu_SetupAction(this, func_809FEC70); func_809FEC70(this, play); } @@ -582,7 +582,7 @@ void func_809FEC70(EnDu* this, PlayState* play) { } else { f32 xzRange = this->actor.xzDistToPlayer + 1.0f; - func_8002F434(&this->actor, play, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); + Actor_OfferGetItem(&this->actor, play, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c index f996fe6c1..e08e794a3 100644 --- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -677,7 +677,7 @@ void func_80A0329C(EnElf* this, PlayState* play) { if (!(this->fairyFlags & FAIRY_FLAG_BIG)) { // GI_MAX in this case allows the player to catch the actor in a bottle - func_8002F434(&this->actor, play, GI_MAX, 80.0f, 60.0f); + Actor_OfferGetItem(&this->actor, play, GI_MAX, 80.0f, 60.0f); } } } diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index a3a196e31..03b343527 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -400,7 +400,7 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, PlayState* play) { s32 getItemId; this->actor.draw = NULL; - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actor.parent = NULL; if (IS_RANDO) { GET_PLAYER(play)->stateFlags1 &= ~(PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD); @@ -415,7 +415,7 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, PlayState* play) { } if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f); } else { GiveItemEntryFromActor(&this->actor, play, getItemEntry, 2000.0f, 1000.0f); } @@ -429,7 +429,7 @@ void EnExItem_TargetPrizeGive(EnExItem* this, PlayState* play) { } else { if (!IS_RANDO) { s32 getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40; - func_8002F434(&this->actor, play, getItemId, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 2000.0f, 1000.0f); diff --git a/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c b/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c index e777d993f..1bd8e3202 100644 --- a/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c +++ b/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c @@ -716,7 +716,7 @@ void EnFish_OrdinaryUpdate(EnFish* this, PlayState* play) { EnFish_BeginRespawn(this); } else if (EnFish_InBottleRange(this, play)) { // GI_MAX in this case allows the player to catch the actor in a bottle - func_8002F434(&this->actor, play, GI_MAX, 80.0f, 20.0f); + Actor_OfferGetItem(&this->actor, play, GI_MAX, 80.0f, 20.0f); } } } diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c index d8ef93a6e..646fc5668 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -1020,7 +1020,7 @@ void EnFr_Deactivate(EnFr* this, PlayState* play) { } else { this->actionFunc = EnFr_GiveReward; if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { - func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, this->reward, 30.0f, 100.0f); } } } @@ -1030,7 +1030,7 @@ void EnFr_GiveReward(EnFr* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = EnFr_SetIdle; } else { - func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, this->reward, 30.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c index 53c149026..fb37cf0af 100644 --- a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c +++ b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c @@ -360,7 +360,7 @@ void func_80A2FA50(EnGb* this, PlayState* play) { void func_80A2FB40(EnGb* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE && Message_ShouldAdvance(play)) { if (!IS_RANDO) { - func_8002F434(&this->dyna.actor, play, GI_BOTTLE, 100.0f, 10.0f); + Actor_OfferGetItem(&this->dyna.actor, play, GI_BOTTLE, 100.0f, 10.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE); GiveItemEntryFromActor(&this->dyna.actor, play, getItemEntry, 100.0f, 10.0f); @@ -375,7 +375,7 @@ void func_80A2FBB0(EnGb* this, PlayState* play) { this->actionFunc = func_80A2FC0C; } else { if (!IS_RANDO) { - func_8002F434(&this->dyna.actor, play, GI_BOTTLE, 100.0f, 10.0f); + Actor_OfferGetItem(&this->dyna.actor, play, GI_BOTTLE, 100.0f, 10.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE); GiveItemEntryFromActor(&this->dyna.actor, play, getItemEntry, 100.0f, 10.0f); diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index 92a768205..c72205b8f 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -281,7 +281,7 @@ void EnGe1_KickPlayer(EnGe1* this, PlayState* play) { void EnGe1_SpotPlayer(EnGe1* this, PlayState* play) { this->cutsceneTimer = 30; this->actionFunc = EnGe1_KickPlayer; - func_8002DF54(play, &this->actor, 0x5F); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x5F); func_80078884(NA_SE_SY_FOUND); Message_StartTextbox(play, 0x6000, &this->actor); } @@ -573,7 +573,7 @@ void EnGe1_WaitTillItemGiven_Archery(EnGe1* this, PlayState* play) { } if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, getItemId, 10000.0f, 50.0f); } else { GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } @@ -614,7 +614,7 @@ void EnGe1_BeginGiveItem_Archery(EnGe1* this, PlayState* play) { } if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, getItemId, 10000.0f, 50.0f); } else { GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } @@ -662,7 +662,7 @@ void EnGe1_BeginGame_Archery(EnGe1* this, PlayState* play) { Flags_SetEventChkInf(EVENTCHKINF_PLAYED_HORSEBACK_ARCHERY); if (!(player->stateFlags1 & PLAYER_STATE1_ON_HORSE)) { - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); } else { horse = Actor_FindNearby(play, &player->actor, ACTOR_EN_HORSE, ACTORCAT_BG, 1200.0f); player->actor.freezeTimer = 1200; diff --git a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c index 01e0e0176..5602dd883 100644 --- a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -472,7 +472,7 @@ void EnGe2_WaitTillCardGiven(EnGe2* this, PlayState* play) { this->actionFunc = EnGe2_SetActionAfterTalk; } else { if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); @@ -486,7 +486,7 @@ void EnGe2_GiveCard(EnGe2* this, PlayState* play) { this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; this->actionFunc = EnGe2_WaitTillCardGiven; if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); @@ -510,7 +510,7 @@ void EnGe2_SetupCapturePlayer(EnGe2* this, PlayState* play) { this->stateFlags |= GE2_STATE_CAPTURING; this->actor.speedXZ = 0.0f; EnGe2_ChangeAction(this, GE2_ACTION_CAPTURETURN); - func_8002DF54(play, &this->actor, 95); + Player_SetCsActionWithHaltedActors(play, &this->actor, 95); func_80078884(NA_SE_SY_FOUND); Message_StartTextbox(play, 0x6000, &this->actor); } diff --git a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c index 90d2981f0..aaa198060 100644 --- a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c +++ b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c @@ -145,7 +145,7 @@ void EnGe3_WaitTillCardGiven(EnGe3* this, PlayState* play) { this->actionFunc = EnGe3_Wait; } else { if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); @@ -159,7 +159,7 @@ void EnGe3_GiveCard(EnGe3* this, PlayState* play) { this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; this->actionFunc = EnGe3_WaitTillCardGiven; if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); @@ -172,7 +172,7 @@ void EnGe3_ForceTalk(EnGe3* this, PlayState* play) { this->actionFunc = EnGe3_GiveCard; } else { if (!(this->unk_30C & 4)) { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->unk_30C |= 4; } this->actor.textId = 0x6004; diff --git a/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c b/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c index 4ed0e52ee..293f19669 100644 --- a/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c +++ b/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c @@ -918,7 +918,7 @@ void EnGeldB_SpinAttack(EnGeldB* this, PlayState* play) { if (&player->actor == this->swordCollider.base.at) { func_8002F71C(play, &this->actor, 6.0f, this->actor.yawTowardsPlayer, 6.0f); this->spinAttackState = 2; - func_8002DF54(play, &this->actor, 0x18); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x18); Message_StartTextbox(play, 0x6003, &this->actor); this->timer = 30; this->actor.speedXZ = 0.0f; diff --git a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c index 22754a87a..7174a63f1 100644 --- a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -250,7 +250,7 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) { this->actionFunc = func_80A3DD7C; } else { if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MEDIGORON, true, this)) { - func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); } this->actionFunc = func_80A3DF00; @@ -270,7 +270,7 @@ void func_80A3DF00(EnGm* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = func_80A3DF60; } else { - func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index 3ec88fb74..20d1c5326 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -229,7 +229,7 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { talkState = NPC_TALK_STATE_IDLE; break; case 0x3036: - func_8002F434(thisx, play, GI_TUNIC_GORON, xzRange, yRange); + Actor_OfferGetItem(thisx, play, GI_TUNIC_GORON, xzRange, yRange); Flags_SetInfTable(INFTABLE_10D); // EnGo exclusive flag talkState = NPC_TALK_STATE_ACTION; break; @@ -975,7 +975,7 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { yDist = fabsf(this->actor.yDistToPlayer) + 1.0f; xzDist = this->actor.xzDistToPlayer + 1.0f; - func_8002F434(&this->actor, play, getItemId, xzDist, yDist); + Actor_OfferGetItem(&this->actor, play, getItemId, xzDist, yDist); } } diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 783ada21a..47d1d7b0d 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -284,7 +284,7 @@ s32 EnGo2_SpawnDust(EnGo2* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 void EnGo2_GetItem(EnGo2* this, PlayState* play, s32 getItemId) { this->getItemId = getItemId; if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GORON, true, this)) { - func_8002F434(&this->actor, play, getItemId, this->actor.xzDistToPlayer + 1.0f, + Actor_OfferGetItem(&this->actor, play, getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } } @@ -1799,7 +1799,7 @@ void EnGo2_SetupGetItem(EnGo2* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = EnGo2_SetGetItem; } else { - func_8002F434(&this->actor, play, this->getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } } @@ -1936,7 +1936,7 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { (f32)((Math_SinS(this->actor.world.rot.y) * -30.0f) + this->actor.world.pos.x); player->actor.world.pos.z = (f32)((Math_CosS(this->actor.world.rot.y) * -30.0f) + this->actor.world.pos.z); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); Audio_PlayFanfare(NA_BGM_APPEAR); } break; @@ -1973,7 +1973,7 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { case 4: // Finalize walking away Message_CloseTextbox(play); EnGo2_GoronFireClearCamera(this, play); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); Actor_Kill(&this->actor); break; case 1: diff --git a/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c b/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c index ed924dd3c..5b5a97a08 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c +++ b/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c @@ -391,7 +391,7 @@ void EnHeishi1_WaitNight(EnHeishi1* this, PlayState* play) { Message_StartTextbox(play, 0x702D, &this->actor); func_80078884(NA_SE_SY_FOUND); osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST); // "Discovered!" - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->actionFunc = EnHeishi1_SetupKick; } } @@ -475,7 +475,7 @@ void EnHeishi1_Update(Actor* thisx, PlayState* play) { func_80078884(NA_SE_SY_FOUND); // "Discovered!" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); sHeishi1PlayerIsCaught = true; this->actionFunc = EnHeishi1_SetupMoveToLink; } diff --git a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c index 379ce2893..89dcc6808 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c +++ b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c @@ -112,7 +112,7 @@ void EnHeishi2_Init(Actor* thisx, PlayState* play) { this->actor.world.pos.z += 90.0f; this->actor.shape.rot.y = this->actor.world.rot.y; Collider_DestroyCylinder(play, &this->collider); - func_8002DF54(play, 0, 8); + Player_SetCsActionWithHaltedActors(play, 0, 8); this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED; this->actionFunc = func_80A544AC; } @@ -265,7 +265,7 @@ void func_80A5344C(EnHeishi2* this, PlayState* play) { void func_80A53538(EnHeishi2* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (this->unk_300 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play)) { - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); play->msgCtx.msgMode = MSGMODE_PAUSED; this->actionFunc = func_80A535BC; } @@ -337,7 +337,7 @@ void func_80A53850(EnHeishi2* this, PlayState* play) { Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); Message_CloseTextbox(play); this->unk_30C = 1; - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actionFunc = func_80A531E4; } } @@ -426,7 +426,7 @@ void func_80A53AD4(EnHeishi2* this, PlayState* play) { void func_80A53C0C(EnHeishi2* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if ((this->unk_300 == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) { - func_8002DF54(play, 0, 8); + Player_SetCsActionWithHaltedActors(play, 0, 8); play->msgCtx.msgMode = MSGMODE_PAUSED; this->actionFunc = func_80A53C90; } @@ -510,7 +510,7 @@ void func_80A53F30(EnHeishi2* this, PlayState* play) { this->actionFunc = func_80A54038; } else { Message_CloseTextbox(play); - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actionFunc = func_80A53908; } } else { @@ -528,7 +528,7 @@ void func_80A54038(EnHeishi2* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD); Message_CloseTextbox(play); - func_8002DF54(play, 0, 7); + Player_SetCsActionWithHaltedActors(play, 0, 7); this->actionFunc = func_80A53908; } } @@ -653,7 +653,7 @@ void func_80A5455C(EnHeishi2* this, PlayState* play) { EnBom* bomb; if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); Message_CloseTextbox(play); pos.x = Rand_CenteredFloat(20.0f) + this->unk_274.x; diff --git a/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c b/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c index 3ccc932ca..665a06470 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c +++ b/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c @@ -137,7 +137,7 @@ void EnHeishi3_StandSentinelInGrounds(EnHeishi3* this, PlayState* play) { Message_StartTextbox(play, 0x702D, &this->actor); func_80078884(NA_SE_SY_FOUND); osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST); // "Discovered!" - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->actionFunc = EnHeishi3_CatchStart; } } @@ -165,7 +165,7 @@ void EnHeishi3_StandSentinelInCastle(EnHeishi3* this, PlayState* play) { Message_StartTextbox(play, 0x702D, &this->actor); func_80078884(NA_SE_SY_FOUND); osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST); // "Discovered!" - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->actionFunc = EnHeishi3_CatchStart; } } diff --git a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c index 391d7dc5d..d3b81c3d2 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c +++ b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c @@ -270,7 +270,7 @@ void func_80A56994(EnHeishi4* this, PlayState* play) { if ((this->unk_282 == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); Flags_SetInfTable(INFTABLE_6C); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = func_80A56A50; } } @@ -288,7 +288,7 @@ void func_80A56ACC(EnHeishi4* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (this->unk_288 <= currentFrame) { - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actionFunc = func_80A5673C; } } diff --git a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c index c8d70fe1f..eb3556a6e 100644 --- a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c +++ b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c @@ -162,7 +162,7 @@ void func_80A6E740(EnHs* this, PlayState* play) { Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO); func_80A6E3A0(this, func_80A6E630); } else { - func_8002F434(&this->actor, play, GI_ODD_MUSHROOM, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_ODD_MUSHROOM, 10000.0f, 50.0f); } this->unk_2A8 |= 1; @@ -174,7 +174,7 @@ void func_80A6E7BC(EnHs* this, PlayState* play) { case 0: func_80A6E3A0(this, func_80A6E740); if (GameInteractor_Should(GI_VB_TRADE_COJIRO, true, this)) { - func_8002F434(&this->actor, play, GI_ODD_MUSHROOM, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_ODD_MUSHROOM, 10000.0f, 50.0f); } break; case 1: diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index e0ff7470d..6d8640f3f 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -411,7 +411,7 @@ s32 EnHy_IsOsAnimeObjectLoaded(EnHy* this, PlayState* play) { void func_80A6F7CC(EnHy* this, PlayState* play, s32 getItemId) { this->unkGetItemId = getItemId; - func_8002F434(&this->actor, play, getItemId, this->actor.xzDistToPlayer + 1.0f, + Actor_OfferGetItem(&this->actor, play, getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } @@ -1069,7 +1069,7 @@ void func_80A714C4(EnHy* this, PlayState* play) { this->actionFunc = func_80A71530; } else { if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, this->unkGetItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); + Actor_OfferGetItem(&this->actor, play, this->unkGetItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } else { GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } diff --git a/soh/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c b/soh/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c index f412e7398..3503aef08 100644 --- a/soh/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c +++ b/soh/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c @@ -216,7 +216,7 @@ void EnIceHono_CapturableFlame(EnIceHono* this, PlayState* play) { this->actor.parent = NULL; } else if (EnIceHono_InBottleRange(this, play)) { // GI_MAX in this case allows the player to catch the actor in a bottle - func_8002F434(&this->actor, play, GI_MAX, 60.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, GI_MAX, 60.0f, 100.0f); } if (this->actor.xzDistToPlayer < 200.0f) { diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.c b/soh/src/overlays/actors/ovl_En_In/z_en_in.c index 1d0866e6d..6edf01333 100644 --- a/soh/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.c @@ -434,7 +434,7 @@ void func_80A79BAC(EnIn* this, PlayState* play, s32 index, u32 transitionType) { } play->transitionType = transitionType; play->transitionTrigger = TRANS_TRIGGER_START; - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); Interface_ChangeAlpha(1); if (index == 0) { AREG(6) = 0; @@ -856,7 +856,7 @@ void func_80A7ABD4(EnIn* this, PlayState* play) { void func_80A7AE84(EnIn* this, PlayState* play) { Play_ChangeCameraStatus(play, this->activeCamId, CAM_STAT_ACTIVE); Play_ClearCamera(play, this->camId); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); Interface_ChangeAlpha(0x32); this->actionFunc = func_80A7AEF0; } diff --git a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c index 393e10a91..862b6f92b 100644 --- a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c +++ b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c @@ -786,7 +786,7 @@ void EnInsect_Update(Actor* thisx, PlayState* play) { if (!(this->unk_314 & 8) && D_80A7DEB4 < 4 && EnInsect_InBottleRange(this, play) && // GI_MAX in this case allows the player to catch the actor in a bottle - func_8002F434(&this->actor, play, GI_MAX, 60.0f, 30.0f)) { + Actor_OfferGetItem(&this->actor, play, GI_MAX, 60.0f, 30.0f)) { D_80A7DEB4++; } } diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index af10aa086..c79033250 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -379,9 +379,9 @@ void EnIshi_Wait(EnIshi* this, PlayState* play) { if (this->actor.xzDistToPlayer < 90.0f) { // GI_NONE in these cases allows the player to lift the actor if (type == ROCK_LARGE) { - func_8002F434(&this->actor, play, GI_NONE, 80.0f, 20.0f); + Actor_OfferGetItem(&this->actor, play, GI_NONE, 80.0f, 20.0f); } else { - func_8002F434(&this->actor, play, GI_NONE, 50.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_NONE, 50.0f, 10.0f); } } } diff --git a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c index 793017d3d..1baf3413a 100644 --- a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c +++ b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c @@ -136,7 +136,7 @@ void func_80A89160(EnJs* this, PlayState* play) { GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10); gSaveContext.pendingSale = itemEntry.itemId; gSaveContext.pendingSaleMod = itemEntry.modIndex; - func_8002F434(&this->actor, play, GI_BOMBCHUS_10, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_BOMBCHUS_10, 10000.0f, 50.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c index cf2f4499b..99cc81540 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -260,7 +260,7 @@ void func_80A8F8D0(EnKakasi* this, PlayState* play) { void func_80A8F9C8(EnKakasi* this, PlayState* play) { func_80A8F28C(this); SkelAnime_Update(&this->skelanime); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); if (this->unk_196 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play)) { @@ -269,7 +269,7 @@ void func_80A8F9C8(EnKakasi* this, PlayState* play) { } this->camId = OnePointCutscene_Init(play, 2270, -99, &this->actor, MAIN_CAM); play->msgCtx.msgMode = MSGMODE_PAUSED; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); func_8010BD58(play, OCARINA_ACTION_SCARECROW_LONG_PLAYBACK); this->actionFunc = func_80A8FAA4; } @@ -308,7 +308,7 @@ void func_80A8FBB8(EnKakasi* this, PlayState* play) { if (this->unk_196 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play)) { func_8005B1A4(play->cameraPtrs[this->camId]); Message_CloseTextbox(play); - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actionFunc = func_80A8F660; } } diff --git a/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c b/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c index 37b6236a5..9cb4e5de5 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c @@ -296,7 +296,7 @@ void func_80A91620(EnKakasi3* this, PlayState* play) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_03 && play->msgCtx.msgMode == MSGMODE_NONE) { this->dialogState = TEXT_STATE_EVENT; Message_StartTextbox(play, 0x40A5, NULL); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = func_80A91A90; return; } @@ -354,7 +354,7 @@ void func_80A918E4(EnKakasi3* this, PlayState* play) { this->dialogState = TEXT_STATE_EVENT; OnePointCutscene_EndCutscene(play, this->camId); this->camId = SUBCAM_NONE; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = func_80A91A90; return; } @@ -370,7 +370,7 @@ void func_80A918E4(EnKakasi3* this, PlayState* play) { this->unk_195 = true; Message_StartTextbox(play, 0x40A7, NULL); this->dialogState = TEXT_STATE_EVENT; - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); this->actionFunc = func_80A91A90; return; } @@ -384,7 +384,7 @@ void func_80A918E4(EnKakasi3* this, PlayState* play) { void func_80A91A90(EnKakasi3* this, PlayState* play) { func_80A90E28(this); SkelAnime_Update(&this->skelAnime); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); if (this->dialogState == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play)) { if (this->unk_195) { @@ -400,7 +400,7 @@ void func_80A91A90(EnKakasi3* this, PlayState* play) { } Message_CloseTextbox(play); play->msgCtx.ocarinaMode = OCARINA_MODE_04; - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actionFunc = func_80A911F0; } } diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index c801356c9..4e83742c3 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -1215,7 +1215,7 @@ void func_80A99504(EnKo* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = func_80A99560; } else { - func_8002F434(&this->actor, play, GI_SAW, 120.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_SAW, 120.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 3d5c2c354..9ee9f6d0a 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -396,7 +396,7 @@ void EnKz_SetupMweep(EnKz* this, PlayState* play) { initPos.y += -100.0f; initPos.z += 260.0f; Play_CameraSetAtEye(play, this->cutsceneCamera, &pos, &initPos); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->actor.speedXZ = 0.1f * CVarGetInteger("gMweepSpeed", 1); this->actionFunc = EnKz_Mweep; } @@ -428,7 +428,7 @@ void EnKz_Mweep(EnKz* this, PlayState* play) { void EnKz_StopMweep(EnKz* this, PlayState* play) { Play_ChangeCameraStatus(play, this->gameplayCamera, CAM_STAT_ACTIVE); Play_ClearCamera(play, this->cutsceneCamera); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->actionFunc = EnKz_Wait; } @@ -463,7 +463,7 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; yRange = fabsf(this->actor.yDistToPlayer) + 1.0f; xzRange = this->actor.xzDistToPlayer + 1.0f; - func_8002F434(&this->actor, play, getItemId, xzRange, yRange); + Actor_OfferGetItem(&this->actor, play, getItemId, xzRange, yRange); } } diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index 3edae9858..267a49bcd 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -335,7 +335,7 @@ void func_80AA0EA0(EnMa1* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = func_80AA0EFC; } else { - func_8002F434(&this->actor, play, GI_WEIRD_EGG, 120.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_WEIRD_EGG, 120.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c index eac914089..64510807c 100644 --- a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -102,7 +102,7 @@ void func_80AACA94(EnMk* this, PlayState* play) { gSaveContext.eventInf[1] &= ~1; } } else { - func_8002F434(&this->actor, play, GI_EYEDROPS, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_EYEDROPS, 10000.0f, 50.0f); } } @@ -110,7 +110,7 @@ void func_80AACB14(EnMk* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { this->actionFunc = func_80AACA94; if (GameInteractor_Should(GI_VB_TRADE_FROG, true, this)) { - func_8002F434(&this->actor, play, GI_EYEDROPS, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_EYEDROPS, 10000.0f, 50.0f); } } } @@ -205,7 +205,7 @@ void func_80AACFA0(EnMk* this, PlayState* play) { this->actionFunc = func_80AACA40; Flags_SetItemGetInf(ITEMGETINF_10); } else { - func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); } } @@ -213,7 +213,7 @@ void func_80AAD014(EnMk* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { this->actionFunc = func_80AACFA0; if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_LAB_DIVE, true, this)) { - func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c index 72b84db3b..244be5cde 100644 --- a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c +++ b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c @@ -134,7 +134,7 @@ void EnMs_Talk(EnMs* this, PlayState* play) { } if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN, true, this)) { - func_8002F434(&this->actor, play, GI_BEAN, 90.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_BEAN, 90.0f, 10.0f); this->actionFunc = EnMs_Sell; } return; @@ -152,7 +152,7 @@ void EnMs_Sell(EnMs* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = EnMs_TalkAfterPurchase; } else { - func_8002F434(&this->actor, play, GI_BEAN, 90.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_BEAN, 90.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c b/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c index 91730e5bf..0497b82e9 100644 --- a/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c +++ b/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c @@ -467,7 +467,7 @@ void func_80AB6450(EnNiw* this, PlayState* play) { this->actionFunc = func_80AB6BF8; } else { // GI_NONE in this case allows the player to lift the actor - func_8002F434(&this->actor, play, GI_NONE, 25.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_NONE, 25.0f, 10.0f); func_80AB5BF8(this, play, 1); } } diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index b4e6d8892..612abcf0e 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -314,7 +314,7 @@ void func_80ABA654(EnNiwLady* this, PlayState* play) { if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ANJU_AS_CHILD, true, this)) { this->getItemId = GI_BOTTLE; - func_8002F434(&this->actor, play, GI_BOTTLE, 100.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_BOTTLE, 100.0f, 50.0f); } else { // Circumvent the item offer action this->actionFunc = func_80ABAC84; @@ -327,7 +327,7 @@ void func_80ABA654(EnNiwLady* this, PlayState* play) { } if (this->unk_26C == 1) { this->getItemId = GI_RUPEE_PURPLE; - func_8002F434(&this->actor, play, GI_RUPEE_PURPLE, 100.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_RUPEE_PURPLE, 100.0f, 50.0f); this->actionFunc = func_80ABAC00; } this->actionFunc = func_80ABA244; @@ -405,7 +405,7 @@ void func_80ABA9B8(EnNiwLady* this, PlayState* play) { this->actor.parent = NULL; if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ANJU_AS_ADULT, true, this)) { - func_8002F434(&this->actor, play, GI_POCKET_EGG, 200.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, GI_POCKET_EGG, 200.0f, 100.0f); this->actionFunc = func_80ABAC00; } else { // Circumvent the item offer action @@ -440,7 +440,7 @@ void func_80ABAB08(EnNiwLady* this, PlayState* play) { Message_CloseTextbox(play); this->actor.parent = NULL; if (GameInteractor_Should(GI_VB_TRADE_POCKET_CUCCO, true, this)) { - func_8002F434(&this->actor, play, GI_COJIRO, 200.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, GI_COJIRO, 200.0f, 100.0f); this->actionFunc = func_80ABAC00; } else { // Circumvent the item offer action @@ -471,7 +471,7 @@ void func_80ABAC00(EnNiwLady* this, PlayState* play) { if (LINK_IS_ADULT) { getItemId = !Flags_GetItemGetInf(ITEMGETINF_2C) ? GI_POCKET_EGG : GI_COJIRO; } - func_8002F434(&this->actor, play, getItemId, 200.0f, 100.0f); + Actor_OfferGetItem(&this->actor, play, getItemId, 200.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c b/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c index 34ef24e40..a2c1f5f9a 100644 --- a/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c +++ b/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c @@ -1389,7 +1389,7 @@ void EnOssan_GiveItemWithFanfare(PlayState* play, EnOssan* this) { osSyncPrintf("\n" VT_FGCOL(YELLOW) "初めて手にいれた!!" VT_RST "\n\n"); if (!IS_RANDO) { - func_8002F434(&this->actor, play, this->shelfSlots[this->cursorIndex]->getItemId, 120.0f, 120.0f); + Actor_OfferGetItem(&this->actor, play, this->shelfSlots[this->cursorIndex]->getItemId, 120.0f, 120.0f); } else { ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->cursorIndex); // en_ossan/en_girla are also used for the happy mask shop, which never has randomized items @@ -1398,7 +1398,7 @@ void EnOssan_GiveItemWithFanfare(PlayState* play, EnOssan* this) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(shopItemIdentity.randomizerCheck, shopItemIdentity.ogItemId); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 120.0f, 120.0f); } else { - func_8002F434(&this->actor, play, this->shelfSlots[this->cursorIndex]->getItemId, 120.0f, 120.0f); + Actor_OfferGetItem(&this->actor, play, this->shelfSlots[this->cursorIndex]->getItemId, 120.0f, 120.0f); } } play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; @@ -1736,7 +1736,7 @@ void EnOssan_State_GiveItemWithFanfare(EnOssan* this, PlayState* play, Player* p return; } if (!IS_RANDO) { - func_8002F434(&this->actor, play, this->shelfSlots[this->cursorIndex]->getItemId, 120.0f, 120.0f); + Actor_OfferGetItem(&this->actor, play, this->shelfSlots[this->cursorIndex]->getItemId, 120.0f, 120.0f); } else { ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->cursorIndex); // en_ossan/en_girla are also used for the happy mask shop, which never has randomized items @@ -1746,7 +1746,7 @@ void EnOssan_State_GiveItemWithFanfare(EnOssan* this, PlayState* play, Player* p Randomizer_GetItemFromKnownCheck(shopItemIdentity.randomizerCheck, shopItemIdentity.ogItemId); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 120.0f, 120.0f); } else { - func_8002F434(&this->actor, play, this->shelfSlots[this->cursorIndex]->getItemId, 120.0f, 120.0f); + Actor_OfferGetItem(&this->actor, play, this->shelfSlots[this->cursorIndex]->getItemId, 120.0f, 120.0f); } } } diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 4ae7d366f..d46424b0b 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -345,7 +345,7 @@ void func_80ACA71C(EnOwl* this) { } void func_80ACA76C(EnOwl* this, PlayState* play) { - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); if (Actor_TextboxIsClosing(&this->actor, play)) { Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_FANFARE << 24 | 0xFF); @@ -355,7 +355,7 @@ void func_80ACA76C(EnOwl* this, PlayState* play) { } void func_80ACA7E0(EnOwl* this, PlayState* play) { - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); if (Actor_TextboxIsClosing(&this->actor, play)) { Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_FANFARE << 24 | 0xFF); @@ -565,7 +565,7 @@ void EnOwl_WaitLakeHylia(EnOwl* this, PlayState* play) { } void func_80ACB03C(EnOwl* this, PlayState* play) { - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); if (Actor_TextboxIsClosing(&this->actor, play)) { Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_FANFARE << 24 | 0xFF); diff --git a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c index 5bbeb8efe..344a09f19 100644 --- a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c +++ b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c @@ -1040,7 +1040,7 @@ void EnSkj_SariaSongTalk(EnSkj* this, PlayState* play) { } else { func_80AFFE24(this); if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, true, this)) { - func_8002F434(&this->actor, play, GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); + Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); } } } @@ -1056,7 +1056,7 @@ void func_80AFFE44(EnSkj* this, PlayState* play) { EnSkj_SetupPostSariasSong(this); } else { if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, true, this)) { - func_8002F434(&this->actor, play, GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); + Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); } } } @@ -1080,7 +1080,7 @@ void EnSkj_SetupMaskTrade(EnSkj* this) { void EnSkj_StartMaskTrade(EnSkj* this, PlayState* play) { u8 sp1F = Message_GetState(&play->msgCtx); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); if ((sp1F == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { EnSkj_JumpFromStump(this); } @@ -1178,7 +1178,7 @@ void EnSkj_SetupWaitForMaskTextClear(EnSkj* this) { void EnSkj_WaitForMaskTextClear(EnSkj* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->backflipFlag = 1; EnSkj_Backflip(this); } @@ -1553,7 +1553,7 @@ void EnSkj_WaitToGiveReward(EnSkj* this, PlayState* play) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 26.0f, 26.0f); } else { - func_8002F434(&this->actor, play, sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); + Actor_OfferGetItem(&this->actor, play, sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); } this->actionFunc = EnSkj_GiveOcarinaGameReward; @@ -1569,7 +1569,7 @@ void EnSkj_GiveOcarinaGameReward(EnSkj* this, PlayState* play) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 26.0f, 26.0f); } else { - func_8002F434(&this->actor, play, sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); + Actor_OfferGetItem(&this->actor, play, sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); } } } diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c index 908a1af96..7a0332910 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -302,7 +302,7 @@ void EnSth_GivePlayerItem(EnSth* this, PlayState* play) { } if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, getItemId, 10000.0f, 50.0f); } else { GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index d84298800..a406049a9 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -387,7 +387,7 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) { } } if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, true, this)) { - func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); } this->actionFunc = EnSyatekiMan_GivePrize; break; @@ -421,7 +421,7 @@ void EnSyatekiMan_GivePrize(EnSyatekiMan* this, PlayState* play) { if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, true, this)) { this->actionFunc = EnSyatekiMan_FinishPrize; } else { - func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index d62e6ddfc..85f5053d1 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -707,7 +707,7 @@ void func_80B154FC(EnTa* this, PlayState* play) { switch (EnTa_GetSuperCuccosCount(this, play)) { case 1: gSaveContext.timer1State = 0; - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Message_StartTextbox(play, 0x2084, &this->actor); this->actionFunc = func_80B15424; @@ -749,7 +749,7 @@ void func_80B154FC(EnTa* this, PlayState* play) { this->unk_2E0 &= ~0x200; func_80078884(NA_SE_SY_FOUND); gSaveContext.timer1State = 0; - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Message_StartTextbox(play, 0x2081, &this->actor); this->actionFunc = func_80B15424; func_80B14E28(this, play); @@ -802,7 +802,7 @@ void func_80B1585C(EnTa* this, PlayState* play) { Animation_Change(&this->skelAnime, &gTalonSitWakeUpAnim, 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim) - 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim), ANIMMODE_ONCE, 10.0f); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); } } @@ -817,7 +817,7 @@ void func_80B15AD4(EnTa* this, PlayState* play) { func_800F5ACC(NA_BGM_TIMED_MINI_GAME); this->unk_2E0 |= 0x200; Message_CloseTextbox(play); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); } if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { @@ -877,10 +877,10 @@ void func_80B15E80(EnTa* this, PlayState* play) { } this->unk_2E0 &= ~0x2; } else if (this->unk_2E0 & 2) { - func_8002F434(&this->actor, play, GI_MILK, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 50.0f); } else { if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); @@ -895,7 +895,7 @@ void func_80B15F54(EnTa* this, PlayState* play) { this->unk_2E0 &= ~0x2; func_80B13AA0(this, func_80B15E80, func_80B16938); if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); @@ -923,7 +923,7 @@ void func_80B15FE8(EnTa* this, PlayState* play) { GetItemEntry itemEntry = ItemTable_Retrieve(GI_MILK); gSaveContext.pendingSale = itemEntry.itemId; gSaveContext.pendingSaleMod = itemEntry.modIndex; - func_8002F434(&this->actor, play, GI_MILK, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 50.0f); break; } break; @@ -1014,7 +1014,7 @@ void func_80B1642C(EnTa* this, PlayState* play) { Message_CloseTextbox(play); this->unk_2E0 |= 2; func_80B13AA0(this, func_80B15E80, func_80B16938); - func_8002F434(&this->actor, play, GI_MILK, 10000.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 50.0f); } else { Message_ContinueTextbox(play, 0x208A); func_80B13AA0(this, func_80B15E28, func_80B16938); diff --git a/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c b/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c index f614e0f4c..e15d481fd 100644 --- a/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c +++ b/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c @@ -147,7 +147,7 @@ void func_80B17934(EnTakaraMan* this, PlayState* play) { Rupees_ChangeBy(-10); this->unk_214 = 1; this->actor.parent = NULL; - func_8002F434(&this->actor, play, GI_DOOR_KEY, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, GI_DOOR_KEY, 2000.0f, 1000.0f); this->actionFunc = func_80B17A6C; } else { Message_CloseTextbox(play); @@ -172,7 +172,7 @@ void func_80B17A6C(EnTakaraMan* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actionFunc = func_80B17AC4; } else { - func_8002F434(&this->actor, play, GI_DOOR_KEY, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, GI_DOOR_KEY, 2000.0f, 1000.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index c2ac2861b..275b62ba1 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -317,7 +317,7 @@ void func_80B20768(EnToryo* this, PlayState* play) { this->unk_1E4 = 5; Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW); } else { - func_8002F434(&this->actor, play, GI_SWORD_BROKEN, 100.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_SWORD_BROKEN, 100.0f, 10.0f); } return; } diff --git a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c index 658dd63f8..5aeb0a86b 100644 --- a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c +++ b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c @@ -196,7 +196,7 @@ void func_80B3A3D4(EnWonderTalk2* this, PlayState* play) { } this->actor.flags &= ~(ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED); if (GameInteractor_Should(GI_VB_WONDER_TALK, true, this)) { - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); } this->unk_156 = true; this->actionFunc = func_80B3A4F8; @@ -257,7 +257,7 @@ void func_80B3A4F8(EnWonderTalk2* this, PlayState* play) { if (!this->unk_156) { if (GameInteractor_Should(GI_VB_WONDER_TALK, true, this)) { Message_StartTextbox(play, this->actor.textId, NULL); - func_8002DF54(play, NULL, 8); + Player_SetCsActionWithHaltedActors(play, NULL, 8); } this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED; this->actionFunc = func_80B3A3D4; diff --git a/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c b/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c index 133556f52..7234ed57f 100644 --- a/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c +++ b/soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c @@ -421,7 +421,7 @@ void func_80B4BBC4(EnZl1* this, PlayState* play) { Player* player = GET_PLAYER(play); Animation_Change(&this->skelAnime, &gChildZelda1Anim_00438, 1.0f, 0.0f, frameCount, ANIMMODE_LOOP, 0.0f); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Player_PlaySfx(&player->actor, NA_SE_VO_LI_SURPRISE_KID); this->actor.textId = 0x7039; Message_StartTextbox(play, this->actor.textId, NULL); @@ -510,7 +510,7 @@ void func_80B4BF2C(EnZl1* this, PlayState* play) { if ((Message_GetState(msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { this->actor.textId = 0xFFFF; play->talkWithPlayer(play, &this->actor); - func_8002F434(&this->actor, play, GI_LETTER_ZELDA, 120.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_LETTER_ZELDA, 120.0f, 10.0f); play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; play->msgCtx.stateTimer = 4; this->unk_1E2++; @@ -525,7 +525,7 @@ void func_80B4BF2C(EnZl1* this, PlayState* play) { this->actor.parent = NULL; this->unk_1E2++; } else { - func_8002F434(&this->actor, play, GI_LETTER_ZELDA, 120.0f, 10.0f); + Actor_OfferGetItem(&this->actor, play, GI_LETTER_ZELDA, 120.0f, 10.0f); } break; case 3: @@ -554,7 +554,7 @@ void func_80B4BF2C(EnZl1* this, PlayState* play) { break; case 6: if (Actor_TextboxIsClosing(&this->actor, play)) { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); Interface_ChangeAlpha(50); this->actor.flags &= ~ACTOR_FLAG_PLAYER_TALKED_TO; this->unk_1E2 = 4; diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index f805e2fb5..f2abefd97 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -325,7 +325,7 @@ s32 EnZl4_SetupFromLegendCs(EnZl4* this, PlayState* play) { Actor* playerx = &GET_PLAYER(play)->actor; s16 rotY; - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); playerx->world.pos = this->actor.world.pos; rotY = this->actor.shape.rot.y; playerx->world.pos.x += 56.0f * Math_SinS(rotY); @@ -911,7 +911,7 @@ s32 EnZl4_CsLookWindow(EnZl4* this, PlayState* play) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gZeldasCourtyardGanonCs); gSaveContext.cutsceneTrigger = 1; this->talkState++; - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); } break; case 2: @@ -921,7 +921,7 @@ s32 EnZl4_CsLookWindow(EnZl4* this, PlayState* play) { } } else { func_800AA000(0.0f, 0xA0, 0xA, 0x28); - func_8002DF54(play, &this->actor, 1); + Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_30); EnZl4_SetCsCameraAngle(play, 11); Message_StartTextbox(play, 0x7039, NULL); @@ -1109,7 +1109,7 @@ s32 EnZl4_CsMakePlan(EnZl4* this, PlayState* play) { this->talkState = 7; play->talkWithPlayer(play, &this->actor); if (GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LETTER, true, NULL)) { - func_8002F434(&this->actor, play, GI_LETTER_ZELDA, fabsf(this->actor.xzDistToPlayer) + 1.0f, + Actor_OfferGetItem(&this->actor, play, GI_LETTER_ZELDA, fabsf(this->actor.xzDistToPlayer) + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } play->msgCtx.stateTimer = 4; @@ -1121,7 +1121,7 @@ s32 EnZl4_CsMakePlan(EnZl4* this, PlayState* play) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_0); this->talkState++; } else { - func_8002F434(&this->actor, play, GI_LETTER_ZELDA, fabsf(this->actor.xzDistToPlayer) + 1.0f, + Actor_OfferGetItem(&this->actor, play, GI_LETTER_ZELDA, fabsf(this->actor.xzDistToPlayer) + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } // no break here is required for matching @@ -1189,7 +1189,7 @@ void EnZl4_Cutscene(EnZl4* this, PlayState* play) { break; case ZL4_CS_PLAN: if (EnZl4_CsMakePlan(this, play)) { - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); gSaveContext.unk_13EE = 0x32; Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); this->actionFunc = EnZl4_Idle; diff --git a/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c b/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c index 9212362d6..0601a7f5b 100644 --- a/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c +++ b/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c @@ -153,7 +153,7 @@ void EnfHG_Intro(EnfHG* this, PlayState* play) { break; } func_80064520(play, &play->csCtx); - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); this->cutsceneCamera = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->cutsceneCamera, CAM_STAT_ACTIVE); @@ -193,7 +193,7 @@ void EnfHG_Intro(EnfHG* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_GROAN); } if (this->timers[0] == 20) { - func_8002DF54(play, &this->actor, 9); + Player_SetCsActionWithHaltedActors(play, &this->actor, 9); } if (this->timers[0] == 1) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_OPENING_GANON); @@ -354,7 +354,7 @@ void EnfHG_Intro(EnfHG* this, PlayState* play) { this->bossGndSignal = FHG_FINISH; } if (this->timers[0] == 170) { - func_8002DF54(play, &this->actor, 8); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_MASIC2); } Math_ApproachF(&this->cameraEye.z, this->cameraPanZ + (GND_BOSSROOM_CENTER_Z + 100.0f), 0.1f, @@ -401,7 +401,7 @@ void EnfHG_Intro(EnfHG* this, PlayState* play) { func_800C08AC(play, this->cutsceneCamera, 0); this->cutsceneCamera = 0; func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); this->actionFunc = EnfHG_Retreat; } break; diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index 48d85723e..8b7c77aca 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -5160,7 +5160,7 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) { this->actor.parent = NULL; if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f); } else { GiveItemEntryFromActor(&this->actor, play, getItemEntry, 2000.0f, 1000.0f); } @@ -5215,7 +5215,7 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) { this->stateAndTimer = 24; } else { if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_SCALE_GOLD, 2000.0f, 1000.0f); + Actor_OfferGetItem(&this->actor, play, GI_SCALE_GOLD, 2000.0f, 1000.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 2000.0f, 1000.0f); @@ -5572,7 +5572,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { sSubCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, sSubCamId, CAM_STAT_ACTIVE); - func_8002DF54(play, &this->actor, 5); + Player_SetCsActionWithHaltedActors(play, &this->actor, 5); mainCam = Play_GetCamera(play, MAIN_CAM); sCameraEye.x = mainCam->eye.x; sCameraEye.y = mainCam->eye.y; @@ -5604,7 +5604,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { mainCam->at = sCameraAt; func_800C08AC(play, sSubCamId, 0); func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); sFishingPlayerCinematicState = 0; sSubCamId = 0; sFishingCinematicTimer = 30; @@ -5620,7 +5620,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { sSubCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, sSubCamId, CAM_STAT_ACTIVE); - func_8002DF54(play, &this->actor, 5); + Player_SetCsActionWithHaltedActors(play, &this->actor, 5); mainCam = Play_GetCamera(play, MAIN_CAM); sCameraEye.x = mainCam->eye.x; sCameraEye.y = mainCam->eye.y; @@ -5639,7 +5639,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { if ((sFishingCinematicTimer == 0) && Message_ShouldAdvance(play)) { sFishingPlayerCinematicState = 22; sFishingCinematicTimer = 40; - func_8002DF54(play, &this->actor, 0x1C); + Player_SetCsActionWithHaltedActors(play, &this->actor, 0x1C); sSinkingLureHeldY = 0.0f; } break; @@ -5708,7 +5708,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { mainCam->at = sCameraAt; func_800C08AC(play, sSubCamId, 0); func_80064534(play, &play->csCtx); - func_8002DF54(play, &this->actor, 7); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); sFishingPlayerCinematicState = 0; sSubCamId = 0; player->unk_860 = -5; diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index f511d5bbf..5015a3908 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -59,7 +59,7 @@ void ItemBHeart_Update(Actor* thisx, PlayState* play) { Flags_SetCollectible(play, 0x1F); Actor_Kill(&this->actor); } else { - func_8002F434(&this->actor, play, GI_HEART_CONTAINER_2, 30.0f, 40.0f); + Actor_OfferGetItem(&this->actor, play, GI_HEART_CONTAINER_2, 30.0f, 40.0f); } } diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index b12d7b4b0..6fdf162db 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -134,7 +134,7 @@ void func_80B85824(ItemEtcetera* this, PlayState* play) { Actor_Kill(&this->actor); } else { if (!IS_RANDO) { - func_8002F434(&this->actor, play, this->getItemId, 30.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 30.0f, 50.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 30.0f, 50.0f); @@ -157,7 +157,7 @@ void func_80B858B4(ItemEtcetera* this, PlayState* play) { if (0) {} // Necessary to match if (!IS_RANDO) { - func_8002F434(&this->actor, play, this->getItemId, 30.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, this->getItemId, 30.0f, 50.0f); } else { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); GiveItemEntryFromActor(&this->actor, play, getItemEntry, 30.0f, 50.0f); diff --git a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c index dba879115..d14862553 100644 --- a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c +++ b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c @@ -190,7 +190,7 @@ void ItemOcarina_WaitInWater(ItemOcarina* this, PlayState* play) { this->actor.draw = NULL; } else { if (GameInteractor_Should(GI_VB_GIVE_ITEM_OCARINA_OF_TIME, true, NULL)) { - func_8002F434(&this->actor, play, GI_OCARINA_OOT, 30.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_OCARINA_OOT, 30.0f, 50.0f); } if ((play->gameplayFrames & 13) == 0) { diff --git a/soh/src/overlays/actors/ovl_Item_Shield/z_item_shield.c b/soh/src/overlays/actors/ovl_Item_Shield/z_item_shield.c index e54b343fc..beecbf759 100644 --- a/soh/src/overlays/actors/ovl_Item_Shield/z_item_shield.c +++ b/soh/src/overlays/actors/ovl_Item_Shield/z_item_shield.c @@ -103,7 +103,7 @@ void func_80B86AC8(ItemShield* this, PlayState* play) { Actor_Kill(&this->actor); return; } - func_8002F434(&this->actor, play, GI_SHIELD_DEKU, 30.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_SHIELD_DEKU, 30.0f, 50.0f); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 10.0f, 0.0f, 5); if (this->actor.bgCheckFlags & 1) { this->timer--; @@ -125,7 +125,7 @@ void func_80B86BC8(ItemShield* this, PlayState* play) { Actor_Kill(&this->actor); return; } - func_8002F434(&this->actor, play, GI_SHIELD_DEKU, 30.0f, 50.0f); + Actor_OfferGetItem(&this->actor, play, GI_SHIELD_DEKU, 30.0f, 50.0f); if (this->collider.base.acFlags & AC_HIT) { ItemShield_SetupAction(this, func_80B86AC8); this->actor.velocity.y = 4.0f; diff --git a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c index 2346b34ff..0dd03a5be 100644 --- a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c +++ b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c @@ -274,7 +274,7 @@ void ObjTsubo_Idle(ObjTsubo* this, PlayState* play) { phi_v1 = ABS(temp_v0); if (phi_v1 >= 0x5556) { // GI_NONE in this case allows the player to lift the actor - func_8002F434(&this->actor, play, GI_NONE, 30.0f, 30.0f); + Actor_OfferGetItem(&this->actor, play, GI_NONE, 30.0f, 30.0f); } } } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 2bb2b04fd..7125500f7 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -11477,11 +11477,11 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { CsCmdActorAction* linkActionCsCmd = play->csCtx.linkAction; if ((linkActionCsCmd != NULL) && (D_808547C4[linkActionCsCmd->action] != 0)) { - func_8002DF54(play, NULL, 6); + Player_SetCsActionWithHaltedActors(play, NULL, 6); Player_ZeroSpeedXZ(this); } else if ((this->csAction == 0) && !(this->stateFlags2 & PLAYER_STATE2_UNDERWATER) && (play->csCtx.state != CS_STATE_UNSKIPPABLE_INIT)) { - func_8002DF54(play, NULL, 0x31); + Player_SetCsActionWithHaltedActors(play, NULL, 0x31); Player_ZeroSpeedXZ(this); } } @@ -15342,7 +15342,7 @@ void func_808515A4(PlayState* play, Player* this, CsCmdActorAction* arg2) { void func_80851688(PlayState* play, Player* this, CsCmdActorAction* arg2) { if (func_8084B3CC(play, this) == 0) { if ((this->csAction == 0x31) && (play->csCtx.state == CS_STATE_IDLE)) { - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); return; } @@ -15923,7 +15923,7 @@ void func_80852C50(PlayState* play, Player* this, CsCmdActorAction* arg2) { s32 sp24; if (play->csCtx.state == CS_STATE_UNSKIPPABLE_INIT) { - func_8002DF54(play, NULL, 7); + Player_SetCsActionWithHaltedActors(play, NULL, 7); this->cueId = 0; Player_ZeroSpeedXZ(this); return; @@ -16065,7 +16065,7 @@ void Player_StartTalking(PlayState* play, Actor* actor) { this->exchangeItemId = EXCH_ITEM_NONE; if (actor->textId == 0xFFFF) { - func_8002DF54(play, actor, 1); + Player_SetCsActionWithHaltedActors(play, actor, 1); actor->flags |= ACTOR_FLAG_PLAYER_TALKED_TO; func_80832528(play, this); } else { From d6c512904bee3563dd559682febc8c8a16ba98cc Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 3 Apr 2024 21:11:13 -0400 Subject: [PATCH 16/52] vb target in woods (#95) * do some target in woods VB stuff * skip deku scrub hopping out animation * replace a couple IS_RANDOs * cleanup --- .../game-interactor/GameInteractor.h | 2 + .../Enhancements/randomizer/hook_handlers.cpp | 1 + .../Enhancements/timesaver_hook_handlers.cpp | 8 ++++ .../actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c | 3 +- .../actors/ovl_En_Ex_Item/z_en_ex_item.c | 40 ++++++++----------- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 478f82712..c61a82760 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -290,6 +290,8 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, // Opt: *EnSyatekiMan GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, + // Opt: *EnExItem + GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 35031690e..ea3755a69 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -767,6 +767,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: case GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM: + case GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS: case GI_VB_GIVE_ITEM_FROM_GORON: case GI_VB_GIVE_ITEM_FROM_LAB_DIVE: case GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG: diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 02decd7ba..8e733b427 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -296,6 +296,14 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = false; break; } + case ACTOR_EN_EX_ITEM: { + *should = false; + break; + } + case ACTOR_EN_DNT_NOMAL: { + *should = false; + break; + } case ACTOR_EN_TA: case ACTOR_DOOR_SHUTTER: case ACTOR_BG_ICE_SHUTTER: diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c b/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c index f96c93695..102a904cf 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c @@ -12,6 +12,7 @@ #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "objects/object_hintnuts/object_hintnuts.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -252,7 +253,7 @@ void EnDntNomal_TargetWait(EnDntNomal* this, PlayState* play) { if (!LINK_IS_ADULT && !Flags_GetItemGetInf(ITEMGETINF_1D)) { this->hitCounter++; if (this->hitCounter >= 3) { - if(IS_RANDO) { + if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, &this->actor)) { this->actionFunc = EnDntNomal_TargetGivePrize; } else { OnePointCutscene_Init(play, 4140, -99, &this->actor, MAIN_CAM); diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index 03b343527..32f50d9e1 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -8,6 +8,7 @@ #include "overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -376,7 +377,7 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, PlayState* play) { Math_SmoothStepToS(&this->actor.shape.rot.y, -0x4000, 5, 0x1000, 0); } - if (!IS_RANDO && this->timer != 0) { + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, &this->actor) && this->timer != 0) { if (this->prizeRotateTimer != 0) { tmpf1 = play->view.lookAt.x - play->view.eye.x; tmpf2 = play->view.lookAt.y - 10.0f - play->view.eye.y; @@ -396,50 +397,41 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, PlayState* play) { this->actor.world.pos.z += (tmpf3 / tmpf4) * 5.0f; } } else { - GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; s32 getItemId; this->actor.draw = NULL; Player_SetCsActionWithHaltedActors(play, NULL, 7); this->actor.parent = NULL; - if (IS_RANDO) { + + if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, &this->actor)) { GET_PLAYER(play)->stateFlags1 &= ~(PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD); - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); - getItemId = getItemEntry.getItemId; - } else { - if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) { - getItemId = GI_BULLET_BAG_40; - } else { - getItemId = GI_BULLET_BAG_50; - } } - if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f); + if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) { + getItemId = GI_BULLET_BAG_40; } else { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 2000.0f, 1000.0f); + getItemId = GI_BULLET_BAG_50; } + + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, true, &this->actor)) { + Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f); + } + this->actionFunc = EnExItem_TargetPrizeGive; } } void EnExItem_TargetPrizeGive(EnExItem* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, true, &this->actor)) { this->actionFunc = EnExItem_TargetPrizeFinish; } else { - if (!IS_RANDO) { - s32 getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40; - Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 2000.0f, 1000.0f); - } - + s32 getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40; + Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f); } } void EnExItem_TargetPrizeFinish(EnExItem* this, PlayState* play) { - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, true, &this->actor) || (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { // "Successful completion" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST); Flags_SetItemGetInf(ITEMGETINF_1D); From 2339a729eea09c71d066070e01f6de77a496d510 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 3 Apr 2024 22:10:18 -0400 Subject: [PATCH 17/52] vb deku theater (#96) --- .../Enhancements/randomizer/location_list.cpp | 4 +- .../Enhancements/timesaver_hook_handlers.cpp | 52 ++++++++++++++++++- .../actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c | 23 -------- .../actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h | 2 + 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index c58674bae..0ff2837db 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -618,8 +618,8 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, 0x77, "Deku Scrub Near Bridge", "LW Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), 0x33, "Deku Scrub Grotto Rear", "LW Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), 0x79, "Deku Scrub Grotto Front", "LW Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x77, "Deku Theater Skull Mask", "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, {}, SpoilerCollectionCheck::Chest(0x3E, 0x1F), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x7A, "Deku Theater Mask of Truth", "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, {}, SpoilerCollectionCheck::Chest(0x3E, 0x1E), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x77, "Deku Theater Skull Mask", "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x7A, "Deku Theater Mask of Truth", "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); // Sacred Forest Meadow locationTable[RC_SFM_WOLFOS_GROTTO_CHEST] = Location::Chest(RC_SFM_WOLFOS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, 0x11, "Wolfos Grotto Chest", "SFM Wolfos Grotto Chest", RHT_SFM_WOLFOS_GROTTO_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), 0x39, "Deku Scrub Grotto Rear", "SFM Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 8e733b427..18249e0bf 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -22,6 +22,7 @@ extern "C" { #include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h" #include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h" #include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h" +#include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -87,6 +88,36 @@ void EnZl4_SkipToGivingZeldasLetter(EnZl4* enZl4, PlayState* play) { } } +void EnDntDemo_JudgeSkipToReward(EnDntDemo* enDntDemo, PlayState* play) { + // todo: figure out a better way to handle toggling so we don't + // need to double check cvars like this + if(!(IS_RANDO || CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO))) { + EnDntDemo_Judge(enDntDemo, play); + return; + } + + if (enDntDemo->actor.xzDistToPlayer > 30.0f) { + EnDntDemo_Judge(enDntDemo, play); + return; + } + + Player* player = GET_PLAYER(play); + switch (Player_GetMask(play)) { + case PLAYER_MASK_SKULL: { + Flags_SetItemGetInf(ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE); + return; + } + case PLAYER_MASK_TRUTH: { + Flags_SetItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE); + return; + } + default: { + EnDntDemo_Judge(enDntDemo, play); + return; + } + } +} + static int successChimeCooldown = 0; void RateLimitedSuccessChime() { if (successChimeCooldown == 0) { @@ -304,6 +335,10 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = false; break; } + case ACTOR_EN_DNT_DEMO: { + *should = false; + break; + } case ACTOR_EN_TA: case ACTOR_DOOR_SHUTTER: case ACTOR_BG_ICE_SHUTTER: @@ -769,6 +804,11 @@ void TimeSaverOnActorInitHandler(void* actorRef) { enZl4->actionFunc = EnZl4_SkipToGivingZeldasLetter; } + + if (actor->id == ACTOR_EN_DNT_DEMO && (IS_RANDO || CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO))) { + EnDntDemo* enDntDemo = static_cast(actorRef); + enDntDemo->actionFunc = EnDntDemo_JudgeSkipToReward; + } } void TimeSaverOnSceneInitHandler(int16_t sceneNum) { @@ -949,6 +989,16 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { break; } break; + case FLAG_ITEM_GET_INF: + switch (flag) { + case ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DEKU_STICK_CAPACITY_30).GetGIEntry_Copy(); + break; + case ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DEKU_NUT_CAPACITY_40).GetGIEntry_Copy(); + break; + } + break; } } @@ -1016,4 +1066,4 @@ void TimeSaverRegisterHooks() { onPlayerUpdateHook = GameInteractor::Instance->RegisterGameHook(TimeSaverOnPlayerUpdateHandler); onItemReceiveHook = GameInteractor::Instance->RegisterGameHook(TimeSaverOnItemReceiveHandler); }); -} \ No newline at end of file +} diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c index eb9942fba..d63cb14c8 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c @@ -135,29 +135,6 @@ void EnDntDemo_Judge(EnDntDemo* this, PlayState* play) { this->judgeTimer = 0; } } else { - if (IS_RANDO) { - Player* player = GET_PLAYER(play); - switch (Player_GetMask(play)) { - case PLAYER_MASK_SKULL: - if (!Flags_GetTreasure(play, 0x1F) && !Player_InBlockingCsMode(play, player)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DEKU_THEATER_SKULL_MASK, GI_STICK_UPGRADE_30); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0x1F; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } - break; - case PLAYER_MASK_TRUTH: - if (!Flags_GetTreasure(play, 0x1E) && !Player_InBlockingCsMode(play, player)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DEKU_THEATER_MASK_OF_TRUTH, GI_NUT_UPGRADE_40); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0x1E; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } - break; - } - return; - } - if ((Player_GetMask(play) != 0) && (this->subCamera == SUBCAM_FREE)) { this->subCamera = OnePointCutscene_Init(play, 2220, -99, &this->scrubs[3]->actor, MAIN_CAM); } diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h index 9093d451c..c6b9a7efb 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h +++ b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h @@ -64,4 +64,6 @@ typedef enum { /* 5 */ DNT_ACTION_PRIZE } EnDntAction; +void EnDntDemo_Judge(EnDntDemo* enDntDemo, PlayState* play); + #endif From 249490909f8e8f2a675cd43464f3628bdf3966d7 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Thu, 4 Apr 2024 11:26:48 -0400 Subject: [PATCH 18/52] pull docs: talon function names (#98) --- soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c | 192 ++++++++++---------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index 85f5053d1..d8a0ff554 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -16,21 +16,21 @@ void EnTa_Destroy(Actor* thisx, PlayState* play); void EnTa_Update(Actor* thisx, PlayState* play); void EnTa_Draw(Actor* thisx, PlayState* play); -void func_80B14634(EnTa* this, PlayState* play); -void func_80B146F8(EnTa* this, PlayState* play); -void func_80B14754(EnTa* this, PlayState* play); -void func_80B14C18(EnTa* this, PlayState* play); -void func_80B14CAC(EnTa* this, PlayState* play); -void func_80B14D98(EnTa* this, PlayState* play); -void func_80B154FC(EnTa* this, PlayState* play); -void func_80B16504(EnTa* this, PlayState* play); -void func_80B16608(EnTa* this, PlayState* play); -void func_80B166CC(EnTa* this); -void func_80B16700(EnTa* this); -void func_80B167C0(EnTa* this); -void func_80B167FC(EnTa* this); -void func_80B16854(EnTa* this); -void func_80B16938(EnTa* this); +void EnTa_IdleAsleepInCastle(EnTa* this, PlayState* play); +void EnTa_IdleAsleepInLonLonHouse(EnTa* this, PlayState* play); +void EnTa_IdleAsleepInKakariko(EnTa* this, PlayState* play); +void EnTa_IdleAwakeInCastle(EnTa* this, PlayState* play); +void EnTa_IdleAwakeInKakariko(EnTa* this, PlayState* play); +void EnTa_IdleAtRanch(EnTa* this, PlayState* play); +void EnTa_RunCuccoGame(EnTa* this, PlayState* play); +void EnTa_IdleSittingInLonLonHouse(EnTa* this, PlayState* play); +void EnTa_IdleAfterCuccoGameFinished(EnTa* this, PlayState* play); +void EnTa_BlinkWaitUntilNext(EnTa* this); +void EnTa_BlinkAdvanceState(EnTa* this); +void EnTa_AnimRepeatCurrent(EnTa* this); +void EnTa_AnimSleeping(EnTa* this); +void EnTa_AnimSitSleeping(EnTa* this); +void EnTa_AnimRunToEnd(EnTa* this); const ActorInit En_Ta_InitVars = { ACTOR_EN_TA, @@ -65,7 +65,7 @@ static ColliderCylinderInit sCylinderInit = { { 30, 40, 0, { 0, 0, 0 } }, }; -void func_80B13AA0(EnTa* this, EnTaActionFunc arg1, EnTaUnkFunc arg2) { +void EnTa_SetupAction(EnTa* this, EnTaActionFunc arg1, EnTaUnkFunc arg2) { this->actionFunc = arg1; this->unk_260 = arg2; } @@ -114,7 +114,7 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { this->unk_2CE = 0; this->unk_2E2 = 0; this->blinkTimer = 20; - this->unk_2B0 = func_80B166CC; + this->unk_2B0 = EnTa_BlinkWaitUntilNext; Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; this->actor.velocity.y = -4.0f; @@ -129,12 +129,12 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { } else if (!LINK_IS_ADULT) { Actor_Kill(&this->actor); } else if (Flags_GetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_KAKARIKO)) { - func_80B13AA0(this, func_80B14CAC, func_80B167C0); + EnTa_SetupAction(this, EnTa_IdleAwakeInKakariko, EnTa_AnimRepeatCurrent); this->eyeIndex = 0; Animation_PlayOnce(&this->skelAnime, &gTalonStandAnim); this->currentAnimation = &gTalonStandAnim; } else { - func_80B13AA0(this, func_80B14754, func_80B167FC); + EnTa_SetupAction(this, EnTa_IdleAsleepInKakariko, EnTa_AnimSleeping); this->eyeIndex = 2; Animation_PlayOnce(&this->skelAnime, &gTalonSleepAnim); this->currentAnimation = &gTalonSleepAnim; @@ -151,7 +151,7 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { Actor_Kill(&this->actor); osSyncPrintf(VT_FGCOL(CYAN) " 夜はいない \n" VT_RST); } else { - func_80B13AA0(this, func_80B14D98, func_80B167C0); + EnTa_SetupAction(this, EnTa_IdleAtRanch, EnTa_AnimRepeatCurrent); this->eyeIndex = 0; Animation_PlayOnce(&this->skelAnime, &gTalonStandAnim); this->currentAnimation = &gTalonStandAnim; @@ -163,12 +163,12 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { if (Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)) { Actor_Kill(&this->actor); } else if (Flags_GetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_CASTLE)) { - func_80B13AA0(this, func_80B14C18, func_80B167C0); + EnTa_SetupAction(this, EnTa_IdleAwakeInCastle, EnTa_AnimRepeatCurrent); this->eyeIndex = 0; Animation_PlayOnce(&this->skelAnime, &gTalonStandAnim); this->currentAnimation = &gTalonStandAnim; } else { - func_80B13AA0(this, func_80B14634, func_80B167FC); + EnTa_SetupAction(this, EnTa_IdleAsleepInCastle, EnTa_AnimSleeping); this->eyeIndex = 2; Animation_PlayOnce(&this->skelAnime, &gTalonSleepAnim); this->currentAnimation = &gTalonSleepAnim; @@ -196,19 +196,19 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { func_80B13AAC(this, play); if (gSaveContext.eventInf[0] & 0x400) { - func_80B13AA0(this, func_80B16608, func_80B16938); + EnTa_SetupAction(this, EnTa_IdleAfterCuccoGameFinished, EnTa_AnimRunToEnd); Animation_Change(&this->skelAnime, &gTalonSitWakeUpAnim, 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim) - 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim), ANIMMODE_ONCE, 0.0f); gSaveContext.eventInf[0] &= ~0x400; } else { - func_80B13AA0(this, func_80B16504, func_80B16854); + EnTa_SetupAction(this, EnTa_IdleSittingInLonLonHouse, EnTa_AnimSitSleeping); this->eyeIndex = 0; Animation_PlayOnce(&this->skelAnime, &gTalonSitSleepingAnim); this->currentAnimation = &gTalonSitSleepingAnim; } } else { - func_80B13AA0(this, func_80B146F8, func_80B167FC); + EnTa_SetupAction(this, EnTa_IdleAsleepInLonLonHouse, EnTa_AnimSleeping); this->eyeIndex = 2; Animation_PlayOnce(&this->skelAnime, &gTalonSleepAnim); this->currentAnimation = &gTalonSleepAnim; @@ -216,7 +216,7 @@ void EnTa_Init(Actor* thisx, PlayState* play2) { } } } else { - func_80B13AA0(this, func_80B14634, func_80B167FC); + EnTa_SetupAction(this, EnTa_IdleAsleepInCastle, EnTa_AnimSleeping); this->eyeIndex = 2; Animation_PlayOnce(&this->skelAnime, &gTalonSleepAnim); this->currentAnimation = &gTalonSleepAnim; @@ -265,22 +265,22 @@ s32 func_80B142F4(EnTa* this, PlayState* play, u16 textId) { void func_80B14398(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B13AA0(this, func_80B14754, func_80B167FC); + EnTa_SetupAction(this, EnTa_IdleAsleepInKakariko, EnTa_AnimSleeping); } } void func_80B143D4(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B13AA0(this, func_80B146F8, func_80B167FC); + EnTa_SetupAction(this, EnTa_IdleAsleepInLonLonHouse, EnTa_AnimSleeping); } } void func_80B14410(EnTa* this) { if (!LINK_IS_ADULT) { - func_80B13AA0(this, func_80B14C18, func_80B167C0); + EnTa_SetupAction(this, EnTa_IdleAwakeInCastle, EnTa_AnimRepeatCurrent); Flags_SetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_CASTLE); } else { - func_80B13AA0(this, func_80B14CAC, func_80B167C0); + EnTa_SetupAction(this, EnTa_IdleAwakeInKakariko, EnTa_AnimRepeatCurrent); Flags_SetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_KAKARIKO); } } @@ -297,12 +297,12 @@ void func_80B144D8(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { func_80B14410(this); this->blinkTimer = 1; - this->unk_2B0 = func_80B16700; + this->unk_2B0 = EnTa_BlinkAdvanceState; } if (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) { this->eyeIndex = 1; - func_80B13AA0(this, func_80B1448C, func_80B167C0); + EnTa_SetupAction(this, func_80B1448C, EnTa_AnimRepeatCurrent); } func_80B14248(this); this->unk_2E0 |= 4; @@ -312,7 +312,7 @@ void func_80B14570(EnTa* this, PlayState* play) { this->unk_2E0 |= 4; if (this->unk_2CC == 0) { - func_80B13AA0(this, func_80B144D8, func_80B167C0); + EnTa_SetupAction(this, func_80B144D8, EnTa_AnimRepeatCurrent); this->unk_2CE = 3; this->unk_2CC = 60; Animation_PlayOnce(&this->skelAnime, &gTalonWakeUpAnim); @@ -323,11 +323,11 @@ void func_80B14570(EnTa* this, PlayState* play) { void func_80B145F8(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B13AA0(this, func_80B14634, func_80B167FC); + EnTa_SetupAction(this, EnTa_IdleAsleepInCastle, EnTa_AnimSleeping); } } -void func_80B14634(EnTa* this, PlayState* play) { +void EnTa_IdleAsleepInCastle(EnTa* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Actor_ProcessTalkRequest(&this->actor, play)) { @@ -336,14 +336,14 @@ void func_80B14634(EnTa* this, PlayState* play) { switch (exchangeItemId) { case EXCH_ITEM_CHICKEN: player->actor.textId = 0x702B; - func_80B13AA0(this, func_80B14570, func_80B167C0); + EnTa_SetupAction(this, func_80B14570, EnTa_AnimRepeatCurrent); this->unk_2CC = 40; break; default: if (exchangeItemId != EXCH_ITEM_NONE) { player->actor.textId = 0x702A; } - func_80B13AA0(this, func_80B145F8, func_80B167FC); + EnTa_SetupAction(this, func_80B145F8, EnTa_AnimSleeping); break; } } else { @@ -352,15 +352,15 @@ void func_80B14634(EnTa* this, PlayState* play) { } } -void func_80B146F8(EnTa* this, PlayState* play) { +void EnTa_IdleAsleepInLonLonHouse(EnTa* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { - func_80B13AA0(this, func_80B143D4, func_80B167FC); + EnTa_SetupAction(this, func_80B143D4, EnTa_AnimSleeping); } this->actor.textId = 0x204B; func_8002F2CC(&this->actor, play, 100.0f); } -void func_80B14754(EnTa* this, PlayState* play) { +void EnTa_IdleAsleepInKakariko(EnTa* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Actor_ProcessTalkRequest(&this->actor, play)) { @@ -369,14 +369,14 @@ void func_80B14754(EnTa* this, PlayState* play) { switch (exchangeItemId) { case EXCH_ITEM_POCKET_CUCCO: player->actor.textId = 0x702B; - func_80B13AA0(this, func_80B14570, func_80B167C0); + EnTa_SetupAction(this, func_80B14570, EnTa_AnimRepeatCurrent); this->unk_2CC = 40; break; default: if (exchangeItemId != EXCH_ITEM_NONE) { player->actor.textId = 0x5015; } - func_80B13AA0(this, func_80B14398, func_80B167FC); + EnTa_SetupAction(this, func_80B14398, EnTa_AnimSleeping); break; } } else { @@ -411,7 +411,7 @@ void func_80B1490C(EnTa* this, PlayState* play) { this->actor.shape.rot.y += 0xC00; if (this->unk_2CC == 0) { - func_80B13AA0(this, func_80B14898, func_80B167C0); + EnTa_SetupAction(this, func_80B14898, EnTa_AnimRepeatCurrent); this->unk_2CC = 60; } } @@ -421,7 +421,7 @@ void func_80B1496C(EnTa* this, PlayState* play) { func_80B14818(this, play); if (this->unk_2CC == 0) { - func_80B13AA0(this, func_80B1490C, func_80B167C0); + EnTa_SetupAction(this, func_80B1490C, EnTa_AnimRepeatCurrent); this->unk_2CC = 5; } } @@ -431,7 +431,7 @@ void func_80B149F4(EnTa* this, PlayState* play) { this->actor.shape.rot.y -= 0xD00; if (this->unk_2CC == 0) { - func_80B13AA0(this, func_80B1496C, func_80B167C0); + EnTa_SetupAction(this, func_80B1496C, EnTa_AnimRepeatCurrent); this->unk_2CC = 65; } } @@ -445,7 +445,7 @@ void func_80B14A54(EnTa* this, PlayState* play) { } if (this->unk_2CC == 0) { this->unk_2CC = 5; - func_80B13AA0(this, func_80B149F4, func_80B167C0); + EnTa_SetupAction(this, func_80B149F4, EnTa_AnimRepeatCurrent); } } @@ -455,7 +455,7 @@ void func_80B14AF4(EnTa* this, PlayState* play) { if (this->unk_2CC == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_VO_TA_CRY_1); - func_80B13AA0(this, func_80B14A54, func_80B167C0); + EnTa_SetupAction(this, func_80B14A54, EnTa_AnimRepeatCurrent); this->unk_2CC = 65; this->actor.flags |= ACTOR_FLAG_UPDATE_WHILE_CULLED; } @@ -464,7 +464,7 @@ void func_80B14AF4(EnTa* this, PlayState* play) { void func_80B14B6C(EnTa* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) { s16 csCamIdx = OnePointCutscene_Init(play, 4175, -99, &this->actor, MAIN_CAM); - func_80B13AA0(this, func_80B14AF4, func_80B167C0); + EnTa_SetupAction(this, func_80B14AF4, EnTa_AnimRepeatCurrent); this->unk_2CC = 5; Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE); if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { @@ -476,42 +476,42 @@ void func_80B14B6C(EnTa* this, PlayState* play) { this->unk_2E0 |= 1; } -void func_80B14C18(EnTa* this, PlayState* play) { +void EnTa_IdleAwakeInCastle(EnTa* this, PlayState* play) { if (func_80B142F4(this, play, 0x702C)) { - func_80B13AA0(this, func_80B14B6C, func_80B167C0); + EnTa_SetupAction(this, func_80B14B6C, EnTa_AnimRepeatCurrent); } func_80B14248(this); } void func_80B14C60(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B13AA0(this, func_80B14CAC, func_80B167C0); + EnTa_SetupAction(this, EnTa_IdleAwakeInKakariko, EnTa_AnimRepeatCurrent); } this->unk_2E0 |= 1; } -void func_80B14CAC(EnTa* this, PlayState* play) { +void EnTa_IdleAwakeInKakariko(EnTa* this, PlayState* play) { if (Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED)) { if (func_80B142F4(this, play, 0x5017)) { - func_80B13AA0(this, func_80B14C60, func_80B167C0); + EnTa_SetupAction(this, func_80B14C60, EnTa_AnimRepeatCurrent); Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_KAKARIKO); } } else if (func_80B142F4(this, play, 0x5016)) { - func_80B13AA0(this, func_80B14C60, func_80B167C0); + EnTa_SetupAction(this, func_80B14C60, EnTa_AnimRepeatCurrent); } func_80B14248(this); } void func_80B14D4C(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B13AA0(this, func_80B14D98, func_80B167C0); + EnTa_SetupAction(this, EnTa_IdleAtRanch, EnTa_AnimRepeatCurrent); } this->unk_2E0 |= 1; } -void func_80B14D98(EnTa* this, PlayState* play) { +void EnTa_IdleAtRanch(EnTa* this, PlayState* play) { if (func_80B142F4(this, play, 0x2055)) { - func_80B13AA0(this, func_80B14D4C, func_80B167C0); + EnTa_SetupAction(this, func_80B14D4C, EnTa_AnimRepeatCurrent); } } @@ -551,7 +551,7 @@ void func_80B14EDC(EnTa* this, PlayState* play) { } void func_80B14F20(EnTa* this, EnTaActionFunc arg1) { - func_80B13AA0(this, arg1, func_80B16854); + EnTa_SetupAction(this, arg1, EnTa_AnimSitSleeping); this->eyeIndex = 2; Animation_Change(&this->skelAnime, &gTalonSitSleepingAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gTalonSitSleepingAnim), ANIMMODE_ONCE, -5.0f); @@ -561,7 +561,7 @@ void func_80B14F20(EnTa* this, EnTaActionFunc arg1) { void func_80B14FAC(EnTa* this, EnTaActionFunc arg1) { this->eyeIndex = 1; - func_80B13AA0(this, arg1, func_80B16938); + EnTa_SetupAction(this, arg1, EnTa_AnimRunToEnd); this->unk_2E0 &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitWakeUpAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim), ANIMMODE_ONCE, -5.0f); @@ -570,7 +570,7 @@ void func_80B14FAC(EnTa* this, EnTaActionFunc arg1) { void func_80B15034(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); - func_80B14F20(this, func_80B16504); + func_80B14F20(this, EnTa_IdleSittingInLonLonHouse); func_80B13AAC(this, play); } this->unk_2E0 |= 1; @@ -602,7 +602,7 @@ void func_80B15100(EnTa* this, PlayState* play) { this->unk_2E0 &= ~0x10; Message_CloseTextbox(play); unk_2CA = this->unk_2CA; - this->actionFunc = func_80B154FC; + this->actionFunc = EnTa_RunCuccoGame; this->superCuccos[unk_2CA]->actor.gravity = 0.1f; this->superCuccos[unk_2CA]->actor.velocity.y = 0.0f; this->superCuccos[unk_2CA]->actor.speedXZ = 0.0f; @@ -687,7 +687,7 @@ void func_80B15424(EnTa* this, PlayState* play) { } } -void func_80B154FC(EnTa* this, PlayState* play) { +void EnTa_RunCuccoGame(EnTa* this, PlayState* play) { s32 i; for (i = 0; i < ARRAY_COUNT(this->superCuccos); i++) { @@ -797,7 +797,7 @@ void func_80B1585C(EnTa* this, PlayState* play) { } if (this->unk_2CC == 0) { - func_80B13AA0(this, func_80B154FC, func_80B16938); + EnTa_SetupAction(this, EnTa_RunCuccoGame, EnTa_AnimRunToEnd); this->unk_2E0 &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitWakeUpAnim, 1.0f, Animation_GetLastFrame(&gTalonSitWakeUpAnim) - 1.0f, @@ -808,7 +808,7 @@ void func_80B1585C(EnTa* this, PlayState* play) { void func_80B15AD4(EnTa* this, PlayState* play) { if (this->unk_2CC == 0 && this->unk_2E0 & 0x20) { - func_80B13AA0(this, func_80B1585C, func_80B16938); + EnTa_SetupAction(this, func_80B1585C, EnTa_AnimRunToEnd); this->unk_2E0 &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 1.0f, Animation_GetLastFrame(&gTalonSitHandsUpAnim), ANIMMODE_ONCE, 0.0f); @@ -829,7 +829,7 @@ void func_80B15AD4(EnTa* this, PlayState* play) { void func_80B15BF8(EnTa* this, PlayState* play) { if (this->unk_2E0 & 0x10) { - func_80B13AA0(this, func_80B15AD4, func_80B16938); + EnTa_SetupAction(this, func_80B15AD4, EnTa_AnimRunToEnd); this->unk_2E0 &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 0.0f, 1.0f, ANIMMODE_ONCE, 0.0f); this->unk_2CC = 5; @@ -842,7 +842,7 @@ void func_80B15BF8(EnTa* this, PlayState* play) { void func_80B15CC8(EnTa* this, PlayState* play) { if (this->unk_2E0 & 0x10) { - func_80B13AA0(this, func_80B15BF8, func_80B16938); + EnTa_SetupAction(this, func_80B15BF8, EnTa_AnimRunToEnd); this->unk_2E0 &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, -1.0f, 29.0f, 0.0f, ANIMMODE_ONCE, 10.0f); } @@ -853,25 +853,25 @@ void func_80B15CC8(EnTa* this, PlayState* play) { } void func_80B15D90(EnTa* this, PlayState* play) { - func_80B13AA0(this, func_80B15CC8, func_80B16938); + EnTa_SetupAction(this, func_80B15CC8, EnTa_AnimRunToEnd); this->unk_2E0 &= ~0x10; Animation_Change(&this->skelAnime, &gTalonSitHandsUpAnim, 1.0f, 8.0f, 29.0f, ANIMMODE_ONCE, -10.0f); Message_ContinueTextbox(play, 0x2080); this->unk_2E0 &= ~0x20; } -void func_80B15E28(EnTa* this, PlayState* play) { +void EnTa_TalkGeneralInLonLonHouse(EnTa* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - func_80B14F20(this, func_80B16504); + func_80B14F20(this, EnTa_IdleSittingInLonLonHouse); func_80B13AAC(this, play); } this->unk_2E0 |= 1; } -void func_80B15E80(EnTa* this, PlayState* play) { +void EnTa_GiveItemInLonLonHouse(EnTa* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actor.parent = NULL; - this->actionFunc = func_80B15E28; + this->actionFunc = EnTa_TalkGeneralInLonLonHouse; if (!(this->unk_2E0 & 0x2)) { Flags_SetItemGetInf(ITEMGETINF_TALON_BOTTLE); } @@ -889,11 +889,11 @@ void func_80B15E80(EnTa* this, PlayState* play) { this->unk_2E0 |= 1; } -void func_80B15F54(EnTa* this, PlayState* play) { +void EnTa_TalkAfterCuccoGameFirstWon(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); this->unk_2E0 &= ~0x2; - func_80B13AA0(this, func_80B15E80, func_80B16938); + EnTa_SetupAction(this, EnTa_GiveItemInLonLonHouse, EnTa_AnimRunToEnd); if (!IS_RANDO) { Actor_OfferGetItem(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); } else { @@ -910,15 +910,15 @@ void func_80B15FE8(EnTa* this, PlayState* play) { switch (func_80B14DD8()) { case 0: Message_ContinueTextbox(play, 0x85); - func_80B13AA0(this, func_80B15034, func_80B16938); + EnTa_SetupAction(this, func_80B15034, EnTa_AnimRunToEnd); break; case 1: Message_ContinueTextbox(play, 0x208A); - func_80B13AA0(this, func_80B15E28, func_80B16938); + EnTa_SetupAction(this, EnTa_TalkGeneralInLonLonHouse, EnTa_AnimRunToEnd); break; case 2: this->unk_2E0 |= 2; - func_80B13AA0(this, func_80B15E80, func_80B16938); + EnTa_SetupAction(this, EnTa_GiveItemInLonLonHouse, EnTa_AnimRunToEnd); Rupees_ChangeBy(-30); GetItemEntry itemEntry = ItemTable_Retrieve(GI_MILK); gSaveContext.pendingSale = itemEntry.itemId; @@ -930,14 +930,14 @@ void func_80B15FE8(EnTa* this, PlayState* play) { case 1: if (gSaveContext.rupees < 10) { Message_ContinueTextbox(play, 0x85); - func_80B13AA0(this, func_80B15034, func_80B16938); + EnTa_SetupAction(this, func_80B15034, EnTa_AnimRunToEnd); } else { Rupees_ChangeBy(-10); func_80B15D90(this, play); } break; case 2: - func_80B14F20(this, func_80B16504); + func_80B14F20(this, EnTa_IdleSittingInLonLonHouse); func_80B13AAC(this, play); break; } @@ -962,14 +962,14 @@ void func_80B161C0(EnTa* this, PlayState* play) { case 0: if (gSaveContext.rupees < price) { Message_ContinueTextbox(play, 0x85); - func_80B13AA0(this, func_80B15034, func_80B16938); + EnTa_SetupAction(this, func_80B15034, EnTa_AnimRunToEnd); } else { Rupees_ChangeBy(-price); func_80B15D90(this, play); } break; case 1: - func_80B14F20(this, func_80B16504); + func_80B14F20(this, EnTa_IdleSittingInLonLonHouse); func_80B13AAC(this, play); break; } @@ -983,7 +983,7 @@ void func_80B161C0(EnTa* this, PlayState* play) { void func_80B162E8(EnTa* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { Message_ContinueTextbox(play, 0x2087); - func_80B13AA0(this, func_80B15F54, func_80B16938); + EnTa_SetupAction(this, EnTa_TalkAfterCuccoGameFirstWon, EnTa_AnimRunToEnd); } if (this->unk_2E0 & 0x10) { @@ -996,10 +996,10 @@ void func_80B16364(EnTa* this, PlayState* play) { Flags_SetInfTable(INFTABLE_TALKED_TO_TALON_IN_RANCH_HOUSE); if (Flags_GetItemGetInf(ITEMGETINF_TALON_BOTTLE)) { Message_ContinueTextbox(play, 0x208B); - func_80B13AA0(this, func_80B15FE8, func_80B16938); + EnTa_SetupAction(this, func_80B15FE8, EnTa_AnimRunToEnd); } else { Message_ContinueTextbox(play, 0x207F); - func_80B13AA0(this, func_80B161C0, func_80B16938); + EnTa_SetupAction(this, func_80B161C0, EnTa_AnimRunToEnd); } } @@ -1013,16 +1013,16 @@ void func_80B1642C(EnTa* this, PlayState* play) { if (Inventory_HasEmptyBottle()) { Message_CloseTextbox(play); this->unk_2E0 |= 2; - func_80B13AA0(this, func_80B15E80, func_80B16938); + EnTa_SetupAction(this, EnTa_GiveItemInLonLonHouse, EnTa_AnimRunToEnd); Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 50.0f); } else { Message_ContinueTextbox(play, 0x208A); - func_80B13AA0(this, func_80B15E28, func_80B16938); + EnTa_SetupAction(this, EnTa_TalkGeneralInLonLonHouse, EnTa_AnimRunToEnd); } } } -void func_80B16504(EnTa* this, PlayState* play) { +void EnTa_IdleSittingInLonLonHouse(EnTa* this, PlayState* play) { u16 faceReaction = Text_GetFaceReaction(play, 0x18); func_80B13AAC(this, play); @@ -1031,7 +1031,7 @@ void func_80B16504(EnTa* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_VO_TA_SURPRISE); if (faceReaction != 0) { - func_80B14FAC(this, func_80B15E28); + func_80B14FAC(this, EnTa_TalkGeneralInLonLonHouse); } else { Flags_SetInfTable(INFTABLE_TALKED_TO_TALON_IN_RANCH_HOUSE); @@ -1052,7 +1052,7 @@ void func_80B16504(EnTa* this, PlayState* play) { this->unk_2E0 &= ~1; } -void func_80B16608(EnTa* this, PlayState* play) { +void EnTa_IdleAfterCuccoGameFinished(EnTa* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { switch (this->actor.textId) { case 0x2085: @@ -1073,17 +1073,17 @@ void func_80B16608(EnTa* this, PlayState* play) { this->unk_2E0 |= 1; } -void func_80B166CC(EnTa* this) { +void EnTa_BlinkWaitUntilNext(EnTa* this) { s16 temp_v0 = this->blinkTimer - 1; if (temp_v0 != 0) { this->blinkTimer = temp_v0; } else { - this->unk_2B0 = func_80B16700; + this->unk_2B0 = EnTa_BlinkAdvanceState; } } -void func_80B16700(EnTa* this) { +void EnTa_BlinkAdvanceState(EnTa* this) { s16 blinkTimer = this->blinkTimer - 1; if (blinkTimer != 0) { @@ -1101,7 +1101,7 @@ void func_80B16700(EnTa* this) { blinkTimer = (s32)(Rand_ZeroOne() * 60.0f) + 20; } this->blinkTimer = blinkTimer; - this->unk_2B0 = func_80B166CC; + this->unk_2B0 = EnTa_BlinkWaitUntilNext; } else { this->eyeIndex = nextEyeIndex; this->blinkTimer = 1; @@ -1109,13 +1109,13 @@ void func_80B16700(EnTa* this) { } } -void func_80B167C0(EnTa* this) { +void EnTa_AnimRepeatCurrent(EnTa* this) { if (SkelAnime_Update(&this->skelAnime)) { Animation_PlayOnce(&this->skelAnime, this->currentAnimation); } } -void func_80B167FC(EnTa* this) { +void EnTa_AnimSleeping(EnTa* this) { if (SkelAnime_Update(&this->skelAnime)) { Animation_PlayOnce(&this->skelAnime, this->currentAnimation); Audio_PlayActorSound2(&this->actor, NA_SE_VO_TA_SLEEP); @@ -1123,7 +1123,7 @@ void func_80B167FC(EnTa* this) { this->unk_2E0 |= 0xC; } -void func_80B16854(EnTa* this) { +void EnTa_AnimSitSleeping(EnTa* this) { if (this->unk_2E2 > 0) { this->unk_2E2--; } else { @@ -1142,7 +1142,7 @@ void func_80B16854(EnTa* this) { this->unk_2E0 |= 4; } -void func_80B16938(EnTa* this) { +void EnTa_AnimRunToEnd(EnTa* this) { if (!(this->unk_2E0 & 0x10)) { if (SkelAnime_Update(&this->skelAnime)) { this->unk_2E0 |= 0x10; From 1e9cba1d616615234079e414f6d8b354be2c9efb Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Thu, 4 Apr 2024 11:30:45 -0400 Subject: [PATCH 19/52] vb diving game (#100) --- .../game-interactor/GameInteractor.h | 2 ++ .../Enhancements/randomizer/hook_handlers.cpp | 1 + .../actors/ovl_En_Diving_Game/z_en_diving_game.c | 16 ++++++---------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index c61a82760..08f1fe0be 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -292,6 +292,8 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, // Opt: *EnExItem GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, + // Opt: *EnDivingGame + GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index ea3755a69..f1cc89102 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -768,6 +768,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void case GI_VB_TRADE_TIMER_FROG: case GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM: case GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS: + case GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME: case GI_VB_GIVE_ITEM_FROM_GORON: case GI_VB_GIVE_ITEM_FROM_LAB_DIVE: case GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG: diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c index 84ac2749d..b411c1427 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c @@ -8,6 +8,7 @@ #include "overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.h" #include "objects/object_zo/object_zo.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -455,11 +456,8 @@ void func_809EEA00(EnDivingGame* this, PlayState* play) { if ((this->unk_292 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play))) { Message_CloseTextbox(play); this->actor.parent = NULL; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, true, &this->actor)) { Actor_OfferGetItem(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 90.0f, 10.0f); } this->actionFunc = func_809EEA90; } @@ -467,14 +465,11 @@ void func_809EEA00(EnDivingGame* this, PlayState* play) { void func_809EEA90(EnDivingGame* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, true, &this->actor)) { this->actionFunc = func_809EEAF8; } else { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, true, &this->actor)) { Actor_OfferGetItem(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 90.0f, 10.0f); } } } @@ -482,7 +477,8 @@ void func_809EEA90(EnDivingGame* this, PlayState* play) { // Award the scale? void func_809EEAF8(EnDivingGame* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - if (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE && Message_ShouldAdvance(play)) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE && Message_ShouldAdvance(play)) || + !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, true, &this->actor)) { // "Successful completion" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST); this->allRupeesThrown = this->state = this->phase = this->unk_2A2 = this->grabbedRupeesCounter = 0; From 307e1060381bebd338b4769af3e606eecb898c00 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Thu, 4 Apr 2024 11:55:07 -0400 Subject: [PATCH 20/52] vb talon's chickens (#99) --- .../Enhancements/game-interactor/GameInteractor.h | 2 ++ soh/soh/Enhancements/randomizer/hook_handlers.cpp | 1 + soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c | 12 +++--------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 08f1fe0be..f5e70da16 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -292,6 +292,8 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, // Opt: *EnExItem GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, + // Opt: *EnTa + GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS, // Opt: *EnDivingGame GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index f1cc89102..772ce16aa 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -768,6 +768,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void case GI_VB_TRADE_TIMER_FROG: case GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM: case GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS: + case GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS: case GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME: case GI_VB_GIVE_ITEM_FROM_GORON: case GI_VB_GIVE_ITEM_FROM_LAB_DIVE: diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index d8a0ff554..cdec042bc 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -869,7 +869,7 @@ void EnTa_TalkGeneralInLonLonHouse(EnTa* this, PlayState* play) { } void EnTa_GiveItemInLonLonHouse(EnTa* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS, true, &this->actor)) { this->actor.parent = NULL; this->actionFunc = EnTa_TalkGeneralInLonLonHouse; if (!(this->unk_2E0 & 0x2)) { @@ -879,11 +879,8 @@ void EnTa_GiveItemInLonLonHouse(EnTa* this, PlayState* play) { } else if (this->unk_2E0 & 2) { Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 50.0f); } else { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS, true, &this->actor)) { Actor_OfferGetItem(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } } this->unk_2E0 |= 1; @@ -894,11 +891,8 @@ void EnTa_TalkAfterCuccoGameFirstWon(EnTa* this, PlayState* play) { Message_CloseTextbox(play); this->unk_2E0 &= ~0x2; EnTa_SetupAction(this, EnTa_GiveItemInLonLonHouse, EnTa_AnimRunToEnd); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS, true, &this->actor)) { Actor_OfferGetItem(&this->actor, play, GI_MILK_BOTTLE, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } } } From 6d77bbd4a975c56a89d9011e4fcb3f73c8d25b65 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 8 Apr 2024 11:55:16 -0400 Subject: [PATCH 21/52] vb skull rewards (#101) --- .../game-interactor/GameInteractor.h | 2 + .../Enhancements/randomizer/hook_handlers.cpp | 28 ++++++++ soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c | 68 ++++++------------- soh/src/overlays/actors/ovl_En_Sth/z_en_sth.h | 2 + 4 files changed, 51 insertions(+), 49 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index f5e70da16..1f0da656f 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -296,6 +296,8 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS, // Opt: *EnDivingGame GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, + // Opt: *EnSth + GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 772ce16aa..933b27e5a 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -24,6 +24,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Ms/z_en_ms.h" #include "src/overlays/actors/ovl_En_Fr/z_en_fr.h" #include "src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h" +#include "src/overlays/actors/ovl_En_Sth/z_en_sth.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -763,6 +764,33 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = eligible; break; } + case GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD: { + // In z_en_sth.c the rewards are stored in sGetItemIds, the first entry + // in that array is GI_RUPEE_GOLD, and the reward is picked in EnSth_GivePlayerItem + // via sGetItemIds[this->actor.params]. This means if actor.params == 0 we're looking + // at the 100 GS reward + EnSth* enSth = static_cast(optionalArg); + if (enSth->actor.params == 0) { + // if nothing is shuffled onto 100 GS, + // or we already got the 100 GS reward, + // let the player farm + if (!RAND_GET_OPTION(RSK_SHUFFLE_100_GS_REWARD) || + Flags_GetRandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD)) { + *should = true; + break; + } + + // we're giving the 100 GS rando reward! set the rando inf + Flags_SetRandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD); + + // also set the actionfunc so this doesn't immediately get + // called again (and lead to a vanilla+rando item give + // because the flag check will pass next time) + enSth->actionFunc = (EnSthActionFunc)EnSth_RewardObtainedTalk; + } + *should = false; + break; + } case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c index 7a0332910..f8b50d823 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -257,66 +257,34 @@ void EnSth_ParentRewardObtainedWait(EnSth* this, PlayState* play) { void EnSth_GivePlayerItem(EnSth* this, PlayState* play) { u16 getItemId = sGetItemIds[this->actor.params]; - GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; - - if (IS_RANDO) { - switch (getItemId) { - case GI_RUPEE_GOLD: - if (!Flags_GetRandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD)) { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_100_GOLD_SKULLTULA_REWARD, GI_RUPEE_GOLD); - Flags_SetRandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD); - } - break; - case GI_WALLET_ADULT: - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_10_GOLD_SKULLTULA_REWARD, GI_WALLET_ADULT); - break; - case GI_STONE_OF_AGONY: - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_20_GOLD_SKULLTULA_REWARD, GI_STONE_OF_AGONY); - break; - case GI_WALLET_GIANT: - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_30_GOLD_SKULLTULA_REWARD, GI_WALLET_GIANT); - break; - case GI_BOMBCHUS_10: - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_40_GOLD_SKULLTULA_REWARD, GI_BOMBCHUS_10); - break; - case GI_HEART_PIECE: - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_50_GOLD_SKULLTULA_REWARD, GI_HEART_PIECE); - break; - } - getItemId = getItemEntry.getItemId; - } else { - switch (this->actor.params) { - case 1: - case 3: - switch (CUR_UPG_VALUE(UPG_WALLET)) { - case 0: - getItemId = GI_WALLET_ADULT; - break; - case 1: - getItemId = GI_WALLET_GIANT; - break; - } - break; - } + switch (this->actor.params) { + case 1: + case 3: + switch (CUR_UPG_VALUE(UPG_WALLET)) { + case 0: + getItemId = GI_WALLET_ADULT; + break; + + case 1: + getItemId = GI_WALLET_GIANT; + break; + } + break; } - if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - Actor_OfferGetItem(&this->actor, play, getItemId, 10000.0f, 50.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - } + Actor_OfferGetItem(&this->actor, play, getItemId, 10000.0f, 50.0f); } void EnSth_GiveReward(EnSth* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, true, this)) { this->actor.parent = NULL; EnSth_SetupAction(this, EnSth_RewardObtainedTalk); gSaveContext.eventChkInf[EVENTCHKINF_SKULLTULA_REWARD_INDEX] |= this->eventFlag; if (this->eventFlag != 0) { GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SKULLTULA_REWARD_INDEX << 4) + sEventFlagsShift[this->actor.params]); } - } else { + } else if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, true, this)) { EnSth_GivePlayerItem(this, play); } EnSth_FacePlayer(this, play); @@ -326,7 +294,9 @@ void EnSth_RewardUnobtainedTalk(EnSth* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); EnSth_SetupAction(this, EnSth_GiveReward); - EnSth_GivePlayerItem(this, play); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, true, this)) { + EnSth_GivePlayerItem(this, play); + } } EnSth_FacePlayer(this, play); } diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.h b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.h index 9391496ae..c0001f955 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.h +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.h @@ -25,4 +25,6 @@ typedef struct EnSth { /* 0x02B8 */ EnSthActionFunc actionFunc; } EnSth; // size = 0x02BC +void EnSth_RewardObtainedTalk(EnSth* enSth, PlayState* play); + #endif From 9c9fc49d32847a7cce24336a12ce43fd57958574 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 8 Apr 2024 11:59:48 -0400 Subject: [PATCH 22/52] vb horseback archery (#102) * vb horseback archery * Update soh/soh/Enhancements/randomizer/hook_handlers.cpp --------- Co-authored-by: Garrett Cox --- .../game-interactor/GameInteractor.h | 2 + .../Enhancements/randomizer/hook_handlers.cpp | 8 ++ soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c | 77 ++++++------------- 3 files changed, 33 insertions(+), 54 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 1f0da656f..ad3ff9d6f 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -296,6 +296,8 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS, // Opt: *EnDivingGame GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, + // Opt: *EnGe1 + GI_VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY, // Opt: *EnSth GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 933b27e5a..788701b9c 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -764,6 +764,14 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = eligible; break; } + case GI_VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY: { + // give both rewards at the same time + if (gSaveContext.minigameScore >= 1500) { + Flags_SetItemGetInf(ITEMGETINF_0F); + } + *should = false; + break; + } case GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD: { // In z_en_sth.c the rewards are stored in sGetItemIds, the first entry // in that array is GI_RUPEE_GOLD, and the reward is picked in EnSth_GivePlayerItem diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index c72205b8f..995e3d5fd 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -8,6 +8,7 @@ #include "vt.h" #include "objects/object_ge1/object_ge1.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -531,16 +532,8 @@ void EnGe1_WaitTillItemGiven_Archery(EnGe1* this, PlayState* play) { GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; s32 getItemId; - if (Actor_HasParent(&this->actor, play)) { - if (IS_RANDO && gSaveContext.minigameScore >= 1500 && !Flags_GetInfTable(INFTABLE_190)) { - Flags_SetItemGetInf(ITEMGETINF_0F); - Flags_SetInfTable(INFTABLE_190); - this->stateFlags |= GE1_STATE_GIVE_QUIVER; - this->actor.parent = NULL; - return; - } else { - this->actionFunc = EnGe1_SetupWait_Archery; - } + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY, true, this)) { + this->actionFunc = EnGe1_SetupWait_Archery; if (this->stateFlags & GE1_STATE_GIVE_QUIVER) { Flags_SetItemGetInf(ITEMGETINF_0F); @@ -549,33 +542,21 @@ void EnGe1_WaitTillItemGiven_Archery(EnGe1* this, PlayState* play) { } } else { if (this->stateFlags & GE1_STATE_GIVE_QUIVER) { - if (!IS_RANDO) { - switch (CUR_UPG_VALUE(UPG_QUIVER)) { - //! @bug Asschest. See next function for details - case 1: - getItemId = GI_QUIVER_40; - break; - case 2: - getItemId = GI_QUIVER_50; - break; - } - } else { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_HBA_1500_POINTS, CUR_UPG_VALUE(UPG_QUIVER) == 1 ? GI_QUIVER_40 : GI_QUIVER_50); - getItemId = getItemEntry.getItemId; + switch (CUR_UPG_VALUE(UPG_QUIVER)) { + //! @bug Asschest. See next function for details + case 1: + getItemId = GI_QUIVER_40; + break; + case 2: + getItemId = GI_QUIVER_50; + break; } } else { - if (!IS_RANDO) { - getItemId = GI_HEART_PIECE; - } else { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); - getItemId = getItemEntry.getItemId; - } + getItemId = GI_HEART_PIECE; } - if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY, true, this)) { Actor_OfferGetItem(&this->actor, play, getItemId, 10000.0f, 50.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } } } @@ -590,33 +571,21 @@ void EnGe1_BeginGiveItem_Archery(EnGe1* this, PlayState* play) { } if (this->stateFlags & GE1_STATE_GIVE_QUIVER) { - if (!IS_RANDO) { - switch (CUR_UPG_VALUE(UPG_QUIVER)) { - //! @bug Asschest. See next function for details - case 1: - getItemId = GI_QUIVER_40; - break; - case 2: - getItemId = GI_QUIVER_50; - break; - } - } else { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_HBA_1500_POINTS, CUR_UPG_VALUE(UPG_QUIVER) == 1 ? GI_QUIVER_40 : GI_QUIVER_50); - getItemId = getItemEntry.getItemId; + switch (CUR_UPG_VALUE(UPG_QUIVER)) { + //! @bug Asschest. See next function for details + case 1: + getItemId = GI_QUIVER_40; + break; + case 2: + getItemId = GI_QUIVER_50; + break; } } else { - if (!IS_RANDO) { - getItemId = GI_HEART_PIECE; - } else { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); - getItemId = getItemEntry.getItemId; - } + getItemId = GI_HEART_PIECE; } - if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY, true, this)) { Actor_OfferGetItem(&this->actor, play, getItemId, 10000.0f, 50.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } } From fe231147d5b1942c2b700640f25d5faddc672dad Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 9 Apr 2024 23:46:11 -0400 Subject: [PATCH 23/52] vb underwater item (#104) * underwater working pre func_80B858B4 replacement * underwater item update handled by hookhandlers * remove commented out code * remove unused should --- .../Enhancements/randomizer/hook_handlers.cpp | 39 +++++++++++++++++++ .../ovl_Item_Etcetera/z_item_etcetera.c | 35 ++--------------- .../ovl_Item_Etcetera/z_item_etcetera.h | 3 ++ 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 788701b9c..31ba23427 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -25,6 +25,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Fr/z_en_fr.h" #include "src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h" #include "src/overlays/actors/ovl_En_Sth/z_en_sth.h" +#include "src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -274,6 +275,27 @@ void ItemBHeart_UpdateRandomizedItem(Actor* actor, PlayState* play) { } } +void ItemEtcetera_DrawRandomizedItem(ItemEtcetera* itemEtcetera, PlayState* play) { + EnItem00_CustomItemsParticles(&itemEtcetera->actor, play, itemEtcetera->sohItemEntry); + GetItemEntry_Draw(play, itemEtcetera->sohItemEntry); +} + +void ItemEtcetera_func_80B858B4_Randomized(ItemEtcetera* itemEtcetera, PlayState* play) { + if (itemEtcetera->actor.xzDistToPlayer < 30.0f && + fabsf(itemEtcetera->actor.yDistToPlayer) < 50.0f) { + if ((itemEtcetera->actor.params & 0xFF) == 1) { + Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER); + Flags_SetSwitch(play, 0xB); + } + + Actor_Kill(&itemEtcetera->actor); + } else { + if ((play->gameplayFrames & 0xD) == 0) { + EffectSsBubble_Spawn(play, &itemEtcetera->actor.world.pos, 0.0f, 0.0f, 10.0f, 0.13f); + } + } +} + void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) { bool moved = false; @@ -954,6 +976,23 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } } + + if (actor->id == ACTOR_ITEM_ETCETERA) { + ItemEtcetera* itemEtcetera = static_cast(actorRef); + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(itemEtcetera->actor.id, gPlayState->sceneNum, itemEtcetera->actor.params); + if (rc != RC_UNKNOWN_CHECK) { + itemEtcetera->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + itemEtcetera->drawFunc = (ActorFunc)ItemEtcetera_DrawRandomizedItem; + } + + int32_t type = itemEtcetera->actor.params & 0xFF; + switch (type) { + case ITEM_ETC_LETTER: { + itemEtcetera->futureActionFunc = (ItemEtceteraActionFunc)ItemEtcetera_func_80B858B4_Randomized; + break; + } + } + } } void RandomizerRegisterHooks() { diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index 6fdf162db..db42bc15b 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -83,8 +83,7 @@ void ItemEtcetera_Init(Actor* thisx, PlayState* play) { case ITEM_ETC_LETTER: Actor_SetScale(&this->actor, 0.5f); this->futureActionFunc = func_80B858B4; - if ((Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER) && !IS_RANDO) || - (IS_RANDO && Flags_GetTreasure(play, 0x1E))) { + if (Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER)) { Actor_Kill(&this->actor); } break; @@ -147,21 +146,11 @@ void func_80B858B4(ItemEtcetera* this, PlayState* play) { if ((this->actor.params & 0xFF) == 1) { Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER); Flags_SetSwitch(play, 0xB); - - if (IS_RANDO) { - Flags_SetTreasure(play, 0x1E); - } } + Actor_Kill(&this->actor); } else { - if (0) {} // Necessary to match - - if (!IS_RANDO) { - Actor_OfferGetItem(&this->actor, play, this->getItemId, 30.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 30.0f, 50.0f); - } + Actor_OfferGetItem(&this->actor, play, this->getItemId, 30.0f, 50.0f); if ((play->gameplayFrames & 0xD) == 0) { EffectSsBubble_Spawn(play, &this->actor.world.pos, 0.0f, 0.0f, 10.0f, 0.13f); @@ -246,24 +235,6 @@ void ItemEtcetera_Draw(Actor* thisx, PlayState* play) { ItemEtcetera* this = (ItemEtcetera*)thisx; s32 type = this->actor.params & 0xFF; - if (IS_RANDO) { - GetItemEntry randoGetItem = (GetItemEntry)GET_ITEM_NONE; - if (type == ITEM_ETC_ARROW_FIRE) { - randoGetItem = Randomizer_GetItemFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); - } else if (type == ITEM_ETC_LETTER) { - randoGetItem = Randomizer_GetItemFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); - } - - EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem); - - if (randoGetItem.itemId != ITEM_NONE) { - func_8002EBCC(&this->actor, play, 0); - func_8002ED80(&this->actor, play, 0); - GetItemEntry_Draw(play, randoGetItem); - return; - } - } - func_8002EBCC(&this->actor, play, 0); func_8002ED80(&this->actor, play, 0); GetItem_Draw(play, this->giDrawId); diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h index 3ec33b926..ceec9c8b1 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h @@ -16,6 +16,9 @@ typedef struct ItemEtcetera { /* 0x0154 */ u8 objBankIndex; /* 0x0158 */ ActorFunc drawFunc; /* 0x015C */ ItemEtceteraActionFunc actionFunc; + // #region SOH [Randomizer] Caching the get item entry for the draw function for performance + /* */ GetItemEntry sohItemEntry; + // #endregion } ItemEtcetera; // size = 0x0160 typedef enum { From bbbd2520b1611f18da2df7ba13751d9da2694636 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 9 Apr 2024 23:57:07 -0400 Subject: [PATCH 24/52] vb lh sun (#106) * underwater working pre func_80B858B4 replacement * underwater item update handled by hookhandlers * vb lh sun * remove unused should --- .../Enhancements/randomizer/hook_handlers.cpp | 44 +++++++++++++++++++ .../ovl_Item_Etcetera/z_item_etcetera.c | 14 +----- .../ovl_Item_Etcetera/z_item_etcetera.h | 2 + 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 31ba23427..ce24e11d9 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -277,6 +277,8 @@ void ItemBHeart_UpdateRandomizedItem(Actor* actor, PlayState* play) { void ItemEtcetera_DrawRandomizedItem(ItemEtcetera* itemEtcetera, PlayState* play) { EnItem00_CustomItemsParticles(&itemEtcetera->actor, play, itemEtcetera->sohItemEntry); + func_8002EBCC(&itemEtcetera->actor, play, 0); + func_8002ED80(&itemEtcetera->actor, play, 0); GetItemEntry_Draw(play, itemEtcetera->sohItemEntry); } @@ -296,6 +298,44 @@ void ItemEtcetera_func_80B858B4_Randomized(ItemEtcetera* itemEtcetera, PlayState } } +void ItemEtcetera_func_80B85824_Randomized(ItemEtcetera* itemEtcetera, PlayState* play) { + if ((itemEtcetera->actor.params & 0xFF) != 7) { + return; + } + + if (itemEtcetera->actor.xzDistToPlayer < 30.0f && + fabsf(itemEtcetera->actor.yDistToPlayer) < 50.0f) { + + Flags_SetTreasure(play, 0x1F); + Actor_Kill(&itemEtcetera->actor); + } +} + +void ItemEtcetera_MoveRandomizedFireArrowDown(ItemEtcetera* itemEtcetera, PlayState* play) { + Actor_UpdateBgCheckInfo(play, &itemEtcetera->actor, 10.0f, 10.0f, 0.0f, 5); + Actor_MoveForward(&itemEtcetera->actor); + if (!(itemEtcetera->actor.bgCheckFlags & 1)) { + ItemEtcetera_SpawnSparkles(itemEtcetera, play); + } + itemEtcetera->actor.shape.rot.y += 0x400; + ItemEtcetera_func_80B85824_Randomized(itemEtcetera, play); +} + +void ItemEtcetera_UpdateRandomizedFireArrow(ItemEtcetera* itemEtcetera, PlayState* play) { + if ((play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.npcActions[0] != NULL)) { + if (play->csCtx.npcActions[0]->action == 2) { + itemEtcetera->actor.draw = (ActorFunc)ItemEtcetera_DrawRandomizedItem; + itemEtcetera->actor.gravity = -0.1f; + itemEtcetera->actor.minVelocityY = -4.0f; + itemEtcetera->actionFunc = ItemEtcetera_MoveRandomizedFireArrowDown; + } + } else { + itemEtcetera->actor.gravity = -0.1f; + itemEtcetera->actor.minVelocityY = -4.0f; + itemEtcetera->actionFunc = ItemEtcetera_MoveRandomizedFireArrowDown; + } +} + void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) { bool moved = false; @@ -991,6 +1031,10 @@ void RandomizerOnActorInitHandler(void* actorRef) { itemEtcetera->futureActionFunc = (ItemEtceteraActionFunc)ItemEtcetera_func_80B858B4_Randomized; break; } + case ITEM_ETC_ARROW_FIRE: { + itemEtcetera->futureActionFunc = (ItemEtceteraActionFunc)ItemEtcetera_UpdateRandomizedFireArrow; + break; + } } } } diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index db42bc15b..8a26860f7 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -120,24 +120,13 @@ void func_80B857D0(ItemEtcetera* this, PlayState* play) { void func_80B85824(ItemEtcetera* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { - if ((this->actor.params & 0xFF) == 7) { - if (IS_RANDO) { - Flags_SetTreasure(play, 0x1F); - } - } - if ((this->actor.params & 0xFF) == 1) { Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER); Flags_SetSwitch(play, 0xB); } Actor_Kill(&this->actor); } else { - if (!IS_RANDO) { - Actor_OfferGetItem(&this->actor, play, this->getItemId, 30.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 30.0f, 50.0f); - } + Actor_OfferGetItem(&this->actor, play, this->getItemId, 30.0f, 50.0f); } } @@ -233,7 +222,6 @@ void ItemEtcetera_DrawThroughLens(Actor* thisx, PlayState* play) { void ItemEtcetera_Draw(Actor* thisx, PlayState* play) { ItemEtcetera* this = (ItemEtcetera*)thisx; - s32 type = this->actor.params & 0xFF; func_8002EBCC(&this->actor, play, 0); func_8002ED80(&this->actor, play, 0); diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h index ceec9c8b1..5293292a4 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h @@ -38,4 +38,6 @@ typedef enum { /* 0x0D */ ITEM_ETC_KEY_SMALL_CHEST_GAME } ItemEtceteraType; +void ItemEtcetera_SpawnSparkles(ItemEtcetera* ItemEtcetera, PlayState* play); + #endif From f3273e76273ae38306412ddf324be21511a80de9 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 10 Apr 2024 00:31:45 -0400 Subject: [PATCH 25/52] vb treasure chest game (#103) --- soh/include/functions.h | 2 - .../game-interactor/GameInteractor.h | 1 + .../randomizer/3drando/item_pool.cpp | 15 ++-- .../location_access/locacc_castle_town.cpp | 10 +-- .../Enhancements/randomizer/hook_handlers.cpp | 85 +++++++++++++++++++ .../Enhancements/randomizer/location_list.cpp | 20 +++-- .../Enhancements/randomizer/randomizer.cpp | 31 ++++--- .../Enhancements/randomizer/randomizerTypes.h | 10 +++ .../Enhancements/randomizer/randomizer_inf.h | 11 +++ soh/src/code/z_actor.c | 55 ------------ .../overlays/actors/ovl_Door_Ana/z_door_ana.c | 1 - .../actors/ovl_En_Ex_Item/z_en_ex_item.c | 32 +++---- .../ovl_Item_Etcetera/z_item_etcetera.c | 10 --- .../actors/ovl_player_actor/z_player.c | 2 +- 14 files changed, 170 insertions(+), 115 deletions(-) diff --git a/soh/include/functions.h b/soh/include/functions.h index 8efad485a..8ee00ed8d 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -575,8 +575,6 @@ void Flags_UnsetRandomizerInf(RandomizerInf flag); u16 func_80037C30(PlayState* play, s16 arg1); s32 func_80037D98(PlayState* play, Actor* actor, s16 arg2, s32* arg3); s32 func_80038290(PlayState* play, Actor* actor, Vec3s* arg2, Vec3s* arg3, Vec3f arg4); -GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, PlayState* play); -s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, PlayState* play); // ? func_80038600(?); u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList*); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index ad3ff9d6f..3790545fd 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -254,6 +254,7 @@ typedef enum { /*** Give Items ***/ + // Opt: *EnBox GI_VB_GIVE_ITEM_FROM_CHEST, GI_VB_GIVE_ITEM_FROM_BLUE_WARP, // Opt: *EnItem00 diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index a54f522aa..e3e0aa322 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -904,11 +904,16 @@ void GenerateItemPool() { } else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK)) { AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY); // 1 key which will behave as a pack of 6 } else { - ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, false, true); - ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_TREASURE_GAME_SMALL_KEY, false, true); - ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_TREASURE_GAME_SMALL_KEY, false, true); - ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_TREASURE_GAME_SMALL_KEY, false, true); - ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, false, true); }; if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index 874cc76c1..f48a2bb53 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp @@ -234,11 +234,11 @@ void AreaTable_Init_CastleTown() { //Locations LocationAccess(RC_GREG_HINT, {[]{return true;}}), LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_REWARD, {[]{return logic->ChildsWallet && ((logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)));}}), - LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), - LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), - LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), - LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), - LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), }, { //Exits Entrance(RR_THE_MARKET, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index ce24e11d9..ae6beb869 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -26,6 +26,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h" #include "src/overlays/actors/ovl_En_Sth/z_en_sth.h" #include "src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h" +#include "src/overlays/actors/ovl_En_Box/z_en_box.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -282,6 +283,12 @@ void ItemEtcetera_DrawRandomizedItem(ItemEtcetera* itemEtcetera, PlayState* play GetItemEntry_Draw(play, itemEtcetera->sohItemEntry); } +void ItemEtcetera_DrawRandomizedItemThroughLens(ItemEtcetera* itemEtcetera, PlayState* play) { + if (play->actorCtx.lensActive) { + ItemEtcetera_DrawRandomizedItem(itemEtcetera, play); + } +} + void ItemEtcetera_func_80B858B4_Randomized(ItemEtcetera* itemEtcetera, PlayState* play) { if (itemEtcetera->actor.xzDistToPlayer < 30.0f && fabsf(itemEtcetera->actor.yDistToPlayer) < 50.0f) { @@ -394,9 +401,50 @@ RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex) { } } +void RandomizerSetChestGameRandomizerInf(RandomizerCheck rc) { + switch (rc) { + case RC_MARKET_TREASURE_CHEST_GAME_ITEM_1: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1); + break; + case RC_MARKET_TREASURE_CHEST_GAME_ITEM_2: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2); + break; + case RC_MARKET_TREASURE_CHEST_GAME_ITEM_3: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3); + break; + case RC_MARKET_TREASURE_CHEST_GAME_ITEM_4: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4); + break; + case RC_MARKET_TREASURE_CHEST_GAME_ITEM_5: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5); + break; + case RC_MARKET_TREASURE_CHEST_GAME_KEY_1: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1); + break; + case RC_MARKET_TREASURE_CHEST_GAME_KEY_2: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2); + break; + case RC_MARKET_TREASURE_CHEST_GAME_KEY_3: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3); + break; + case RC_MARKET_TREASURE_CHEST_GAME_KEY_4: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4); + break; + case RC_MARKET_TREASURE_CHEST_GAME_KEY_5: + Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); + break; + } +} + void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { case GI_VB_GIVE_ITEM_FROM_CHEST: { + EnBox* chest = static_cast(optionalArg); + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(chest->dyna.actor.id, gPlayState->sceneNum, chest->dyna.actor.params); + + // if this is a treasure chest game chest then set the appropriate rando inf + RandomizerSetChestGameRandomizerInf(rc); + Player* player = GET_PLAYER(gPlayState); player->av2.actionVar2 = 1; player->getItemId = GI_NONE; @@ -895,6 +943,32 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } void RandomizerOnSceneInitHandler(int16_t sceneNum) { + // Treasure Chest Game + // todo: for now we're just unsetting all of them, we will + // probably need to do something different when we implement shuffle + if (sceneNum == SCENE_TREASURE_BOX_SHOP) { + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4)->MarkAsNotObtained(); + Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->MarkAsNotObtained(); + } + // LACs & Prelude checks static uint32_t updateHook = 0; @@ -1035,6 +1109,17 @@ void RandomizerOnActorInitHandler(void* actorRef) { itemEtcetera->futureActionFunc = (ItemEtceteraActionFunc)ItemEtcetera_UpdateRandomizedFireArrow; break; } + case ITEM_ETC_RUPEE_GREEN_CHEST_GAME: + case ITEM_ETC_RUPEE_BLUE_CHEST_GAME: + case ITEM_ETC_RUPEE_RED_CHEST_GAME: + case ITEM_ETC_RUPEE_PURPLE_CHEST_GAME: + case ITEM_ETC_HEART_PIECE_CHEST_GAME: + case ITEM_ETC_KEY_SMALL_CHEST_GAME: { + if (rc != RC_UNKNOWN_CHECK) { + itemEtcetera->drawFunc = (ActorFunc)ItemEtcetera_DrawRandomizedItemThroughLens; + } + break; + } } } } diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 0ff2837db..39f9b7477 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -207,6 +207,11 @@ std::vector Rando::StaticData::overworldLocations = { RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, + RC_MARKET_TREASURE_CHEST_GAME_KEY_1, + RC_MARKET_TREASURE_CHEST_GAME_KEY_2, + RC_MARKET_TREASURE_CHEST_GAME_KEY_3, + RC_MARKET_TREASURE_CHEST_GAME_KEY_4, + RC_MARKET_TREASURE_CHEST_GAME_KEY_5, // Market Shops RC_MARKET_BOMBCHU_SHOP_ITEM_1, @@ -674,11 +679,16 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", "MK Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(INFTABLE_191), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", "MK Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", "MK 10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x01, "Chest Game First Room Chest", "MK Chest Game First Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x03, "Chest Game Second Room Chest", "MK Chest Game Second Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x05, "Chest Game Third Room Chest", "MK Chest Game Third Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x07, "Chest Game Fourth Room Chest", "MK Chest Game Fourth Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x09, "Chest Game Fifth Room Chest", "MK Chest Game Fifth Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game First Room Item", "MK Chest Game First Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Second Room Item", "MK Chest Game Second Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Third Room Item", "MK Chest Game Third Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Fourth Room Item", "MK Chest Game Fourth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Fifth Room Item", "MK Chest Game Fifth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game First Room Key", "MK Chest Game First Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Second Room Key", "MK Chest Game Second Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Third Room Key", "MK Chest Game Third Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Fourth Room Key", "MK Chest Game Fourth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Fifth Room Key", "MK Chest Game Fifth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); // Hyrule Castle locationTable[RC_HC_MALON_EGG] = Location::Base(RC_HC_MALON_EGG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, 0x47, "Malon Egg", "HC Malon Egg", RHT_HC_MALON_EGG, RG_WEIRD_EGG, {}, SpoilerCollectionCheck::EventChkInf(0x12), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_HC_ZELDAS_LETTER] = Location::Base(RC_HC_ZELDAS_LETTER, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, 0x0B, "Zeldas Letter", "HC Zeldas Letter", RHT_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x40), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 5d32e7a35..eb34721b5 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1649,21 +1649,28 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, RandomizerCheck specialRc = RC_UNKNOWN_CHECK; // TODO: Migrate these special cases into table, or at least document why they are special switch(sceneNum) { - case SCENE_TREASURE_BOX_SHOP: - if(actorParams == 20170) specialRc = RC_MARKET_TREASURE_CHEST_GAME_REWARD; + case SCENE_TREASURE_BOX_SHOP: { + if ((actorId == ACTOR_EN_BOX && actorParams == 20170) || (actorId == ACTOR_ITEM_ETCETERA && actorParams == 2572)) { + specialRc = RC_MARKET_TREASURE_CHEST_GAME_REWARD; + } - // RANDOTODO update logic to match 3ds rando when we implement keysanity - // keep keys og - if ((actorParams & 0x60) == 0x20) break; - - if (GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { - if((actorParams & 0xF) < 2) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_1; - if((actorParams & 0xF) < 4) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_2; - if((actorParams & 0xF) < 6) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_3; - if((actorParams & 0xF) < 8) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_4; - if((actorParams & 0xF) < 10) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_5; + // todo: handle the itemetc part of this so drawing works when we implement shuffle + if (actorId == ACTOR_EN_BOX) { + bool isAKey = (actorParams & 0x60) == 0x20; + if ((actorParams & 0xF) < 2) { + specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_1 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_1; + } else if ((actorParams & 0xF) < 4) { + specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_2 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_2; + } else if ((actorParams & 0xF) < 6) { + specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_3 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_3; + } else if ((actorParams & 0xF) < 8) { + specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_4 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_4; + } else if ((actorParams & 0xF) < 10) { + specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_5 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_5; + } } break; + } case SCENE_SACRED_FOREST_MEADOW: if (actorId == ACTOR_EN_SA) { specialRc = RC_SONG_FROM_SARIA; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 91906d127..f1d368763 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -733,6 +733,11 @@ typedef enum { RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, + RC_MARKET_TREASURE_CHEST_GAME_KEY_1, + RC_MARKET_TREASURE_CHEST_GAME_KEY_2, + RC_MARKET_TREASURE_CHEST_GAME_KEY_3, + RC_MARKET_TREASURE_CHEST_GAME_KEY_4, + RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RC_MARKET_GS_GUARD_HOUSE, RC_MARKET_BAZAAR_ITEM_1, RC_MARKET_BAZAAR_ITEM_2, @@ -2332,6 +2337,11 @@ typedef enum { RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, + RHT_MARKET_TREASURE_CHEST_GAME_KEY_1, + RHT_MARKET_TREASURE_CHEST_GAME_KEY_2, + RHT_MARKET_TREASURE_CHEST_GAME_KEY_3, + RHT_MARKET_TREASURE_CHEST_GAME_KEY_4, + RHT_MARKET_TREASURE_CHEST_GAME_KEY_5, RHT_MARKET_GS_GUARD_HOUSE, RHT_MARKET_BAZAAR_ITEM_1, RHT_MARKET_BAZAAR_ITEM_2, diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 67b396d74..14749e574 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -282,6 +282,17 @@ typedef enum { RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, RAND_INF_OGC_GREAT_FAIRY_REWARD, + RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1, + RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2, + RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3, + RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4, + RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5, + RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1, + RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2, + RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3, + RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4, + RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5, + // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) RAND_INF_MAX, diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index e4edcc1d3..2379c8ba9 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -6275,58 +6275,3 @@ s32 func_80038290(PlayState* play, Actor* actor, Vec3s* arg2, Vec3s* arg3, Vec3f return true; } - -GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, PlayState* play) { - if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { - // RANDOTODO update this logic when we implement keysanity - // because 3drando replaces the keys not the rupees - if (ogDrawId == GID_RUPEE_GREEN || - ogDrawId == GID_RUPEE_BLUE || - ogDrawId == GID_RUPEE_RED) - { - switch(room) { - case 1: - if(!Flags_GetCollectible(play, 0x1B)) { - return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, GI_RUPEE_GREEN); - } - break; - case 2: - if(!Flags_GetCollectible(play, 0x1C)) { - return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, GI_RUPEE_GREEN); - } - break; - case 3: - if(!Flags_GetCollectible(play, 0x1D)) { - return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, GI_RUPEE_BLUE); - } - break; - case 4: - if(!Flags_GetCollectible(play, 0x1E)) { - return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, GI_RUPEE_BLUE); - } - break; - case 5: - if(!Flags_GetCollectible(play, 0x1F)) { - return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, GI_RUPEE_RED); - } - break; - } - } - } - - if(ogDrawId == GID_HEART_PIECE) { - return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_REWARD, GI_HEART_PIECE); - } - - return (GetItemEntry)GET_ITEM_NONE; -} - -s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, PlayState* play) { - GetItemEntry randoGetItem = GetChestGameRandoGetItem(room, ogDrawId, play); - - if (randoGetItem.itemId != ITEM_NONE) { - return randoGetItem.gid; - } - - return ogDrawId; -} diff --git a/soh/src/overlays/actors/ovl_Door_Ana/z_door_ana.c b/soh/src/overlays/actors/ovl_Door_Ana/z_door_ana.c index 22c850111..04f388b39 100644 --- a/soh/src/overlays/actors/ovl_Door_Ana/z_door_ana.c +++ b/soh/src/overlays/actors/ovl_Door_Ana/z_door_ana.c @@ -20,7 +20,6 @@ void DoorAna_WaitClosed(DoorAna* this, PlayState* play); void DoorAna_WaitOpen(DoorAna* this, PlayState* play); void DoorAna_GrabPlayer(DoorAna* this, PlayState* play); -s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, PlayState* play); void Grotto_OverrideActorEntrance(Actor* thisx); const ActorInit Door_Ana_InitVars = { diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index 32f50d9e1..3860336ef 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -229,25 +229,19 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) { this->scale = 0.5f; this->unkFloat = 0.5f; this->actor.velocity.y = 10.0f; - if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { - switch (this->type) { - case EXITEM_GREEN_RUPEE_CHEST: - this->giDrawId = GID_RUPEE_GREEN; - break; - case EXITEM_BLUE_RUPEE_CHEST: - this->giDrawId = GID_RUPEE_BLUE; - break; - case EXITEM_RED_RUPEE_CHEST: - this->giDrawId = GID_RUPEE_RED; - break; - case EXITEM_14: - this->giDrawId = GID_RUPEE_PURPLE; - break; - } - } else { - if (play->sceneNum == SCENE_TREASURE_BOX_SHOP) { - this->giDrawId = GetChestGameRandoGiDrawId(play->roomCtx.curRoom.num, GID_RUPEE_GREEN, play); - } + switch (this->type) { + case EXITEM_GREEN_RUPEE_CHEST: + this->giDrawId = GID_RUPEE_GREEN; + break; + case EXITEM_BLUE_RUPEE_CHEST: + this->giDrawId = GID_RUPEE_BLUE; + break; + case EXITEM_RED_RUPEE_CHEST: + this->giDrawId = GID_RUPEE_RED; + break; + case EXITEM_14: + this->giDrawId = GID_RUPEE_PURPLE; + break; } this->actionFunc = EnExItem_ExitChest; break; diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index 8a26860f7..796b157a3 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -206,16 +206,6 @@ void ItemEtcetera_DrawThroughLens(Actor* thisx, PlayState* play) { if (play->actorCtx.lensActive) { func_8002EBCC(&this->actor, play, 0); func_8002ED80(&this->actor, play, 0); - - if(IS_RANDO && play->sceneNum == SCENE_TREASURE_BOX_SHOP) { - GetItemEntry randoGetItem = GetChestGameRandoGetItem(this->actor.room, this->giDrawId, play); - EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem); - if (randoGetItem.itemId != ITEM_NONE) { - GetItemEntry_Draw(play, randoGetItem); - return; - } - } - GetItem_Draw(play, this->giDrawId); } } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 7125500f7..dff81a13e 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6866,7 +6866,7 @@ s32 Player_ActionChange_2(Player* this, PlayState* play) { } func_80836898(play, this, func_8083A434); - if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_CHEST, true, &giEntry)) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_CHEST, true, chest)) { this->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE; func_8083AE40(this, giEntry.objectId); } From 63afaa3cc993254cc35c4acc92ce1f31759f09cd Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 16 Apr 2024 20:18:26 -0400 Subject: [PATCH 26/52] vb ocarina memory (#107) * Ocarina Memory Game * vb memory game --------- Co-authored-by: Taw --- .../game-interactor/GameInteractor.h | 2 ++ .../Enhancements/randomizer/hook_handlers.cpp | 8 ++++++ soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c | 27 ++++++------------- soh/src/overlays/actors/ovl_En_Skj/z_en_skj.h | 2 ++ 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 3790545fd..440a241ef 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -287,6 +287,8 @@ typedef enum { // Opt: *EnFr GI_VB_GIVE_ITEM_FROM_FROGS, // Opt: *EnSkj + GI_VB_GIVE_ITEM_FROM_OCARINA_MEMORY_GAME, + // Opt: *EnSkj GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, // Opt: *EnSyatekiMan diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index ae6beb869..47441fb31 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -27,6 +27,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Sth/z_en_sth.h" #include "src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h" #include "src/overlays/actors/ovl_En_Box/z_en_box.h" +#include "src/overlays/actors/ovl_En_Skj/z_en_skj.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -909,6 +910,13 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; break; } + case GI_VB_GIVE_ITEM_FROM_OCARINA_MEMORY_GAME: { + EnSkj* enSkj = static_cast(optionalArg); + Flags_SetItemGetInf(ITEMGETINF_17); + enSkj->actionFunc = (EnSkjActionFunc)EnSkj_CleanupOcarinaGame; + *should = false; + break; + } case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: diff --git a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c index 344a09f19..94df7a49f 100644 --- a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c +++ b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c @@ -1541,7 +1541,9 @@ void EnSkj_WaitForOfferResponse(EnSkj* this, PlayState* play) { void EnSkj_WonOcarinaMiniGame(EnSkj* this, PlayState* play) { if (D_80B01EA0) { - this->actionFunc = EnSkj_WaitToGiveReward; + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_OCARINA_MEMORY_GAME, true, this)) { + this->actionFunc = EnSkj_WaitToGiveReward; + } } else { func_8002F2CC(&this->actor, play, 26.0f); } @@ -1549,13 +1551,8 @@ void EnSkj_WonOcarinaMiniGame(EnSkj* this, PlayState* play) { void EnSkj_WaitToGiveReward(EnSkj* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - if (IS_RANDO && gSaveContext.ocarinaGameRoundNum != 3) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 26.0f, 26.0f); - } else { - Actor_OfferGetItem(&this->actor, play, sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); - } - + Actor_OfferGetItem(&this->actor, play, + sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); this->actionFunc = EnSkj_GiveOcarinaGameReward; } } @@ -1565,12 +1562,8 @@ void EnSkj_GiveOcarinaGameReward(EnSkj* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = EnSkj_FinishOcarinaGameRound; } else { - if (IS_RANDO && gSaveContext.ocarinaGameRoundNum != 3) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 26.0f, 26.0f); - } else { - Actor_OfferGetItem(&this->actor, play, sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); - } + Actor_OfferGetItem(&this->actor, play, + sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); } } @@ -1582,11 +1575,7 @@ void EnSkj_FinishOcarinaGameRound(EnSkj* this, PlayState* play) { gSaveContext.ocarinaGameRoundNum++; } - if (IS_RANDO) { - gSaveContext.ocarinaGameRoundNum = 3; - } - - if (ocarinaGameRoundNum == 2 || IS_RANDO) { + if (ocarinaGameRoundNum == 2) { Flags_SetItemGetInf(ITEMGETINF_17); this->actionFunc = EnSkj_CleanupOcarinaGame; } else { diff --git a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.h b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.h index bc8febcd4..3f8b75ba2 100644 --- a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.h +++ b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.h @@ -37,4 +37,6 @@ typedef struct EnSkj { /* 0x02F4 */ Vec3f posCopy; } EnSkj; // size = 0x0300 +void EnSkj_CleanupOcarinaGame(EnSkj* enSkj, PlayState* play); + #endif From 60d74f720a0c9b032b1f4bbd7392b95102da01f3 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 16 Apr 2024 20:28:20 -0400 Subject: [PATCH 27/52] vb richard (#108) * Lost Dog + Custom Hook Handler * vb richard * fix the merge --------- Co-authored-by: Taw --- .../game-interactor/GameInteractor.h | 2 + .../Enhancements/randomizer/hook_handlers.cpp | 10 ++++ soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c | 54 +++++++------------ soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h | 2 + 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 440a241ef..a4054f2cb 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -303,6 +303,8 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY, // Opt: *EnSth GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, + // Opt: *EnHy + GI_VB_GIVE_ITEM_FROM_LOST_DOG, GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 47441fb31..dcc36873a 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -28,6 +28,7 @@ extern "C" { #include "src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h" #include "src/overlays/actors/ovl_En_Box/z_en_box.h" #include "src/overlays/actors/ovl_En_Skj/z_en_skj.h" +#include "src/overlays/actors/ovl_En_Hy/z_en_hy.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -917,6 +918,15 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; break; } + case GI_VB_GIVE_ITEM_FROM_LOST_DOG: { + EnHy* enHy = static_cast(optionalArg); + Flags_SetInfTable(INFTABLE_191); + gSaveContext.dogParams = 0; + gSaveContext.dogIsLost = false; + enHy->actionFunc = func_80A7127C; + *should = false; + break; + } case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index 6d8640f3f..adb50441e 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -14,6 +14,7 @@ #include "objects/object_cne/object_cne.h" #include "objects/object_cob/object_cob.h" #include "objects/object_os_anime/object_os_anime.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -659,19 +660,10 @@ s16 func_80A70058(PlayState* play, Actor* thisx) { gSaveContext.dogParams = 0; break; case 0x709F: - if (Flags_GetInfTable(INFTABLE_191)) { // Already brought the lost dog back - func_80A6F7CC(this, play, GI_RUPEE_BLUE); - } else { - if (!IS_RANDO) { - func_80A6F7CC(this, play, GI_HEART_PIECE); - } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_LOST_DOG, GI_HEART_PIECE); - // The follownig line and last arguments of GiveItemEntryFromActor are copied from func_80A6F7CC - this->unkGetItemId = this->getItemEntry.getItemId; - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); - } + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_LOST_DOG, true, this)) { + func_80A6F7CC(this, play, Flags_GetInfTable(INFTABLE_191) ? GI_RUPEE_BLUE : GI_HEART_PIECE); + this->actionFunc = func_80A714C4; } - this->actionFunc = func_80A714C4; break; } return NPC_TALK_STATE_IDLE; @@ -1068,36 +1060,26 @@ void func_80A714C4(EnHy* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actionFunc = func_80A71530; } else { - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - Actor_OfferGetItem(&this->actor, play, this->unkGetItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); - } + Actor_OfferGetItem(&this->actor, play, this->unkGetItemId, this->actor.xzDistToPlayer + 1.0f, + fabsf(this->actor.yDistToPlayer) + 1.0f); } } void func_80A71530(EnHy* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - if (IS_RANDO) { - if (!Flags_GetInfTable(INFTABLE_191)) { - Flags_SetInfTable(INFTABLE_191); - } - gSaveContext.dogParams = 0; - gSaveContext.dogIsLost = false; - } else { - switch (this->unkGetItemId) { - case GI_HEART_PIECE: - gSaveContext.dogParams = 0; - gSaveContext.dogIsLost = false; - Flags_SetInfTable(INFTABLE_191); - break; - case GI_RUPEE_BLUE: - Rupees_ChangeBy(5); - gSaveContext.dogParams = 0; - gSaveContext.dogIsLost = false; - break; - } + switch (this->unkGetItemId) { + case GI_HEART_PIECE: + gSaveContext.dogParams = 0; + gSaveContext.dogIsLost = false; + SET_INFTABLE(INFTABLE_191); + break; + case GI_RUPEE_BLUE: + Rupees_ChangeBy(5); + gSaveContext.dogParams = 0; + gSaveContext.dogIsLost = false; + break; } + this->actionFunc = func_80A7127C; } } diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h index 6a5ed2680..7d94a5ca6 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h @@ -62,4 +62,6 @@ typedef struct EnHy { /* */ GetItemEntry getItemEntry; } EnHy; // size = 0x0334 +void func_80A7127C(EnHy* enHy, PlayState* play); + #endif From 84db4c8ab807112bd8931c7cf78f46da61c1b583 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:02:16 -0400 Subject: [PATCH 28/52] vb beehives (#109) * vb beehives * format --- .../Enhancements/randomizer/hook_handlers.cpp | 78 ++++++++++++++++++- .../overlays/actors/ovl_Obj_Comb/z_obj_comb.c | 29 +------ .../overlays/actors/ovl_Obj_Comb/z_obj_comb.h | 2 + 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index dcc36873a..f1715c8eb 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -29,6 +29,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Box/z_en_box.h" #include "src/overlays/actors/ovl_En_Skj/z_en_skj.h" #include "src/overlays/actors/ovl_En_Hy/z_en_hy.h" +#include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -599,7 +600,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void case GI_VB_GIVE_ITEM_FROM_ITEM_00: { EnItem00* item00 = static_cast(optionalArg); if (item00->actor.params == ITEM00_SOH_DUMMY) { - Flags_SetCollectible(gPlayState, item00->collectibleFlag); + if (item00->randoInf != RAND_INF_MAX) { + Flags_SetRandomizerInf(item00->randoInf); + } else { + Flags_SetCollectible(gPlayState, item00->collectibleFlag); + } Actor_Kill(&item00->actor); *should = false; } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY) { @@ -1043,6 +1048,70 @@ void EnDns_RandomizerPurchase(EnDns* enDns) { Flags_SetRandomizerInf(enDns->sohScrubIdentity.randomizerInf); } +void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) { + s16 params = objComb->actor.params & 0x1F; + + if ( + RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && + !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf) + ) { + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &objComb->actor.world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = objComb->beehiveIdentity.randomizerInf; + item00->itemEntry = OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(objComb->beehiveIdentity.randomizerCheck, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + return; + } + + if ((params > 0) || (params < 0x1A)) { + if (params == 6) { + if (Flags_GetCollectible(play, (objComb->actor.params >> 8) & 0x3F)) { + params = -1; + } else { + params = (params | (((objComb->actor.params >> 8) & 0x3F) << 8)); + } + } else if (Rand_ZeroOne() < 0.5f) { + params = -1; + } + if (params >= 0 && !CVarGetInteger("gNoRandomDrops", 0)) { + Item_DropCollectible(play, &objComb->actor.world.pos, params); + } + } +} + +void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { + s32 dmgFlags; + + objComb->unk_1B0 -= 50; + if ( + RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && + !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf) + ) { + if (objComb->unk_1B0 <= -5000) { + objComb->unk_1B0 = 1500; + } + } else if (objComb->unk_1B0 < 0) { + objComb->unk_1B0 = 0; + } + + if ((objComb->collider.base.acFlags & AC_HIT) != 0) { + objComb->collider.base.acFlags &= ~AC_HIT; + dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags; + if (dmgFlags & 0x4001F866) { + objComb->unk_1B0 = 1500; + } else { + ObjComb_Break(objComb, play); + ObjComb_RandomizerChooseItemDrop(objComb, play); + Actor_Kill(&objComb->actor); + } + } else { + CollisionCheck_SetAC(play, &play->colChkCtx, &objComb->collider.base); + } + + if (objComb->actor.update != NULL) { + CollisionCheck_SetOC(play, &play->colChkCtx, &objComb->collider.base); + } +} + void RandomizerOnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); @@ -1140,6 +1209,13 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } } + + if (actor->id == ACTOR_OBJ_COMB) { + ObjComb* objComb = static_cast(actorRef); + s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); + objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive(gPlayState->sceneNum, (s16)actor->world.pos.x, respawnData); + objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait; + } } void RandomizerRegisterHooks() { diff --git a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c index 0dde415e0..e17de7597 100644 --- a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c +++ b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c @@ -132,21 +132,6 @@ void ObjComb_Break(ObjComb* this, PlayState* play) { void ObjComb_ChooseItemDrop(ObjComb* this, PlayState* play) { s16 params = this->actor.params & 0x1F; - if ( - IS_RANDO && - Randomizer_GetSettingValue(RSK_SHUFFLE_BEEHIVES) && - !Flags_GetRandomizerInf(this->beehiveIdentity.randomizerInf) - ) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(this->beehiveIdentity.randomizerCheck, GI_NONE); - - EnItem00* actor = (EnItem00*)Item_DropCollectible2(play, &this->actor.world.pos, ITEM00_SMALL_KEY); - actor->randoCheck = this->beehiveIdentity.randomizerCheck; - actor->randoGiEntry = getItemEntry; - actor->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - actor->randoInf = this->beehiveIdentity.randomizerInf; - return; - } - if ((params > 0) || (params < 0x1A)) { if (params == 6) { if (Flags_GetCollectible(play, (this->actor.params >> 8) & 0x3F)) { @@ -170,10 +155,6 @@ void ObjComb_Init(Actor* thisx, PlayState* play) { Collider_InitJntSph(play, &this->collider); Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->colliderItems); ObjComb_SetupWait(this); - if (IS_RANDO) { - s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - this->beehiveIdentity = Randomizer_IdentifyBeehive(play->sceneNum, (s16)this->actor.world.pos.x, respawnData); - } } void ObjComb_Destroy(Actor* thisx, PlayState* play2) { @@ -191,15 +172,7 @@ void ObjComb_Wait(ObjComb* this, PlayState* play) { s32 dmgFlags; this->unk_1B0 -= 50; - if ( - IS_RANDO && - Randomizer_GetSettingValue(RSK_SHUFFLE_BEEHIVES) && - !Flags_GetRandomizerInf(this->beehiveIdentity.randomizerInf) - ) { - if (this->unk_1B0 <= -5000) { - this->unk_1B0 = 1500; - } - } else if (this->unk_1B0 < 0) { + if (this->unk_1B0 < 0) { this->unk_1B0 = 0; } diff --git a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h index f7713a961..ded72dfc4 100644 --- a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h +++ b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h @@ -18,4 +18,6 @@ typedef struct ObjComb { /* */ BeehiveIdentity beehiveIdentity; } ObjComb; // size = 0x01B4 +void ObjComb_Break(ObjComb* objComb, PlayState* play); + #endif From f6a583446b21cd0f338a718d13700c1602036da7 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 17 Apr 2024 20:49:29 -0400 Subject: [PATCH 29/52] vb bombchu bowling (#110) * vb bombchu bowling * don't need it * it's drawing the right thing but it's tiny * scale * no need to should, don't rescale every draw * slightly safer --- .../game-interactor/GameInteractor.h | 2 + .../Enhancements/randomizer/hook_handlers.cpp | 59 +++++++++++++++++++ .../ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c | 35 ++--------- .../ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h | 1 - .../actors/ovl_En_Ex_Item/z_en_ex_item.c | 48 ++------------- .../actors/ovl_En_Ex_Item/z_en_ex_item.h | 5 ++ 6 files changed, 75 insertions(+), 75 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index a4054f2cb..89d2467c6 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -305,6 +305,8 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, // Opt: *EnHy GI_VB_GIVE_ITEM_FROM_LOST_DOG, + // Opt: *EnBomBowlPit + GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING, GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index f1715c8eb..07f2ecb54 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -30,6 +30,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Skj/z_en_skj.h" #include "src/overlays/actors/ovl_En_Hy/z_en_hy.h" #include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h" +#include "src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -256,6 +257,30 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { } } +void EnExItem_DrawRandomizedItem(EnExItem* enExItem, PlayState* play) { + func_8002ED80(&enExItem->actor, play, 0); + EnItem00_CustomItemsParticles(&enExItem->actor, play, enExItem->sohItemEntry); + GetItemEntry_Draw(play, enExItem->sohItemEntry); +} + +void EnExItem_WaitForObjectRandomized(EnExItem* enExItem, PlayState* play) { + EnExItem_WaitForObject(enExItem, play); + if (Object_IsLoaded(&play->objectCtx, enExItem->objectIdx)) { + enExItem->actor.draw = (ActorFunc)EnExItem_DrawRandomizedItem; + Actor_SetScale(&enExItem->actor, enExItem->scale); + + // for now we're just using this to not have items float + // below the bowling counter, but it would be nice to use + // this to not draw gigantic skull tokens etc. + switch (enExItem->type) { + case EXITEM_BOMB_BAG_COUNTER: { + enExItem->actor.shape.yOffset = -10.0f; + break; + } + } + } +} + void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play) { f32 mtxScale = CVarGetFloat("gTimeSavers.SkipGetItemAnimationScale", 10.0f); Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); @@ -932,6 +957,13 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; break; } + case GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING: { + EnBomBowlPit* enBomBowlPit = static_cast(optionalArg); + if (enBomBowlPit->prizeIndex == EXITEM_BOMB_BAG_BOWLING || enBomBowlPit->prizeIndex == EXITEM_HEART_PIECE_BOWLING) { + *should = false; + } + break; + } case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: @@ -1216,6 +1248,33 @@ void RandomizerOnActorInitHandler(void* actorRef) { objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive(gPlayState->sceneNum, (s16)actor->world.pos.x, respawnData); objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait; } + + if (actor->id == ACTOR_EN_EX_ITEM) { + EnExItem* enExItem = static_cast(actorRef); + + RandomizerCheck rc = RC_UNKNOWN_CHECK; + switch (enExItem->type) { + case EXITEM_BOMB_BAG_COUNTER: + case EXITEM_BOMB_BAG_BOWLING: + rc = RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE; + break; + case EXITEM_HEART_PIECE_COUNTER: + case EXITEM_HEART_PIECE_BOWLING: + rc = RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE; + break; + case EXITEM_BOMBCHUS_COUNTER: + case EXITEM_BOMBCHUS_BOWLING: + rc = RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS; + break; + case EXITEM_BULLET_BAG: + rc = RC_LW_TARGET_IN_WOODS; + break; + } + if (rc != RC_UNKNOWN_CHECK) { + enExItem->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + enExItem->actionFunc = (EnExItemActionFunc)EnExItem_WaitForObjectRandomized; + } + } } void RandomizerRegisterHooks() { diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c index 232b096f9..7e5cc3ef1 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c @@ -2,6 +2,7 @@ #include "vt.h" #include "overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h" #include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -177,56 +178,30 @@ void EnBomBowlPit_GivePrize(EnBomBowlPit* this, PlayState* play) { Player_SetCsActionWithHaltedActors(play, NULL, 7); this->getItemId = sGetItemIds[this->prizeIndex]; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; if ((this->getItemId == GI_BOMB_BAG_30) && (CUR_CAPACITY(UPG_BOMB_BAG) == 30)) { this->getItemId = GI_BOMB_BAG_40; } - if (IS_RANDO) { - switch (this->prizeIndex) { - case EXITEM_BOMB_BAG_BOWLING: - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); - this->getItemId = this->getItemEntry.getItemId; - break; - case EXITEM_HEART_PIECE_BOWLING: - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); - this->getItemId = this->getItemEntry.getItemId; - break; - case EXITEM_BOMBCHUS_BOWLING: - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); - this->getItemId = this->getItemEntry.getItemId; - break; - } - } - player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; this->actor.parent = NULL; - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING, true, this)) { Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f); } player->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; this->actionFunc = EnBomBowlPit_WaitTillPrizeGiven; } void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING, true, this)) { this->actionFunc = EnBomBowlPit_Reset; } else { - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f); - } + Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); } } void EnBomBowlPit_Reset(EnBomBowlPit* this, PlayState* play) { - if (((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && - Message_ShouldAdvance(play)) || - (IS_RANDO && this->getItemId == GI_ICE_TRAP)) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { // "Normal termination"/"completion" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST); if (this->getItemId == GI_HEART_PIECE) { diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h index 97ff39ac8..48cfbd5c2 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h @@ -33,7 +33,6 @@ typedef struct EnBomBowlPit { /* 0x01D4 */ Vec3f unk_1D4; // camera eye (maxsteps) /* 0x01E0 */ EnExItem* exItem; /* 0x01E4 */ char unk_1E4[0x3520]; - /* */ GetItemEntry getItemEntry; } EnBomBowlPit; // size = 0x3704 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index 3860336ef..28e89036d 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -138,12 +138,7 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) { onCounter = true; case EXITEM_BOMB_BAG_BOWLING: this->unk_17C = func_8002EBCC; - if (IS_RANDO) { - this->giDrawId = - Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20).gid; - } else { - this->giDrawId = GID_BOMB_BAG_30; - } + this->giDrawId = GID_BOMB_BAG_30; this->timer = 65; this->prizeRotateTimer = 35; this->scale = 0.5f; @@ -151,7 +146,7 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) { this->actionFunc = EnExItem_BowlPrize; } else { this->actionFunc = EnExItem_SetupBowlCounter; - this->actor.shape.yOffset = IS_RANDO ? -10.0f : -18.0f; + this->actor.shape.yOffset = -18.0f; } break; case EXITEM_HEART_PIECE_COUNTER: @@ -173,11 +168,7 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) { onCounter = true; case EXITEM_BOMBCHUS_BOWLING: this->unk_17C = func_8002EBCC; - if (IS_RANDO) { - this->giDrawId = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10).gid; - } else { - this->giDrawId = GID_BOMBCHU; - } + this->giDrawId = GID_BOMBCHU; this->timer = 65; this->prizeRotateTimer = 35; this->scale = 0.5f; @@ -496,43 +487,12 @@ void EnExItem_DrawItems(EnExItem* this, PlayState* play) { } if (this) {} func_8002ED80(&this->actor, play, 0); - if (IS_RANDO) { - GetItemEntry randoGetItem = (GetItemEntry)GET_ITEM_NONE; - switch (this->type) { - case EXITEM_BOMB_BAG_BOWLING: - case EXITEM_BOMB_BAG_COUNTER: - randoGetItem = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); - break; - case EXITEM_BOMBCHUS_BOWLING: - case EXITEM_BOMBCHUS_COUNTER: - randoGetItem = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); - break; - case EXITEM_BULLET_BAG: - randoGetItem = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); - break; - } - - if (randoGetItem.getItemId != GI_NONE) { - EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem); - GetItemEntry_Draw(play, randoGetItem); - return; - } - } - GetItem_Draw(play, this->giDrawId); } void EnExItem_DrawHeartPiece(EnExItem* this, PlayState* play) { func_8002ED80(&this->actor, play, 0); - - if (IS_RANDO) { - GetItemEntry randoGetItem = - Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); - EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem); - GetItemEntry_Draw(play, randoGetItem); - } else { - GetItem_Draw(play, GID_HEART_PIECE); - } + GetItem_Draw(play, GID_HEART_PIECE); } void EnExItem_DrawMagic(EnExItem* this, PlayState* play, s16 magicIndex) { diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h index d014e19be..090d7028c 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h @@ -27,6 +27,9 @@ typedef struct EnExItem { /* 0x0170 */ Vec3f initPos; // unused /* 0x017C */ EnExItemLightFunc unk_17C; /* 0x0180 */ EnExItemLightFunc unk_180; + // #region SOH [Randomizer] Caching the get item entry for the draw function for performance + /* */ GetItemEntry sohItemEntry; + // #endregion } EnExItem; // size = 0x0184 typedef enum { @@ -52,6 +55,8 @@ typedef enum { /* 19 */ EXITEM_BULLET_BAG } EnExItemType; +void EnExItem_WaitForObject(EnExItem* enExItem, PlayState* play); + #define EXITEM_COUNTER 5 #define EXITEM_CHEST 10 #define EXITEM_MAGIC 16 From 54b15051371561df1344257b6be9c946afbcfbda Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 17 Apr 2024 21:17:00 -0400 Subject: [PATCH 30/52] vb gerudo (#111) * vb gerudo * clean up --- .../game-interactor/GameInteractor.h | 6 ++++ .../randomizer/3drando/spoiler_log.hpp | 1 - .../Enhancements/randomizer/hook_handlers.cpp | 32 +++++++++++++++++++ soh/soh/Enhancements/randomizer/location.h | 4 --- .../Enhancements/randomizer/location_list.cpp | 2 +- .../randomizer/randomizer_check_tracker.cpp | 2 -- .../Enhancements/randomizer/randomizer_inf.h | 2 ++ .../ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c | 17 ++-------- soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c | 23 +++---------- soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h | 2 ++ soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c | 31 +++++------------- soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c | 15 +++------ 12 files changed, 63 insertions(+), 74 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 89d2467c6..a3d7e9045 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -212,6 +212,10 @@ typedef enum { // Opt: *BgDyYoseizo // Vanilla condition: see soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c GI_VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD, + // Vanilla condition: see CheckCarpentersFreed in z_en_ge1 and z_en_ge2 + GI_VB_GERUDOS_BE_FRIENDLY, + // Vanilla condition: switch + GI_VB_GTG_GATE_BE_OPEN, /*** Play Cutscenes ***/ @@ -308,6 +312,8 @@ typedef enum { // Opt: *EnBomBowlPit GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING, + GI_VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD, + GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, GI_VB_GIVE_ITEM_LIGHT_ARROW, diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp index 7e20b176a..89b9d36bc 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp @@ -20,7 +20,6 @@ typedef enum { SPOILER_CHK_INF_TABLE, SPOILER_CHK_FISH, SPOILER_CHK_MINIGAME, - SPOILER_CHK_GERUDO_MEMBERSHIP_CARD, SPOILER_CHK_POE_POINTS, SPOILER_CHK_SHOP_ITEM, SPOILER_CHK_MASTER_SWORD, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 07f2ecb54..f8e1c5020 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -31,6 +31,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Hy/z_en_hy.h" #include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h" #include "src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h" +#include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -135,6 +136,13 @@ void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { } void RandomizerOnSceneFlagSetHandler(int16_t sceneNum, int16_t flagType, int16_t flag) { + if (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF && + sceneNum == SCENE_GERUDOS_FORTRESS && + flagType == FLAG_SCENE_SWITCH && + flag == 0x3A) { + Flags_SetRandomizerInf(RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN); + } + RandomizerCheck rc = GetRandomizerCheckFromSceneFlag(sceneNum, flagType, flag); if (rc == RC_UNKNOWN_CHECK) return; @@ -964,6 +972,21 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } break; } + case GI_VB_GERUDOS_BE_FRIENDLY: { + *should = CHECK_QUEST_ITEM(QUEST_GERUDO_CARD); + break; + } + case GI_VB_GTG_GATE_BE_OPEN: { + if (Flags_GetRandomizerInf(RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN)) { + *should = true; + } + break; + } + case GI_VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD: { + Flags_SetRandomizerInf(RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS); + *should = false; + break; + } case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: @@ -1275,6 +1298,15 @@ void RandomizerOnActorInitHandler(void* actorRef) { enExItem->actionFunc = (EnExItemActionFunc)EnExItem_WaitForObjectRandomized; } } + + if (actor->id == ACTOR_EN_GE1) { + EnGe1* enGe1 = static_cast(actorRef); + auto ge1Type = enGe1->actor.params & 0xFF; + if (ge1Type == GE1_TYPE_TRAINING_GROUNDS_GUARD && + Flags_GetRandomizerInf(RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN)) { + enGe1->actionFunc = (EnGe1ActionFunc)EnGe1_SetNormalText; + } + } } void RandomizerRegisterHooks() { diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index a962e4501..1731067cf 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -59,10 +59,6 @@ class SpoilerCollectionCheck { return SpoilerCollectionCheck(SPOILER_CHK_MINIGAME, 0x00, bit); } - static auto GerudoToken() { - return SpoilerCollectionCheck(SPOILER_CHK_GERUDO_MEMBERSHIP_CARD, 0x00, 0x00); - } - static auto BigPoePoints() { return SpoilerCollectionCheck(SPOILER_CHK_POE_POINTS, 0x00, 0x00); } diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 39f9b7477..1dfa2f5e4 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -659,7 +659,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x3E, "GF HBA 1000 Points", "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(INFTABLE_190), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); locationTable[RC_GF_HBA_1500_POINTS] = Location::Base(RC_GF_HBA_1500_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x30, "GF HBA 1500 Points", "GF HBA 1500 Points", RHT_GF_HBA_1500_POINTS, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(15), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); // RandoTodo: Do we replace these with the RC_HIDEOUT keys or keep these? - locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, 0x3A, "GF Gerudo Membership Card", "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::GerudoToken(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, 0x3A, "GF Gerudo Membership Card", "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); locationTable[RC_GF_NORTH_F1_CARPENTER] = Location::Collectable(RC_GF_NORTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3089, 0x0C, "GF North F1 Carpenter", "GF North F1 Carpenter", RHT_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); locationTable[RC_GF_NORTH_F2_CARPENTER] = Location::Collectable(RC_GF_NORTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 2577, 0x0A, "GF North F2 Carpenter", "GF North F2 Carpenter", RHT_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); locationTable[RC_GF_SOUTH_F1_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3601, 0x0E, "GF South F1 Carpenter", "GF South F1 Carpenter", RHT_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 7c5b63c37..fda9d717d 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -426,8 +426,6 @@ bool HasItemBeenCollected(RandomizerCheck rc) { return Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc)); case SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF: return gSaveContext.eventChkInf[flag / 16] & (0x01 << flag % 16); - case SpoilerCollectionCheckType::SPOILER_CHK_GERUDO_MEMBERSHIP_CARD: - return CHECK_FLAG_ALL(gSaveContext.eventChkInf[0x09], 0x0F); case SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA: return GET_GS_FLAGS(scene) & flag; case SpoilerCollectionCheckType::SPOILER_CHK_INF_TABLE: diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 14749e574..465f5316c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -293,6 +293,8 @@ typedef enum { RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4, RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5, + RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS, + RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN, // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) RAND_INF_MAX, diff --git a/soh/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c b/soh/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c index 519767534..6d65c049f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c @@ -6,6 +6,7 @@ #include "z_bg_spot12_saku.h" #include "objects/object_spot12_obj/object_spot12_obj.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -58,15 +59,9 @@ void func_808B3420(BgSpot12Saku* this, PlayState* play, CollisionHeader* collisi void BgSpot12Saku_Init(Actor* thisx, PlayState* play) { BgSpot12Saku* this = (BgSpot12Saku*)thisx; - // If ER is on, force the gate to always use its permanent flag - // (which it only uses in Child Gerudo Fortress in the vanilla game) - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) { - thisx->params = 0x0002; - } - func_808B3420(this, play, &gGerudoFortressGTGShutterCol, DPM_UNK); Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { + if (GameInteractor_Should(GI_VB_GTG_GATE_BE_OPEN, Flags_GetSwitch(play, this->dyna.actor.params & 0x3F), NULL)) { func_808B3714(this); } else { func_808B3550(this); @@ -87,7 +82,7 @@ void func_808B3550(BgSpot12Saku* this) { } void func_808B357C(BgSpot12Saku* this, PlayState* play) { - if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { + if (GameInteractor_Should(GI_VB_GTG_GATE_BE_OPEN, Flags_GetSwitch(play, this->dyna.actor.params & 0x3F), NULL)) { func_808B35E4(this); this->timer = 20; OnePointCutscene_Init(play, 4170, -99, &this->dyna.actor, MAIN_CAM); @@ -131,12 +126,6 @@ void func_808B37AC(BgSpot12Saku* this, PlayState* play) { void BgSpot12Saku_Update(Actor* thisx, PlayState* play) { BgSpot12Saku* this = (BgSpot12Saku*)thisx; - // If ER is on, when the guard opens the GtG gate its permanent flag will be set. - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF && - Flags_GetSwitch(play, 0x3A)) { - Flags_SetSwitch(play, 0x2); - } - if (this->timer > 0) { this->timer--; } diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index 995e3d5fd..2086e528f 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -134,7 +134,7 @@ void EnGe1_Init(Actor* thisx, PlayState* play) { case GE1_TYPE_GATE_OPERATOR: this->hairstyle = GE1_HAIR_STRAIGHT; - if (EnGe1_CheckCarpentersFreed()) { + if (GameInteractor_Should(GI_VB_GERUDOS_BE_FRIENDLY, EnGe1_CheckCarpentersFreed(), NULL)) { this->actionFunc = EnGe1_CheckGate_GateOp; } else { this->actionFunc = EnGe1_WatchForPlayerFrontOnly; @@ -144,7 +144,7 @@ void EnGe1_Init(Actor* thisx, PlayState* play) { case GE1_TYPE_NORMAL: this->hairstyle = GE1_HAIR_STRAIGHT; - if (EnGe1_CheckCarpentersFreed()) { + if (GameInteractor_Should(GI_VB_GERUDOS_BE_FRIENDLY, EnGe1_CheckCarpentersFreed(), NULL)) { this->actionFunc = EnGe1_SetNormalText; } else { this->actionFunc = EnGe1_WatchForAndSensePlayer; @@ -174,7 +174,7 @@ void EnGe1_Init(Actor* thisx, PlayState* play) { if (gSaveContext.eventInf[0] & 0x100) { this->actionFunc = EnGe1_TalkAfterGame_Archery; - } else if (EnGe1_CheckCarpentersFreed()) { + } else if (GameInteractor_Should(GI_VB_GERUDOS_BE_FRIENDLY, EnGe1_CheckCarpentersFreed(), NULL)) { this->actionFunc = EnGe1_Wait_Archery; } else { this->actionFunc = EnGe1_WatchForPlayerFrontOnly; @@ -184,13 +184,8 @@ void EnGe1_Init(Actor* thisx, PlayState* play) { case GE1_TYPE_TRAINING_GROUNDS_GUARD: this->hairstyle = GE1_HAIR_STRAIGHT; - if (EnGe1_CheckCarpentersFreed()) { - // If the gtg gate is permanently open, don't let the gaurd charge to open it again - if (IS_RANDO && gSaveContext.sceneFlags[93].swch & 0x00000004) { - this->actionFunc = EnGe1_SetNormalText; - } else { - this->actionFunc = EnGe1_CheckForCard_GTGGuard; - } + if (GameInteractor_Should(GI_VB_GERUDOS_BE_FRIENDLY, EnGe1_CheckCarpentersFreed(), NULL)) { + this->actionFunc = EnGe1_CheckForCard_GTGGuard; } else { this->actionFunc = EnGe1_WatchForPlayerFrontOnly; } @@ -236,14 +231,6 @@ void EnGe1_SetAnimationIdle(EnGe1* this) { } s32 EnGe1_CheckCarpentersFreed(void) { - if (IS_RANDO) { - if (CHECK_QUEST_ITEM(QUEST_GERUDO_CARD)) { - return 1; - } else { - return 0; - } - } - u16 carpenterFlags = gSaveContext.eventChkInf[9]; if (!((carpenterFlags & 1) && (carpenterFlags & 2) && (carpenterFlags & 4) && (carpenterFlags & 8))) { return 0; diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h index 1851fdbce..afb57fb41 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h @@ -57,4 +57,6 @@ typedef struct EnGe1 { /* 0x02B8 */ EnGe1AnimFunc animFunc; } EnGe1; // size = 0x02BC +void EnGe1_SetNormalText(EnGe1* enGe1, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c index 5602dd883..0b5b9c09e 100644 --- a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -8,6 +8,7 @@ #include "vt.h" #include "objects/object_gla/object_gla.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -139,14 +140,14 @@ void EnGe2_Init(Actor* thisx, PlayState* play) { switch (this->actor.params & 0xFF) { case GE2_TYPE_PATROLLING: EnGe2_ChangeAction(this, GE2_ACTION_WALK); - if (EnGe2_CheckCarpentersFreed()) { + if (GameInteractor_Should(GI_VB_GERUDOS_BE_FRIENDLY, EnGe2_CheckCarpentersFreed(), NULL)) { this->actor.update = EnGe2_UpdateFriendly; this->actor.targetMode = 6; } break; case GE2_TYPE_STATIONARY: EnGe2_ChangeAction(this, GE2_ACTION_STAND); - if (EnGe2_CheckCarpentersFreed()) { + if (GameInteractor_Should(GI_VB_GERUDOS_BE_FRIENDLY, EnGe2_CheckCarpentersFreed(), NULL)) { this->actor.update = EnGe2_UpdateFriendly; this->actor.targetMode = 6; } @@ -227,14 +228,6 @@ s32 Ge2_DetectPlayerInUpdate(PlayState* play, EnGe2* this, Vec3f* pos, s16 yRot, } s32 EnGe2_CheckCarpentersFreed(void) { - if (IS_RANDO) { - if (CHECK_QUEST_ITEM(QUEST_GERUDO_CARD)) { - return 1; - } else { - return 0; - } - } - if (CHECK_FLAG_ALL(gSaveContext.eventChkInf[EVENTCHKINF_CARPENTERS_FREE_INDEX] & (EVENTCHKINF_CARPENTERS_FREE_MASK_ALL | 0xF0), EVENTCHKINF_CARPENTERS_FREE_MASK_ALL)) { @@ -467,16 +460,11 @@ void EnGe2_WaitLookAtPlayer(EnGe2* this, PlayState* play) { } void EnGe2_WaitTillCardGiven(EnGe2* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD, true, NULL)) { this->actor.parent = NULL; this->actionFunc = EnGe2_SetActionAfterTalk; } else { - if (!IS_RANDO) { - Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - } + Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); } } @@ -485,11 +473,8 @@ void EnGe2_GiveCard(EnGe2* this, PlayState* play) { Message_CloseTextbox(play); this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; this->actionFunc = EnGe2_WaitTillCardGiven; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD, true, NULL)) { Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } } } @@ -620,7 +605,7 @@ void EnGe2_Update(Actor* thisx, PlayState* play) { } EnGe2_MoveAndBlink(this, play); - if (EnGe2_CheckCarpentersFreed() && !(this->stateFlags & GE2_STATE_KO)) { + if (GameInteractor_Should(GI_VB_GERUDOS_BE_FRIENDLY, EnGe2_CheckCarpentersFreed(), NULL) && !(this->stateFlags & GE2_STATE_KO)) { this->actor.update = EnGe2_UpdateFriendly; this->actor.targetMode = 6; } @@ -645,7 +630,7 @@ void EnGe2_UpdateStunned(Actor* thisx, PlayState* play2) { } CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); - if (EnGe2_CheckCarpentersFreed()) { + if (GameInteractor_Should(GI_VB_GERUDOS_BE_FRIENDLY, EnGe2_CheckCarpentersFreed(), NULL)) { this->actor.update = EnGe2_UpdateFriendly; this->actor.targetMode = 6; this->actor.colorFilterTimer = 0; diff --git a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c index aaa198060..1265ba51e 100644 --- a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c +++ b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c @@ -6,6 +6,7 @@ #include "z_en_ge3.h" #include "objects/object_geldb/object_geldb.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -140,16 +141,11 @@ void EnGe3_WaitLookAtPlayer(EnGe3* this, PlayState* play) { } void EnGe3_WaitTillCardGiven(EnGe3* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD, true, NULL)) { this->actor.parent = NULL; this->actionFunc = EnGe3_Wait; } else { - if (!IS_RANDO) { - Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - } + Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); } } @@ -158,11 +154,8 @@ void EnGe3_GiveCard(EnGe3* this, PlayState* play) { Message_CloseTextbox(play); this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; this->actionFunc = EnGe3_WaitTillCardGiven; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD, true, NULL)) { Actor_OfferGetItem(&this->actor, play, GI_GERUDO_CARD, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } } } From edf6d9334a7a6f275e18c8d448a1ae64e4faa8e6 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 18 Apr 2024 20:42:25 -0500 Subject: [PATCH 31/52] Migrate ganon trials --- .../Enhancements/debugger/debugSaveEditor.h | 7 -- .../Enhancements/randomizer/hook_handlers.cpp | 15 ++++ .../Enhancements/randomizer/randomizer.cpp | 28 +++---- soh/soh/Enhancements/randomizer/randomizer.h | 2 +- .../Enhancements/randomizer/randomizer_inf.h | 7 -- soh/soh/Enhancements/randomizer/savefile.cpp | 13 ++- soh/soh/OTRGlobals.cpp | 4 +- soh/soh/OTRGlobals.h | 2 +- .../actors/ovl_Demo_Kekkai/z_demo_kekkai.c | 80 +++---------------- .../ovl_Object_Kankyo/z_object_kankyo.c | 21 ----- 10 files changed, 48 insertions(+), 131 deletions(-) diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index ff9f9bf8f..047df95f8 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -358,13 +358,6 @@ const std::vector flagTables = { { RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" }, { RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" }, - { RAND_INF_TRIALS_DONE_LIGHT_TRIAL, "TRIALS_DONE_LIGHT_TRIAL" }, - { RAND_INF_TRIALS_DONE_FOREST_TRIAL, "TRIALS_DONE_FOREST_TRIAL" }, - { RAND_INF_TRIALS_DONE_FIRE_TRIAL, "TRIALS_DONE_FIRE_TRIAL" }, - { RAND_INF_TRIALS_DONE_WATER_TRIAL, "TRIALS_DONE_WATER_TRIAL" }, - { RAND_INF_TRIALS_DONE_SPIRIT_TRIAL, "TRIALS_DONE_SPIRIT_TRIAL" }, - { RAND_INF_TRIALS_DONE_SHADOW_TRIAL, "TRIALS_DONE_SHADOW_TRIAL" }, - { RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, "COWS_MILKED_KF_LINKS_HOUSE_COW" }, { RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" }, { RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" }, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index f8e1c5020..f47d1adad 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -107,6 +107,15 @@ bool MeetsLACSRequirements() { return false; } +bool CompletedAllTrials() { + return Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_WATER_TRIAL) && + Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_LIGHT_TRIAL) && + Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FIRE_TRIAL) && + Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_SHADOW_TRIAL) && + Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_SPIRIT_TRIAL) && + Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL); +} + // Todo Move this to randomizer context, clear it out on save load etc static std::queue randomizerQueuedChecks; static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK; @@ -1307,6 +1316,12 @@ void RandomizerOnActorInitHandler(void* actorRef) { enGe1->actionFunc = (EnGe1ActionFunc)EnGe1_SetNormalText; } } + + if (actor->id == ACTOR_DEMO_KEKKAI && actor->params == 0) { // 0 == KEKKAI_TOWER + if (CompletedAllTrials()) { + Actor_Kill(actor); + } + } } void RandomizerRegisterHooks() { diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index eb34721b5..74409c4c7 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -164,21 +164,6 @@ Randomizer::Randomizer() { Randomizer::~Randomizer() { } -std::unordered_map spoilerFileTrialToEnum = { - { "the Forest Trial", RAND_INF_TRIALS_DONE_FOREST_TRIAL }, - { "l'épreuve de la Forêt", RAND_INF_TRIALS_DONE_FOREST_TRIAL }, - { "the Fire Trial", RAND_INF_TRIALS_DONE_FIRE_TRIAL }, - { "l'épreuve du Feu", RAND_INF_TRIALS_DONE_FIRE_TRIAL }, - { "the Water Trial", RAND_INF_TRIALS_DONE_WATER_TRIAL }, - { "l'épreuve de l'Eau", RAND_INF_TRIALS_DONE_WATER_TRIAL }, - { "the Spirit Trial", RAND_INF_TRIALS_DONE_SPIRIT_TRIAL }, - { "l'épreuve de l'Esprit", RAND_INF_TRIALS_DONE_SPIRIT_TRIAL }, - { "the Shadow Trial", RAND_INF_TRIALS_DONE_SHADOW_TRIAL }, - { "l'épreuve de l'Ombre", RAND_INF_TRIALS_DONE_SHADOW_TRIAL }, - { "the Light Trial", RAND_INF_TRIALS_DONE_LIGHT_TRIAL }, - { "l'épreuve de la Lumière", RAND_INF_TRIALS_DONE_LIGHT_TRIAL } -}; - std::unordered_map spoilerFileDungeonToScene = { { "Deku Tree", SCENE_DEKU_TREE }, { "Dodongo's Cavern", SCENE_DODONGOS_CAVERN }, @@ -576,8 +561,17 @@ void Randomizer::LoadMerchantMessages() { "\x08{{item}} {{price}} Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w\x09\x02")); } -bool Randomizer::IsTrialRequired(RandomizerInf trial) { - return Rando::Context::GetInstance()->GetTrial(trial - RAND_INF_TRIALS_DONE_LIGHT_TRIAL)->IsRequired(); +std::map trialFlagToTrialKey = { + { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, Rando::TrialKey::LIGHT_TRIAL, }, + { EVENTCHKINF_COMPLETED_FOREST_TRIAL, Rando::TrialKey::FOREST_TRIAL, }, + { EVENTCHKINF_COMPLETED_FIRE_TRIAL, Rando::TrialKey::FIRE_TRIAL, }, + { EVENTCHKINF_COMPLETED_WATER_TRIAL, Rando::TrialKey::WATER_TRIAL, }, + { EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, Rando::TrialKey::SPIRIT_TRIAL, }, + { EVENTCHKINF_COMPLETED_SHADOW_TRIAL, Rando::TrialKey::SHADOW_TRIAL, } +}; + +bool Randomizer::IsTrialRequired(s32 trialFlag) { + return Rando::Context::GetInstance()->GetTrial(trialFlagToTrialKey[trialFlag])->IsRequired(); } GetItemEntry Randomizer::GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 4d5a2ff30..de7f216e6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -46,7 +46,7 @@ class Randomizer { bool SpoilerFileExists(const char* spoilerFileName); void LoadMerchantMessages(); void LoadHintMessages(); - bool IsTrialRequired(RandomizerInf trial); + bool IsTrialRequired(s32 trialFlag); u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey); RandomizerCheck GetCheckFromRandomizerInf(RandomizerInf randomizerInf); RandomizerInf GetRandomizerInfFromCheck(RandomizerCheck rc); diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 465f5316c..8bd2cc7c1 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -10,13 +10,6 @@ typedef enum { RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, - RAND_INF_TRIALS_DONE_LIGHT_TRIAL, - RAND_INF_TRIALS_DONE_FOREST_TRIAL, - RAND_INF_TRIALS_DONE_FIRE_TRIAL, - RAND_INF_TRIALS_DONE_WATER_TRIAL, - RAND_INF_TRIALS_DONE_SPIRIT_TRIAL, - RAND_INF_TRIALS_DONE_SHADOW_TRIAL, - RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 95840b15c..a43e9e2be 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -351,10 +351,15 @@ extern "C" void Randomizer_InitSaveFile() { gSaveContext.entranceIndex = -1; } - // If any trials aren't required, set them as completed - for (u16 i = RAND_INF_TRIALS_DONE_LIGHT_TRIAL; i <= RAND_INF_TRIALS_DONE_SHADOW_TRIAL; i++) { - if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired((RandomizerInf)i)) { - Flags_SetRandomizerInf((RandomizerInf)i); + for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, + EVENTCHKINF_COMPLETED_FOREST_TRIAL, + EVENTCHKINF_COMPLETED_FIRE_TRIAL, + EVENTCHKINF_COMPLETED_WATER_TRIAL, + EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, + EVENTCHKINF_COMPLETED_SHADOW_TRIAL } + ) { + if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag)) { + Flags_SetEventChkInf(trialFlag); } } diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index a01d96fed..c7e363ad7 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2359,8 +2359,8 @@ extern "C" void Randomizer_LoadMerchantMessages() { OTRGlobals::Instance->gRandomizer->LoadMerchantMessages(); } -extern "C" bool Randomizer_IsTrialRequired(RandomizerInf trial) { - return OTRGlobals::Instance->gRandomizer->IsTrialRequired(trial); +extern "C" bool Randomizer_IsTrialRequired(s32 trialFlag) { + return OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag); } extern "C" u32 SpoilerFileExists(const char* spoilerFileName) { diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index c90f07316..00b643bcb 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -159,7 +159,7 @@ FishIdentity Randomizer_IdentifyFish(s32 sceneNum, s32 actorParams); void Randomizer_ParseSpoiler(const char* fileLoc); void Randomizer_LoadHintMessages(); void Randomizer_LoadMerchantMessages(); -bool Randomizer_IsTrialRequired(RandomizerInf trial); +bool Randomizer_IsTrialRequired(s32 trialFlag); GetItemEntry Randomizer_GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId); GetItemEntry Randomizer_GetItemFromActorWithoutObtainabilityCheck(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId); GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); diff --git a/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c b/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c index 01a2ab047..09a45856b 100644 --- a/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c +++ b/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c @@ -64,66 +64,23 @@ static u8 sEnergyColors[] = { /* Forest prim */ 255, 255, 170, /* env */ 0, 200, 0, }; -// Translates from the barrier's actor params to their corresponding randInf flags. -RandomizerInf trialParamToRandInf(u16 params) { - switch (params) { - case KEKKAI_LIGHT: - return RAND_INF_TRIALS_DONE_LIGHT_TRIAL; - case KEKKAI_FOREST: - return RAND_INF_TRIALS_DONE_FOREST_TRIAL; - case KEKKAI_FIRE: - return RAND_INF_TRIALS_DONE_FIRE_TRIAL; - case KEKKAI_WATER: - return RAND_INF_TRIALS_DONE_WATER_TRIAL; - case KEKKAI_SPIRIT: - return RAND_INF_TRIALS_DONE_SPIRIT_TRIAL; - case KEKKAI_SHADOW: - return RAND_INF_TRIALS_DONE_SHADOW_TRIAL; - } -} - s32 DemoKekkai_CheckEventFlag(s32 params) { - static s32 eventFlags[] = { 0xC3, 0xBC, 0xBF, 0xBE, 0xBD, 0xAD, 0xBB }; + static s32 eventFlags[] = { + EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER, + EVENTCHKINF_COMPLETED_WATER_TRIAL, + EVENTCHKINF_COMPLETED_LIGHT_TRIAL, + EVENTCHKINF_COMPLETED_FIRE_TRIAL, + EVENTCHKINF_COMPLETED_SHADOW_TRIAL, + EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, + EVENTCHKINF_COMPLETED_FOREST_TRIAL, + }; if ((params < KEKKAI_TOWER) || (params > KEKKAI_FOREST)) { return true; } - if (IS_RANDO && params > KEKKAI_TOWER) { - return Flags_GetRandomizerInf(trialParamToRandInf(params)); - } return Flags_GetEventChkInf(eventFlags[params]); } -u32 TrialsDoneCount() { - u8 trialCount = 0; - - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_LIGHT_TRIAL)) { - trialCount++; - } - - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FOREST_TRIAL)) { - trialCount++; - } - - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FIRE_TRIAL)) { - trialCount++; - } - - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_WATER_TRIAL)) { - trialCount++; - } - - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SPIRIT_TRIAL)) { - trialCount++; - } - - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SHADOW_TRIAL)) { - trialCount++; - } - - return trialCount; -} - void DemoKekkai_Init(Actor* thisx, PlayState* play) { s32 pad; DemoKekkai* this = (DemoKekkai*)thisx; @@ -147,13 +104,6 @@ void DemoKekkai_Init(Actor* thisx, PlayState* play) { this->collider2.dim.radius = thisx->scale.x * 6100.0f; this->collider2.dim.height = thisx->scale.y * 5000.0f; this->collider2.dim.yShift = 300; - - if (IS_RANDO) { - if (TrialsDoneCount() == NUM_TRIALS) { - Actor_Kill(thisx); - return; - } - } break; case KEKKAI_WATER: case KEKKAI_LIGHT: @@ -161,10 +111,6 @@ void DemoKekkai_Init(Actor* thisx, PlayState* play) { case KEKKAI_SHADOW: case KEKKAI_SPIRIT: case KEKKAI_FOREST: - if (IS_RANDO && Flags_GetRandomizerInf(trialParamToRandInf(thisx->params))) { - Actor_Kill(thisx); - return; - } this->energyAlpha = 1.0f; this->orbScale = 1.0f; Actor_SetScale(thisx, 0.1f); @@ -265,18 +211,10 @@ void DemoKekkai_Update(Actor* thisx, PlayState* play2) { } void DemoKekkai_TrialBarrierDispel(Actor* thisx, PlayState* play) { - static s32 eventFlags[] = { 0xC3, 0xBC, 0xBF, 0xBE, 0xBD, 0xAD, 0xBB }; static u16 csFrames[] = { 0, 280, 280, 280, 280, 280, 280 }; s32 pad; DemoKekkai* this = (DemoKekkai*)thisx; - if (IS_RANDO) { - Flags_SetRandomizerInf(trialParamToRandInf(thisx->params)); - // May or may not be needed. Not sure if needed for anything - // that randoInf isn't already covering. Leaving it for safety. - Flags_SetEventChkInf(eventFlags[thisx->params]); - } - if (play->csCtx.frames == csFrames[this->actor.params]) { func_800F3F3C(0xA); } diff --git a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c index eefaf9c0c..2600acd6b 100644 --- a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -136,27 +136,6 @@ void ObjectKankyo_Init(Actor* thisx, PlayState* play) { this->effects[5].size = 0.0f; } - if (IS_RANDO) { - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FOREST_TRIAL)) { - this->effects[0].size = 0.0f; - } - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_WATER_TRIAL)) { - this->effects[1].size = 0.0f; - } - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SHADOW_TRIAL)) { - this->effects[2].size = 0.0f; - } - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FIRE_TRIAL)) { - this->effects[3].size = 0.0f; - } - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_LIGHT_TRIAL)) { - this->effects[4].size = 0.0f; - } - if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SPIRIT_TRIAL)) { - this->effects[5].size = 0.0f; - } - } - if (gSaveContext.cutsceneTrigger != 0) { if (gSaveContext.entranceIndex == ENTR_INSIDE_GANONS_CASTLE_2) { this->effects[0].size = 0.1f; From 16836172105ee90802f2e81ddcedf67193b2a20d Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 18 Apr 2024 21:13:40 -0500 Subject: [PATCH 32/52] Migrate rainbow bridge --- .../game-interactor/GameInteractor.h | 2 + .../Enhancements/randomizer/hook_handlers.cpp | 57 +++++++++++++ .../Enhancements/timesaver_hook_handlers.cpp | 7 ++ .../ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c | 82 +++++-------------- 4 files changed, 85 insertions(+), 63 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index a3d7e9045..8dc20e215 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -113,6 +113,7 @@ typedef enum { GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER, // Vanilla condition: !EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT and EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP GI_VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT, + GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE, /* Vanilla Condition: ``` LINK_IS_ADULT && @@ -255,6 +256,7 @@ typedef enum { GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE, // Opt: *EnOkarinaTag GI_VB_PLAY_DOOR_OF_TIME_CS, + GI_VB_PLAY_RAINBOW_BRIDGE_CS, /*** Give Items ***/ diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index f47d1adad..a2fe8697e 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -116,6 +116,59 @@ bool CompletedAllTrials() { Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL); } +bool MeetsRainbowBridgeRequirements() { + switch (RAND_GET_OPTION(RSK_RAINBOW_BRIDGE)) { + case RO_BRIDGE_VANILLA: { + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && + (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT)) { + return true; + } + break; + } + case RO_BRIDGE_STONES: { + if ((CheckStoneCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_STONE_COUNT)) { + return true; + } + break; + } + case RO_BRIDGE_MEDALLIONS: { + if ((CheckMedallionCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT)) { + return true; + } + break; + } + case RO_BRIDGE_DUNGEON_REWARDS: { + if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_REWARD_COUNT)) { + return true; + } + break; + } + case RO_BRIDGE_DUNGEONS: { + if ((CheckDungeonCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT)) { + return true; + } + break; + } + case RO_BRIDGE_TOKENS: { + if (gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_TOKEN_COUNT)) { + return true; + } + break; + } + case RO_BRIDGE_GREG: { + if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) { + return true; + } + break; + } + case RO_BRIDGE_ALWAYS_OPEN: { + return true; + } + } + + return false; +} + // Todo Move this to randomizer context, clear it out on save load etc static std::queue randomizerQueuedChecks; static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK; @@ -996,6 +1049,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; break; } + case GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE: { + *should = MeetsRainbowBridgeRequirements(); + break; + } case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 18249e0bf..886b3ddea 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -666,6 +666,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; } + case GI_VB_PLAY_RAINBOW_BRIDGE_CS: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { + *should = false; + func_800F595C(NA_BGM_BRIDGE_TO_GANONS); + } + break; + } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c b/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c index b592edcd5..543770505 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c +++ b/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c @@ -7,6 +7,7 @@ #include "z_bg_gjyo_bridge.h" #include "objects/object_gjyo_objects/object_gjyo_objects.h" #include "scenes/dungeons/ganon_tou/ganon_tou_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -50,8 +51,7 @@ void BgGjyoBridge_Init(Actor* thisx, PlayState* play) { this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, thisx, colHeader); - int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE); - if (Flags_GetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT) || (IS_RANDO && bridge == RO_BRIDGE_ALWAYS_OPEN)) { + if (Flags_GetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT)) { this->actionFunc = func_808787A4; } else { this->dyna.actor.draw = NULL; @@ -70,8 +70,10 @@ void func_808787A4(BgGjyoBridge* this, PlayState* play) { } void LaunchBridgeCutscene(BgGjyoBridge* this, PlayState* play) { - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs); - gSaveContext.cutsceneTrigger = 1; + if (GameInteractor_Should(GI_VB_PLAY_RAINBOW_BRIDGE_CS, true, NULL)) { + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs); + gSaveContext.cutsceneTrigger = 1; + } this->actionFunc = BgGjyoBridge_SpawnBridge; } @@ -84,70 +86,24 @@ u8 CheckPlayerPosition(Player* player, PlayState* play) { void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (!IS_RANDO) { - if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && - (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) && CheckPlayerPosition(player, play)) { - LaunchBridgeCutscene(this, play); - } - } else { - int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE); - int bridgeStoneCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_STONE_COUNT); - int bridgeMedallionCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT); - int bridgeRewardCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_REWARD_COUNT); - int bridgeDungeonCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT); - int bridgeTokenCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_TOKEN_COUNT); + u8 vanillaBridgeCondition = + CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && + (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) && + CheckPlayerPosition(player, play); - switch (bridge) { - case RO_BRIDGE_VANILLA: - if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && - (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT)) { - this->actionFunc = BgGjyoBridge_SpawnBridge; - func_800F595C(NA_BGM_BRIDGE_TO_GANONS); - } - break; - case RO_BRIDGE_STONES: - if ((CheckStoneCount() + CheckBridgeRewardCount()) >= bridgeStoneCount) { - this->actionFunc = BgGjyoBridge_SpawnBridge; - func_800F595C(NA_BGM_BRIDGE_TO_GANONS); - } - break; - case RO_BRIDGE_MEDALLIONS: - if ((CheckMedallionCount() + CheckBridgeRewardCount()) >= bridgeMedallionCount) { - this->actionFunc = BgGjyoBridge_SpawnBridge; - func_800F595C(NA_BGM_BRIDGE_TO_GANONS); - } - break; - case RO_BRIDGE_DUNGEON_REWARDS: - if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >= bridgeRewardCount) { - this->actionFunc = BgGjyoBridge_SpawnBridge; - func_800F595C(NA_BGM_BRIDGE_TO_GANONS); - } - break; - case RO_BRIDGE_DUNGEONS: - if ((CheckDungeonCount() + CheckBridgeRewardCount()) >= bridgeDungeonCount) { - this->actionFunc = BgGjyoBridge_SpawnBridge; - func_800F595C(NA_BGM_BRIDGE_TO_GANONS); - } - break; - case RO_BRIDGE_TOKENS: - if (gSaveContext.inventory.gsTokens >= bridgeTokenCount) { - this->actionFunc = BgGjyoBridge_SpawnBridge; - func_800F595C(NA_BGM_BRIDGE_TO_GANONS); - } - break; - case RO_BRIDGE_GREG: - if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) { - this->actionFunc = BgGjyoBridge_SpawnBridge; - func_800F595C(NA_BGM_BRIDGE_TO_GANONS); - } - break; - } + if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE, vanillaBridgeCondition, NULL)) { + LaunchBridgeCutscene(this, play); } } void BgGjyoBridge_SpawnBridge(BgGjyoBridge* this, PlayState* play) { - if (IS_RANDO || (play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.npcActions[2] != NULL) && - (play->csCtx.npcActions[2]->action == 2)) { + u8 vanillaBridgeCondition = + (play->csCtx.state != CS_STATE_IDLE) && + (play->csCtx.npcActions[2] != NULL) && + (play->csCtx.npcActions[2]->action == 2); + + if (!GameInteractor_Should(GI_VB_PLAY_RAINBOW_BRIDGE_CS, true, NULL) || vanillaBridgeCondition) { this->dyna.actor.draw = BgGjyoBridge_Draw; func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId); Flags_SetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT); From abdbe25c8a92c0c38b28ef2445ef197c45883187 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 18 Apr 2024 21:36:10 -0500 Subject: [PATCH 33/52] Migrate purple poe faster fight --- .../Enhancements/timesaver_hook_handlers.cpp | 30 +++++++++++++++++++ .../ovl_En_Po_Sisters/z_en_po_sisters.c | 11 ------- .../ovl_En_Po_Sisters/z_en_po_sisters.h | 2 ++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 886b3ddea..6c6930ec4 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -23,6 +23,7 @@ extern "C" { #include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h" #include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h" #include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h" +#include "src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -686,6 +687,8 @@ static uint32_t enFuUpdateHook = 0; static uint32_t enFuKillHook = 0; static uint32_t bgSpot02UpdateHook = 0; static uint32_t bgSpot02KillHook = 0; +static uint32_t enPoSistersUpdateHook = 0; +static uint32_t enPoSistersKillHook = 0; void TimeSaverOnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); @@ -816,6 +819,33 @@ void TimeSaverOnActorInitHandler(void* actorRef) { EnDntDemo* enDntDemo = static_cast(actorRef); enDntDemo->actionFunc = EnDntDemo_JudgeSkipToReward; } + + // Forest Temple entrance cutscene + if (actor->id == ACTOR_EN_PO_SISTERS && actor->params == 4124) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0)) { + Flags_SetSwitch(gPlayState, 0x1B); + Actor_Kill(actor); + } + } + + // Forest Temple purple poe fight speedup + if (actor->id == ACTOR_EN_PO_SISTERS && actor->params == 28) { + enPoSistersUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_EN_PO_SISTERS && innerActor->params == 28 && (CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO))) { + EnPoSisters* enPoSisters = static_cast(innerActorRef); + if (enPoSisters->actionFunc == func_80ADB338) { + enPoSisters->unk_19C = 0; + } + } + }); + enPoSistersKillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(enPoSistersUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enPoSistersKillHook); + enPoSistersUpdateHook = 0; + enPoSistersKillHook = 0; + }); + } } void TimeSaverOnSceneInitHandler(int16_t sceneNum) { diff --git a/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c b/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c index ea324c5a5..280640efd 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c +++ b/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c @@ -183,12 +183,6 @@ void EnPoSisters_Init(Actor* thisx, PlayState* play) { this->epoch++; - // Skip Poe Intro Cutscene - if (IS_RANDO && thisx->params == 4124 && !Randomizer_GetSettingValue(RSK_ENABLE_GLITCH_CUTSCENES)) { - Flags_SetSwitch(play, 0x1B); - Actor_Kill(thisx); - } - Actor_ProcessInitChain(&this->actor, sInitChain); ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 50.0f); SkelAnime_Init(play, &this->skelAnime, &gPoeSistersSkel, &gPoeSistersSwayAnim, this->jointTable, @@ -862,11 +856,6 @@ void func_80ADB338(EnPoSisters* this, PlayState* play) { if (Actor_WorldDistXZToPoint(&player->actor, &this->actor.home.pos) < 600.0f) { if (this->unk_19C != 0) { this->unk_19C--; - - // Force Meg to respawn instantly after getting hit - if (IS_RANDO) { - this->unk_19C = 0; - } } } else { this->unk_19C = 100; diff --git a/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h b/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h index 2bd780983..5f42856a4 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h +++ b/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h @@ -32,4 +32,6 @@ typedef struct EnPoSisters { u32 epoch; } EnPoSisters; // size = 0x0338 +void func_80ADB338(EnPoSisters* enPoSisters, PlayState* play); + #endif From 6c384c3cb69ba3a651148f2739fd2754542c0926 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 18 Apr 2024 21:52:38 -0500 Subject: [PATCH 34/52] Finish glitch aiding cutscenes toggle --- soh/soh/Enhancements/randomizer/savefile.cpp | 4 ---- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 8 ++++++++ soh/soh/SohMenuBar.cpp | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index a43e9e2be..ffab46e49 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -302,10 +302,6 @@ extern "C" void Randomizer_InitSaveFile() { // gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 0x1F); // desert colossus kaepora // gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= (1 << 0x5); // hyrule castle kaepora - if (!Randomizer_GetSettingValue(RSK_ENABLE_GLITCH_CUTSCENES)) { - Flags_SetInfTable(INFTABLE_SPOKE_TO_DARUNIA_IN_FIRE_TEMPLE); // Darunia in Fire Temple - } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_A); Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 6c6930ec4..5d77515da 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -846,6 +846,14 @@ void TimeSaverOnActorInitHandler(void* actorRef) { enPoSistersKillHook = 0; }); } + + // Fire Temple Darunia cutscene + if (actor->id == ACTOR_EN_DU && gPlayState->sceneNum == SCENE_FIRE_TEMPLE) { + if (CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0)) { + Flags_SetInfTable(INFTABLE_SPOKE_TO_DARUNIA_IN_FIRE_TEMPLE); + Actor_Kill(actor); + } + } } void TimeSaverOnSceneInitHandler(int16_t sceneNum) { diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index b32a39627..95f59a14f 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -581,7 +581,7 @@ void DrawEnhancementsMenu() { CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) && - CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0) && CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) && CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) && @@ -593,7 +593,7 @@ void DrawEnhancementsMenu() { CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) || - CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0) || CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) || CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) || @@ -637,7 +637,7 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); - UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, 0); UIWidgets::Tooltip("Skip cutscenes that are associated with useful glitches, currently this is only the Fire Temple Darunia CS and Forest Temple Poe Sisters CS"); UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); From ed0ef62c0cc86cc82a3aac4eb0521094411107ba Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:15:15 -0400 Subject: [PATCH 35/52] fix: add location access for treasure chest game items vb treasure chest game added new RCs for the treasure chest game (now there are RCs for each of the 5 keys and each of the 5 non key chests), but the location area table only had the keys, this adds the items --- .../3drando/location_access/locacc_castle_town.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index f48a2bb53..ac4a8ef50 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp @@ -235,10 +235,15 @@ void AreaTable_Init_CastleTown() { LocationAccess(RC_GREG_HINT, {[]{return true;}}), LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_REWARD, {[]{return logic->ChildsWallet && ((logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)));}}), LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), + LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}), }, { //Exits Entrance(RR_THE_MARKET, {[]{return true;}}), From d3beac7337f1c62a666dfdde852795e25ec99f08 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:29:37 -0400 Subject: [PATCH 36/52] fix: gift from sages location access --- .../randomizer/3drando/location_access/locacc_castle_town.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index ac4a8ef50..9527f5243 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp @@ -65,6 +65,7 @@ void AreaTable_Init_CastleTown() { }, { //Locations LocationAccess(RC_TOT_MASTER_SWORD, {[]{return logic->IsAdult;}}), + LocationAccess(RC_GIFT_FROM_SAGES, {[]{return logic->IsAdult;}}), LocationAccess(RC_SHEIK_AT_TEMPLE, {[]{return logic->ForestMedallion && logic->IsAdult;}}), }, { //Exits From 3b0548f585b4a4894157c3f7d63bdef786023a0e Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:05:38 -0400 Subject: [PATCH 37/52] vb tower escape --- .../Enhancements/randomizer/option_descriptions.cpp | 2 -- soh/soh/Enhancements/randomizer/randomizerTypes.h | 1 - soh/soh/Enhancements/randomizer/settings.cpp | 4 ---- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 11 ++++++++++- soh/soh/SohMenuBar.cpp | 10 ++++++++-- soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c | 8 +------- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index e50846005..82228dbed 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -438,8 +438,6 @@ void Settings::CreateOptionDescriptions() { "Start with Zelda's Letter and the item Impa would normally give you and skip the sequence up " "until after meeting Zelda. Disables the ability to shuffle Weird Egg."; mOptionDescriptions[RSK_SKIP_EPONA_RACE] = "Epona can be summoned with Epona's Song without needing to race Ingo."; - mOptionDescriptions[RSK_SKIP_TOWER_ESCAPE] = - "The tower escape sequence between Ganondorf and Ganon will be skipped."; mOptionDescriptions[RSK_COMPLETE_MASK_QUEST] = "Once the happy mask shop is opened, all masks will be available to be borrowed."; mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG] = diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index f1d368763..074849b00 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -3598,7 +3598,6 @@ typedef enum { RSK_CUCCO_COUNT, RSK_BIG_POE_COUNT, RSK_SKIP_EPONA_RACE, - RSK_SKIP_TOWER_ESCAPE, RSK_COMPLETE_MASK_QUEST, RSK_SKIP_SCARECROWS_SONG, RSK_ENABLE_GLITCH_CUTSCENES, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index ac947d4da..5edc219dd 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -147,7 +147,6 @@ void Settings::CreateOptions() { mOptions[RSK_KEYRINGS_GANONS_CASTLE] = Option::Bool("Ganon's Castle", "gRandomizeShuffleKeyRingsGanonsCastle"); mOptions[RSK_SKIP_CHILD_STEALTH] = Option::Bool("Skip Child Stealth", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipChildStealth", mOptionDescriptions[RSK_SKIP_CHILD_STEALTH], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); mOptions[RSK_SKIP_CHILD_ZELDA] = Option::Bool("Skip Child Zelda", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipChildZelda", mOptionDescriptions[RSK_SKIP_CHILD_ZELDA], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); - mOptions[RSK_SKIP_TOWER_ESCAPE] = Option::Bool("Skip Tower Escape", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipTowerEscape", mOptionDescriptions[RSK_SKIP_TOWER_ESCAPE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); mOptions[RSK_SKIP_EPONA_RACE] = Option::Bool("Skip Epona Race", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipEponaRace", mOptionDescriptions[RSK_SKIP_EPONA_RACE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); mOptions[RSK_SKIP_SCARECROWS_SONG] = Option::Bool("Skip Scarecrow's Song", "gRandomizeSkipScarecrowsSong", mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG]); mOptions[RSK_BIG_POE_COUNT] = Option::U8("Big Poe Target Count", {NumOpts(1, 10)}, OptionCategory::Setting, "gRandomizeBigPoeTargetCount", mOptionDescriptions[RSK_BIG_POE_COUNT], WidgetType::Slider, 9); @@ -716,7 +715,6 @@ void Settings::CreateOptions() { &mOptions[RSK_SKIP_CHILD_STEALTH], &mOptions[RSK_SKIP_CHILD_ZELDA], &mOptions[RSK_SKIP_EPONA_RACE], - &mOptions[RSK_SKIP_TOWER_ESCAPE], &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] }, false, WidgetContainerType::COLUMN); @@ -1200,7 +1198,6 @@ void Settings::CreateOptions() { { "Timesaver Settings:Big Poe Target Count", RSK_BIG_POE_COUNT }, { "Timesaver Settings:Skip Child Stealth", RSK_SKIP_CHILD_STEALTH }, { "Timesaver Settings:Skip Epona Race", RSK_SKIP_EPONA_RACE }, - { "Timesaver Settings:Skip Tower Escape", RSK_SKIP_TOWER_ESCAPE }, { "Timesaver Settings:Complete Mask Quest", RSK_COMPLETE_MASK_QUEST }, { "Timesaver Settings:Skip Scarecrow's Song", RSK_SKIP_SCARECROWS_SONG }, { "Timesaver Settings:Enable Glitch-Useful Cutscenes", RSK_ENABLE_GLITCH_CUTSCENES }, @@ -2523,7 +2520,6 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { case RSK_SKIP_CHILD_ZELDA: case RSK_SKIP_CHILD_STEALTH: case RSK_SKIP_EPONA_RACE: - case RSK_SKIP_TOWER_ESCAPE: if (it.value() == "Don't Skip") { mOptions[index].SetSelectedIndex(RO_GENERIC_DONT_SKIP); } else if (it.value() == "Skip") { diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 5d77515da..61a83b482 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -136,7 +136,7 @@ void TimeSaverOnGameFrameUpdateHandler() { void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* opt) { switch (id) { - case GI_VB_PLAY_TRANSITION_CS: + case GI_VB_PLAY_TRANSITION_CS: { if (CVarGetInteger("gTimeSavers.SkipCutscene.Intro", IS_RANDO) && gSaveContext.entranceIndex == ENTR_LINKS_HOUSE_0 && gSaveContext.cutsceneIndex == 0xFFF1) { gSaveContext.cutsceneIndex = 0; *should = false; @@ -260,7 +260,16 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = false; } } + + if (gSaveContext.entranceIndex == ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0) { + if (CVarGetInteger("gTimeSavers.SkipTowerEscape", false) || IS_BOSS_RUSH) { + Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); + gSaveContext.entranceIndex = ENTR_GANON_BOSS_0; + *should = false; + } + } break; + } case GI_VB_PLAY_ENTRANCE_CS: { s32* entranceFlag = static_cast(opt); if (CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) && (*entranceFlag != EVENTCHKINF_EPONA_OBTAINED)) { diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 95f59a14f..c11b88a62 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -586,7 +586,8 @@ void DrawEnhancementsMenu() { CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) && - CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO); + CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipTowerEscape", false); bool someChecked = CVarGetInteger("gTimeSavers.SkipCutscene.Intro", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) || @@ -598,7 +599,8 @@ void DrawEnhancementsMenu() { CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) || - CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO); + CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipTowerEscape", false); ImGuiContext* g = ImGui::GetCurrentContext(); ImGuiItemFlags backup_item_flags = g->CurrentItemFlags; @@ -616,6 +618,7 @@ void DrawEnhancementsMenu() { CVarSetInteger("gTimeSavers.SkipOwlInteractions", 1); CVarSetInteger("gTimeSavers.SkipMiscInteractions", 1); CVarSetInteger("gTimeSavers.DisableTitleCard", 1); + CVarSetInteger("gTimeSavers.SkipTowerEscape", 1); } else { CVarSetInteger("gTimeSavers.SkipCutscene.Intro", 0); CVarSetInteger("gTimeSavers.SkipCutscene.Entrances", 0); @@ -628,6 +631,7 @@ void DrawEnhancementsMenu() { CVarSetInteger("gTimeSavers.SkipOwlInteractions", 0); CVarSetInteger("gTimeSavers.SkipMiscInteractions", 0); CVarSetInteger("gTimeSavers.DisableTitleCard", 0); + CVarSetInteger("gTimeSavers.SkipTowerEscape", 0); } LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } @@ -645,6 +649,8 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementCheckbox("Skip Owl Interactions", "gTimeSavers.SkipOwlInteractions", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Misc Interactions", "gTimeSavers.SkipMiscInteractions", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Disable Title Card", "gTimeSavers.DisableTitleCard", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Tower Escape", "gTimeSavers.SkipTowerEscape", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false); + UIWidgets::Tooltip("Skip the tower escape sequence between Ganondorf and Ganon."); UIWidgets::PaddedText("Skip Get Item Animations", true, false); UIWidgets::EnhancementCombobox("gTimeSavers.SkipGetItemAnimation", skipGetItemAnimationOptions, SGIA_DISABLED); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index b1c45feed..169794568 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -1539,13 +1539,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { if (this->csTimer == 180) { play->transitionTrigger = TRANS_TRIGGER_START; - if ((IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE) || IS_BOSS_RUSH)) { - Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); - play->nextEntranceIndex = ENTR_GANON_BOSS_0; - } - else { - play->nextEntranceIndex = ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0; - } + play->nextEntranceIndex = ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0; play->transitionType = TRANS_TYPE_FADE_WHITE_FAST; } break; From 14c7f0c3e1c2e02eb26cd1dcb7de94c5f5ff9061 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 21 Apr 2024 09:14:46 -0500 Subject: [PATCH 38/52] More time cutscene skip fixes --- .../game-interactor/GameInteractor.h | 3 ++ .../Enhancements/timesaver_hook_handlers.cpp | 29 ++++++++++++++++--- .../actors/ovl_Obj_Dekujr/z_obj_dekujr.c | 3 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 8dc20e215..fd5611df8 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -83,6 +83,9 @@ typedef enum { // Opt: *EnMd // Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) GI_VB_MIDO_CONSIDER_DEKU_TREE_DEAD, + // Opt: *ObjDekujr + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) + GI_VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, // Opt: *EnKo // Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) GI_VB_OPEN_KOKIRI_FOREST, diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 61a83b482..b920419bb 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -155,6 +155,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); // Normally happens in the cutscene + gSaveContext.dayTime = gSaveContext.skyboxTime = 0xAC60; if (GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) { Item_Give(gPlayState, ITEM_SONG_REQUIEM); } @@ -183,8 +184,6 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* uint8_t isBlueWarp = 0; // Deku Tree Blue warp if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) { - gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; - gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_11; isBlueWarp = 1; // Dodongo's Cavern Blue warp @@ -199,9 +198,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) { // Normally set in the blue warp cutscene Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT); - gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; - gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + if (IS_RANDO) { + gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + } else { + gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12; + } + isBlueWarp = 1; // Fire Temple Blue warp } else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && gSaveContext.cutsceneIndex == 0xFFF3) { @@ -209,6 +212,9 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* isBlueWarp = 1; // Water Temple Blue warp } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) { + // Normally set in the blue warp cutscene + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800; + gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_9; isBlueWarp = 1; // Spirit Temple Blue warp @@ -222,6 +228,9 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } if (isBlueWarp) { + // Normally set in the blue warp cutscene + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; + *should = false; gSaveContext.cutsceneIndex = 0; @@ -232,6 +241,9 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* // Flee hyrule castle cutscene if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_0 && gSaveContext.cutsceneIndex == 0xFFF1) { + // Normally set in the blue warp cutscene + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4AAA; + gSaveContext.cutsceneIndex = 0; *should = false; } @@ -420,6 +432,14 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case GI_VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED: { + // We're overriding this so that the Deku JR doesn't despawn after skipping the forest temple blue warp cutscene. + // It typically relies on the forest medallion being obtained, but that isn't given yet until after scene init + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) { + *should = Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); + } + break; + } case GI_VB_GIVE_ITEM_FROM_BLUE_WARP: case GI_VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS: case GI_VB_GIVE_ITEM_FAIRY_OCARINA: @@ -514,6 +534,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } else { gPlayState->nextEntranceIndex = ENTR_HYRULE_FIELD_17; } + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; gPlayState->transitionType = TRANS_TYPE_FADE_WHITE; gPlayState->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.nextTransitionType = 2; diff --git a/soh/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c b/soh/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c index ae9545825..9463d45af 100644 --- a/soh/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c +++ b/soh/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c @@ -6,6 +6,7 @@ #include "z_obj_dekujr.h" #include "objects/object_dekujr/object_dekujr.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -56,7 +57,7 @@ void ObjDekujr_Init(Actor* thisx, PlayState* play) { this->unk_19C = 0; this->unk_19B = 1; } - if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST)) { + if (!GameInteractor_Should(GI_VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST), this)) { Actor_Kill(thisx); } else { ActorShape_Init(&thisx->shape, 0.0f, NULL, 0.0f); From 5813b37415d3eb37aa7d4cdbd431ce7067ddfba2 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 21 Apr 2024 09:38:53 -0500 Subject: [PATCH 39/52] Migrate child stealth --- .../Enhancements/timesaver_hook_handlers.cpp | 7 +++++++ soh/soh/SohMenuBar.cpp | 18 ++++++------------ soh/src/code/z_play.c | 12 ------------ 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index b920419bb..700e55e18 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -280,6 +280,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = false; } } + + if (gSaveContext.entranceIndex == ENTR_CASTLE_COURTYARD_GUARDS_DAY_0) { + if (CVarGetInteger("gTimeSavers.SkipChildStealth", false)) { + gSaveContext.entranceIndex = ENTR_CASTLE_COURTYARD_ZELDA_0; + *should = false; + } + } break; } case GI_VB_PLAY_ENTRANCE_CS: { diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index c11b88a62..3821f9df4 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -581,26 +581,22 @@ void DrawEnhancementsMenu() { CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) && - CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0) && CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) && CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) && - CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO) && - CVarGetInteger("gTimeSavers.SkipTowerEscape", false); + CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO); bool someChecked = CVarGetInteger("gTimeSavers.SkipCutscene.Intro", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) || - CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0) || CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) || CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) || - CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO) || - CVarGetInteger("gTimeSavers.SkipTowerEscape", false); + CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO); ImGuiContext* g = ImGui::GetCurrentContext(); ImGuiItemFlags backup_item_flags = g->CurrentItemFlags; @@ -612,26 +608,22 @@ void DrawEnhancementsMenu() { CVarSetInteger("gTimeSavers.SkipCutscene.Story", 1); CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 1); CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 1); - CVarSetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 1); CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 1); CVarSetInteger("gTimeSavers.NoForcedDialog", 1); CVarSetInteger("gTimeSavers.SkipOwlInteractions", 1); CVarSetInteger("gTimeSavers.SkipMiscInteractions", 1); CVarSetInteger("gTimeSavers.DisableTitleCard", 1); - CVarSetInteger("gTimeSavers.SkipTowerEscape", 1); } else { CVarSetInteger("gTimeSavers.SkipCutscene.Intro", 0); CVarSetInteger("gTimeSavers.SkipCutscene.Entrances", 0); CVarSetInteger("gTimeSavers.SkipCutscene.Story", 0); CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 0); CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 0); - CVarSetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0); CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 0); CVarSetInteger("gTimeSavers.NoForcedDialog", 0); CVarSetInteger("gTimeSavers.SkipOwlInteractions", 0); CVarSetInteger("gTimeSavers.SkipMiscInteractions", 0); CVarSetInteger("gTimeSavers.DisableTitleCard", 0); - CVarSetInteger("gTimeSavers.SkipTowerEscape", 0); } LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } @@ -641,14 +633,16 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); - UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, 0); - UIWidgets::Tooltip("Skip cutscenes that are associated with useful glitches, currently this is only the Fire Temple Darunia CS and Forest Temple Poe Sisters CS"); UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::Tooltip("Prevent forced conversations with Navi or other NPCs"); UIWidgets::PaddedEnhancementCheckbox("Skip Owl Interactions", "gTimeSavers.SkipOwlInteractions", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Misc Interactions", "gTimeSavers.SkipMiscInteractions", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Disable Title Card", "gTimeSavers.DisableTitleCard", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, 0); + UIWidgets::Tooltip("Skip cutscenes that are associated with useful glitches, currently this is only the Fire Temple Darunia CS and Forest Temple Poe Sisters CS"); + UIWidgets::PaddedEnhancementCheckbox("Skip Child Stealth", "gTimeSavers.SkipChildStealth", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false); + UIWidgets::Tooltip("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."); UIWidgets::PaddedEnhancementCheckbox("Skip Tower Escape", "gTimeSavers.SkipTowerEscape", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false); UIWidgets::Tooltip("Skip the tower escape sequence between Ganondorf and Ganon."); diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 3ce5eeefc..43d30f54b 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -363,18 +363,6 @@ void Play_Init(GameState* thisx) { u8 tempSetupIndex; s32 pad[2]; - // Skip Child Stealth when option is enabled, Zelda's Letter isn't obtained and Impa's reward hasn't been received - // eventChkInf[4] & 1 = Got Zelda's Letter - // eventChkInf[5] & 0x200 = Got Impa's reward - // entranceIndex 0x7A, ENTR_CASTLE_COURTYARD_GUARDS_DAY_0, Castle Courtyard - Day from crawlspace - // entranceIndex 0x400, ENTR_CASTLE_COURTYARD_ZELDA_0, Zelda's Courtyard - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_CHILD_STEALTH) && - !Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY)) { - if (gSaveContext.entranceIndex == ENTR_CASTLE_COURTYARD_GUARDS_DAY_0) { - gSaveContext.entranceIndex = ENTR_CASTLE_COURTYARD_ZELDA_0; - } - } - // Properly initialize the frame counter so it doesn't use garbage data if (!firstInit) { play->gameplayFrames = 0; From a554c1550dd63f66caddaed44e5b1edc4b4d8685 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 21 Apr 2024 18:53:15 -0500 Subject: [PATCH 40/52] Fix shadow & spirit rewards, remove remaning usage of duplicate dungeon done flags --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 36 +++++++++---------- .../Enhancements/debugger/debugSaveEditor.h | 6 ---- soh/soh/Enhancements/presets.h | 2 ++ .../Enhancements/randomizer/hook_handlers.cpp | 11 +++++- .../Enhancements/randomizer/location_list.cpp | 12 +++---- .../Enhancements/randomizer/randomizer_inf.h | 6 ---- soh/src/code/z_map_exp.c | 2 +- soh/src/code/z_play.c | 12 +++---- .../z_bg_spot06_objects.c | 8 ++--- .../overlays/actors/ovl_En_Ossan/z_en_ossan.c | 2 +- 10 files changed, 48 insertions(+), 49 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 63414f88c..9dbbad527 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -129,15 +129,15 @@ void BossRush_SpawnBlueWarps(PlayState* play) { // Spawn blue warps in Chamber of Sages based on what bosses have been defeated. if (gSaveContext.linkAge == LINK_AGE_CHILD) { // Forest Medallion (Gohma) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -100, 6, -170, 0, 0, 0, -1, false); } // Fire Medallion (King Dodongo) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 100, 6, -170, 0, 0, 0, -1, false); } // Water Medallion (Barinade) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 199, 6, 0, 0, 0, 0, -1, false); } } else { @@ -146,15 +146,15 @@ void BossRush_SpawnBlueWarps(PlayState* play) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -199, 6, 0, 0, 0, 0, -1, false); } // Forest Medallion (Phantom Ganondorf) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -100, 6, -170, 0, 0, 0, -1, false); } // Fire Medallion (Volvagia) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 100, 6, -170, 0, 0, 0, -1, false); } // Water Medallion (Morpha) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 199, 6, 0, 0, 0, 0, -1, false); } // Spirit Medallion (Twinrova) @@ -242,22 +242,22 @@ void BossRush_HandleCompleteBoss(PlayState* play) { gSaveContext.isBossRushPaused = 1; switch (play->sceneNum) { case SCENE_DEKU_TREE_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE); + Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP); break; case SCENE_DODONGOS_CAVERN_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN); + Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP); break; case SCENE_JABU_JABU_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY); + Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); break; case SCENE_FOREST_TEMPLE_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE); + Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); break; case SCENE_FIRE_TEMPLE_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE); + Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP); break; case SCENE_WATER_TEMPLE_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE); + Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP); break; case SCENE_SPIRIT_TEMPLE_BOSS: Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); @@ -432,13 +432,13 @@ void BossRush_InitSave() { // Set flags and Link's age based on chosen settings. if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ADULT || gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) { - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY); + Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP); + Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP); + Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) { - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE); + Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); + Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP); + Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP); Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE); } diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 047df95f8..53cd4b7ae 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -349,12 +349,6 @@ const std::vector flagTables = { { 0x30, "Entered the Market" }, } }, { "Randomizer Inf Flags", RANDOMIZER_INF, 16, { - { RAND_INF_DUNGEONS_DONE_DEKU_TREE, "DUNGEONS_DONE_DEKU_TREE" }, - { RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN, "DUNGEONS_DONE_DODONGOS_CAVERN" }, - { RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY, "DUNGEONS_DONE_JABU_JABUS_BELLY" }, - { RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE, "DUNGEONS_DONE_FOREST_TEMPLE" }, - { RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE, "DUNGEONS_DONE_FIRE_TEMPLE" }, - { RAND_INF_DUNGEONS_DONE_WATER_TEMPLE, "DUNGEONS_DONE_WATER_TEMPLE" }, { RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" }, { RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" }, diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index 3cce3dd74..83cf25bd9 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -292,6 +292,8 @@ const std::vector enhancementsCvars = { "gTimeSavers.SkipMiscInteractions", "gTimeSavers.DisableTitleCard", "gTimeSavers.SkipGetItemAnimation", + "gTimeSavers.SkipChildStealth", + "gTimeSavers.SkipTowerEscape", }; const std::vector cheatCvars = { diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index a2fe8697e..42dabae88 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -642,7 +642,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void if (!Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { GET_PLAYER(gPlayState)->exchangeItemId = EXCH_ITEM_LETTER_RUTO; } - *should = Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY); + *should = Flags_GetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); break; } case GI_VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER: { @@ -1053,6 +1053,15 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = MeetsRainbowBridgeRequirements(); break; } + case GI_VB_PLAY_BLUE_WARP_CS: { + // We need to override just these two temples because they check medallions instead of flags + if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { + *should = !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); + } else if (gPlayState->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { + *should = !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE); + } + break; + } case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 1dfa2f5e4..fbe80d638 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1282,12 +1282,12 @@ void Rando::StaticData::InitLocationTable() { // // Bosses locationTable[RC_LINKS_POCKET] = Location::Reward(RC_LINKS_POCKET, RCQUEST_BOTH, RCTYPE_LINKS_POCKET, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Link's Pocket", "Link's Pocket", RHT_LINKS_POCKET, RG_NONE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LINKS_POCKET), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, true); - locationTable[RC_QUEEN_GOHMA] = Location::Reward(RC_QUEEN_GOHMA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DEKU_TREE, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, DungeonId::DUNGEON_DEKU_TREE, "Queen Gohma", "Queen Gohma", RHT_QUEEN_GOHMA, RG_KOKIRI_EMERALD, {}, SpoilerCollectionCheck::EventChkInf(0x07), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_KING_DODONGO] = Location::Reward(RC_KING_DODONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_DOOR_WARP1, SCENE_DODONGOS_CAVERN_BOSS, 0x00, DungeonId::DUNGEON_DODONGOS_CAVERN, "King Dodongo", "King Dodongo", RHT_KING_DODONGO, RG_GORON_RUBY, {}, SpoilerCollectionCheck::EventChkInf(0x25), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_BARINADE] = Location::Reward(RC_BARINADE, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, DungeonId::DUNGEON_JABUJABUS_BELLY, "Barinade", "Barinade", RHT_BARINADE, RG_ZORA_SAPPHIRE, {}, SpoilerCollectionCheck::EventChkInf(0x37), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_PHANTOM_GANON] = Location::Reward(RC_PHANTOM_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FOREST_TEMPLE, "Phantom Ganon", "Phantom Ganon", RHT_PHANTOM_GANON, RG_FOREST_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(0x48), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_VOLVAGIA] = Location::Reward(RC_VOLVAGIA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FIRE_TEMPLE, "Volvagia", "Volvagia", RHT_VOLVAGIA, RG_FIRE_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(0x49), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_MORPHA] = Location::Reward(RC_MORPHA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_WATER_TEMPLE, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_WATER_TEMPLE, "Morpha", "Morpha", RHT_MORPHA, RG_WATER_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(0x4A), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_QUEEN_GOHMA] = Location::Reward(RC_QUEEN_GOHMA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DEKU_TREE, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, DungeonId::DUNGEON_DEKU_TREE, "Queen Gohma", "Queen Gohma", RHT_QUEEN_GOHMA, RG_KOKIRI_EMERALD, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); + locationTable[RC_KING_DODONGO] = Location::Reward(RC_KING_DODONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_DOOR_WARP1, SCENE_DODONGOS_CAVERN_BOSS, 0x00, DungeonId::DUNGEON_DODONGOS_CAVERN, "King Dodongo", "King Dodongo", RHT_KING_DODONGO, RG_GORON_RUBY, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); + locationTable[RC_BARINADE] = Location::Reward(RC_BARINADE, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, DungeonId::DUNGEON_JABUJABUS_BELLY, "Barinade", "Barinade", RHT_BARINADE, RG_ZORA_SAPPHIRE, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_PHANTOM_GANON] = Location::Reward(RC_PHANTOM_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FOREST_TEMPLE, "Phantom Ganon", "Phantom Ganon", RHT_PHANTOM_GANON, RG_FOREST_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_VOLVAGIA] = Location::Reward(RC_VOLVAGIA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FIRE_TEMPLE, "Volvagia", "Volvagia", RHT_VOLVAGIA, RG_FIRE_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_MORPHA] = Location::Reward(RC_MORPHA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_WATER_TEMPLE, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_WATER_TEMPLE, "Morpha", "Morpha", RHT_MORPHA, RG_WATER_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); locationTable[RC_TWINROVA] = Location::Reward(RC_TWINROVA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_SPIRIT_TEMPLE, "Twinrova", "Twinrova", RHT_TWINROVA, RG_SPIRIT_MEDALLION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); locationTable[RC_BONGO_BONGO] = Location::Reward(RC_BONGO_BONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_SHADOW_TEMPLE, "Bongo Bongo", "Bongo Bongo", RHT_BONGO_BONGO, RG_SHADOW_MEDALLION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); locationTable[RC_GANON] = Location::Reward(RC_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_GANONS_CASTLE, ACTOR_DOOR_WARP1, SCENE_GANON_BOSS, 0x00, DungeonId::DUNGEON_GANONS_CASTLE_CRUMBLING, "Ganon", "Ganon", RHT_NONE, RG_TRIFORCE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 8bd2cc7c1..f1ae83121 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1,12 +1,6 @@ #pragma once typedef enum { - RAND_INF_DUNGEONS_DONE_DEKU_TREE, - RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN, - RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY, - RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE, - RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE, - RAND_INF_DUNGEONS_DONE_WATER_TEMPLE, RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, diff --git a/soh/src/code/z_map_exp.c b/soh/src/code/z_map_exp.c index 213ee018d..5ed13f810 100644 --- a/soh/src/code/z_map_exp.c +++ b/soh/src/code/z_map_exp.c @@ -395,7 +395,7 @@ void Map_InitData(PlayState* play, s16 room) { } else if (play->sceneNum == SCENE_LAKE_HYLIA) { if ((LINK_AGE_IN_YEARS == YEARS_ADULT) && ((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)))) { + (IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)))) { extendedMapIndex = 0x15; } } else if (play->sceneNum == SCENE_GERUDO_VALLEY) { diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 43d30f54b..4e27e6cb8 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -277,27 +277,27 @@ u8 CheckMedallionCount() { u8 CheckDungeonCount() { u8 dungeonCount = 0; - if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE)) { + if (Flags_GetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP)) { dungeonCount++; } - if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN)) { + if (Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) { dungeonCount++; } - if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY)) { + if (Flags_GetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) { dungeonCount++; } - if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE)) { + if (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { dungeonCount++; } - if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE)) { + if (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { dungeonCount++; } - if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) { + if (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { dungeonCount++; } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c index 816f96aa4..0a4738092 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c @@ -217,7 +217,7 @@ void BgSpot06Objects_Destroy(Actor* thisx, PlayState* play) { // Due to Ships resource caching, the water box collisions for the river have to be manually reset play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z; - if (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) { + if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { // For randomizer when leaving lake hylia while the water level is lowered, // reset the "raise lake hylia water" flag back to on if the water temple is cleared Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); @@ -461,7 +461,7 @@ void BgSpot06Objects_Update(Actor* thisx, PlayState* play) { Object_Spawn(&play->objectCtx, OBJECT_GAMEPLAY_DANGEON_KEEP); s16 switchParams; - if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) { + if (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { // Toggle-able floor switch, // linked to temp_switch 0x1E (room temporary, cleared when room unloads) switchParams = 0x3E10; @@ -477,7 +477,7 @@ void BgSpot06Objects_Update(Actor* thisx, PlayState* play) { 0x0000 | (TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN & 0xFF), false); // Spawn a Navi check spot when Water Temple isn't cleared - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, -896.0f, -1243.0f, 6953.0f, 0, 0, 0, 0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF), false); } @@ -485,7 +485,7 @@ void BgSpot06Objects_Update(Actor* thisx, PlayState* play) { actionCounter++; return; } else if (actionCounter == 1) { - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { // Remove the link to ice block so melting it doesn't set the flag lakeControlFloorSwitch->params = 0x3E01; } diff --git a/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c b/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c index a2c1f5f9a..afa825e57 100644 --- a/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c +++ b/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c @@ -535,7 +535,7 @@ void EnOssan_TalkGoronShopkeeper(PlayState* play) { Message_ContinueTextbox(play, 0x300F); } } else if ((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) { + (IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP))) { Message_ContinueTextbox(play, 0x3057); } else { Message_ContinueTextbox(play, 0x305B); From 3c6c46d95dea547bbff236e4c2347ab8a26368f5 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 21 Apr 2024 21:09:52 -0500 Subject: [PATCH 41/52] Fix for some chests not appearing --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 700e55e18..27947f3ea 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -26,6 +26,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; +extern int32_t D_8011D3AC; } #define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() @@ -315,6 +316,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* case GI_VB_PLAY_ONEPOINT_ACTOR_CS: { if (CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO)) { Actor* actor = static_cast(opt); + + // there are a few checks throughout the game (such as chest spawns) that rely on this + // the checks are for func_8005B198() == this->dyna.actor.category + // func_8005B198 just returns D_8011D3AC + // D_8011D3AC is set to camera->target->category in Camera_Demo5 + D_8011D3AC = actor->category; + switch (actor->category) { case ACTORCAT_BG: if (actor->id == ACTOR_BG_DDAN_KD) { From 5174a48be1c39b08a8b8bc1966188b8793f3841f Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 22 Apr 2024 19:16:58 -0500 Subject: [PATCH 42/52] Point LUS to fork temporarily for dl fix --- libultraship | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libultraship b/libultraship index b135db823..b505413e8 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit b135db823aaabf6e848fcbd2796933b0771f9968 +Subproject commit b505413e85591ffc633c063ee2fe43cd7810b981 From 854e20680ad9cfbf814727a3af978102ab5efff9 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 23 Apr 2024 09:17:57 -0500 Subject: [PATCH 43/52] Fix forest temple entrance cs skip --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 27947f3ea..46b4353ee 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -866,10 +866,12 @@ void TimeSaverOnActorInitHandler(void* actorRef) { } // Forest Temple entrance cutscene - if (actor->id == ACTOR_EN_PO_SISTERS && actor->params == 4124) { + // This is a bit of a hack, we can't effectively override the behavior of the torches + // or poes from which the cutscene is triggered until we can have a "BeforeActorInit" hook. + // So for now we're just going to set the flag before they get to the room the cutscene is in + if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && actor->id == ACTOR_EN_ST && !Flags_GetSwitch(gPlayState, 0x1B)) { if (CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0)) { Flags_SetSwitch(gPlayState, 0x1B); - Actor_Kill(actor); } } From c67d8f4baaf7702703dc15e07c68b67ff2d61d9a Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 23 Apr 2024 11:31:34 -0500 Subject: [PATCH 44/52] Add missing RHT entries --- .../randomizer/3drando/hint_list.cpp | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index c6269d5de..54d2cf056 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -404,6 +404,81 @@ void HintTable_Init() { /*french*/ "la #cinquième salle# de la Chasse-aux-Trésors contient", /*spanish*/ "#en la quinta sala del Cofre del Tesoro# aguarda" }); + hintTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_1] = HintText::Sometimes( + { + // obscure text + Text{ "#gambling once# grants", /*french*/ "#parier une fois# donne", + /*spanish*/ "#apostar solo una vez# revelará" }, + Text{ "the #first or second game chest# contains", + /*french*/ "le #premier ou deuxième coffre à jeu# contient", + /*spanish*/ "#el primer o segundo cofre del azar# revela" }, + }, + {}, + // clear text + Text{ "the #first locked room# in the chest game contains", + /*french*/ "la #première salle# de la Chasse-aux-Trésors contient", + /*spanish*/ "#en la primera sala del Cofre del Tesoro# aguarda" }); + + hintTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_2] = HintText::Sometimes( + { + // obscure text + Text{ "#gambling twice# grants", /*french*/ "#parier deux fois# donne", + /*spanish*/ "#apostar dos veces# revelará" }, + Text{ "the #third or fourth game chest# contains", + /*french*/ "le #troisième ou quatrième coffre à jeu# contient", + /*spanish*/ "#el tercer o cuarto cofre del azar# revela" }, + }, + {}, + // clear text + Text{ "the #second locked room# in the chest game contains", + /*french*/ "la #deuxième salle# de la Chasse-aux-Trésors contient", + /*spanish*/ "#en la segunda sala del Cofre del Tesoro# aguarda" }); + + hintTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_3] = HintText::Sometimes( + { + // obscure text + Text{ "#gambling 3 times# grants", /*french*/ "#parier trois fois# donne", + /*spanish*/ "#apostar tres veces# revelará" }, + Text{ "the #fifth or sixth game chest# contains", + /*french*/ "le #cinquième ou sixième coffre à jeu# contient", + /*spanish*/ "#el quinto o sexto cofre del azar# revela" }, + }, + {}, + // clear text + Text{ "the #third locked room# in the chest game contains", + /*french*/ "la #troisième salle# de la Chasse-aux-Trésors contient", + /*spanish*/ "#en la tercera sala del Cofre del Tesoro# aguarda" }); + + hintTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_4] = HintText::Sometimes( + { + // obscure text + Text{ "#gambling 4 times# grants", /*french*/ "#parier quatre fois# donne", + /*spanish*/ "#apostar cuatro veces# revelará" }, + Text{ "the #seventh or eighth game chest# contains", + /*french*/ "le #septième ou huitième coffre à jeu# contient", + /*spanish*/ "#el séptimo u octavo cofre del azar# revela" }, + }, + {}, + // clear text + Text{ "the #fourth locked room# in the chest game contains", + /*french*/ "la #quatrième salle# de la Chasse-aux-Trésors contient", + /*spanish*/ "#en la cuarta sala del Cofre del Tesoro# aguarda" }); + + hintTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_5] = HintText::Sometimes( + { + // obscure text + Text{ "#gambling 5 times# grants", /*french*/ "#parier cinq fois# donne", + /*spanish*/ "#apostar cinco veces# revelará" }, + Text{ "the #ninth or tenth game chest# contains", + /*french*/ "le #neuvième ou dixième coffre à jeu# contient", + /*spanish*/ "#el noveno o décimo cofre del azar# revela" }, + }, + {}, + // clear text + Text{ "the #fifth locked room# in the chest game contains", + /*french*/ "la #cinquième salle# de la Chasse-aux-Trésors contient", + /*spanish*/ "#en la quinta sala del Cofre del Tesoro# aguarda" }); + hintTable[RHT_GF_HBA_1500_POINTS] = HintText::Sometimes( { // obscure text From d22dbd69338e770eb2f944d458fdb65ab3560dac Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Sun, 21 Apr 2024 21:16:59 -0400 Subject: [PATCH 45/52] move `RawJson` to LUS (#4063) --- soh/soh/Enhancements/tts/tts.cpp | 12 ++++++------ soh/soh/OTRGlobals.cpp | 2 -- soh/soh/resource/importer/RawJsonFactory.cpp | 19 ------------------- soh/soh/resource/importer/RawJsonFactory.h | 11 ----------- soh/soh/resource/type/RawJson.cpp | 14 -------------- soh/soh/resource/type/RawJson.h | 20 -------------------- soh/soh/resource/type/SohResourceType.h | 1 - 7 files changed, 6 insertions(+), 73 deletions(-) delete mode 100644 soh/soh/resource/importer/RawJsonFactory.cpp delete mode 100644 soh/soh/resource/importer/RawJsonFactory.h delete mode 100644 soh/soh/resource/type/RawJson.cpp delete mode 100644 soh/soh/resource/type/RawJson.h diff --git a/soh/soh/Enhancements/tts/tts.cpp b/soh/soh/Enhancements/tts/tts.cpp index f4b498815..3a375230f 100644 --- a/soh/soh/Enhancements/tts/tts.cpp +++ b/soh/soh/Enhancements/tts/tts.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -12,7 +13,6 @@ #include "overlays/gamestates/ovl_file_choose/file_choose.h" #include "soh/Enhancements/boss-rush/BossRush.h" #include "soh/resource/type/SohResourceType.h" -#include "soh/resource/type/RawJson.h" extern "C" { extern MapData* gMapData; @@ -1041,19 +1041,19 @@ void InitTTSBank() { auto initData = std::make_shared(); initData->Format = RESOURCE_FORMAT_BINARY; - initData->Type = static_cast(SOH::ResourceType::SOH_RawJson); + initData->Type = static_cast(LUS::ResourceType::Json); initData->ResourceVersion = 0; - sceneMap = std::static_pointer_cast( + sceneMap = std::static_pointer_cast( LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/scenes" + languageSuffix, true, initData))->Data; - miscMap = std::static_pointer_cast( + miscMap = std::static_pointer_cast( LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/misc" + languageSuffix, true, initData))->Data; - kaleidoMap = std::static_pointer_cast( + kaleidoMap = std::static_pointer_cast( LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/kaleidoscope" + languageSuffix, true, initData))->Data; - fileChooseMap = std::static_pointer_cast( + fileChooseMap = std::static_pointer_cast( LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/filechoose" + languageSuffix, true, initData))->Data; } diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index c7e363ad7..d62e75703 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -120,7 +120,6 @@ GameInteractorSail* GameInteractorSail::Instance; #include "soh/resource/importer/SkeletonLimbFactory.h" #include "soh/resource/importer/TextFactory.h" #include "soh/resource/importer/BackgroundFactory.h" -#include "soh/resource/importer/RawJsonFactory.h" #include "soh/config/ConfigUpdaters.h" @@ -349,7 +348,6 @@ OTRGlobals::OTRGlobals() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "AudioSoundFont", static_cast(SOH::ResourceType::SOH_AudioSoundFont), 2); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "AudioSequence", static_cast(SOH::ResourceType::SOH_AudioSequence), 2); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Background", static_cast(SOH::ResourceType::SOH_Background), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "RawJson", static_cast(SOH::ResourceType::SOH_RawJson), 0); gSaveStateMgr = std::make_shared(); gRandoContext = Rando::Context::CreateInstance(); diff --git a/soh/soh/resource/importer/RawJsonFactory.cpp b/soh/soh/resource/importer/RawJsonFactory.cpp deleted file mode 100644 index 4978f6f96..000000000 --- a/soh/soh/resource/importer/RawJsonFactory.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "soh/resource/importer/RawJsonFactory.h" -#include "soh/resource/type/RawJson.h" -#include "spdlog/spdlog.h" - -namespace SOH { -std::shared_ptr ResourceFactoryBinaryRawJsonV0::ReadResource(std::shared_ptr file) { - if (!FileHasValidFormatAndReader(file)) { - return nullptr; - } - - auto rawJson = std::make_shared(file->InitData); - auto reader = std::get>(file->Reader); - - rawJson->DataSize = file->Buffer->size(); - rawJson->Data = nlohmann::json::parse(reader->ReadCString(), nullptr, true, true); - - return rawJson; -} -} // namespace SOH diff --git a/soh/soh/resource/importer/RawJsonFactory.h b/soh/soh/resource/importer/RawJsonFactory.h deleted file mode 100644 index d5fa656b6..000000000 --- a/soh/soh/resource/importer/RawJsonFactory.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "resource/Resource.h" -#include "resource/ResourceFactoryBinary.h" - -namespace SOH { -class ResourceFactoryBinaryRawJsonV0 : public LUS::ResourceFactoryBinary { - public: - std::shared_ptr ReadResource(std::shared_ptr file) override; -}; -}; // namespace SOH diff --git a/soh/soh/resource/type/RawJson.cpp b/soh/soh/resource/type/RawJson.cpp deleted file mode 100644 index 3022a67ef..000000000 --- a/soh/soh/resource/type/RawJson.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "RawJson.h" - -namespace SOH { -RawJson::RawJson() : Resource(std::shared_ptr()) { -} - -void* RawJson::GetPointer() { - return &Data; -} - -size_t RawJson::GetPointerSize() { - return DataSize * sizeof(char); -} -} // namespace SOH diff --git a/soh/soh/resource/type/RawJson.h b/soh/soh/resource/type/RawJson.h deleted file mode 100644 index 47e0323cc..000000000 --- a/soh/soh/resource/type/RawJson.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "resource/Resource.h" -#include - -namespace SOH { - -class RawJson : public LUS::Resource { - public: - using Resource::Resource; - - RawJson(); - - void* GetPointer() override; - size_t GetPointerSize() override; - - nlohmann::json Data; - size_t DataSize; -}; -}; // namespace SOH diff --git a/soh/soh/resource/type/SohResourceType.h b/soh/soh/resource/type/SohResourceType.h index 3ef4163fe..fdf39031e 100644 --- a/soh/soh/resource/type/SohResourceType.h +++ b/soh/soh/resource/type/SohResourceType.h @@ -17,6 +17,5 @@ enum class ResourceType { SOH_AudioSequence = 0x4F534551, // OSEQ SOH_Background = 0x4F424749, // OBGI SOH_SceneCommand = 0x4F52434D, // ORCM - SOH_RawJson = 0x4A534F4E, // JSON }; } // namespace SOH From b2041df311fa68331836246b55f58dbd515aefca Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 24 Apr 2024 21:21:22 -0400 Subject: [PATCH 46/52] latest lus main --- libultraship | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libultraship b/libultraship index b505413e8..493639d5d 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit b505413e85591ffc633c063ee2fe43cd7810b981 +Subproject commit 493639d5daf75c8fa5d374f96fc95b652714299f From 1fff8fd6d5da26b089f7ec1ec0ef7e4bce17f1ee Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 24 Apr 2024 21:48:31 -0400 Subject: [PATCH 47/52] don't skip item give animation in chu bowling --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 42dabae88..bd71f7e0c 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -244,6 +244,9 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() { // Skipping ItemGet animation incompatible with checks that require closing a text box to finish rc != RC_HF_OCARINA_OF_TIME_ITEM && rc != RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && + rc != RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE && + rc != RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE && + rc != RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS && // Always show ItemGet animation for ice traps !(getItemEntry.modIndex == MOD_RANDOMIZER && getItemEntry.getItemId == RG_ICE_TRAP) && ( From baaa00569d13ab690fa837295091a6efba0e4907 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 30 Apr 2024 23:31:08 -0400 Subject: [PATCH 48/52] Adds Quick Boss Death checkbox and implements Phantom Ganon's quick death (#119) * Adds Quick Boss Death checkbox and implements Phantom Ganon's quick death. * Clarifies relocation comment. --- .../game-interactor/GameInteractor.h | 4 + .../Enhancements/timesaver_hook_handlers.cpp | 27 ++++++ soh/soh/SohMenuBar.cpp | 5 ++ .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 83 ++++++------------- .../ovl_Boss_Ganondrof/z_boss_ganondrof.h | 17 ++++ 5 files changed, 80 insertions(+), 56 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index fd5611df8..716d20b08 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -376,6 +376,10 @@ typedef enum { /*** Fixes ***/ // Vanilla condition: false GI_VB_FIX_SAW_SOFTLOCK, + + /*** Quick Boss Deaths ***/ + // Vanilla condition: true + GI_VB_PHANTOM_GANON_DEATH_SCENE, } GIVanillaBehavior; #ifdef __cplusplus diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 46b4353ee..52e14ab8c 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -24,6 +24,8 @@ extern "C" { #include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h" #include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h" #include "src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h" +#include +#include extern SaveContext gSaveContext; extern PlayState* gPlayState; extern int32_t D_8011D3AC; @@ -719,6 +721,31 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case GI_VB_PHANTOM_GANON_DEATH_SCENE: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", IS_RANDO || IS_BOSS_RUSH)) { + *should = false; + BossGanondrof* pg = static_cast(opt); + Player* player = GET_PLAYER(gPlayState); + if (pg != nullptr && pg->work[GND_ACTION_STATE] == DEATH_SPASM) { + // Skip to death scream animation and move ganondrof to middle + pg->deathState = DEATH_SCREAM; + pg->timers[0] = 50; + AnimationHeader* screamAnim = (AnimationHeader*)gPhantomGanonScreamAnim; + Animation_MorphToLoop(&pg->skelAnime, screamAnim, -10.0f); + pg->actor.world.pos.x = GND_BOSSROOM_CENTER_X; + pg->actor.world.pos.y = GND_BOSSROOM_CENTER_Y + 83.0f; + pg->actor.world.pos.z = GND_BOSSROOM_CENTER_Z; + pg->actor.shape.rot.y = 0; + pg->work[GND_BODY_DECAY_INDEX] = 0; + Audio_PlayActorSound2(&pg->actor, NA_SE_EN_FANTOM_LAST); + + // Move Player out of the center of the room + player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f; + player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z; + } + } + break; + } } } diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 3821f9df4..98de7a48c 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -581,6 +581,7 @@ void DrawEnhancementsMenu() { CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) && + CVarGetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) && CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) && CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) && @@ -592,6 +593,7 @@ void DrawEnhancementsMenu() { CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) || + CVarGetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) || CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) || CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) || @@ -608,6 +610,7 @@ void DrawEnhancementsMenu() { CVarSetInteger("gTimeSavers.SkipCutscene.Story", 1); CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 1); CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 1); + CVarSetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", 1); CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 1); CVarSetInteger("gTimeSavers.NoForcedDialog", 1); CVarSetInteger("gTimeSavers.SkipOwlInteractions", 1); @@ -619,6 +622,7 @@ void DrawEnhancementsMenu() { CVarSetInteger("gTimeSavers.SkipCutscene.Story", 0); CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 0); CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 0); + CVarSetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", 0); CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 0); CVarSetInteger("gTimeSavers.NoForcedDialog", 0); CVarSetInteger("gTimeSavers.SkipOwlInteractions", 0); @@ -633,6 +637,7 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); + UIWidgets::PaddedEnhancementCheckbox("Quick Boss Deaths", "gTimeSavers.SkipCutscene.QuickBossDeaths", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::Tooltip("Prevent forced conversations with Navi or other NPCs"); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index 82fe2c131..0b025dcd6 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -12,19 +12,10 @@ #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) -typedef enum { - /* 0 */ NOT_DEAD, - /* 1 */ DEATH_START, - /* 2 */ DEATH_THROES, - /* 3 */ DEATH_WARP, - /* 4 */ DEATH_SCREAM, - /* 5 */ DEATH_DISINTEGRATE, - /* 6 */ DEATH_FINISH -} BossGanondrofDeathState; - typedef enum { /* 0 */ THROW_NORMAL, /* 1 */ THROW_SLOW @@ -42,12 +33,6 @@ typedef enum { /* 3 */ CHARGE_FINISH } BossGanondrofChargeAction; -typedef enum { - /* 0 */ DEATH_SPASM, - /* 1 */ DEATH_LIMP, - /* 2 */ DEATH_HUNCHED -} BossGanondrofDeathAction; - void BossGanondrof_Init(Actor* thisx, PlayState* play); void BossGanondrof_Destroy(Actor* thisx, PlayState* play); void BossGanondrof_Update(Actor* thisx, PlayState* play); @@ -959,26 +944,13 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) { case DEATH_THROES: switch (this->work[GND_ACTION_STATE]) { case DEATH_SPASM: - if (Animation_OnFrame(&this->skelAnime, this->fwork[GND_END_FRAME]) && !IS_RANDO && !IS_BOSS_RUSH) { - this->fwork[GND_END_FRAME] = Animation_GetLastFrame(&gPhantomGanonAirDamageAnim); - Animation_Change(&this->skelAnime, &gPhantomGanonAirDamageAnim, 0.5f, 0.0f, - this->fwork[GND_END_FRAME], ANIMMODE_ONCE_INTERP, 0.0f); - this->work[GND_ACTION_STATE] = DEATH_LIMP; - } else if (IS_RANDO || IS_BOSS_RUSH) { - // Skip to death scream animation and move ganondrof to middle - this->deathState = DEATH_SCREAM; - this->timers[0] = 50; - Animation_MorphToLoop(&this->skelAnime, &gPhantomGanonScreamAnim, -10.0f); - this->actor.world.pos.x = GND_BOSSROOM_CENTER_X; - this->actor.world.pos.y = GND_BOSSROOM_CENTER_Y + 83.0f; - this->actor.world.pos.z = GND_BOSSROOM_CENTER_Z; - this->actor.shape.rot.y = 0; - this->work[GND_BODY_DECAY_INDEX] = 0; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_LAST); - - // Move Player out of the center of the room - player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f; - player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z; + if (GameInteractor_Should(GI_VB_PHANTOM_GANON_DEATH_SCENE, true, this)) { + if (Animation_OnFrame(&this->skelAnime, this->fwork[GND_END_FRAME])) { + this->fwork[GND_END_FRAME] = Animation_GetLastFrame(&gPhantomGanonAirDamageAnim); + Animation_Change(&this->skelAnime, &gPhantomGanonAirDamageAnim, 0.5f, 0.0f, + this->fwork[GND_END_FRAME], ANIMMODE_ONCE_INTERP, 0.0f); + this->work[GND_ACTION_STATE] = DEATH_LIMP; + } } break; case DEATH_LIMP: @@ -991,26 +963,25 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) { bodyDecayLevel = 1; break; } - if (IS_RANDO || IS_BOSS_RUSH) { - break; - } - Math_ApproachS(&this->actor.shape.rot.y, this->work[GND_VARIANCE_TIMER] * -100, 5, 0xBB8); - Math_ApproachF(&this->cameraNextEye.z, this->targetPos.z + 60.0f, 0.02f, 0.5f); - Math_ApproachF(&this->actor.world.pos.y, GND_BOSSROOM_CENTER_Y + 133.0f, 0.05f, 100.0f); - this->actor.world.pos.y += Math_SinS(this->work[GND_VARIANCE_TIMER] * 1500); - this->cameraNextAt.x = this->targetPos.x; - this->cameraNextAt.y = this->targetPos.y - 10.0f; - this->cameraNextAt.z = this->targetPos.z; - if (this->timers[0] == 0) { - this->deathState = DEATH_WARP; - this->timers[0] = 350; - this->timers[1] = 50; - this->fwork[GND_CAMERA_ZOOM] = 300.0f; - this->cameraNextEye.y = GND_BOSSROOM_CENTER_Y + 233.0f; - player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f; - player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z; - holdCamera = true; - bodyDecayLevel = 1; + if (GameInteractor_Should(GI_VB_PHANTOM_GANON_DEATH_SCENE, true, NULL)) { + Math_ApproachS(&this->actor.shape.rot.y, this->work[GND_VARIANCE_TIMER] * -100, 5, 0xBB8); + Math_ApproachF(&this->cameraNextEye.z, this->targetPos.z + 60.0f, 0.02f, 0.5f); + Math_ApproachF(&this->actor.world.pos.y, GND_BOSSROOM_CENTER_Y + 133.0f, 0.05f, 100.0f); + this->actor.world.pos.y += Math_SinS(this->work[GND_VARIANCE_TIMER] * 1500); + this->cameraNextAt.x = this->targetPos.x; + this->cameraNextAt.y = this->targetPos.y - 10.0f; + this->cameraNextAt.z = this->targetPos.z; + if (this->timers[0] == 0) { + this->deathState = DEATH_WARP; + this->timers[0] = 350; + this->timers[1] = 50; + this->fwork[GND_CAMERA_ZOOM] = 300.0f; + this->cameraNextEye.y = GND_BOSSROOM_CENTER_Y + 233.0f; + player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f; + player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z; + holdCamera = true; + bodyDecayLevel = 1; + } } break; case DEATH_WARP: diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h index ff4a841d6..1e45ca766 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h @@ -61,6 +61,23 @@ typedef enum { /* 13 */ GND_FLOAT_COUNT = 13 } BossGanondrofF32Var; +// SOH [Enhancements] Relocated from z_boss_ganondrof.c to use in time saver. +typedef enum { + /* 0 */ NOT_DEAD, + /* 1 */ DEATH_START, + /* 2 */ DEATH_THROES, + /* 3 */ DEATH_WARP, + /* 4 */ DEATH_SCREAM, + /* 5 */ DEATH_DISINTEGRATE, + /* 6 */ DEATH_FINISH +} BossGanondrofDeathState; + +typedef enum { + /* 0 */ DEATH_SPASM, + /* 1 */ DEATH_LIMP, + /* 2 */ DEATH_HUNCHED +} BossGanondrofDeathAction; + typedef struct BossGanondrof { /* 0x0000 */ Actor actor; /* 0x014C */ SkelAnime skelAnime; From 7da6a5b604f3fe2143fabdea9b5dcd154aaa5edd Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:36:26 -0400 Subject: [PATCH 49/52] vb deku stick cheat (#115) * vb deku stick cheat * it's the 21st now --------- Co-authored-by: Garrett Cox --- soh/soh/Enhancements/cheat_hook_handlers.cpp | 56 +++++++++++++++++++ soh/soh/Enhancements/cheat_hook_handlers.h | 6 ++ .../game-interactor/GameInteractor.h | 7 +++ soh/soh/Enhancements/mods.cpp | 2 + .../actors/ovl_player_actor/z_player.c | 37 +++++------- 5 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 soh/soh/Enhancements/cheat_hook_handlers.cpp create mode 100644 soh/soh/Enhancements/cheat_hook_handlers.h diff --git a/soh/soh/Enhancements/cheat_hook_handlers.cpp b/soh/soh/Enhancements/cheat_hook_handlers.cpp new file mode 100644 index 000000000..cdc8333ce --- /dev/null +++ b/soh/soh/Enhancements/cheat_hook_handlers.cpp @@ -0,0 +1,56 @@ +#include +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/enhancementTypes.h" + +extern "C" { +#include "macros.h" +#include "variables.h" + +extern SaveContext gSaveContext; +extern PlayState* gPlayState; +} + +void CheatsOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* opt) { + switch (id) { + case GI_VB_DEKU_STICK_BREAK: { + if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) { + *should = false; + } + break; + } + case GI_VB_DEKU_STICK_BE_ON_FIRE: { + if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE) { + Player* player = GET_PLAYER(gPlayState); + player->unk_860 = 200; // Keeps the stick's flame lit + player->unk_85C = 1.0f; // Ensures the stick is the proper length + *should = true; + } + break; + } + case GI_VB_DEKU_STICK_BURN_OUT: { + if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) { + *should = false; + } + break; + } + case GI_VB_DEKU_STICK_BURN_DOWN: { + if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) { + *should = false; + } + break; + } + } +} + +static uint32_t onVanillaBehaviorHook = 0; +void CheatsRegisterHooks() { + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) mutable { + + GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); + onVanillaBehaviorHook = 0; + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(CheatsOnVanillaBehaviorHandler); + + }); +} diff --git a/soh/soh/Enhancements/cheat_hook_handlers.h b/soh/soh/Enhancements/cheat_hook_handlers.h new file mode 100644 index 000000000..88a79f285 --- /dev/null +++ b/soh/soh/Enhancements/cheat_hook_handlers.h @@ -0,0 +1,6 @@ +#ifndef CHEAT_HOOK_HANDLERS_H +#define CHEAT_HOOK_HANDLERS_H + +void CheatsRegisterHooks(); + +#endif // CHEAT_HOOK_HANDLERS_H diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 716d20b08..17b6198b3 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -377,6 +377,13 @@ typedef enum { // Vanilla condition: false GI_VB_FIX_SAW_SOFTLOCK, + /*** Cheats? ***/ + GI_VB_DEKU_STICK_BE_ON_FIRE, + GI_VB_DEKU_STICK_BREAK, + GI_VB_DEKU_STICK_BURN_DOWN, + GI_VB_DEKU_STICK_BURN_OUT, + GI_VB_DEKU_UPDATE_BURNING_DEKU_STICK, + /*** Quick Boss Deaths ***/ // Vanilla condition: true GI_VB_PHANTOM_GANON_DEATH_SCENE, diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 580c29b3c..c0425f148 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -11,6 +11,7 @@ #include #include "soh/Enhancements/nametag.h" #include "soh/Enhancements/timesaver_hook_handlers.h" +#include "soh/Enhancements/cheat_hook_handlers.h" #include "soh/Enhancements/randomizer/hook_handlers.h" #include "objects/object_gi_compass/object_gi_compass.h" @@ -1715,6 +1716,7 @@ void RegisterRandomizerCompasses() { void InitMods() { RandomizerRegisterHooks(); TimeSaverRegisterHooks(); + CheatsRegisterHooks(); RegisterTTS(); RegisterInfiniteMoney(); RegisterInfiniteHealth(); diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 2b994f56f..43a34c778 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -8515,15 +8515,14 @@ void func_80842A28(PlayState* play, Player* this) { } void func_80842A88(PlayState* play, Player* this) { - if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) { - Inventory_ChangeAmmo(ITEM_STICK, -1); - Player_UseItem(play, this, ITEM_NONE); - } + Inventory_ChangeAmmo(ITEM_STICK, -1); + Player_UseItem(play, this, ITEM_NONE); } s32 func_80842AC4(PlayState* play, Player* this) { if ((this->heldItemAction == PLAYER_IA_DEKU_STICK) && (this->unk_85C > 0.5f)) { - if (AMMO(ITEM_STICK) != 0 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) { + + if (GameInteractor_Should(GI_VB_DEKU_STICK_BREAK, AMMO(ITEM_STICK) != 0, NULL)) { EffectSsStick_Spawn(play, &this->bodyPartsPos[PLAYER_BODYPART_R_HAND], this->actor.shape.rot.y + 0x8000); this->unk_85C = 0.5f; @@ -10942,37 +10941,30 @@ static Vec3f D_808547B0 = { 0.0f, 0.5f, 0.0f }; static Color_RGBA8 D_808547BC = { 255, 255, 100, 255 }; static Color_RGBA8 D_808547C0 = { 255, 50, 0, 0 }; -void func_80848A04(PlayState* play, Player* this) { +void Player_UpdateBurningDekuStick(PlayState* play, Player* this) { f32 temp; - if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE) { - f32 temp2 = 1.0f; // Secondary temporary variable to use with the alleged draw flame function - this->unk_860 = 200; // Keeps the stick's flame lit - this->unk_85C = 1.0f; // Ensures the stick is the proper length - func_8002836C(play, &this->meleeWeaponInfo[0].tip, &D_808547A4, &D_808547B0, &D_808547BC, &D_808547C0, temp2 * 200.0f, - 0, 8); // I believe this draws the flame effect - } - - if (this->unk_85C == 0.0f && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) { - Player_UseItem(play, this, 0xFF); + if (GameInteractor_Should(GI_VB_DEKU_STICK_BURN_OUT, this->unk_85C == 0.0f, NULL)) { + Player_UseItem(play, this, ITEM_NONE); return; } temp = 1.0f; - if (DECR(this->unk_860) == 0 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) { + uint8_t vanillaShouldBurnOutCondition = DECR(this->unk_860) == 0; + if (GameInteractor_Should(GI_VB_DEKU_STICK_BURN_OUT, vanillaShouldBurnOutCondition, NULL)) { Inventory_ChangeAmmo(ITEM_STICK, -1); this->unk_860 = 1; temp = 0.0f; this->unk_85C = temp; } else if (this->unk_860 > 200) { temp = (210 - this->unk_860) / 10.0f; - } else if (this->unk_860 < 20 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) { + } else if (GameInteractor_Should(GI_VB_DEKU_STICK_BURN_DOWN, this->unk_860 < 20, NULL)) { temp = this->unk_860 / 20.0f; this->unk_85C = temp; } - func_8002836C(play, &this->meleeWeaponInfo[0].tip, &D_808547A4, &D_808547B0, &D_808547BC, &D_808547C0, temp * 200.0f, - 0, 8); + func_8002836C(play, &this->meleeWeaponInfo[0].tip, &D_808547A4, &D_808547B0, &D_808547BC, &D_808547C0, + temp * 200.0f, 0, 8); } void Player_UpdateBodyShock(PlayState* play, Player* this) { @@ -11267,8 +11259,9 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { func_808473D4(play, this); func_80836BEC(this, play); - if ((this->heldItemAction == PLAYER_IA_DEKU_STICK) && ((this->unk_860 != 0) || CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE)) { - func_80848A04(play, this); + if (this->heldItemAction == PLAYER_IA_DEKU_STICK && + GameInteractor_Should(GI_VB_DEKU_STICK_BE_ON_FIRE, this->unk_860 != 0, NULL)) { + Player_UpdateBurningDekuStick(play, this); } else if ((this->heldItemAction == PLAYER_IA_FISHING_POLE) && (this->unk_860 < 0)) { this->unk_860++; } From de715da1842ac3df36badacc9b66b50f7e850565 Mon Sep 17 00:00:00 2001 From: Archez Date: Sat, 4 May 2024 17:49:36 -0400 Subject: [PATCH 50/52] explicitly include unordered_map header (#122) --- soh/soh/Enhancements/game-interactor/GameInteractor.h | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 17b6198b3..e0b1c1ce1 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -420,6 +420,7 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state); #ifdef __cplusplus #include +#include #include #include #include From e71839ed8f90a902679f2533fde78d44e3000e6a Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Sat, 4 May 2024 17:50:19 -0400 Subject: [PATCH 51/52] Conversion of Nabooru Quick Death to VB hook (#120) * Nabooru quick death conversion * Fix brackets, not sure exactly how this was working before. --- .../game-interactor/GameInteractor.h | 1 + .../Enhancements/timesaver_hook_handlers.cpp | 24 +++++++++++++++++++ soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c | 20 +--------------- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index e0b1c1ce1..84126099f 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -387,6 +387,7 @@ typedef enum { /*** Quick Boss Deaths ***/ // Vanilla condition: true GI_VB_PHANTOM_GANON_DEATH_SCENE, + GI_VB_NABOORU_KNUCKLE_DEATH_SCENE, } GIVanillaBehavior; #ifdef __cplusplus diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 52e14ab8c..642eae7cc 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -25,6 +25,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h" #include "src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h" #include +#include #include extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -746,6 +747,29 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case GI_VB_NABOORU_KNUCKLE_DEATH_SCENE: { + EnIk* ik = static_cast(opt); + if (CVarGetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", IS_RANDO)) { + // Because no CS in rando, we hide the death of the knuckle by spawning flames and kill the actor + if ((ik->actor.colChkInfo.health <= 10)) { + s32 i; + Vec3f pos; + Vec3f sp7C = { 0.0f, 0.5f, 0.0f }; + int flameAmount = 100; + + for (i = flameAmount; i >= 0; i--) { + pos.x = ik->actor.world.pos.x + Rand_CenteredFloat(120.0f); + pos.z = ik->actor.world.pos.z + Rand_CenteredFloat(120.0f); + pos.y = ik->actor.world.pos.y + 20.0f + Rand_CenteredFloat(120.0f); + EffectSsDeadDb_Spawn(gPlayState, &pos, &sp7C, &sp7C, 100, 0, 255, 255, 255, 255, 0, 0, 255, 1, 9, + true); + } + Actor_Kill(&ik->actor); + } + *should = false; + } + break; + } } } diff --git a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c index aaf0e0342..5f1634237 100644 --- a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c +++ b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c @@ -1439,28 +1439,10 @@ void func_80A781CC(Actor* thisx, PlayState* play) { if (!Play_InCsMode(play)) { this->actor.update = EnIk_Update; this->actor.draw = EnIk_Draw; - // Don't initiate nabooru defeat CS in rando - if (!(IS_RANDO)) { + if (GameInteractor_Should(GI_VB_NABOORU_KNUCKLE_DEATH_SCENE, true, this)) { Cutscene_SetSegment(play, gSpiritBossNabooruKnuckleDefeatCs); gSaveContext.cutsceneTrigger = 1; Actor_SetScale(&this->actor, 0.01f); - } else { - // Because no CS in rando, we hide the death of the knuckle by spawning flames and kill the actor - if ((this->actor.colChkInfo.health <= 10)) { - s32 i; - Vec3f pos; - Vec3f sp7C = { 0.0f, 0.5f, 0.0f }; - int flameAmount = 100; - - for (i = flameAmount; i >= 0; i--) { - pos.x = this->actor.world.pos.x + Rand_CenteredFloat(120.0f); - pos.z = this->actor.world.pos.z + Rand_CenteredFloat(120.0f); - pos.y = this->actor.world.pos.y + 20.0f + Rand_CenteredFloat(120.0f); - EffectSsDeadDb_Spawn(play, &pos, &sp7C, &sp7C, 100, 0, 255, 255, 255, 255, 0, 0, 255, 1, 9, - true); - } - Actor_Kill(&this->actor); - } } Flags_SetEventChkInf(EVENTCHKINF_FINISHED_NABOORU_BATTLE); func_80A7735C(this, play); From 0c69ff17c2525607cc28acc9d2097879218b3fae Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 5 May 2024 14:46:23 -0500 Subject: [PATCH 52/52] Fix two minor issues from merge --- soh/soh/Enhancements/randomizer/location_list.cpp | 1 + soh/soh/Enhancements/randomizer/randomizer.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 97d432de3..92a91f32a 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1,4 +1,5 @@ #include "static_data.h" +#include "z64save.h" #define TWO_ACTOR_PARAMS(a, b) (abs(a) << 16) | abs(b) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index ea0b30bfb..de0295b30 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -329,13 +329,13 @@ void Randomizer::LoadMerchantMessages() { "Je te vends mon dernier %rHaricot&magique%w pour %r99 Rubis%w.\x1B&%gAcheter&Ne pas acheter%w")); } -std::map trialFlagToTrialKey = { - { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, Rando::TrialKey::LIGHT_TRIAL, }, - { EVENTCHKINF_COMPLETED_FOREST_TRIAL, Rando::TrialKey::FOREST_TRIAL, }, - { EVENTCHKINF_COMPLETED_FIRE_TRIAL, Rando::TrialKey::FIRE_TRIAL, }, - { EVENTCHKINF_COMPLETED_WATER_TRIAL, Rando::TrialKey::WATER_TRIAL, }, - { EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, Rando::TrialKey::SPIRIT_TRIAL, }, - { EVENTCHKINF_COMPLETED_SHADOW_TRIAL, Rando::TrialKey::SHADOW_TRIAL, } +std::map trialFlagToTrialKey = { + { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, TK_LIGHT_TRIAL, }, + { EVENTCHKINF_COMPLETED_FOREST_TRIAL, TK_FOREST_TRIAL, }, + { EVENTCHKINF_COMPLETED_FIRE_TRIAL, TK_FIRE_TRIAL, }, + { EVENTCHKINF_COMPLETED_WATER_TRIAL, TK_WATER_TRIAL, }, + { EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, TK_SPIRIT_TRIAL, }, + { EVENTCHKINF_COMPLETED_SHADOW_TRIAL, TK_SHADOW_TRIAL, } }; bool Randomizer::IsTrialRequired(s32 trialFlag) {