NPC souls

This commit is contained in:
Demur Rumed 2025-01-13 05:10:38 +00:00
commit 2407e01291
48 changed files with 1254 additions and 265 deletions

View file

@ -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;
}

View file

@ -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) &&

View file

@ -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
{

View file

@ -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);
}

View file

@ -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

View file

@ -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<GameInteractor::OnPlayerUpdate>([]() {
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() &&

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);}),

View file

@ -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);});}),

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()),

View file

@ -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;}),

View file

@ -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;}),

View file

@ -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;}),

View file

@ -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;}),

View file

@ -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()),

View file

@ -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;}),

View file

@ -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, {}, {

View file

@ -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()),

View file

@ -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()),

View file

@ -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;}),

View file

@ -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;}),

View file

@ -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)),

View file

@ -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()),

View file

@ -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;}),

View file

@ -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

View file

@ -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)),

View file

@ -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;}),

View file

@ -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;}),

View file

@ -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;}),

View file

@ -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)),

View file

@ -1,4 +1,5 @@
#include "static_data.h"
#include "z64save.h"
#include "context.h"
#include "dungeon.h"

View file

@ -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<RandomizerGet, uint32_t> 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:

View file

@ -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);

View file

@ -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

View file

@ -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<GetItemMessage, 112> getItemMessages = { {
const std::array<GetItemMessage, 160> 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<RandomizerGet, RandomizerInf> 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) {

View file

@ -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,

View file

@ -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

View file

@ -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)
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

View file

@ -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);
@ -1277,6 +1278,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],
},
@ -1516,6 +1518,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],

View file

@ -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;

View file

@ -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) &&