1 /* 2 * Copyright (C) 2011-2020 by the Widelands Development Team 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 * 18 */ 19 20 #ifndef WL_ECONOMY_SHIP_FLEET_H 21 #define WL_ECONOMY_SHIP_FLEET_H 22 23 #include <memory> 24 25 #include "base/macros.h" 26 #include "economy/shipping_schedule.h" 27 #include "logic/map_objects/map_object.h" 28 #include "logic/map_objects/tribes/wareworker.h" 29 #include "logic/path.h" 30 #include "logic/widelands_geometry.h" 31 32 namespace Widelands { 33 34 class Economy; 35 struct Flag; 36 struct RoutingNodeNeighbour; 37 38 class ShipFleetDescr : public MapObjectDescr { 39 public: ShipFleetDescr(char const * const init_name,char const * const init_descname)40 ShipFleetDescr(char const* const init_name, char const* const init_descname) 41 : MapObjectDescr(MapObjectType::SHIP_FLEET, init_name, init_descname, "") { 42 } ~ShipFleetDescr()43 ~ShipFleetDescr() override { 44 } 45 46 private: 47 DISALLOW_COPY_AND_ASSIGN(ShipFleetDescr); 48 }; 49 50 constexpr int32_t kFleetInterval = 4000; 51 constexpr uint32_t kRouteNotCalculated = std::numeric_limits<uint32_t>::max(); 52 53 /** 54 * Manage all ships and ports of a player that are connected 55 * by ocean. 56 * 57 * That is, two ports belong to the same fleet if - and only if - ships can 58 * travel between them, and so on. Players may have several fleets, if they 59 * build ports that cannot communicate (e.g. one port on the ocean, and another 60 * in a lake). 61 * 62 * @paragraph Lifetime 63 * 64 * Fleet objects are created on-the-fly by @ref Ship and @ref PortDock, 65 * and destroy themselves when they become empty. 66 * 67 * The intention is for fleet objects to merge automatically and separate 68 * again in reaction to changes in the map. However, this may not work 69 * properly at the moment. 70 */ 71 struct ShipFleet : MapObject { 72 struct PortPath { 73 int32_t cost; 74 std::shared_ptr<Path> path; 75 PortPathShipFleet::PortPath76 PortPath() : cost(-1) { 77 } 78 }; 79 80 const ShipFleetDescr& descr() const; 81 82 explicit ShipFleet(Player* player); 83 84 PortDock* get_dock(Flag& flag) const; 85 PortDock* get_dock(EditorGameBase&, Coords) const; 86 PortDock* get_arbitrary_dock() const; 87 void set_economy(Economy* e, WareWorker); 88 89 bool active() const; 90 91 bool init(EditorGameBase&) override; 92 void cleanup(EditorGameBase&) override; 93 void update(EditorGameBase&); 94 95 void add_ship(EditorGameBase&, Ship* ship); 96 void remove_ship(EditorGameBase& egbase, Ship* ship); 97 void add_port(EditorGameBase& egbase, PortDock* port); 98 void remove_port(EditorGameBase& egbase, PortDock* port); 99 bool has_ports() const; 100 101 void log_general_info(const EditorGameBase&) const override; 102 103 bool get_path(const PortDock& start, const PortDock& end, Path& path); 104 void add_neighbours(PortDock& pd, std::vector<RoutingNodeNeighbour>& neighbours); 105 106 uint32_t count_ships() const; 107 uint32_t count_ports() const; 108 bool get_act_pending() const; 109 110 bool empty() const; 111 get_scheduleShipFleet112 ShippingSchedule& get_schedule() { 113 return schedule_; 114 } 115 get_shipsShipFleet116 std::vector<Ship*>& get_ships() { 117 return ships_; 118 } get_portsShipFleet119 std::vector<PortDock*>& get_ports() { 120 return ports_; 121 } 122 123 protected: 124 void act(Game&, uint32_t data) override; 125 126 private: 127 bool find_other_fleet(EditorGameBase& egbase); 128 bool merge(EditorGameBase& egbase, ShipFleet* other); 129 void check_merge_economy(); 130 void connect_port(EditorGameBase& egbase, uint32_t idx); 131 132 PortPath& portpath(uint32_t i, uint32_t j); 133 const PortPath& portpath(uint32_t i, uint32_t j) const; 134 PortPath& portpath_bidir(uint32_t i, uint32_t j, bool& reverse); 135 const PortPath& portpath_bidir(uint32_t i, uint32_t j, bool& reverse) const; 136 137 std::vector<Ship*> ships_; 138 std::vector<PortDock*> ports_; 139 140 bool act_pending_; 141 142 /** 143 * Store all pairs shortest paths between port docks 144 * 145 * Let i < j, then the path from ports_[i] to ports_[j] is stored in 146 * portpaths_[binom(j,2) + i] 147 */ 148 std::vector<PortPath> portpaths_; 149 150 ShippingSchedule schedule_; 151 152 // saving and loading 153 protected: 154 struct Loader : MapObject::Loader { 155 Loader(); 156 157 void load(FileRead&); 158 void load_pointers() override; 159 void load_finish() override; 160 161 uint8_t packet_version_; 162 163 private: 164 std::vector<uint32_t> ships_; 165 std::vector<uint32_t> ports_; 166 }; 167 168 public: has_new_save_supportShipFleet169 bool has_new_save_support() override { 170 return true; 171 } 172 void save(EditorGameBase&, MapObjectSaver&, FileWrite&) override; 173 174 static MapObject::Loader* load(EditorGameBase&, MapObjectLoader&, FileRead&); 175 }; 176 177 } // namespace Widelands 178 179 #endif // end of include guard: WL_ECONOMY_SHIP_FLEET_H 180