void ProductionQueueOrder::ExecuteImpl() const { ValidateEmpireID(); Empire* empire = GetEmpire(EmpireID()); try { if (m_item.build_type == BT_BUILDING || m_item.build_type == BT_SHIP) { empire->PlaceBuildInQueue(m_item, m_number, m_location, m_new_index); } else if (m_new_blocksize != INVALID_QUANTITY) { DebugLogger() << "ProductionQueueOrder quantity " << m_new_quantity << " Blocksize " << m_new_blocksize; empire->SetBuildQuantityAndBlocksize(m_index, m_new_quantity, m_new_blocksize); } else if (m_new_quantity != INVALID_QUANTITY) { empire->SetBuildQuantity(m_index, m_new_quantity); } else if (m_new_index != INVALID_INDEX) { empire->MoveBuildWithinQueue(m_index, m_new_index); } else if (m_rally_point_id != INVALID_OBJECT_ID) { DebugLogger() << "ProductionQueueOrder setting rally point to id: " << m_rally_point_id; empire->SetBuildRallyPoint(m_index, m_rally_point_id); } else if (m_index != INVALID_INDEX) { DebugLogger() << "ProductionQueueOrder removing build from index " << m_index; empire->RemoveBuildFromQueue(m_index); } else { ErrorLogger() << "Malformed ProductionQueueOrder."; } } catch (const std::exception& e) { ErrorLogger() << "Build order execution threw exception: " << e.what(); } }
void ProductionQueueOrder::ExecuteImpl() const { ValidateEmpireID(); Empire* empire = GetEmpire(EmpireID()); try { if (m_build_type == BT_BUILDING) empire->PlaceBuildInQueue(BT_BUILDING, m_item_name, m_number, m_location); else if (m_build_type == BT_SHIP) empire->PlaceBuildInQueue(BT_SHIP, m_design_id, m_number, m_location); else if (m_new_blocksize != INVALID_QUANTITY) { DebugLogger() << "ProductionQueueOrder quantity " << m_new_quantity << " Blocksize " << m_new_blocksize; empire->SetBuildQuantityAndBlocksize(m_index, m_new_quantity, m_new_blocksize); } else if (m_new_quantity != INVALID_QUANTITY) empire->SetBuildQuantity(m_index, m_new_quantity); else if (m_new_index != INVALID_INDEX) empire->MoveBuildWithinQueue(m_index, m_new_index); else if (m_index != INVALID_INDEX) { DebugLogger() << "ProductionQueueOrder removing build from index " << m_index; empire->RemoveBuildFromQueue(m_index); } else ErrorLogger() << "Malformed ProductionQueueOrder."; } catch (const std::exception& e) { ErrorLogger() << "Build order execution threw exception: " << e.what(); } }
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); } }
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(); }
void ResearchQueueOrder::ExecuteImpl() const { ValidateEmpireID(); Empire* empire = GetEmpire(EmpireID()); if (!empire) return; if (m_remove) { DebugLogger() << "ResearchQueueOrder::ExecuteImpl: removing from queue tech: " << m_tech_name; empire->RemoveTechFromQueue(m_tech_name); } else empire->PlaceTechInQueue(m_tech_name, m_position); }
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); } }
bool ScrapOrder::UndoImpl() const { ValidateEmpireID(); int empire_id = EmpireID(); if (TemporaryPtr<Ship> ship = GetShip(m_object_id)) { if (ship->OwnedBy(empire_id)) ship->SetOrderedScrapped(false); } else if (TemporaryPtr<Building> building = GetBuilding(m_object_id)) { if (building->OwnedBy(empire_id)) building->SetOrderedScrapped(false); } else { return false; } return true; }
void ChangeFocusOrder::ExecuteImpl() const { ValidateEmpireID(); TemporaryPtr<Planet> planet = GetPlanet(PlanetID()); if (!planet) { ErrorLogger() << "Illegal planet id specified in change planet focus order."; return; } if (!planet->OwnedBy(EmpireID())) { ErrorLogger() << "Empire attempted to issue change planet focus to another's planet."; return; } planet->SetFocus(m_focus); }
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; }
void ScrapOrder::ExecuteImpl() const { ValidateEmpireID(); int empire_id = EmpireID(); if (TemporaryPtr<Ship> ship = GetShip(m_object_id)) { if (ship->SystemID() != INVALID_OBJECT_ID && ship->OwnedBy(empire_id)) { ship->SetOrderedScrapped(true); //DebugLogger() << "ScrapOrder::ExecuteImpl empire: " << empire_id // << " on ship: " << ship->ID() << " at system: " << ship->SystemID() // << " ... ordered scrapped?: " << ship->OrderedScrapped(); } } else if (TemporaryPtr<Building> building = GetBuilding(m_object_id)) { int planet_id = building->PlanetID(); if (TemporaryPtr<const Planet> planet = GetPlanet(planet_id)) { if (building->OwnedBy(empire_id) && planet->OwnedBy(empire_id)) building->SetOrderedScrapped(true); } } }
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()); }
void RenameOrder::ExecuteImpl() const { ValidateEmpireID(); TemporaryPtr<UniverseObject> obj = GetUniverseObject(m_object); if (!obj) { ErrorLogger() << "Attempted to rename nonexistant object with id " << m_object; return; } // verify that empire specified in order owns specified object if (!obj->OwnedBy(EmpireID())) { ErrorLogger() << "Empire specified in rename order does not own specified object."; return; } // disallow the name "", since that denotes an unknown object if (m_name == "") { ErrorLogger() << "Name \"\" specified in rename order is invalid."; return; } obj->Rename(m_name); }
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 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 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 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 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(); }