OpenClonk
C4InfoCore.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 /* Structures for object and player info components */
19 
20 #include "C4Include.h"
21 #include "object/C4InfoCore.h"
22 
23 #include "c4group/C4Components.h"
24 #include "c4group/C4Group.h"
25 #include "lib/C4Markup.h"
26 #include "lib/C4Random.h"
27 #include "object/C4Def.h"
28 #include "object/C4DefList.h"
29 #include "object/C4GameObjects.h"
30 #include "player/C4RankSystem.h"
31 
32 
33 //------------------------------- Player Info ----------------------------------------
34 
36 {
37  Default();
38 }
39 
41 {
42  *Comment = '\0';
43  *RankName = '\0';
44  TotalScore = 0;
45  Rounds = 0;
46  RoundsWon = 0;
47  RoundsLost = 0;
48  TotalPlayingTime = 0;
49  *LeagueName = '\0';
53  Rank = 0;
54  SCopy("Neuling",PrefName);
55  if (pRanks)
56  {
57  SCopy(pRanks->GetRankName(Rank, false).getData(), RankName);
58  }
59  else
60  {
61  SCopy("Rang", RankName);
62  }
63  PrefClonkSkin = 0;
64  PrefColor = 0;
65  PrefColorDw = 0xff;
66  PrefColor2Dw = 0;
67  OldPrefControl = 0;
68  PrefMouse = 1;
72  ExtraData.Reset();
73 }
74 
76 {
77  DWORD valRGB[12] = { 0xFF0000E8, 0xFFF40000, 0xFF00C800, 0xFFFCF41C,
78  0xFFC48444, 0xFF784830, 0xFFA04400, 0xFFF08050,
79  0xFF848484, 0xFFFFFFFF, 0xFF0094F8, 0xFFBC00C0
80  };
81  if (Inside<int32_t>(iPrefColor, 0, 11))
82  {
83  return valRGB[iPrefColor];
84  }
85  return 0xFFAAAAAA;
86 }
87 
89 {
90  // New version
91  StdStrBuf Source;
92  if (hGroup.LoadEntryString(C4CFN_PlayerInfoCore, &Source))
93  {
94  // Compile
95  StdStrBuf GrpName = hGroup.GetFullName();
97  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, Source, GrpName.getData()))
98  {
99  return false;
100  }
101  // Pref for AutoContextMenus is still undecided: default by player's control style
102  if (OldPrefAutoContextMenu == -1)
103  {
105  }
106  // Determine true color from indexed pref color
107  if (!PrefColorDw)
108  {
110  }
111  // Validate colors
112  PrefColorDw &= 0xffffff;
113  PrefColor2Dw &= 0xffffff;
114  // Validate name
116  // Success
117  return true;
118  }
119 
120  // Old version no longer supported - sorry
121  return false;
122 }
123 
125 {
126  StdStrBuf Source, Name = hGroup.GetFullName(); Name.Append(DirSep C4CFN_PlayerInfoCore);
127  if (!DecompileToBuf_Log<StdCompilerINIWrite>(*this, &Source, Name.getData()))
128  {
129  return false;
130  }
131  if (!hGroup.Add(C4CFN_PlayerInfoCore, Source, false, true))
132  {
133  return false;
134  }
135  hGroup.Delete("C4Player.ocb");
136  return true;
137 }
138 
139 void C4PlayerInfoCore::Promote(int32_t iRank, C4RankSystem &rRanks)
140 {
141  Rank = iRank;
142  SCopy(rRanks.GetRankName(Rank, true).getData(), RankName, C4MaxName);
143 }
144 
146 {
147  if (TotalScore >= rRanks.Experience(Rank + 1))
148  {
149  Promote(Rank + 1,rRanks);
150  return true;
151  }
152  return false;
153 }
154 
156 {
157  C4ValueNumbers numbers;
158  pComp->Name("Player");
159  pComp->Value(mkNamingAdapt(toC4CStr(PrefName), "Name", "Neuling"));
160  pComp->Value(mkNamingAdapt(toC4CStr(Comment), "Comment", ""));
161  pComp->Value(mkNamingAdapt(Rank, "Rank", 0));
162  pComp->Value(mkNamingAdapt(toC4CStr(RankName), "RankName", LoadResStr("IDS_MSG_RANK"))); // TODO: check if this would be desirable
163  pComp->Value(mkNamingAdapt(TotalScore, "Score", 0));
164  pComp->Value(mkNamingAdapt(Rounds, "Rounds", 0));
165  pComp->Value(mkNamingAdapt(RoundsWon, "RoundsWon", 0));
166  pComp->Value(mkNamingAdapt(RoundsLost, "RoundsLost", 0));
167  pComp->Value(mkNamingAdapt(TotalPlayingTime, "TotalPlayingTime", 0));
168  pComp->Value(mkNamingAdapt(mkParAdapt(ExtraData, &numbers), "ExtraData", C4ValueMapData()));
169  pComp->Value(mkNamingAdapt(numbers, "ExtraDataValues"));
170  if (pComp->isDeserializer())
171  {
172  numbers.Denumerate();
173  ExtraData.Denumerate(&numbers);
174  }
175  pComp->Value(mkNamingAdapt(toC4CStr(LeagueName), "LeagueName", ""));
176  pComp->NameEnd();
177 
178  pComp->Name("Preferences");
179  pComp->Value(mkNamingAdapt(PrefColor, "Color", 0));
180  pComp->Value(mkNamingAdapt(PrefColorDw, "ColorDw", 0xffu));
181  pComp->Value(mkNamingAdapt(PrefColor2Dw, "AlternateColorDw", 0u));
182  pComp->Value(mkNamingAdapt(PrefMouse, "Mouse", 1));
183  pComp->Value(mkNamingAdapt(OldPrefControl, "Control", 1));
184  pComp->Value(mkNamingAdapt(OldPrefControlStyle, "AutoStopControl", 0));
185  pComp->Value(mkNamingAdapt(OldPrefAutoContextMenu, "AutoContextMenu", -1)); // Compiling default is -1 (if this is detected, AutoContextMenus will be defaulted by control style)
186  pComp->Value(mkNamingAdapt(PrefControl, "ControlSet", StdStrBuf()));
187  pComp->Value(mkNamingAdapt(PrefClonkSkin, "ClonkSkin", 0));
188  pComp->NameEnd();
189 
190  pComp->Value(mkNamingAdapt(LastRound, "LastRound"));
191  pComp->Value(mkNamingAdapt(Achievements, "Achievements"));
192 }
193 
194 //------------------------------- Object Info ----------------------------------------
195 
197 {
198  Default();
199 }
200 
201 void C4ObjectInfoCore::Default(C4ID n_id, C4DefList *pDefs, const char *cpNames)
202 {
203  // Def
204  C4Def *pDef = nullptr;
205  if (pDefs)
206  {
207  pDef = pDefs->ID2Def(n_id);
208  }
209 
210  // Defaults
211  id = n_id;
212  Participation = 1;
213  Rank = 0;
214  Experience = 0;
215  Rounds = 0;
216  DeathCount = 0;
217  Birthday = 0;
218  TotalPlayingTime = 0;
219  SCopy("Clonk", Name, C4MaxName);
220  SCopy("Clonk", TypeName, C4MaxName);
221  sRankName.Copy("Clonk");
223  NextRankExp = 0;
224  DeathMessage[0] = '\0';
225  Age = 0;
226  ExtraData.Reset();
227 
228  // Type
229  if (pDef)
230  {
231  SCopy(pDef->GetName(), TypeName, C4MaxName);
232  }
233 
234  // Name
235  if (cpNames)
236  {
237  SCopySegment(cpNames, Random(SCharCount(0x0A, cpNames)), Name, 0x0A, C4MaxName + 1);
239  SReplaceChar(Name, 0x0D, 0x00);
240  if (!Name[0])
241  {
242  SCopy("Clonk", Name, C4MaxName);
243  }
244  }
245 
246  if (pDefs)
247  {
248  UpdateCustomRanks(pDefs);
249  }
250 }
251 
252 void C4ObjectInfoCore::Promote(int32_t iRank, C4RankSystem &rRanks, bool fForceRankName)
253 {
254  Rank = iRank;
255  // Copy new rank name if defined only, or forced to use highest defined rank for too high info ranks
256  StdStrBuf sNewRank(rRanks.GetRankName(Rank, fForceRankName));
257  if (sNewRank)
258  {
259  sRankName.Copy(sNewRank);
260  }
261 }
262 
264 {
265  assert(pDefs);
266  C4Def *pDef = pDefs->ID2Def(id);
267  if (!pDef) return;
268  if (pDef->pRankNames)
269  {
270  StdStrBuf sRank(pDef->pRankNames->GetRankName(Rank, false));
271  if (sRank)
272  {
273  sRankName.Copy(sRank);
274  }
275  // Next rank data
276  StdStrBuf sNextRank(pDef->pRankNames->GetRankName(Rank + 1, false));
277  if (sNextRank)
278  {
279  sNextRankName.Copy(sNextRank);
280  NextRankExp = pDef->pRankNames->Experience(Rank + 1);
281  }
282  else
283  {
284  // No more promotion possible by custom rank system
287  }
288  }
289  else
290  {
291  // Definition does not have custom rank names
293  NextRankExp = 0;
294  }
295 }
296 
297 bool C4ObjectInfoCore::GetNextRankInfo(C4RankSystem &rDefaultRanks, int32_t *piNextRankExp, StdStrBuf *psNextRankName)
298 {
299  int32_t iNextRankExp;
300  // Custom rank assigned?
301  if (NextRankExp)
302  {
303  iNextRankExp = NextRankExp;
304  if (psNextRankName)
305  {
306  psNextRankName->Copy(sNextRankName);
307  }
308  }
309  else
310  {
311  // No custom rank: Get from default set
312  StdStrBuf sRank(rDefaultRanks.GetRankName(Rank + 1, false));
313  if (sRank)
314  {
315  iNextRankExp = rDefaultRanks.Experience(Rank + 1);
316  if (psNextRankName)
317  {
318  psNextRankName->Copy(sRank);
319  }
320  }
321  else
322  {
323  // No more promotion
324  iNextRankExp = C4RankSystem::EXP_NoPromotion;
325  }
326  }
327  // Return result
328  if (piNextRankExp)
329  {
330  *piNextRankExp = iNextRankExp;
331  }
332  // Return value is whether additional promotion is possible
333  return iNextRankExp != C4RankSystem::EXP_NoPromotion;
334 }
335 
337 {
338  StdStrBuf Source;
339  return hGroup.LoadEntryString(C4CFN_ObjectInfoCore, &Source) &&
340  Compile(Source.getData());
341 }
342 
344 {
345  // Rank overload by def: Update any NextRank-stuff
346  if (pDefs)
347  {
348  UpdateCustomRanks(pDefs);
349  }
350  StdStrBuf Buffer;
351  if (!Decompile(Buffer))
352  {
353  return false;
354  }
355  if (!hGroup.Add(C4CFN_ObjectInfoCore, Buffer, false, true))
356  {
357  return false;
358  }
359  return true;
360 }
361 
363 {
364  C4ValueNumbers numbers;
365  pComp->Value(mkNamingAdapt(id, "id", C4ID::None));
366  pComp->Value(mkNamingAdapt(toC4CStr(Name), "Name", "Clonk"));
367  pComp->Value(mkNamingAdapt(toC4CStr(DeathMessage), "DeathMessage", ""));
368  pComp->Value(mkNamingAdapt(Rank, "Rank", 0));
369  pComp->Value(mkNamingAdapt(sRankName, "RankName", "Clonk"));
370  pComp->Value(mkNamingAdapt(sNextRankName, "NextRankName", ""));
371  pComp->Value(mkNamingAdapt(toC4CStr(TypeName), "TypeName", "Clonk"));
372  pComp->Value(mkNamingAdapt(Participation, "Participation", 1));
373  pComp->Value(mkNamingAdapt(Experience, "Experience", 0));
374  pComp->Value(mkNamingAdapt(NextRankExp, "NextRankExp", 0));
375  pComp->Value(mkNamingAdapt(Rounds, "Rounds", 0));
376  pComp->Value(mkNamingAdapt(DeathCount, "DeathCount", 0));
377  pComp->Value(mkNamingAdapt(Birthday, "Birthday", 0));
378  pComp->Value(mkNamingAdapt(TotalPlayingTime, "TotalPlayingTime", 0));
379  pComp->Value(mkNamingAdapt(Age, "Age", 0));
380  pComp->Value(mkNamingAdapt(mkParAdapt(ExtraData, &numbers), "ExtraData", C4ValueMapData()));
381  pComp->Value(mkNamingAdapt(numbers, "ExtraDataValues"));
382  if (pComp->isDeserializer())
383  {
384  numbers.Denumerate();
385  ExtraData.Denumerate(&numbers);
386  }
387 }
388 
389 bool C4ObjectInfoCore::Compile(const char *szSource)
390 {
391  bool ret = CompileFromBuf_LogWarn<StdCompilerINIRead>(
392  mkNamingAdapt(*this, "ObjectInfo"),
393  StdStrBuf(szSource),
394  "ObjectInfo");
395  // DeathMessages are not allowed to stay forever
396  if ('@' == DeathMessage[0])
397  {
398  DeathMessage[0] = ' ';
399  }
400  return ret;
401 }
402 
404 {
405  if (!DecompileToBuf_Log<StdCompilerINIWrite>(
406  mkNamingAdapt(*this, "ObjectInfo"),
407  &Buf,
408  "ObjectInfo"))
409  {
410  return false;
411  }
412  return true;
413 }
414 
415 
416 //------------------------------- Round Info ------------------------------------------
417 
419 {
420  InplaceReconstruct(this);
421 }
422 
424 {
425  pComp->Value(mkNamingAdapt(Title, "Title", ""));
426  pComp->Value(mkNamingAdapt(Date, "Date", 0u));
427  pComp->Value(mkNamingAdapt(Duration, "Duration", 0));
428  pComp->Value(mkNamingAdapt(Won, "Won", 0));
429  pComp->Value(mkNamingAdapt(Score, "Score", 0));
430  pComp->Value(mkNamingAdapt(FinalScore, "FinalScore", 0));
431  pComp->Value(mkNamingAdapt(TotalScore, "TotalScore", 0));
432  pComp->Value(mkNamingAdapt(Bonus, "Bonus", 0));
433  pComp->Value(mkNamingAdapt(Level, "Level", 0));
434 }
#define C4CFN_PlayerInfoCore
Definition: C4Components.h:45
#define C4CFN_ObjectInfoCore
Definition: C4Components.h:47
const unsigned int C4MaxName
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
uint32_t Random()
Definition: C4Random.cpp:43
#define DirSep
uint32_t DWORD
unsigned int SCharCount(char cTarget, const char *szInStr, const char *cpUntil)
Definition: Standard.cpp:326
void SReplaceChar(char *str, char fc, char tc)
Definition: Standard.cpp:354
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
Definition: Standard.cpp:279
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
int SClearFrontBack(char *szString, char cClear)
Definition: Standard.cpp:461
std::enable_if< std::is_nothrow_default_constructible< T >::value >::type InplaceReconstruct(T *obj)
Definition: Standard.h:35
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:490
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
#define toC4CStr(szString)
Definition: StdAdaptors.h:24
Definition: C4Def.h:99
C4RankSystem * pRankNames
Definition: C4Def.h:188
C4Def * ID2Def(C4ID id)
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2638
bool Add(const char *filename, const char *entry_name)
Definition: C4Group.cpp:1621
bool LoadEntryString(const char *entry_name, StdStrBuf *buffer)
Definition: C4Group.cpp:2430
bool Delete(const char *files, bool recursive=false)
Definition: C4Group.cpp:1645
Definition: C4Id.h:26
static const C4ID None
Definition: C4Id.h:39
static bool StripMarkup(char *szText)
Definition: C4Markup.cpp:148
bool Load(C4Group &hGroup)
Definition: C4InfoCore.cpp:336
int32_t DeathCount
Definition: C4InfoCore.h:44
int32_t TotalPlayingTime
Definition: C4InfoCore.h:46
void Promote(int32_t iRank, C4RankSystem &rRanks, bool fForceRankName)
Definition: C4InfoCore.cpp:252
char Name[C4MaxName+1]
Definition: C4InfoCore.h:37
void UpdateCustomRanks(C4DefList *pDefs)
Definition: C4InfoCore.cpp:263
bool Compile(const char *szSource)
Definition: C4InfoCore.cpp:389
int32_t NextRankExp
Definition: C4InfoCore.h:42
int32_t Birthday
Definition: C4InfoCore.h:46
StdStrBuf sNextRankName
Definition: C4InfoCore.h:41
int32_t Participation
Definition: C4InfoCore.h:38
int32_t Rounds
Definition: C4InfoCore.h:43
bool Save(C4Group &hGroup, class C4DefList *pDefs)
Definition: C4InfoCore.cpp:343
char TypeName[C4MaxName+1+1]
Definition: C4InfoCore.h:45
void CompileFunc(StdCompiler *pComp)
Definition: C4InfoCore.cpp:362
char DeathMessage[C4MaxDeathMsg+1]
Definition: C4InfoCore.h:48
StdStrBuf sRankName
Definition: C4InfoCore.h:40
int32_t Experience
Definition: C4InfoCore.h:43
C4ValueMapData ExtraData
Definition: C4InfoCore.h:49
bool GetNextRankInfo(C4RankSystem &rDefaultRanks, int32_t *piNextRankExp, StdStrBuf *psNextRankName)
Definition: C4InfoCore.cpp:297
void Default(C4ID n_id=C4ID::None, class C4DefList *pDefs=nullptr, const char *cpNames=nullptr)
Definition: C4InfoCore.cpp:201
bool Decompile(StdStrBuf &Buf)
Definition: C4InfoCore.cpp:403
char Comment[C4MaxComment+1]
Definition: C4InfoCore.h:86
StdCopyStrBuf PrefControl
Definition: C4InfoCore.h:96
int32_t OldPrefControlStyle
Definition: C4InfoCore.h:104
bool Load(C4Group &hGroup)
Definition: C4InfoCore.cpp:88
void Promote(int32_t iRank, C4RankSystem &rRanks)
Definition: C4InfoCore.cpp:139
uint32_t PrefColor2Dw
Definition: C4InfoCore.h:99
static DWORD GetPrefColorValue(int32_t iPrefColor)
Definition: C4InfoCore.cpp:75
int32_t RoundsWon
Definition: C4InfoCore.h:90
int32_t PrefColor
Definition: C4InfoCore.h:98
char LeagueName[C4MaxName+1]
Definition: C4InfoCore.h:94
int32_t TotalPlayingTime
Definition: C4InfoCore.h:91
int32_t Rounds
Definition: C4InfoCore.h:90
int32_t OldPrefAutoContextMenu
Definition: C4InfoCore.h:105
char RankName[C4MaxName+1]
Definition: C4InfoCore.h:88
int32_t RoundsLost
Definition: C4InfoCore.h:90
void Default(C4RankSystem *pRanks=nullptr)
Definition: C4InfoCore.cpp:40
void CompileFunc(StdCompiler *pComp)
Definition: C4InfoCore.cpp:155
C4RoundResult LastRound
Definition: C4InfoCore.h:92
char PrefName[C4MaxName+1]
Definition: C4InfoCore.h:85
int32_t PrefClonkSkin
Definition: C4InfoCore.h:100
uint32_t PrefColorDw
Definition: C4InfoCore.h:99
int32_t TotalScore
Definition: C4InfoCore.h:89
int32_t PrefMouse
Definition: C4InfoCore.h:97
bool CheckPromotion(C4RankSystem &rRanks)
Definition: C4InfoCore.cpp:145
bool Save(C4Group &hGroup)
Definition: C4InfoCore.cpp:124
C4ValueMapData ExtraData
Definition: C4InfoCore.h:93
int32_t OldPrefControl
Definition: C4InfoCore.h:103
C4ScenarioParameters Achievements
Definition: C4InfoCore.h:108
const char * GetName() const override
Definition: C4PropList.cpp:243
StdStrBuf GetRankName(int iRank, bool fReturnLastIfOver)
int Experience(int iRank)
uint32_t Date
Definition: C4InfoCore.h:68
int32_t Bonus
Definition: C4InfoCore.h:72
int32_t Duration
Definition: C4InfoCore.h:69
int32_t FinalScore
Definition: C4InfoCore.h:71
int32_t TotalScore
Definition: C4InfoCore.h:71
int32_t Level
Definition: C4InfoCore.h:73
int32_t Score
Definition: C4InfoCore.h:71
int32_t Won
Definition: C4InfoCore.h:70
void CompileFunc(StdCompiler *pComp)
Definition: C4InfoCore.cpp:423
StdCopyStrBuf Title
Definition: C4InfoCore.h:67
void Denumerate(C4ValueNumbers *)
Definition: C4ValueMap.cpp:254
void Denumerate()
Definition: C4Value.cpp:281
void Value(const T &rStruct)
Definition: StdCompiler.h:161
virtual void NameEnd(bool fBreak=false)
Definition: StdCompiler.h:78
virtual bool isDeserializer()
Definition: StdCompiler.h:53
virtual bool Name(const char *szName)
Definition: StdCompiler.h:77
const char * getData() const
Definition: StdBuf.h:442
void Copy()
Definition: StdBuf.h:467
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519
void Clear()
Definition: StdBuf.h:466