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 "c4group/C4Components.h"
24 #include "object/C4Def.h"
25 #include "object/C4DefList.h"
26 #include "object/C4GameObjects.h"
27 #include "object/C4ObjectInfo.h"
28 #include "player/C4RankSystem.h"
29 
31 {
32  Default();
33 }
34 
36 {
37  Clear();
38 }
39 
41 {
42  First=nullptr;
43  iNumCreated=0;
44 }
45 
47 {
48  C4ObjectInfo *next;
49  while (First)
50  {
51  next=First->Next;
52  delete First;
53  First=next;
54  }
55 }
56 
58 {
59  C4ObjectInfo *ninf;
60  int32_t infn=0;
61  char entryname[256+1];
62 
63  // Search all oci files
64  hGroup.ResetSearch();
65  while (hGroup.FindNextEntry(C4CFN_ObjectInfoFiles,entryname))
66  if ((ninf=new C4ObjectInfo))
67  {
68  if (ninf->Load(hGroup,entryname)) { Add(ninf); infn++; }
69  else delete ninf;
70  }
71 
72  // Search subfolders
73  hGroup.ResetSearch();
74  while (hGroup.FindNextEntry("*", entryname))
75  {
76  C4Group ItemGroup;
77  if (ItemGroup.OpenAsChild(&hGroup, entryname))
78  Load(ItemGroup);
79  }
80 
81  return infn;
82 }
83 
85 {
86  if (!pInfo) return false;
87  pInfo->Next=First;
88  First=pInfo;
89  return true;
90 }
91 
93 {
94  char tstr[_MAX_PATH];
95  int32_t iname;
96  size_t namelen = SLen(sName);
97  for (iname=2; NameExists(sName); iname++)
98  {
99  sprintf(tstr," %d",iname);
100  SCopy(tstr, sName + std::min(namelen, C4MaxName - SLen(tstr)));
101  }
102 }
103 
104 bool C4ObjectInfoList::NameExists(const char *szName)
105 {
106  C4ObjectInfo *cinf;
107  for (cinf=First; cinf; cinf=cinf->Next)
108  if (SEqualNoCase(szName,cinf->Name))
109  return true;
110  return false;
111 }
112 
114 {
115  C4Def *pDef;
116  C4ObjectInfo *pInfo;
117  C4ObjectInfo *pHiExp=nullptr;
118 
119  // Search list
120  for (pInfo=First; pInfo; pInfo=pInfo->Next)
121  // Valid only
122  if ((pDef = rDefs.ID2Def(pInfo->id)))
123  // Use standard crew or matching id
124  if ( (!c_id && !pDef->NativeCrew) || (pInfo->id==c_id) )
125  // Participating and not in action
126  if (pInfo->Participation && !pInfo->InAction && !pInfo->HasDied)
127  // Highest experience
128  if (!pHiExp || (pInfo->Experience>pHiExp->Experience))
129  // Set this
130  pHiExp=pInfo;
131 
132  // Found
133  if (pHiExp)
134  {
135  pHiExp->Recruit();
136  return pHiExp;
137  }
138 
139  return nullptr;
140 }
141 
143 {
144  C4ObjectInfo *pInfo;
145  // Create new info object
146  if (!(pInfo = new C4ObjectInfo)) return nullptr;
147  // Default type clonk if none specified
148  if (n_id == C4ID::None) n_id = C4ID::Clonk;
149  // Check type valid and def available
150  C4Def *pDef = nullptr;
151  if (pDefs)
152  if (!(pDef = pDefs->ID2Def(n_id)))
153  { delete pInfo; return nullptr; }
154  // Set name source
155  const char *cpNames = Game.Names.GetData();
156  if (pDef->pClonkNames) cpNames = pDef->pClonkNames->GetData();
157  // Default by type
158  ((C4ObjectInfoCore*)pInfo)->Default(n_id, pDefs, cpNames);
159  // Set birthday
160  pInfo->Birthday=time(nullptr);
161  // Make valid names
162  MakeValidName(pInfo->Name);
163  // Add
164  Add(pInfo);
165  ++iNumCreated;
166  return pInfo;
167 }
168 
170 {
171  C4ObjectInfo *cinf;
172  for (cinf=First; cinf; cinf=cinf->Next)
173  cinf->Evaluate();
174 }
175 
176 bool C4ObjectInfoList::Save(C4Group &hGroup, bool fSavegame, bool fStoreTiny, C4DefList *pDefs)
177 {
178  // Save in opposite order (for identical crew order on load)
179  C4ObjectInfo *pInfo;
180  for (pInfo = GetLast(); pInfo; pInfo = GetPrevious(pInfo))
181  {
182  // don't safe TemporaryCrew in regular player files
183  if (!fSavegame)
184  {
185  C4Def *pDef=C4Id2Def(pInfo->id);
186  if (pDef) if (pDef->TemporaryCrew) continue;
187  }
188  // save
189  if (!pInfo->Save(hGroup, fStoreTiny, pDefs))
190  return false;
191  }
192  return true;
193 }
194 
196 {
197  C4ObjectInfo *pInfo;
198  // Find matching name, participating, alive and not in action
199  for (pInfo=First; pInfo; pInfo=pInfo->Next)
200  if (SEqualNoCase(pInfo->Name,szByName))
201  if (pInfo->Participation && !pInfo->InAction && !pInfo->HasDied)
202  {
203  pInfo->Recruit();
204  return pInfo;
205  }
206  return nullptr;
207 }
208 
210 {
211  C4ObjectInfo *cinf;
212  for (cinf=First; cinf; cinf=cinf->Next)
213  ::Objects.ClearInfo(cinf);
214 }
215 
217 {
218  C4ObjectInfo *cInfo = First;
219  while (cInfo && cInfo->Next) cInfo=cInfo->Next;
220  return cInfo;
221 }
222 
224 {
225  for (C4ObjectInfo *cInfo = First; cInfo; cInfo=cInfo->Next)
226  if (cInfo->Next == pInfo)
227  return cInfo;
228  return nullptr;
229 }
230 
232 {
233  for (C4ObjectInfo *cInfo = First; cInfo; cInfo=cInfo->Next)
234  if (cInfo == pInfo) return true;
235  return false;
236 }
237 
239 {
240  C4ObjectInfo *pInfo, *pPrev;
241  // Search list
242  for (pInfo=First, pPrev=nullptr; pInfo; )
243  {
244  // Invalid?
245  if (!rDefs.ID2Def(pInfo->id))
246  {
247  C4ObjectInfo *pDelete = pInfo;
248  if (pPrev) pPrev->Next = pInfo->Next; else First = pInfo->Next;
249  pInfo = pInfo->Next;
250  delete pDelete;
251  }
252  else
253  {
254  pPrev = pInfo;
255  pInfo = pInfo->Next;
256  }
257  }
258 }
C4Def * ID2Def(C4ID id)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
int32_t Load(C4Group &hGroup)
C4Game Game
Definition: C4Globals.cpp:52
#define sprintf
Definition: Standard.h:164
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:207
C4ObjectInfo * Next
Definition: C4ObjectInfo.h:41
int32_t NativeCrew
Definition: C4Def.h:113
#define _MAX_PATH
C4ComponentHost * pClonkNames
Definition: C4Def.h:185
#define C4CFN_ObjectInfoFiles
Definition: C4Components.h:170
size_t SLen(const char *sptr)
Definition: Standard.h:74
C4ComponentHost Names
Definition: C4Game.h:78
int32_t Participation
Definition: C4InfoCore.h:38
static const C4ID None
Definition: C4Id.h:39
Definition: C4Def.h:98
int32_t Birthday
Definition: C4InfoCore.h:46
const unsigned int C4MaxName
char Name[C4MaxName+1]
Definition: C4InfoCore.h:37
C4ObjectInfo * First
Definition: C4Id.h:25
bool NameExists(const char *szName)
bool Save(C4Group &hGroup, bool fSavegame, bool fStoreTiny, C4DefList *pDefs)
C4Def * C4Id2Def(C4ID id)
Definition: C4DefList.h:84
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:42
bool IsElement(C4ObjectInfo *pInfo)
C4ObjectInfo * GetLast()
int32_t Experience
Definition: C4InfoCore.h:43
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1013
bool Add(C4ObjectInfo *pInfo)
int32_t TemporaryCrew
Definition: C4Def.h:140
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