PageRenderTime 63ms CodeModel.GetById 21ms app.highlight 36ms RepoModel.GetById 1ms 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
 21/* Rank list for players or crew members */
 22
 23#include <C4Include.h>
 24#include <C4RankSystem.h>
 25
 26#ifndef BIG_C4INCLUDE
 27#include <C4Log.h>
 28#include <C4Group.h>
 29#include <C4ComponentHost.h>
 30#include <C4FacetEx.h>
 31#include <C4Game.h>
 32#include <C4GraphicsResource.h>
 33#endif
 34
 35#include <StdRegistry.h>
 36
 37C4RankSystem::C4RankSystem()
 38  {
 39	Default();
 40  }
 41
 42int C4RankSystem::Init(const char *szRegister,
 43											 const char *szDefRanks,
 44											 int iRankBase)
 45  {
 46
 47	// Init
 48	SCopy(szRegister,Register,256);
 49	RankBase=iRankBase;
 50
 51	// Check registry for present rank names and set defaults
 52#ifdef _WIN32
 53	int crank=0;
 54	char rankname[C4MaxName+1],keyname[30];
 55	bool Checking=true;
 56	while (Checking)
 57		{
 58		sprintf(keyname,"Rank%03d",crank+1);
 59		if (GetRegistryString(Register,keyname,rankname,C4MaxName+1))
 60			{
 61			// Rank present
 62			crank++;
 63			}
 64		else
 65			{
 66			// Rank not defined, check for default
 67			if (SCopySegment(szDefRanks,crank,rankname,'|',C4MaxName)
 68			 && SetRegistryString(Register,keyname,rankname))
 69				crank++;
 70			else
 71				Checking=false;
 72			}
 73		}
 74	return crank;
 75#else
 76	// clear any loaded rank names
 77	Clear();
 78	if (!szDefRanks) return 0;
 79	// make a copy
 80	szRankNames = new char[strlen(szDefRanks) + 1];
 81	strcpy (szRankNames, szDefRanks);
 82	// split into substrings by replacing the | with zeros
 83	for (char * p = szRankNames; *p; ++p) if (*p == '|')
 84		{
 85		*p = 0;
 86		++iRankNum;
 87		}
 88	++ iRankNum; // The last rank is already terminated by zero
 89	// build a list of substrings
 90	pszRankNames = new char *[iRankNum];
 91	char * p = szRankNames;
 92	for (int i = 0; i < iRankNum; ++i)
 93		{
 94		pszRankNames[i] = p;
 95		p += strlen(p) + 1;
 96		}
 97	return iRankNum;
 98#endif
 99  }
100
101bool C4RankSystem::Load(C4Group &hGroup, const char *szFilenames, int DefRankBase, const char *szLanguage)
102	{
103	// clear any loaded rank names
104	Clear();
105	assert(szFilenames); assert(szLanguage);
106	// load new
107	C4ComponentHost Ranks;
108	if (!Ranks.LoadEx("Ranks", hGroup, szFilenames, szLanguage)) return false;
109	size_t iSize = Ranks.GetDataSize();
110	if (!iSize) return false;
111	szRankNames=new char[iSize+1];
112	memcpy(szRankNames, Ranks.GetData(), iSize * sizeof(char));
113	szRankNames[iSize]=0;
114	Ranks.Close();
115	// replace line breaks by zero-chars
116	unsigned int i=0;
117	for (; i<iSize; ++i)
118		if (szRankNames[i] == 0x0A || szRankNames[i] == 0x0D) szRankNames[i]=0;
119	// count names
120	char *pRank0=szRankNames, *pPos=szRankNames;
121	for (i=0; i<iSize; ++i,++pPos)
122		if (!*pPos)
123			{
124			// zero-character found: content?
125			if (pPos-pRank0>0)
126				{
127				// rank extension?
128				if (*pRank0 == '*')
129					++iRankExtNum;
130				// no comment?
131				else if (*pRank0 != '#')
132					// no setting?
133					if (SCharPos('=', pRank0) < 0)
134						// count as name!
135						++iRankNum;
136				}
137			// advance pos
138			pRank0=pPos+1;
139			}
140	// safety
141	if (!iRankNum) { Clear(); return false; }
142	// set default rank base
143	RankBase=DefRankBase;
144	// alloc lists
145	pszRankNames = new char *[iRankNum];
146	if (iRankExtNum) pszRankExtensions = new char *[iRankExtNum];
147	// fill list with names
148	// count names
149	pRank0=szRankNames; pPos=szRankNames;
150	char **pszCurrRank=pszRankNames;
151	char **pszCurrRankExt=pszRankExtensions;
152	for (i=0; i<iSize; ++i,++pPos)
153		if (!*pPos)
154			{
155			// zero-character found: content?
156			if (pPos-pRank0>0)
157				// extension?
158				if (*pRank0 == '*')
159					{
160					*pszCurrRankExt++ = pRank0+1;
161					}
162				// no comment?
163				else if (*pRank0 != '#')
164					{
165					// check if it's a setting
166					int iEqPos=SCharPos('=', pRank0);
167					if (iEqPos >= 0)
168						{
169						// get name and value of setting
170						pRank0[iEqPos]=0; char *szValue=pRank0+iEqPos+1;
171						if (SEqual(pRank0, "Base"))
172							// get rankbase
173							// note that invalid numbers may cause desyncs here...not very likely though :)
174							sscanf(szValue, "%d", &RankBase);
175						}
176					else
177						// yeeehaa! it's a name! store it, store it!
178						*pszCurrRank++=pRank0;
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
189StdStrBuf 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		sprintf(keyname,"Rank%03d",iRank+1);
224		if (GetRegistryString(Register,keyname,RankName,C4MaxName+1))
225			return StdStrBuf(RankName);
226		if (!fReturnLastIfOver) return StdStrBuf(NULL);
227		--iRank;
228		}
229#endif
230  return StdStrBuf();
231	}
232
233int C4RankSystem::Experience(int iRank)
234  {
235  if (iRank<0) return 0;
236  return (int) ( pow (double(iRank), 1.5) * RankBase );
237  }
238
239int C4RankSystem::RankByExperience(int iExp)
240	{
241	int iRank=0;
242	while (Experience(iRank+1)<=iExp) ++iRank;
243	return iRank;
244	}
245
246bool C4RankSystem::Check(int iRank, const char  *szDefRankName)
247	{
248#ifdef _WIN32
249	char rankname[C4MaxName+1],keyname[30];
250	sprintf(keyname,"Rank%03d",iRank);
251	if (GetRegistryString(Register,keyname,rankname,C4MaxName+1))
252		return false;
253	if (!szDefRankName || (SLen(szDefRankName)>C4MaxName))
254		return false;
255	return SetRegistryString(Register,keyname,szDefRankName);
256#else
257	return true;
258#endif
259	}
260
261void C4RankSystem::Clear()
262	{
263	// clear any loaded rank names
264	if (pszRankNames) { delete [] pszRankNames; pszRankNames=NULL; }
265	if (pszRankExtensions) { delete [] pszRankExtensions; pszRankExtensions = NULL; }
266	if (szRankNames) { delete [] szRankNames; szRankNames=NULL; }
267	// reset number of ranks
268	iRankNum=0;
269	iRankExtNum=0;
270	}
271
272void C4RankSystem::Default()
273	{
274	Register[0]=0;
275	RankName[0]=0;
276	RankBase=1000;
277	pszRankNames=NULL;
278	szRankNames=NULL;
279	pszRankExtensions=NULL;
280	iRankExtNum=0;
281	}
282
283bool 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
345C4RankSystem DefaultRanks;