From f481b863864df24394011bd66e14ecad9c2eb9d9 Mon Sep 17 00:00:00 2001 From: Josh Bodner <30329717+jbodner09@users.noreply.github.com> Date: Mon, 27 Feb 2023 21:07:47 -0800 Subject: [PATCH] Change autosave to use dropdown (#2550) --- soh/soh/Enhancements/mods.cpp | 14 +++++++++++--- soh/soh/GameMenuBar.cpp | 23 +++++++++++++++++------ soh/src/code/z_play.c | 8 +++++--- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 98150fa3f..e0f2ff71e 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -11,10 +11,18 @@ extern void Play_PerformSave(PlayState* play); void RegisterAutoSaveOnReceiveItemHook() { GameInteractor::Instance->RegisterGameHook([](u8 item) { - if (CVarGetInteger("gAutosave", 0) && (gPlayState != NULL) && (gPlayState->sceneNum != SCENE_KENJYANOMA) && (gSaveContext.pendingSale == ITEM_NONE) && (gPlayState->sceneNum != SCENE_GANON_DEMO)) { - if (CVarGetInteger("gAutosaveAllItems", 0)) { + + // Don't autosave immediately after buying items from shops to prevent getting them for free! + // Don't autosave in the Chamber of Sages since resuming from that map breaks the game + // Don't autosave during the Ganon fight when picking up the Master Sword + if ((CVarGetInteger("gAutosave", 0) > 0) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) && + (gPlayState->sceneNum != SCENE_KENJYANOMA) && (gPlayState->sceneNum != SCENE_GANON_DEMO)) { + if ((CVarGetInteger("gAutosave", 0) == 2) || (CVarGetInteger("gAutosave", 0) == 5)) { + // Autosave for all items Play_PerformSave(gPlayState); - } else if (CVarGetInteger("gAutosaveMajorItems", 1)) { + + } else if ((CVarGetInteger("gAutosave", 0) == 1) || (CVarGetInteger("gAutosave", 0) == 4)) { + // Autosave for major items switch (item) { case ITEM_STICK: case ITEM_NUT: diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index c0540ed79..89991d4e6 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -814,12 +814,23 @@ namespace GameMenuBar { ImGui::EndMenu(); } - UIWidgets::PaddedEnhancementCheckbox("Autosave", "gAutosave", true, false); - UIWidgets::Tooltip("Automatically save the game every time a new area is entered or item is obtained\n" - "To disable saving when obtaining a major item, manually set gAutosaveMajorItems to 0\n" - "To enable saving when obtaining any item, manually set gAutosaveAllItems to 1\n" - "gAutosaveAllItems takes priority over gAutosaveMajorItems if both are set to 1\n" - "gAutosaveMajorItems excludes rupees and health/magic/ammo refills (but includes bombchus)"); + UIWidgets::PaddedSeparator(false, true); + + // Autosave enum value of 1 is the default in presets and the old checkbox "on" state for backwards compatibility + const uint16_t selectedAutosaveId = CVarGetInteger("gAutosave", 0); + std::string autosaveLabels[] = { "Off", "New Location + Major Item", "New Location + Any Item", "New Location", "Major Item", "Any Item" }; + UIWidgets::PaddedText("Autosave", false, true); + if (ImGui::BeginCombo("##AutosaveComboBox", autosaveLabels[selectedAutosaveId].c_str())) { + for (int index = 0; index < sizeof(autosaveLabels) / sizeof(autosaveLabels[0]); index++) { + if (ImGui::Selectable(autosaveLabels[index].c_str(), index == selectedAutosaveId)) { + CVarSetInteger("gAutosave", index); + } + } + + ImGui::EndCombo(); + } + UIWidgets::Tooltip("Automatically save the game every time a new area is entered and/or item is obtained\n" + "Major items exclude rupees and health/magic/ammo refills (but include bombchus unless bombchu drops are enabled)"); UIWidgets::Spacer(0); diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index bc5b4a42a..71e5984e0 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -870,9 +870,11 @@ void Play_Update(PlayState* play) { R_UPDATE_RATE = 3; } - // Don't autosave in grottos or cutscenes - // Also don't save when you first load a file - if (CVarGetInteger("gAutosave", 0) && (gSaveContext.cutsceneIndex == 0) && (play->gameplayFrames > 60) && + // Autosave on area transition unless you're in a cutscene or a grotto since resuming from grottos breaks the game + // Also don't save when you first load a file to prevent consumables like magic from being lost + // Also don't save if there's a pending shop sale to prevent getting the item for a discount! + if ((CVarGetInteger("gAutosave", 0) >= 1) && (CVarGetInteger("gAutosave", 0) <= 3) && + (gSaveContext.cutsceneIndex == 0) && (play->gameplayFrames > 60) && (gSaveContext.pendingSale == ITEM_NONE) && (play->sceneNum != SCENE_YOUSEI_IZUMI_TATE) && (play->sceneNum != SCENE_KAKUSIANA) && (play->sceneNum != SCENE_KENJYANOMA)) { Play_PerformSave(play); }