From 48ee0864eacaac1a2f58f9dbb660d22f332ca52d Mon Sep 17 00:00:00 2001 From: Trsdy <914137150@qq.com> Date: Wed, 4 Mar 2026 12:12:06 +0800 Subject: [PATCH] legacy shit --- src/Misc/SavedGamesInSubdir.cpp | 89 +++++++++++++++++++++++++++++++++ src/Spawner/Spawner.Config.cpp | 1 + src/Spawner/Spawner.Config.h | 2 + src/Spawner/Spawner.Hook.cpp | 7 +++ src/Spawner/Spawner.cpp | 2 +- 5 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/Misc/SavedGamesInSubdir.cpp b/src/Misc/SavedGamesInSubdir.cpp index 6a9ce5bf..3bf72031 100644 --- a/src/Misc/SavedGamesInSubdir.cpp +++ b/src/Misc/SavedGamesInSubdir.cpp @@ -284,6 +284,8 @@ DEFINE_HOOK(0x67D2E3, SaveGame_AdditionalInfoForClient, 0x6) { if (Spawner::GetConfig()->CustomMissionID) WriteToStorage(pStorage); + if (Spawner::GetConfig()->DisableSaveLoad)// you fucking cheater + pStorage->DestroyElement(L"CONTENTS"); } return 0; @@ -343,3 +345,90 @@ DEFINE_HOOK(0x55DC85, MainLoop_SaveGame_SanitizeFilename, 0x7) return 0x55DC90; } + +#pragma region nosaveload +#include +#include + +DEFINE_HOOK(0x686089, DoLose_RetryDialogForCampaigns, 0x7) +{ + if (!Spawner::GetConfig()->DisableSaveLoad) return 0; + + WWMessageBox::Instance.Process( + PRIMARYLANGID(GetUserDefaultUILanguage()) == LANG_CHINESE ? L"\u83dc" : L"GG", + StringTable::LoadString("TXT_OK"), nullptr, nullptr); + + return 0x6860EE; +} + +// disable load, save and delete buttons on the ingame menu +DEFINE_HOOK(0x4F17F6, sub_4F1720_DisableSaves, 0x6) +{ + if (!Spawner::GetConfig()->DisableSaveLoad) return 0; + GET(HWND, hDlg, EBP); + + enum { LoadGameButton = 1310, DeleteGameButton = 1312 }; + + for (int item = LoadGameButton; item <= DeleteGameButton; ++item) + { + if (HWND hItem = GetDlgItem(hDlg, item)) + EnableWindow(hItem, FALSE); + } + + return 0x4F1834; +} +inline const wchar_t* get_TXT_HARDCORE_MODE() +{ + std::wstring_view msg = StringTable::LoadString("TXT_HARDCORE_MODE"); + if (msg.empty() || msg.starts_with(L"MISSING")) + msg = L"HARDCORE"; + return msg.data(); +} +DEFINE_HOOK(0x553076, LoadProgressMgr_Draw_ExtraText_Campaign, 0x5) +{ + GET(LoadProgressManager*, self, EBP); + if (!Spawner::GetConfig()->DisableSaveLoad) return 0; + + 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 + { + self->ProgressSurface->DrawText(get_TXT_HARDCORE_MODE(), &pos, COLOR_RED); + } + + return 0; +} + +DEFINE_HOOK(0x4F4573, GScreenClass_Draw_SpawnerShit, 0x5) +{ + if (!Spawner::GetConfig()->DisableSaveLoad) return 0; + wchar_t buffer[0x20] {}; + int seconds = Unsorted::CurrentFrame / 15; + swprintf(buffer, std::size(buffer), L"%s %d:%02d", get_TXT_HARDCORE_MODE(), seconds / 60, seconds % 60); + auto wanted = Drawing::GetTextDimensions(buffer, { 0,0 }, 0, 2, 0); + + RectangleStruct rect = { + DSurface::Composite->GetWidth() - wanted.Width - 20, + 0, + wanted.Width + 10, + wanted.Height + 10 + }; + + Point2D location { rect.X - 5,5 }; + + DSurface::Composite->FillRect(&rect, COLOR_BLACK); + DSurface::Composite->DrawText(buffer, &location, COLOR_WHITE); + + //Fucking Phobos + R->ECX(*(int*)0x887640); + return 0x4F4589; +} +#pragma endregion diff --git a/src/Spawner/Spawner.Config.cpp b/src/Spawner/Spawner.Config.cpp index f7297e85..2126991b 100644 --- a/src/Spawner/Spawner.Config.cpp +++ b/src/Spawner/Spawner.Config.cpp @@ -118,6 +118,7 @@ void SpawnerConfig::LoadFromINIFile(CCINIClass* pINI) ContinueWithoutHumans = pINI->ReadBool(pSettingsSection, "ContinueWithoutHumans", ContinueWithoutHumans); DefeatedBecomesObserver = pINI->ReadBool(pSettingsSection, "DefeatedBecomesObserver", DefeatedBecomesObserver); Observer_ShowAIOnSidebar = pINI->ReadBool(pSettingsSection, "Observer.ShowAIOnSidebar", Observer_ShowAIOnSidebar); + DisableSaveLoad = pINI->ReadBool(pSettingsSection, "DisableSaveLoad", false) && IsCampaign && !LoadSaveGame; } } diff --git a/src/Spawner/Spawner.Config.h b/src/Spawner/Spawner.Config.h index 44c7248b..0360df01 100644 --- a/src/Spawner/Spawner.Config.h +++ b/src/Spawner/Spawner.Config.h @@ -147,6 +147,7 @@ class SpawnerConfig bool ContinueWithoutHumans; bool DefeatedBecomesObserver; bool Observer_ShowAIOnSidebar; + bool DisableSaveLoad; SpawnerConfig() // default values // Game Mode Options @@ -242,6 +243,7 @@ class SpawnerConfig , ContinueWithoutHumans { false } , DefeatedBecomesObserver { false } , Observer_ShowAIOnSidebar { false } + , DisableSaveLoad { false } { } void LoadFromINIFile(CCINIClass* pINI); diff --git a/src/Spawner/Spawner.Hook.cpp b/src/Spawner/Spawner.Hook.cpp index 0659dcad..0b2ddc29 100644 --- a/src/Spawner/Spawner.Hook.cpp +++ b/src/Spawner/Spawner.Hook.cpp @@ -73,6 +73,13 @@ DEFINE_HOOK(0x6BD7C5, WinMain_SpawnerInit, 0x6) // Skip load *.PKT, *.YRO and *.YRM map files Patch::Apply_LJMP(0x699AD9, 0x69A1B2); // SessionClass::Read_Scenario_Descriptions + + if (Spawner::GetConfig()->DisableSaveLoad) + { + Patch::Apply_LJMP(0x55DBCD, 0x55DC99); // Disable MainLoop_SaveGame (Spawner&Phobos) + Patch::Apply_RAW(0x67CEF0, { 0x33,0xC0,0xC3 }); // Corrupt savegame function + Patch::Apply_TYPED(0x83D560, { (DWORD)std::rand() }); // Corrupt save game magicn + } } return 0; diff --git a/src/Spawner/Spawner.cpp b/src/Spawner/Spawner.cpp index 2cc048db..e3b6e296 100644 --- a/src/Spawner/Spawner.cpp +++ b/src/Spawner/Spawner.cpp @@ -315,7 +315,7 @@ bool Spawner::StartScenario(const char* pScenarioName) bool result = ScenarioClass::StartScenario(pScenarioName, 1, 0); - if (Spawner::Config->CustomMissionID != 0) // after parsing + if (Spawner::Config->CustomMissionID != 0 || Spawner::Config->DisableSaveLoad) // after parsing ScenarioClass::Instance->EndOfGame = true; return result;