From 9bd34a0d0210338a8f230f80b7133e76d04d7f30 Mon Sep 17 00:00:00 2001 From: gymnast86 Date: Sun, 21 Jun 2026 09:07:54 -0700 Subject: [PATCH 1/4] fix gor liggs always setting item bit for 3 key shards --- src/dusk/randomizer/generator/data/flow_patches.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/dusk/randomizer/generator/data/flow_patches.yaml b/src/dusk/randomizer/generator/data/flow_patches.yaml index 92e7a43261..37cfe6bfe2 100644 --- a/src/dusk/randomizer/generator/data/flow_patches.yaml +++ b/src/dusk/randomizer/generator/data/flow_patches.yaml @@ -57,7 +57,16 @@ event: 42 parameters: 0x00000000 next node index: 0x10C -#5: # zel_05.bmg + +5: # zel_05.bmg + # Patch Gor Liggs to not set the flag for the third key shard + # Change event index 17 to event index 42 which does nothing + - index: 0x258 + type: event + event: 42 + parameters: 0x00000000 + next node index: 0x1AC + #6: # zel_06.bmg #7: # zel_07.bmg #8: # zel_08.bmg From 4239cea3d529ee83cabec793b8442b857c697137 Mon Sep 17 00:00:00 2001 From: gymnast86 Date: Sun, 21 Jun 2026 15:59:39 -0700 Subject: [PATCH 2/4] Fix arbiters grounds sometimes not being listed as a required dungeon --- .../data/world/overworld/Snowpeak Province.yaml | 2 ++ src/dusk/randomizer/generator/logic/area.cpp | 2 +- src/dusk/randomizer/generator/logic/world.cpp | 16 ++++++++-------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/dusk/randomizer/generator/data/world/overworld/Snowpeak Province.yaml b/src/dusk/randomizer/generator/data/world/overworld/Snowpeak Province.yaml index c2efddc69e..e0bcc777b8 100644 --- a/src/dusk/randomizer/generator/data/world/overworld/Snowpeak Province.yaml +++ b/src/dusk/randomizer/generator/data/world/overworld/Snowpeak Province.yaml @@ -102,12 +102,14 @@ Snowpeak Summit Lower: Nothing - Name: Snowpeak Ruins East Door Interior + Region: Snowpeak Ruins Can Transform: Never Exits: Snowpeak Ruins East Door Exterior: Can_Open_Doors Snowpeak Ruins Entrance: Nothing - Name: Snowpeak Ruins West Door Interior + Region: Snowpeak Ruins Can Transform: Never Exits: Snowpeak Ruins West Door Exterior: Can_Open_Doors diff --git a/src/dusk/randomizer/generator/logic/area.cpp b/src/dusk/randomizer/generator/logic/area.cpp index 5d06c8c6bf..96f173f7a1 100644 --- a/src/dusk/randomizer/generator/logic/area.cpp +++ b/src/dusk/randomizer/generator/logic/area.cpp @@ -250,7 +250,7 @@ namespace randomizer::logic::area this->AddHintRegion(region); LOG_TO_DEBUG("Assigned \"" + region + "\" as hint region to \"" + this->GetName() + "\""); - // Also assign any loactions in this area to the dungeon if there are any dungeon regions + // Also assign any locations in this area to the dungeon if there are any dungeon regions if (dungeons.contains(region)) { auto locAccs = this->GetLocations(); diff --git a/src/dusk/randomizer/generator/logic/world.cpp b/src/dusk/randomizer/generator/logic/world.cpp index 05bbc48eff..73a795085c 100644 --- a/src/dusk/randomizer/generator/logic/world.cpp +++ b/src/dusk/randomizer/generator/logic/world.cpp @@ -728,22 +728,22 @@ namespace randomizer::logic::world for (auto& [areaName, area] : this->_areaTable) { area->AssignHintRegionsAndDungeonLocations(); + } + for (auto& [areaName, area] : this->_areaTable) + { // Also assign dungeons their starting entrance for (const auto& exit : area->GetExits()) { auto parentRegions = exit->GetParentArea()->GetHintRegions(); auto connectedRegions = exit->GetConnectedArea()->GetHintRegions(); - if (!parentRegions.contains("None")) + for (auto& [dungeonName, dungeon] : this->_dungeons) { - for (auto& [dungeonName, dungeon] : this->_dungeons) + // If this exit leads into a dungeon and its parent area is not part of the dungeon + // then this is the entrance that leads into the dungeon + if (connectedRegions.contains(dungeonName) && !parentRegions.contains(dungeonName)) { - // If this exit leads into a dungeon and its parent area is not part of the dungeon - // then this is the entrance that leads into the dungeon - if (connectedRegions.contains(dungeonName) && !parentRegions.contains(dungeonName)) - { - dungeon->AddStartingEntrance(exit); - } + dungeon->AddStartingEntrance(exit); } } } From e57c952deb93542aef21dee7d55fc6ee30430b38 Mon Sep 17 00:00:00 2001 From: gymnast86 Date: Sun, 21 Jun 2026 16:18:07 -0700 Subject: [PATCH 3/4] print required dungeons to spoiler log --- .../generator/logic/spoiler_log.cpp | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/dusk/randomizer/generator/logic/spoiler_log.cpp b/src/dusk/randomizer/generator/logic/spoiler_log.cpp index b5b470358a..651b21752a 100644 --- a/src/dusk/randomizer/generator/logic/spoiler_log.cpp +++ b/src/dusk/randomizer/generator/logic/spoiler_log.cpp @@ -65,19 +65,19 @@ namespace randomizer::logic::spoiler_log LogBasicInfo(spoilerLog, randomizer); // Gather worlds with starting inventories - std::list worldswithStartingInventories = {}; + std::list worldsWithStartingInventories = {}; for (const auto& world : worlds) { if (!world->GetStartingItemPool().empty()) { - worldswithStartingInventories.push_back(world.get()); + worldsWithStartingInventories.push_back(world.get()); } } // Print starting inventories if there are any - if (!worldswithStartingInventories.empty()) + if (!worldsWithStartingInventories.empty()) { spoilerLog << std::endl << "All Starting Items:" << std::endl; - for (const auto& world : worldswithStartingInventories) + for (const auto& world : worldsWithStartingInventories) { spoilerLog << " World " << world->GetID() << ":" << std::endl; for (const auto& item : world->GetStartingItemPool()) @@ -87,7 +87,31 @@ namespace randomizer::logic::spoiler_log } } - // TODO: Print required dungeons + // Gather worlds with required dungeons + std::list worldsWithRequiredDungeons = {}; + for (const auto& world : worlds) + { + for (const auto& [dungeonName, dungeon] : world->GetDungeonTable()) { + if (dungeon->IsRequired()) { + worldsWithRequiredDungeons.push_back(world.get()); + break; + } + } + } + // Print required dungeons if there are any + if (!worldsWithRequiredDungeons.empty()) + { + spoilerLog << std::endl << "Required Dungeons:" << std::endl; + for (const auto& world : worldsWithRequiredDungeons) + { + spoilerLog << " World " << world->GetID() << ":" << std::endl; + for (const auto& [dungeonName, dungeon] : world->GetDungeonTable()) { + if (dungeon->IsRequired()) { + spoilerLog << " - " << dungeonName << std::endl; + } + } + } + } // Get name lengths for pretty formatting size_t longestNameLength = 0; From 6592871fa2df2c2f4f91c568c612b0c00d24df86 Mon Sep 17 00:00:00 2001 From: gymnast86 Date: Tue, 23 Jun 2026 09:16:39 -0700 Subject: [PATCH 4/4] add mirror chamber access setting --- src/d/actor/d_a_obj_gb.cpp | 12 ++++ src/d/d_com_inf_game.cpp | 7 ++ .../randomizer/game/randomizer_context.cpp | 64 +++++++++++++++++-- .../randomizer/game/randomizer_context.hpp | 26 +++++--- .../generator/data/entrance_shuffle_data.yaml | 16 ++--- .../generator/data/object_patches.yaml | 22 +++++++ .../generator/data/settings_list.yaml | 9 +++ .../data/world/overworld/Gerudo Desert.yaml | 2 +- .../randomizer/generator/logic/item_pool.cpp | 9 +++ src/dusk/ui/rando_config.cpp | 4 +- 10 files changed, 148 insertions(+), 23 deletions(-) diff --git a/src/d/actor/d_a_obj_gb.cpp b/src/d/actor/d_a_obj_gb.cpp index a610dfd5fb..795631c066 100644 --- a/src/d/actor/d_a_obj_gb.cpp +++ b/src/d/actor/d_a_obj_gb.cpp @@ -12,6 +12,11 @@ #include "d/d_com_inf_game.h" #include +#if TARGET_PC +#include "dusk/randomizer/game/stages.h" +#include "dusk/randomizer/game/tools.h" +#endif + static int daObj_Gb_Draw(obj_gb_class* i_this) { g_env_light.settingTevStruct(0x10, &i_this->current.pos, &i_this->tevStr); g_env_light.setLightTevColorType_MAJI(i_this->mModel, &i_this->tevStr); @@ -169,6 +174,13 @@ static int useHeapInit(fopAc_ac_c* actor) { static int daObj_Gb_Create(fopAc_ac_c* actor) { fopAcM_ct(actor, obj_gb_class); obj_gb_class* i_this = (obj_gb_class*)actor; +#if TARGET_PC + // Only spawn the added wall in randomizer if it should exist + if (randomizer_IsActive() && getStageID() == StageIDs::Mirror_Chamber && + !randomizer_mirrorChamberWallShouldExist()) { + return cPhs_ERROR_e; + } +#endif int rv = dComIfG_resLoad(&i_this->mPhase, "Obj_gb"); if (rv == cPhs_COMPLEATE_e) { diff --git a/src/d/d_com_inf_game.cpp b/src/d/d_com_inf_game.cpp index db6d243f9a..e0fe128c15 100644 --- a/src/d/d_com_inf_game.cpp +++ b/src/d/d_com_inf_game.cpp @@ -2013,6 +2013,13 @@ stage_arrow_class* dComIfGp_getRoomArrow(int i_roomNo) { void dComIfGp_setNextStage(char const* i_stage, s16 i_point, s8 i_roomNo, s8 i_layer, f32 i_lastSpeed, u32 i_lastMode, int i_setPoint, s8 i_wipe, s16 i_lastAngle, int param_9, int i_wipeSpeedT) { +#if TARGET_PC + // In rando, override this entrance if applicable + if (randomizer_IsActive()) { + randomizer_checkAndOverrideEntranceData(i_stage, i_roomNo, i_point, i_layer); + } +#endif + if (i_layer >= 15) { i_layer = -1; } diff --git a/src/dusk/randomizer/game/randomizer_context.cpp b/src/dusk/randomizer/game/randomizer_context.cpp index 64e159a50b..e03ae7072e 100644 --- a/src/dusk/randomizer/game/randomizer_context.cpp +++ b/src/dusk/randomizer/game/randomizer_context.cpp @@ -121,6 +121,10 @@ std::optional RandomizerContext::WriteToFile() { textData << YAML::EndMap; textData << YAML::EndMap; + for (const auto& [key, override] : mEntranceOverrides) { + out["mEntranceOverrides"][key] = std::bit_cast(override); + } + seedData << YAML::Dump(out); seedData << '\n' << textData.c_str(); seedData.close(); @@ -278,6 +282,13 @@ std::optional RandomizerContext::LoadFromHash(const std::string& ha } } + // Entrance Overrides + for (const auto& entranceNode : in["mEntranceOverrides"]) { + auto key = entranceNode.first.as(); + auto override = std::bit_cast(entranceNode.second.as()); + this->mEntranceOverrides[key] = override; + } + dusk::ui::push_toast(dusk::ui::Toast{ .title = "Randomizer", .content = fmt::format("Loaded Randomizer Seed {}", this->mHash), @@ -291,7 +302,7 @@ std::filesystem::path RandomizerContext::GetSeedDataPath() const { } int RandomizerContext::SettingToEnum(const std::string& settingName) { - static const std::unordered_map nameToEnum = { + static const std::map nameToEnum = { {"Hyrule Barrier Dungeons", HYRULE_BARRIER_DUNGEONS}, {"Hyrule Barrier Requirements", HYRULE_BARRIER_REQUIREMENTS}, {"Hyrule Barrier Fused Shadows", HYRULE_BARRIER_FUSED_SHADOWS}, @@ -309,6 +320,7 @@ int RandomizerContext::SettingToEnum(const std::string& settingName) { {"Skip Minor Cutscenes", SKIP_MINOR_CUTSCENES}, {"Skip Major Cutscenes", SKIP_MAJOR_CUTSCENES}, {"Skip Bridge Donation", SKIP_BRIDGE_DONATION}, + {"Mirror Chamber Access", MIRROR_CHAMBER_ACCESS}, }; if (nameToEnum.contains(settingName)) { @@ -319,7 +331,7 @@ int RandomizerContext::SettingToEnum(const std::string& settingName) { } int RandomizerContext::OptionToEnum(const std::string& optionName) { - static const std::unordered_map nameToEnum = { + static const std::map nameToEnum = { {"On", ON}, {"Off", OFF}, {"None", NONE}, @@ -334,6 +346,8 @@ int RandomizerContext::OptionToEnum(const std::string& optionName) { {"Ordon Sword", ORDON_SWORD}, {"Master Sword", MASTER_SWORD}, {"Light Sword", LIGHT_SWORD}, + {"Closed", CLOSED}, + {"Barrier", BARRIER}, }; if (nameToEnum.contains(optionName)) { @@ -531,7 +545,7 @@ static void updateGoalFlags() { } } - // Palace of Twlight Access + // Palace of Twilight Access if (!dComIfGs_isEventBit(FIXED_THE_MIRROR_OF_TWILIGHT)) { bool openPalace = false; switch (settings[RandomizerContext::PALACE_OF_TWILIGHT_REQUIREMENTS]) { @@ -798,6 +812,21 @@ int randomizer_getItemAtLocation(const std::string& locationName) { return randomizer_GetContext().mItemLocations[locationName].itemId; } +void randomizer_checkAndOverrideEntranceData(const char*& stageName, s8& roomNo, s16& pointNo, s8& mapLayer) { + RandomizerContext::EntranceOverride override = { + static_cast(getStageID(stageName)), roomNo, static_cast(pointNo), mapLayer + }; + + int key = std::bit_cast(override); + if (randomizer_GetContext().mEntranceOverrides.contains(key)) { + auto& newOverride = randomizer_GetContext().mEntranceOverrides[key]; + stageName = allStages[newOverride.stageId]; + pointNo = newOverride.pointNo; + roomNo = newOverride.roomNo; + mapLayer = newOverride.mapLayer; + } +} + static void randomizer_setTempFlag(RandomizerContext::itemLocationData data) { // If stage is 0xFF, then this is an event flag if (data.stage == 0xFF) { @@ -861,6 +890,12 @@ bool randomizer_checkTempleOfTimeRequirement() { return false; } +bool randomizer_mirrorChamberWallShouldExist() { + auto mirrorChamberAccess = randomizer_GetContext().mSettings[RandomizerContext::MIRROR_CHAMBER_ACCESS]; + return mirrorChamberAccess == RandomizerContext::CLOSED || + (mirrorChamberAccess == RandomizerContext::BARRIER && !dComIfGs_isStageBossEnemy(0x13)); +} + u8 randomizer_getRandomFoolishItemModelID() { static constexpr auto foolishItemModels = std::to_array({ dItemNo_Randomizer_ARMOR_e, @@ -1204,7 +1239,7 @@ RandomizerContext WriteSeedData(randomizer::logic::world::World* world) { const auto& stageName = stageNode.first.as(); for (const auto& roomNode : stageNode.second) { u8 roomNo{}; - // Special value for + // Special value for actors always on the stage and not just one specific room if (roomNode.first.as() == "Stage") { roomNo = RandomizerContext::ROOM_STAGE; } else { @@ -1316,6 +1351,27 @@ RandomizerContext WriteSeedData(randomizer::logic::world::World* world) { } } + // Entrance Overrides + if (world->Setting("Mirror Chamber Access") == "Closed") { + // Set exiting the Arbiter's Grounds Boss Room to spawn at the Arbiter's Grounds entrance + // if mirror chamber access is closed + RandomizerContext::EntranceOverride original = { + StageIDs::Mirror_Chamber, + 4, + 0, + -1 + }; + + RandomizerContext::EntranceOverride override = { + StageIDs::Bulblin_Camp, + 3, + 3, + -1 + }; + + randoData.mEntranceOverrides[std::bit_cast(original)] = override; + } + return std::move(randoData); } diff --git a/src/dusk/randomizer/game/randomizer_context.hpp b/src/dusk/randomizer/game/randomizer_context.hpp index 7f5fcf8bf0..28c142149f 100644 --- a/src/dusk/randomizer/game/randomizer_context.hpp +++ b/src/dusk/randomizer/game/randomizer_context.hpp @@ -70,14 +70,15 @@ public: // Map of language -> map of key -> string std::unordered_map> mTextOverrides{}; - // TODO: hook this up to generator data - struct { - // for now use hardcoded values for this - std::string mapName = "F_SP103"; // (Ordon) Outside Link's House - int pointNo = 1; - int roomNo = 1; - int mapLayer = -1; - } mStartLocation; + struct EntranceOverride { + u8 stageId = 0xFF; + s8 roomNo = -1; + s8 pointNo = -1; + s8 mapLayer = -1; + }; + + // keyed by stageId << 24 | pointNo << 16 | roomNo << 8 | mapLayer + std::unordered_map mEntranceOverrides{}; std::optional WriteToFile(); std::optional LoadFromHash(const std::string& hash); @@ -101,6 +102,7 @@ public: SKIP_MINOR_CUTSCENES, SKIP_MAJOR_CUTSCENES, SKIP_BRIDGE_DONATION, + MIRROR_CHAMBER_ACCESS, }; enum Options { @@ -118,6 +120,8 @@ public: ORDON_SWORD, MASTER_SWORD, LIGHT_SWORD, + BARRIER, + CLOSED, }; static int SettingToEnum(const std::string& settingName); @@ -206,6 +210,10 @@ bool randomizer_IsActive(); int randomizer_getItemAtLocation(const std::string& locationName); +/* + * @brief Overrides the given entrance paramaters if an override exists for them + */ +void randomizer_checkAndOverrideEntranceData(const char*& i_Name, s8& i_RoomNo, s16& i_Point, s8& i_Layer); /* * @brief Puts the associated flag into the randomizer state's temporary flag * variable. This allows the tracker/Archipelago to know a location has been checked @@ -217,6 +225,8 @@ void randomizer_setTempFlagForFLWOverride(u32 key); bool randomizer_checkTempleOfTimeRequirement(); +bool randomizer_mirrorChamberWallShouldExist(); + u8 randomizer_getRandomFoolishItemModelID(); /** diff --git a/src/dusk/randomizer/generator/data/entrance_shuffle_data.yaml b/src/dusk/randomizer/generator/data/entrance_shuffle_data.yaml index eee0d702cb..4634003d31 100644 --- a/src/dusk/randomizer/generator/data/entrance_shuffle_data.yaml +++ b/src/dusk/randomizer/generator/data/entrance_shuffle_data.yaml @@ -5,9 +5,9 @@ - Type: Spawn Forward: Connection: Links Spawn -> Outside Links House - Stage: -1 - Room: -1 - Spawn: "" + Stage: 43 + Room: 1 + Spawn: "01" Spawn Type: "" Parameters: "" State: "FF" @@ -449,11 +449,11 @@ Return: Connection: Arbiters Grounds Boss Room -> Mirror Chamber Lower Alias: Arbiters Grounds Boss Room -> Mirror Chamber - Stage: -1 - Room: -1 - Spawn: "" - Spawn Type: "" - Parameters: "" + Stage: 60 + Room: 4 + Spawn: "00" + Spawn Type: "10" + Parameters: "501F" State: "FF" - Type: Boss diff --git a/src/dusk/randomizer/generator/data/object_patches.yaml b/src/dusk/randomizer/generator/data/object_patches.yaml index 27ba39f482..1f8fa231e3 100644 --- a/src/dusk/randomizer/generator/data/object_patches.yaml +++ b/src/dusk/randomizer/generator/data/object_patches.yaml @@ -3470,6 +3470,28 @@ F_SP124: layers: - 0 +# Mirror Chamber +F_SP125: + # Room 4 - Main Chamber + 4: + # Add barrier to prevent players from going back to the Arbiters Boss Room + # depending on settings + - action: add + name: Obj_gb + parameters: 0x800F0601 + position: + x: 1794.0 + y: 2523.0 + z: -17400.0 + angle: + x: 0xFF7F + y: 0x0000 + z: 0x0000 + set id: 0xFFFF + layers: + - 0 + - 1 + # Upper Zora's River F_SP126: # Room 0 - Main area diff --git a/src/dusk/randomizer/generator/data/settings_list.yaml b/src/dusk/randomizer/generator/data/settings_list.yaml index 48111657b5..fae5064bfa 100644 --- a/src/dusk/randomizer/generator/data/settings_list.yaml +++ b/src/dusk/randomizer/generator/data/settings_list.yaml @@ -79,6 +79,15 @@ - Closed: "Midna will block the player from leaving Faron Woods until Forest Temple is completed." - Open: "Midna will not prevent the player from leaving Faron Woods." +- Name: Mirror Chamber Access + Need In Game: True + Tracker Important: True + Default Option: Open + Options: + - Open: "The entrance is open and operates like normal. If you start with the Mirror Chamber Portal, you can access the Stallord boss fight without going through Arbiter's Grounds." + - Barrier: "A barrier is placed in front of the Mirror Chamber entrance and goes away once Stallord is defeated." + - Closed: "The Mirror Chamber is isolated from the world and cannot be reached from the Stallord boss room. To access it, players will either need the portal or access from Palace of Twilight." + ###################### ## Item Pool ## ###################### diff --git a/src/dusk/randomizer/generator/data/world/overworld/Gerudo Desert.yaml b/src/dusk/randomizer/generator/data/world/overworld/Gerudo Desert.yaml index 6b02b6e684..a860328b78 100644 --- a/src/dusk/randomizer/generator/data/world/overworld/Gerudo Desert.yaml +++ b/src/dusk/randomizer/generator/data/world/overworld/Gerudo Desert.yaml @@ -126,7 +126,7 @@ Can Warp: True Exits: Mirror Chamber Upper: Nothing - Arbiters Grounds Boss Room: Nothing + Arbiters Grounds Boss Room: Mirror_Chamber_Access == Open or (Mirror_Chamber_Access == Barrier and 'Can_Complete_Arbiters_Grounds') - Name: Mirror Chamber Upper Map Sector: Desert Province diff --git a/src/dusk/randomizer/generator/logic/item_pool.cpp b/src/dusk/randomizer/generator/logic/item_pool.cpp index 9058ab2132..498aaf5798 100644 --- a/src/dusk/randomizer/generator/logic/item_pool.cpp +++ b/src/dusk/randomizer/generator/logic/item_pool.cpp @@ -423,6 +423,15 @@ namespace randomizer::logic::item_pool startingItems["Castle Town Portal"] = 1; } + // Automatically give players the Mirror Chamber Portal if Mirror Chamber Access is closed + // and they aren't both randomizing and decoupling dungeon entrances. Otherwise, there's no + // way to access the chamber + if (world->Setting("Mirror Chamber Access") == "Closed" && + !(world->Setting("Randomize Dungeon Entrances") == "On" && world->Setting("Decouple Entrances") == "On")) + { + startingItems["Mirror Chamber Portal"] = 1; + } + // Add each item to the world's _startingItemPool and erase it from the regular _itemPool for (const auto& [itemName, count] : startingItems) { diff --git a/src/dusk/ui/rando_config.cpp b/src/dusk/ui/rando_config.cpp index b512e627dc..b8f830e6b7 100644 --- a/src/dusk/ui/rando_config.cpp +++ b/src/dusk/ui/rando_config.cpp @@ -926,6 +926,7 @@ RandomizerWindow::RandomizerWindow(dFile_select_c* fileSelect /*= nullptr*/) : m }); rando_config_group(leftPane, rightPane, "Palace of Twilight Requirements"); rando_config_group(leftPane, rightPane, "Faron Woods Logic"); + rando_config_group(leftPane, rightPane, "Mirror Chamber Access"); // leftPane.add_section("World (TODO)"); @@ -1220,8 +1221,7 @@ RandomizerWindow::RandomizerWindow(dFile_select_c* fileSelect /*= nullptr*/) : m leftPane.register_control(leftPane.add_button("Warp to Start").on_pressed([] { mDoAud_seStartMenu(kSoundClick); - auto& locData = randomizer_GetContext().mStartLocation; - dComIfGp_setNextStage(locData.mapName.c_str(), locData.pointNo, locData.roomNo, locData.mapLayer); + dComIfGp_setNextStage("F_SP103", 1, 1, -1); }), rightPane, [](Pane& pane) { pane.clear(); pane.add_rml("Respawns the player at their appropriate starting location.");