1 #ifndef _Order_h_
2 #define _Order_h_
3 
4 #include "../universe/EnumsFwd.h"
5 #include "Export.h"
6 #include "../Empire/Empire.h"
7 
8 #include <boost/serialization/access.hpp>
9 #include <boost/serialization/nvp.hpp>
10 #include <boost/uuid/uuid.hpp>
11 
12 #include <string>
13 #include <vector>
14 
15 class ShipDesign;
16 
17 /////////////////////////////////////////////////////
18 // Order
19 /////////////////////////////////////////////////////
20 /** The abstract base class for serializable player actions.  Orders are
21   * generally executed on the client side as soon as they are issued.  Those
22   * that define UndoImpl() may also be undone on the client side.  Subclass-
23   * defined UndoImpl() \a must return true, indicating that the call had some
24   * effect; the default implementation does nothing and returns false. Note that
25   * only some Order subclasses define UndoImpl(), specifically those that need
26   * to be undone before another order of a similar type can be issued. For
27   * example, ColonizeOrder needs to be undoable; otherwise, once the user clicks
28   * the colonize button, she is locked in to this decision. */
29 class FO_COMMON_API Order {
30 public:
31     /** \name Structors */ //@{
Order()32     Order()
33     {}
34 
35     /** ctor taking the ID of the Empire issuing the order. */
Order(int empire)36     Order(int empire) :
37         m_empire(empire)
38     {}
39 
~Order()40     virtual ~Order()
41     {}
42     //@}
43 
44     /** \name Accessors */ //@{
45     /** Returns the ID of the Empire issuing the order. */
EmpireID()46     int EmpireID() const { return m_empire; }
47 
48     /** Returns true iff this order has been executed (a second execution
49       * indicates server-side execution). */
50     bool Executed() const;
51     //@}
52 
53     /** Executes the order on the Universe and Empires.
54      *
55      *  Preconditions of Execute():
56      *  For all order subclasses, the empire ID for the order
57      *  must be that of an existing empire.
58      *
59      *  The order has not already been executed.
60      *
61      *  Subclasses add additional preconditions.  An std::runtime_error
62      *   should be thrown if any precondition fails.
63      */
64     void Execute() const;
65 
66     /** If this function returns true, it reverts the game state to what it was
67      *  before this order was executed, otherwise it returns false and has no
68      *  effect. If an order is undone on the client and then still sent to the server it will be
69      *  executed on the server, which is probably not desired. */
70     bool Undo() const;
71 
72 protected:
73     /** \name Mutators */ //@{
74     /** Verifies that the empire ID in this order is valid and return the Empire pointer.
75      *  Throws an std::runtime_error if not valid. */
76     Empire* GetValidatedEmpire() const;
77     //@}
78 
79 private:
80     virtual void ExecuteImpl() const = 0;
81     virtual bool UndoImpl() const;
82 
83     int m_empire = ALL_EMPIRES;
84 
85     /** Indicates that Execute() has occured, and so an undo is legal. */
86     mutable bool m_executed = false;
87 
88     friend class boost::serialization::access;
89     template <typename Archive>
90     void serialize(Archive& ar, const unsigned int version);
91 };
92 
93 
94 /////////////////////////////////////////////////////
95 // RenameOrder
96 /////////////////////////////////////////////////////
97 /** the Order subclass that represents the renaming of a UniverseObject. */
98 class FO_COMMON_API RenameOrder : public Order {
99 public:
100     /** \name Structors */ //@{
101     RenameOrder(int empire, int object, const std::string& name);
102     //@}
103 
104     /** \name Accessors */ //@{
105     /** Returns ID of fleet selected in this order. */
ObjectID()106     int ObjectID() const
107     { return m_object; }
108 
109     /** Returns the new name of the fleet. */
Name()110     const std::string& Name() const
111     { return m_name; }
112     //@}
113 
114     //! Returns true when the Order parameters are valid.
115     static bool Check(int empire, int object, const std::string& new_name);
116 
117 private:
118     RenameOrder() = default;
119 
120     /**
121      * Preconditions of execute:
122      *    - the designated planet must exist, be owned by the issuing empire
123      *
124      *  Postconditions:
125      *    - the planet focus is changed which=0(primary),1(secondary)
126      *
127      */
128     void ExecuteImpl() const override;
129 
130     int m_object = INVALID_OBJECT_ID;
131     std::string m_name;
132 
133     friend class boost::serialization::access;
134     template <typename Archive>
135     void serialize(Archive& ar, const unsigned int version);
136 };
137 
138 
139 /////////////////////////////////////////////////////
140 // NewFleetOrder
141 /////////////////////////////////////////////////////
142 /** the Order subclass that represents forming a new fleet.
143     Only one of system or position will be used to place the new fleet.*/
144 class FO_COMMON_API NewFleetOrder : public Order {
145 public:
146     /** \name Structors */ //@{
147     NewFleetOrder(int empire, const std::string& fleet_name,
148                   const std::vector<int>& ship_ids,
149                   bool aggressive);
150     //@}
151 
152     /** \name Accessors */ //@{
FleetName()153     const std::string& FleetName() const
154     { return m_fleet_name; }
155 
FleetID()156     const int& FleetID() const
157     { return m_fleet_id; }
158 
ShipIDs()159     const std::vector<int>& ShipIDs() const
160     { return m_ship_ids; }
161 
Aggressive()162     bool Aggressive() const
163     { return m_aggressive; }
164     //@}
165 
166     static bool Check(int empire, const std::string& fleet_name, const std::vector<int>& ship_ids, bool aggressive);
167 private:
168     NewFleetOrder() = default;
169 
170     /**
171      * Preconditions of execute:
172      *    None.
173      *
174      *  Postconditions:
175      *    - new fleets will exist in system with id m_system_id,
176      *      and will belong to the creating empire.
177      */
178     void ExecuteImpl() const override;
179 
180     std::string m_fleet_name;
181     /** m_fleet_id is mutable because ExecuteImpl generates the fleet id. */
182     mutable int m_fleet_id = INVALID_OBJECT_ID;
183     std::vector<int> m_ship_ids;
184     bool m_aggressive = false;
185 
186     friend class boost::serialization::access;
187     template <typename Archive>
188     void serialize(Archive& ar, const unsigned int version);
189 };
190 
191 
192 /////////////////////////////////////////////////////
193 // FleetMoveOrder
194 /////////////////////////////////////////////////////
195 /** the Order subclass that represents fleet movement
196     These orders change the current destination of a fleet */
197 class FO_COMMON_API FleetMoveOrder : public Order {
198 public:
199     /** \name Structors */ //@{
200     FleetMoveOrder(int empire_id, int fleet_id, int dest_system_id,
201                    bool append = false);
202     //@}
203 
204     /** \name Accessors */ //@{
205     /** Returns ID of fleet selected in this order. */
FleetID()206     int FleetID() const
207     { return m_fleet; }
208 
209     /* Returns ID of system set as destination for this order. */
DestinationSystemID()210     int DestinationSystemID() const
211     { return m_dest_system; }
212 
213     /* Returns the IDs of the systems in the route specified by this Order. */
Route()214     const std::vector<int>& Route() const
215     { return m_route; }
216     //@}
217 
218     static bool Check(int empire_id, int fleet_id, int dest_fleet_id, bool append = false);
219 private:
220     FleetMoveOrder() = default;
221 
222     /**
223      * Preconditions of execute:
224      *    - m_fleet is a valid id of a fleet owned by the order-giving empire
225      *    - if the fleet is located in a system, m_start_system is the id of that system
226      *    - if the fleet is not located in a system, m_start_system is the id of the system the fleet is moving to
227      *    -
228      *
229      *  Postconditions:
230      *    - TODO: WRITE THIS
231      *
232      */
233     void ExecuteImpl() const override;
234 
235     int m_fleet = INVALID_OBJECT_ID;
236     int m_dest_system = INVALID_OBJECT_ID;
237     std::vector<int> m_route;
238     bool m_append = false;
239 
240     friend class boost::serialization::access;
241     template <typename Archive>
242     void serialize(Archive& ar, const unsigned int version);
243 };
244 
245 
246 /////////////////////////////////////////////////////
247 // FleetTransferOrder
248 /////////////////////////////////////////////////////
249 /** The Order subclass that represents transfer of ships between existing fleets
250   * A FleetTransferOrder is used to transfer ships from one existing fleet to
251   * another. */
252 class FO_COMMON_API FleetTransferOrder : public Order {
253 public:
254     /** \name Structors */ //@{
255     FleetTransferOrder(int empire, int dest_fleet, const std::vector<int>& ships);
256     //@}
257 
258     /** \name Accessors */ //@{
259     /* Returns ID of the fleet that the ships will go into. */
DestinationFleet()260     int DestinationFleet() const
261     { return m_dest_fleet; }
262 
263     /** Returns IDs of the ships selected for addition to the fleet. */
Ships()264     const std::vector<int>& Ships() const
265     { return m_add_ships; }
266     //@}
267 
268     static bool Check(int empire_id, int dest_fleet_id, const std::vector<int>& ship_ids);
269 
270 private:
271     FleetTransferOrder() = default;
272 
273     /**
274      *  FleetTransferOrder's preconditions are:
275      *    - m_into_fleet must be the ID of a fleet owned by the issuing empire
276      *    - each element of m_add_ships must be the ID of a ship owned by the issuing empire
277      *
278      *  Postconditions:
279      *     - all ships in m_add_ships will be moved from their initial fleet to the destination fleet
280      *     - any resulting empty fleets will be deleted
281      */
282     void ExecuteImpl() const override;
283 
284     int m_dest_fleet = INVALID_OBJECT_ID;
285     std::vector<int> m_add_ships;
286 
287     friend class boost::serialization::access;
288     template <typename Archive>
289     void serialize(Archive& ar, const unsigned int version);
290 };
291 
292 
293 /////////////////////////////////////////////////////
294 // ColonizeOrder
295 /////////////////////////////////////////////////////
296 /** the Order subclass that represents a planet colonization action*/
297 class FO_COMMON_API ColonizeOrder : public Order {
298 public:
299     /** \name Structors */ //@{
300     ColonizeOrder(int empire, int ship, int planet);
301     //@}
302 
303     /** \name Accessors */ //@{
304     /** Returns ID of the planet to be colonized. */
PlanetID()305     int PlanetID() const
306     { return m_planet; }
307 
308     /** Returns ID of the ship which is colonizing the planet. */
ShipID()309     int ShipID() const
310     { return m_ship; }
311     //@}
312 
313     static bool Check(int empire_id, int ship_id, int planet_id);
314 
315 private:
316     ColonizeOrder() = default;
317 
318     /**
319      *  Preconditions:
320      *     - m_planet must be the ID of an un-owned planet.
321      *     - m_ship must be the the ID of a ship owned by the issuing empire
322      *     - m_ship must be the ID of a ship that can colonize and that is in
323      *       the same system as the planet.
324      *
325      *  Postconditions:
326      *      - The ship with ID m_ship will be marked to colonize the planet with
327      *        id m_planet during the next turn processing.
328      */
329     void ExecuteImpl() const override;
330 
331     bool UndoImpl() const override;
332 
333     int m_ship = INVALID_OBJECT_ID;
334     int m_planet = INVALID_OBJECT_ID;
335 
336     friend class boost::serialization::access;
337     template <typename Archive>
338     void serialize(Archive& ar, const unsigned int version);
339 };
340 
341 
342 /////////////////////////////////////////////////////
343 // InvadeOrder
344 /////////////////////////////////////////////////////
345 /** the Order subclass that represents a planet invasion action*/
346 class FO_COMMON_API InvadeOrder : public Order {
347 public:
348     /** \name Structors */ //@{
349     InvadeOrder(int empire, int ship, int planet);
350     //@}
351 
352     /** \name Accessors */ //@{
353     /** Returns ID of the planet to be invaded. */
PlanetID()354     int PlanetID() const
355     { return m_planet; }
356 
357     /** Returns ID of the ship which is invading the planet. */
ShipID()358     int ShipID() const
359     { return m_ship; }
360     //@}
361 
362     static bool Check(int empire_id, int ship_id, int planet_id);
363 
364 private:
365     InvadeOrder() = default;
366 
367     /**
368      *  Preconditions:
369      *     - m_planet must be the ID of a populated planet not owned by the issuing empire
370      *     - m_ship must be the the ID of a ship owned by the issuing empire
371      *     - m_ship must be the ID of a ship that can invade and that is in
372      *       the same system as the planet.
373      *
374      *  Postconditions:
375      *      - The ship with ID m_ship will be marked to invade the planet with
376      *        id m_planet during the next turn processing.
377      */
378     void ExecuteImpl() const override;
379 
380     bool UndoImpl() const override;
381 
382     int m_ship = INVALID_OBJECT_ID;
383     int m_planet = INVALID_OBJECT_ID;
384 
385     friend class boost::serialization::access;
386     template <typename Archive>
387     void serialize(Archive& ar, const unsigned int version);
388 };
389 
390 
391 /////////////////////////////////////////////////////
392 // BombardOrder
393 /////////////////////////////////////////////////////
394 /** the Order subclass that represents a planet bombardment action*/
395 class FO_COMMON_API BombardOrder : public Order {
396 public:
397     /** \name Structors */ //@{
398     BombardOrder(int empire, int ship, int planet);
399     //@}
400 
401     /** \name Accessors */ //@{
402     /** Returns ID of the planet to be bombarded. */
PlanetID()403     int PlanetID() const
404     { return m_planet; }
405 
406     /** Returns ID of the ship which is bombarding the planet. */
ShipID()407     int ShipID() const
408     { return m_ship; }
409     //@}
410 
411     static bool Check(int empire_id, int ship_id, int planet_id);
412 
413 private:
414     BombardOrder() = default;
415 
416     /**
417      *  Preconditions:
418      *     - m_planet must be the ID of a planet
419      *     - m_ship must be the the ID of a ship owned by the issuing empire
420      *
421      *  Postconditions:
422      *      - The ship with ID m_ship will be marked to bombard the planet with
423      *        id m_planet during the next turn processing.
424      */
425     void ExecuteImpl() const override;
426 
427     bool UndoImpl() const override;
428 
429     int m_ship = INVALID_OBJECT_ID;
430     int m_planet = INVALID_OBJECT_ID;
431 
432     friend class boost::serialization::access;
433     template <typename Archive>
434     void serialize(Archive& ar, const unsigned int version);
435 };
436 
437 
438 /////////////////////////////////////////////////////
439 // ChangeFocusOrder
440 /////////////////////////////////////////////////////
441 /** the Order subclass that represents changing a planet focus*/
442 class FO_COMMON_API ChangeFocusOrder : public Order {
443 public:
444     /** \name Structors */ //@{
445     ChangeFocusOrder(int empire, int planet, const std::string& focus);
446     //@}
447 
448     /** \name Accessors */ //@{
449     /* Returns ID of the fleet to be deleted. */
PlanetID()450     int PlanetID() const
451     { return m_planet; }
452     //@}
453 
454     static bool Check(int empire_id, int planet_id, const std::string& focus);
455 
456 private:
457     ChangeFocusOrder() = default;
458 
459     /**
460      * Preconditions of execute:
461      *    - the designated planet must exist, be owned by the issuing empire
462      *
463      *  Postconditions:
464      *    - the planet focus is changed
465      */
466     void ExecuteImpl() const override;
467 
468     int m_planet = INVALID_OBJECT_ID;
469     std::string m_focus;
470 
471     friend class boost::serialization::access;
472     template <typename Archive>
473     void serialize(Archive& ar, const unsigned int version);
474 };
475 
476 
477 /////////////////////////////////////////////////////
478 // ResearchQueueOrder
479 /////////////////////////////////////////////////////
480 /** The Order subclass that represents changing an empire's research queue.  The
481   * 2-arg ctor removes the named tech from \a empire's queue, whereas the 3-arg
482   * ctor places \a tech_name at position \a position in \a empire's research queue. */
483 class FO_COMMON_API ResearchQueueOrder : public Order {
484 public:
485     /** \name Structors */ //@{
486     ResearchQueueOrder(int empire, const std::string& tech_name);
487     ResearchQueueOrder(int empire, const std::string& tech_name, int position);
488     ResearchQueueOrder(int empire, const std::string& tech_name, bool pause, float dummy);
489     //@}
490 
491 private:
492     ResearchQueueOrder() = default;
493 
494     void ExecuteImpl() const override;
495 
496     std::string m_tech_name;
497     int m_position = INVALID_INDEX;
498     bool m_remove = false;
499     int m_pause = INVALID_PAUSE_RESUME;
500 
501     static const int INVALID_INDEX = -500;
502     static const int PAUSE = 1;
503     static const int RESUME = 2;
504     static const int INVALID_PAUSE_RESUME = -1;
505 
506     friend class boost::serialization::access;
507     template <typename Archive>
508     void serialize(Archive& ar, const unsigned int version);
509 };
510 
511 
512 /////////////////////////////////////////////////////
513 // ProductionQueueOrder
514 /////////////////////////////////////////////////////
515 /** The Order subclass that represents changing an empire's production queue.
516   * The ProductionItem ctor adds the build to the beginning or end of \a empire's queue, the 3-arg
517   * ctor moves an existing build from its current location at \a index to a new
518   * one at \a new_index, and the 2-arg ctor removes the build at \a index from
519   * \a empire's queue. */
520 class FO_COMMON_API ProductionQueueOrder : public Order {
521 public:
522     enum ProdQueueOrderAction : int {
523         INVALID_PROD_QUEUE_ACTION = -1,
524         PLACE_IN_QUEUE,
525         REMOVE_FROM_QUEUE,
526         SPLIT_INCOMPLETE,
527         DUPLICATE_ITEM,
528         SET_QUANTITY_AND_BLOCK_SIZE,
529         SET_QUANTITY,
530         MOVE_ITEM_TO_INDEX,
531         SET_RALLY_POINT,
532         PAUSE_PRODUCTION,
533         RESUME_PRODUCTION,
534         ALLOW_STOCKPILE_USE,
535         DISALLOW_STOCKPILE_USE,
536         NUM_PROD_QUEUE_ACTIONS
537     };
538 
539     /** \name Structors */ //@{
540     ProductionQueueOrder(ProdQueueOrderAction action, int empire,
541                          const ProductionQueue::ProductionItem& item,
542                          int number, int location, int pos = -1);
543     ProductionQueueOrder(ProdQueueOrderAction action, int empire,
544                          boost::uuids::uuid uuid,
545                          int num1 = -1, int num2 = -1);
546     //@}
547 
548 private:
549     ProductionQueueOrder() = default;
550 
551     void ExecuteImpl() const override;
552 
553     ProductionQueue::ProductionItem m_item;
554     int                             m_location = INVALID_OBJECT_ID;
555     int                             m_new_quantity = INVALID_QUANTITY;
556     int                             m_new_blocksize = INVALID_QUANTITY;
557     int                             m_new_index = INVALID_INDEX;
558     int                             m_rally_point_id = INVALID_OBJECT_ID;
559     boost::uuids::uuid              m_uuid, m_uuid2;
560     ProdQueueOrderAction            m_action = INVALID_PROD_QUEUE_ACTION;
561 
562     static const int INVALID_INDEX = -500;
563     static const int INVALID_QUANTITY = -1000;
564 
565     friend class boost::serialization::access;
566     template <typename Archive>
567     void serialize(Archive& ar, const unsigned int version);
568 };
569 
570 
571 /////////////////////////////////////////////////////
572 // ShipDesignOrder
573 /////////////////////////////////////////////////////
574 /** The Order subclass that represents manipulating an empire's ship designs.
575   * The 2-arg ctor adds the existing ship design to the \a empire's set of
576   * designs - remembering, or "keeping" the design and enabling the \a empire to
577   * produce ships of that design (if all design prerequisites are met)
578   * The 3-arg ctor taking a bool removes the indicated design from the empire's
579   * set of remembered designs.
580   * The 3-arg ctor taking a ShipDesign argument creates a new shipdesign in the
581   * universe's catalog of shipdesigns with the passed new design id, and adds
582   * this design to the \a empire's set of remembered designs.  The new design
583   * must be marked as designed by this \a empire.
584   */
585 class FO_COMMON_API ShipDesignOrder : public Order {
586 public:
587     /** \name Structors */ //@{
588     ShipDesignOrder(int empire, int existing_design_id_to_remember);
589     ShipDesignOrder(int empire, int design_id_to_erase, bool dummy);
590     ShipDesignOrder(int empire, const ShipDesign& ship_design);
591     ShipDesignOrder(int empire, int existing_design_id, const std::string& new_name,
592                     const std::string& new_description = "");
593     //@}
594 
DesignID()595     int DesignID() const
596     { return m_design_id; }
597 
598 private:
599     ShipDesignOrder();
600 
601     /**
602      * Preconditions of execute:
603      *    - For creating a new design, the passed design is a valid reference
604      *      to a design created by the empire issuing the order
605      *    - For remembering an existing ship design, there exists a ship design
606      *      with the passed id, and the empire is aware of this ship design
607      *    - For removing a shipdesign from the empire's set of designs, there
608      *      empire has a design with the passed id in its set of designs
609      *
610      *  Postconditions:
611      *    - For creating a new ship design, the universe will contain a new ship
612      *      design, and the creating empire will have the new design as of of
613      *      its designs
614      *    - For remembering a ship design, the empire will have the design's id
615      *      in its set of design ids
616      *    - For removing a design, the empire will no longer have the design's
617      *      id in its set of design ids
618      */
619     void ExecuteImpl() const override;
620 
621     /// m_design_id is mutable to save the id for the server when the client calls ExecuteImpl.
622     mutable int m_design_id = INVALID_DESIGN_ID;
623     boost::uuids::uuid m_uuid;
624     bool m_update_name_or_description = false;
625     bool m_delete_design_from_empire = false;
626     bool m_create_new_design = false;
627 
628     // details of design to create
629     std::string m_name;
630     std::string m_description;
631     int m_designed_on_turn = 0;
632     std::string m_hull;
633     std::vector<std::string> m_parts;
634     bool m_is_monster  = false;
635     std::string m_icon;
636     std::string m_3D_model;
637     bool m_name_desc_in_stringtable = false;
638     // end details of design to create
639 
640     friend class boost::serialization::access;
641     template <typename Archive>
642     void serialize(Archive& ar, const unsigned int version);
643 };
644 
645 
646 /////////////////////////////////////////////////////
647 // ScrapOrder
648 /////////////////////////////////////////////////////
649 /** the Order subclass that represents the scrapping / recycling / destroying
650   * a building or ship owned by an empire. */
651 class FO_COMMON_API ScrapOrder : public Order {
652 public:
653     /** \name Structors */ //@{
654     ScrapOrder(int empire, int object_id);
655     //@}
656 
657     /** \name Accessors */ //@{
658     /** Returns ID of object selected in this order. */
ObjectID()659     int ObjectID() const
660     { return m_object_id; }
661     //@}
662 
663     static bool Check(int empire_id, int object_id);
664 private:
665     ScrapOrder() = default;
666 
667     /**
668      *  Preconditions:
669      *     - m_object_id must be the ID of an object owned by issuing empire
670      *     - the object must be scrappable: ships or buildings
671      *
672      *  Postconditions:
673      *     - the object is marked to be scrapped during the next turn processing.
674      */
675     void ExecuteImpl() const override;
676 
677     bool UndoImpl() const override;
678 
679     int m_object_id = INVALID_OBJECT_ID;
680 
681     friend class boost::serialization::access;
682     template <typename Archive>
683     void serialize(Archive& ar, const unsigned int version);
684 };
685 
686 
687 /////////////////////////////////////////////////////
688 // AggressiveOrder
689 /////////////////////////////////////////////////////
690 /** the Order subclass that represents setting the aggression state of objects
691   * controlled by an empire. */
692 class FO_COMMON_API AggressiveOrder : public Order {
693 public:
694     /** \name Structors */ //@{
695     AggressiveOrder(int empire, int object_id, bool aggression = true);
696     //@}
697 
698     /** \name Accessors */ //@{
699     /** Returns ID of object selected in this order. */
ObjectID()700     int ObjectID() const
701     { return m_object_id; }
702 
703     /** Returns aggression state to set object to. */
Aggression()704     bool Aggression() const
705     { return m_aggression; }
706     //@}
707 
708     static bool Check(int empire_id, int object_id, bool aggression);
709 
710 private:
711     AggressiveOrder() = default;
712 
713     /**
714      *  Preconditions:
715      *     - m_object_id must be the ID of an object owned by issuing empire
716      *     - the object must have an aggression status: fleets
717      *
718      *  Postconditions:
719      *     - the object is set to the new aggression state
720      */
721     void ExecuteImpl() const override;
722 
723     int m_object_id = INVALID_OBJECT_ID;
724     bool m_aggression = false;
725 
726     friend class boost::serialization::access;
727     template <typename Archive>
728     void serialize(Archive& ar, const unsigned int version);
729 };
730 
731 
732 /////////////////////////////////////////////////////
733 // GiveObjectToEmpireOrder
734 /////////////////////////////////////////////////////
735 /** the Order subclass that represents giving control of a ship to
736   * another empire */
737 class FO_COMMON_API GiveObjectToEmpireOrder : public Order {
738 public:
739     /** \name Structors */ //@{
740     GiveObjectToEmpireOrder(int empire, int object_id, int recipient);
741     //@}
742 
743     /** \name Accessors */ //@{
744     /** Returns ID of object selected in this order. */
ObjectID()745     int ObjectID() const
746     { return m_object_id; }
747 
748     /** Returns ID of empire to which object is given. */
RecipientEmpireID()749     int RecipientEmpireID()
750     { return m_recipient_empire_id; }
751     //@}
752 
753     static bool Check(int empire_id, int object_id, int recipient_empire_id);
754 private:
755     GiveObjectToEmpireOrder() = default;
756 
757     /**
758      *  Preconditions:
759      *     - m_object_id must be the ID of an object owned by issuing empire
760      *     - m_recipient_empire_id must be the ID of another empire
761      *
762      *  Postconditions:
763      *     - the object's ownership is set to the other empire
764      */
765     void ExecuteImpl() const override;
766 
767     bool UndoImpl() const override;
768 
769     int m_object_id = INVALID_OBJECT_ID;
770     int m_recipient_empire_id = ALL_EMPIRES;
771 
772     friend class boost::serialization::access;
773     template <typename Archive>
774     void serialize(Archive& ar, const unsigned int version);
775 };
776 
777 /////////////////////////////////////////////////////
778 // ForgetOrder
779 /////////////////////////////////////////////////////
780 /** ForgetOrder removes the object from the empire's known objects. */
781 class FO_COMMON_API ForgetOrder : public Order {
782 public:
783     /** \name Structors */ //@{
784     ForgetOrder(int empire, int object_id);
785     //@}
786 
787     /** \name Accessors */ //@{
788     /** Returns ID of object selected in this order. */
ObjectID()789     int ObjectID() const
790     { return m_object_id; }
791     //@}
792 
793 private:
794     ForgetOrder() = default;
795 
796     /**
797      *  Preconditions:
798      *     - m_object_id must be the ID of an object not owned by issuing empire
799      *
800      *  Postconditions:
801      *     - the object is removed from the table of known objects.
802      */
803     void ExecuteImpl() const override;
804 
805     int m_object_id = INVALID_OBJECT_ID;
806 
807     friend class boost::serialization::access;
808     template <typename Archive>
809     void serialize(Archive& ar, const unsigned int version);
810 };
811 
812 
813 // Note: *::serialize() implemented in SerializeOrderSet.cpp.
814 
815 #endif // _Order_h_
816