don't respawn at randomized starting entrance on loading an existing file

This commit is contained in:
gymnast86
2026-09-01 04:58:57 -07:00
parent 4bdb8dd57f
commit 9203935273
5 changed files with 39 additions and 58 deletions
+15 -12
View File
@@ -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<char const*>(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<int*>(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<dSv_player_item_c__setLineUpItem>(svc_hook);
mods::hook::uninstall<dSv_info_c__onSwitch>(svc_hook);
mods::hook::uninstall<dScnName_c__changeGameScene>();
mods::hook::uninstall<setNextStage>();
mods::hook::uninstall<ObjGb_Create>(svc_hook);
@@ -3494,8 +3499,6 @@ ModResult uninstall() {
mods::hook::uninstall<daE_MD_c__create>(svc_hook);
mods::hook::uninstall<dScnName_c__changeGameScene>();
mods::hook::uninstall<daNpc_zrZ_c__isDelete>(svc_hook);
mods::hook::uninstall<daTbox2_c__Create>(svc_hook);
@@ -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<u8>(getStageID(stageName)), .roomNo = roomNo, .mapLayer = mapLayer, .pointNo = static_cast<s16>(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;
}
@@ -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
*/
-45
View File
@@ -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())
-1
View File
@@ -44,5 +44,4 @@ void shutdown();
void deactivateSeed();
void setupRandomizerFile();
void registerStageEdits();
void registerStartingLocation();
}