/* * 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 "ItemContainer.h" #include "Soldier.h" #include "SavedGame.h" #include "Ufo.h" #include "Waypoint.h" #include "../Engine/Language.h" #include "../Ruleset/RuleItem.h" #include "Transfer.h" namespace OpenXcom { /** * Initializes an empty base. * @param rule Pointer to ruleset. */ Base::Base(const Ruleset *rule) : Target(), _rule(rule), _name(L""), _facilities(), _soldiers(), _crafts(), _scientists(0), _engineers(0) { _items = new ItemContainer(); } /** * 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; } delete _items; } /** * Loads the base from a YAML file. * @param node YAML node. * @param save Pointer to saved game. */ void Base::load(const YAML::Node &node, 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 int 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), this, x, y); f->load(node["facilities"][i]); _facilities.push_back(f); } size = node["crafts"].size(); for (unsigned int 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 int i = 0; i < size; ++i) { Soldier *s = new Soldier(_rule->getSoldier("XCOM"), _rule->getArmor("STR_NONE_UC")); 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); } _items->load(node["items"]); node["scientists"] >> _scientists; node["engineers"] >> _engineers; size = node["transfers"].size(); for (unsigned int i = 0; i < size; ++i) { int hours; node["transfers"][i]["hours"] >> hours; Transfer *t = new Transfer(hours); t->load(node["transfers"][i], this, _rule); _transfers.push_back(t); } } /** * 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; _items->save(out); out << YAML::Key << "scientists" << YAML::Value << _scientists; out << YAML::Key << "engineers" << YAML::Value << _engineers; out << YAML::Key << "transfers" << YAML::Value; out << YAML::BeginSeq; for (std::vector::const_iterator i = _transfers.begin(); i != _transfers.end(); ++i) { (*i)->save(out); } out << YAML::EndSeq; 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 *const Base::getFacilities() { return &_facilities; } /** * Returns the list of soldiers in the base. * @return Pointer to the soldier list. */ std::vector *const Base::getSoldiers() { return &_soldiers; } /** * Returns the list of crafts in the base. * @return Pointer to the craft list. */ std::vector *const Base::getCrafts() { return &_crafts; } /** * Returns the list of transfers destined * to this base. * @return Pointer to the transfer list. */ std::vector *const Base::getTransfers() { return &_transfers; } /** * Returns the list of items in the base. * @return Pointer to the item list. */ ItemContainer *const Base::getItems() { return _items; } /** * Returns the amount of scientists currently in the base. * @return Number of scientists. */ int Base::getScientists() const { return _scientists; } /** * Changes the amount of scientists currently in the base. * @param scientists Number of scientists. */ void Base::setScientists(int scientists) { _scientists = scientists; } /** * Returns the amount of engineers currently in the base. * @return Number of engineers. */ int Base::getEngineers() const { return _engineers; } /** * Changes the amount of engineers currently 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 { int total = _soldiers.size(); for (std::vector::const_iterator i = _transfers.begin(); i != _transfers.end(); ++i) { if ((*i)->getType() == TRANSFER_SOLDIER) { total += (*i)->getQuantity(); } } return total; } /** * Returns the amount of scientists contained * in the base without any assignments. * @return Number of scientists. */ int Base::getAvailableScientists() const { return _scientists; } /** * Returns the total amount of scientists contained * in the base. * @return Number of scientists. */ int Base::getTotalScientists() const { int total = _scientists; for (std::vector::const_iterator i = _transfers.begin(); i != _transfers.end(); ++i) { if ((*i)->getType() == TRANSFER_SCIENTIST) { total += (*i)->getQuantity(); } } return total; } /** * Returns the amount of engineers contained * in the base without any assignments. * @return Number of engineers. */ int Base::getAvailableEngineers() const { return _engineers; } /** * Returns the total amount of engineers contained * in the base. * @return Number of engineers. */ int Base::getTotalEngineers() const { int total = _engineers; for (std::vector::const_iterator i = _transfers.begin(); i != _transfers.end(); ++i) { if ((*i)->getType() == TRANSFER_ENGINEER) { total += (*i)->getQuantity(); } } return total; } /** * 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 = _items->getTotalSize(_rule); for (std::vector::const_iterator i = _crafts.begin(); i != _crafts.end(); ++i) { total += (*i)->getItems()->getTotalSize(_rule); } for (std::vector::const_iterator i = _transfers.begin(); i != _transfers.end(); ++i) { if ((*i)->getType() == TRANSFER_ITEM) { total += (*i)->getQuantity() * _rule->getItem((*i)->getItems())->getSize(); } } 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 { int total = _crafts.size(); for (std::vector::const_iterator i = _transfers.begin(); i != _transfers.end(); ++i) { if ((*i)->getType() == TRANSFER_CRAFT) { total += (*i)->getQuantity(); } } return total; } /** * 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()->getCost(); } 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() * _rule->getSoldierCost(); total += _engineers * _rule->getEngineerCost(); total += _scientists * _rule->getScientistCost(); 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(); } }