OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4RankSystem.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 /* Rank list for players or crew members */
19 
20 #include "C4Include.h"
21 #include "player/C4RankSystem.h"
22 
23 #include "lib/C4Log.h"
24 #include "c4group/C4Group.h"
26 #include "graphics/C4FacetEx.h"
27 #include "game/C4Game.h"
29 
30 #include "platform/StdRegistry.h"
31 
33  : pszRankNames(nullptr), szRankNames(nullptr), pszRankExtensions(nullptr)
34 {
35  Default();
36 }
37 
38 int C4RankSystem::Init(const char *szRegister,
39  const char *szDefRanks,
40  int iRankBase)
41 {
42 
43  // Init
44  SCopy(szRegister,Register,256);
45  RankBase=iRankBase;
46 
47  // Check registry for present rank names and set defaults
48 #ifdef _WIN32
49  int crank=0;
50  char keyname[30];
51  StdCopyStrBuf rankname;
52  bool Checking=true;
53  while (Checking)
54  {
55  sprintf(keyname,"Rank%03d",crank+1);
56  rankname = GetRegistryString(Register,keyname);
57  if (!rankname.isNull())
58  {
59  // Rank present
60  crank++;
61  }
62  else
63  {
64  // Rank not defined, check for default
65  rankname.AppendChars('\0', C4MaxName);
66  if (SCopySegment(szDefRanks,crank,rankname.getMData(),'|',C4MaxName)
67  && SetRegistryString(Register,keyname,rankname.getData()))
68  crank++;
69  else
70  Checking=false;
71  }
72  }
73  return crank;
74 #else
75  // clear any loaded rank names
76  Clear();
77  if (!szDefRanks) return 0;
78  // make a copy
79  szRankNames = new char[strlen(szDefRanks) + 1];
80  strcpy (szRankNames, szDefRanks);
81  // split into substrings by replacing the | with zeros
82  for (char * p = szRankNames; *p; ++p) if (*p == '|')
83  {
84  *p = 0;
85  ++iRankNum;
86  }
87  ++ iRankNum; // The last rank is already terminated by zero
88  // build a list of substrings
89  pszRankNames = new char *[iRankNum];
90  char * p = szRankNames;
91  for (int i = 0; i < iRankNum; ++i)
92  {
93  pszRankNames[i] = p;
94  p += strlen(p) + 1;
95  }
96  return iRankNum;
97 #endif
98 }
99 
100 bool C4RankSystem::Load(C4Group &hGroup, const char *szFilenames, int DefRankBase, const char *szLanguage)
101 {
102  // clear any loaded rank names
103  Clear();
104  assert(szFilenames); assert(szLanguage);
105  // load new
106  C4ComponentHost Ranks;
107  if (!C4Language::LoadComponentHost(&Ranks, hGroup, szFilenames, szLanguage)) return false;
108  size_t iSize = Ranks.GetDataSize();
109  if (!iSize) return false;
110  szRankNames=new char[iSize+1];
111  memcpy(szRankNames, Ranks.GetData(), iSize * sizeof(char));
112  szRankNames[iSize]=0;
113  // replace line breaks by zero-chars
114  unsigned int i=0;
115  for (; i<iSize; ++i)
116  if (szRankNames[i] == 0x0A || szRankNames[i] == 0x0D) szRankNames[i]=0;
117  // count names
118  char *pRank0=szRankNames, *pPos=szRankNames;
119  for (i=0; i<iSize; ++i,++pPos)
120  if (!*pPos)
121  {
122  // zero-character found: content?
123  if (pPos-pRank0>0)
124  {
125  // rank extension?
126  if (*pRank0 == '*')
127  ++iRankExtNum;
128  // no comment?
129  else if (*pRank0 != '#')
130  // no setting?
131  if (SCharPos('=', pRank0) < 0)
132  // count as name!
133  ++iRankNum;
134  }
135  // advance pos
136  pRank0=pPos+1;
137  }
138  // safety
139  if (!iRankNum) { Clear(); return false; }
140  // set default rank base
141  RankBase=DefRankBase;
142  // alloc lists
143  pszRankNames = new char *[iRankNum];
144  if (iRankExtNum) pszRankExtensions = new char *[iRankExtNum];
145  // fill list with names
146  // count names
147  pRank0=szRankNames; pPos=szRankNames;
148  char **pszCurrRank=pszRankNames;
149  char **pszCurrRankExt=pszRankExtensions;
150  for (i=0; i<iSize; ++i,++pPos)
151  if (!*pPos)
152  {
153  // zero-character found: content?
154  if (pPos-pRank0>0)
155  {
156  // extension?
157  if (*pRank0 == '*')
158  {
159  *pszCurrRankExt++ = pRank0+1;
160  }
161  // no comment?
162  else if (*pRank0 != '#')
163  {
164  // check if it's a setting
165  int iEqPos=SCharPos('=', pRank0);
166  if (iEqPos >= 0)
167  {
168  // get name and value of setting
169  pRank0[iEqPos]=0; char *szValue=pRank0+iEqPos+1;
170  if (SEqual(pRank0, "Base"))
171  // get rankbase
172  // note that invalid numbers may cause desyncs here...not very likely though :)
173  sscanf(szValue, "%d", &RankBase);
174  }
175  else
176  // yeeehaa! it's a name! store it, store it!
177  *pszCurrRank++=pRank0;
178  }
179  }
180  // advance pos
181  pRank0=pPos+1;
182  }
183  // check rankbase
184  if (!RankBase) RankBase=1000;
185  // ranks read, success
186  return true;
187 }
188 
189 StdStrBuf C4RankSystem::GetRankName(int iRank, bool fReturnLastIfOver)
190 {
191  if (iRank<0) return StdStrBuf();
192  // if a new-style ranklist is loaded, seek there
193  if (pszRankNames)
194  {
195  if (iRankNum<=0) return StdStrBuf();
196  // overflow check
197  if (iRank>=iRankNum*(iRankExtNum+1))
198  {
199  // rank undefined: Fallback to last rank
200  if (!fReturnLastIfOver) return StdStrBuf();
201  iRank = iRankNum*(iRankExtNum+1)-1;
202  }
203  StdStrBuf sResult;
204  if (iRank >= iRankNum)
205  {
206  // extended rank composed of two parts
207  int iExtension = iRank / iRankNum - 1;
208  iRank = iRank % iRankNum;
209  sResult.Format(pszRankExtensions[iExtension], pszRankNames[iRank]);
210  }
211  else
212  {
213  // simple rank
214  sResult.Ref(pszRankNames[iRank]);
215  }
216  return sResult;
217  }
218 #ifdef _WIN32
219  // old-style registry fallback
220  while (iRank>=0)
221  {
222  char keyname[30];
223  StdCopyStrBuf rankname;
224  sprintf(keyname,"Rank%03d",iRank+1);
225  rankname = GetRegistryString(Register,keyname);
226  if (!rankname.isNull())
227  return rankname;
228  if (!fReturnLastIfOver) return StdStrBuf();
229  --iRank;
230  }
231 #endif
232  return StdStrBuf();
233 }
234 
236 {
237  if (iRank<0) return 0;
238  return (int) ( pow (double(iRank), 1.5) * RankBase );
239 }
240 
242 {
243  int iRank=0;
244  while (Experience(iRank+1)<=iExp) ++iRank;
245  return iRank;
246 }
247 
248 bool C4RankSystem::Check(int iRank, const char *szDefRankName)
249 {
250 #ifdef _WIN32
251  char keyname[30];
252  sprintf(keyname,"Rank%03d",iRank);
253  if (!GetRegistryString(Register,keyname).isNull())
254  return false;
255  if (!szDefRankName || (SLen(szDefRankName)>C4MaxName))
256  return false;
257  return SetRegistryString(Register,keyname,szDefRankName);
258 #else
259  return true;
260 #endif
261 }
262 
264 {
265  // clear any loaded rank names
266  if (pszRankNames) { delete [] pszRankNames; pszRankNames=nullptr; }
267  if (pszRankExtensions) { delete [] pszRankExtensions; pszRankExtensions = nullptr; }
268  if (szRankNames) { delete [] szRankNames; szRankNames=nullptr; }
269  // reset number of ranks
270  iRankNum=0;
271  iRankExtNum=0;
272 }
273 
275 {
276  Clear();
277  Register[0]=0;
278  RankName[0]=0;
279  RankBase=1000;
280  iRankExtNum=0;
281 }
282 
283 bool C4RankSystem::DrawRankSymbol(C4FacetSurface *fctSymbol, int32_t iRank, C4Facet *pfctRankSymbols, int32_t iRankSymbolCount, bool fOwnSurface, int32_t iXOff, C4Facet *cgoDrawDirect)
284 {
285  // safety
286  if (iRank<0) iRank = 0;
287  // symbol by rank
288  int32_t iMaxRankSym,Q;
289  if (pfctRankSymbols->GetPhaseNum(iMaxRankSym, Q))
290  {
291  if (!iMaxRankSym) iMaxRankSym=1;
292  int32_t iBaseRank=iRank%iRankSymbolCount;
293  if (iRank/iRankSymbolCount)
294  {
295  // extended rank: draw
296  // extension star defaults to captain star; but use extended symbols if they are in the gfx
297  C4Facet fctExtended = ::GraphicsResource.fctCaptain;
298  if (iMaxRankSym > iRankSymbolCount)
299  {
300  int32_t iExtended = iRank / iRankSymbolCount - 1 + iRankSymbolCount;
301  if (iExtended >= iMaxRankSym)
302  {
303  // max rank exceeded
304  iExtended = iMaxRankSym - 1;
305  iBaseRank = iRankSymbolCount - 1;
306  }
307  fctExtended = pfctRankSymbols->GetPhase(iExtended);
308  }
309  int32_t iSize = pfctRankSymbols->Wdt;
310  if (!cgoDrawDirect)
311  {
312  fctSymbol->Create(iSize,iSize);
313  pfctRankSymbols->DrawX(fctSymbol->Surface, 0,0,iSize,iSize,iBaseRank);
314  fctExtended.DrawX(fctSymbol->Surface, 0,0,iSize*2/3,iSize*2/3);
315  }
316  else
317  {
318  pfctRankSymbols->Draw(cgoDrawDirect->Surface,cgoDrawDirect->X+iXOff,cgoDrawDirect->Y,iBaseRank);
319  fctExtended.Draw(cgoDrawDirect->Surface, cgoDrawDirect->X+iXOff-4,cgoDrawDirect->Y-3);
320  }
321  }
322  else
323  {
324  // regular rank: copy facet
325  if (cgoDrawDirect)
326  {
327  pfctRankSymbols->Draw(cgoDrawDirect->Surface, cgoDrawDirect->X+iXOff,cgoDrawDirect->Y,iBaseRank);
328  }
329  else if (fOwnSurface)
330  {
331  int32_t iSize = pfctRankSymbols->Wdt;
332  fctSymbol->Create(iSize,iSize);
333  pfctRankSymbols->DrawX(fctSymbol->Surface, 0,0,iSize,iSize,iBaseRank);
334  }
335  else
336  {
337  fctSymbol->Set(pfctRankSymbols->GetPhase(iBaseRank));
338  }
339  }
340  return true;
341  }
342  return false;
343 }
344 
const char * getData() const
Definition: StdBuf.h:450
float Y
Definition: C4Facet.h:120
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:122
bool Load(C4Group &hGroup, const char *szFilenames, int DefRankBase, const char *szLanguage)
#define sprintf
Definition: Standard.h:171
const char * GetData() const
bool GetPhaseNum(int32_t &rX, int32_t &rY)
Definition: C4Facet.cpp:472
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
Definition: Standard.cpp:243
C4RankSystem DefaultRanks
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:181
size_t SLen(const char *sptr)
Definition: Standard.h:78
void AppendChars(char cChar, size_t iCnt)
Definition: StdBuf.h:590
char ** pszRankExtensions
Definition: C4RankSystem.h:40
C4GraphicsResource GraphicsResource
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:97
char RankName[C4MaxName+1]
Definition: C4RankSystem.h:35
void Set(const C4Facet &cpy)
Definition: C4FacetEx.h:46
char Register[256+1]
Definition: C4RankSystem.h:34
StdStrBuf GetRankName(int iRank, bool fReturnLastIfOver)
char * getMData()
Definition: StdBuf.h:451
size_t GetDataSize() const
char * szRankNames
Definition: C4RankSystem.h:38
static bool LoadComponentHost(C4ComponentHost *host, C4Group &hGroup, const char *szFilename, const char *szLanguage)
Definition: C4Language.cpp:235
void DrawX(C4Surface *sfcTarget, float iX, float iY, float iWdt, float iHgt, int32_t iPhaseX=0, int32_t iPhaseY=0) const
Definition: C4Facet.cpp:358
static bool DrawRankSymbol(C4FacetSurface *fctSymbol, int32_t iRank, C4Facet *pfctRankSymbols, int32_t iRankSymbolCount, bool fOwnSurface, int32_t iXOff=0, C4Facet *cgoDrawDirect=nullptr)
void Draw(C4Facet &cgo, bool fAspect=true, int32_t iPhaseX=0, int32_t iPhaseY=0, bool fTransparent=true)
Definition: C4Facet.cpp:154
const unsigned int C4MaxName
void Ref(const char *pnData)
Definition: StdBuf.h:463
int Init(const char *szRegister, const char *szDefRanks, int iRankBase)
bool isNull() const
Definition: StdBuf.h:449
bool Create(int iWdt, int iHgt, int iWdt2=C4FCT_Full, int iHgt2=C4FCT_Full)
Definition: C4FacetEx.cpp:54
bool Check(int iRank, const char *szDefRankName)
int RankByExperience(int iExp)
int SCharPos(char cTarget, const char *szInStr, int iIndex)
Definition: Standard.cpp:203
C4Surface * Surface
Definition: C4Facet.h:119
char ** pszRankNames
Definition: C4RankSystem.h:37
float Wdt
Definition: C4Facet.h:120
C4Facet GetPhase(int iPhaseX=0, int iPhaseY=0)
Definition: C4Facet.cpp:59
float X
Definition: C4Facet.h:120
int Experience(int iRank)
int iSize
Definition: TstC4NetIO.cpp:35