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(); }