OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4GameSave.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // game saving functionality
17 
18 #include "C4Include.h"
19 #include "control/C4GameSave.h"
20 
21 #include "C4Version.h"
22 #include "c4group/C4Components.h"
24 #include "control/C4Record.h"
25 #include "control/C4RoundResults.h"
26 #include "landscape/C4Landscape.h"
27 #include "landscape/C4MassMover.h"
28 #include "landscape/C4PXS.h"
29 #include "player/C4PlayerList.h"
30 #include "network/C4Network2.h"
31 #include "script/C4Value.h"
32 
33 // *** C4GameSave main class
34 
35 bool C4GameSave::SaveCreateGroup(const char *szFilename, C4Group &hUseGroup)
36 {
37  // erase any previous item (2do: work in C4Groups?)
38  EraseItem(szFilename);
39  // copy from previous group?
40  if (GetCopyScenario())
41  if (!ItemIdentical(Game.ScenarioFilename, szFilename))
42  if (!C4Group_CopyItem(Game.ScenarioFilename, szFilename))
43  { LogF(LoadResStr("IDS_CNS_SAVEASERROR"), szFilename); return false; }
44  // open it
45  if (!hUseGroup.Open(szFilename, !GetCopyScenario()))
46  {
47  EraseItem(szFilename);
48  LogF(LoadResStr("IDS_CNS_SAVEASERROR"), szFilename);
49  return false;
50  }
51  // done, success
52  return true;
53 }
54 
55 bool C4GameSave::SaveCore()
56 {
57  // base on original, current core
58  rC4S = Game.C4S;
59  // Always mark current engine version
60  rC4S.Head.C4XVer[0]=C4XVER1; rC4S.Head.C4XVer[1]=C4XVER2;
61  // Some flags are not to be set for initial settings:
62  // They depend on whether specific runtime data is present, which may simply not be stored into initial
63  // saves, because they rely on any data present and up-to-date within the scenario!
64  if (!fInitial)
65  {
66  // NoInitialize: Marks whether object data is contained and not to be created from core
67  rC4S.Head.NoInitialize = true;
68  // the SaveGame-value, despite it's name, marks whether exact runtime data is contained
69  // the flag must not be altered for pure
71  }
72  // some values relevant for synced saves only
73  if (IsExact())
74  {
76  }
77  // reset some network flags
78  rC4S.Head.NetworkGame=false;
79  // Title in language game was started in (not: save scenarios and net references)
80  if (!GetKeepTitle())
81  {
83  }
84  // some adjustments for everything but saved scenarios
85  if (IsExact())
86  {
87  // Store used definitions
89  // Save game parameters
90  if (!Game.Parameters.Save(*pSaveGroup, &Game.C4S)) return false;
91  }
92  // clear MissionAccess in save games and records (sulai)
93  rC4S.Head.MissionAccess.clear();
94  // store origin
95  if (GetSaveOrigin())
96  {
97  // keep if assigned already (e.g., when doing a record of a savegame)
98  if (!rC4S.Head.Origin.getLength())
99  {
102  }
103  }
104  else if (GetClearOrigin())
105  rC4S.Head.Origin.Clear();
106  // adjust specific values (virtual call)
107  AdjustCore(rC4S);
108  // Save scenario core
109  return !!rC4S.Save(*pSaveGroup);
110 }
111 
112 bool C4GameSave::SaveScenarioSections()
113 {
114  // any scenario sections?
115  if (!Game.pScenarioSections) return true;
116  // prepare section filename
117  int iWildcardPos = SCharPos('*', C4CFN_ScenarioSections);
118  char fn[_MAX_FNAME+1];
119  // save all modified sections
120  for (C4ScenarioSection *pSect = Game.pScenarioSections; pSect; pSect = pSect->pNext)
121  {
122  // compose section filename
124  SDelete(fn, 1, iWildcardPos); SInsert(fn, pSect->name.getData(), iWildcardPos);
125  // do not save self, because that is implied in CurrentScenarioSection and the main landscape/object data
126  if (pSect == Game.pCurrentScenarioSection)
127  pSaveGroup->DeleteEntry(fn);
128  else if (pSect->fModified)
129  {
130  // modified section: delete current
131  pSaveGroup->DeleteEntry(fn);
132  // replace by new
133  pSaveGroup->Add(pSect->temp_filename.getData(), fn);
134  }
135  }
136  // done, success
137  return true;
138 }
139 
140 bool C4GameSave::SaveLandscape()
141 {
142  // exact?
144  {
145  C4DebugRecOff DBGRECOFF;
146  // Landscape
147  bool fSuccess;
149  fSuccess = !!::Landscape.Save(*pSaveGroup);
150  else
151  fSuccess = !!::Landscape.SaveDiff(*pSaveGroup, !IsSynced());
152  if (!fSuccess) return false;
153  DBGRECOFF.Clear();
154  // PXS
155  if (!::PXS.Save(*pSaveGroup)) return false;
156  // MassMover (create copy, may not modify running data)
157  C4MassMoverSet MassMoverSet;
158  MassMoverSet.Copy(::MassMover);
159  if (!MassMoverSet.Save(*pSaveGroup)) return false;
160  // Material enumeration
161  if (!::MaterialMap.SaveEnumeration(*pSaveGroup)) return false;
162  }
163  // static / dynamic
165  {
166  // static map
167  // remove old-style landscape.bmp
169  // save materials if not already done
170  if (!GetForceExactLandscape())
171  {
172  // save map
173  if (!::Landscape.SaveMap(*pSaveGroup)) return false;
174  // save textures (if changed)
175  if (!::Landscape.SaveTextures(*pSaveGroup)) return false;
176  }
177  }
178  else if (::Landscape.GetMode() != LandscapeMode::Exact)
179  {
180  // dynamic map by landscape.txt or scenario core: nothing to save
181  // in fact, it doesn't even make much sense to save the Objects.txt
182  // but the user pressed save after all...
183  }
184  return true;
185 }
186 
187 bool C4GameSave::SaveRuntimeData()
188 {
189  // Game.txt data (general runtime data and objects)
190  C4ValueNumbers numbers;
191  if (!Game.SaveData(*pSaveGroup, false, IsExact(), IsSynced(), &numbers))
192  { Log(LoadResStr("IDS_ERR_SAVE_RUNTIMEDATA")); return false; }
193  // scenario sections (exact only)
194  if (IsExact()) if (!SaveScenarioSections())
195  { Log(LoadResStr("IDS_ERR_SAVE_SCENSECTIONS")); return false; }
196  // landscape
197  if (!SaveLandscape()) { Log(LoadResStr("IDS_ERR_SAVE_LANDSCAPE")); return false; }
198  // Round results
200  { Log(LoadResStr("IDS_ERR_ERRORSAVINGROUNDRESULTS")); return false; }
201  // Teams
202  if (!Game.Teams.Save(*pSaveGroup))
203  { Log(LoadResStr(LoadResStr("IDS_ERR_ERRORSAVINGTEAMS"))); return false; }
205  {
206  // player infos
207  // the stored player info filenames will point into the scenario file, and no resource information
208  // will be saved. PlayerInfo must be saved first, because those will generate the storage filenames to be used by
209  // C4PlayerList
210  C4PlayerInfoList RestoreInfos;
212  if (!RestoreInfos.Save(*pSaveGroup, C4CFN_SavePlayerInfos))
213  { Log(LoadResStr("IDS_ERR_SAVE_RESTOREPLAYERINFOS")); return false; }
214  // Players
215  // this will save the player files to the savegame scenario group only
216  // synchronization to the original player files will be done in global game
217  // synchronization (via control queue)
219  {
220  if (!::Players.Save((*pSaveGroup), GetCreateSmallFile(), RestoreInfos))
221  { Log(LoadResStr("IDS_ERR_SAVE_PLAYERS")); return false; }
222  }
223  }
224  else
225  {
226  // non-exact runtime data: remove any exact files
227  // No player files
230  }
231  // done, success
232  return true;
233 }
234 
236 {
237  // Unfortunately, there's no way to prealloc the buffer in an appropriate size
238  StdStrBuf sBuffer;
239 
240  // Scenario title
241  sBuffer.Append(Game.ScenarioTitle.getData());
242  sBuffer.Append(LineFeed LineFeed);
243 
244  // OK; each specializations has its own desc format
245  WriteDesc(sBuffer);
246 
247  // Generate Filename
248  StdStrBuf sFilename; char szLang[3];
249  SCopyUntil(Config.General.Language, szLang, ',', 2);
250  sFilename.Format(C4CFN_ScenarioDesc,szLang);
251 
252  // Save to file
253  return !!hToGroup.Add(sFilename.getData(),sBuffer,false,true);
254 }
255 
257 {
258  // paragraph end + cosmetics
259  sBuf.Append(LineFeed LineFeed);
260 }
261 
262 void C4GameSave::WriteDescDate(StdStrBuf &sBuf, bool fRecord)
263 {
264  // write local time/date
265  time_t tTime; time(&tTime);
266  struct tm *pLocalTime;
267  pLocalTime=localtime(&tTime);
268  sBuf.AppendFormat(LoadResStr(fRecord ? "IDS_DESC_DATEREC" : (::Network.isEnabled() ? "IDS_DESC_DATENET" : "IDS_DESC_DATE")),
269  pLocalTime->tm_mday,
270  pLocalTime->tm_mon+1,
271  pLocalTime->tm_year+1900,
272  pLocalTime->tm_hour,
273  pLocalTime->tm_min);
274  WriteDescLineFeed(sBuf);
275 }
276 
278 {
279  // Write game duration
280  if (Game.Time)
281  {
282  sBuf.AppendFormat(LoadResStr("IDS_DESC_DURATION"),
283  Game.Time/3600,(Game.Time%3600)/60,Game.Time%60);
284  WriteDescLineFeed(sBuf);
285  }
286 }
287 
289 {
290  char ver[32]; sprintf(ver, "%d.%d", (int)C4XVER1, (int)C4XVER2);
291  sBuf.AppendFormat(LoadResStr("IDS_DESC_VERSION"), ver);
292  WriteDescLineFeed(sBuf);
293 }
294 
295 void C4GameSave::WriteDescLeague(StdStrBuf &sBuf, bool fLeague, const char *strLeagueName)
296 {
297  if (fLeague)
298  {
299  sBuf.AppendFormat(LoadResStr("IDS_PRC_LEAGUE"), strLeagueName);
300  WriteDescLineFeed(sBuf);
301  }
302 }
303 
305 {
306  // Definition specs
307  if (Game.DefinitionFilenames[0])
308  {
309  char szDef[_MAX_PATH+1];
310  // Desc
311  sBuf.Append(LoadResStr("IDS_DESC_DEFSPECS"));
312  // Get definition modules
313  for (int cnt=0; SGetModule(Game.DefinitionFilenames,cnt,szDef); cnt++)
314  {
315  // Get exe relative path
316  StdStrBuf sDefFilename;
317  sDefFilename.Copy(Config.AtRelativePath(szDef));
318  // Append comma
319  if (cnt>0) sBuf.Append(", ");
320  // Apend to desc
321  sBuf.Append(sDefFilename);
322  }
323  // End of line
324  WriteDescLineFeed(sBuf);
325  }
326 }
327 
329 {
330  // Desc
331  sBuf.Append(LoadResStr("IDS_DESC_CLIENTS"));
332  // Client names
333  for (C4Network2Client *pClient=::Network.Clients.GetNextClient(nullptr); pClient; pClient=::Network.Clients.GetNextClient(pClient))
334  { sBuf.Append(", "); sBuf.Append(pClient->getName()); }
335  // End of line
336  WriteDescLineFeed(sBuf);
337 }
338 
339 void C4GameSave::WriteDescPlayers(StdStrBuf &sBuf, bool fByTeam, int32_t idTeam)
340 {
341  // write out all players; only if they match the given team if specified
342  C4PlayerInfo *pPlr; bool fAnyPlrWritten = false;
343  for (int i = 0; (pPlr = Game.PlayerInfos.GetPlayerInfoByIndex(i)); i++)
344  if (pPlr->HasJoined() && !pPlr->IsRemoved() && !pPlr->IsInvisible())
345  {
346  if (fByTeam)
347  {
348  if (idTeam)
349  {
350  // match team
351  if (pPlr->GetTeam() != idTeam) continue;
352  }
353  else
354  {
355  // must be in no known team
356  if (Game.Teams.GetTeamByID(pPlr->GetTeam())) continue;
357  }
358  }
359  if (fAnyPlrWritten)
360  sBuf.Append(", ");
361  else if (fByTeam && idTeam)
362  {
363  C4Team *pTeam = Game.Teams.GetTeamByID(idTeam);
364  if (pTeam) sBuf.AppendFormat("%s: ", pTeam->GetName());
365  }
366  sBuf.Append(pPlr->GetName());
367  fAnyPlrWritten = true;
368  }
369  if (fAnyPlrWritten) WriteDescLineFeed(sBuf);
370 }
371 
373 {
374  // New style using Game.PlayerInfos
376  {
377  sBuf.Append(LoadResStr("IDS_DESC_PLRS"));
379  {
380  // Teams defined: Print players sorted by teams
381  WriteDescLineFeed(sBuf);
382  C4Team *pTeam; int32_t i=0;
383  while ((pTeam = Game.Teams.GetTeamByIndex(i++)))
384  {
385  WriteDescPlayers(sBuf, true, pTeam->GetID());
386  }
387  // Finally, print out players outside known teams (those can only be achieved by script using SetPlayerTeam)
388  WriteDescPlayers(sBuf, true, 0);
389  }
390  else
391  {
392  // No teams defined: Print all players that have ever joined
393  WriteDescPlayers(sBuf, false, 0);
394  }
395  }
396 }
397 
398 bool C4GameSave::Save(const char *szFilename)
399 {
400  // close any previous
401  Close();
402  // create group
403  C4Group *pLSaveGroup = new C4Group();
404  if (!SaveCreateGroup(szFilename, *pLSaveGroup))
405  {
406  LogF(LoadResStr("IDS_ERR_SAVE_TARGETGRP"), szFilename ? szFilename : "nullptr!");
407  delete pLSaveGroup;
408  return false;
409  }
410  // save to it
411  return Save(*pLSaveGroup, true);
412 }
413 
414 bool C4GameSave::Save(C4Group &hToGroup, bool fKeepGroup)
415 {
416  // close any previous
417  Close();
418  // set group
419  pSaveGroup = &hToGroup; fOwnGroup = fKeepGroup;
420  // PreSave-actions (virtual call)
421  if (!OnSaving()) return false;
422  // always save core
423  if (!SaveCore()) { Log(LoadResStr("IDS_ERR_SAVE_CORE")); return false; }
424  // cleanup group
426  // remove: Title text, image and icon if specified
427  if (!GetKeepTitle())
428  {
434  }
435  // save additional runtime data
436  if (GetSaveRuntimeData()) if (!SaveRuntimeData()) return false;
437  // Desc
438  if (GetSaveDesc())
439  if (!SaveDesc(*pSaveGroup))
440  Log(LoadResStr("IDS_ERR_SAVE_DESC")); /* nofail */
441  // save specialized components (virtual call)
442  if (!SaveComponents()) return false;
443  // done, success
444  return true;
445 }
446 
448 {
449  bool fSuccess = true;
450  // any group open?
451  if (pSaveGroup)
452  {
453  // sort group
454  const char *szSortOrder = GetSortOrder();
455  if (szSortOrder) pSaveGroup->Sort(szSortOrder);
456  // close if owned group
457  if (fOwnGroup)
458  {
459  fSuccess = !!pSaveGroup->Close();
460  delete pSaveGroup;
461  fOwnGroup = false;
462  }
463  pSaveGroup = nullptr;
464  }
465  return fSuccess;
466 }
467 
468 
469 // *** C4GameSaveSavegame
470 
472 {
473  if (!Game.IsRunning) return true;
474  // synchronization to sync player files on all clients
475  // this resets playing times and stores them in the players?
476  // but doing so would be too late when the queue is executed!
477  // TODO: remove it? (-> PeterW ;))
478  if (::Network.isEnabled())
480  else
482  // OK; save now
483  return true;
484 }
485 
487 {
488  // Determine save game index from trailing number in group file name
489  int iSaveGameIndex = GetTrailingNumber(GetFilenameOnly(pSaveGroup->GetFullName().getData()));
490  // Looks like a decent index: set numbered icon
491  if (Inside(iSaveGameIndex, 1, 10))
492  rC4S.Head.Icon = 2 + (iSaveGameIndex - 1);
493  // Else: set normal script icon
494  else
495  rC4S.Head.Icon = 29;
496 }
497 
499 {
500  // special for savegames: save a screenshot
501  if (!Game.SaveGameTitle((*pSaveGroup)))
502  Log(LoadResStr("IDS_ERR_SAVE_GAMETITLE")); /* nofail */
503  // done, success
504  return true;
505 }
506 
508 {
509  // compose savegame desc
510  WriteDescDate(sBuf);
511  WriteDescGameTime(sBuf);
512  WriteDescDefinitions(sBuf);
514  WriteDescPlayers(sBuf);
515  // done, success
516  return true;
517 }
518 
519 
520 // *** C4GameSaveRecord
521 
523 {
524  // specific recording flags
525  rC4S.Head.Replay=true;
526  if (!rC4S.Head.Film) rC4S.Head.Film=C4SFilm_Normal; /* default to film */
527  rC4S.Head.Icon=29;
528  // default record title
529  char buf[1024 + 1];
530  sprintf(buf, "%03i %s [%d.%d]", iNum, Game.ScenarioTitle.getData(), (int)C4XVER1, (int)C4XVER2);
531  rC4S.Head.Title = buf;
532 }
533 
535 {
536  // special: records need player infos even if done initially
538  // for !fInitial, player infos will be saved as regular runtime data
539  // done, success
540  return true;
541 }
542 
544 {
545  // compose record desc
546  WriteDescDate(sBuf, true);
547  WriteDescGameTime(sBuf);
548  WriteDescEngine(sBuf);
549  WriteDescDefinitions(sBuf);
550  WriteDescLeague(sBuf, fLeague, Game.Parameters.League.getData());
552  WriteDescPlayers(sBuf);
553  // done, success
554  return true;
555 }
556 
557 
558 // *** C4GameSaveNetwork
559 
561 {
562  // specific dynamic flags
563  rC4S.Head.NetworkGame=true;
565 }
void Copy(C4MassMoverSet &rSet)
const char * getData() const
Definition: StdBuf.h:442
StdCopyStrBuf Origin
Definition: C4Scenario.h:80
bool IsRunning
Definition: C4Game.h:139
bool SGetModule(const char *szList, int iIndex, char *sTarget, int iSize)
Definition: Standard.cpp:533
int32_t Icon
Definition: C4Scenario.h:68
virtual bool GetCopyScenario()
Definition: C4GameSave.h:60
bool NetworkRuntimeJoin
Definition: C4Scenario.h:79
int32_t GetID() const
Definition: C4Teams.h:66
virtual void AdjustCore(C4Scenario &rC4S)
Definition: C4GameSave.h:72
char ScenarioFilename[_MAX_PATH+1]
Definition: C4Game.h:102
C4Config Config
Definition: C4Config.cpp:833
int32_t RandomSeed
Definition: C4Game.h:134
const char * GetName() const
Definition: C4PlayerInfo.h:157
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
C4SDefinitions Definitions
Definition: C4Scenario.h:231
bool SynchronizeLocalFiles()
C4Network2Client * GetNextClient(C4Network2Client *pClient)
bool Save(C4Group &hGroup, bool fSaveSection=false)
Definition: C4Scenario.cpp:114
int32_t GetPlayerCount() const
bool ItemIdentical(const char *szFilename1, const char *szFilename2)
Definition: StdFile.cpp:855
C4Game Game
Definition: C4Globals.cpp:52
bool fOwnGroup
Definition: C4GameSave.h:39
bool SetAsRestoreInfos(C4PlayerInfoList &rFromPlayers, bool fSaveUserPlrs, bool fSaveScriptPlrs, bool fSetUserPlrRefToLocalGroup, bool fSetScriptPlrRefToLocalGroup)
C4Scenario C4S
Definition: C4Game.h:74
std::string MissionAccess
Definition: C4Scenario.h:76
void Clear()
Definition: StdBuf.h:466
C4ConfigGeneral General
Definition: C4Config.h:251
#define sprintf
Definition: Standard.h:164
Definition: C4Teams.h:30
StdCopyStrBuf ScenarioTitle
Definition: C4Game.h:103
bool Replay
Definition: C4Scenario.h:72
C4Group * pSaveGroup
Definition: C4GameSave.h:38
bool IsAutoGenerateTeams() const
Definition: C4Teams.h:172
StdCopyStrBuf League
void Add(C4PacketType eType, C4ControlPacket *pCtrl)
Definition: C4Control.h:82
void WriteDescNetworkClients(StdStrBuf &sBuf)
Definition: C4GameSave.cpp:328
C4PlayerInfo * GetPlayerInfoByIndex(int32_t index) const
bool IsInvisible() const
Definition: C4PlayerInfo.h:175
void Clear()
Definition: C4Record.cpp:52
void WriteDescEngine(StdStrBuf &sBuf)
Definition: C4GameSave.cpp:288
std::string Title
Definition: C4Scenario.h:64
void AdjustCore(C4Scenario &rC4S) override
Definition: C4GameSave.cpp:560
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
bool IsMultiTeams() const
Definition: C4Teams.h:162
bool IsExact()
Definition: C4GameSave.h:78
bool Delete(const char *szFiles, bool fRecursive=false)
Definition: C4Group.cpp:1334
C4Team * GetTeamByID(int32_t iID) const
Definition: C4Teams.cpp:383
#define C4CFN_Titles
Definition: C4Components.h:146
#define _MAX_PATH
const char * GetFilenameOnly(const char *strFilename)
Definition: StdFile.cpp:60
void WriteDescLineFeed(StdStrBuf &sBuf)
Definition: C4GameSave.cpp:256
bool SaveData(C4Group &hGroup, bool fSaveSection, bool fSaveExact, bool fSaveSync, C4ValueNumbers *)
Definition: C4Game.cpp:1775
#define C4CFN_Landscape
Definition: C4Components.h:60
C4GameParameters & Parameters
Definition: C4Game.h:67
virtual bool GetSaveOrigin()
Definition: C4GameSave.h:64
void WriteDescGameTime(StdStrBuf &sBuf)
Definition: C4GameSave.cpp:277
bool Save(C4Group &hGroup)
Definition: C4PXS.cpp:325
C4TeamList & Teams
Definition: C4Game.h:70
bool Save(C4Group &hGroup, const char *szToFile)
virtual const char * GetSortOrder()
Definition: C4GameSave.h:61
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
bool SaveTextures(C4Group &hGroup) const
void AppendFormat(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:190
int GetTrailingNumber(const char *strString)
Definition: StdFile.cpp:87
#define C4CFN_PlayerFiles
Definition: C4Components.h:168
bool SaveEnumeration(C4Group &hGroup)
Definition: C4Material.cpp:570
bool SaveDiff(C4Group &hGroup, bool fSyncSave) const
bool Save(C4Group &hGroup)
Definition: C4Teams.cpp:646
void WriteDescLeague(StdStrBuf &sBuf, bool fLeague, const char *strLeagueName)
Definition: C4GameSave.cpp:295
#define C4CFN_Info
Definition: C4Components.h:70
bool SaveGame
Definition: C4Scenario.h:71
bool SaveDesc(C4Group &hToGroup)
Definition: C4GameSave.cpp:235
bool Close()
Definition: C4GameSave.cpp:447
C4Network2 Network
Definition: C4Globals.cpp:53
bool Save(const char *szFilename)
Definition: C4GameSave.cpp:398
void WriteDescDate(StdStrBuf &sBuf, bool fRecord=false)
Definition: C4GameSave.cpp:262
char UserDataPath[CFG_MaxString+1]
Definition: C4Config.h:54
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2078
#define C4CFN_SavePlayerInfos
Definition: C4Components.h:125
C4Landscape Landscape
bool Save(C4Group &hGroup)
void SInsert(char *szString, const char *szInsert, int iPosition, int iMaxLen)
Definition: Standard.cpp:503
virtual bool GetSaveDesc()
Definition: C4GameSave.h:59
bool SaveGameTitle(C4Group &hGroup)
Definition: C4Game.cpp:1829
#define C4CFN_ScenarioSections
Definition: C4Components.h:38
bool Open(const char *szGroupName, bool fCreate=false)
Definition: C4Group.cpp:514
virtual bool GetKeepTitle()
Definition: C4GameSave.h:58
int32_t C4XVer[2]
Definition: C4Scenario.h:63
virtual bool GetSaveRuntimeData()
Definition: C4GameSave.h:57
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519
C4Team * GetTeamByIndex(int32_t iIndex) const
Definition: C4Teams.cpp:404
C4PlayerList Players
bool C4Group_CopyItem(const char *szSource, const char *szTarget1, bool fNoSort, bool fResetAttributes)
Definition: C4Group.cpp:100
bool Save(C4Group &hGroup) const
int32_t Time
Definition: C4Game.h:131
int32_t GetTeam() const
Definition: C4PlayerInfo.h:195
bool NetworkGame
Definition: C4Scenario.h:78
bool IsRemoved() const
Definition: C4PlayerInfo.h:164
bool IsSynced()
Definition: C4GameSave.h:79
C4ScenarioSection * pScenarioSections
Definition: C4Game.h:91
char SystemDataPath[CFG_MaxString+1]
Definition: C4Config.h:55
const char * GetName() const
Definition: C4Teams.h:65
bool Close()
Definition: C4Group.cpp:755
C4PXSSystem PXS
Definition: C4PXS.cpp:423
void WriteDescDefinitions(StdStrBuf &sBuf)
Definition: C4GameSave.cpp:304
#define _MAX_FNAME
virtual bool GetCreateSmallFile()
Definition: C4GameSave.h:62
bool isEnabled() const
Definition: C4Network2.h:203
bool WriteDesc(StdStrBuf &sBuf) override
Definition: C4GameSave.cpp:543
C4RoundResults & RoundResults
Definition: C4Game.h:73
bool Save(C4Group &hGroup, C4Scenario *pDefault)
char Language[CFG_MaxString+1]
Definition: C4Config.h:36
LandscapeMode GetMode() const
bool WriteDesc(StdStrBuf &sBuf) override
Definition: C4GameSave.cpp:507
bool OnSaving() override
Definition: C4GameSave.cpp:471
C4Control & Input
Definition: C4Game.h:82
#define LineFeed
Definition: Standard.h:147
void SDelete(char *szString, int iLen, int iPosition)
Definition: Standard.cpp:515
#define C4CFN_PlayerInfos
Definition: C4Components.h:124
bool DeleteEntry(const char *szFilename, bool fRecycle=false)
Definition: C4Group.cpp:1384
C4MassMoverSet MassMover
C4Network2ClientList Clients
Definition: C4Network2.h:116
bool SaveComponents() override
Definition: C4GameSave.cpp:498
C4PlayerInfoList & PlayerInfos
Definition: C4Game.h:71
virtual bool GetSaveUserPlayers()
Definition: C4GameSave.h:66
bool Save(C4Group &hGroup, const char *szFilename=C4CFN_RoundResults)
void AdjustCore(C4Scenario &rC4S) override
Definition: C4GameSave.cpp:486
virtual bool GetSaveScriptPlayers()
Definition: C4GameSave.h:67
virtual bool SaveComponents()
Definition: C4GameSave.h:74
virtual bool GetSaveUserPlayerFiles()
Definition: C4GameSave.h:68
bool fInitial
Definition: C4GameSave.h:45
#define C4CFN_ScenarioDesc
Definition: C4Components.h:88
bool EraseItem(const char *szItemName)
Definition: StdFile.cpp:809
void SetModules(const char *szList, const char *szRelativeToPath=nullptr, const char *szRelativeToPath2=nullptr)
Definition: C4Scenario.cpp:462
virtual bool OnSaving()
Definition: C4GameSave.h:75
void ForceRelativePath(StdStrBuf *sFilename)
Definition: C4Config.cpp:664
void WriteDescPlayers(StdStrBuf &sBuf, bool fByTeam, int32_t idTeam)
Definition: C4GameSave.cpp:339
C4MaterialMap MaterialMap
Definition: C4Material.cpp:970
bool Log(const char *szMessage)
Definition: C4Log.cpp:202
bool Add(const char *szFile, const char *szAddAs)
Definition: C4Group.cpp:1316
char DefinitionFilenames[20 *_MAX_PATH+1]
Definition: C4Game.h:105
size_t getLength() const
Definition: StdBuf.h:445
bool Sort(const char *szSortList)
Definition: C4Group.cpp:1963
int SCharPos(char cTarget, const char *szInStr, int iIndex)
Definition: Standard.cpp:233
void AdjustCore(C4Scenario &rC4S) override
Definition: C4GameSave.cpp:522
C4SHead Head
Definition: C4Scenario.h:230
const char * AtRelativePath(const char *szFilename)
Definition: C4Config.cpp:656
bool SaveMap(C4Group &hGroup) const
virtual bool GetSaveScriptPlayerFiles()
Definition: C4GameSave.h:69
C4ScenarioSection * pNext
Definition: C4Scenario.h:264
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:260
#define C4CFN_ScenarioIcon
Definition: C4Components.h:85
bool HasJoined() const
Definition: C4PlayerInfo.h:165
bool NoInitialize
Definition: C4Scenario.h:69
virtual bool GetClearOrigin()
Definition: C4GameSave.h:65
virtual bool WriteDesc(StdStrBuf &sBuf)
Definition: C4GameSave.h:73
void Copy()
Definition: StdBuf.h:467
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:43
#define C4CFN_ScenarioTitle
Definition: C4Components.h:84
bool Save(bool fSaveLocalOnly)
void SCopyUntil(const char *szSource, char *sTarget, char cUntil, int iMaxL, int iIndex)
Definition: Standard.cpp:168
C4ScenarioSection * pCurrentScenarioSection
Definition: C4Game.h:91
int32_t RandomSeed
Definition: C4Scenario.h:74
int32_t Film
Definition: C4Scenario.h:73
virtual bool GetForceExactLandscape()
Definition: C4GameSave.h:63
bool SaveComponents() override
Definition: C4GameSave.cpp:534
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270