From 97e4429591001433ffa2a1a6cdf8f295a233ec78 Mon Sep 17 00:00:00 2001 From: KJeff01 Date: Mon, 28 Aug 2023 13:41:27 -0500 Subject: [PATCH] Add a save realism mode No manual saving while in-game through scripts, quicksaves, or even autosaves. One save is created after each mission loads for the first time. If there are multiple video series queued up they only play 1 tick later at a time. So lets delay the autosave by 1 second. --- src/cheat.cpp | 5 +++++ src/configuration.cpp | 2 ++ src/frontend.cpp | 34 ++++++++++++++++++++++++++++++++++ src/frontend.h | 2 ++ src/ingameop.cpp | 9 ++++++--- src/keybind.cpp | 14 ++++++++++++-- src/loadsave.cpp | 11 ++++++++--- src/loadsave.h | 2 +- src/main.cpp | 9 +++++++++ src/warzoneconfig.cpp | 12 ++++++++++++ src/warzoneconfig.h | 2 ++ 11 files changed, 93 insertions(+), 9 deletions(-) diff --git a/src/cheat.cpp b/src/cheat.cpp index 207e6c69e07..ec2bd4042f2 100644 --- a/src/cheat.cpp +++ b/src/cheat.cpp @@ -36,6 +36,7 @@ #include "qtscript.h" #include "template.h" #include "activity.h" +#include "warzoneconfig.h" struct CHEAT_ENTRY { @@ -183,6 +184,10 @@ void sendProcessDebugMappings(bool val) { return; } + if (war_getSaveRealism()) + { + return; + } NETbeginEncode(NETgameQueue(selectedPlayer), GAME_DEBUG_MODE); NETbool(&val); NETend(); diff --git a/src/configuration.cpp b/src/configuration.cpp index 8955a289004..9bdb63c5e5a 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -618,6 +618,7 @@ bool loadConfig() war_setPointLightPerPixelLighting(value.value_or(false)); } + war_setSaveRealism(iniGetBool("saveRealism", war_getSaveRealism()).value()); ActivityManager::instance().endLoadingSettings(); return true; } @@ -779,6 +780,7 @@ bool saveConfig() iniSetInteger("shadowFilterSize", (int)war_getShadowFilterSize()); iniSetInteger("shadowMapResolution", (int)war_getShadowMapResolution()); iniSetBool("pointLightsPerpixel", war_getPointLightPerPixelLighting()); + iniSetBool("saveRealism", war_getSaveRealism()); iniSetInteger("configVersion", CURRCONFVERSION); // write out ini file changes diff --git a/src/frontend.cpp b/src/frontend.cpp index eb90250426a..bb26fd24233 100644 --- a/src/frontend.cpp +++ b/src/frontend.cpp @@ -2641,6 +2641,11 @@ static std::string gameOptionsCameraSpeedString() return cameraSpeed; } +char const *gameOptionsSaveRealism() +{ + return war_getSaveRealism() ? _("On") : _("Off"); +} + // //////////////////////////////////////////////////////////////////////////// // Game Options Menu @@ -2861,6 +2866,7 @@ static std::shared_ptr makeLanguageDropdown() widgSetString(psWScreen, FRONTEND_COLOUR_CAM, _("Campaign")); widgSetString(psWScreen, FRONTEND_COLOUR_MP, _("Skirmish/Multiplayer")); widgSetString(psWScreen, FRONTEND_DIFFICULTY, _("Campaign Difficulty")); + widgSetString(psWScreen, FRONTEND_SAVEREALISM, _("Save Realism")); widgSetString(psWScreen, FRONTEND_CAMERASPEED, _("Camera Speed")); widgSetString(psWScreen, FRONTEND_DIFFICULTY_R, gameOptionsDifficultyString()); @@ -2920,6 +2926,12 @@ void startGameOptionsMenu() makeTextButton(FRONTEND_DIFFICULTY_R, gameOptionsDifficultyString(), WBUT_SECONDARY, MINIMUM_GAME_OPTIONS_RIGHT_BUTTON_WIDTH) ); + // Save Realism + gridBuilder.addRow( + makeTextButton(FRONTEND_SAVEREALISM, _("Save Realism"), WBUT_SECONDARY, MINIMUM_GAME_OPTIONS_BUTTON_WIDTH), + makeTextButton(FRONTEND_SAVEREALISM_R, gameOptionsSaveRealism(), WBUT_SECONDARY, MINIMUM_GAME_OPTIONS_RIGHT_BUTTON_WIDTH) + ); + // Camera speed gridBuilder.addRow( makeTextButton(FRONTEND_CAMERASPEED, _("Camera Speed"), WBUT_SECONDARY, MINIMUM_GAME_OPTIONS_BUTTON_WIDTH), @@ -3044,6 +3056,28 @@ bool runGameOptionsMenu() widgSetString(psWScreen, FRONTEND_CAMERASPEED_R, gameOptionsCameraSpeedString().c_str()); break; + case FRONTEND_SAVEREALISM: + case FRONTEND_SAVEREALISM_R: + war_setSaveRealism(!war_getSaveRealism()); + widgSetString(psWScreen, FRONTEND_SAVEREALISM_R, gameOptionsSaveRealism()); + if (war_getSaveRealism()) + { + const std::string REAL_TAG = "Realism"; + + if (!hasNotificationsWithTag(REAL_TAG)) + { + WZ_Notification notification; + notification.duration = 8 * GAME_TICKS_PER_SEC; + notification.contentTitle = _("Realism mode"); + notification.contentText = _("One automatic save per mission and no cheats!"); + notification.tag = REAL_TAG; + notification.largeIcon = WZ_Notification_Image("images/notifications/skull_crossbones.png"); + + addNotification(notification, WZ_Notification_Trigger::Immediate()); + } + } + break; + case FRONTEND_QUIT: changeTitleMode(OPTIONS); break; diff --git a/src/frontend.h b/src/frontend.h index 868ebe5e78c..3c2b9a5ebcd 100644 --- a/src/frontend.h +++ b/src/frontend.h @@ -278,6 +278,8 @@ enum FRONTEND_DIFFICULTY_R, FRONTEND_CAMERASPEED, FRONTEND_CAMERASPEED_R, + FRONTEND_SAVEREALISM, + FRONTEND_SAVEREALISM_R, FRONTEND_GRAPHICSOPTIONS = 22000, // Graphics Options Menu FRONTEND_FMVMODE, diff --git a/src/ingameop.cpp b/src/ingameop.cpp index fd44ce4cc76..b64aee495f4 100644 --- a/src/ingameop.cpp +++ b/src/ingameop.cpp @@ -256,9 +256,12 @@ static bool _intAddInGameOptions() // add 'load' addIGTextButton(INTINGAMEOP_LOAD_MISSION, INTINGAMEOP_1_X, INTINGAMEOPAUTO_Y_LINE(row), INTINGAMEOP_OP_W, _("Load Game"), OPALIGN); row++; - // add 'save' - addIGTextButton(INTINGAMEOP_SAVE_MISSION, INTINGAMEOP_1_X, INTINGAMEOPAUTO_Y_LINE(row), INTINGAMEOP_OP_W, _("Save Game"), OPALIGN); - row++; + if (!war_getSaveRealism()) + { + // add 'save' + addIGTextButton(INTINGAMEOP_SAVE_MISSION, INTINGAMEOP_1_X, INTINGAMEOPAUTO_Y_LINE(row), INTINGAMEOP_OP_W, _("Save Game"), OPALIGN); + row++; + } } } diff --git a/src/keybind.cpp b/src/keybind.cpp index afc4e6a29b3..b114cd087d7 100644 --- a/src/keybind.cpp +++ b/src/keybind.cpp @@ -451,7 +451,7 @@ void kf_MakeMeHero() if (psDroid->selected && psDroid->droidType == DROID_COMMAND) { psDroid->experience = 8 * 65536 * 128; - } + } else if (psDroid->selected) { psDroid->experience = 4 * 65536 * 128; @@ -746,7 +746,7 @@ void kf_ListDroids() debug(LOG_INFO, "droid %i;%s;%i;%i;%i", i, psDroid->aName, psDroid->droidType, x, y); } } - + } @@ -2543,6 +2543,11 @@ void kf_QuickSave() { return; } + if (war_getSaveRealism()) + { + console(_("QuickSave not allowed during realism mode")); + return; + } const char *filename = bMultiPlayer ? QUICKSAVE_SKI_FILENAME : QUICKSAVE_CAM_FILENAME; const char *quickSaveFolder = bMultiPlayer ? QUICKSAVE_SKI_FOLDER : QUICKSAVE_CAM_FOLDER; @@ -2572,6 +2577,11 @@ void kf_QuickLoad() { return; } + if (war_getSaveRealism()) + { + console(_("QuickLoad not allowed during realism mode")); + return; + } const char *filename = bMultiPlayer ? QUICKSAVE_SKI_FILENAME : QUICKSAVE_CAM_FILENAME; // check for .json version, because that's what going to be loaded anyway diff --git a/src/loadsave.cpp b/src/loadsave.cpp index ffb0980d6a7..3c066cb8269 100644 --- a/src/loadsave.cpp +++ b/src/loadsave.cpp @@ -60,6 +60,7 @@ #include "ingameop.h" #include "game.h" #include "version.h" +#include "warzoneconfig.h" #define totalslots 36 // saves slots #define slotsInColumn 12 // # of slots in a column #define totalslotspace 64 // guessing 64 max chars for filename. @@ -390,7 +391,7 @@ bool addLoadSave(LOADSAVE_MODE savemode, const char *title) ASSERT(latestTagResult.has_value(), "No extractable latest tag?? - Please try re-downloading the latest official source bundle"); const TagVer buildTagVer = latestTagResult.value_or(TagVer()); try - { + { WZ_PHYSFS_enumerateFolders(NewSaveGamePath, [NewSaveGamePath, &buildTagVer, &saveGameNamesAndTimes](const char* dirName){ if (strcmp(dirName, "auto") == 0) { @@ -1132,7 +1133,7 @@ static void freeAutoSaveSlot(SAVEGAME_LOC loc) deleteSaveGame_classic(savefile); } -bool autoSave() +bool autoSave(bool forceRealismSaveIfPossible) { // Bail out if we're running a _true_ multiplayer game or are playing a tutorial/debug/cheating/autogames const DebugInputManager& dbgInputManager = gInputManager.debugManager(); @@ -1140,6 +1141,10 @@ bool autoSave() { return false; } + if (war_getSaveRealism() && !forceRealismSaveIfPossible) + { + return false; + } // Bail out if we're running a replay if (NETisReplay()) { @@ -1152,7 +1157,7 @@ bool autoSave() // no old .gam found: check for new saves freeAutoSaveSlot(bMultiPlayer ? SAVEGAME_LOC_SKI_AUTO : SAVEGAME_LOC_CAM_AUTO); } - + time_t now = time(nullptr); struct tm timeinfo = getLocalTime(now); char savedate[PATH_MAX]; diff --git a/src/loadsave.h b/src/loadsave.h index b86618d377e..210017308d0 100644 --- a/src/loadsave.h +++ b/src/loadsave.h @@ -92,6 +92,6 @@ void loadSaveScreenSizeDidChange(unsigned int oldWidth, unsigned int oldHeight, bool findLastSave(); -bool autoSave(); +bool autoSave(bool forceRealismSaveIfPossible=false); #endif // __INCLUDED_SRC_LOADSAVE_H__ diff --git a/src/main.cpp b/src/main.cpp index 1d78634f109..9c93be98ed0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -185,6 +185,7 @@ char MultiCustomMapsPath[PATH_MAX]; char MultiPlayersPath[PATH_MAX]; char KeyMapPath[PATH_MAX]; char FavoriteStructuresPath[PATH_MAX]; +static unsigned int realismSaveTime = 0; // Start game in title mode: static GS_GAMEMODE gameStatus = GS_TITLE_SCREEN; // Status of the gameloop @@ -986,6 +987,7 @@ static void startGameLoop() addMissionTimerInterface(); } triggerEvent(TRIGGER_START_LEVEL); + realismSaveTime = gameTime + 1000; //Really just to prevent Intel videos messages from not getting saved if run immediately. screen_disableMapPreview(); GameStoryLogger::instance().logStartGame(); @@ -1084,6 +1086,7 @@ static void stopGameLoop() GameStoryLogger::instance().reset(); gameInitialised = false; + realismSaveTime = 0; } @@ -1316,6 +1319,12 @@ void mainLoop() realTimeUpdate(); // Update realTime. } + if (!bMultiPlayer && war_getSaveRealism() && (realismSaveTime != 0) && (gameTime > realismSaveTime)) + { + realismSaveTime = 0; + autoSave(true); + } + wzApplyCursor(); runNotifications(); #if defined(ENABLE_DISCORD) diff --git a/src/warzoneconfig.cpp b/src/warzoneconfig.cpp index b1fe8074c1a..ac9151601f1 100644 --- a/src/warzoneconfig.cpp +++ b/src/warzoneconfig.cpp @@ -92,6 +92,8 @@ struct WARZONE_GLOBALS bool pointLightLighting = false; // groups UI bool groupsMenuEnabled = true; + // save realism + bool saveRealism = false; // run-time only settings (not persisted to config!) bool allowVulkanImplicitLayers = false; @@ -680,3 +682,13 @@ bool war_getAllowVulkanImplicitLayers() { return warGlobs.allowVulkanImplicitLayers; } + +bool war_getSaveRealism() +{ + return warGlobs.saveRealism; +} + +void war_setSaveRealism(bool mode) +{ + warGlobs.saveRealism = mode; +} diff --git a/src/warzoneconfig.h b/src/warzoneconfig.h index 91b00d5cff7..e2a65e9efa9 100644 --- a/src/warzoneconfig.h +++ b/src/warzoneconfig.h @@ -171,6 +171,8 @@ void war_setGroupsMenuEnabled(bool enabled); void war_runtimeOnlySetAllowVulkanImplicitLayers(bool allowed); // not persisted to config bool war_getAllowVulkanImplicitLayers(); +bool war_getSaveRealism(); +void war_setSaveRealism(bool mode); /** * Enable or disable sound initialization *