diff --git a/Source/gamemenu.cpp b/Source/gamemenu.cpp index 4a515fd53..5fd82eecc 100644 --- a/Source/gamemenu.cpp +++ b/Source/gamemenu.cpp @@ -104,14 +104,14 @@ void GamemenuUpdateSingle() sgSingleMenu[0].setEnabled(enable); } -std::string_view GetSaveGameMenuLabel() -{ -#ifndef _DEBUG - return _("Save Game"); -#else - if (HasPendingAutoSave()) { - saveGameMenuLabel = fmt::format(fmt::runtime(_("Save Game ({:s})")), _("ready")); - return saveGameMenuLabel; +std::string_view GetSaveGameMenuLabel() +{ +#ifndef _DEBUG + return _("Save Game"); +#else + if (HasPendingAutoSave()) { + saveGameMenuLabel = fmt::format(fmt::runtime(_("Save Game ({:s})")), _("ready")); + return saveGameMenuLabel; } const int seconds = GetSecondsUntilNextAutoSave(); @@ -119,11 +119,11 @@ std::string_view GetSaveGameMenuLabel() saveGameMenuLabel = _("Save Game"); return saveGameMenuLabel; } - - saveGameMenuLabel = fmt::format(fmt::runtime(_("Save Game ({:d})")), seconds); - return saveGameMenuLabel; -#endif -} + + saveGameMenuLabel = fmt::format(fmt::runtime(_("Save Game ({:d})")), seconds); + return saveGameMenuLabel; +#endif +} void GamemenuPrevious(bool /*bActivate*/) { diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index a2b302c94..8b9b6d6d7 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -2926,26 +2926,26 @@ void SaveGameData(SaveWriter &saveWriter) SaveLevelSeeds(saveWriter); } -void SaveGame() -{ - gbValidSaveFile = true; - -#if defined(UNPACKED_SAVES) && defined(DVL_NO_FILESYSTEM) - pfile_write_hero(/*writeGameData=*/true); - sfile_write_stash(); -#else - const bool gameSaved = pfile_write_game_with_backup(); - if (!gameSaved) { - gbValidSaveFile = false; - return; - } - - if (!pfile_write_stash_with_backup()) { - gbValidSaveFile = false; - return; - } -#endif -} +void SaveGame() +{ + gbValidSaveFile = true; + +#if defined(UNPACKED_SAVES) && defined(DVL_NO_FILESYSTEM) + pfile_write_hero(/*writeGameData=*/true); + sfile_write_stash(); +#else + const bool gameSaved = pfile_write_game_with_backup(); + if (!gameSaved) { + gbValidSaveFile = false; + return; + } + + if (!pfile_write_stash_with_backup()) { + gbValidSaveFile = false; + return; + } +#endif +} void SaveLevel(SaveWriter &saveWriter) { diff --git a/Source/options.cpp b/Source/options.cpp index c47fff11f..5a8a91439 100644 --- a/Source/options.cpp +++ b/Source/options.cpp @@ -865,12 +865,12 @@ GameplayOptions::GameplayOptions() , autoRefillBelt("Auto Refill Belt", OptionEntryFlags::None, N_("Auto Refill Belt"), N_("Refill belt from inventory when belt item is consumed."), false) , disableCripplingShrines("Disable Crippling Shrines", OptionEntryFlags::None, N_("Disable Crippling Shrines"), N_("When enabled Cauldrons, Fascinating Shrines, Goat Shrines, Ornate Shrines, Sacred Shrines and Murphy's Shrines are not able to be clicked on and labeled as disabled."), false) , quickCast("Quick Cast", OptionEntryFlags::None, N_("Quick Cast"), N_("Spell hotkeys instantly cast the spell, rather than switching the readied spell."), false) - , autoSaveEnabled("Auto Save", OptionEntryFlags::CantChangeInMultiPlayer, N_("Auto Save"), N_("Autosave works only in single player and only at safe moments."), false) -#ifdef _DEBUG - , autoSaveIntervalSeconds("Auto Save Interval", OptionEntryFlags::CantChangeInMultiPlayer, N_("Autosave interval (seconds)"), N_("Time between periodic autosave attempts."), 120, { 30, 60, 90, 120, 180, 300, 600 }) -#else - , autoSaveIntervalSeconds("Auto Save Interval", OptionEntryFlags::CantChangeInMultiPlayer | OptionEntryFlags::Invisible, "", "", 120, { 30, 60, 90, 120, 180, 300, 600 }) -#endif + , autoSaveEnabled("Auto Save", OptionEntryFlags::CantChangeInMultiPlayer, N_("Auto Save"), N_("Autosave works only in single player and only at safe moments."), false) +#ifdef _DEBUG + , autoSaveIntervalSeconds("Auto Save Interval", OptionEntryFlags::CantChangeInMultiPlayer, N_("Autosave interval (seconds)"), N_("Time between periodic autosave attempts."), 120, { 30, 60, 90, 120, 180, 300, 600 }) +#else + , autoSaveIntervalSeconds("Auto Save Interval", OptionEntryFlags::CantChangeInMultiPlayer | OptionEntryFlags::Invisible, "", "", 120, { 30, 60, 90, 120, 180, 300, 600 }) +#endif , numHealPotionPickup("Heal Potion Pickup", OptionEntryFlags::None, N_("Heal Potion Pickup"), N_("Number of Healing potions to pick up automatically."), 0, { 0, 1, 2, 4, 8, 16 }) , numFullHealPotionPickup("Full Heal Potion Pickup", OptionEntryFlags::None, N_("Full Heal Potion Pickup"), N_("Number of Full Healing potions to pick up automatically."), 0, { 0, 1, 2, 4, 8, 16 }) , numManaPotionPickup("Mana Potion Pickup", OptionEntryFlags::None, N_("Mana Potion Pickup"), N_("Number of Mana potions to pick up automatically."), 0, { 0, 1, 2, 4, 8, 16 }) @@ -890,13 +890,13 @@ std::vector GameplayOptions::GetEntries() &randomizeQuests, &theoQuest, &cowQuest, - &runInTown, - &quickCast, - &autoSaveEnabled, -#ifdef _DEBUG - &autoSaveIntervalSeconds, -#endif - &testBard, + &runInTown, + &quickCast, + &autoSaveEnabled, +#ifdef _DEBUG + &autoSaveIntervalSeconds, +#endif + &testBard, &testBarbarian, &experienceBar, &showItemGraphicsInStores, diff --git a/Source/pfile.cpp b/Source/pfile.cpp index 251c70205..d2b0e9985 100644 --- a/Source/pfile.cpp +++ b/Source/pfile.cpp @@ -76,12 +76,12 @@ std::string GetSavePath(uint32_t saveNum, std::string_view savePrefix = {}) ); } -std::string GetStashSavePath(std::string_view savePrefix = {}) -{ - return StrCat(paths::PrefPath(), savePrefix, - gbIsSpawn ? "stash_spawn" : "stash", -#ifdef UNPACKED_SAVES - gbIsHellfire ? "_hsv" DIRECTORY_SEPARATOR_STR : "_sv" DIRECTORY_SEPARATOR_STR +std::string GetStashSavePath(std::string_view savePrefix = {}) +{ + return StrCat(paths::PrefPath(), savePrefix, + gbIsSpawn ? "stash_spawn" : "stash", +#ifdef UNPACKED_SAVES + gbIsHellfire ? "_hsv" DIRECTORY_SEPARATOR_STR : "_sv" DIRECTORY_SEPARATOR_STR #else gbIsHellfire ? ".hsv" : ".sv" #endif @@ -165,44 +165,44 @@ SaveWriter GetSaveWriter(uint32_t saveNum) return SaveWriter(GetSavePath(saveNum)); } -SaveWriter GetStashWriter() -{ - return SaveWriter(GetStashSavePath()); -} - -#if !(defined(UNPACKED_SAVES) && defined(DVL_NO_FILESYSTEM)) -void CopySaveLocation(const std::string &sourceLocation, const std::string &targetLocation) -{ -#if defined(UNPACKED_SAVES) - if (!targetLocation.empty()) { - CreateDir(targetLocation.c_str()); - } - for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(sourceLocation)) { - const std::filesystem::path targetFilePath = std::filesystem::path(targetLocation) / entry.path().filename(); - CopyFileOverwrite(entry.path().string().c_str(), targetFilePath.string().c_str()); - } -#else - CopyFileOverwrite(sourceLocation.c_str(), targetLocation.c_str()); -#endif -} - -void RestoreSaveLocation(const std::string &targetLocation, const std::string &backupLocation) -{ -#if defined(UNPACKED_SAVES) - if (DirectoryExists(targetLocation.c_str())) { - for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(targetLocation)) - RemoveFile(entry.path().string().c_str()); - } - CreateDir(targetLocation.c_str()); - for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(backupLocation)) { - const std::filesystem::path restoredFilePath = std::filesystem::path(targetLocation) / entry.path().filename(); - CopyFileOverwrite(entry.path().string().c_str(), restoredFilePath.string().c_str()); - } -#else - CopyFileOverwrite(backupLocation.c_str(), targetLocation.c_str()); -#endif -} -#endif +SaveWriter GetStashWriter() +{ + return SaveWriter(GetStashSavePath()); +} + +#if !(defined(UNPACKED_SAVES) && defined(DVL_NO_FILESYSTEM)) +void CopySaveLocation(const std::string &sourceLocation, const std::string &targetLocation) +{ +#if defined(UNPACKED_SAVES) + if (!targetLocation.empty()) { + CreateDir(targetLocation.c_str()); + } + for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(sourceLocation)) { + const std::filesystem::path targetFilePath = std::filesystem::path(targetLocation) / entry.path().filename(); + CopyFileOverwrite(entry.path().string().c_str(), targetFilePath.string().c_str()); + } +#else + CopyFileOverwrite(sourceLocation.c_str(), targetLocation.c_str()); +#endif +} + +void RestoreSaveLocation(const std::string &targetLocation, const std::string &backupLocation) +{ +#if defined(UNPACKED_SAVES) + if (DirectoryExists(targetLocation.c_str())) { + for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(targetLocation)) + RemoveFile(entry.path().string().c_str()); + } + CreateDir(targetLocation.c_str()); + for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(backupLocation)) { + const std::filesystem::path restoredFilePath = std::filesystem::path(targetLocation) / entry.path().filename(); + CopyFileOverwrite(entry.path().string().c_str(), restoredFilePath.string().c_str()); + } +#else + CopyFileOverwrite(backupLocation.c_str(), targetLocation.c_str()); +#endif +} +#endif void Game2UiPlayer(const Player &player, _uiheroinfo *heroinfo, bool bHasSaveFile) { @@ -637,73 +637,73 @@ const char *pfile_get_password() return gbIsMultiplayer ? PASSWORD_MULTI : PASSWORD_SINGLE; } -void pfile_write_hero(bool writeGameData) -{ - SaveWriter saveWriter = GetSaveWriter(gSaveNumber); - pfile_write_hero(saveWriter, writeGameData); -} - -#if !(defined(UNPACKED_SAVES) && defined(DVL_NO_FILESYSTEM)) -bool pfile_write_game_with_backup() -{ - const std::string backupPrefix = "backup_"; - const std::string backupLocation = GetSavePath(gSaveNumber, backupPrefix); - const std::string saveLocation = GetSavePath(gSaveNumber); - - if (FileExists(saveLocation) || DirectoryExists(saveLocation.c_str())) - CopySaveLocation(saveLocation, backupLocation); - - pfile_write_hero(/*writeGameData=*/true); - - auto archive = OpenSaveArchive(gSaveNumber); - const bool saveIsValid = archive && ArchiveContainsGame(*archive); - if (saveIsValid || !(FileExists(backupLocation) || DirectoryExists(backupLocation.c_str()))) - return saveIsValid; - - RestoreSaveLocation(saveLocation, backupLocation); - - return false; -} - -bool pfile_write_stash_with_backup() -{ - if (!Stash.dirty) - return true; - - const std::string backupPrefix = "backup_"; - const std::string backupLocation = GetStashSavePath(backupPrefix); - const std::string stashLocation = GetStashSavePath(); - - if (FileExists(stashLocation) || DirectoryExists(stashLocation.c_str())) - CopySaveLocation(stashLocation, backupLocation); - - SaveWriter stashWriter = GetStashWriter(); - SaveStash(stashWriter); - - auto archive = OpenStashArchive(); - const char *stashFileName = gbIsMultiplayer ? "mpstashitems" : "spstashitems"; - const bool stashIsValid = archive && ReadArchive(*archive, stashFileName) != nullptr; - if (stashIsValid || !(FileExists(backupLocation) || DirectoryExists(backupLocation.c_str()))) { - if (stashIsValid) - Stash.dirty = false; - return stashIsValid; - } - - RestoreSaveLocation(stashLocation, backupLocation); - - return false; -} -#endif - -#ifndef DISABLE_DEMOMODE -#if !(defined(UNPACKED_SAVES) && defined(DVL_NO_FILESYSTEM)) -void pfile_write_hero_demo(int demo) -{ - const std::string saveLocation = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_reference_")); - CopySaveLocation(GetSavePath(gSaveNumber), saveLocation); - auto saveWriter = SaveWriter(saveLocation.c_str()); - pfile_write_hero(saveWriter, true); -} +void pfile_write_hero(bool writeGameData) +{ + SaveWriter saveWriter = GetSaveWriter(gSaveNumber); + pfile_write_hero(saveWriter, writeGameData); +} + +#if !(defined(UNPACKED_SAVES) && defined(DVL_NO_FILESYSTEM)) +bool pfile_write_game_with_backup() +{ + const std::string backupPrefix = "backup_"; + const std::string backupLocation = GetSavePath(gSaveNumber, backupPrefix); + const std::string saveLocation = GetSavePath(gSaveNumber); + + if (FileExists(saveLocation) || DirectoryExists(saveLocation.c_str())) + CopySaveLocation(saveLocation, backupLocation); + + pfile_write_hero(/*writeGameData=*/true); + + auto archive = OpenSaveArchive(gSaveNumber); + const bool saveIsValid = archive && ArchiveContainsGame(*archive); + if (saveIsValid || !(FileExists(backupLocation) || DirectoryExists(backupLocation.c_str()))) + return saveIsValid; + + RestoreSaveLocation(saveLocation, backupLocation); + + return false; +} + +bool pfile_write_stash_with_backup() +{ + if (!Stash.dirty) + return true; + + const std::string backupPrefix = "backup_"; + const std::string backupLocation = GetStashSavePath(backupPrefix); + const std::string stashLocation = GetStashSavePath(); + + if (FileExists(stashLocation) || DirectoryExists(stashLocation.c_str())) + CopySaveLocation(stashLocation, backupLocation); + + SaveWriter stashWriter = GetStashWriter(); + SaveStash(stashWriter); + + auto archive = OpenStashArchive(); + const char *stashFileName = gbIsMultiplayer ? "mpstashitems" : "spstashitems"; + const bool stashIsValid = archive && ReadArchive(*archive, stashFileName) != nullptr; + if (stashIsValid || !(FileExists(backupLocation) || DirectoryExists(backupLocation.c_str()))) { + if (stashIsValid) + Stash.dirty = false; + return stashIsValid; + } + + RestoreSaveLocation(stashLocation, backupLocation); + + return false; +} +#endif + +#ifndef DISABLE_DEMOMODE +#if !(defined(UNPACKED_SAVES) && defined(DVL_NO_FILESYSTEM)) +void pfile_write_hero_demo(int demo) +{ + const std::string saveLocation = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_reference_")); + CopySaveLocation(GetSavePath(gSaveNumber), saveLocation); + auto saveWriter = SaveWriter(saveLocation.c_str()); + pfile_write_hero(saveWriter, true); +} HeroCompareResult pfile_compare_hero_demo(int demo, bool logDetails) { @@ -712,33 +712,33 @@ HeroCompareResult pfile_compare_hero_demo(int demo, bool logDetails) if (!FileExists(referenceSavePath.c_str())) return { HeroCompareResult::ReferenceNotFound, {} }; - const std::string actualSavePath = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_actual_")); - { - CopySaveLocation(GetSavePath(gSaveNumber), actualSavePath); - SaveWriter saveWriter(actualSavePath.c_str()); - pfile_write_hero(saveWriter, true); - } - - return CompareSaves(actualSavePath, referenceSavePath, logDetails); -} -#else -// Demo save comparison is unavailable on UNPACKED_SAVES targets without filesystem support. -void pfile_write_hero_demo(int demo) -{ - (void)demo; -} - -HeroCompareResult pfile_compare_hero_demo(int demo, bool logDetails) -{ - (void)demo; - (void)logDetails; - return { HeroCompareResult::ReferenceNotFound, {} }; -} -#endif -#endif - -void sfile_write_stash() -{ + const std::string actualSavePath = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_actual_")); + { + CopySaveLocation(GetSavePath(gSaveNumber), actualSavePath); + SaveWriter saveWriter(actualSavePath.c_str()); + pfile_write_hero(saveWriter, true); + } + + return CompareSaves(actualSavePath, referenceSavePath, logDetails); +} +#else +// Demo save comparison is unavailable on UNPACKED_SAVES targets without filesystem support. +void pfile_write_hero_demo(int demo) +{ + (void)demo; +} + +HeroCompareResult pfile_compare_hero_demo(int demo, bool logDetails) +{ + (void)demo; + (void)logDetails; + return { HeroCompareResult::ReferenceNotFound, {} }; +} +#endif +#endif + +void sfile_write_stash() +{ if (!Stash.dirty) return; diff --git a/Source/pfile.h b/Source/pfile.h index 9375c979e..6960cd857 100644 --- a/Source/pfile.h +++ b/Source/pfile.h @@ -100,9 +100,9 @@ std::optional OpenSaveArchive(uint32_t saveNum); std::optional OpenStashArchive(); const char *pfile_get_password(); std::unique_ptr ReadArchive(SaveReader &archive, const char *pszName, size_t *pdwLen = nullptr); -void pfile_write_hero(bool writeGameData = false); -bool pfile_write_game_with_backup(); -bool pfile_write_stash_with_backup(); +void pfile_write_hero(bool writeGameData = false); +bool pfile_write_game_with_backup(); +bool pfile_write_stash_with_backup(); #ifndef DISABLE_DEMOMODE /** @@ -119,7 +119,7 @@ void pfile_write_hero_demo(int demo); HeroCompareResult pfile_compare_hero_demo(int demo, bool logDetails); #endif -void sfile_write_stash(); +void sfile_write_stash(); bool pfile_ui_set_hero_infos(bool (*uiAddHeroInfo)(_uiheroinfo *)); void pfile_ui_set_class_stats(HeroClass playerClass, _uidefaultstats *classStats); uint32_t pfile_ui_get_first_unused_save_num(); diff --git a/Source/player.cpp b/Source/player.cpp index 019c9a147..ba21a1fc9 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -1531,7 +1531,7 @@ uint16_t GetPlayerSpriteWidth(HeroClass cls, player_graphic graphic, PlayerWeapo return spriteData.bow; return spriteData.attack; case player_graphic::Hit: - return spriteData.swHit; + return spriteData.swHit; case player_graphic::Block: return spriteData.block; case player_graphic::Lightning: