Difference between revisions of "User:Geoff the Medio/Coding"
From FreeOrionWiki
m (→SidePanel::ClickColoinze()) |
|||
Line 174: | Line 174: | ||
}; | }; | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | ==FleetColonizeOrder function definitions== | ||
+ | |||
+ | <pre> | ||
+ | FleetColonizeOrder::FleetColonizeOrder() : | ||
+ | Order(), | ||
+ | m_ship(UniverseObject::INVALID_OBJECT_ID), | ||
+ | m_planet(UniverseObject::INVALID_OBJECT_ID) | ||
+ | { | ||
+ | } | ||
+ | |||
+ | FleetColonizeOrder::FleetColonizeOrder(const GG::XMLElement& elem) : Order(elem.Child("Order")) | ||
+ | { | ||
+ | if(elem.Tag() != ("FleetColonizeOrder")) | ||
+ | throw std::invalid_argument("Attempted to construct FleetColonizeOrder from malformed XMLElement"); | ||
+ | |||
+ | m_ship = lexical_cast<int>(elem.Child("m_ship").Text()); | ||
+ | m_planet = lexical_cast<int>(elem.Child("m_planet").Text()); | ||
+ | m_colony_fleet_id = lexical_cast<int>(elem.Child("m_colony_fleet_id").Text()); | ||
+ | } | ||
+ | |||
+ | FleetColonizeOrder::FleetColonizeOrder(int empire, int ship, int planet) : | ||
+ | Order(empire), | ||
+ | m_ship(ship), | ||
+ | m_planet(planet) | ||
+ | { | ||
+ | } | ||
+ | |||
+ | void FleetColonizeOrder::ServerExecute() const | ||
+ | { | ||
+ | Universe& universe = GetUniverse(); | ||
+ | universe.Delete(m_ship); | ||
+ | Planet* planet = universe.Object<Planet>(m_planet); | ||
+ | planet->ResetMaxMeters(); | ||
+ | planet->AdjustMaxMeters(); | ||
+ | planet->AdjustPop(INITIAL_COLONY_POP); | ||
+ | planet->GetMeter(METER_FARMING)->SetCurrent(INITIAL_COLONY_POP); | ||
+ | planet->GetMeter(METER_HEALTH)->SetCurrent(planet->GetMeter(METER_HEALTH)->Max()); | ||
+ | planet->AddOwner(EmpireID()); | ||
+ | if (System* system = planet->GetSystem()) | ||
+ | system->AddOwner(EmpireID()); | ||
+ | } | ||
+ | |||
+ | XMLElement FleetColonizeOrder::XMLEncode() const | ||
+ | { | ||
+ | XMLElement retval("FleetColonizeOrder"); | ||
+ | retval.AppendChild(Order::XMLEncode()); | ||
+ | retval.AppendChild(XMLElement("m_ship", lexical_cast<std::string>(m_ship))); | ||
+ | retval.AppendChild(XMLElement("m_planet", lexical_cast<std::string>(m_planet))); | ||
+ | retval.AppendChild(XMLElement("m_colony_fleet_id", lexical_cast<std::string>(m_colony_fleet_id))); | ||
+ | return retval; | ||
+ | } | ||
+ | |||
+ | void FleetColonizeOrder::ExecuteImpl() const | ||
+ | { | ||
+ | ValidateEmpireID(); | ||
+ | |||
+ | Universe& universe = GetUniverse(); | ||
+ | |||
+ | // look up the ship and fleet in question | ||
+ | Ship* ship = universe.Object<Ship>(m_ship); | ||
+ | Fleet* fleet = universe.Object<Fleet>(ship->FleetID()); | ||
+ | |||
+ | // ensure fleet exists | ||
+ | if (!fleet) | ||
+ | throw std::runtime_error("Illegal fleet id specified in fleet colonize order."); | ||
+ | |||
+ | // verify that empire issuing order owns specified fleet | ||
+ | if (!fleet->OwnedBy(EmpireID())) | ||
+ | throw std::runtime_error("Empire attempted to issue colonize order to another's fleet."); | ||
+ | |||
+ | // verify that planet exists and is un-occupied. | ||
+ | Planet* planet = universe.Object<Planet>(m_planet); | ||
+ | if (planet == NULL) | ||
+ | throw std::runtime_error("Colonization order issued with invalid planet id."); | ||
+ | |||
+ | if (!planet->Unowned()) | ||
+ | throw std::runtime_error("Colonization order issued for owned planet."); | ||
+ | |||
+ | // verify that planet is in same system as the fleet | ||
+ | if (planet->SystemID() != fleet->SystemID() || | ||
+ | planet->SystemID() == UniverseObject::INVALID_OBJECT_ID) { | ||
+ | throw std::runtime_error("Fleet specified in colonization order is not in " | ||
+ | "specified system."); | ||
+ | } | ||
+ | |||
+ | planet->SetIsAboutToBeColonized(true); | ||
+ | |||
+ | m_colony_fleet_id = fleet->ID(); // record the fleet in which the colony ship started | ||
+ | |||
+ | // Remove colony ship from fleet; | ||
+ | fleet->RemoveShip(m_ship); | ||
+ | } | ||
+ | |||
+ | bool FleetColonizeOrder::UndoImpl() const | ||
+ | { | ||
+ | // Note that this function does double duty: it serves as a normal client-side undo, but must also | ||
+ | // serve as a server-side undo, when more than one empire tries to colonize the same planet at the | ||
+ | // same time. | ||
+ | |||
+ | Universe& universe = GetUniverse(); | ||
+ | |||
+ | Fleet* fleet = universe.Object<Fleet>(m_colony_fleet_id); | ||
+ | Planet* planet = universe.Object<Planet>(m_planet); | ||
+ | |||
+ | planet->SetIsAboutToBeColonized(false); | ||
+ | |||
+ | Ship* ship = universe.Object<Ship>(m_ship); | ||
+ | |||
+ | // if the fleet from which the colony ship came no longer exists or has moved, make a new one | ||
+ | if (!fleet || fleet->SystemID() != ship->SystemID()) { | ||
+ | System* system = planet->GetSystem(); | ||
+ | fleet = new Fleet("Colony Fleet", system->X(), system->Y(), EmpireID()); | ||
+ | universe.Insert(fleet); | ||
+ | fleet->AddShip(ship->ID()); | ||
+ | system->Insert(fleet); | ||
+ | } else { | ||
+ | fleet->AddShip(ship->ID()); | ||
+ | } | ||
+ | |||
+ | return true; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | ==DeleteFleetOrder function definitions= | ||
+ | |||
+ | <pre> | ||
+ | //////////////////////////////////////////////// | ||
+ | // DeleteFleetOrder | ||
+ | //////////////////////////////////////////////// | ||
+ | DeleteFleetOrder::DeleteFleetOrder() : | ||
+ | Order(), | ||
+ | m_fleet(-1) | ||
+ | { | ||
+ | } | ||
+ | |||
+ | DeleteFleetOrder::DeleteFleetOrder(const GG::XMLElement& elem): | ||
+ | Order(elem.Child("Order")) | ||
+ | { | ||
+ | if(elem.Tag() != ("DeleteFleetOrder")) | ||
+ | throw std::invalid_argument("Attempted to construct DeleteFleetOrder from malformed XMLElement"); | ||
+ | |||
+ | m_fleet = lexical_cast<int>(elem.Child("m_fleet").Text()); | ||
+ | } | ||
+ | |||
+ | DeleteFleetOrder::DeleteFleetOrder(int empire, int fleet) : | ||
+ | Order(empire), | ||
+ | m_fleet(fleet) | ||
+ | { | ||
+ | } | ||
+ | |||
+ | GG::XMLElement DeleteFleetOrder::XMLEncode() const | ||
+ | { | ||
+ | XMLElement retval("DeleteFleetOrder"); | ||
+ | retval.AppendChild(Order::XMLEncode()); | ||
+ | retval.AppendChild(XMLElement("m_fleet", lexical_cast<std::string>(m_fleet))); | ||
+ | return retval; | ||
+ | } | ||
+ | |||
+ | void DeleteFleetOrder::ExecuteImpl() const | ||
+ | { | ||
+ | ValidateEmpireID(); | ||
+ | |||
+ | Fleet* fleet = GetUniverse().Object<Fleet>(FleetID()); | ||
+ | |||
+ | if(!fleet) | ||
+ | throw std::runtime_error("Illegal fleet id specified in fleet colonize order."); | ||
+ | |||
+ | if (!fleet->OwnedBy(EmpireID())) | ||
+ | throw std::runtime_error("Empire attempted to issue deletion order to another's fleet."); | ||
+ | |||
+ | if (fleet->NumShips()) | ||
+ | throw std::runtime_error("Attempted to delete an unempty fleet."); | ||
+ | |||
+ | // store info so as to be able to recind order | ||
+ | m_system_id = fleet->GetSystem()->ID(); | ||
+ | m_fleet_name = fleet->Name(); | ||
+ | |||
+ | GetUniverse().Delete(FleetID()); | ||
+ | } | ||
+ | |||
+ | bool DeleteFleetOrder::UndoImpl() const | ||
+ | { | ||
+ | Universe& universe = GetUniverse(); | ||
+ | System* system = universe.Object<System>(m_system_id); | ||
+ | |||
+ | Fleet *fleet = new Fleet(m_fleet_name, system->X(), system->Y(), EmpireID()); | ||
+ | |||
+ | universe.InsertID(fleet, m_fleet); | ||
+ | system->Insert(fleet); | ||
+ | |||
+ | return true; | ||
+ | } | ||
</pre> | </pre> |
Revision as of 04:16, 16 May 2005
Contents
SidePanel::ClickColoinze()
void SidePanel::PlanetPanel::ClickColonize() { const Planet *planet = GetPlanet(); int empire_id = HumanClientApp::GetApp()->EmpireID(); std::map<int, int> pending_colonization_orders = HumanClientApp::GetApp()->PendingColonizationOrders(); std::map<int, int>::const_iterator it = pending_colonization_orders.find(planet->ID()); if(it == pending_colonization_orders.end()) // colonize { Ship *ship = FindColonyShip(planet->SystemID()); if(!ship) throw std::runtime_error("SidePanel::PlanetPanel::ClickColonize ship not found!"); Fleet *fleet = ship->GetFleet(); if(!fleet->Accept(StationaryFleetVisitor(*fleet->Owners().begin()))) { GG::ThreeButtonDlg dlg(320,200,UserString("SP_USE_DEPARTING_COLONY_SHIPS_QUESTION"), ClientUI::FONT,ClientUI::PTS,ClientUI::WND_COLOR,ClientUI::CTRL_BORDER_COLOR,ClientUI::CTRL_COLOR,ClientUI::TEXT_COLOR,2, "Yes","No"); dlg.Run(); if(dlg.Result()!=0) return; } HumanClientApp::Orders().IssueOrder( new FleetColonizeOrder(empire_id, ship->ID(), planet->ID()) ); if (!fleet->NumShips()) { HumanClientApp::Orders().IssueOrder( new DeleteFleetOrder( empire_id, fleet->ID()) ); } } else // cancel colonization { const FleetColonizeOrder *col_order = dynamic_cast<const FleetColonizeOrder*>(HumanClientApp::Orders().ExamineOrder(it->second)); int ship_id = col_order ? col_order->ShipID() : UniverseObject::INVALID_OBJECT_ID; Ship *ship = GetUniverse().Object<Ship>(ship_id); int fleet_id = ship->FleetID(); // check if ship's fleet still exists Fleet *fleet = ship ? GetUniverse().Object<Fleet>(fleet_id) : NULL; if (!fleet) { // fleet doesn't exist, so recind order that deleted it, thus recreating it std::map<int, int> del_ords = HumanClientApp::GetApp()->PendingDeleteFleetOrders(); std::map<int, int>::iterator del_ord_it = del_ords.find(fleet_id); if (del_ord_it != del_ords.end()) HumanClientApp::Orders().RecindOrder(del_ord_it->second); // try again to get poitner... fleet = GetUniverse().Object<Fleet>(fleet_id); } if (!fleet) throw std::runtime_error("Sidepanel::ClickColonize: Fleet couldn't be recreated by recinding delete order!"); // Recind colonization order, adding ship back into fleet HumanClientApp::Orders().RecindOrder(it->second); // make sure that fleet appears at a possibly opend FleetWnd for (FleetWnd::FleetWndItr it = FleetWnd::FleetWndBegin(); it != FleetWnd::FleetWndEnd(); ++it) { FleetWnd *fleet_wnd = *it; if(fleet->SystemID() == fleet_wnd->SystemID() && !fleet_wnd->ContainsFleet(fleet->ID())) { fleet_wnd->AddFleet(GetUniverse().Object<Fleet>(fleet->ID())); break; } } } }
FleetColonizeOrder class header
class FleetColonizeOrder : public Order { public: /** \name Structors */ //@{ FleetColonizeOrder(); FleetColonizeOrder(const GG::XMLElement& elem); FleetColonizeOrder(int empire, int ship, int planet); //@} /** \name Accessors */ //@{ int PlanetID() const {return m_planet;} ///< returns ID of the planet to be colonized int ShipID () const {return m_ship ;} ///< returns ID of the ship which is colonizing the planet virtual void ServerExecute() const; //< called if the server allows the colonization effort virtual GG::XMLElement XMLEncode() const; ///< constructs an XMLElement for the order //@} private: /** * Preconditions: * - m_fleet must be the ID of a fleet owned by issuing empire * - m_planet must be the ID of an un-owned planet. * - the fleet and the planet must have the same x,y coordinates * - the fleet must contain a colony ship * * Postconditions: * - a colony ship will be removed from the fleet and deallocated * if the fleet becomes empty it will be deallocated. * - the empire issuing the order will be added to the list of owners * for the planet * - the planet's population will be increased * - the planet will be added to the empire's list of owned planets * */ //< either ExecuteServerApply or ExecuteServerRevoke is called!!! virtual void ExecuteImpl() const; virtual bool UndoImpl() const; int m_ship; int m_planet; // these are for undoing this order only mutable int m_colony_fleet_id; // the fleet from which the colony ship was taken };
DeleteFleetOrder class header
///////////////////////////////////////////////////// // DeleteFleetOrder ///////////////////////////////////////////////////// /** the Order subclass that represents forming a new fleet. Only one of system or position will be used to place the new fleet.*/ class DeleteFleetOrder : public Order { public: /** \name Structors */ //@{ DeleteFleetOrder(); DeleteFleetOrder(const GG::XMLElement& elem); DeleteFleetOrder(int empire, int fleet); //@} /** \name Accessors */ //@{ int FleetID() const {return m_fleet;} ///< returns ID of the fleet to be deleted virtual GG::XMLElement XMLEncode() const; ///< constructs an XMLElement for the order //@} private: /** * Preconditions: * - m_fleet must be the ID of a fleet owned by issuing empire * - m_planet must be the ID of an un-owned planet. * - the fleet and the planet must have the same x,y coordinates * - the fleet must contain a colony ship * * Postconditions: * - a colony ship will be removed from the fleet and deallocated * if the fleet becomes empty it will be deallocated. * - the empire issuing the order will be added to the list of owners * for the planet * - the planet's population will be increased * - the planet will be added to the empire's list of owned planets * */ //< either ExecuteServerApply or ExecuteServerRevoke is called!!! virtual void ExecuteImpl() const; virtual bool UndoImpl() const; int m_fleet; // these are for undoing this order only mutable std::string m_fleet_name; mutable int m_system_id; };
FleetColonizeOrder function definitions
FleetColonizeOrder::FleetColonizeOrder() : Order(), m_ship(UniverseObject::INVALID_OBJECT_ID), m_planet(UniverseObject::INVALID_OBJECT_ID) { } FleetColonizeOrder::FleetColonizeOrder(const GG::XMLElement& elem) : Order(elem.Child("Order")) { if(elem.Tag() != ("FleetColonizeOrder")) throw std::invalid_argument("Attempted to construct FleetColonizeOrder from malformed XMLElement"); m_ship = lexical_cast<int>(elem.Child("m_ship").Text()); m_planet = lexical_cast<int>(elem.Child("m_planet").Text()); m_colony_fleet_id = lexical_cast<int>(elem.Child("m_colony_fleet_id").Text()); } FleetColonizeOrder::FleetColonizeOrder(int empire, int ship, int planet) : Order(empire), m_ship(ship), m_planet(planet) { } void FleetColonizeOrder::ServerExecute() const { Universe& universe = GetUniverse(); universe.Delete(m_ship); Planet* planet = universe.Object<Planet>(m_planet); planet->ResetMaxMeters(); planet->AdjustMaxMeters(); planet->AdjustPop(INITIAL_COLONY_POP); planet->GetMeter(METER_FARMING)->SetCurrent(INITIAL_COLONY_POP); planet->GetMeter(METER_HEALTH)->SetCurrent(planet->GetMeter(METER_HEALTH)->Max()); planet->AddOwner(EmpireID()); if (System* system = planet->GetSystem()) system->AddOwner(EmpireID()); } XMLElement FleetColonizeOrder::XMLEncode() const { XMLElement retval("FleetColonizeOrder"); retval.AppendChild(Order::XMLEncode()); retval.AppendChild(XMLElement("m_ship", lexical_cast<std::string>(m_ship))); retval.AppendChild(XMLElement("m_planet", lexical_cast<std::string>(m_planet))); retval.AppendChild(XMLElement("m_colony_fleet_id", lexical_cast<std::string>(m_colony_fleet_id))); return retval; } void FleetColonizeOrder::ExecuteImpl() const { ValidateEmpireID(); Universe& universe = GetUniverse(); // look up the ship and fleet in question Ship* ship = universe.Object<Ship>(m_ship); Fleet* fleet = universe.Object<Fleet>(ship->FleetID()); // ensure fleet exists if (!fleet) throw std::runtime_error("Illegal fleet id specified in fleet colonize order."); // verify that empire issuing order owns specified fleet if (!fleet->OwnedBy(EmpireID())) throw std::runtime_error("Empire attempted to issue colonize order to another's fleet."); // verify that planet exists and is un-occupied. Planet* planet = universe.Object<Planet>(m_planet); if (planet == NULL) throw std::runtime_error("Colonization order issued with invalid planet id."); if (!planet->Unowned()) throw std::runtime_error("Colonization order issued for owned planet."); // verify that planet is in same system as the fleet if (planet->SystemID() != fleet->SystemID() || planet->SystemID() == UniverseObject::INVALID_OBJECT_ID) { throw std::runtime_error("Fleet specified in colonization order is not in " "specified system."); } planet->SetIsAboutToBeColonized(true); m_colony_fleet_id = fleet->ID(); // record the fleet in which the colony ship started // Remove colony ship from fleet; fleet->RemoveShip(m_ship); } bool FleetColonizeOrder::UndoImpl() const { // Note that this function does double duty: it serves as a normal client-side undo, but must also // serve as a server-side undo, when more than one empire tries to colonize the same planet at the // same time. Universe& universe = GetUniverse(); Fleet* fleet = universe.Object<Fleet>(m_colony_fleet_id); Planet* planet = universe.Object<Planet>(m_planet); planet->SetIsAboutToBeColonized(false); Ship* ship = universe.Object<Ship>(m_ship); // if the fleet from which the colony ship came no longer exists or has moved, make a new one if (!fleet || fleet->SystemID() != ship->SystemID()) { System* system = planet->GetSystem(); fleet = new Fleet("Colony Fleet", system->X(), system->Y(), EmpireID()); universe.Insert(fleet); fleet->AddShip(ship->ID()); system->Insert(fleet); } else { fleet->AddShip(ship->ID()); } return true; }
=DeleteFleetOrder function definitions
//////////////////////////////////////////////// // DeleteFleetOrder //////////////////////////////////////////////// DeleteFleetOrder::DeleteFleetOrder() : Order(), m_fleet(-1) { } DeleteFleetOrder::DeleteFleetOrder(const GG::XMLElement& elem): Order(elem.Child("Order")) { if(elem.Tag() != ("DeleteFleetOrder")) throw std::invalid_argument("Attempted to construct DeleteFleetOrder from malformed XMLElement"); m_fleet = lexical_cast<int>(elem.Child("m_fleet").Text()); } DeleteFleetOrder::DeleteFleetOrder(int empire, int fleet) : Order(empire), m_fleet(fleet) { } GG::XMLElement DeleteFleetOrder::XMLEncode() const { XMLElement retval("DeleteFleetOrder"); retval.AppendChild(Order::XMLEncode()); retval.AppendChild(XMLElement("m_fleet", lexical_cast<std::string>(m_fleet))); return retval; } void DeleteFleetOrder::ExecuteImpl() const { ValidateEmpireID(); Fleet* fleet = GetUniverse().Object<Fleet>(FleetID()); if(!fleet) throw std::runtime_error("Illegal fleet id specified in fleet colonize order."); if (!fleet->OwnedBy(EmpireID())) throw std::runtime_error("Empire attempted to issue deletion order to another's fleet."); if (fleet->NumShips()) throw std::runtime_error("Attempted to delete an unempty fleet."); // store info so as to be able to recind order m_system_id = fleet->GetSystem()->ID(); m_fleet_name = fleet->Name(); GetUniverse().Delete(FleetID()); } bool DeleteFleetOrder::UndoImpl() const { Universe& universe = GetUniverse(); System* system = universe.Object<System>(m_system_id); Fleet *fleet = new Fleet(m_fleet_name, system->X(), system->Y(), EmpireID()); universe.InsertID(fleet, m_fleet); system->Insert(fleet); return true; }