void PopCenter::SetSpecies(const std::string& species_name) { const Species* species = GetSpecies(species_name); if (!species && !species_name.empty()) { Logger().errorStream() << "PopCenter::SetSpecies couldn't get species with name " << species_name; } m_species_name = species_name; }
PlanetEnvironment Planet::EnvironmentForSpecies(const std::string& species_name/* = ""*/) const { const Species* species = nullptr; if (species_name.empty()) { const std::string& this_planet_species_name = this->SpeciesName(); if (this_planet_species_name.empty()) return PE_UNINHABITABLE; species = GetSpecies(this_planet_species_name); } else { species = GetSpecies(species_name); } if (!species) { ErrorLogger() << "Planet::EnvironmentForSpecies couldn't get species with name \"" << species_name << "\""; return PE_UNINHABITABLE; } return species->GetPlanetEnvironment(m_type); }
PlanetType Planet::NextBetterPlanetTypeForSpecies(const std::string& species_name/* = ""*/) const { const Species* species = nullptr; if (species_name.empty()) { const std::string& this_planet_species_name = this->SpeciesName(); if (this_planet_species_name.empty()) return m_type; species = GetSpecies(this_planet_species_name); } else { species = GetSpecies(species_name); } if (!species) { ErrorLogger() << "Planet::NextBetterPlanetTypeForSpecies couldn't get species with name \"" << species_name << "\""; return m_type; } return species->NextBetterPlanetType(m_type); }
const std::string& Planet::FocusIcon(const std::string& focus_name) const { if (const Species* species = GetSpecies(this->SpeciesName())) { for (const FocusType& focus_type : species->Foci()) { if (focus_type.Name() == focus_name) return focus_type.Graphic(); } } return EMPTY_STRING; }
bool Planet::HasTag(const std::string& name) const { const Species* species = GetSpecies(SpeciesName()); if (!species) return false; const std::vector<std::string>& tags = species->Tags(); for (std::vector<std::string>::const_iterator it = tags.begin(); it != tags.end(); ++it) if (*it == name) return true; return false; }
const std::string& Planet::FocusIcon(const std::string& focus_name) const { if (const Species* species = GetSpecies(this->SpeciesName())) { const std::vector<FocusType>& foci = species->Foci(); for (std::vector<FocusType>::const_iterator it = foci.begin(); it != foci.end(); ++it) { const FocusType& focus_type = *it; if (focus_type.Name() == focus_name) return focus_type.Graphic(); } } return EMPTY_STRING; }
bool Ship::CanColonize() const { if (m_species_name.empty()) return false; const Species* species = GetSpecies(m_species_name); if (!species) return false; if (!species->CanColonize()) return false; const ShipDesign* design = this->Design(); return design && design->CanColonize(); // use design->CanColonize because zero-capacity colony ships still count as outpost ships, can "can colonize" as far as order / the UI are concerned }
bool WantToContinue(creatureADT *creatureP,int num,double *time) { int i; int *k; string str; symtabADT symtab=NewSymbolTable(); for (i=0;i<=num-1;i++) { if ( Lookup ( symtab ,SpeciesName ( GetSpecies (creatureP[i]) ) )==UNDEFINED ) { k=GetBlock(sizeof (int) ); *k=1; Enter( symtab , SpeciesName ( GetSpecies (creatureP[i]) ) , k); } else { k=(int*)Lookup(symtab,SpeciesName ( GetSpecies (creatureP[i]) )); *k=*k+1; } } printf("\nInventory:\n"); MapSymbolTable(PrintInventory,symtab,NULL); FreeSymbolTable(symtab); ChangeTimeInterval(time); while(TRUE) { printf("\npress s+Enter to stop and c+Enter to continue :"); str=GetLine(); if (StringEqual(str,"s")) {return FALSE;} if (StringEqual(str,"c")) { printf("\nTo pause,click mouse on the graph.\n"); return TRUE; } } }
std::vector<std::string> Planet::AvailableFoci() const { std::vector<std::string> retval; ScriptingContext context(this); if (const Species* species = GetSpecies(this->SpeciesName())) { const std::vector<FocusType>& foci = species->Foci(); for (std::vector<FocusType>::const_iterator it = foci.begin(); it != foci.end(); ++it) { const FocusType& focus_type = *it; if (const Condition::ConditionBase* location = focus_type.Location()) { if (location->Eval(context, this)) retval.push_back(focus_type.Name()); } } } return retval; }
std::vector<std::string> Planet::AvailableFoci() const { std::vector<std::string> retval; auto this_planet = std::dynamic_pointer_cast<const Planet>(UniverseObject::shared_from_this()); if (!this_planet) return retval; ScriptingContext context(this_planet); if (const auto* species = GetSpecies(this_planet->SpeciesName())) { for (const auto& focus_type : species->Foci()) { if (const auto* location = focus_type.Location()) { if (location->Eval(context, this_planet)) retval.push_back(focus_type.Name()); } } } return retval; }
bool Ship::CanColonize() const { if (m_species_name.empty()) return false; const Species* species = GetSpecies(m_species_name); if (!species) return false; if (!species->CanColonize()) return false; const ShipDesign* design = Design(); if (!design) return false; if (!design->CanColonize()) return false; return true; }
std::vector<std::string> Planet::AvailableFoci() const { std::vector<std::string> retval; TemporaryPtr<const Planet> this_planet = boost::dynamic_pointer_cast<const Planet>(TemporaryFromThis()); if (!this_planet) return retval; ScriptingContext context(this_planet); if (const Species* species = GetSpecies(this_planet->SpeciesName())) { for (const FocusType& focus_type : species->Foci()) { if (const Condition::ConditionBase* location = focus_type.Location()) { if (location->Eval(context, this_planet)) retval.push_back(focus_type.Name()); } } } return retval; }
std::vector<std::string> Planet::AvailableFoci() const { std::vector<std::string> retval; ScriptingContext context(this); if (const Species* species = GetSpecies(this->SpeciesName())) { const std::vector<FocusType>& foci = species->Foci(); for (std::vector<FocusType>::const_iterator it = foci.begin(); it != foci.end(); ++it) { const FocusType& focus_type = *it; if (const Condition::ConditionBase* location = focus_type.Location()) { Condition::ObjectSet potential_targets; potential_targets.reserve(RESERVE_SET_SIZE); potential_targets.push_back(this); Condition::ObjectSet matched_targets; matched_targets.reserve(RESERVE_SET_SIZE); location->Eval(context, matched_targets, potential_targets); if (!matched_targets.empty()) retval.push_back(focus_type.Name()); } } } return retval; }
void avtSpeciesMetaData::Print(ostream &out, int indent) const { Indent(out, indent); out << "Name = " << name.c_str() << endl; if (name != originalName) { Indent(out, indent); out << "Original Name = " << originalName.c_str() << endl; } Indent(out, indent); out << "Mesh Name = " << meshName.c_str() << endl; Indent(out, indent); out << "Material Name = " << materialName.c_str() << endl; Indent(out, indent); out << "Number of materials = " << numMaterials << endl; for (int i = 0 ; i < GetNumSpecies() ; i++) { Indent(out, indent); const avtMatSpeciesMetaData &s = GetSpecies(i); out << "Material " << i << ", number of species = " << s.numSpecies << endl; Indent(out, indent); out << "Species names are: "; for (int j = 0 ; j < s.numSpecies ; j++) { out << "\"" << s.speciesNames[j].c_str() << "\""; if(j < s.numSpecies - 1) out << ", "; } out << endl; } if (!validVariable) { Indent(out, indent); out << "THIS IS NOT A VALID VARIABLE." << endl; } }
bool Ship::HasTag(const std::string& name) const { const ShipDesign* design = GetShipDesign(m_design_id); if (design) { // check hull for tag const HullType* hull = ::GetHullType(design->Hull()); if (hull && hull->Tags().count(name)) return true; // check parts for tag const std::vector<std::string>& parts = design->Parts(); for (std::vector<std::string>::const_iterator part_it = parts.begin(); part_it != parts.end(); ++part_it) { const PartType* part = GetPartType(*part_it); if (part && part->Tags().count(name)) return true; } } // check species for tag const Species* species = GetSpecies(SpeciesName()); if (species && species->Tags().count(name)) return true; return false; }
Ship::Ship(int empire_id, int design_id, const std::string& species_name, int produced_by_empire_id/* = ALL_EMPIRES*/) : m_design_id(design_id), m_fleet_id(INVALID_OBJECT_ID), m_ordered_scrapped(false), m_ordered_colonize_planet_id(INVALID_OBJECT_ID), m_ordered_invade_planet_id(INVALID_OBJECT_ID), m_ordered_bombard_planet_id(INVALID_OBJECT_ID), m_last_turn_active_in_combat(INVALID_GAME_TURN), m_species_name(species_name), m_produced_by_empire_id(produced_by_empire_id) { if (!GetShipDesign(design_id)) throw std::invalid_argument("Attempted to construct a Ship with an invalid design id"); if (!m_species_name.empty() && !GetSpecies(m_species_name)) Logger().debugStream() << "Ship created with invalid species name: " << m_species_name; SetOwner(empire_id); UniverseObject::Init(); AddMeter(METER_FUEL); AddMeter(METER_MAX_FUEL); AddMeter(METER_SHIELD); AddMeter(METER_MAX_SHIELD); AddMeter(METER_DETECTION); AddMeter(METER_STRUCTURE); AddMeter(METER_MAX_STRUCTURE); AddMeter(METER_BATTLE_SPEED); AddMeter(METER_STARLANE_SPEED); const std::vector<std::string>& part_names = Design()->Parts(); for (std::size_t i = 0; i < part_names.size(); ++i) { if (part_names[i] != "") { const PartType* part = GetPartType(part_names[i]); if (!part) { Logger().errorStream() << "Ship::Ship couldn't get part with name " << part_names[i]; continue; } switch (part->Class()) { case PC_SHORT_RANGE: case PC_POINT_DEFENSE: { m_part_meters[std::make_pair(METER_DAMAGE, part->Name())]; m_part_meters[std::make_pair(METER_ROF, part->Name())]; m_part_meters[std::make_pair(METER_RANGE, part->Name())]; break; } case PC_MISSILES: { std::pair<std::size_t, std::size_t>& part_missiles = m_missiles[part_names[i]]; ++part_missiles.first; part_missiles.second += boost::get<LRStats>(part->Stats()).m_capacity; m_part_meters[std::make_pair(METER_DAMAGE, part->Name())]; m_part_meters[std::make_pair(METER_ROF, part->Name())]; m_part_meters[std::make_pair(METER_RANGE, part->Name())]; m_part_meters[std::make_pair(METER_SPEED, part->Name())]; m_part_meters[std::make_pair(METER_STEALTH, part->Name())]; m_part_meters[std::make_pair(METER_STRUCTURE, part->Name())]; m_part_meters[std::make_pair(METER_CAPACITY, part->Name())]; break; } case PC_FIGHTERS: { std::pair<std::size_t, std::size_t>& part_fighters = m_fighters[part_names[i]]; ++part_fighters.first; part_fighters.second += boost::get<FighterStats>(part->Stats()).m_capacity; m_part_meters[std::make_pair(METER_ANTI_SHIP_DAMAGE, part->Name())]; m_part_meters[std::make_pair(METER_ANTI_FIGHTER_DAMAGE, part->Name())]; m_part_meters[std::make_pair(METER_LAUNCH_RATE, part->Name())]; m_part_meters[std::make_pair(METER_FIGHTER_WEAPON_RANGE,part->Name())]; m_part_meters[std::make_pair(METER_SPEED, part->Name())]; m_part_meters[std::make_pair(METER_STEALTH, part->Name())]; m_part_meters[std::make_pair(METER_STRUCTURE, part->Name())]; m_part_meters[std::make_pair(METER_DETECTION, part->Name())]; m_part_meters[std::make_pair(METER_CAPACITY, part->Name())]; break; } default: break; } } } }
bool Planet::HasTag(const std::string& name) const { const Species* species = GetSpecies(SpeciesName()); return species && species->Tags().count(name); }
std::set<std::string> Planet::Tags() const { const Species* species = GetSpecies(SpeciesName()); if (!species) return std::set<std::string>(); return species->Tags(); }
bool ShipDesign::ProductionLocation(int empire_id, int location_id) const { const UniverseObject* location = GetUniverseObject(location_id); if (!location) return false; // currently ships can only be built at planets, and by species that are // not planetbound const Planet* planet = universe_object_cast<const Planet*>(location); if (!planet) return false; const std::string& species_name = planet->SpeciesName(); if (species_name.empty()) return false; const Species* species = GetSpecies(species_name); if (!species) return false; if (!species->CanProduceShips()) return false; // also, species that can't colonize can't produce colony ships if (this->CanColonize() && !species->CanColonize()) return false; Empire* empire = Empires().Lookup(empire_id); if (!empire) { Logger().debugStream() << "ShipDesign::ProductionLocation: Unable to get pointer to empire " << empire_id; return false; } // get a source object, which is owned by the empire with the passed-in // empire id. this is used in conditions to reference which empire is // doing the producing. Ideally this will be the capital, but any object // owned by the empire will work. const UniverseObject* source = SourceForEmpire(empire_id); // if this empire doesn't own ANYTHING, then how is it producing anyway? if (!source) return false; // apply hull location conditions to potential location const HullType* hull = GetHull(); if (!hull) { Logger().errorStream() << "ShipDesign::ProductionLocation ShipDesign couldn't get its own hull with name " << m_hull; return false; } if (!hull->Location()->Eval(ScriptingContext(source), location)) return false; // apply external and internal parts' location conditions to potential location for (std::vector<std::string>::const_iterator part_it = m_parts.begin(); part_it != m_parts.end(); ++part_it) { std::string part_name = *part_it; if (part_name.empty()) continue; // empty slots don't limit build location const PartType* part = GetPartType(part_name); if (!part) { Logger().errorStream() << "ShipDesign::ProductionLocation ShipDesign couldn't get part with name " << part_name; return false; } if (!part->Location()->Eval(ScriptingContext(source), location)) return false; } // location matched all hull and part conditions, so is a valid build location return true; }
void HumanClientApp::NewSinglePlayerGame(bool quickstart) { if (!GetOptionsDB().Get<bool>("force-external-server")) { try { StartServer(); } catch (const std::runtime_error& err) { ErrorLogger() << "HumanClientApp::NewSinglePlayerGame : Couldn't start server. Got error message: " << err.what(); ClientUI::MessageBox(UserString("SERVER_WONT_START"), true); return; } } bool ended_with_ok = false; if (!quickstart) { GalaxySetupWnd galaxy_wnd; galaxy_wnd.Run(); ended_with_ok = galaxy_wnd.EndedWithOk(); } bool failed = false; unsigned int start_time = Ticks(); while (!m_networking.ConnectToLocalHostServer(boost::posix_time::seconds(2))) { if (SERVER_CONNECT_TIMEOUT < Ticks() - start_time) { ClientUI::MessageBox(UserString("ERR_CONNECT_TIMED_OUT"), true); failed = true; break; } } m_connected = !failed; if (!failed && (quickstart || ended_with_ok)) { DebugLogger() << "HumanClientApp::NewSinglePlayerGame : Connected to server"; SinglePlayerSetupData setup_data; setup_data.m_new_game = true; setup_data.m_filename.clear(); // not used for new game // get values stored in options from previous time game was run or // from just having run GalaxySetupWnd // GalaxySetupData setup_data.m_seed = GetOptionsDB().Get<std::string>("GameSetup.seed"); setup_data.m_size = GetOptionsDB().Get<int>("GameSetup.stars"); setup_data.m_shape = GetOptionsDB().Get<Shape>("GameSetup.galaxy-shape"); setup_data.m_age = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.galaxy-age"); setup_data.m_starlane_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.starlane-frequency"); setup_data.m_planet_density = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.planet-density"); setup_data.m_specials_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.specials-frequency"); setup_data.m_monster_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.monster-frequency"); setup_data.m_native_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.native-frequency"); setup_data.m_ai_aggr = GetOptionsDB().Get<Aggression>("GameSetup.ai-aggression"); // SinglePlayerSetupData contains a map of PlayerSetupData, for // the human and AI players. Need to compile this information // from the specified human options and number of requested AIs // Human player setup data first PlayerSetupData human_player_setup_data; human_player_setup_data.m_player_name = GetOptionsDB().Get<std::string>("GameSetup.player-name"); human_player_setup_data.m_empire_name = GetOptionsDB().Get<std::string>("GameSetup.empire-name"); // DB stores index into array of available colours, so need to get that array to look up value of index. // if stored value is invalid, use a default colour const std::vector<GG::Clr>& empire_colours = EmpireColors(); int colour_index = GetOptionsDB().Get<int>("GameSetup.empire-color"); if (colour_index >= 0 && colour_index < static_cast<int>(empire_colours.size())) human_player_setup_data.m_empire_color = empire_colours[colour_index]; else human_player_setup_data.m_empire_color = GG::CLR_GREEN; human_player_setup_data.m_starting_species_name = GetOptionsDB().Get<std::string>("GameSetup.starting-species"); if (human_player_setup_data.m_starting_species_name == "1") human_player_setup_data.m_starting_species_name = "SP_HUMAN"; // kludge / bug workaround for bug with options storage and retreival. Empty-string options are stored, but read in as "true" boolean, and converted to string equal to "1" if (!GetSpecies(human_player_setup_data.m_starting_species_name)) { const SpeciesManager& sm = GetSpeciesManager(); if (sm.NumPlayableSpecies() < 1) human_player_setup_data.m_starting_species_name.clear(); else human_player_setup_data.m_starting_species_name = sm.playable_begin()->first; } human_player_setup_data.m_save_game_empire_id = ALL_EMPIRES; // not used for new games human_player_setup_data.m_client_type = Networking::CLIENT_TYPE_HUMAN_PLAYER; // add to setup data players setup_data.m_players.push_back(human_player_setup_data); // AI player setup data. One entry for each requested AI int num_AIs = GetOptionsDB().Get<int>("GameSetup.ai-players"); for (int ai_i = 1; ai_i <= num_AIs; ++ai_i) { PlayerSetupData ai_setup_data; ai_setup_data.m_player_name = "AI_" + boost::lexical_cast<std::string>(ai_i); ai_setup_data.m_empire_name.clear(); // leave blank, to be set by server in Universe::GenerateEmpires ai_setup_data.m_empire_color = GG::CLR_ZERO; // to be set by server ai_setup_data.m_starting_species_name.clear(); // leave blank, to be set by server ai_setup_data.m_save_game_empire_id = ALL_EMPIRES; // not used for new games ai_setup_data.m_client_type = Networking::CLIENT_TYPE_AI_PLAYER; setup_data.m_players.push_back(ai_setup_data); } m_networking.SendMessage(HostSPGameMessage(setup_data)); m_fsm->process_event(HostSPGameRequested()); } else { DebugLogger() << "HumanClientApp::NewSinglePlayerGame killing server due to canceled game or server connection failure"; if (m_networking.Connected()) { DebugLogger() << "HumanClientApp::NewSinglePlayerGame Sending server shutdown message."; m_networking.SendMessage(ShutdownServerMessage(m_networking.PlayerID())); boost::this_thread::sleep(boost::posix_time::seconds(1)); m_networking.DisconnectFromServer(); if (!m_networking.Connected()) DebugLogger() << "HumanClientApp::NewSinglePlayerGame Disconnected from server."; else ErrorLogger() << "HumanClientApp::NewSinglePlayerGame Unexpectedly still connected to server...?"; } KillServer(); } }
void Ship::SetSpecies(const std::string& species_name) { if (!GetSpecies(species_name)) ErrorLogger() << "Ship::SetSpecies couldn't get species with name " << species_name; m_species_name = species_name; }
bool Planet::Colonize(int empire_id, const std::string& species_name, double population) { const Species* species = 0; // if desired pop > 0, we want a colony, not an outpost, so we need to do some checks if (population > 0.0) { // check if specified species exists and get reference species = GetSpecies(species_name); if (!species) { Logger().errorStream() << "Planet::Colonize couldn't get species already on planet with name: " << species_name; return false; } // check if specified species can colonize this planet if (EnvironmentForSpecies(species_name) < PE_HOSTILE) { Logger().errorStream() << "Planet::Colonize: can't colonize planet already populated by species " << species_name; return false; } } // reset the planet to unowned/unpopulated Reset(); // if desired pop > 0, we want a colony, not an outpost, so we have to set the colony species if (population > 0.0) SetSpecies(species_name); // find a default focus. use first defined available focus. // AvailableFoci function should return a vector of all names of // available foci. std::vector<std::string> available_foci = AvailableFoci(); if (species && !available_foci.empty()) { bool found_preference = false; for (std::vector<std::string>::const_iterator it = available_foci.begin(); it != available_foci.end(); ++it) { if (!it->empty() && *it == species->PreferredFocus()) { SetFocus(*it); found_preference = true; break; } } if (!found_preference) SetFocus(*available_foci.begin()); } else { Logger().debugStream() << "Planet::Colonize unable to find a focus to set for species " << species_name; } // set colony population GetMeter(METER_POPULATION)->SetCurrent(population); GetMeter(METER_TARGET_POPULATION)->SetCurrent(population); GetMeter(METER_HAPPINESS)->SetCurrent(20.0f); BackPropegateMeters(); // set specified empire as owner SetOwner(empire_id); // if there are buildings on the planet, set the specified empire as their owner too std::vector<TemporaryPtr<Building> > buildings = Objects().FindObjects<Building>(BuildingIDs()); for (std::vector<TemporaryPtr<Building> >::iterator building_it = buildings.begin(); building_it != buildings.end(); ++building_it) { (*building_it)->SetOwner(empire_id); } return true; }
bool Planet::Colonize(int empire_id, const std::string& species_name, double population) { const Species* species = nullptr; // if desired pop > 0, we want a colony, not an outpost, so we need to do some checks if (population > 0.0) { // check if specified species exists and get reference species = GetSpecies(species_name); if (!species) { ErrorLogger() << "Planet::Colonize couldn't get species already on planet with name: " << species_name; return false; } // check if specified species can colonize this planet if (EnvironmentForSpecies(species_name) < PE_HOSTILE) { ErrorLogger() << "Planet::Colonize: can't colonize planet already populated by species " << species_name; return false; } } // reset the planet to unowned/unpopulated if (!OwnedBy(empire_id)) { Reset(); } else { PopCenter::Reset(); for (int building_id : m_buildings) if (auto building = GetBuilding(building_id)) building->Reset(); m_just_conquered = false; m_is_about_to_be_colonized = false; m_is_about_to_be_invaded = false; m_is_about_to_be_bombarded = false; SetOwner(ALL_EMPIRES); } // if desired pop > 0, we want a colony, not an outpost, so we have to set the colony species if (population > 0.0) SetSpecies(species_name); // find a default focus. use first defined available focus. // AvailableFoci function should return a vector of all names of // available foci. std::vector<std::string> available_foci = AvailableFoci(); if (species && !available_foci.empty()) { bool found_preference = false; for (const std::string& focus : available_foci) { if (!focus.empty() && focus == species->PreferredFocus()) { SetFocus(focus); found_preference = true; break; } } if (!found_preference) SetFocus(*available_foci.begin()); } else { DebugLogger() << "Planet::Colonize unable to find a focus to set for species " << species_name; } // set colony population GetMeter(METER_POPULATION)->SetCurrent(population); GetMeter(METER_TARGET_POPULATION)->SetCurrent(population); BackPropagateMeters(); // set specified empire as owner SetOwner(empire_id); // if there are buildings on the planet, set the specified empire as their owner too for (auto& building : Objects().FindObjects<Building>(BuildingIDs())) { building->SetOwner(empire_id); } return true; }
Ship::Ship(int empire_id, int design_id, const std::string& species_name, int produced_by_empire_id/* = ALL_EMPIRES*/) : UniverseObject(), m_design_id(design_id), m_fleet_id(INVALID_OBJECT_ID), m_ordered_scrapped(false), m_ordered_colonize_planet_id(INVALID_OBJECT_ID), m_ordered_invade_planet_id(INVALID_OBJECT_ID), m_ordered_bombard_planet_id(INVALID_OBJECT_ID), m_last_turn_active_in_combat(INVALID_GAME_TURN), m_species_name(species_name), m_produced_by_empire_id(produced_by_empire_id), m_arrived_on_turn(CurrentTurn()) { if (!GetShipDesign(design_id)) throw std::invalid_argument("Attempted to construct a Ship with an invalid design id"); if (!m_species_name.empty() && !GetSpecies(m_species_name)) DebugLogger() << "Ship created with invalid species name: " << m_species_name; SetOwner(empire_id); UniverseObject::Init(); AddMeter(METER_FUEL); AddMeter(METER_MAX_FUEL); AddMeter(METER_SHIELD); AddMeter(METER_MAX_SHIELD); AddMeter(METER_DETECTION); AddMeter(METER_STRUCTURE); AddMeter(METER_MAX_STRUCTURE); AddMeter(METER_SPEED); AddMeter(METER_TARGET_INDUSTRY); AddMeter(METER_INDUSTRY); AddMeter(METER_TARGET_RESEARCH); AddMeter(METER_RESEARCH); AddMeter(METER_TARGET_TRADE); AddMeter(METER_TRADE); const std::vector<std::string>& part_names = Design()->Parts(); for (std::size_t i = 0; i < part_names.size(); ++i) { if (part_names[i] != "") { const PartType* part = GetPartType(part_names[i]); if (!part) { ErrorLogger() << "Ship::Ship couldn't get part with name " << part_names[i]; continue; } switch (part->Class()) { case PC_COLONY: case PC_TROOPS: { m_part_meters[std::make_pair(METER_CAPACITY, part->Name())]; break; } case PC_DIRECT_WEAPON: // capacity is damage, secondary stat is shots per attack case PC_FIGHTER_HANGAR: { // capacity is how many fighters contained, secondary stat is damage per fighter attack m_part_meters[std::make_pair(METER_SECONDARY_STAT, part->Name())]; m_part_meters[std::make_pair(METER_MAX_SECONDARY_STAT, part->Name())]; // intentionally no break here } case PC_FIGHTER_BAY: { // capacity is how many fighters launched per combat round m_part_meters[std::make_pair(METER_CAPACITY, part->Name())]; m_part_meters[std::make_pair(METER_MAX_CAPACITY, part->Name())]; break; } default: break; } } } }