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
This commit is contained in:
Josh Bodner 2022-08-04 21:15:49 -07:00 committed by GitHub
parent 2f5f089e7f
commit c23457d666
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 13 deletions

View File

@ -1267,6 +1267,12 @@ namespace SohImGui {
ImGui::EndMenu(); 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(); EXPERIMENTAL();
const char* fps_cvar = "gInterpolationFPS"; const char* fps_cvar = "gInterpolationFPS";

View File

@ -1528,6 +1528,7 @@ s32 func_800C0CB8(GlobalContext* globalCtx);
s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx); s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx);
s32 func_800C0D34(GlobalContext* globalCtx, Actor* actor, s16* yaw); s32 func_800C0D34(GlobalContext* globalCtx, Actor* actor, s16* yaw);
s32 func_800C0DB4(GlobalContext* globalCtx, Vec3f* pos); 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_SetValuesSave(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf, void* cvg);
void PreRender_Init(PreRender* this); void PreRender_Init(PreRender* this);
void PreRender_SetValues(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf); void PreRender_SetValues(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf);

View File

@ -2188,6 +2188,52 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp); osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp);
INV_CONTENT(item) = item; 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; return temp;
} }

View File

@ -698,6 +698,11 @@ void Gameplay_Update(GlobalContext* globalCtx) {
gTrnsnUnkState = 0; gTrnsnUnkState = 0;
R_UPDATE_RATE = 3; 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; globalCtx->sceneLoadFlag = 0;
} else { } else {
@ -1972,3 +1977,19 @@ s32 func_800C0DB4(GlobalContext* globalCtx, Vec3f* pos) {
return false; 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();
}
}

View File

@ -3844,19 +3844,7 @@ void KaleidoScope_Update(GlobalContext* globalCtx)
} else { } else {
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0,
&D_801333E8); &D_801333E8);
Gameplay_SaveSceneFlags(globalCtx); Gameplay_PerformSave(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();
}
pauseCtx->unk_1EC = 4; pauseCtx->unk_1EC = 4;
D_8082B25C = 3; D_8082B25C = 3;
} }