From 03fbd6a78ce8104c8a6d0056b29659b59c2de64f Mon Sep 17 00:00:00 2001 From: Trsdy <914137150@qq.com> Date: Sun, 17 Nov 2024 20:59:49 +0800 Subject: [PATCH] cyka --- docs/User-Interface.md | 13 +++++++++++++ docs/Whats-New.md | 2 ++ src/Commands/QuickSave.cpp | 6 ++++++ src/Ext/Scenario/Body.cpp | 2 ++ src/Misc/Hooks.PCX.cpp | 24 ++++++++++++++++++++++++ src/Misc/RetryDialog.cpp | 7 +++++++ src/Phobos.Ext.cpp | 6 ++++++ src/Phobos.INI.cpp | 31 +++++++++++++++++++++++++++++-- src/Phobos.h | 1 + 9 files changed, 90 insertions(+), 2 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 2e1ad86969..cac37476e2 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -589,3 +589,16 @@ In `RA2MD.ini`: [Phobos] SaveGameOnScenarioStart=true ; boolean ``` + + +### Forbid saving game + +Game save can be forbidden in singleplayer games as some sort of "hardcore" mode. All existing save/load functionalities will be disabled. +- When trying to click the save button, a message box with `TXT_HARDCORE_NOSAVE` CSF entry will appear instead of saving the game. +- Scenarios successions will be disabled as well. +- On the loading screen, the single-frame `hardcorelogo.shp` (for `Palette.pal`) will be drawn on the top right corner of the screen. If not present, the text with csf `TXT_HARDCORE_MODE` will be displayed instead. +In `RA2MD.ini`: +```ini + [Phobos] + NoSaveLoad=false ; boolean + ``` diff --git a/docs/Whats-New.md b/docs/Whats-New.md index fe6adaa3d9..7d041c585c 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -92,6 +92,7 @@ ToolTipDescriptions=true ; boolean ToolTipBlur=false ; boolean SaveGameOnScenarioStart=true ; boolean HideLightFlashEffects=false ; boolean +NoSaveLoad = false ; boolean ``` ### For Map Editor (Final Alert 2) @@ -549,6 +550,7 @@ Vanilla fixes: - Fixed infantry `SecondaryFire` / `SecondaryProne` sequences being displayed in water instead of `WetAttack` (by Starkku) - Fixed objects with ally target and `AttackFriendlies=true` having their target reset every frame, particularly AI-owned buildings (by Starkku) - Follower vehicle index for preplaced vehicles in maps is now explicitly constrained to `[Units]` list in map files and is no longer thrown off by vehicles that could not be created or created vehicles having other vehicles as initial passengers (by Starkku) +- Save game disabler (by Trsdy) Phobos fixes: - Fixed a few errors of calling for superweapon launch by `LaunchSW` or building infiltration (by Trsdy) diff --git a/src/Commands/QuickSave.cpp b/src/Commands/QuickSave.cpp index 03c552d33d..1a969f5878 100644 --- a/src/Commands/QuickSave.cpp +++ b/src/Commands/QuickSave.cpp @@ -37,6 +37,12 @@ void QuickSaveCommandClass::Execute(WWKey eInput) const ); }; + if(Phobos::Config::NoSaveLoad) + { + PrintMessage(StringTable::LoadString(GameStrings::TXT_ERROR_SAVING_GAME)); + return; + } + if (SessionClass::IsSingleplayer()) { *reinterpret_cast(0xABCE08) = false; diff --git a/src/Ext/Scenario/Body.cpp b/src/Ext/Scenario/Body.cpp index 53c8ef3985..a266fd52ec 100644 --- a/src/Ext/Scenario/Body.cpp +++ b/src/Ext/Scenario/Body.cpp @@ -148,6 +148,8 @@ void ScenarioExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->ShowBriefing = ini_missionmd.ReadBool(scenarioName, "ShowBriefing", pINI->ReadBool(GameStrings::Basic, "ShowBriefing", this->ShowBriefing)); this->BriefingTheme = ini_missionmd.ReadTheme(scenarioName, "BriefingTheme", pINI->ReadTheme(GameStrings::Basic, "BriefingTheme", this->BriefingTheme)); + if (Phobos::Config::NoSaveLoad) + ScenarioClass::Instance->EndOfGame = true; } } diff --git a/src/Misc/Hooks.PCX.cpp b/src/Misc/Hooks.PCX.cpp index a3751bc5d4..5c5b0a265d 100644 --- a/src/Misc/Hooks.PCX.cpp +++ b/src/Misc/Hooks.PCX.cpp @@ -83,6 +83,30 @@ DEFINE_HOOK(0x552FCB, LoadProgressMgr_Draw_PCXLoadingScreen_Campaign, 0x6) return 0; } +DEFINE_HOOK(0x553076,LoadProgressMgr_Draw_ExtraText_Campaign,0x5) +{ + GET(LoadProgressManager*, self, EBP); + if(Phobos::Config::NoSaveLoad) + { + Point2D pos + { + self->TitleBarRect.X + self->TitleBarRect.Width - 100, + self->TitleBarRect.Y + 10 + }; + LEA_STACK(RectangleStruct*, pBnd, STACK_OFFSET(0x1268,-0x1204)); + if(auto logo = FileSystem::LoadSHPFile("hardcorelogo.shp")) + { + self->ProgressSurface->DrawSHP(FileSystem::PALETTE_PAL,logo,0,&pos,pBnd,BlitterFlags::bf_400,0,0,ZGradient::Ground,1000,0,nullptr,0,0,0); + } + else + { + auto msg = GeneralUtils::LoadStringUnlessMissing("TXT_HARDCORE_MODE",L"HARDCORE"); + self->ProgressSurface->DrawTextA(msg,&pos,COLOR_RED); + } + } + return 0; +} + DEFINE_HOOK(0x6A99F3, StripClass_Draw_DrawMissing, 0x6) { GET_STACK(SHPStruct*, pCameo, STACK_OFFSET(0x48C, -0x444)); diff --git a/src/Misc/RetryDialog.cpp b/src/Misc/RetryDialog.cpp index e458db9ef1..74c1749f3f 100644 --- a/src/Misc/RetryDialog.cpp +++ b/src/Misc/RetryDialog.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace RetryDialogFlag { @@ -16,6 +17,12 @@ DEFINE_HOOK(0x686092, DoLose_RetryDialogForCampaigns, 0x7) { enum { OK = 0x6860F6, Cancel = 0x6860EE, LoadGame = 0x686231 }; + if(Phobos::Config::NoSaveLoad) + { + WWMessageBox::Instance->Process(L"GG",StringTable::LoadString(GameStrings::TXT_OK),nullptr,nullptr); + return Cancel; + } + while (true) { // WWMessageBox buttons look like below: diff --git a/src/Phobos.Ext.cpp b/src/Phobos.Ext.cpp index 4d4f29cdb7..6c40745237 100644 --- a/src/Phobos.Ext.cpp +++ b/src/Phobos.Ext.cpp @@ -279,6 +279,12 @@ DEFINE_HOOK(0x67D04E, GameSave_SavegameInformation, 0x7) Info.ExecutableName.Size - sizeof(" + Phobos " FILE_VERSION_STR) ); + if (Phobos::Config::NoSaveLoad) + { + // You've somehow cheated to make through this + Debug::FatalErrorAndExit("Hard Core mode enabled, save game not allowed!"); + } + return 0; } diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 1f5d20345d..8a299a4251 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -5,7 +5,8 @@ #include #include #include - +#include +#include #include #include #include @@ -55,6 +56,7 @@ bool Phobos::Config::ShowHarvesterCounter = false; bool Phobos::Config::ShowPowerDelta = true; bool Phobos::Config::ShowWeedsCounter = false; bool Phobos::Config::HideLightFlashEffects = true; +bool Phobos::Config::NoSaveLoad = false; bool Phobos::Misc::CustomGS = false; int Phobos::Misc::CustomGS_ChangeInterval[7] = { -1, -1, -1, -1, -1, -1, -1 }; @@ -92,6 +94,13 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) } Phobos::Config::ShowDesignatorRange = CCINIClass::INI_RA2MD->ReadBool("Phobos", "ShowDesignatorRange", false); + Phobos::Config::NoSaveLoad = CCINIClass::INI_RA2MD->ReadBool("Phobos", "NoSaveLoad", false); + if (Phobos::Config::NoSaveLoad) + { + Patch::Apply_LJMP(0x55DBCD, 0x55DC99); // Disable MainLoop_SaveGame + Patch::Apply_RAW(0x67CEF0, {0x33,0xC0,0xC3}); // Corrupt savegame function + Patch::Apply_TYPED(0x83D560, {(DWORD)std::rand()}); // Corrupt save game magicn + } CCINIClass ini_uimd {}; ini_uimd.LoadFromFile(GameStrings::UIMD_INI); @@ -259,7 +268,7 @@ DEFINE_HOOK(0x55DBCD, MainLoop_SaveGame, 0x6) enum { SkipSave = 0x55DC99, InitialSave = 0x55DBE6 }; bool& scenario_saved = *reinterpret_cast(0xABCE08); - if (SessionClass::IsSingleplayer() && !scenario_saved) + if (SessionClass::IsSingleplayer() && !scenario_saved && !Phobos::Config::NoSaveLoad) { scenario_saved = true; if (Phobos::ShouldQuickSave) @@ -274,3 +283,21 @@ DEFINE_HOOK(0x55DBCD, MainLoop_SaveGame, 0x6) return SkipSave; } + +// Yeah I know you are going to say Ares pre 0.A had similar save/load button disable, but better not use that less informative approach +DEFINE_HOOK(0x558DDC, LoadOptionsClass_MakeDlg_NoSL, 0x5) +{ + if (!Phobos::Config::NoSaveLoad) + return 0; + + GET(LoadOptionsClass*, self, ESI); + if (self->Mode != LoadOptionsMode::Save && self->Mode != LoadOptionsMode::Load) + return 0; + + WWMessageBox::Instance->Process( + GeneralUtils::LoadStringUnlessMissing("TXT_HARDCORE_NOSAVE",L"Hard-Core mode on, save/load forbidden!"), + StringTable::LoadString(GameStrings::TXT_OK), + nullptr, nullptr + ); + return 0x558EA9; +} diff --git a/src/Phobos.h b/src/Phobos.h index 9ba1a63879..6ae474bf85 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -90,6 +90,7 @@ class Phobos static bool ShowWeedsCounter; static bool ShowPlanningPath; static bool HideLightFlashEffects; + static bool NoSaveLoad; }; class Misc