Example #1
0
/**
 * Generates a brand new saved game with starting data.
 * @return A new saved game.
 */
SavedGame *Ruleset::newSave() const
{
	SavedGame *save = new SavedGame();

	// Add countries
	for (std::vector<std::string>::const_iterator i = _countriesIndex.begin(); i != _countriesIndex.end(); ++i)
	{
		save->getCountries()->push_back(new Country(getCountry(*i)));
	}
	// Adjust funding to total $6M
	int missing = ((6000 - save->getCountryFunding()/1000) / (int)save->getCountries()->size()) * 1000;
	for (std::vector<Country*>::iterator i = save->getCountries()->begin(); i != save->getCountries()->end(); ++i)
	{
		(*i)->setFunding((*i)->getFunding().back() + missing);
	}
	save->setFunds(save->getCountryFunding());

	// Add regions
	for (std::vector<std::string>::const_iterator i = _regionsIndex.begin(); i != _regionsIndex.end(); ++i)
	{
		save->getRegions()->push_back(new Region(getRegion(*i)));
	}

	// Set up IDs
	std::map<std::string, int> ids;
	for (std::vector<std::string>::const_iterator i = _craftsIndex.begin(); i != _craftsIndex.end(); ++i)
	{
		ids[*i] = 1;
	}
	save->initIds(ids);

	// Set up starting base
	Base *base = new Base(this);
	base->load(_startingBase, save, true);

	// Correct IDs
	for (std::vector<Craft*>::const_iterator i = base->getCrafts()->begin(); i != base->getCrafts()->end(); ++i)
	{
		save->getId((*i)->getRules()->getType());
	}

	// Generate soldiers
	int soldiers = _startingBase["randomSoldiers"].as<int>(0);
	for (int i = 0; i < soldiers; ++i)
	{
		Soldier *soldier = new Soldier(getSoldier("XCOM"), getArmor("STR_NONE_UC"), &_names, save->getId("STR_SOLDIER"));
		soldier->setCraft(base->getCrafts()->front());
		base->getSoldiers()->push_back(soldier);
	}

	save->getBases()->push_back(base);
	// Setup alien strategy
	save->getAlienStrategy().init(this);
	save->setTime(_startingTime);

	return save;
}
Example #2
0
/**
 * Prepares debriefing: gathers Aliens, Corpses, Artefacts, UFO Components.
 * Adds the items to the craft.
 * Also calculates the soldiers experience, and possible promotions.
 * If aborted, only the things on the exit area are recovered.
 */
void DebriefingState::prepareDebriefing()
{
	_stats.push_back(new DebriefingStat("STR_ALIENS_KILLED", false));
	_stats.push_back(new DebriefingStat("STR_ALIEN_CORPSES_RECOVERED", false));
	_stats.push_back(new DebriefingStat("STR_LIVE_ALIENS_RECOVERED", false));
	_stats.push_back(new DebriefingStat("STR_ALIEN_ARTIFACTS_RECOVERED", false));
	_stats.push_back(new DebriefingStat("STR_ALIEN_BASE_CONTROL_DESTROYED", false));
	_stats.push_back(new DebriefingStat("STR_CIVILIANS_KILLED_BY_ALIENS", false));
	_stats.push_back(new DebriefingStat("STR_CIVILIANS_KILLED_BY_XCOM_OPERATIVES", false));
	_stats.push_back(new DebriefingStat("STR_CIVILIANS_SAVED", false));
	_stats.push_back(new DebriefingStat("STR_XCOM_OPERATIVES_KILLED", false));
	//_stats.push_back(new DebriefingStat("STR_XCOM_OPERATIVES_RETIRED_THROUGH_INJURY", false));
	_stats.push_back(new DebriefingStat("STR_XCOM_OPERATIVES_MISSING_IN_ACTION", false));
	_stats.push_back(new DebriefingStat("STR_TANKS_DESTROYED", false));
	_stats.push_back(new DebriefingStat("STR_XCOM_CRAFT_LOST", false));
	_stats.push_back(new DebriefingStat("STR_UFO_POWER_SOURCE", true));
	_stats.push_back(new DebriefingStat("STR_UFO_NAVIGATION", true));
	_stats.push_back(new DebriefingStat("STR_UFO_CONSTRUCTION", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_FOOD", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_REPRODUCTION", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_ENTERTAINMENT", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_SURGERY", true));
	_stats.push_back(new DebriefingStat("STR_EXAMINATION_ROOM", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_ALLOYS", true));
	_stats.push_back(new DebriefingStat("STR_ELERIUM_115", true));

	SavedGame *save = _game->getSavedGame();
	SavedBattleGame *battle = save->getBattleGame();
	bool aborted = battle->isAborted();
	Craft* craft = 0;
	std::vector<Craft*>::iterator craftIterator;
	Base* base = 0;

	int playerInExitArea = 0; // if this stays 0 the craft is lost...
	int playersSurvived = 0; // if this stays 0 the craft is lost...

	for (std::vector<Base*>::iterator i = save->getBases()->begin(); i != save->getBases()->end(); ++i)
	{

		// in case we have a craft - check which craft it is about
		for (std::vector<Craft*>::iterator j = (*i)->getCrafts()->begin(); j != (*i)->getCrafts()->end(); ++j)
		{
			if ((*j)->isInBattlescape())
			{
				craft = (*j);
				base = (*i);
				craftIterator = j;
				craft->returnToBase();
				craft->setLowFuel(true);
				craft->setInBattlescape(false);
			}
		}
	}

	// UFO crash/landing site disappears
	for (std::vector<Ufo*>::iterator i = save->getUfos()->begin(); i != save->getUfos()->end(); ++i)
	{
		if ((*i)->isInBattlescape())
		{
			delete *i;
			save->getUfos()->erase(i);
			break;
		}
	}

	// lets see what happens with units
	for (std::vector<BattleUnit*>::iterator j = battle->getUnits()->begin(); j != battle->getUnits()->end(); ++j)
	{
		UnitStatus status = (*j)->getStatus();
		UnitFaction faction = (*j)->getFaction();
		int value = (*j)->getValue();
		Soldier *soldier = save->getSoldier((*j)->getId());

		if (status == STATUS_DEAD)
		{
			if (faction == FACTION_HOSTILE)
			{
				addStat("STR_ALIENS_KILLED", 1, value);
			}
			if (faction == FACTION_PLAYER)
			{
				if (soldier != 0)
				{
					addStat("STR_XCOM_OPERATIVES_KILLED", 1, -value);
					for (std::vector<Soldier*>::iterator i = base->getSoldiers()->begin(); i != base->getSoldiers()->end(); ++i)
					{
						if ((*i) == soldier)
						{
							delete (*i);
							base->getSoldiers()->erase(i);
							break;
						}
					}
				}
				else
				{
					// non soldier player = tank
					addStat("STR_TANKS_DESTROYED", 1, -value);
				}
			}
		}
		else if (status == STATUS_UNCONSCIOUS)
		{
			if (faction == FACTION_HOSTILE && (!aborted || (*j)->isInExitArea()))
			{
				addStat("STR_LIVE_ALIENS_RECOVERED", 1, value);
			}
		}
		else if (faction == FACTION_PLAYER)
		{
			playersSurvived++;
			if ((*j)->isInExitArea() || !aborted)
			{
				playerInExitArea++;
				(*j)->postMissionProcedures(save);
			}
			else
			{
				addStat("STR_XCOM_OPERATIVES_MISSING_IN_ACTION", 1, -value);
				for (std::vector<Soldier*>::iterator i = base->getSoldiers()->begin(); i != base->getSoldiers()->end(); ++i)
				{
					if ((*i) == soldier)
					{
						delete (*i);
						base->getSoldiers()->erase(i);
						break;
					}
				}
			}
		}
	}
	if (((playerInExitArea == 0 && aborted) || (playersSurvived == 0)) && craft != 0)
	{
		addStat("STR_XCOM_CRAFT_LOST", 1, -200);
		delete craft;
		base->getCrafts()->erase(craftIterator);
		for (std::vector<Soldier*>::iterator i = base->getSoldiers()->begin(); i != base->getSoldiers()->end();)
		{
			if ((*i)->getCraft() == craft)
			{
				delete (*i);
				i = base->getSoldiers()->erase(i);
			}
			else
			{
				 ++i;
			}
		}
		_txtTitle->setText(_game->getLanguage()->getString("STR_CRAFT_IS_LOST"));
		return;
	}

	if (!aborted && playersSurvived > 0) 	// RECOVER UFO : run through all tiles to recover UFO components and items
	{
		if (battle->getMissionType() == "STR_BASE_DEFENCE")
		{
			_txtTitle->setText(_game->getLanguage()->getString("STR_BASE_IS_SAVED"));
		}
		else
		{
			_txtTitle->setText(_game->getLanguage()->getString("STR_UFO_IS_RECOVERED"));
		}

		for (int i = 0; i < battle->getHeight() * battle->getLength() * battle->getWidth(); ++i)
		{
			for (int part = 0; part < 4; part++)
			{
				if (battle->getTiles()[i]->getMapData(part))
				{
					switch (battle->getTiles()[i]->getMapData(part)->getSpecialType())
					{
					case UFO_POWER_SOURCE:
						addStat("STR_UFO_POWER_SOURCE", 1, 1); break;
					case DESTROY_OBJECTIVE:break; // this is the brain
					case UFO_NAVIGATION:
						addStat("STR_UFO_NAVIGATION", 1, 1); break;
					case ALIEN_FOOD:
						addStat("STR_ALIEN_FOOD", 1, 1); break;
					case ALIEN_REPRODUCTION:
						addStat("STR_ALIEN_REPRODUCTION", 1, 1); break;
					case ALIEN_ENTERTAINMENT:
						addStat("STR_ALIEN_ENTERTAINMENT", 1, 1); break;
					case ALIEN_SURGERY:
						addStat("STR_ALIEN_SURGERY", 1, 1); break;
					case UNKNOWN09:
						addStat("STR_UFO_CONSTRUCTION", 1, 1); break;
					case ALIEN_ALLOYS:
						addStat("STR_ALIEN_ALLOYS", 1, 1); break;
					case EXAM_ROOM:
						addStat("STR_EXAMINATION_ROOM", 1, 1); break;
					}

				}
			}
		}

		// alien alloys recovery values are divided by 10 or divided by 150 in case of an alien base
		int divider = battle->getMissionType()=="STR_ALIEN_BASE_ASSAULT"?150:10;
		for (std::vector<DebriefingStat*>::iterator i = _stats.begin(); i != _stats.end(); ++i)
		{
			if ((*i)->item == "STR_ALIEN_ALLOYS")
			{
				(*i)->qty = (*i)->qty / divider;
				(*i)->score = (*i)->score / divider;
				break;
			}

			/*if ((*i)->recovery && (*i)->qty > 0)
			{
				base->getItems()->addItem((*i)->item, (*i)->qty);
			}*/
		}
	}
	else
	{
		if (battle->getMissionType() == "STR_BASE_DEFENCE")
		{
			_txtTitle->setText(_game->getLanguage()->getString("STR_BASE_IS_LOST"));
		}
		else
		{
			_txtTitle->setText(_game->getLanguage()->getString("STR_UFO_IS_NOT_RECOVERED"));
		}
	}

}
Example #3
0
/**
 * Loads new battle data from a YAML file.
 * @param filename YAML filename.
 */
void NewBattleState::load(const std::string &filename)
{
	std::string s = Options::getMasterUserFolder() + filename + ".cfg";
	if (!CrossPlatform::fileExists(s))
	{
		initSave();
	}
	else
	{
		try
		{
			YAML::Node doc = YAML::LoadFile(s);
			_cbxMission->setSelected(std::min(doc["mission"].as<size_t>(0), _missionTypes.size() - 1));
			cbxMissionChange(0);
			_cbxCraft->setSelected(std::min(doc["craft"].as<size_t>(0), _crafts.size() - 1));
			_slrDarkness->setValue(doc["darkness"].as<size_t>(0));
			_cbxTerrain->setSelected(std::min(doc["terrain"].as<size_t>(0), _terrainTypes.size() - 1));
			cbxTerrainChange(0);
			_cbxAlienRace->setSelected(std::min(doc["alienRace"].as<size_t>(0), _alienRaces.size() - 1));
			_cbxDifficulty->setSelected(doc["difficulty"].as<size_t>(0));
			_slrAlienTech->setValue(doc["alienTech"].as<size_t>(0));

			if (doc["base"])
			{
				const Mod *mod = _game->getMod();
				SavedGame *save = new SavedGame();

				Base *base = new Base(mod);
				base->load(doc["base"], save, false);
				save->getBases()->push_back(base);

				// Add research
				const std::vector<std::string> &research = mod->getResearchList();
				for (std::vector<std::string>::const_iterator i = research.begin(); i != research.end(); ++i)
				{
					save->addFinishedResearchSimple(mod->getResearch(*i));
				}

				// Generate items
				base->getStorageItems()->getContents()->clear();
				const std::vector<std::string> &items = mod->getItemsList();
				for (std::vector<std::string>::const_iterator i = items.begin(); i != items.end(); ++i)
				{
					RuleItem *rule = _game->getMod()->getItem(*i);
					if (rule->getBattleType() != BT_CORPSE && rule->isRecoverable())
					{
						base->getStorageItems()->addItem(*i, 1);
					}
				}

				// Fix invalid contents
				if (base->getCrafts()->empty())
				{
					std::string craftType = _crafts[_cbxCraft->getSelected()];
					_craft = new Craft(_game->getMod()->getCraft(craftType), base, save->getId(craftType));
					base->getCrafts()->push_back(_craft);
				}
				else
				{
					_craft = base->getCrafts()->front();
					for (std::map<std::string, int>::iterator i = _craft->getItems()->getContents()->begin(); i != _craft->getItems()->getContents()->end(); ++i)
					{
						RuleItem *rule = _game->getMod()->getItem(i->first);
						if (!rule)
						{
							i->second = 0;
						}
					}
				}

				_game->setSavedGame(save);
			}
			else
			{
				initSave();
			}
		}
		catch (YAML::Exception &e)
		{
			Log(LOG_WARNING) << e.what();
			initSave();
		}
	}
}
Example #4
0
/**
 * Initializes a new savegame with
 * everything available.
 */
void NewBattleState::initSave()
{
	const Mod *mod = _game->getMod();
	SavedGame *save = new SavedGame();
	Base *base = new Base(mod);
	const YAML::Node &starter = _game->getMod()->getStartingBase();
	base->load(starter, save, true, true);
	save->getBases()->push_back(base);

	// Kill everything we don't want in this base
	for (std::vector<Soldier*>::iterator i = base->getSoldiers()->begin(); i != base->getSoldiers()->end(); ++i) delete (*i);
	base->getSoldiers()->clear();
	for (std::vector<Craft*>::iterator i = base->getCrafts()->begin(); i != base->getCrafts()->end(); ++i) delete (*i);
	base->getCrafts()->clear();
	base->getStorageItems()->getContents()->clear();

	_craft = new Craft(mod->getCraft(_crafts[_cbxCraft->getSelected()]), base, 1);
	base->getCrafts()->push_back(_craft);

	// Generate soldiers
	for (int i = 0; i < 30; ++i)
	{
		int randomType = RNG::generate(0, _game->getMod()->getSoldiersList().size() - 1);
		Soldier *soldier = mod->genSoldier(save, _game->getMod()->getSoldiersList().at(randomType));

		for (int n = 0; n < 5; ++n)
		{
			if (RNG::percent(70))
				continue;
			soldier->promoteRank();

			UnitStats* stats = soldier->getCurrentStats();
			stats->tu 			+= RNG::generate(0, 5);
			stats->stamina		+= RNG::generate(0, 5);
			stats->health		+= RNG::generate(0, 5);
			stats->bravery		+= RNG::generate(0, 5);
			stats->reactions	+= RNG::generate(0, 5);
			stats->firing		+= RNG::generate(0, 5);
			stats->throwing		+= RNG::generate(0, 5);
			stats->strength		+= RNG::generate(0, 5);
			stats->psiStrength	+= RNG::generate(0, 5);
			stats->melee		+= RNG::generate(0, 5);
			stats->psiSkill		+= RNG::generate(0, 20);
		}
		UnitStats* stats = soldier->getCurrentStats();
		stats->bravery = (int)ceil(stats->bravery / 10.0) * 10; // keep it a multiple of 10

		base->getSoldiers()->push_back(soldier);
		if (i < _craft->getRules()->getSoldiers())
			soldier->setCraft(_craft);
	}

	// Generate items
	const std::vector<std::string> &items = mod->getItemsList();
	for (std::vector<std::string>::const_iterator i = items.begin(); i != items.end(); ++i)
	{
		RuleItem *rule = _game->getMod()->getItem(*i);
		if (rule->getBattleType() != BT_CORPSE && rule->isRecoverable())
		{
			base->getStorageItems()->addItem(*i, 1);
			if (rule->getBattleType() != BT_NONE && !rule->isFixed() && rule->getBigSprite() > -1)
			{
				_craft->getItems()->addItem(*i, 1);
			}
		}
	}

	// Add research
	const std::vector<std::string> &research = mod->getResearchList();
	for (std::vector<std::string>::const_iterator i = research.begin(); i != research.end(); ++i)
	{
		save->addFinishedResearchSimple(mod->getResearch(*i));
	}

	_game->setSavedGame(save);
	cbxMissionChange(0);
}
Example #5
0
void StatisticsState::listStats()
{
	SavedGame *save = _game->getSavedGame();

	std::ostringstream ss;
	GameTime *time = save->getTime();
	if (save->getEnding() == END_WIN)
	{
		ss << tr("STR_VICTORY");
	}
	else if (save->getEnding() == END_LOSE)
	{
		ss << tr("STR_DEFEAT");
	}
	else
	{
		ss << tr("STR_STATISTICS");
	}
	ss << Unicode::TOK_NL_SMALL << time->getDayString(_game->getLanguage()) << " " << tr(time->getMonthString()) << " " << time->getYear();
	_txtTitle->setText(ss.str());

	int monthlyScore = sumVector(save->getResearchScores()) / save->getResearchScores().size();
	int64_t totalIncome = sumVector(save->getIncomes());
	int64_t totalExpenses = sumVector(save->getExpenditures());

	int alienBasesDestroyed = 0, xcomBasesLost = 0;
	int missionsWin = 0, missionsLoss = 0, nightMissions = 0;
	int bestScore = -9999, worstScore = 9999;
	for (std::vector<MissionStatistics*>::const_iterator i = save->getMissionStatistics()->begin(); i != save->getMissionStatistics()->end(); ++i)
	{
		if ((*i)->success)
		{
			missionsWin++;
		}
		else
		{
			missionsLoss++;
		}
		bestScore = std::max(bestScore, (*i)->score);
		worstScore = std::min(worstScore, (*i)->score);
		if ((*i)->daylight > 5)
		{
			nightMissions++;
		}
		if ((*i)->isAlienBase() && (*i)->success)
		{
			alienBasesDestroyed++;
		}
		if ((*i)->isBaseDefense() && !(*i)->success)
		{
			xcomBasesLost++;
		}
	}
	// Make sure dummy values aren't left in
	bestScore = (bestScore == -9999) ? 0 : bestScore;
	worstScore = (worstScore == 9999) ? 0 : worstScore;

	std::vector<Soldier*> allSoldiers;
	for (std::vector<Base*>::const_iterator i = save->getBases()->begin(); i != save->getBases()->end(); ++i)
	{
		allSoldiers.insert(allSoldiers.end(), (*i)->getSoldiers()->begin(), (*i)->getSoldiers()->end());
	}
	allSoldiers.insert(allSoldiers.end(), save->getDeadSoldiers()->begin(), save->getDeadSoldiers()->end());
	int soldiersRecruited = allSoldiers.size();
	int soldiersLost = save->getDeadSoldiers()->size();

	int aliensKilled = 0, aliensCaptured = 0, friendlyKills = 0;
	int daysWounded = 0, longestMonths = 0;
	int shotsFired = 0, shotsLanded = 0;
	std::map<std::string, int> weaponKills, alienKills;
	for (std::vector<Soldier*>::iterator i = allSoldiers.begin(); i != allSoldiers.end(); ++i)
	{
		SoldierDiary *diary = (*i)->getDiary();
		aliensKilled += diary->getKillTotal();
		aliensCaptured += diary->getStunTotal();
		daysWounded += diary->getDaysWoundedTotal();
		longestMonths = std::max(longestMonths, diary->getMonthsService());
		std::map<std::string, int> weaponTotal = diary->getWeaponTotal();
		shotsFired += diary->getShotsFiredTotal();
		shotsLanded += diary->getShotsLandedTotal();
		for (std::map<std::string, int>::const_iterator j = weaponTotal.begin(); j != weaponTotal.end(); ++j)
		{
			if (weaponKills.find(j->first) == weaponKills.end())
			{
				weaponKills[j->first] = j->second;
			}
			else
			{
				weaponKills[j->first] += j->second;
			}
		}

		if ((*i)->getDeath() != 0 && (*i)->getDeath()->getCause() != 0)
		{
			const BattleUnitKills *kills = (*i)->getDeath()->getCause();
			if (kills->faction == FACTION_PLAYER)
			{
				friendlyKills++;
			}
			if (!kills->race.empty())
			{
				if (alienKills.find(kills->race) == alienKills.end())
				{
					alienKills[kills->race] = 1;
				}
				else
				{
					alienKills[kills->race] += 1;
				}
			}
		}
	}
	int accuracy = 0;
	if (shotsFired > 0)
	{
		accuracy = 100 * shotsLanded / shotsFired;
	}

	int maxWeapon = 0;
	std::string highestWeapon = "STR_NONE";
	for (std::map<std::string, int>::const_iterator i = weaponKills.begin(); i != weaponKills.end(); ++i)
	{
		if (i->second > maxWeapon)
		{
			maxWeapon = i->second;
			highestWeapon = i->first;
		}
	}
	int maxAlien = 0;
	std::string highestAlien = "STR_NONE";
	for (std::map<std::string, int>::const_iterator i = alienKills.begin(); i != alienKills.end(); ++i)
	{
		if (i->second > maxAlien)
		{
			maxAlien = i->second;
			highestAlien = i->first;
		}
	}

	std::map<std::string, int> ids = save->getAllIds();
	int alienBases = alienBasesDestroyed;
	for (std::vector<AlienBase*>::iterator i = save->getAlienBases()->begin(); i != save->getAlienBases()->end(); ++i)
	{
		if ((*i)->isDiscovered())
		{
			alienBases++;
		}
	}
	int ufosDetected = std::max(0, ids["STR_UFO"] - 1);
	int terrorSites = std::max(0, ids["STR_TERROR_SITE"] - 1);
	int totalCrafts = 0;
	for (std::vector<std::string>::const_iterator i = _game->getMod()->getCraftsList().begin(); i != _game->getMod()->getCraftsList().end(); ++i)
	{
		totalCrafts += std::max(0, ids[*i] - 1);
	}

	int xcomBases = save->getBases()->size() + xcomBasesLost;
	int currentScientists = 0, currentEngineers = 0;
	for (std::vector<Base*>::const_iterator i = save->getBases()->begin(); i != save->getBases()->end(); ++i)
	{
		currentScientists += (*i)->getTotalScientists();
		currentEngineers += (*i)->getTotalEngineers();
	}

	int countriesLost = 0;
	for (std::vector<Country*>::const_iterator i = save->getCountries()->begin(); i != save->getCountries()->end(); ++i)
	{
		if ((*i)->getPact())
		{
			countriesLost++;
		}
	}

	int researchDone = save->getDiscoveredResearch().size();

	std::string difficulty[] = { "STR_1_BEGINNER", "STR_2_EXPERIENCED", "STR_3_VETERAN", "STR_4_GENIUS", "STR_5_SUPERHUMAN" };

	_lstStats->addRow(2, tr("STR_DIFFICULTY").c_str(), tr(difficulty[save->getDifficulty()]).c_str());
	_lstStats->addRow(2, tr("STR_AVERAGE_MONTHLY_RATING").c_str(), Unicode::formatNumber(monthlyScore).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_INCOME").c_str(), Unicode::formatFunding(totalIncome).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_EXPENDITURE").c_str(), Unicode::formatFunding(totalExpenses).c_str());
	_lstStats->addRow(2, tr("STR_MISSIONS_WON").c_str(), Unicode::formatNumber(missionsWin).c_str());
	_lstStats->addRow(2, tr("STR_MISSIONS_LOST").c_str(), Unicode::formatNumber(missionsLoss).c_str());
	_lstStats->addRow(2, tr("STR_NIGHT_MISSIONS").c_str(), Unicode::formatNumber(nightMissions).c_str());
	_lstStats->addRow(2, tr("STR_BEST_RATING").c_str(), Unicode::formatNumber(bestScore).c_str());
	_lstStats->addRow(2, tr("STR_WORST_RATING").c_str(), Unicode::formatNumber(worstScore).c_str());
	_lstStats->addRow(2, tr("STR_SOLDIERS_RECRUITED").c_str(), Unicode::formatNumber(soldiersRecruited).c_str());
	_lstStats->addRow(2, tr("STR_SOLDIERS_LOST").c_str(), Unicode::formatNumber(soldiersLost).c_str());
	_lstStats->addRow(2, tr("STR_ALIEN_KILLS").c_str(), Unicode::formatNumber(aliensKilled).c_str());
	_lstStats->addRow(2, tr("STR_ALIEN_CAPTURES").c_str(), Unicode::formatNumber(aliensCaptured).c_str());
	_lstStats->addRow(2, tr("STR_FRIENDLY_KILLS").c_str(), Unicode::formatNumber(friendlyKills).c_str());
	_lstStats->addRow(2, tr("STR_AVERAGE_ACCURACY").c_str(), Unicode::formatPercentage(accuracy).c_str());
	_lstStats->addRow(2, tr("STR_WEAPON_MOST_KILLS").c_str(), tr(highestWeapon).c_str());
	_lstStats->addRow(2, tr("STR_ALIEN_MOST_KILLS").c_str(), tr(highestAlien).c_str());
	_lstStats->addRow(2, tr("STR_LONGEST_SERVICE").c_str(), Unicode::formatNumber(longestMonths).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_DAYS_WOUNDED").c_str(), Unicode::formatNumber(daysWounded).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_UFOS").c_str(), Unicode::formatNumber(ufosDetected).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_ALIEN_BASES").c_str(), Unicode::formatNumber(alienBases).c_str());
	_lstStats->addRow(2, tr("STR_COUNTRIES_LOST").c_str(), Unicode::formatNumber(countriesLost).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_TERROR_SITES").c_str(), Unicode::formatNumber(terrorSites).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_BASES").c_str(), Unicode::formatNumber(xcomBases).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_CRAFT").c_str(), Unicode::formatNumber(totalCrafts).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_SCIENTISTS").c_str(), Unicode::formatNumber(currentScientists).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_ENGINEERS").c_str(), Unicode::formatNumber(currentEngineers).c_str());
	_lstStats->addRow(2, tr("STR_TOTAL_RESEARCH").c_str(), Unicode::formatNumber(researchDone).c_str());
}