From c23457d666e3ced250e535e4c9a014d7cf63bbd0 Mon Sep 17 00:00:00 2001 From: Josh Bodner <30329717+jbodner09@users.noreply.github.com> Date: Thu, 4 Aug 2022 21:15:49 -0700 Subject: [PATCH] Automatically save after every scene transition (#984) * Automatically save after every scene transition * Refactor and don't save in grottos * Don't save in cutscenes * Save after getting items as well * Fix paren --- libultraship/libultraship/ImGuiImpl.cpp | 6 +++ soh/include/functions.h | 1 + soh/src/code/z_parameter.c | 46 +++++++++++++++++++ soh/src/code/z_play.c | 21 +++++++++ .../ovl_kaleido_scope/z_kaleido_scope_PAL.c | 14 +----- 5 files changed, 75 insertions(+), 13 deletions(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index 583d36f01..a33e75be6 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -1267,6 +1267,12 @@ namespace SohImGui { ImGui::EndMenu(); } + EnhancementCheckbox("Autosave", "gAutosave"); + Tooltip("Automatically save the game every time a new area is entered or item is obtained\n" + "To disable saving when obtaining an item, manually set gAutosaveAllItems and gAutosaveMajorItems to 0\n" + "gAutosaveAllItems takes priority over gAutosaveMajorItems if both are set to 1\n" + "gAutosaveMajorItems excludes rupees and health/magic/ammo refills (but includes bombchus)"); + EXPERIMENTAL(); const char* fps_cvar = "gInterpolationFPS"; diff --git a/soh/include/functions.h b/soh/include/functions.h index b185519f4..eb53be6fd 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -1528,6 +1528,7 @@ s32 func_800C0CB8(GlobalContext* globalCtx); s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx); s32 func_800C0D34(GlobalContext* globalCtx, Actor* actor, s16* yaw); s32 func_800C0DB4(GlobalContext* globalCtx, Vec3f* pos); +void Gameplay_PerformSave(GlobalContext* globalCtx); void PreRender_SetValuesSave(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf, void* cvg); void PreRender_Init(PreRender* this); void PreRender_SetValues(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 364e63956..24211c590 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2188,6 +2188,52 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp); INV_CONTENT(item) = item; + // Autosave after getting items by default (cvars are not shown in the UI) + if (CVar_GetS32("gAutosave", 0)) { + if (CVar_GetS32("gAutosaveAllItems", 1)) { + Gameplay_PerformSave(globalCtx); + } + else if (CVar_GetS32("gAutosaveMajorItems", 1)) { + switch (item) { + case ITEM_STICK: + case ITEM_NUT: + case ITEM_BOMB: + case ITEM_BOW: + case ITEM_SEEDS: + case ITEM_FISHING_POLE: + case ITEM_MAGIC_SMALL: + case ITEM_MAGIC_LARGE: + case ITEM_INVALID_4: + case ITEM_INVALID_5: + case ITEM_INVALID_6: + case ITEM_INVALID_7: + case ITEM_HEART: + case ITEM_RUPEE_GREEN: + case ITEM_RUPEE_BLUE: + case ITEM_RUPEE_RED: + case ITEM_RUPEE_PURPLE: + case ITEM_RUPEE_GOLD: + case ITEM_INVALID_8: + case ITEM_STICKS_5: + case ITEM_STICKS_10: + case ITEM_NUTS_5: + case ITEM_NUTS_10: + case ITEM_BOMBS_5: + case ITEM_BOMBS_10: + case ITEM_BOMBS_20: + case ITEM_BOMBS_30: + case ITEM_ARROWS_SMALL: + case ITEM_ARROWS_MEDIUM: + case ITEM_ARROWS_LARGE: + case ITEM_SEEDS_30: + break; + default: + Gameplay_PerformSave(globalCtx); + break; + } + } + } + return temp; } diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 8974495fb..5c3b97da6 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -698,6 +698,11 @@ void Gameplay_Update(GlobalContext* globalCtx) { gTrnsnUnkState = 0; R_UPDATE_RATE = 3; } + + // Don't autosave in grottos or cutscenes + if (CVar_GetS32("gAutosave", 0) && (globalCtx->sceneNum != SCENE_YOUSEI_IZUMI_TATE) && (globalCtx->sceneNum != SCENE_KAKUSIANA) && (gSaveContext.cutsceneIndex == 0)) { + Gameplay_PerformSave(globalCtx); + } } globalCtx->sceneLoadFlag = 0; } else { @@ -1972,3 +1977,19 @@ s32 func_800C0DB4(GlobalContext* globalCtx, Vec3f* pos) { return false; } } + +void Gameplay_PerformSave(GlobalContext* globalCtx) { + Gameplay_SaveSceneFlags(globalCtx); + gSaveContext.savedSceneNum = globalCtx->sceneNum; + if (gSaveContext.temporaryWeapon) { + gSaveContext.equips.buttonItems[0] = ITEM_NONE; + GET_PLAYER(globalCtx)->currentSwordItem = ITEM_NONE; + Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE); + Save_SaveFile(); + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; + GET_PLAYER(globalCtx)->currentSwordItem = ITEM_SWORD_KOKIRI; + Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI); + } else { + Save_SaveFile(); + } +} diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 6e88d975d..e3e093129 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -3844,19 +3844,7 @@ void KaleidoScope_Update(GlobalContext* globalCtx) } else { Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - Gameplay_SaveSceneFlags(globalCtx); - gSaveContext.savedSceneNum = globalCtx->sceneNum; - if (gSaveContext.temporaryWeapon) { - gSaveContext.equips.buttonItems[0] = ITEM_NONE; - player->currentSwordItem = ITEM_NONE; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE); - Save_SaveFile(); - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; - player->currentSwordItem = ITEM_SWORD_KOKIRI; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI); - } else { - Save_SaveFile(); - } + Gameplay_PerformSave(globalCtx); pauseCtx->unk_1EC = 4; D_8082B25C = 3; }