/* * Copyright 2010 OpenXcom Developers. * * This file is part of OpenXcom. * * OpenXcom is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenXcom is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenXcom. If not, see . */ #include "Base.h" #include #include "BaseFacility.h" #include "../Ruleset/RuleBaseFacility.h" #include "Craft.h" #include "../Ruleset/RuleCraft.h" #include "../Ruleset/Ruleset.h" #include "Item.h" #include "Soldier.h" #include "SavedGame.h" #include "Ufo.h" #include "Waypoint.h" #include "../Engine/Language.h" namespace OpenXcom { #define SOLDIER_MAINT 20000 #define ENGINEER_MAINT 25000 #define SCIENTIST_MAINT 30000 /** * Initializes an empty base. */ Base::Base() : Target(), _name(L""), _facilities(), _soldiers(), _crafts(), _items(), _scientists(0), _engineers(0) { } /** * Deletes the contents of the base from memory. */ Base::~Base() { for (std::vector::iterator i = _facilities.begin(); i != _facilities.end(); i++) { delete *i; } for (std::vector::iterator i = _soldiers.begin(); i != _soldiers.end(); i++) { delete *i; } for (std::vector::iterator i = _crafts.begin(); i != _crafts.end(); i++) { delete *i; } for (std::map::iterator i = _items.begin(); i != _items.end(); i++) { delete i->second; } } /** * Loads the base from a YAML file. * @param node YAML node. * @param rule Ruleset for the saved game. * @param save Pointer to saved game. */ void Base::load(const YAML::Node &node, Ruleset *rule, SavedGame *save) { unsigned int size = 0; Target::load(node); std::string name; node["name"] >> name; _name = Language::utf8ToWstr(name); size = node["facilities"].size(); for (unsigned i = 0; i < size; i++) { int x, y; node["facilities"][i]["x"] >> x; node["facilities"][i]["y"] >> y; std::string type; node["facilities"][i]["type"] >> type; BaseFacility *f = new BaseFacility(rule->getBaseFacility(type), x, y); f->load(node["facilities"][i]); _facilities.push_back(f); } size = node["crafts"].size(); for (unsigned i = 0; i < size; i++) { std::string type; node["crafts"][i]["type"] >> type; Craft *c = new Craft(rule->getCraft(type), this); c->load(node["crafts"][i], rule); if (const YAML::Node *pName = node["crafts"][i].FindValue("dest")) { std::string type; int id; (*pName)["type"] >> type; (*pName)["id"] >> id; if (type == "STR_BASE") { c->returnToBase(); } else if (type == "STR_UFO") { for (std::vector::iterator i = save->getUfos()->begin(); i != save->getUfos()->end(); i++) { if ((*i)->getId() == id) { c->setDestination(*i); break; } } } else if (type == "STR_WAYPOINT") { for (std::vector::iterator i = save->getWaypoints()->begin(); i != save->getWaypoints()->end(); i++) { if ((*i)->getId() == id) { c->setDestination(*i); break; } } } } _crafts.push_back(c); } size = node["soldiers"].size(); for (unsigned i = 0; i < size; i++) { Soldier *s = new Soldier(); s->load(node["soldiers"][i]); if (const YAML::Node *pName = node["soldiers"][i].FindValue("craft")) { std::string type; int id; (*pName)["type"] >> type; (*pName)["id"] >> id; for (std::vector::iterator i = _crafts.begin(); i != _crafts.end(); i++) { if ((*i)->getRules()->getType() == type && (*i)->getId() == id) { s->setCraft(*i); break; } } } _soldiers.push_back(s); } size = node["items"].size(); for (unsigned i = 0; i < size; i++) { int qty; node["items"][i]["qty"] >> qty; std::string type; node["items"][i]["type"] >> type; Item *it = new Item(rule->getItem(type), qty); it->load(node["items"][i]); _items.insert(std::pair(type, it)); } node["scientists"] >> _scientists; node["engineers"] >> _engineers; } /** * Saves the base to a YAML file. * @param out YAML emitter. */ void Base::save(YAML::Emitter &out) const { Target::save(out); out << YAML::Key << "name" << YAML::Value << Language::wstrToUtf8(_name); out << YAML::Key << "facilities" << YAML::Value; out << YAML::BeginSeq; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { (*i)->save(out); } out << YAML::EndSeq; out << YAML::Key << "soldiers" << YAML::Value; out << YAML::BeginSeq; for (std::vector::const_iterator i = _soldiers.begin(); i != _soldiers.end(); i++) { (*i)->save(out); } out << YAML::EndSeq; out << YAML::Key << "crafts" << YAML::Value; out << YAML::BeginSeq; for (std::vector::const_iterator i = _crafts.begin(); i != _crafts.end(); i++) { (*i)->save(out); } out << YAML::EndSeq; out << YAML::Key << "items" << YAML::Value; out << YAML::BeginSeq; for (std::map::const_iterator i = _items.begin(); i != _items.end(); i++) { (*i).second->save(out); } out << YAML::EndSeq; out << YAML::Key << "scientists" << YAML::Value << _scientists; out << YAML::Key << "engineers" << YAML::Value << _engineers; out << YAML::EndMap; } /** * Saves the base's unique identifiers to a YAML file. * @param out YAML emitter. */ void Base::saveId(YAML::Emitter &out) const { Target::saveId(out); out << YAML::Key << "type" << YAML::Value << "STR_BASE"; out << YAML::Key << "id" << YAML::Value << 0; out << YAML::EndMap; } /** * Returns the custom name for the base. * @param lang Language to get strings from. * @return Name. */ std::wstring Base::getName(Language *lang) const { return _name; } /** * Changes the custom name for the base. * @param name Name. */ void Base::setName(const std::wstring &name) { _name = name; } /** * Returns the list of facilities in the base. * @return Pointer to the facility list. */ std::vector *Base::getFacilities() { return &_facilities; } /** * Returns the list of soldiers in the base. * @return Pointer to the soldier list. */ std::vector *Base::getSoldiers() { return &_soldiers; } /** * Returns the list of crafts in the base. * @return Pointer to the craft list. */ std::vector *Base::getCrafts() { return &_crafts; } /** * Returns the list of items in the base. * @return Pointer to the item list. */ std::map *Base::getItems() { return &_items; } /** * Changes the amount of scientists in the base. * @param scientists Number of scientists. */ void Base::setScientists(int scientists) { _scientists = scientists; } /** * Changes the amount of engineers in the base. * @param engineers Number of engineers. */ void Base::setEngineers(int engineers) { _engineers = engineers; } /** * Returns the amount of soldiers contained * in the base without any assignments. * @return Number of soldiers. */ int Base::getAvailableSoldiers() const { int total = 0; for (std::vector::const_iterator i = _soldiers.begin(); i != _soldiers.end(); i++) { if ((*i)->getCraft() == 0) total++; } return total; } /** * Returns the total amount of soldiers contained * in the base. * @return Number of soldiers. */ int Base::getTotalSoldiers() const { return _soldiers.size(); } /** * Returns the amount of scientists contained * in the base without any assignments. * @return Number of scientists. */ int Base::getAvailableScientists() const { return 0; } /** * Returns the total amount of scientists contained * in the base. * @return Number of scientists. */ int Base::getTotalScientists() const { return _scientists; } /** * Returns the amount of engineers contained * in the base without any assignments. * @return Number of engineers. */ int Base::getAvailableEngineers() const { return 0; } /** * Returns the total amount of engineers contained * in the base. * @return Number of engineers. */ int Base::getTotalEngineers() const { return _engineers; } /** * Returns the amount of living quarters used up * by personnel in the base. * @return Living space. */ int Base::getUsedQuarters() const { return getTotalSoldiers() + getTotalScientists() + getTotalEngineers(); } /** * Returns the total amount of living quarters * available in the base. * @return Living space. */ int Base::getAvailableQuarters() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0) { total += (*i)->getRules()->getPersonnel(); } } return total; } /** * Returns the amount of stores used up * by equipment in the base. * @return Storage space. */ int Base::getUsedStores() const { double total = 0; for (std::map::const_iterator i = _items.begin(); i != _items.end(); i++) { total += i->second->getTotalSize(); } for (std::vector::const_iterator i = _crafts.begin(); i != _crafts.end(); i++) { for (std::map::const_iterator j = (*i)->getItems()->begin(); j != (*i)->getItems()->end(); j++) { total += j->second->getTotalSize(); } } return (int)floor(total); } /** * Returns the total amount of stores * available in the base. * @return Storage space. */ int Base::getAvailableStores() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0) { total += (*i)->getRules()->getStorage(); } } return total; } /** * Returns the amount of laboratories used up * by research projects in the base. * @return Laboratory space. */ int Base::getUsedLaboratories() const { return 0; } /** * Returns the total amount of laboratories * available in the base. * @return Laboratory space. */ int Base::getAvailableLaboratories() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0) { total += (*i)->getRules()->getLaboratories(); } } return total; } /** * Returns the amount of workshops used up * by manufacturing projects in the base. * @return Storage space. */ int Base::getUsedWorkshops() const { return 0; } /** * Returns the total amount of workshops * available in the base. * @return Workshop space. */ int Base::getAvailableWorkshops() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0) { total += (*i)->getRules()->getWorkshops(); } } return total; } /** * Returns the amount of hangars used up * by crafts in the base. * @return Storage space. */ int Base::getUsedHangars() const { return _crafts.size(); } /** * Returns the total amount of hangars * available in the base. * @return Number of hangars. */ int Base::getAvailableHangars() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0) { total += (*i)->getRules()->getCrafts(); } } return total; } /** * Returns the total defence value of all * the facilities in the base. * @return Defence value. */ int Base::getDefenceValue() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0) { total += (*i)->getRules()->getDefenceValue(); } } return total; } /** * Returns the total amount of short range * detection facilities in the base. * @return Defence value. */ int Base::getShortRangeDetection() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0 && (*i)->getRules()->getRadarRange() == 1500) { total++; } } return total; } /** * Returns the total amount of long range * detection facilities in the base. * @return Defence value. */ int Base::getLongRangeDetection() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0 && (*i)->getRules()->getRadarRange() > 1500) { total++; } } return total; } /** * Returns the total amount of craft of * a certain type stored in the base. * @param craft Craft type. * @return Number of craft. */ int Base::getCraftCount(std::string craft) const { int total = 0; for (std::vector::const_iterator i = _crafts.begin(); i != _crafts.end(); i++) { if ((*i)->getRules()->getType() == craft) { total++; } } return total; } /** * Returns the total amount of monthly costs * for maintaining the craft in the base. * @return Maintenance costs. */ int Base::getCraftMaintenance() const { int total = 0; for (std::vector::const_iterator i = _crafts.begin(); i != _crafts.end(); i++) { total += (*i)->getRules()->getMonthlyFee(); } return total; } /** * Returns the total amount of monthly costs * for maintaining the personnel in the base. * @return Maintenance costs. */ int Base::getPersonnelMaintenance() const { int total = 0; total += _soldiers.size() * SOLDIER_MAINT; total += _engineers * ENGINEER_MAINT; total += _scientists * SCIENTIST_MAINT; return total; } /** * Returns the total amount of monthly costs * for maintaining the facilities in the base. * @return Maintenance costs. */ int Base::getFacilityMaintenance() const { int total = 0; for (std::vector::const_iterator i = _facilities.begin(); i != _facilities.end(); i++) { if ((*i)->getBuildTime() == 0) { total += (*i)->getRules()->getMonthlyCost(); } } return total; } /** * Returns the total amount of all the maintenance * monthly costs in the base. * @return Maintenance costs. */ int Base::getMonthlyMaintenace() const { return getCraftMaintenance() + getPersonnelMaintenance() + getFacilityMaintenance(); } }