OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4ObjectInfoList.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Dynamic list for crew member info */
19 
20 #include "C4Include.h"
22 
23 #include "object/C4Def.h"
24 #include "object/C4DefList.h"
25 #include "object/C4ObjectInfo.h"
26 #include "c4group/C4Components.h"
27 #include "game/C4Game.h"
28 #include "player/C4RankSystem.h"
29 #include "config/C4Config.h"
30 #include "object/C4GameObjects.h"
31 
33 {
34  Default();
35 }
36 
38 {
39  Clear();
40 }
41 
43 {
44  First=nullptr;
45  iNumCreated=0;
46 }
47 
49 {
50  C4ObjectInfo *next;
51  while (First)
52  {
53  next=First->Next;
54  delete First;
55  First=next;
56  }
57 }
58 
60 {
61  C4ObjectInfo *ninf;
62  int32_t infn=0;
63  char entryname[256+1];
64 
65  // Search all oci files
66  hGroup.ResetSearch();
67  while (hGroup.FindNextEntry(C4CFN_ObjectInfoFiles,entryname))
68  if ((ninf=new C4ObjectInfo))
69  {
70  if (ninf->Load(hGroup,entryname)) { Add(ninf); infn++; }
71  else delete ninf;
72  }
73 
74  // Search subfolders
75  hGroup.ResetSearch();
76  while (hGroup.FindNextEntry("*", entryname))
77  {
78  C4Group ItemGroup;
79  if (ItemGroup.OpenAsChild(&hGroup, entryname))
80  Load(ItemGroup);
81  }
82 
83  return infn;
84 }
85 
87 {
88  if (!pInfo) return false;
89  pInfo->Next=First;
90  First=pInfo;
91  return true;
92 }
93 
95 {
96  char tstr[_MAX_PATH];
97  int32_t iname;
98  size_t namelen = SLen(sName);
99  for (iname=2; NameExists(sName); iname++)
100  {
101  sprintf(tstr," %d",iname);
102  SCopy(tstr, sName + std::min(namelen, C4MaxName - SLen(tstr)));
103  }
104 }
105 
106 bool C4ObjectInfoList::NameExists(const char *szName)
107 {
108  C4ObjectInfo *cinf;
109  for (cinf=First; cinf; cinf=cinf->Next)
110  if (SEqualNoCase(szName,cinf->Name))
111  return true;
112  return false;
113 }
114 
116 {
117  C4Def *pDef;
118  C4ObjectInfo *pInfo;
119  C4ObjectInfo *pHiExp=nullptr;
120 
121  // Search list
122  for (pInfo=First; pInfo; pInfo=pInfo->Next)
123  // Valid only
124  if ((pDef = rDefs.ID2Def(pInfo->id)))
125  // Use standard crew or matching id
126  if ( (!c_id && !pDef->NativeCrew) || (pInfo->id==c_id) )
127  // Participating and not in action
128  if (pInfo->Participation && !pInfo->InAction && !pInfo->HasDied)
129  // Highest experience
130  if (!pHiExp || (pInfo->Experience>pHiExp->Experience))
131  // Set this
132  pHiExp=pInfo;
133 
134  // Found
135  if (pHiExp)
136  {
137  pHiExp->Recruit();
138  return pHiExp;
139  }
140 
141  return nullptr;
142 }
143 
145 {
146  C4ObjectInfo *pInfo;
147  // Create new info object
148  if (!(pInfo = new C4ObjectInfo)) return nullptr;
149  // Default type clonk if none specified
150  if (n_id == C4ID::None) n_id = C4ID::Clonk;
151  // Check type valid and def available
152  C4Def *pDef = nullptr;
153  if (pDefs)
154  if (!(pDef = pDefs->ID2Def(n_id)))
155  { delete pInfo; return nullptr; }
156  // Set name source
157  const char *cpNames = Game.Names.GetData();
158  if (pDef->pClonkNames) cpNames = pDef->pClonkNames->GetData();
159  // Default by type
160  ((C4ObjectInfoCore*)pInfo)->Default(n_id, pDefs, cpNames);
161  // Set birthday
162  pInfo->Birthday=time(nullptr);
163  // Make valid names
164  MakeValidName(pInfo->Name);
165  // Add
166  Add(pInfo);
167  ++iNumCreated;
168  return pInfo;
169 }
170 
172 {
173  C4ObjectInfo *cinf;
174  for (cinf=First; cinf; cinf=cinf->Next)
175  cinf->Evaluate();
176 }
177 
178 bool C4ObjectInfoList::Save(C4Group &hGroup, bool fSavegame, bool fStoreTiny, C4DefList *pDefs)
179 {
180  // Save in opposite order (for identical crew order on load)
181  C4ObjectInfo *pInfo;
182  for (pInfo = GetLast(); pInfo; pInfo = GetPrevious(pInfo))
183  {
184  // don't safe TemporaryCrew in regular player files
185  if (!fSavegame)
186  {
187  C4Def *pDef=C4Id2Def(pInfo->id);
188  if (pDef) if (pDef->TemporaryCrew) continue;
189  }
190  // save
191  if (!pInfo->Save(hGroup, fStoreTiny, pDefs))
192  return false;
193  }
194  return true;
195 }
196 
198 {
199  C4ObjectInfo *pInfo;
200  // Find matching name, participating, alive and not in action
201  for (pInfo=First; pInfo; pInfo=pInfo->Next)
202  if (SEqualNoCase(pInfo->Name,szByName))
203  if (pInfo->Participation && !pInfo->InAction && !pInfo->HasDied)
204  {
205  pInfo->Recruit();
206  return pInfo;
207  }
208  return nullptr;
209 }
210 
212 {
213  C4ObjectInfo *cinf;
214  for (cinf=First; cinf; cinf=cinf->Next)
215  ::Objects.ClearInfo(cinf);
216 }
217 
219 {
220  C4ObjectInfo *cInfo = First;
221  while (cInfo && cInfo->Next) cInfo=cInfo->Next;
222  return cInfo;
223 }
224 
226 {
227  for (C4ObjectInfo *cInfo = First; cInfo; cInfo=cInfo->Next)
228  if (cInfo->Next == pInfo)
229  return cInfo;
230  return nullptr;
231 }
232 
234 {
235  for (C4ObjectInfo *cInfo = First; cInfo; cInfo=cInfo->Next)
236  if (cInfo == pInfo) return true;
237  return false;
238 }
239 
241 {
242  C4ObjectInfo *pInfo, *pPrev;
243  // Search list
244  for (pInfo=First, pPrev=nullptr; pInfo; )
245  {
246  // Invalid?
247  if (!rDefs.ID2Def(pInfo->id))
248  {
249  C4ObjectInfo *pDelete = pInfo;
250  if (pPrev) pPrev->Next = pInfo->Next; else First = pInfo->Next;
251  pInfo = pInfo->Next;
252  delete pDelete;
253  }
254  else
255  {
256  pPrev = pInfo;
257  pInfo = pInfo->Next;
258  }
259  }
260 }
C4Def * ID2Def(C4ID id)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:122
int32_t Load(C4Group &hGroup)
C4Game Game
Definition: C4Globals.cpp:52
#define sprintf
Definition: Standard.h:171
const char * GetData() const
void MakeValidName(char *sName)
void ClearInfo(C4ObjectInfo *pInfo)
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:177
C4ObjectInfo * Next
Definition: C4ObjectInfo.h:41
int32_t NativeCrew
Definition: C4Def.h:115
#define _MAX_PATH
C4ComponentHost * pClonkNames
Definition: C4Def.h:188
#define C4CFN_ObjectInfoFiles
Definition: C4Components.h:169
size_t SLen(const char *sptr)
Definition: Standard.h:78
C4ComponentHost Names
Definition: C4Game.h:80
int32_t Participation
Definition: C4InfoCore.h:39
static const C4ID None
Definition: C4Id.h:42
Definition: C4Def.h:100
int32_t Birthday
Definition: C4InfoCore.h:47
const unsigned int C4MaxName
char Name[C4MaxName+1]
Definition: C4InfoCore.h:38
C4ObjectInfo * First
Definition: C4Id.h:28
bool NameExists(const char *szName)
bool Save(C4Group &hGroup, bool fSavegame, bool fStoreTiny, C4DefList *pDefs)
C4Def * C4Id2Def(C4ID id)
Definition: C4DefList.h:80
bool FindNextEntry(const char *szWildCard, StdStrBuf *sFileName=nullptr, size_t *iSize=nullptr, bool fStartAtFilename=false)
Definition: C4Group.cpp:1780
static const C4ID Clonk
Definition: C4Id.h:45
bool IsElement(C4ObjectInfo *pInfo)
C4ObjectInfo * GetLast()
int32_t Experience
Definition: C4InfoCore.h:44
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1013
bool Add(C4ObjectInfo *pInfo)
int32_t TemporaryCrew
Definition: C4Def.h:143
void Strip(C4DefList &rDefs)
C4ObjectInfo * New(C4ID n_id, C4DefList *pDefs)
C4ObjectInfo * GetIdle(C4ID c_id, C4DefList &rDefs)
bool Load(C4Group &hGroup)
bool OpenAsChild(C4Group *pMother, const char *szEntryName, bool fExclusive=false, bool fCreate=false)
Definition: C4Group.cpp:1585
C4ObjectInfo * GetPrevious(C4ObjectInfo *pInfo)
bool Save(C4Group &hGroup, bool fStoreTiny, C4DefList *pDefs)
C4GameObjects Objects
Definition: C4Globals.cpp:48