Rando: Boss Entrance Shuffle (#2194)

* sync 3ds upstream logic changes for boss rooms

* add boss shuffle settings and handling to 3ds code

* add boss shuffle handling to game code

* repair authentically bugged entrances for boss shuffle

* add boss entrances to the entrance tracker

* unset hint area for boss rooms to fix altar hint

* update boss reward hints to not mention dungeons

* one more boss heart container hint fix

* reorder entrance rando funcs

* support closed forest with boss shuffle and simple boss room entrance pairs in shuffle table

* fix death warp in boss rooms without saving; fix KD boss room in tracker

* remove boss shuffle check from dungeon open checks and some cleanups

* add boss shuffle to preset clear

* remove dungeon entry exit connection from boss rooms

* another no hint fix for boss shuffle

* undo change for exact location hints

* clarify comments
This commit is contained in:
Adam Bird 2023-01-20 01:00:12 -05:00 committed by GitHub
parent 7964bde063
commit 261db2c3e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 919 additions and 881 deletions

View File

@ -233,6 +233,7 @@ const std::vector<const char*> randomizerCvars = {
"gRandomizeShopsanity",
"gRandomizeShuffleAdultTrade",
"gRandomizeShuffleBeans",
"gRandomizeShuffleBossEntrances",
"gRandomizeShuffleCows",
"gRandomizeShuffleDungeonReward",
"gRandomizeShuffleDungeonsEntrances",

View File

@ -81,12 +81,25 @@ void SetAllEntrancesData(std::vector<EntranceInfoPair>& entranceShuffleTable) {
forwardEntrance->SetBlueWarp(forwardEntry.blueWarp);
forwardEntrance->SetType(forwardEntry.type);
forwardEntrance->SetAsPrimary();
// When decouple entrances is on, mark it for entrances except boss rooms
if (Settings::DecoupleEntrances && forwardEntry.type != EntranceType::ChildBoss &&
forwardEntry.type != EntranceType::AdultBoss) {
forwardEntrance->SetDecoupled();
}
if (returnEntry.parentRegion != NONE) {
Entrance* returnEntrance = AreaTable(returnEntry.parentRegion)->GetExit(returnEntry.connectedRegion);
returnEntrance->SetIndex(returnEntry.index);
returnEntrance->SetBlueWarp(returnEntry.blueWarp);
returnEntrance->SetType(returnEntry.type);
forwardEntrance->BindTwoWay(returnEntrance);
// Mark reverse entrance as decoupled
if (Settings::DecoupleEntrances && returnEntry.type != EntranceType::ChildBoss &&
returnEntry.type != EntranceType::AdultBoss) {
returnEntrance->SetDecoupled();
}
}
}
}
@ -96,7 +109,7 @@ static std::vector<Entrance*> AssumeEntrancePool(std::vector<Entrance*>& entranc
for (Entrance* entrance : entrancePool) {
totalRandomizableEntrances++;
Entrance* assumedForward = entrance->AssumeReachable();
if (entrance->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) {
Entrance* assumedReturn = entrance->GetReverse()->AssumeReachable();
if (!(Settings::MixedEntrancePools && (Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances.Is(SHUFFLEINTERIORS_ALL)))) {
auto type = entrance->GetType();
@ -218,7 +231,7 @@ static void ChangeConnections(Entrance* entrance, Entrance* targetEntrance) {
SPDLOG_DEBUG(message);
entrance->Connect(targetEntrance->Disconnect());
entrance->SetReplacement(targetEntrance->GetReplacement());
if (entrance->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) {
targetEntrance->GetReplacement()->GetReverse()->Connect(entrance->GetReverse()->GetAssumed()->Disconnect());
targetEntrance->GetReplacement()->GetReverse()->SetReplacement(entrance->GetReverse());
}
@ -229,7 +242,7 @@ static void ChangeConnections(Entrance* entrance, Entrance* targetEntrance) {
static void RestoreConnections(Entrance* entrance, Entrance* targetEntrance) {
targetEntrance->Connect(entrance->Disconnect());
entrance->SetReplacement(nullptr);
if (entrance->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) {
entrance->GetReverse()->GetAssumed()->Connect(targetEntrance->GetReplacement()->GetReverse()->Disconnect());
targetEntrance->GetReplacement()->GetReverse()->SetReplacement(nullptr);
}
@ -247,7 +260,7 @@ static void DeleteTargetEntrance(Entrance* targetEntrance) {
static void ConfirmReplacement(Entrance* entrance, Entrance* targetEntrance) {
DeleteTargetEntrance(targetEntrance);
if (entrance->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) {
auto replacedReverse = targetEntrance->GetReplacement()->GetReverse();
DeleteTargetEntrance(replacedReverse->GetReverse()->GetAssumed());
}
@ -786,9 +799,9 @@ int ShuffleAllEntrances() {
{EntranceType::SpecialInterior, KAK_POTION_SHOP_BACK, KAK_BACKYARD, 0x04FF}},
// Grotto Loads use an entrance index of 0x0700 + their grotto id. The id is used as index for the
// grottoLoadTable in src/grotto.c
// grottoLoadTable in soh/soh/Enhancements/randomizer/randomizer_grotto.c
// Grotto Returns use an entrance index of 0x0800 + their grotto id. The id is used as index for the
// grottoReturnTable in src/grotto.c
// grottoReturnTable in soh/soh/Enhancements/randomizer/randomizer_grotto.c
{{EntranceType::GrottoGrave, DESERT_COLOSSUS, COLOSSUS_GROTTO, 0x0700},
{EntranceType::GrottoGrave, COLOSSUS_GROTTO, DESERT_COLOSSUS, 0x0800}},
{{EntranceType::GrottoGrave, LAKE_HYLIA, LH_GROTTO, 0x0701},
@ -933,6 +946,23 @@ int ShuffleAllEntrances() {
{{EntranceType::WarpSong, REQUIEM_OF_SPIRIT_WARP, DESERT_COLOSSUS, 0x01F1}, NO_RETURN_ENTRANCE},
{{EntranceType::WarpSong, NOCTURNE_OF_SHADOW_WARP, GRAVEYARD_WARP_PAD_REGION, 0x0568}, NO_RETURN_ENTRANCE},
{{EntranceType::WarpSong, PRELUDE_OF_LIGHT_WARP, TEMPLE_OF_TIME, 0x05F4}, NO_RETURN_ENTRANCE},
{{EntranceType::ChildBoss, DEKU_TREE_BOSS_ENTRYWAY, DEKU_TREE_BOSS_ROOM, 0x040F},
{EntranceType::ChildBoss, DEKU_TREE_BOSS_ROOM, DEKU_TREE_BOSS_ENTRYWAY, 0x0252, 0x0457}},
{{EntranceType::ChildBoss, DODONGOS_CAVERN_BOSS_ENTRYWAY, DODONGOS_CAVERN_BOSS_ROOM, 0x040B},
{EntranceType::ChildBoss, DODONGOS_CAVERN_BOSS_ROOM, DODONGOS_CAVERN_BOSS_ENTRYWAY, 0x00C5, 0x047A}},
{{EntranceType::ChildBoss, JABU_JABUS_BELLY_BOSS_ENTRYWAY, JABU_JABUS_BELLY_BOSS_ROOM, 0x0301},
{EntranceType::ChildBoss, JABU_JABUS_BELLY_BOSS_ROOM, JABU_JABUS_BELLY_BOSS_ENTRYWAY, 0x0407, 0x010E}},
{{EntranceType::AdultBoss, FOREST_TEMPLE_BOSS_ENTRYWAY, FOREST_TEMPLE_BOSS_ROOM, 0x000C},
{EntranceType::AdultBoss, FOREST_TEMPLE_BOSS_ROOM, FOREST_TEMPLE_BOSS_ENTRYWAY, 0x024E, 0x0608}},
{{EntranceType::AdultBoss, FIRE_TEMPLE_BOSS_ENTRYWAY, FIRE_TEMPLE_BOSS_ROOM, 0x0305},
{EntranceType::AdultBoss, FIRE_TEMPLE_BOSS_ROOM, FIRE_TEMPLE_BOSS_ENTRYWAY, 0x0175, 0x0564}},
{{EntranceType::AdultBoss, WATER_TEMPLE_BOSS_ENTRYWAY, WATER_TEMPLE_BOSS_ROOM, 0x0417},
{EntranceType::AdultBoss, WATER_TEMPLE_BOSS_ROOM, WATER_TEMPLE_BOSS_ENTRYWAY, 0x0423, 0x060C}},
{{EntranceType::AdultBoss, SPIRIT_TEMPLE_BOSS_ENTRYWAY, SPIRIT_TEMPLE_BOSS_ROOM, 0x008D},
{EntranceType::AdultBoss, SPIRIT_TEMPLE_BOSS_ROOM, SPIRIT_TEMPLE_BOSS_ENTRYWAY, 0x02F5, 0x0610}},
{{EntranceType::AdultBoss, SHADOW_TEMPLE_BOSS_ENTRYWAY, SHADOW_TEMPLE_BOSS_ROOM, 0x0413},
{EntranceType::AdultBoss, SHADOW_TEMPLE_BOSS_ROOM, SHADOW_TEMPLE_BOSS_ENTRYWAY, 0x02B2, 0x0580}},
};
std::map<std::string, PriorityEntrance> priorityEntranceTable = {
@ -971,6 +1001,28 @@ int ShuffleAllEntrances() {
}
}
// Shuffle Bosses
if (Settings::ShuffleBossEntrances.IsNot(SHUFFLEBOSSES_OFF)) {
if (Settings::ShuffleBossEntrances.Is(SHUFFLEBOSSES_FULL)) {
entrancePools[EntranceType::Boss] = GetShuffleableEntrances(EntranceType::ChildBoss);
AddElementsToPool(entrancePools[EntranceType::Boss], GetShuffleableEntrances(EntranceType::AdultBoss));
// If forest is closed, ensure Ghoma is inside the Deku tree
// Deku tree being in its vanilla location is handled below
if (Settings::OpenForest.Is(OPENFOREST_CLOSED) && !(Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances)) {
FilterAndEraseFromPool(entrancePools[EntranceType::Boss], [](const Entrance* entrance){return entrance->GetParentRegionKey() == DEKU_TREE_BOSS_ENTRYWAY &&
entrance->GetConnectedRegionKey() == DEKU_TREE_BOSS_ROOM;});
}
} else {
entrancePools[EntranceType::ChildBoss] = GetShuffleableEntrances(EntranceType::ChildBoss);
entrancePools[EntranceType::AdultBoss] = GetShuffleableEntrances(EntranceType::AdultBoss);
// If forest is closed, ensure Ghoma is inside the Deku tree
if (Settings::OpenForest.Is(OPENFOREST_CLOSED) && !(Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances)) {
FilterAndEraseFromPool(entrancePools[EntranceType::ChildBoss], [](const Entrance* entrance){return entrance->GetParentRegionKey() == DEKU_TREE_BOSS_ENTRYWAY &&
entrance->GetConnectedRegionKey() == DEKU_TREE_BOSS_ROOM;});
}
}
}
//Shuffle Dungeon Entrances
if (Settings::ShuffleDungeonEntrances.IsNot(SHUFFLEDUNGEONS_OFF)) {
entrancePools[EntranceType::Dungeon] = GetShuffleableEntrances(EntranceType::Dungeon);

View File

@ -22,6 +22,9 @@ enum class EntranceType {
Dungeon,
GanonDungeon,
DungeonReverse,
Boss,
ChildBoss,
AdultBoss,
Interior,
InteriorReverse,
SpecialInterior,
@ -180,6 +183,14 @@ public:
return primary;
}
bool IsDecoupled() const {
return decoupled;
}
void SetDecoupled() {
decoupled = true;
}
int16_t GetIndex() const {
return index;
}
@ -269,6 +280,7 @@ private:
bool shuffled = false;
bool primary = false;
bool addedToPool = false;
bool decoupled = false;
std::string name = "";
};

View File

@ -296,7 +296,7 @@ std::vector<uint32_t> GetAccessibleLocations(const std::vector<uint32_t>& allowe
entranceSphere.push_back(&exit);
exit.AddToPool();
// Don't list a two-way coupled entrance from both directions
if (exit.GetReverse() != nullptr && exit.GetReplacement()->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
if (exit.GetReverse() != nullptr && exit.GetReplacement()->GetReverse() != nullptr && !exit.IsDecoupled()) {
exit.GetReplacement()->GetReverse()->AddToPool();
}
}

View File

@ -2519,93 +2519,61 @@ void HintTable_Init() {
| BOSS HINT TEXT |
---------------------------*/
hintTable[QUEEN_GOHMA] = HintText::Boss(
{
// obscure text
Text{ "An #ancient tree# rewards", /*french*/ "le #vieil arbre# octroie",
/*spanish*/ "un #ancestral árbol# premia con" },
},
{},
// clear text
Text{ "the #Deku Tree# rewards", /*french*/ "l'#Arbre Mojo# octroie",
/*spanish*/ "el #Gran Árbol Deku# premia con" });
hintTable[QUEEN_GOHMA] = HintText::Boss({
// obscure text
Text{"the #Parasitic Armored Arachnid# holds", /*french*/"le #monstre insectoïde géant# possède", /*spanish*/"el #arácnido parasitario acorazado# porta"},
}, {},
//clear text
Text{"#Queen Gohma# holds", /*french*/"la #Reine Gohma# possède", /*spanish*/"la #Reina Goma# porta"});
hintTable[KING_DODONGO] = HintText::Boss(
{
// obscure text
Text{ "An #immense cavern# rewards", /*french*/ "l'#immense caverne# octroie",
/*spanish*/ "una #descomunal cueva# premia con" },
},
{},
// clear text
Text{ "#Dodongo's Cavern# rewards", /*french*/ "la #Caverne Dodongo# octroie",
/*spanish*/ "la #Cueva de los Dodongos# premia con" });
hintTable[KING_DODONGO] = HintText::Boss({
//obscure text
Text{"the #Infernal Dinosaur# holds", /*french*/"le #dinosaure infernal# possède", /*spanish*/"el #dinosaurio infernal# porta"},
}, {},
//clear text
Text{"#King Dodongo# holds", /*french*/"le #Roi Dodongo# possède", /*spanish*/"el #Rey Dodongo# porta"});
hintTable[BARINADE] = HintText::Boss(
{
// obscure text
Text{ "the #belly of a deity# rewards", /*french*/ "le #ventre du gardien# octroie",
/*spanish*/ "la #tripa de cierta deidad# premia con" },
},
{},
// clear text
Text{ "#Jabu-Jabu's Belly# rewards", /*french*/ "le #Ventre de Jabu-Jabu# octroie",
/*spanish*/ "la #tripa de Jabu-Jabu# premia con" });
hintTable[BARINADE] = HintText::Boss({
//obscure text
Text{"the #Bio-Electric Anemone# holds", /*french*/"l'#anémone bioélectrique# possède", /*spanish*/"la #anémona bioeléctrica# porta"},
}, {},
//clear text
Text{"#Barinade# holds", /*french*/"#Barinade# possède", /*spanish*/"#Barinade# porta"});
hintTable[PHANTOM_GANON] = HintText::Boss(
{
// obscure text
Text{ "a #deep forest# rewards", /*french*/ "la #profonde forêt# octroie",
/*spanish*/ "el #profundo bosque# premia con" },
},
{},
// clear text
Text{ "the #Forest Temple# rewards", /*french*/ "le #Temple de la Forêt# octroie",
/*spanish*/ "el #Templo del Bosque# premia con" });
hintTable[PHANTOM_GANON] = HintText::Boss({
//obscure text
Text{"the #Evil Spirit from Beyond# holds", /*french*/"l'#esprit maléfique de l'au-delà# possède", /*spanish*/"el #espíritu maligno de ultratumba# porta"},
}, {},
//clear text
Text{"#Phantom Ganon# holds", /*french*/"#Ganon Spectral# possède", /*spanish*/"#Ganon Fantasma# porta"});
hintTable[VOLVAGIA] = HintText::Boss(
{
// obscure text
Text{ "a #high mountain# rewards", /*french*/ "la #grande montagne# octroie",
/*spanish*/ "una #alta montaña# premia con" },
},
{},
// clear text
Text{ "the #Fire Temple# rewards", /*french*/ "le #Temple du Feu# octroie",
/*spanish*/ "el #Templo del Fuego# premia con" });
hintTable[VOLVAGIA] = HintText::Boss({
//obscure text
Text{"the #Subterranean Lava Dragon# holds", /*french*/"le #dragon des profondeurs# possède", /*spanish*/"el #dragón de lava subterráneo# porta"},
}, {},
//clear text
Text{"#Volvagia# holds", /*french*/"#Volvagia# possède", /*spanish*/"#Volvagia# porta"});
hintTable[MORPHA] = HintText::Boss(
{
// obscure text
Text{ "a #vast lake# rewards", /*french*/ "le #vaste lac# octroie",
/*spanish*/ "un #lago inmenso# premia con" },
},
{},
// clear text
Text{ "the #Water Temple# rewards", /*french*/ "le #Temple de l'Eau# octroie",
/*spanish*/ "el #Templo del Agua# premia con" });
hintTable[MORPHA] = HintText::Boss({
//obscure text
Text{"the #Giant Aquatic Amoeba# holds", /*french*/"l'#amibe aquatique géante# possède", /*spanish*/"la #ameba acuática gigante# porta"},
}, {},
//clear text
Text{"#Morpha# holds", /*french*/"#Morpha# possède", /*spanish*/"#Morpha# porta"});
hintTable[BONGO_BONGO] = HintText::Boss(
{
// obscure text
Text{ "the #house of the dead# rewards", /*french*/ "la #maison des morts# octroie",
/*spanish*/ "la #casa de la muerte# premia con" },
},
{},
// clear text
Text{ "the #Shadow Temple# rewards", /*french*/ "le #Temple de l'Ombre# octroie",
/*spanish*/ "el #Templo de las Sombras#" });
hintTable[BONGO_BONGO] = HintText::Boss({
//obscure text
Text{"the #Phantom Shadow Beast# holds", /*french*/"le #monstre de l'ombre# possède", /*spanish*/"la #alimaña oscura espectral# porta"},
}, {},
//clear text
Text{"#Bongo Bongo# holds", /*french*/"#Bongo Bongo# possède", /*spanish*/"#Bongo Bongo# porta"});
hintTable[TWINROVA] = HintText::Boss(
{
// obscure text
Text{ "a #goddess of the sand# rewards", /*french*/ "la #déesse des sables# octroie",
/*spanish*/ "la #diosa de la arena# premia con" },
},
{},
// clear text
Text{ "the #Spirit Temple# rewards", /*french*/ "le #Temple de l'Esprit# octroie",
/*spanish*/ "el #Templo del Espíritu# premia con" });
hintTable[TWINROVA] = HintText::Boss({
//obscure text
Text{"the #Sorceress Sisters# hold", /*french*/"#les sorcières jumelles# possède", /*spanish*/"las #hermanas hechiceras# portan"},
}, {},
//clear text
Text{"#Twinrova# holds", /*french*/"#Twinrova# possède", /*spanish*/"#Birova# porta"});
//
// [LINKS_POCKET_BOSS] = HintText::Boss({
// //obscure text

View File

@ -317,17 +317,12 @@ static void CreateWothHint(uint8_t* remainingDungeonWothHints) {
Location(hintedLocation)->SetAsHinted();
uint32_t gossipStone = RandomElement(gossipStoneLocations);
// form hint text
Text locationText;
if (Location(hintedLocation)->IsDungeon()) {
*remainingDungeonWothHints -= 1;
uint32_t parentRegion = Location(hintedLocation)->GetParentRegionKey();
locationText = AreaTable(parentRegion)->GetHint().GetText();
} else {
uint32_t parentRegion = Location(hintedLocation)->GetParentRegionKey();
locationText = GetHintRegion(parentRegion)->GetHint().GetText();
}
// form hint text
Text locationText = GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->GetHint().GetText();
Text finalWothHint = Hint(PREFIX).GetText() + "#" + locationText + "#" + Hint(WAY_OF_THE_HERO).GetText();
SPDLOG_DEBUG("\tMessage: ");
SPDLOG_DEBUG(finalWothHint.english);
@ -365,16 +360,12 @@ static void CreateBarrenHint(uint8_t* remainingDungeonBarrenHints, std::vector<u
Location(hintedLocation)->SetAsHinted();
uint32_t gossipStone = RandomElement(gossipStoneLocations);
// form hint text
Text locationText;
if (Location(hintedLocation)->IsDungeon()) {
*remainingDungeonBarrenHints -= 1;
uint32_t parentRegion = Location(hintedLocation)->GetParentRegionKey();
locationText = Hint(AreaTable(parentRegion)->hintKey).GetText();
} else {
uint32_t parentRegion = Location(hintedLocation)->GetParentRegionKey();
locationText = Hint(GetHintRegion(parentRegion)->hintKey).GetText();
}
// form hint text
Text locationText = GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->GetHint().GetText();
Text finalBarrenHint =
Hint(PREFIX).GetText() + Hint(PLUNDERING).GetText() + "#" + locationText + "#" + Hint(FOOLISH).GetText();
SPDLOG_DEBUG("\tMessage: ");
@ -419,16 +410,15 @@ static void CreateRandomLocationHint(const bool goodItem = false) {
//form hint text
Text itemText = Location(hintedLocation)->GetPlacedItem().GetHint().GetText();
Text locationText = GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->GetHint().GetText();
// RANDOTODO: reconsider dungeon vs non-dungeon item location hints when boss shuffle mixed pools happens
if (Location(hintedLocation)->IsDungeon()) {
uint32_t parentRegion = Location(hintedLocation)->GetParentRegionKey();
Text locationText = AreaTable(parentRegion)->GetHint().GetText();
Text finalHint = Hint(PREFIX).GetText()+"#"+locationText+"# "+Hint(HOARDS).GetText()+" #"+itemText+"#.";
SPDLOG_DEBUG("\tMessage: ");
SPDLOG_DEBUG(finalHint.english);
SPDLOG_DEBUG("\n\n");
AddHint(finalHint, gossipStone, {QM_GREEN, QM_RED});
} else {
Text locationText = GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->GetHint().GetText();
Text finalHint = Hint(PREFIX).GetText()+"#"+itemText+"# "+Hint(CAN_BE_FOUND_AT).GetText()+" #"+locationText+"#.";
SPDLOG_DEBUG("\tMessage: ");
SPDLOG_DEBUG(finalHint.english);

View File

@ -1083,6 +1083,8 @@ typedef enum {
DEATH_MOUNTAIN_CRATER,
//AREAS
MARKER_AREAS_START, // Used for area key count
ROOT,
ROOT_EXITS,
CHILD_SPAWN,
@ -1263,6 +1265,16 @@ typedef enum {
DEKU_TREE_BASEMENT_BACK_ROOM,
DEKU_TREE_BASEMENT_UPPER,
DEKU_TREE_OUTSIDE_BOSS_ROOM,
DEKU_TREE_MQ_LOBBY,
DEKU_TREE_MQ_COMPASS_ROOM,
DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT,
DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK,
DEKU_TREE_MQ_BASEMENT_BACK_ROOM,
DEKU_TREE_MQ_BASEMENT_LEDGE,
DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM,
DEKU_TREE_BOSS_ENTRYWAY,
DEKU_TREE_BOSS_ROOM,
DODONGOS_CAVERN_BEGINNING,
@ -1287,6 +1299,14 @@ typedef enum {
DODONGOS_CAVERN_FAR_BRIDGE,
DODONGOS_CAVERN_BOSS_AREA,
DODONGOS_CAVERN_BACK_ROOM,
DODONGOS_CAVERN_MQ_BEGINNING,
DODONGOS_CAVERN_MQ_LOBBY,
DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE,
DODONGOS_CAVERN_MQ_BOMB_BAG_AREA,
DODONGOS_CAVERN_MQ_BOSS_AREA,
DODONGOS_CAVERN_BOSS_ENTRYWAY,
DODONGOS_CAVERN_BOSS_ROOM,
JABU_JABUS_BELLY_BEGINNING,
@ -1306,6 +1326,13 @@ typedef enum {
JABU_JABUS_BELLY_ABOVE_BIGOCTO,
JABU_JABUS_BELLY_LIFT_UPPER,
JABU_JABUS_BELLY_NEAR_BOSS_ROOM,
JABU_JABUS_BELLY_MQ_BEGINNING,
JABU_JABUS_BELLY_MQ_MAIN,
JABU_JABUS_BELLY_MQ_DEPTHS,
JABU_JABUS_BELLY_MQ_BOSS_AREA,
JABU_JABUS_BELLY_BOSS_ENTRYWAY,
JABU_JABUS_BELLY_BOSS_ROOM,
FOREST_TEMPLE_FIRST_ROOM,
@ -1335,11 +1362,24 @@ typedef enum {
FOREST_TEMPLE_GREEN_POE_ROOM,
FOREST_TEMPLE_EAST_CORRIDOR,
FOREST_TEMPLE_BOSS_REGION,
FOREST_TEMPLE_MQ_LOBBY,
FOREST_TEMPLE_MQ_CENTRAL_AREA,
FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE,
FOREST_TEMPLE_MQ_OUTDOOR_LEDGE,
FOREST_TEMPLE_MQ_NW_OUTDOORS,
FOREST_TEMPLE_MQ_NE_OUTDOORS,
FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES,
FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE,
FOREST_TEMPLE_MQ_BOW_REGION,
FOREST_TEMPLE_MQ_FALLING_ROOM,
FOREST_TEMPLE_MQ_BOSS_REGION,
FOREST_TEMPLE_BOSS_ENTRYWAY,
FOREST_TEMPLE_BOSS_ROOM,
FIRE_TEMPLE_FIRST_ROOM,
FIRE_TEMPLE_NEAR_BOSS_ROOM,
FIRE_TEMPLE_BOSS_ROOM,
FIRE_TEMPLE_LOOP_ENEMIES,
FIRE_TEMPLE_LOOP_TILES,
FIRE_TEMPLE_LOOP_FLARE_DANCER,
@ -1374,6 +1414,16 @@ typedef enum {
FIRE_TEMPLE_HAMMER_RETURN_PATH,
FIRE_TEMPLE_ABOVE_FIRE_MAZE,
FIRE_TEMPLE_MQ_LOWER,
FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR,
FIRE_TEMPLE_MQ_BIG_LAVA_ROOM,
FIRE_TEMPLE_MQ_LOWER_MAZE,
FIRE_TEMPLE_MQ_UPPER_MAZE,
FIRE_TEMPLE_MQ_UPPER,
FIRE_TEMPLE_BOSS_ENTRYWAY,
FIRE_TEMPLE_BOSS_ROOM,
WATER_TEMPLE_LOBBY,
WATER_TEMPLE_EAST_LOWER,
WATER_TEMPLE_MAP_ROOM,
@ -1401,6 +1451,14 @@ typedef enum {
WATER_TEMPLE_LONGSHOT_ROOM,
WATER_TEMPLE_RIVER,
WATER_TEMPLE_PRE_BOSS_ROOM,
WATER_TEMPLE_MQ_LOBBY,
WATER_TEMPLE_MQ_DIVE,
WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS,
WATER_TEMPLE_MQ_DARK_LINK_REGION,
WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS,
WATER_TEMPLE_BOSS_ENTRYWAY,
WATER_TEMPLE_BOSS_ROOM,
SPIRIT_TEMPLE_LOBBY,
@ -1411,82 +1469,7 @@ typedef enum {
SPIRIT_TEMPLE_OUTDOOR_HANDS,
SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR,
SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR,
SHADOW_TEMPLE_BEGINNING,
SHADOW_TEMPLE_FIRST_BEAMOS,
SHADOW_TEMPLE_HUGE_PIT,
SHADOW_TEMPLE_WIND_TUNNEL,
SHADOW_TEMPLE_BEYOND_BOAT,
BOTTOM_OF_THE_WELL,
BOTTOM_OF_THE_WELL_MAIN_AREA,
ICE_CAVERN_BEGINNING,
ICE_CAVERN_MAIN,
GERUDO_TRAINING_GROUNDS_LOBBY,
GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE,
GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT,
GERUDO_TRAINING_GROUNDS_LAVA_ROOM,
GERUDO_TRAINING_GROUNDS_HAMMER_ROOM,
GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER,
GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER,
GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM,
GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM,
GANONS_CASTLE_LOBBY,
GANONS_CASTLE_DEKU_SCRUBS,
GANONS_CASTLE_FOREST_TRIAL,
GANONS_CASTLE_FIRE_TRIAL,
GANONS_CASTLE_WATER_TRIAL,
GANONS_CASTLE_SHADOW_TRIAL,
GANONS_CASTLE_SPIRIT_TRIAL,
GANONS_CASTLE_LIGHT_TRIAL,
GANONS_CASTLE_TOWER,
DEKU_TREE_MQ_LOBBY,
DEKU_TREE_MQ_COMPASS_ROOM,
DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT,
DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK,
DEKU_TREE_MQ_BASEMENT_BACK_ROOM,
DEKU_TREE_MQ_BASEMENT_LEDGE,
DODONGOS_CAVERN_MQ_BEGINNING,
DODONGOS_CAVERN_MQ_LOBBY,
DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE,
DODONGOS_CAVERN_MQ_BOMB_BAG_AREA,
DODONGOS_CAVERN_MQ_BOSS_AREA,
JABU_JABUS_BELLY_MQ_BEGINNING,
JABU_JABUS_BELLY_MQ_MAIN,
JABU_JABUS_BELLY_MQ_DEPTHS,
JABU_JABUS_BELLY_MQ_BOSS_AREA,
FOREST_TEMPLE_MQ_LOBBY,
FOREST_TEMPLE_MQ_CENTRAL_AREA,
FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE,
FOREST_TEMPLE_MQ_OUTDOOR_LEDGE,
FOREST_TEMPLE_MQ_NW_OUTDOORS,
FOREST_TEMPLE_MQ_NE_OUTDOORS,
FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES,
FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE,
FOREST_TEMPLE_MQ_BOW_REGION,
FOREST_TEMPLE_MQ_FALLING_ROOM,
FOREST_TEMPLE_MQ_BOSS_REGION,
FIRE_TEMPLE_MQ_LOWER,
FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR,
FIRE_TEMPLE_MQ_BIG_LAVA_ROOM,
FIRE_TEMPLE_MQ_LOWER_MAZE,
FIRE_TEMPLE_MQ_UPPER_MAZE,
FIRE_TEMPLE_MQ_UPPER,
FIRE_TEMPLE_MQ_BOSS_ROOM,
WATER_TEMPLE_MQ_LOBBY,
WATER_TEMPLE_MQ_DIVE,
WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS,
WATER_TEMPLE_MQ_DARK_LINK_REGION,
WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS,
SPIRIT_TEMPLE_INSIDE_STATUE_HEAD,
SPIRIT_TEMPLE_MQ_LOBBY,
SPIRIT_TEMPLE_MQ_CHILD,
@ -1496,6 +1479,16 @@ typedef enum {
SPIRIT_TEMPLE_MQ_BOSS_AREA,
SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND,
SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND,
SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD,
SPIRIT_TEMPLE_BOSS_ENTRYWAY,
SPIRIT_TEMPLE_BOSS_ROOM,
SHADOW_TEMPLE_BEGINNING,
SHADOW_TEMPLE_FIRST_BEAMOS,
SHADOW_TEMPLE_HUGE_PIT,
SHADOW_TEMPLE_WIND_TUNNEL,
SHADOW_TEMPLE_BEYOND_BOAT,
SHADOW_TEMPLE_MQ_ENTRYWAY,
SHADOW_TEMPLE_MQ_BEGINNING,
@ -1507,15 +1500,32 @@ typedef enum {
SHADOW_TEMPLE_MQ_BEYOND_BOAT,
SHADOW_TEMPLE_MQ_INVISIBLE_MAZE,
BOTTOM_OF_THE_WELL_MQ,
SHADOW_TEMPLE_BOSS_ENTRYWAY,
SHADOW_TEMPLE_BOSS_ROOM,
BOTTOM_OF_THE_WELL_MAIN_AREA,
BOTTOM_OF_THE_WELL_MQ_PERIMETER,
BOTTOM_OF_THE_WELL_MQ_MIDDLE,
ICE_CAVERN_BEGINNING,
ICE_CAVERN_MAIN,
ICE_CAVERN_MQ_BEGINNING,
ICE_CAVERN_MQ_MAP_ROOM,
ICE_CAVERN_MQ_IRON_BOOTS_REGION,
ICE_CAVERN_MQ_COMPASS_ROOM,
GERUDO_TRAINING_GROUNDS_LOBBY,
GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE,
GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT,
GERUDO_TRAINING_GROUNDS_LAVA_ROOM,
GERUDO_TRAINING_GROUNDS_HAMMER_ROOM,
GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER,
GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER,
GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM,
GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM,
GERUDO_TRAINING_GROUNDS_MQ_LOBBY,
GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE,
GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER,
@ -1524,6 +1534,16 @@ typedef enum {
GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS,
GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT,
GANONS_CASTLE_LOBBY,
GANONS_CASTLE_DEKU_SCRUBS,
GANONS_CASTLE_FOREST_TRIAL,
GANONS_CASTLE_FIRE_TRIAL,
GANONS_CASTLE_WATER_TRIAL,
GANONS_CASTLE_SHADOW_TRIAL,
GANONS_CASTLE_SPIRIT_TRIAL,
GANONS_CASTLE_LIGHT_TRIAL,
GANONS_CASTLE_TOWER,
GANONS_CASTLE_MQ_LOBBY,
GANONS_CASTLE_MQ_DEKU_SCRUBS,
GANONS_CASTLE_MQ_FOREST_TRIAL,
@ -1533,6 +1553,8 @@ typedef enum {
GANONS_CASTLE_MQ_SPIRIT_TRIAL,
GANONS_CASTLE_MQ_LIGHT_TRIAL,
MARKER_AREAS_END, // Used for area key count
//DUNGEONS
DEKU_TREE,
DODONGOS_CAVERN,
@ -1542,8 +1564,8 @@ typedef enum {
WATER_TEMPLE,
SPIRIT_TEMPLE,
SHADOW_TEMPLE,
BOTTOM_OF_THE_WELL,
ICE_CAVERN,
//BOTTOM_OF_THE_WELL,
GERUDO_TRAINING_GROUNDS,
GANONS_CASTLE,

View File

@ -371,458 +371,24 @@ void AreaTable_Init() {
namespace Areas {
static std::array<const uint32_t, 424> allAreas = {
ROOT,
ROOT_EXITS,
const auto GetAllAreas() {
static const size_t areaCount = MARKER_AREAS_END - (MARKER_AREAS_START + 1);
CHILD_SPAWN,
ADULT_SPAWN,
MINUET_OF_FOREST_WARP,
BOLERO_OF_FIRE_WARP,
SERENADE_OF_WATER_WARP,
REQUIEM_OF_SPIRIT_WARP,
NOCTURNE_OF_SHADOW_WARP,
PRELUDE_OF_LIGHT_WARP,
static std::array<uint32_t, areaCount> allAreas = {};
KOKIRI_FOREST,
KF_LINKS_HOUSE,
KF_MIDOS_HOUSE,
KF_SARIAS_HOUSE,
KF_HOUSE_OF_TWINS,
KF_KNOW_IT_ALL_HOUSE,
KF_KOKIRI_SHOP,
KF_STORMS_GROTTO,
KF_OUTSIDE_DEKU_TREE,
DEKU_TREE_ENTRYWAY,
static bool intialized = false;
if (!intialized) {
for (size_t i = 0; i < areaCount; i++) {
allAreas[i] = (MARKER_AREAS_START + 1) + i;
}
intialized = true;
}
THE_LOST_WOODS,
LW_BRIDGE_FROM_FOREST,
LW_BRIDGE,
LW_FOREST_EXIT,
LW_BEYOND_MIDO,
LW_NEAR_SHORTCUTS_GROTTO,
DEKU_THEATER,
LW_SCRUBS_GROTTO,
SFM_ENTRYWAY,
SACRED_FOREST_MEADOW,
SFM_WOLFOS_GROTTO,
SFM_FAIRY_GROTTO,
SFM_STORMS_GROTTO,
FOREST_TEMPLE_ENTRYWAY,
KAKARIKO_VILLAGE,
KAK_CARPENTER_BOSS_HOUSE,
KAK_HOUSE_OF_SKULLTULA,
KAK_IMPAS_HOUSE,
KAK_IMPAS_LEDGE,
KAK_IMPAS_HOUSE_BACK,
KAK_IMPAS_HOUSE_NEAR_COW,
KAK_WINDMILL,
KAK_BAZAAR,
KAK_SHOOTING_GALLERY,
KAK_POTION_SHOP_FRONT,
KAK_POTION_SHOP_BACK,
KAK_ROOFTOP,
KAK_IMPAS_ROOFTOP,
KAK_BEHIND_GATE,
KAK_BACKYARD,
KAK_ODD_POTION_BUILDING,
KAK_REDEAD_GROTTO,
KAK_OPEN_GROTTO,
BOTTOM_OF_THE_WELL_ENTRYWAY,
THE_GRAVEYARD,
GRAVEYARD_DAMPES_GRAVE,
GRAVEYARD_DAMPES_HOUSE,
GRAVEYARD_SHIELD_GRAVE,
GRAVEYARD_COMPOSERS_GRAVE,
GRAVEYARD_HEART_PIECE_GRAVE,
GRAVEYARD_WARP_PAD_REGION,
SHADOW_TEMPLE_ENTRYWAY,
DEATH_MOUNTAIN_TRAIL,
DEATH_MOUNTAIN_SUMMIT,
DMT_OWL_FLIGHT,
DMT_GREAT_FAIRY_FOUNTAIN,
DMT_COW_GROTTO,
DMT_STORMS_GROTTO,
DODONGOS_CAVERN_ENTRYWAY,
DMC_UPPER_LOCAL,
DMC_CENTRAL_LOCAL,
DMC_LOWER_LOCAL,
DMC_LOWER_NEARBY,
DMC_UPPER_NEARBY,
DMC_CENTRAL_NEARBY,
DMC_LADDER_AREA_NEARBY,
DMC_UPPER_GROTTO,
DMC_HAMMER_GROTTO,
DMC_GREAT_FAIRY_FOUNTAIN,
FIRE_TEMPLE_ENTRYWAY,
GORON_CITY,
GC_WOODS_WARP,
GC_DARUNIAS_CHAMBER,
GC_GROTTO_PLATFORM,
GC_SHOP,
GC_GROTTO,
ZR_FRONT,
ZORAS_RIVER,
ZR_BEHIND_WATERFALL,
ZR_OPEN_GROTTO,
ZR_FAIRY_GROTTO,
ZR_STORMS_GROTTO,
ZORAS_DOMAIN,
ZD_BEHIND_KING_ZORA,
ZD_SHOP,
ZD_STORMS_GROTTO,
ZORAS_FOUNTAIN,
ZF_GREAT_FAIRY_FOUNTAIN,
JABU_JABUS_BELLY_ENTRYWAY,
ICE_CAVERN_ENTRYWAY,
HYRULE_FIELD,
HF_SOUTHEAST_GROTTO,
HF_OPEN_GROTTO,
HF_INSIDE_FENCE_GROTTO,
HF_COW_GROTTO,
HF_NEAR_MARKET_GROTTO,
HF_FAIRY_GROTTO,
HF_NEAR_KAK_GROTTO,
HF_TEKTITE_GROTTO,
LON_LON_RANCH,
LLR_TALONS_HOUSE,
LLR_STABLES,
LLR_TOWER,
LLR_GROTTO,
LAKE_HYLIA,
LH_OWL_FLIGHT,
LH_LAB,
LH_FISHING_ISLAND,
LH_FISHING_HOLE,
LH_GROTTO,
WATER_TEMPLE_ENTRYWAY,
GERUDO_VALLEY,
GV_UPPER_STREAM,
GV_LOWER_STREAM,
GV_GROTTO_LEDGE,
GV_CRATE_LEDGE,
GV_OCTOROK_GROTTO,
GV_FORTRESS_SIDE,
GV_CARPENTER_TENT,
GV_STORMS_GROTTO,
GERUDO_FORTRESS,
GF_OUTSIDE_GATE,
GF_STORMS_GROTTO,
GERUDO_TRAINING_GROUNDS_ENTRYWAY,
WASTELAND_NEAR_FORTRESS,
HAUNTED_WASTELAND,
WASTELAND_NEAR_COLOSSUS,
DESERT_COLOSSUS,
DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY,
COLOSSUS_GREAT_FAIRY_FOUNTAIN,
COLOSSUS_GROTTO,
SPIRIT_TEMPLE_ENTRYWAY,
MARKET_ENTRANCE,
THE_MARKET,
MARKET_GUARD_HOUSE,
MARKET_BAZAAR,
MARKET_MASK_SHOP,
MARKET_SHOOTING_GALLERY,
MARKET_BOMBCHU_BOWLING,
MARKET_TREASURE_CHEST_GAME,
MARKET_POTION_SHOP,
MARKET_BACK_ALLEY,
MARKET_BOMBCHU_SHOP,
MARKET_DOG_LADY_HOUSE,
MARKET_MAN_IN_GREEN_HOUSE,
TOT_ENTRANCE,
TEMPLE_OF_TIME,
TOT_BEYOND_DOOR_OF_TIME,
CASTLE_GROUNDS,
HYRULE_CASTLE_GROUNDS,
HC_GARDEN,
HC_GREAT_FAIRY_FOUNTAIN,
HC_STORMS_GROTTO,
GANONS_CASTLE_GROUNDS,
OGC_GREAT_FAIRY_FOUNTAIN,
GANONS_CASTLE_ENTRYWAY,
DEKU_TREE_LOBBY,
DEKU_TREE_2F_MIDDLE_ROOM,
DEKU_TREE_SLINGSHOT_ROOM,
DEKU_TREE_COMPASS_ROOM,
DEKU_TREE_BASEMENT_LOWER,
DEKU_TREE_BASEMENT_SCRUB_ROOM,
DEKU_TREE_BASEMENT_WATER_ROOM,
DEKU_TREE_BASEMENT_TORCH_ROOM,
DEKU_TREE_BASEMENT_BACK_LOBBY,
DEKU_TREE_BASEMENT_BACK_ROOM,
DEKU_TREE_BASEMENT_UPPER,
DEKU_TREE_OUTSIDE_BOSS_ROOM,
DEKU_TREE_BOSS_ROOM,
DODONGOS_CAVERN_BEGINNING,
DODONGOS_CAVERN_LOBBY,
DODONGOS_CAVERN_LOBBY_SWITCH,
DODONGOS_CAVERN_SE_CORRIDOR,
DODONGOS_CAVERN_SE_ROOM,
DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS,
DODONGOS_CAVERN_LOWER_LIZALFOS,
DODONGOS_CAVERN_DODONGO_ROOM,
DODONGOS_CAVERN_NEAR_DODONGO_ROOM,
DODONGOS_CAVERN_STAIRS_LOWER,
DODONGOS_CAVERN_STAIRS_UPPER,
DODONGOS_CAVERN_COMPASS_ROOM,
DODONGOS_CAVERN_ARMOS_ROOM,
DODONGOS_CAVERN_BOMB_ROOM_LOWER,
DODONGOS_CAVERN_2F_SIDE_ROOM,
DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM,
DODONGOS_CAVERN_UPPER_LIZALFOS,
DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM,
DODONGOS_CAVERN_BOMB_ROOM_UPPER,
DODONGOS_CAVERN_FAR_BRIDGE,
DODONGOS_CAVERN_BOSS_AREA,
DODONGOS_CAVERN_BACK_ROOM,
DODONGOS_CAVERN_BOSS_ROOM,
JABU_JABUS_BELLY_BEGINNING,
JABU_JABUS_BELLY_LIFT_MIDDLE,
JABU_JABUS_BELLY_MAIN_UPPER,
JABU_JABUS_BELLY_MAIN_LOWER,
JABU_JABUS_BELLY_SHABOMB_CORRIDOR,
JABU_JABUS_BELLY_LOWER_SIDE_ROOM,
JABU_JABUS_BELLY_LIFT_LOWER,
JABU_JABUS_BELLY_FORKED_CORRIDOR,
JABU_JABUS_BELLY_BOOMERANG_ROOM,
JABU_JABUS_BELLY_MAP_ROOM,
JABU_JABUS_BELLY_COMPASS_ROOM,
JABU_JABUS_BELLY_BLUE_TENTACLE,
JABU_JABUS_BELLY_GREEN_TENTACLE,
JABU_JABUS_BELLY_BIGOCTO_ROOM,
JABU_JABUS_BELLY_ABOVE_BIGOCTO,
JABU_JABUS_BELLY_LIFT_UPPER,
JABU_JABUS_BELLY_NEAR_BOSS_ROOM,
JABU_JABUS_BELLY_BOSS_ROOM,
FOREST_TEMPLE_FIRST_ROOM,
FOREST_TEMPLE_SOUTH_CORRIDOR,
FOREST_TEMPLE_LOBBY,
FOREST_TEMPLE_NORTH_CORRIDOR,
FOREST_TEMPLE_LOWER_STALFOS,
FOREST_TEMPLE_NW_OUTDOORS_LOWER,
FOREST_TEMPLE_NW_OUTDOORS_UPPER,
FOREST_TEMPLE_NE_OUTDOORS_LOWER,
FOREST_TEMPLE_NE_OUTDOORS_UPPER,
FOREST_TEMPLE_MAP_ROOM,
FOREST_TEMPLE_SEWER,
FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST,
FOREST_TEMPLE_FLOORMASTER_ROOM,
FOREST_TEMPLE_WEST_CORRIDOR,
FOREST_TEMPLE_BLOCK_PUSH_ROOM,
FOREST_TEMPLE_NW_CORRIDOR_TWISTED,
FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED,
FOREST_TEMPLE_RED_POE_ROOM,
FOREST_TEMPLE_UPPER_STALFOS,
FOREST_TEMPLE_BLUE_POE_ROOM,
FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED,
FOREST_TEMPLE_NE_CORRIDOR_TWISTED,
FOREST_TEMPLE_FROZEN_EYE_ROOM,
FOREST_TEMPLE_FALLING_ROOM,
FOREST_TEMPLE_GREEN_POE_ROOM,
FOREST_TEMPLE_EAST_CORRIDOR,
FOREST_TEMPLE_BOSS_REGION,
FOREST_TEMPLE_BOSS_ROOM,
FIRE_TEMPLE_FIRST_ROOM,
FIRE_TEMPLE_NEAR_BOSS_ROOM,
FIRE_TEMPLE_BOSS_ROOM,
FIRE_TEMPLE_LOOP_ENEMIES,
FIRE_TEMPLE_LOOP_TILES,
FIRE_TEMPLE_LOOP_FLARE_DANCER,
FIRE_TEMPLE_LOOP_HAMMER_SWITCH,
FIRE_TEMPLE_LOOP_GORON_ROOM,
FIRE_TEMPLE_LOOP_EXIT,
FIRE_TEMPLE_BIG_LAVA_ROOM,
FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON,
FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES,
FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON,
FIRE_TEMPLE_FIRE_PILLAR_ROOM,
FIRE_TEMPLE_SHORTCUT_ROOM,
FIRE_TEMPLE_SHORTCUT_CLIMB,
FIRE_TEMPLE_BOULDER_MAZE_LOWER,
FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM,
FIRE_TEMPLE_EAST_CENTRAL_ROOM,
FIRE_TEMPLE_FIRE_WALL_CHASE,
FIRE_TEMPLE_MAP_AREA,
FIRE_TEMPLE_BOULDER_MAZE_UPPER,
FIRE_TEMPLE_SCARECROW_ROOM,
FIRE_TEMPLE_EAST_PEAK,
FIRE_TEMPLE_CORRIDOR,
FIRE_TEMPLE_FIRE_MAZE_ROOM,
FIRE_TEMPLE_FIRE_MAZE_UPPER,
FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM,
FIRE_TEMPLE_WEST_CENTRAL_LOWER,
FIRE_TEMPLE_WEST_CENTRAL_UPPER,
FIRE_TEMPLE_LATE_FIRE_MAZE,
FIRE_TEMPLE_UPPER_FLARE_DANCER,
FIRE_TEMPLE_WEST_CLIMB,
FIRE_TEMPLE_WEST_PEAK,
FIRE_TEMPLE_HAMMER_RETURN_PATH,
FIRE_TEMPLE_ABOVE_FIRE_MAZE,
WATER_TEMPLE_LOBBY,
WATER_TEMPLE_EAST_LOWER,
WATER_TEMPLE_MAP_ROOM,
WATER_TEMPLE_CRACKED_WALL,
WATER_TEMPLE_TORCH_ROOM,
WATER_TEMPLE_NORTH_LOWER,
WATER_TEMPLE_BOULDERS_LOWER,
WATER_TEMPLE_BLOCK_ROOM,
WATER_TEMPLE_JETS_ROOM,
WATER_TEMPLE_BOULDERS_UPPER,
WATER_TEMPLE_BOSS_KEY_ROOM,
WATER_TEMPLE_SOUTH_LOWER,
WATER_TEMPLE_WEST_LOWER,
WATER_TEMPLE_DRAGON_ROOM,
WATER_TEMPLE_CENTRAL_PILLAR_LOWER,
WATER_TEMPLE_CENTRAL_PILLAR_UPPER,
WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT,
WATER_TEMPLE_EAST_MIDDLE,
WATER_TEMPLE_WEST_MIDDLE,
WATER_TEMPLE_HIGH_WATER,
WATER_TEMPLE_BLOCK_CORRIDOR,
WATER_TEMPLE_FALLING_PLATFORM_ROOM,
WATER_TEMPLE_DRAGON_PILLARS_ROOM,
WATER_TEMPLE_DARK_LINK_ROOM,
WATER_TEMPLE_LONGSHOT_ROOM,
WATER_TEMPLE_RIVER,
WATER_TEMPLE_PRE_BOSS_ROOM,
WATER_TEMPLE_BOSS_ROOM,
SPIRIT_TEMPLE_LOBBY,
SPIRIT_TEMPLE_CHILD,
SPIRIT_TEMPLE_CHILD_CLIMB,
SPIRIT_TEMPLE_EARLY_ADULT,
SPIRIT_TEMPLE_CENTRAL_CHAMBER,
SPIRIT_TEMPLE_OUTDOOR_HANDS,
SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR,
SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR,
SHADOW_TEMPLE_BEGINNING,
SHADOW_TEMPLE_FIRST_BEAMOS,
SHADOW_TEMPLE_HUGE_PIT,
SHADOW_TEMPLE_WIND_TUNNEL,
SHADOW_TEMPLE_BEYOND_BOAT,
BOTTOM_OF_THE_WELL,
BOTTOM_OF_THE_WELL_MAIN_AREA,
ICE_CAVERN_BEGINNING,
ICE_CAVERN_MAIN,
GERUDO_TRAINING_GROUNDS_LOBBY,
GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE,
GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT,
GERUDO_TRAINING_GROUNDS_LAVA_ROOM,
GERUDO_TRAINING_GROUNDS_HAMMER_ROOM,
GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER,
GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER,
GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM,
GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM,
GANONS_CASTLE_LOBBY,
GANONS_CASTLE_DEKU_SCRUBS,
GANONS_CASTLE_FOREST_TRIAL,
GANONS_CASTLE_FIRE_TRIAL,
GANONS_CASTLE_WATER_TRIAL,
GANONS_CASTLE_SHADOW_TRIAL,
GANONS_CASTLE_SPIRIT_TRIAL,
GANONS_CASTLE_LIGHT_TRIAL,
GANONS_CASTLE_TOWER,
DEKU_TREE_MQ_LOBBY,
DEKU_TREE_MQ_COMPASS_ROOM,
DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT,
DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK,
DEKU_TREE_MQ_BASEMENT_BACK_ROOM,
DEKU_TREE_MQ_BASEMENT_LEDGE,
DODONGOS_CAVERN_MQ_BEGINNING,
DODONGOS_CAVERN_MQ_LOBBY,
DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE,
DODONGOS_CAVERN_MQ_BOMB_BAG_AREA,
DODONGOS_CAVERN_MQ_BOSS_AREA,
JABU_JABUS_BELLY_MQ_BEGINNING,
JABU_JABUS_BELLY_MQ_MAIN,
JABU_JABUS_BELLY_MQ_DEPTHS,
JABU_JABUS_BELLY_MQ_BOSS_AREA,
FOREST_TEMPLE_MQ_LOBBY,
FOREST_TEMPLE_MQ_CENTRAL_AREA,
FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE,
FOREST_TEMPLE_MQ_OUTDOOR_LEDGE,
FOREST_TEMPLE_MQ_NW_OUTDOORS,
FOREST_TEMPLE_MQ_NE_OUTDOORS,
FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES,
FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE,
FOREST_TEMPLE_MQ_BOW_REGION,
FOREST_TEMPLE_MQ_FALLING_ROOM,
FOREST_TEMPLE_MQ_BOSS_REGION,
FIRE_TEMPLE_MQ_LOWER,
FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR,
FIRE_TEMPLE_MQ_BIG_LAVA_ROOM,
FIRE_TEMPLE_MQ_LOWER_MAZE,
FIRE_TEMPLE_MQ_UPPER_MAZE,
FIRE_TEMPLE_MQ_UPPER,
FIRE_TEMPLE_MQ_BOSS_ROOM,
WATER_TEMPLE_MQ_LOBBY,
WATER_TEMPLE_MQ_DIVE,
WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS,
WATER_TEMPLE_MQ_DARK_LINK_REGION,
WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS,
SPIRIT_TEMPLE_MQ_LOBBY,
SPIRIT_TEMPLE_MQ_CHILD,
SPIRIT_TEMPLE_MQ_ADULT,
SPIRIT_TEMPLE_MQ_SHARED,
SPIRIT_TEMPLE_MQ_LOWER_ADULT,
SPIRIT_TEMPLE_MQ_BOSS_AREA,
SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND,
SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND,
SHADOW_TEMPLE_MQ_ENTRYWAY,
SHADOW_TEMPLE_MQ_BEGINNING,
SHADOW_TEMPLE_MQ_DEAD_HAND_AREA,
SHADOW_TEMPLE_MQ_FIRST_BEAMOS,
SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT,
SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT,
SHADOW_TEMPLE_MQ_WIND_TUNNEL,
SHADOW_TEMPLE_MQ_BEYOND_BOAT,
SHADOW_TEMPLE_MQ_INVISIBLE_MAZE,
BOTTOM_OF_THE_WELL_MQ,
BOTTOM_OF_THE_WELL_MQ_PERIMETER,
BOTTOM_OF_THE_WELL_MQ_MIDDLE,
ICE_CAVERN_MQ_BEGINNING,
ICE_CAVERN_MQ_MAP_ROOM,
ICE_CAVERN_MQ_IRON_BOOTS_REGION,
ICE_CAVERN_MQ_COMPASS_ROOM,
GERUDO_TRAINING_GROUNDS_MQ_LOBBY,
GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE,
GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER,
GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE,
GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM,
GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS,
GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT,
GANONS_CASTLE_MQ_LOBBY,
GANONS_CASTLE_MQ_DEKU_SCRUBS,
GANONS_CASTLE_MQ_FOREST_TRIAL,
GANONS_CASTLE_MQ_FIRE_TRIAL,
GANONS_CASTLE_MQ_WATER_TRIAL,
GANONS_CASTLE_MQ_SHADOW_TRIAL,
GANONS_CASTLE_MQ_SPIRIT_TRIAL,
GANONS_CASTLE_MQ_LIGHT_TRIAL,
};
return allAreas;
}
void AccessReset() {
for (const uint32_t area : allAreas) {
for (const uint32_t area : GetAllAreas()) {
AreaTable(area)->ResetVariables();
}
@ -843,7 +409,7 @@ namespace Areas {
//Reset exits and clear items from locations
void ResetAllLocations() {
for (const uint32_t area : allAreas) {
for (const uint32_t area : GetAllAreas()) {
AreaTable(area)->ResetVariables();
//Erase item from every location in this exit
for (LocationAccess& locPair : AreaTable(area)->locations) {
@ -868,7 +434,7 @@ namespace Areas {
}
bool HasTimePassAccess(uint8_t age) {
for (const uint32_t areaKey : allAreas) {
for (const uint32_t areaKey : GetAllAreas()) {
auto area = AreaTable(areaKey);
if (area->timePass && ((age == AGE_CHILD && area->Child()) || (age == AGE_ADULT && area->Adult()))) {
return true;
@ -886,7 +452,7 @@ namespace Areas {
worldGraph.open (str + ".dot");
worldGraph << "digraph {\n\tcenter=true;\n";
for (const uint32_t areaKey : allAreas) {
for (const uint32_t areaKey : GetAllAreas()) {
auto area = AreaTable(areaKey);
for (auto exit : area->exits) {
if (exit.GetConnectedRegion()->regionName != "Invalid Area") {
@ -939,7 +505,7 @@ Area* AreaTable(const uint32_t areaKey) {
//Retrieve all the shuffable entrances of a specific type
std::vector<Entrance*> GetShuffleableEntrances(EntranceType type, bool onlyPrimary /*= true*/) {
std::vector<Entrance*> entrancesToShuffle = {};
for (uint32_t area : Areas::allAreas) {
for (uint32_t area : Areas::GetAllAreas()) {
for (auto& exit: AreaTable(area)->exits) {
if ((exit.GetType() == type || type == EntranceType::All) && (exit.IsPrimary() || !onlyPrimary) && exit.GetType() != EntranceType::None) {
entrancesToShuffle.push_back(&exit);

View File

@ -38,7 +38,7 @@ void AreaTable_Init_DekuTree() {
/*Glitched*/[]{return CanUse(MEGATON_HAMMER);}}),
Entrance(DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;},
/*Glitched*/[]{return CanDoGlitch(GlitchType::Megaflip, GlitchDifficulty::NOVICE);}}),
Entrance(DEKU_TREE_BOSS_ROOM, {[]{return false;},
Entrance(DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;},
/*Glitched*/[]{return IsChild && CanUse(KOKIRI_SWORD) && Nuts && CanDoGlitch(GlitchType::SeamWalk, GlitchDifficulty::EXPERT);}}),
});
@ -72,7 +72,7 @@ void AreaTable_Init_DekuTree() {
}, {
//Exits
Entrance(DEKU_TREE_LOBBY, {[]{return HasFireSourceWithTorch || CanUse(BOW);}}),
Entrance(DEKU_TREE_BOSS_ROOM, {[]{return false;},
Entrance(DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;},
/*Glitched*/[]{return CanDoGlitch(GlitchType::HookshotJump_Boots, GlitchDifficulty::ADVANCED);}}),
});
@ -161,21 +161,7 @@ void AreaTable_Init_DekuTree() {
areaTable[DEKU_TREE_OUTSIDE_BOSS_ROOM] = Area("Deku Tree Outside Boss Room", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(DEKU_TREE_BASEMENT_UPPER, {[]{return true;}}),
Entrance(DEKU_TREE_BOSS_ROOM, {[]{return Here(DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return HasShield;});}}),
});
areaTable[DEKU_TREE_BOSS_ROOM] = Area("Deku Tree Boss Room", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&DekuTreeClear, {[]{return DekuTreeClear || ((IsAdult || KokiriSword || Sticks) && (Nuts || CanUse(SLINGSHOT) || CanUse(BOW) || HookshotOrBoomerang));},
/*Glitched*/[]{return CanDoGlitch(GlitchType::ISG, GlitchDifficulty::NOVICE);}}),
}, {
//Locations
LocationAccess(QUEEN_GOHMA, {[]{return DekuTreeClear;}}),
LocationAccess(DEKU_TREE_QUEEN_GOHMA_HEART, {[]{return DekuTreeClear;}}),
}, {
//Exits
Entrance(DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return true;}}),
Entrance(DEKU_TREE_ENTRYWAY, {[]{return DekuTreeClear;}}),
Entrance(DEKU_TREE_BOSS_ENTRYWAY, {[]{return Here(DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return HasShield;});}}),
});
}
@ -261,6 +247,51 @@ void AreaTable_Init_DekuTree() {
//Exits
Entrance(DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return IsChild;}}),
Entrance(DEKU_TREE_MQ_LOBBY, {[]{return true;}}),
Entrance(DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM,
{ [] { return Here(DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return HasFireSourceWithTorch; }); } }),
});
areaTable[DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] =
Area("Deku Tree MQ Outside Boss Room", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(DEKU_TREE_MQ_BASEMENT_LEDGE, { [] { return true; } }),
Entrance(DEKU_TREE_BOSS_ENTRYWAY,
{ [] { return Here(DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return HasShield; }); } }),
});
}
/*---------------------------
| BOSS ROOM |
---------------------------*/
areaTable[DEKU_TREE_BOSS_ENTRYWAY] =
Area("Deku Tree Boss Entryway", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(DEKU_TREE_OUTSIDE_BOSS_ROOM, { [] { return Dungeon::DekuTree.IsVanilla(); } }),
Entrance(DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, { [] { return Dungeon::DekuTree.IsMQ(); } }),
Entrance(DEKU_TREE_BOSS_ROOM, { [] { return true; } }),
});
areaTable[DEKU_TREE_BOSS_ROOM] =
Area("Deku Tree Boss Room", "Deku Tree", NONE, NO_DAY_NIGHT_CYCLE,
{
// Events
EventAccess(&DekuTreeClear, { [] {
return DekuTreeClear ||
(CanJumpslash && (Nuts || CanUse(SLINGSHOT) || CanUse(BOW) ||
HookshotOrBoomerang));
},
/*Glitched*/
[] { return CanDoGlitch(GlitchType::ISG, GlitchDifficulty::NOVICE); } }),
},
{
// Locations
LocationAccess(QUEEN_GOHMA, { [] { return DekuTreeClear; } }),
LocationAccess(DEKU_TREE_QUEEN_GOHMA_HEART, { [] { return DekuTreeClear; } }),
},
{
// Exits
Entrance(DEKU_TREE_BOSS_ENTRYWAY, { [] { return true; } }),
});
}

View File

@ -50,7 +50,7 @@ void AreaTable_Init_DodongosCavern() {
Entrance(DODONGOS_CAVERN_FAR_BRIDGE, {[]{return HasAccessTo(DODONGOS_CAVERN_FAR_BRIDGE);},
/*Glitched*/[]{return CanDoGlitch(GlitchType::HookshotJump_Boots, GlitchDifficulty::INTERMEDIATE);}}),
Entrance(DODONGOS_CAVERN_BOSS_AREA, {[]{return Here(DODONGOS_CAVERN_FAR_BRIDGE, []{return HasExplosives;});}}),
Entrance(DODONGOS_CAVERN_BOSS_ROOM, {[]{return false;},
Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY,{[]{return false;},
/*Glitched*/[]{return CanDoGlitch(GlitchType::HookshotJump_Boots, GlitchDifficulty::ADVANCED);}}),
});
@ -220,7 +220,7 @@ void AreaTable_Init_DodongosCavern() {
Entrance(DODONGOS_CAVERN_LOBBY, {[]{return true;}}),
Entrance(DODONGOS_CAVERN_BACK_ROOM, {[]{return Here(DODONGOS_CAVERN_BOSS_AREA, []{return CanBlastOrSmash;});},
/*Glitched*/[]{return Here(DODONGOS_CAVERN_BOSS_AREA, []{return (GlitchBlueFireWall && BlueFire) || (CanUse(STICKS) && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::ADVANCED));});}}),
Entrance(DODONGOS_CAVERN_BOSS_ROOM, {[]{return true;}}),
Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}),
});
areaTable[DODONGOS_CAVERN_BACK_ROOM] = Area("Dodongos Cavern Back Room", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
@ -231,21 +231,6 @@ void AreaTable_Init_DodongosCavern() {
//Exits
Entrance(DODONGOS_CAVERN_BOSS_AREA, {[]{return true;}}),
});
areaTable[DODONGOS_CAVERN_BOSS_ROOM] = Area("Dodongos Cavern Boss Room", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&DodongosCavernClear, {[]{return DodongosCavernClear || (Here(DODONGOS_CAVERN_BOSS_ROOM, []{return HasExplosives || (CanUse(MEGATON_HAMMER) && CanShield);}) && (Bombs || GoronBracelet) && (IsAdult || Sticks || KokiriSword));},
/*Glitched*/[]{return Here(DODONGOS_CAVERN_BOSS_ROOM, []{return HasExplosives || (CanUse(MEGATON_HAMMER) && CanShield) || (GlitchBlueFireWall && HasBottle && BlueFireAccess);}) && (HasExplosives || GoronBracelet) && (IsAdult || Sticks || KokiriSword || CanUse(MEGATON_HAMMER));}}),
}, {
//Locations
LocationAccess(DODONGOS_CAVERN_BOSS_ROOM_CHEST, {[]{return true;}}),
LocationAccess(DODONGOS_CAVERN_KING_DODONGO_HEART, {[]{return DodongosCavernClear;}}),
LocationAccess(KING_DODONGO, {[]{return DodongosCavernClear;}}),
}, {
//Exits
Entrance(DODONGOS_CAVERN_BOSS_AREA, {[]{return true;}}),
Entrance(DODONGOS_CAVERN_ENTRYWAY, {[]{return DodongosCavernClear;}}),
});
}
/*---------------------------
@ -314,6 +299,53 @@ void AreaTable_Init_DodongosCavern() {
LocationAccess(DODONGOS_CAVERN_KING_DODONGO_HEART, {[]{return CanBlastOrSmash && (Bombs || GoronBracelet) && (IsAdult || Sticks || KokiriSword);}}),
LocationAccess(KING_DODONGO, {[]{return CanBlastOrSmash && (Bombs || GoronBracelet) && (IsAdult || Sticks || KokiriSword);}}),
LocationAccess(DODONGOS_CAVERN_MQ_GS_BACK_AREA, {[]{return true;}}),
}, {});
}, {
//Exits
Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}),
});
}
/*---------------------------
| BOSS ROOM |
---------------------------*/
areaTable[DODONGOS_CAVERN_BOSS_ENTRYWAY] =
Area("Dodongos Cavern Boss Entryway", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(DODONGOS_CAVERN_BOSS_AREA, { [] { return Dungeon::DodongosCavern.IsVanilla(); } }),
Entrance(DODONGOS_CAVERN_MQ_BOSS_AREA, { [] { return Dungeon::DodongosCavern.IsMQ(); } }),
Entrance(DODONGOS_CAVERN_BOSS_ROOM, { [] { return true; } }),
});
areaTable[DODONGOS_CAVERN_BOSS_ROOM] =
Area("Dodongos Cavern Boss Room", "Dodongos Cavern", NONE, NO_DAY_NIGHT_CYCLE,
{
// Events
EventAccess(&DodongosCavernClear,
{ [] {
return DodongosCavernClear ||
(Here(DODONGOS_CAVERN_BOSS_ROOM,
[] { return HasExplosives || (CanUse(MEGATON_HAMMER) && CanShield); }) &&
(Bombs || GoronBracelet) && CanJumpslash);
},
/*Glitched*/
[] {
return Here(DODONGOS_CAVERN_BOSS_ROOM,
[] {
return HasExplosives || (CanUse(MEGATON_HAMMER) && CanShield) ||
(GlitchBlueFireWall && BlueFire);
}) &&
(HasExplosives || GoronBracelet) && CanJumpslash;
} }),
},
{
// Locations
LocationAccess(DODONGOS_CAVERN_BOSS_ROOM_CHEST, { [] { return true; } }),
LocationAccess(DODONGOS_CAVERN_KING_DODONGO_HEART, { [] { return DodongosCavernClear; } }),
LocationAccess(KING_DODONGO, { [] { return DodongosCavernClear; } }),
},
{
// Exits
Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY, { [] { return true; } }),
});
}

View File

@ -42,25 +42,11 @@ void AreaTable_Init_FireTemple() {
}, {
//Exits
Entrance(FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}),
Entrance(FIRE_TEMPLE_BOSS_ROOM, {[]{return BossKeyFireTemple && ((IsAdult && LogicFireBossDoorJump) || CanUse(HOVER_BOOTS) || Here(FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return CanUse(MEGATON_HAMMER);}));},
Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyFireTemple && ((IsAdult && LogicFireBossDoorJump) || CanUse(HOVER_BOOTS) || Here(FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return CanUse(MEGATON_HAMMER);}));},
/*Glitched*/[]{return BossKeyFireTemple && (CanDoGlitch(GlitchType::Megaflip, GlitchDifficulty::NOVICE) ||
(Bombs && HasBombchus && CanDoGlitch(GlitchType::BombHover, GlitchDifficulty::INTERMEDIATE) && CanDoGlitch(GlitchType::ISG, GlitchDifficulty::INTERMEDIATE)));}}),
});
areaTable[FIRE_TEMPLE_BOSS_ROOM] = Area("Fire Temple Boss Room", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&FireTempleClear, {[]{return FireTempleClear || (FireTimer >= 64 && CanUse(MEGATON_HAMMER));},
/*Glitched*/[]{return FireTimer >= 48 && ((CanUse(STICKS) && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::NOVICE)) ||
CanUse(MEGATON_HAMMER)) && Bombs && CanDoGlitch(GlitchType::ISG, GlitchDifficulty::INTERMEDIATE);}}),
}, {
//Locations
LocationAccess(FIRE_TEMPLE_VOLVAGIA_HEART, {[]{return FireTempleClear;}}),
LocationAccess(VOLVAGIA, {[]{return FireTempleClear;}}),
}, {
//Exits
Entrance(FIRE_TEMPLE_ENTRYWAY, {[]{return FireTempleClear;}}),
});
areaTable[FIRE_TEMPLE_LOOP_ENEMIES] = Area("Fire Temple Loop Enemies", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(FIRE_TEMPLE_FIRST_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 8) || !IsKeysanity;}}),
@ -308,7 +294,7 @@ void AreaTable_Init_FireTemple() {
areaTable[FIRE_TEMPLE_WEST_CENTRAL_UPPER] = Area("Fire Temple West Central Upper", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(FIRE_TEMPLE_BOSS_ROOM, {[]{return false;},
Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return false;},
/*Glitched*/[]{return CanDoGlitch(GlitchType::LedgeClip, GlitchDifficulty::INTERMEDIATE);}}),
Entrance(FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return true;}}),
Entrance(FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return true;}}),
@ -375,7 +361,7 @@ void AreaTable_Init_FireTemple() {
}, {
//Exits
Entrance(FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}),
Entrance(FIRE_TEMPLE_MQ_BOSS_ROOM, {[]{return IsAdult && CanUse(GORON_TUNIC) && CanUse(MEGATON_HAMMER) && BossKeyFireTemple && ((HasFireSource && (LogicFireBossDoorJump || HoverBoots)) || HasAccessTo(FIRE_TEMPLE_MQ_UPPER));}}),
Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return IsAdult && CanUse(GORON_TUNIC) && CanUse(MEGATON_HAMMER) && BossKeyFireTemple && ((HasFireSource && (LogicFireBossDoorJump || HoverBoots)) || HasAccessTo(FIRE_TEMPLE_MQ_UPPER));}}),
Entrance(FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, {[]{return SmallKeys(FIRE_TEMPLE, 5) && (IsAdult || KokiriSword);}}),
Entrance(FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return IsAdult && FireTimer >= 24 && CanUse(MEGATON_HAMMER);}}),
});
@ -443,14 +429,41 @@ void AreaTable_Init_FireTemple() {
LocationAccess(FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, {[]{return IsAdult && CanUse(HOOKSHOT) && SmallKeys(FIRE_TEMPLE, 5);}}),
//Trick: (IsAdult && CanUse(HOOKSHOT) && SmallKeys(FIRE_TEMPLE, 5)) || (LogicFireMQAboveMazeGS && IsAdult && CanUse(LONGSHOT))
}, {});
areaTable[FIRE_TEMPLE_MQ_BOSS_ROOM] = Area("Fire Temple MQ Boss Room", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&FireTempleClear, {[]{return true;}}),
}, {
//Locations
LocationAccess(FIRE_TEMPLE_VOLVAGIA_HEART, {[]{return true;}}),
LocationAccess(VOLVAGIA, {[]{return true;}}),
}, {});
}
/*---------------------------
| BOSS ROOM |
---------------------------*/
areaTable[FIRE_TEMPLE_BOSS_ENTRYWAY] =
Area("Fire Temple Boss Entryway", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(FIRE_TEMPLE_NEAR_BOSS_ROOM, { [] { return Dungeon::FireTemple.IsVanilla() && false; } }),
Entrance(FIRE_TEMPLE_MQ_LOWER, { [] { return Dungeon::FireTemple.IsMQ() && false; } }),
Entrance(FIRE_TEMPLE_BOSS_ROOM, { [] { return true; } }),
});
areaTable[FIRE_TEMPLE_BOSS_ROOM] =
Area("Fire Temple Boss Room", "Fire Temple", NONE, NO_DAY_NIGHT_CYCLE,
{
// Events
EventAccess(&FireTempleClear,
{ [] { return FireTempleClear || (FireTimer >= 64 && CanUse(MEGATON_HAMMER)); },
/*Glitched*/
[] {
return FireTimer >= 48 &&
((CanUse(STICKS) && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::NOVICE)) ||
CanUse(MEGATON_HAMMER)) &&
Bombs && CanDoGlitch(GlitchType::ISG, GlitchDifficulty::INTERMEDIATE);
} }),
},
{
// Locations
LocationAccess(FIRE_TEMPLE_VOLVAGIA_HEART, { [] { return FireTempleClear; } }),
LocationAccess(VOLVAGIA, { [] { return FireTempleClear; } }),
},
{
// Exits
Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }),
});
}

View File

@ -58,7 +58,7 @@ void AreaTable_Init_ForestTemple() {
Entrance(FOREST_TEMPLE_EAST_CORRIDOR, {[]{return false;},
/*Glitched*/[]{return CanDoGlitch(GlitchType::BombHover, GlitchDifficulty::NOVICE);}}),
Entrance(FOREST_TEMPLE_BOSS_REGION, {[]{return ForestTempleMeg;}}),
Entrance(FOREST_TEMPLE_BOSS_ROOM, {[]{return false;},
Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;},
/*Glitched*/[]{return IsAdult && (CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT)) && GlitchForestBKSkip;}}),
});
@ -97,7 +97,7 @@ void AreaTable_Init_ForestTemple() {
/*Glitched*/[]{return CanDoGlitch(GlitchType::HookshotJump_Boots, GlitchDifficulty::INTERMEDIATE) || (IsAdult && CanDoGlitch(GlitchType::HoverBoost, GlitchDifficulty::NOVICE)) || (Bombs && HasBombchus && CanDoGlitch(GlitchType::BombHover, GlitchDifficulty::NOVICE) && CanDoGlitch(GlitchType::ISG, GlitchDifficulty::INTERMEDIATE));}}),
Entrance(FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}),
Entrance(FOREST_TEMPLE_SEWER, {[]{return GoldScale || CanUse(IRON_BOOTS) || HasAccessTo(FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}),
Entrance(FOREST_TEMPLE_BOSS_ROOM, {[]{return false;},
Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;},
/*Glitched*/[]{return CanDoGlitch(GlitchType::HookshotJump_Boots, GlitchDifficulty::INTERMEDIATE);}}),
});
@ -304,19 +304,7 @@ void AreaTable_Init_ForestTemple() {
}, {
//Exits
Entrance(FOREST_TEMPLE_LOBBY, {[]{return true;}}),
Entrance(FOREST_TEMPLE_BOSS_ROOM, {[]{return BossKeyForestTemple;}}),
});
areaTable[FOREST_TEMPLE_BOSS_ROOM] = Area("Forest Temple Boss Room", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&ForestTempleClear, {[]{return ForestTempleClear || ((IsAdult || KokiriSword) && (CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT)));}}),
}, {
//Locations
LocationAccess(FOREST_TEMPLE_PHANTOM_GANON_HEART, {[]{return ForestTempleClear;}}),
LocationAccess(PHANTOM_GANON, {[]{return ForestTempleClear;}}),
}, {
//Exits
Entrance(FOREST_TEMPLE_ENTRYWAY, {[]{return ForestTempleClear;}}),
Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyForestTemple;}}),
});
}
@ -439,14 +427,43 @@ void AreaTable_Init_ForestTemple() {
Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return true;}}),
});
areaTable[FOREST_TEMPLE_MQ_BOSS_REGION] = Area("Forest Temple MQ Boss Region", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&ForestTempleClear, {[]{return ForestTempleClear || BossKeyForestTemple;}}),
}, {
areaTable[FOREST_TEMPLE_MQ_BOSS_REGION] = Area("Forest Temple MQ Boss Region", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LocationAccess(FOREST_TEMPLE_MQ_BASEMENT_CHEST, {[]{return true;}}),
LocationAccess(FOREST_TEMPLE_PHANTOM_GANON_HEART, {[]{return BossKeyForestTemple;}}),
LocationAccess(PHANTOM_GANON, {[]{return BossKeyForestTemple;}}),
}, {});
}, {
//Exits
Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyForestTemple;}}),
});
}
/*---------------------------
| BOSS ROOM |
---------------------------*/
areaTable[FOREST_TEMPLE_BOSS_ENTRYWAY] =
Area("Forest Temple Boss Entryway", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(FOREST_TEMPLE_BOSS_REGION, { [] { return Dungeon::ForestTemple.IsVanilla() && false; } }),
Entrance(FOREST_TEMPLE_MQ_BOSS_REGION, { [] { return Dungeon::ForestTemple.IsMQ() && false; } }),
Entrance(FOREST_TEMPLE_BOSS_ROOM, { [] { return true; } }),
});
areaTable[FOREST_TEMPLE_BOSS_ROOM] = Area(
"Forest Temple Boss Room", "Forest Temple", NONE, NO_DAY_NIGHT_CYCLE,
{
// Events
EventAccess(&ForestTempleClear, { [] {
return ForestTempleClear || ((CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) &&
(CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT)));
} }),
},
{
// Locations
LocationAccess(FOREST_TEMPLE_PHANTOM_GANON_HEART, { [] { return ForestTempleClear; } }),
LocationAccess(PHANTOM_GANON, { [] { return ForestTempleClear; } }),
},
{
// Exits
Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }),
});
}

View File

@ -162,23 +162,10 @@ void AreaTable_Init_JabuJabusBelly() {
}, {
//Exits
Entrance(JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}),
Entrance(JABU_JABUS_BELLY_BOSS_ROOM, {[]{return CanUse(BOOMERANG);},
Entrance(JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return CanUse(BOOMERANG);},
/*Glitched*/[]{return (CanUse(HOVER_BOOTS) && (CanUse(BOW) || CanUse(SLINGSHOT))) || CanDoGlitch(GlitchType::HookshotClip, GlitchDifficulty::NOVICE) ||
(CanUse(STICKS) && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::NOVICE)) || (Bombs && CanDoGlitch(GlitchType::ISG, GlitchDifficulty::NOVICE)) || CanDoGlitch(GlitchType::SuperStab, GlitchDifficulty::NOVICE);}}),
});
areaTable[JABU_JABUS_BELLY_BOSS_ROOM] = Area("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&JabuJabusBellyClear, {[]{return JabuJabusBellyClear || CanUse(BOOMERANG);}}),
}, {
//Locations
LocationAccess(JABU_JABUS_BELLY_BARINADE_HEART, {[]{return JabuJabusBellyClear;}}),
LocationAccess(BARINADE, {[]{return JabuJabusBellyClear;}}),
}, {
//Exits
Entrance(JABU_JABUS_BELLY_NEAR_BOSS_ROOM, {[]{return JabuJabusBellyClear;}}),
Entrance(JABU_JABUS_BELLY_ENTRYWAY, {[]{return JabuJabusBellyClear;}}),
});
}
/*---------------------------
@ -234,12 +221,39 @@ void AreaTable_Init_JabuJabusBelly() {
//Locations
LocationAccess(JABU_JABUS_BELLY_MQ_COW, {[]{return CanPlay(EponasSong);}}),
LocationAccess(JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, {[]{return true;}}),
LocationAccess(JABU_JABUS_BELLY_BARINADE_HEART, {[]{return true;}}),
LocationAccess(BARINADE, {[]{return true;}}),
LocationAccess(JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, {[]{return true;}}),
}, {
//Exits
Entrance(JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}),
Entrance(JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return CanUse(SLINGSHOT);}}),
});
}
/*---------------------------
| BOSS ROOM |
---------------------------*/
areaTable[JABU_JABUS_BELLY_BOSS_ENTRYWAY] =
Area("Jabu Jabus Belly Boss Entryway", "Jabu Jabus Belly", JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(JABU_JABUS_BELLY_NEAR_BOSS_ROOM, { [] { return Dungeon::JabuJabusBelly.IsVanilla(); } }),
Entrance(JABU_JABUS_BELLY_MQ_BOSS_AREA, { [] { return Dungeon::JabuJabusBelly.IsMQ(); } }),
Entrance(JABU_JABUS_BELLY_BOSS_ROOM, { [] { return true; } }),
});
areaTable[JABU_JABUS_BELLY_BOSS_ROOM] =
Area("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", NONE, NO_DAY_NIGHT_CYCLE,
{
// Events
EventAccess(&JabuJabusBellyClear, { [] { return JabuJabusBellyClear || CanUse(BOOMERANG); } }),
},
{
// Locations
LocationAccess(JABU_JABUS_BELLY_BARINADE_HEART, { [] { return JabuJabusBellyClear; } }),
LocationAccess(BARINADE, { [] { return JabuJabusBellyClear; } }),
},
{
// Exits
Entrance(JABU_JABUS_BELLY_BOSS_ENTRYWAY, { [] { return false; } }),
});
}

View File

@ -81,18 +81,16 @@ void AreaTable_Init_ShadowTemple() {
Entrance(SHADOW_TEMPLE_BEYOND_BOAT, {[]{return CanPlay(ZeldasLullaby) && SmallKeys(SHADOW_TEMPLE, 4, 5);}}),
});
areaTable[SHADOW_TEMPLE_BEYOND_BOAT] = Area("Shadow Temple Beyond Boat", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&ShadowTempleClear, {[]{return ShadowTempleClear || (SmallKeys(SHADOW_TEMPLE, 5) && BossKeyShadowTemple && (Bow || CanUse(DISTANT_SCARECROW) || (LogicShadowStatue && HasBombchus)));}}),
}, {
areaTable[SHADOW_TEMPLE_BEYOND_BOAT] = Area("Shadow Temple Beyond Boat", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LocationAccess(SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, {[]{return CanUse(DINS_FIRE);}}),
LocationAccess(SHADOW_TEMPLE_BOSS_KEY_CHEST, {[]{return CanUse(DINS_FIRE);}}),
LocationAccess(SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, {[]{return true;}}),
LocationAccess(SHADOW_TEMPLE_BONGO_BONGO_HEART, {[]{return SmallKeys(SHADOW_TEMPLE, 5) && BossKeyShadowTemple && (Bow || CanUse(DISTANT_SCARECROW) || (LogicShadowStatue && HasBombchus));}}),
LocationAccess(BONGO_BONGO, {[]{return SmallKeys(SHADOW_TEMPLE, 5) && BossKeyShadowTemple && (Bow || CanUse(DISTANT_SCARECROW) || (LogicShadowStatue && HasBombchus));}}),
LocationAccess(SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, {[]{return true;}}),
}, {});
}, {
//Exits
Entrance(SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (CanUse(BOW) || CanUse(DISTANT_SCARECROW) || (LogicShadowStatue && HasBombchus)) && SmallKeys(SHADOW_TEMPLE, 5) && CanUse(HOVER_BOOTS) && BossKeyShadowTemple;}})
});
}
/*---------------------------
@ -164,18 +162,14 @@ void AreaTable_Init_ShadowTemple() {
Entrance(SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return CanPlay(ZeldasLullaby) && SmallKeys(SHADOW_TEMPLE, 5);}}),
});
areaTable[SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Area("Shadow Temple MQ Beyond Boat", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&ShadowTempleClear, {[]{return ShadowTempleClear || ((Bow || (LogicShadowStatue && HasBombchus)) && BossKeyShadowTemple);}}),
}, {
areaTable[SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Area("Shadow Temple MQ Beyond Boat", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LocationAccess(SHADOW_TEMPLE_BONGO_BONGO_HEART, {[]{return (Bow || (LogicShadowStatue && HasBombchus)) && BossKeyShadowTemple;}}),
LocationAccess(BONGO_BONGO, {[]{return (Bow || (LogicShadowStatue && HasBombchus)) && BossKeyShadowTemple;}}),
LocationAccess(SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, {[]{return true;}}),
LocationAccess(SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, {[]{return Bow || (LogicShadowStatue && HasBombchus);}}),
}, {
//Exits
Entrance(SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return Bow && CanPlay(SongOfTime) && IsAdult && CanUse(LONGSHOT);}}),
Entrance(SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (CanUse(BOW) || (LogicShadowStatue && HasBombchus)) && CanUse(HOVER_BOOTS) && BossKeyShadowTemple;}}),
});
areaTable[SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Area("Shadow Temple MQ Invisible Maze", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
@ -186,4 +180,37 @@ void AreaTable_Init_ShadowTemple() {
LocationAccess(SHADOW_TEMPLE_MQ_FREESTANDING_KEY, {[]{return true;}}),
}, {});
}
/*---------------------------
| BOSS ROOM |
---------------------------*/
areaTable[SHADOW_TEMPLE_BOSS_ENTRYWAY] =
Area("Shadow Temple Boss Entryway", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(SHADOW_TEMPLE_BEYOND_BOAT, { [] { return Dungeon::ShadowTemple.IsVanilla() && false; } }),
Entrance(SHADOW_TEMPLE_MQ_BEYOND_BOAT, { [] { return Dungeon::ShadowTemple.IsMQ() && false; } }),
Entrance(SHADOW_TEMPLE_BOSS_ROOM, { [] { return true; } }),
});
areaTable[SHADOW_TEMPLE_BOSS_ROOM] =
Area("Shadow Temple Boss Room", "Shadow Temple", NONE, NO_DAY_NIGHT_CYCLE,
{
// Events
EventAccess(&ShadowTempleClear, { [] {
return ShadowTempleClear ||
((CanUse(LENS_OF_TRUTH) || ((Dungeon::ShadowTemple.IsVanilla() && LogicLensShadowBack) ||
(Dungeon::ShadowTemple.IsMQ() && LogicLensShadowMQBack))) &&
(CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)));
} }),
},
{
// Locations
LocationAccess(SHADOW_TEMPLE_BONGO_BONGO_HEART, { [] { return ShadowTempleClear; } }),
LocationAccess(BONGO_BONGO, { [] { return ShadowTempleClear; } }),
},
{
// Exits
Entrance(SHADOW_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }),
});
}

View File

@ -122,16 +122,22 @@ void AreaTable_Init_SpiritTemple() {
Entrance(SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return SmallKeys(SPIRIT_TEMPLE, 5) && (LogicSpiritWall || CanUse(LONGSHOT) || HasBombchus || ((Bombs || Nuts || CanUse(DINS_FIRE)) && (Bow || CanUse(HOOKSHOT) || Hammer)));}}),
});
areaTable[SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Final Locked Door", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&SpiritTempleClear, {[]{return SpiritTempleClear || (MirrorShield && HasExplosives && Hookshot && BossKeySpiritTemple);}}),
}, {
areaTable[SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Final Locked Door", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LocationAccess(SPIRIT_TEMPLE_BOSS_KEY_CHEST, {[]{return CanPlay(ZeldasLullaby) && ((CanTakeDamage && LogicFlamingChests) || (Bow && Hookshot));}}),
LocationAccess(SPIRIT_TEMPLE_TOPMOST_CHEST, {[]{return MirrorShield || (SunlightArrows && CanUse(LIGHT_ARROWS));}}),
LocationAccess(SPIRIT_TEMPLE_TWINROVA_HEART, {[]{return MirrorShield && HasExplosives && Hookshot && BossKeySpiritTemple;}}),
LocationAccess(TWINROVA, {[]{return MirrorShield && HasExplosives && Hookshot && BossKeySpiritTemple;}}),
}, {});
}, {
//Exits
Entrance(SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return MirrorShield && HasExplosives && Hookshot;}}),
});
areaTable[SPIRIT_TEMPLE_INSIDE_STATUE_HEAD] =
Area("Spirit Temple Inside Statue Head", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(SPIRIT_TEMPLE_CENTRAL_CHAMBER, { [] { return true; } }),
Entrance(SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return BossKeySpiritTemple; } }),
});
}
/*---------------------------
@ -209,15 +215,21 @@ void AreaTable_Init_SpiritTemple() {
LocationAccess(SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, {[]{return SmallKeys(SPIRIT_TEMPLE, 7) && Hammer && Ocarina && SongOfTime && EponasSong && SunsSong && SongOfStorms && ZeldasLullaby;}}),
}, {});
areaTable[SPIRIT_TEMPLE_MQ_BOSS_AREA] = Area("Spirit Temple MQ Boss Area", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&SpiritTempleClear, {[]{return SpiritTempleClear || (MirrorShield && BossKeySpiritTemple);}}),
}, {
areaTable[SPIRIT_TEMPLE_MQ_BOSS_AREA] = Area("Spirit Temple MQ Boss Area", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LocationAccess(SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, {[]{return LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH);}}),
LocationAccess(SPIRIT_TEMPLE_TWINROVA_HEART, {[]{return MirrorShield && BossKeySpiritTemple;}}),
LocationAccess(TWINROVA, {[]{return MirrorShield && BossKeySpiritTemple;}}),
}, {});
}, {
//Exits
Entrance(SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return MirrorShield && Hookshot;}}),
});
areaTable[SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] =
Area("Spirit Temple MQ Inside Statue Head", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(SPIRIT_TEMPLE_MQ_SHARED, { [] { return true; } }),
Entrance(SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return BossKeySpiritTemple; } }),
});
areaTable[SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Area("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
@ -229,4 +241,35 @@ void AreaTable_Init_SpiritTemple() {
LocationAccess(SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, {[]{return true;}}),
}, {});
}
/*---------------------------
| BOSS ROOM |
---------------------------*/
areaTable[SPIRIT_TEMPLE_BOSS_ENTRYWAY] = Area(
"Spirit Temple Boss Entryway", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, { [] { return Dungeon::SpiritTemple.IsVanilla() && false; } }),
Entrance(SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, { [] { return Dungeon::SpiritTemple.IsMQ() && false; } }),
Entrance(SPIRIT_TEMPLE_BOSS_ROOM, { [] { return true; } }),
});
areaTable[SPIRIT_TEMPLE_BOSS_ROOM] = Area(
"Spirit Temple Boss Room", "Spirit Temple", NONE, NO_DAY_NIGHT_CYCLE,
{
// Events
EventAccess(&SpiritTempleClear, { [] {
return SpiritTempleClear || (CanUse(MIRROR_SHIELD) &&
(CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)));
} }),
},
{
// Locations
LocationAccess(SPIRIT_TEMPLE_TWINROVA_HEART, { [] { return SpiritTempleClear; } }),
LocationAccess(TWINROVA, { [] { return SpiritTempleClear; } }),
},
{
// Exits
Entrance(SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }),
});
}

View File

@ -275,19 +275,7 @@ void AreaTable_Init_WaterTemple() {
}, {}, {
//Exits
Entrance(WATER_TEMPLE_LOBBY, {[]{return true;}}),
Entrance(WATER_TEMPLE_BOSS_ROOM, {[]{return BossKeyWaterTemple;}}),
});
areaTable[WATER_TEMPLE_BOSS_ROOM] = Area("Water Temple Boss Room", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&WaterTempleClear, {[]{return WaterTempleClear || (CanUse(HOOKSHOT) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)));}}),
}, {
//Locations
LocationAccess(WATER_TEMPLE_MORPHA_HEART, {[]{return WaterTempleClear;}}),
LocationAccess(MORPHA, {[]{return WaterTempleClear;}}),
}, {
//Exits
Entrance(WATER_TEMPLE_ENTRYWAY, {[]{return WaterTempleClear;}}),
Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyWaterTemple;}}),
});
}
@ -295,18 +283,12 @@ void AreaTable_Init_WaterTemple() {
| MASTER QUEST DUNGEON |
---------------------------*/
if (Dungeon::WaterTemple.IsMQ()) {
areaTable[WATER_TEMPLE_MQ_LOBBY] = Area("Water Temple MQ Lobby", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&WaterTempleClear, {[]{return BossKeyWaterTemple && IsAdult && CanUse(LONGSHOT);}}),
}, {
//Locations
LocationAccess(WATER_TEMPLE_MORPHA_HEART, {[]{return BossKeyWaterTemple && IsAdult && CanUse(LONGSHOT);}}),
LocationAccess(MORPHA, {[]{return BossKeyWaterTemple && IsAdult && CanUse(LONGSHOT);}}),
}, {
areaTable[WATER_TEMPLE_MQ_LOBBY] = Area("Water Temple MQ Lobby", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(WATER_TEMPLE_ENTRYWAY, {[]{return true;}}),
Entrance(WATER_TEMPLE_MQ_DIVE, {[]{return IsAdult && WaterTimer >= 24 && CanUse(IRON_BOOTS);}}),
Entrance(WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return SmallKeys(WATER_TEMPLE, 1) && IsAdult && CanUse(LONGSHOT);}}),
Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyWaterTemple && IsAdult && CanUse(LONGSHOT);}}),
});
areaTable[WATER_TEMPLE_MQ_DIVE] = Area("Water Temple MQ Dive", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
@ -348,4 +330,35 @@ void AreaTable_Init_WaterTemple() {
//Trick: LogicWaterMQLockedGS || (SmallKeys(WATER_TEMPLE, 2) && (HoverBoots || CanUse(SCARECROW) || LogicWaterNorthBasementLedgeJump))
}, {});
}
/*---------------------------
| BOSS ROOM |
---------------------------*/
areaTable[WATER_TEMPLE_BOSS_ENTRYWAY] =
Area("Water Temple Boss Entryway", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {},
{
// Exits
Entrance(WATER_TEMPLE_PRE_BOSS_ROOM, { [] { return Dungeon::WaterTemple.IsVanilla() && false; } }),
Entrance(WATER_TEMPLE_MQ_LOBBY, { [] { return Dungeon::WaterTemple.IsMQ() && false; } }),
Entrance(WATER_TEMPLE_BOSS_ROOM, { [] { return true; } }),
});
areaTable[WATER_TEMPLE_BOSS_ROOM] = Area(
"Water Temple Boss Room", "Water Temple", NONE, NO_DAY_NIGHT_CYCLE,
{
// Events
EventAccess(&WaterTempleClear, { [] {
return WaterTempleClear ||
(CanUse(HOOKSHOT) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)));
} }),
},
{
// Locations
LocationAccess(WATER_TEMPLE_MORPHA_HEART, { [] { return WaterTempleClear; } }),
LocationAccess(MORPHA, { [] { return WaterTempleClear; } }),
},
{
// Exits
Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }),
});
}

View File

@ -164,6 +164,17 @@ string_view dungeonEntrancesDesc = "Shuffle the pool of dungeon entrances,
"Temple, Bottom of the Well and Gerudo Training\n" //
"Ground are opened for both adult and child."; //
/*------------------------------ //
| BOSS ENTRANCES | //
------------------------------*/ //
string_view bossEntrancesDesc = "Shuffle the pool of dungeon boss entrances.\n" //
"This affects the boss rooms of all stone and\n" //
"medallion dungeons.\n" //
"\n" //
"Child and adult boss rooms can be shuffled\n" //
"separately.\n" //
"Child may be expected to defeat Phantom Ganon\n" //
"and/or Bongo Bongo."; //
/*------------------------------ //
| OVERWORLD ENTRANCES | //
------------------------------*/ //
string_view overworldEntrancesDesc = "Shuffle the pool of Overworld entrances, which\n" //
@ -238,7 +249,9 @@ string_view decoupledEntrancesDesc = "Decouple entrances when shuffling them.
"you came from when you go back through an\n" //
"entrance. This also adds the one-way entrance from"
"Gerudo Valley to Lake Hylia in the pool of\n" //
"overworld entrances when they are shuffled."; //
"overworld entrances when they are shuffled.\n" //
"Boss entrances are currently excluded from this\n"//
"and remain coupled regardless."; //
/*------------------------------ //
| BOMBCHUS IN LOGIC | //
------------------------------*/ //

View File

@ -57,6 +57,8 @@ extern string_view shuffleEntrancesDesc;
extern string_view dungeonEntrancesDesc;
extern string_view bossEntrancesDesc;
extern string_view overworldEntrancesDesc;
extern string_view grottoEntrancesDesc;

View File

@ -89,6 +89,7 @@ namespace Settings {
uint8_t ResolvedStartingAge;
Option ShuffleEntrances = Option::Bool("Shuffle Entrances", {"Off", "On"}, {shuffleEntrancesDesc});
Option ShuffleDungeonEntrances = Option::U8 ("Dungeon Entrances", {"Off", "On", "On + Ganon"}, {dungeonEntrancesDesc});
Option ShuffleBossEntrances = Option::U8 ("Boss Entrances", {"Off", "Age Restricted", "Full"}, {bossEntrancesDesc});
Option ShuffleOverworldEntrances = Option::Bool("Overworld Entrances", {"Off", "On"}, {overworldEntrancesDesc});
Option ShuffleInteriorEntrances = Option::U8 ("Interior Entrances", {"Off", "Simple", "All"}, {interiorEntrancesOff, interiorEntrancesSimple, interiorEntrancesAll});
Option ShuffleGrottoEntrances = Option::Bool("Grottos Entrances", {"Off", "On"}, {grottoEntrancesDesc});
@ -125,6 +126,7 @@ namespace Settings {
&StartingAge,
&ShuffleEntrances,
&ShuffleDungeonEntrances,
&ShuffleBossEntrances,
&ShuffleOverworldEntrances,
&ShuffleInteriorEntrances,
&ShuffleGrottoEntrances,
@ -1291,6 +1293,7 @@ namespace Settings {
ctx.startingAge = StartingAge.Value<uint8_t>();
ctx.resolvedStartingAge = ResolvedStartingAge;
ctx.shuffleDungeonEntrances = ShuffleDungeonEntrances.Value<uint8_t>();
ctx.shuffleBossEntrances = ShuffleBossEntrances.Value<uint8_t>();
ctx.shuffleOverworldEntrances = (ShuffleOverworldEntrances) ? 1 : 0;
ctx.shuffleInteriorEntrances = ShuffleInteriorEntrances.Value<uint8_t>();
ctx.shuffleGrottoEntrances = (ShuffleGrottoEntrances) ? 1 : 0;
@ -1973,6 +1976,7 @@ namespace Settings {
//Show Shuffle options when Shuffle Entrances is On
if (ShuffleEntrances) {
ShuffleDungeonEntrances.Unhide();
ShuffleBossEntrances.Unhide();
ShuffleOverworldEntrances.Unhide();
ShuffleInteriorEntrances.Unhide();
ShuffleGrottoEntrances.Unhide();
@ -1984,6 +1988,8 @@ namespace Settings {
} else {
ShuffleDungeonEntrances.SetSelectedIndex(SHUFFLEDUNGEONS_OFF);
ShuffleDungeonEntrances.Hide();
ShuffleBossEntrances.SetSelectedIndex(SHUFFLEBOSSES_OFF);
ShuffleBossEntrances.Hide();
ShuffleOverworldEntrances.SetSelectedIndex(OFF);
ShuffleOverworldEntrances.Hide();
ShuffleInteriorEntrances.SetSelectedIndex(SHUFFLEINTERIORS_OFF);
@ -2464,6 +2470,7 @@ namespace Settings {
// Sanity Check Entrance Shuffling
if (!ShuffleEntrances) {
ShuffleDungeonEntrances.SetSelectedIndex(OFF);
ShuffleBossEntrances.SetSelectedIndex(OFF);
ShuffleOverworldEntrances.SetSelectedIndex(OFF);
ShuffleInteriorEntrances.SetSelectedIndex(OFF);
ShuffleGrottoEntrances.SetSelectedIndex(OFF);
@ -2681,6 +2688,7 @@ namespace Settings {
// Shuffle Entrances
ShuffleEntrances.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_ENTRANCES]);
ShuffleDungeonEntrances.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_DUNGEON_ENTRANCES]);
ShuffleBossEntrances.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_BOSS_ENTRANCES]);
ShuffleOverworldEntrances.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_OVERWORLD_ENTRANCES]);
ShuffleInteriorEntrances.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_INTERIOR_ENTRANCES]);
ShuffleGrottoEntrances.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_GROTTO_ENTRANCES]);

View File

@ -92,6 +92,12 @@ typedef enum {
SHUFFLEDUNGEONS_GANON,
} ShuffleDungeonEntrancesSetting;
typedef enum {
SHUFFLEBOSSES_OFF,
SHUFFLEBOSSES_AGE_RESTRICTED,
SHUFFLEBOSSES_FULL,
} ShuffleBossEntrancesSetting;
typedef enum {
SHUFFLEINTERIORS_OFF,
SHUFFLEINTERIORS_SIMPLE,
@ -387,6 +393,7 @@ typedef struct {
uint8_t startingAge;
uint8_t resolvedStartingAge;
uint8_t shuffleDungeonEntrances;
uint8_t shuffleBossEntrances;
uint8_t shuffleOverworldEntrances;
uint8_t shuffleInteriorEntrances;
uint8_t shuffleGrottoEntrances;
@ -903,6 +910,7 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin
extern uint8_t ResolvedStartingAge;
extern Option ShuffleEntrances;
extern Option ShuffleDungeonEntrances;
extern Option ShuffleBossEntrances;
extern Option ShuffleOverworldEntrances;
extern Option ShuffleInteriorEntrances;
extern Option ShuffleGrottoEntrances;

View File

@ -306,7 +306,7 @@ static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance)
std::string name = entrance->GetName();
std::string text = entrance->GetConnectedRegion()->regionName + " from " + entrance->GetReplacement()->GetParentRegion()->regionName;
if (entrance->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) {
destinationIndex = entrance->GetReverse()->GetIndex();
replacementDestinationIndex = entrance->GetReplacement()->GetReverse()->GetIndex();
replacementBlueWarp = entrance->GetReplacement()->GetReverse()->GetBlueWarp();
@ -323,7 +323,7 @@ static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance)
jsonData["entrances"].push_back(entranceJson);
// When decoupled entrances is off, handle saving reverse entrances with blue warps
if (entrance->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) {
json reverseEntranceJson = json::object({
{"index", replacementDestinationIndex},
{"destination", replacementIndex},

View File

@ -236,6 +236,7 @@ std::unordered_map<std::string, RandomizerSettingKey> SpoilerfileSettingNameToEn
{ "World Settings:Bombchus in Logic", RSK_BOMBCHUS_IN_LOGIC },
{ "World Settings:Shuffle Entrances", RSK_SHUFFLE_ENTRANCES },
{ "World Settings:Dungeon Entrances", RSK_SHUFFLE_DUNGEON_ENTRANCES },
{ "World Settings:Boss Entrances", RSK_SHUFFLE_BOSS_ENTRANCES },
{ "World Settings:Overworld Entrances", RSK_SHUFFLE_OVERWORLD_ENTRANCES },
{ "World Settings:Interior Entrances", RSK_SHUFFLE_INTERIOR_ENTRANCES },
{ "World Settings:Grottos Entrances", RSK_SHUFFLE_GROTTO_ENTRANCES },
@ -987,6 +988,15 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
gSaveContext.randoSettings[index].value = RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON;
}
break;
case RSK_SHUFFLE_BOSS_ENTRANCES:
if (it.value() == "Off") {
gSaveContext.randoSettings[index].value = RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF;
} else if (it.value() == "Age Restricted") {
gSaveContext.randoSettings[index].value = RO_BOSS_ROOM_ENTRANCE_SHUFFLE_AGE_RESTRICTED;
} else if (it.value() == "Full") {
gSaveContext.randoSettings[index].value = RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL;
}
break;
case RSK_SHUFFLE_INTERIOR_ENTRANCES:
if (it.value() == "Off") {
gSaveContext.randoSettings[index].value = RO_INTERIOR_ENTRANCE_SHUFFLE_OFF;
@ -2870,6 +2880,7 @@ void GenerateRandomizerImgui() {
// Enable if any of the entrance rando options are enabled.
cvarSettings[RSK_SHUFFLE_ENTRANCES] = CVarGetInteger("gRandomizeShuffleDungeonsEntrances", RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) ||
CVarGetInteger("gRandomizeShuffleBossEntrances", RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) ||
CVarGetInteger("gRandomizeShuffleOverworldEntrances", RO_GENERIC_OFF) ||
CVarGetInteger("gRandomizeShuffleInteriorsEntrances", RO_INTERIOR_ENTRANCE_SHUFFLE_OFF) ||
CVarGetInteger("gRandomizeShuffleGrottosEntrances", RO_GENERIC_OFF) ||
@ -2878,6 +2889,7 @@ void GenerateRandomizerImgui() {
CVarGetInteger("gRandomizeShuffleOverworldSpawns", RO_GENERIC_OFF);
cvarSettings[RSK_SHUFFLE_DUNGEON_ENTRANCES] = CVarGetInteger("gRandomizeShuffleDungeonsEntrances", RO_DUNGEON_ENTRANCE_SHUFFLE_OFF);
cvarSettings[RSK_SHUFFLE_BOSS_ENTRANCES] = CVarGetInteger("gRandomizeShuffleBossEntrances", RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
cvarSettings[RSK_SHUFFLE_OVERWORLD_ENTRANCES] = CVarGetInteger("gRandomizeShuffleOverworldEntrances", RO_GENERIC_OFF);
cvarSettings[RSK_SHUFFLE_INTERIOR_ENTRANCES] = CVarGetInteger("gRandomizeShuffleInteriorsEntrances", RO_INTERIOR_ENTRANCE_SHUFFLE_OFF);
cvarSettings[RSK_SHUFFLE_GROTTO_ENTRANCES] = CVarGetInteger("gRandomizeShuffleGrottosEntrances", RO_GENERIC_OFF);
@ -2937,6 +2949,7 @@ void DrawRandoEditor(bool& open) {
// World Settings
static const char* randoStartingAge[3] = { "Child", "Adult", "Random" };
static const char* randoShuffleDungeonsEntrances[3] = { "Off", "On", "On + Ganon" };
static const char* randoShuffleBossEntrances[3] = { "Off", "Age Restricted", "Full" };
static const char* randoShuffleInteriorsEntrances[3] = { "Off", "Simple", "All" };
static const char* randoBombchusInLogic[2] = { "Off", "On" };
static const char* randoAmmoDrops[3] = { "On + Bombchu", "Off", "On" };
@ -3273,6 +3286,19 @@ void DrawRandoEditor(bool& open) {
UIWidgets::PaddedSeparator();
// Shuffle Boss Entrances
ImGui::Text("Shuffle Boss Entrances");
UIWidgets::InsertHelpHoverText(
"Shuffle the pool of dungeon boss entrances. This affects the boss rooms of all stone and medallion dungeons.\n"
"\n"
"Age Restricted - Shuffle the entrances of child and adult boss rooms separately.\n"
"\n"
"Full - Shuffle the entrances of all boss rooms together. Child may be expected to defeat Phantom Ganon and/or Bongo Bongo."
);
UIWidgets::EnhancementCombobox("gRandomizeShuffleBossEntrances", randoShuffleBossEntrances, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_MAX, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
UIWidgets::PaddedSeparator();
// Shuffle Overworld Entrances
UIWidgets::EnhancementCheckbox("Shuffle Overworld Entrances", "gRandomizeShuffleOverworldEntrances");
UIWidgets::InsertHelpHoverText(

View File

@ -1090,6 +1090,7 @@ typedef enum {
RSK_DECOUPLED_ENTRANCES,
RSK_STARTING_SKULLTULA_TOKEN,
RSK_ALL_LOCATIONS_REACHABLE,
RSK_SHUFFLE_BOSS_ENTRANCES,
RSK_MAX
} RandomizerSettingKey;
@ -1267,6 +1268,14 @@ typedef enum {
RO_DUNGEON_ENTRANCE_SHUFFLE_MAX,
} RandoOptionDungeonEntranceShuffle;
//Shuffle Boss Room Entrance Settings (Off, Age Restricted, Full)
typedef enum {
RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF,
RO_BOSS_ROOM_ENTRANCE_SHUFFLE_AGE_RESTRICTED,
RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL,
RO_BOSS_ROOM_ENTRANCE_SHUFFLE_MAX,
} RandoOptionBossRoomEntranceShuffle;
//Shuffle Interior Entrance Settings (Off, simple, all)
typedef enum {
RO_INTERIOR_ENTRANCE_SHUFFLE_OFF,

View File

@ -25,9 +25,39 @@ s16 dynamicExitList[] = { 0x045B, 0x0482, 0x03E8, 0x044B, 0x02A2, 0x0201, 0x03B8
// Owl Flights : 0x492064 and 0x492080
static s16 entranceOverrideTable[ENTRANCE_TABLE_SIZE] = {0};
// Boss scenes (normalize boss scene range to 0 on lookup) to the replaced dungeon scene it is connected to
static s16 dungeonBossSceneOverrides[SHUFFLEABLE_BOSS_COUNT] = {0};
static ActorEntry modifiedLinkActorEntry = {0};
EntranceInfo originalEntranceTable[ENTRANCE_TABLE_SIZE] = {0};
typedef struct {
s16 blueWarp;
s16 destination;
} BlueWarpReplacement;
typedef struct {
s16 entryway;
s16 exit;
s16 bossDoor;
s16 bossDoorReverse;
s16 blueWarp;
s16 scene;
s16 bossScene;
} DungeonEntranceInfo;
static DungeonEntranceInfo dungeons[] = {
//entryway exit, boss, reverse,bluewarp,dungeon scene, boss scene
{ DEKU_TREE_ENTRANCE, 0x0209, 0x040F, 0x0252, 0x0457, SCENE_YDAN, SCENE_YDAN_BOSS },
{ DODONGOS_CAVERN_ENTRANCE, 0x0242, 0x040B, 0x00C5, 0x047A, SCENE_DDAN, SCENE_DDAN_BOSS },
{ JABU_JABUS_BELLY_ENTRANCE, 0x0221, 0x0301, 0x0407, 0x010E, SCENE_BDAN, SCENE_BDAN_BOSS },
{ FOREST_TEMPLE_ENTRANCE, 0x0215, 0x000C, 0x024E, 0x0608, SCENE_BMORI1, SCENE_MORIBOSSROOM },
{ FIRE_TEMPLE_ENTRANCE, 0x024A, 0x0305, 0x0175, 0x0564, SCENE_HIDAN, SCENE_FIRE_BS },
{ WATER_TEMPLE_ENTRANCE, 0x021D, 0x0417, 0x0423, 0x060C, SCENE_MIZUSIN, SCENE_MIZUSIN_BS },
{ SPIRIT_TEMPLE_ENTRANCE, 0x01E1, 0x008D, 0x02F5, 0x0610, SCENE_JYASINZOU, SCENE_JYASINBOSS },
{ SHADOW_TEMPLE_ENTRANCE, 0x0205, 0x0413, 0x02B2, 0x0580, SCENE_HAKADAN, SCENE_HAKADAN_BS },
};
//These variables store the new entrance indices for dungeons so that
//savewarping and game overs respawn players at the proper entrance.
//By default, these will be their vanilla values.
@ -86,6 +116,9 @@ void Entrance_ResetEntranceTable(void) {
void Entrance_Init(void) {
s32 index;
size_t blueWarpRemapIdx = 0;
BlueWarpReplacement bluewarps[SHUFFLEABLE_BOSS_COUNT] = {0};
Entrance_CopyOriginalEntranceTable();
// Skip Child Stealth if given by settings
@ -109,6 +142,11 @@ void Entrance_Init(void) {
entranceOverrideTable[i] = i;
}
// Initialize all boss rooms connected to their vanilla dungeon
for (s16 i = 1; i < SHUFFLEABLE_BOSS_COUNT; i++) {
dungeonBossSceneOverrides[i] = i;
}
// Initialize the grotto exit and load lists
Grotto_InitExitAndLoadLists();
@ -138,7 +176,33 @@ void Entrance_Init(void) {
entranceOverrideTable[originalIndex] = overrideIndex;
if (blueWarpIndex != 0) {
entranceOverrideTable[blueWarpIndex] = overrideIndex;
// When boss shuffle is enabled, we need to know what dungeon the boss room is connected to for
// death/save warping, and for the blue warp
if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) {
s16 bossScene = -1;
s16 replacedDungeonScene = -1;
s16 replacedDungeonExit = -1;
// Search for the boss scene and replaced blue warp exits
for (s16 j = 0; j <= SHUFFLEABLE_BOSS_COUNT; j++) {
if (blueWarpIndex == dungeons[j].blueWarp) {
bossScene = dungeons[j].bossScene;
}
if (overrideIndex == dungeons[j].bossDoorReverse) {
replacedDungeonScene = dungeons[j].scene;
replacedDungeonExit = dungeons[j].exit;
}
}
// assign the boss scene override
if (bossScene != -1 && replacedDungeonScene != -1 && replacedDungeonExit != -1) {
dungeonBossSceneOverrides[bossScene - SCENE_YDAN_BOSS] = replacedDungeonScene;
bluewarps[blueWarpRemapIdx].blueWarp = blueWarpIndex;
bluewarps[blueWarpRemapIdx].destination = replacedDungeonExit;
blueWarpRemapIdx++;
}
} else {
entranceOverrideTable[blueWarpIndex] = overrideIndex;
}
}
//Override both land and water entrances for Hyrule Field -> ZR Front and vice versa
@ -149,6 +213,14 @@ void Entrance_Init(void) {
}
}
// If we have remapped blue warps from boss shuffle, handle setting those and grabbing the override for
// the replaced dungeons exit in the event that dungeon shuffle is also turned on
for (size_t i = 0; i < ARRAY_COUNT(bluewarps); i++) {
if (bluewarps[i].blueWarp != 0 && bluewarps[i].destination != 0) {
entranceOverrideTable[bluewarps[i].blueWarp] = Entrance_GetOverride(bluewarps[i].destination);
}
}
// Stop playing background music during shuffled entrance transitions
// so that we don't get duplicated or overlapping music tracks
if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) {
@ -236,12 +308,20 @@ u32 Entrance_SceneAndSpawnAre(u8 scene, u8 spawn) {
return currentEntrance.scene == scene && currentEntrance.spawn == spawn;
}
//Properly respawn the player after a game over, accounding for dungeon entrance
//randomizer. It's easier to rewrite this entirely compared to performing an ASM
//dance for just the boss rooms. Entrance Indexes can be found here:
//https://wiki.cloudmodding.com/oot/Entrance_Table_(Data)
// Properly respawn the player after a game over, accounting for dungeon entrance randomizer
void Entrance_SetGameOverEntrance(void) {
s16 scene = gPlayState->sceneNum;
// When in a boss room and boss shuffle is on, get the connected dungeon's original boss room entrance
// then run the normal game over overrides on it
if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF &&
scene >= SCENE_YDAN_BOSS && scene <= SCENE_HAKADAN_BS) {
// Normalize boss scene range to 0 on lookup
scene = dungeonBossSceneOverrides[scene - SCENE_YDAN_BOSS];
gSaveContext.entranceIndex = dungeons[scene].bossDoor;
}
//Set the current entrance depending on which entrance the player last came through
switch (gSaveContext.entranceIndex) {
case 0x040F : //Deku Tree Boss Room
@ -274,14 +354,19 @@ void Entrance_SetGameOverEntrance(void) {
}
}
//Properly savewarp the player accounting for dungeon entrance randomizer.
//It's easier to rewrite this entirely compared to performing an ASM
//dance for just the boss rooms.
//https://wiki.cloudmodding.com/oot/Entrance_Table_(Data)
// Properly savewarp the player accounting for dungeon entrance randomizer.
void Entrance_SetSavewarpEntrance(void) {
s16 scene = gSaveContext.savedSceneNum;
// When in a boss room and boss shuffle is on, use the boss scene override to remap to its
// connected dungeon and use that for the final entrance
if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF &&
scene >= SCENE_YDAN_BOSS && scene <= SCENE_HAKADAN_BS) {
// Normalize boss scene range to 0 on lookup
scene = dungeonBossSceneOverrides[scene - SCENE_YDAN_BOSS];
}
if (scene == SCENE_YDAN || scene == SCENE_YDAN_BOSS) {
gSaveContext.entranceIndex = newDekuTreeEntrance;
} else if (scene == SCENE_DDAN || scene == SCENE_DDAN_BOSS) {
@ -586,23 +671,71 @@ void Entrance_OverrideGeurdoGuardCapture(void) {
}
void Entrance_OverrideSpawnScene(s32 sceneNum, s32 spawn) {
// Copy the actorEntry properties to avoid modifying the original cached pointer
// Then assign a pointer of our modified actoreEntry back
modifiedLinkActorEntry.id = gPlayState->linkActorEntry->id;
modifiedLinkActorEntry.pos = gPlayState->linkActorEntry->pos;
modifiedLinkActorEntry.rot = gPlayState->linkActorEntry->rot;
modifiedLinkActorEntry.params = gPlayState->linkActorEntry->params;
if (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) == RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON) {
// Move Hyrule's Castle Courtyard exit spawn to be before the crates so players don't skip Talon
if (sceneNum == 95 && spawn == 1) {
gPlayState->linkActorEntry->pos.x = 0x033A;
gPlayState->linkActorEntry->pos.y = 0x0623;
gPlayState->linkActorEntry->pos.z = 0xFF22;
modifiedLinkActorEntry.pos.x = 0x033A;
modifiedLinkActorEntry.pos.y = 0x0623;
modifiedLinkActorEntry.pos.z = 0xFF22;
gPlayState->linkActorEntry = &modifiedLinkActorEntry;
}
// Move Ganon's Castle exit spawn to be on the small ledge near the castle and not over the void
// to prevent Link from falling if the bridge isn't spawned
if (sceneNum == 100 && spawn == 1) {
gPlayState->linkActorEntry->pos.x = 0xFEA8;
gPlayState->linkActorEntry->pos.y = 0x065C;
gPlayState->linkActorEntry->pos.z = 0x0290;
gPlayState->linkActorEntry->rot.y = 0x0700;
gPlayState->linkActorEntry->params = 0x0DFF; // stationary spawn
modifiedLinkActorEntry.pos.x = 0xFEA8;
modifiedLinkActorEntry.pos.y = 0x065C;
modifiedLinkActorEntry.pos.z = 0x0290;
modifiedLinkActorEntry.rot.y = 0x0700;
modifiedLinkActorEntry.params = 0x0DFF; // stationary spawn
gPlayState->linkActorEntry = &modifiedLinkActorEntry;
}
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) {
// Repair the authentically bugged entrance when leaving Barniades boss room -> JabuJabu's belly
// Link's position needs to be adjusted to prevent him from falling through the floor
if (sceneNum == SCENE_BDAN && spawn == 1) {
modifiedLinkActorEntry.pos.z = 0xF7F4;
gPlayState->linkActorEntry = &modifiedLinkActorEntry;
}
// Repair the authentically bugged entrance when leaving Morpha's boass room -> Water Temple
// Link's position was at the start of the Water Temple entrance
// This updates it to place him in the hallway outside of Morpha's boss room.
if (sceneNum == SCENE_MIZUSIN && spawn == 1) {
modifiedLinkActorEntry.pos.x = 0xFF4C;
modifiedLinkActorEntry.pos.y = 0x0406;
modifiedLinkActorEntry.pos.z = 0xF828;
modifiedLinkActorEntry.rot.y = 0x0;
gPlayState->linkActorEntry = &modifiedLinkActorEntry;
}
}
}
s32 Entrance_OverrideSpawnSceneRoom(s32 sceneNum, s32 spawn, s32 roomNum) {
if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) {
// Repair the authentically bugged scene/spawn info for leaving Barinade's boss room -> JabuJabu's belly
// to load the correct room outside Barniade's boss room
if (sceneNum == SCENE_BDAN && spawn == 1) {
return 5;
}
// Repair the authentically bugged scene/spawn info for leaving Morhpa's boss room -> Water Temple
// to load the correct room for the hallway before Morpha's boss room
if (sceneNum == SCENE_MIZUSIN && spawn == 1) {
return 11;
}
}
return roomNum;
}
u8 Entrance_GetIsSceneDiscovered(u8 sceneNum) {

View File

@ -26,7 +26,8 @@
#define ENTRANCE_RANDO_GROTTO_EXIT_START 0x0800
#define MAX_ENTRANCE_RANDO_USED_INDEX 0x0820
#define ENTRANCE_OVERRIDES_MAX_COUNT 256
#define ENTRANCE_OVERRIDES_MAX_COUNT 259 // 11 one-way entrances + 124 two-way entrances (x2)
#define SHUFFLEABLE_BOSS_COUNT 8
#define SAVEFILE_ENTRANCES_DISCOVERED_IDX_COUNT 66 // Max entrance rando index is 0x0820, (2080 / 32 == 65) + 1
#define SAVEFILE_SCENES_DISCOVERED_IDX_COUNT 4 // Max scene ID is 0x6E, (110 / 32 == 3) + 1
@ -46,6 +47,7 @@ int16_t Entrance_GetOverride(int16_t index);
int16_t Entrance_OverrideNextIndex(int16_t nextEntranceIndex);
int16_t Entrance_OverrideDynamicExit(int16_t dynamicExitIndex);
uint32_t Entrance_SceneAndSpawnAre(uint8_t scene, uint8_t spawn);
void Entrance_SetGameOverEntrance(void);
void Entrance_SetSavewarpEntrance(void);
void Entrance_SetWarpSongEntrance(void);
void Entrance_OverrideBlueWarp(void);
@ -54,6 +56,7 @@ void Entrance_HandleEponaState(void);
void Entrance_OverrideWeatherState(void);
void Entrance_OverrideGeurdoGuardCapture(void);
void Entrance_OverrideSpawnScene(int32_t sceneNum, int32_t spawn);
int32_t Entrance_OverrideSpawnSceneRoom(int32_t sceneNum, int32_t spawn, int32_t room);
void Entrance_EnableFW(void);
uint8_t Entrance_GetIsEntranceDiscovered(uint16_t entranceIndex);
void Entrance_SetEntranceDiscovered(uint16_t entranceIndex);

View File

@ -85,24 +85,26 @@ const EntranceData entranceData[] = {
{ 0x027E, -1, SINGLE_SCENE_INFO(0x57), "LH Owl Flight", "Hyrule Field Owl Drop", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY},
// Kokiri Forest
{ 0x05E0, 0x020D, SINGLE_SCENE_INFO(0x55), "KF", "Lost Woods Bridge", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"},
{ 0x011E, 0x0286, SINGLE_SCENE_INFO(0x55), "KF", "Lost Woods", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"},
{ 0x0272, 0x0211, SINGLE_SCENE_INFO(0x55), "KF", "Link's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x0433, 0x0443, SINGLE_SCENE_INFO(0x55), "KF", "Mido's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x0437, 0x0447, SINGLE_SCENE_INFO(0x55), "KF", "Saria's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x009C, 0x033C, SINGLE_SCENE_INFO(0x55), "KF", "House of Twins", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x00C9, 0x026A, SINGLE_SCENE_INFO(0x55), "KF", "Know-It-All House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x00C1, 0x0266, SINGLE_SCENE_INFO(0x55), "KF", "KF Shop", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x071B, 0x081B, SINGLE_SCENE_INFO(0x55), "KF", "KF Storms Grotto", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_GROTTO, "chest", 1},
{ 0x0000, 0x0209, SINGLE_SCENE_INFO(0x55), "KF", "Deku Tree", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0211, 0x0272, SINGLE_SCENE_INFO(0x34), "Link's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x0443, 0x0433, SINGLE_SCENE_INFO(0x28), "Mido's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x0447, 0x0437, SINGLE_SCENE_INFO(0x29), "Saria's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x033C, 0x009C, SINGLE_SCENE_INFO(0x27), "House of Twins", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x026A, 0x00C9, SINGLE_SCENE_INFO(0x26), "Know-It-All House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x0266, 0x00C1, SINGLE_SCENE_INFO(0x2D), "KF Shop", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x081B, 0x071B, {{ 0x3E, 0x00 }}, "KF Storms Grotto", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_GROTTO, "chest"},
{ 0x0209, 0x0000, SINGLE_SCENE_INFO(0x00), "Deku Tree", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, ""},
{ 0x05E0, 0x020D, SINGLE_SCENE_INFO(0x55), "KF", "Lost Woods Bridge", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"},
{ 0x011E, 0x0286, SINGLE_SCENE_INFO(0x55), "KF", "Lost Woods", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"},
{ 0x0272, 0x0211, SINGLE_SCENE_INFO(0x55), "KF", "Link's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x0433, 0x0443, SINGLE_SCENE_INFO(0x55), "KF", "Mido's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x0437, 0x0447, SINGLE_SCENE_INFO(0x55), "KF", "Saria's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x009C, 0x033C, SINGLE_SCENE_INFO(0x55), "KF", "House of Twins", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x00C9, 0x026A, SINGLE_SCENE_INFO(0x55), "KF", "Know-It-All House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x00C1, 0x0266, SINGLE_SCENE_INFO(0x55), "KF", "KF Shop", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x071B, 0x081B, SINGLE_SCENE_INFO(0x55), "KF", "KF Storms Grotto", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_GROTTO, "chest", 1},
{ 0x0000, 0x0209, SINGLE_SCENE_INFO(0x55), "KF", "Deku Tree", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0211, 0x0272, SINGLE_SCENE_INFO(0x34), "Link's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x0443, 0x0433, SINGLE_SCENE_INFO(0x28), "Mido's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x0447, 0x0437, SINGLE_SCENE_INFO(0x29), "Saria's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x033C, 0x009C, SINGLE_SCENE_INFO(0x27), "House of Twins", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x026A, 0x00C9, SINGLE_SCENE_INFO(0x26), "Know-It-All House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x0266, 0x00C1, SINGLE_SCENE_INFO(0x2D), "KF Shop", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""},
{ 0x081B, 0x071B, {{ 0x3E, 0x00 }}, "KF Storms Grotto", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_GROTTO, "chest"},
{ 0x0209, 0x0000, SINGLE_SCENE_INFO(0x00), "Deku Tree", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, ""},
{ 0x040F, 0x0252, SINGLE_SCENE_INFO(0x00), "Deku Tree Boss Door", "Gohma", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0252, 0x040F, SINGLE_SCENE_INFO(0x11), "Gohma", "Deku Tree Boss Door", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1},
// Lost Woods
{ 0x020D, 0x05E0, SINGLE_SCENE_INFO(0x5B), "Lost Woods Bridge", "KF", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_OVERWORLD, "lw"},
@ -119,15 +121,17 @@ const EntranceData entranceData[] = {
{ 0x0820, 0x0720, {{ 0x3E, 0x0C }}, "Deku Theater", "Lost Woods", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,mask,stage"},
// Sacred Forest Meadow
{ 0x01A9, 0x00FC, SINGLE_SCENE_INFO(0x56), "SFM", "Lost Woods", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"},
{ 0x0716, 0x0816, SINGLE_SCENE_INFO(0x56), "SFM", "SFM Wolfos Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "chest", 1},
{ 0x0718, 0x0818, SINGLE_SCENE_INFO(0x56), "SFM", "SFM Fairy Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x0717, 0x0817, SINGLE_SCENE_INFO(0x56), "SFM", "SFM Storms Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "scrubs", 1},
{ 0x0169, 0x0215, SINGLE_SCENE_INFO(0x56), "SFM", "Forest Temple", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0816, 0x0716, {{ 0x3E, 0x08 }}, "SFM Wolfos Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO},
{ 0x0818, 0x0718, {{ 0x3C, 0x00 }}, "SFM Fairy Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO},
{ 0x0817, 0x0717, {{ 0x3E, 0x0A }}, "SFM Storms Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "scrubs"},
{ 0x0215, 0x0169, SINGLE_SCENE_INFO(0x03), "Forest Temple", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON},
{ 0x01A9, 0x00FC, SINGLE_SCENE_INFO(0x56), "SFM", "Lost Woods", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"},
{ 0x0716, 0x0816, SINGLE_SCENE_INFO(0x56), "SFM", "SFM Wolfos Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "chest", 1},
{ 0x0718, 0x0818, SINGLE_SCENE_INFO(0x56), "SFM", "SFM Fairy Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x0717, 0x0817, SINGLE_SCENE_INFO(0x56), "SFM", "SFM Storms Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "scrubs", 1},
{ 0x0169, 0x0215, SINGLE_SCENE_INFO(0x56), "SFM", "Forest Temple", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0816, 0x0716, {{ 0x3E, 0x08 }}, "SFM Wolfos Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO},
{ 0x0818, 0x0718, {{ 0x3C, 0x00 }}, "SFM Fairy Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO},
{ 0x0817, 0x0717, {{ 0x3E, 0x0A }}, "SFM Storms Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "scrubs"},
{ 0x0215, 0x0169, SINGLE_SCENE_INFO(0x03), "Forest Temple", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON},
{ 0x000C, 0x024E, SINGLE_SCENE_INFO(0x03), "Forest Temple Boss Door", "Phantom Ganon", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x024E, 0x000C, SINGLE_SCENE_INFO(0x14), "Phantom Ganon", "Forest Temple Boss Door", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1},
// Kakariko Village
{ 0x017D, 0x00DB, SINGLE_SCENE_INFO(0x52), "Kakariko", "Hyrule Field", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"},
@ -161,32 +165,36 @@ const EntranceData entranceData[] = {
{ 0x02A6, 0x0098, SINGLE_SCENE_INFO(0x08), "Bottom of the Well", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_DUNGEON, "botw"},
// The Graveyard
{ 0x0195, 0x00E4, SINGLE_SCENE_INFO(0x53), "Graveyard", "Kakariko", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD},
{ 0x030D, 0x0355, SINGLE_SCENE_INFO(0x53), "Graveyard", "Dampe's Shack", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x004B, 0x035D, SINGLE_SCENE_INFO(0x53), "Graveyard", "Shield Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x031C, 0x0361, SINGLE_SCENE_INFO(0x53), "Graveyard", "Heart Piece Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x002D, 0x050B, SINGLE_SCENE_INFO(0x53), "Graveyard", "Composer's Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x044F, 0x0359, SINGLE_SCENE_INFO(0x53), "Graveyard", "Dampe's Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "race", 1},
{ 0x0037, 0x0205, SINGLE_SCENE_INFO(0x53), "Graveyard", "Shadow Temple", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0355, 0x030D, SINGLE_SCENE_INFO(0x3A), "Dampe's Shack", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_INTERIOR},
{ 0x035D, 0x004B, SINGLE_SCENE_INFO(0x40), "Shield Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO},
{ 0x0361, 0x031C, SINGLE_SCENE_INFO(0x3F), "Heart Piece Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO},
{ 0x050B, 0x002D, SINGLE_SCENE_INFO(0x41), "Composer's Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO},
{ 0x0359, 0x044F, SINGLE_SCENE_INFO(0x48), "Dampe's Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "race"},
{ 0x0205, 0x0037, SINGLE_SCENE_INFO(0x07), "Shadow Temple", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON},
{ 0x0195, 0x00E4, SINGLE_SCENE_INFO(0x53), "Graveyard", "Kakariko", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD},
{ 0x030D, 0x0355, SINGLE_SCENE_INFO(0x53), "Graveyard", "Dampe's Shack", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x004B, 0x035D, SINGLE_SCENE_INFO(0x53), "Graveyard", "Shield Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x031C, 0x0361, SINGLE_SCENE_INFO(0x53), "Graveyard", "Heart Piece Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x002D, 0x050B, SINGLE_SCENE_INFO(0x53), "Graveyard", "Composer's Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x044F, 0x0359, SINGLE_SCENE_INFO(0x53), "Graveyard", "Dampe's Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "race", 1},
{ 0x0037, 0x0205, SINGLE_SCENE_INFO(0x53), "Graveyard", "Shadow Temple", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0355, 0x030D, SINGLE_SCENE_INFO(0x3A), "Dampe's Shack", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_INTERIOR},
{ 0x035D, 0x004B, SINGLE_SCENE_INFO(0x40), "Shield Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO},
{ 0x0361, 0x031C, SINGLE_SCENE_INFO(0x3F), "Heart Piece Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO},
{ 0x050B, 0x002D, SINGLE_SCENE_INFO(0x41), "Composer's Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO},
{ 0x0359, 0x044F, SINGLE_SCENE_INFO(0x48), "Dampe's Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "race"},
{ 0x0205, 0x0037, SINGLE_SCENE_INFO(0x07), "Shadow Temple", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON},
{ 0x0413, 0x02B2, SINGLE_SCENE_INFO(0x07), "Shadow Temple Boss Door", "Bongo-Bongo", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x02B2, 0x0413, SINGLE_SCENE_INFO(0x18), "Bongo-Bongo", "Shadow Temple Boss Door", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1},
// Death Mountain Trail
{ 0x0191, 0x013D, SINGLE_SCENE_INFO(0x60), "DMT", "Kakariko", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD},
{ 0x014D, 0x01B9, SINGLE_SCENE_INFO(0x60), "DMT", "Goron City", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "gc"},
{ 0x0147, 0x01BD, SINGLE_SCENE_INFO(0x60), "DMT", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_OVERWORLD},
{ 0x0315, 0x045B, SINGLE_SCENE_INFO(0x60), "DMT", "DMT Great Fairy Fountain", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x0708, 0x0808, SINGLE_SCENE_INFO(0x60), "DMT", "DMT Storms Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "chest", 1},
{ 0x0709, 0x0809, SINGLE_SCENE_INFO(0x60), "DMT", "DMT Cow Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x0004, 0x0242, SINGLE_SCENE_INFO(0x60), "DMT", "Dodongo's Cavern", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1},
{ 0x045B, 0x0315, {{ 0x3B, 0x00 }}, "DMT Great Fairy Fountain", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_INTERIOR},
{ 0x0808, 0x0708, {{ 0x3E, 0x00 }}, "DMT Storms Grotto", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "chest"},
{ 0x0809, 0x0709, {{ 0x3E, 0x0D }}, "DMT Cow Grotto", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO},
{ 0x0242, 0x0004, SINGLE_SCENE_INFO(0x01), "Dodongo's Cavern", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc"},
{ 0x0191, 0x013D, SINGLE_SCENE_INFO(0x60), "DMT", "Kakariko", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD},
{ 0x014D, 0x01B9, SINGLE_SCENE_INFO(0x60), "DMT", "Goron City", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "gc"},
{ 0x0147, 0x01BD, SINGLE_SCENE_INFO(0x60), "DMT", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_OVERWORLD},
{ 0x0315, 0x045B, SINGLE_SCENE_INFO(0x60), "DMT", "DMT Great Fairy Fountain", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x0708, 0x0808, SINGLE_SCENE_INFO(0x60), "DMT", "DMT Storms Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "chest", 1},
{ 0x0709, 0x0809, SINGLE_SCENE_INFO(0x60), "DMT", "DMT Cow Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "", 1},
{ 0x0004, 0x0242, SINGLE_SCENE_INFO(0x60), "DMT", "Dodongo's Cavern", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1},
{ 0x045B, 0x0315, {{ 0x3B, 0x00 }}, "DMT Great Fairy Fountain", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_INTERIOR},
{ 0x0808, 0x0708, {{ 0x3E, 0x00 }}, "DMT Storms Grotto", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "chest"},
{ 0x0809, 0x0709, {{ 0x3E, 0x0D }}, "DMT Cow Grotto", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO},
{ 0x0242, 0x0004, SINGLE_SCENE_INFO(0x01), "Dodongo's Cavern", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc"},
{ 0x040B, 0x00C5, SINGLE_SCENE_INFO(0x01), "Dodongo's Cavern Boss Door", "King Dodongo", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1},
{ 0x00C5, 0x040B, SINGLE_SCENE_INFO(0x12), "King Dodongo", "Dodongo's Cavern Boss Door", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1},
// Death Mountain Crater
{ 0x01C1, 0x0246, SINGLE_SCENE_INFO(0x61), "DMC", "Goron City", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "gc"},
@ -199,6 +207,8 @@ const EntranceData entranceData[] = {
{ 0x0806, 0x0706, {{ 0x3E, 0x00 }}, "DMC Upper Grotto", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "chest"},
{ 0x0805, 0x0705, {{ 0x3E, 0x04 }}, "DMC Hammer Grotto", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs"},
{ 0x024A, 0x0165, SINGLE_SCENE_INFO(0x04), "Fire Temple", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON},
{ 0x0305, 0x0175, SINGLE_SCENE_INFO(0x04), "Fire Temple Boss Door", "Volvagia", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0175, 0x0305, SINGLE_SCENE_INFO(0x15), "Volvagia", "Fire Temple Boss Door", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1},
// Goron City
{ 0x01B9, 0x014D, SINGLE_SCENE_INFO(0x62), "Goron City", "DMT", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_OVERWORLD, "gc"},
@ -230,13 +240,15 @@ const EntranceData entranceData[] = {
{ 0x081C, 0x071C, {{ 0x3C, 0x00 }}, "ZD Storms Grotto", "Zora's Domain", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_GROTTO, "fairy"},
// Zora's Fountain
{ 0x01A1, 0x0225, SINGLE_SCENE_INFO(0x59), "ZF", "Zora's Domain", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD},
{ 0x0371, 0x0394, SINGLE_SCENE_INFO(0x59), "ZF", "ZF Great Fairy Fountain", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x0028, 0x0221, SINGLE_SCENE_INFO(0x59), "ZF", "Jabu Jabu's Belly", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0088, 0x03D4, SINGLE_SCENE_INFO(0x59), "ZF", "Ice Cavern", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0394, 0x0371, {{ 0x3D, 0x00 }}, "ZF Great Fairy Fountain", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_INTERIOR},
{ 0x0221, 0x0028, SINGLE_SCENE_INFO(0x02), "Jabu Jabu's Belly", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON},
{ 0x03D4, 0x0088, SINGLE_SCENE_INFO(0x09), "Ice Cavern", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON},
{ 0x01A1, 0x0225, SINGLE_SCENE_INFO(0x59), "ZF", "Zora's Domain", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD},
{ 0x0371, 0x0394, SINGLE_SCENE_INFO(0x59), "ZF", "ZF Great Fairy Fountain", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_INTERIOR, "", 1},
{ 0x0028, 0x0221, SINGLE_SCENE_INFO(0x59), "ZF", "Jabu Jabu's Belly", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0088, 0x03D4, SINGLE_SCENE_INFO(0x59), "ZF", "Ice Cavern", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0394, 0x0371, {{ 0x3D, 0x00 }}, "ZF Great Fairy Fountain", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_INTERIOR},
{ 0x0221, 0x0028, SINGLE_SCENE_INFO(0x02), "Jabu Jabu's Belly", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON},
{ 0x0301, 0x0407, SINGLE_SCENE_INFO(0x02), "Jabu Jabu's Belly Boss Door", "Barinade", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x0407, 0x0301, SINGLE_SCENE_INFO(0x13), "Barinade", "Jabu Jabu's Belly Boss Door", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x03D4, 0x0088, SINGLE_SCENE_INFO(0x09), "Ice Cavern", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON},
// Hyrule Field
{ 0x04DE, 0x0185, SINGLE_SCENE_INFO(0x51), "Hyrule Field", "Lost Woods Bridge", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "hf,lw"},
@ -275,16 +287,18 @@ const EntranceData entranceData[] = {
{ 0x0815, 0x0715, {{ 0x3E, 0x04 }}, "LLR Grotto", "Lon Lon Ranch", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_GROTTO, "scrubs"},
// Lake Hylia
{ 0x0189, 0x0102, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "Hyrule Field", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "lh"},
{ 0x0328, 0x0560, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "Zora's Domain", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD, "lh"},
{ 0x0043, 0x03CC, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "LH Lab", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh", 1},
{ 0x045F, 0x0309, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "Fishing Hole", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh", 1},
{ 0x0701, 0x0801, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "LH Grotto", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_GROTTO, "scrubs", 1},
{ 0x0010, 0x021D, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "Water Temple", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1},
{ 0x03CC, 0x0043, SINGLE_SCENE_INFO(0x38), "LH Lab", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh"},
{ 0x0309, 0x045F, SINGLE_SCENE_INFO(0x49), "Fishing Hole", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh"},
{ 0x0801, 0x0701, {{ 0x3E, 0x04 }}, "LH Grotto", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_GROTTO, "lh,scrubs"},
{ 0x021D, 0x0010, SINGLE_SCENE_INFO(0x05), "Water Temple", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh"},
{ 0x0189, 0x0102, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "Hyrule Field", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "lh"},
{ 0x0328, 0x0560, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "Zora's Domain", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD, "lh"},
{ 0x0043, 0x03CC, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "LH Lab", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh", 1},
{ 0x045F, 0x0309, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "Fishing Hole", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh", 1},
{ 0x0701, 0x0801, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "LH Grotto", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_GROTTO, "scrubs", 1},
{ 0x0010, 0x021D, SINGLE_SCENE_INFO(0x57), "Lake Hylia", "Water Temple", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1},
{ 0x03CC, 0x0043, SINGLE_SCENE_INFO(0x38), "LH Lab", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh"},
{ 0x0309, 0x045F, SINGLE_SCENE_INFO(0x49), "Fishing Hole", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh"},
{ 0x0801, 0x0701, {{ 0x3E, 0x04 }}, "LH Grotto", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_GROTTO, "lh,scrubs"},
{ 0x021D, 0x0010, SINGLE_SCENE_INFO(0x05), "Water Temple", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh"},
{ 0x0417, 0x0423, SINGLE_SCENE_INFO(0x05), "Water Temple Boss Door", "Morpha", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1},
{ 0x0423, 0x0417, SINGLE_SCENE_INFO(0x16), "Morpha", "Water Temple Boss Door", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1},
// Gerudo Area
{ 0x018D, 0x0117, SINGLE_SCENE_INFO(0x5A), "GV", "Hyrule Field", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"},
@ -313,6 +327,8 @@ const EntranceData entranceData[] = {
{ 0x057C, 0x0588, {{ 0x3D, 0x02 }}, "Colossus Great Fairy Fountain", "Colossus", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_INTERIOR, "dc"},
{ 0x0800, 0x0700, {{ 0x3E, 0x0A }}, "Colossus Grotto", "Desert Colossus", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_GROTTO, "dc,scrubs"},
{ 0x01E1, 0x0082, SINGLE_SCENE_INFO(0x06), "Spirit Temple", "Desert Colossus", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "dc"},
{ 0x008D, 0x02F5, SINGLE_SCENE_INFO(0x06), "Spirit Temple Boss Door", "Twinrova", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "", 1},
{ 0x02F5, 0x008D, SINGLE_SCENE_INFO(0x17), "Twinrova", "Spirit Temple Boss Door", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "", 1},
// Market
{ 0x01FD, 0x0276, {SCENE_NO_SPAWN(0x1B), SCENE_NO_SPAWN(0x1C), SCENE_NO_SPAWN(0x1D)}, "Market Entrance", "Hyrule Field", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"},

View File

@ -1,5 +1,6 @@
#include "global.h"
#include "vt.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
void func_80095AB4(PlayState* play, Room* room, u32 flags);
void func_80095D04(PlayState* play, Room* room, u32 flags);
@ -575,6 +576,12 @@ u32 func_80096FE8(PlayState* play, RoomContext* roomCtx) {
s32 func_8009728C(PlayState* play, RoomContext* roomCtx, s32 roomNum) {
size_t size;
// In ER, override roomNum to load based on scene and spawn
if (gSaveContext.n64ddFlag && gSaveContext.respawnFlag <= 0 &&
Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
roomNum = Entrance_OverrideSpawnSceneRoom(play->sceneNum, play->curSpawn, roomNum);
}
return OTRfunc_8009728C(play, roomCtx, roomNum);
if (roomCtx->status == 0) {

View File

@ -49,8 +49,9 @@ void BgSpot01Idosoko_Init(Actor* thisx, PlayState* play) {
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader);
// If dungeon entrance randomizer is on, remove the well stone as adult Link when
// child Link has drained the water to the well
if (!LINK_IS_ADULT || gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) &&
Flags_GetEventChkInf(0x67)) {
if (!LINK_IS_ADULT || (gSaveContext.n64ddFlag &&
Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF &&
Flags_GetEventChkInf(0x67))) {
Actor_Kill(&this->dyna.actor);
} else {
BgSpot01Idosoko_SetupAction(this, func_808ABF54);

View File

@ -60,7 +60,7 @@ void BgSpot12Saku_Init(Actor* thisx, PlayState* play) {
// If ER is on, force the gate to always use its permanent flag
// (which it only uses in Child Gerudo Fortress in the vanilla game)
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) {
thisx->params = 0x0002;
}
@ -132,7 +132,7 @@ void BgSpot12Saku_Update(Actor* thisx, PlayState* play) {
BgSpot12Saku* this = (BgSpot12Saku*)thisx;
// If ER is on, when the guard opens the GtG gate its permanent flag will be set.
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) &&
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF &&
Flags_GetSwitch(play, 0x3A)) {
Flags_SetSwitch(play, 0x2);
}

View File

@ -73,8 +73,10 @@ void BgTreemouth_Init(Actor* thisx, PlayState* play) {
if ((gSaveContext.sceneSetupIndex < 4) && !LINK_IS_ADULT) {
BgTreemouth_SetupAction(this, func_808BC8B8);
// If dungeon entrance randomizer is on, keep the tree mouth open when link is adult and sword & shield have been shown to mido
} else if ((LINK_IS_ADULT && (!gSaveContext.n64ddFlag || !Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) ||
// If dungeon entrance randomizer is on, keep the tree mouth open
// when Link is adult and sword & shield have been shown to mido
} else if ((LINK_IS_ADULT && (!gSaveContext.n64ddFlag ||
Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) == RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) ||
!Flags_GetEventChkInf(0x4)) || (gSaveContext.sceneSetupIndex == 7)) {
this->unk_168 = 0.0f;
BgTreemouth_SetupAction(this, BgTreemouth_DoNothing);

View File

@ -582,7 +582,8 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0;
}
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
if (gSaveContext.n64ddFlag && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
Entrance_OverrideBlueWarp();
}
@ -688,7 +689,8 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0xFFF0;
}
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
if (gSaveContext.n64ddFlag && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
Entrance_OverrideBlueWarp();
}
@ -903,7 +905,8 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
}
}
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES)) {
if (gSaveContext.n64ddFlag && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
Entrance_OverrideBlueWarp();
}

View File

@ -332,7 +332,8 @@ void EnIshi_Init(Actor* thisx, PlayState* play) {
}
// If dungeon entrance randomizer is on, remove the grey boulders that normally
// block child Link from reaching the Fire Temple entrance.
if (type == ROCK_LARGE && gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) &&
if (type == ROCK_LARGE && gSaveContext.n64ddFlag &&
Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF &&
play->sceneNum == 0x061) { // Death Mountain Creater
Actor_Kill(&this->actor);
}

View File

@ -4127,6 +4127,11 @@ void KaleidoScope_Update(PlayState* play)
gSaveContext.entranceIndex = 0x041B;
break;
}
// In ER, handle overriding the game over respawn entrance
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
Entrance_SetGameOverEntrance();
}
} else {
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
}