PageRenderTime 113ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

/src/game/player/C4RankSystem.cpp

https://bitbucket.org/randrian/openclonk2
C++ | 345 lines | 260 code | 17 blank | 68 comment | 65 complexity | 867730f34f3b9b68fe957f65fc0768d5 MD5 | raw file
Possible License(s): WTFPL, 0BSD, LGPL-2.1, CC-BY-3.0
  1. /*
  2. * OpenClonk, http://www.openclonk.org
  3. *
  4. * Copyright (c) 1998-2000 Matthes Bender
  5. * Copyright (c) 2002, 2006-2007 Sven Eberhardt
  6. * Copyright (c) 2005-2006 G?nther Brammer
  7. * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
  8. *
  9. * Portions might be copyrighted by other authors who have contributed
  10. * to OpenClonk.
  11. *
  12. * Permission to use, copy, modify, and/or distribute this software for any
  13. * purpose with or without fee is hereby granted, provided that the above
  14. * copyright notice and this permission notice appear in all copies.
  15. * See isc_license.txt for full license and disclaimer.
  16. *
  17. * "Clonk" is a registered trademark of Matthes Bender.
  18. * See clonk_trademark_license.txt for full license.
  19. */
  20. /* Rank list for players or crew members */
  21. #include <C4Include.h>
  22. #include <C4RankSystem.h>
  23. #ifndef BIG_C4INCLUDE
  24. #include <C4Log.h>
  25. #include <C4Group.h>
  26. #include <C4ComponentHost.h>
  27. #include <C4FacetEx.h>
  28. #include <C4Game.h>
  29. #include <C4GraphicsResource.h>
  30. #endif
  31. #include <StdRegistry.h>
  32. C4RankSystem::C4RankSystem()
  33. {
  34. Default();
  35. }
  36. int C4RankSystem::Init(const char *szRegister,
  37. const char *szDefRanks,
  38. int iRankBase)
  39. {
  40. // Init
  41. SCopy(szRegister,Register,256);
  42. RankBase=iRankBase;
  43. // Check registry for present rank names and set defaults
  44. #ifdef _WIN32
  45. int crank=0;
  46. char rankname[C4MaxName+1],keyname[30];
  47. bool Checking=true;
  48. while (Checking)
  49. {
  50. sprintf(keyname,"Rank%03d",crank+1);
  51. if (GetRegistryString(Register,keyname,rankname,C4MaxName+1))
  52. {
  53. // Rank present
  54. crank++;
  55. }
  56. else
  57. {
  58. // Rank not defined, check for default
  59. if (SCopySegment(szDefRanks,crank,rankname,'|',C4MaxName)
  60. && SetRegistryString(Register,keyname,rankname))
  61. crank++;
  62. else
  63. Checking=false;
  64. }
  65. }
  66. return crank;
  67. #else
  68. // clear any loaded rank names
  69. Clear();
  70. if (!szDefRanks) return 0;
  71. // make a copy
  72. szRankNames = new char[strlen(szDefRanks) + 1];
  73. strcpy (szRankNames, szDefRanks);
  74. // split into substrings by replacing the | with zeros
  75. for (char * p = szRankNames; *p; ++p) if (*p == '|')
  76. {
  77. *p = 0;
  78. ++iRankNum;
  79. }
  80. ++ iRankNum; // The last rank is already terminated by zero
  81. // build a list of substrings
  82. pszRankNames = new char *[iRankNum];
  83. char * p = szRankNames;
  84. for (int i = 0; i < iRankNum; ++i)
  85. {
  86. pszRankNames[i] = p;
  87. p += strlen(p) + 1;
  88. }
  89. return iRankNum;
  90. #endif
  91. }
  92. bool C4RankSystem::Load(C4Group &hGroup, const char *szFilenames, int DefRankBase, const char *szLanguage)
  93. {
  94. // clear any loaded rank names
  95. Clear();
  96. assert(szFilenames); assert(szLanguage);
  97. // load new
  98. C4ComponentHost Ranks;
  99. if (!Ranks.LoadEx("Ranks", hGroup, szFilenames, szLanguage)) return false;
  100. size_t iSize = Ranks.GetDataSize();
  101. if (!iSize) return false;
  102. szRankNames=new char[iSize+1];
  103. memcpy(szRankNames, Ranks.GetData(), iSize * sizeof(char));
  104. szRankNames[iSize]=0;
  105. Ranks.Close();
  106. // replace line breaks by zero-chars
  107. unsigned int i=0;
  108. for (; i<iSize; ++i)
  109. if (szRankNames[i] == 0x0A || szRankNames[i] == 0x0D) szRankNames[i]=0;
  110. // count names
  111. char *pRank0=szRankNames, *pPos=szRankNames;
  112. for (i=0; i<iSize; ++i,++pPos)
  113. if (!*pPos)
  114. {
  115. // zero-character found: content?
  116. if (pPos-pRank0>0)
  117. {
  118. // rank extension?
  119. if (*pRank0 == '*')
  120. ++iRankExtNum;
  121. // no comment?
  122. else if (*pRank0 != '#')
  123. // no setting?
  124. if (SCharPos('=', pRank0) < 0)
  125. // count as name!
  126. ++iRankNum;
  127. }
  128. // advance pos
  129. pRank0=pPos+1;
  130. }
  131. // safety
  132. if (!iRankNum) { Clear(); return false; }
  133. // set default rank base
  134. RankBase=DefRankBase;
  135. // alloc lists
  136. pszRankNames = new char *[iRankNum];
  137. if (iRankExtNum) pszRankExtensions = new char *[iRankExtNum];
  138. // fill list with names
  139. // count names
  140. pRank0=szRankNames; pPos=szRankNames;
  141. char **pszCurrRank=pszRankNames;
  142. char **pszCurrRankExt=pszRankExtensions;
  143. for (i=0; i<iSize; ++i,++pPos)
  144. if (!*pPos)
  145. {
  146. // zero-character found: content?
  147. if (pPos-pRank0>0)
  148. // extension?
  149. if (*pRank0 == '*')
  150. {
  151. *pszCurrRankExt++ = pRank0+1;
  152. }
  153. // no comment?
  154. else if (*pRank0 != '#')
  155. {
  156. // check if it's a setting
  157. int iEqPos=SCharPos('=', pRank0);
  158. if (iEqPos >= 0)
  159. {
  160. // get name and value of setting
  161. pRank0[iEqPos]=0; char *szValue=pRank0+iEqPos+1;
  162. if (SEqual(pRank0, "Base"))
  163. // get rankbase
  164. // note that invalid numbers may cause desyncs here...not very likely though :)
  165. sscanf(szValue, "%d", &RankBase);
  166. }
  167. else
  168. // yeeehaa! it's a name! store it, store it!
  169. *pszCurrRank++=pRank0;
  170. }
  171. // advance pos
  172. pRank0=pPos+1;
  173. }
  174. // check rankbase
  175. if (!RankBase) RankBase=1000;
  176. // ranks read, success
  177. return true;
  178. }
  179. StdStrBuf C4RankSystem::GetRankName(int iRank, bool fReturnLastIfOver)
  180. {
  181. if (iRank<0) return StdStrBuf();
  182. // if a new-style ranklist is loaded, seek there
  183. if (pszRankNames)
  184. {
  185. if(iRankNum<=0) return StdStrBuf();
  186. // overflow check
  187. if (iRank>=iRankNum*(iRankExtNum+1))
  188. {
  189. // rank undefined: Fallback to last rank
  190. if (!fReturnLastIfOver) return StdStrBuf();
  191. iRank = iRankNum*(iRankExtNum+1)-1;
  192. }
  193. StdStrBuf sResult;
  194. if (iRank >= iRankNum)
  195. {
  196. // extended rank composed of two parts
  197. int iExtension = iRank / iRankNum - 1;
  198. iRank = iRank % iRankNum;
  199. sResult.Format(pszRankExtensions[iExtension], pszRankNames[iRank]);
  200. }
  201. else
  202. {
  203. // simple rank
  204. sResult.Ref(pszRankNames[iRank]);
  205. }
  206. return sResult;
  207. }
  208. #ifdef _WIN32
  209. // old-style registry fallback
  210. while (iRank>=0)
  211. {
  212. char keyname[30];
  213. sprintf(keyname,"Rank%03d",iRank+1);
  214. if (GetRegistryString(Register,keyname,RankName,C4MaxName+1))
  215. return StdStrBuf(RankName);
  216. if (!fReturnLastIfOver) return StdStrBuf(NULL);
  217. --iRank;
  218. }
  219. #endif
  220. return StdStrBuf();
  221. }
  222. int C4RankSystem::Experience(int iRank)
  223. {
  224. if (iRank<0) return 0;
  225. return (int) ( pow (double(iRank), 1.5) * RankBase );
  226. }
  227. int C4RankSystem::RankByExperience(int iExp)
  228. {
  229. int iRank=0;
  230. while (Experience(iRank+1)<=iExp) ++iRank;
  231. return iRank;
  232. }
  233. bool C4RankSystem::Check(int iRank, const char *szDefRankName)
  234. {
  235. #ifdef _WIN32
  236. char rankname[C4MaxName+1],keyname[30];
  237. sprintf(keyname,"Rank%03d",iRank);
  238. if (GetRegistryString(Register,keyname,rankname,C4MaxName+1))
  239. return false;
  240. if (!szDefRankName || (SLen(szDefRankName)>C4MaxName))
  241. return false;
  242. return SetRegistryString(Register,keyname,szDefRankName);
  243. #else
  244. return true;
  245. #endif
  246. }
  247. void C4RankSystem::Clear()
  248. {
  249. // clear any loaded rank names
  250. if (pszRankNames) { delete [] pszRankNames; pszRankNames=NULL; }
  251. if (pszRankExtensions) { delete [] pszRankExtensions; pszRankExtensions = NULL; }
  252. if (szRankNames) { delete [] szRankNames; szRankNames=NULL; }
  253. // reset number of ranks
  254. iRankNum=0;
  255. iRankExtNum=0;
  256. }
  257. void C4RankSystem::Default()
  258. {
  259. Register[0]=0;
  260. RankName[0]=0;
  261. RankBase=1000;
  262. pszRankNames=NULL;
  263. szRankNames=NULL;
  264. pszRankExtensions=NULL;
  265. iRankExtNum=0;
  266. }
  267. bool C4RankSystem::DrawRankSymbol(C4FacetSurface *fctSymbol, int32_t iRank, C4Facet *pfctRankSymbols, int32_t iRankSymbolCount, bool fOwnSurface, int32_t iXOff, C4Facet *cgoDrawDirect)
  268. {
  269. // safety
  270. if (iRank<0) iRank = 0;
  271. // symbol by rank
  272. int32_t iMaxRankSym,Q;
  273. if (pfctRankSymbols->GetPhaseNum(iMaxRankSym, Q))
  274. {
  275. if (!iMaxRankSym) iMaxRankSym=1;
  276. int32_t iBaseRank=iRank%iRankSymbolCount;
  277. if (iRank/iRankSymbolCount)
  278. {
  279. // extended rank: draw
  280. // extension star defaults to captain star; but use extended symbols if they are in the gfx
  281. C4Facet fctExtended = ::GraphicsResource.fctCaptain;
  282. if (iMaxRankSym > iRankSymbolCount)
  283. {
  284. int32_t iExtended = iRank / iRankSymbolCount - 1 + iRankSymbolCount;
  285. if (iExtended >= iMaxRankSym)
  286. {
  287. // max rank exceeded
  288. iExtended = iMaxRankSym - 1;
  289. iBaseRank = iRankSymbolCount - 1;
  290. }
  291. fctExtended = pfctRankSymbols->GetPhase(iExtended);
  292. }
  293. int32_t iSize = pfctRankSymbols->Wdt;
  294. if (!cgoDrawDirect)
  295. {
  296. fctSymbol->Create(iSize,iSize);
  297. pfctRankSymbols->DrawX(fctSymbol->Surface, 0,0,iSize,iSize,iBaseRank);
  298. fctExtended.DrawX(fctSymbol->Surface, 0,0,iSize*2/3,iSize*2/3);
  299. }
  300. else
  301. {
  302. pfctRankSymbols->Draw(cgoDrawDirect->Surface,cgoDrawDirect->X+iXOff,cgoDrawDirect->Y,iBaseRank);
  303. fctExtended.Draw(cgoDrawDirect->Surface, cgoDrawDirect->X+iXOff-4,cgoDrawDirect->Y-3);
  304. }
  305. }
  306. else
  307. {
  308. // regular rank: copy facet
  309. if (cgoDrawDirect)
  310. {
  311. pfctRankSymbols->Draw(cgoDrawDirect->Surface, cgoDrawDirect->X+iXOff,cgoDrawDirect->Y,iBaseRank);
  312. }
  313. else if (fOwnSurface)
  314. {
  315. int32_t iSize = pfctRankSymbols->Wdt;
  316. fctSymbol->Create(iSize,iSize);
  317. pfctRankSymbols->DrawX(fctSymbol->Surface, 0,0,iSize,iSize,iBaseRank);
  318. }
  319. else
  320. {
  321. fctSymbol->Set(pfctRankSymbols->GetPhase(iBaseRank));
  322. }
  323. }
  324. return true;
  325. }
  326. return false;
  327. }
  328. C4RankSystem DefaultRanks;