diff options
| author | Jordan Longstaff <JordanLongstaff@users.noreply.github.com> | 2026-08-07 16:44:30 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-07 15:44:30 -0500 |
| commit | 546243636fc14448fb7260170afe56ad4c76a07b (patch) | |
| tree | 88082abe0c33aa9e59929bec7ec894b2d5269a1d | |
| parent | b8f855a975f2cc3be7a62a572f68c04a4a41ea54 (diff) | |
Time Moves When You Move: fix saving zero time speed (#1850)develop-keiichi
* Time Moves When You Move: fix saving zero time speed
* Fix oversight with Autosave
* OnSaveLoad hook repairs broken time speed
* Check text ID in choice condition
* Add Game Over save prompt as condition
* Guaranteed save file repair hook
| -rw-r--r-- | mm/2s2h/Enhancements/Modes/TimeMovesWhenYouMove.cpp | 48 | ||||
| -rw-r--r-- | mm/2s2h/Enhancements/Saving/AutoSave.cpp | 5 |
2 files changed, 41 insertions, 12 deletions
diff --git a/mm/2s2h/Enhancements/Modes/TimeMovesWhenYouMove.cpp b/mm/2s2h/Enhancements/Modes/TimeMovesWhenYouMove.cpp index 16291a263..aa98b0556 100644 --- a/mm/2s2h/Enhancements/Modes/TimeMovesWhenYouMove.cpp +++ b/mm/2s2h/Enhancements/Modes/TimeMovesWhenYouMove.cpp @@ -13,7 +13,33 @@ extern "C" { #define DEFAULT_TIME_OFFSET -12345 static s32 sStoredTimeOffset = DEFAULT_TIME_OFFSET; -void RegisterTimeMovesWhenYouMove() { +static void UpdateTimeSpeedOffset(PauseContext* pauseCtx) { + Player* player = GET_PLAYER(gPlayState); + + // Time is considered to be moving when any of the following is true: + // - The player is moving (since that's the basis of this enhancement) + // - The player is playing the Ocarina (so that Inverted SoT still works properly) + // - The player is choosing whether to save at an Owl Statue (so that it doesn't save the wrong time speed) + // - The pause menu save prompt is open (so that Pause Save doesn't either) + // - The Game Over save prompt is open (not reachable right now, but there for future-proofing) + bool timeShouldMove = + (player->stateFlags2 & PLAYER_STATE2_USING_OCARINA) || player->speedXZ != 0.0f || + (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CHOICE && gPlayState->msgCtx.currentTextId == 0xC01) || + pauseCtx->state == PAUSE_STATE_SAVEPROMPT || pauseCtx->state == PAUSE_STATE_GAMEOVER_SAVE_PROMPT; + + if (timeShouldMove && sStoredTimeOffset != DEFAULT_TIME_OFFSET) { + gSaveContext.save.timeSpeedOffset = sStoredTimeOffset; + sStoredTimeOffset = DEFAULT_TIME_OFFSET; + + // This is for the section above, lets arrows continue flying after they were fired with time frozen + // player->unk_D57 = 4; + } else if (!timeShouldMove && sStoredTimeOffset == DEFAULT_TIME_OFFSET) { + sStoredTimeOffset = gSaveContext.save.timeSpeedOffset; + gSaveContext.save.timeSpeedOffset = -R_TIME_SPEED; + } +} + +static void RegisterTimeMovesWhenYouMove() { if (!CVAR && sStoredTimeOffset != DEFAULT_TIME_OFFSET) { gSaveContext.save.timeSpeedOffset = sStoredTimeOffset; sStoredTimeOffset = DEFAULT_TIME_OFFSET; @@ -60,21 +86,19 @@ void RegisterTimeMovesWhenYouMove() { // } // }); - COND_ID_HOOK(OnActorUpdate, ACTOR_PLAYER, CVAR, [](Actor* actor) { - Player* player = GET_PLAYER(gPlayState); - bool timeShouldMove = (player->stateFlags2 & PLAYER_STATE2_USING_OCARINA) || player->speedXZ != 0.0f; + COND_ID_HOOK(OnActorUpdate, ACTOR_PLAYER, CVAR, [](Actor* actor) { UpdateTimeSpeedOffset(&gPlayState->pauseCtx); }); - if (timeShouldMove && sStoredTimeOffset != DEFAULT_TIME_OFFSET) { - gSaveContext.save.timeSpeedOffset = sStoredTimeOffset; - sStoredTimeOffset = DEFAULT_TIME_OFFSET; + COND_HOOK(OnKaleidoUpdate, CVAR, UpdateTimeSpeedOffset); +} - // This is for the section above, lets arrows continue flying after they were fired with time frozen - // player->unk_D57 = 4; - } else if (!timeShouldMove && sStoredTimeOffset == DEFAULT_TIME_OFFSET) { - sStoredTimeOffset = gSaveContext.save.timeSpeedOffset; - gSaveContext.save.timeSpeedOffset = -R_TIME_SPEED; +static void RegisterTimeSpeedOffsetRepair() { + COND_HOOK(OnSaveLoad, true, [](s16) { + sStoredTimeOffset = DEFAULT_TIME_OFFSET; + if (gSaveContext.save.timeSpeedOffset < -2) { + gSaveContext.save.timeSpeedOffset = 0; } }); } +static RegisterShipInitFunc initFunc_Repair(RegisterTimeSpeedOffsetRepair); static RegisterShipInitFunc initFunc(RegisterTimeMovesWhenYouMove, { CVAR_NAME }); diff --git a/mm/2s2h/Enhancements/Saving/AutoSave.cpp b/mm/2s2h/Enhancements/Saving/AutoSave.cpp index 1495069f5..69d424e8c 100644 --- a/mm/2s2h/Enhancements/Saving/AutoSave.cpp +++ b/mm/2s2h/Enhancements/Saving/AutoSave.cpp @@ -47,6 +47,11 @@ void HandleAutoSave() { return; } + // Time must be moving for autosave to work. Fixes an issue with Time Moves When You Move. + if (gSaveContext.save.timeSpeedOffset == -R_TIME_SPEED && R_TIME_SPEED != 0) { + return; + } + // If owl save available to create, do it and reset the interval. if (SavingEnhancements_CanSave() && gPlayState->pauseCtx.state == 0) { |
