diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp index d743bead9..123523e14 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp @@ -1,6 +1,7 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ShipInit.hpp" +#include "soh/Enhancements/randomizer/context.h" extern "C" { #include "z64save.h" @@ -17,9 +18,12 @@ void RegisterSkipLostWoodsBridge() { COND_VB_SHOULD(VB_PLAY_TRANSITION_CS, CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), { if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); - if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true)) { - Item_Give(gPlayState, ITEM_OCARINA_FAIRY); + if (!IS_RANDO || !Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_NPC_SOULS).Get() || + Flags_GetRandomizerInf(RAND_INF_SARIA_SOUL)) { + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true)) { + Item_Give(gPlayState, ITEM_OCARINA_FAIRY); + } } *should = false; } diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 186307aed..66c8d0147 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -142,6 +142,16 @@ typedef enum { // - None VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, + // #### `result` + // ```c + // CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && + // CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) && !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE) && + // LINK_IS_CHILD + // ``` + // #### `args` + // - None + VB_BE_ELIGIBLE_FOR_OCARINA_OF_TIME, + // #### `result` // ```c // !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index f5195c91d..3a424fdd6 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2028,6 +2028,55 @@ void StaticData::HintTable_Init_Item() { CustomMessage("an evil soul", /*german*/"eine böse Seele", /*french*/"une âme maléfique"), CustomMessage("some powerful essence", /*german*/"etwas mächtige Essenz", /*french*/"une essence incroyablement puissante")}); + hintTextTable[RHT_ANJU_SOUL] = HintText(CustomMessage("Anju's Soul")); + hintTextTable[RHT_TALON_SOUL] = HintText(CustomMessage("Talon's Soul")); + hintTextTable[RHT_GROG_SOUL] = HintText(CustomMessage("Grog's Soul")); + hintTextTable[RHT_GRANNY_SOUL] = HintText(CustomMessage("Granny's Soul")); + hintTextTable[RHT_FADO_SOUL] = HintText(CustomMessage("Fado's Soul")); + hintTextTable[RHT_LINK_SOUL] = HintText(CustomMessage("Darunia's Son's Soul")); + hintTextTable[RHT_BIGGORON_SOUL] = HintText(CustomMessage("Biggoron's Soul")); + hintTextTable[RHT_HOT_RODDER_SOUL] = HintText(CustomMessage("Hot Rodder's Soul")); + hintTextTable[RHT_MEDIGORON_SOUL] = HintText(CustomMessage("Medigoron's Soul")); + hintTextTable[RHT_CARPENTER_BOSS_SOUL] = HintText(CustomMessage("Carpenter Boss's Soul")); + hintTextTable[RHT_ICHIRO_SOUL] = HintText(CustomMessage("Ichiro's Soul")); + hintTextTable[RHT_SABOORO_SOUL] = HintText(CustomMessage("Sabooro's Soul")); + hintTextTable[RHT_JIRO_SOUL] = HintText(CustomMessage("Jiro's Soul")); + hintTextTable[RHT_SHIRO_SOUL] = HintText(CustomMessage("Shiro's Soul")); + hintTextTable[RHT_HW_GATEKEEPER_SOUL] = HintText(CustomMessage("Haunted Wasteland Gate Operator's Soul")); + hintTextTable[RHT_GTG_GATEKEEPER_SOUL] = HintText(CustomMessage("Training Ground Gate Operator's Soul")); + hintTextTable[RHT_ARCHER_SOUL] = HintText(CustomMessage("Horseback Archer's Soul")); + hintTextTable[RHT_GREAT_FAIRY_SOUL] = HintText(CustomMessage("Great Fairy's Soul")); + hintTextTable[RHT_POE_COLLECTOR_SOUL] = HintText(CustomMessage("Poe Collector's Soul")); + hintTextTable[RHT_DAMPE_SOUL] = HintText(CustomMessage("Dampe's Soul")); + hintTextTable[RHT_WINDMILL_MAN_SOUL] = HintText(CustomMessage("Windmill Man's Soul")); + hintTextTable[RHT_MAN_ON_ROOF_SOUL] = HintText(CustomMessage("Man on Roof's Soul")); + hintTextTable[RHT_KAKARIKO_GATEKEEPER_SOUL] = HintText(CustomMessage("Kakariko Gatekeeper's Soul")); + hintTextTable[RHT_MALON_SOUL] = HintText(CustomMessage("Malon's Soul")); + hintTextTable[RHT_BEGGAR_SOUL] = HintText(CustomMessage("Beggar's Soul")); + hintTextTable[RHT_DOG_LADY_SOUL] = HintText(CustomMessage("Dog Lady's Soul")); + hintTextTable[RHT_ARMS_DEALER_SOUL] = HintText(CustomMessage("Arms Dealer's Soul")); + hintTextTable[RHT_BEAN_SALESMAN_SOUL] = HintText(CustomMessage("Bean Salesman's Soul")); + hintTextTable[RHT_SHOOTING_SOUL] = HintText(CustomMessage("Shooter's Soul")); + hintTextTable[RHT_KOKIRI_SHOPKEEPER_SOUL] = HintText(CustomMessage("Kokiri Shopkeeper's Soul")); + hintTextTable[RHT_POTION_SHOPKEEPER_SOUL] = HintText(CustomMessage("Potion Shopkeeper's Soul")); + hintTextTable[RHT_BAZAAR_SHOPKEEPER_SOUL] = HintText(CustomMessage("Bazaar Shopkeeper's Soul")); + hintTextTable[RHT_GORON_SHOPKEEPER_SOUL] = HintText(CustomMessage("Goron Shopkeeper's Soul")); + hintTextTable[RHT_ZORA_SHOPKEEPER_SOUL] = HintText(CustomMessage("Zora Shopkeeper's Soul")); + hintTextTable[RHT_BOMBCHU_SHOPKEEPER_SOUL] = HintText(CustomMessage("Bombchu Shopkeeper's Soul")); + hintTextTable[RHT_MASK_SALESMAN_SOUL] = HintText(CustomMessage("Mask Salesman's Soul")); + hintTextTable[RHT_TREASURE_MAN_SOUL] = HintText(CustomMessage("Treasure Man's Soul")); + hintTextTable[RHT_BOMBCHU_LADY_SOUL] = HintText(CustomMessage("Bombchu Lady's Soul")); + hintTextTable[RHT_DIVING_SOUL] = HintText(CustomMessage("Diver's Soul")); + hintTextTable[RHT_SCIENTIST_SOUL] = HintText(CustomMessage("Scientist's Soul")); + hintTextTable[RHT_KAEPORA_SOUL] = HintText(CustomMessage("Kaepora's Soul")); + hintTextTable[RHT_RAURU_SOUL] = HintText(CustomMessage("Rauru's Soul")); + hintTextTable[RHT_SARIA_SOUL] = HintText(CustomMessage("Saria's Soul")); + hintTextTable[RHT_DARUNIA_SOUL] = HintText(CustomMessage("Darunia's Soul")); + hintTextTable[RHT_RUTO_SOUL] = HintText(CustomMessage("Ruto's Soul")); + hintTextTable[RHT_NABOORU_SOUL] = HintText(CustomMessage("Nabooru's Soul")); + hintTextTable[RHT_IMPA_SOUL] = HintText(CustomMessage("Impa's Soul")); + hintTextTable[RHT_ZELDA_SOUL] = HintText(CustomMessage("Zelda's Soul")); + hintTextTable[RHT_OCARINA_A_BUTTON] = HintText(CustomMessage("an Ocarina A Button", /*german*/"die A-Taste der Okarina", /*french*/"la Touche A de l'Ocarina"), // /*spanish*/un botón A de Ocarina { diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index fbe800662..9b9557622 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -753,29 +753,23 @@ void GenerateItemPool() { } if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { - AddItemToMainPool(RG_GOHMA_SOUL); - AddItemToMainPool(RG_KING_DODONGO_SOUL); - AddItemToMainPool(RG_BARINADE_SOUL); - AddItemToMainPool(RG_PHANTOM_GANON_SOUL); - AddItemToMainPool(RG_VOLVAGIA_SOUL); - AddItemToMainPool(RG_MORPHA_SOUL); - AddItemToMainPool(RG_BONGO_BONGO_SOUL); - AddItemToMainPool(RG_TWINROVA_SOUL); + for (int rg = RG_GOHMA_SOUL; rg <= RG_TWINROVA_SOUL; rg++) { + AddItemToMainPool((RandomizerGet)rg); + ctx->possibleIceTrapModels.push_back((RandomizerGet)rg); + } - ctx->possibleIceTrapModels.push_back(RG_GOHMA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_KING_DODONGO_SOUL); - ctx->possibleIceTrapModels.push_back(RG_BARINADE_SOUL); - ctx->possibleIceTrapModels.push_back(RG_PHANTOM_GANON_SOUL); - ctx->possibleIceTrapModels.push_back(RG_VOLVAGIA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_MORPHA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_BONGO_BONGO_SOUL); - ctx->possibleIceTrapModels.push_back(RG_TWINROVA_SOUL); if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { AddItemToMainPool(RG_GANON_SOUL); ctx->possibleIceTrapModels.push_back(RG_GANON_SOUL); } } + if (ctx->GetOption(RSK_SHUFFLE_NPC_SOULS)) { + for (int rg = RG_ANJU_SOUL; rg <= RG_ZELDA_SOUL; rg++) { + AddItemToMainPool((RandomizerGet)rg); + } + } + if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET)) { AddItemToMainPool(RG_PROGRESSIVE_WALLET); } diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index b9cc0b10b..73dd4e046 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -963,11 +963,16 @@ extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEn Matrix_ReplaceRotation(&play->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); - gDPSetGrayscaleColor(POLY_XLU_DISP++, flameColors[slot][0], flameColors[slot][1], flameColors[slot][2], 255); + if (slot >= 0 && slot < 9) { + gDPSetGrayscaleColor(POLY_XLU_DISP++, flameColors[slot][0], flameColors[slot][1], flameColors[slot][2], 255); + } else { + gDPSetGrayscaleColor(POLY_XLU_DISP++, 255, 255, 255, 255); + } gSPGrayscale(POLY_XLU_DISP++, true); gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiBlueFireFlameDL); gSPGrayscale(POLY_XLU_DISP++, false); Matrix_Pop(); + CLOSE_DISPS(play->state.gfxCtx); // Draw the generic boss soul model diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index a6bbae638..a7ab7871b 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -23,6 +23,7 @@ extern "C" { #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" #include "src/overlays/actors/ovl_En_Si/z_en_si.h" +#include "src/overlays/actors/ovl_En_Ossan/z_en_ossan.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_En_Gb/z_en_gb.h" @@ -820,17 +821,20 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; case VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER: { - *should = - !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && !Flags_GetTreasure(gPlayState, 0x2); + *should = !(RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) && !Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && + !Flags_GetTreasure(gPlayState, 0x2); break; } case VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER: - *should = - !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && Flags_GetTreasure(gPlayState, 0x2); + *should = !(RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) && !Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && + Flags_GetTreasure(gPlayState, 0x2); break; case VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT: - *should = - !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); + *should = !(RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) && !Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); break; case VB_MIDO_SPAWN: if (RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_OFF && @@ -853,16 +857,25 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD: *should = !Flags_GetRandomizerInf(RAND_INF_DARUNIAS_JOY); break; + case VB_BE_ELIGIBLE_FOR_OCARINA_OF_TIME: + if (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) && + (!Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL) || !Flags_GetRandomizerInf(RAND_INF_IMPA_SOUL))) { + *should = false; + } + break; case VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS: *should = LINK_IS_ADULT && (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && + (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) != RO_NPC_SOULS_ON_PLUS_SAGES || + Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && MeetsLACSRequirements(); break; case 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); + CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && + (!RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) || Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)); break; case VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD: { // Don't require a bomb bag to get prize in rando @@ -1461,6 +1474,32 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_PLAY_BLUE_WARP_CS: { + if (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) == RO_NPC_SOULS_ON_PLUS_SAGES) { + bool hasSoul = true; + switch (gPlayState->sceneNum) { + case SCENE_FOREST_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_SARIA_SOUL); + break; + case SCENE_DODONGOS_CAVERN_BOSS: + case SCENE_FIRE_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_DARUNIA_SOUL); + break; + case SCENE_JABU_JABU_BOSS: + case SCENE_WATER_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_RUTO_SOUL); + break; + case SCENE_SPIRIT_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_NABOORU_SOUL); + break; + case SCENE_SHADOW_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_IMPA_SOUL); + break; + } + if (!hasSoul) { + *should = false; + break; + } + } // 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); @@ -1800,7 +1839,9 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { 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) { + CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && + (!RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) || Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && + gPlayState->roomCtx.curRoom.num == 0) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); } @@ -2063,6 +2104,195 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } + if (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS)) { + auto inf = RAND_INF_MAX; + switch (actor->id) { + case ACTOR_EN_NIW_LADY: + inf = RAND_INF_ANJU_SOUL; + break; + case ACTOR_BG_SPOT15_RRBOX: + // milk crates, prevent reaching Zelda without Talon's Soul + if (gPlayState->sceneNum == SCENE_HYRULE_CASTLE) { + inf = RAND_INF_TALON_SOUL; + } + break; + case ACTOR_EN_TA: + inf = RAND_INF_TALON_SOUL; + break; + case ACTOR_EN_HS: + case ACTOR_EN_HS2: + inf = RAND_INF_GROG_SOUL; + break; + case ACTOR_EN_DS: + inf = RAND_INF_GRANNY_SOUL; + break; + case ACTOR_EN_KO: + if ((actor->params & 0xFF) == ENKO_TYPE_CHILD_FADO) { + inf = RAND_INF_FADO_SOUL; + } + break; + case ACTOR_EN_GO2: + switch (actor->params & 0x1F) { + case GORON_CITY_LINK: + inf = RAND_INF_LINK_SOUL; + break; + case GORON_DMT_BIGGORON: + inf = RAND_INF_BIGGORON_SOUL; + break; + case GORON_CITY_ROLLING_BIG: + inf = RAND_INF_HOT_RODDER_SOUL; + break; + } + break; + case ACTOR_EN_GM: + inf = RAND_INF_MEDIGORON_SOUL; + break; + case ACTOR_EN_TORYO: + inf = RAND_INF_CARPENTER_BOSS_SOUL; + break; + case ACTOR_EN_DAIKU: + case ACTOR_EN_DAIKU_KAKARIKO: + inf = (RandomizerInf)(RAND_INF_ICHIRO_SOUL + (actor->params & 3)); + break; + case ACTOR_EN_GE1: + switch (actor->params & 0xFF) { + case GE1_TYPE_HORSEBACK_ARCHERY: + inf = RAND_INF_ARCHER_SOUL; + break; + case GE1_TYPE_TRAINING_GROUND_GUARD: + inf = RAND_INF_GTG_GATEKEEPER_SOUL; + break; + case GE1_TYPE_GATE_OPERATOR: + inf = RAND_INF_HW_GATEKEEPER_SOUL; + break; + } + break; + case ACTOR_EN_OKARINA_TAG: + if (gPlayState->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC || + gPlayState->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS) { + inf = RAND_INF_GREAT_FAIRY_SOUL; + } + break; + case ACTOR_EN_GB: + inf = RAND_INF_POE_COLLECTOR_SOUL; + break; + case ACTOR_EN_TK: + case ACTOR_EN_PO_RELAY: + inf = RAND_INF_DAMPE_SOUL; + break; + case ACTOR_EN_FU: + inf = RAND_INF_WINDMILL_MAN_SOUL; + break; + case ACTOR_EN_ANI: + inf = RAND_INF_MAN_ON_ROOF_SOUL; + break; + case ACTOR_EN_HEISHI2: + if ((actor->params & 0xFF) == 5) { + inf = RAND_INF_KAKARIKO_GATEKEEPER_SOUL; + } + break; + case ACTOR_EN_MA1: + case ACTOR_EN_MA2: + case ACTOR_EN_MA3: + inf = RAND_INF_MALON_SOUL; + break; + case ACTOR_EN_SA: + inf = RAND_INF_SARIA_SOUL; + break; + case ACTOR_EN_DU: + inf = RAND_INF_DARUNIA_SOUL; + break; + case ACTOR_EN_RU1: + case ACTOR_EN_RU2: + inf = RAND_INF_RUTO_SOUL; + break; + case ACTOR_EN_NB: + inf = RAND_INF_NABOORU_SOUL; + break; + case ACTOR_EN_XC: + case ACTOR_EN_ZL1: + case ACTOR_EN_ZL4: + inf = RAND_INF_ZELDA_SOUL; + break; + case ACTOR_EN_ZL2: + case ACTOR_EN_ZL3: + case ACTOR_BOSS_GANON: + case ACTOR_BOSS_GANON2: + if (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) == RO_NPC_SOULS_ON_PLUS_SAGES) { + inf = RAND_INF_ZELDA_SOUL; + } + break; + case ACTOR_EN_HY: + switch (actor->params & 0x7F) { + case ENHY_TYPE_BOJ_5: + inf = RAND_INF_BEGGAR_SOUL; + break; + case ENHY_TYPE_AOB: + inf = RAND_INF_DOG_LADY_SOUL; + break; + } + break; + case ACTOR_EN_JS: + inf = RAND_INF_ARMS_DEALER_SOUL; + break; + case ACTOR_EN_MS: + inf = RAND_INF_BEAN_SALESMAN_SOUL; + break; + case ACTOR_EN_SYATEKI_MAN: + inf = RAND_INF_SHOOTING_SOUL; + break; + case ACTOR_EN_OSSAN: + switch (actor->params) { + case OSSAN_TYPE_KOKIRI: + inf = RAND_INF_KOKIRI_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_KAKARIKO_POTION: + case OSSAN_TYPE_MARKET_POTION: + inf = RAND_INF_POTION_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_BAZAAR: + case OSSAN_TYPE_ADULT: + inf = RAND_INF_BAZAAR_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_GORON: + inf = RAND_INF_GORON_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_ZORA: + inf = RAND_INF_ZORA_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_BOMBCHUS: + inf = RAND_INF_BOMBCHU_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_MASK: + inf = RAND_INF_MASK_SALESMAN_SOUL; + break; + } + break; + case ACTOR_EN_TAKARA_MAN: + inf = RAND_INF_TREASURE_MAN_SOUL; + break; + case ACTOR_EN_BOM_BOWL_MAN: + case ACTOR_EN_WALL_TUBO: // crashes when bombchu lady missing + inf = RAND_INF_BOMBCHU_LADY_SOUL; + break; + case ACTOR_EN_DIVING_GAME: + inf = RAND_INF_DIVING_SOUL; + break; + case ACTOR_EN_MK: + inf = RAND_INF_SCIENTIST_SOUL; + break; + case ACTOR_EN_OWL: + inf = RAND_INF_KAEPORA_SOUL; + break; + } + if (inf != RAND_INF_MAX && !Flags_GetRandomizerInf(inf)) { + if (inf == RAND_INF_KAEPORA_SOUL) { + Flags_SetSwitch(gPlayState, 0x23); // allow child link to pull Lake Hylia grave + } + Actor_Kill(actor); + } + } + // In MQ Spirit, remove the large silver block in the hole as child so the chest in the silver block hallway // can be guaranteed accessible if (actor->id == ACTOR_OBJ_OSHIHIKI && LINK_IS_CHILD && ResourceMgr_IsGameMasterQuest() && diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 786717c80..2fa4d7df8 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -316,7 +316,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BUY_BOMBS_535] = Item(RG_BUY_BOMBS_535, Text{ "Buy Bombs (5) [35]", "Acheter: Bombes (5) [35]", "Bomben kaufen (5) [35]" }, ITEMTYPE_SHOP, GI_BOMBS_5, true, LOGIC_BUY_BOMB, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 35); itemTable[RG_BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{ "Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Rotes Elixier kaufen [40]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 40); itemTable[RG_BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{ "Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Rotes Elixier kaufen [50]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50); - // Misc. + // Boss souls itemTable[RG_GOHMA_SOUL] = Item(RG_GOHMA_SOUL, Text{ "Gohma's Soul", "Âme de Gohma", "Gohmas Seele" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_CAN_SUMMON_GOHMA, RHT_GOHMA_SOUL, RG_GOHMA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_GOHMA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_KING_DODONGO_SOUL] = Item(RG_KING_DODONGO_SOUL, Text{ "King Dodongo's Soul", "Âme du Roi Dodongo", "König Dodongos Seele" }, ITEMTYPE_ITEM, 0xE1, true, LOGIC_CAN_SUMMON_KINGDODONGO, RHT_KING_DODONGO_SOUL, RG_KING_DODONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); @@ -335,6 +335,104 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_TWINROVA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_GANON_SOUL] = Item(RG_GANON_SOUL, Text{ "Ganon's Soul", "Âme de Ganon", "Ganons Seele" }, ITEMTYPE_ITEM, 0xE8, true, LOGIC_CAN_SUMMON_GANON, RHT_GANON_SOUL, RG_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_GANON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + // NPC souls + itemTable[RG_ANJU_SOUL] = Item(RG_ANJU_SOUL, Text{ "Anju's Soul", "Âme de Anju", "Anjus Seele" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ANJU, RHT_ANJU_SOUL, RG_ANJU_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ANJU_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_TALON_SOUL] = Item(RG_TALON_SOUL, Text{ "Talon's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_TALON, RHT_TALON_SOUL, RG_TALON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_TALON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GROG_SOUL] = Item(RG_GROG_SOUL, Text{ "Grog's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GROG, RHT_GROG_SOUL, RG_GROG_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GROG_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GRANNY_SOUL] = Item(RG_GRANNY_SOUL, Text{ "Granny's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GRANNY, RHT_GRANNY_SOUL, RG_GRANNY_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GRANNY_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_FADO_SOUL] = Item(RG_FADO_SOUL, Text{ "Fado's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_FADO, RHT_FADO_SOUL, RG_FADO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_FADO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_LINK_SOUL] = Item(RG_LINK_SOUL, Text{ "Darunia's Son's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_LINK, RHT_LINK_SOUL, RG_LINK_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_LINK_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BIGGORON_SOUL] = Item(RG_BIGGORON_SOUL, Text{ "Biggoron's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BIGGORON, RHT_BIGGORON_SOUL, RG_BIGGORON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BIGGORON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_HOT_RODDER_SOUL] = Item(RG_HOT_RODDER_SOUL, Text{ "Hot Rodder's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_HOT_RODDER, RHT_HOT_RODDER_SOUL, RG_HOT_RODDER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_HOT_RODDER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_MEDIGORON_SOUL] = Item(RG_MEDIGORON_SOUL, Text{ "Medigoron's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MEDIGORON, RHT_MEDIGORON_SOUL, RG_MEDIGORON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MEDIGORON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_CARPENTER_BOSS_SOUL] = Item(RG_CARPENTER_BOSS_SOUL, Text{ "Carpenter Boss's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_CARPENTER_BOSS, RHT_CARPENTER_BOSS_SOUL, RG_CARPENTER_BOSS_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_CARPENTER_BOSS_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ICHIRO_SOUL] = Item(RG_ICHIRO_SOUL, Text{ "Ichiro's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ICHIRO, RHT_ICHIRO_SOUL, RG_ICHIRO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_FADO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SABOORO_SOUL] = Item(RG_SABOORO_SOUL, Text{ "Sabooro's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SABOORO, RHT_SABOORO_SOUL, RG_FADO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SABOORO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_JIRO_SOUL] = Item(RG_JIRO_SOUL, Text{ "Jiro's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_JIRO, RHT_JIRO_SOUL, RG_JIRO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_JIRO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SHIRO_SOUL] = Item(RG_SHIRO_SOUL, Text{ "Shiro's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SHIRO, RHT_SHIRO_SOUL, RG_SHIRO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SHIRO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_HW_GATEKEEPER_SOUL] = Item(RG_HW_GATEKEEPER_SOUL, Text{ "Haunted Wasteland Gate Operator's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_HW_GATEKEEPER, RHT_HW_GATEKEEPER_SOUL, RG_HW_GATEKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_HW_GATEKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GTG_GATEKEEPER_SOUL] = Item(RG_GTG_GATEKEEPER_SOUL, Text{ "Training Ground Gate Operator's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GTG_GATEKEEPER, RHT_GTG_GATEKEEPER_SOUL, RG_GTG_GATEKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GTG_GATEKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ARCHER_SOUL] = Item(RG_ARCHER_SOUL, Text{ "Horseback Archer's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ARCHER, RHT_ARCHER_SOUL, RG_ARCHER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ARCHER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GREAT_FAIRY_SOUL] = Item(RG_GREAT_FAIRY_SOUL, Text{ "Great Fairy's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GREAT_FAIRY, RHT_GREAT_FAIRY_SOUL, RG_GREAT_FAIRY_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GREAT_FAIRY_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_POE_COLLECTOR_SOUL] = Item(RG_POE_COLLECTOR_SOUL, Text{ "Poe Collector's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_POE_COLLECTOR, RHT_POE_COLLECTOR_SOUL, RG_POE_COLLECTOR_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_POE_COLLECTOR_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_DAMPE_SOUL] = Item(RG_DAMPE_SOUL, Text{ "Dampe's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_DAMPE, RHT_DAMPE_SOUL, RG_DAMPE_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DAMPE_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_WINDMILL_MAN_SOUL] = Item(RG_WINDMILL_MAN_SOUL, Text{ "Windmill Man's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_WINDMILL_MAN, RHT_WINDMILL_MAN_SOUL, RG_WINDMILL_MAN_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_WINDMILL_MAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_MAN_ON_ROOF_SOUL] = Item(RG_MAN_ON_ROOF_SOUL, Text{ "Man on Roof's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MAN_ON_ROOF, RHT_MAN_ON_ROOF_SOUL, RG_MAN_ON_ROOF_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MAN_ON_ROOF_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_KAKARIKO_GATEKEEPER_SOUL] = Item(RG_KAKARIKO_GATEKEEPER_SOUL, Text{ "Kakariko Gatekeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_KAKARIKO_GATEKEEPER, RHT_KAKARIKO_GATEKEEPER_SOUL, RG_KAKARIKO_GATEKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_KAKARIKO_GATEKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_MALON_SOUL] = Item(RG_MALON_SOUL, Text{ "Malon's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MALON, RHT_MALON_SOUL, RG_MALON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MALON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BEGGAR_SOUL] = Item(RG_BEGGAR_SOUL, Text{ "Beggar's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BEGGAR, RHT_BEGGAR_SOUL, RG_BEGGAR_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BEGGAR_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_DOG_LADY_SOUL] = Item(RG_DOG_LADY_SOUL, Text{ "Dog Lady's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_DOG_LADY, RHT_DOG_LADY_SOUL, RG_DOG_LADY_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DOG_LADY_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ARMS_DEALER_SOUL] = Item(RG_ARMS_DEALER_SOUL, Text{ "Arms Dealer's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ARMS_DEALER, RHT_ARMS_DEALER_SOUL, RG_ARMS_DEALER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ARMS_DEALER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BEAN_SALESMAN_SOUL] = Item(RG_BEAN_SALESMAN_SOUL, Text{ "Bean Salesman's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BEAN_SALESMAN, RHT_BEAN_SALESMAN_SOUL, RG_BEAN_SALESMAN_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BEAN_SALESMAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SHOOTING_SOUL] = Item(RG_SHOOTING_SOUL, Text{ "Shooter's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SHOOTING, RHT_SHOOTING_SOUL, RG_SHOOTING_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SHOOTING_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_KOKIRI_SHOPKEEPER_SOUL] = Item(RG_KOKIRI_SHOPKEEPER_SOUL, Text{ "Kokiri Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_KOKIRI_SHOPKEEPER, RHT_KOKIRI_SHOPKEEPER_SOUL, RG_KOKIRI_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_KOKIRI_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_POTION_SHOPKEEPER_SOUL] = Item(RG_POTION_SHOPKEEPER_SOUL, Text{ "Potion Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_POTION_SHOPKEEPER, RHT_POTION_SHOPKEEPER_SOUL, RG_POTION_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_POTION_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BAZAAR_SHOPKEEPER_SOUL] = Item(RG_BAZAAR_SHOPKEEPER_SOUL, Text{ "Bazaar Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BAZAAR_SHOPKEEPER, RHT_BAZAAR_SHOPKEEPER_SOUL, RG_BAZAAR_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BAZAAR_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GORON_SHOPKEEPER_SOUL] = Item(RG_GORON_SHOPKEEPER_SOUL, Text{ "Goron Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GORON_SHOPKEEPER, RHT_GORON_SHOPKEEPER_SOUL, RG_GORON_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GORON_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ZORA_SHOPKEEPER_SOUL] = Item(RG_ZORA_SHOPKEEPER_SOUL, Text{ "Zora Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ZORA_SHOPKEEPER, RHT_ZORA_SHOPKEEPER_SOUL, RG_ZORA_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ZORA_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BOMBCHU_SHOPKEEPER_SOUL] = Item(RG_BOMBCHU_SHOPKEEPER_SOUL, Text{ "Bombchu Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BOMBCHU_SHOPKEEPER, RHT_BOMBCHU_SHOPKEEPER_SOUL, RG_BOMBCHU_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BOMBCHU_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_MASK_SALESMAN_SOUL] = Item(RG_MASK_SALESMAN_SOUL, Text{ "Mask Salesman's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MASK_SALESMAN, RHT_MASK_SALESMAN_SOUL, RG_MASK_SALESMAN_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_SALESMAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_TREASURE_MAN_SOUL] = Item(RG_TREASURE_MAN_SOUL, Text{ "Treasure Man's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_TREASURE_MAN, RHT_TREASURE_MAN_SOUL, RG_TREASURE_MAN_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_TREASURE_MAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BOMBCHU_LADY_SOUL] = Item(RG_BOMBCHU_LADY_SOUL, Text{ "Bombchu Lady's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BOMBCHU_LADY, RHT_BOMBCHU_LADY_SOUL, RG_BOMBCHU_LADY_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BOMBCHU_LADY_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_DIVING_SOUL] = Item(RG_DIVING_SOUL, Text{ "Diver's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_DIVING, RHT_DIVING_SOUL, RG_DIVING_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DIVING_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SCIENTIST_SOUL] = Item(RG_SCIENTIST_SOUL, Text{ "Scientist's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SCIENTIST, RHT_SCIENTIST_SOUL, RG_SCIENTIST_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SCIENTIST_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_KAEPORA_SOUL] = Item(RG_KAEPORA_SOUL, Text{ "Kaepora's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_KAEPORA, RHT_KAEPORA_SOUL, RG_KAEPORA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_KAEPORA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_RAURU_SOUL] = Item(RG_RAURU_SOUL, Text{ "Rauru's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_RAURU, RHT_RAURU_SOUL, RG_RAURU_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_RAURU_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SARIA_SOUL] = Item(RG_SARIA_SOUL, Text{ "Saria's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SARIA, RHT_SARIA_SOUL, RG_SARIA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SARIA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_DARUNIA_SOUL] = Item(RG_DARUNIA_SOUL, Text{ "Darunia's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_DARUNIA, RHT_DARUNIA_SOUL, RG_DARUNIA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DARUNIA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_RUTO_SOUL] = Item(RG_RUTO_SOUL, Text{ "Ruto's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_RUTO, RHT_RUTO_SOUL, RG_RUTO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_RUTO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_NABOORU_SOUL] = Item(RG_NABOORU_SOUL, Text{ "Nabooru's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_NABOORU, RHT_NABOORU_SOUL, RG_NABOORU_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_NABOORU_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_IMPA_SOUL] = Item(RG_IMPA_SOUL, Text{ "Impa's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_IMPA, RHT_IMPA_SOUL, RG_IMPA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_IMPA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ZELDA_SOUL] = Item(RG_ZELDA_SOUL, Text{ "Zelda's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ZELDA, RHT_ZELDA_SOUL, RG_ZELDA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ZELDA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + // Misc. itemTable[RG_FISHING_POLE] = Item(RG_FISHING_POLE, Text{ "Fishing Pole", "Canne à Pêche", "Angelrute" }, ITEMTYPE_ITEM, RG_FISHING_POLE, true, LOGIC_FISHING_POLE, RHT_FISHING_POLE, RG_FISHING_POLE, OBJECT_GI_FISH, GID_FISHING_POLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_FISHING_POLE].SetCustomDrawFunc(Randomizer_DrawFishingPoleGI); @@ -354,7 +452,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); - + itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BOMB_BAG_INF] = Item(RG_BOMB_BAG_INF, Text{ "Infinite Bomb Bag", "Sac de Bombes Infini", "Unendliche Bombentasche" }, ITEMTYPE_ITEM, RG_BOMB_BAG_INF, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BOMB_BAG_INF, RG_BOMB_BAG_INF, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BULLET_BAG_INF] = Item(RG_BULLET_BAG_INF, Text{ "Infinite Bullet Bag", "Sac de Graines Infinis", "Unendliche Munitionstasche" }, ITEMTYPE_ITEM, RG_BULLET_BAG_INF, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BULLET_BAG_INF, RG_BULLET_BAG_INF, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index bef3b58ae..86909da2d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -573,19 +573,20 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", SCENE_DODONGOS_CAVERN_BOSS, { // Events // Blue Fire Arrows need similar accuracy as hammer trick, only put in logic when both hammer & blue fire tricks enabled - EventAccess(&logic->DodongosCavernClear, []{return Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || + EventAccess(&logic->DodongosCavernWin, []{return Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_DC_HAMMER_FLOOR) ? logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->BlueFire()) : ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE));}) && logic->CanKillEnemy(RE_KING_DODONGO);}), + EventAccess(&logic->DodongosCavernClear, []{return logic->DodongosCavernWin && logic->HasSage(RG_DARUNIA_SOUL);}), }, { // Locations LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true), - LOCATION(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, logic->DodongosCavernClear), + LOCATION(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, logic->DodongosCavernWin), LOCATION(RC_KING_DODONGO, logic->DodongosCavernClear), }, { // Exits Entrance(RR_DODONGOS_CAVERN_BOSS_EXIT, []{return true;}), - Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->DodongosCavernClear;}, false), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->DodongosCavernWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index f57d6bd21..a77586a5c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -744,15 +744,16 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", SCENE_FIRE_TEMPLE_BOSS, { // Events - EventAccess(&logic->FireTempleClear, []{return logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA);}), + EventAccess(&logic->FireTempleWin, []{return logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA);}), + EventAccess(&logic->FireTempleClear, []{return logic->FireTempleWin && logic->HasSage(RG_DARUNIA_SOUL);}), }, { // Locations - LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear), + LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleWin), LOCATION(RC_VOLVAGIA, logic->FireTempleClear), }, { // Exits Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTempleClear;}, false), + Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index d3149c009..c8eebc878 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -606,15 +606,16 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", SCENE_FOREST_TEMPLE_BOSS, { // Events - EventAccess(&logic->ForestTempleClear, []{return logic->CanKillEnemy(RE_PHANTOM_GANON);}), + EventAccess(&logic->ForestTempleWin, []{return logic->CanKillEnemy(RE_PHANTOM_GANON);}), + EventAccess(&logic->ForestTempleClear, []{return logic->ForestTempleWin && logic->HasSage(RG_SARIA_SOUL);}), }, { // Locations - LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear), + LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleWin), LOCATION(RC_PHANTOM_GANON, logic->ForestTempleClear), }, { // Exits Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->ForestTempleClear;}, false), + Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->ForestTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 8571ba384..73f8a82af 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -19,7 +19,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_LOBBY] = Region("Ganon's Castle Lobby", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_SHEIK_HINT_GC, true), + LOCATION(RC_SHEIK_HINT_GC, logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_GANONS_CASTLE_ENTRYWAY, []{return true;}), @@ -147,7 +147,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_MAIN] = Region("Ganon's Castle MQ Main", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_SHEIK_HINT_MQ_GC, true), + LOCATION(RC_SHEIK_HINT_MQ_GC, logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_LOBBY, []{return true;}), @@ -483,7 +483,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_TOWER_GANONDORF_LAIR] = Region("Ganondorf's Lair", SCENE_GANONDORF_BOSS, {}, { //Locations - LOCATION(RC_GANONDORF_HINT, logic->HasBossSoul(RG_GANON_SOUL)), + LOCATION(RC_GANONDORF_HINT, logic->HasSoul(RG_GANON_SOUL)), }, { //Exits Entrance(RR_GANONS_CASTLE_ESCAPE, []{return logic->CanKillEnemy(RE_GANONDORF);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 5151377ce..83ea456e1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -33,7 +33,7 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->IsAdult), LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()), LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS)), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult && logic->HasSoul(RG_ZELDA_SOUL)), LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire()), LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire() && logic->HookshotOrBoomerang()), @@ -123,7 +123,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_STALFOS_ROOM] = Region("Ice Cavern MQ Stalfos Room", SCENE_ICE_CAVERN, {}, { //Locations LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_STALFOS)), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS)), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS) && logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_ICE_CAVERN_MQ_WEST_CORRIDOR, []{return Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index c40ccf805..8749f1f21 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -48,7 +48,7 @@ void RegionTable_Init_JabuJabusBelly() { //contains B1 of hole room (aside from the ledge leading to big octo), 2 octorock room and north water switch room areaTable[RR_JABU_JABUS_BELLY_B1_NORTH] = Region("Jabu Jabus Belly B1 North", SCENE_JABU_JABU, { //Events - EventAccess(&logic->JabuRutoIn1F, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}), + EventAccess(&logic->JabuRutoIn1F, []{return logic->HasSoul(RG_RUTO_SOUL) && (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE));}), EventAccess(&logic->FairyPot, []{return logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK));}), }, { //Locations @@ -365,7 +365,8 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", SCENE_JABU_JABU_BOSS, { // Events //todo: add pot kill trick - EventAccess(&logic->JabuJabusBellyClear, []{return logic->CanKillEnemy(RE_BARINADE);}), + EventAccess(&logic->JabuJabusBellyWin, []{return logic->CanKillEnemy(RE_BARINADE);}), + EventAccess(&logic->JabuJabusBellyClear, []{return logic->JabuJabusBellyWin && logic->HasSage(RG_RUTO_SOUL);}), }, { // Locations LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()), @@ -374,12 +375,12 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_4, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_5, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_6, logic->CanBreakPots()), - LOCATION(RC_JABU_JABUS_BELLY_BARINADE_HEART, logic->JabuJabusBellyClear), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_HEART, logic->JabuJabusBellyWin), LOCATION(RC_BARINADE, logic->JabuJabusBellyClear), }, { // Exits Entrance(RR_JABU_JABUS_BELLY_BOSS_EXIT, []{return false;}), - Entrance(RR_ZORAS_FOUNTAIN, []{return logic->JabuJabusBellyClear;}, false), + Entrance(RR_ZORAS_FOUNTAIN, []{return logic->JabuJabusBellyWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index d276fc418..aab680b5e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -409,15 +409,16 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", SCENE_SHADOW_TEMPLE_BOSS, { // Events - EventAccess(&logic->ShadowTempleClear, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}), + EventAccess(&logic->ShadowTempleWin, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}), + EventAccess(&logic->ShadowTempleClear, []{ return logic->ShadowTempleWin && logic->HasSage(RG_IMPA_SOUL); }), }, { // Locations - LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear), + LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleWin), LOCATION(RC_BONGO_BONGO, logic->ShadowTempleClear), }, { // Exits Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return logic->ShadowTempleClear;}, false), + Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return logic->ShadowTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 98c783e20..e9d67e092 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -32,14 +32,14 @@ void RegionTable_Init_SpiritTemple() { EventAccess(&logic->NutCrate, []{return true;}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), - LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_1, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_2, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_3, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_4, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, logic->CanBreakSmallCrates()), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_1, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_2, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_3, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_4, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, logic->CanBreakSmallCrates()), }, { //Exits @@ -556,15 +556,16 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", SCENE_SPIRIT_TEMPLE_BOSS, { // Events - EventAccess(&logic->SpiritTempleClear, []{return logic->CanKillEnemy(RE_TWINROVA);}), + EventAccess(&logic->SpiritTempleWin, []{return logic->CanKillEnemy(RE_TWINROVA);}), + EventAccess(&logic->SpiritTempleClear, []{return logic->SpiritTempleWin && logic->HasSage(RG_NABOORU_SOUL);}), }, { // Locations - LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear), + LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleWin), LOCATION(RC_TWINROVA, logic->SpiritTempleClear), }, { // Exits Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_DESERT_COLOSSUS, []{return logic->SpiritTempleClear;}, false), + Entrance(RR_DESERT_COLOSSUS, []{return logic->SpiritTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 20280a6af..3cfea66e6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -773,7 +773,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - + }, { //Exits @@ -848,15 +848,16 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", SCENE_WATER_TEMPLE_BOSS, { // Events - EventAccess(&logic->WaterTempleClear, []{return logic->CanKillEnemy(RE_MORPHA);}), + EventAccess(&logic->WaterTempleWin, []{return logic->CanKillEnemy(RE_MORPHA);}), + EventAccess(&logic->WaterTempleClear, []{return logic->WaterTempleWin && logic->HasSage(RG_RUTO_SOUL);}), }, { // Locations - LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear), + LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleWin), LOCATION(RC_MORPHA, logic->WaterTempleClear), }, { // Exits Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_LAKE_HYLIA, []{return logic->WaterTempleClear;}, false), + Entrance(RR_LAKE_HYLIA, []{return logic->WaterTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/gerudo_fortress.cpp index 1a55e6829..320476b55 100644 --- a/soh/soh/Enhancements/randomizer/location_access/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/gerudo_fortress.cpp @@ -13,17 +13,17 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GERUDO_FORTRESS] = Region("Gerudo Fortress", SCENE_GERUDOS_FORTRESS, { //Events EventAccess(&logic->CarpenterRescue, []{return logic->CanFinishGerudoFortress();}), - EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}), - EventAccess(&logic->GtG_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET);}), + EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasSoul(RG_HW_GATEKEEPER_SOUL);}), + EventAccess(&logic->GtG_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET) && logic->HasSoul(RG_GTG_GATEKEEPER_SOUL);}), }, { //Locations LOCATION(RC_GF_CHEST, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_GF_HBA_1000_POINTS, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), - LOCATION(RC_GF_HBA_1500_POINTS, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), - LOCATION(RC_GF_NORTH_F1_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), - LOCATION(RC_GF_NORTH_F2_CARPENTER, (logic->CanKillEnemy(RE_GERUDO_WARRIOR)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))), - LOCATION(RC_GF_SOUTH_F1_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), - LOCATION(RC_GF_SOUTH_F2_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), + LOCATION(RC_GF_HBA_1000_POINTS, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay && logic->HasSoul(RG_ARCHER_SOUL)), + LOCATION(RC_GF_HBA_1500_POINTS, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay && logic->HasSoul(RG_ARCHER_SOUL)), + LOCATION(RC_GF_NORTH_F1_CARPENTER, logic->HasSoul(RG_ICHIRO_SOUL) && logic->CanKillEnemy(RE_GERUDO_WARRIOR)), + LOCATION(RC_GF_NORTH_F2_CARPENTER, logic->HasSoul(RG_SABOORO_SOUL) && (logic->CanKillEnemy(RE_GERUDO_WARRIOR)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))), + LOCATION(RC_GF_SOUTH_F1_CARPENTER, logic->HasSoul(RG_JIRO_SOUL) && logic->CanKillEnemy(RE_GERUDO_WARRIOR)), + LOCATION(RC_GF_SOUTH_F2_CARPENTER, logic->HasSoul(RG_SHIRO_SOUL) && logic->CanKillEnemy(RE_GERUDO_WARRIOR)), LOCATION(RC_GF_GERUDO_MEMBERSHIP_CARD, logic->CanFinishGerudoFortress()), LOCATION(RC_GF_GS_ARCHERY_RANGE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanGetNightTimeGS()), LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN) || ctx->GetTrickOption(RT_GF_JUMP)) && logic->CanGetNightTimeGS()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index b9525386c..fd961293e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -23,7 +23,7 @@ void RegionTable_Init_CastleGrounds() { EventAccess(&logic->BugRock, []{return true;}), }, { //Locations - LOCATION(RC_HC_MALON_EGG, true), + LOCATION(RC_HC_MALON_EGG, logic->HasSoul(RG_MALON_SOUL)), LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), @@ -36,7 +36,7 @@ void RegionTable_Init_CastleGrounds() { }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return true;}), - Entrance(RR_HC_GARDEN, []{return logic->CanUse(RG_WEIRD_EGG) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}), + Entrance(RR_HC_GARDEN, []{return (logic->HasSoul(RG_TALON_SOUL) && logic->CanUse(RG_WEIRD_EGG)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}), Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, []{return logic->BlastOrSmash();}), Entrance(RR_HC_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), }); @@ -52,7 +52,7 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_HC_GREAT_FAIRY_FOUNTAIN] = Region("HC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, {}, { //Locations - LOCATION(RC_HC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_HC_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return true;}), @@ -102,7 +102,7 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_OGC_GREAT_FAIRY_FOUNTAIN] = Region("OGC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { //Locations - LOCATION(RC_OGC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_OGC_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index be1b2043a..f36bfdd03 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -67,7 +67,7 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_CENTRAL_NEARBY] = Region("DMC Central Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts() >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL) || (ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)))), - LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48;}), @@ -101,7 +101,7 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Region("DMC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { //Locations - LOCATION(RC_DMC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_DMC_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_DMC_LOWER_LOCAL, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index dbf218947..0afeb99f4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -36,9 +36,9 @@ void RegionTable_Init_DeathMountainTrail() { EventAccess(&logic->BugRock, []{return logic->IsChild;}), }, { //Locations - LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)), - LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->CanUse(RG_EYEDROPS)), - LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)), + LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->HasSoul(RG_BIGGORON_SOUL) && logic->CanUse(RG_BROKEN_SWORD)), + LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->HasSoul(RG_BIGGORON_SOUL) && logic->CanUse(RG_EYEDROPS)), + LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->HasSoul(RG_BIGGORON_SOUL) && logic->CanUse(RG_CLAIM_CHECK)), LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || ctx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS()), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), @@ -47,14 +47,14 @@ void RegionTable_Init_DeathMountainTrail() { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}), Entrance(RR_DMC_UPPER_LOCAL, []{return true;}), - Entrance(RR_DMT_OWL_FLIGHT, []{return logic->IsChild;}, false), + Entrance(RR_DMT_OWL_FLIGHT, []{return logic->IsChild && logic->HasSoul(RG_KAEPORA_SOUL);}), Entrance(RR_DMT_COW_GROTTO, []{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}), Entrance(RR_DMT_GREAT_FAIRY_FOUNTAIN, []{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}), }); areaTable[RR_DMT_OWL_FLIGHT] = Region("DMT Owl Flight", SCENE_DEATH_MOUNTAIN_TRAIL, {}, {}, { //Exits - Entrance(RR_KAK_IMPAS_ROOFTOP, []{return true;}), + Entrance(RR_KAK_IMPAS_ROOFTOP, []{return true;}, false), }); areaTable[RR_DMT_COW_GROTTO] = Region("DMT Cow Grotto", SCENE_GROTTOS, {}, { @@ -100,7 +100,7 @@ void RegionTable_Init_DeathMountainTrail() { areaTable[RR_DMT_GREAT_FAIRY_FOUNTAIN] = Region("DMT Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { //Locations - LOCATION(RC_DMT_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_DMT_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index f4b8b01c3..8ea97bf1d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -52,7 +52,7 @@ void RegionTable_Init_DesertColossus() { areaTable[RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE] = Region("Desert Colossus From Spirit Entryway", SCENE_DESERT_COLOSSUS, {}, { //Locations - LOCATION(RC_SHEIK_AT_COLOSSUS, true), + LOCATION(RC_SHEIK_AT_COLOSSUS, logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exist Entrance(RR_DESERT_COLOSSUS, []{return true;}), @@ -60,7 +60,7 @@ void RegionTable_Init_DesertColossus() { areaTable[RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN] = Region("Colossus Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, {}, { //Locations - LOCATION(RC_COLOSSUS_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_COLOSSUS_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_DESERT_COLOSSUS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index 4959636e2..8e290f90d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -69,7 +69,7 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_FORTRESS_SIDE] = Region("GV Fortress Side", SCENE_GERUDO_VALLEY, {}, { //Locations LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), + LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->HasSoul(RG_CARPENTER_BOSS_SOUL) && logic->CanUse(RG_POACHERS_SAW)), LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index 7027ab6c6..3bac476e1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -14,19 +14,18 @@ void RegionTable_Init_GoronCity() { EventAccess(&logic->GCWoodsWarpOpen, []{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER) || logic->GoronCityChildFire;}), EventAccess(&logic->GCDaruniasDoorOpenChild, []{return logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY);}), // bottle animation causes similar complications as stopping goron with Din's Fire, only put in logic when both din's & blue fire tricks enabled - EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || - (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && (logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)))));}), + EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->IsAdult && logic->HasSoul(RG_LINK_SOUL) && + (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && (logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)))));}), }, { //Locations LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))), LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), - LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), + LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && logic->HasSoul(RG_HOT_RODDER_SOUL) && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult), LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()), - LOCATION(RC_GC_MEDIGORON, logic->IsAdult && (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CallGossipFairyExceptSuns()), LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), @@ -49,6 +48,7 @@ void RegionTable_Init_GoronCity() { areaTable[RR_GC_MEDIGORON] = Region("GC Medigoron", SCENE_GORON_CITY, {}, { //Locations + LOCATION(RC_GC_MEDIGORON, logic->IsAdult && logic->HasSoul(RG_MEDIGORON_SOUL)), LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, true), @@ -72,7 +72,7 @@ void RegionTable_Init_GoronCity() { EventAccess(&logic->GoronCityChildFire, []{return logic->IsChild && logic->CanUse(RG_STICKS);}), }, { //Locations - LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), + LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->HasSoul(RG_DARUNIA_SOUL) && logic->CanUse(RG_SARIAS_SONG)), LOCATION(RC_GC_DARUNIA_POT_1, logic->CanBreakPots()), LOCATION(RC_GC_DARUNIA_POT_2, logic->CanBreakPots()), LOCATION(RC_GC_DARUNIA_POT_3, logic->CanBreakPots()), @@ -90,14 +90,14 @@ void RegionTable_Init_GoronCity() { areaTable[RR_GC_SHOP] = Region("GC Shop", SCENE_GORON_SHOP, {}, { //Locations - LOCATION(RC_GC_SHOP_ITEM_1, true), - LOCATION(RC_GC_SHOP_ITEM_2, true), - LOCATION(RC_GC_SHOP_ITEM_3, true), - LOCATION(RC_GC_SHOP_ITEM_4, true), - LOCATION(RC_GC_SHOP_ITEM_5, true), - LOCATION(RC_GC_SHOP_ITEM_6, true), - LOCATION(RC_GC_SHOP_ITEM_7, true), - LOCATION(RC_GC_SHOP_ITEM_8, true), + LOCATION(RC_GC_SHOP_ITEM_1, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_2, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_3, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_4, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_5, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_6, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_7, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_8, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_GORON_CITY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 763d12575..d44c48286 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -13,7 +13,7 @@ void RegionTable_Init_Graveyard() { }, { //Locations LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change + LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasSoul(RG_DAMPE_SOUL) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), @@ -88,11 +88,11 @@ void RegionTable_Init_Graveyard() { areaTable[RR_GRAVEYARD_DAMPES_GRAVE] = Region("Graveyard Dampes Grave", SCENE_WINDMILL_AND_DAMPES_GRAVE, { //Events EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->DampesWindmillAccess, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), + EventAccess(&logic->DampesWindmillAccess, []{return logic->IsAdult && logic->HasSoul(RG_DAMPE_SOUL) && logic->CanUse(RG_SONG_OF_TIME);}), }, { //Locations - LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH)), + LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->HasSoul(RG_DAMPE_SOUL) && (logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH))), LOCATION(RC_GY_DAMPES_GRAVE_POT_1, logic->CanBreakPots()), LOCATION(RC_GY_DAMPES_GRAVE_POT_2, logic->CanBreakPots()), LOCATION(RC_GY_DAMPES_GRAVE_POT_3, logic->CanBreakPots()), @@ -102,15 +102,15 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_1, true), LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_2, true), LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_3, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, logic->HasSoul(RG_DAMPE_SOUL)), }, { //Exits Entrance(RR_THE_GRAVEYARD, []{return true;}), - Entrance(RR_KAK_WINDMILL, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}, false), + Entrance(RR_KAK_WINDMILL, []{return logic->DampesWindmillAccess;}, false), }); areaTable[RR_GRAVEYARD_DAMPES_HOUSE] = Region("Graveyard Dampes House", SCENE_GRAVEKEEPERS_HUT, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp index 930ffcb4f..a1d4fbc4c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp @@ -19,11 +19,11 @@ void RegionTable_Init_HauntedWasteland() { //Events EventAccess(&logic->FairyPot, []{return true;}), EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->CarpetMerchant, []{return logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + EventAccess(&logic->CarpetMerchant, []{return logic->HasSoul(RG_ARMS_DEALER_SOUL) && logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), }, { //Locations LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), - LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->HasSoul(RG_ARMS_DEALER_SOUL) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))), LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()), LOCATION(RC_WASTELAND_NEAR_GS_POT_1, logic->CanBreakPots()), LOCATION(RC_WASTELAND_NEAR_GS_POT_2, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index 9ee999914..53713bdb5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -10,8 +10,8 @@ void RegionTable_Init_HyruleField() { EventAccess(&logic->BigPoeKill, []{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_EPONA) && logic->HasBottle();}), }, { //Locations - LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), - LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE) && logic->HasSoul(RG_ZELDA_SOUL) && logic->HasSoul(RG_IMPA_SOUL)), + LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE) && logic->HasSoul(RG_ZELDA_SOUL) && logic->HasSoul(RG_IMPA_SOUL)), LOCATION(RC_HF_POND_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_HF_CENTRAL_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_HF_CENTRAL_GRASS_2, logic->CanCutShrubs()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 13490c9a4..b2d8b1dd4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -9,13 +9,13 @@ void RegionTable_Init_Kakariko() { //Events EventAccess(&logic->BugRock, []{return true;}), //Open Gate setting is applied in RR_ROOT - EventAccess(&logic->KakarikoVillageGateOpen, []{return logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER);}), + EventAccess(&logic->KakarikoVillageGateOpen, []{return logic->IsChild && logic->HasSoul(RG_KAKARIKO_GATEKEEPER_SOUL) && logic->HasItem(RG_ZELDAS_LETTER);}), }, { //Locations - LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)), - LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay), - LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay), - LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && (logic->CanUse(RG_POCKET_EGG) && logic->WakeUpAdultTalon)), + LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION) && logic->HasSoul(RG_ZELDA_SOUL)), + LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay && logic->HasSoul(RG_ANJU_SOUL)), + LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay && logic->HasSoul(RG_ANJU_SOUL)), + LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && logic->HasSoul(RG_ANJU_SOUL) && (logic->CanUse(RG_POCKET_EGG) && logic->WakeUpAdultTalon)), //Can kill lower kak skulls with pots LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()), @@ -71,7 +71,7 @@ void RegionTable_Init_Kakariko() { Entrance(RR_KAK_REDEAD_GROTTO, []{return logic->CanOpenBombGrotto();}), Entrance(RR_KAK_IMPAS_LEDGE, []{return (logic->IsChild && logic->AtDay) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}), Entrance(RR_KAK_WATCHTOWER, []{return logic->IsAdult || logic->AtDay || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer());}), - Entrance(RR_KAK_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && logic->IsAdult);}), + Entrance(RR_KAK_ROOFTOP, []{return logic->HasSoul(RG_MAN_ON_ROOF_SOUL) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && logic->IsAdult));}), Entrance(RR_KAK_IMPAS_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}), Entrance(RR_THE_GRAVEYARD, []{return true;}), Entrance(RR_KAK_BEHIND_GATE, []{return logic->IsAdult || logic->KakarikoVillageGateOpen;}), @@ -128,7 +128,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Region("Kak Carpenter Boss House", SCENE_KAKARIKO_CENTER_GUEST_HOUSE, { //Events - EventAccess(&logic->WakeUpAdultTalon, []{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG);}), + EventAccess(&logic->WakeUpAdultTalon, []{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG) && logic->HasSoul(RG_TALON_SOUL);}), }, {}, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -170,7 +170,7 @@ void RegionTable_Init_Kakariko() { }, { //Locations LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslashExceptHammer() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))), - LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA)), + LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasSoul(RG_WINDMILL_MAN_SOUL) && logic->HasItem(RG_FAIRY_OCARINA)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -178,14 +178,14 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_BAZAAR] = Region("Kak Bazaar", SCENE_BAZAAR, {}, { //Locations - LOCATION(RC_KAK_BAZAAR_ITEM_1, true), - LOCATION(RC_KAK_BAZAAR_ITEM_2, true), - LOCATION(RC_KAK_BAZAAR_ITEM_3, true), - LOCATION(RC_KAK_BAZAAR_ITEM_4, true), - LOCATION(RC_KAK_BAZAAR_ITEM_5, true), - LOCATION(RC_KAK_BAZAAR_ITEM_6, true), - LOCATION(RC_KAK_BAZAAR_ITEM_7, true), - LOCATION(RC_KAK_BAZAAR_ITEM_8, true), + LOCATION(RC_KAK_BAZAAR_ITEM_1, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_2, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_3, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_4, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_5, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_6, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_7, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_8, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -193,7 +193,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_SHOOTING_GALLERY] = Region("Kak Shooting Gallery", SCENE_SHOOTING_GALLERY, {}, { //Locations - LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->IsAdult && logic->HasSoul(RG_SHOOTING_SOUL) && logic->CanUse(RG_FAIRY_BOW)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -201,14 +201,14 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_POTION_SHOP_FRONT] = Region("Kak Potion Shop Front", SCENE_POTION_SHOP_KAKARIKO, {}, { //Locations - LOCATION(RC_KAK_POTION_SHOP_ITEM_1, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_2, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_3, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_4, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_5, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_6, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_7, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_8, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_1, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_2, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_3, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_4, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_5, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_6, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_7, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_8, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -226,8 +226,8 @@ void RegionTable_Init_Kakariko() { // RANDOTODO blue pot access }, { //Locations - LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->CanUse(RG_ODD_MUSHROOM)), - LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM))), + LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->HasSoul(RG_GRANNY_SOUL) && logic->CanUse(RG_ODD_MUSHROOM)), + LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && logic->HasSoul(RG_GRANNY_SOUL) && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM))), }, { // Exits Entrance(RR_KAK_BACKYARD, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 525e22200..5eaafe7df 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -159,14 +159,14 @@ void RegionTable_Init_KokiriForest() { areaTable[RR_KF_KOKIRI_SHOP] = Region("KF Kokiri Shop", SCENE_KOKIRI_SHOP, {}, { //Locations - LOCATION(RC_KF_SHOP_ITEM_1, true), - LOCATION(RC_KF_SHOP_ITEM_2, true), - LOCATION(RC_KF_SHOP_ITEM_3, true), - LOCATION(RC_KF_SHOP_ITEM_4, true), - LOCATION(RC_KF_SHOP_ITEM_5, true), - LOCATION(RC_KF_SHOP_ITEM_6, true), - LOCATION(RC_KF_SHOP_ITEM_7, true), - LOCATION(RC_KF_SHOP_ITEM_8, true), + LOCATION(RC_KF_SHOP_ITEM_1, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_2, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_3, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_4, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_5, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_6, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_7, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_8, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_KOKIRI_FOREST, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index 964b781ce..a401796a1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -85,7 +85,7 @@ void RegionTable_Init_LakeHylia() { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), Entrance(RR_LH_FROM_SHORTCUT, []{return true;}), - Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}), + Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild && logic->HasSoul(RG_KAEPORA_SOUL);}), Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->WaterTempleClear) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}), Entrance(RR_LH_FROM_WATER_TEMPLE, []{return true;}), @@ -117,8 +117,8 @@ void RegionTable_Init_LakeHylia() { areaTable[RR_LH_LAB] = Region("LH Lab", SCENE_LAKESIDE_LABORATORY, {}, { //Locations - LOCATION(RC_LH_LAB_DIVE, logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE))), - LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), + LOCATION(RC_LH_LAB_DIVE, logic->HasSoul(RG_SCIENTIST_SOUL) && (logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE)))), + LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->HasSoul(RG_SCIENTIST_SOUL) && logic->CanUse(RG_EYEBALL_FROG)), LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanBreakCrates()), LOCATION(RC_LH_LAB_FRONT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), LOCATION(RC_LH_LAB_LEFT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index c29a5924e..6776a9eff 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -8,10 +8,10 @@ void RegionTable_Init_LonLonRanch() { areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", SCENE_LON_LON_RANCH, { //Events EventAccess(&logic->FreedEpona, []{return (logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), - EventAccess(&logic->LinksCow, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), + EventAccess(&logic->LinksCow, []{return logic->HasSoul(RG_MALON_SOUL) && logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), }, { //Locations - LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), + LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasSoul(RG_MALON_SOUL) && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), LOCATION(RC_LLR_GS_TREE, logic->IsChild), LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), @@ -35,7 +35,7 @@ void RegionTable_Init_LonLonRanch() { areaTable[RR_LLR_TALONS_HOUSE] = Region("LLR Talons House", SCENE_LON_LON_BUILDINGS, {}, { //Locations - LOCATION(RC_LLR_TALONS_CHICKENS, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtDay && logic->HasItem(RG_ZELDAS_LETTER)), + LOCATION(RC_LLR_TALONS_CHICKENS, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtDay && logic->HasSoul(RG_TALON_SOUL) && logic->HasItem(RG_ZELDAS_LETTER)), LOCATION(RC_LLR_TALONS_HOUSE_POT_1, logic->CanBreakPots()), LOCATION(RC_LLR_TALONS_HOUSE_POT_2, logic->CanBreakPots()), LOCATION(RC_LLR_TALONS_HOUSE_POT_3, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index e949a7b1e..b14b9354b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -18,9 +18,9 @@ void RegionTable_Init_LostWoods() { }, { //Locations LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), - LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->CanUse(RG_COJIRO)), + LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->HasSoul(RG_GROG_SOUL) && logic->CanUse(RG_COJIRO)), //I cannot think of a case where you can use Odd pot but not Cojiro to reset the quadrant should you have both. If one exists, add it to logic - LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->CanUse(RG_ODD_POTION)), + LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->HasSoul(RG_FADO_SOUL) && logic->CanUse(RG_ODD_POTION)), //all 5 buttons are logically required for memory game //because the chances of being able to beat it //every time you attempt it are as follows: @@ -130,7 +130,7 @@ void RegionTable_Init_LostWoods() { areaTable[RR_LW_BRIDGE_FROM_FOREST] = Region("LW Bridge From Forest", SCENE_LOST_WOODS, {}, { //Locations - LOCATION(RC_LW_GIFT_FROM_SARIA, true), + LOCATION(RC_LW_GIFT_FROM_SARIA, logic->HasSoul(RG_SARIA_SOUL)), }, { //Exits Entrance(RR_LW_BRIDGE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 7d7655ef0..9098fe065 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -54,7 +54,7 @@ void RegionTable_Init_Market() { EventAccess(&logic->CanEmptyBigPoes, []{return logic->IsAdult;}), }, { //Locations - LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->BigPoeKill || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())), + LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && logic->HasSoul(RG_POE_COLLECTOR_SOUL) && (logic->BigPoeKill || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())), LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()), @@ -123,14 +123,14 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_BAZAAR] = Region("Market Bazaar", SCENE_BAZAAR, {}, { //Locations - LOCATION(RC_MARKET_BAZAAR_ITEM_1, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_2, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_3, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_4, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_5, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_6, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_7, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_8, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_1, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_2, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_3, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_4, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_5, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_6, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_7, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_8, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), @@ -138,7 +138,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", SCENE_HAPPY_MASK_SHOP, { //Events - EventAccess(&logic->SkullMask, []{return logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE));}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket + EventAccess(&logic->SkullMask, []{return logic->HasSoul(RG_MASK_SALESMAN_SOUL) && logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE));}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket EventAccess(&logic->MaskOfTruth, []{return logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3));}), }, { //Locations @@ -150,7 +150,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_SHOOTING_GALLERY] = Region("Market Shooting Gallery", SCENE_SHOOTING_GALLERY, {}, { //Locations - LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasItem(RG_CHILD_WALLET)), + LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasSoul(RG_SHOOTING_SOUL) && logic->HasItem(RG_CHILD_WALLET)), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), @@ -158,7 +158,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_BOMBCHU_BOWLING] = Region("Market Bombchu Bowling", SCENE_BOMBCHU_BOWLING_ALLEY, { //Events - EventAccess(&logic->CouldPlayBowling, []{return (logic->HasItem(RG_CHILD_WALLET));}), + EventAccess(&logic->CouldPlayBowling, []{return logic->HasSoul(RG_BOMBCHU_LADY_SOUL) && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations LOCATION(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()), @@ -170,14 +170,14 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_POTION_SHOP] = Region("Market Potion Shop", SCENE_POTION_SHOP_MARKET, {}, { //Locations - LOCATION(RC_MARKET_POTION_SHOP_ITEM_1, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_2, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_3, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_4, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_5, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_6, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_7, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_8, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_1, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_2, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_3, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_4, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_5, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_6, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_7, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_8, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), @@ -185,18 +185,18 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", SCENE_TREASURE_BOX_SHOP, {}, { //Locations - LOCATION(RC_GREG_HINT, logic->HasItem(RG_CHILD_WALLET)), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_GREG_HINT, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET)), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), @@ -204,14 +204,14 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_BOMBCHU_SHOP] = Region("Market Bombchu Shop", SCENE_BOMBCHU_SHOP, {}, { //Locations - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_1, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_2, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_3, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_4, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_5, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_6, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_7, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_8, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_1, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_2, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_3, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_4, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_5, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_6, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_7, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_8, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_MARKET_BACK_ALLEY, []{return true;}), @@ -219,7 +219,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_DOG_LADY_HOUSE] = Region("Market Dog Lady House", SCENE_DOG_LADY_HOUSE, {}, { //Locations - LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight), + LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight && logic->HasSoul(RG_DOG_LADY_SOUL)), LOCATION(RC_MK_LOST_DOG_HOUSE_CRATE, logic->CanBreakCrates()), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp index 9d641ac98..5a53c50ea 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp @@ -17,8 +17,8 @@ void RegionTable_Init_SacredForestMeadow() { EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), }, { //Locations - LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)), - LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult), + LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasSoul(RG_SARIA_SOUL) && logic->HasItem(RG_ZELDAS_LETTER)), + LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult && logic->HasSoul(RG_ZELDA_SOUL)), LOCATION(RC_SFM_GS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp index 07efc4326..64c44c7af 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp @@ -33,7 +33,7 @@ void RegionTable_Init_TempleOfTime() { LOCATION(RC_TOT_LIGHT_ARROWS_CUTSCENE, logic->IsAdult && logic->CanTriggerLACS()), LOCATION(RC_ALTAR_HINT_CHILD, logic->IsChild), LOCATION(RC_ALTAR_HINT_ADULT, logic->IsAdult), - LOCATION(RC_TOT_SHEIK_HINT, logic->IsAdult), + LOCATION(RC_TOT_SHEIK_HINT, logic->IsAdult && logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_TOT_ENTRANCE, []{return true;}), @@ -46,8 +46,8 @@ void RegionTable_Init_TempleOfTime() { }, { //Locations LOCATION(RC_TOT_MASTER_SWORD, logic->IsAdult), - LOCATION(RC_GIFT_FROM_RAURU, logic->IsAdult), - LOCATION(RC_SHEIK_AT_TEMPLE, logic->HasItem(RG_FOREST_MEDALLION) && logic->IsAdult), + LOCATION(RC_GIFT_FROM_RAURU, logic->IsAdult && logic->HasSoul(RG_RAURU_SOUL)), + LOCATION(RC_SHEIK_AT_TEMPLE, logic->HasItem(RG_FOREST_MEDALLION) && logic->IsAdult && logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_TEMPLE_OF_TIME, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 3a626a2f9..19124e47d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -15,7 +15,7 @@ void RegionTable_Init_ZorasDomain() { EventAccess(&logic->DeliverLetter, []{return logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN);}), }, { //Locations - LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), + LOCATION(RC_ZD_DIVING_MINIGAME, logic->IsChild && logic->HasSoul(RG_DIVING_SOUL) && logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET)), LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS)), LOCATION(RC_ZD_KING_ZORA_THAWED, logic->IsAdult && logic->KingZoraThawed), LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->IsAdult && logic->KingZoraThawed && logic->CanUse(RG_PRESCRIPTION)), @@ -64,14 +64,14 @@ void RegionTable_Init_ZorasDomain() { areaTable[RR_ZD_SHOP] = Region("ZD Shop", SCENE_ZORA_SHOP, {}, { //Locations - LOCATION(RC_ZD_SHOP_ITEM_1, true), - LOCATION(RC_ZD_SHOP_ITEM_2, true), - LOCATION(RC_ZD_SHOP_ITEM_3, true), - LOCATION(RC_ZD_SHOP_ITEM_4, true), - LOCATION(RC_ZD_SHOP_ITEM_5, true), - LOCATION(RC_ZD_SHOP_ITEM_6, true), - LOCATION(RC_ZD_SHOP_ITEM_7, true), - LOCATION(RC_ZD_SHOP_ITEM_8, true), + LOCATION(RC_ZD_SHOP_ITEM_1, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_2, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_3, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_4, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_5, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_6, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_7, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_8, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_ZORAS_DOMAIN, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index cfd2125c1..12df5cdaa 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -112,7 +112,7 @@ void RegionTable_Init_ZorasFountain() { areaTable[RR_ZF_GREAT_FAIRY_FOUNTAIN] = Region("ZF Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, {}, { //Locations - LOCATION(RC_ZF_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_ZF_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_ZORAS_FOUNTAIN, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 5473ee2ca..0abbe6dad 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -34,7 +34,7 @@ void RegionTable_Init_ZoraRiver() { EventAccess(&logic->BugShrub, []{return logic->CanCutShrubs();}), }, { //Locations - LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), + LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->HasSoul(RG_BEAN_SALESMAN_SOUL)), LOCATION(RC_ZR_FROGS_OCARINA_GAME, logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_SARIAS_SONG) && logic->CanUse(RG_SUNS_SONG) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_FROGS_IN_THE_RAIN, logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_FROGS_ZELDAS_LULLABY, logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY)), diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 597828e34..bbada607a 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" #include "context.h" #include "dungeon.h" diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index d4c3efd1d..0edb0804e 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -143,8 +143,57 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_BONGO_BONGO_SOUL: case RG_TWINROVA_SOUL: case RG_GANON_SOUL: + // NPC Souls + case RG_ANJU_SOUL: + case RG_TALON_SOUL: + case RG_GROG_SOUL: + case RG_GRANNY_SOUL: + case RG_FADO_SOUL: + case RG_LINK_SOUL: + case RG_BIGGORON_SOUL: + case RG_HOT_RODDER_SOUL: + case RG_MEDIGORON_SOUL: + case RG_CARPENTER_BOSS_SOUL: + case RG_ICHIRO_SOUL: + case RG_SABOORO_SOUL: + case RG_JIRO_SOUL: + case RG_SHIRO_SOUL: + case RG_HW_GATEKEEPER_SOUL: + case RG_GTG_GATEKEEPER_SOUL: + case RG_ARCHER_SOUL: + case RG_GREAT_FAIRY_SOUL: + case RG_POE_COLLECTOR_SOUL: + case RG_DAMPE_SOUL: + case RG_WINDMILL_MAN_SOUL: + case RG_MAN_ON_ROOF_SOUL: + case RG_KAKARIKO_GATEKEEPER_SOUL: + case RG_MALON_SOUL: + case RG_BEGGAR_SOUL: + case RG_DOG_LADY_SOUL: + case RG_ARMS_DEALER_SOUL: + case RG_BEAN_SALESMAN_SOUL: + case RG_SHOOTING_SOUL: + case RG_KOKIRI_SHOPKEEPER_SOUL: + case RG_POTION_SHOPKEEPER_SOUL: + case RG_BAZAAR_SHOPKEEPER_SOUL: + case RG_GORON_SHOPKEEPER_SOUL: + case RG_ZORA_SHOPKEEPER_SOUL: + case RG_BOMBCHU_SHOPKEEPER_SOUL: + case RG_MASK_SALESMAN_SOUL: + case RG_TREASURE_MAN_SOUL: + case RG_BOMBCHU_LADY_SOUL: + case RG_DIVING_SOUL: + case RG_SCIENTIST_SOUL: + case RG_KAEPORA_SOUL: + case RG_RAURU_SOUL: + case RG_SARIA_SOUL: + case RG_DARUNIA_SOUL: + case RG_RUTO_SOUL: + case RG_NABOORU_SOUL: + case RG_IMPA_SOUL: + case RG_ZELDA_SOUL: + // Overworld Keys case RG_SKELETON_KEY: - // Overworld Keys case RG_GUARD_HOUSE_KEY: case RG_MARKET_BAZAAR_KEY: case RG_MARKET_POTION_SHOP_KEY: @@ -406,10 +455,7 @@ bool Logic::HasProjectile(HasProjectileAge age) { (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))); } -bool Logic::HasBossSoul(RandomizerGet itemName) { - if (!ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { - return true; - } +bool Logic::HasSoul(RandomizerGet itemName) { switch (itemName) { case RG_GOHMA_SOUL: case RG_KING_DODONGO_SOUL: @@ -419,15 +465,67 @@ bool Logic::HasBossSoul(RandomizerGet itemName) { case RG_MORPHA_SOUL: case RG_BONGO_BONGO_SOUL: case RG_TWINROVA_SOUL: - return HasItem(itemName); + return !ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS) || HasItem(itemName); case RG_GANON_SOUL: - return ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) ? HasItem(RG_GANON_SOUL) - : true; + return !ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) || HasItem(RG_GANON_SOUL); + case RG_ANJU_SOUL: + case RG_TALON_SOUL: + case RG_GROG_SOUL: + case RG_GRANNY_SOUL: + case RG_FADO_SOUL: + case RG_LINK_SOUL: + case RG_BIGGORON_SOUL: + case RG_HOT_RODDER_SOUL: + case RG_MEDIGORON_SOUL: + case RG_CARPENTER_BOSS_SOUL: + case RG_ICHIRO_SOUL: + case RG_SABOORO_SOUL: + case RG_JIRO_SOUL: + case RG_SHIRO_SOUL: + case RG_HW_GATEKEEPER_SOUL: + case RG_GTG_GATEKEEPER_SOUL: + case RG_ARCHER_SOUL: + case RG_GREAT_FAIRY_SOUL: + case RG_POE_COLLECTOR_SOUL: + case RG_DAMPE_SOUL: + case RG_WINDMILL_MAN_SOUL: + case RG_MAN_ON_ROOF_SOUL: + case RG_KAKARIKO_GATEKEEPER_SOUL: + case RG_MALON_SOUL: + case RG_BEGGAR_SOUL: + case RG_DOG_LADY_SOUL: + case RG_ARMS_DEALER_SOUL: + case RG_BEAN_SALESMAN_SOUL: + case RG_SHOOTING_SOUL: + case RG_KOKIRI_SHOPKEEPER_SOUL: + case RG_POTION_SHOPKEEPER_SOUL: + case RG_BAZAAR_SHOPKEEPER_SOUL: + case RG_GORON_SHOPKEEPER_SOUL: + case RG_ZORA_SHOPKEEPER_SOUL: + case RG_BOMBCHU_SHOPKEEPER_SOUL: + case RG_MASK_SALESMAN_SOUL: + case RG_TREASURE_MAN_SOUL: + case RG_BOMBCHU_LADY_SOUL: + case RG_DIVING_SOUL: + case RG_SCIENTIST_SOUL: + case RG_KAEPORA_SOUL: + case RG_RAURU_SOUL: + case RG_SARIA_SOUL: + case RG_DARUNIA_SOUL: + case RG_RUTO_SOUL: + case RG_NABOORU_SOUL: + case RG_IMPA_SOUL: + case RG_ZELDA_SOUL: + return !ctx->GetOption(RSK_SHUFFLE_NPC_SOULS) || HasItem(itemName); default: return false; } } +bool Logic::HasSage(RandomizerGet itemName) { + return !ctx->GetOption(RSK_SHUFFLE_NPC_SOULS).Is(RO_NPC_SOULS_ON_PLUS_SAGES) || HasItem(itemName); +} + // RANDOMISERTODO intergrate into HasItem bool Logic::CanOpenOverworldDoor(RandomizerGet key) { if (!ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { @@ -728,27 +826,27 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal // without shenanigans anyway. Bunny makes it free return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD); case RE_GOHMA: - return HasBossSoul(RG_GOHMA_SOUL) && CanJumpslash() && + return HasSoul(RG_GOHMA_SOUL) && CanJumpslash() && (CanUse(RG_NUTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HookshotOrBoomerang()); case RE_KING_DODONGO: - return HasBossSoul(RG_KING_DODONGO_SOUL) && CanJumpslash() && + return HasSoul(RG_KING_DODONGO_SOUL) && CanJumpslash() && (CanUse(RG_BOMB_BAG) || HasItem(RG_GORONS_BRACELET)); case RE_BARINADE: - return HasBossSoul(RG_BARINADE_SOUL) && CanUse(RG_BOOMERANG) && CanJumpslashExceptHammer(); + return HasSoul(RG_BARINADE_SOUL) && CanUse(RG_BOOMERANG) && CanJumpslashExceptHammer(); case RE_PHANTOM_GANON: - return HasBossSoul(RG_PHANTOM_GANON_SOUL) && CanUseSword() && + return HasSoul(RG_PHANTOM_GANON_SOUL) && CanUseSword() && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT)); case RE_VOLVAGIA: - return HasBossSoul(RG_VOLVAGIA_SOUL) && CanUse(RG_MEGATON_HAMMER); + return HasSoul(RG_VOLVAGIA_SOUL) && CanUse(RG_MEGATON_HAMMER); case RE_MORPHA: - return HasBossSoul(RG_MORPHA_SOUL) && CanUse(RG_HOOKSHOT) && (CanUseSword() || CanUse(RG_MEGATON_HAMMER)); + return HasSoul(RG_MORPHA_SOUL) && CanUse(RG_HOOKSHOT) && (CanUseSword() || CanUse(RG_MEGATON_HAMMER)); case RE_BONGO_BONGO: - return HasBossSoul(RG_BONGO_BONGO_SOUL) && - (CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && CanUseSword() && + return HasSoul(RG_BONGO_BONGO_SOUL) && (CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && + CanUseSword() && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO)); case RE_TWINROVA: - return HasBossSoul(RG_TWINROVA_SOUL) && CanUse(RG_MIRROR_SHIELD) && + return HasSoul(RG_TWINROVA_SOUL) && CanUse(RG_MIRROR_SHIELD) && (CanUseSword() || CanUse(RG_MEGATON_HAMMER)); case RE_GANONDORF: // RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the @@ -758,9 +856,9 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal // for killing ganondorf and all of those can reflect the energy ball // This will not be the case once ammo logic in taken into account as // sticks are limited and using a bottle might become a requirement in that case - return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_LIGHT_ARROWS) && CanUseSword(); + return HasSoul(RG_GANON_SOUL) && CanUse(RG_LIGHT_ARROWS) && CanUseSword(); case RE_GANON: - return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_MASTER_SWORD); + return HasSoul(RG_GANON_SOUL) && HasSage(RG_ZELDA_SOUL) && CanUse(RG_MASTER_SWORD); case RE_DARK_LINK: // RANDOTODO Dark link is buggy right now, retest when he is not return CanJumpslash() || CanUse(RG_FAIRY_BOW); @@ -1301,13 +1399,16 @@ bool Logic::TradeQuestStep(RandomizerGet rg) { } bool Logic::CanFinishGerudoFortress() { - return (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && - CanKillEnemy(RE_GERUDO_WARRIOR) && - (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || - CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || - (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && - CanKillEnemy(RE_GERUDO_WARRIOR)) || - ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE); + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL)) { + return SmallKeys(RR_GERUDO_FORTRESS, 4) && CanKillEnemy(RE_GERUDO_WARRIOR) && HasSoul(RG_ICHIRO_SOUL) && + HasSoul(RG_SABOORO_SOUL) && HasSoul(RG_JIRO_SOUL) && HasSoul(RG_SHIRO_SOUL) && + (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || + CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN)); + } else if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST)) { + return SmallKeys(RR_GERUDO_FORTRESS, 1) && CanKillEnemy(RE_GERUDO_WARRIOR) && HasSoul(RG_ICHIRO_SOUL); + } else { + return true; + } } bool Logic::CanStandingShield() { @@ -1463,6 +1564,54 @@ std::map Logic::RandoGetToRandInf = { { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, + { RG_ANJU_SOUL, RAND_INF_ANJU_SOUL }, + { RG_TALON_SOUL, RAND_INF_TALON_SOUL }, + { RG_GROG_SOUL, RAND_INF_GROG_SOUL }, + { RG_GRANNY_SOUL, RAND_INF_GRANNY_SOUL }, + { RG_FADO_SOUL, RAND_INF_FADO_SOUL }, + { RG_ICHIRO_SOUL, RAND_INF_ICHIRO_SOUL }, + { RG_SABOORO_SOUL, RAND_INF_SABOORO_SOUL }, + { RG_JIRO_SOUL, RAND_INF_JIRO_SOUL }, + { RG_SHIRO_SOUL, RAND_INF_SHIRO_SOUL }, + { RG_HW_GATEKEEPER_SOUL, RAND_INF_HW_GATEKEEPER_SOUL }, + { RG_GTG_GATEKEEPER_SOUL, RAND_INF_GTG_GATEKEEPER_SOUL }, + { RG_ARCHER_SOUL, RAND_INF_ARCHER_SOUL }, + { RG_LINK_SOUL, RAND_INF_LINK_SOUL }, + { RG_BIGGORON_SOUL, RAND_INF_BIGGORON_SOUL }, + { RG_HOT_RODDER_SOUL, RAND_INF_HOT_RODDER_SOUL }, + { RG_MEDIGORON_SOUL, RAND_INF_MEDIGORON_SOUL }, + { RG_CARPENTER_BOSS_SOUL, RAND_INF_CARPENTER_BOSS_SOUL }, + { RG_GREAT_FAIRY_SOUL, RAND_INF_GREAT_FAIRY_SOUL }, + { RG_POE_COLLECTOR_SOUL, RAND_INF_POE_COLLECTOR_SOUL }, + { RG_DAMPE_SOUL, RAND_INF_DAMPE_SOUL }, + { RG_WINDMILL_MAN_SOUL, RAND_INF_WINDMILL_MAN_SOUL }, + { RG_MAN_ON_ROOF_SOUL, RAND_INF_MAN_ON_ROOF_SOUL }, + { RG_KAKARIKO_GATEKEEPER_SOUL, RAND_INF_KAKARIKO_GATEKEEPER_SOUL }, + { RG_MALON_SOUL, RAND_INF_MALON_SOUL }, + { RG_RAURU_SOUL, RAND_INF_RAURU_SOUL }, + { RG_SARIA_SOUL, RAND_INF_SARIA_SOUL }, + { RG_DARUNIA_SOUL, RAND_INF_DARUNIA_SOUL }, + { RG_RUTO_SOUL, RAND_INF_RUTO_SOUL }, + { RG_NABOORU_SOUL, RAND_INF_NABOORU_SOUL }, + { RG_IMPA_SOUL, RAND_INF_IMPA_SOUL }, + { RG_ZELDA_SOUL, RAND_INF_ZELDA_SOUL }, + { RG_BEGGAR_SOUL, RAND_INF_BEGGAR_SOUL }, + { RG_DOG_LADY_SOUL, RAND_INF_DOG_LADY_SOUL }, + { RG_ARMS_DEALER_SOUL, RAND_INF_ARMS_DEALER_SOUL }, + { RG_BEAN_SALESMAN_SOUL, RAND_INF_BEAN_SALESMAN_SOUL }, + { RG_SHOOTING_SOUL, RAND_INF_SHOOTING_SOUL }, + { RG_KOKIRI_SHOPKEEPER_SOUL, RAND_INF_KOKIRI_SHOPKEEPER_SOUL }, + { RG_POTION_SHOPKEEPER_SOUL, RAND_INF_POTION_SHOPKEEPER_SOUL }, + { RG_BAZAAR_SHOPKEEPER_SOUL, RAND_INF_BAZAAR_SHOPKEEPER_SOUL }, + { RG_GORON_SHOPKEEPER_SOUL, RAND_INF_GORON_SHOPKEEPER_SOUL }, + { RG_ZORA_SHOPKEEPER_SOUL, RAND_INF_ZORA_SHOPKEEPER_SOUL }, + { RG_BOMBCHU_SHOPKEEPER_SOUL, RAND_INF_BOMBCHU_SHOPKEEPER_SOUL }, + { RG_MASK_SALESMAN_SOUL, RAND_INF_MASK_SALESMAN_SOUL }, + { RG_TREASURE_MAN_SOUL, RAND_INF_TREASURE_MAN_SOUL }, + { RG_BOMBCHU_LADY_SOUL, RAND_INF_BOMBCHU_LADY_SOUL }, + { RG_DIVING_SOUL, RAND_INF_DIVING_SOUL }, + { RG_SCIENTIST_SOUL, RAND_INF_SCIENTIST_SOUL }, + { RG_KAEPORA_SOUL, RAND_INF_KAEPORA_SOUL }, { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, @@ -1829,6 +1978,54 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_BONGO_BONGO_SOUL: case RG_TWINROVA_SOUL: case RG_GANON_SOUL: + case RG_ANJU_SOUL: + case RG_TALON_SOUL: + case RG_GROG_SOUL: + case RG_GRANNY_SOUL: + case RG_FADO_SOUL: + case RG_LINK_SOUL: + case RG_BIGGORON_SOUL: + case RG_HOT_RODDER_SOUL: + case RG_MEDIGORON_SOUL: + case RG_CARPENTER_BOSS_SOUL: + case RG_ICHIRO_SOUL: + case RG_SABOORO_SOUL: + case RG_JIRO_SOUL: + case RG_SHIRO_SOUL: + case RG_HW_GATEKEEPER_SOUL: + case RG_GTG_GATEKEEPER_SOUL: + case RG_ARCHER_SOUL: + case RG_GREAT_FAIRY_SOUL: + case RG_POE_COLLECTOR_SOUL: + case RG_DAMPE_SOUL: + case RG_WINDMILL_MAN_SOUL: + case RG_MAN_ON_ROOF_SOUL: + case RG_KAKARIKO_GATEKEEPER_SOUL: + case RG_MALON_SOUL: + case RG_BEGGAR_SOUL: + case RG_DOG_LADY_SOUL: + case RG_ARMS_DEALER_SOUL: + case RG_BEAN_SALESMAN_SOUL: + case RG_SHOOTING_SOUL: + case RG_KOKIRI_SHOPKEEPER_SOUL: + case RG_POTION_SHOPKEEPER_SOUL: + case RG_BAZAAR_SHOPKEEPER_SOUL: + case RG_GORON_SHOPKEEPER_SOUL: + case RG_ZORA_SHOPKEEPER_SOUL: + case RG_BOMBCHU_SHOPKEEPER_SOUL: + case RG_MASK_SALESMAN_SOUL: + case RG_TREASURE_MAN_SOUL: + case RG_BOMBCHU_LADY_SOUL: + case RG_DIVING_SOUL: + case RG_SCIENTIST_SOUL: + case RG_KAEPORA_SOUL: + case RG_RAURU_SOUL: + case RG_SARIA_SOUL: + case RG_DARUNIA_SOUL: + case RG_RUTO_SOUL: + case RG_NABOORU_SOUL: + case RG_IMPA_SOUL: + case RG_ZELDA_SOUL: case RG_OCARINA_A_BUTTON: case RG_OCARINA_C_UP_BUTTON: case RG_OCARINA_C_DOWN_BUTTON: diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 9a5c87751..b04387d94 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -41,6 +41,13 @@ class Logic { bool WakeUpAdultTalon = false; // Dungeon Clears + bool DodongosCavernWin = false; + bool JabuJabusBellyWin = false; + bool ForestTempleWin = false; + bool FireTempleWin = false; + bool WaterTempleWin = false; + bool SpiritTempleWin = false; + bool ShadowTempleWin = false; bool DekuTreeClear = false; bool DodongosCavernClear = false; bool JabuJabusBellyClear = false; @@ -185,7 +192,8 @@ class Logic { bool CanUse(RandomizerGet itemName); bool HasProjectile(HasProjectileAge age); bool HasItem(RandomizerGet itemName); - bool HasBossSoul(RandomizerGet itemName); + bool HasSoul(RandomizerGet itemName); + bool HasSage(RandomizerGet itemName); bool CanOpenOverworldDoor(RandomizerGet itemName); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 16c89a1c4..931fca5cb 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -758,5 +758,8 @@ void Settings::CreateOptionDescriptions() { "Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its " "respective soul." "\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul."; + mOptionDescriptions[RSK_SHUFFLE_NPC_SOULS] = + "Shuffles souls of NPCs. An NPC will not appear until you collect its respective soul." + "\n\"On + Sages\" requires sage souls to receive blue warp reward. Zelda is required to defeat Ganon."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 8eb0192b6..1fa57981c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5343,7 +5343,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = { { + const std::array getItemMessages = { { GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!", "Félicitation! Vous avez trouvé %gGreg%w!"), GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!", @@ -5638,6 +5638,106 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_GANON_SOUL, ITEM_BIG_POE, "You found the soul for %cGanon%w!", "Du hast die Seele von&%cGanon%w gefunden!", "Vous obtenez l'âme de %cGanon%w!"), + GIMESSAGE_NO_GERMAN(RG_ANJU_SOUL, ITEM_BIG_POE, "You found the soul for %bAnju%w!", + "Vous obtenez l'âme de %bAnju%w!"), + GIMESSAGE_NO_GERMAN(RG_TALON_SOUL, ITEM_BIG_POE, "You found the soul for %bTalon%w!", + "Vous obtenez l'âme de %bTalon%w!"), + GIMESSAGE_NO_GERMAN(RG_GROG_SOUL, ITEM_BIG_POE, "You found the soul for %bGrog%w!", + "Vous obtenez l'âme de %bGrog%w!"), + GIMESSAGE_NO_GERMAN(RG_GRANNY_SOUL, ITEM_BIG_POE, "You found the soul for %bGranny%w!", + "Vous obtenez l'âme de %bGranny%w!"), + GIMESSAGE_NO_GERMAN(RG_FADO_SOUL, ITEM_BIG_POE, "You found the soul for %bFado%w!", + "Vous obtenez l'âme de %bFado%w!"), + GIMESSAGE_NO_GERMAN(RG_LINK_SOUL, ITEM_BIG_POE, "You found the soul for %bDarunia's Son%w!", + "Vous obtenez l'âme de %ble fils de Darunia%w!"), + GIMESSAGE_NO_GERMAN(RG_BIGGORON_SOUL, ITEM_BIG_POE, "You found the soul for %bBiggoron%w!", + "Vous obtenez l'âme de %bBiggoron%w!"), + GIMESSAGE_NO_GERMAN(RG_HOT_RODDER_SOUL, ITEM_BIG_POE, "You found the soul for %bHot Rodder%w!", + "Vous obtenez l'âme de %bHot Rodder%w!"), + GIMESSAGE_NO_GERMAN(RG_MEDIGORON_SOUL, ITEM_BIG_POE, "You found the soul for %bMedigoron%w!", + "Vous obtenez l'âme de %bMedigoron%w!"), + GIMESSAGE_NO_GERMAN(RG_CARPENTER_BOSS_SOUL, ITEM_BIG_POE, "You found the soul for %bCarpenter Boss%w!", + "Vous obtenez l'âme de %bCarpenter Boss%w!"), + GIMESSAGE_NO_GERMAN(RG_ICHIRO_SOUL, ITEM_BIG_POE, "You found the soul for %bIchiro%w!", + "Vous obtenez l'âme de %bIchiro%w!"), + GIMESSAGE_NO_GERMAN(RG_SABOORO_SOUL, ITEM_BIG_POE, "You found the soul for %bSabooro%w!", + "Vous obtenez l'âme de %bSabooro%w!"), + GIMESSAGE_NO_GERMAN(RG_JIRO_SOUL, ITEM_BIG_POE, "You found the soul for %bJiro%w!", + "Vous obtenez l'âme de %bJiro%w!"), + GIMESSAGE_NO_GERMAN(RG_SHIRO_SOUL, ITEM_BIG_POE, "You found the soul for %bShiro%w!", + "Vous obtenez l'âme de %bShiro%w!"), + GIMESSAGE_NO_GERMAN(RG_HW_GATEKEEPER_SOUL, ITEM_BIG_POE, + "You found the soul for %bHaunted Wasteland Gate Operator%w!", + "Vous obtenez l'âme de %bHaunted Wasteland Gate Operator%w!"), + GIMESSAGE_NO_GERMAN(RG_GTG_GATEKEEPER_SOUL, ITEM_BIG_POE, + "You found the soul for %bTraining Ground Gate Operator%w!", + "Vous obtenez l'âme de %bTraining Ground Gate Operator%w!"), + GIMESSAGE_NO_GERMAN(RG_ARCHER_SOUL, ITEM_BIG_POE, "You found the soul for %bHorseback Archer%w!", + "Vous obtenez l'âme de %bHorseback Archer%w!"), + GIMESSAGE_NO_GERMAN(RG_GREAT_FAIRY_SOUL, ITEM_BIG_POE, "You found the soul for %bGreat Fairy%w!", + "Vous obtenez l'âme de %bGreat Fairy%w!"), + GIMESSAGE_NO_GERMAN(RG_POE_COLLECTOR_SOUL, ITEM_BIG_POE, "You found the soul for %bPoe Collector%w!", + "Vous obtenez l'âme de %bPoe Collector%w!"), + GIMESSAGE_NO_GERMAN(RG_DAMPE_SOUL, ITEM_BIG_POE, "You found the soul for %bDampe%w!", + "Vous obtenez l'âme de %bDampe%w!"), + GIMESSAGE_NO_GERMAN(RG_WINDMILL_MAN_SOUL, ITEM_BIG_POE, "You found the soul for %bWindmill Man%w!", + "Vous obtenez l'âme de %bWindmill Man%w!"), + GIMESSAGE_NO_GERMAN(RG_MAN_ON_ROOF_SOUL, ITEM_BIG_POE, "You found the soul for %bMan on Roof%w!", + "Vous obtenez l'âme de %bMan on Roof%w!"), + GIMESSAGE_NO_GERMAN(RG_KAKARIKO_GATEKEEPER_SOUL, ITEM_BIG_POE, + "You found the soul for %bKakariko Gatekeeper%w!", + "Vous obtenez l'âme de %bKakariko Gatekeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_MALON_SOUL, ITEM_BIG_POE, "You found the soul for %bMalon%w!", + "Vous obtenez l'âme de %bMalon%w!"), + GIMESSAGE_NO_GERMAN(RG_BEGGAR_SOUL, ITEM_BIG_POE, "You found the soul for %bBeggar%w!", + "Vous obtenez l'âme de %bBeggar%w!"), + GIMESSAGE_NO_GERMAN(RG_DOG_LADY_SOUL, ITEM_BIG_POE, "You found the soul for %bDog Lady%w!", + "Vous obtenez l'âme de %bDog Lady%w!"), + GIMESSAGE_NO_GERMAN(RG_ARMS_DEALER_SOUL, ITEM_BIG_POE, "You found the soul for %bArms Dealer%w!", + "Vous obtenez l'âme de %bArms Dealer%w!"), + GIMESSAGE_NO_GERMAN(RG_BEAN_SALESMAN_SOUL, ITEM_BIG_POE, "You found the soul for %bBean Salesman%w!", + "Vous obtenez l'âme de %bBean Salesman%w!"), + GIMESSAGE_NO_GERMAN(RG_SHOOTING_SOUL, ITEM_BIG_POE, "You found the soul for %bShooter%w!", + "Vous obtenez l'âme de %bShooter%w!"), + GIMESSAGE_NO_GERMAN(RG_KOKIRI_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bKokiri Shopkeeper%w!", + "Vous obtenez l'âme de %bKokiri Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_POTION_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bPotion Shopkeeper%w!", + "Vous obtenez l'âme de %bPotion Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_BAZAAR_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bBazaar Shopkeeper%w!", + "Vous obtenez l'âme de %bBazaar Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_GORON_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bGoron Shopkeeper%w!", + "Vous obtenez l'âme de %bGoron Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_ZORA_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bZora Shopkeeper%w!", + "Vous obtenez l'âme de %bZora Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_BOMBCHU_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bBombchu Shopkeeper%w!", + "Vous obtenez l'âme de %bBombchu Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_MASK_SALESMAN_SOUL, ITEM_BIG_POE, "You found the soul for %bMask Salesman%w!", + "Vous obtenez l'âme de %bMask Salesman%w!"), + GIMESSAGE_NO_GERMAN(RG_TREASURE_MAN_SOUL, ITEM_BIG_POE, "You found the soul for %bTreasure Man%w!", + "Vous obtenez l'âme de %bTreasure Man%w!"), + GIMESSAGE_NO_GERMAN(RG_BOMBCHU_LADY_SOUL, ITEM_BIG_POE, "You found the soul for %bBombchu Lady%w!", + "Vous obtenez l'âme de %bBombchu Lady%w!"), + GIMESSAGE_NO_GERMAN(RG_DIVING_SOUL, ITEM_BIG_POE, "You found the soul for %bDiver%w!", + "Vous obtenez l'âme de %bDiver%w!"), + GIMESSAGE_NO_GERMAN(RG_SCIENTIST_SOUL, ITEM_BIG_POE, "You found the soul for %bScientist%w!", + "Vous obtenez l'âme de %bScientifique%w!"), + GIMESSAGE_NO_GERMAN(RG_KAEPORA_SOUL, ITEM_BIG_POE, "You found the soul for %bKaepora%w!", + "Vous obtenez l'âme de %bKaepora%w!"), + GIMESSAGE_NO_GERMAN(RG_RAURU_SOUL, ITEM_BIG_POE, "You found the soul for %bRauru%w!", + "Vous obtenez l'âme de %bRauru%w!"), + GIMESSAGE_NO_GERMAN(RG_SARIA_SOUL, ITEM_BIG_POE, "You found the soul for %bSaria%w!", + "Vous obtenez l'âme de %bSaria%w!"), + GIMESSAGE_NO_GERMAN(RG_DARUNIA_SOUL, ITEM_BIG_POE, "You found the soul for %bDarunia%w!", + "Vous obtenez l'âme de %bDarunia%w!"), + GIMESSAGE_NO_GERMAN(RG_RUTO_SOUL, ITEM_BIG_POE, "You found the soul for %bRuto%w!", + "Vous obtenez l'âme de %bRuto%w!"), + GIMESSAGE_NO_GERMAN(RG_NABOORU_SOUL, ITEM_BIG_POE, "You found the soul for %bNabooru%w!", + "Vous obtenez l'âme de %bNabooru%w!"), + GIMESSAGE_NO_GERMAN(RG_IMPA_SOUL, ITEM_BIG_POE, "You found the soul for %bImpa%w!", + "Vous obtenez l'âme de %bImpa%w!"), + GIMESSAGE_NO_GERMAN(RG_ZELDA_SOUL, ITEM_BIG_POE, "You found the soul for %bZelda%w!", + "Vous obtenez l'âme de %bZelda%w!"), + GIMESSAGE(RG_OCARINA_A_BUTTON, ITEM_OCARINA_TIME, "You got the %b\x9f%r button for the&Ocarina%w! You can now use it&while playing songs!", "Der %b\x9f%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", @@ -5802,6 +5902,54 @@ std::map randomizerGetToRandInf = { { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, + { RG_ANJU_SOUL, RAND_INF_ANJU_SOUL }, + { RG_TALON_SOUL, RAND_INF_TALON_SOUL }, + { RG_GROG_SOUL, RAND_INF_GROG_SOUL }, + { RG_GRANNY_SOUL, RAND_INF_GRANNY_SOUL }, + { RG_FADO_SOUL, RAND_INF_FADO_SOUL }, + { RG_LINK_SOUL, RAND_INF_LINK_SOUL }, + { RG_BIGGORON_SOUL, RAND_INF_BIGGORON_SOUL }, + { RG_HOT_RODDER_SOUL, RAND_INF_HOT_RODDER_SOUL }, + { RG_MEDIGORON_SOUL, RAND_INF_MEDIGORON_SOUL }, + { RG_CARPENTER_BOSS_SOUL, RAND_INF_CARPENTER_BOSS_SOUL }, + { RG_ICHIRO_SOUL, RAND_INF_ICHIRO_SOUL }, + { RG_SABOORO_SOUL, RAND_INF_SABOORO_SOUL }, + { RG_JIRO_SOUL, RAND_INF_JIRO_SOUL }, + { RG_SHIRO_SOUL, RAND_INF_SHIRO_SOUL }, + { RG_HW_GATEKEEPER_SOUL, RAND_INF_HW_GATEKEEPER_SOUL }, + { RG_GTG_GATEKEEPER_SOUL, RAND_INF_GTG_GATEKEEPER_SOUL }, + { RG_ARCHER_SOUL, RAND_INF_ARCHER_SOUL }, + { RG_GREAT_FAIRY_SOUL, RAND_INF_GREAT_FAIRY_SOUL }, + { RG_POE_COLLECTOR_SOUL, RAND_INF_POE_COLLECTOR_SOUL }, + { RG_DAMPE_SOUL, RAND_INF_DAMPE_SOUL }, + { RG_WINDMILL_MAN_SOUL, RAND_INF_WINDMILL_MAN_SOUL }, + { RG_MAN_ON_ROOF_SOUL, RAND_INF_MAN_ON_ROOF_SOUL }, + { RG_KAKARIKO_GATEKEEPER_SOUL, RAND_INF_KAKARIKO_GATEKEEPER_SOUL }, + { RG_MALON_SOUL, RAND_INF_MALON_SOUL }, + { RG_RAURU_SOUL, RAND_INF_RAURU_SOUL }, + { RG_SARIA_SOUL, RAND_INF_SARIA_SOUL }, + { RG_DARUNIA_SOUL, RAND_INF_DARUNIA_SOUL }, + { RG_RUTO_SOUL, RAND_INF_RUTO_SOUL }, + { RG_NABOORU_SOUL, RAND_INF_NABOORU_SOUL }, + { RG_IMPA_SOUL, RAND_INF_IMPA_SOUL }, + { RG_ZELDA_SOUL, RAND_INF_ZELDA_SOUL }, + { RG_BEGGAR_SOUL, RAND_INF_BEGGAR_SOUL }, + { RG_DOG_LADY_SOUL, RAND_INF_DOG_LADY_SOUL }, + { RG_ARMS_DEALER_SOUL, RAND_INF_ARMS_DEALER_SOUL }, + { RG_BEAN_SALESMAN_SOUL, RAND_INF_BEAN_SALESMAN_SOUL }, + { RG_SHOOTING_SOUL, RAND_INF_SHOOTING_SOUL }, + { RG_KOKIRI_SHOPKEEPER_SOUL, RAND_INF_KOKIRI_SHOPKEEPER_SOUL }, + { RG_POTION_SHOPKEEPER_SOUL, RAND_INF_POTION_SHOPKEEPER_SOUL }, + { RG_BAZAAR_SHOPKEEPER_SOUL, RAND_INF_BAZAAR_SHOPKEEPER_SOUL }, + { RG_GORON_SHOPKEEPER_SOUL, RAND_INF_GORON_SHOPKEEPER_SOUL }, + { RG_ZORA_SHOPKEEPER_SOUL, RAND_INF_ZORA_SHOPKEEPER_SOUL }, + { RG_BOMBCHU_SHOPKEEPER_SOUL, RAND_INF_BOMBCHU_SHOPKEEPER_SOUL }, + { RG_MASK_SALESMAN_SOUL, RAND_INF_MASK_SALESMAN_SOUL }, + { RG_TREASURE_MAN_SOUL, RAND_INF_TREASURE_MAN_SOUL }, + { RG_BOMBCHU_LADY_SOUL, RAND_INF_BOMBCHU_LADY_SOUL }, + { RG_DIVING_SOUL, RAND_INF_DIVING_SOUL }, + { RG_SCIENTIST_SOUL, RAND_INF_SCIENTIST_SOUL }, + { RG_KAEPORA_SOUL, RAND_INF_KAEPORA_SOUL }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index c3bda412a..42420bd7c 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -203,6 +203,54 @@ typedef enum { LOGIC_CAN_SUMMON_BONGOBONGO, LOGIC_CAN_SUMMON_TWINROVA, LOGIC_CAN_SUMMON_GANON, + LOGIC_CAN_SUMMON_ANJU, + LOGIC_CAN_SUMMON_TALON, + LOGIC_CAN_SUMMON_GROG, + LOGIC_CAN_SUMMON_GRANNY, + LOGIC_CAN_SUMMON_FADO, + LOGIC_CAN_SUMMON_LINK, + LOGIC_CAN_SUMMON_BIGGORON, + LOGIC_CAN_SUMMON_HOT_RODDER, + LOGIC_CAN_SUMMON_MEDIGORON, + LOGIC_CAN_SUMMON_CARPENTER_BOSS, + LOGIC_CAN_SUMMON_ICHIRO, + LOGIC_CAN_SUMMON_SABOORO, + LOGIC_CAN_SUMMON_JIRO, + LOGIC_CAN_SUMMON_SHIRO, + LOGIC_CAN_SUMMON_HW_GATEKEEPER, + LOGIC_CAN_SUMMON_GTG_GATEKEEPER, + LOGIC_CAN_SUMMON_ARCHER, + LOGIC_CAN_SUMMON_GREAT_FAIRY, + LOGIC_CAN_SUMMON_POE_COLLECTOR, + LOGIC_CAN_SUMMON_DAMPE, + LOGIC_CAN_SUMMON_WINDMILL_MAN, + LOGIC_CAN_SUMMON_MAN_ON_ROOF, + LOGIC_CAN_SUMMON_KAKARIKO_GATEKEEPER, + LOGIC_CAN_SUMMON_MALON, + LOGIC_CAN_SUMMON_BEGGAR, + LOGIC_CAN_SUMMON_DOG_LADY, + LOGIC_CAN_SUMMON_ARMS_DEALER, + LOGIC_CAN_SUMMON_BEAN_SALESMAN, + LOGIC_CAN_SUMMON_SHOOTING, + LOGIC_CAN_SUMMON_KOKIRI_SHOPKEEPER, + LOGIC_CAN_SUMMON_POTION_SHOPKEEPER, + LOGIC_CAN_SUMMON_BAZAAR_SHOPKEEPER, + LOGIC_CAN_SUMMON_GORON_SHOPKEEPER, + LOGIC_CAN_SUMMON_ZORA_SHOPKEEPER, + LOGIC_CAN_SUMMON_BOMBCHU_SHOPKEEPER, + LOGIC_CAN_SUMMON_MASK_SALESMAN, + LOGIC_CAN_SUMMON_TREASURE_MAN, + LOGIC_CAN_SUMMON_BOMBCHU_LADY, + LOGIC_CAN_SUMMON_DIVING, + LOGIC_CAN_SUMMON_SCIENTIST, + LOGIC_CAN_SUMMON_KAEPORA, + LOGIC_CAN_SUMMON_RAURU, + LOGIC_CAN_SUMMON_SARIA, + LOGIC_CAN_SUMMON_DARUNIA, + LOGIC_CAN_SUMMON_RUTO, + LOGIC_CAN_SUMMON_NABOORU, + LOGIC_CAN_SUMMON_IMPA, + LOGIC_CAN_SUMMON_ZELDA, LOGIC_FISHING_POLE, LOGIC_OCARINA_A_BUTTON, LOGIC_OCARINA_C_UP_BUTTON, @@ -3963,6 +4011,54 @@ typedef enum { RG_BONGO_BONGO_SOUL, RG_TWINROVA_SOUL, RG_GANON_SOUL, + RG_ANJU_SOUL, // used by loop, must be first NPC soul + RG_TALON_SOUL, + RG_GROG_SOUL, + RG_GRANNY_SOUL, + RG_FADO_SOUL, + RG_LINK_SOUL, + RG_BIGGORON_SOUL, + RG_HOT_RODDER_SOUL, + RG_MEDIGORON_SOUL, + RG_CARPENTER_BOSS_SOUL, + RG_ICHIRO_SOUL, + RG_SABOORO_SOUL, + RG_JIRO_SOUL, + RG_SHIRO_SOUL, + RG_HW_GATEKEEPER_SOUL, + RG_GTG_GATEKEEPER_SOUL, + RG_ARCHER_SOUL, + RG_GREAT_FAIRY_SOUL, + RG_POE_COLLECTOR_SOUL, + RG_DAMPE_SOUL, + RG_WINDMILL_MAN_SOUL, + RG_MAN_ON_ROOF_SOUL, + RG_KAKARIKO_GATEKEEPER_SOUL, + RG_MALON_SOUL, + RG_BEGGAR_SOUL, + RG_DOG_LADY_SOUL, + RG_ARMS_DEALER_SOUL, + RG_BEAN_SALESMAN_SOUL, + RG_SHOOTING_SOUL, + RG_KOKIRI_SHOPKEEPER_SOUL, + RG_POTION_SHOPKEEPER_SOUL, + RG_BAZAAR_SHOPKEEPER_SOUL, + RG_GORON_SHOPKEEPER_SOUL, + RG_ZORA_SHOPKEEPER_SOUL, + RG_BOMBCHU_SHOPKEEPER_SOUL, + RG_MASK_SALESMAN_SOUL, + RG_TREASURE_MAN_SOUL, + RG_BOMBCHU_LADY_SOUL, + RG_DIVING_SOUL, + RG_SCIENTIST_SOUL, + RG_KAEPORA_SOUL, + RG_RAURU_SOUL, + RG_SARIA_SOUL, + RG_DARUNIA_SOUL, + RG_RUTO_SOUL, + RG_NABOORU_SOUL, + RG_IMPA_SOUL, + RG_ZELDA_SOUL, // used by loop, must be last NPC soul RG_OCARINA_A_BUTTON, RG_OCARINA_C_UP_BUTTON, RG_OCARINA_C_DOWN_BUTTON, @@ -5166,6 +5262,54 @@ typedef enum { RHT_BONGO_BONGO_SOUL, RHT_TWINROVA_SOUL, RHT_GANON_SOUL, + RHT_ANJU_SOUL, + RHT_TALON_SOUL, + RHT_GROG_SOUL, + RHT_GRANNY_SOUL, + RHT_FADO_SOUL, + RHT_LINK_SOUL, + RHT_BIGGORON_SOUL, + RHT_HOT_RODDER_SOUL, + RHT_MEDIGORON_SOUL, + RHT_CARPENTER_BOSS_SOUL, + RHT_ICHIRO_SOUL, + RHT_SABOORO_SOUL, + RHT_JIRO_SOUL, + RHT_SHIRO_SOUL, + RHT_HW_GATEKEEPER_SOUL, + RHT_GTG_GATEKEEPER_SOUL, + RHT_ARCHER_SOUL, + RHT_GREAT_FAIRY_SOUL, + RHT_POE_COLLECTOR_SOUL, + RHT_DAMPE_SOUL, + RHT_WINDMILL_MAN_SOUL, + RHT_MAN_ON_ROOF_SOUL, + RHT_KAKARIKO_GATEKEEPER_SOUL, + RHT_MALON_SOUL, + RHT_BEGGAR_SOUL, + RHT_DOG_LADY_SOUL, + RHT_ARMS_DEALER_SOUL, + RHT_BEAN_SALESMAN_SOUL, + RHT_SHOOTING_SOUL, + RHT_KOKIRI_SHOPKEEPER_SOUL, + RHT_POTION_SHOPKEEPER_SOUL, + RHT_BAZAAR_SHOPKEEPER_SOUL, + RHT_GORON_SHOPKEEPER_SOUL, + RHT_ZORA_SHOPKEEPER_SOUL, + RHT_BOMBCHU_SHOPKEEPER_SOUL, + RHT_MASK_SALESMAN_SOUL, + RHT_TREASURE_MAN_SOUL, + RHT_BOMBCHU_LADY_SOUL, + RHT_DIVING_SOUL, + RHT_SCIENTIST_SOUL, + RHT_KAEPORA_SOUL, + RHT_RAURU_SOUL, + RHT_SARIA_SOUL, + RHT_DARUNIA_SOUL, + RHT_RUTO_SOUL, + RHT_NABOORU_SOUL, + RHT_IMPA_SOUL, + RHT_ZELDA_SOUL, RHT_OCARINA_A_BUTTON, RHT_OCARINA_C_UP_BUTTON, RHT_OCARINA_C_DOWN_BUTTON, @@ -5903,6 +6047,7 @@ typedef enum { RSK_SHUFFLE_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, + RSK_SHUFFLE_NPC_SOULS, RSK_MAX } RandomizerSettingKey; @@ -6041,6 +6186,12 @@ typedef enum { RO_BOSS_SOULS_ON_PLUS_GANON, } RandoOptionBossSouls; +typedef enum { + RO_NPC_SOULS_OFF, + RO_NPC_SOULS_ON, + RO_NPC_SOULS_ON_PLUS_SAGES, +} RandoOptionNpcSouls; + // Fishsanity settings (off, loach only, pond only, grottos only, both) typedef enum { RO_FISHSANITY_OFF, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index adaf03cea..a265759b3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -619,16 +619,46 @@ void CheckTrackerTransition(uint32_t sceneNum) { doAreaScroll = true; previousArea = currentArea; currentArea = GetCheckArea(); - switch (sceneNum) { - case SCENE_KOKIRI_SHOP: - case SCENE_BAZAAR: - case SCENE_POTION_SHOP_MARKET: - case SCENE_BOMBCHU_SHOP: - case SCENE_POTION_SHOP_KAKARIKO: - case SCENE_GORON_SHOP: - case SCENE_ZORA_SHOP: - SetShopSeen(sceneNum, false); - break; + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_NPC_SOULS) == RO_NPC_SOULS_OFF) { + SetShopSeen(sceneNum, false); + } else { + switch (sceneNum) { + case SCENE_KOKIRI_SHOP: + if (Flags_GetRandomizerInf(RAND_INF_KOKIRI_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_BAZAAR: + if (Flags_GetRandomizerInf(RAND_INF_BAZAAR_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_POTION_SHOP_MARKET: + if (Flags_GetRandomizerInf(RAND_INF_POTION_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_BOMBCHU_SHOP: + if (Flags_GetRandomizerInf(RAND_INF_BOMBCHU_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_POTION_SHOP_KAKARIKO: + if (Flags_GetRandomizerInf(RAND_INF_POTION_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_GORON_SHOP: + if (Flags_GetRandomizerInf(RAND_INF_GORON_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_ZORA_SHOP: + if (Flags_GetRandomizerInf(RAND_INF_ZORA_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + } } if (!IsAreaSpoiled(currentArea) && (RandomizerCheckObjects::AreaIsOverworld(currentArea) || std::find(spoilingEntrances.begin(), spoilingEntrances.end(), @@ -1526,9 +1556,6 @@ void LoadSettings() { bool IsCheckShuffled(RandomizerCheck rc) { Rando::Location* loc = Rando::StaticData::GetLocation(rc); - if (loc->GetRCType() == RCTYPE_SHOP) { - auto identity = OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1); - } if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) != RO_LOGIC_VANILLA) { return (loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations (loc->GetRCType() != RCTYPE_GOSSIP_STONE) && // TODO: Don't show hints until tracker supports them diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index f36a7f8b8..3a24babb3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1951,4 +1951,52 @@ DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8) // End Grass -DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER) \ No newline at end of file +DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER) +DEFINE_RAND_INF(RAND_INF_ANJU_SOUL) // used by loop, must be first NPC soul +DEFINE_RAND_INF(RAND_INF_TALON_SOUL) +DEFINE_RAND_INF(RAND_INF_GROG_SOUL) +DEFINE_RAND_INF(RAND_INF_GRANNY_SOUL) +DEFINE_RAND_INF(RAND_INF_FADO_SOUL) +DEFINE_RAND_INF(RAND_INF_LINK_SOUL) +DEFINE_RAND_INF(RAND_INF_BIGGORON_SOUL) +DEFINE_RAND_INF(RAND_INF_HOT_RODDER_SOUL) +DEFINE_RAND_INF(RAND_INF_MEDIGORON_SOUL) +DEFINE_RAND_INF(RAND_INF_CARPENTER_BOSS_SOUL) +DEFINE_RAND_INF(RAND_INF_ICHIRO_SOUL) +DEFINE_RAND_INF(RAND_INF_SABOORO_SOUL) +DEFINE_RAND_INF(RAND_INF_JIRO_SOUL) +DEFINE_RAND_INF(RAND_INF_SHIRO_SOUL) +DEFINE_RAND_INF(RAND_INF_HW_GATEKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_GTG_GATEKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_ARCHER_SOUL) +DEFINE_RAND_INF(RAND_INF_GREAT_FAIRY_SOUL) +DEFINE_RAND_INF(RAND_INF_POE_COLLECTOR_SOUL) +DEFINE_RAND_INF(RAND_INF_DAMPE_SOUL) +DEFINE_RAND_INF(RAND_INF_WINDMILL_MAN_SOUL) +DEFINE_RAND_INF(RAND_INF_MAN_ON_ROOF_SOUL) +DEFINE_RAND_INF(RAND_INF_KAKARIKO_GATEKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_MALON_SOUL) +DEFINE_RAND_INF(RAND_INF_BEGGAR_SOUL) +DEFINE_RAND_INF(RAND_INF_DOG_LADY_SOUL) +DEFINE_RAND_INF(RAND_INF_ARMS_DEALER_SOUL) +DEFINE_RAND_INF(RAND_INF_BEAN_SALESMAN_SOUL) +DEFINE_RAND_INF(RAND_INF_SHOOTING_SOUL) +DEFINE_RAND_INF(RAND_INF_KOKIRI_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_POTION_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_BAZAAR_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_GORON_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_ZORA_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_BOMBCHU_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_MASK_SALESMAN_SOUL) +DEFINE_RAND_INF(RAND_INF_BOMBCHU_LADY_SOUL) +DEFINE_RAND_INF(RAND_INF_TREASURE_MAN_SOUL) +DEFINE_RAND_INF(RAND_INF_DIVING_SOUL) +DEFINE_RAND_INF(RAND_INF_SCIENTIST_SOUL) +DEFINE_RAND_INF(RAND_INF_KAEPORA_SOUL) +DEFINE_RAND_INF(RAND_INF_RAURU_SOUL) +DEFINE_RAND_INF(RAND_INF_SARIA_SOUL) +DEFINE_RAND_INF(RAND_INF_DARUNIA_SOUL) +DEFINE_RAND_INF(RAND_INF_RUTO_SOUL) +DEFINE_RAND_INF(RAND_INF_NABOORU_SOUL) +DEFINE_RAND_INF(RAND_INF_IMPA_SOUL) +DEFINE_RAND_INF(RAND_INF_ZELDA_SOUL) // used by loop, must be last NPC soul diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index c88d70db1..e7f3f13d5 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -233,6 +233,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); OPT_BOOL(RSK_SHUFFLE_100_GS_REWARD, "Shuffle 100 GS Reward", CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_U8(RSK_SHUFFLE_BOSS_SOULS, "Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox); + OPT_U8(RSK_SHUFFLE_NPC_SOULS, "Shuffle NPC Souls", {"Off", "On", "On + Sages"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleNpcSouls"), mOptionDescriptions[RSK_SHUFFLE_NPC_SOULS], WidgetType::Combobox); OPT_BOOL(RSK_SHUFFLE_DEKU_STICK_BAG, "Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_BOOL(RSK_SHUFFLE_DEKU_NUT_BAG, "Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_U8(RSK_SHUFFLE_FREESTANDING, "Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WidgetType::Combobox, RO_SHUFFLE_FREESTANDING_OFF); @@ -1278,6 +1279,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], + &mOptions[RSK_SHUFFLE_NPC_SOULS], &mOptions[RSK_SHUFFLE_FAIRIES], &mOptions[RSK_SHUFFLE_GRASS], }, @@ -1517,6 +1519,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], + &mOptions[RSK_SHUFFLE_NPC_SOULS], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index dd8185c1d..8d1f9cd69 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -463,9 +463,12 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li 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(VB_GIVE_ITEM_LIGHT_MEDALLION, true)) { - Item_Give(gPlayState, ITEM_MEDALLION_LIGHT); + if (!IS_RANDO || !RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) || + Flags_GetRandomizerInf(RAND_INF_RAURU_SOUL)) { + Flags_SetEventChkInf(EVENTCHKINF_TIME_TRAVELED_TO_ADULT); + if (GameInteractor_Should(VB_GIVE_ITEM_LIGHT_MEDALLION, true)) { + Item_Give(gPlayState, ITEM_MEDALLION_LIGHT); + } } } *should = false; 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 a3a46ed36..9ae66bbe3 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 @@ -8,6 +8,7 @@ #include "objects/object_spot00_objects/object_spot00_objects.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED @@ -214,9 +215,11 @@ void BgSpot00Hanebasi_Update(Actor* thisx, PlayState* play) { if (this->dyna.actor.params == DT_DRAWBRIDGE) { if (play->sceneNum == SCENE_HYRULE_FIELD) { - if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && - CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) && !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE) && - LINK_IS_CHILD) { + if (GameInteractor_Should(VB_BE_ELIGIBLE_FOR_OCARINA_OF_TIME, + CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && + CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) && + !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE) && + LINK_IS_CHILD)) { Player* player = GET_PLAYER(play); if ((player->actor.world.pos.x > -450.0f) && (player->actor.world.pos.x < 450.0f) &&