summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFantaTanked <86494849+FantaTanked@users.noreply.github.com>2026-07-01 13:55:22 +0100
committerGitHub <noreply@github.com>2026-07-01 12:55:22 +0000
commit2418d51df56f54c7edc9969ab6d2b3edd11fcf40 (patch)
treea349f338ae95324a3177199e53386cf1a10a2d3a
parentd12c0d4ed7aba9486bc9ff1e47126bdb953bdc51 (diff)
Fix for actors / crawlspaces / doors not loading after loading a savestate (#6838)
Fixes an issue where actors do not load properly after creating a savestate and then going to either a new scene or loading a different area of the map (graveyard near shadow -> main section of graveyard dampes door is missing after loading again.)
-rw-r--r--soh/soh/Enhancements/savestates.cpp24
-rw-r--r--soh/soh/z_scene_otr.cpp6
2 files changed, 28 insertions, 2 deletions
diff --git a/soh/soh/Enhancements/savestates.cpp b/soh/soh/Enhancements/savestates.cpp
index 672de6658..acf4fcd63 100644
--- a/soh/soh/Enhancements/savestates.cpp
+++ b/soh/soh/Enhancements/savestates.cpp
@@ -323,6 +323,9 @@ typedef struct SaveStateInfo {
s16 sMessageHasSetSfx_copy;
u16 sOcarinaSongBitFlags_copy;
+ u8 transitionActorCount_copy;
+ s16 transitionActorIds_copy[256];
+
} SaveStateInfo;
class SaveState {
@@ -346,9 +349,10 @@ class SaveState {
void LoadOnePointDemoData(void);
void SaveOverlayStaticData(void);
void LoadOverlayStaticData(void);
-
void SaveMiscCodeData(void);
void LoadMiscCodeData(void);
+ void SaveTransitionActors(void);
+ void LoadTransitionActors(void);
SaveStateInfo* GetSaveStateInfo(void);
};
@@ -812,6 +816,20 @@ void SaveState::LoadMiscCodeData(void) {
sOcarinaSongBitFlags = info->sOcarinaSongBitFlags_copy;
}
+void SaveState::SaveTransitionActors(void) {
+ info->transitionActorCount_copy = gPlayState->transiActorCtx.numActors;
+ for (u32 i = 0; i < info->transitionActorCount_copy; i++) {
+ info->transitionActorIds_copy[i] = gPlayState->transiActorCtx.list[i].id;
+ }
+}
+
+void SaveState::LoadTransitionActors(void) {
+ u32 numActors = MIN(info->transitionActorCount_copy, gPlayState->transiActorCtx.numActors);
+ for (u32 i = 0; i < numActors; i++) {
+ gPlayState->transiActorCtx.list[i].id = info->transitionActorIds_copy[i];
+ }
+}
+
extern "C" void ProcessSaveStateRequests(void) {
OTRGlobals::Instance->gSaveStateMgr->ProcessSaveStateRequests();
}
@@ -918,6 +936,7 @@ void SaveState::Save(void) {
SaveOnePointDemoData();
SaveOverlayStaticData();
SaveMiscCodeData();
+ SaveTransitionActors();
}
void SaveState::Load(void) {
@@ -951,4 +970,5 @@ void SaveState::Load(void) {
LoadOnePointDemoData();
LoadOverlayStaticData();
LoadMiscCodeData();
-}
+ LoadTransitionActors();
+} \ No newline at end of file
diff --git a/soh/soh/z_scene_otr.cpp b/soh/soh/z_scene_otr.cpp
index b5a82e659..5b0132da2 100644
--- a/soh/soh/z_scene_otr.cpp
+++ b/soh/soh/z_scene_otr.cpp
@@ -202,6 +202,12 @@ bool Scene_CommandTransitionActorList(PlayState* play, SOH::ISceneCommand* cmd)
play->transiActorCtx.numActors = cmdActor->numTransitionActors;
play->transiActorCtx.list = (TransitionActorEntry*)cmdActor->GetRawPointer();
+ // Loops transition actors and sets them to default values (not spawned yet)
+ // used as fix for doors / crawlspaces not loading after they've already been loaded once.
+ for (s32 i = 0; i < play->transiActorCtx.numActors; i++) {
+ play->transiActorCtx.list[i].id = ABS(play->transiActorCtx.list[i].id);
+ }
+
return false;
}