Skip to content

Commit b256465

Browse files
MP S&L and AutoSave (#24)
* Reconcile_Players * maybe incorrect * StartScenario * AutoSave * fix * Update src/Spawner/Spawner.cpp Co-authored-by: Kerbiter <crabiter@vivaldi.net> * fix * update * Update Spawner.cpp * Update Spawner.cpp * need help * Fix wrong include * move to UI dir * I should read more carefully * Remove empty caption that was screwing up the dialog * A temp hook for testing * dialog works * Update src/UI/Hooks.cpp Co-authored-by: Kerbiter <crabiter@vivaldi.net> * Post-merge fix * Fix beacon crash, add credits --------- Co-authored-by: Kerbiter <crabiter@vivaldi.net>
1 parent 6b0fbcf commit b256465

File tree

12 files changed

+503
-14
lines changed

12 files changed

+503
-14
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,16 @@ Credits
2121
- **[Kerbiter (Metadorius)](https://github.com/Metadorius)**
2222
- Further maintenance
2323
- Event verification checks
24+
- Save button for multiplayer pause menu
25+
- Beacon crash fix for multiplayer save/load
26+
- **[TaranDahl](https://github.com/TaranDahl)**
27+
- Porting of multiplayer save/load
28+
- Porting of autosaves
2429
- **[Rampastring](https://github.com/Rampastring)**
2530
- Original event verification checks
31+
- **[Vinifera](https://github.com/Vinifera-Developers/Vinifera) Contributors and [TS Patches](https://github.com/CnCNet/ts-patches) Contributors**
32+
- Original TS implementation of multiplayer save/load
33+
- Original TS implementation of autosaves
2634
- **[CnCNet](https://github.com/CnCNet) Contributors** - the [original spawner](https://github.com/CnCNet/yr-patches)
2735
- **[Ares](https://github.com/Ares-Developers/Ares) and [Phobos](https://github.com/Phobos-developers/Phobos) Contributors** - [YRpp](https://github.com/Phobos-developers/yrpp) and [Syringe](https://github.com/Ares-Developers/Syringe) which are used and some code snippets
2836

Spawner.vcxproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
<!-- Compiled files -->
1818
<ItemGroup>
1919
<!-- Root -->
20+
<ClCompile Include="src\UI\Dialogs.cpp" />
21+
<ClCompile Include="src\UI\Hooks.cpp" />
2022
<ResourceCompile Include="$(ThisDir)\src\version.rc" />
2123
<ClCompile Include="$(ThisDir)\src\Main.cpp" />
2224
<ClCompile Include="$(ThisDir)\src\Main.Config.cpp" />
@@ -63,6 +65,8 @@
6365
<!-- Utilities -->
6466
<ClCompile Include="$(ThisDir)\src\Utilities\Debug.cpp" />
6567
<ClCompile Include="$(ThisDir)\src\Utilities\Patch.cpp" />
68+
<!-- Dialogs -->
69+
<ResourceCompile Include="$(ThisDir)\src\UI\MultiplayerGameOptionsDialog.rc" />
6670
</ItemGroup>
6771
<!-- Header files -->
6872
<ItemGroup>
@@ -76,6 +80,7 @@
7680
<!-- CnCNetYR -->
7781
<ClInclude Include="$(ThisDir)\src\CnCNetYR\Ra2Mode.h" />
7882
<!-- Misc -->
83+
<ClInclude Include="$(ThisDir)\src\UI\Dialogs.h" />
7984
<!-- Spawner -->
8085
<ClInclude Include="$(ThisDir)\src\Spawner\NetHack.h" />
8186
<ClInclude Include="$(ThisDir)\src\Spawner\ProtocolZero.h" />

src/Ext/Event/Body.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "Body.h"
2121
#include <Spawner/ProtocolZero.h>
22+
#include <Spawner/Spawner.h>
2223

2324
#include <Helpers/Macro.h>
2425
#include <EventClass.h>

src/Spawner/Spawner.Config.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,14 @@ void SpawnerConfig::LoadFromINIFile(CCINIClass* pINI)
5252
MultiByteToWideChar(CP_UTF8, 0, Main::readBuffer, strlen(Main::readBuffer), UIGameMode, std::size(UIGameMode));
5353
}
5454

55-
// SaveGame Options
56-
LoadSaveGame = pINI->ReadBool(pSettingsSection, "LoadSaveGame", LoadSaveGame);
57-
/* SavedGameDir */ pINI->ReadString(pSettingsSection, "SavedGameDir", SavedGameDir, SavedGameDir, sizeof(SavedGameDir));
58-
/* SaveGameName */ pINI->ReadString(pSettingsSection, "SaveGameName", SaveGameName, SaveGameName, sizeof(SaveGameName));
55+
{// SaveGame Options
56+
LoadSaveGame = pINI->ReadBool(pSettingsSection, "LoadSaveGame", LoadSaveGame);
57+
/* SavedGameDir */ pINI->ReadString(pSettingsSection, "SavedGameDir", SavedGameDir, SavedGameDir, sizeof(SavedGameDir));
58+
/* SaveGameName */ pINI->ReadString(pSettingsSection, "SaveGameName", SaveGameName, SaveGameName, sizeof(SaveGameName));
59+
AutoSaveCount = pINI->ReadInteger(pSettingsSection, "AutoSaveCount", AutoSaveCount);
60+
AutoSaveInterval = pINI->ReadInteger(pSettingsSection, "AutoSaveInterval", AutoSaveInterval);
61+
NextAutoSaveNumber = pINI->ReadInteger(pSettingsSection, "NextAutoSaveNumber", NextAutoSaveNumber);
62+
}
5963

6064
{ // Scenario Options
6165
Seed = pINI->ReadInteger(pSettingsSection, "Seed", Seed);

src/Spawner/Spawner.Config.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ class SpawnerConfig
9494
bool LoadSaveGame;
9595
char SavedGameDir[MAX_PATH]; // Nested paths are also supported, e.g. "Saved Games\\Yuri's Revenge"
9696
char SaveGameName[60];
97+
int AutoSaveCount;
98+
int AutoSaveInterval;
99+
int NextAutoSaveNumber;
97100

98101
// Scenario Options
99102
int Seed;
@@ -161,6 +164,9 @@ class SpawnerConfig
161164
, LoadSaveGame { false }
162165
, SavedGameDir { "Saved Games" }
163166
, SaveGameName { "" }
167+
, AutoSaveCount { 5 }
168+
, AutoSaveInterval { 7200 }
169+
, NextAutoSaveNumber { 0 }
164170

165171
// Scenario Options
166172
, Seed { 0 }

src/Spawner/Spawner.Hook.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222

2323
#include <HouseClass.h>
2424
#include <SessionClass.h>
25+
#include <BeaconManagerClass.h>
2526
#include <Utilities/Debug.h>
2627
#include <Utilities/Macro.h>
28+
#include <Unsorted.h>
2729

2830
DEFINE_HOOK(0x6BD7C5, WinMain_SpawnerInit, 0x6)
2931
{
@@ -179,3 +181,57 @@ DEFINE_HOOK(0x4FC57C, HouseClass__MPlayerDefeated_CheckAliveAndHumans, 0x7)
179181
}
180182

181183
#pragma endregion MPlayerDefeated
184+
185+
#pragma region Save&Load
186+
187+
DEFINE_HOOK_AGAIN(0x624271, SomeFunc_InterceptMainLoop, 0x5);
188+
DEFINE_HOOK_AGAIN(0x623D72, SomeFunc_InterceptMainLoop, 0x5);
189+
DEFINE_HOOK_AGAIN(0x62314E, SomeFunc_InterceptMainLoop, 0x5);
190+
DEFINE_HOOK_AGAIN(0x60D407, SomeFunc_InterceptMainLoop, 0x5);
191+
DEFINE_HOOK_AGAIN(0x608206, SomeFunc_InterceptMainLoop, 0x5);
192+
DEFINE_HOOK(0x48CE8A, SomeFunc_InterceptMainLoop, 0x5)
193+
{
194+
/**
195+
* Main loop.
196+
*/
197+
Game::MainLoop();
198+
199+
/**
200+
* After loop.
201+
*/
202+
Spawner::After_Main_Loop();
203+
return R->Origin() + 0x5;
204+
}
205+
206+
DEFINE_HOOK(0x52DAED, Game_Start_ResetGlobal, 0x7)
207+
{
208+
Spawner::DoSave = false;
209+
Spawner::NextAutoSaveFrame = -1;
210+
Spawner::NextAutoSaveNumber = 0;
211+
return 0;
212+
}
213+
214+
DEFINE_HOOK(0x686B20, INIClass_ReadScenario_AutoSave, 0x6)
215+
{
216+
/**
217+
* Schedule the next autosave.
218+
*/
219+
Spawner::NextAutoSaveFrame = Unsorted::CurrentFrame;
220+
Spawner::NextAutoSaveFrame += Spawner::GetConfig()->AutoSaveInterval;
221+
return 0;
222+
}
223+
224+
DEFINE_HOOK(0x4C7A14, EventClass_RespondToEvent_SaveGame, 0x5)
225+
{
226+
Spawner::DoSave = true;
227+
return 0x4C7B42;
228+
}
229+
230+
// for some reason beacons are only inited on scenario init, which doesn't happen on load
231+
DEFINE_HOOK(0x67E6DA, LoadGame_AfterInit, 0x6)
232+
{
233+
BeaconManagerClass::Instance.LoadArt();
234+
return 0;
235+
}
236+
237+
#pragma endregion

0 commit comments

Comments
 (0)