@@ -136,7 +136,7 @@ bool C4GameSave::SaveScenarioSections()
136
136
return true ;
137
137
}
138
138
139
- bool C4GameSave::SaveLandscape (C4Section §ion)
139
+ bool C4GameSave::SaveLandscape (C4Section §ion, C4Group &group )
140
140
{
141
141
// exact?
142
142
if (section.Landscape .Mode == C4LSC_Exact || GetForceExactLandscape ())
@@ -146,20 +146,20 @@ bool C4GameSave::SaveLandscape(C4Section §ion)
146
146
section.Objects .RemoveSolidMasks ();
147
147
bool fSuccess ;
148
148
if (section.Landscape .Mode == C4LSC_Exact)
149
- fSuccess = !!section.Landscape .Save (*pSaveGroup );
149
+ fSuccess = !!section.Landscape .SaveExact (group );
150
150
else
151
- fSuccess = !!section.Landscape .SaveDiff (*pSaveGroup , !IsSynced ());
151
+ fSuccess = !!section.Landscape .SaveDiff (group , !IsSynced ());
152
152
section.Objects .PutSolidMasks ();
153
153
if (!fSuccess ) return false ;
154
154
DBGRECOFF.Clear ();
155
155
// PXS
156
- if (!section.PXS .Save (*pSaveGroup )) return false ;
156
+ if (!section.PXS .Save (group )) return false ;
157
157
// MassMover (create copy, may not modify running data)
158
158
C4MassMoverSet MassMoverSet{section};
159
159
MassMoverSet.Copy (section.MassMover );
160
- if (!MassMoverSet.Save (*pSaveGroup )) return false ;
160
+ if (!MassMoverSet.Save (group )) return false ;
161
161
// Material enumeration
162
- if (!section.Material .SaveEnumeration (*pSaveGroup )) return false ;
162
+ if (!section.Material .SaveEnumeration (group )) return false ;
163
163
}
164
164
// static / dynamic
165
165
if (section.Landscape .Mode == C4LSC_Static)
@@ -171,9 +171,9 @@ bool C4GameSave::SaveLandscape(C4Section §ion)
171
171
if (!GetForceExactLandscape ())
172
172
{
173
173
// save map
174
- if (!section.Landscape .SaveMap (*pSaveGroup )) return false ;
174
+ if (!section.Landscape .SaveMap (group )) return false ;
175
175
// save textures (if changed)
176
- if (!section.Landscape .SaveTextures (*pSaveGroup )) return false ;
176
+ if (!section.Landscape .SaveTextures (group )) return false ;
177
177
}
178
178
}
179
179
else if (section.Landscape .Mode != C4LSC_Exact)
@@ -193,11 +193,46 @@ bool C4GameSave::SaveRuntimeData()
193
193
Log (C4ResStrTableKey::IDS_ERR_SAVE_SCENSECTIONS); return false ;
194
194
}
195
195
196
- for ( const auto §ion : Game.Sections )
196
+ if (! SaveSection (* Game.Sections . front (), *pSaveGroup, false ) )
197
197
{
198
- if (!SaveSection (*section))
198
+ return false ;
199
+ }
200
+
201
+ if (IsExact ())
202
+ {
203
+ std::size_t counter{1 };
204
+
205
+ for (auto it = std::next (Game.Sections .begin ()); it != Game.Sections .end (); ++it)
199
206
{
200
- return false ;
207
+ C4Section §ion{**it};
208
+ if (!SaveSection (section, std::format (C4CFN_SavedSection, counter++, section.Number ), true ))
209
+ {
210
+ return false ;
211
+ }
212
+ }
213
+ }
214
+ else
215
+ {
216
+ for (auto it = std::next (Game.Sections .begin ()); it != Game.Sections .end (); ++it)
217
+ {
218
+ C4Section §ion{**it};
219
+
220
+ C4Group sectGroup;
221
+ const std::string filename{std::format (C4CFN_Section, section.GetNameForSaveGame ())};
222
+ if (sectGroup.OpenAsChild (pSaveGroup, filename.c_str ()))
223
+ {
224
+ if (!SaveSection (section, sectGroup, true ))
225
+ {
226
+ return false ;
227
+ }
228
+ }
229
+ else
230
+ {
231
+ if (!SaveSection (section, filename, true ))
232
+ {
233
+ return false ;
234
+ }
235
+ }
201
236
}
202
237
}
203
238
@@ -263,22 +298,77 @@ bool C4GameSave::SaveRuntimeData()
263
298
return true ;
264
299
}
265
300
266
- bool C4GameSave::SaveSection (C4Section §ion)
301
+ bool C4GameSave::SaveSection (C4Section §ion, const std::string &filename, const bool saveRuntimeData)
302
+ {
303
+ pSaveGroup->SetStdOutput (true );
304
+ std::string tmpFile{Config.AtTempPath (filename.c_str ())};
305
+ MakeTempFilename (tmpFile.data ());
306
+
307
+ {
308
+ C4Group tmpGroup;
309
+ if (!tmpGroup.Open (tmpFile.c_str (), true ))
310
+ {
311
+ return false ;
312
+ }
313
+
314
+ if (!SaveSection (section, tmpGroup, saveRuntimeData))
315
+ {
316
+ return false ;
317
+ }
318
+
319
+ tmpGroup.Close ();
320
+ }
321
+
322
+ if (!pSaveGroup->Move (tmpFile.c_str (), filename.c_str ()))
323
+ {
324
+ return false ;
325
+ }
326
+
327
+ return true ;
328
+ }
329
+
330
+ bool C4GameSave::SaveSection (C4Section §ion, C4Group &group, const bool saveRuntimeData)
267
331
{
268
332
// landscape
269
- if (!SaveLandscape (section))
333
+ if (!SaveLandscape (section, group ))
270
334
{
271
335
Log (C4ResStrTableKey::IDS_ERR_SAVE_LANDSCAPE);
272
336
return false ;
273
337
}
274
338
275
339
// Objects
276
- if (!section.Objects .Save (section, (*pSaveGroup) , IsExact (), true ))
340
+ if (!section.Objects .Save (section, group , IsExact (), true ))
277
341
{
278
342
Log (C4ResStrTableKey::IDS_ERR_SAVE_OBJECTS);
279
343
return false ;
280
344
}
281
345
346
+ // Save core for non-scenarios
347
+ if (!IsExact ())
348
+ {
349
+ C4Scenario c4s;
350
+ c4s.Animals = rC4S.Animals ;
351
+ c4s.Disasters = rC4S.Disasters ;
352
+ c4s.Environment = rC4S.Environment ;
353
+ c4s.Game = rC4S.Game ;
354
+ c4s.Landscape = rC4S.Landscape ;
355
+ std::ranges::copy (rC4S.PlrStart , c4s.PlrStart );
356
+ c4s.Weather = rC4S.Weather ;
357
+
358
+ if (!c4s.Save (group))
359
+ {
360
+ return false ;
361
+ }
362
+ }
363
+
364
+ if (saveRuntimeData)
365
+ {
366
+ if (!section.SaveRuntimeData (group))
367
+ {
368
+ return false ;
369
+ }
370
+ }
371
+
282
372
return true ;
283
373
}
284
374
@@ -308,7 +398,7 @@ bool C4GameSave::SaveDesc(C4Group &hToGroup)
308
398
309
399
// Save to file
310
400
StdStrBuf buf{desc.c_str (), desc.size ()};
311
- return !!hToGroup.Add (fmt::sprintf (C4CFN_ScenarioDesc, szLang).c_str (), buf, false , true );
401
+ return !!hToGroup.Add (std::format (C4CFN_ScenarioDesc, szLang).c_str (), buf, false , true );
312
402
}
313
403
314
404
void C4GameSave::WriteDescLineFeed (std::string &desc)
@@ -500,7 +590,7 @@ bool C4GameSave::Save(C4Group &hToGroup, bool fKeepGroup)
500
590
{
501
591
pSaveGroup->Delete (C4CFN_ScenarioTitle);
502
592
pSaveGroup->Delete (C4CFN_ScenarioIcon);
503
- pSaveGroup->Delete (fmt::sprintf (C4CFN_ScenarioDesc, " *" ).c_str ());
593
+ pSaveGroup->Delete (std::format (C4CFN_ScenarioDesc, " *" ).c_str ());
504
594
pSaveGroup->Delete (C4CFN_Titles);
505
595
pSaveGroup->Delete (C4CFN_Info);
506
596
}
@@ -533,7 +623,12 @@ bool C4GameSave::Close()
533
623
// close if owned group
534
624
if (fOwnGroup )
535
625
{
536
- fSuccess = !!pSaveGroup->Close ();
626
+ fSuccess = !!pSaveGroup->Save (false );
627
+ if (!fSuccess )
628
+ {
629
+ LogNTr (spdlog::level::err, " Error closing save file group: {}" , pSaveGroup->GetError ());
630
+ }
631
+ pSaveGroup->Close ();
537
632
delete pSaveGroup;
538
633
fOwnGroup = false ;
539
634
}
0 commit comments