1 #ifndef _Fleet_h_
2 #define _Fleet_h_
3 
4 #include "UniverseObject.h"
5 #include "ObjectMap.h"
6 #include "../util/Export.h"
7 
8 #include <boost/serialization/version.hpp>
9 
10 ////////////////////////////////////////////////
11 // MovePathNode
12 ////////////////////////////////////////////////
13 /** Contains info about a single notable point on the move path of a fleet or
14   * other UniverseObject. */
15 struct MovePathNode {
16     MovePathNode(double x_, double y_, bool turn_end_, int eta_, int id_, int lane_start_id_, int lane_end_id_, bool post_blockade_ = false) :
xMovePathNode17     x(x_), y(y_), turn_end(turn_end_), eta(eta_), object_id(id_), lane_start_id(lane_start_id_), lane_end_id(lane_end_id_), post_blockade(post_blockade_)
18     {}
19     double  x, y;           ///< location in Universe of node
20     bool    turn_end;       ///< true if the fleet will end a turn at this point
21     int     eta;            ///< estimated turns to reach this node
22     int     object_id;      ///< id of object (most likely a system) located at this node, or INVALID_OBJECT_ID if there is no object here
23     int     lane_start_id;  ///< id of object (most likely a system) at the start of the starlane on which this MovePathNode is located, or INVALID_OBJECT_ID if not on a starlane
24     int     lane_end_id;    ///< id of object (most likely a system) at the end of the starlane on which this MovePathNode is located, or INVALID_OBJECT_ID if not on a starlane
25     bool    post_blockade;  ///< estimation of whether this node is past a blockade for the subject fleet
26 };
27 
28 /** Encapsulates data for a FreeOrion fleet.  Fleets are basically a group of
29   * ships that travel together. */
30 class FO_COMMON_API Fleet : public UniverseObject {
31 public:
32     /** \name Accessors */ //@{
33     bool HostileToEmpire(int empire_id) const override;
34 
35     UniverseObjectType ObjectType() const override;
36 
37     std::string Dump(unsigned short ntabs = 0) const override;
38 
39     int ContainerObjectID() const override;
40 
41     const std::set<int>& ContainedObjectIDs() const override;
42 
43     bool Contains(int object_id) const override;
44 
45     bool ContainedBy(int object_id) const override;
46 
47     const std::string& PublicName(int empire_id) const override;
48 
49     std::shared_ptr<UniverseObject>Accept(const UniverseObjectVisitor& visitor) const override;
50 
ShipIDs()51     const std::set<int>&                ShipIDs() const     { return m_ships; }         ///< returns set of IDs of ships in fleet.
52     int                                 MaxShipAgeInTurns() const;                      ///< Returns the age of the oldest ship in the fleet
53 
54     /** Returns the list of systems that this fleet will move through en route
55       * to its destination (may be empty).  If this fleet is currently at a
56       * system, that system will be the first one in the list. */
57     const std::list<int>&               TravelRoute() const;
58 
OrderedGivenToEmpire()59     int                                 OrderedGivenToEmpire() const    { return m_ordered_given_to_empire_id; }///< returns the ID of the empire this fleet has been ordered given to, or ALL_EMPIRES if this fleet hasn't been ordered given to an empire
60 
Aggressive()61     bool                                Aggressive() const  { return m_aggressive; }
62 
63     /** Returns a list of locations at which notable events will occur along the fleet's path if it follows the
64         specified route.  It is assumed in the calculation that the fleet starts its move path at its actual current
65         location, however the fleet's current location will not be on the list, even if it is currently in a system. */
66     std::list<MovePathNode>             MovePath(const std::list<int>& route, bool flag_blockades = false) const;
67     std::list<MovePathNode>             MovePath(bool flag_blockades = false) const;            ///< Returns MovePath for fleet's current TravelRoute
68     std::pair<int, int>                 ETA() const;                                            ///< Returns the number of turns which must elapse before the fleet arrives at its current final destination and the turns to the next system, respectively.
69     std::pair<int, int>                 ETA(const std::list<MovePathNode>& move_path) const;    ///< Returns the number of turns which must elapse before the fleet arrives at the final destination and next system in the spepcified \a move_path
70 
71     float   Damage() const;                     ///< Returns total amount of damage this fleet has, which is the sum of the ships' damage
72     float   Structure() const;                  ///< Returns total amount of structure this fleet has, which is the sum of the ships' structure
73     float   Shields() const;                    ///< Returns total amount of shields this fleet has, which is the sum of the ships' shields
74     float   Fuel() const;                       ///< Returns effective amount of fuel this fleet has, which is the least of the amounts of fuel that the ships have
75     float   MaxFuel() const;                    ///< Returns effective maximum amount of fuel this fleet has, which is the least of the max amounts of fuel that the ships can have
76     int     FinalDestinationID() const;         ///< Returns ID of system that this fleet is moving to or INVALID_OBJECT_ID if staying still.
PreviousSystemID()77     int     PreviousSystemID() const    { return m_prev_system; }               ///< Returns ID of system that this fleet is moving away from as it moves to its destination.
NextSystemID()78     int     NextSystemID() const        { return m_next_system; }               ///< Returns ID of system that this fleet is moving to next as it moves to its destination.
79     bool    Blockaded() const;                  ///< returns true iff either (i) fleet is stationary and at least one system exit is blocked for this fleet or (ii) fleet is attempting to depart a system along a blocked system exit
80     bool    BlockadedAtSystem(int start_system_id, int dest_system_id) const;   ///< returns true iff this fleet's movement would be blockaded at system.
81     float   Speed() const;                      ///< Returns speed of fleet. (Should be equal to speed of slowest ship in fleet, unless in future the calculation of fleet speed changes.)
CanChangeDirectionEnRoute()82     bool    CanChangeDirectionEnRoute() const   { return false; }               ///< Returns true iff this fleet can change its direction while in interstellar space.
83     bool    HasMonsters() const;                ///< returns true iff this fleet contains monster ships.
84     bool    HasArmedShips() const;              ///< Returns true if there is at least one armed ship in the fleet, meaning it has direct fire weapons or fighters that can be launched and that do damage
85     bool    HasFighterShips() const;            ///< Returns true if there is at least one ship with fighters in the fleet.
86     bool    HasColonyShips() const;             ///< Returns true if there is at least one colony ship with nonzero capacity in the fleet.
87     bool    HasOutpostShips() const;            ///< Returns true if there is at least one colony ship with zero capacity in the fleet
88     bool    HasTroopShips() const;              ///< Returns true if there is at least one troop ship in the fleet.
89     bool    HasShipsOrderedScrapped() const;    ///< Returns true if there is at least one ship ordered scrapped in the fleet.
90     bool    HasShipsWithoutScrapOrders() const; ///< Returns true if there is at least one ship without any scrap orders in the fleet.
NumShips()91     int     NumShips() const            { return m_ships.size(); }  ///< Returns number of ships in fleet.
Empty()92     bool    Empty() const               { return m_ships.empty(); } ///< Returns true if fleet contains no ships, false otherwise.
93     float   ResourceOutput(ResourceType type) const;
94 
95     /** Returns true iff this fleet is moving, but the route is unknown.  This
96       * is usually the case when a foreign player A's fleet is represented on
97       * another player B's client, and player B has never seen one or more of
98       * the systems in the fleet's route. */
99     bool UnknownRoute() const;
100 
101     /** Returns true iff this fleet arrived at its current System this turn. */
ArrivedThisTurn()102     bool ArrivedThisTurn() const { return m_arrived_this_turn; }
103 
104     /** Has two primary uses: orientation in tactical combat, and determination of starlane blockade restrictions.
105      * Returns the ID of the starlane that this fleet arrived on, if it arrived into a blockade which is not yet broken.
106      * If in a system and not blockaded, the value is the current system ID. The blockade intent is that you can't
107      * break a blockade unless you beat the blockaders (via combat or they retreat).**/
ArrivalStarlane()108     int ArrivalStarlane() const { return m_arrival_starlane; }
109     //@}
110 
111     /** \name Mutators */ //@{
112     void Copy(std::shared_ptr<const UniverseObject> copied_object, int empire_id = ALL_EMPIRES) override;
113 
114     void MovementPhase() override;
115 
116     void ResetTargetMaxUnpairedMeters() override;
117 
118     void SetRoute(const std::list<int>& route);             ///< sets this fleet to move through the series of systems in the list, in order
119     void CalculateRouteTo(int target_system_id);            ///< sets this fleet to move through the series of systems that makes the shortest path from its current location to target_system_id
120 
121     void SetAggressive(bool aggressive = true);             ///< sets this fleet to be agressive (true) or passive (false)
122 
123     void AddShips(const std::vector<int>& ship_ids);        ///< adds the ships to the fleet
124     void RemoveShips(const std::vector<int>& ship_ids);     ///< removes the ships from the fleet.
125 
126     void SetNextAndPreviousSystems(int next, int prev);     ///< sets the previous and next systems for this fleet.  Useful after moving a moving fleet to a different location, so that it moves along its new local starlanes
SetArrivalStarlane(int starlane)127     void SetArrivalStarlane(int starlane) { m_arrival_starlane = starlane; }///< sets the arrival starlane, used to clear blockaded status after combat
ClearArrivalFlag()128     void ClearArrivalFlag() { m_arrived_this_turn = false; }///< used to clear the m_arrived_this_turn flag, prior to any fleets moving, for accurate blockade tests
129 
130     void SetGiveToEmpire(int empire_id);                    ///< marks fleet to be given to empire
131     void ClearGiveToEmpire();                               ///< marks fleet not to be given to any empire
132     //@}
133 
134     /* returns a name for a fleet based on its ships*/
135     std::string GenerateFleetName();
136 
137     static const int ETA_NEVER;                             ///< returned by ETA when fleet can't reach destination due to lack of route or inability to move
138     static const int ETA_UNKNOWN;                           ///< returned when ETA can't be determined
139     static const int ETA_OUT_OF_RANGE;                      ///< returned by ETA when fleet can't reach destination due to insufficient fuel capacity and lack of fleet resupply on route
140 
141 protected:
142     friend class Universe;
143     friend class ObjectMap;
144 
145     /** \name Structors */ //@{
Fleet()146     Fleet() {}
147 
148 public:
149     Fleet(const std::string& name, double x, double y, int owner);      ///< general ctor taking name, position and owner id
150 
151 protected:
152     template <typename T> friend void boost::python::detail::value_destroyer<false>::execute(T const volatile* p);
153 
154 public:
~Fleet()155     ~Fleet() {}
156 
157 protected:
158     /** Returns new copy of this Fleet. */
159     Fleet* Clone(int empire_id = ALL_EMPIRES) const override;
160     //@}
161 
162 private:
163     std::set<int>               m_ships;
164 
165     // these two uniquely describe the starlane graph edge the fleet is on, if it it's on one
166     int                         m_prev_system = INVALID_OBJECT_ID;  ///< the previous system in the route, if any
167     int                         m_next_system = INVALID_OBJECT_ID;  ///< the next system in the route, if any
168 
169     bool                        m_aggressive = true;    ///< should this fleet attack enemies in the same system?
170 
171     int                         m_ordered_given_to_empire_id = ALL_EMPIRES;
172 
173     /** list of systems on travel route of fleet from current position to
174       * destination.  If the fleet is currently in a system, that will be the
175       * first system on the list.  Otherwise, the first system on the list will
176       * be the next system the fleet will reach along its path.  The list may
177       * also contain a single null pointer, which indicates that the route is
178       * unknown.  The list may also be empty, which indicates that the fleet
179       * is not planning to move. */
180     std::list<int>              m_travel_route;
181 
182     bool                        m_arrived_this_turn = false;
183     int                         m_arrival_starlane = INVALID_OBJECT_ID; // see comment for ArrivalStarlane()
184 
185     friend class boost::serialization::access;
186     template <typename Archive>
187     void serialize(Archive& ar, const unsigned int version);
188 };
189 
190 #endif // _Fleet_h_
191