From 815f81bc2d5c649d45907a1021954547d1035044 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sun, 16 Feb 2025 23:27:15 +0100 Subject: [PATCH] Add RSK_SHUFFLE_GANON_TOWER_ENTRANCE --- soh/soh/Enhancements/randomizer/entrance.cpp | 21 +++++++++++++++++++ soh/soh/Enhancements/randomizer/entrance.h | 1 + .../dungeons/ganons_castle.cpp | 15 +++++++++---- .../randomizer/option_descriptions.cpp | 2 ++ .../Enhancements/randomizer/randomizerTypes.h | 3 ++- .../randomizer_entrance_tracker.cpp | 20 ++++++++++-------- soh/soh/Enhancements/randomizer/settings.cpp | 16 +++++++++++++- 7 files changed, 63 insertions(+), 15 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 81afbf33c..874457f52 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -1145,6 +1145,9 @@ int EntranceShuffler::ShuffleAllEntrances() { { { EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, RR_SHADOW_TEMPLE_BOSS_ROOM, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE }, { EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, ENTR_SHADOW_TEMPLE_BOSS_DOOR } }, + { { EntranceType::GanonTower, RR_GANONS_TOWER_ENTRYWAY, RR_GANONS_TOWER_FLOOR_1, ENTR_GANONS_TOWER_0 }, + { EntranceType::GanonTower, RR_GANONS_TOWER_FLOOR_1, RR_GANONS_TOWER_ENTRYWAY, ENTR_INSIDE_GANONS_CASTLE_1 } }, + { { EntranceType::BlueWarp, RR_DEKU_TREE_BOSS_ROOM, RR_KF_OUTSIDE_DEKU_TREE, ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP }, NO_RETURN_ENTRANCE }, { { EntranceType::BlueWarp, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP }, @@ -1222,6 +1225,15 @@ int EntranceShuffler::ShuffleAllEntrances() { entrancePools[EntranceType::BossReverse].push_back(entrance->GetReverse()); } } + + if (ctx->GetOption(RSK_SHUFFLE_GANON_TOWER_ENTRANCE).IsNot(RO_GENERIC_OFF)) { + AddElementsToPool(entrancePools[EntranceType::Boss], GetShuffleableEntrances(EntranceType::GanonTower)); + if (ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) { + for (Entrance* entrance : GetShuffleableEntrances(EntranceType::GanonTower)) { + entrancePools[EntranceType::BossReverse].push_back(entrance->GetReverse()); + } + } + } } else { entrancePools[EntranceType::ChildBoss] = GetShuffleableEntrances(EntranceType::ChildBoss); entrancePools[EntranceType::AdultBoss] = GetShuffleableEntrances(EntranceType::AdultBoss); @@ -1241,6 +1253,15 @@ int EntranceShuffler::ShuffleAllEntrances() { entrancePools[EntranceType::AdultBossReverse].push_back(entrance->GetReverse()); } } + + if (ctx->GetOption(RSK_SHUFFLE_GANON_TOWER_ENTRANCE).IsNot(RO_GENERIC_OFF)) { + AddElementsToPool(entrancePools[EntranceType::AdultBoss], GetShuffleableEntrances(EntranceType::GanonTower)); + if (ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) { + for (Entrance* entrance : GetShuffleableEntrances(EntranceType::GanonTower)) { + entrancePools[EntranceType::AdultBossReverse].push_back(entrance->GetReverse()); + } + } + } } } diff --git a/soh/soh/Enhancements/randomizer/entrance.h b/soh/soh/Enhancements/randomizer/entrance.h index 48a80c550..b4327446a 100644 --- a/soh/soh/Enhancements/randomizer/entrance.h +++ b/soh/soh/Enhancements/randomizer/entrance.h @@ -25,6 +25,7 @@ enum class EntranceType { ChildBossReverse, AdultBoss, AdultBossReverse, + GanonTower, Interior, InteriorReverse, SpecialInterior, 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 2a7301701..663625787 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -28,7 +28,7 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, []{return true;}), Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, []{return true;}), Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}), - Entrance(RR_GANONS_TOWER_FLOOR_1, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && + Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && (logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && (logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && (logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && @@ -162,7 +162,7 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_CHAIRS_ROOM, []{return true;}), Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_DINOLFOS_ROOM, []{return Here(RR_GANONS_CASTLE_MQ_MAIN, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS);});}), //RANDOTODO could we just set these events automatically based on the setting? - Entrance(RR_GANONS_TOWER_FLOOR_1, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && + Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && (logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && (logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && (logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && @@ -431,10 +431,17 @@ void RegionTable_Init_GanonsCastle() { #pragma region Tower and Escape + areaTable[RR_GANONS_TOWER_ENTRYWAY] = Region("Ganon's Tower MQ Decider", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_GANONS_CASTLE_LOBBY, []{return ctx->GetDungeon(GANONS_CASTLE)->IsVanilla();}), + Entrance(RR_GANONS_CASTLE_MQ_MAIN, []{return ctx->GetDungeon(GANONS_CASTLE)->IsMQ();}), + Entrance(RR_GANONS_TOWER_FLOOR_1, []{return true;}), + }); + areaTable[RR_GANONS_TOWER_FLOOR_1] = Region("Ganon's Tower Floor 1", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_GANONS_CASTLE_LOBBY, []{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}), - Entrance(RR_GANONS_TOWER_FLOOR_2, []{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_GANONS_TOWER_FLOOR_2, []{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}), }); areaTable[RR_GANONS_TOWER_FLOOR_2] = Region("Ganon's Tower Floor 2", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index a3184765f..ba6e0346e 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -145,6 +145,8 @@ void Settings::CreateOptionDescriptions() { "\n" "Full - Shuffle the entrances of all boss rooms together. Child may be expected to defeat Phantom Ganon and/or " "Bongo Bongo."; + mOptionDescriptions[RSK_SHUFFLE_GANON_TOWER_ENTRANCE] = + "Shuffle the entrance from Ganon's Castle to Ganon's Tower into the pool of boss entrances."; mOptionDescriptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES] = "Shuffle the pool of Overworld entrances, which corresponds to almost all loading zones between overworld " "areas.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 550f2b1af..e1dc99964 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -988,7 +988,6 @@ typedef enum { RR_GANONS_CASTLE_SHADOW_TRIAL, RR_GANONS_CASTLE_SPIRIT_TRIAL, RR_GANONS_CASTLE_LIGHT_TRIAL, - RR_GANONS_CASTLE_TOWER, RR_GANONS_CASTLE_MQ_LOBBY, RR_GANONS_CASTLE_MQ_MAIN, @@ -1017,6 +1016,7 @@ typedef enum { RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_BACK, RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, + RR_GANONS_TOWER_ENTRYWAY, RR_GANONS_TOWER_FLOOR_1, RR_GANONS_TOWER_FLOOR_2, RR_GANONS_TOWER_FLOOR_3, @@ -5205,6 +5205,7 @@ typedef enum { RSK_DAMAGE_MULTIPLIER, RSK_ALL_LOCATIONS_REACHABLE, RSK_SHUFFLE_BOSS_ENTRANCES, + RSK_SHUFFLE_GANON_TOWER_ENTRANCE, RSK_SHUFFLE_100_GS_REWARD, RSK_TRIFORCE_HUNT, RSK_TRIFORCE_HUNT_PIECES_TOTAL, diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 4c3cb971e..8ac4cf0a0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -371,15 +371,17 @@ const EntranceData entranceData[] = { { ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE, ENTR_TEMPLE_OF_TIME_ENTRANCE, SINGLE_SCENE_INFO(SCENE_TEMPLE_OF_TIME), "Temple of Time Entrance", "Outside Temple of Time", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "tot"}, // Hyrule Castle - { ENTR_MARKET_DAY_CASTLE_EXIT, ENTR_CASTLE_GROUNDS_SOUTH_EXIT, {SCENE_NO_SPAWN(SCENE_HYRULE_CASTLE), SCENE_NO_SPAWN(SCENE_OUTSIDE_GANONS_CASTLE)}, "Castle Grounds South Exit", "Market Castle Exit", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD, "outside ganon's castle"}, - { ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, SINGLE_SCENE_INFO(SCENE_HYRULE_CASTLE), "HC Boulder Crawlspace", "HC Great Fairy Fountain", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_CASTLE), "HC Storms Grotto Entry", "HC Storms Grotto", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_GROTTO, "bombable", 1}, - { ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0x01 }}, "HC Great Fairy Fountain", "HC Boulder Crawlspace", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR}, - { ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x09 }}, "HC Storms Grotto", "HC Storms Grotto Entry", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_GROTTO, "bombable"}, - { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD, ENTR_POTION_SHOP_KAKARIKO_1, SINGLE_SCENE_INFO(SCENE_OUTSIDE_GANONS_CASTLE), "OGC Behind Pillar", "OGC Great Fairy Fountain", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "outside ganon's castle", 1}, - { ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, SINGLE_SCENE_INFO(SCENE_OUTSIDE_GANONS_CASTLE), "OGC Rainbow Bridge Exit", "Inside Ganon's Castle Entrance", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "outside ganon's castle,gc", 1}, - { ENTR_POTION_SHOP_KAKARIKO_1, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x02 }}, "OGC Great Fairy Fountain", "OGC Behind Pillar", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "outside ganon's castle"}, - { ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_INSIDE_GANONS_CASTLE), "Inside Ganon's Castle Entrance", "OGC Rainbow Bridge Exit", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "outside ganon's castle,gc"} + { ENTR_MARKET_DAY_CASTLE_EXIT, ENTR_CASTLE_GROUNDS_SOUTH_EXIT, {SCENE_NO_SPAWN(SCENE_HYRULE_CASTLE), SCENE_NO_SPAWN(SCENE_OUTSIDE_GANONS_CASTLE)}, "Castle Grounds South Exit", "Market Castle Exit", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD, "outside ganon's castle"}, + { ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, SINGLE_SCENE_INFO(SCENE_HYRULE_CASTLE), "HC Boulder Crawlspace", "HC Great Fairy Fountain", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_CASTLE), "HC Storms Grotto Entry", "HC Storms Grotto", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_GROTTO, "bombable", 1}, + { ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0x01 }}, "HC Great Fairy Fountain", "HC Boulder Crawlspace", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x09 }}, "HC Storms Grotto", "HC Storms Grotto Entry", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_GROTTO, "bombable"}, + { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD, ENTR_POTION_SHOP_KAKARIKO_1, SINGLE_SCENE_INFO(SCENE_OUTSIDE_GANONS_CASTLE), "OGC Behind Pillar", "OGC Great Fairy Fountain", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "outside ganon's castle", 1}, + { ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, SINGLE_SCENE_INFO(SCENE_OUTSIDE_GANONS_CASTLE), "OGC Rainbow Bridge Exit", "Inside Ganon's Castle Entrance", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "outside ganon's castle,gc", 1}, + { ENTR_POTION_SHOP_KAKARIKO_1, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x02 }}, "OGC Great Fairy Fountain", "OGC Behind Pillar", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "outside ganon's castle"}, + { ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_INSIDE_GANONS_CASTLE), "Inside Ganon's Castle Entrance", "OGC Rainbow Bridge Exit", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "outside ganon's castle,gc"}, + { ENTR_INSIDE_GANONS_CASTLE_1, ENTR_GANONS_TOWER_0, SINGLE_SCENE_INFO(SCENE_GANONS_TOWER), "Ganon's Tower Entrance", "Inside Ganon's Castle Past Trials", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "gc"}, + { ENTR_GANONS_TOWER_0, ENTR_INSIDE_GANONS_CASTLE_1, SINGLE_SCENE_INFO(SCENE_INSIDE_GANONS_CASTLE), "Inside Ganon's Castle Past Trials", "Ganon's Tower Entrance", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "gc"}, }; // Check if Link is in the area and return that scene/entrance for tracking diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index cf1acdd7f..d85355f59 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -136,6 +136,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_ENTRANCES, "Shuffle Entrances"); OPT_U8(RSK_SHUFFLE_DUNGEON_ENTRANCES, "Dungeon Entrances", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], WidgetType::Combobox, RO_DUNGEON_ENTRANCE_SHUFFLE_OFF); OPT_U8(RSK_SHUFFLE_BOSS_ENTRANCES, "Boss Entrances", {"Off", "Age Restricted", "Full"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), mOptionDescriptions[RSK_SHUFFLE_BOSS_ENTRANCES], WidgetType::Combobox, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF); + OPT_BOOL(RSK_SHUFFLE_GANON_TOWER_ENTRANCE, "Ganon Tower Entrance", CVAR_RANDOMIZER_SETTING("ShuffleGanonTowerEntrance"), mOptionDescriptions[RSK_SHUFFLE_GANON_TOWER_ENTRANCE]); OPT_BOOL(RSK_SHUFFLE_OVERWORLD_ENTRANCES, "Overworld Entrances", CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), mOptionDescriptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES]); OPT_U8(RSK_SHUFFLE_INTERIOR_ENTRANCES, "Interior Entrances", {"Off", "Simple", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), mOptionDescriptions[RSK_SHUFFLE_INTERIOR_ENTRANCES], WidgetType::Combobox, RO_INTERIOR_ENTRANCE_SHUFFLE_OFF); OPT_BOOL(RSK_SHUFFLE_GROTTO_ENTRANCES, "Grottos Entrances", CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), mOptionDescriptions[RSK_SHUFFLE_GROTTO_ENTRANCES]); @@ -594,6 +595,7 @@ void Settings::CreateOptions() { mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI] = OptionGroup::SubGroup("Shuffle Entrances", { &mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], &mOptions[RSK_SHUFFLE_BOSS_ENTRANCES], + &mOptions[RSK_SHUFFLE_GANON_TOWER_ENTRANCE], &mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES], &mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES], &mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES], @@ -829,6 +831,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ENTRANCES], &mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], &mOptions[RSK_SHUFFLE_BOSS_ENTRANCES], + &mOptions[RSK_SHUFFLE_GANON_TOWER_ENTRANCE], &mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES], &mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES], &mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES], @@ -1401,7 +1404,13 @@ void Settings::UpdateOptionProperties() { int overworldShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), RO_GENERIC_OFF); int interiorShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), RO_GENERIC_OFF); int grottoShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), RO_GENERIC_OFF); - + + if (!bossShuffle) { + mOptions[RSK_SHUFFLE_GANON_TOWER_ENTRANCE].Hide(); + } else { + mOptions[RSK_SHUFFLE_GANON_TOWER_ENTRANCE].Unhide(); + } + // Hide Mixed Entrances option if no applicable entrance shuffles are visible if (!dungeonShuffle && !bossShuffle && !overworldShuffle && !interiorShuffle && !grottoShuffle) { mOptions[RSK_MIXED_ENTRANCE_POOLS].Hide(); @@ -1885,6 +1894,7 @@ void Context::FinalizeSettings(const std::set& excludedLocation // If any of the individual shuffle settings are on, turn on the main Shuffle Entrances option if (mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES].IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) || mOptions[RSK_SHUFFLE_BOSS_ENTRANCES].IsNot(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) + || mOptions[RSK_SHUFFLE_GANON_TOWER_ENTRANCE] || mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES] || mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES].IsNot(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF) || mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES] || mOptions[RSK_SHUFFLE_OWL_DROPS] @@ -1894,6 +1904,10 @@ void Context::FinalizeSettings(const std::set& excludedLocation mOptions[RSK_SHUFFLE_ENTRANCES].Set(RO_GENERIC_OFF); } + if (mOptions[RSK_SHUFFLE_BOSS_ENTRANCES].Is(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { + mOptions[RSK_SHUFFLE_GANON_TOWER_ENTRANCE].Set(RO_GENERIC_OFF); + } + if (mOptions[RSK_SHUFFLE_DUNGEON_REWARDS].Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { mOptions[RSK_LINKS_POCKET].Set(RO_LINKS_POCKET_DUNGEON_REWARD); }