From a3416023e3bd0729601177fae0400f0181a00158 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Mon, 7 Jul 2025 01:45:15 +0000 Subject: [PATCH 01/14] shuffle silver --- soh/include/z64save.h | 29 ++ .../vanilla-behavior/GIVanillaBehavior.h | 8 + .../hint_list/hint_list_exclude_dungeon.cpp | 9 + .../3drando/hint_list/hint_list_item.cpp | 2 + .../randomizer/3drando/item_pool.cpp | 67 ++++- .../randomizer/3drando/starting_inventory.cpp | 6 + .../Enhancements/randomizer/SeedContext.cpp | 1 + .../Enhancements/randomizer/ShuffleSilver.cpp | 284 ++++++++++++++++++ soh/soh/Enhancements/randomizer/Traps.cpp | 118 ++++++++ soh/soh/Enhancements/randomizer/draw.cpp | 23 ++ soh/soh/Enhancements/randomizer/draw.h | 1 + soh/soh/Enhancements/randomizer/item.cpp | 6 +- soh/soh/Enhancements/randomizer/item_list.cpp | 59 ++++ .../dungeons/bottom_of_the_well.cpp | 11 +- .../dungeons/dodongos_cavern.cpp | 13 +- .../dungeons/ganons_castle.cpp | 88 ++++-- .../dungeons/gerudo_training_ground.cpp | 122 ++++++-- .../location_access/dungeons/ice_cavern.cpp | 24 +- .../dungeons/shadow_temple.cpp | 116 +++++-- .../dungeons/spirit_temple.cpp | 55 +++- soh/soh/Enhancements/randomizer/logic.cpp | 81 ++++- .../randomizer/option_descriptions.cpp | 3 + .../Enhancements/randomizer/randomizer.cpp | 275 +++++++++++++++++ soh/soh/Enhancements/randomizer/randomizer.h | 2 + .../randomizer/randomizerEnums/LogicVal.h | 29 ++ .../randomizerEnums/RandomizerCheck.h | 157 ++++++++++ .../randomizerEnums/RandomizerGet.h | 29 ++ .../randomizerEnums/RandomizerHintTextKey.h | 9 + .../randomizerEnums/RandomizerInf.h | 157 ++++++++++ .../randomizerEnums/RandomizerMiscEnums.h | 1 + .../randomizerEnums/RandomizerOptions.h | 8 + .../randomizerEnums/RandomizerSettingKey.h | 1 + .../randomizer/randomizer_check_objects.cpp | 2 + .../randomizer/randomizer_check_tracker.cpp | 4 + soh/soh/Enhancements/randomizer/savefile.cpp | 6 + soh/soh/Enhancements/randomizer/settings.cpp | 3 + .../Enhancements/randomizer/static_data.cpp | 32 ++ soh/soh/Enhancements/randomizer/static_data.h | 2 + soh/soh/SaveManager.cpp | 74 +++++ .../actors/ovl_En_G_Switch/z_en_g_switch.c | 5 +- 40 files changed, 1809 insertions(+), 113 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/ShuffleSilver.cpp diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 35f30c26398..10704933037 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -205,6 +205,35 @@ typedef struct { typedef struct ShipRandomizerSaveContextData { u8 triforcePiecesCollected; u8 bombchuUpgradeLevel; + s8 silverShadowBlades; + s8 silverShadowPit; + s8 silverShadowSpikes; + s8 silverSpiritChild; + s8 silverSpiritSun; + s8 silverSpiritBoulders; + s8 silverBotw; + s8 silverIceCavernBlades; + s8 silverIceCavernBlock; + s8 silverGtgSlope; + s8 silverGtgLava; + s8 silverGtgWater; + s8 silverGanonLight; + s8 silverGanonForest; + s8 silverGanonFire; + s8 silverGanonSpirit; + s8 silverMqDodongosCavern; + s8 silverMqShadowBlades; + s8 silverMqShadowPit; + s8 silverMqShadowInvisibleBlades; + s8 silverMqShadowSpikes; + s8 silverMqSpiritLobby; + s8 silverMqSpiritBigWall; + s8 silverMqGtgSlope; + s8 silverMqGtgLava; + s8 silverMqGtgWater; + s8 silverMqGanonFire; + s8 silverMqGanonWater; + s8 silverMqGanonShadow; } ShipRandomizerSaveContextData; typedef struct ShipBossRushSaveContextData { diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index d1ed4534100..04b1e4461f1 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2214,6 +2214,14 @@ typedef enum { // - None VB_SHOW_TITLE_CARD, + // #### `result` + // ```c + // Flags_GetSwitch(play, this->switchFlag) + // ``` + // #### `args` + // - *EnGSwitch + VB_SILVER_DESPAWN, + // #### `result` // ```c // true diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp index 2413003cd22..740e1c9e1cd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp @@ -6,6 +6,15 @@ namespace Rando { void StaticData::HintTable_Init_Exclude_Dungeon() { // clang-format off + // TODO move these to region specific sections when hint text stable + hintTextTable[RHT_DODONGOS_CAVERN_SILVER] = HintText(CustomMessage("They say that silver in #Dodongo's Cavern# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_SHADOW_TEMPLE_SILVER] = HintText(CustomMessage("They say that silver in #Shadow Temple# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_SPIRIT_TEMPLE_SILVER] = HintText(CustomMessage("They say that silver in #Spirit Temple# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_BOTW_SILVER] = HintText(CustomMessage("They say that silver in #Bottom of the Well# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_ICE_CAVERN_SILVER] = HintText(CustomMessage("They say that silver in #Ice Cavern# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GTG_SILVER] = HintText(CustomMessage("They say that silver in #Gerudo Training Ground# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN})); + hintTextTable[RHT_GANONS_CASTLE_SILVER] = HintText(CustomMessage("They say that silver in #Ganon's Castle# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*-------------------------- | DEKU TREE | ---------------------------*/ diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 2b2fd83f100..2a5b964c121 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2108,6 +2108,8 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("sack of mice", /*german*/"ein Sack Mäuse", /*french*/"un Sac rempli de souris")}); + hintTextTable[RHT_SILVER] = HintText(CustomMessage("a Silver Rupee", /*german*/ TODO_TRANSLATE, /*french*/ TODO_TRANSLATE)); + hintTextTable[RHT_SKELETON_KEY] = HintText(CustomMessage("a Skeleton Key", /*german*/ "der Skelettschlüssel", /*french*/ "une Clé Squelette"), // /*spanish*/una Llave Maestra { diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 97f06fd1299..7d318076f87 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -218,7 +218,7 @@ void GenerateItemPool() { 1 + infiniteProgressive); //clang-format on - int extraWallets =(ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET) ? 1 : 0) + (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET) ? 1 : 0); + int extraWallets = (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET) ? 1 : 0) + (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET) ? 1 : 0); AddItemToPool(RG_PROGRESSIVE_WALLET, 3 + infiniteProgressive + extraWallets, 2 + infiniteProgressive + extraWallets, 2 + infiniteProgressive + extraWallets, @@ -864,6 +864,71 @@ void GenerateItemPool() { } } + bool silverActive = ctx->GetOption(RSK_SHUFFLE_SILVER).Get(); + if (silverActive) { + PlaceItemsForType(RCTYPE_SILVER, silverActive, silverActive); + } + + if (ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_ON) || + ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET)) { + ctx->possibleIceTrapModels.insert(RG_SHADOW_SILVER_BLADES); // ice traps reroll this into a random silver rupee + bool isWallet = ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET); + auto dungeons = ctx->GetDungeons(); + if (dungeons->GetDungeonFromScene(SCENE_DODONGOS_CAVERN)->IsMQ()) { + AddFixedItemToPool(RG_DODONGOS_CAVERN_MQ_SILVER, isWallet ? 1 : 5, false); + } + + if (dungeons->GetDungeonFromScene(SCENE_SHADOW_TEMPLE)->IsVanilla()) { + AddFixedItemToPool(RG_SHADOW_SILVER_BLADES, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_SHADOW_SILVER_PIT, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_SHADOW_SILVER_SPIKES, isWallet ? 1 : 5, false); + } else { + AddFixedItemToPool(RG_SHADOW_MQ_SILVER_BLADES, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_SHADOW_MQ_SILVER_PIT, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES, isWallet ? 1 : 10, false); + AddFixedItemToPool(RG_SHADOW_MQ_SILVER_SPIKES, isWallet ? 1 : 10, false); + } + + if (dungeons->GetDungeonFromScene(SCENE_SPIRIT_TEMPLE)->IsVanilla()) { + AddFixedItemToPool(RG_SPIRIT_SILVER_CHILD, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_SPIRIT_SILVER_SUN, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_SPIRIT_SILVER_BOULDERS, isWallet ? 1 : 5, false); + } else { + AddFixedItemToPool(RG_SPIRIT_MQ_SILVER_LOBBY, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_SPIRIT_MQ_SILVER_BIG_WALL, isWallet ? 1 : 5, false); + } + + if (dungeons->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL)->IsVanilla()) { + AddFixedItemToPool(RG_BOTW_SILVER, isWallet ? 1 : 5, false); + } + + if (dungeons->GetDungeonFromScene(SCENE_ICE_CAVERN)->IsVanilla()) { + AddFixedItemToPool(RG_ICE_CAVERN_SILVER_BLADES, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_ICE_CAVERN_SILVER_BLOCK, isWallet ? 1 : 5, false); + } + + if (dungeons->GetDungeonFromScene(SCENE_GERUDO_TRAINING_GROUND)->IsVanilla()) { + AddFixedItemToPool(RG_GTG_SILVER_SLOPE, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_GTG_SILVER_LAVA, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_GTG_SILVER_WATER, isWallet ? 1 : 5, false); + } else { + AddFixedItemToPool(RG_GTG_MQ_SILVER_SLOPE, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_GTG_MQ_SILVER_LAVA, isWallet ? 1 : 6, false); + AddFixedItemToPool(RG_GTG_MQ_SILVER_WATER, isWallet ? 1 : 3, false); + } + + if (dungeons->GetDungeonFromScene(SCENE_INSIDE_GANONS_CASTLE)->IsVanilla()) { + AddFixedItemToPool(RG_GANONS_CASTLE_SILVER_LIGHT, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_GANONS_CASTLE_SILVER_FOREST, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_GANONS_CASTLE_SILVER_FIRE, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_GANONS_CASTLE_SILVER_SPIRIT, isWallet ? 1 : 5, false); + } else { + AddFixedItemToPool(RG_GANONS_CASTLE_MQ_SILVER_FIRE, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_GANONS_CASTLE_MQ_SILVER_WATER, isWallet ? 1 : 5, false); + AddFixedItemToPool(RG_GANONS_CASTLE_MQ_SILVER_SHADOW, isWallet ? 1 : 5, false); + } + } + int maxHearts = 20; switch (ctx->GetOption(RSK_ITEM_POOL).Get()) { case RO_ITEM_POOL_PLENTIFUL: diff --git a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp index e7f875bf1c4..c3e47da2a20 100644 --- a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp @@ -53,6 +53,12 @@ void GenerateStartingInventory() { AddItemToInventory(RG_SHADOW_TEMPLE_BOSS_KEY); } + if (ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_STARTWITH)) { + for (int rg = (int)RG_SHADOW_SILVER_BLADES; rg <= (int)RG_GANONS_CASTLE_MQ_SILVER_SHADOW; rg++) { + AddItemToInventory((RandomizerGet)rg); + } + } + // Add Ganon's Boss key with Triforce Hunt's Win setting so the game thinks it's obtainable from the start. // During save init, the boss key isn't actually given and it's instead given when completing the triforce. if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH) || diff --git a/soh/soh/Enhancements/randomizer/SeedContext.cpp b/soh/soh/Enhancements/randomizer/SeedContext.cpp index 71bbd84d2b8..76acdfda8b0 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -229,6 +229,7 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_WONDER_ITEMS].Is(RO_SHUFFLE_WONDER_ITEMS_OFF)) || (location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || + (location.GetRCType() == RCTYPE_SILVER && !mOptions[RSK_SHUFFLE_SILVER]) || (location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) { continue; } diff --git a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp new file mode 100644 index 00000000000..aff819fa05f --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp @@ -0,0 +1,284 @@ +#include +#include "dungeon.h" +#include "SeedContext.h" +#include "draw.h" +#include "static_data.h" + +extern "C" { +#include "overlays/actors/ovl_En_G_Switch/z_en_g_switch.h" +extern PlayState* gPlayState; +extern SaveContext gSaveContext; +} + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +static bool IsSilverCleared(s16 switchFlag) { + bool isMQ = Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(gPlayState->sceneNum)->IsMQ(); + switch (gPlayState->sceneNum) { + case SCENE_DODONGOS_CAVERN: + return gSaveContext.ship.quest.data.randomizer.silverMqDodongosCavern >= 5; + case SCENE_SHADOW_TEMPLE: + switch (switchFlag) { + case 1: + + return isMQ ? gSaveContext.ship.quest.data.randomizer.silverMqShadowBlades >= 5 + : gSaveContext.ship.quest.data.randomizer.silverShadowBlades >= 5; + case 3: + return gSaveContext.ship.quest.data.randomizer.silverMqShadowInvisibleBlades >= 10; + case 8: + return isMQ ? gSaveContext.ship.quest.data.randomizer.silverMqShadowSpikes >= 10 + : gSaveContext.ship.quest.data.randomizer.silverShadowSpikes >= 5; + case 9: + return gSaveContext.ship.quest.data.randomizer.silverShadowPit >= 5; + case 17: + return gSaveContext.ship.quest.data.randomizer.silverMqShadowPit >= 5; + } + case SCENE_SPIRIT_TEMPLE: + switch (switchFlag) { + case 0: + return gSaveContext.ship.quest.data.randomizer.silverMqSpiritBigWall >= 5; + case 2: + return gSaveContext.ship.quest.data.randomizer.silverSpiritBoulders >= 5; + case 5: + return gSaveContext.ship.quest.data.randomizer.silverSpiritChild >= 5; + case 10: + return gSaveContext.ship.quest.data.randomizer.silverSpiritSun >= 5; + case 55: + return gSaveContext.ship.quest.data.randomizer.silverMqSpiritLobby >= 5; + } + case SCENE_BOTTOM_OF_THE_WELL: + return gSaveContext.ship.quest.data.randomizer.silverBotw >= 5; + case SCENE_ICE_CAVERN: + switch (switchFlag) { + case 8: + return gSaveContext.ship.quest.data.randomizer.silverIceCavernBlock >= 5; + case 31: + return gSaveContext.ship.quest.data.randomizer.silverIceCavernBlades >= 5; + } + case SCENE_GERUDO_TRAINING_GROUND: + switch (switchFlag) { + case 12: + return isMQ ? gSaveContext.ship.quest.data.randomizer.silverMqGtgLava >= 6 + : gSaveContext.ship.quest.data.randomizer.silverGtgLava >= 5; + case 27: + return isMQ ? gSaveContext.ship.quest.data.randomizer.silverMqGtgWater >= 3 + : gSaveContext.ship.quest.data.randomizer.silverGtgWater >= 5; + case 28: + return isMQ ? gSaveContext.ship.quest.data.randomizer.silverMqGtgSlope >= 5 + : gSaveContext.ship.quest.data.randomizer.silverGtgSlope >= 5; + } + case SCENE_INSIDE_GANONS_CASTLE: + switch (switchFlag) { + case 1: + return gSaveContext.ship.quest.data.randomizer.silverMqGanonFire >= 5; + case 2: + return gSaveContext.ship.quest.data.randomizer.silverMqGanonWater >= 5; + case 9: + return gSaveContext.ship.quest.data.randomizer.silverGanonFire >= 5; + case 11: + return isMQ ? gSaveContext.ship.quest.data.randomizer.silverMqGanonShadow >= 5 + : gSaveContext.ship.quest.data.randomizer.silverGanonSpirit >= 5; + case 14: + return gSaveContext.ship.quest.data.randomizer.silverGanonForest >= 5; + case 18: + return gSaveContext.ship.quest.data.randomizer.silverGanonLight >= 5; + } + } + return false; +} + +void RegisterShuffleSilver() { + bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_SILVER); + + COND_VB_SHOULD(VB_SILVER_DESPAWN, shouldRegister, { + EnGSwitch* silver = va_arg(args, EnGSwitch*); + if (silver->type == ENGSWITCH_SILVER_RUPEE) { + auto silverIdentity = OTRGlobals::Instance->gRandomizer->IdentifySilver( + gPlayState->sceneNum, (s16)silver->actor.world.pos.x, (s16)silver->actor.world.pos.z); + *should = true; + if (silverIdentity.randomizerCheck == RC_UNKNOWN_CHECK || + Flags_GetRandomizerInf(silverIdentity.randomizerInf)) { + return; + } + + EnItem00* item00 = + (EnItem00*)Item_DropCollectible2(gPlayState, &silver->actor.world.pos, ITEM00_SOH_DUMMY | 0x4000); + item00->randoCheck = silverIdentity.randomizerCheck; + item00->randoInf = silverIdentity.randomizerInf; + item00->itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(silverIdentity.randomizerCheck, false, GI_RUPEE_BLUE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + } else if (silver->type == ENGSWITCH_SILVER_TRACKER) { + if (IsSilverCleared(silver->switchFlag)) { + Flags_SetSwitch(gPlayState, silver->switchFlag); + } + *should = true; + } + }); +} + +void Rando::StaticData::RegisterSilverLocations() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + locationTable[RC_SHADOW_SILVER_BLADES_1] = Location::Collectable(RC_SHADOW_SILVER_BLADES_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3243, -1061), "RC_SHADOW_SILVER_BLADES_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_BLADES_1)); + locationTable[RC_SHADOW_SILVER_BLADES_2] = Location::Collectable(RC_SHADOW_SILVER_BLADES_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3007, -1222), "RC_SHADOW_SILVER_BLADES_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_BLADES_2)); + locationTable[RC_SHADOW_SILVER_BLADES_3] = Location::Collectable(RC_SHADOW_SILVER_BLADES_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3554, -1432), "RC_SHADOW_SILVER_BLADES_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_BLADES_3)); + locationTable[RC_SHADOW_SILVER_BLADES_4] = Location::Collectable(RC_SHADOW_SILVER_BLADES_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2869, -948), "RC_SHADOW_SILVER_BLADES_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_BLADES_4)); + locationTable[RC_SHADOW_SILVER_BLADES_5] = Location::Collectable(RC_SHADOW_SILVER_BLADES_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3399, -838), "RC_SHADOW_SILVER_BLADES_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_BLADES_5)); + locationTable[RC_SHADOW_SILVER_PIT_1] = Location::Collectable(RC_SHADOW_SILVER_PIT_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2131, 3030), "RC_SHADOW_SILVER_PIT_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_PIT_1)); + locationTable[RC_SHADOW_SILVER_PIT_2] = Location::Collectable(RC_SHADOW_SILVER_PIT_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2115, 3738), "RC_SHADOW_SILVER_PIT_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_PIT_2)); + locationTable[RC_SHADOW_SILVER_PIT_3] = Location::Collectable(RC_SHADOW_SILVER_PIT_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2110, 3368), "RC_SHADOW_SILVER_PIT_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_PIT_3)); + locationTable[RC_SHADOW_SILVER_PIT_4] = Location::Collectable(RC_SHADOW_SILVER_PIT_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2243, 3361), "RC_SHADOW_SILVER_PIT_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_PIT_4)); + locationTable[RC_SHADOW_SILVER_PIT_5] = Location::Collectable(RC_SHADOW_SILVER_PIT_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(1998, 3358), "RC_SHADOW_SILVER_PIT_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_PIT_5)); + locationTable[RC_SHADOW_SILVER_SPIKES_1] = Location::Collectable(RC_SHADOW_SILVER_SPIKES_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2042, 849), "RC_SHADOW_SILVER_SPIKES_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_SPIKES_1)); + locationTable[RC_SHADOW_SILVER_SPIKES_2] = Location::Collectable(RC_SHADOW_SILVER_SPIKES_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2940, 1069), "RC_SHADOW_SILVER_SPIKES_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_SPIKES_2)); + locationTable[RC_SHADOW_SILVER_SPIKES_3] = Location::Collectable(RC_SHADOW_SILVER_SPIKES_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2478, 1208), "RC_SHADOW_SILVER_SPIKES_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_SPIKES_3)); + locationTable[RC_SHADOW_SILVER_SPIKES_4] = Location::Collectable(RC_SHADOW_SILVER_SPIKES_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2135, 1297), "RC_SHADOW_SILVER_SPIKES_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_SPIKES_4)); + locationTable[RC_SHADOW_SILVER_SPIKES_5] = Location::Collectable(RC_SHADOW_SILVER_SPIKES_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2254, 988), "RC_SHADOW_SILVER_SPIKES_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_SILVER_SPIKES_5)); + locationTable[RC_SPIRIT_SILVER_CHILD_1] = Location::Collectable(RC_SPIRIT_SILVER_CHILD_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-766, -1075), "RC_SPIRIT_SILVER_CHILD_1", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_CHILD_1)); + locationTable[RC_SPIRIT_SILVER_CHILD_2] = Location::Collectable(RC_SPIRIT_SILVER_CHILD_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-672, -1075), "RC_SPIRIT_SILVER_CHILD_2", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_CHILD_2)); + locationTable[RC_SPIRIT_SILVER_CHILD_3] = Location::Collectable(RC_SPIRIT_SILVER_CHILD_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-511, -1075), "RC_SPIRIT_SILVER_CHILD_3", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_CHILD_3)); + locationTable[RC_SPIRIT_SILVER_CHILD_4] = Location::Collectable(RC_SPIRIT_SILVER_CHILD_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-347, -1075), "RC_SPIRIT_SILVER_CHILD_4", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_CHILD_4)); + locationTable[RC_SPIRIT_SILVER_CHILD_5] = Location::Collectable(RC_SPIRIT_SILVER_CHILD_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-335, -1409), "RC_SPIRIT_SILVER_CHILD_5", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_CHILD_5)); + locationTable[RC_SPIRIT_SILVER_SUN_1] = Location::Collectable(RC_SPIRIT_SILVER_SUN_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1836, -446), "RC_SPIRIT_SILVER_SUN_1", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_SUN_1)); + locationTable[RC_SPIRIT_SILVER_SUN_2] = Location::Collectable(RC_SPIRIT_SILVER_SUN_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1433, -283), "RC_SPIRIT_SILVER_SUN_2", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_SUN_2)); + locationTable[RC_SPIRIT_SILVER_SUN_3] = Location::Collectable(RC_SPIRIT_SILVER_SUN_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1275, -247), "RC_SPIRIT_SILVER_SUN_3", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_SUN_3)); + locationTable[RC_SPIRIT_SILVER_SUN_4] = Location::Collectable(RC_SPIRIT_SILVER_SUN_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1123, 428), "RC_SPIRIT_SILVER_SUN_4", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_SUN_4)); + locationTable[RC_SPIRIT_SILVER_SUN_5] = Location::Collectable(RC_SPIRIT_SILVER_SUN_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-984, -450), "RC_SPIRIT_SILVER_SUN_5", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_SUN_5)); + locationTable[RC_SPIRIT_SILVER_BOULDERS_1] = Location::Collectable(RC_SPIRIT_SILVER_BOULDERS_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1284, -1355), "RC_SPIRIT_SILVER_BOULDERS_1", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_BOULDERS_1)); + locationTable[RC_SPIRIT_SILVER_BOULDERS_2] = Location::Collectable(RC_SPIRIT_SILVER_BOULDERS_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1284, -813), "RC_SPIRIT_SILVER_BOULDERS_2", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_BOULDERS_2)); + locationTable[RC_SPIRIT_SILVER_BOULDERS_3] = Location::Collectable(RC_SPIRIT_SILVER_BOULDERS_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1856, -944), "RC_SPIRIT_SILVER_BOULDERS_3", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_BOULDERS_3)); + locationTable[RC_SPIRIT_SILVER_BOULDERS_4] = Location::Collectable(RC_SPIRIT_SILVER_BOULDERS_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1856, -1219), "RC_SPIRIT_SILVER_BOULDERS_4", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_BOULDERS_4)); + locationTable[RC_SPIRIT_SILVER_BOULDERS_5] = Location::Collectable(RC_SPIRIT_SILVER_BOULDERS_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1573, -920), "RC_SPIRIT_SILVER_BOULDERS_5", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_SILVER_BOULDERS_5)); + locationTable[RC_BOTW_SILVER_1] = Location::Collectable(RC_BOTW_SILVER_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-796, -150), "RC_BOTW_SILVER_1", RHT_BOTW_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_SILVER_1)); + locationTable[RC_BOTW_SILVER_2] = Location::Collectable(RC_BOTW_SILVER_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-614, -297), "RC_BOTW_SILVER_2", RHT_BOTW_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_SILVER_2)); + locationTable[RC_BOTW_SILVER_3] = Location::Collectable(RC_BOTW_SILVER_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-560, -291), "RC_BOTW_SILVER_3", RHT_BOTW_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_SILVER_3)); + locationTable[RC_BOTW_SILVER_4] = Location::Collectable(RC_BOTW_SILVER_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-402, -401), "RC_BOTW_SILVER_4", RHT_BOTW_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_SILVER_4)); + locationTable[RC_BOTW_SILVER_5] = Location::Collectable(RC_BOTW_SILVER_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-259, -234), "RC_BOTW_SILVER_5", RHT_BOTW_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_SILVER_5)); + locationTable[RC_ICE_CAVERN_SILVER_BLADES_1] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLADES_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1, -143), "RC_ICE_CAVERN_SILVER_BLADES_1", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLADES_1)); + locationTable[RC_ICE_CAVERN_SILVER_BLADES_2] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLADES_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(198, -388), "RC_ICE_CAVERN_SILVER_BLADES_2", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLADES_2)); + locationTable[RC_ICE_CAVERN_SILVER_BLADES_3] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLADES_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(278, -637), "RC_ICE_CAVERN_SILVER_BLADES_3", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLADES_3)); + locationTable[RC_ICE_CAVERN_SILVER_BLADES_4] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLADES_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(389, -382), "RC_ICE_CAVERN_SILVER_BLADES_4", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLADES_4)); + locationTable[RC_ICE_CAVERN_SILVER_BLADES_5] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLADES_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(414, -579), "RC_ICE_CAVERN_SILVER_BLADES_5", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLADES_5)); + locationTable[RC_ICE_CAVERN_SILVER_BLOCK_1] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLOCK_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1676, -552), "RC_ICE_CAVERN_SILVER_BLOCK_1", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLOCK_1)); + locationTable[RC_ICE_CAVERN_SILVER_BLOCK_2] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLOCK_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1558, -951), "RC_ICE_CAVERN_SILVER_BLOCK_2", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLOCK_2)); + locationTable[RC_ICE_CAVERN_SILVER_BLOCK_3] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLOCK_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1294, -899), "RC_ICE_CAVERN_SILVER_BLOCK_3", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLOCK_3)); + locationTable[RC_ICE_CAVERN_SILVER_BLOCK_4] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLOCK_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1120, -1577), "RC_ICE_CAVERN_SILVER_BLOCK_4", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLOCK_4)); + locationTable[RC_ICE_CAVERN_SILVER_BLOCK_5] = Location::Collectable(RC_ICE_CAVERN_SILVER_BLOCK_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1040, -485), "RC_ICE_CAVERN_SILVER_BLOCK_5", RHT_ICE_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SILVER_BLOCK_5)); + locationTable[RC_GTG_SILVER_SLOPE_1] = Location::Collectable(RC_GTG_SILVER_SLOPE_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1332, -992), "RC_GTG_SILVER_SLOPE_1", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_SLOPE_1)); + locationTable[RC_GTG_SILVER_SLOPE_2] = Location::Collectable(RC_GTG_SILVER_SLOPE_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1886, -956), "RC_GTG_SILVER_SLOPE_2", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_SLOPE_2)); + locationTable[RC_GTG_SILVER_SLOPE_3] = Location::Collectable(RC_GTG_SILVER_SLOPE_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1579, -999), "RC_GTG_SILVER_SLOPE_3", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_SLOPE_3)); + locationTable[RC_GTG_SILVER_SLOPE_4] = Location::Collectable(RC_GTG_SILVER_SLOPE_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1627, -1462), "RC_GTG_SILVER_SLOPE_4", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_SLOPE_4)); + locationTable[RC_GTG_SILVER_SLOPE_5] = Location::Collectable(RC_GTG_SILVER_SLOPE_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1887, -2134), "RC_GTG_SILVER_SLOPE_5", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_SLOPE_5)); + locationTable[RC_GTG_SILVER_LAVA_1] = Location::Collectable(RC_GTG_SILVER_LAVA_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1320, -1248), "RC_GTG_SILVER_LAVA_1", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_LAVA_1)); + locationTable[RC_GTG_SILVER_LAVA_2] = Location::Collectable(RC_GTG_SILVER_LAVA_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1558, -1370), "RC_GTG_SILVER_LAVA_2", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_LAVA_2)); + locationTable[RC_GTG_SILVER_LAVA_3] = Location::Collectable(RC_GTG_SILVER_LAVA_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1134, -1841), "RC_GTG_SILVER_LAVA_3", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_LAVA_3)); + locationTable[RC_GTG_SILVER_LAVA_4] = Location::Collectable(RC_GTG_SILVER_LAVA_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1437, -2193), "RC_GTG_SILVER_LAVA_4", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_LAVA_4)); + locationTable[RC_GTG_SILVER_LAVA_5] = Location::Collectable(RC_GTG_SILVER_LAVA_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1560, -1861), "RC_GTG_SILVER_LAVA_5", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_LAVA_5)); + locationTable[RC_GTG_SILVER_WATER_1] = Location::Collectable(RC_GTG_SILVER_WATER_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(2308, -1464), "RC_GTG_SILVER_WATER_1", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_WATER_1)); + locationTable[RC_GTG_SILVER_WATER_2] = Location::Collectable(RC_GTG_SILVER_WATER_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(2497, -1465), "RC_GTG_SILVER_WATER_2", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_WATER_2)); + locationTable[RC_GTG_SILVER_WATER_3] = Location::Collectable(RC_GTG_SILVER_WATER_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(2453, -1612), "RC_GTG_SILVER_WATER_3", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_WATER_3)); + locationTable[RC_GTG_SILVER_WATER_4] = Location::Collectable(RC_GTG_SILVER_WATER_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(2078, -1458), "RC_GTG_SILVER_WATER_4", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_WATER_4)); + locationTable[RC_GTG_SILVER_WATER_5] = Location::Collectable(RC_GTG_SILVER_WATER_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(2160, -1315), "RC_GTG_SILVER_WATER_5", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_SILVER_WATER_5)); + locationTable[RC_GANONS_CASTLE_SILVER_LIGHT_1] = Location::Collectable(RC_GANONS_CASTLE_SILVER_LIGHT_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2509, -1091), "RC_GANONS_CASTLE_SILVER_LIGHT_1", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_1)); + locationTable[RC_GANONS_CASTLE_SILVER_LIGHT_2] = Location::Collectable(RC_GANONS_CASTLE_SILVER_LIGHT_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2649, -545), "RC_GANONS_CASTLE_SILVER_LIGHT_2", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_2)); + locationTable[RC_GANONS_CASTLE_SILVER_LIGHT_3] = Location::Collectable(RC_GANONS_CASTLE_SILVER_LIGHT_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2646, -839), "RC_GANONS_CASTLE_SILVER_LIGHT_3", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_3)); + locationTable[RC_GANONS_CASTLE_SILVER_LIGHT_4] = Location::Collectable(RC_GANONS_CASTLE_SILVER_LIGHT_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2680, -893), "RC_GANONS_CASTLE_SILVER_LIGHT_4", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_4)); + locationTable[RC_GANONS_CASTLE_SILVER_LIGHT_5] = Location::Collectable(RC_GANONS_CASTLE_SILVER_LIGHT_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2674, -777), "RC_GANONS_CASTLE_SILVER_LIGHT_5", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_5)); + locationTable[RC_GANONS_CASTLE_SILVER_FOREST_1] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FOREST_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1247, 1787), "RC_GANONS_CASTLE_SILVER_FOREST_1", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FOREST_1)); + locationTable[RC_GANONS_CASTLE_SILVER_FOREST_2] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FOREST_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1361, 1222), "RC_GANONS_CASTLE_SILVER_FOREST_2", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FOREST_2)); + locationTable[RC_GANONS_CASTLE_SILVER_FOREST_3] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FOREST_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1538, 2225), "RC_GANONS_CASTLE_SILVER_FOREST_3", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FOREST_3)); + locationTable[RC_GANONS_CASTLE_SILVER_FOREST_4] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FOREST_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1651, 2021), "RC_GANONS_CASTLE_SILVER_FOREST_4", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FOREST_4)); + locationTable[RC_GANONS_CASTLE_SILVER_FOREST_5] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FOREST_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1634, 1550), "RC_GANONS_CASTLE_SILVER_FOREST_5", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FOREST_5)); + locationTable[RC_GANONS_CASTLE_SILVER_FIRE_1] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FIRE_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-854, -3679), "RC_GANONS_CASTLE_SILVER_FIRE_1", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FIRE_1)); + locationTable[RC_GANONS_CASTLE_SILVER_FIRE_2] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FIRE_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1555, -2317), "RC_GANONS_CASTLE_SILVER_FIRE_2", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FIRE_2)); + locationTable[RC_GANONS_CASTLE_SILVER_FIRE_3] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FIRE_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-515, -3253), "RC_GANONS_CASTLE_SILVER_FIRE_3", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FIRE_3)); + locationTable[RC_GANONS_CASTLE_SILVER_FIRE_4] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FIRE_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-604, -2592), "RC_GANONS_CASTLE_SILVER_FIRE_4", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FIRE_4)); + locationTable[RC_GANONS_CASTLE_SILVER_FIRE_5] = Location::Collectable(RC_GANONS_CASTLE_SILVER_FIRE_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1867, -2754), "RC_GANONS_CASTLE_SILVER_FIRE_5", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_FIRE_5)); + locationTable[RC_GANONS_CASTLE_SILVER_SPIRIT_1] = Location::Collectable(RC_GANONS_CASTLE_SILVER_SPIRIT_1, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-829, 591), "RC_GANONS_CASTLE_SILVER_SPIRIT_1", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_1)); + locationTable[RC_GANONS_CASTLE_SILVER_SPIRIT_2] = Location::Collectable(RC_GANONS_CASTLE_SILVER_SPIRIT_2, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-940, 270), "RC_GANONS_CASTLE_SILVER_SPIRIT_2", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_2)); + locationTable[RC_GANONS_CASTLE_SILVER_SPIRIT_3] = Location::Collectable(RC_GANONS_CASTLE_SILVER_SPIRIT_3, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-865, 656), "RC_GANONS_CASTLE_SILVER_SPIRIT_3", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_3)); + locationTable[RC_GANONS_CASTLE_SILVER_SPIRIT_4] = Location::Collectable(RC_GANONS_CASTLE_SILVER_SPIRIT_4, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-725, 942), "RC_GANONS_CASTLE_SILVER_SPIRIT_4", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_4)); + locationTable[RC_GANONS_CASTLE_SILVER_SPIRIT_5] = Location::Collectable(RC_GANONS_CASTLE_SILVER_SPIRIT_5, RCQUEST_VANILLA, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1142, 639), "RC_GANONS_CASTLE_SILVER_SPIRIT_5", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_5)); + locationTable[RC_DODONGOS_CAVERN_MQ_SILVER_1] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_SILVER_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-2277, -1362), "RC_DODONGOS_CAVERN_MQ_SILVER_1", RHT_DODONGOS_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_SILVER_2] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_SILVER_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-2189, -1834), "RC_DODONGOS_CAVERN_MQ_SILVER_2", RHT_DODONGOS_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_SILVER_3] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_SILVER_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-2411, -1836), "RC_DODONGOS_CAVERN_MQ_SILVER_3", RHT_DODONGOS_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_3)); + locationTable[RC_DODONGOS_CAVERN_MQ_SILVER_4] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_SILVER_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-1907, -1243), "RC_DODONGOS_CAVERN_MQ_SILVER_4", RHT_DODONGOS_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_4)); + locationTable[RC_DODONGOS_CAVERN_MQ_SILVER_5] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_SILVER_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-1512, -1083), "RC_DODONGOS_CAVERN_MQ_SILVER_5", RHT_DODONGOS_CAVERN_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_5)); + locationTable[RC_SHADOW_MQ_SILVER_BLADES_1] = Location::Collectable(RC_SHADOW_MQ_SILVER_BLADES_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2810, -961 ), "RC_SHADOW_MQ_SILVER_BLADES_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_BLADES_1)); + locationTable[RC_SHADOW_MQ_SILVER_BLADES_2] = Location::Collectable(RC_SHADOW_MQ_SILVER_BLADES_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3007, -1222), "RC_SHADOW_MQ_SILVER_BLADES_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_BLADES_2)); + locationTable[RC_SHADOW_MQ_SILVER_BLADES_3] = Location::Collectable(RC_SHADOW_MQ_SILVER_BLADES_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3243, -1061), "RC_SHADOW_MQ_SILVER_BLADES_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_BLADES_3)); + locationTable[RC_SHADOW_MQ_SILVER_BLADES_4] = Location::Collectable(RC_SHADOW_MQ_SILVER_BLADES_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3399, -838 ), "RC_SHADOW_MQ_SILVER_BLADES_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_BLADES_4)); + locationTable[RC_SHADOW_MQ_SILVER_BLADES_5] = Location::Collectable(RC_SHADOW_MQ_SILVER_BLADES_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3558, -1490), "RC_SHADOW_MQ_SILVER_BLADES_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_BLADES_5)); + locationTable[RC_SHADOW_MQ_SILVER_PIT_1] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(1970, 3372), "RC_SHADOW_MQ_SILVER_PIT_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_1)); + locationTable[RC_SHADOW_MQ_SILVER_PIT_2] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2110, 3372), "RC_SHADOW_MQ_SILVER_PIT_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_2)); + locationTable[RC_SHADOW_MQ_SILVER_PIT_3] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2110, 3372), "RC_SHADOW_MQ_SILVER_PIT_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_3)); + locationTable[RC_SHADOW_MQ_SILVER_PIT_4] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2131, 3030), "RC_SHADOW_MQ_SILVER_PIT_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_4)); + locationTable[RC_SHADOW_MQ_SILVER_PIT_5] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2250, 3372), "RC_SHADOW_MQ_SILVER_PIT_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_5)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5089, 2049), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5158, 2315), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5217, 1852), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5270, 2453), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5404, 1977), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5466, 2243), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5489, 2476), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5601, 1898), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5637, 2134), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9)); + locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5667, 2686), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_1] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2042, 849), "RC_SHADOW_MQ_SILVER_SPIKES_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_1)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_2] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2135, 1297), "RC_SHADOW_MQ_SILVER_SPIKES_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_2)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_3] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2254, 988), "RC_SHADOW_MQ_SILVER_SPIKES_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_3)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_4] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2478, 893), "RC_SHADOW_MQ_SILVER_SPIKES_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_4)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_5] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2478, 1208), "RC_SHADOW_MQ_SILVER_SPIKES_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_5)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_6] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_6, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2478, 1200), "RC_SHADOW_MQ_SILVER_SPIKES_6", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_6)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_7] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_7, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2478, 1404), "RC_SHADOW_MQ_SILVER_SPIKES_7", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_7)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_8] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_8, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2705, 1089), "RC_SHADOW_MQ_SILVER_SPIKES_8", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_8)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_9] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_9, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2730, 876), "RC_SHADOW_MQ_SILVER_SPIKES_9", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_9)); + locationTable[RC_SHADOW_MQ_SILVER_SPIKES_10] = Location::Collectable(RC_SHADOW_MQ_SILVER_SPIKES_10, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2940, 1069), "RC_SHADOW_MQ_SILVER_SPIKES_10", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_SPIKES_10)); + locationTable[RC_SPIRIT_MQ_SILVER_LOBBY_1] = Location::Collectable(RC_SPIRIT_MQ_SILVER_LOBBY_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1016, -73), "RC_SPIRIT_MQ_SILVER_LOBBY_1", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_1)); + locationTable[RC_SPIRIT_MQ_SILVER_LOBBY_2] = Location::Collectable(RC_SPIRIT_MQ_SILVER_LOBBY_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(160, 268), "RC_SPIRIT_MQ_SILVER_LOBBY_2", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_2)); + locationTable[RC_SPIRIT_MQ_SILVER_LOBBY_3] = Location::Collectable(RC_SPIRIT_MQ_SILVER_LOBBY_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-160, 270), "RC_SPIRIT_MQ_SILVER_LOBBY_3", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_3)); + locationTable[RC_SPIRIT_MQ_SILVER_LOBBY_4] = Location::Collectable(RC_SPIRIT_MQ_SILVER_LOBBY_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(967, -547), "RC_SPIRIT_MQ_SILVER_LOBBY_4", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_4)); + locationTable[RC_SPIRIT_MQ_SILVER_LOBBY_5] = Location::Collectable(RC_SPIRIT_MQ_SILVER_LOBBY_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(744, 4), "RC_SPIRIT_MQ_SILVER_LOBBY_5", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_5)); + locationTable[RC_SPIRIT_MQ_SILVER_BIG_WALL_1] = Location::Collectable(RC_SPIRIT_MQ_SILVER_BIG_WALL_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(723, -75), "RC_SPIRIT_MQ_SILVER_BIG_WALL_1", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_1)); + locationTable[RC_SPIRIT_MQ_SILVER_BIG_WALL_2] = Location::Collectable(RC_SPIRIT_MQ_SILVER_BIG_WALL_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(582, -75), "RC_SPIRIT_MQ_SILVER_BIG_WALL_2", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_2)); + locationTable[RC_SPIRIT_MQ_SILVER_BIG_WALL_3] = Location::Collectable(RC_SPIRIT_MQ_SILVER_BIG_WALL_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(754, -75), "RC_SPIRIT_MQ_SILVER_BIG_WALL_3", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_3)); + locationTable[RC_SPIRIT_MQ_SILVER_BIG_WALL_4] = Location::Collectable(RC_SPIRIT_MQ_SILVER_BIG_WALL_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(644, -75), "RC_SPIRIT_MQ_SILVER_BIG_WALL_4", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_4)); + locationTable[RC_SPIRIT_MQ_SILVER_BIG_WALL_5] = Location::Collectable(RC_SPIRIT_MQ_SILVER_BIG_WALL_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(681, -75), "RC_SPIRIT_MQ_SILVER_BIG_WALL_5", RHT_SPIRIT_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_5)); + locationTable[RC_GTG_MQ_SILVER_SLOPE_1] = Location::Collectable(RC_GTG_MQ_SILVER_SLOPE_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1245, -2112), "RC_GTG_MQ_SILVER_SLOPE_1", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_SLOPE_1)); + locationTable[RC_GTG_MQ_SILVER_SLOPE_2] = Location::Collectable(RC_GTG_MQ_SILVER_SLOPE_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1542, -1467), "RC_GTG_MQ_SILVER_SLOPE_2", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_SLOPE_2)); + locationTable[RC_GTG_MQ_SILVER_SLOPE_3] = Location::Collectable(RC_GTG_MQ_SILVER_SLOPE_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1480, -1000), "RC_GTG_MQ_SILVER_SLOPE_3", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_SLOPE_3)); + locationTable[RC_GTG_MQ_SILVER_SLOPE_4] = Location::Collectable(RC_GTG_MQ_SILVER_SLOPE_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1886, -956), "RC_GTG_MQ_SILVER_SLOPE_4", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_SLOPE_4)); + locationTable[RC_GTG_MQ_SILVER_SLOPE_5] = Location::Collectable(RC_GTG_MQ_SILVER_SLOPE_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-1261, -923), "RC_GTG_MQ_SILVER_SLOPE_5", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_SLOPE_5)); + locationTable[RC_GTG_MQ_SILVER_LAVA_1] = Location::Collectable(RC_GTG_MQ_SILVER_LAVA_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1560, -1861), "RC_GTG_MQ_SILVER_LAVA_1", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_LAVA_1)); + locationTable[RC_GTG_MQ_SILVER_LAVA_2] = Location::Collectable(RC_GTG_MQ_SILVER_LAVA_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1134, -1841), "RC_GTG_MQ_SILVER_LAVA_2", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_LAVA_2)); + locationTable[RC_GTG_MQ_SILVER_LAVA_3] = Location::Collectable(RC_GTG_MQ_SILVER_LAVA_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1404, -1653), "RC_GTG_MQ_SILVER_LAVA_3", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_LAVA_3)); + locationTable[RC_GTG_MQ_SILVER_LAVA_4] = Location::Collectable(RC_GTG_MQ_SILVER_LAVA_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1560, -1380), "RC_GTG_MQ_SILVER_LAVA_4", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_LAVA_4)); + locationTable[RC_GTG_MQ_SILVER_LAVA_5] = Location::Collectable(RC_GTG_MQ_SILVER_LAVA_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1083, -1374), "RC_GTG_MQ_SILVER_LAVA_5", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_LAVA_5)); + locationTable[RC_GTG_MQ_SILVER_LAVA_6] = Location::Collectable(RC_GTG_MQ_SILVER_LAVA_6, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1317, -1243), "RC_GTG_MQ_SILVER_LAVA_6", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_LAVA_6)); + locationTable[RC_GTG_MQ_SILVER_WATER_1] = Location::Collectable(RC_GTG_MQ_SILVER_WATER_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(2453, -1612), "RC_GTG_MQ_SILVER_WATER_1", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_WATER_1)); + locationTable[RC_GTG_MQ_SILVER_WATER_2] = Location::Collectable(RC_GTG_MQ_SILVER_WATER_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(2302, -1464), "RC_GTG_MQ_SILVER_WATER_2", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_WATER_2)); + locationTable[RC_GTG_MQ_SILVER_WATER_3] = Location::Collectable(RC_GTG_MQ_SILVER_WATER_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(2160, -1315), "RC_GTG_MQ_SILVER_WATER_3", RHT_GTG_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GTG_MQ_SILVER_WATER_3)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_FIRE_1] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_FIRE_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-970, -3747), "RC_GANONS_CASTLE_MQ_SILVER_FIRE_1", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_1)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_FIRE_2] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_FIRE_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1891, -2753), "RC_GANONS_CASTLE_MQ_SILVER_FIRE_2", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_2)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_FIRE_3] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_FIRE_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2044, -3354), "RC_GANONS_CASTLE_MQ_SILVER_FIRE_3", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_3)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_FIRE_4] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_FIRE_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-686, -2945), "RC_GANONS_CASTLE_MQ_SILVER_FIRE_4", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_4)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_FIRE_5] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_FIRE_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1655, -2133), "RC_GANONS_CASTLE_MQ_SILVER_FIRE_5", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_5)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_WATER_1] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_WATER_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2757, -765), "RC_GANONS_CASTLE_MQ_SILVER_WATER_1", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_1)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_WATER_2] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_WATER_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2912, -971), "RC_GANONS_CASTLE_MQ_SILVER_WATER_2", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_2)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_WATER_3] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_WATER_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2905, -1478), "RC_GANONS_CASTLE_MQ_SILVER_WATER_3", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_3)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_WATER_4] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_WATER_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3253, -649), "RC_GANONS_CASTLE_MQ_SILVER_WATER_4", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_4)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_WATER_5] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_WATER_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2905, -1263), "RC_GANONS_CASTLE_MQ_SILVER_WATER_5", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_5)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_SHADOW_1] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1322, -2262), "RC_GANONS_CASTLE_MQ_SILVER_SHADOW_1", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_1)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_SHADOW_2] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1279, -3111), "RC_GANONS_CASTLE_MQ_SILVER_SHADOW_2", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_2)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_SHADOW_3] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1529, -4117), "RC_GANONS_CASTLE_MQ_SILVER_SHADOW_3", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_3)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_SHADOW_4] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1829, -4071), "RC_GANONS_CASTLE_MQ_SILVER_SHADOW_4", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_4)); + locationTable[RC_GANONS_CASTLE_MQ_SILVER_SHADOW_5] = Location::Collectable(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1100, -2554), "RC_GANONS_CASTLE_MQ_SILVER_SHADOW_5", RHT_GANONS_CASTLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_5)); + // clang-format on +} + +static RegisterShipInitFunc registerShuffleSilver(RegisterShuffleSilver, { "IS_RANDO" }); +static RegisterShipInitFunc registerShuffleSilverLocations(Rando::StaticData::RegisterSilverLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/Traps.cpp b/soh/soh/Enhancements/randomizer/Traps.cpp index d6334ba3a7f..f2e5a767f7d 100644 --- a/soh/soh/Enhancements/randomizer/Traps.cpp +++ b/soh/soh/Enhancements/randomizer/Traps.cpp @@ -1224,6 +1224,122 @@ static void InitTrickNames() { Text{ "Squid-Hunt Key", "Squid-Hunt Key", "Squid-Hunt Key" }, }; + trickNameTable[RG_SHADOW_SILVER_BLADES] = { + // TODO_TRANSLATE + Text{ "Shadow Silver: Bladders" }, + }; + trickNameTable[RG_SHADOW_SILVER_PIT] = { + // TODO_TRANSLATE + Text{ "Shadow Silver: Bit" }, + }; + trickNameTable[RG_SHADOW_SILVER_SPIKES] = { + // TODO_TRANSLATE + Text{ "Shadow Silver: Spines" }, + }; + trickNameTable[RG_SPIRIT_SILVER_CHILD] = { + // TODO_TRANSLATE + Text{ "Spirit Silver: Chill" }, + }; + trickNameTable[RG_SPIRIT_SILVER_SUN] = { + // TODO_TRANSLATE + Text{ "Spirit Silver: Son" }, + }; + trickNameTable[RG_SPIRIT_SILVER_BOULDERS] = { + // TODO_TRANSLATE + Text{ "Spirit Silver: Bounders" }, + }; + trickNameTable[RG_BOTW_SILVER] = { + // TODO_TRANSLATE + Text{ "Bottom of the Well Slipper" }, + }; + trickNameTable[RG_ICE_CAVERN_SILVER_BLADES] = { + // TODO_TRANSLATE + Text{ "Ice Cavern Silver: Blaze" }, + }; + trickNameTable[RG_ICE_CAVERN_SILVER_BLOCK] = { + // TODO_TRANSLATE + Text{ "Ice Cavern Silver: Black" }, + }; + trickNameTable[RG_GTG_SILVER_SLOPE] = { + // TODO_TRANSLATE + Text{ "Training Ground Silver: Snope" }, + }; + trickNameTable[RG_GTG_SILVER_LAVA] = { + // TODO_TRANSLATE + Text{ "Traning Ground Silver: Love" }, + }; + trickNameTable[RG_GTG_SILVER_WATER] = { + // TODO_TRANSLATE + Text{ "Training Pound Silver: Water" }, + }; + trickNameTable[RG_GANONS_CASTLE_SILVER_LIGHT] = { + // TODO_TRANSLATE + Text{ "Ganon's Castle Silver: Lighter" }, + }; + trickNameTable[RG_GANONS_CASTLE_SILVER_FOREST] = { + // TODO_TRANSLATE + Text{ "Ganon's Castle Silver: Frost" }, + }; + trickNameTable[RG_GANONS_CASTLE_SILVER_FIRE] = { + // TODO_TRANSLATE + Text{ "Ganon's Castle Silver: Free" }, + }; + trickNameTable[RG_GANONS_CASTLE_SILVER_SPIRIT] = { + // TODO_TRANSLATE + Text{ "Ganon's Castle Silver: Sprite" }, + }; + trickNameTable[RG_DODONGOS_CAVERN_MQ_SILVER] = { + // TODO_TRANSLATE + Text{ "Dodongo's Cave Silver" }, + }; + trickNameTable[RG_SHADOW_MQ_SILVER_BLADES] = { + // TODO_TRANSLATE + Text{ "Shadow Silver: Blank" }, + }; + trickNameTable[RG_SHADOW_MQ_SILVER_PIT] = { + // TODO_TRANSLATE + Text{ "Shadow Silver: Pitch" }, + }; + trickNameTable[RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES] = { + // TODO_TRANSLATE + Text{ "Shadow Silver: Invisible" }, + }; + trickNameTable[RG_SHADOW_MQ_SILVER_SPIKES] = { + // TODO_TRANSLATE + Text{ "Shadow Silver: Spire" }, + }; + trickNameTable[RG_SPIRIT_MQ_SILVER_LOBBY] = { + // TODO_TRANSLATE + Text{ "Spirit Silver: Foyer" }, + }; + trickNameTable[RG_SPIRIT_MQ_SILVER_BIG_WALL] = { + // TODO_TRANSLATE + Text{ "Spirit Silver: Brick" }, + }; + trickNameTable[RG_GTG_MQ_SILVER_SLOPE] = { + // TODO_TRANSLATE + Text{ "Training Ground Silver: Sleep" }, + }; + trickNameTable[RG_GTG_MQ_SILVER_LAVA] = { + // TODO_TRANSLATE + Text{ "Traning Ground Silver: Lake" }, + }; + trickNameTable[RG_GTG_MQ_SILVER_WATER] = { + // TODO_TRANSLATE + Text{ "Training Ground Silver: Waver" }, + }; + trickNameTable[RG_GANONS_CASTLE_MQ_SILVER_FIRE] = { + // TODO_TRANSLATE + Text{ "Ganon's Castle Silver: Firm" }, + }; + trickNameTable[RG_GANONS_CASTLE_MQ_SILVER_WATER] = { + // TODO_TRANSLATE + Text{ "Ganon's Castle Silver: Wheat" }, + }; + trickNameTable[RG_GANONS_CASTLE_MQ_SILVER_SHADOW] = { + // TODO_TRANSLATE + Text{ "Ganon's Castle Silver: Shabom" }, + }; /* //Names for individual upgrades, in case progressive names are replaced trickNameTable[GI_HOOKSHOT] = { @@ -1444,6 +1560,8 @@ RandomizerGet Rando::Traps::GetTrapTrickModel() { trickModel = ShipUtils::RandomElement(Rando::StaticData::overworldKeys); } else if (trickModel == RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) { trickModel = ShipUtils::RandomElement(Rando::StaticData::beanSouls); + } else if (trickModel == RG_SHADOW_SILVER_BLADES) { + trickModel = ShipUtils::RandomElement(Rando::StaticData::silverRupees); } return trickModel; diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index db5f2294bf1..59bdd6e214c 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -20,6 +20,7 @@ extern "C" { #include "objects/object_gi_compass/object_gi_compass.h" #include "objects/object_gi_map/object_gi_map.h" #include "objects/object_gi_hearts/object_gi_hearts.h" +#include "objects/object_gi_rupy/object_gi_rupy.h" #include "objects/object_gi_scale/object_gi_scale.h" #include "objects/object_gi_fire/object_gi_fire.h" #include "objects/object_fish/object_fish.h" @@ -38,6 +39,7 @@ extern "C" { #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" #include "objects/object_gi_shield_1/object_gi_shield_1.h" +#include "objects/object_mo/object_mo.h" extern PlayState* gPlayState; extern SaveContext gSaveContext; } @@ -1280,6 +1282,27 @@ extern "C" void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemE CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawSilverRupee(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 255 / 5, 255 / 5, 255 / 5, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiRupeeInnerDL); + + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255 * 0.75f, 255 * 0.75f, 255 * 0.75f, 255); + gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiRupeeOuterDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry) { Vec3f pos; OPEN_DISPS(play->state.gfxCtx); diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index d674f562fac..87726a91cb4 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -27,6 +27,7 @@ void Randomizer_DrawLadder(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawJabberNut(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawSilverRupee(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getItemEntry); diff --git a/soh/soh/Enhancements/randomizer/item.cpp b/soh/soh/Enhancements/randomizer/item.cpp index 3ab5080d0f6..1a909a5ee81 100644 --- a/soh/soh/Enhancements/randomizer/item.cpp +++ b/soh/soh/Enhancements/randomizer/item.cpp @@ -451,8 +451,10 @@ bool Item::IsMajorItem() const { return false; } - if (type == ITEMTYPE_SMALLKEY && (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA) || - ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON))) { + if (type == ITEMTYPE_SMALLKEY && + !(randomizerGet >= RG_SHADOW_SILVER_BLADES && randomizerGet <= RG_SHADOW_SILVER_BLADES) && + (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA) || + ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON))) { return false; } diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 339ff6135f9..b754213a7bf 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -241,6 +241,65 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_GANONS_CASTLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_TREASURE_GAME_KEY_RING] = Item(RG_TREASURE_GAME_KEY_RING, Text{ "Chest Game Key Ring", "Trousseau du jeu la Chasse-aux-Trésors", "Schlüsselbund für das Truhenspiel" }, ITEMTYPE_SMALLKEY, 0xDE, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_KEY_RING, RG_TREASURE_GAME_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER, {"the ", "le ", "den "}); itemTable[RG_TREASURE_GAME_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); + // Silver Rupees + itemTable[RG_SHADOW_SILVER_BLADES] = Item(RG_SHADOW_SILVER_BLADES, Text{ "Shadow Silver: Blades" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SHADOW_SILVER_BLADES].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SHADOW_SILVER_PIT] = Item(RG_SHADOW_SILVER_PIT, Text{ "Shadow Silver: Pit" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SHADOW_SILVER_PIT].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SHADOW_SILVER_SPIKES] = Item(RG_SHADOW_SILVER_SPIKES, Text{ "Shadow Silver: Spikes" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SHADOW_SILVER_SPIKES].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SPIRIT_SILVER_CHILD] = Item(RG_SPIRIT_SILVER_CHILD, Text{ "Spirit Silver: Child" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SPIRIT_SILVER_CHILD].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SPIRIT_SILVER_SUN] = Item(RG_SPIRIT_SILVER_SUN, Text{ "Spirit Silver: Sun" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SPIRIT_SILVER_SUN].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SPIRIT_SILVER_BOULDERS] = Item(RG_SPIRIT_SILVER_BOULDERS, Text{ "Spirit Silver: Boulders" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SPIRIT_SILVER_BOULDERS].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_BOTW_SILVER] = Item(RG_BOTW_SILVER, Text{ "Bottom of the Well Silver" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_BOTW_SILVER].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_ICE_CAVERN_SILVER_BLADES] = Item(RG_ICE_CAVERN_SILVER_BLADES, Text{ "Ice Cavern Silver: Blades" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_ICE_CAVERN_SILVER_BLADES].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_ICE_CAVERN_SILVER_BLOCK] = Item(RG_ICE_CAVERN_SILVER_BLOCK, Text{ "Ice Cavern Silver: Block" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_ICE_CAVERN_SILVER_BLOCK].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GTG_SILVER_SLOPE] = Item(RG_GTG_SILVER_SLOPE, Text{ "Training Ground Silver: Slope" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GTG_SILVER_SLOPE].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GTG_SILVER_LAVA] = Item(RG_GTG_SILVER_LAVA, Text{ "Training Ground Silver: Lava" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GTG_SILVER_LAVA].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GTG_SILVER_WATER] = Item(RG_GTG_SILVER_WATER, Text{ "Training Ground Silver: Water" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GTG_SILVER_WATER].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GANONS_CASTLE_SILVER_LIGHT] = Item(RG_GANONS_CASTLE_SILVER_LIGHT, Text{ "Ganon's Castle Silver: Light" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GANONS_CASTLE_SILVER_LIGHT].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GANONS_CASTLE_SILVER_FOREST] = Item(RG_GANONS_CASTLE_SILVER_FOREST, Text{ "Ganon's Castle Silver: Forest" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GANONS_CASTLE_SILVER_FOREST].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GANONS_CASTLE_SILVER_FIRE] = Item(RG_GANONS_CASTLE_SILVER_FIRE, Text{ "Ganon's Castle Silver: Fire" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GANONS_CASTLE_SILVER_FIRE].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GANONS_CASTLE_SILVER_SPIRIT] = Item(RG_GANONS_CASTLE_SILVER_SPIRIT, Text{ "Ganon's Castle Silver: Spirit" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GANONS_CASTLE_SILVER_SPIRIT].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_DODONGOS_CAVERN_MQ_SILVER] = Item(RG_DODONGOS_CAVERN_MQ_SILVER, Text{ "Dodongo's Cavern Silver" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_DODONGOS_CAVERN_MQ_SILVER].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SHADOW_MQ_SILVER_BLADES] = Item(RG_SHADOW_MQ_SILVER_BLADES, Text{ "Shadow Silver: Blades" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SHADOW_MQ_SILVER_BLADES].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SHADOW_MQ_SILVER_PIT] = Item(RG_SHADOW_MQ_SILVER_PIT, Text{ "Shadow Silver: Pit" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SHADOW_MQ_SILVER_PIT].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES] = Item(RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES, Text{ "Shadow Silver: Invisible Blades" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SHADOW_MQ_SILVER_SPIKES] = Item(RG_SHADOW_MQ_SILVER_SPIKES, Text{ "Shadow Silver: Spikes" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SHADOW_MQ_SILVER_SPIKES].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SPIRIT_MQ_SILVER_LOBBY] = Item(RG_SPIRIT_MQ_SILVER_LOBBY, Text{ "Spirit Silver: Lobby" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SPIRIT_MQ_SILVER_LOBBY].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_SPIRIT_MQ_SILVER_BIG_WALL] = Item(RG_SPIRIT_MQ_SILVER_BIG_WALL, Text{ "Spirit Silver: Big Wall" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_SPIRIT_MQ_SILVER_BIG_WALL].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GTG_MQ_SILVER_SLOPE] = Item(RG_GTG_MQ_SILVER_SLOPE, Text{ "Training Ground Silver: Slope" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GTG_MQ_SILVER_SLOPE].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GTG_MQ_SILVER_LAVA] = Item(RG_GTG_MQ_SILVER_LAVA, Text{ "Training Ground Silver: Lava" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GTG_MQ_SILVER_LAVA].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GTG_MQ_SILVER_WATER] = Item(RG_GTG_MQ_SILVER_WATER, Text{ "Training Ground Silver: Water" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GTG_MQ_SILVER_WATER].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GANONS_CASTLE_MQ_SILVER_FIRE] = Item(RG_GANONS_CASTLE_MQ_SILVER_FIRE, Text{ "Ganon's Castle Silver: Fire" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GANONS_CASTLE_MQ_SILVER_FIRE].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GANONS_CASTLE_MQ_SILVER_WATER] = Item(RG_GANONS_CASTLE_MQ_SILVER_WATER, Text{ "Ganon's Castle Silver: Water" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GANONS_CASTLE_MQ_SILVER_WATER].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_GANONS_CASTLE_MQ_SILVER_SHADOW] = Item(RG_GANONS_CASTLE_MQ_SILVER_SHADOW, Text{ "Ganon's Castle Silver: Shadow" }, ITEMTYPE_SMALLKEY, GI_RUPEE_GOLD, true, LOGIC_NONE, RHT_SILVER, RG_NONE, OBJECT_GI_RUPY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GANONS_CASTLE_MQ_SILVER_SHADOW].SetCustomDrawFunc(Randomizer_DrawSilverRupee); // Dungeon Rewards itemTable[RG_KOKIRI_EMERALD] = Item(RG_KOKIRI_EMERALD, Text{ "Kokiri's Emerald", "Émeraude Kokiri", "Kokiri-Smaragd" }, ITEMTYPE_DUNGEONREWARD, 0xCB, true, LOGIC_KOKIRI_EMERALD, RHT_KOKIRI_EMERALD, ITEM_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "l'", "den "}, "%g"); itemTable[RG_GORON_RUBY] = Item(RG_GORON_RUBY, Text{ "Goron's Ruby", "Rubis Goron", "Goronen-Rubin" }, ITEMTYPE_DUNGEONREWARD, 0xCC, true, LOGIC_GORON_RUBY, RHT_GORON_RUBY, ITEM_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "}, "%r"); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index a802598ea79..74ecbac27df 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -185,7 +185,9 @@ void RegionTable_Init_BottomOfTheWell() { ENTRANCE(RR_BOTW_NEAR_BOSS_UPPER, logic->CanKillEnemy(RE_DEAD_HAND)), }); - areaTable[RR_BOTW_B3_OOZE] = Region("Bottom of the Well B3 Ooze", SCENE_BOTTOM_OF_THE_WELL, {}, { + areaTable[RR_BOTW_B3_OOZE] = Region("Bottom of the Well B3 Ooze", SCENE_BOTTOM_OF_THE_WELL, { + EventAccess(LOGIC_BOTW_SILVER, []{return true;}), + }, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, logic->CanBreakPots()), @@ -210,9 +212,14 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTW_BOULDER_4, logic->BlastOrSmash()), LOCATION(RC_BOTW_BOULDER_5, logic->BlastOrSmash()), LOCATION(RC_BOTW_BOULDER_6, logic->BlastOrSmash()), + LOCATION(RC_BOTW_SILVER_1, true /*CanClimbHigh()*/), + LOCATION(RC_BOTW_SILVER_2, true /*CanClimb()*/), + LOCATION(RC_BOTW_SILVER_3, true), + LOCATION(RC_BOTW_SILVER_4, true), + LOCATION(RC_BOTW_SILVER_5, true), }, { //Exits - ENTRANCE(RR_BOTW_HIDDEN_POTS, logic->CanClimbHighLadder()), + ENTRANCE(RR_BOTW_HIDDEN_POTS, logic->HasItem(RG_BOTW_SILVER) && logic->CanClimbHighLadder()), //It's possible to abuse boulder's limited range of collision detection to detonate the flowers through the boulder with bow, but this is a glitch //the exact range is just past the furthest away plank in the green goo section ENTRANCE(RR_BOTW_B3_BOMB_FLOWERS, AnyAgeTime([]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BOTW_BASEMENT) && logic->CanUse(RG_STICKS)) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_FAIRY_BOW));})), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index 357a2f98684..9163906c213 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -354,6 +354,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_DODONGOS_CAVERN_MQ_SILVER_1, true), + LOCATION(RC_DODONGOS_CAVERN_MQ_SILVER_2, logic->CanBreakCrates()), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_LOBBY, true), @@ -376,7 +378,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER] = Region("Dodongos Cavern MQ Stairs Upper", SCENE_DODONGOS_CAVERN, { //Events - EVENT_ACCESS(LOGIC_DC_MQ_STAIRS_SILVER_RUPEES, logic->HasItem(RG_CLIMB)), + EVENT_ACCESS(LOGIC_DODONGOS_CAVERN_MQ_SILVER, (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_CLIMB)), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), @@ -384,17 +386,22 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, logic->CanBreakCrates()), LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, logic->CanBreakCrates()), LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, logic->CanBreakCrates()), + LOCATION(RC_DODONGOS_CAVERN_MQ_SILVER_3, logic->CanBreakCrates()), + LOCATION(RC_DODONGOS_CAVERN_MQ_SILVER_5, logic->CanBreakCrates()), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, true), ENTRANCE(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS, logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->CanUse(RG_HOVER_BOOTS)), }); - areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS] = Region("Dodongos Cavern MQ Past Big Skulltulas", SCENE_DODONGOS_CAVERN, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS] = Region("Dodongos Cavern MQ Past Big Skulltulas", SCENE_DODONGOS_CAVERN, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_SILVER_4, true /*CanClimb()*/), + }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->CanUse(RG_HOVER_BOOTS)), ENTRANCE(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, logic->TakeDamage()), - ENTRANCE(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, logic->Get(LOGIC_DC_MQ_STAIRS_SILVER_RUPEES)), + ENTRANCE(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, logic->HasItem(RG_DODONGOS_CAVERN_MQ_SILVER)), }); areaTable[RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM] = Region("Dodongos Cavern MQ Dodongo Room", SCENE_DODONGOS_CAVERN, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 3af0ffcad27..8979428902a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -72,8 +72,16 @@ void RegionTable_Init_GanonsCastle() { }); areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM] = Region("Ganon's Castle Forest Trial Beamos Room", SCENE_INSIDE_GANONS_CASTLE, { - EVENT_ACCESS(LOGIC_FOREST_TRIAL_SILVER_RUPEES, logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || (logic->IsChild && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), // child can get these by voiding after switch - }, {}, { + EVENT_ACCESS(LOGIC_GANONS_CASTLE_SILVER_FOREST, logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || (logic->IsChild && ctx->GetTrickOption(RT_VOIDOUT_COLLECTION))), // child can get these by voiding after switch + }, { + //Locations + //TODO figure it out + LOCATION(RC_GANONS_CASTLE_SILVER_FOREST_1, true), + LOCATION(RC_GANONS_CASTLE_SILVER_FOREST_2, true), + LOCATION(RC_GANONS_CASTLE_SILVER_FOREST_3, true), + LOCATION(RC_GANONS_CASTLE_SILVER_FOREST_4, true), + LOCATION(RC_GANONS_CASTLE_SILVER_FOREST_5, logic->Get(LOGIC_GANONS_CASTLE_SILVER_FOREST)), + }, { //Exits ENTRANCE(RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM, true), ENTRANCE(RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM_END, true), @@ -88,7 +96,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM_FINAL_DOOR] = Region("Ganon's Castle Forest Trial Beamos Room Final Door", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { //Exits ENTRANCE(RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM_END, true), - ENTRANCE(RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM, logic->Get(LOGIC_FOREST_TRIAL_SILVER_RUPEES)), + ENTRANCE(RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM, logic->HasItem(RG_GANONS_CASTLE_SILVER_FOREST)), }); areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Forest Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { @@ -110,10 +118,15 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_FIRE_TRIAL_FROM_OPEN] = Region("Ganon's Castle Fire Trial From Open Door", SCENE_INSIDE_GANONS_CASTLE, { // backwalking hoverboots with backflip reaches silver rupee without needing str3 - EVENT_ACCESS(LOGIC_FIRE_TRIAL_SILVER_RUPEES, logic->FireTimer() >= 48 && logic->CanUse(RG_GOLDEN_GAUNTLETS)), + EVENT_ACCESS(LOGIC_GANONS_CASTLE_SILVER_FIRE, logic->FireTimer() >= 48 && logic->CanUse(RG_GOLDEN_GAUNTLETS)), }, { //Locations LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_HEART, logic->FireTimer() >= 16), + LOCATION(RC_GANONS_CASTLE_SILVER_FIRE_1, logic->FireTimer() >= 24), + LOCATION(RC_GANONS_CASTLE_SILVER_FIRE_2, logic->FireTimer() >= 24), + LOCATION(RC_GANONS_CASTLE_SILVER_FIRE_3, logic->FireTimer() >= 40 && logic->CanUse(RG_GOLDEN_GAUNTLETS)), + LOCATION(RC_GANONS_CASTLE_SILVER_FIRE_4, logic->FireTimer() >= 8), + LOCATION(RC_GANONS_CASTLE_SILVER_FIRE_5, logic->FireTimer() >= 32 && logic->CanUse(RG_GOLDEN_GAUNTLETS)), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_FIRE_TRIAL_OPEN_DOOR, true), @@ -134,7 +147,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_FIRE_TRIAL_BARRED_DOOR] = Region("Ganon's Castle Fire Trial Barred Door", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { //Exits - ENTRANCE(RR_GANONS_CASTLE_FIRE_TRIAL_FINAL_ROOM, logic->Get(LOGIC_FIRE_TRIAL_SILVER_RUPEES)), + ENTRANCE(RR_GANONS_CASTLE_FIRE_TRIAL_FINAL_ROOM, logic->HasItem(RG_GANONS_CASTLE_SILVER_FIRE)), }); areaTable[RR_GANONS_CASTLE_FIRE_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Fire Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { @@ -298,14 +311,21 @@ void RegionTable_Init_GanonsCastle() { ENTRANCE(RR_GANONS_CASTLE_SHADOW_TRIAL_END, true), }); - areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM] = Region("Ganon's Castle Spirit Trial Beamos Room", SCENE_INSIDE_GANONS_CASTLE, {}, { + areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM] = Region("Ganon's Castle Spirit Trial Beamos Room", SCENE_INSIDE_GANONS_CASTLE, { + EVENT_ACCESS(LOGIC_GANONS_CASTLE_SILVER_SPIRIT, ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)), + }, { //Locations LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, true), + LOCATION(RC_GANONS_CASTLE_SILVER_SPIRIT_1, logic->HasItem(RG_GANONS_CASTLE_SILVER_SPIRIT)), + LOCATION(RC_GANONS_CASTLE_SILVER_SPIRIT_2, true), + LOCATION(RC_GANONS_CASTLE_SILVER_SPIRIT_3, true), + LOCATION(RC_GANONS_CASTLE_SILVER_SPIRIT_4, true), + LOCATION(RC_GANONS_CASTLE_SILVER_SPIRIT_5, true), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MAIN, true), - ENTRANCE(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH, ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)), + ENTRANCE(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH, logic->HasItem(RG_GANONS_CASTLE_SILVER_SPIRIT)), }); areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH] = Region("Ganon's Castle Spirit Trial Before Switch", SCENE_INSIDE_GANONS_CASTLE, {}, { @@ -364,13 +384,21 @@ void RegionTable_Init_GanonsCastle() { ENTRANCE(RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM, logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2)), }); - areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM] = Region("Ganon's Castle Light Trial Boulder Room", SCENE_INSIDE_GANONS_CASTLE, {}, { + areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM] = Region("Ganon's Castle Light Trial Boulder Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EVENT_ACCESS(LOGIC_GANONS_CASTLE_SILVER_LIGHT, logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump())), + }, { //Locations LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_SILVER_LIGHT_1, true), + LOCATION(RC_GANONS_CASTLE_SILVER_LIGHT_2, true), + LOCATION(RC_GANONS_CASTLE_SILVER_LIGHT_3, logic->HasItem(RG_GANONS_CASTLE_SILVER_LIGHT)), + LOCATION(RC_GANONS_CASTLE_SILVER_LIGHT_4, true), + LOCATION(RC_GANONS_CASTLE_SILVER_LIGHT_5, true), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_LIGHT_TRIAL_TRIFORCE_ROOM, logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2)), - ENTRANCE(RR_GANONS_CASTLE_LIGHT_TRIAL_FINAL_ROOM, logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump())), + ENTRANCE(RR_GANONS_CASTLE_LIGHT_TRIAL_FINAL_ROOM, logic->HasItem(RG_GANONS_CASTLE_SILVER_LIGHT)), }); areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Light Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { @@ -494,15 +522,17 @@ void RegionTable_Init_GanonsCastle() { ENTRANCE(RR_GANONS_CASTLE_MQ_FOREST_TRIAL_BEAMOS_ROOM_END, true), }); - areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_OPEN_DOOR] = Region("Ganon's Castle MQ Fire Trial Open Door", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { - //Exits - ENTRANCE(RR_GANONS_CASTLE_MQ_MAIN, true), - }); - areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FROM_OPEN] = Region("Ganon's Castle MQ Fire Trial From Open Door", SCENE_INSIDE_GANONS_CASTLE, { //Events - EVENT_ACCESS(LOGIC_FIRE_TRIAL_SILVER_RUPEES, logic->FireTimer() >= 72 && logic->CanUse(RG_GOLDEN_GAUNTLETS);), - }, {}, { + EVENT_ACCESS(LOGIC_GANONS_CASTLE_MQ_SILVER_FIRE, logic->FireTimer() >= 80 && logic->CanUse(RG_GOLDEN_GAUNTLETS);), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_FIRE_1, logic->FireTimer() >= 32), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_FIRE_2, logic->FireTimer() >= 40), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_FIRE_3, logic->FireTimer() >= 64), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_FIRE_4, logic->FireTimer() >= 16), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_FIRE_5, logic->FireTimer() >= 48), + }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_OPEN_DOOR, true), ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_BARRED_DOOR, logic->FireTimer() >= 32 && (logic->CanUse(RG_LONGSHOT) || @@ -516,7 +546,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_BARRED_DOOR] = Region("Ganon's Castle MQ Fire Trial Barred Door", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { //Exits - ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FINAL_ROOM, logic->Get(LOGIC_FIRE_TRIAL_SILVER_RUPEES)), + ENTRANCE(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FINAL_ROOM, logic->HasItem(RG_GANONS_CASTLE_MQ_SILVER_FIRE)), }); areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Fire Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { @@ -568,7 +598,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM] = Region("Ganon's Castle MQ Water Trial Block Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EVENT_ACCESS(LOGIC_WATER_TRIAL_MQ_SILVER_RUPEES, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->CanMiddairGroundJump()) && logic->BlueFire()), + EVENT_ACCESS(LOGIC_GANONS_CASTLE_MQ_SILVER_WATER, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->CanMiddairGroundJump()) && logic->BlueFire()), EVENT_ACCESS(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE, (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS)) || ((logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS)/* && logic->CanUse(RG_ROLL)*/)) && logic->HasItem(RG_POWER_BRACELET) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE))), }, { //Locations @@ -578,6 +608,12 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && logic->CanUse(RG_BOOMERANG)), LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && logic->CanUse(RG_BOOMERANG)), LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && logic->CanUse(RG_BOOMERANG)), + //TODO figure it out + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_WATER_1, true), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_WATER_2, true /*logic->IsAdult || str0*/), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_WATER_3, logic->IsAdult && logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_WATER_4, true), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_WATER_5, true), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM, logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 3)), @@ -595,7 +631,7 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE)), }, { ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE)), - ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_FINAL_ROOM, logic->Get(LOGIC_WATER_TRIAL_MQ_SILVER_RUPEES)), + ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_FINAL_ROOM, logic->HasItem(RG_GANONS_CASTLE_MQ_SILVER_WATER)), }); areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Water Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { @@ -613,6 +649,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE] = Region("Ganon's Castle MQ Shadow Trial Starting Ledge", SCENE_INSIDE_GANONS_CASTLE, { //Events EVENT_ACCESS(LOGIC_SHADOW_TRIAL_FIRST_CHEST, logic->CanUse(RG_FAIRY_BOW)), + EVENT_ACCESS(LOGIC_GANONS_CASTLE_MQ_SILVER_SHADOW, true), // TODO }, {}, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_MAIN, true), @@ -638,6 +675,8 @@ void RegionTable_Init_GanonsCastle() { }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL, (logic->CanDetonateBombFlowers() || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE))) && (logic->TakeDamage() || logic->CanUse(RG_NAYRUS_LOVE))), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_1, true), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_5, true), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM, logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)), @@ -645,7 +684,10 @@ void RegionTable_Init_GanonsCastle() { }); - areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_BEAMOS_TORCH] = Region("Ganon's Castle MQ Shadow Trial Beamos Torch", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { + areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_BEAMOS_TORCH] = Region("Ganon's Castle MQ Shadow Trial Beamos Torch", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_2, true), + }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_MOVING_PLATFORM, ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), //A torch run from RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE is possible but very tight, so would be a trick @@ -657,15 +699,17 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_FAR_SIDE] = Region("Ganon's Castle MQ Shadow Trial Far Side", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_3, ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_4, ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_BEAMOS_TORCH, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS)), //Modelling the silver rupees properly will require a way to check temp flags in different regions. //It may be tempting to use a Here-like command for this but it could cause sphere skipping in playthroughs //So a system like event access which sets based on TimeAge would be preferable, as the application of these can be tracked and accounted for, unlike Here-like commands - //For Now I am assuming the player has made it all the way from RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE, which logically means every rupee is available + //For now I am assuming the player has made it all the way from RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE, which logically means every rupee is available //with no extra requirements except the lens logic needed to reach the door, which also enables the beamos-platform rupee - ENTRANCE(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_FINAL_ROOM, (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + ENTRANCE(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_FINAL_ROOM, (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_GANONS_CASTLE_MQ_SILVER_SHADOW)), }); areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Shadow Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 1c154627344..6d46da5a601 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -38,9 +38,20 @@ void RegionTable_Init_GerudoTrainingGround() { ENTRANCE(RR_GERUDO_TRAINING_GROUND_BOULDER_ROOM, AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);})), }); - areaTable[RR_GERUDO_TRAINING_GROUND_BOULDER_ROOM] = Region("Gerudo Training Ground Boulder Room", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { + areaTable[RR_GERUDO_TRAINING_GROUND_BOULDER_ROOM] = Region("Gerudo Training Ground Boulder Room", SCENE_GERUDO_TRAINING_GROUND, { + //Events + EVENT_ACCESS(LOGIC_GTG_SILVER_SLOPE, logic->CanUse(logic->IsAdult ? RG_HOOKSHOT : RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_WITHOUT_HOOKSHOT)), + }, { + //Locations + LOCATION(RC_GTG_SILVER_SLOPE_1, true), + LOCATION(RC_GTG_SILVER_SLOPE_2, true), + LOCATION(RC_GTG_SILVER_SLOPE_3, logic->CanUse(logic->IsAdult ? RG_HOOKSHOT : RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_WITHOUT_HOOKSHOT)), + LOCATION(RC_GTG_SILVER_SLOPE_4, true), + LOCATION(RC_GTG_SILVER_SLOPE_5, true), + }, { + //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_SAND_ROOM, true), - ENTRANCE(RR_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_ROOM, AnyAgeTime([]{return logic->CanUse(logic->IsAdult ? RG_HOOKSHOT : RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_WITHOUT_HOOKSHOT);})), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_ROOM, logic->HasItem(RG_GTG_SILVER_SLOPE)), }); areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE] = Region("Gerudo Training Ground Central Maze", SCENE_GERUDO_TRAINING_GROUND, {}, { @@ -61,6 +72,7 @@ void RegionTable_Init_GerudoTrainingGround() { LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, true), + LOCATION(RC_GTG_SILVER_LAVA_5, true), }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, true), @@ -148,24 +160,42 @@ void RegionTable_Init_GerudoTrainingGround() { }); areaTable[RR_GERUDO_TRAINING_GROUND_LAVA_ROOM] = Region("Gerudo Training Ground Lava Room", SCENE_GERUDO_TRAINING_GROUND, { - EVENT_ACCESS(LOGIC_GTG_PLATFORM_SILVER_RUPEES, logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild)), - }, {}, { + EVENT_ACCESS(LOGIC_GTG_SILVER_LAVA, logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild)), + }, { + //Locations + LOCATION(RC_GTG_SILVER_LAVA_1, true), + LOCATION(RC_GTG_SILVER_LAVA_2, true), + LOCATION(RC_GTG_SILVER_LAVA_3, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME)), + LOCATION(RC_GTG_SILVER_LAVA_5, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME)), + }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_DINALFOS, true), ENTRANCE(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild), ENTRANCE(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM_UPPER_LEDGE, logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild || (logic->IsAdult && ctx->GetTrickOption(RT_GTG_LAVA_JUMP)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage())))), - ENTRANCE(RR_GERUDO_TRAINING_GROUND_UNDERWATER, logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES)), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_UNDERWATER, logic->HasItem(RG_GTG_SILVER_LAVA)), }); - areaTable[RR_GERUDO_TRAINING_GROUND_LAVA_ROOM_UPPER_LEDGE] = Region("Gerudo Training Ground Lava Room", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { + areaTable[RR_GERUDO_TRAINING_GROUND_LAVA_ROOM_UPPER_LEDGE] = Region("Gerudo Training Ground Lava Room", SCENE_GERUDO_TRAINING_GROUND, {}, { + LOCATION(RC_GTG_SILVER_LAVA_4, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_GTG_SILVER_LAVA_5, true), + }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild || (logic->IsAdult && ctx->GetTrickOption(RT_GTG_LAVA_JUMP)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage())), ENTRANCE(RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM, true), }); - areaTable[RR_GERUDO_TRAINING_GROUND_UNDERWATER] = Region("Gerudo Training Ground Underwater", SCENE_GERUDO_TRAINING_GROUND, {}, { + areaTable[RR_GERUDO_TRAINING_GROUND_UNDERWATER] = Region("Gerudo Training Ground Underwater", SCENE_GERUDO_TRAINING_GROUND, { + //Events + EventAccess(LOGIC_GTG_SILVER_WATER, []{return logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && logic->WaterTimer() >= 24;}), + }, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && logic->WaterTimer() >= 24 && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->Get(LOGIC_GTG_SILVER_WATER) && logic->HasItem(RG_OPEN_CHEST)), + // 3 & 5 can be retrieved with only iron boots by attempting to backflip underwater + LOCATION(RC_GTG_SILVER_WATER_1, logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_GTG_SILVER_WATER_2, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_GOLDEN_SCALE)), + LOCATION(RC_GTG_SILVER_WATER_3, logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_GTG_SILVER_WATER_4, logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT)) && logic->WaterTimer() >= 16), + LOCATION(RC_GTG_SILVER_WATER_5, logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, true), @@ -245,7 +275,10 @@ void RegionTable_Init_GerudoTrainingGround() { ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM, AnyAgeTime([]{return logic->CanKillEnemy(RE_IRON_KNUCKLE);})), }); - areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM] = Region("Gerudo Training Ground MQ Left Side", SCENE_GERUDO_TRAINING_GROUND, {}, { + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM] = Region("Gerudo Training Ground MQ Left Side", SCENE_GERUDO_TRAINING_GROUND, { + //Events + EventAccess(LOGIC_GTG_MQ_SILVER_SLOPE, []{return logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_MQ_WITHOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_HOOKSHOT));}) + }, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1, logic->CanClearStalagmite()), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_2, logic->CanClearStalagmite()), @@ -260,10 +293,15 @@ void RegionTable_Init_GerudoTrainingGround() { LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_1, true), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_2, true), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_TOP_RIGHT_STALACTITE_3, true), - }, { + LOCATION(RC_GTG_MQ_SILVER_SLOPE_1, true), + LOCATION(RC_GTG_MQ_SILVER_SLOPE_2, true), + LOCATION(RC_GTG_MQ_SILVER_SLOPE_3, logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_MQ_WITHOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_GTG_MQ_SILVER_SLOPE_4, true), + LOCATION(RC_GTG_MQ_SILVER_SLOPE_5, true), + }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM, true), - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, AnyAgeTime([]{return logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_MQ_WITHOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_HOOKSHOT));})), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, logic->HasItem(RG_GTG_MQ_SILVER_SLOPE)), }); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM] = Region("Gerudo Training Ground MQ Stalfos Room", SCENE_GERUDO_TRAINING_GROUND, { @@ -344,30 +382,31 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_SWITCH_LEDGE] = Region("Gerudo Training Ground MQ Switch Ledge", SCENE_GERUDO_TRAINING_GROUND, { //Events - EVENT_ACCESS(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH, logic->CanUse(RG_MEGATON_HAMMER)), - EVENT_ACCESS(LOGIC_GTG_PLATFORM_SILVER_RUPEES, logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS)), + EVENT_ACCESS(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH, logic->CanUse(RG_MEGATON_HAMMER)), + EVENT_ACCESS(LOGIC_GTG_MQ_SILVER_LAVA, logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS)), }, {}, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, logic->CanUse(RG_FIRE_ARROWS)), //the fire bubble here is a jerk if you are aiming for the nearest hook platform, you have to aim to the right hand side with hook to dodge it - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, logic->CanUse(RG_LONGSHOT) || (logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES) && logic->CanUse(RG_HOOKSHOT)) || ((logic->CanUse(RG_FIRE_ARROWS) && logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES)) && logic->CanUse(RG_HOVER_BOOTS))), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, logic->CanUse(RG_LONGSHOT) || (logic->HasItem(RG_GTG_MQ_SILVER_LAVA) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_FIRE_ARROWS) && logic->HasItem(RG_GTG_MQ_SILVER_LAVA) && logic->CanUse(RG_HOVER_BOOTS))), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, logic->Get(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH) && logic->CanUse(RG_LONGSHOT)), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SLUG_ROOM, true), }); - //this region exists to place silver rupee items on later, normally it's all on fire and cannot be stood on without access from another area - //This covers the 2 platforms that can be jumped to directly from RR_GERUDO_TRAINING_GROUND_MQ_SWITCH_LEDGE - //the unshuffled rupee collection is handled by the event GTGPlatformSilverRupees - areaTable[RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS] = Region("Gerudo Training Ground MQ Ledge Side Platforms", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { + //This covers the 2 platforms that can be jumped to directly from RR_GERUDO_TRAINING_GROUND_MQ_SWITCH_LEDGE, without flame circles + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS] = Region("Gerudo Training Ground MQ Ledge Side Platforms", SCENE_GERUDO_TRAINING_GROUND, {}, { + LOCATION(RC_GTG_MQ_SILVER_LAVA_1, true), + LOCATION(RC_GTG_MQ_SILVER_LAVA_3, true), + }, { //Exits //This is merely to extend this region's logic if you have hovers ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM, logic->CanUse(RG_HOVER_BOOTS)), }); - //this region exists to place silver rupee items on later, normally it's all on fire and cannot be stood on without access from another area - //This covers the platform that needs hover boots or the spawned targets to reach from any starting point other than RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT - //the unshuffled rupee collection is handled by the event GTGPlatformSilverRupees - areaTable[RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM] = Region("Gerudo Training Ground MQ Furthest Platform", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { + //This covers the platform that needs hover boots or the spawned targets to reach from any starting point other than RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, without flame circles + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM] = Region("Gerudo Training Ground MQ Furthest Platform", SCENE_GERUDO_TRAINING_GROUND, {}, { + LOCATION(RC_GTG_MQ_SILVER_LAVA_2, true), + }, { //Exits //This is merely to extend this region's logic if you have hovers ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, logic->CanUse(RG_HOVER_BOOTS)), @@ -375,10 +414,14 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH] = Region("Gerudo Training Ground MQ Platforms Unlit Torch", SCENE_GERUDO_TRAINING_GROUND, { //Events - EVENT_ACCESS(LOGIC_GTG_PLATFORM_SILVER_RUPEES, logic->HasFireSource() && logic->CanUse(RG_HOVER_BOOTS)), - }, {}, { + EVENT_ACCESS(LOGIC_GTG_MQ_SILVER_LAVA, logic->HasFireSource() && logic->CanUse(RG_HOVER_BOOTS)), + }, { + LOCATION(RC_GTG_MQ_SILVER_LAVA_4, logic->HasFireSource()), + LOCATION(RC_GTG_MQ_SILVER_LAVA_5, logic->HasFireSource()), + LOCATION(RC_GTG_MQ_SILVER_LAVA_6, logic->HasFireSource()), + }, { //Exits - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER, logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES)), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER, logic->HasItem(RG_GTG_MQ_SILVER_LAVA)), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, logic->HasFireSource() && logic->CanUse(RG_HOVER_BOOTS)), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS, logic->HasFireSource() || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER))), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, logic->Get(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH) && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->HasFireSource()))), @@ -387,8 +430,13 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS] = Region("Gerudo Training Ground Torch Side Platforms", SCENE_GERUDO_TRAINING_GROUND, { //Events //this torch shot is possible as child but tight and obtuse enough to be a trick - EVENT_ACCESS(LOGIC_GTG_PLATFORM_SILVER_RUPEES, ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)) && logic->CanUse(RG_HOVER_BOOTS)), - }, {}, { + EVENT_ACCESS(LOGIC_GTG_MQ_SILVER_LAVA, ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)) && logic->CanUse(RG_HOVER_BOOTS)), + }, { + //Locations + LOCATION(RC_GTG_MQ_SILVER_LAVA_4, (logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)), + LOCATION(RC_GTG_MQ_SILVER_LAVA_5, (logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)), + LOCATION(RC_GTG_MQ_SILVER_LAVA_6, (logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)), + }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_GTG_LAVA_JUMP)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage()))), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, (logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER))), @@ -396,28 +444,38 @@ void RegionTable_Init_GerudoTrainingGround() { ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM, true), }); - areaTable[RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER] = Region("Gerudo Training Ground MQ Underwater", SCENE_GERUDO_TRAINING_GROUND, {}, { + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER] = Region("Gerudo Training Ground MQ Underwater", SCENE_GERUDO_TRAINING_GROUND, { + EVENT_ACCESS(LOGIC_GTG_MQ_SILVER_WATER, logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->TakeDamage()), + }, { //Locations //it is possible to snipe the stingers with bow or sling before dropping in, or just get really lucky, and avoid needing to take damage, but that might be trick worthy - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, (logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->HasItem(RG_BRONZE_SCALE) && logic->TakeDamage()) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasItem(RG_GTG_MQ_SILVER_WATER) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GTG_MQ_SILVER_WATER_1, logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->TakeDamage()), + LOCATION(RC_GTG_MQ_SILVER_WATER_2, logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->TakeDamage()), + LOCATION(RC_GTG_MQ_SILVER_WATER_3, logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->TakeDamage()), }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, true), }); - areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT] = Region("Gerudo Training Ground MQ Maze Right", SCENE_GERUDO_TRAINING_GROUND, { //Events - EVENT_ACCESS(LOGIC_GTG_PLATFORM_SILVER_RUPEES, logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS)), + EVENT_ACCESS(LOGIC_GTG_MQ_SILVER_LAVA, logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS)), }, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GTG_MQ_SILVER_LAVA_1, logic->CanUse(RG_FIRE_ARROWS)), + LOCATION(RC_GTG_MQ_SILVER_LAVA_2, logic->CanUse(RG_FIRE_ARROWS)), + LOCATION(RC_GTG_MQ_SILVER_LAVA_3, logic->CanUse(RG_FIRE_ARROWS)), + LOCATION(RC_GTG_MQ_SILVER_LAVA_4, logic->CanUse(RG_FIRE_ARROWS)), + LOCATION(RC_GTG_MQ_SILVER_LAVA_5, logic->CanUse(RG_FIRE_ARROWS)), + LOCATION(RC_GTG_MQ_SILVER_LAVA_6, logic->CanUse(RG_FIRE_ARROWS)), }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, true), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER))), - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES) ? RG_HOOKSHOT : RG_LONGSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->Get(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER))), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(logic->HasItem(RG_GTG_MQ_SILVER_LAVA) ? RG_HOOKSHOT : RG_LONGSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->Get(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER))), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, logic->CanUse(RG_FIRE_ARROWS)), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM, logic->CanUse(RG_FIRE_ARROWS)), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 4df089717fa..358249dd791 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -39,7 +39,10 @@ void RegionTable_Init_IceCavern() { ENTRANCE(RR_ICE_CAVERN_ABOVE_BEGINNING, false), }); - areaTable[RR_ICE_CAVERN_HUB] = Region("Ice Cavern Hub", SCENE_ICE_CAVERN, {}, { + areaTable[RR_ICE_CAVERN_HUB] = Region("Ice Cavern Hub", SCENE_ICE_CAVERN, { + //Events + EVENT_ACCESS(LOGIC_ICE_CAVERN_SILVER_BLADES, (logic->IsAdult /*|| (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())*/) && logic->CanClearStalagmite()), + }, { //Locations LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), LOCATION(RC_ICE_CAVERN_HALL_POT_1, logic->CanBreakPots()), @@ -57,11 +60,16 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_RIGHT_STALAGMITE, logic->CanClearStalagmite()), LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_EAST_RED_ICE, logic->BlueFire()), LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_WEST_RED_ICE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_SILVER_BLADES_1, logic->CanClearStalagmite()), + LOCATION(RC_ICE_CAVERN_SILVER_BLADES_2, true), + LOCATION(RC_ICE_CAVERN_SILVER_BLADES_3, true), + LOCATION(RC_ICE_CAVERN_SILVER_BLADES_4, true), + LOCATION(RC_ICE_CAVERN_SILVER_BLADES_5, (logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump()))), }, { //Exits ENTRANCE(RR_ICE_CAVERN_BEGINNING, true), //child can make this with a ground jump for the first step, and a glitchless jump for the second, but it's a separate trick - ENTRANCE(RR_ICE_CAVERN_MAP_ROOM, (logic->IsAdult /*|| logic->CanGroundJump()*/) && logic->CanClearStalagmite()), + ENTRANCE(RR_ICE_CAVERN_MAP_ROOM, (logic->IsAdult /*|| logic->CanGroundJump()*/) && logic->HasItem(RG_ICE_CAVERN_SILVER_BLADES)), ENTRANCE(RR_ICE_CAVERN_COMPASS_ROOM, AnyAgeTime([]{return logic->BlueFire();})), ENTRANCE(RR_ICE_CAVERN_BLOCK_ROOM, AnyAgeTime([]{return logic->BlueFire();}) && (logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP))), }); @@ -129,7 +137,10 @@ void RegionTable_Init_IceCavern() { ENTRANCE(RR_ICE_CAVERN_HUB, true), }); - areaTable[RR_ICE_CAVERN_BLOCK_ROOM] = Region("Ice Cavern Block Room", SCENE_ICE_CAVERN, {}, { + areaTable[RR_ICE_CAVERN_BLOCK_ROOM] = Region("Ice Cavern Block Room", SCENE_ICE_CAVERN, { + //Events + EVENT_ACCESS(LOGIC_ICE_CAVERN_SILVER_BLOCK, (logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && ctx->GetTrickOption(RT_SLIDE_JUMP))) && AnyAgeTime([]{return logic->BlueFire();})), + }, { //Locations // trick involves backflip, could be merged into general trick LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH))), @@ -145,11 +156,16 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_2, true), LOCATION(RC_ICE_CAVERN_PUSH_BLOCK_HALL_STALACTITE_3, true), LOCATION(RC_ICE_CAVERN_SILVER_RUPEE_RED_ICE, (logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))) && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_SILVER_BLOCK_1, true), + LOCATION(RC_ICE_CAVERN_SILVER_BLOCK_2, true), + LOCATION(RC_ICE_CAVERN_SILVER_BLOCK_3, true), + LOCATION(RC_ICE_CAVERN_SILVER_BLOCK_4, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_SILVER_BLOCK_5, true), }, { //Exits ENTRANCE(RR_ICE_CAVERN_HUB, logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)), ENTRANCE(RR_ICE_CAVERN_BLOCK_ROOM_BLUE_FIRE, logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))), - ENTRANCE(RR_ICE_CAVERN_AFTER_BLOCK_ROOM, (logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))) && AnyAgeTime([]{return logic->BlueFire();})), + ENTRANCE(RR_ICE_CAVERN_AFTER_BLOCK_ROOM, (logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))) && logic->HasItem(RG_ICE_CAVERN_SILVER_BLOCK)), }); areaTable[RR_ICE_CAVERN_BLOCK_ROOM_BLUE_FIRE] = Region("Ice Cavern Block Room Blue Fire", SCENE_ICE_CAVERN, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index c374402a9d4..3f0b1536f9c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -103,9 +103,17 @@ void RegionTable_Init_ShadowTemple() { ENTRANCE(RR_SHADOW_TEMPLE_FIRST_BEAMOS, AnyAgeTime([]{return logic->CanKillEnemy(RE_GIBDO);})), }); - areaTable[RR_SHADOW_TEMPLE_SPINNING_BLADES] = Region("Shadow Temple Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_SPINNING_BLADES] = Region("Shadow Temple Spinning Blades", SCENE_SHADOW_TEMPLE, { + //Events + EVENT_ACCESS(LOGIC_SHADOW_SILVER_BLADES, (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump())) || logic->CanUse(RG_HOOKSHOT)), + }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, ((logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump())) || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, logic->HasItem(RG_SHADOW_SILVER_BLADES) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_SILVER_BLADES_1, true), + LOCATION(RC_SHADOW_SILVER_BLADES_2, (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump())) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_SILVER_BLADES_3, true), + LOCATION(RC_SHADOW_SILVER_BLADES_4, true), + LOCATION(RC_SHADOW_SILVER_BLADES_5, true), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_FIRST_BEAMOS, true), @@ -141,11 +149,21 @@ void RegionTable_Init_ShadowTemple() { ENTRANCE(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2)), }); - areaTable[RR_SHADOW_TEMPLE_LOWER_HUGE_PIT] = Region("Shadow Temple Lower Huge Pit", SCENE_SHADOW_TEMPLE, {}, {},{ + areaTable[RR_SHADOW_TEMPLE_LOWER_HUGE_PIT] = Region("Shadow Temple Lower Huge Pit", SCENE_SHADOW_TEMPLE, { + //Events + EVENT_ACCESS(LOGIC_SHADOW_SILVER_PIT, true), + }, { + //Locations + LOCATION(RC_SHADOW_SILVER_PIT_1, true), + LOCATION(RC_SHADOW_SILVER_PIT_2, true), + LOCATION(RC_SHADOW_SILVER_PIT_3, true), + LOCATION(RC_SHADOW_SILVER_PIT_4, true), + LOCATION(RC_SHADOW_SILVER_PIT_5, true), + },{ //Exits ENTRANCE(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, logic->IsAdult || logic->CanJumpslash()), ENTRANCE(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT_DOOR_LEDGE, (ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)), - ENTRANCE(RR_SHADOW_TEMPLE_STONE_UMBRELLA, true), + ENTRANCE(RR_SHADOW_TEMPLE_STONE_UMBRELLA, logic->HasItem(RG_SHADOW_SILVER_PIT)), }); // See MQ for comments @@ -195,18 +213,30 @@ void RegionTable_Init_ShadowTemple() { ENTRANCE(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT_DOOR_LEDGE, true), }); - areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES] = Region("Shadow Temple Invisible Spikes", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES] = Region("Shadow Temple Invisible Spikes", SCENE_SHADOW_TEMPLE, { + //Events + EVENT_ACCESS(LOGIC_SHADOW_SILVER_SPIKES, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanMiddairGroundJump()))), + }, { //Locations LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_SILVER_SPIKES_1, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump() && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_SHADOW_SILVER_SPIKES_2, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_SILVER_SPIKES_3, ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage()), + LOCATION(RC_SHADOW_SILVER_SPIKES_4, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT_DOOR_LEDGE, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2)), - ENTRANCE(RR_SHADOW_TEMPLE_SKULL_JAR, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanMiddairGroundJump()))), + ENTRANCE(RR_SHADOW_TEMPLE_SKULL_JAR, logic->HasItem(RG_SHADOW_SILVER_SPIKES)), ENTRANCE(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && ((logic->IsAdult && logic->CanMiddairGroundJump()) || logic->CanUse(AnyAgeTime([]{return logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC));}) ? RG_HOOKSHOT : RG_LONGSHOT))), }); - areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM] = Region("Shadow Temple Invisible Spikes Platform", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM] = Region("Shadow Temple Invisible Spikes Platform", SCENE_SHADOW_TEMPLE, {}, { + //Locations + // can also get 2 & 4 with hovers backwalk backflip + LOCATION(RC_SHADOW_SILVER_SPIKES_1, logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_SHADOW_SILVER_SPIKES_5, true), + }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, true), ENTRANCE(RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 3)), @@ -467,12 +497,20 @@ void RegionTable_Init_ShadowTemple() { ENTRANCE(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, AnyAgeTime([]{return logic->CanKillEnemy(RE_GIBDO);})), }); - areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", SCENE_SHADOW_TEMPLE, { + //Events + EVENT_ACCESS(LOGIC_SHADOW_MQ_SILVER_BLADES, logic->CanKillEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump()))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && logic->HasItem(RG_SHADOW_MQ_SILVER_BLADES) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_MQ_SILVER_BLADES_1, logic->CanPassEnemy(RE_BIG_SKULLTULA)), + LOCATION(RC_SHADOW_MQ_SILVER_BLADES_2, logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump()))), + LOCATION(RC_SHADOW_MQ_SILVER_BLADES_3, true), + LOCATION(RC_SHADOW_MQ_SILVER_BLADES_4, true), + LOCATION(RC_SHADOW_MQ_SILVER_BLADES_5, logic->CanPassEnemy(RE_BIG_SKULLTULA)), }, { //Exits - ENTRANCE(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, AnyAgeTime([]{return logic->CanKillEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));})), + ENTRANCE(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, logic->HasItem(RG_SHADOW_MQ_SILVER_BLADES)), ENTRANCE(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, logic->CanPassEnemy(RE_BIG_SKULLTULA)), }); @@ -516,26 +554,46 @@ void RegionTable_Init_ShadowTemple() { ENTRANCE(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, true), }); - areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM] = Region("Shadow Temple MQ Invisible Blades Room", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM] = Region("Shadow Temple MQ Invisible Blades Room", SCENE_SHADOW_TEMPLE, { + //Events + EVENT_ACCESS(LOGIC_SHADOW_MQ_SILVER_INVISIBLE_BLADES, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) && + (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH))), + }, { //Locations //RT_SHADOW_MQ_INVISIBLE_BLADES does not work with NL as like-likes will not swallow you, likewise like-likes will not spit you with a fairy revive //you take half a heart base from a spit out, double check EffectiveHealth when damage logic gets reworked //Child is too small to get hit by the blades doesn't need the trick or lens for dodging them - LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) && - (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) && - ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE))) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, logic->HasItem(RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->HasItem(RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9, ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, true), }); - areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Region("Shadow Temple MQ Lower Huge Pit", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Region("Shadow Temple MQ Lower Huge Pit", SCENE_SHADOW_TEMPLE, { + //Events + EVENT_ACCESS(LOGIC_SHADOW_MQ_SILVER_PIT, logic->CanUse(RG_LONGSHOT)), + }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->HasItem(RG_SHADOW_MQ_SILVER_PIT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_SHADOW_MQ_SILVER_PIT_1, true), + LOCATION(RC_SHADOW_MQ_SILVER_PIT_2, logic->HasItem(RG_LONGSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_PIT_3, logic->HasItem(RG_LONGSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_PIT_4, true), + LOCATION(RC_SHADOW_MQ_SILVER_PIT_5, true), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3, logic->CanUse(RG_LONGSHOT)), @@ -580,7 +638,7 @@ void RegionTable_Init_ShadowTemple() { //while the spikes here are annoying, they don't really stop you doing anything, so I'll assume either lens trick, lens to see them, or taking damage from them. Not hovers though as a new player won't see the threat without lens to react properly areaTable[RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM] = Region("Shadow Temple MQ Floor Spikes Room", SCENE_SHADOW_TEMPLE, { //Events //lens or trick is always required for hookshot targets. We handle it here to not complicate the RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_UPPER_DOOR logic - EVENT_ACCESS(LOGIC_SHADOW_MQ_FLOOR_SPIKES_RUPEES, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && + EVENT_ACCESS(LOGIC_SHADOW_MQ_SILVER_SPIKES, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && //Upper door side high rupee needs (hookshot and redead kill(as either age) for chest and adult) or longshot. hovers can cross from the left side with a backflip but that would be a trick //East midair rupee needs (hookshot and(hover boots or jumpslash from the upper door platform)) or longshot. //Combined these are longshot or (IsAdult && hookshot && (CanJumpslash || (Hover Boots && Here(CanKillRedeads)))) @@ -590,16 +648,32 @@ void RegionTable_Init_ShadowTemple() { }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->TakeDamage() || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_GORON_TUNIC)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_1, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_2, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_4, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_5, ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage()), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_6, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_7, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_8, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_GORON_TUNIC)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_10, logic->CanUse(RG_HOOKSHOT)), }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 3)), - ENTRANCE(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, logic->Get(LOGIC_SHADOW_MQ_FLOOR_SPIKES_RUPEES)), + ENTRANCE(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, logic->HasItem(RG_SHADOW_MQ_SILVER_SPIKES)), //We need to assume we can get here with or without the glass platforms - ENTRANCE(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_PLATFORM, ((logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->Get(LOGIC_SHADOW_MQ_FLOOR_SPIKES_RUPEES) || AnyAgeTime([]{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))) || + ENTRANCE(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_PLATFORM, ((logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->HasItem(RG_SHADOW_MQ_SILVER_SPIKES) || AnyAgeTime([]{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))) || ((ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->IsAdult && logic->CanMiddairGroundJump()))), }); - areaTable[RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_PLATFORM] = Region("Shadow Temple MQ Floor Spikes Platform", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_PLATFORM] = Region("Shadow Temple MQ Floor Spikes Platform", SCENE_SHADOW_TEMPLE, {}, { + //Locations + // can also get 2 & 10 with hovers backwalk backflip + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_1, logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_3, true), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_4, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_6, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_MQ_SILVER_SPIKES_9, true), + }, { //Exits ENTRANCE(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, true), ENTRANCE(RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4)), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 392224cda5a..f23e8aa88a4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -84,16 +84,21 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_NORTH] = Region("Spirit Temple Rupee Bridge North", SCENE_SPIRIT_TEMPLE, { //Events - EVENT_ACCESS(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), + EVENT_ACCESS(LOGIC_SPIRIT_SILVER_CHILD, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), EVENT_ACCESS(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE_TORCHES, (logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE) && logic->HasFireSourceWithTorch()) || logic->CanUse(RG_DINS_FIRE)), }, { //Locations LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE_TORCHES) && logic->HasItem(RG_OPEN_CHEST)), - // possible to collect without lowering fence, should be a trick - LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) && logic->HasItem(RG_CLIMB)), + // possible to collect by climbing around token without lowering fence, should be a trick. boomerang can grab through fence + LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->HasItem(RG_SPIRIT_SILVER_CHILD) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) && logic->HasItem(RG_CLIMB)), + LOCATION(RC_SPIRIT_SILVER_CHILD_1, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SPIRIT_SILVER_CHILD_2, true), + LOCATION(RC_SPIRIT_SILVER_CHILD_3, true), + LOCATION(RC_SPIRIT_SILVER_CHILD_4, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SPIRIT_SILVER_CHILD_5, true), }, { //Exits - ENTRANCE(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH, logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE)), + ENTRANCE(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH, logic->HasItem(RG_SPIRIT_SILVER_CHILD)), ENTRANCE(RR_SPIRIT_TEMPLE_1F_ANUBIS, true), }); @@ -106,7 +111,7 @@ void RegionTable_Init_SpiritTemple() { }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_CHILD_SIDE_HUB, true), - ENTRANCE(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_NORTH, logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE)), + ENTRANCE(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_NORTH, logic->HasItem(RG_SPIRIT_SILVER_CHILD)), }); areaTable[RR_SPIRIT_TEMPLE_CHILD_BOXES] = Region("Child Spirit Temple Before Climb", SCENE_SPIRIT_TEMPLE, {}, { @@ -164,8 +169,11 @@ void RegionTable_Init_SpiritTemple() { //Jumpslash is possible as child, but pretty tight. Jumpslash as late as you can //A damage boost off the boulder is also possible, but you need to land on the middle of the boulder //to get enough distance to reach the rupee - EVENT_ACCESS(LOGIC_SPIRIT_BOUNDERS_SILVERS, logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash() || logic->CanUse(RG_LONGSHOT)/* || CanBunnyHop()*/), - }, {}, { + EVENT_ACCESS(LOGIC_SPIRIT_SILVER_BOULDERS, logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash() || logic->CanUse(RG_LONGSHOT)/* || CanBunnyHop()*/), + }, { + //Locations + LOCATION(RC_SPIRIT_SILVER_BOULDERS_5, logic->Get(LOGIC_SPIRIT_SILVER_BOULDERS)), + }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_ADULT_SIDE_HUB, true), ENTRANCE(RR_SPIRIT_TEMPLE_BOULDERS, true), @@ -174,10 +182,14 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BOULDERS] = Region("Spirit Temple Boulders", SCENE_SPIRIT_TEMPLE, {}, { //Locations LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanKillEnemy(RE_GOLD_SKULLTULA)), + LOCATION(RC_SPIRIT_SILVER_BOULDERS_1, true), + LOCATION(RC_SPIRIT_SILVER_BOULDERS_2, true), + LOCATION(RC_SPIRIT_SILVER_BOULDERS_3, true), + LOCATION(RC_SPIRIT_SILVER_BOULDERS_4, true), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_ABOVE_BOULDERS, logic->IsAdult || logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanGroundJump()), - ENTRANCE(RR_SPIRIT_TEMPLE_PAST_BOULDERS, logic->Get(LOGIC_SPIRIT_BOUNDERS_SILVERS)), + ENTRANCE(RR_SPIRIT_TEMPLE_PAST_BOULDERS, logic->HasItem(RG_SPIRIT_SILVER_BOULDERS)), }); areaTable[RR_SPIRIT_TEMPLE_PAST_BOULDERS] = Region("Spirit Temple Past Boulders", SCENE_SPIRIT_TEMPLE, {}, { @@ -290,7 +302,13 @@ void RegionTable_Init_SpiritTemple() { ENTRANCE(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, true), }); - areaTable[RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM] = Region("Spirit Temple Sun Block Room", SCENE_SPIRIT_TEMPLE, {}, {}, { + areaTable[RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM] = Region("Spirit Temple Sun Block Room", SCENE_SPIRIT_TEMPLE, {}, { + //Locations + LOCATION(RC_SPIRIT_SILVER_SUN_1, true), + LOCATION(RC_SPIRIT_SILVER_SUN_2, true), + LOCATION(RC_SPIRIT_SILVER_SUN_3, true), + LOCATION(RC_SPIRIT_SILVER_SUN_5, true), + }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_EMPTY_STAIRS, logic->HasItem(RG_POWER_BRACELET) || logic->SunlightArrows()), //The blocks can be used to get onto this ledge itemless @@ -301,14 +319,15 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_SUN_BLOCK_CHEST_LEDGE] = Region("Spirit Temple Sun Block Chest ledge", SCENE_SPIRIT_TEMPLE, { //Events //Assumes RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM access - EVENT_ACCESS(LOGIC_SPIRIT_SUN_BLOCK_TORCH, SpiritShared(RR_SPIRIT_TEMPLE_SUN_BLOCK_CHEST_LEDGE, []{return true;}, true)), + EVENT_ACCESS(LOGIC_SPIRIT_SILVER_SUN, SpiritShared(RR_SPIRIT_TEMPLE_SUN_BLOCK_CHEST_LEDGE, []{return true;}, true)), }, { //Locations //Spawning the chest to get here is accounted for in movement logic, so we only need to confirm it can be spawned here LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_BLOCK_CHEST_LEDGE, []{return logic->HasFireSource() || - (logic->Get(LOGIC_SPIRIT_SUN_BLOCK_TORCH) && + (logic->HasItem(RG_SPIRIT_SILVER_SUN) && (logic->CanUse(RG_STICKS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))));}) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_SILVER_SUN_4, SpiritShared(RR_SPIRIT_TEMPLE_SUN_BLOCK_CHEST_LEDGE, []{return true;}, true)), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, true), @@ -565,7 +584,7 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST) && ((AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->IsChild ? logic->CanHitEyeTargets() : logic->CanUse(RG_FAIRY_SLINGSHOT)))), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Get(LOGIC_SPIRIT_1F_SILVER_RUPEES) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->HasItem(RG_SPIRIT_MQ_SILVER_LOBBY) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), @@ -576,6 +595,11 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, logic->CanUse(RG_BOMBCHU_5)), LOCATION(RC_SPIRIT_TEMPLE_LEFT_SNAKE_STATUE, logic->CanRead()), LOCATION(RC_SPIRIT_TEMPLE_RIGHT_SNAKE_STATUE, logic->CanRead()), + LOCATION(RC_SPIRIT_MQ_SILVER_LOBBY_1, true), + LOCATION(RC_SPIRIT_MQ_SILVER_LOBBY_2, true), + LOCATION(RC_SPIRIT_MQ_SILVER_LOBBY_3, true), + LOCATION(RC_SPIRIT_MQ_SILVER_LOBBY_4, true), + LOCATION(RC_SPIRIT_MQ_SILVER_LOBBY_5, true), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_ENTRYWAY, true), @@ -924,7 +948,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_BEHIND_GEYSER] = Region("Spirit Temple MQ 1F East", SCENE_SPIRIT_TEMPLE, { //Events //Assumes RR_SPIRIT_TEMPLE_MQ_FOYER access - EVENT_ACCESS(LOGIC_SPIRIT_1F_SILVER_RUPEES, logic->CanUse(RG_MEGATON_HAMMER)), + EVENT_ACCESS(LOGIC_SPIRIT_MQ_SILVER_LOBBY, logic->CanUse(RG_MEGATON_HAMMER)), }, { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), @@ -1049,6 +1073,11 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_1, true), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_2, true), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_3, true), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_4, true), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_5, true), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, true), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 8b714759e6f..ece29d10a14 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -265,6 +265,47 @@ bool Logic::HasItem(RandomizerGet itemName) { return CheckRandoInf(RAND_INF_CAN_CRAWL); case RG_OPEN_CHEST: return CheckRandoInf(RAND_INF_CAN_OPEN_CHEST); + // Silver Rupees + case RG_SHADOW_SILVER_BLADES: + case RG_SHADOW_SILVER_PIT: + case RG_SHADOW_SILVER_SPIKES: + case RG_SPIRIT_SILVER_CHILD: + case RG_SPIRIT_SILVER_SUN: + case RG_SPIRIT_SILVER_BOULDERS: + case RG_BOTW_SILVER: + case RG_ICE_CAVERN_SILVER_BLADES: + case RG_ICE_CAVERN_SILVER_BLOCK: + case RG_GTG_SILVER_SLOPE: + case RG_GTG_SILVER_LAVA: + case RG_GTG_SILVER_WATER: + case RG_GANONS_CASTLE_SILVER_LIGHT: + case RG_GANONS_CASTLE_SILVER_FOREST: + case RG_GANONS_CASTLE_SILVER_FIRE: + case RG_GANONS_CASTLE_SILVER_SPIRIT: + case RG_DODONGOS_CAVERN_MQ_SILVER: + case RG_SHADOW_MQ_SILVER_BLADES: + case RG_SHADOW_MQ_SILVER_PIT: + case RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES: + case RG_SHADOW_MQ_SILVER_SPIKES: + case RG_SPIRIT_MQ_SILVER_LOBBY: + case RG_SPIRIT_MQ_SILVER_BIG_WALL: + case RG_GTG_MQ_SILVER_SLOPE: + case RG_GTG_MQ_SILVER_LAVA: + case RG_GTG_MQ_SILVER_WATER: + case RG_GANONS_CASTLE_MQ_SILVER_FIRE: + case RG_GANONS_CASTLE_MQ_SILVER_WATER: + case RG_GANONS_CASTLE_MQ_SILVER_SHADOW: { + if (!ctx->GetOption(RSK_SHUFFLE_SILVER)) { + return Get((LogicVal)(LOGIC_SHADOW_SILVER_BLADES + (itemName - RG_SHADOW_SILVER_BLADES))); + } + s8 field = *Randomizer::SilverFieldFromSaveContext(mSaveContext, itemName); + return field >= (itemName == RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES || itemName == RG_SHADOW_MQ_SILVER_SPIKES + ? 10 + : itemName == RG_GTG_MQ_SILVER_LAVA ? 6 + : itemName == RG_GTG_MQ_SILVER_WATER ? 3 + : 5); + } + // Trade Items case RG_POCKET_EGG: return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG) || CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO); @@ -2113,23 +2154,41 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case ITEMTYPE_FORTRESS_SMALLKEY: case ITEMTYPE_SMALLKEY: { auto randoGet = item.GetRandomizerGet(); - auto keyring = randoGet >= RG_FOREST_TEMPLE_KEY_RING && randoGet <= RG_GANONS_CASTLE_KEY_RING; - auto dungeonIndex = RandoGetToDungeonScene.find(randoGet)->second; - auto count = GetSmallKeyCount(dungeonIndex); - if (!state) { - if (keyring) { - count = 0; + if (randoGet >= RG_SHADOW_SILVER_BLADES && randoGet <= RG_GANONS_CASTLE_MQ_SILVER_SHADOW) { + s8* field = Randomizer::SilverFieldFromSaveContext(mSaveContext, randoGet); + bool isWallet = ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET); + if (!state) { + if (isWallet) { + *field = 0; + } else { + *field -= 1; + } } else { - count -= 1; + if (isWallet) { + *field = 10; + } else { + *field += 1; + } } } else { - if (keyring) { - count = 10; + auto keyring = randoGet >= RG_FOREST_TEMPLE_KEY_RING && randoGet <= RG_GANONS_CASTLE_KEY_RING; + auto dungeonIndex = RandoGetToDungeonScene.find(randoGet)->second; + auto count = GetSmallKeyCount(dungeonIndex); + if (!state) { + if (keyring) { + count = 0; + } else { + count -= 1; + } } else { - count += 1; + if (keyring) { + count = 10; + } else { + count += 1; + } } + SetSmallKeyCount(dungeonIndex, count); } - SetSmallKeyCount(dungeonIndex, count); } break; case ITEMTYPE_TOKEN: mSaveContext->inventory.gsTokens += (!state ? -1 : 1); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index d4b9d41f172..b9b0dca3468 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -529,6 +529,9 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n" "\n" "All Items - Shuffle all freestanding rupees & hearts."; + mOptionDescriptions[RSK_SHUFFLE_SILVER] = "Silver rupees will be shuffled.\n" + "Items will be added to pool which completes the silver rupee puzzles,\n" + "while silver rupee locations will be random items."; mOptionDescriptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES] = "Shuffle fairies in fountain locations. " "This includes the sets of fairies found in Ganon's Castle and the Desert Oasis."; diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 8fad3d16fa1..ad417de2f24 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -283,6 +283,71 @@ bool Randomizer::IsTrialRequired(s32 trialFlag) { return Rando::Context::GetInstance()->GetTrial(trialFlagToTrialKey[trialFlag])->IsRequired(); } +s8* Randomizer::SilverFieldFromSaveContext(SaveContext* saveContext, RandomizerGet rg) { + switch (rg) { + case RG_SHADOW_SILVER_BLADES: + return &saveContext->ship.quest.data.randomizer.silverShadowBlades; + case RG_SHADOW_SILVER_PIT: + return &saveContext->ship.quest.data.randomizer.silverShadowPit; + case RG_SHADOW_SILVER_SPIKES: + return &saveContext->ship.quest.data.randomizer.silverShadowSpikes; + case RG_SPIRIT_SILVER_CHILD: + return &saveContext->ship.quest.data.randomizer.silverSpiritChild; + case RG_SPIRIT_SILVER_SUN: + return &saveContext->ship.quest.data.randomizer.silverSpiritSun; + case RG_SPIRIT_SILVER_BOULDERS: + return &saveContext->ship.quest.data.randomizer.silverSpiritBoulders; + case RG_BOTW_SILVER: + return &saveContext->ship.quest.data.randomizer.silverBotw; + case RG_ICE_CAVERN_SILVER_BLADES: + return &saveContext->ship.quest.data.randomizer.silverIceCavernBlades; + case RG_ICE_CAVERN_SILVER_BLOCK: + return &saveContext->ship.quest.data.randomizer.silverIceCavernBlock; + case RG_GTG_SILVER_SLOPE: + return &saveContext->ship.quest.data.randomizer.silverGtgSlope; + case RG_GTG_SILVER_LAVA: + return &saveContext->ship.quest.data.randomizer.silverGtgLava; + case RG_GTG_SILVER_WATER: + return &saveContext->ship.quest.data.randomizer.silverGtgWater; + case RG_GANONS_CASTLE_SILVER_LIGHT: + return &saveContext->ship.quest.data.randomizer.silverGanonLight; + case RG_GANONS_CASTLE_SILVER_FOREST: + return &saveContext->ship.quest.data.randomizer.silverGanonForest; + case RG_GANONS_CASTLE_SILVER_FIRE: + return &saveContext->ship.quest.data.randomizer.silverGanonFire; + case RG_GANONS_CASTLE_SILVER_SPIRIT: + return &saveContext->ship.quest.data.randomizer.silverGanonSpirit; + case RG_DODONGOS_CAVERN_MQ_SILVER: + return &saveContext->ship.quest.data.randomizer.silverMqDodongosCavern; + case RG_SHADOW_MQ_SILVER_BLADES: + return &saveContext->ship.quest.data.randomizer.silverMqShadowBlades; + case RG_SHADOW_MQ_SILVER_PIT: + return &saveContext->ship.quest.data.randomizer.silverMqShadowPit; + case RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES: + return &saveContext->ship.quest.data.randomizer.silverMqShadowInvisibleBlades; + case RG_SHADOW_MQ_SILVER_SPIKES: + return &saveContext->ship.quest.data.randomizer.silverMqShadowSpikes; + case RG_SPIRIT_MQ_SILVER_LOBBY: + return &saveContext->ship.quest.data.randomizer.silverMqSpiritLobby; + case RG_SPIRIT_MQ_SILVER_BIG_WALL: + return &saveContext->ship.quest.data.randomizer.silverMqSpiritBigWall; + case RG_GTG_MQ_SILVER_SLOPE: + return &saveContext->ship.quest.data.randomizer.silverMqGtgSlope; + case RG_GTG_MQ_SILVER_LAVA: + return &saveContext->ship.quest.data.randomizer.silverMqGtgLava; + case RG_GTG_MQ_SILVER_WATER: + return &saveContext->ship.quest.data.randomizer.silverMqGtgWater; + case RG_GANONS_CASTLE_MQ_SILVER_FIRE: + return &saveContext->ship.quest.data.randomizer.silverMqGanonFire; + case RG_GANONS_CASTLE_MQ_SILVER_WATER: + return &saveContext->ship.quest.data.randomizer.silverMqGanonWater; + case RG_GANONS_CASTLE_MQ_SILVER_SHADOW: + return &saveContext->ship.quest.data.randomizer.silverMqGanonShadow; + default: + return nullptr; + } +} + GetItemEntry Randomizer::GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, bool checkObtainability) { return Rando::Context::GetInstance()->GetFinalGIEntry(GetCheckFromActor(actorId, sceneNum, actorParams), @@ -3782,6 +3847,160 @@ std::map rcToRandomizerInf = { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4 }, { RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5 }, + { RC_SHADOW_SILVER_BLADES_1, RAND_INF_SHADOW_SILVER_BLADES_1 }, + { RC_SHADOW_SILVER_BLADES_2, RAND_INF_SHADOW_SILVER_BLADES_2 }, + { RC_SHADOW_SILVER_BLADES_3, RAND_INF_SHADOW_SILVER_BLADES_3 }, + { RC_SHADOW_SILVER_BLADES_4, RAND_INF_SHADOW_SILVER_BLADES_4 }, + { RC_SHADOW_SILVER_BLADES_5, RAND_INF_SHADOW_SILVER_BLADES_5 }, + { RC_SHADOW_SILVER_PIT_1, RAND_INF_SHADOW_SILVER_PIT_1 }, + { RC_SHADOW_SILVER_PIT_2, RAND_INF_SHADOW_SILVER_PIT_2 }, + { RC_SHADOW_SILVER_PIT_3, RAND_INF_SHADOW_SILVER_PIT_3 }, + { RC_SHADOW_SILVER_PIT_4, RAND_INF_SHADOW_SILVER_PIT_4 }, + { RC_SHADOW_SILVER_PIT_5, RAND_INF_SHADOW_SILVER_PIT_5 }, + { RC_SHADOW_SILVER_SPIKES_1, RAND_INF_SHADOW_SILVER_SPIKES_1 }, + { RC_SHADOW_SILVER_SPIKES_2, RAND_INF_SHADOW_SILVER_SPIKES_2 }, + { RC_SHADOW_SILVER_SPIKES_3, RAND_INF_SHADOW_SILVER_SPIKES_3 }, + { RC_SHADOW_SILVER_SPIKES_4, RAND_INF_SHADOW_SILVER_SPIKES_4 }, + { RC_SHADOW_SILVER_SPIKES_5, RAND_INF_SHADOW_SILVER_SPIKES_5 }, + { RC_SPIRIT_SILVER_CHILD_1, RAND_INF_SPIRIT_SILVER_CHILD_1 }, + { RC_SPIRIT_SILVER_CHILD_2, RAND_INF_SPIRIT_SILVER_CHILD_2 }, + { RC_SPIRIT_SILVER_CHILD_3, RAND_INF_SPIRIT_SILVER_CHILD_3 }, + { RC_SPIRIT_SILVER_CHILD_4, RAND_INF_SPIRIT_SILVER_CHILD_4 }, + { RC_SPIRIT_SILVER_CHILD_5, RAND_INF_SPIRIT_SILVER_CHILD_5 }, + { RC_SPIRIT_SILVER_SUN_1, RAND_INF_SPIRIT_SILVER_SUN_1 }, + { RC_SPIRIT_SILVER_SUN_2, RAND_INF_SPIRIT_SILVER_SUN_2 }, + { RC_SPIRIT_SILVER_SUN_3, RAND_INF_SPIRIT_SILVER_SUN_3 }, + { RC_SPIRIT_SILVER_SUN_4, RAND_INF_SPIRIT_SILVER_SUN_4 }, + { RC_SPIRIT_SILVER_SUN_5, RAND_INF_SPIRIT_SILVER_SUN_5 }, + { RC_SPIRIT_SILVER_BOULDERS_1, RAND_INF_SPIRIT_SILVER_BOULDERS_1 }, + { RC_SPIRIT_SILVER_BOULDERS_2, RAND_INF_SPIRIT_SILVER_BOULDERS_2 }, + { RC_SPIRIT_SILVER_BOULDERS_3, RAND_INF_SPIRIT_SILVER_BOULDERS_3 }, + { RC_SPIRIT_SILVER_BOULDERS_4, RAND_INF_SPIRIT_SILVER_BOULDERS_4 }, + { RC_SPIRIT_SILVER_BOULDERS_5, RAND_INF_SPIRIT_SILVER_BOULDERS_5 }, + { RC_BOTW_SILVER_1, RAND_INF_BOTW_SILVER_1 }, + { RC_BOTW_SILVER_2, RAND_INF_BOTW_SILVER_2 }, + { RC_BOTW_SILVER_3, RAND_INF_BOTW_SILVER_3 }, + { RC_BOTW_SILVER_4, RAND_INF_BOTW_SILVER_4 }, + { RC_BOTW_SILVER_5, RAND_INF_BOTW_SILVER_5 }, + { RC_ICE_CAVERN_SILVER_BLADES_1, RAND_INF_ICE_CAVERN_SILVER_BLADES_1 }, + { RC_ICE_CAVERN_SILVER_BLADES_2, RAND_INF_ICE_CAVERN_SILVER_BLADES_2 }, + { RC_ICE_CAVERN_SILVER_BLADES_3, RAND_INF_ICE_CAVERN_SILVER_BLADES_3 }, + { RC_ICE_CAVERN_SILVER_BLADES_4, RAND_INF_ICE_CAVERN_SILVER_BLADES_4 }, + { RC_ICE_CAVERN_SILVER_BLADES_5, RAND_INF_ICE_CAVERN_SILVER_BLADES_5 }, + { RC_ICE_CAVERN_SILVER_BLOCK_1, RAND_INF_ICE_CAVERN_SILVER_BLOCK_1 }, + { RC_ICE_CAVERN_SILVER_BLOCK_2, RAND_INF_ICE_CAVERN_SILVER_BLOCK_2 }, + { RC_ICE_CAVERN_SILVER_BLOCK_3, RAND_INF_ICE_CAVERN_SILVER_BLOCK_3 }, + { RC_ICE_CAVERN_SILVER_BLOCK_4, RAND_INF_ICE_CAVERN_SILVER_BLOCK_4 }, + { RC_ICE_CAVERN_SILVER_BLOCK_5, RAND_INF_ICE_CAVERN_SILVER_BLOCK_5 }, + { RC_GTG_SILVER_SLOPE_1, RAND_INF_GTG_SILVER_SLOPE_1 }, + { RC_GTG_SILVER_SLOPE_2, RAND_INF_GTG_SILVER_SLOPE_2 }, + { RC_GTG_SILVER_SLOPE_3, RAND_INF_GTG_SILVER_SLOPE_3 }, + { RC_GTG_SILVER_SLOPE_4, RAND_INF_GTG_SILVER_SLOPE_4 }, + { RC_GTG_SILVER_SLOPE_5, RAND_INF_GTG_SILVER_SLOPE_5 }, + { RC_GTG_SILVER_LAVA_1, RAND_INF_GTG_SILVER_LAVA_1 }, + { RC_GTG_SILVER_LAVA_2, RAND_INF_GTG_SILVER_LAVA_2 }, + { RC_GTG_SILVER_LAVA_3, RAND_INF_GTG_SILVER_LAVA_3 }, + { RC_GTG_SILVER_LAVA_4, RAND_INF_GTG_SILVER_LAVA_4 }, + { RC_GTG_SILVER_LAVA_5, RAND_INF_GTG_SILVER_LAVA_5 }, + { RC_GTG_SILVER_WATER_1, RAND_INF_GTG_SILVER_WATER_1 }, + { RC_GTG_SILVER_WATER_2, RAND_INF_GTG_SILVER_WATER_2 }, + { RC_GTG_SILVER_WATER_3, RAND_INF_GTG_SILVER_WATER_3 }, + { RC_GTG_SILVER_WATER_4, RAND_INF_GTG_SILVER_WATER_4 }, + { RC_GTG_SILVER_WATER_5, RAND_INF_GTG_SILVER_WATER_5 }, + { RC_GANONS_CASTLE_SILVER_LIGHT_1, RAND_INF_GANONS_CASTLE_SILVER_LIGHT_1 }, + { RC_GANONS_CASTLE_SILVER_LIGHT_2, RAND_INF_GANONS_CASTLE_SILVER_LIGHT_2 }, + { RC_GANONS_CASTLE_SILVER_LIGHT_3, RAND_INF_GANONS_CASTLE_SILVER_LIGHT_3 }, + { RC_GANONS_CASTLE_SILVER_LIGHT_4, RAND_INF_GANONS_CASTLE_SILVER_LIGHT_4 }, + { RC_GANONS_CASTLE_SILVER_LIGHT_5, RAND_INF_GANONS_CASTLE_SILVER_LIGHT_5 }, + { RC_GANONS_CASTLE_SILVER_FOREST_1, RAND_INF_GANONS_CASTLE_SILVER_FOREST_1 }, + { RC_GANONS_CASTLE_SILVER_FOREST_2, RAND_INF_GANONS_CASTLE_SILVER_FOREST_2 }, + { RC_GANONS_CASTLE_SILVER_FOREST_3, RAND_INF_GANONS_CASTLE_SILVER_FOREST_3 }, + { RC_GANONS_CASTLE_SILVER_FOREST_4, RAND_INF_GANONS_CASTLE_SILVER_FOREST_4 }, + { RC_GANONS_CASTLE_SILVER_FOREST_5, RAND_INF_GANONS_CASTLE_SILVER_FOREST_5 }, + { RC_GANONS_CASTLE_SILVER_FIRE_1, RAND_INF_GANONS_CASTLE_SILVER_FIRE_1 }, + { RC_GANONS_CASTLE_SILVER_FIRE_2, RAND_INF_GANONS_CASTLE_SILVER_FIRE_2 }, + { RC_GANONS_CASTLE_SILVER_FIRE_3, RAND_INF_GANONS_CASTLE_SILVER_FIRE_3 }, + { RC_GANONS_CASTLE_SILVER_FIRE_4, RAND_INF_GANONS_CASTLE_SILVER_FIRE_4 }, + { RC_GANONS_CASTLE_SILVER_FIRE_5, RAND_INF_GANONS_CASTLE_SILVER_FIRE_5 }, + { RC_GANONS_CASTLE_SILVER_SPIRIT_1, RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_1 }, + { RC_GANONS_CASTLE_SILVER_SPIRIT_2, RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_2 }, + { RC_GANONS_CASTLE_SILVER_SPIRIT_3, RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_3 }, + { RC_GANONS_CASTLE_SILVER_SPIRIT_4, RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_4 }, + { RC_GANONS_CASTLE_SILVER_SPIRIT_5, RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_5 }, + { RC_DODONGOS_CAVERN_MQ_SILVER_1, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_1 }, + { RC_DODONGOS_CAVERN_MQ_SILVER_2, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_2 }, + { RC_DODONGOS_CAVERN_MQ_SILVER_3, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_3 }, + { RC_DODONGOS_CAVERN_MQ_SILVER_4, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_4 }, + { RC_DODONGOS_CAVERN_MQ_SILVER_5, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_5 }, + { RC_SHADOW_MQ_SILVER_BLADES_1, RAND_INF_SHADOW_MQ_SILVER_BLADES_1 }, + { RC_SHADOW_MQ_SILVER_BLADES_2, RAND_INF_SHADOW_MQ_SILVER_BLADES_2 }, + { RC_SHADOW_MQ_SILVER_BLADES_3, RAND_INF_SHADOW_MQ_SILVER_BLADES_3 }, + { RC_SHADOW_MQ_SILVER_BLADES_4, RAND_INF_SHADOW_MQ_SILVER_BLADES_4 }, + { RC_SHADOW_MQ_SILVER_BLADES_5, RAND_INF_SHADOW_MQ_SILVER_BLADES_5 }, + { RC_SHADOW_MQ_SILVER_PIT_1, RAND_INF_SHADOW_MQ_SILVER_PIT_1 }, + { RC_SHADOW_MQ_SILVER_PIT_2, RAND_INF_SHADOW_MQ_SILVER_PIT_2 }, + { RC_SHADOW_MQ_SILVER_PIT_3, RAND_INF_SHADOW_MQ_SILVER_PIT_3 }, + { RC_SHADOW_MQ_SILVER_PIT_4, RAND_INF_SHADOW_MQ_SILVER_PIT_4 }, + { RC_SHADOW_MQ_SILVER_PIT_5, RAND_INF_SHADOW_MQ_SILVER_PIT_5 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9 }, + { RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10, RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10 }, + { RC_SHADOW_MQ_SILVER_SPIKES_1, RAND_INF_SHADOW_MQ_SILVER_SPIKES_1 }, + { RC_SHADOW_MQ_SILVER_SPIKES_2, RAND_INF_SHADOW_MQ_SILVER_SPIKES_2 }, + { RC_SHADOW_MQ_SILVER_SPIKES_3, RAND_INF_SHADOW_MQ_SILVER_SPIKES_3 }, + { RC_SHADOW_MQ_SILVER_SPIKES_4, RAND_INF_SHADOW_MQ_SILVER_SPIKES_4 }, + { RC_SHADOW_MQ_SILVER_SPIKES_5, RAND_INF_SHADOW_MQ_SILVER_SPIKES_5 }, + { RC_SHADOW_MQ_SILVER_SPIKES_6, RAND_INF_SHADOW_MQ_SILVER_SPIKES_6 }, + { RC_SHADOW_MQ_SILVER_SPIKES_7, RAND_INF_SHADOW_MQ_SILVER_SPIKES_7 }, + { RC_SHADOW_MQ_SILVER_SPIKES_8, RAND_INF_SHADOW_MQ_SILVER_SPIKES_8 }, + { RC_SHADOW_MQ_SILVER_SPIKES_9, RAND_INF_SHADOW_MQ_SILVER_SPIKES_9 }, + { RC_SHADOW_MQ_SILVER_SPIKES_10, RAND_INF_SHADOW_MQ_SILVER_SPIKES_10 }, + { RC_SPIRIT_MQ_SILVER_LOBBY_1, RAND_INF_SPIRIT_MQ_SILVER_LOBBY_1 }, + { RC_SPIRIT_MQ_SILVER_LOBBY_2, RAND_INF_SPIRIT_MQ_SILVER_LOBBY_2 }, + { RC_SPIRIT_MQ_SILVER_LOBBY_3, RAND_INF_SPIRIT_MQ_SILVER_LOBBY_3 }, + { RC_SPIRIT_MQ_SILVER_LOBBY_4, RAND_INF_SPIRIT_MQ_SILVER_LOBBY_4 }, + { RC_SPIRIT_MQ_SILVER_LOBBY_5, RAND_INF_SPIRIT_MQ_SILVER_LOBBY_5 }, + { RC_SPIRIT_MQ_SILVER_BIG_WALL_1, RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_1 }, + { RC_SPIRIT_MQ_SILVER_BIG_WALL_2, RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_2 }, + { RC_SPIRIT_MQ_SILVER_BIG_WALL_3, RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_3 }, + { RC_SPIRIT_MQ_SILVER_BIG_WALL_4, RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_4 }, + { RC_SPIRIT_MQ_SILVER_BIG_WALL_5, RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_5 }, + { RC_GTG_MQ_SILVER_SLOPE_1, RAND_INF_GTG_MQ_SILVER_SLOPE_1 }, + { RC_GTG_MQ_SILVER_SLOPE_2, RAND_INF_GTG_MQ_SILVER_SLOPE_2 }, + { RC_GTG_MQ_SILVER_SLOPE_3, RAND_INF_GTG_MQ_SILVER_SLOPE_3 }, + { RC_GTG_MQ_SILVER_SLOPE_4, RAND_INF_GTG_MQ_SILVER_SLOPE_4 }, + { RC_GTG_MQ_SILVER_SLOPE_5, RAND_INF_GTG_MQ_SILVER_SLOPE_5 }, + { RC_GTG_MQ_SILVER_LAVA_1, RAND_INF_GTG_MQ_SILVER_LAVA_1 }, + { RC_GTG_MQ_SILVER_LAVA_2, RAND_INF_GTG_MQ_SILVER_LAVA_2 }, + { RC_GTG_MQ_SILVER_LAVA_3, RAND_INF_GTG_MQ_SILVER_LAVA_3 }, + { RC_GTG_MQ_SILVER_LAVA_4, RAND_INF_GTG_MQ_SILVER_LAVA_4 }, + { RC_GTG_MQ_SILVER_LAVA_5, RAND_INF_GTG_MQ_SILVER_LAVA_5 }, + { RC_GTG_MQ_SILVER_LAVA_6, RAND_INF_GTG_MQ_SILVER_LAVA_6 }, + { RC_GTG_MQ_SILVER_WATER_1, RAND_INF_GTG_MQ_SILVER_WATER_1 }, + { RC_GTG_MQ_SILVER_WATER_2, RAND_INF_GTG_MQ_SILVER_WATER_2 }, + { RC_GTG_MQ_SILVER_WATER_3, RAND_INF_GTG_MQ_SILVER_WATER_3 }, + { RC_GANONS_CASTLE_MQ_SILVER_FIRE_1, RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_1 }, + { RC_GANONS_CASTLE_MQ_SILVER_FIRE_2, RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_2 }, + { RC_GANONS_CASTLE_MQ_SILVER_FIRE_3, RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_3 }, + { RC_GANONS_CASTLE_MQ_SILVER_FIRE_4, RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_4 }, + { RC_GANONS_CASTLE_MQ_SILVER_FIRE_5, RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_5 }, + { RC_GANONS_CASTLE_MQ_SILVER_WATER_1, RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_1 }, + { RC_GANONS_CASTLE_MQ_SILVER_WATER_2, RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_2 }, + { RC_GANONS_CASTLE_MQ_SILVER_WATER_3, RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_3 }, + { RC_GANONS_CASTLE_MQ_SILVER_WATER_4, RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_4 }, + { RC_GANONS_CASTLE_MQ_SILVER_WATER_5, RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_5 }, + { RC_GANONS_CASTLE_MQ_SILVER_SHADOW_1, RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_1 }, + { RC_GANONS_CASTLE_MQ_SILVER_SHADOW_2, RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_2 }, + { RC_GANONS_CASTLE_MQ_SILVER_SHADOW_3, RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_3 }, + { RC_GANONS_CASTLE_MQ_SILVER_SHADOW_4, RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_4 }, + { RC_GANONS_CASTLE_MQ_SILVER_SHADOW_5, RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_5 }, }; CheckIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { @@ -4409,6 +4628,24 @@ CheckIdentity Randomizer::IdentifyRedIce(s32 sceneNum, s32 posX, s32 posZ) { return redIceIdentity; } +CheckIdentity Randomizer::IdentifySilver(s32 sceneNum, s32 posX, s32 posZ) { + struct CheckIdentity silverIdentity; + + silverIdentity.randomizerInf = RAND_INF_MAX; + silverIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + + Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_G_SWITCH, sceneNum, actorParams); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + silverIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + silverIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return silverIdentity; +} + u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); } @@ -4921,6 +5158,44 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { INV_CONTENT(ITEM_NAYRUS_LOVE) = ITEM_ROCS_FEATHER; } break; + case RG_SHADOW_SILVER_BLADES: + case RG_SHADOW_SILVER_PIT: + case RG_SHADOW_SILVER_SPIKES: + case RG_SPIRIT_SILVER_CHILD: + case RG_SPIRIT_SILVER_SUN: + case RG_SPIRIT_SILVER_BOULDERS: + case RG_BOTW_SILVER: + case RG_ICE_CAVERN_SILVER_BLADES: + case RG_ICE_CAVERN_SILVER_BLOCK: + case RG_GTG_SILVER_SLOPE: + case RG_GTG_SILVER_LAVA: + case RG_GTG_SILVER_WATER: + case RG_GANONS_CASTLE_SILVER_LIGHT: + case RG_GANONS_CASTLE_SILVER_FOREST: + case RG_GANONS_CASTLE_SILVER_FIRE: + case RG_GANONS_CASTLE_SILVER_SPIRIT: + case RG_DODONGOS_CAVERN_MQ_SILVER: + case RG_SHADOW_MQ_SILVER_BLADES: + case RG_SHADOW_MQ_SILVER_PIT: + case RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES: + case RG_SHADOW_MQ_SILVER_SPIKES: + case RG_SPIRIT_MQ_SILVER_LOBBY: + case RG_SPIRIT_MQ_SILVER_BIG_WALL: + case RG_GTG_MQ_SILVER_SLOPE: + case RG_GTG_MQ_SILVER_LAVA: + case RG_GTG_MQ_SILVER_WATER: + case RG_GANONS_CASTLE_MQ_SILVER_FIRE: + case RG_GANONS_CASTLE_MQ_SILVER_WATER: + case RG_GANONS_CASTLE_MQ_SILVER_SHADOW: { + s8* field = Randomizer::SilverFieldFromSaveContext(&gSaveContext, item); + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SILVER) == + RO_SHUFFLE_SILVER_WALLET) { + *field = 10; + } else { + *field += 1; + } + break; + } default: LUSLOG_WARN("Randomizer_Item_Give didn't have behaviour specified for getItemId=%d", item); assert(false); diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index c577f39e4bb..3f2fc43b038 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -25,6 +25,7 @@ class Randomizer { static Sprite* GetSeedTexture(uint8_t index); bool SpoilerFileExists(const char* spoilerFileName); bool IsTrialRequired(s32 trialFlag); + static s8* SilverFieldFromSaveContext(SaveContext* saveContext, RandomizerGet rg); u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey); RandomizerCheck GetCheckFromRandomizerInf(RandomizerInf randomizerInf); RandomizerInf GetRandomizerInfFromCheck(RandomizerCheck rc); @@ -45,6 +46,7 @@ class Randomizer { CheckIdentity IdentifyBeggar(s32 sceneNum, s32 textId); CheckIdentity IdentifyIcicle(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifyRedIce(s32 sceneNum, s32 posX, s32 posZ); + CheckIdentity IdentifySilver(s32 sceneNum, s32 posX, s32 posZ); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/LogicVal.h b/soh/soh/Enhancements/randomizer/randomizerEnums/LogicVal.h index fc35b4bca58..26168d81fff 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/LogicVal.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/LogicVal.h @@ -177,6 +177,35 @@ RANDO_ENUM_ITEM(LOGIC_OCARINA_C_UP_BUTTON) RANDO_ENUM_ITEM(LOGIC_OCARINA_C_DOWN_BUTTON) RANDO_ENUM_ITEM(LOGIC_OCARINA_C_LEFT_BUTTON) RANDO_ENUM_ITEM(LOGIC_OCARINA_C_RIGHT_BUTTON) +RANDO_ENUM_ITEM(LOGIC_SHADOW_SILVER_BLADES) +RANDO_ENUM_ITEM(LOGIC_SHADOW_SILVER_PIT) +RANDO_ENUM_ITEM(LOGIC_SHADOW_SILVER_SPIKES) +RANDO_ENUM_ITEM(LOGIC_SPIRIT_SILVER_CHILD) +RANDO_ENUM_ITEM(LOGIC_SPIRIT_SILVER_SUN) +RANDO_ENUM_ITEM(LOGIC_SPIRIT_SILVER_BOULDERS) +RANDO_ENUM_ITEM(LOGIC_BOTW_SILVER) +RANDO_ENUM_ITEM(LOGIC_ICE_CAVERN_SILVER_BLADES) +RANDO_ENUM_ITEM(LOGIC_ICE_CAVERN_SILVER_BLOCK) +RANDO_ENUM_ITEM(LOGIC_GTG_SILVER_SLOPE) +RANDO_ENUM_ITEM(LOGIC_GTG_SILVER_LAVA) +RANDO_ENUM_ITEM(LOGIC_GTG_SILVER_WATER) +RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_SILVER_LIGHT) +RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_SILVER_FOREST) +RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_SILVER_FIRE) +RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_SILVER_SPIRIT) +RANDO_ENUM_ITEM(LOGIC_DODONGOS_CAVERN_MQ_SILVER) +RANDO_ENUM_ITEM(LOGIC_SHADOW_MQ_SILVER_BLADES) +RANDO_ENUM_ITEM(LOGIC_SHADOW_MQ_SILVER_PIT) +RANDO_ENUM_ITEM(LOGIC_SHADOW_MQ_SILVER_INVISIBLE_BLADES) +RANDO_ENUM_ITEM(LOGIC_SHADOW_MQ_SILVER_SPIKES) +RANDO_ENUM_ITEM(LOGIC_SPIRIT_MQ_SILVER_LOBBY) +RANDO_ENUM_ITEM(LOGIC_SPIRIT_MQ_SILVER_BIG_WALL) +RANDO_ENUM_ITEM(LOGIC_GTG_MQ_SILVER_SLOPE) +RANDO_ENUM_ITEM(LOGIC_GTG_MQ_SILVER_LAVA) +RANDO_ENUM_ITEM(LOGIC_GTG_MQ_SILVER_WATER) +RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_MQ_SILVER_FIRE) +RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_MQ_SILVER_WATER) +RANDO_ENUM_ITEM(LOGIC_GANONS_CASTLE_MQ_SILVER_SHADOW) RANDO_ENUM_ITEM(LOGIC_TRIFORCE_PIECES) RANDO_ENUM_ITEM(LOGIC_ROCS_FEATHER) RANDO_ENUM_ITEM(LOGIC_CAN_BORROW_MASKS) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h index dfdb5d22c6e..bd93f87bd83 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h @@ -2500,6 +2500,163 @@ RANDO_ENUM_ITEM(RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE) RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL) // End Wonder Items +// Start Silver Rupees +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_BLADES_1) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_BLADES_2) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_BLADES_3) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_BLADES_4) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_BLADES_5) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_PIT_1) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_PIT_2) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_PIT_3) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_PIT_4) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_PIT_5) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_SPIKES_1) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_SPIKES_2) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_SPIKES_3) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_SPIKES_4) +RANDO_ENUM_ITEM(RC_SHADOW_SILVER_SPIKES_5) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_CHILD_1) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_CHILD_2) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_CHILD_3) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_CHILD_4) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_CHILD_5) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_SUN_1) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_SUN_2) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_SUN_3) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_SUN_4) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_SUN_5) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_BOULDERS_1) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_BOULDERS_2) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_BOULDERS_3) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_BOULDERS_4) +RANDO_ENUM_ITEM(RC_SPIRIT_SILVER_BOULDERS_5) +RANDO_ENUM_ITEM(RC_BOTW_SILVER_1) +RANDO_ENUM_ITEM(RC_BOTW_SILVER_2) +RANDO_ENUM_ITEM(RC_BOTW_SILVER_3) +RANDO_ENUM_ITEM(RC_BOTW_SILVER_4) +RANDO_ENUM_ITEM(RC_BOTW_SILVER_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLADES_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLADES_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLADES_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLADES_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLADES_5) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLOCK_1) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLOCK_2) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLOCK_3) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLOCK_4) +RANDO_ENUM_ITEM(RC_ICE_CAVERN_SILVER_BLOCK_5) +RANDO_ENUM_ITEM(RC_GTG_SILVER_SLOPE_1) +RANDO_ENUM_ITEM(RC_GTG_SILVER_SLOPE_2) +RANDO_ENUM_ITEM(RC_GTG_SILVER_SLOPE_3) +RANDO_ENUM_ITEM(RC_GTG_SILVER_SLOPE_4) +RANDO_ENUM_ITEM(RC_GTG_SILVER_SLOPE_5) +RANDO_ENUM_ITEM(RC_GTG_SILVER_LAVA_1) +RANDO_ENUM_ITEM(RC_GTG_SILVER_LAVA_2) +RANDO_ENUM_ITEM(RC_GTG_SILVER_LAVA_3) +RANDO_ENUM_ITEM(RC_GTG_SILVER_LAVA_4) +RANDO_ENUM_ITEM(RC_GTG_SILVER_LAVA_5) +RANDO_ENUM_ITEM(RC_GTG_SILVER_WATER_1) +RANDO_ENUM_ITEM(RC_GTG_SILVER_WATER_2) +RANDO_ENUM_ITEM(RC_GTG_SILVER_WATER_3) +RANDO_ENUM_ITEM(RC_GTG_SILVER_WATER_4) +RANDO_ENUM_ITEM(RC_GTG_SILVER_WATER_5) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_LIGHT_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_LIGHT_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_LIGHT_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_LIGHT_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_LIGHT_5) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FOREST_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FOREST_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FOREST_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FOREST_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FOREST_5) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FIRE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FIRE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FIRE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FIRE_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_FIRE_5) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_SPIRIT_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_SPIRIT_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_SPIRIT_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_SPIRIT_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_SILVER_SPIRIT_5) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_SILVER_1) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_SILVER_2) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_SILVER_3) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_SILVER_4) +RANDO_ENUM_ITEM(RC_DODONGOS_CAVERN_MQ_SILVER_5) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_BLADES_1) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_BLADES_2) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_BLADES_3) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_BLADES_4) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_BLADES_5) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_PIT_1) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_PIT_2) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_PIT_3) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_PIT_4) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_PIT_5) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_1) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_2) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_3) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_4) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_5) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_6) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_7) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_8) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_9) +RANDO_ENUM_ITEM(RC_SHADOW_MQ_SILVER_SPIKES_10) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_LOBBY_1) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_LOBBY_2) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_LOBBY_3) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_LOBBY_4) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_LOBBY_5) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_BIG_WALL_1) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_BIG_WALL_2) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_BIG_WALL_3) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_BIG_WALL_4) +RANDO_ENUM_ITEM(RC_SPIRIT_MQ_SILVER_BIG_WALL_5) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_SLOPE_1) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_SLOPE_2) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_SLOPE_3) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_SLOPE_4) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_SLOPE_5) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_LAVA_1) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_LAVA_2) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_LAVA_3) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_LAVA_4) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_LAVA_5) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_LAVA_6) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_WATER_1) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_WATER_2) +RANDO_ENUM_ITEM(RC_GTG_MQ_SILVER_WATER_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_FIRE_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_FIRE_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_FIRE_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_FIRE_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_FIRE_5) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_WATER_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_WATER_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_WATER_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_WATER_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_WATER_5) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_1) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_2) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_3) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_4) +RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_SILVER_SHADOW_5) +// End Silver Rupees + RANDO_ENUM_ITEM(RC_SFM_FAIRY_GROTTO_FAIRY_1) RANDO_ENUM_ITEM(RC_SFM_FAIRY_GROTTO_FAIRY_2) RANDO_ENUM_ITEM(RC_SFM_FAIRY_GROTTO_FAIRY_3) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerGet.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerGet.h index 3b7806385f6..e23639bb2b5 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerGet.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerGet.h @@ -136,6 +136,35 @@ RANDO_ENUM_ITEM(RG_GERUDO_TRAINING_GROUND_KEY_RING) RANDO_ENUM_ITEM(RG_GERUDO_FORTRESS_KEY_RING) RANDO_ENUM_ITEM(RG_GANONS_CASTLE_KEY_RING) RANDO_ENUM_ITEM(RG_TREASURE_GAME_KEY_RING) +RANDO_ENUM_ITEM(RG_SHADOW_SILVER_BLADES) +RANDO_ENUM_ITEM(RG_SHADOW_SILVER_PIT) +RANDO_ENUM_ITEM(RG_SHADOW_SILVER_SPIKES) +RANDO_ENUM_ITEM(RG_SPIRIT_SILVER_CHILD) +RANDO_ENUM_ITEM(RG_SPIRIT_SILVER_SUN) +RANDO_ENUM_ITEM(RG_SPIRIT_SILVER_BOULDERS) +RANDO_ENUM_ITEM(RG_BOTW_SILVER) +RANDO_ENUM_ITEM(RG_ICE_CAVERN_SILVER_BLADES) +RANDO_ENUM_ITEM(RG_ICE_CAVERN_SILVER_BLOCK) +RANDO_ENUM_ITEM(RG_GTG_SILVER_SLOPE) +RANDO_ENUM_ITEM(RG_GTG_SILVER_LAVA) +RANDO_ENUM_ITEM(RG_GTG_SILVER_WATER) +RANDO_ENUM_ITEM(RG_GANONS_CASTLE_SILVER_LIGHT) +RANDO_ENUM_ITEM(RG_GANONS_CASTLE_SILVER_FOREST) +RANDO_ENUM_ITEM(RG_GANONS_CASTLE_SILVER_FIRE) +RANDO_ENUM_ITEM(RG_GANONS_CASTLE_SILVER_SPIRIT) +RANDO_ENUM_ITEM(RG_DODONGOS_CAVERN_MQ_SILVER) +RANDO_ENUM_ITEM(RG_SHADOW_MQ_SILVER_BLADES) +RANDO_ENUM_ITEM(RG_SHADOW_MQ_SILVER_PIT) +RANDO_ENUM_ITEM(RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES) +RANDO_ENUM_ITEM(RG_SHADOW_MQ_SILVER_SPIKES) +RANDO_ENUM_ITEM(RG_SPIRIT_MQ_SILVER_LOBBY) +RANDO_ENUM_ITEM(RG_SPIRIT_MQ_SILVER_BIG_WALL) +RANDO_ENUM_ITEM(RG_GTG_MQ_SILVER_SLOPE) +RANDO_ENUM_ITEM(RG_GTG_MQ_SILVER_LAVA) +RANDO_ENUM_ITEM(RG_GTG_MQ_SILVER_WATER) +RANDO_ENUM_ITEM(RG_GANONS_CASTLE_MQ_SILVER_FIRE) +RANDO_ENUM_ITEM(RG_GANONS_CASTLE_MQ_SILVER_WATER) +RANDO_ENUM_ITEM(RG_GANONS_CASTLE_MQ_SILVER_SHADOW) RANDO_ENUM_ITEM(RG_KOKIRI_EMERALD) RANDO_ENUM_ITEM(RG_GORON_RUBY) RANDO_ENUM_ITEM(RG_ZORA_SAPPHIRE) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h index b6e8eb6c5eb..1f3c0e2c8f2 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h @@ -1079,6 +1079,7 @@ RANDO_ENUM_ITEM(RHT_SPEAK) RANDO_ENUM_ITEM(RHT_OPEN_CHEST) RANDO_ENUM_ITEM(RHT_FISHING_POLE) RANDO_ENUM_ITEM(RHT_SKELETON_KEY) +RANDO_ENUM_ITEM(RHT_SILVER) RANDO_ENUM_ITEM(RHT_EPONA) RANDO_ENUM_ITEM(RHT_OVERWORLD_KEY) RANDO_ENUM_ITEM(RHT_HINT_MYSTERIOUS) @@ -1444,6 +1445,14 @@ RANDO_ENUM_ITEM(RHT_ICE_CAVERN_HEART) RANDO_ENUM_ITEM(RHT_ICE_CAVERN_RUPEE) RANDO_ENUM_ITEM(RHT_GERUDO_TRAINING_GROUNDS_HEART) RANDO_ENUM_ITEM(RHT_GANONS_CASTLE_HEART) +// Silver Shuffle +RANDO_ENUM_ITEM(RHT_DODONGOS_CAVERN_SILVER) +RANDO_ENUM_ITEM(RHT_SHADOW_TEMPLE_SILVER) +RANDO_ENUM_ITEM(RHT_SPIRIT_TEMPLE_SILVER) +RANDO_ENUM_ITEM(RHT_BOTW_SILVER) +RANDO_ENUM_ITEM(RHT_ICE_CAVERN_SILVER) +RANDO_ENUM_ITEM(RHT_GTG_SILVER) +RANDO_ENUM_ITEM(RHT_GANONS_CASTLE_SILVER) // Fairy Shuffle RANDO_ENUM_ITEM(RHT_SFM_FAIRY_GROTTO_FAIRY) RANDO_ENUM_ITEM(RHT_ZR_FAIRY_GROTTO_FAIRY) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h index ddf673ac489..7af530160fd 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h @@ -1975,6 +1975,163 @@ RANDO_ENUM_ITEM(RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE) RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL) // End Wonder Items +// Start Silver Rupees +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_BLADES_1) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_BLADES_2) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_BLADES_3) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_BLADES_4) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_BLADES_5) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_PIT_1) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_PIT_2) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_PIT_3) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_PIT_4) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_PIT_5) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_SPIKES_1) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_SPIKES_2) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_SPIKES_3) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_SPIKES_4) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_SILVER_SPIKES_5) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_CHILD_1) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_CHILD_2) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_CHILD_3) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_CHILD_4) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_CHILD_5) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_SUN_1) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_SUN_2) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_SUN_3) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_SUN_4) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_SUN_5) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_BOULDERS_1) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_BOULDERS_2) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_BOULDERS_3) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_BOULDERS_4) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_SILVER_BOULDERS_5) +RANDO_ENUM_ITEM(RAND_INF_BOTW_SILVER_1) +RANDO_ENUM_ITEM(RAND_INF_BOTW_SILVER_2) +RANDO_ENUM_ITEM(RAND_INF_BOTW_SILVER_3) +RANDO_ENUM_ITEM(RAND_INF_BOTW_SILVER_4) +RANDO_ENUM_ITEM(RAND_INF_BOTW_SILVER_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLADES_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLADES_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLADES_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLADES_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLADES_5) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLOCK_1) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLOCK_2) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLOCK_3) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLOCK_4) +RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_SILVER_BLOCK_5) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_SLOPE_1) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_SLOPE_2) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_SLOPE_3) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_SLOPE_4) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_SLOPE_5) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_LAVA_1) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_LAVA_2) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_LAVA_3) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_LAVA_4) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_LAVA_5) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_WATER_1) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_WATER_2) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_WATER_3) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_WATER_4) +RANDO_ENUM_ITEM(RAND_INF_GTG_SILVER_WATER_5) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_LIGHT_5) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FOREST_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FOREST_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FOREST_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FOREST_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FOREST_5) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FIRE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FIRE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FIRE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FIRE_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_FIRE_5) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_SILVER_SPIRIT_5) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_1) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_2) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_3) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_4) +RANDO_ENUM_ITEM(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_5) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_BLADES_1) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_BLADES_2) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_BLADES_3) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_BLADES_4) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_BLADES_5) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_PIT_1) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_PIT_2) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_PIT_3) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_PIT_4) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_PIT_5) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_2) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_3) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_4) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_5) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_6) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_7) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_8) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_9) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_10) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_1) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_2) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_3) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_4) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_5) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_6) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_7) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_8) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_9) +RANDO_ENUM_ITEM(RAND_INF_SHADOW_MQ_SILVER_SPIKES_10) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_1) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_2) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_3) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_4) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_LOBBY_5) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_1) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_2) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_3) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_4) +RANDO_ENUM_ITEM(RAND_INF_SPIRIT_MQ_SILVER_BIG_WALL_5) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_SLOPE_1) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_SLOPE_2) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_SLOPE_3) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_SLOPE_4) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_SLOPE_5) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_LAVA_1) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_LAVA_2) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_LAVA_3) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_LAVA_4) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_LAVA_5) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_LAVA_6) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_WATER_1) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_WATER_2) +RANDO_ENUM_ITEM(RAND_INF_GTG_MQ_SILVER_WATER_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_FIRE_5) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_WATER_5) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_1) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_2) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_3) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_4) +RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_SILVER_SHADOW_5) +// End Silver Rupees + RANDO_ENUM_ITEM(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1) RANDO_ENUM_ITEM(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2) RANDO_ENUM_ITEM(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h index 6eb2bb4e082..45018977d31 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h @@ -127,6 +127,7 @@ RANDO_ENUM_ITEM(RCTYPE_OCARINA) // Ocarina locations RANDO_ENUM_ITEM(RCTYPE_BEEHIVE) // Beehives RANDO_ENUM_ITEM(RCTYPE_FISH) // Fishes RANDO_ENUM_ITEM(RCTYPE_FREESTANDING) // Freestanding rupees and hearts +RANDO_ENUM_ITEM(RCTYPE_SILVER) // Silver rupees RANDO_ENUM_ITEM(RCTYPE_FOUNTAIN_FAIRY) // Fairies in Fountains RANDO_ENUM_ITEM(RCTYPE_STONE_FAIRY) // Fairies from Gossip Stones RANDO_ENUM_ITEM(RCTYPE_BEAN_FAIRY) // Fairies from Beans diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h index 8d8fe074c01..312ac324e43 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h @@ -374,6 +374,14 @@ RANDO_ENUM_ITEM(RO_SHUFFLE_WONDER_ITEMS_OVERWORLD) RANDO_ENUM_ITEM(RO_SHUFFLE_WONDER_ITEMS_ALL) RANDO_ENUM_END(RandoOptionWonderItems) +// Shuffle Silver settings (off, on, wallet, start with) +RANDO_ENUM_BEGIN(RandoOptionSilver) +RANDO_ENUM_ITEM(RO_SHUFFLE_SILVER_OFF) +RANDO_ENUM_ITEM(RO_SHUFFLE_SILVER_ON) +RANDO_ENUM_ITEM(RO_SHUFFLE_SILVER_WALLET) +RANDO_ENUM_ITEM(RO_SHUFFLE_SILVER_STARTWITH) +RANDO_ENUM_END(RandoOptionSilver) + // Shuffle Pots settings (off, dungeons, overworld, all) RANDO_ENUM_BEGIN(RandoOptionShufflePots) RANDO_ENUM_ITEM(RO_SHUFFLE_POTS_OFF) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h index 08d489e3db2..660baf73355 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h @@ -241,6 +241,7 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_DEKU_STICK_BAG) RANDO_ENUM_ITEM(RSK_SHUFFLE_DEKU_NUT_BAG) RANDO_ENUM_ITEM(RSK_SHUFFLE_FREESTANDING) RANDO_ENUM_ITEM(RSK_SHUFFLE_WONDER_ITEMS) +RANDO_ENUM_ITEM(RSK_SHUFFLE_SILVER) RANDO_ENUM_ITEM(RSK_SHUFFLE_FOUNTAIN_FAIRIES) RANDO_ENUM_ITEM(RSK_SHUFFLE_STONE_FAIRIES) RANDO_ENUM_ITEM(RSK_SHUFFLE_BEAN_FAIRIES) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index fb9ba56b919..0a62ca591c8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -181,6 +181,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_DUNGEONS) && RandomizerCheckObjects::AreaIsDungeon(location.GetArea()))) && + (location.GetRCType() != RCTYPE_SILVER || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSilver"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_BEEHIVE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_COW || diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 29418cb9184..b0bc464f49b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -67,6 +67,7 @@ bool showBeehives; bool showCows; bool showOverworldFreestanding; bool showDungeonFreestanding; +bool showSilver; bool showAdultTrade; bool showKokiriSword; bool showMasterSword; @@ -1627,6 +1628,8 @@ void LoadSettings() { showDungeonFreestanding = false; break; } + + showSilver = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SILVER); } else { // Vanilla showOverworldFreestanding = false; showDungeonFreestanding = true; @@ -1722,6 +1725,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_FREESTANDING || (showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_SILVER || showSilver) && (loc->GetRCType() != RCTYPE_ADULT_TRADE || showAdultTrade || rc == RC_KAK_ANJU_AS_ADULT || // adult trade checks that are always shuffled rc == RC_DMT_TRADE_CLAIM_CHECK // even when shuffle adult trade is off diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index da024d51650..fc050980c3e 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -224,6 +224,12 @@ void SetStartingItems() { } } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_SILVER) == RO_SHUFFLE_SILVER_STARTWITH) { + for (int rg = (int)RG_SHADOW_SILVER_BLADES; rg <= (int)RG_GANONS_CASTLE_MQ_SILVER_SHADOW; rg++) { + *Randomizer::SilverFieldFromSaveContext(&gSaveContext, (RandomizerGet)rg) = 10; + } + } + if (Randomizer_GetSettingValue(RSK_BOSS_KEYSANITY) == RO_DUNGEON_ITEM_LOC_STARTWITH) { gSaveContext.inventory.dungeonItems[SCENE_FOREST_TEMPLE] |= 1; // Forest gSaveContext.inventory.dungeonItems[SCENE_FIRE_TEMPLE] |= 1; // Fire diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 1acb4d78a8a..730bcc5b4eb 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -1052,6 +1052,7 @@ void Settings::CreateOptions() { }); OPT_U8(RSK_SHUFFLE_FREESTANDING, "Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_FREESTANDING_OFF); OPT_U8(RSK_SHUFFLE_WONDER_ITEMS, "Shuffle Wonder Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWonderItems"), mOptionDescriptions[RSK_SHUFFLE_WONDER_ITEMS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_WONDER_ITEMS_OFF); + OPT_U8(RSK_SHUFFLE_SILVER, "Shuffle Silver Rupees", {"Off", "On", "Wallet", "Start With"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSilver"), mOptionDescriptions[RSK_SHUFFLE_SILVER], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_SILVER_OFF); OPT_U8(RSK_FISHSANITY, "Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WIDGET_CVAR_COMBOBOX, RO_FISHSANITY_OFF); OPT_CALLBACK(RSK_FISHSANITY, { // Hide fishing pond settings if we aren't shuffling the fishing pond @@ -1867,6 +1868,7 @@ void Settings::CreateOptions() { &mOptions[RSK_FISHSANITY_AGE_SPLIT], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_WONDER_ITEMS], + &mOptions[RSK_SHUFFLE_SILVER], &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], @@ -2200,6 +2202,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_WONDER_ITEMS], + &mOptions[RSK_SHUFFLE_SILVER], &mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES], &mOptions[RSK_SHUFFLE_STONE_FAIRIES], &mOptions[RSK_SHUFFLE_BEAN_FAIRIES], diff --git a/soh/soh/Enhancements/randomizer/static_data.cpp b/soh/soh/Enhancements/randomizer/static_data.cpp index 390febf5e80..7874276ed55 100644 --- a/soh/soh/Enhancements/randomizer/static_data.cpp +++ b/soh/soh/Enhancements/randomizer/static_data.cpp @@ -537,4 +537,36 @@ std::vector StaticData::overworldKeys = { RG_HYLIA_LAB_KEY, RG_FISHING_HOLE_KEY, }; + +std::vector StaticData::silverRupees = { + RG_SHADOW_SILVER_BLADES, + RG_SHADOW_SILVER_PIT, + RG_SHADOW_SILVER_SPIKES, + RG_SPIRIT_SILVER_CHILD, + RG_SPIRIT_SILVER_SUN, + RG_SPIRIT_SILVER_BOULDERS, + RG_BOTW_SILVER, + RG_ICE_CAVERN_SILVER_BLADES, + RG_ICE_CAVERN_SILVER_BLOCK, + RG_GTG_SILVER_SLOPE, + RG_GTG_SILVER_LAVA, + RG_GTG_SILVER_WATER, + RG_GANONS_CASTLE_SILVER_LIGHT, + RG_GANONS_CASTLE_SILVER_FOREST, + RG_GANONS_CASTLE_SILVER_FIRE, + RG_GANONS_CASTLE_SILVER_SPIRIT, + RG_DODONGOS_CAVERN_MQ_SILVER, + RG_SHADOW_MQ_SILVER_BLADES, + RG_SHADOW_MQ_SILVER_PIT, + RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES, + RG_SHADOW_MQ_SILVER_SPIKES, + RG_SPIRIT_MQ_SILVER_LOBBY, + RG_SPIRIT_MQ_SILVER_BIG_WALL, + RG_GTG_MQ_SILVER_SLOPE, + RG_GTG_MQ_SILVER_LAVA, + RG_GTG_MQ_SILVER_WATER, + RG_GANONS_CASTLE_MQ_SILVER_FIRE, + RG_GANONS_CASTLE_MQ_SILVER_WATER, + RG_GANONS_CASTLE_MQ_SILVER_SHADOW, +}; } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 241f6794a06..6d332b164e7 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -59,6 +59,7 @@ class StaticData { static void RegisterFairyLocations(); static void RegisterPotLocations(); static void RegisterFreestandingLocations(); + static void RegisterSilverLocations(); static void RegisterGrassLocations(); static void RegisterCrateLocations(); static void RegisterRockLocations(); @@ -93,6 +94,7 @@ class StaticData { static std::vector normalBottles; static std::vector beanSouls; static std::vector overworldKeys; + static std::vector silverRupees; StaticData(); ~StaticData(); diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 0772b93ebd6..4a1440cd46e 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -231,6 +231,43 @@ void SaveManager::LoadRandomizer() { SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->LoadData("bombchuUpgradeLevel", gSaveContext.ship.quest.data.randomizer.bombchuUpgradeLevel); + SaveManager::Instance->LoadData("silverShadowBlades", gSaveContext.ship.quest.data.randomizer.silverShadowBlades); + SaveManager::Instance->LoadData("silverShadowPit", gSaveContext.ship.quest.data.randomizer.silverShadowPit); + SaveManager::Instance->LoadData("silverShadowSpikes", gSaveContext.ship.quest.data.randomizer.silverShadowSpikes); + SaveManager::Instance->LoadData("silverSpiritChild", gSaveContext.ship.quest.data.randomizer.silverSpiritChild); + SaveManager::Instance->LoadData("silverSpiritSun", gSaveContext.ship.quest.data.randomizer.silverSpiritSun); + SaveManager::Instance->LoadData("silverSpiritBoulders", + gSaveContext.ship.quest.data.randomizer.silverSpiritBoulders); + SaveManager::Instance->LoadData("silverBotw", gSaveContext.ship.quest.data.randomizer.silverBotw); + SaveManager::Instance->LoadData("silverIceCavernBlades", + gSaveContext.ship.quest.data.randomizer.silverIceCavernBlades); + SaveManager::Instance->LoadData("silverIceCavernBlock", + gSaveContext.ship.quest.data.randomizer.silverIceCavernBlock); + SaveManager::Instance->LoadData("silverGtgSlope", gSaveContext.ship.quest.data.randomizer.silverGtgSlope); + SaveManager::Instance->LoadData("silverGtgLava", gSaveContext.ship.quest.data.randomizer.silverGtgLava); + SaveManager::Instance->LoadData("silverGtgWater", gSaveContext.ship.quest.data.randomizer.silverGtgWater); + SaveManager::Instance->LoadData("silverGanonLight", gSaveContext.ship.quest.data.randomizer.silverGanonLight); + SaveManager::Instance->LoadData("silverGanonForest", gSaveContext.ship.quest.data.randomizer.silverGanonForest); + SaveManager::Instance->LoadData("silverGanonFire", gSaveContext.ship.quest.data.randomizer.silverGanonFire); + SaveManager::Instance->LoadData("silverGanonSpirit", gSaveContext.ship.quest.data.randomizer.silverGanonSpirit); + SaveManager::Instance->LoadData("silverMqDodongosCavern", + gSaveContext.ship.quest.data.randomizer.silverMqDodongosCavern); + SaveManager::Instance->LoadData("silverMqShadowBlades", + gSaveContext.ship.quest.data.randomizer.silverMqShadowBlades); + SaveManager::Instance->LoadData("silverMqShadowPit", gSaveContext.ship.quest.data.randomizer.silverMqShadowPit); + SaveManager::Instance->LoadData("silverMqShadowInvisibleBlades", + gSaveContext.ship.quest.data.randomizer.silverMqShadowInvisibleBlades); + SaveManager::Instance->LoadData("silverMqShadowSpikes", + gSaveContext.ship.quest.data.randomizer.silverMqShadowSpikes); + SaveManager::Instance->LoadData("silverMqSpiritLobby", gSaveContext.ship.quest.data.randomizer.silverMqSpiritLobby); + SaveManager::Instance->LoadData("silverMqSpiritBigWall", + gSaveContext.ship.quest.data.randomizer.silverMqSpiritBigWall); + SaveManager::Instance->LoadData("silverMqGtgSlope", gSaveContext.ship.quest.data.randomizer.silverMqGtgSlope); + SaveManager::Instance->LoadData("silverMqGtgLava", gSaveContext.ship.quest.data.randomizer.silverMqGtgLava); + SaveManager::Instance->LoadData("silverMqGtgWater", gSaveContext.ship.quest.data.randomizer.silverMqGtgWater); + SaveManager::Instance->LoadData("silverMqGanonFire", gSaveContext.ship.quest.data.randomizer.silverMqGanonFire); + SaveManager::Instance->LoadData("silverMqGanonWater", gSaveContext.ship.quest.data.randomizer.silverMqGanonWater); + SaveManager::Instance->LoadData("silverMqGanonShadow", gSaveContext.ship.quest.data.randomizer.silverMqGanonShadow); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount); @@ -385,6 +422,43 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f SaveManager::Instance->SaveData("triforcePiecesCollected", saveContext->ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->SaveData("bombchuUpgradeLevel", saveContext->ship.quest.data.randomizer.bombchuUpgradeLevel); + SaveManager::Instance->SaveData("silverShadowBlades", gSaveContext.ship.quest.data.randomizer.silverShadowBlades); + SaveManager::Instance->SaveData("silverShadowPit", gSaveContext.ship.quest.data.randomizer.silverShadowPit); + SaveManager::Instance->SaveData("silverShadowSpikes", gSaveContext.ship.quest.data.randomizer.silverShadowSpikes); + SaveManager::Instance->SaveData("silverSpiritChild", gSaveContext.ship.quest.data.randomizer.silverSpiritChild); + SaveManager::Instance->SaveData("silverSpiritSun", gSaveContext.ship.quest.data.randomizer.silverSpiritSun); + SaveManager::Instance->SaveData("silverSpiritBoulders", + gSaveContext.ship.quest.data.randomizer.silverSpiritBoulders); + SaveManager::Instance->SaveData("silverBotw", gSaveContext.ship.quest.data.randomizer.silverBotw); + SaveManager::Instance->SaveData("silverIceCavernBlades", + gSaveContext.ship.quest.data.randomizer.silverIceCavernBlades); + SaveManager::Instance->SaveData("silverIceCavernBlock", + gSaveContext.ship.quest.data.randomizer.silverIceCavernBlock); + SaveManager::Instance->SaveData("silverGtgSlope", gSaveContext.ship.quest.data.randomizer.silverGtgSlope); + SaveManager::Instance->SaveData("silverGtgLava", gSaveContext.ship.quest.data.randomizer.silverGtgLava); + SaveManager::Instance->SaveData("silverGtgWater", gSaveContext.ship.quest.data.randomizer.silverGtgWater); + SaveManager::Instance->SaveData("silverGanonLight", gSaveContext.ship.quest.data.randomizer.silverGanonLight); + SaveManager::Instance->SaveData("silverGanonForest", gSaveContext.ship.quest.data.randomizer.silverGanonForest); + SaveManager::Instance->SaveData("silverGanonFire", gSaveContext.ship.quest.data.randomizer.silverGanonFire); + SaveManager::Instance->SaveData("silverGanonSpirit", gSaveContext.ship.quest.data.randomizer.silverGanonSpirit); + SaveManager::Instance->SaveData("silverMqDodongosCavern", + gSaveContext.ship.quest.data.randomizer.silverMqDodongosCavern); + SaveManager::Instance->SaveData("silverMqShadowBlades", + gSaveContext.ship.quest.data.randomizer.silverMqShadowBlades); + SaveManager::Instance->SaveData("silverMqShadowPit", gSaveContext.ship.quest.data.randomizer.silverMqShadowPit); + SaveManager::Instance->SaveData("silverMqShadowInvisibleBlades", + gSaveContext.ship.quest.data.randomizer.silverMqShadowInvisibleBlades); + SaveManager::Instance->SaveData("silverMqShadowSpikes", + gSaveContext.ship.quest.data.randomizer.silverMqShadowSpikes); + SaveManager::Instance->SaveData("silverMqSpiritLobby", gSaveContext.ship.quest.data.randomizer.silverMqSpiritLobby); + SaveManager::Instance->SaveData("silverMqSpiritBigWall", + gSaveContext.ship.quest.data.randomizer.silverMqSpiritBigWall); + SaveManager::Instance->SaveData("silverMqGtgSlope", gSaveContext.ship.quest.data.randomizer.silverMqGtgSlope); + SaveManager::Instance->SaveData("silverMqGtgLava", gSaveContext.ship.quest.data.randomizer.silverMqGtgLava); + SaveManager::Instance->SaveData("silverMqGtgWater", gSaveContext.ship.quest.data.randomizer.silverMqGtgWater); + SaveManager::Instance->SaveData("silverMqGanonFire", gSaveContext.ship.quest.data.randomizer.silverMqGanonFire); + SaveManager::Instance->SaveData("silverMqGanonWater", gSaveContext.ship.quest.data.randomizer.silverMqGanonWater); + SaveManager::Instance->SaveData("silverMqGanonShadow", gSaveContext.ship.quest.data.randomizer.silverMqGanonShadow); SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->ship.pendingIceTrapCount); diff --git a/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c b/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c index 5337a61bc77..5918516ce44 100644 --- a/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c +++ b/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c @@ -12,6 +12,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_tsubo/object_tsubo.h" #include "objects/object_gi_rupy/object_gi_rupy.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/frame_interpolation.h" #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) @@ -101,7 +102,7 @@ void EnGSwitch_Init(Actor* thisx, PlayState* play) { // "maximum number of checks" osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 最大チェック数 ☆☆☆☆☆ %d\n" VT_RST, this->silverCount); osSyncPrintf("\n\n"); - if (Flags_GetSwitch(play, this->switchFlag)) { + if (GameInteractor_Should(VB_SILVER_DESPAWN, Flags_GetSwitch(play, this->switchFlag), this)) { // This is a reference to Hokuto no Ken osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ You are Shock! ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag); Actor_Kill(&this->actor); @@ -119,7 +120,7 @@ void EnGSwitch_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); this->actor.draw = EnGSwitch_DrawRupee; this->actor.shape.yOffset = 700.0f; - if (Flags_GetSwitch(play, this->switchFlag)) { + if (GameInteractor_Should(VB_SILVER_DESPAWN, Flags_GetSwitch(play, this->switchFlag), this)) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ You are Shock! ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag); Actor_Kill(&this->actor); } else { From 569ec2303467e527316592d7618a6a9d5971691c Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 4 Jan 2026 04:24:06 +0000 Subject: [PATCH 02/14] port improvements from leggettc's version --- .../vanilla-behavior/GIVanillaBehavior.h | 16 +++++ .../Enhancements/randomizer/ShuffleSilver.cpp | 63 ++++++++++++++----- .../Enhancements/randomizer/randomizer.cpp | 7 ++- soh/soh/Enhancements/randomizer/randomizer.h | 2 +- .../actors/ovl_En_G_Switch/z_en_g_switch.c | 44 ++++++------- 5 files changed, 91 insertions(+), 41 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 04b1e4461f1..af0c6795f4b 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2214,6 +2214,22 @@ typedef enum { // - None VB_SHOW_TITLE_CARD, + // #### `result` + // ```c + // this->actor.xyzDistToPlayerSq < 900.0f + // ``` + // #### `args` + // - *EnGSwitch + VB_SILVER_COLLECT, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - *EnGSwitch + VB_SILVER_COUNT_CHECK, + // #### `result` // ```c // Flags_GetSwitch(play, this->switchFlag) diff --git a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp index aff819fa05f..89b490e0b20 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp @@ -87,31 +87,60 @@ static bool IsSilverCleared(s16 switchFlag) { return false; } +extern "C" void EnGSwitch_RandomizerDraw(Actor* thisx, PlayState* play) { + EnGSwitch* silver = reinterpret_cast(thisx); + Matrix_Push(); + Matrix_Scale(17.5f, 17.5f, 17.5f, MTXMODE_APPLY); + if (silver->type == ENGSWITCH_SILVER_RUPEE) { + if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { + GetItemEntry_Draw(play, GET_ITEM_MYSTERY); + } else { + auto silverIdentity = + OTRGlobals::Instance->gRandomizer->IdentifySilver(gPlayState->sceneNum, silver->actor.world.pos); + auto itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(silverIdentity.randomizerCheck, true, GI_NONE); + GetItemEntry_Draw(play, itemEntry); + } + Matrix_Pop(); + } +} + void RegisterShuffleSilver() { bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_SILVER); + COND_VB_SHOULD(VB_SILVER_COLLECT, shouldRegister, { + if (*should) { + EnGSwitch* silver = va_arg(args, EnGSwitch*); + auto silverIdentity = + OTRGlobals::Instance->gRandomizer->IdentifySilver(gPlayState->sceneNum, silver->actor.world.pos); + Flags_SetRandomizerInf(silverIdentity.randomizerInf); + Actor_Kill(&silver->actor); + *should = false; + } + }); + + COND_VB_SHOULD(VB_SILVER_COUNT_CHECK, shouldRegister, { + EnGSwitch* silver = va_arg(args, EnGSwitch*); + *should = false; + if (IsSilverCleared(silver->switchFlag)) { + Flags_SetSwitch(gPlayState, silver->switchFlag); + Actor_Kill(&silver->actor); + } + }); + COND_VB_SHOULD(VB_SILVER_DESPAWN, shouldRegister, { EnGSwitch* silver = va_arg(args, EnGSwitch*); if (silver->type == ENGSWITCH_SILVER_RUPEE) { - auto silverIdentity = OTRGlobals::Instance->gRandomizer->IdentifySilver( - gPlayState->sceneNum, (s16)silver->actor.world.pos.x, (s16)silver->actor.world.pos.z); - *should = true; + auto silverIdentity = + OTRGlobals::Instance->gRandomizer->IdentifySilver(gPlayState->sceneNum, silver->actor.world.pos); if (silverIdentity.randomizerCheck == RC_UNKNOWN_CHECK || Flags_GetRandomizerInf(silverIdentity.randomizerInf)) { + *should = true; return; } - - EnItem00* item00 = - (EnItem00*)Item_DropCollectible2(gPlayState, &silver->actor.world.pos, ITEM00_SOH_DUMMY | 0x4000); - item00->randoCheck = silverIdentity.randomizerCheck; - item00->randoInf = silverIdentity.randomizerInf; - item00->itemEntry = - Rando::Context::GetInstance()->GetFinalGIEntry(silverIdentity.randomizerCheck, false, GI_RUPEE_BLUE); - item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; - } else if (silver->type == ENGSWITCH_SILVER_TRACKER) { - if (IsSilverCleared(silver->switchFlag)) { - Flags_SetSwitch(gPlayState, silver->switchFlag); - } + silver->actor.draw = EnGSwitch_RandomizerDraw; + } else if (silver->type == ENGSWITCH_SILVER_TRACKER && IsSilverCleared(silver->switchFlag)) { + Flags_SetSwitch(gPlayState, silver->switchFlag); *should = true; } }); @@ -214,8 +243,8 @@ void Rando::StaticData::RegisterSilverLocations() { locationTable[RC_SHADOW_MQ_SILVER_BLADES_4] = Location::Collectable(RC_SHADOW_MQ_SILVER_BLADES_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3399, -838 ), "RC_SHADOW_MQ_SILVER_BLADES_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_BLADES_4)); locationTable[RC_SHADOW_MQ_SILVER_BLADES_5] = Location::Collectable(RC_SHADOW_MQ_SILVER_BLADES_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3558, -1490), "RC_SHADOW_MQ_SILVER_BLADES_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_BLADES_5)); locationTable[RC_SHADOW_MQ_SILVER_PIT_1] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(1970, 3372), "RC_SHADOW_MQ_SILVER_PIT_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_1)); - locationTable[RC_SHADOW_MQ_SILVER_PIT_2] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2110, 3372), "RC_SHADOW_MQ_SILVER_PIT_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_2)); - locationTable[RC_SHADOW_MQ_SILVER_PIT_3] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2110, 3372), "RC_SHADOW_MQ_SILVER_PIT_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_3)); + locationTable[RC_SHADOW_MQ_SILVER_PIT_2] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_2, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2110, -970), "RC_SHADOW_MQ_SILVER_PIT_2", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_2)); + locationTable[RC_SHADOW_MQ_SILVER_PIT_3] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_3, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2110, -1092), "RC_SHADOW_MQ_SILVER_PIT_3", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_3)); locationTable[RC_SHADOW_MQ_SILVER_PIT_4] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_4, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2131, 3030), "RC_SHADOW_MQ_SILVER_PIT_4", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_4)); locationTable[RC_SHADOW_MQ_SILVER_PIT_5] = Location::Collectable(RC_SHADOW_MQ_SILVER_PIT_5, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(2250, 3372), "RC_SHADOW_MQ_SILVER_PIT_5", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_PIT_5)); locationTable[RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1] = Location::Collectable(RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1, RCQUEST_MQ, RCTYPE_SILVER, ACTOR_EN_G_SWITCH, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5089, 2049), "RC_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1", RHT_SHADOW_TEMPLE_SILVER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_MQ_SILVER_INVISIBLE_BLADES_1)); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index ad417de2f24..e5da48e7030 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4628,13 +4628,16 @@ CheckIdentity Randomizer::IdentifyRedIce(s32 sceneNum, s32 posX, s32 posZ) { return redIceIdentity; } -CheckIdentity Randomizer::IdentifySilver(s32 sceneNum, s32 posX, s32 posZ) { +CheckIdentity Randomizer::IdentifySilver(s32 sceneNum, Vec3f pos) { struct CheckIdentity silverIdentity; silverIdentity.randomizerInf = RAND_INF_MAX; silverIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + s32 actorParams = TWO_ACTOR_PARAMS((s16)pos.x, (s16)pos.z); + if (sceneNum == SCENE_SHADOW_TEMPLE && actorParams == TWO_ACTOR_PARAMS(2110, 3372)) { + actorParams = TWO_ACTOR_PARAMS((s16)pos.x, (s16)pos.y); + } Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_G_SWITCH, sceneNum, actorParams); diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 3f2fc43b038..87097036730 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -46,7 +46,7 @@ class Randomizer { CheckIdentity IdentifyBeggar(s32 sceneNum, s32 textId); CheckIdentity IdentifyIcicle(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifyRedIce(s32 sceneNum, s32 posX, s32 posZ); - CheckIdentity IdentifySilver(s32 sceneNum, s32 posX, s32 posZ); + CheckIdentity IdentifySilver(s32 sceneNum, Vec3f pos); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c b/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c index 5918516ce44..db8dcd5f390 100644 --- a/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c +++ b/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c @@ -212,28 +212,30 @@ void EnGSwitch_WaitForObject(EnGSwitch* this, PlayState* play) { void EnGSwitch_SilverRupeeTracker(EnGSwitch* this, PlayState* play) { static s8 majorScale[] = { 0, 2, 4, 5, 7, 9, 11, 13, 15, 17 }; - if (this->noteIndex < sCollectedCount) { - if (sCollectedCount < (CVarGetInteger(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), 0) ? 10 : 5)) { - // "sound?" - osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 音? ☆☆☆☆☆ %d\n" VT_RST, this->noteIndex); - Audio_PlaySoundTransposed(&gSfxDefaultPos, NA_SE_EV_FIVE_COUNT_LUPY, majorScale[this->noteIndex]); - this->noteIndex = sCollectedCount; + if (GameInteractor_Should(VB_SILVER_COUNT_CHECK, true, this)) { + if (this->noteIndex < sCollectedCount) { + if (sCollectedCount < (CVarGetInteger(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), 0) ? 10 : 5)) { + // "sound?" + osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 音? ☆☆☆☆☆ %d\n" VT_RST, this->noteIndex); + Audio_PlaySoundTransposed(&gSfxDefaultPos, NA_SE_EV_FIVE_COUNT_LUPY, majorScale[this->noteIndex]); + this->noteIndex = sCollectedCount; + } } - } - if (sCollectedCount >= this->silverCount) { - // "It is now the end of the century." - // This another reference to Hokuto no Ken. - osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 時はまさに世紀末〜 ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag); - // "Last!" - osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ らすとぉ! ☆☆☆☆☆ \n" VT_RST); - if ((play->sceneNum == SCENE_GERUDO_TRAINING_GROUND) && (this->actor.room == 2)) { - Flags_SetTempClear(play, this->actor.room); - } else { - Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); - Flags_SetSwitch(play, this->switchFlag); + if (sCollectedCount >= this->silverCount) { + // "It is now the end of the century." + // This another reference to Hokuto no Ken. + osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 時はまさに世紀末〜 ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag); + // "Last!" + osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ らすとぉ! ☆☆☆☆☆ \n" VT_RST); + if ((play->sceneNum == SCENE_GERUDO_TRAINING_GROUND) && (this->actor.room == 2)) { + Flags_SetTempClear(play, this->actor.room); + } else { + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); + Flags_SetSwitch(play, this->switchFlag); + } + Sfx_PlaySfxCentered(NA_SE_SY_GET_RUPY); + Actor_Kill(&this->actor); } - Sfx_PlaySfxCentered(NA_SE_SY_GET_RUPY); - Actor_Kill(&this->actor); } } @@ -241,7 +243,7 @@ void EnGSwitch_SilverRupeeIdle(EnGSwitch* this, PlayState* play) { Player* player = GET_PLAYER(play); this->actor.shape.rot.y += 0x800; - if (this->actor.xyzDistToPlayerSq < 900.0f) { + if (GameInteractor_Should(VB_SILVER_COLLECT, this->actor.xyzDistToPlayerSq < 900.0f, this)) { Rupees_ChangeBy(5); sCollectedCount++; Sfx_PlaySfxCentered(NA_SE_SY_GET_RUPY); From 68538b8a93806bcdae929447e3c3145606aee42a Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 4 Jan 2026 14:39:04 +0000 Subject: [PATCH 03/14] fix big wall, fix toilet --- .../dungeons/gerudo_training_ground.cpp | 2 +- .../location_access/dungeons/spirit_temple.cpp | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 6d46da5a601..69c9d88ab18 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -189,7 +189,7 @@ void RegionTable_Init_GerudoTrainingGround() { EventAccess(LOGIC_GTG_SILVER_WATER, []{return logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && logic->WaterTimer() >= 24;}), }, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->Get(LOGIC_GTG_SILVER_WATER) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasItem(RG_GTG_SILVER_WATER) && logic->HasItem(RG_OPEN_CHEST)), // 3 & 5 can be retrieved with only iron boots by attempting to backflip underwater LOCATION(RC_GTG_SILVER_WATER_1, logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), LOCATION(RC_GTG_SILVER_WATER_2, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_GOLDEN_SCALE)), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index f23e8aa88a4..760618f99d7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -1073,11 +1073,6 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, logic->CanBreakPots()), - LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_1, true), - LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_2, true), - LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_3, true), - LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_4, true), - LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_5, true), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, true), @@ -1089,10 +1084,16 @@ void RegionTable_Init_SpiritTemple() { //Events //Getting some of these with just climbing downwards is theoretically possible but definitely a trick EVENT_ACCESS(LOGIC_SPIRIT_MQ_BIG_WALL_SILVERS, (logic->CanKillEnemy(RE_KEESE) || logic->CanUse(RG_SKULL_MASK)) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT))), - }, {}, { + }, { + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_1, logic->Get(LOGIC_SPIRIT_MQ_SILVER_BIG_WALL) || logic->TakeDamage()), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_2, logic->Get(LOGIC_SPIRIT_MQ_SILVER_BIG_WALL) || logic->TakeDamage()), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_3, logic->Get(LOGIC_SPIRIT_MQ_SILVER_BIG_WALL) || logic->TakeDamage()), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_4, logic->Get(LOGIC_SPIRIT_MQ_SILVER_BIG_WALL) || logic->TakeDamage()), + LOCATION(RC_SPIRIT_MQ_SILVER_BIG_WALL_5, logic->Get(LOGIC_SPIRIT_MQ_SILVER_BIG_WALL) || logic->TakeDamage()), + }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_BASE, true), - ENTRANCE(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, logic->Get(LOGIC_SPIRIT_MQ_BIG_WALL_SILVERS)), + ENTRANCE(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, logic->HasItem(RG_SPIRIT_MQ_SILVER_BIG_WALL)), }); areaTable[RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL] = Region("Spirit Temple MQ 4F Central", SCENE_SPIRIT_TEMPLE, {}, { From 2f3e61ce73a81d561d4ff8de62549862afba219a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sun, 29 Mar 2026 22:28:19 +0000 Subject: [PATCH 04/14] fixes --- .../location_access/dungeons/bottom_of_the_well.cpp | 2 +- .../location_access/dungeons/gerudo_training_ground.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index 74ecbac27df..a106ba4d8a7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -186,7 +186,7 @@ void RegionTable_Init_BottomOfTheWell() { }); areaTable[RR_BOTW_B3_OOZE] = Region("Bottom of the Well B3 Ooze", SCENE_BOTTOM_OF_THE_WELL, { - EventAccess(LOGIC_BOTW_SILVER, []{return true;}), + EVENT_ACCESS(LOGIC_BOTW_SILVER, true), }, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 69c9d88ab18..77d52ad1efd 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -186,7 +186,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_UNDERWATER] = Region("Gerudo Training Ground Underwater", SCENE_GERUDO_TRAINING_GROUND, { //Events - EventAccess(LOGIC_GTG_SILVER_WATER, []{return logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && logic->WaterTimer() >= 24;}), + EVENT_ACCESS(LOGIC_GTG_SILVER_WATER, logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && logic->WaterTimer() >= 24), }, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasItem(RG_GTG_SILVER_WATER) && logic->HasItem(RG_OPEN_CHEST)), @@ -277,7 +277,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM] = Region("Gerudo Training Ground MQ Left Side", SCENE_GERUDO_TRAINING_GROUND, { //Events - EventAccess(LOGIC_GTG_MQ_SILVER_SLOPE, []{return logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_MQ_WITHOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_HOOKSHOT));}) + EVENT_ACCESS(LOGIC_GTG_MQ_SILVER_SLOPE, logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_GTG_MQ_WITHOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_HOOKSHOT))), }, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BOULDER_ROOM_STALAGMITE_1, logic->CanClearStalagmite()), From 63701f5dfa51f4b7e66a03886308417da6ce3929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sun, 29 Mar 2026 22:27:31 +0000 Subject: [PATCH 05/14] tracker --- .../Enhancements/randomizer/3drando/fill.cpp | 4 +- .../Enhancements/randomizer/SeedContext.cpp | 4 + soh/soh/Enhancements/randomizer/SeedContext.h | 1 + .../Enhancements/randomizer/ShuffleSilver.cpp | 2 +- .../Enhancements/randomizer/hook_handlers.cpp | 15 +- soh/soh/Enhancements/randomizer/logic.cpp | 8 +- .../Enhancements/randomizer/randomizer.cpp | 54 + soh/soh/Enhancements/randomizer/randomizer.h | 3 + .../Enhancements/randomizer/randomizerEnums.h | 1 + .../randomizer/randomizer_check_tracker.cpp | 10 +- .../randomizer/randomizer_item_tracker.cpp | 1258 +++++++++-------- .../randomizer/randomizer_item_tracker.h | 53 +- soh/soh/ResourceManagerHelpers.cpp | 2 +- soh/soh/SohGui/ImGuiUtils.cpp | 22 +- 14 files changed, 821 insertions(+), 616 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 158d125aa91..dd8d96bd0c8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -399,8 +399,8 @@ bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals RandomizerGet locItem = location->GetPlacedRandomizerGet(); RandomizerCheckQuest quest = Rando::StaticData::GetLocation(loc)->GetQuest(); assert(ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || quest == RCQUEST_BOTH || - (quest == RCQUEST_VANILLA && ctx->GetDungeons()->GetDungeonFromScene(parentRegion->scene)->IsVanilla()) || - (quest == RCQUEST_MQ && ctx->GetDungeons()->GetDungeonFromScene(parentRegion->scene)->IsMQ())); + (quest == RCQUEST_VANILLA && ctx->GetDungeonFromScene(parentRegion->scene)->IsVanilla()) || + (quest == RCQUEST_MQ && ctx->GetDungeonFromScene(parentRegion->scene)->IsMQ())); if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, logic->CalculatingAvailableChecks)) { location->AddToPool(); diff --git a/soh/soh/Enhancements/randomizer/SeedContext.cpp b/soh/soh/Enhancements/randomizer/SeedContext.cpp index 76acdfda8b0..30f98f6fa5c 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -525,6 +525,10 @@ DungeonInfo* Context::GetDungeon(size_t key) const { return mDungeons->GetDungeon(static_cast(key)); } +DungeonInfo* Context::GetDungeonFromScene(SceneID scene) const { + return mDungeons->GetDungeonFromScene(scene); +} + std::shared_ptr Context::GetLogic() { if (mLogic.get() == nullptr) { mLogic = std::make_shared(); diff --git a/soh/soh/Enhancements/randomizer/SeedContext.h b/soh/soh/Enhancements/randomizer/SeedContext.h index 46b117616cb..ddebd49f88a 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.h +++ b/soh/soh/Enhancements/randomizer/SeedContext.h @@ -90,6 +90,7 @@ class Context { std::shared_ptr GetDungeons(); std::shared_ptr GetFishsanity(); DungeonInfo* GetDungeon(size_t key) const; + DungeonInfo* GetDungeonFromScene(SceneID key) const; std::shared_ptr GetLogic(); std::shared_ptr GetTrials(); std::shared_ptr GetKaleido(); diff --git a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp index 89b490e0b20..992a05b8487 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp @@ -13,7 +13,7 @@ extern SaveContext gSaveContext; extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); static bool IsSilverCleared(s16 switchFlag) { - bool isMQ = Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(gPlayState->sceneNum)->IsMQ(); + bool isMQ = Rando::Context::GetInstance()->GetDungeonFromScene((SceneID)gPlayState->sceneNum)->IsMQ(); switch (gPlayState->sceneNum) { case SCENE_DODONGOS_CAVERN: return gSaveContext.ship.quest.data.randomizer.silverMqDodongosCavern >= 5; diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 61aa08b2129..5647ecb4b95 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -84,7 +84,7 @@ bool LocMatchesQuest(Rando::Location loc) { if (loc.GetQuest() == RCQUEST_BOTH) { return true; } else { - auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene()); + auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(loc.GetScene()); return (dungeon->IsMQ() && loc.GetQuest() == RCQUEST_MQ) || (dungeon->IsVanilla() && loc.GetQuest() == RCQUEST_VANILLA); } @@ -281,7 +281,7 @@ void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { void RandomizerOnSceneFlagSetHandler(int16_t sceneNum, int16_t flagType, int16_t flag) { if (flagType == FLAG_SCENE_SWITCH) { - auto dungeonInfo = Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(sceneNum); + auto dungeonInfo = Rando::Context::GetInstance()->GetDungeonFromScene((SceneID)sceneNum); bool isVanilla = dungeonInfo == nullptr || dungeonInfo->IsVanilla(); switch (sceneNum) { @@ -1534,8 +1534,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_OKARINA_TAG_COMPLETE: { if (gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL) { - auto dungeon = - OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); + auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); if (dungeon->IsVanilla()) { EnOkarinaTag* enOkarinaTag = va_arg(args, EnOkarinaTag*); if (enOkarinaTag->switchFlag >= 0 && Flags_GetSwitch(gPlayState, enOkarinaTag->switchFlag)) { @@ -1548,8 +1547,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_OKARINA_TAG_COMPLETED: { if (gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL) { - auto dungeon = - OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); + auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); if (dungeon->IsVanilla()) { *should = false; } @@ -2086,7 +2084,7 @@ void RandomizerOnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); if (actor->id == ACTOR_PLAYER) { - auto dungeonInfo = Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(gPlayState->sceneNum); + auto dungeonInfo = Rando::Context::GetInstance()->GetDungeonFromScene((SceneID)gPlayState->sceneNum); bool isVanilla = dungeonInfo == nullptr || dungeonInfo->IsVanilla(); switch (gPlayState->sceneNum) { case SCENE_DEKU_TREE: @@ -2473,8 +2471,7 @@ void RandomizerOnActorInitHandler(void* actorRef) { // Turn MQ switch into toggle if (actor->id == ACTOR_OBJ_SWITCH && gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL && (actor->params & 0x3f07) == 0x303) { - auto dungeon = - OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); + auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); if (dungeon->IsMQ()) { actor->params |= 0x10; } diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index ece29d10a14..7a9444dfb9b 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -299,11 +299,7 @@ bool Logic::HasItem(RandomizerGet itemName) { return Get((LogicVal)(LOGIC_SHADOW_SILVER_BLADES + (itemName - RG_SHADOW_SILVER_BLADES))); } s8 field = *Randomizer::SilverFieldFromSaveContext(mSaveContext, itemName); - return field >= (itemName == RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES || itemName == RG_SHADOW_MQ_SILVER_SPIKES - ? 10 - : itemName == RG_GTG_MQ_SILVER_LAVA ? 6 - : itemName == RG_GTG_MQ_SILVER_WATER ? 3 - : 5); + return field >= Randomizer::SilverTotal(itemName); } // Trade Items case RG_POCKET_EGG: @@ -2454,7 +2450,7 @@ const std::vector& GetThievesHideoutSmallKeyDoors() { const std::vector& GetDungeonSmallKeyDoors(SceneID sceneId) { static const std::vector emptyVector; - auto dungeonInfo = Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(sceneId); + auto dungeonInfo = Rando::Context::GetInstance()->GetDungeonFromScene(sceneId); if (dungeonInfo == nullptr) { return emptyVector; } diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index e5da48e7030..2bd9e7b0192 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -283,6 +283,60 @@ bool Randomizer::IsTrialRequired(s32 trialFlag) { return Rando::Context::GetInstance()->GetTrial(trialFlagToTrialKey[trialFlag])->IsRequired(); } +RandomizerCheckQuest Randomizer::SilverQuest(RandomizerGet rg) { + return rg < RG_DODONGOS_CAVERN_MQ_SILVER ? RCQUEST_VANILLA : RCQUEST_MQ; +} + +SceneID Randomizer::SilverScene(RandomizerGet rg) { + switch (rg) { + case RG_SHADOW_SILVER_BLADES: + case RG_SHADOW_SILVER_PIT: + case RG_SHADOW_SILVER_SPIKES: + case RG_SHADOW_MQ_SILVER_BLADES: + case RG_SHADOW_MQ_SILVER_PIT: + case RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES: + case RG_SHADOW_MQ_SILVER_SPIKES: + return SCENE_SHADOW_TEMPLE; + case RG_SPIRIT_SILVER_CHILD: + case RG_SPIRIT_SILVER_SUN: + case RG_SPIRIT_SILVER_BOULDERS: + case RG_SPIRIT_MQ_SILVER_LOBBY: + case RG_SPIRIT_MQ_SILVER_BIG_WALL: + return SCENE_SPIRIT_TEMPLE; + case RG_BOTW_SILVER: + return SCENE_BOTTOM_OF_THE_WELL; + case RG_ICE_CAVERN_SILVER_BLADES: + case RG_ICE_CAVERN_SILVER_BLOCK: + return SCENE_ICE_CAVERN; + case RG_GTG_SILVER_SLOPE: + case RG_GTG_SILVER_LAVA: + case RG_GTG_SILVER_WATER: + case RG_GTG_MQ_SILVER_SLOPE: + case RG_GTG_MQ_SILVER_LAVA: + case RG_GTG_MQ_SILVER_WATER: + return SCENE_GERUDO_TRAINING_GROUND; + case RG_GANONS_CASTLE_SILVER_LIGHT: + case RG_GANONS_CASTLE_SILVER_FOREST: + case RG_GANONS_CASTLE_SILVER_FIRE: + case RG_GANONS_CASTLE_SILVER_SPIRIT: + case RG_GANONS_CASTLE_MQ_SILVER_FIRE: + case RG_GANONS_CASTLE_MQ_SILVER_WATER: + case RG_GANONS_CASTLE_MQ_SILVER_SHADOW: + return SCENE_INSIDE_GANONS_CASTLE; + case RG_DODONGOS_CAVERN_MQ_SILVER: + return SCENE_DODONGOS_CAVERN; + default: + return SCENE_ID_MAX; + } +} + +s8 Randomizer::SilverTotal(RandomizerGet rg) { + return rg == RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES || rg == RG_SHADOW_MQ_SILVER_SPIKES ? 10 + : rg == RG_GTG_MQ_SILVER_LAVA ? 6 + : rg == RG_GTG_MQ_SILVER_WATER ? 3 + : 5; +} + s8* Randomizer::SilverFieldFromSaveContext(SaveContext* saveContext, RandomizerGet rg) { switch (rg) { case RG_SHADOW_SILVER_BLADES: diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 87097036730..69e67c38a88 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -25,6 +25,9 @@ class Randomizer { static Sprite* GetSeedTexture(uint8_t index); bool SpoilerFileExists(const char* spoilerFileName); bool IsTrialRequired(s32 trialFlag); + static s8 SilverTotal(RandomizerGet rg); + static SceneID SilverScene(RandomizerGet rg); + static RandomizerCheckQuest SilverQuest(RandomizerGet rg); static s8* SilverFieldFromSaveContext(SaveContext* saveContext, RandomizerGet rg); u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey); RandomizerCheck GetCheckFromRandomizerInf(RandomizerInf randomizerInf); diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums.h b/soh/soh/Enhancements/randomizer/randomizerEnums.h index cc625627bb5..b5d4601e244 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums.h @@ -1,3 +1,4 @@ +#pragma once // Default expansion: real enums #if !defined(RANDO_ENUM_BEGIN) && !defined(RANDO_ENUM_ITEM) && !defined(RANDO_ENUM_END) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index b0bc464f49b..373f2269862 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -839,11 +839,10 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { for (auto& loc : Rando::StaticData::GetLocationTable()) { if ((!IS_RANDO && ((loc.GetQuest() == RCQUEST_MQ && !IS_MASTER_QUEST) || (loc.GetQuest() == RCQUEST_VANILLA && IS_MASTER_QUEST))) || - (IS_RANDO && - !(OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene()) == nullptr) && - ((OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene())->IsMQ() && + (IS_RANDO && !(OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(loc.GetScene()) == nullptr) && + ((OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(loc.GetScene())->IsMQ() && loc.GetQuest() == RCQUEST_VANILLA) || - OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene())->IsVanilla() && + OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(loc.GetScene())->IsVanilla() && loc.GetQuest() == RCQUEST_MQ))) { continue; } @@ -1256,8 +1255,7 @@ void CheckTrackerWindow::DrawElement() { areaTotalsTooltipSS << "Checked / Total"; if (showVOrMQ && RandomizerCheckObjects::AreaIsDungeon(rcArea)) { - if (OTRGlobals::Instance->gRandoContext->GetDungeons() - ->GetDungeonFromScene(DungeonSceneLookupByArea(rcArea)) + if (OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(DungeonSceneLookupByArea(rcArea)) ->IsMQ()) { areaTotalsSS << " - MQ"; } else { diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 4db72568050..acac5bac4f8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -11,6 +11,7 @@ #include "randomizerTypes.h" #include "soh/cvar_prefixes.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/randomizer/dungeon.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/SaveManager.h" @@ -60,6 +61,7 @@ static WidgetInfo bossSoulsTracking; static WidgetInfo jabberNutsTracking; static WidgetInfo ocarinaButtonTracking; static WidgetInfo overworldKeysTracking; +static WidgetInfo silverRupeeTracking; static WidgetInfo fishingPoleTracking; static WidgetInfo personalNotesWiget; static WidgetInfo hookshotIdentWidget; @@ -99,35 +101,35 @@ std::vector miscItems = { ITEM_TRACKER_ITEM(ITEM_HEART_CONTAINER, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_HEART_PIECE, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_MAGIC_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM(QUEST_GERUDO_CARD, 1 << 22, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_SKULL_TOKEN, 1 << 23, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_STONE_OF_AGONY, 1 << 21, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_GERUDO_CARD, 1 << 22, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_SKULL_TOKEN, 1 << 23, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_STONE_OF_AGONY, 1 << 21, DrawQuest), }; std::vector dungeonRewardStones = { - ITEM_TRACKER_ITEM(QUEST_KOKIRI_EMERALD, 1 << 18, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_GORON_RUBY, 1 << 19, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_ZORA_SAPPHIRE, 1 << 20, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_KOKIRI_EMERALD, 1 << 18, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_GORON_RUBY, 1 << 19, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_ZORA_SAPPHIRE, 1 << 20, DrawQuest), }; std::vector dungeonRewardMedallions = { - ITEM_TRACKER_ITEM(QUEST_MEDALLION_FOREST, 1 << 0, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_MEDALLION_FIRE, 1 << 1, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_MEDALLION_WATER, 1 << 2, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_MEDALLION_SPIRIT, 1 << 3, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_MEDALLION_SHADOW, 1 << 4, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_MEDALLION_LIGHT, 1 << 5, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_MEDALLION_FOREST, 1 << 0, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_MEDALLION_FIRE, 1 << 1, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_MEDALLION_WATER, 1 << 2, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_MEDALLION_SPIRIT, 1 << 3, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_MEDALLION_SHADOW, 1 << 4, DrawQuest), + ITEM_TRACKER_QUEST(QUEST_MEDALLION_LIGHT, 1 << 5, DrawQuest), }; std::vector dungeonRewards = {}; std::vector songItems = { - ITEM_TRACKER_ITEM(QUEST_SONG_LULLABY, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_EPONA, 0, DrawSong), - ITEM_TRACKER_ITEM(QUEST_SONG_SARIA, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_SUN, 0, DrawSong), - ITEM_TRACKER_ITEM(QUEST_SONG_TIME, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_STORMS, 0, DrawSong), - ITEM_TRACKER_ITEM(QUEST_SONG_MINUET, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_BOLERO, 0, DrawSong), - ITEM_TRACKER_ITEM(QUEST_SONG_SERENADE, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_REQUIEM, 0, DrawSong), - ITEM_TRACKER_ITEM(QUEST_SONG_NOCTURNE, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_PRELUDE, 0, DrawSong), + ITEM_TRACKER_QUEST(QUEST_SONG_LULLABY, 0, DrawSong), ITEM_TRACKER_QUEST(QUEST_SONG_EPONA, 0, DrawSong), + ITEM_TRACKER_QUEST(QUEST_SONG_SARIA, 0, DrawSong), ITEM_TRACKER_QUEST(QUEST_SONG_SUN, 0, DrawSong), + ITEM_TRACKER_QUEST(QUEST_SONG_TIME, 0, DrawSong), ITEM_TRACKER_QUEST(QUEST_SONG_STORMS, 0, DrawSong), + ITEM_TRACKER_QUEST(QUEST_SONG_MINUET, 0, DrawSong), ITEM_TRACKER_QUEST(QUEST_SONG_BOLERO, 0, DrawSong), + ITEM_TRACKER_QUEST(QUEST_SONG_SERENADE, 0, DrawSong), ITEM_TRACKER_QUEST(QUEST_SONG_REQUIEM, 0, DrawSong), + ITEM_TRACKER_QUEST(QUEST_SONG_NOCTURNE, 0, DrawSong), ITEM_TRACKER_QUEST(QUEST_SONG_PRELUDE, 0, DrawSong), }; std::vector gregItems = { @@ -135,101 +137,136 @@ std::vector gregItems = { }; std::vector triforcePieces = { - ITEM_TRACKER_ITEM(RG_TRIFORCE_PIECE, 0, DrawItem), + ITEM_TRACKER_RG(RG_TRIFORCE_PIECE, 0, DrawItem), }; std::vector rocsFeather = { - ITEM_TRACKER_ITEM(RG_ROCS_FEATHER, 0, DrawItem), + ITEM_TRACKER_RG(RG_ROCS_FEATHER, 0, DrawItem), }; std::vector swimItems = { - ITEM_TRACKER_ITEM_CUSTOM(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, ITEM_SCALE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, 0, DrawItem), }; std::vector crawlItems = { - ITEM_TRACKER_ITEM(RG_CRAWL, 0, DrawItem), + ITEM_TRACKER_RG(RG_CRAWL, 0, DrawItem), }; std::vector climbItems = { - ITEM_TRACKER_ITEM(RG_CLIMB, 0, DrawItem), + ITEM_TRACKER_RG(RG_CLIMB, 0, DrawItem), }; std::vector grabItems = { - ITEM_TRACKER_ITEM(RG_POWER_BRACELET, 0, DrawItem), + ITEM_TRACKER_RG(RG_POWER_BRACELET, 0, DrawItem), }; std::vector openChestItems = { - ITEM_TRACKER_ITEM(RG_OPEN_CHEST, 0, DrawItem), + ITEM_TRACKER_RG(RG_OPEN_CHEST, 0, DrawItem), }; std::vector beanSoulItems = { - ITEM_TRACKER_ITEM_CUSTOM(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_DESERT_COLOSSUS_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_GERUDO_VALLEY_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_GRAVEYARD_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_KOKIRI_FOREST_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_LAKE_HYLIA_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_LOST_WOODS_BRIDGE_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_LOST_WOODS_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_ZORAS_RIVER_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_DESERT_COLOSSUS_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GERUDO_VALLEY_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GRAVEYARD_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_KOKIRI_FOREST_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_LAKE_HYLIA_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_LOST_WOODS_BRIDGE_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_LOST_WOODS_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_ZORAS_RIVER_BEAN_SOUL, ITEM_BEAN, 0, DrawItem), }; std::vector bossSoulItems = { - ITEM_TRACKER_ITEM(RG_GOHMA_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_KING_DODONGO_SOUL, 0, DrawItem), - ITEM_TRACKER_ITEM(RG_BARINADE_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_PHANTOM_GANON_SOUL, 0, DrawItem), - ITEM_TRACKER_ITEM(RG_VOLVAGIA_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_MORPHA_SOUL, 0, DrawItem), - ITEM_TRACKER_ITEM(RG_BONGO_BONGO_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_TWINROVA_SOUL, 0, DrawItem), - ITEM_TRACKER_ITEM(RG_GANON_SOUL, 0, DrawItem), + ITEM_TRACKER_RG(RG_GOHMA_SOUL, 0, DrawItem), ITEM_TRACKER_RG(RG_KING_DODONGO_SOUL, 0, DrawItem), + ITEM_TRACKER_RG(RG_BARINADE_SOUL, 0, DrawItem), ITEM_TRACKER_RG(RG_PHANTOM_GANON_SOUL, 0, DrawItem), + ITEM_TRACKER_RG(RG_VOLVAGIA_SOUL, 0, DrawItem), ITEM_TRACKER_RG(RG_MORPHA_SOUL, 0, DrawItem), + ITEM_TRACKER_RG(RG_BONGO_BONGO_SOUL, 0, DrawItem), ITEM_TRACKER_RG(RG_TWINROVA_SOUL, 0, DrawItem), + ITEM_TRACKER_RG(RG_GANON_SOUL, 0, DrawItem), }; std::vector jabbernutItems = { - ITEM_TRACKER_ITEM(RG_SPEAK_DEKU, 0, DrawItem), ITEM_TRACKER_ITEM(RG_SPEAK_GERUDO, 0, DrawItem), - ITEM_TRACKER_ITEM(RG_SPEAK_GORON, 0, DrawItem), ITEM_TRACKER_ITEM(RG_SPEAK_HYLIAN, 0, DrawItem), - ITEM_TRACKER_ITEM(RG_SPEAK_KOKIRI, 0, DrawItem), ITEM_TRACKER_ITEM(RG_SPEAK_ZORA, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPEAK_DEKU, ITEM_NUT, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPEAK_GERUDO, ITEM_NUT, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPEAK_GORON, ITEM_NUT, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPEAK_HYLIAN, ITEM_NUT, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPEAK_KOKIRI, ITEM_NUT, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPEAK_ZORA, ITEM_NUT, 0, DrawItem), }; std::vector ocarinaButtonItems = { // Hack for right now, just gonna draw ocarina buttons as ocarinas. // Will replace with other macro once we have a custom texture - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_A_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_UP_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_DOWN_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_LEFT_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_RIGHT_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_OCARINA_A_BUTTON, ITEM_OCARINA_TIME, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_OCARINA_C_UP_BUTTON, ITEM_OCARINA_TIME, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_OCARINA_C_DOWN_BUTTON, ITEM_OCARINA_TIME, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_OCARINA_C_LEFT_BUTTON, ITEM_OCARINA_TIME, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_OCARINA_C_RIGHT_BUTTON, ITEM_OCARINA_TIME, 0, DrawItem), }; std::vector overworldKeyItems = { // Hack for right now, just gonna overworld keys as dungeon keys. // Will replace with other macro once we have a custom texture - ITEM_TRACKER_ITEM_CUSTOM(RG_GUARD_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_BAZAAR_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_MASK_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_BOMBCHU_BOWLING_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_TREASURE_CHEST_GAME_BUILDING_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_BOMBCHU_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_ALLEY_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_BAZAAR_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_BOSS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_GRANNYS_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_SKULLTULA_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_IMPAS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_WINDMILL_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_DAMPES_HUT_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_TALONS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_STABLES_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_BACK_TOWER_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_HYLIA_LAB_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_FISHING_HOLE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GUARD_HOUSE_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_MARKET_BAZAAR_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_MARKET_POTION_SHOP_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_MASK_SHOP_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_MARKET_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_BOMBCHU_BOWLING_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_TREASURE_CHEST_GAME_BUILDING_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_BOMBCHU_SHOP_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_ALLEY_HOUSE_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_KAK_BAZAAR_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_KAK_POTION_SHOP_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_BOSS_HOUSE_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GRANNYS_POTION_SHOP_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SKULLTULA_HOUSE_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_IMPAS_HOUSE_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_WINDMILL_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_KAK_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_DAMPES_HUT_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_TALONS_HOUSE_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_STABLES_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_BACK_TOWER_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_HYLIA_LAB_KEY, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_FISHING_HOLE_KEY, ITEM_KEY_SMALL, 0, DrawItem), }; std::vector fishingPoleItems = { ITEM_TRACKER_ITEM(ITEM_FISHING_POLE, 0, DrawItem) }; +std::vector silverRupeeItems = { + ITEM_TRACKER_RG_CUSTOM(RG_ICE_CAVERN_SILVER_BLADES, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_ICE_CAVERN_SILVER_BLOCK, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_BOTW_SILVER, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GTG_SILVER_SLOPE, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GTG_SILVER_LAVA, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GTG_SILVER_WATER, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPIRIT_SILVER_CHILD, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPIRIT_SILVER_SUN, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPIRIT_SILVER_BOULDERS, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SHADOW_SILVER_BLADES, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SHADOW_SILVER_PIT, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SHADOW_SILVER_SPIKES, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GANONS_CASTLE_SILVER_LIGHT, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GANONS_CASTLE_SILVER_FOREST, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GANONS_CASTLE_SILVER_FIRE, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GANONS_CASTLE_SILVER_SPIRIT, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_DODONGOS_CAVERN_MQ_SILVER, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SHADOW_MQ_SILVER_BLADES, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SHADOW_MQ_SILVER_PIT, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SHADOW_MQ_SILVER_SPIKES, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPIRIT_MQ_SILVER_LOBBY, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_SPIRIT_MQ_SILVER_BIG_WALL, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GTG_MQ_SILVER_SLOPE, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GTG_MQ_SILVER_LAVA, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GTG_MQ_SILVER_WATER, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GANONS_CASTLE_MQ_SILVER_FIRE, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GANONS_CASTLE_MQ_SILVER_WATER, ITEM_RUPEE_SILVER, 0, DrawItem), + ITEM_TRACKER_RG_CUSTOM(RG_GANONS_CASTLE_MQ_SILVER_SHADOW, ITEM_RUPEE_SILVER, 0, DrawItem), +}; + std::vector itemTrackerDungeonsWithMapsHorizontal = { { SCENE_DEKU_TREE, { ITEM_DUNGEON_MAP, ITEM_COMPASS } }, { SCENE_DODONGOS_CAVERN, { ITEM_DUNGEON_MAP, ITEM_COMPASS } }, @@ -505,132 +542,133 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { result.maxCapacity = 0; result.currentAmmo = 0; - switch (item.id) { - case ITEM_STICK: - result.currentCapacity = CUR_CAPACITY(UPG_STICKS); - result.maxCapacity = 30; - result.currentAmmo = AMMO(ITEM_STICK); - break; - case ITEM_NUT: - result.currentCapacity = CUR_CAPACITY(UPG_NUTS); - result.maxCapacity = 40; - result.currentAmmo = AMMO(ITEM_NUT); - break; - case ITEM_BOMB: - result.currentCapacity = CUR_CAPACITY(UPG_BOMB_BAG); - result.maxCapacity = 40; - result.currentAmmo = AMMO(ITEM_BOMB); - break; - case ITEM_BOW: - result.currentCapacity = CUR_CAPACITY(UPG_QUIVER); - result.maxCapacity = 50; - result.currentAmmo = AMMO(ITEM_BOW); - break; - case ITEM_SLINGSHOT: - result.currentCapacity = CUR_CAPACITY(UPG_BULLET_BAG); - result.maxCapacity = 50; - result.currentAmmo = AMMO(ITEM_SLINGSHOT); - break; - case ITEM_WALLET_ADULT: - case ITEM_WALLET_GIANT: - result.currentCapacity = - IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET); - result.maxCapacity = - IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999 - : 500; - result.currentAmmo = gSaveContext.rupees; - break; - case ITEM_BOMBCHU: { - auto bombchuBag = RAND_GET_OPTION(RSK_BOMBCHU_BAG); - - uint8_t capacity = 0; - - if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU) { - if (bombchuBag.Is(RO_BOMBCHU_BAG_PROGRESSIVE)) { - capacity = OTRGlobals::Instance->gRandoContext->GetBombchuCapacity(); - } else { - capacity = 50; + if (item.kind == ITEM_KIND_ITEM) { + switch (item.id) { + case ITEM_STICK: + result.currentCapacity = CUR_CAPACITY(UPG_STICKS); + result.maxCapacity = 30; + result.currentAmmo = AMMO(ITEM_STICK); + break; + case ITEM_NUT: + result.currentCapacity = CUR_CAPACITY(UPG_NUTS); + result.maxCapacity = 40; + result.currentAmmo = AMMO(ITEM_NUT); + break; + case ITEM_BOMB: + result.currentCapacity = CUR_CAPACITY(UPG_BOMB_BAG); + result.maxCapacity = 40; + result.currentAmmo = AMMO(ITEM_BOMB); + break; + case ITEM_BOW: + result.currentCapacity = CUR_CAPACITY(UPG_QUIVER); + result.maxCapacity = 50; + result.currentAmmo = AMMO(ITEM_BOW); + break; + case ITEM_SLINGSHOT: + result.currentCapacity = CUR_CAPACITY(UPG_BULLET_BAG); + result.maxCapacity = 50; + result.currentAmmo = AMMO(ITEM_SLINGSHOT); + break; + case ITEM_WALLET_ADULT: + case ITEM_WALLET_GIANT: + result.currentCapacity = + IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET); + result.maxCapacity = + IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) + ? 999 + : 500; + result.currentAmmo = gSaveContext.rupees; + break; + case ITEM_BOMBCHU: { + auto bombchuBag = RAND_GET_OPTION(RSK_BOMBCHU_BAG); + + uint8_t capacity = 0; + + if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU) { + if (bombchuBag.Is(RO_BOMBCHU_BAG_PROGRESSIVE)) { + capacity = OTRGlobals::Instance->gRandoContext->GetBombchuCapacity(); + } else { + capacity = 50; + } } - } - result.currentCapacity = capacity; - result.maxCapacity = 50; - result.currentAmmo = AMMO(ITEM_BOMBCHU); - break; - } - case ITEM_BEAN: - result.currentCapacity = INV_CONTENT(ITEM_BEAN) == ITEM_BEAN ? 10 : 0; - result.maxCapacity = 10; - result.currentAmmo = AMMO(ITEM_BEAN); - break; - case QUEST_SKULL_TOKEN: - result.maxCapacity = result.currentCapacity = 100; - result.currentAmmo = gSaveContext.inventory.gsTokens; - break; - case ITEM_HEART_CONTAINER: - result.maxCapacity = result.currentCapacity = 8; - result.currentAmmo = gSaveContext.ship.stats.heartContainers; - break; - case ITEM_HEART_PIECE: - result.maxCapacity = result.currentCapacity = 36; - result.currentAmmo = gSaveContext.ship.stats.heartPieces; - break; - case ITEM_KEY_SMALL: - // Though the ammo/capacity naming doesn't really make sense for keys, we are - // hijacking the same system to display key counts as there are enough similarities - result.currentAmmo = MAX(gSaveContext.inventory.dungeonKeys[item.data], 0); - result.currentCapacity = gSaveContext.ship.stats.dungeonKeys[item.data]; - switch (item.data) { - case SCENE_FOREST_TEMPLE: - result.maxCapacity = FOREST_TEMPLE_SMALL_KEY_MAX; - break; - case SCENE_FIRE_TEMPLE: - result.maxCapacity = FIRE_TEMPLE_SMALL_KEY_MAX; - break; - case SCENE_WATER_TEMPLE: - result.maxCapacity = WATER_TEMPLE_SMALL_KEY_MAX; - break; - case SCENE_SPIRIT_TEMPLE: - result.maxCapacity = SPIRIT_TEMPLE_SMALL_KEY_MAX; - break; - case SCENE_SHADOW_TEMPLE: - result.maxCapacity = SHADOW_TEMPLE_SMALL_KEY_MAX; - break; - case SCENE_BOTTOM_OF_THE_WELL: - result.maxCapacity = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; - break; - case SCENE_GERUDO_TRAINING_GROUND: - result.maxCapacity = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; - break; - case SCENE_THIEVES_HIDEOUT: - if (IS_RANDO) { - switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)) { - case RO_GF_CARPENTERS_NORMAL: - result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX; - break; - case RO_GF_CARPENTERS_FAST: - result.maxCapacity = 1; - break; - case RO_GF_CARPENTERS_FREE: - result.maxCapacity = 0; - break; - default: - result.maxCapacity = 0; - SPDLOG_ERROR( - "Invalid value for RSK_GERUDO_FORTRESS: {}", - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)); - assert(false); - break; + result.currentCapacity = capacity; + result.maxCapacity = 50; + result.currentAmmo = AMMO(ITEM_BOMBCHU); + } break; + case ITEM_BEAN: + result.currentCapacity = INV_CONTENT(ITEM_BEAN) == ITEM_BEAN ? 10 : 0; + result.maxCapacity = 10; + result.currentAmmo = AMMO(ITEM_BEAN); + break; + case ITEM_HEART_CONTAINER: + result.maxCapacity = result.currentCapacity = 8; + result.currentAmmo = gSaveContext.ship.stats.heartContainers; + break; + case ITEM_HEART_PIECE: + result.maxCapacity = result.currentCapacity = 36; + result.currentAmmo = gSaveContext.ship.stats.heartPieces; + break; + case ITEM_KEY_SMALL: + // Though the ammo/capacity naming doesn't really make sense for keys, we are + // hijacking the same system to display key counts as there are enough similarities + result.currentAmmo = MAX(gSaveContext.inventory.dungeonKeys[item.data], 0); + result.currentCapacity = gSaveContext.ship.stats.dungeonKeys[item.data]; + switch (item.data) { + case SCENE_FOREST_TEMPLE: + result.maxCapacity = FOREST_TEMPLE_SMALL_KEY_MAX; + break; + case SCENE_FIRE_TEMPLE: + result.maxCapacity = FIRE_TEMPLE_SMALL_KEY_MAX; + break; + case SCENE_WATER_TEMPLE: + result.maxCapacity = WATER_TEMPLE_SMALL_KEY_MAX; + break; + case SCENE_SPIRIT_TEMPLE: + result.maxCapacity = SPIRIT_TEMPLE_SMALL_KEY_MAX; + break; + case SCENE_SHADOW_TEMPLE: + result.maxCapacity = SHADOW_TEMPLE_SMALL_KEY_MAX; + break; + case SCENE_BOTTOM_OF_THE_WELL: + result.maxCapacity = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; + break; + case SCENE_GERUDO_TRAINING_GROUND: + result.maxCapacity = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; + break; + case SCENE_THIEVES_HIDEOUT: + if (IS_RANDO) { + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)) { + case RO_GF_CARPENTERS_NORMAL: + result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX; + break; + case RO_GF_CARPENTERS_FAST: + result.maxCapacity = 1; + break; + case RO_GF_CARPENTERS_FREE: + result.maxCapacity = 0; + break; + default: + result.maxCapacity = 0; + SPDLOG_ERROR( + "Invalid value for RSK_GERUDO_FORTRESS: {}", + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)); + assert(false); + break; + } + } else { + result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX; } - } else { - result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX; - } - break; - case SCENE_INSIDE_GANONS_CASTLE: - result.maxCapacity = GANONS_CASTLE_SMALL_KEY_MAX; - break; - } - break; + break; + case SCENE_INSIDE_GANONS_CASTLE: + result.maxCapacity = GANONS_CASTLE_SMALL_KEY_MAX; + break; + } + break; + } + } else if (item.kind == ITEM_KIND_QUEST && item.id == QUEST_SKULL_TOKEN) { + result.maxCapacity = result.currentCapacity = 100; + result.currentAmmo = gSaveContext.inventory.gsTokens; } return result; @@ -799,6 +837,27 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { ImGui::PushStyleColor(ImGuiCol_Text, maxColor); ImGui::Text("%s", maxString.c_str()); ImGui::PopStyleColor(); + } else if (item.id >= RG_SHADOW_SILVER_BLADES && item.id <= RG_GANONS_CASTLE_MQ_SILVER_SHADOW && IS_RANDO && + OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_SILVER).Get() && IsValidSaveFile()) { + RandomizerGet rg = static_cast(item.id); + std::string current = ""; + std::string max = ""; + uint8_t rupees = *Randomizer::SilverFieldFromSaveContext(&gSaveContext, rg); + uint8_t rupeesMax = Randomizer::SilverTotal(rg); + ImU32 currentColor = rupees >= rupeesMax ? IM_COL_GREEN : IM_COL_WHITE; + ImU32 maxColor = IM_COL_GREEN; + current += std::to_string(rupees); + current += "/"; + max += std::to_string(rupeesMax); + ImGui::SetCursorScreenPos( + ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize((current + max).c_str()).x / 2), p.y - 14)); + ImGui::PushStyleColor(ImGuiCol_Text, currentColor); + ImGui::Text("%d/", rupees); + ImGui::PopStyleColor(); + ImGui::SameLine(0, 0.0f); + ImGui::PushStyleColor(ImGuiCol_Text, maxColor); + ImGui::Text("%d", rupeesMax); + ImGui::PopStyleColor(); } else { ImGui::SetCursorScreenPos(ImVec2(p.x, p.y - 14)); ImGui::Text(""); @@ -841,373 +900,408 @@ bool HasBossSoul(RandomizerInf bossSoul) { } void DrawItem(ItemTrackerItem item) { - uint32_t actualItemId = GameInteractor::IsSaveLoaded() ? INV_CONTENT(item.id) : ITEM_NONE; float iconSize = static_cast(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36)); bool hasItem = actualItemId != ITEM_NONE; std::string itemName = ""; - // Hack fix as RG_MARKET_SHOOTING_GALLERY_KEY is RandomizerGet #255 which collides - // with ITEM_NONE (ItemId #255) due to the lack of a modid to separate them - if (item.name != "ITEM_KEY_SMALL" && item.id == ITEM_NONE) { - return; - } - - switch (item.id) { - case ITEM_HEART_CONTAINER: - actualItemId = item.id; - hasItem = gSaveContext.ship.stats.heartContainers > 0; - break; - case ITEM_HEART_PIECE: - actualItemId = item.id; - hasItem = gSaveContext.ship.stats.heartPieces > 0; - break; - case ITEM_MAGIC_SMALL: - case ITEM_MAGIC_LARGE: - actualItemId = gSaveContext.magicLevel == 2 ? ITEM_MAGIC_LARGE : ITEM_MAGIC_SMALL; - hasItem = gSaveContext.magicLevel > 0; - break; - case ITEM_WALLET_ADULT: - case ITEM_WALLET_GIANT: - actualItemId = CUR_UPG_VALUE(UPG_WALLET) == 2 ? ITEM_WALLET_GIANT : ITEM_WALLET_ADULT; - hasItem = !IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_WALLET); - break; - case ITEM_BRACELET: - case ITEM_GAUNTLETS_SILVER: - case ITEM_GAUNTLETS_GOLD: - actualItemId = CUR_UPG_VALUE(UPG_STRENGTH) >= 3 ? ITEM_GAUNTLETS_GOLD - : CUR_UPG_VALUE(UPG_STRENGTH) == 2 ? ITEM_GAUNTLETS_SILVER - : ITEM_BRACELET; - hasItem = CUR_UPG_VALUE(UPG_STRENGTH) > 0; - break; - case ITEM_SCALE_SILVER: - case ITEM_SCALE_GOLDEN: - actualItemId = CUR_UPG_VALUE(UPG_SCALE) == 2 ? ITEM_SCALE_GOLDEN : ITEM_SCALE_SILVER; - hasItem = CUR_UPG_VALUE(UPG_SCALE) > 0; - break; - case ITEM_RUPEE_GREEN: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_GREG_FOUND); - break; - case RG_TRIFORCE_PIECE: - actualItemId = item.id; - hasItem = IS_RANDO && (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) != - RO_TRIFORCE_HUNT_OFF); - itemName = "Triforce Piece"; - break; - case ITEM_NAYRUS_LOVE: - if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_ROCS_FEATHER)) { - hasItem = Flags_GetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE); - } - break; - case RG_ROCS_FEATHER: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_OBTAINED_ROCS_FEATHER); - itemName = "Roc's Feather"; - break; - case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL); - itemName = "Death Mountain Crater Bean Soul"; - break; - case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL); - itemName = "Death Mountain Trail Bean Soul"; - break; - case RG_DESERT_COLOSSUS_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL); - itemName = "Desert Colossus Bean Soul"; - break; - case RG_GERUDO_VALLEY_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_GERUDO_VALLEY_BEAN_SOUL); - itemName = "Gerudo Valley Bean Soul"; - break; - case RG_GRAVEYARD_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_GRAVEYARD_BEAN_SOUL); - itemName = "Graveyard Bean Soul"; - break; - case RG_KOKIRI_FOREST_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_KOKIRI_FOREST_BEAN_SOUL); - itemName = "Kokiri Forest Bean Soul"; - break; - case RG_LAKE_HYLIA_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_LAKE_HYLIA_BEAN_SOUL); - itemName = "Lake Hylia Bean Soul"; - break; - case RG_LOST_WOODS_BRIDGE_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL); - itemName = "Lost Woods Bridge Bean Soul"; - break; - case RG_LOST_WOODS_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_LOST_WOODS_BEAN_SOUL); - itemName = "Lost Woods Theatre Bean Soul"; - break; - case RG_ZORAS_RIVER_BEAN_SOUL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_ZORAS_RIVER_BEAN_SOUL); - itemName = "Zora's River Bean Soul"; - break; - case RG_GOHMA_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_GOHMA_SOUL); - itemName = "Gohma's Soul"; - break; - case RG_KING_DODONGO_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_KING_DODONGO_SOUL); - itemName = "King Dodongo's Soul"; - break; - case RG_BARINADE_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_BARINADE_SOUL); - itemName = "Barinade's Soul"; - break; - case RG_PHANTOM_GANON_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_PHANTOM_GANON_SOUL); - itemName = "Phantom Ganon's Soul"; - break; - case RG_VOLVAGIA_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_VOLVAGIA_SOUL); - itemName = "Volvagia's Soul"; - break; - case RG_MORPHA_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_MORPHA_SOUL); - itemName = "Morpha's Soul"; - break; - case RG_BONGO_BONGO_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_BONGO_BONGO_SOUL); - itemName = "Bongo Bongo's Soul"; - break; - case RG_TWINROVA_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_TWINROVA_SOUL); - itemName = "Twinrova's Soul"; - break; - case RG_GANON_SOUL: - actualItemId = item.id; - hasItem = HasBossSoul(RAND_INF_GANON_SOUL); - itemName = "Ganon's Soul"; - break; - - case RG_SPEAK_DEKU: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_DEKU); - itemName = "Deku Jabber Nut"; - break; - case RG_SPEAK_GERUDO: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_GERUDO); - itemName = "Gerudo Jabber Nut"; - break; - case RG_SPEAK_GORON: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_GORON); - itemName = "Goron Jabber Nut"; - break; - case RG_SPEAK_HYLIAN: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_HYLIAN); - itemName = "Hylian Jabber Nut"; - break; - case RG_SPEAK_KOKIRI: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_KOKIRI); - itemName = "Kokiri Jabber Nut"; - break; - case RG_SPEAK_ZORA: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_ZORA); - itemName = "Zora Jabber Nut"; - break; - - case RG_OCARINA_A_BUTTON: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A); - itemName = "Ocarina A Button"; - break; - case RG_OCARINA_C_UP_BUTTON: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP); - itemName = "Ocarina C Up Button"; - break; - case RG_OCARINA_C_DOWN_BUTTON: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); - itemName = "Ocarina C Down Button"; - break; - case RG_OCARINA_C_LEFT_BUTTON: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT); - itemName = "Ocarina C Left Button"; - break; - case RG_OCARINA_C_RIGHT_BUTTON: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT); - itemName = "Ocarina C Right Button"; - break; - case ITEM_FISHING_POLE: - actualItemId = item.id; - hasItem = IS_RANDO && Flags_GetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); - itemName = "Fishing Pole"; - break; - - case RG_GUARD_HOUSE_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_GUARD_HOUSE_KEY_OBTAINED); - itemName = "Guard House Key"; - break; - case RG_MARKET_BAZAAR_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_MARKET_BAZAAR_KEY_OBTAINED); - itemName = "Market Bazaar Key"; - break; - case RG_MARKET_POTION_SHOP_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED); - itemName = "Market Potion Shop Key"; - break; - case RG_MASK_SHOP_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_MASK_SHOP_KEY_OBTAINED); - itemName = "Mask Shop Key"; - break; - case RG_MARKET_SHOOTING_GALLERY_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED); - itemName = "Market Shooting Gallery Key"; - break; - case RG_BOMBCHU_BOWLING_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED); - itemName = "Bombchu Bowling Key"; - break; - case RG_TREASURE_CHEST_GAME_BUILDING_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED); - itemName = "Treasure Chest Game Building Key"; - break; - case RG_BOMBCHU_SHOP_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED); - itemName = "Bombchu Shop Key"; - break; - case RG_RICHARDS_HOUSE_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED); - itemName = "Richards House Key"; - break; - case RG_ALLEY_HOUSE_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_ALLEY_HOUSE_KEY_OBTAINED); - itemName = "Alley House Key"; - break; - case RG_KAK_BAZAAR_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_KAK_BAZAAR_KEY_OBTAINED); - itemName = "Kak Bazaar Key"; - break; - case RG_KAK_POTION_SHOP_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED); - itemName = "Kak Potion Shop Key"; - break; - case RG_BOSS_HOUSE_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_BOSS_HOUSE_KEY_OBTAINED); - itemName = "Boss House Key"; - break; - case RG_GRANNYS_POTION_SHOP_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED); - itemName = "Granny's Potion Shop Key"; - break; - case RG_SKULLTULA_HOUSE_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED); - itemName = "Skulltula House Key"; - break; - case RG_IMPAS_HOUSE_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_IMPAS_HOUSE_KEY_OBTAINED); - itemName = "Impa's House Key"; - break; - case RG_WINDMILL_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_WINDMILL_KEY_OBTAINED); - itemName = "Windmill Key"; - break; - case RG_KAK_SHOOTING_GALLERY_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED); - itemName = "Kak Shooting Gallery Key"; - break; - case RG_DAMPES_HUT_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_DAMPES_HUT_KEY_OBTAINED); - itemName = "Dampé's Hut Key"; - break; - case RG_TALONS_HOUSE_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_TALONS_HOUSE_KEY_OBTAINED); - itemName = "Talon's House Key"; - break; - case RG_STABLES_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_STABLES_KEY_OBTAINED); - itemName = "Stables Key"; - break; - case RG_BACK_TOWER_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_BACK_TOWER_KEY_OBTAINED); - itemName = "Back Tower Key"; - break; - case RG_HYLIA_LAB_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_HYLIA_LAB_KEY_OBTAINED); - itemName = "Hylia Lab Key"; - break; - case RG_FISHING_HOLE_KEY: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_FISHING_HOLE_KEY_OBTAINED); - itemName = "Fishing Hole Key"; - break; - case RG_BRONZE_SCALE: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SWIM); - itemName = "Swim"; - break; - case RG_CRAWL: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_CRAWL); - itemName = "Crawl"; - break; - case RG_CLIMB: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_CLIMB); - itemName = "Climb"; - break; - case RG_POWER_BRACELET: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_GRAB); - itemName = "Grab"; - break; - case RG_OPEN_CHEST: - actualItemId = item.id; - hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); - itemName = "Open"; - break; + if (item.kind == ITEM_KIND_ITEM) { + switch (item.id) { + case ITEM_HEART_CONTAINER: + actualItemId = item.id; + hasItem = gSaveContext.ship.stats.heartContainers > 0; + break; + case ITEM_HEART_PIECE: + actualItemId = item.id; + hasItem = gSaveContext.ship.stats.heartPieces > 0; + break; + case ITEM_MAGIC_SMALL: + case ITEM_MAGIC_LARGE: + actualItemId = gSaveContext.magicLevel == 2 ? ITEM_MAGIC_LARGE : ITEM_MAGIC_SMALL; + hasItem = gSaveContext.magicLevel > 0; + break; + case ITEM_WALLET_ADULT: + case ITEM_WALLET_GIANT: + actualItemId = CUR_UPG_VALUE(UPG_WALLET) == 2 ? ITEM_WALLET_GIANT : ITEM_WALLET_ADULT; + hasItem = !IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_WALLET); + break; + case ITEM_BRACELET: + case ITEM_GAUNTLETS_SILVER: + case ITEM_GAUNTLETS_GOLD: + actualItemId = CUR_UPG_VALUE(UPG_STRENGTH) >= 3 ? ITEM_GAUNTLETS_GOLD + : CUR_UPG_VALUE(UPG_STRENGTH) == 2 ? ITEM_GAUNTLETS_SILVER + : ITEM_BRACELET; + hasItem = CUR_UPG_VALUE(UPG_STRENGTH) > 0; + break; + case ITEM_SCALE_SILVER: + case ITEM_SCALE_GOLDEN: + actualItemId = CUR_UPG_VALUE(UPG_SCALE) == 2 ? ITEM_SCALE_GOLDEN : ITEM_SCALE_SILVER; + hasItem = CUR_UPG_VALUE(UPG_SCALE) > 0; + break; + case ITEM_RUPEE_GREEN: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_GREG_FOUND); + break; + case ITEM_NONE: // spacer, don't render + return; + } + } else if (item.kind == ITEM_KIND_RG) { + switch (item.id) { + case RG_TRIFORCE_PIECE: + actualItemId = item.id; + hasItem = IS_RANDO && (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) != + RO_TRIFORCE_HUNT_OFF); + itemName = "Triforce Piece"; + break; + case ITEM_NAYRUS_LOVE: + if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_ROCS_FEATHER)) { + hasItem = Flags_GetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE); + } + break; + case RG_ROCS_FEATHER: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_OBTAINED_ROCS_FEATHER); + itemName = "Roc's Feather"; + break; + case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL); + itemName = "Death Mountain Crater Bean Soul"; + break; + case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL); + itemName = "Death Mountain Trail Bean Soul"; + break; + case RG_DESERT_COLOSSUS_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL); + itemName = "Desert Colossus Bean Soul"; + break; + case RG_GERUDO_VALLEY_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_GERUDO_VALLEY_BEAN_SOUL); + itemName = "Gerudo Valley Bean Soul"; + break; + case RG_GRAVEYARD_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_GRAVEYARD_BEAN_SOUL); + itemName = "Graveyard Bean Soul"; + break; + case RG_KOKIRI_FOREST_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_KOKIRI_FOREST_BEAN_SOUL); + itemName = "Kokiri Forest Bean Soul"; + break; + case RG_LAKE_HYLIA_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_LAKE_HYLIA_BEAN_SOUL); + itemName = "Lake Hylia Bean Soul"; + break; + case RG_LOST_WOODS_BRIDGE_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL); + itemName = "Lost Woods Bridge Bean Soul"; + break; + case RG_LOST_WOODS_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_LOST_WOODS_BEAN_SOUL); + itemName = "Lost Woods Theatre Bean Soul"; + break; + case RG_ZORAS_RIVER_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_ZORAS_RIVER_BEAN_SOUL); + itemName = "Zora's River Bean Soul"; + break; + case RG_GOHMA_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_GOHMA_SOUL); + itemName = "Gohma's Soul"; + break; + case RG_KING_DODONGO_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_KING_DODONGO_SOUL); + itemName = "King Dodongo's Soul"; + break; + case RG_BARINADE_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_BARINADE_SOUL); + itemName = "Barinade's Soul"; + break; + case RG_PHANTOM_GANON_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_PHANTOM_GANON_SOUL); + itemName = "Phantom Ganon's Soul"; + break; + case RG_VOLVAGIA_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_VOLVAGIA_SOUL); + itemName = "Volvagia's Soul"; + break; + case RG_MORPHA_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_MORPHA_SOUL); + itemName = "Morpha's Soul"; + break; + case RG_BONGO_BONGO_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_BONGO_BONGO_SOUL); + itemName = "Bongo Bongo's Soul"; + break; + case RG_TWINROVA_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_TWINROVA_SOUL); + itemName = "Twinrova's Soul"; + break; + case RG_GANON_SOUL: + actualItemId = item.id; + hasItem = HasBossSoul(RAND_INF_GANON_SOUL); + itemName = "Ganon's Soul"; + break; + + case RG_SPEAK_DEKU: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_DEKU); + itemName = "Deku Jabber Nut"; + break; + case RG_SPEAK_GERUDO: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_GERUDO); + itemName = "Gerudo Jabber Nut"; + break; + case RG_SPEAK_GORON: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_GORON); + itemName = "Goron Jabber Nut"; + break; + case RG_SPEAK_HYLIAN: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_HYLIAN); + itemName = "Hylian Jabber Nut"; + break; + case RG_SPEAK_KOKIRI: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_KOKIRI); + itemName = "Kokiri Jabber Nut"; + break; + case RG_SPEAK_ZORA: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK_ZORA); + itemName = "Zora Jabber Nut"; + break; + + case RG_OCARINA_A_BUTTON: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A); + itemName = "Ocarina A Button"; + break; + case RG_OCARINA_C_UP_BUTTON: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP); + itemName = "Ocarina C Up Button"; + break; + case RG_OCARINA_C_DOWN_BUTTON: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); + itemName = "Ocarina C Down Button"; + break; + case RG_OCARINA_C_LEFT_BUTTON: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT); + itemName = "Ocarina C Left Button"; + break; + case RG_OCARINA_C_RIGHT_BUTTON: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT); + itemName = "Ocarina C Right Button"; + break; + case ITEM_FISHING_POLE: + actualItemId = item.id; + hasItem = IS_RANDO && Flags_GetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); + itemName = "Fishing Pole"; + break; + + case RG_GUARD_HOUSE_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_GUARD_HOUSE_KEY_OBTAINED); + itemName = "Guard House Key"; + break; + case RG_MARKET_BAZAAR_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_MARKET_BAZAAR_KEY_OBTAINED); + itemName = "Market Bazaar Key"; + break; + case RG_MARKET_POTION_SHOP_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED); + itemName = "Market Potion Shop Key"; + break; + case RG_MASK_SHOP_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_MASK_SHOP_KEY_OBTAINED); + itemName = "Mask Shop Key"; + break; + case RG_MARKET_SHOOTING_GALLERY_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED); + itemName = "Market Shooting Gallery Key"; + break; + case RG_BOMBCHU_BOWLING_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED); + itemName = "Bombchu Bowling Key"; + break; + case RG_TREASURE_CHEST_GAME_BUILDING_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED); + itemName = "Treasure Chest Game Building Key"; + break; + case RG_BOMBCHU_SHOP_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED); + itemName = "Bombchu Shop Key"; + break; + case RG_RICHARDS_HOUSE_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED); + itemName = "Richards House Key"; + break; + case RG_ALLEY_HOUSE_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_ALLEY_HOUSE_KEY_OBTAINED); + itemName = "Alley House Key"; + break; + case RG_KAK_BAZAAR_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_KAK_BAZAAR_KEY_OBTAINED); + itemName = "Kak Bazaar Key"; + break; + case RG_KAK_POTION_SHOP_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED); + itemName = "Kak Potion Shop Key"; + break; + case RG_BOSS_HOUSE_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_BOSS_HOUSE_KEY_OBTAINED); + itemName = "Boss House Key"; + break; + case RG_GRANNYS_POTION_SHOP_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED); + itemName = "Granny's Potion Shop Key"; + break; + case RG_SKULLTULA_HOUSE_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED); + itemName = "Skulltula House Key"; + break; + case RG_IMPAS_HOUSE_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_IMPAS_HOUSE_KEY_OBTAINED); + itemName = "Impa's House Key"; + break; + case RG_WINDMILL_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_WINDMILL_KEY_OBTAINED); + itemName = "Windmill Key"; + break; + case RG_KAK_SHOOTING_GALLERY_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED); + itemName = "Kak Shooting Gallery Key"; + break; + case RG_DAMPES_HUT_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_DAMPES_HUT_KEY_OBTAINED); + itemName = "Dampé's Hut Key"; + break; + case RG_TALONS_HOUSE_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_TALONS_HOUSE_KEY_OBTAINED); + itemName = "Talon's House Key"; + break; + case RG_STABLES_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_STABLES_KEY_OBTAINED); + itemName = "Stables Key"; + break; + case RG_BACK_TOWER_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_BACK_TOWER_KEY_OBTAINED); + itemName = "Back Tower Key"; + break; + case RG_HYLIA_LAB_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_HYLIA_LAB_KEY_OBTAINED); + itemName = "Hylia Lab Key"; + break; + case RG_SHADOW_SILVER_BLADES: + case RG_SHADOW_SILVER_PIT: + case RG_SHADOW_SILVER_SPIKES: + case RG_SPIRIT_SILVER_CHILD: + case RG_SPIRIT_SILVER_SUN: + case RG_SPIRIT_SILVER_BOULDERS: + case RG_BOTW_SILVER: + case RG_ICE_CAVERN_SILVER_BLADES: + case RG_ICE_CAVERN_SILVER_BLOCK: + case RG_GTG_SILVER_SLOPE: + case RG_GTG_SILVER_LAVA: + case RG_GTG_SILVER_WATER: + case RG_GANONS_CASTLE_SILVER_LIGHT: + case RG_GANONS_CASTLE_SILVER_FOREST: + case RG_GANONS_CASTLE_SILVER_FIRE: + case RG_GANONS_CASTLE_SILVER_SPIRIT: + case RG_DODONGOS_CAVERN_MQ_SILVER: + case RG_SHADOW_MQ_SILVER_BLADES: + case RG_SHADOW_MQ_SILVER_PIT: + case RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES: + case RG_SHADOW_MQ_SILVER_SPIKES: + case RG_SPIRIT_MQ_SILVER_LOBBY: + case RG_SPIRIT_MQ_SILVER_BIG_WALL: + case RG_GTG_MQ_SILVER_SLOPE: + case RG_GTG_MQ_SILVER_LAVA: + case RG_GTG_MQ_SILVER_WATER: + case RG_GANONS_CASTLE_MQ_SILVER_FIRE: + case RG_GANONS_CASTLE_MQ_SILVER_WATER: + case RG_GANONS_CASTLE_MQ_SILVER_SHADOW: + actualItemId = item.id; + hasItem = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_SILVER).Get(); + itemName = Rando::StaticData::RetrieveItem(static_cast(actualItemId)) + .GetName() + .GetForLanguage(CVarGetInteger(CVAR_SETTING("Languages"), LANGUAGE_ENG)); + break; + case RG_FISHING_HOLE_KEY: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_FISHING_HOLE_KEY_OBTAINED); + itemName = "Fishing Hole Key"; + break; + case RG_BRONZE_SCALE: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_SWIM); + itemName = "Swim"; + break; + case RG_CRAWL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_CRAWL); + itemName = "Crawl"; + break; + case RG_CLIMB: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_CLIMB); + itemName = "Climb"; + break; + case RG_POWER_BRACELET: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_GRAB); + itemName = "Grab"; + break; + case RG_OPEN_CHEST: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); + itemName = "Open"; + break; + } } if (GameInteractor::IsSaveLoaded() && @@ -1285,7 +1379,7 @@ void DrawItem(ItemTrackerItem item) { ImGui::EndGroup(); - if (itemName == "") { + if (itemName == "" && item.kind == ITEM_KIND_ITEM) { itemName = SohUtils::GetItemName(item.id); } @@ -1788,6 +1882,23 @@ void UpdateVectors() { mainWindowItems.insert(mainWindowItems.end(), overworldKeyItems.begin(), overworldKeyItems.end()); } + // If we're adding silver rupees to the main window... + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.SilverRupees"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_MAIN_WINDOW) { + while (mainWindowItems.size() % 6) { + mainWindowItems.push_back(ITEM_TRACKER_ITEM(ITEM_NONE, 0, DrawItem)); + } + for (auto silverRupee : silverRupeeItems) { + SceneID dungeonScene = Randomizer::SilverScene(static_cast(silverRupee.id)); + RandomizerCheckQuest dungeonQuest = + OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(dungeonScene)->IsMQ() ? RCQUEST_MQ + : RCQUEST_VANILLA; + if (dungeonQuest == Randomizer::SilverQuest(static_cast(silverRupee.id))) { + mainWindowItems.push_back(silverRupee); + } + } + } + shouldUpdateVectors = false; } @@ -1980,6 +2091,23 @@ void ItemTrackerWindow::DrawElement() { EndFloatingWindows(); } + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.SilverRupees"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { + std::vector questMatchingSilverRupeeItems; + for (auto silverRupee : silverRupeeItems) { + SceneID dungeonScene = Randomizer::SilverScene(static_cast(silverRupee.id)); + RandomizerCheckQuest dungeonQuest = + OTRGlobals::Instance->gRandoContext->GetDungeonFromScene(dungeonScene)->IsMQ() ? RCQUEST_MQ + : RCQUEST_VANILLA; + if (dungeonQuest == Randomizer::SilverQuest(static_cast(silverRupee.id))) { + questMatchingSilverRupeeItems.push_back(silverRupee); + } + } + BeginFloatingWindows("Silver Rupee Tracker"); + DrawItemsInRows(questMatchingSilverRupeeItems); + EndFloatingWindows(); + } + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.FishingPole"), SECTION_DISPLAY_EXTENDED_HIDDEN) == SECTION_DISPLAY_EXTENDED_SEPARATE) { BeginFloatingWindows("Fishing Pole Tracker"); @@ -2186,6 +2314,7 @@ void ItemTrackerSettingsWindow::DrawElement() { SohGui::mSohMenu->MenuDrawItem(jabberNutsTracking, 250, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(ocarinaButtonTracking, 250, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(overworldKeysTracking, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(silverRupeeTracking, 250, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(fishingPoleTracking, 250, THEME_COLOR); if (CVarCombobox("Total Checks", CVAR_TRACKER_ITEM("TotalChecks.DisplayType"), minimalDisplayTypes, @@ -2383,6 +2512,19 @@ void RegisterItemTrackerWidgets() { SohGui::mSohMenu->AddSearchWidget( { fishingPoleTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + silverRupeeTracking = { .name = "Silver Rupees", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + silverRupeeTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.SilverRupees")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(displayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget( + { silverRupeeTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + personalNotesWiget = { .name = "Personal notes", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; static const char* notesDisabledTooltip = "Disabled because tracker is set to floating and display combo is enabled."; diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h index 0538e9f71ad..04e844dccfe 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h @@ -7,8 +7,15 @@ void DrawItemAmmo(int itemId); +typedef enum ItemKind { + ITEM_KIND_ITEM, + ITEM_KIND_QUEST, + ITEM_KIND_RG, +} ItemKind; + typedef struct ItemTrackerItem { uint32_t id; + ItemKind kind; std::string name; std::string nameFaded; uint32_t data; @@ -20,26 +27,36 @@ bool HasQuestItem(ItemTrackerItem); bool HasEquipment(ItemTrackerItem); #define ITEM_TRACKER_ITEM(id, data, drawFunc) \ - { id, #id, #id "_Faded", data, drawFunc } + { id, ITEM_KIND_ITEM, #id, #id "_Faded", data, drawFunc } +#define ITEM_TRACKER_ITEM_CUSTOM(id, name, data, drawFunc) \ + { id, ITEM_KIND_ITEM, #name, #name "_Faded", data, drawFunc } + +#define ITEM_TRACKER_QUEST(id, data, drawFunc) \ + { id, ITEM_KIND_QUEST, #id, #id "_Faded", data, drawFunc } +#define ITEM_TRACKER_QUEST_CUSTOM(id, name, data, drawFunc) \ + { id, ITEM_KIND_QUEST, #name, #name "_Faded", data, drawFunc } -#define ITEM_TRACKER_ITEM_CUSTOM(id, name, nameFaded, data, drawFunc) \ - { id, #name, #nameFaded "_Faded", data, drawFunc } +#define ITEM_TRACKER_RG(id, data, drawFunc) \ + { id, ITEM_KIND_RG, #id, #id "_Faded", data, drawFunc } +#define ITEM_TRACKER_RG_CUSTOM(id, name, data, drawFunc) \ + { id, ITEM_KIND_RG, #name, #name "_Faded", data, drawFunc } -static std::vector itemTrackerWindowIDs = { "Item Tracker", - "Inventory Items Tracker", - "Equipment Items Tracker", - "Misc Items Tracker", - "Dungeon Rewards Tracker", - "Songs Tracker", - "Dungeon Items Tracker", - "Greg Tracker", - "Triforce Piece Tracker", - "Boss Soul Tracker", - "Ocarina Button Tracker", - "Overworld Key Tracker", - "Fishing Pole Tracker", - "Personal Notes", - "Total Checks" }; +static std::array itemTrackerWindowIDs = { "Item Tracker", + "Inventory Items Tracker", + "Equipment Items Tracker", + "Misc Items Tracker", + "Dungeon Rewards Tracker", + "Songs Tracker", + "Dungeon Items Tracker", + "Greg Tracker", + "Triforce Piece Tracker", + "Boss Soul Tracker", + "Ocarina Button Tracker", + "Overworld Key Tracker", + "Silver Rupee Tracker", + "Fishing Pole Tracker", + "Personal Notes", + "Total Checks" }; void ItemTracker_LoadFromPreset(nlohmann::json trackerInfo); typedef struct ItemTrackerDungeon { diff --git a/soh/soh/ResourceManagerHelpers.cpp b/soh/soh/ResourceManagerHelpers.cpp index 56399e52ce6..29950ecf7f5 100644 --- a/soh/soh/ResourceManagerHelpers.cpp +++ b/soh/soh/ResourceManagerHelpers.cpp @@ -103,7 +103,7 @@ u32 IsSceneMasterQuest(s16 sceneNum) { } if (IS_RANDO) { - auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(sceneNum); + auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeonFromScene((SceneID)sceneNum); if (dungeon != nullptr && dungeon->IsMQ()) { return true; } diff --git a/soh/soh/SohGui/ImGuiUtils.cpp b/soh/soh/SohGui/ImGuiUtils.cpp index 9ea36ebd08e..e75a6971830 100644 --- a/soh/soh/SohGui/ImGuiUtils.cpp +++ b/soh/soh/SohGui/ImGuiUtils.cpp @@ -159,15 +159,6 @@ std::map actionShuffleMapping = { { RG_POWER_BRACELET, { RG_POWER_BRACELET, "RG_POWER_BRACELET", "RG_POWER_BRACELET_Faded", gButtonBackgroundTex } }, }; -std::map jabbernutMapping = { - { RG_SPEAK_DEKU, { RG_SPEAK_DEKU, "RG_SPEAK_DEKU", "RG_SPEAK_DEKU_Faded", (char*)gItemIcons[ITEM_NUT] } }, - { RG_SPEAK_GERUDO, { RG_SPEAK_GERUDO, "RG_SPEAK_GERUDO", "RG_SPEAK_GERUDO_Faded", (char*)gItemIcons[ITEM_NUT] } }, - { RG_SPEAK_GORON, { RG_SPEAK_GORON, "RG_SPEAK_GORON", "RG_SPEAK_GORON_Faded", (char*)gItemIcons[ITEM_NUT] } }, - { RG_SPEAK_HYLIAN, { RG_SPEAK_HYLIAN, "RG_SPEAK_HYLIAN", "RG_SPEAK_HYLIAN_Faded", (char*)gItemIcons[ITEM_NUT] } }, - { RG_SPEAK_KOKIRI, { RG_SPEAK_KOKIRI, "RG_SPEAK_KOKIRI", "RG_SPEAK_KOKIRI_Faded", (char*)gItemIcons[ITEM_NUT] } }, - { RG_SPEAK_ZORA, { RG_SPEAK_ZORA, "RG_SPEAK_ZORA", "RG_SPEAK_ZORA_Faded", (char*)gItemIcons[ITEM_NUT] } }, -}; - std::map questMapping = { QUEST_MAP_ENTRY(QUEST_MEDALLION_FOREST, dgQuestIconMedallionForestTex), QUEST_MAP_ENTRY(QUEST_MEDALLION_FIRE, dgQuestIconMedallionFireTex), @@ -250,12 +241,13 @@ void RegisterImGuiItemIcons() { ->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } - for (const auto& entry : jabbernutMapping) { - std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()) - ->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); - std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()) - ->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); - } + ImVec4 silver = ImVec4(0.7f, 0.7f, 0.7f, 1.0f); + ImVec4 silverFaded = silver; + silverFaded.w = 0.3f; + std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_RUPEE_SILVER", gRupeeCounterIconTex, silver); + std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()) + ->LoadGuiTexture("ITEM_RUPEE_SILVER_Faded", gRupeeCounterIconTex, silverFaded); for (const auto& entry : questMapping) { std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()) From aca528b9e28e8cf30a38e0629956538773838f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Wed, 1 Apr 2026 04:48:48 +0000 Subject: [PATCH 06/14] SCENE_WATER_TEMPLE --- soh/soh/Enhancements/randomizer/logic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 7a9444dfb9b..e01f0e907b4 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2367,7 +2367,7 @@ void Logic::InitSaveContext() { mSaveContext->horseData.angle = -0x6AD9; mSaveContext->magicLevel = 0; mSaveContext->infTable[29] = 1; - mSaveContext->sceneFlags[5].swch = 0x40000000; + mSaveContext->sceneFlags[SCENE_WATER_TEMPLE].swch = 0x40000000; // SoH specific mSaveContext->ship.backupFW = mSaveContext->fw; From 4d73e016274aa020e82f37183b2d16e14f2584ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 2 Apr 2026 03:03:40 +0000 Subject: [PATCH 07/14] fix rendering --- soh/soh/Enhancements/randomizer/draw.cpp | 52 ++++++++++++++++-------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 59bdd6e214c..43b4729ac68 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -14,6 +14,7 @@ extern "C" { #include "variables.h" #include "dungeon.h" #include "objects/object_box/object_box.h" +#include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_gi_key/object_gi_key.h" #include "objects/object_gi_bosskey/object_gi_bosskey.h" #include "objects/object_gi_bracelet/object_gi_bracelet.h" @@ -35,11 +36,11 @@ extern "C" { #include "objects/object_mo/object_mo.h" #include "objects/object_mori_objects/object_mori_objects.h" #include "objects/object_sst/object_sst.h" -#include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h" #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" #include "objects/object_gi_shield_1/object_gi_shield_1.h" #include "objects/object_mo/object_mo.h" +#include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h" extern PlayState* gPlayState; extern SaveContext gSaveContext; } @@ -1284,22 +1285,41 @@ extern "C" void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemE extern "C" void Randomizer_DrawSilverRupee(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); - Gfx_SetupDL_25Opa(play->state.gfxCtx); - - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); - - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, 255, 255, 255, 255); - gDPSetEnvColor(POLY_OPA_DISP++, 255 / 5, 255 / 5, 255 / 5, 255); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiRupeeInnerDL); - - Gfx_SetupDL_25Xlu(play->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, 255); - gDPSetEnvColor(POLY_XLU_DISP++, 255 * 0.75f, 255 * 0.75f, 255 * 0.75f, 255); - gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiRupeeOuterDL); - + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + Color_RGB8 defaultColor = { 255, 255, 255 }; + if (CVarGetInteger("gNewDrops", 0) != 0) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + Color_RGB8 silverRupeeColor = CVarGetColor24("gCosmetics.Consumable_SilverRupee.Value", defaultColor); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, silverRupeeColor.r, silverRupeeColor.g, silverRupeeColor.b, 255); + gDPSetEnvColor(POLY_OPA_DISP++, silverRupeeColor.r / 5, silverRupeeColor.g / 5, silverRupeeColor.b / 5, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiRupeeInnerDL); + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, silverRupeeColor.r * 0.75f, silverRupeeColor.g * 0.75f, + silverRupeeColor.b * 0.75f, 255); + gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiRupeeOuterDL); + } else { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + if (CVarGetInteger("gCosmetics.Consumable_SilverRupee.Changed", 0)) { + Color_RGB8 rupeeColor = CVarGetColor24("gCosmetics.Consumable_SilverRupee.Value", defaultColor); + gDPSetGrayscaleColor(POLY_OPA_DISP++, rupeeColor.r, rupeeColor.g, rupeeColor.b, 255); + gSPGrayscale(POLY_OPA_DISP++, true); + gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL((uintptr_t)gRupeeSilverTex)); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gRupeeDL); + gSPGrayscale(POLY_OPA_DISP++, false); + } else { + gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL((uintptr_t)gRupeeSilverTex)); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gRupeeDL); + } + } CLOSE_DISPS(play->state.gfxCtx); } From f3ac99701f5d800f7a71c999d5f574e8b633e34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 2 Apr 2026 06:39:51 +0000 Subject: [PATCH 08/14] fix tracker putting number on greg by being more strict about item.kind --- .../randomizer/randomizer_item_tracker.cpp | 104 +++++++++--------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index acac5bac4f8..f21e4bca440 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -515,14 +515,17 @@ bool IsValidSaveFile() { } bool HasSong(ItemTrackerItem item) { + assert(item.kind == ITEM_KIND_QUEST); return GameInteractor::IsSaveLoaded() ? ((1 << item.id) & gSaveContext.inventory.questItems) : false; } bool HasQuestItem(ItemTrackerItem item) { + assert(item.kind == ITEM_KIND_QUEST); return GameInteractor::IsSaveLoaded() ? (item.data & gSaveContext.inventory.questItems) : false; } bool HasEquipment(ItemTrackerItem item) { + assert(item.kind == ITEM_KIND_ITEM); return GameInteractor::IsSaveLoaded() ? (item.data & gSaveContext.inventory.equipment) : false; } @@ -693,30 +696,27 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY); int32_t trackerKeyNumberDisplayMode = CVarGetInteger(CVAR_TRACKER_ITEM("KeyCounts"), KEYS_COLLECTED_MAX); float textScalingFactor = static_cast(iconSize) / 36.0f; - uint32_t actualItemId = INV_CONTENT(item.id); - bool hasItem = actualItemId != ITEM_NONE; - - if (CVarGetInteger(CVAR_TRACKER_ITEM("HookshotIdentifier"), 0)) { - if ((actualItemId == ITEM_HOOKSHOT || actualItemId == ITEM_LONGSHOT) && hasItem) { - - // Calculate the scaled position for the text - ImVec2 textPos = - ImVec2(p.x + (iconSize / 2) - - (ImGui::CalcTextSize(item.id == ITEM_HOOKSHOT ? "H" : "L").x * textScalingFactor / 2) + - 8 * textScalingFactor, - p.y - 22 * textScalingFactor); - - ImGui::SetCursorScreenPos(textPos); - ImGui::SetWindowFontScale(textScalingFactor); - - ImGui::Text(item.id == ITEM_HOOKSHOT ? "H" : "L"); - ImGui::SetWindowFontScale(1.0f); // Reset font scale to the original state - } + uint32_t actualItemId = item.kind == ITEM_KIND_ITEM ? INV_CONTENT(item.id) : ITEM_NONE; + + if (CVarGetInteger(CVAR_TRACKER_ITEM("HookshotIdentifier"), 0) && + (actualItemId == ITEM_HOOKSHOT || actualItemId == ITEM_LONGSHOT)) { + // Calculate the scaled position for the text + ImVec2 textPos = + ImVec2(p.x + (iconSize / 2) - + (ImGui::CalcTextSize(item.id == ITEM_HOOKSHOT ? "H" : "L").x * textScalingFactor / 2) + + 8 * textScalingFactor, + p.y - 22 * textScalingFactor); + + ImGui::SetCursorScreenPos(textPos); + ImGui::SetWindowFontScale(textScalingFactor); + + ImGui::Text(item.id == ITEM_HOOKSHOT ? "H" : "L"); + ImGui::SetWindowFontScale(1.0f); // Reset font scale to the original state } ImGui::SetWindowFontScale(textSize / 13.0f); - if (item.id == ITEM_KEY_SMALL && IsValidSaveFile()) { + if (item.kind == ITEM_KIND_ITEM && item.id == ITEM_KEY_SMALL && IsValidSaveFile()) { std::string currentString = ""; std::string maxString = hideMax ? "???" : std::to_string(currentAndMax.maxCapacity); ImU32 currentColor = IM_COL_WHITE; @@ -747,17 +747,19 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { std::string currentString = ""; std::string maxString = ""; ImU32 currentColor = IM_COL_WHITE; - ImU32 maxColor = item.id == QUEST_SKULL_TOKEN ? IM_COL_RED : IM_COL_GREEN; + ImU32 maxColor = item.kind == ITEM_KIND_QUEST && item.id == QUEST_SKULL_TOKEN ? IM_COL_RED : IM_COL_GREEN; bool shouldAlignToLeft = CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountAlignLeft"), 0) && trackerNumberDisplayMode != ITEM_TRACKER_NUMBER_CAPACITY && trackerNumberDisplayMode != ITEM_TRACKER_NUMBER_AMMO; - bool shouldDisplayAmmo = trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_AMMO || - trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY || - // These items have a static capacity, so display ammo instead - item.id == ITEM_BEAN || item.id == QUEST_SKULL_TOKEN || - item.id == ITEM_HEART_CONTAINER || item.id == ITEM_HEART_PIECE; + bool shouldDisplayAmmo = + trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_AMMO || + trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY || + // These items have a static capacity, so display ammo instead + (item.kind == ITEM_KIND_QUEST && item.id == QUEST_SKULL_TOKEN) || + (item.kind == ITEM_KIND_ITEM && + (item.id == ITEM_BEAN || item.id == ITEM_HEART_CONTAINER || item.id == ITEM_HEART_PIECE)); bool shouldDisplayMax = !(trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY); @@ -765,7 +767,7 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { if (shouldDisplayAmmo) { currentString = std::to_string(currentAndMax.currentAmmo); if (currentAndMax.currentAmmo >= currentAndMax.currentCapacity) { - if (item.id == QUEST_SKULL_TOKEN) { + if (item.kind == ITEM_KIND_QUEST && item.id == QUEST_SKULL_TOKEN) { currentColor = IM_COL_RED; } else { currentColor = IM_COL_GREEN; @@ -800,7 +802,7 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { ImGui::PushStyleColor(ImGuiCol_Text, maxColor); ImGui::Text("%s", maxString.c_str()); ImGui::PopStyleColor(); - } else if (item.id == RG_TRIFORCE_PIECE && IS_RANDO && + } else if (item.kind == ITEM_KIND_RG && item.id == RG_TRIFORCE_PIECE && IS_RANDO && (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) != RO_TRIFORCE_HUNT_OFF) && IsValidSaveFile()) { std::string currentString = ""; @@ -837,7 +839,8 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { ImGui::PushStyleColor(ImGuiCol_Text, maxColor); ImGui::Text("%s", maxString.c_str()); ImGui::PopStyleColor(); - } else if (item.id >= RG_SHADOW_SILVER_BLADES && item.id <= RG_GANONS_CASTLE_MQ_SILVER_SHADOW && IS_RANDO && + } else if (item.kind == ITEM_KIND_RG && item.id >= RG_SHADOW_SILVER_BLADES && + item.id <= RG_GANONS_CASTLE_MQ_SILVER_SHADOW && IS_RANDO && OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_SILVER).Get() && IsValidSaveFile()) { RandomizerGet rg = static_cast(item.id); std::string current = ""; @@ -865,6 +868,7 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { } void DrawEquip(ItemTrackerItem item) { + assert(item.kind == ITEM_KIND_ITEM); bool hasEquip = HasEquipment(item); float iconSize = static_cast(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36)); ImGui::Image(std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()) @@ -875,6 +879,7 @@ void DrawEquip(ItemTrackerItem item) { } void DrawQuest(ItemTrackerItem item) { + assert(item.kind == ITEM_KIND_QUEST); bool hasQuestItem = HasQuestItem(item); float iconSize = static_cast(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36)); ImGui::BeginGroup(); @@ -900,7 +905,8 @@ bool HasBossSoul(RandomizerInf bossSoul) { } void DrawItem(ItemTrackerItem item) { - uint32_t actualItemId = GameInteractor::IsSaveLoaded() ? INV_CONTENT(item.id) : ITEM_NONE; + uint32_t actualItemId = + GameInteractor::IsSaveLoaded() && item.kind == ITEM_KIND_ITEM ? INV_CONTENT(item.id) : ITEM_NONE; float iconSize = static_cast(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36)); bool hasItem = actualItemId != ITEM_NONE; std::string itemName = ""; @@ -1305,7 +1311,7 @@ void DrawItem(ItemTrackerItem item) { } if (GameInteractor::IsSaveLoaded() && - (hasItem && item.id != actualItemId && + (hasItem && item.kind == ITEM_KIND_ITEM && item.id != actualItemId && actualItemTrackerItemMap.find(actualItemId) != actualItemTrackerItemMap.end())) { item = actualItemTrackerItemMap[actualItemId]; } @@ -1318,7 +1324,8 @@ void DrawItem(ItemTrackerItem item) { DrawItemCount(item, false); - if (item.id >= RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL && item.id <= RG_ZORAS_RIVER_BEAN_SOUL) { + if (item.kind == ITEM_KIND_RG && item.id >= RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL && + item.id <= RG_ZORAS_RIVER_BEAN_SOUL) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string beanName = itemTrackerBeanShortNames[item.id]; ImGui::SetCursorScreenPos( @@ -1326,9 +1333,7 @@ void DrawItem(ItemTrackerItem item) { ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); ImGui::Text("%s", beanName.c_str()); ImGui::PopStyleColor(); - } - - if (item.id >= RG_GOHMA_SOUL && item.id <= RG_GANON_SOUL) { + } else if (item.kind == ITEM_KIND_RG && item.id >= RG_GOHMA_SOUL && item.id <= RG_GANON_SOUL) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string bossName = itemTrackerBossShortNames[item.id]; ImGui::SetCursorScreenPos( @@ -1336,9 +1341,7 @@ void DrawItem(ItemTrackerItem item) { ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); ImGui::Text("%s", bossName.c_str()); ImGui::PopStyleColor(); - } - - if (item.id >= RG_SPEAK_DEKU && item.id <= RG_SPEAK_ZORA) { + } else if (item.kind == ITEM_KIND_RG && item.id >= RG_SPEAK_DEKU && item.id <= RG_SPEAK_ZORA) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string name = itemTrackerJabberNutShortNames[item.id]; ImGui::SetCursorScreenPos( @@ -1346,9 +1349,7 @@ void DrawItem(ItemTrackerItem item) { ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); ImGui::Text("%s", name.c_str()); ImGui::PopStyleColor(); - } - - if (item.id >= RG_OCARINA_A_BUTTON && item.id <= RG_OCARINA_C_RIGHT_BUTTON) { + } else if (item.kind == ITEM_KIND_RG && item.id >= RG_OCARINA_A_BUTTON && item.id <= RG_OCARINA_C_RIGHT_BUTTON) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string ocarinaButtonName = itemTrackerOcarinaButtonShortNames[item.id]; ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(ocarinaButtonName.c_str()).x / 2), @@ -1356,9 +1357,7 @@ void DrawItem(ItemTrackerItem item) { ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); ImGui::Text("%s", ocarinaButtonName.c_str()); ImGui::PopStyleColor(); - } - - if (item.id >= RG_GUARD_HOUSE_KEY && item.id <= RG_FISHING_HOLE_KEY) { + } else if (item.kind == ITEM_KIND_RG && item.id >= RG_GUARD_HOUSE_KEY && item.id <= RG_FISHING_HOLE_KEY) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string overworldKeyName = itemTrackerOverworldKeyShortNames[item.id]; ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(overworldKeyName.c_str()).x / 2), @@ -1366,9 +1365,7 @@ void DrawItem(ItemTrackerItem item) { ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); ImGui::Text("%s", overworldKeyName.c_str()); ImGui::PopStyleColor(); - } - - if (item.id >= RG_BRONZE_SCALE && item.id <= RG_OPEN_CHEST) { + } else if (item.kind == ITEM_KIND_RG && item.id >= RG_BRONZE_SCALE && item.id <= RG_OPEN_CHEST) { ImVec2 p = ImGui::GetCursorScreenPos(); ImGui::SetCursorScreenPos( ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(itemName.c_str()).x / 2), p.y - (iconSize + 2))); @@ -1387,6 +1384,7 @@ void DrawItem(ItemTrackerItem item) { } void DrawBottle(ItemTrackerItem item) { + assert(item.kind == ITEM_KIND_ITEM); uint32_t actualItemId = GameInteractor::IsSaveLoaded() ? (gSaveContext.inventory.items[SLOT(item.id) + item.data]) : false; bool hasItem = actualItemId != ITEM_NONE; @@ -1406,6 +1404,7 @@ void DrawBottle(ItemTrackerItem item) { }; void DrawDungeonItem(ItemTrackerItem item) { + assert(item.kind == ITEM_KIND_ITEM); uint32_t itemId = item.id; ImU32 dungeonColor = IM_COL_WHITE; uint32_t bitMask = 1 << (item.id - ITEM_KEY_BOSS); // Bitset starts at ITEM_KEY_BOSS == 0. the rest are sequential @@ -1460,6 +1459,7 @@ void DrawDungeonItem(ItemTrackerItem item) { } void DrawSong(ItemTrackerItem item) { + assert(item.kind == ITEM_KIND_QUEST); float iconSize = static_cast(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36)); ImVec2 p = ImGui::GetCursorScreenPos(); bool hasSong = HasSong(item); @@ -1752,8 +1752,9 @@ void UpdateVectors() { SECTION_DISPLAY_EXTENDED_MISC_WINDOW && CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Misc"), SECTION_DISPLAY_MAIN_WINDOW) != SECTION_DISPLAY_MAIN_WINDOW) { - if (std::none_of(miscItems.begin(), miscItems.end(), - [](ItemTrackerItem item) { return item.id == ITEM_RUPEE_GREEN; })) + if (std::none_of(miscItems.begin(), miscItems.end(), [](ItemTrackerItem item) { + return item.kind == ITEM_KIND_ITEM && item.id == ITEM_RUPEE_GREEN; + })) miscItems.insert(miscItems.end(), gregItems.begin(), gregItems.end()); } else { miscItems.erase(std::remove_if(miscItems.begin(), miscItems.end(), @@ -1797,8 +1798,9 @@ void UpdateVectors() { SECTION_DISPLAY_EXTENDED_MISC_WINDOW && CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Misc"), SECTION_DISPLAY_MAIN_WINDOW) != SECTION_DISPLAY_MAIN_WINDOW) { - if (std::none_of(miscItems.begin(), miscItems.end(), - [](ItemTrackerItem item) { return item.id == ITEM_FISHING_POLE; })) + if (std::none_of(miscItems.begin(), miscItems.end(), [](ItemTrackerItem item) { + return item.kind == ITEM_KIND_ITEM && item.id == ITEM_FISHING_POLE; + })) miscItems.insert(miscItems.end(), fishingPoleItems.begin(), fishingPoleItems.end()); } else { miscItems.erase(std::remove_if(miscItems.begin(), miscItems.end(), From da5b7e68484ac7084eb5df9165b1d034a5d7a5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 2 Apr 2026 12:59:35 +0000 Subject: [PATCH 09/14] tooltip --- soh/soh/Enhancements/randomizer/option_descriptions.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index b9b0dca3468..8e3fa7e8297 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -531,7 +531,14 @@ void Settings::CreateOptionDescriptions() { "All Items - Shuffle all freestanding rupees & hearts."; mOptionDescriptions[RSK_SHUFFLE_SILVER] = "Silver rupees will be shuffled.\n" "Items will be added to pool which completes the silver rupee puzzles,\n" - "while silver rupee locations will be random items."; + "while silver rupee locations will be random items.\n" + "Off - silver rupees won't be shuffled." + "\n" + "On - silver rupees will be individually spread out." + "\n" + "Wallet - silver rupees are shuffled as wallets, a single check to set flag for collecting them." + "\n" + "Start With - Silver rupees are still replaced with items, but all silver rupee flags start set."; mOptionDescriptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES] = "Shuffle fairies in fountain locations. " "This includes the sets of fairies found in Ganon's Castle and the Desert Oasis."; From 854ad9b21d40cba62e9c1efa539ae430cbe4eb87 Mon Sep 17 00:00:00 2001 From: Demur Rumed <159546+serprex@users.noreply.github.com> Date: Sat, 30 May 2026 16:37:28 +0000 Subject: [PATCH 10/14] fixes --- soh/soh/Enhancements/randomizer/ShuffleSilver.cpp | 1 + soh/soh/Enhancements/randomizer/logic.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp index 992a05b8487..593199c7ede 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp @@ -3,6 +3,7 @@ #include "SeedContext.h" #include "draw.h" #include "static_data.h" +#include "randomizer.h" extern "C" { #include "overlays/actors/ovl_En_G_Switch/z_en_g_switch.h" diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index e01f0e907b4..fef8b11b532 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -5,6 +5,7 @@ #include #include "soh/OTRGlobals.h" +#include "randomizer.h" #include "dungeon.h" #include "SeedContext.h" #include "macros.h" From 2e9684c44457c22d0e75088e06ffb771c32bc784 Mon Sep 17 00:00:00 2001 From: Demur Rumed <159546+serprex@users.noreply.github.com> Date: Sat, 30 May 2026 17:40:21 +0000 Subject: [PATCH 11/14] fix starts with --- soh/soh/Enhancements/randomizer/logic.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index fef8b11b532..f552216a2c5 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2153,15 +2153,16 @@ void Logic::ApplyItemEffect(Item& item, bool state) { auto randoGet = item.GetRandomizerGet(); if (randoGet >= RG_SHADOW_SILVER_BLADES && randoGet <= RG_GANONS_CASTLE_MQ_SILVER_SHADOW) { s8* field = Randomizer::SilverFieldFromSaveContext(mSaveContext, randoGet); - bool isWallet = ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET); + bool fullGroup = ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET) || + ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_STARTWITH); if (!state) { - if (isWallet) { + if (fullGroup) { *field = 0; } else { *field -= 1; } } else { - if (isWallet) { + if (fullGroup) { *field = 10; } else { *field += 1; From 6cd18410b4a8142305b32e96cce4da7bc43fce88 Mon Sep 17 00:00:00 2001 From: Demur Rumed <159546+serprex@users.noreply.github.com> Date: Sat, 30 May 2026 18:49:11 +0000 Subject: [PATCH 12/14] missed a GetDungeonFromScene --- .../randomizer/3drando/item_pool.cpp | 7 ++++--- .../randomizer/option_descriptions.cpp | 21 ++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 7d318076f87..3f474b59b25 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -130,11 +130,12 @@ static void PlaceItemsForType(RandomizerCheckType rctype, bool overworldActive = if (currentQuest == RCQUEST_BOTH) { AddFixedItemToPool(loc->GetVanillaItem(), 1, false); } else { - // Check if current item's dungeon is vanilla or MQ, and only add if quest corresponds to it. + // Check if current item's dungeon is vanilla or MQ, and only add if quest corresponds to it SceneID itemScene = loc->GetScene(); + auto dungeon = ctx->GetDungeonFromScene(itemScene); - if (itemScene >= SCENE_DEKU_TREE && itemScene <= SCENE_GERUDO_TRAINING_GROUND) { - bool isMQ = ctx->GetDungeon(itemScene)->IsMQ(); + if (dungeon != nullptr) { + bool isMQ = dungeon->IsMQ(); if ((isMQ && currentQuest == RCQUEST_MQ) || (!isMQ && currentQuest == RCQUEST_VANILLA)) { AddFixedItemToPool(loc->GetVanillaItem(), 1, false); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 8e3fa7e8297..570ea81c360 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -529,16 +529,17 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n" "\n" "All Items - Shuffle all freestanding rupees & hearts."; - mOptionDescriptions[RSK_SHUFFLE_SILVER] = "Silver rupees will be shuffled.\n" - "Items will be added to pool which completes the silver rupee puzzles,\n" - "while silver rupee locations will be random items.\n" - "Off - silver rupees won't be shuffled." - "\n" - "On - silver rupees will be individually spread out." - "\n" - "Wallet - silver rupees are shuffled as wallets, a single check to set flag for collecting them." - "\n" - "Start With - Silver rupees are still replaced with items, but all silver rupee flags start set."; + mOptionDescriptions[RSK_SHUFFLE_SILVER] = + "Silver rupees will be shuffled.\n" + "Items will be added to pool which completes the silver rupee puzzles,\n" + "while silver rupee locations will be random items.\n" + "Off - silver rupees won't be shuffled." + "\n" + "On - silver rupees will be individually spread out." + "\n" + "Wallet - silver rupees are shuffled as wallets, a single check to set flag for collecting them." + "\n" + "Start With - Silver rupees are still replaced with items, but all silver rupee flags start set."; mOptionDescriptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES] = "Shuffle fairies in fountain locations. " "This includes the sets of fairies found in Ganon's Castle and the Desert Oasis."; From 591552f1aeb12e1d3f79d695a1dce99fb4bbc74d Mon Sep 17 00:00:00 2001 From: Demur Rumed <159546+serprex@users.noreply.github.com> Date: Sun, 31 May 2026 03:46:17 +0000 Subject: [PATCH 13/14] fixes while investigating closed door of time generation problems --- soh/soh/Enhancements/randomizer/3drando/menu.cpp | 2 +- .../randomizer/3drando/playthrough.cpp | 15 ++++++--------- .../location_access/dungeons/ganons_castle.cpp | 5 +++++ soh/soh/Enhancements/randomizer/logic.cpp | 16 +++++++++------- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index 820c5066d07..148e3d3c1fe 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -44,7 +44,7 @@ bool GenerateRandomizer(std::set excludedLocations, std::setClearItemLocations(); int ret = Playthrough::Playthrough_Init(ctx->GetSeed(), excludedLocations, enabledTricks); if (ret < 0) { - if (ret == -1) { // Failed to generate after 5 tries + if (ret == -1) { SPDLOG_ERROR("Failed to generate after 5 tries."); return false; } else { diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index 4ee635323cc..ae43d45f375 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -5,7 +5,6 @@ #include "../location_access.h" #include "random.hpp" #include "spoiler_log.hpp" -#include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/randomizer/settings.h" #include "variables.h" #include "soh/cvar_prefixes.h" @@ -72,14 +71,12 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, GenerateHash(); - if (true) { - // TODO: Handle different types of file output (Spoiler Log, Plando Template, Patch Files, Race Files, etc.) - SPDLOG_INFO("Writing Spoiler Log..."); - StartPerformanceTimer(PT_SPOILER_LOG); - SpoilerLog_Write(); - StopPerformanceTimer(PT_SPOILER_LOG); - SPDLOG_INFO("Writing Spoiler Log Done"); - } + // TODO: Handle different types of file output (Spoiler Log, Plando Template, Patch Files, Race Files, etc.) + SPDLOG_INFO("Writing Spoiler Log..."); + StartPerformanceTimer(PT_SPOILER_LOG); + SpoilerLog_Write(); + StopPerformanceTimer(PT_SPOILER_LOG); + SPDLOG_INFO("Writing Spoiler Log Done"); ctx->playthroughLocations.clear(); ctx->playthroughBeatable = false; diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 8979428902a..4dc04ea37e1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -522,6 +522,11 @@ void RegionTable_Init_GanonsCastle() { ENTRANCE(RR_GANONS_CASTLE_MQ_FOREST_TRIAL_BEAMOS_ROOM_END, true), }); + areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_OPEN_DOOR] = Region("Ganon's Castle MQ Fire Trial Open Door", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { + //Exits + ENTRANCE(RR_GANONS_CASTLE_MQ_MAIN, true), + }); + areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FROM_OPEN] = Region("Ganon's Castle MQ Fire Trial From Open Door", SCENE_INSIDE_GANONS_CASTLE, { //Events EVENT_ACCESS(LOGIC_GANONS_CASTLE_MQ_SILVER_FIRE, logic->FireTimer() >= 80 && logic->CanUse(RG_GOLDEN_GAUNTLETS);), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index f552216a2c5..5d65abded63 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -298,9 +298,12 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_GANONS_CASTLE_MQ_SILVER_SHADOW: { if (!ctx->GetOption(RSK_SHUFFLE_SILVER)) { return Get((LogicVal)(LOGIC_SHADOW_SILVER_BLADES + (itemName - RG_SHADOW_SILVER_BLADES))); + } else if (ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_STARTWITH)) { + return true; + } else { + s8 field = *Randomizer::SilverFieldFromSaveContext(mSaveContext, itemName); + return field >= Randomizer::SilverTotal(itemName); } - s8 field = *Randomizer::SilverFieldFromSaveContext(mSaveContext, itemName); - return field >= Randomizer::SilverTotal(itemName); } // Trade Items case RG_POCKET_EGG: @@ -2153,16 +2156,15 @@ void Logic::ApplyItemEffect(Item& item, bool state) { auto randoGet = item.GetRandomizerGet(); if (randoGet >= RG_SHADOW_SILVER_BLADES && randoGet <= RG_GANONS_CASTLE_MQ_SILVER_SHADOW) { s8* field = Randomizer::SilverFieldFromSaveContext(mSaveContext, randoGet); - bool fullGroup = ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET) || - ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_STARTWITH); + bool isWallet = ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET); if (!state) { - if (fullGroup) { + if (isWallet) { *field = 0; } else { *field -= 1; } } else { - if (fullGroup) { + if (isWallet) { *field = 10; } else { *field += 1; @@ -2385,7 +2387,7 @@ void Logic::InitSaveContext() { void Logic::NewSaveContext() { if (mSaveContext != nullptr && mSaveContext != &gSaveContext) { - free(mSaveContext); + delete mSaveContext; } mSaveContext = new SaveContext(); InitSaveContext(); From fe26da56a3d996a2fcda327dee03332865c68088 Mon Sep 17 00:00:00 2001 From: Demur Rumed <159546+serprex@users.noreply.github.com> Date: Sun, 31 May 2026 15:30:49 +0000 Subject: [PATCH 14/14] fix despawning --- soh/soh/Enhancements/randomizer/ShuffleSilver.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp index 593199c7ede..2a16d198d29 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleSilver.cpp @@ -34,6 +34,7 @@ static bool IsSilverCleared(s16 switchFlag) { case 17: return gSaveContext.ship.quest.data.randomizer.silverMqShadowPit >= 5; } + break; case SCENE_SPIRIT_TEMPLE: switch (switchFlag) { case 0: @@ -47,6 +48,7 @@ static bool IsSilverCleared(s16 switchFlag) { case 55: return gSaveContext.ship.quest.data.randomizer.silverMqSpiritLobby >= 5; } + break; case SCENE_BOTTOM_OF_THE_WELL: return gSaveContext.ship.quest.data.randomizer.silverBotw >= 5; case SCENE_ICE_CAVERN: @@ -56,6 +58,7 @@ static bool IsSilverCleared(s16 switchFlag) { case 31: return gSaveContext.ship.quest.data.randomizer.silverIceCavernBlades >= 5; } + break; case SCENE_GERUDO_TRAINING_GROUND: switch (switchFlag) { case 12: @@ -68,6 +71,7 @@ static bool IsSilverCleared(s16 switchFlag) { return isMQ ? gSaveContext.ship.quest.data.randomizer.silverMqGtgSlope >= 5 : gSaveContext.ship.quest.data.randomizer.silverGtgSlope >= 5; } + break; case SCENE_INSIDE_GANONS_CASTLE: switch (switchFlag) { case 1: @@ -84,6 +88,7 @@ static bool IsSilverCleared(s16 switchFlag) { case 18: return gSaveContext.ship.quest.data.randomizer.silverGanonLight >= 5; } + break; } return false; } @@ -134,12 +139,12 @@ void RegisterShuffleSilver() { if (silver->type == ENGSWITCH_SILVER_RUPEE) { auto silverIdentity = OTRGlobals::Instance->gRandomizer->IdentifySilver(gPlayState->sceneNum, silver->actor.world.pos); - if (silverIdentity.randomizerCheck == RC_UNKNOWN_CHECK || - Flags_GetRandomizerInf(silverIdentity.randomizerInf)) { - *should = true; - return; + *should = silverIdentity.randomizerCheck == RC_UNKNOWN_CHECK || + Flags_GetRandomizerInf(silverIdentity.randomizerInf); + if (!*should) { + *should = false; + silver->actor.draw = EnGSwitch_RandomizerDraw; } - silver->actor.draw = EnGSwitch_RandomizerDraw; } else if (silver->type == ENGSWITCH_SILVER_TRACKER && IsSilverCleared(silver->switchFlag)) { Flags_SetSwitch(gPlayState, silver->switchFlag); *should = true;