Skip to content

Commit 698d92a

Browse files
committed
hardcore init
1 parent 853e505 commit 698d92a

5 files changed

Lines changed: 100 additions & 3 deletions

File tree

src/Misc/SavedGamesInSubdir.cpp

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,12 @@ DEFINE_HOOK(0x67D2E3, SaveGame_AdditionalInfoForClient, 0x6)
280280
GET_STACK(IStorage*, pStorage, STACK_OFFSET(0x4A0, -0x490));
281281
using namespace SavedGames;
282282

283-
if (pStorage)
283+
if (SessionClass::IsCampaign() && pStorage)
284284
{
285-
if (SessionClass::IsCampaign() && Spawner::GetConfig()->CustomMissionID)
285+
if (Spawner::GetConfig()->CustomMissionID)
286286
AppendToStorage<CustomMissionID>(pStorage);
287+
if (Spawner::GetConfig()->DisableSaveLoad)// you fucking cheater
288+
pStorage->DestroyElement(L"CONTENTS");
287289
}
288290

289291
return 0;
@@ -343,3 +345,88 @@ DEFINE_HOOK(0x55DC85, MainLoop_SaveGame_SanitizeFilename, 0x7)
343345

344346
return 0x55DC90;
345347
}
348+
349+
#pragma region nosaveload
350+
#include <WWMessageBox.h>
351+
#include <LoadProgressManager.h>
352+
DEFINE_HOOK(0x686089, DoLose_RetryDialogForCampaigns, 0x7)
353+
{
354+
if (!Spawner::GetConfig()->DisableSaveLoad) return 0;
355+
356+
WWMessageBox::Instance.Process(
357+
PRIMARYLANGID(GetUserDefaultUILanguage()) == LANG_CHINESE ? L"\u83dc" : L"GG",
358+
StringTable::LoadString(GameStrings::TXT_OK), nullptr, nullptr);
359+
return 0x6860EE;
360+
}
361+
362+
// disable load, save and delete buttons on the ingame menu
363+
DEFINE_HOOK(0x4F17F6, sub_4F1720_DisableSaves, 0x6)
364+
{
365+
if (!Spawner::GetConfig()->DisableSaveLoad) return 0;
366+
GET(HWND, hDlg, EBP);
367+
368+
enum { LoadGameButton = 1310, DeleteGameButton = 1312 };
369+
370+
for (int item = LoadGameButton; item <= DeleteGameButton; ++item)
371+
{
372+
if (HWND hItem = GetDlgItem(hDlg, item))
373+
EnableWindow(hItem, FALSE);
374+
}
375+
376+
return 0x4F1834;
377+
}
378+
inline const wchar_t* get_TXT_HARDCORE_MODE()
379+
{
380+
std::wstring_view msg = StringTable::LoadString("TXT_HARDCORE_MODE");
381+
if (msg.empty() || msg.starts_with(L"MISSING"))
382+
msg = L"HARDCORE";
383+
return msg.data();
384+
}
385+
DEFINE_HOOK(0x553076, LoadProgressMgr_Draw_ExtraText_Campaign, 0x5)
386+
{
387+
GET(LoadProgressManager*, self, EBP);
388+
if (!Spawner::GetConfig()->DisableSaveLoad) return 0;
389+
390+
Point2D pos
391+
{
392+
self->TitleBarRect.X + self->TitleBarRect.Width - 100,
393+
self->TitleBarRect.Y + 10
394+
};
395+
LEA_STACK(RectangleStruct*, pBnd, STACK_OFFSET(0x1268, -0x1204));
396+
if (auto logo = FileSystem::LoadSHPFile("hardcorelogo.shp"))
397+
{
398+
self->ProgressSurface->DrawSHP(FileSystem::PALETTE_PAL, logo, 0, &pos, pBnd, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0);
399+
}
400+
else
401+
{
402+
self->ProgressSurface->DrawText(get_TXT_HARDCORE_MODE(), &pos, COLOR_RED);
403+
}
404+
405+
return 0;
406+
}
407+
408+
DEFINE_HOOK(0x4F4573, GScreenClass_Draw_SpawnerShit, 0x5)
409+
{
410+
if (!Spawner::GetConfig()->DisableSaveLoad) return 0;
411+
wchar_t buffer[0x20] {};
412+
int seconds = Unsorted::CurrentFrame / 15;
413+
std::format_to(buffer, L"{} {}:{:02}", get_TXT_HARDCORE_MODE(), seconds / 60, seconds % 60);
414+
auto wanted = Drawing::GetTextDimensions(buffer, { 0,0 }, 0, 2, 0);
415+
416+
RectangleStruct rect = {
417+
DSurface::Composite->GetWidth() - wanted.Width - 20,
418+
0,
419+
wanted.Width + 10,
420+
wanted.Height + 10
421+
};
422+
423+
Point2D location { rect.X - 5,5 };
424+
425+
DSurface::Composite->FillRect(&rect, COLOR_BLACK);
426+
DSurface::Composite->DrawText(buffer, &location, COLOR_WHITE);
427+
428+
//Fucking Phobos
429+
R->ECX(*(int*)0x887640u);
430+
return 0x4F4589;
431+
}
432+
#pragma endregion

src/Spawner/Spawner.Config.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ void SpawnerConfig::LoadFromINIFile(CCINIClass* pINI)
118118
ContinueWithoutHumans = pINI->ReadBool(pSettingsSection, "ContinueWithoutHumans", ContinueWithoutHumans);
119119
DefeatedBecomesObserver = pINI->ReadBool(pSettingsSection, "DefeatedBecomesObserver", DefeatedBecomesObserver);
120120
Observer_ShowAIOnSidebar = pINI->ReadBool(pSettingsSection, "Observer.ShowAIOnSidebar", Observer_ShowAIOnSidebar);
121+
DisableSaveLoad = pINI->ReadBool(pSettingsSection, "DisableSaveLoad", false) && IsCampaign && !LoadSaveGame;
121122
}
122123
}
123124

src/Spawner/Spawner.Config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class SpawnerConfig
147147
bool ContinueWithoutHumans;
148148
bool DefeatedBecomesObserver;
149149
bool Observer_ShowAIOnSidebar;
150+
bool DisableSaveLoad;
150151

151152
SpawnerConfig() // default values
152153
// Game Mode Options
@@ -242,6 +243,7 @@ class SpawnerConfig
242243
, ContinueWithoutHumans { false }
243244
, DefeatedBecomesObserver { false }
244245
, Observer_ShowAIOnSidebar { false }
246+
, DisableSaveLoad { false }
245247
{ }
246248

247249
void LoadFromINIFile(CCINIClass* pINI);

src/Spawner/Spawner.Hook.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ DEFINE_HOOK(0x6BD7C5, WinMain_SpawnerInit, 0x6)
7373

7474
// Skip load *.PKT, *.YRO and *.YRM map files
7575
Patch::Apply_LJMP(0x699AD9, 0x69A1B2); // SessionClass::Read_Scenario_Descriptions
76+
77+
if (Spawner::GetConfig()->DisableSaveLoad)
78+
{
79+
Patch::Apply_LJMP(0x55DBCD, 0x55DC99); // Disable MainLoop_SaveGame (Spawner&Phobos)
80+
Patch::Apply_RAW(0x67CEF0, { 0x33,0xC0,0xC3 }); // Corrupt savegame function
81+
Patch::Apply_TYPED(0x83D560, { (DWORD)std::rand() }); // Corrupt save game magicn
82+
}
7683
}
7784

7885
return 0;

src/Spawner/Spawner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ bool Spawner::StartScenario(const char* pScenarioName)
316316

317317
bool result = ScenarioClass::StartScenario(pScenarioName, 1, 0);
318318

319-
if (Spawner::Config->CustomMissionID != 0) // after parsing
319+
if (Spawner::Config->CustomMissionID != 0 || Spawner::Config->DisableSaveLoad) // after parsing
320320
ScenarioClass::Instance->EndOfGame = true;
321321

322322
return result;

0 commit comments

Comments
 (0)