std::vector<float> Ship::AllWeaponsDamage() const { std::vector<float> retval; const ShipDesign* design = GetShipDesign(m_design_id); if (!design) return retval; const std::vector<std::string>& parts = design->Parts(); // for each weapon part, get its damage meter value for (std::vector<std::string>::const_iterator part_it = parts.begin(); part_it != parts.end(); ++part_it) { const std::string& part_name = *part_it; const PartType* part = GetPartType(part_name); if (!part) continue; ShipPartClass part_class = part->Class(); // get the attack power for each weapon part float part_attack = 0.0; if (part_class == PC_SHORT_RANGE || part_class == PC_POINT_DEFENSE || part_class == PC_MISSILES) part_attack = this->CurrentPartMeterValue(METER_DAMAGE, part_name); else if (part_class == PC_FIGHTERS) part_attack = this->CurrentPartMeterValue(METER_ANTI_SHIP_DAMAGE, part_name); if (part_attack > 0.0) retval.push_back(part_attack); } return retval; }
std::vector<float> Ship::AllWeaponsMaxDamage(float shield_DR , bool include_fighters) const { std::vector<float> retval; const ShipDesign* design = GetShipDesign(m_design_id); if (!design) return retval; return WeaponDamageImpl(this, design, shield_DR, true, include_fighters); }
ShipDesignPanel::ShipDesignPanel(GG::X w, GG::Y h, int design_id) : GG::Control(GG::X0, GG::Y0, w, h, GG::NO_WND_FLAGS), m_design_id(design_id), m_graphic(0), m_name(0) { if (const ShipDesign* design = GetShipDesign(m_design_id)) { m_graphic = new GG::StaticGraphic(ClientUI::ShipDesignIcon(design_id), GG::GRAPHIC_PROPSCALE | GG::GRAPHIC_FITGRAPHIC); m_graphic->Resize(GG::Pt(w, h)); AttachChild(m_graphic); m_name = new CUILabel(design->Name(), GG::FORMAT_NOWRAP); m_name->SetTextColor(GG::CLR_WHITE); AttachChild(m_name); } }
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; }
std::set<std::string> Ship::Tags() const { std::set<std::string> retval; const ShipDesign* design = GetShipDesign(m_design_id); if (!design) return retval; const HullType* hull = ::GetHullType(design->Hull()); if (!hull) return retval; retval.insert(hull->Tags().begin(), hull->Tags().end()); const std::vector<std::string>& parts = design->Parts(); if (parts.empty()) return retval; for (std::vector<std::string>::const_iterator part_it = parts.begin(); part_it != parts.end(); ++part_it) { if (const PartType* part = GetPartType(*part_it)) { retval.insert(part->Tags().begin(), part->Tags().end()); } } return retval; }
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; } } } }
const ShipDesign* Ship::Design() const { return GetShipDesign(m_design_id); }
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; } } } }
void ShipDesignOrder::ExecuteImpl() const { ValidateEmpireID(); Universe& universe = GetUniverse(); Empire* empire = GetEmpire(EmpireID()); if (m_delete_design_from_empire) { // player is ordering empire to forget about a particular design if (!empire->ShipDesignKept(m_design_id)) { ErrorLogger() << "Tried to remove a ShipDesign that the empire wasn't remembering"; return; } empire->RemoveShipDesign(m_design_id); } else if (m_create_new_design) { // check if a design with this ID already exists if (universe.GetShipDesign(m_design_id)) { ErrorLogger() << "Tried to create a new ShipDesign with an id of an already-existing ShipDesign"; return; } ShipDesign* new_ship_design = new ShipDesign(m_name, m_description, m_designed_on_turn, EmpireID(), m_hull, m_parts, m_icon, m_3D_model, m_name_desc_in_stringtable, m_is_monster); universe.InsertShipDesignID(new_ship_design, m_design_id); universe.SetEmpireKnowledgeOfShipDesign(m_design_id, EmpireID()); empire->AddShipDesign(m_design_id); } else if (m_update_name_or_description) { // player is ordering empire to rename a design const std::set<int>& empire_known_design_ids = universe.EmpireKnownShipDesignIDs(EmpireID()); std::set<int>::iterator design_it = empire_known_design_ids.find(m_design_id); if (design_it == empire_known_design_ids.end()) { ErrorLogger() << "Tried to rename/redescribe a ShipDesign that this empire hasn't seen"; return; } const ShipDesign* design = GetShipDesign(*design_it); if (!design) { ErrorLogger() << "Tried to rename/redescribe a ShipDesign that doesn't exist (but this empire has seen it)!"; return; } if (design->DesignedByEmpire() != EmpireID()) { ErrorLogger() << "Tried to rename/redescribe a ShipDesign that isn't owned by this empire!"; return; } GetUniverse().RenameShipDesign(m_design_id, m_name, m_description); } else if (m_move_design) { //Move an existing design from its current location to just before the after_design if (!empire->ShipDesignKept(m_design_id)) { ErrorLogger() << "Tried to move a ShipDesign that the empire wasn't remembering"; return; } if (m_design_id == m_design_id_after) return; empire->RemoveShipDesign(m_design_id); empire->AddShipDesign(m_design_id, m_design_id_after); DebugLogger() << "Move Ship Design " << m_design_id << " to before " << m_design_id_after; } else { // player is ordering empire to retain a particular design, so that is can // be used to construct ships by that empire. // TODO: consider removing this order, so that an empire needs to use // espionage or trade to gain access to a ship design made by another // player // check if empire is already remembering the design if (empire->ShipDesignKept(m_design_id)) { ErrorLogger() << "Tried to remember a ShipDesign that was already being remembered"; return; } // check if the empire can see any objects that have this design (thus enabling it to be copied) const std::set<int>& empire_known_design_ids = universe.EmpireKnownShipDesignIDs(EmpireID()); if (empire_known_design_ids.find(m_design_id) != empire_known_design_ids.end()) { empire->AddShipDesign(m_design_id); } else { ErrorLogger() << "Tried to remember a ShipDesign that this empire hasn't seen"; return; } } }
void ShipDesignPanel::Update() { if (const ShipDesign* design = GetShipDesign(m_design_id)) { m_name->SetText(design->Name()); m_name->Resize(GG::Pt(Width(), m_name->Height())); } }