From 920393527382e83c884a922079728036a5ac786d Mon Sep 17 00:00:00 2001 From: gymnast86 Date: Tue, 1 Sep 2026 04:58:57 -0700 Subject: [PATCH] don't respawn at randomized starting entrance on loading an existing file --- mods/randomizer/src/hooks.cpp | 27 +++++++------ mods/randomizer/src/randomizer_context.cpp | 18 +++++++++ mods/randomizer/src/randomizer_context.hpp | 6 +++ mods/randomizer/src/session.cpp | 45 ---------------------- mods/randomizer/src/session.hpp | 1 - 5 files changed, 39 insertions(+), 58 deletions(-) diff --git a/mods/randomizer/src/hooks.cpp b/mods/randomizer/src/hooks.cpp index 150380d375..973e3023e0 100644 --- a/mods/randomizer/src/hooks.cpp +++ b/mods/randomizer/src/hooks.cpp @@ -83,6 +83,8 @@ DEFINE_HOOK(&dSv_player_item_c::setLineUpItem, dSv_player_item_c__setLineUpItem) DEFINE_HOOK(&dSv_info_c::onSwitch, dSv_info_c__onSwitch); +DEFINE_HOOK(&dScnName_c::changeGameScene, dScnName_c__changeGameScene); + #ifdef _MSVC_LANG #define setNextStage_sig "?dComIfGp_setNextStage@@YAXPEBDFCCMIHCFHH@Z" #else @@ -146,8 +148,6 @@ DEFINE_HOOK(&daNpc_ykW_c::isDelete, daNpc_ykW_c__isDelete); DEFINE_HOOK_SYMBOL("daE_MD_Create", int(fopAc_ac_c*), daE_MD_c__create); -DEFINE_HOOK(&dScnName_c::changeGameScene, dScnName_c__changeGameScene); - DEFINE_HOOK(&daNpc_zrZ_c::isDelete, daNpc_zrZ_c__isDelete); DEFINE_HOOK(&daTbox2_c::Create, daTbox2_c__Create); @@ -714,6 +714,14 @@ HookAction hookPreGetItemFunc(ModContext*, void* args, void*, void*) { return HOOK_SKIP_ORIGINAL; } +HookAction hookPre_dScnName_c__changeGameScene(ModContext*, void*, void*, void*) { + // Don't override our next entrance when starting a file + if (!mDoRst::isReset() && !fopOvlpM_IsPeek()) { + randomizer_dontOverrideNextEntrance(); + } + return HOOK_CONTINUE; +} + HookAction hookPreSetNextStage(ModContext*, void* args, void*, void*) { randomizer_checkAndOverrideEntranceData( mods::arg_ref(args, 0), @@ -2245,12 +2253,6 @@ void hookPostEMdCreate(ModContext*, void* args, void*, void*) { hookEMdCreate_prevSkipInfo = 0; } -void hookPost_dScnName_c__changeGameScene(ModContext* ctx, void* args, void* retval, void* userdata) { - if (!mDoRst::isReset() && !fopOvlpM_IsPeek()) { - randomizer::session::registerStartingLocation(); - } -} - void hookPostTbox2Create(ModContext*, void* args, void* retval, void*) { if (*static_cast(retval) != 1) { return; @@ -3293,6 +3295,8 @@ ModResult initialize() { ADD_HOOK_PRE(dSv_info_c__onSwitch, hookPreSaveInfoOnSwitch); + ADD_HOOK_PRE(dScnName_c__changeGameScene, hookPre_dScnName_c__changeGameScene); + ADD_HOOK_PRE(setNextStage, hookPreSetNextStage); ADD_HOOK_PRE(ObjGb_Create, hookPreObjGbCreate); @@ -3353,8 +3357,6 @@ ModResult initialize() { ADD_HOOK_PRE(daE_MD_c__create, hookPreEMdCreate); ADD_HOOK_POST(daE_MD_c__create, hookPostEMdCreate); - ADD_HOOK_POST(dScnName_c__changeGameScene, hookPost_dScnName_c__changeGameScene); - ADD_HOOK_POST(daNpc_zrZ_c__isDelete, hookPostNpcZrzIsDelete); ADD_HOOK_POST(daTbox2_c__Create, hookPostTbox2Create); @@ -3438,6 +3440,9 @@ ModResult uninstall() { mods::hook::uninstall(svc_hook); mods::hook::uninstall(svc_hook); + + mods::hook::uninstall(); + mods::hook::uninstall(); mods::hook::uninstall(svc_hook); @@ -3494,8 +3499,6 @@ ModResult uninstall() { mods::hook::uninstall(svc_hook); - mods::hook::uninstall(); - mods::hook::uninstall(svc_hook); mods::hook::uninstall(svc_hook); diff --git a/mods/randomizer/src/randomizer_context.cpp b/mods/randomizer/src/randomizer_context.cpp index bf3aba3f69..b3662a1804 100644 --- a/mods/randomizer/src/randomizer_context.cpp +++ b/mods/randomizer/src/randomizer_context.cpp @@ -882,7 +882,17 @@ int randomizer_getItemAtLocation(const std::string& locationName) { return randomizer_GetContext().mItemLocations[nameLookupOverride(locationName)].itemId; } +void randomizer_dontOverrideNextEntrance() { + g_randomizerState.mTryOverrideNextEntrance = false; +} + void randomizer_checkAndOverrideEntranceData(const char*& stageName, s8& roomNo, s16& pointNo, s8& mapLayer, u32& lastMode) { + if (!g_randomizerState.mTryOverrideNextEntrance) { + mods::log::debug("Skipping next entrance override"); + g_randomizerState.mTryOverrideNextEntrance = true; + return; + } + RandomizerContext::EntranceOverride override = { .stageId = static_cast(getStageID(stageName)), .roomNo = roomNo, .mapLayer = mapLayer, .pointNo = static_cast(pointNo)}; @@ -927,6 +937,12 @@ void randomizer_checkAndOverrideEntranceData(const char*& stageName, s8& roomNo, pointNo = 30; } + // If this is our starting spawn, also set it as our return place for saving + if (override.stageId == getStageID("F_SP103") && override.roomNo == 1 && override.pointNo == 1) { + auto& returnPlace = dComIfGs_getSaveData()->mPlayer.getPlayerReturnPlace(); + returnPlace.set(stageName, roomNo, pointNo); + } + // mods::log::info("New Stage:{}, {}, {}, {}",stageName,roomNo,pointNo,mapLayer); } } @@ -1010,6 +1026,8 @@ void randomizer_returnToSpawn(bool tryOverride) { entrance.pointNo = 2; } + // Don't attempt to override returning to a dungeon entrance + randomizer_dontOverrideNextEntrance(); dComIfGp_setNextStage(allStages[entrance.stageId], entrance.pointNo, entrance.roomNo, entrance.mapLayer); return; } diff --git a/mods/randomizer/src/randomizer_context.hpp b/mods/randomizer/src/randomizer_context.hpp index 1fa6e948b0..4b935a6ac8 100644 --- a/mods/randomizer/src/randomizer_context.hpp +++ b/mods/randomizer/src/randomizer_context.hpp @@ -239,6 +239,7 @@ public: int stage{-1}; int flag{-1}; } mTrackerTempItemFlag; + bool mTryOverrideNextEntrance{true}; }; extern RandomizerState g_randomizerState; @@ -249,6 +250,11 @@ bool randomizer_IsActive(); int randomizer_getItemAtLocation(const std::string& locationName); +/* + * @brief Sets a flag to skip overriding the next entrance that gets set + */ +void randomizer_dontOverrideNextEntrance(); + /* * @brief Overrides the given entrance paramaters if an override exists for them */ diff --git a/mods/randomizer/src/session.cpp b/mods/randomizer/src/session.cpp index dc45aa39e1..94bebc8a48 100644 --- a/mods/randomizer/src/session.cpp +++ b/mods/randomizer/src/session.cpp @@ -379,51 +379,6 @@ void registerStageEdits() { } } -// Set link to spawn outside of his house if we are playing with entrance rando and aren't already spawning in a dungeon -void registerStartingLocation() { - auto& ctx = randomizer_GetContext(); - - if (ctx.mEntranceOverrides.empty()) { - return; - } - - // Check that we aren't playing only with the setting Mirror Chamber Access set to Closed - bool isExclusivelyMirrorChamber = false; - const auto& mirrorChamberIt = ctx.mEntranceOverrides.find(RandomizerContext::EntranceOverride{ - .stageId = StageIDs::Mirror_Chamber, - .roomNo = 4, - .mapLayer = -1, - .pointNo = 0 - }); - if (ctx.mEntranceOverrides.size() == 1 && mirrorChamberIt != ctx.mEntranceOverrides.end()) { - if (mirrorChamberIt->second == RandomizerContext::EntranceOverride{ - .stageId = StageIDs::Bulblin_Camp, - .roomNo = 3, - .mapLayer = -1, - .pointNo = 3, - }) { - isExclusivelyMirrorChamber = true; - } - } - - if (isExclusivelyMirrorChamber) { - return; - } - - dSv_player_return_place_c& returnPlace = dComIfGs_getSaveData()->mPlayer.getPlayerReturnPlace(); - - // If we are loading into a dungeon, preserve our original return place - if (std::string(returnPlace.getName()).find("D_MN") == 0) { - // Force-set the entrance without the override - g_dComIfG_gameInfo.play.mNextStage.getStartStage()->set(returnPlace.getName(), returnPlace.getRoomNo(), returnPlace.mPlayerStatus, -1); - return; - } - - // Set the spawn to outside of link's house, which will get overrided later if we are replacing it - returnPlace.set("F_SP103",1,1); - dComIfGp_setNextStage("F_SP103", 1, 1, -1); -} - ModResult onNewSave(void*, ModError*) { const std::string hash = g_pending_seed_hash; if (hash.empty()) diff --git a/mods/randomizer/src/session.hpp b/mods/randomizer/src/session.hpp index a75befb0c1..acaac605fc 100644 --- a/mods/randomizer/src/session.hpp +++ b/mods/randomizer/src/session.hpp @@ -44,5 +44,4 @@ void shutdown(); void deactivateSeed(); void setupRandomizerFile(); void registerStageEdits(); -void registerStartingLocation(); }