1 // ==============================================================
2 //	This file is part of Glest (www.glest.org)
3 //
4 //	Copyright (C) 2001-2008 Martiño Figueroa
5 //
6 //	You can redistribute this code and/or modify it under
7 //	the terms of the GNU General Public License as published
8 //	by the Free Software Foundation; either version 2 of the
9 //	License, or (at your option) any later version
10 // ==============================================================
11 
12 #include "stats.h"
13 #include "lang.h"
14 #include "leak_dumper.h"
15 
16 namespace Glest{ namespace Game{
17 
PlayerStats()18 PlayerStats::PlayerStats() {
19 	control = ctClosed;
20 	resourceMultiplier=1.0f;
21 	//factionTypeName = "";
22 	personalityType = fpt_Normal;
23 	teamIndex = 0;
24 	victory = false;
25 	kills = 0;
26 	enemykills = 0;
27 	deaths = 0;
28 	unitsProduced = 0;
29 	resourcesHarvested = 0;
30 	//playerName = "";
31 	playerLeftBeforeEnd = false;
32 	timePlayerLeft = -1;
33 	playerColor = Vec3f(0,0,0);
34 }
35 
getStats() const36 string PlayerStats::getStats() const {
37 	string result = "";
38 
39 	Lang &lang= Lang::getInstance();
40 	string controlString = "";
41 
42 	if(personalityType == fpt_Observer) {
43 		controlString= GameConstants::OBSERVER_SLOTNAME;
44 	}
45 	else {
46 		switch(control) {
47 		case ctCpuEasy:
48 			controlString= lang.getString("CpuEasy");
49 			break;
50 		case ctCpu:
51 			controlString= lang.getString("Cpu");
52 			break;
53 		case ctCpuUltra:
54 			controlString= lang.getString("CpuUltra");
55 			break;
56 		case ctCpuMega:
57 			controlString= lang.getString("CpuMega");
58 			break;
59 		case ctNetwork:
60 			controlString= lang.getString("Network");
61 			break;
62 		case ctHuman:
63 			controlString= lang.getString("Human");
64 			break;
65 
66 		case ctNetworkCpuEasy:
67 			controlString= lang.getString("NetworkCpuEasy");
68 			break;
69 		case ctNetworkCpu:
70 			controlString= lang.getString("NetworkCpu");
71 			break;
72 		case ctNetworkCpuUltra:
73 			controlString= lang.getString("NetworkCpuUltra");
74 			break;
75 		case ctNetworkCpuMega:
76 			controlString= lang.getString("NetworkCpuMega");
77 			break;
78 
79 		default:
80 			printf("Error control = %d\n",control);
81 			assert(false);
82 			break;
83 		};
84 	}
85 
86 	if((control != ctHuman && control != ctNetwork) ||
87 			(control == ctNetwork && playerLeftBeforeEnd == true)) {
88 		controlString += " x " + floatToStr(resourceMultiplier,1);
89 	}
90 
91 	result += playerName + " (" + controlString + ") ";
92 	if(control == ctNetwork && playerLeftBeforeEnd==true ) {
93 		result += "player left before end ";
94 	}
95 	result += "faction: " + factionTypeName + " ";
96 	result += "Team: " + intToStr(teamIndex) + " ";
97 	result += "victory: " + boolToStr(victory) + " ";
98 	result += "# kills: " + intToStr(kills) + " ";
99 	result += "# enemy kills: " + intToStr(enemykills) + " ";
100 	result += "# deaths: " + intToStr(deaths) + "\n";
101 	result += "# units produced: " + intToStr(unitsProduced) + " ";
102 	result += "# resources harvested: " + intToStr(resourcesHarvested);
103 
104 	return result;
105 }
106 
107 // =====================================================
108 // class Stats
109 // =====================================================
110 
init(int factionCount,int thisFactionIndex,const string & description,const string & techName)111 void Stats::init(int factionCount, int thisFactionIndex, const string& description, const string &techName) {
112 	this->thisFactionIndex= thisFactionIndex;
113 	this->factionCount= factionCount;
114 	this->description= description;
115 	this->techName = techName;
116 }
117 
setVictorious(int playerIndex)118 void Stats::setVictorious(int playerIndex){
119 	playerStats[playerIndex].victory= true;
120 }
121 
kill(int killerFactionIndex,int killedFactionIndex,bool isEnemy,bool isDeathCounted,bool isKillCounted)122 void Stats::kill(int killerFactionIndex, int killedFactionIndex, bool isEnemy, bool isDeathCounted, bool isKillCounted) {
123 	if(isKillCounted == true){
124 		playerStats[killerFactionIndex].kills++;
125 	}
126 	if(isDeathCounted == true){
127 		playerStats[killedFactionIndex].deaths++;
128 	}
129 	if(isEnemy == true && isKillCounted == true) {
130 		playerStats[killerFactionIndex].enemykills++;
131 	}
132 }
133 
die(int diedFactionIndex,bool isDeathCounted)134 void Stats::die(int diedFactionIndex, bool isDeathCounted){
135 	if(isDeathCounted == true){
136 		playerStats[diedFactionIndex].deaths++;
137 	}
138 }
139 
produce(int producerFactionIndex,bool isProductionCounted)140 void Stats::produce(int producerFactionIndex, bool isProductionCounted){
141 	if(isProductionCounted == true){
142 		playerStats[producerFactionIndex].unitsProduced++;
143 	}
144 }
145 
harvest(int harvesterFactionIndex,int amount)146 void Stats::harvest(int harvesterFactionIndex, int amount){
147 	playerStats[harvesterFactionIndex].resourcesHarvested+= amount;
148 }
149 
getStats() const150 string Stats::getStats() const {
151 	string result = "";
152 
153 	result += "Description: " + description + "\n";
154 	result += "Faction count: " + intToStr(factionCount) + "\n";
155 
156 	result += "Game duration (mins): " + intToStr(getFramesToCalculatePlaytime()/GameConstants::updateFps/60) + "\n";
157 	result += "Max Concurrent Units: " + intToStr(maxConcurrentUnitCount) + "\n";
158 	result += "Total EndGame Concurrent Unit Count: " + intToStr(totalEndGameConcurrentUnitCount) + "\n";
159 
160 	for(unsigned int i = 0; i < (unsigned int)factionCount; ++i) {
161 		const PlayerStats &player = playerStats[i];
162 
163 		result += "player #" + uIntToStr(i) + " " + player.getStats() + "\n";
164 	}
165 
166 	return result;
167 }
168 
saveGame(XmlNode * rootNode)169 void Stats::saveGame(XmlNode *rootNode) {
170 	std::map<string,string> mapTagReplacements;
171 	XmlNode *statsNode = rootNode->addChild("Stats");
172 
173 //	PlayerStats playerStats[GameConstants::maxPlayers];
174 	for(unsigned int i = 0; i < (unsigned int)GameConstants::maxPlayers; ++i) {
175 		PlayerStats &stat = playerStats[i];
176 
177 		XmlNode *statsNodePlayer = statsNode->addChild("Player");
178 
179 //		ControlType control;
180 		statsNodePlayer->addAttribute("control",intToStr(stat.control), mapTagReplacements);
181 //		float resourceMultiplier;
182 		statsNodePlayer->addAttribute("resourceMultiplier",floatToStr(stat.resourceMultiplier,6), mapTagReplacements);
183 //		string factionTypeName;
184 		statsNodePlayer->addAttribute("factionTypeName",stat.factionTypeName, mapTagReplacements);
185 //		FactionPersonalityType personalityType;
186 		statsNodePlayer->addAttribute("personalityType",intToStr(stat.personalityType), mapTagReplacements);
187 //		int teamIndex;
188 		statsNodePlayer->addAttribute("teamIndex",intToStr(stat.teamIndex), mapTagReplacements);
189 //		bool victory;
190 		statsNodePlayer->addAttribute("victory",intToStr(stat.victory), mapTagReplacements);
191 //		int kills;
192 		statsNodePlayer->addAttribute("kills",intToStr(stat.kills), mapTagReplacements);
193 //		int enemykills;
194 		statsNodePlayer->addAttribute("enemykills",intToStr(stat.enemykills), mapTagReplacements);
195 //		int deaths;
196 		statsNodePlayer->addAttribute("deaths",intToStr(stat.deaths), mapTagReplacements);
197 //		int unitsProduced;
198 		statsNodePlayer->addAttribute("unitsProduced",intToStr(stat.unitsProduced), mapTagReplacements);
199 //		int resourcesHarvested;
200 		statsNodePlayer->addAttribute("resourcesHarvested",intToStr(stat.resourcesHarvested), mapTagReplacements);
201 //		string playerName;
202 		statsNodePlayer->addAttribute("playerName",stat.playerName, mapTagReplacements);
203 //		Vec3f playerColor;
204 		statsNodePlayer->addAttribute("playerColor",stat.playerColor.getString(), mapTagReplacements);
205 	}
206 //	string description;
207 	statsNode->addAttribute("description",description, mapTagReplacements);
208 //	int factionCount;
209 	statsNode->addAttribute("factionCount",intToStr(factionCount), mapTagReplacements);
210 //	int thisFactionIndex;
211 	statsNode->addAttribute("thisFactionIndex",intToStr(thisFactionIndex), mapTagReplacements);
212 //
213 //	float worldTimeElapsed;
214 	statsNode->addAttribute("worldTimeElapsed",floatToStr(worldTimeElapsed,6), mapTagReplacements);
215 //	int framesPlayed;
216 	statsNode->addAttribute("framesPlayed",intToStr(framesPlayed), mapTagReplacements);
217 //	int framesToCalculatePlaytime;
218 	statsNode->addAttribute("framesToCalculatePlaytime",intToStr(framesToCalculatePlaytime), mapTagReplacements);
219 //	int maxConcurrentUnitCount;
220 	statsNode->addAttribute("maxConcurrentUnitCount",intToStr(maxConcurrentUnitCount), mapTagReplacements);
221 //	int totalEndGameConcurrentUnitCount;
222 	statsNode->addAttribute("totalEndGameConcurrentUnitCount",intToStr(totalEndGameConcurrentUnitCount), mapTagReplacements);
223 //	bool isMasterserverMode;
224 }
225 
loadGame(const XmlNode * rootNode)226 void Stats::loadGame(const XmlNode *rootNode) {
227 	const XmlNode *statsNode = rootNode->getChild("Stats");
228 
229 	//	PlayerStats playerStats[GameConstants::maxPlayers];
230 
231 	vector<XmlNode *> statsNodePlayerList = statsNode->getChildList("Player");
232 	for(unsigned int i = 0; i < statsNodePlayerList.size(); ++i) {
233 		XmlNode *statsNodePlayer = statsNodePlayerList[i];
234 		PlayerStats &stat = playerStats[i];
235 
236 	//		ControlType control;
237 		stat.control = static_cast<ControlType>(statsNodePlayer->getAttribute("control")->getIntValue());
238 	//		float resourceMultiplier;
239 		stat.resourceMultiplier = statsNodePlayer->getAttribute("resourceMultiplier")->getFloatValue();
240 	//		string factionTypeName;
241 		stat.factionTypeName = statsNodePlayer->getAttribute("factionTypeName")->getValue();
242 	//		FactionPersonalityType personalityType;
243 		stat.personalityType = static_cast<FactionPersonalityType>(statsNodePlayer->getAttribute("personalityType")->getIntValue());
244 	//		int teamIndex;
245 		stat.teamIndex = statsNodePlayer->getAttribute("teamIndex")->getIntValue();
246 	//		bool victory;
247 		stat.victory = statsNodePlayer->getAttribute("victory")->getIntValue() != 0;
248 	//		int kills;
249 		stat.kills = statsNodePlayer->getAttribute("kills")->getIntValue();
250 	//		int enemykills;
251 		stat.enemykills = statsNodePlayer->getAttribute("enemykills")->getIntValue();
252 	//		int deaths;
253 		stat.deaths = statsNodePlayer->getAttribute("deaths")->getIntValue();
254 	//		int unitsProduced;
255 		stat.unitsProduced = statsNodePlayer->getAttribute("unitsProduced")->getIntValue();
256 	//		int resourcesHarvested;
257 		stat.resourcesHarvested = statsNodePlayer->getAttribute("resourcesHarvested")->getIntValue();
258 	//		string playerName;
259 		stat.playerName = statsNodePlayer->getAttribute("playerName")->getValue();
260 	//		Vec3f playerColor;
261 		stat.playerColor = Vec3f::strToVec3(statsNodePlayer->getAttribute("playerColor")->getValue());
262 	}
263 	//	string description;
264 	//statsNode->addAttribute("description",description, mapTagReplacements);
265 	description = statsNode->getAttribute("description")->getValue();
266 	//	int factionCount;
267 	factionCount = statsNode->getAttribute("factionCount")->getIntValue();
268 	//	int thisFactionIndex;
269 	thisFactionIndex = statsNode->getAttribute("thisFactionIndex")->getIntValue();
270 	//
271 	//	float worldTimeElapsed;
272 	worldTimeElapsed = statsNode->getAttribute("worldTimeElapsed")->getFloatValue();
273 	//	int framesPlayed;
274 	framesPlayed = statsNode->getAttribute("framesPlayed")->getIntValue();
275 	//	int framesToCalculatePlaytime;
276 	framesToCalculatePlaytime = statsNode->getAttribute("framesToCalculatePlaytime")->getIntValue();
277 	//	int maxConcurrentUnitCount;
278 	maxConcurrentUnitCount = statsNode->getAttribute("maxConcurrentUnitCount")->getIntValue();
279 	//	int totalEndGameConcurrentUnitCount;
280 	totalEndGameConcurrentUnitCount = statsNode->getAttribute("totalEndGameConcurrentUnitCount")->getIntValue();
281 	//	bool isMasterserverMode;
282 }
283 }}//end namespace
284