User:Geoff the Medio/Coding
From FreeOrionWiki
< User:Geoff the Medio
Revision as of 04:20, 16 May 2005 by Geoff the Medio (Talk | contribs) (→DeleteFleetOrder class header)
Contents
SidePanel::ClickColoinze()
Goes in SidePanel.cpp
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
Goes in Order.h
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
Goes in Order.h
///////////////////////////////////////////////////// // 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; }