int IssueRequeueProductionOrder(int old_queue_index, int new_queue_index) { if (old_queue_index == new_queue_index) { Logger().errorStream() << "AIInterface::IssueRequeueProductionOrder : passed same old and new indexes... nothing to do."; return 0; } int empire_id = AIClientApp::GetApp()->EmpireID(); Empire* empire = AIClientApp::GetApp()->Empires().Lookup(empire_id); const ProductionQueue& queue = empire->GetProductionQueue(); if (old_queue_index < 0 || static_cast<int>(queue.size()) <= old_queue_index) { Logger().errorStream() << "AIInterface::IssueRequeueProductionOrder : passed old_queue_index outside range of items on queue."; return 0; } // After removing an earlier entry in queue, all later entries are shifted down one queue index, so // inserting before the specified item index should now insert before the previous item index. This // also allows moving to the end of the queue, rather than only before the last item on the queue. int actual_new_index = new_queue_index; if (old_queue_index < new_queue_index) actual_new_index = new_queue_index - 1; if (new_queue_index < 0 || static_cast<int>(queue.size()) <= actual_new_index) { Logger().errorStream() << "AIInterface::IssueRequeueProductionOrder : passed new_queue_index outside range of items on queue."; return 0; } AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new ProductionQueueOrder(empire_id, old_queue_index, new_queue_index))); return 1; }
void UpdateProductionQueue() { int empire_id = AIClientApp::GetApp()->EmpireID(); Empire* empire = Empires().Lookup(empire_id); if (!empire) { Logger().errorStream() << "AIInterface::UpdateProductionQueue : couldn't get empire with id " << empire_id; return; } empire->UpdateProductionQueue(); }
void UpdateProductionQueue() { int empire_id = AIClientApp::GetApp()->EmpireID(); Empire* empire = ::GetEmpire(empire_id); if (!empire) { ErrorLogger() << "UpdateProductionQueue : couldn't get empire with id " << empire_id; return; } empire->UpdateProductionQueue(); }
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 ProductionWnd::ChangeBuildQuantityBlockSlot(int queue_idx, int quantity, int blocksize) { if (!m_order_issuing_enabled) return; int client_empire_id = HumanClientApp::GetApp()->EmpireID(); Empire* empire = Empires().Lookup(client_empire_id); if (!empire) return; HumanClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new ProductionQueueOrder(client_empire_id, queue_idx, quantity, blocksize))); empire->UpdateProductionQueue(); }
void ProductionWnd::DeleteQueueItem(GG::ListBox::iterator it) { if (!m_order_issuing_enabled) return; int client_empire_id = HumanClientApp::GetApp()->EmpireID(); Empire* empire = Empires().Lookup(client_empire_id); if (!empire) return; HumanClientApp::GetApp()->Orders().IssueOrder( OrderPtr(new ProductionQueueOrder(client_empire_id, std::distance(m_queue_lb->begin(), it)))); empire->UpdateProductionQueue(); }
void ProductionWnd::QueueItemPaused(GG::ListBox::iterator it, bool pause) { if (!m_order_issuing_enabled) return; int client_empire_id = HumanClientApp::GetApp()->EmpireID(); Empire* empire = GetEmpire(client_empire_id); if (!empire) return; HumanClientApp::GetApp()->Orders().IssueOrder( OrderPtr(new ProductionQueueOrder(client_empire_id, std::distance(m_queue_wnd->GetQueueListBox()->begin(), it), pause, -1.0f))); empire->UpdateProductionQueue(); }
void ProductionWnd::AddBuildToQueueSlot(BuildType build_type, int design_id, int number, int location) { if (!m_order_issuing_enabled) return; int client_empire_id = HumanClientApp::GetApp()->EmpireID(); Empire* empire = Empires().Lookup(client_empire_id); if (!empire) return; HumanClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new ProductionQueueOrder(client_empire_id, build_type, design_id, number, location))); empire->UpdateProductionQueue(); m_build_designator_wnd->CenterOnBuild(m_queue_lb->NumRows() - 1); }
int IssueEnqueueShipProductionOrder(int design_id, int location_id) { int empire_id = AIClientApp::GetApp()->EmpireID(); Empire* empire = AIClientApp::GetApp()->Empires().Lookup(empire_id); if (!empire->ProducibleItem(BT_SHIP, design_id, location_id)) { Logger().errorStream() << "AIInterface::IssueEnqueueShipProductionOrder : specified design_id and location_id that don't indicate a design that can be built at that location"; return 0; } AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new ProductionQueueOrder(empire_id, BT_SHIP, design_id, 1, location_id))); return 1; }
int IssueEnqueueBuildingProductionOrder(const std::string& item_name, int location_id) { int empire_id = AIClientApp::GetApp()->EmpireID(); Empire* empire = AIClientApp::GetApp()->Empires().Lookup(empire_id); if (!empire->ProducibleItem(BT_BUILDING, item_name, location_id)) { Logger().errorStream() << "AIInterface::IssueEnqueueBuildingProductionOrder : specified item_name and location_id that don't indicate an item that can be built at that location"; return 0; } AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new ProductionQueueOrder(empire_id, BT_BUILDING, item_name, 1, location_id))); return 1; }
void ProductionWnd::AddBuildToQueueSlot(const ProductionQueue::ProductionItem& item, int number, int location, int pos) { if (!m_order_issuing_enabled) return; int client_empire_id = HumanClientApp::GetApp()->EmpireID(); Empire* empire = GetEmpire(client_empire_id); if (!empire) return; HumanClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new ProductionQueueOrder(client_empire_id, item, number, location, pos))); empire->UpdateProductionQueue(); m_build_designator_wnd->CenterOnBuild(pos >= 0 ? pos : m_queue_wnd->GetQueueListBox()->NumRows() - 1); }
int IssueDequeueProductionOrder(int queue_index) { int empire_id = AIClientApp::GetApp()->EmpireID(); Empire* empire = AIClientApp::GetApp()->Empires().Lookup(empire_id); const ProductionQueue& queue = empire->GetProductionQueue(); if (queue_index < 0 || static_cast<int>(queue.size()) <= queue_index) { Logger().errorStream() << "AIInterface::IssueDequeueProductionOrder : passed queue_index outside range of items on queue."; return 0; } AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new ProductionQueueOrder(empire_id, queue_index))); return 1; }
void ProductionWnd::QueueItemMoved(GG::ListBox::Row* row, std::size_t position) { if (!m_order_issuing_enabled) return; int client_empire_id = HumanClientApp::GetApp()->EmpireID(); Empire* empire = Empires().Lookup(client_empire_id); if (!empire) return; HumanClientApp::GetApp()->Orders().IssueOrder( OrderPtr(new ProductionQueueOrder(client_empire_id, boost::polymorphic_downcast<QueueRow*>(row)->queue_index, position))); empire->UpdateProductionQueue(); }
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 Planet::Conquer(int conquerer) { if (conquerer == ALL_EMPIRES) return; m_just_conquered = true; Empire* empire = Empires().Lookup(conquerer); if (!empire) { Logger().errorStream() << "Planet::Conquer: attempted to conquer a planet with an invalid conquerer with id: " << conquerer; return; } // deal with things on production queue located at this planet empire->ConquerBuildsAtLocation(ID()); // deal with UniverseObjects (eg. buildings) located on this planet std::vector<UniverseObject*> contained_objects = this->FindObjects(); for (std::vector<UniverseObject*>::iterator it = contained_objects.begin(); it != contained_objects.end(); ++it) { UniverseObject* obj = *it; // Buildings: if (Building* building = universe_object_cast<Building*>(obj)) { const BuildingType* type = building->GetBuildingType(); // determine what to do with building of this type... const CaptureResult cap_result = type->GetCaptureResult(obj->Owner(), conquerer, this->ID(), false); if (cap_result == CR_CAPTURE) { // replace ownership obj->SetOwner(conquerer); } else if (cap_result == CR_DESTROY) { // destroy object Logger().debugStream() << "Planet::Conquer destroying object: " << obj->Name(); GetUniverse().Destroy(obj->ID()); obj = 0; } else if (cap_result == CR_RETAIN) { // do nothing } } // TODO: deal with any other UniverseObject subclasses...? } // replace ownership SetOwner(conquerer); }
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(); } }
int IssueChangeProductionQuantityOrder(int queue_index, int new_quantity, int new_blocksize) { int empire_id = AIClientApp::GetApp()->EmpireID(); Empire* empire = AIClientApp::GetApp()->Empires().Lookup(empire_id); const ProductionQueue& queue = empire->GetProductionQueue(); if (queue_index < 0 || static_cast<int>(queue.size()) <= queue_index) { Logger().errorStream() << "AIInterface::IssueChangeProductionQuantityOrder : passed queue_index outside range of items on queue."; return 0; } if (queue[queue_index].item.build_type != BT_SHIP) { Logger().errorStream() << "AIInterface::IssueChangeProductionQuantityOrder : passed queue_index for a non-ship item."; return 0; } AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr( new ProductionQueueOrder(empire_id, queue_index, new_quantity, new_blocksize))); return 1; }
void ProductionWnd::QueueItemRallied(GG::ListBox::iterator it, int object_id) { if (!m_order_issuing_enabled) return; int client_empire_id = HumanClientApp::GetApp()->EmpireID(); Empire* empire = GetEmpire(client_empire_id); if (!empire) return; int rally_point_id = object_id; if (rally_point_id == INVALID_OBJECT_ID) { // get rally point from selected system rally_point_id = SidePanel::SystemID(); } if (rally_point_id == INVALID_OBJECT_ID) return; HumanClientApp::GetApp()->Orders().IssueOrder( OrderPtr(new ProductionQueueOrder(client_empire_id, std::distance(m_queue_wnd->GetQueueListBox()->begin(), it), rally_point_id, false, false))); empire->UpdateProductionQueue(); }
void ResearchWnd::AddTechsToQueueSlot(const std::vector<std::string>& tech_vec, int pos) { if (!m_enabled) return; int empire_id = HumanClientApp::GetApp()->EmpireID(); Empire* empire = GetEmpire(empire_id); if (!empire) return; const ResearchQueue& queue = empire->GetResearchQueue(); OrderSet& orders = HumanClientApp::GetApp()->Orders(); for (std::vector<std::string>::const_iterator it = tech_vec.begin(); it != tech_vec.end(); ++it) { const std::string& tech_name = *it; if (empire->TechResearched(tech_name)) continue; // AddTechsToQueueSlot is currently used for (i) adding a tech and any not-yet-queued prereqs to the // end of the queue (but any already-queued prereqs are NOT to be moved to the end of the queue), or // (ii) prioritizing a tech by placing it and any not-yet-completed techs, whether currently queued or not, // to the front of the queue. If at some time this routine is desired to be used to move a group of techs from // early positions in the queue to later positions, the below tests would need to change. // If we're adding to the end of the queue (pos==-1), we'll need to put in a ResearchQueueOrder iff the tech is // not yet in the queue. Otherwise (adding to beginning) we'll need to put in a ResearchQueueOrder if the tech is // not yet in the queue or if the tech's current position in the queue is after the desired position. When // adding/moving a group of techs to the queue beginning, we increment our insertion point for every tech we add, // or that we skipped because it happened to already be in the right spot. if (pos == -1) { if (!queue.InQueue(tech_name)) { orders.IssueOrder(OrderPtr(new ResearchQueueOrder(empire_id, tech_name, pos))); } } else if (!queue.InQueue(tech_name) || ((queue.find(tech_name) - queue.begin()) > pos)) { orders.IssueOrder(OrderPtr(new ResearchQueueOrder(empire_id, tech_name, pos))); pos += 1; } else { if ((queue.find(tech_name) - queue.begin()) == pos) pos += 1; } } empire->UpdateResearchQueue(); }
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 Fleet::MovementPhase() { //Logger().debugStream() << "Fleet::MovementPhase this: " << this->Name() << " id: " << this->ID(); m_arrived_this_turn = false; m_arrival_starlane = INVALID_OBJECT_ID; int prev_prev_system = m_prev_system; Empire* empire = Empires().Lookup(this->Owner()); // if owner of fleet can resupply ships at the location of this fleet, then // resupply all ships in this fleet if (empire && empire->FleetOrResourceSupplyableAtSystem(this->SystemID())) for (Fleet::const_iterator ship_it = this->begin(); ship_it != this->end(); ++ship_it) if (Ship* ship = GetShip(*ship_it)) ship->Resupply(); System* current_system = GetSystem(SystemID()); System* const initial_system = current_system; std::list<MovePathNode> move_path = this->MovePath(); std::list<MovePathNode>::const_iterator it = move_path.begin(); std::list<MovePathNode>::const_iterator next_it = it; if (next_it != move_path.end()) ++next_it; // is the ship stuck in a system for a whole turn? if (current_system) { // in a system. if there is no system after the current one in the // path, or the current and next nodes have the same system id, that // is an actual system, then won't be moving this turn. if ((next_it == move_path.end()) || (it->object_id != INVALID_OBJECT_ID && it->object_id == next_it->object_id) ) { // fuel regeneration for ships in stationary fleet if (this->FinalDestinationID() == INVALID_OBJECT_ID || this->FinalDestinationID() == this->SystemID()) { for (Fleet::const_iterator ship_it = this->begin(); ship_it != this->end(); ++ship_it) { if (Ship* ship = GetShip(*ship_it)) if (Meter* fuel_meter = ship->UniverseObject::GetMeter(METER_FUEL)) { fuel_meter->AddToCurrent(0.1001); fuel_meter->BackPropegate(); } } } return; } } // if fleet not moving, nothing more to do. if (move_path.empty() || move_path.size() == 1) { //Logger().debugStream() << "Fleet::MovementPhase: Fleet move path is empty or has only one entry. doing nothing"; return; } //Logger().debugStream() << "Fleet::MovementPhase move path:"; //for (std::list<MovePathNode>::const_iterator it = move_path.begin(); it != move_path.end(); ++it) // Logger().debugStream() << "... (" << it->x << ", " << it->y << ") at object id: " << it->object_id << " eta: " << it->eta << (it->turn_end ? " (end of turn)" : " (during turn)"); // move fleet in sequence to MovePathNodes it can reach this turn double fuel_consumed = 0.0; for (it = move_path.begin(); it != move_path.end(); ++it) { next_it = it; ++next_it; System* system = GetSystem(it->object_id); //Logger().debugStream() << "... node " << (system ? system->Name() : "no system"); // is this system the last node reached this turn? either it's an end of turn node, // or there are no more nodes after this one on path bool node_is_next_stop = (it->turn_end || next_it == move_path.end()); if (system) { // node is a system. explore system for all owners of this fleet if (empire) empire->AddExploredSystem(it->object_id); prev_prev_system = m_prev_system; m_prev_system = system->ID(); // passing a system, so update previous system of this fleet bool resupply_here = empire ? empire->FleetOrResourceSupplyableAtSystem(system->ID()) : false; // if this system can provide supplies, reset consumed fuel and refuel ships if (resupply_here) { //Logger().debugStream() << " ... node has fuel supply. consumed fuel for movement reset to 0 and fleet resupplied"; fuel_consumed = 0.0; for (Fleet::const_iterator ship_it = this->begin(); ship_it != this->end(); ++ship_it) { Ship* ship = GetShip(*ship_it); assert(ship); ship->Resupply(); } } if (node_is_next_stop) { // is system the last node reached this turn? system->Insert(this); // fleet ends turn at this node. insert fleet into system current_system = system; //Logger().debugStream() << "... ... inserted fleet into system"; break; } else { // fleet will continue past this system this turn. //Logger().debugStream() << "... ... moved fleet to system (not inserted)"; if (!resupply_here) { fuel_consumed += 1.0; //Logger().debugStream() << "... ... consuming 1 unit of fuel to continue moving. total fuel consumed now: " << fuel_consumed; } else { //Logger().debugStream() << "... ... not consuming fuel to depart resupply system"; } } } else { // node is not a system. if (node_is_next_stop) { // node is not a system, but is it the last node reached this turn? MoveTo(it->x, it->y); // fleet ends turn at this node. move fleet here //Logger().debugStream() << "... ... moved fleet to position"; break; } } } //Logger().debugStream() << "Fleet::MovementPhase rest of move path:"; //for (std::list<MovePathNode>::const_iterator it2 = it; it2 != move_path.end(); ++it2) // Logger().debugStream() << "... (" << it2->x << ", " << it2->y << ") at object id: " << it2->object_id << " eta: " << it2->eta << (it2->turn_end ? " (end of turn)" : " (during turn)"); // update next system if (m_moving_to != SystemID() && next_it != move_path.end() && it != move_path.end()) { // there is another system later on the path to aim for. find it for (; next_it != move_path.end(); ++next_it) { if (GetSystem(next_it->object_id)) { //Logger().debugStream() << "___ setting m_next_system to " << next_it->object_id; m_next_system = next_it->object_id; break; } } } else { // no more systems on path m_arrived_this_turn = current_system != initial_system; m_arrival_starlane = prev_prev_system; m_moving_to = m_next_system = m_prev_system = INVALID_OBJECT_ID; } // consume fuel from ships in fleet if (fuel_consumed > 0.0) { for (const_iterator ship_it = begin(); ship_it != end(); ++ship_it) if (Ship* ship = GetShip(*ship_it)) if (Meter* meter = ship->UniverseObject::GetMeter(METER_FUEL)) { meter->AddToCurrent(-fuel_consumed); meter->BackPropegate(); } } }