diff options
| author | Garrett Cox <garrettjcox@gmail.com> | 2024-05-30 22:20:29 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-30 23:20:29 -0400 |
| commit | 464c55fcbb5191694b5f9b402c1a2bc74e85192c (patch) | |
| tree | b3061e69b35cf7e097fc49adedc95286de260a28 | |
| parent | 8ac7dc6b7d65a363b450d6799e9f135537a88303 (diff) | |
Tweaks to autosaves and pause saves to always persist them, along with preventing saves when it's too early or late in the game (#616)
| -rw-r--r-- | mm/2s2h/BenGui/BenMenuBar.cpp | 12 | ||||
| -rw-r--r-- | mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp | 50 | ||||
| -rw-r--r-- | mm/2s2h/Enhancements/Saving/SavingEnhancements.h | 11 | ||||
| -rw-r--r-- | mm/include/functions.h | 4 | ||||
| -rw-r--r-- | mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c | 9 |
5 files changed, 65 insertions, 21 deletions
diff --git a/mm/2s2h/BenGui/BenMenuBar.cpp b/mm/2s2h/BenGui/BenMenuBar.cpp index d5a2efc96..036a5c778 100644 --- a/mm/2s2h/BenGui/BenMenuBar.cpp +++ b/mm/2s2h/BenGui/BenMenuBar.cpp @@ -437,14 +437,14 @@ void DrawEnhancementsMenu() { UIWidgets::CVarCheckbox( "Pause Menu Save", "gEnhancements.Saving.PauseSave", { .tooltip = "Re-introduce the pause menu save system. Pressing B in the pause menu will give you the " - "option to create an Owl Save from your current location.\n\nWhen loading back into the " - "game, you will be placed either at the entrance of the dungeon you saved in, or in South " - "Clock Town." }); + "option to create a persistent Owl Save from your current location.\n\nWhen loading back " + "into the game, you will be placed either at the entrance of the dungeon you saved in, or " + "in South Clock Town." }); if (UIWidgets::CVarCheckbox( "Autosave", "gEnhancements.Saving.Autosave", - { .tooltip = "Automatically create owl saves on the chosen interval.\n\nWhen loading back into the " - "game, you will be placed either at the entrance of the dungeon you saved in, or in " - "South Clock Town." })) { + { .tooltip = "Automatically create a persistent Owl Save on the chosen interval.\n\nWhen loading " + "back into the game, you will be placed either at the entrance of the dungeon you " + "saved in, or in South Clock Town." })) { RegisterAutosave(); } UIWidgets::CVarSliderInt("Autosave Interval (minutes): %d", "gEnhancements.Saving.AutosaveInterval", 1, 60, diff --git a/mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp b/mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp index ed8171cc9..d0e6d32b8 100644 --- a/mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp +++ b/mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp @@ -16,8 +16,8 @@ static uint32_t autosaveGameStateUpdateHookId = 0; static uint32_t autosaveGameStateDrawFinishHookId = 0; // Used for saving through Autosaves and Pause Menu saves. -extern "C" int32_t GetSaveEntrance(PlayState* play) { - switch (play->sceneId) { +extern "C" int SavingEnhancements_GetSaveEntrance() { + switch (gPlayState->sceneId) { // Woodfall Temple + Odolwa case SCENE_MITURIN: case SCENE_MITURIN_BS: @@ -40,6 +40,43 @@ extern "C" int32_t GetSaveEntrance(PlayState* play) { } } +extern "C" bool SavingEnhancements_CanSave() { + // Game State + if (gPlayState == NULL || GET_PLAYER(gPlayState) == NULL) { + return false; + } + + // Owl saving available + if (!gSaveContext.flashSaveAvailable || gSaveContext.fileNum == 255) { + return false; + } + + // Not in a blocking cutscene + if (Player_InBlockingCsMode(gPlayState, GET_PLAYER(gPlayState))) { + return false; + } + + // Not in the middle of dialog + if (gPlayState->msgCtx.msgMode != 0) { + return false; + } + + // Hasn't gotten to clock town yet + if (gPlayState->sceneId == SCENE_SPOT00 || gPlayState->sceneId == SCENE_LOST_WOODS || + gPlayState->sceneId == SCENE_OPENINGDAN) { + return false; + } + + // Can't save once you've gone to the moon + if (gPlayState->sceneId == SCENE_SOUGEN || gPlayState->sceneId == SCENE_LAST_LINK || + gPlayState->sceneId == SCENE_LAST_DEKU || gPlayState->sceneId == SCENE_LAST_GORON || + gPlayState->sceneId == SCENE_LAST_ZORA || gPlayState->sceneId == SCENE_LAST_BS) { + return false; + } + + return true; +} + void DeleteOwlSave() { // Remove Owl Save on time cycle reset, needed when persisting owl saves and/or when // creating owl saves without the player being send back to the file select screen. @@ -82,9 +119,7 @@ void HandleAutoSave() { } // If owl save available to create, do it and reset the interval. - if (gSaveContext.flashSaveAvailable && gSaveContext.fileNum != 255 && - !Player_InBlockingCsMode(gPlayState, player) && gPlayState->pauseCtx.state == 0 && - gPlayState->msgCtx.msgMode == 0) { + if (SavingEnhancements_CanSave() && gPlayState->pauseCtx.state == 0) { // Reset timestamp, set icon timer to show autosave icon for 5 seconds (100 frames) lastSaveTimestamp = GetUnixTimestamp(); @@ -92,7 +127,7 @@ void HandleAutoSave() { // Create owl save gSaveContext.save.isOwlSave = true; - gSaveContext.save.shipSaveInfo.pauseSaveEntrance = GetSaveEntrance(gPlayState); + gSaveContext.save.shipSaveInfo.pauseSaveEntrance = SavingEnhancements_GetSaveEntrance(); Play_SaveCycleSceneFlags(&gPlayState->state); gSaveContext.save.saveInfo.playerData.savedSceneId = gPlayState->sceneId; func_8014546C(&gPlayState->sramCtx); @@ -106,7 +141,8 @@ void HandleAutoSave() { void RegisterSavingEnhancements() { REGISTER_VB_SHOULD(GI_VB_DELETE_OWL_SAVE, { - if (CVarGetInteger("gEnhancements.Saving.PersistentOwlSaves", 0)) { + if (CVarGetInteger("gEnhancements.Saving.PersistentOwlSaves", 0) || + gSaveContext.save.shipSaveInfo.pauseSaveEntrance != -1) { *should = false; } }); diff --git a/mm/2s2h/Enhancements/Saving/SavingEnhancements.h b/mm/2s2h/Enhancements/Saving/SavingEnhancements.h index 327817c1d..71018fe64 100644 --- a/mm/2s2h/Enhancements/Saving/SavingEnhancements.h +++ b/mm/2s2h/Enhancements/Saving/SavingEnhancements.h @@ -4,4 +4,15 @@ void RegisterSavingEnhancements(); void RegisterAutosave(); +#ifdef __cplusplus +extern "C" { +#endif + +int SavingEnhancements_GetSaveEntrance(); +bool SavingEnhancements_CanSave(); + +#ifdef __cplusplus +} +#endif + #endif // SAVING_ENHANCEMENTS_H diff --git a/mm/include/functions.h b/mm/include/functions.h index ea5806f21..62ac3cb60 100644 --- a/mm/include/functions.h +++ b/mm/include/functions.h @@ -1365,10 +1365,6 @@ void osSpTaskYield(void); void osViSetXScale(f32 value); void osViSetYScale(f32 value); // #endregion -// #region 2S2H [Enhancements] -// [Autosaves & Pause Menu Saves] -int32_t GetSaveEntrance(PlayState* play); -// #endregion void Regs_InitData(PlayState* play); diff --git a/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c b/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c index 172e06919..071f4d208 100644 --- a/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c +++ b/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c @@ -18,6 +18,7 @@ #include "archives/item_name_static/item_name_static.h" #include "archives/map_name_static/map_name_static.h" #include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" +#include "2s2h/Enhancements/Saving/SavingEnhancements.h" #include "2s2h_assets.h" @@ -3377,7 +3378,7 @@ void KaleidoScope_Update(PlayState* play) { if (!pauseCtx->itemDescriptionOn && (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_B))) { Interface_SetAButtonDoAction(play, DO_ACTION_NONE); - if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0)) { + if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0) && SavingEnhancements_CanSave()) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) { pauseCtx->state = PAUSE_STATE_SAVEPROMPT; Audio_PlaySfx_MessageDecide(); @@ -3418,7 +3419,7 @@ void KaleidoScope_Update(PlayState* play) { // Abort having the player play the song and close the pause menu AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); Interface_SetAButtonDoAction(play, DO_ACTION_NONE); - if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0)) { + if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0) && SavingEnhancements_CanSave()) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) { pauseCtx->state = PAUSE_STATE_SAVEPROMPT; Audio_PlaySfx_MessageDecide(); @@ -3461,7 +3462,7 @@ void KaleidoScope_Update(PlayState* play) { if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_B)) { AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); Interface_SetAButtonDoAction(play, DO_ACTION_NONE); - if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0)) { + if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0) && SavingEnhancements_CanSave()) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) { pauseCtx->state = PAUSE_STATE_SAVEPROMPT; Audio_PlaySfx_MessageDecide(); @@ -3518,7 +3519,7 @@ void KaleidoScope_Update(PlayState* play) { // 2S2H [Enhancement] Eventually we might allow them to load from their last entrance, // but we need to first identify and fix edge cases where that doesn't work properly // like grottos and cutscenes - gSaveContext.save.shipSaveInfo.pauseSaveEntrance = GetSaveEntrance(play); + gSaveContext.save.shipSaveInfo.pauseSaveEntrance = SavingEnhancements_GetSaveEntrance(); } Play_SaveCycleSceneFlags(&play->state); gSaveContext.save.saveInfo.playerData.savedSceneId = play->sceneId; |
