bool BombardOrder::UndoImpl() const { TemporaryPtr<Planet> planet = GetPlanet(m_planet); if (!planet) { ErrorLogger() << "BombardOrder::UndoImpl couldn't get planet with id " << m_planet; return false; } TemporaryPtr<Ship> ship = GetShip(m_ship); if (!ship) { ErrorLogger() << "BombardOrder::UndoImpl couldn't get ship with id " << m_ship; return false; } if (ship->OrderedBombardPlanet() != m_planet) { ErrorLogger() << "BombardOrder::UndoImpl ship is not about to bombard planet"; return false; } planet->SetIsAboutToBeBombarded(false); ship->ClearBombardPlanet(); if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID())) fleet->StateChangedSignal(); return true; }
bool ColonizeOrder::UndoImpl() const { TemporaryPtr<Planet> planet = GetPlanet(m_planet); if (!planet) { ErrorLogger() << "ColonizeOrder::UndoImpl couldn't get planet with id " << m_planet; return false; } if (!planet->IsAboutToBeColonized()) { ErrorLogger() << "ColonizeOrder::UndoImpl planet is not about to be colonized..."; return false; } TemporaryPtr<Ship> ship = GetShip(m_ship); if (!ship) { ErrorLogger() << "ColonizeOrder::UndoImpl couldn't get ship with id " << m_ship; return false; } if (ship->OrderedColonizePlanet() != m_planet) { ErrorLogger() << "ColonizeOrder::UndoImpl ship is not about to colonize planet"; return false; } planet->SetIsAboutToBeColonized(false); ship->ClearColonizePlanet(); if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID())) fleet->StateChangedSignal(); return true; }
void Fleet::AddShip(int ship_id) { if (this->Contains(ship_id)) { Logger().debugStream() << "Fleet::AddShip this fleet '" << this->Name() << "' already contained ship '" << ship_id << "'"; return; } Ship* ship = GetShip(ship_id); if (!ship) { Logger().errorStream() << "Fleet::AddShips() : Attempted to add an id (" << ship_id << ") of a non-ship object to a fleet."; return; } //Logger().debugStream() << "Fleet '" << this->Name() << "' adding ship: " << ship_id; // remove ship from old fleet if (Fleet* old_fleet = GetFleet(ship->FleetID())) old_fleet->RemoveShip(ship_id); // ensure ship is in same system as this fleet int ship_system_id = ship->SystemID(); int this_fleet_system_id = this->SystemID(); if (ship_system_id != this_fleet_system_id) if (System* system = GetSystem(this_fleet_system_id)) system->Insert(ship); // sets ship's system, remove from old system (if any) and moves ship to system's location (if necessary) // add ship to this fleet, and set its internal fleet record ship->SetFleetID(ID()); m_ships.insert(ship_id); RecalculateFleetSpeed(); StateChangedSignal(); }
void System::Remove(int id) { if (id == INVALID_OBJECT_ID) return; bool removed_fleet = false; std::set<int>::iterator it = m_fleets.find(id); if (it != m_fleets.end()) { m_fleets.erase(it); removed_fleet = true; } it = m_planets.find(id); if (it != m_planets.end()) { m_planets.erase(it); for (int i = 0; i < static_cast<int>(m_orbits.size()); ++i) if (m_orbits[i] == id) m_orbits[i] = INVALID_OBJECT_ID; } m_ships.erase(id); m_fields.erase(id); m_buildings.erase(id); m_objects.erase(id); if (removed_fleet) { if (TemporaryPtr<Fleet> fleet = GetFleet(id)) { std::vector<TemporaryPtr<Fleet> > fleets; fleets.push_back(fleet); FleetsRemovedSignal(fleets); } } StateChangedSignal(); }
FleetMoveOrder::FleetMoveOrder(int empire, int fleet_id, int start_system_id, int dest_system_id, bool append) : Order(empire), m_fleet(fleet_id), m_start_system(start_system_id), m_dest_system(dest_system_id), m_append(append) { // perform sanity checks TemporaryPtr<const Fleet> fleet = GetFleet(FleetID()); if (!fleet) { ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet with id " << FleetID() << " to move, but no such fleet exists"; return; } TemporaryPtr<const System> destination_system = GetSystem(DestinationSystemID()); if (!destination_system) { ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet to move to system with id " << DestinationSystemID() << " but no such system exists / is known to exist"; return; } // verify that empire specified in order owns specified fleet if (!fleet->OwnedBy(EmpireID()) ) { ErrorLogger() << "Empire with id " << EmpireID() << " order to move but does not own fleet with id " << FleetID(); return; } std::pair<std::list<int>, double> short_path = GetUniverse().ShortestPath(m_start_system, m_dest_system, empire); m_route.clear(); std::copy(short_path.first.begin(), short_path.first.end(), std::back_inserter(m_route)); // ensure a zero-length (invalid) route is not requested / sent to a fleet if (m_route.empty()) m_route.push_back(m_start_system); }
std::vector<Fleet> Game::Fleets() const { std::vector<Fleet> r; for (size_t i = 0; i < NumFleets(); ++i) { r.push_back(GetFleet(i)); } return r; }
void AggressiveOrder::ExecuteImpl() const { ValidateEmpireID(); int empire_id = EmpireID(); if (TemporaryPtr<Fleet> fleet = GetFleet(m_object_id)) { if (fleet->OwnedBy(empire_id)) fleet->SetAggressive(m_aggression); } }
std::vector<Fleet> Game::EnemyFleets() const { std::vector<Fleet> r; for (size_t i = 0; i < NumFleets(); ++i) { if (state.fleets[i].owner > 1) r.push_back(GetFleet(i)); } return r; }
void BombardOrder::ExecuteImpl() const { ValidateEmpireID(); int empire_id = EmpireID(); TemporaryPtr<Ship> ship = GetShip(m_ship); if (!ship) { ErrorLogger() << "BombardOrder::ExecuteImpl couldn't get ship with id " << m_ship; return; } if (!ship->CanBombard()) { ErrorLogger() << "BombardOrder::ExecuteImpl got ship that can't bombard"; return; } if (!ship->OwnedBy(empire_id)) { ErrorLogger() << "BombardOrder::ExecuteImpl got ship that isn't owned by the order-issuing empire"; return; } TemporaryPtr<Planet> planet = GetPlanet(m_planet); if (!planet) { ErrorLogger() << "BombardOrder::ExecuteImpl couldn't get planet with id " << m_planet; return; } if (planet->OwnedBy(empire_id)) { ErrorLogger() << "BombardOrder::ExecuteImpl given planet that is already owned by the order-issuing empire"; return; } if (!planet->Unowned() && Empires().GetDiplomaticStatus(planet->Owner(), empire_id) != DIPLO_WAR) { ErrorLogger() << "BombardOrder::ExecuteImpl given planet owned by an empire not at war with order-issuing empire"; return; } if (GetUniverse().GetObjectVisibilityByEmpire(m_planet, empire_id) < VIS_BASIC_VISIBILITY) { ErrorLogger() << "BombardOrder::ExecuteImpl given planet that empire reportedly has insufficient visibility of, but will be allowed to proceed pending investigation"; //return; } int ship_system_id = ship->SystemID(); if (ship_system_id == INVALID_OBJECT_ID) { ErrorLogger() << "BombardOrder::ExecuteImpl given id of ship not in a system"; return; } int planet_system_id = planet->SystemID(); if (ship_system_id != planet_system_id) { ErrorLogger() << "BombardOrder::ExecuteImpl given ids of ship and planet not in the same system"; return; } // note: multiple ships, from same or different empires, can invade the same planet on the same turn DebugLogger() << "BombardOrder::ExecuteImpl set for ship " << m_ship << " " << ship->Name() << " to bombard planet " << m_planet << " " << planet->Name(); planet->SetIsAboutToBeBombarded(true); ship->SetBombardPlanet(m_planet); if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID())) fleet->StateChangedSignal(); }
int IssueColonizeOrder(int ship_id, int planet_id) { int empire_id = AIClientApp::GetApp()->EmpireID(); // make sure ship_id is a ship... TemporaryPtr<const Ship> ship = GetShip(ship_id); if (!ship) { Logger().errorStream() << "AIInterface::IssueColonizeOrder : passed an invalid ship_id"; return 0; } // get fleet of ship TemporaryPtr<const Fleet> fleet = GetFleet(ship->FleetID()); if (!fleet) { Logger().errorStream() << "AIInterface::IssueColonizeOrder : ship with passed ship_id has invalid fleet_id"; return 0; } // make sure player owns ship and its fleet if (!fleet->OwnedBy(empire_id)) { Logger().errorStream() << "AIInterface::IssueColonizeOrder : empire does not own fleet of passed ship"; return 0; } if (!ship->OwnedBy(empire_id)) { Logger().errorStream() << "AIInterface::IssueColonizeOrder : empire does not own passed ship"; return 0; } // verify that planet exists and is un-occupied. TemporaryPtr<const Planet> planet = GetPlanet(planet_id); if (!planet) { Logger().errorStream() << "AIInterface::IssueColonizeOrder : no planet with passed planet_id"; return 0; } if ((!planet->Unowned()) && !( planet->OwnedBy(empire_id) && planet->CurrentMeterValue(METER_POPULATION)==0)) { Logger().errorStream() << "AIInterface::IssueColonizeOrder : planet with passed planet_id "<<planet_id<<" is already owned, or colonized by own empire"; return 0; } // verify that planet is in same system as the fleet if (planet->SystemID() != fleet->SystemID()) { Logger().errorStream() << "AIInterface::IssueColonizeOrder : fleet and planet are not in the same system"; return 0; } if (ship->SystemID() == INVALID_OBJECT_ID) { Logger().errorStream() << "AIInterface::IssueColonizeOrder : ship is not in a system"; return 0; } AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new ColonizeOrder(empire_id, ship_id, planet_id))); return 1; }
void GiveObjectToEmpireOrder::ExecuteImpl() const { ValidateEmpireID(); int empire_id = EmpireID(); if (TemporaryPtr<Fleet> fleet = GetFleet(m_object_id)) { if (fleet->OwnedBy(empire_id)) fleet->SetGiveToEmpire(m_recipient_empire_id); } else if (TemporaryPtr<Planet> planet = GetPlanet(m_object_id)) { if (planet->OwnedBy(empire_id)) planet->SetGiveToEmpire(m_recipient_empire_id); } }
void Ship::Copy(TemporaryPtr<const UniverseObject> copied_object, int empire_id) { if (copied_object == this) return; TemporaryPtr<const Ship> copied_ship = boost::dynamic_pointer_cast<const Ship>(copied_object); if (!copied_ship) { Logger().errorStream() << "Ship::Copy passed an object that wasn't a Ship"; return; } int copied_object_id = copied_object->ID(); Visibility vis = GetUniverse().GetObjectVisibilityByEmpire(copied_object_id, empire_id); std::set<std::string> visible_specials = GetUniverse().GetObjectVisibleSpecialsByEmpire(copied_object_id, empire_id); UniverseObject::Copy(copied_object, vis, visible_specials);; if (vis >= VIS_BASIC_VISIBILITY) { if (this->m_fleet_id != copied_ship->m_fleet_id) { // as with other containers, removal from the old container is triggered by the contained Object; removal from System is handled by UniverseObject::Copy if (TemporaryPtr<Fleet> oldFleet = GetFleet(this->m_fleet_id)) oldFleet->RemoveShip(this->ID()); this->m_fleet_id = copied_ship->m_fleet_id; // as with other containers (Systems), actual insertion into fleet ships set is handled by the fleet } if (vis >= VIS_PARTIAL_VISIBILITY) { if (this->Unowned()) this->m_name = copied_ship->m_name; this->m_design_id = copied_ship->m_design_id; this->m_fighters = copied_ship->m_fighters; this->m_missiles = copied_ship->m_missiles; for (PartMeterMap::const_iterator it = copied_ship->m_part_meters.begin(); it != copied_ship->m_part_meters.end(); ++it) { this->m_part_meters[it->first]; } this->m_species_name = copied_ship->m_species_name; if (vis >= VIS_FULL_VISIBILITY) { this->m_ordered_scrapped = copied_ship->m_ordered_scrapped; this->m_ordered_colonize_planet_id= copied_ship->m_ordered_colonize_planet_id; this->m_ordered_invade_planet_id = copied_ship->m_ordered_invade_planet_id; this->m_ordered_bombard_planet_id = copied_ship->m_ordered_bombard_planet_id; this->m_last_turn_active_in_combat= copied_ship->m_last_turn_active_in_combat; this->m_part_meters = copied_ship->m_part_meters; this->m_produced_by_empire_id = copied_ship->m_produced_by_empire_id; } } } }
bool GiveObjectToEmpireOrder::UndoImpl() const { ValidateEmpireID(); int empire_id = EmpireID(); if (TemporaryPtr<Fleet> fleet = GetFleet(m_object_id)) { if (fleet->OwnedBy(empire_id)) { fleet->ClearGiveToEmpire(); return true; } } else if (TemporaryPtr<Planet> planet = GetPlanet(m_object_id)) { if (planet->OwnedBy(empire_id)) { planet->ClearGiveToEmpire(); return true; } } return false; }
int IssueAggressionOrder(int object_id, bool aggressive) { int empire_id = AIClientApp::GetApp()->EmpireID(); TemporaryPtr<const Fleet> fleet = GetFleet(object_id); if (!fleet) { Logger().errorStream() << "AIInterface::IssueAggressionOrder : no fleet with passed id"; return 0; } if (!fleet->OwnedBy(empire_id)) { Logger().errorStream() << "AIInterface::IssueAggressionOrder : passed object_id of object not owned by player"; return 0; } AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new AggressiveOrder(empire_id, object_id, aggressive))); return 1; }
int IssueFleetTransferOrder(int ship_id, int new_fleet_id) { int empire_id = AIClientApp::GetApp()->EmpireID(); TemporaryPtr<const Ship> ship = GetShip(ship_id); if (!ship) { Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : passed an invalid ship_id " << ship_id; return 0; } int ship_sys_id = ship->SystemID(); if (ship_sys_id == INVALID_OBJECT_ID) { Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : ship is not in a system"; return 0; } if (!ship->OwnedBy(empire_id)) { Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : passed ship_id of ship not owned by player"; return 0; } TemporaryPtr<const Fleet> fleet = GetFleet(new_fleet_id); if (!fleet) { Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : passed an invalid new_fleet_id " << new_fleet_id; return 0; } int fleet_sys_id = fleet->SystemID(); if (fleet_sys_id == INVALID_OBJECT_ID) { Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : new fleet is not in a system"; return 0; } if (!fleet->OwnedBy(empire_id)) { Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : passed fleet_id "<< new_fleet_id << " of fleet not owned by player"; return 0; } if (fleet_sys_id != ship_sys_id) { Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : new fleet in system " << fleet_sys_id << " and ship in system "<< ship_sys_id << " are not in the same system"; return 0; } std::vector<int> ship_ids; ship_ids.push_back(ship_id); AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new FleetTransferOrder(empire_id, new_fleet_id, ship_ids))); return 1; }
void DeleteFleetOrder::ExecuteImpl() const { ValidateEmpireID(); TemporaryPtr<Fleet> fleet = GetFleet(FleetID()); if (!fleet) { ErrorLogger() << "Illegal fleet id specified in fleet delete order: " << FleetID(); return; } if (!fleet->OwnedBy(EmpireID())) { ErrorLogger() << "Empire attempted to issue deletion order to another's fleet."; return; } if (!fleet->Empty()) return; // should be no ships to delete TemporaryPtr<System> system = GetSystem(fleet->SystemID()); if (system) system->Remove(fleet->ID()); GetUniverse().Destroy(FleetID()); }
int IssueFleetMoveOrder(int fleet_id, int destination_id) { TemporaryPtr<const Fleet> fleet = GetFleet(fleet_id); if (!fleet) { Logger().errorStream() << "AIInterface::IssueFleetMoveOrder : passed an invalid fleet_id"; return 0; } int empire_id = AIClientApp::GetApp()->EmpireID(); if (!fleet->OwnedBy(empire_id)) { Logger().errorStream() << "AIInterface::IssueFleetMoveOrder : passed fleet_id of fleet not owned by player"; return 0; } int start_id = fleet->SystemID(); if (start_id == INVALID_OBJECT_ID) start_id = fleet->NextSystemID(); if (destination_id != INVALID_OBJECT_ID && destination_id == start_id) Logger().debugStream() << "AIInterface::IssueFleetMoveOrder : pass destination system id (" << destination_id << ") that fleet is already in"; AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new FleetMoveOrder(empire_id, fleet_id, start_id, destination_id))); return 1; }
void FleetButton::Init(const std::vector<int>& fleet_IDs, SizeType size_type) { //std::cout << "FleetButton::Init" << std::endl; // get fleets std::vector<TemporaryPtr<const Fleet> > fleets; for (std::vector<int>::const_iterator it = fleet_IDs.begin(); it != fleet_IDs.end(); ++it) { TemporaryPtr<const Fleet> fleet = GetFleet(*it); if (!fleet) { ErrorLogger() << "FleetButton::FleetButton couldn't get fleet with id " << *it; continue; } m_fleets.push_back(*it); fleets.push_back(fleet); } // determine owner(s) of fleet(s). Only care whether or not there is more than one owner, as owner // is used to determine colouration int owner_id = ALL_EMPIRES; int multiple_owners = false; if (fleets.empty()) { // leave as ALL_EMPIRES } else if (fleets.size() == 1) { owner_id = (*fleets.begin())->Owner(); } else { owner_id = (*fleets.begin())->Owner(); // use ALL_EMPIRES if there are multiple owners (including no owner and an owner) for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) { TemporaryPtr<const Fleet> fleet = *it; if (fleet->Owner() != owner_id) { owner_id = ALL_EMPIRES; multiple_owners = true; break; } } } // get fleet colour if (multiple_owners) { SetColor(GG::CLR_WHITE); } else if (owner_id == ALL_EMPIRES) { // all ships owned by now empire bool monsters = true; // find if any ship in fleets in button is not a monster for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) { TemporaryPtr<const Fleet> fleet = *it; for (std::set<int>::const_iterator ship_it = fleet->ShipIDs().begin(); ship_it != fleet->ShipIDs().end(); ++ship_it) { if (TemporaryPtr<const Ship> ship = GetShip(*ship_it)) { if (!ship->IsMonster()) { monsters = false; break; } } } } if (monsters) SetColor(GG::CLR_RED); else SetColor(GG::CLR_WHITE); } else { // single empire owner if (const Empire* empire = GetEmpire(owner_id)) SetColor(empire->Color()); else SetColor(GG::CLR_GRAY); // should never be necessary... but just in case } // determine direction button should be rotated to orient along a starlane GLfloat pointing_angle = 0.0f; TemporaryPtr<const Fleet> first_fleet; if (!m_fleets.empty()) first_fleet = *fleets.begin(); if (first_fleet && first_fleet->SystemID() == INVALID_OBJECT_ID && first_fleet->NextSystemID() != INVALID_OBJECT_ID) { int next_sys_id = first_fleet->NextSystemID(); if (TemporaryPtr<const UniverseObject> obj = GetUniverseObject(next_sys_id)) { // fleet is not in a system and has a valid next destination, so can orient it in that direction // fleet icons might not appear on the screen in the exact place corresponding to their // actual universe position, but if they're moving along a starlane, this code will assume // their apparent position will only be different from their true position in a direction // parallel with the starlane, so the direction from their true position to their destination // position can be used to get a direction vector to orient the icon float dest_x = obj->X(), dest_y = obj->Y(); float cur_x = first_fleet->X(), cur_y = first_fleet->Y(); const MapWnd* map_wnd = ClientUI::GetClientUI()->GetMapWnd(); GG::Pt dest = map_wnd->ScreenCoordsFromUniversePosition(dest_x, dest_y); GG::Pt cur = map_wnd->ScreenCoordsFromUniversePosition(cur_x, cur_y); GG::Pt direction_vector = dest - cur; if (direction_vector.x != GG::X0 || direction_vector.y != GG::Y0) pointing_angle = 360.0f / TWO_PI * std::atan2(static_cast<float>(Value(direction_vector.y)), static_cast<float>(Value(direction_vector.x))) + 90; } } // select icon(s) for fleet(s) int num_ships = 0; for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) { TemporaryPtr<const Fleet> fleet = *it; if (fleet) num_ships += fleet->NumShips(); } boost::shared_ptr<GG::Texture> size_texture = FleetSizeIcon(num_ships, size_type); std::vector<boost::shared_ptr<GG::Texture> > head_textures = FleetHeadIcons(fleets, size_type); // add RotatingGraphics for all icons needed if (size_texture) { RotatingGraphic* icon = new RotatingGraphic(size_texture, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE); icon->SetPhaseOffset(pointing_angle); icon->SetRPM(0.0f); icon->SetColor(this->Color()); m_icons.push_back(icon); Resize(GG::Pt(size_texture->DefaultWidth(), size_texture->DefaultHeight())); AttachChild(icon); } for (std::vector<boost::shared_ptr<GG::Texture> >::const_iterator it = head_textures.begin(); it != head_textures.end(); ++it) { RotatingGraphic* icon = new RotatingGraphic(*it, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE); icon->SetPhaseOffset(pointing_angle); icon->SetRPM(0.0f); icon->SetColor(this->Color()); m_icons.push_back(icon); if (Width() < (*it)->DefaultWidth()) Resize(GG::Pt((*it)->DefaultWidth(), (*it)->DefaultHeight())); AttachChild(icon); } // set up selection indicator m_selection_indicator = new RotatingGraphic(FleetSelectionIndicatorIcon(), GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE); m_selection_indicator->SetRPM(ClientUI::SystemSelectionIndicatorRPM()); LayoutIcons(); // Scanlines for not currently-visible objects? int empire_id = HumanClientApp::GetApp()->EmpireID(); if (empire_id == ALL_EMPIRES || !GetOptionsDB().Get<bool>("UI.system-fog-of-war")) return; bool at_least_one_fleet_visible = false; for (std::vector<int>::const_iterator it = m_fleets.begin(); it != m_fleets.end(); ++it) { if (GetUniverse().GetObjectVisibilityByEmpire(*it, empire_id) >= VIS_BASIC_VISIBILITY) { at_least_one_fleet_visible = true; break; } } // Create scanline renderer control m_scanline_control = new ScanlineControl(GG::X0, GG::Y0, Width(), Height()); if (!at_least_one_fleet_visible) AttachChild(m_scanline_control); }
void FleetMoveOrder::ExecuteImpl() const { ValidateEmpireID(); TemporaryPtr<Fleet> fleet = GetFleet(FleetID()); if (!fleet) { ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet with id " << FleetID() << " to move, but no such fleet exists"; return; } TemporaryPtr<const System> destination_system = GetEmpireKnownSystem(DestinationSystemID(), EmpireID()); if (!destination_system) { ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet to move to system with id " << DestinationSystemID() << " but no such system is known to that empire"; return; } // reject empty routes if (m_route.empty()) { ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet to move on empty route"; return; } // verify that empire specified in order owns specified fleet if (!fleet->OwnedBy(EmpireID()) ) { ErrorLogger() << "Empire with id " << EmpireID() << " order to move but does not own fleet with id " << FleetID(); return; } // verify fleet route first system int fleet_sys_id = fleet->SystemID(); if (!m_append || fleet->TravelRoute().empty()) { if (fleet_sys_id != INVALID_OBJECT_ID) { // fleet is in a system. Its move path should also start from that system. if (fleet_sys_id != m_start_system) { ErrorLogger() << "Empire with id " << EmpireID() << " ordered a fleet to move from a system with id " << m_start_system << " that it is not at. Fleet is located at system with id " << fleet_sys_id; return; } } else { // fleet is not in a system. Its move path should start from the next system it is moving to. int next_system = fleet->NextSystemID(); if (next_system != m_start_system) { ErrorLogger() << "Empire with id " << EmpireID() << " ordered a fleet to move starting from a system with id " << m_start_system << ", but the fleet's next destination is system with id " << next_system; return; } } } else { // We should append and there is something to append to int last_system = fleet->TravelRoute().back(); if (last_system != m_start_system) { ErrorLogger() << "Empire with id " << EmpireID() << " ordered a fleet to continue from system with id " << m_start_system << ", but the fleet's current route won't lead there, it leads to system " << last_system; return; } } // convert list of ids to list of System std::list<int> route_list; if(m_append && !fleet->TravelRoute().empty()){ route_list = fleet->TravelRoute(); route_list.erase(--route_list.end());// Remove the last one since it is the first one of the other } std::copy(m_route.begin(), m_route.end(), std::back_inserter(route_list)); // validate route. Only allow travel between systems connected in series by starlanes known to this fleet's owner. // check destination validity: disallow movement that's out of range std::pair<int, int> eta = fleet->ETA(fleet->MovePath(route_list)); if (eta.first == Fleet::ETA_NEVER || eta.first == Fleet::ETA_OUT_OF_RANGE) { DebugLogger() << "FleetMoveOrder::ExecuteImpl rejected out of range move order"; return; } std::string waypoints; for (std::list<int>::iterator it = route_list.begin(); it != route_list.end(); ++it) { waypoints += std::string(" ") + boost::lexical_cast<std::string>(*it); } DebugLogger() << "FleetMoveOrder::ExecuteImpl Setting route of fleet " << fleet->ID() << " to " << waypoints; fleet->SetRoute(route_list); }
void NewFleetOrder::ExecuteImpl() const { ValidateEmpireID(); if (m_system_id == INVALID_OBJECT_ID) { ErrorLogger() << "Empire attempted to create a new fleet outside a system"; return; } TemporaryPtr<System> system = GetSystem(m_system_id); if (!system) { ErrorLogger() << "Empire attempted to create a new fleet in a nonexistant system"; return; } if (m_fleet_names.empty()) return; if (m_fleet_names.size() != m_fleet_ids.size() || m_fleet_names.size() != m_ship_id_groups.size() || m_fleet_names.size() != m_aggressives.size()) { ErrorLogger() << "NewFleetOrder has inconsistent data container sizes..."; return; } GetUniverse().InhibitUniverseObjectSignals(true); std::vector<TemporaryPtr<Fleet> > created_fleets; created_fleets.reserve(m_fleet_names.size()); // create fleet for each group of ships for (int i = 0; i < static_cast<int>(m_fleet_names.size()); ++i) { const std::string& fleet_name = m_fleet_names[i]; int fleet_id = m_fleet_ids[i]; const std::vector<int>& ship_ids = m_ship_id_groups[i]; bool aggressive = m_aggressives[i]; if (ship_ids.empty()) continue; // nothing to do... // validate specified ships std::vector<TemporaryPtr<Ship> > validated_ships; std::vector<int> validated_ships_ids; for (unsigned int i = 0; i < ship_ids.size(); ++i) { // verify that empire is not trying to take ships from somebody else's fleet TemporaryPtr<Ship> ship = GetShip(ship_ids[i]); if (!ship) { ErrorLogger() << "Empire attempted to create a new fleet with an invalid ship"; continue; } if (!ship->OwnedBy(EmpireID())) { ErrorLogger() << "Empire attempted to create a new fleet with ships from another's fleet."; continue; } if (ship->SystemID() != m_system_id) { ErrorLogger() << "Empire attempted to make a new fleet from ship in the wrong system"; continue; } validated_ships.push_back(ship); validated_ships_ids.push_back(ship->ID()); } if (validated_ships.empty()) continue; // create fleet TemporaryPtr<Fleet> fleet = GetUniverse().CreateFleet(fleet_name, system->X(), system->Y(), EmpireID(), fleet_id); fleet->GetMeter(METER_STEALTH)->SetCurrent(Meter::LARGE_VALUE); fleet->SetAggressive(aggressive); // an ID is provided to ensure consistancy between server and client universes GetUniverse().SetEmpireObjectVisibility(EmpireID(), fleet->ID(), VIS_FULL_VISIBILITY); system->Insert(fleet); // new fleet will get same m_arrival_starlane as fleet of the first ship in the list. TemporaryPtr<Ship> firstShip = validated_ships[0]; TemporaryPtr<Fleet> firstFleet = GetFleet(firstShip->FleetID()); if (firstFleet) fleet->SetArrivalStarlane(firstFleet->ArrivalStarlane()); // remove ships from old fleet(s) and add to new for (std::vector<TemporaryPtr<Ship> >::iterator ship_it = validated_ships.begin(); ship_it != validated_ships.end(); ++ship_it) { TemporaryPtr<Ship> ship = *ship_it; if (TemporaryPtr<Fleet> old_fleet = GetFleet(ship->FleetID())) old_fleet->RemoveShip(ship->ID()); ship->SetFleetID(fleet->ID()); } fleet->AddShips(validated_ships_ids); created_fleets.push_back(fleet); } GetUniverse().InhibitUniverseObjectSignals(false); system->FleetsInsertedSignal(created_fleets); system->StateChangedSignal(); }
void FleetTransferOrder::ExecuteImpl() const { ValidateEmpireID(); // look up the destination fleet TemporaryPtr<Fleet> target_fleet = GetFleet(DestinationFleet()); if (!target_fleet) { ErrorLogger() << "Empire attempted to move ships to a nonexistant fleet"; return; } // check that destination fleet is owned by empire if (!target_fleet->OwnedBy(EmpireID())) { ErrorLogger() << "Empire attempted to move ships to a fleet it does not own"; return; } // verify that fleet is in a system if (target_fleet->SystemID() == INVALID_OBJECT_ID) { ErrorLogger() << "Empire attempted to transfer ships to/from fleet(s) not in a system"; return; } // check that all ships are in the same system std::vector<TemporaryPtr<Ship> > ships = Objects().FindObjects<Ship>(m_add_ships); std::vector<TemporaryPtr<Ship> > validated_ships; validated_ships.reserve(m_add_ships.size()); std::vector<int> validated_ship_ids; validated_ship_ids.reserve(m_add_ships.size()); for (std::vector<TemporaryPtr<Ship> >::const_iterator it = ships.begin(); it != ships.end(); ++it) { TemporaryPtr<Ship> ship = *it; if (!ship->OwnedBy(EmpireID())) continue; if (ship->SystemID() != target_fleet->SystemID()) continue; if (ship->FleetID() == target_fleet->ID()) continue; validated_ships.push_back(ship); validated_ship_ids.push_back(ship->ID()); } if (validated_ships.empty()) return; GetUniverse().InhibitUniverseObjectSignals(true); // remove from old fleet(s) std::set<TemporaryPtr<Fleet> > modified_fleets; for (std::vector<TemporaryPtr<Ship> >::iterator it = validated_ships.begin(); it != validated_ships.end(); ++it) { TemporaryPtr<Ship> ship = *it; if (TemporaryPtr<Fleet> source_fleet = GetFleet(ship->FleetID())) { source_fleet->RemoveShip(ship->ID()); modified_fleets.insert(source_fleet); } ship->SetFleetID(target_fleet->ID()); } // add to new fleet target_fleet->AddShips(validated_ship_ids); GetUniverse().InhibitUniverseObjectSignals(false); // signal change to fleet states modified_fleets.insert(target_fleet); for (std::set<TemporaryPtr<Fleet> >::iterator it = modified_fleets.begin(); it != modified_fleets.end(); ++it) { TemporaryPtr<Fleet> modified_fleet = *it; if (!modified_fleet->Empty()) modified_fleet->StateChangedSignal(); // if modified fleet is empty, it should be immently destroyed, so that updating it now is redundant } }
void ColonizeOrder::ExecuteImpl() const { ValidateEmpireID(); int empire_id = EmpireID(); TemporaryPtr<Ship> ship = GetShip(m_ship); if (!ship) { ErrorLogger() << "ColonizeOrder::ExecuteImpl couldn't get ship with id " << m_ship; return; } if (!ship->CanColonize()) { // verifies that species exists and can colonize and that ship can colonize ErrorLogger() << "ColonizeOrder::ExecuteImpl got ship that can't colonize"; return; } if (!ship->OwnedBy(empire_id)) { ErrorLogger() << "ColonizeOrder::ExecuteImpl got ship that isn't owned by the order-issuing empire"; return; } float colonist_capacity = ship->ColonyCapacity(); TemporaryPtr<Planet> planet = GetPlanet(m_planet); if (!planet) { ErrorLogger() << "ColonizeOrder::ExecuteImpl couldn't get planet with id " << m_planet; return; } if (planet->CurrentMeterValue(METER_POPULATION) > 0.0f) { ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that already has population"; return; } if (!planet->Unowned() && planet->Owner() != empire_id) { ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that owned by another empire"; return; } if (planet->OwnedBy(empire_id) && colonist_capacity == 0.0f) { ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that is already owned by empire and colony ship with zero capcity"; return; } if (GetUniverse().GetObjectVisibilityByEmpire(m_planet, empire_id) < VIS_PARTIAL_VISIBILITY) { ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that empire has insufficient visibility of"; return; } if (colonist_capacity > 0.0f && planet->EnvironmentForSpecies(ship->SpeciesName()) < PE_HOSTILE) { ErrorLogger() << "ColonizeOrder::ExecuteImpl nonzero colonist capacity and planet that ship's species can't colonize"; return; } int ship_system_id = ship->SystemID(); if (ship_system_id == INVALID_OBJECT_ID) { ErrorLogger() << "ColonizeOrder::ExecuteImpl given id of ship not in a system"; return; } int planet_system_id = planet->SystemID(); if (ship_system_id != planet_system_id) { ErrorLogger() << "ColonizeOrder::ExecuteImpl given ids of ship and planet not in the same system"; return; } if (planet->IsAboutToBeColonized()) { ErrorLogger() << "ColonizeOrder::ExecuteImpl given id planet that is already being colonized"; return; } planet->SetIsAboutToBeColonized(true); ship->SetColonizePlanet(m_planet); if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID())) fleet->StateChangedSignal(); }
void FleetButton::Init(const std::vector<int>& fleet_IDs, SizeType size_type) { if (!scanline_shader && GetOptionsDB().Get<bool>("UI.system-fog-of-war")) { boost::filesystem::path shader_path = GetRootDataDir() / "default" / "shaders" / "scanlines.frag"; std::string shader_text; ReadFile(shader_path, shader_text); scanline_shader = boost::shared_ptr<ShaderProgram>( ShaderProgram::shaderProgramFactory("", shader_text)); } // get fleets std::vector<TemporaryPtr<const Fleet> > fleets; for (std::vector<int>::const_iterator it = fleet_IDs.begin(); it != fleet_IDs.end(); ++it) { TemporaryPtr<const Fleet> fleet = GetFleet(*it); if (!fleet) { Logger().errorStream() << "FleetButton::FleetButton couldn't get fleet with id " << *it; continue; } m_fleets.push_back(*it); fleets.push_back(fleet); } // determine owner(s) of fleet(s). Only care whether or not there is more than one owner, as owner // is used to determine colouration int owner_id = ALL_EMPIRES; int multiple_owners = false; if (fleets.empty()) { // leave as ALL_EMPIRES } else if (fleets.size() == 1) { owner_id = (*fleets.begin())->Owner(); } else { owner_id = (*fleets.begin())->Owner(); // use ALL_EMPIRES if there are multiple owners (including no owner and an owner) for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) { TemporaryPtr<const Fleet> fleet = *it; if (fleet->Owner() != owner_id) { owner_id = ALL_EMPIRES; multiple_owners = true; break; } } } // get fleet colour if (multiple_owners) { SetColor(GG::CLR_WHITE); } else if (owner_id == ALL_EMPIRES) { // all ships owned by now empire bool monsters = true; // find if any ship in fleets in button is not a monster for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) { TemporaryPtr<const Fleet> fleet = *it; for (std::set<int>::const_iterator ship_it = fleet->ShipIDs().begin(); ship_it != fleet->ShipIDs().end(); ++ship_it) { if (TemporaryPtr<const Ship> ship = GetShip(*ship_it)) { if (!ship->IsMonster()) { monsters = false; break; } } } } if (monsters) SetColor(GG::CLR_RED); else SetColor(GG::CLR_WHITE); } else { // single empire owner if (const Empire* empire = Empires().Lookup(owner_id)) SetColor(empire->Color()); else SetColor(GG::CLR_GRAY); // should never be necessary... but just in case } // select icon(s) for fleet(s) int num_ships = 0; for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) { TemporaryPtr<const Fleet> fleet = *it; if (fleet) num_ships += fleet->NumShips(); } m_size_icon = FleetSizeIcon(num_ships, size_type); m_head_icons = FleetHeadIcons(fleets, size_type); // resize to fit icon by first determining necessary size, and then resizing GG::X texture_width(0); GG::Y texture_height(0); if (!m_head_icons.empty()) { texture_width = m_head_icons.front()->DefaultWidth(); texture_height = m_head_icons.front()->DefaultHeight(); } if (m_size_icon) { texture_width = std::max(texture_width, m_size_icon->DefaultWidth()); texture_height = std::max(texture_height, m_size_icon->DefaultHeight()); } // determine if fleet icon should be rotated. this should be done if the fleet is moving along // a starlane, which is the case if the fleet is not in a system and has a valid next system GG::Pt direction_vector(GG::X(0), GG::Y(1)); // default, unrotated button orientation TemporaryPtr<const Fleet> first_fleet; if (!m_fleets.empty()) first_fleet = *fleets.begin(); if (first_fleet && first_fleet->SystemID() == INVALID_OBJECT_ID) { int next_sys_id = first_fleet->NextSystemID(); if (TemporaryPtr<const UniverseObject> obj = GetUniverseObject(next_sys_id)) { // fleet is not in a system and has a valid next destination, so can orient it in that direction // fleet icons might not appear on the screen in the exact place corresponding to their // actual universe position, but if they're moving along a starlane, this code will assume // their apparent position will only be different from their true position in a direction // parallel with the starlane, so the direction from their true position to their destination // position can be used to get a direction vector to orient the icon double dest_x = obj->X(), dest_y = obj->Y(); double cur_x = first_fleet->X(), cur_y = first_fleet->Y(); const MapWnd* map_wnd = ClientUI::GetClientUI()->GetMapWnd(); GG::Pt dest = map_wnd->ScreenCoordsFromUniversePosition(dest_x, dest_y); GG::Pt cur = map_wnd->ScreenCoordsFromUniversePosition(cur_x, cur_y); direction_vector = dest - cur; } } // check for unrotated texture if (Value(direction_vector.x) == 0) { // not rotated. can do simple texture blits m_vertex_components.clear(); } else { // texture is rotated, so need some extra math // get rotated corner vetex x and y components (x1, y1, x2, y2, x3, y3, x4, y4) for texture of appropriate size m_vertex_components = VectorAlignedQuadVertices(direction_vector, Value(texture_height), Value(texture_width)); } // size icon according to texture size (average two dimensions) int diameter = static_cast<int>((Value(texture_width) + Value(texture_height)) / 2.0); Resize(GG::Pt(GG::X(diameter), GG::Y(diameter))); // get selection indicator texture m_selection_texture = ClientUI::GetTexture(ClientUI::ArtDir() / "icons" / "fleet" / "fleet_selection.png", true); }
SitRepEntry CreateFleetArrivedAtDestinationSitRep(int system_id, int fleet_id, int recipient_empire_id) { TemporaryPtr<const Fleet> fleet = GetFleet(fleet_id); //bool system_contains_recipient_empire_planets = false; //if (const System* system = GetSystem(system_id)) { // std::vector<int> system_planets = system->FindObjectIDs<Planet>(); // for (std::vector<int>::const_iterator planet_it = system_planets.begin(); // planet_it != system_planets.end(); ++planet_it) // { // const Planet* planet = GetPlanet(*planet_it); // if (!planet || planet->Unowned()) // continue; // if (planet->OwnedBy(recipient_empire_id)) { // system_contains_recipient_empire_planets = true; // break; // } // } //} //There are variants of this message for {monster, own, foreign} * {one ship, fleet}. // TODO: More variants for systems with / without recipient-owned planets //These should really be assembled from several pieces: a fleet description, //a system description, and a message template into which both are substituted. if (!fleet) { SitRepEntry sitrep(UserStringNop("SITREP_FLEET_ARRIVED_AT_SYSTEM"), "icons/sitrep/fleet_arrived.png"); sitrep.AddVariable(VarText::SYSTEM_ID_TAG, boost::lexical_cast<std::string>(system_id)); sitrep.AddVariable(VarText::FLEET_ID_TAG, boost::lexical_cast<std::string>(fleet_id)); return sitrep; } else if (fleet->Unowned() && fleet->HasMonsters()) { if (fleet->NumShips() == 1) { SitRepEntry sitrep(UserStringNop("SITREP_MONSTER_SHIP_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png"); sitrep.AddVariable(VarText::SYSTEM_ID_TAG, boost::lexical_cast<std::string>(system_id)); sitrep.AddVariable(VarText::FLEET_ID_TAG, boost::lexical_cast<std::string>(fleet_id)); int ship_id = *fleet->ShipIDs().begin(); sitrep.AddVariable(VarText::SHIP_ID_TAG, boost::lexical_cast<std::string>(ship_id)); if (TemporaryPtr<const Ship> ship = GetShip(ship_id)) sitrep.AddVariable(VarText::DESIGN_ID_TAG, boost::lexical_cast<std::string>(ship->DesignID())); return sitrep; } else { SitRepEntry sitrep(UserStringNop("SITREP_MONSTER_FLEET_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png"); sitrep.AddVariable(VarText::SYSTEM_ID_TAG, boost::lexical_cast<std::string>(system_id)); sitrep.AddVariable(VarText::FLEET_ID_TAG, boost::lexical_cast<std::string>(fleet_id)); sitrep.AddVariable(VarText::RAW_TEXT_TAG, boost::lexical_cast<std::string>(fleet->NumShips())); return sitrep; } } else if (fleet->Unowned()) { SitRepEntry sitrep(UserStringNop("SITREP_FLEET_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png"); sitrep.AddVariable(VarText::SYSTEM_ID_TAG, boost::lexical_cast<std::string>(system_id)); sitrep.AddVariable(VarText::FLEET_ID_TAG, boost::lexical_cast<std::string>(fleet_id)); sitrep.AddVariable(VarText::RAW_TEXT_TAG, boost::lexical_cast<std::string>(fleet->NumShips())); return sitrep; } else if (fleet->OwnedBy(recipient_empire_id)) { if (fleet->NumShips() == 1) { SitRepEntry sitrep(UserStringNop("SITREP_OWN_SHIP_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png"); sitrep.AddVariable(VarText::SYSTEM_ID_TAG, boost::lexical_cast<std::string>(system_id)); sitrep.AddVariable(VarText::FLEET_ID_TAG, boost::lexical_cast<std::string>(fleet_id)); sitrep.AddVariable(VarText::EMPIRE_ID_TAG, boost::lexical_cast<std::string>(fleet->Owner())); int ship_id = *fleet->ShipIDs().begin(); sitrep.AddVariable(VarText::SHIP_ID_TAG, boost::lexical_cast<std::string>(ship_id)); if (TemporaryPtr<const Ship> ship = GetShip(ship_id)) sitrep.AddVariable(VarText::DESIGN_ID_TAG, boost::lexical_cast<std::string>(ship->DesignID())); return sitrep; } else { SitRepEntry sitrep(UserStringNop("SITREP_OWN_FLEET_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png"); sitrep.AddVariable(VarText::SYSTEM_ID_TAG, boost::lexical_cast<std::string>(system_id)); sitrep.AddVariable(VarText::FLEET_ID_TAG, boost::lexical_cast<std::string>(fleet_id)); sitrep.AddVariable(VarText::EMPIRE_ID_TAG, boost::lexical_cast<std::string>(fleet->Owner())); sitrep.AddVariable(VarText::RAW_TEXT_TAG, boost::lexical_cast<std::string>(fleet->NumShips())); return sitrep; } } else { if (fleet->NumShips() == 1) { SitRepEntry sitrep(UserStringNop("SITREP_FOREIGN_SHIP_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png"); sitrep.AddVariable(VarText::SYSTEM_ID_TAG, boost::lexical_cast<std::string>(system_id)); sitrep.AddVariable(VarText::FLEET_ID_TAG, boost::lexical_cast<std::string>(fleet_id)); sitrep.AddVariable(VarText::EMPIRE_ID_TAG, boost::lexical_cast<std::string>(fleet->Owner())); int ship_id = *fleet->ShipIDs().begin(); sitrep.AddVariable(VarText::SHIP_ID_TAG, boost::lexical_cast<std::string>(ship_id)); if (TemporaryPtr<const Ship> ship = GetShip(ship_id)) sitrep.AddVariable(VarText::DESIGN_ID_TAG, boost::lexical_cast<std::string>(ship->DesignID())); return sitrep; } else { SitRepEntry sitrep(UserStringNop("SITREP_FOREIGN_FLEET_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png"); sitrep.AddVariable(VarText::SYSTEM_ID_TAG, boost::lexical_cast<std::string>(system_id)); sitrep.AddVariable(VarText::FLEET_ID_TAG, boost::lexical_cast<std::string>(fleet_id)); sitrep.AddVariable(VarText::EMPIRE_ID_TAG, boost::lexical_cast<std::string>(fleet->Owner())); sitrep.AddVariable(VarText::RAW_TEXT_TAG, boost::lexical_cast<std::string>(fleet->NumShips())); return sitrep; } } }
int IssueInvadeOrder(int ship_id, int planet_id) { int empire_id = AIClientApp::GetApp()->EmpireID(); // make sure ship_id is a ship... TemporaryPtr<const Ship> ship = GetShip(ship_id); if (!ship) { Logger().errorStream() << "AIInterface::IssueInvadeOrder : passed an invalid ship_id"; return 0; } // get fleet of ship TemporaryPtr<const Fleet> fleet = GetFleet(ship->FleetID()); if (!fleet) { Logger().errorStream() << "AIInterface::IssueInvadeOrder : ship with passed ship_id has invalid fleet_id"; return 0; } // make sure player owns ship and its fleet if (!fleet->OwnedBy(empire_id)) { Logger().errorStream() << "AIInterface::IssueInvadeOrder : empire does not own fleet of passed ship"; return 0; } if (!ship->OwnedBy(empire_id)) { Logger().errorStream() << "AIInterface::IssueInvadeOrder : empire does not own passed ship"; return 0; } // verify that planet exists and is occupied by another empire TemporaryPtr<const Planet> planet = GetPlanet(planet_id); if (!planet) { Logger().errorStream() << "AIInterface::IssueInvadeOrder : no planet with passed planet_id"; return 0; } bool owned_by_invader = planet->OwnedBy(empire_id); bool unowned = planet->Unowned(); bool populated = planet->CurrentMeterValue(METER_POPULATION) > 0.; bool visible = GetUniverse().GetObjectVisibilityByEmpire(planet_id, empire_id) >= VIS_PARTIAL_VISIBILITY; bool vulnerable = planet->CurrentMeterValue(METER_SHIELD) <= 0.; float shields = planet->CurrentMeterValue(METER_SHIELD); std::string thisSpecies = planet->SpeciesName(); //bool being_invaded = planet->IsAboutToBeInvaded(); bool invadable = !owned_by_invader && vulnerable && (populated || !unowned) && visible ;// && !being_invaded; a 'being_invaded' check prevents AI from invading with multiple ships at once, which is important if (!invadable) { Logger().errorStream() << "AIInterface::IssueInvadeOrder : planet with passed planet_id "<< planet_id <<" and species "<<thisSpecies<<" is " << "not invadable due to one or more of: owned by invader empire, " << "not visible to invader empire, has shields above zero, " << "or is already being invaded."; if (!unowned) Logger().errorStream() << "AIInterface::IssueInvadeOrder : planet (id " << planet_id << ") is not unowned"; if (!visible) Logger().errorStream() << "AIInterface::IssueInvadeOrder : planet (id " << planet_id << ") is not visible"; if (!vulnerable) Logger().errorStream() << "AIInterface::IssueInvadeOrder : planet (id " << planet_id << ") is not vulnerable, shields at "<<shields; return 0; } // verify that planet is in same system as the fleet if (planet->SystemID() != fleet->SystemID()) { Logger().errorStream() << "AIInterface::IssueInvadeOrder : fleet and planet are not in the same system"; return 0; } if (ship->SystemID() == INVALID_OBJECT_ID) { Logger().errorStream() << "AIInterface::IssueInvadeOrder : ship is not in a system"; return 0; } AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new InvadeOrder(empire_id, ship_id, planet_id))); return 1; }
CombatInfo::CombatInfo(int system_id_) : system_id(system_id_) { const Universe& universe = GetUniverse(); const ObjectMap& universe_objects = universe.Objects(); const System* system = universe_objects.Object<System>(system_id); if (!system) { Logger().errorStream() << "CombatInfo constructed with invalid system id: " << system_id; return; } // add copy of system to full / complete objects in combat System* copy_system = system->Clone(); objects.Insert(system_id, copy_system); // find ships and their owners in system std::vector<int> ship_ids = system->FindObjectIDs<Ship>(); for (std::vector<int>::const_iterator it = ship_ids.begin(); it != ship_ids.end(); ++it) { int ship_id = *it; const Ship* ship = GetShip(ship_id); if (!ship) { Logger().errorStream() << "CombatInfo::CombatInfo couldn't get ship with id " << ship_id << " in system " << system->Name() << " (" << system_id << ")"; continue; } // add owner to empires that have assets in this battle empire_ids.insert(ship->Owner()); // add copy of ship to full / complete copy of objects in system Ship* copy = ship->Clone(); objects.Insert(ship_id, copy); } // find planets and their owners in system std::vector<int> planet_ids = system->FindObjectIDs<Planet>(); for (std::vector<int>::const_iterator it = planet_ids.begin(); it != planet_ids.end(); ++it) { int planet_id = *it; const Planet* planet = GetPlanet(planet_id); if (!planet) { Logger().errorStream() << "CombatInfo::CombatInfo couldn't get planet with id " << planet_id << " in system " << system->Name() << " (" << system_id << ")"; continue; } // if planet is populated, add owner to empires that have assets in this battle if (planet->CurrentMeterValue(METER_POPULATION) > 0.0) empire_ids.insert(planet->Owner()); // add copy of ship to full / complete copy of objects in system Planet* copy = planet->Clone(); objects.Insert(planet_id, copy); } // TODO: should buildings be considered separately? // now that all participants in the battle have been found, loop through // objects again to assemble each participant empire's latest // known information about all objects in this battle // system for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) { int empire_id = *empire_it; if (empire_id == ALL_EMPIRES) continue; System* visibility_limited_copy = system->Clone(empire_id); empire_known_objects[empire_id].Insert(system_id, visibility_limited_copy); } // ships for (std::vector<int>::const_iterator it = ship_ids.begin(); it != ship_ids.end(); ++it) { int ship_id = *it; const Ship* ship = GetShip(ship_id); if (!ship) { Logger().errorStream() << "CombatInfo::CombatInfo couldn't get ship with id " << ship_id << " in system " << system->Name() << " (" << system_id << ")"; continue; } const Fleet* fleet = GetFleet(ship->FleetID()); if (!fleet) { Logger().errorStream() << "CombatInfo::CombatInfo couldn't get fleet with id " << ship->FleetID() << " in system " << system->Name() << " (" << system_id << ")"; continue; } for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) { int empire_id = *empire_it; if (empire_id == ALL_EMPIRES) continue; if (universe.GetObjectVisibilityByEmpire(ship_id, empire_id) >= VIS_BASIC_VISIBILITY || (fleet->Aggressive() && (empire_id == ALL_EMPIRES || fleet->Unowned() || Empires().GetDiplomaticStatus(empire_id, fleet->Owner()) == DIPLO_WAR))) { Ship* visibility_limited_copy = ship->Clone(empire_id); empire_known_objects[empire_id].Insert(ship_id, visibility_limited_copy); } } } // planets for (std::vector<int>::const_iterator it = planet_ids.begin(); it != planet_ids.end(); ++it) { int planet_id = *it; const Planet* planet = GetPlanet(planet_id); if (!planet) { Logger().errorStream() << "CombatInfo::CombatInfo couldn't get planet with id " << planet_id << " in system " << system->Name() << " (" << system_id << ")"; continue; } for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) { int empire_id = *empire_it; if (empire_id == ALL_EMPIRES) continue; if (universe.GetObjectVisibilityByEmpire(planet_id, empire_id) >= VIS_BASIC_VISIBILITY) { Planet* visibility_limited_copy = planet->Clone(empire_id); empire_known_objects[empire_id].Insert(planet_id, visibility_limited_copy); } } } // after battle is simulated, any changes to latest known or actual objects // will be copied back to the main Universe's ObjectMap and the Universe's // empire latest known objects ObjectMap }
CombatInfo::CombatInfo(int system_id_, int turn_) : turn(turn_), system_id(system_id_) { TemporaryPtr<System> system = ::GetSystem(system_id); if (!system) { Logger().errorStream() << "CombatInfo constructed with invalid system id: " << system_id; return; } // add system to full / complete objects in combat - NOTE: changed from copy of system objects.Insert(system); // find ships and their owners in system std::vector<TemporaryPtr<Ship> > ships = Objects().FindObjects<Ship>(system->ShipIDs()); for (std::vector<TemporaryPtr<Ship> >::const_iterator ship_it = ships.begin(); ship_it != ships.end(); ++ship_it) { TemporaryPtr<Ship> ship = *ship_it; // add owner to empires that have assets in this battle empire_ids.insert(ship->Owner()); objects.Insert(ship); } // find planets and their owners in system std::vector<TemporaryPtr<Planet> > planets = Objects().FindObjects<Planet>(system->PlanetIDs()); for (std::vector<TemporaryPtr<Planet> >::const_iterator planet_it = planets.begin(); planet_it != planets.end(); ++planet_it) { TemporaryPtr<Planet> planet = *planet_it; // if planet is populated, add owner to empires that have assets in this battle if (planet->CurrentMeterValue(METER_POPULATION) > 0.0) empire_ids.insert(planet->Owner()); objects.Insert(planet); } // TODO: should buildings be considered separately? // now that all participants in the battle have been found, loop through // objects again to assemble each participant empire's latest // known information about all objects in this battle // system for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) { int empire_id = *empire_it; if (empire_id == ALL_EMPIRES) continue; empire_known_objects[empire_id].Insert(GetEmpireKnownSystem(system->ID(), empire_id)); } // ships for (std::vector<TemporaryPtr<Ship> >::const_iterator it = ships.begin(); it != ships.end(); ++it) { TemporaryPtr<Ship> ship = *it; int ship_id = ship->ID(); TemporaryPtr<const Fleet> fleet = GetFleet(ship->FleetID()); if (!fleet) { Logger().errorStream() << "CombatInfo::CombatInfo couldn't get fleet with id " << ship->FleetID() << " in system " << system->Name() << " (" << system_id << ")"; continue; } for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) { int empire_id = *empire_it; if (empire_id == ALL_EMPIRES) continue; if (GetUniverse().GetObjectVisibilityByEmpire(ship_id, empire_id) >= VIS_BASIC_VISIBILITY || (fleet->Aggressive() && (empire_id == ALL_EMPIRES || fleet->Unowned() || Empires().GetDiplomaticStatus(empire_id, fleet->Owner()) == DIPLO_WAR))) { empire_known_objects[empire_id].Insert(GetEmpireKnownShip(ship->ID(), empire_id));} } } // planets for (std::vector<TemporaryPtr<Planet> >::const_iterator it = planets.begin(); it != planets.end(); ++it) { TemporaryPtr<Planet> planet = *it; int planet_id = planet->ID(); for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) { int empire_id = *empire_it; if (empire_id == ALL_EMPIRES) continue; if (GetUniverse().GetObjectVisibilityByEmpire(planet_id, empire_id) >= VIS_BASIC_VISIBILITY) { empire_known_objects[empire_id].Insert(GetEmpireKnownPlanet(planet->ID(), empire_id)); } } } // after battle is simulated, any changes to latest known or actual objects // will be copied back to the main Universe's ObjectMap and the Universe's // empire latest known objects ObjectMap - NOTE: Using the real thing now }