From 03b489fd0c59d514d2a2dac1e99180ecec472484 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Mon, 7 Jul 2025 01:45:15 +0000 Subject: [PATCH 1/9] 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 + .../Enhancements/randomizer/hook_handlers.cpp | 2 + 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 | 92 ++++-- .../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 +- 41 files changed, 1815 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 9842c54edde..3648604cae8 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2108,6 +2108,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 2a44e9786e2..f52e3dde730 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 5783be19ca3..0384aa5c399 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 5a5e85cd55a..9f87e03095b 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, @@ -853,6 +853,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 62ff1f9cc55..c54364b1099 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -221,6 +221,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 050913a4a00..e83d29d33e7 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 = RandomElement(Rando::StaticData::overworldKeys); } else if (trickModel == RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) { trickModel = RandomElement(Rando::StaticData::beanSouls); + } else if (trickModel == RG_SHADOW_SILVER_BLADES) { + trickModel = RandomElement(Rando::StaticData::silverRupees); } return trickModel; diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index f16ae7440cd..9c86097bd21 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -19,6 +19,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" @@ -37,6 +38,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; } @@ -1279,6 +1281,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/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 340aad2874f..e0c60002d1d 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -399,6 +399,8 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() { getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER || // Treat small keys as junk if Skeleton Key is obtained. (getItemEntry.getItemCategory == ITEM_CATEGORY_SMALL_KEY && + !(getItemEntry.getItemId >= RG_SHADOW_SILVER_BLADES && + getItemEntry.getItemId <= RG_SHADOW_SILVER_BLADES) && Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY))))))) { Item_DropCollectible(gPlayState, &spawnPos, static_cast(ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000)); } diff --git a/soh/soh/Enhancements/randomizer/item.cpp b/soh/soh/Enhancements/randomizer/item.cpp index e784612f7cd..92792b443ce 100644 --- a/soh/soh/Enhancements/randomizer/item.cpp +++ b/soh/soh/Enhancements/randomizer/item.cpp @@ -450,8 +450,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 892cc8ac04c..14b1f2d062a 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -242,6 +242,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 ", "den ", "le "}); 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 ", "den ", "le "}, "%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 ", "den ", "le "}, "%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 7fe50d23236..5966d56e996 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()), @@ -203,9 +205,14 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3, logic->CanCutShrubs()), + 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 6410e262781..ef121b1af3b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -349,6 +349,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), @@ -371,7 +373,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()), @@ -379,17 +381,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 48348de4457..93324b678c7 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)), // child can get these by voiding after switch - }, {}, { + EVENT_ACCESS(LOGIC_GANONS_CASTLE_SILVER_FOREST, logic->IsAdult || logic->CanUse(RG_HOOKSHOT)), // 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, { @@ -263,14 +276,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, {}, { @@ -329,13 +349,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, { @@ -459,15 +487,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) || @@ -481,7 +511,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, { @@ -512,9 +542,17 @@ 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)) && logic->HasItem(RG_POWER_BRACELET) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)), - }, {}, { + }, { + //Locations + //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)), ENTRANCE(RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM_END, logic->Get(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE) && (logic->IsAdult || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_POWER_BRACELET)) || logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP))), @@ -524,7 +562,7 @@ void RegionTable_Init_GanonsCastle() { EVENT_ACCESS(LOGIC_WATER_TRIAL_MQ_MELTED_FINAL_DOOR_RED_ICE, logic->BlueFire()), }, {}, { 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, { @@ -542,6 +580,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), @@ -567,6 +606,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)), @@ -574,7 +615,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 @@ -586,15 +630,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 b4322f64b63..10c08962596 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,10 +275,20 @@ 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_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, { @@ -321,30 +361,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)), @@ -352,10 +393,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()))), @@ -364,8 +409,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))), @@ -373,28 +423,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 176ffaee881..8e6136ee57f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -27,7 +27,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()), @@ -35,11 +38,16 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_1, logic->CanBreakPots()), LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_2, logic->CanBreakPots()), LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_3, logic->CanBreakPots()), + 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))), }); @@ -75,18 +83,26 @@ 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))), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->CanUse(RG_BOOMERANG)), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->CanUse(RG_BOOMERANG)), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->CanUse(RG_BOOMERANG)), + 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_BEFORE_FINAL_ROOM, (logic->HasItem(RG_POWER_BRACELET) || (logic->IsAdult && (logic->CanGroundJump() || ctx->GetTrickOption(RT_SLIDE_JUMP)))) && AnyAgeTime([]{return logic->BlueFire();})), + ENTRANCE(RR_ICE_CAVERN_BEFORE_FINAL_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 97b65a2c160..3d07af605e8 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 @@ -194,18 +212,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)), @@ -463,12 +493,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)), }); @@ -512,26 +550,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)), @@ -575,7 +633,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)))) @@ -585,16 +643,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 fcbdce9a73c..4b747cb85dc 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -82,16 +82,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), }); @@ -104,7 +109,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, {}, { @@ -162,8 +167,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), @@ -172,10 +180,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, {}, { @@ -287,7 +299,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 @@ -298,14 +316,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), @@ -559,11 +578,16 @@ 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()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, logic->CanBreakPots()), + 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), @@ -908,7 +932,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()), @@ -1032,6 +1056,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 075296105e9..405f3536253 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); @@ -2109,23 +2150,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 017ed13ca10..65ddbcfcd49 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -520,6 +520,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 c28a5425c81..9b338bc07f4 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -284,6 +284,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), @@ -3270,6 +3335,160 @@ std::map rcToRandomizerInf = { { RC_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM, RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM }, { RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE, RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE }, { RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL, RAND_INF_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL }, + { 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) { @@ -3815,6 +4034,24 @@ CheckIdentity Randomizer::IdentifyWonderItem(s32 sceneNum, s32 par1, s32 par2) { return wonderIdentity; } +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(); } @@ -4374,6 +4611,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 7b1fcdba48d..be15318d7d7 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -29,6 +29,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 IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifySign(s32 sceneNum, s32 posX, s32 posZ, s32 id); CheckIdentity IdentifyWonderItem(s32 sceneNum, s32 par1, s32 par2); + 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 095a6b00906..7373aee50b2 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h @@ -2205,6 +2205,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 cb69dca986d..2dbd3476444 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 7ff5d9a5ca3..24fa6cd603f 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h @@ -1690,6 +1690,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 9581e44e1bb..0779a8151fe 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h @@ -125,6 +125,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 b81225cb23f..3949e08e702 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h @@ -373,6 +373,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 762f747c749..fbed5d21d84 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h @@ -238,6 +238,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 23b7f505e0b..74779501706 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -179,6 +179,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 e52f6bd0aff..30559ae8770 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -65,6 +65,7 @@ bool showBeehives; bool showCows; bool showOverworldFreestanding; bool showDungeonFreestanding; +bool showSilver; bool showAdultTrade; bool showKokiriSword; bool showMasterSword; @@ -1567,6 +1568,8 @@ void LoadSettings() { showDungeonFreestanding = false; break; } + + showSilver = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SILVER); } else { // Vanilla showOverworldFreestanding = false; showDungeonFreestanding = true; @@ -1655,6 +1658,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 064eabff646..78a1ac2ef0b 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -223,6 +223,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 581ce39bf78..ef51140635c 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -1040,6 +1040,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 @@ -1852,6 +1853,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], @@ -2175,6 +2177,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 ecd4a11e30c..4c96bd7357a 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 8d91f9b70a0..ba30b0fee64 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 RegisterTreeLocations(); @@ -89,6 +90,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 89224c0ab57..8545f58874a 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -230,6 +230,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); @@ -384,6 +421,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 ab85292a00396d623e47bd6529d112f24e0f1512 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 4 Jan 2026 04:24:06 +0000 Subject: [PATCH 2/9] 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 3648604cae8..7b2b20bf08f 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2108,6 +2108,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 9b338bc07f4..a3b8c2bea9b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4034,13 +4034,16 @@ CheckIdentity Randomizer::IdentifyWonderItem(s32 sceneNum, s32 par1, s32 par2) { return wonderIdentity; } -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 be15318d7d7..0c5c285152f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -46,7 +46,7 @@ class Randomizer { CheckIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifySign(s32 sceneNum, s32 posX, s32 posZ, s32 id); CheckIdentity IdentifyWonderItem(s32 sceneNum, s32 par1, s32 par2); - 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 f9db09796e0761022173fa3219e086f099746390 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 4 Jan 2026 14:39:04 +0000 Subject: [PATCH 3/9] 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 10c08962596..d20c1339337 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 4b747cb85dc..f930b0df9da 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -1056,11 +1056,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), @@ -1072,10 +1067,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 4cca9d961c446d996ea933cd20e6342ec926fdaf 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 4/9] 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 5966d56e996..4a203d8eb3a 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 d20c1339337..120de287874 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_GTG_MQ_SILVER_SLOPE_1, true), From 5a51e560e3088eb40b313a1c6dfc3913939e4b3d 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 5/9] 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 5f92344c6cb..605ac466813 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 c54364b1099..229a7b83533 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -513,6 +513,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 9ca42751a95..70742885906 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 e0c60002d1d..442470940c1 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -82,7 +82,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); } @@ -279,7 +279,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) { @@ -1490,8 +1490,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)) { @@ -1504,8 +1503,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; } @@ -2042,7 +2040,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: @@ -2429,8 +2427,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 405f3536253..5717751b436 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: @@ -2450,7 +2446,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 a3b8c2bea9b..775849f1fda 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -284,6 +284,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 0c5c285152f..b26f7b88757 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -29,6 +29,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 30559ae8770..b405cbc588f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -835,11 +835,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; } @@ -1226,8 +1225,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 0ccc205a6df..fba313a9787 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" @@ -57,6 +58,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; @@ -96,35 +98,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 = { @@ -132,101 +134,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 } }, @@ -502,132 +539,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; @@ -796,6 +834,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(""); @@ -838,373 +897,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() && @@ -1282,7 +1376,7 @@ void DrawItem(ItemTrackerItem item) { ImGui::EndGroup(); - if (itemName == "") { + if (itemName == "" && item.kind == ITEM_KIND_ITEM) { itemName = SohUtils::GetItemName(item.id); } @@ -1785,6 +1879,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; } @@ -1977,6 +2088,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"); @@ -2183,6 +2311,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, @@ -2380,6 +2509,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 fab47c9531f..7792d4f153d 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 4d4f9126455..a54cd9a616b 100644 --- a/soh/soh/ResourceManagerHelpers.cpp +++ b/soh/soh/ResourceManagerHelpers.cpp @@ -100,7 +100,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 3f01e6e5543..244b11bf742 100644 --- a/soh/soh/SohGui/ImGuiUtils.cpp +++ b/soh/soh/SohGui/ImGuiUtils.cpp @@ -157,15 +157,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), @@ -248,12 +239,13 @@ void RegisterImGuiItemIcons() { entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } - for (const auto& entry : jabbernutMapping) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, - ImVec4(1, 1, 1, 1)); - 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; + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_RUPEE_SILVER", gRupeeCounterIconTex, + silver); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_RUPEE_SILVER_Faded", gRupeeCounterIconTex, + silverFaded); for (const auto& entry : questMapping) { Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, From f8b0dd5501465bf0a5540af2d9339f5df63d4ea5 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 6/9] 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 5717751b436..b4c1144b9e0 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2363,7 +2363,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 ab790a36db50e5d7512d3812334542b393edf4a0 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 7/9] 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 9c86097bd21..f0b735b6fbe 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -13,6 +13,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" @@ -34,11 +35,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; } @@ -1283,22 +1284,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 ef25bd181dd8668f227128106d7aea3a5b48206d 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 8/9] 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 fba313a9787..5fe4b968857 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -512,14 +512,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; } @@ -690,30 +693,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; @@ -744,17 +744,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); @@ -762,7 +764,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; @@ -797,7 +799,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 = ""; @@ -834,7 +836,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 = ""; @@ -862,6 +865,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(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( @@ -872,6 +876,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(); @@ -897,7 +902,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 = ""; @@ -1302,7 +1308,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]; } @@ -1315,7 +1321,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( @@ -1323,9 +1330,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( @@ -1333,9 +1338,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( @@ -1343,9 +1346,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), @@ -1353,9 +1354,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), @@ -1363,9 +1362,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))); @@ -1384,6 +1381,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; @@ -1403,6 +1401,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 @@ -1457,6 +1456,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); @@ -1749,8 +1749,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(), @@ -1794,8 +1795,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 543523d2b1c1d58471f66ec3a3d2148247e92683 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 9/9] 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 65ddbcfcd49..98238e098f6 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -522,7 +522,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.";