1 /* 2 * Copyright (C) 2002-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_LOGIC_MAP_OBJECTS_TRIBES_MILITARYSITE_H 21 #define WL_LOGIC_MAP_OBJECTS_TRIBES_MILITARYSITE_H 22 23 #include <memory> 24 25 #include "base/macros.h" 26 #include "economy/request.h" 27 #include "logic/map_objects/tribes/building.h" 28 #include "logic/map_objects/tribes/requirements.h" 29 #include "logic/map_objects/tribes/soldiercontrol.h" 30 #include "scripting/lua_table.h" 31 32 namespace Widelands { 33 34 // I assume elsewhere, that enum SoldierPreference fits to uint8_t. 35 enum class SoldierPreference : uint8_t { 36 kRookies, 37 kHeroes, 38 }; 39 40 class MilitarySiteDescr : public BuildingDescr { 41 public: 42 MilitarySiteDescr(const std::string& init_descname, const LuaTable& t, const Tribes& tribes); ~MilitarySiteDescr()43 ~MilitarySiteDescr() override { 44 } 45 46 Building& create_object() const override; 47 get_conquers()48 uint32_t get_conquers() const override { 49 return conquer_radius_; 50 } get_max_number_of_soldiers()51 Quantity get_max_number_of_soldiers() const { 52 return num_soldiers_; 53 } get_heal_per_second()54 uint32_t get_heal_per_second() const { 55 return heal_per_second_; 56 } 57 58 bool prefers_heroes_at_start_; 59 std::string occupied_str_; 60 std::string aggressor_str_; 61 std::string attack_str_; 62 std::string defeated_enemy_str_; 63 std::string defeated_you_str_; 64 65 private: 66 uint32_t conquer_radius_; 67 Quantity num_soldiers_; 68 uint32_t heal_per_second_; 69 DISALLOW_COPY_AND_ASSIGN(MilitarySiteDescr); 70 }; 71 72 class MilitarySite : public Building { 73 friend class MapBuildingdataPacket; 74 MO_DESCR(MilitarySiteDescr) 75 76 public: 77 explicit MilitarySite(const MilitarySiteDescr&); 78 ~MilitarySite() override; 79 80 bool init(EditorGameBase&) override; 81 void cleanup(EditorGameBase&) override; 82 void act(Game&, uint32_t data) override; 83 void remove_worker(Worker&) override; 84 85 void set_economy(Economy*, WareWorker) override; 86 bool get_building_work(Game&, Worker&, bool success) override; 87 88 /// Launch the given soldier on an attack towards the given 89 /// target building. 90 void send_attacker(Soldier&, Building&); 91 92 /// This methods are helper for use at configure this site. 93 void set_requirements(const Requirements&); 94 void clear_requirements(); get_requirements()95 const Requirements& get_requirements() const { 96 return soldier_requirements_; 97 } 98 99 void reinit_after_conqueration(Game&); 100 101 void update_soldier_request(bool i = false); 102 103 void set_soldier_preference(SoldierPreference); get_soldier_preference()104 SoldierPreference get_soldier_preference() const { 105 return soldier_preference_; 106 } 107 108 const BuildingSettings* create_building_settings() const override; 109 110 protected: 111 void conquer_area(EditorGameBase&); 112 113 private: 114 void update_statistics_string(std::string*) override; 115 116 bool is_present(Soldier&) const; 117 static void 118 request_soldier_callback(Game&, Request&, DescriptionIndex, Worker*, PlayerImmovable&); 119 120 MapObject* pop_soldier_job(Soldier*, bool* stayhome = nullptr); 121 bool has_soldier_job(Soldier&); 122 bool military_presence_kept(Game&); 123 void notify_player(Game&, bool discovered = false); 124 bool update_upgrade_requirements(); 125 void update_normal_soldier_request(); 126 void update_upgrade_soldier_request(); 127 bool incorporate_upgraded_soldier(EditorGameBase& game, Soldier& s); 128 Soldier* find_least_suited_soldier(); 129 bool drop_least_suited_soldier(bool new_has_arrived, Soldier* s); 130 131 private: 132 // We can be attacked if we have stationed soldiers. 133 class AttackTarget : public Widelands::AttackTarget { 134 public: AttackTarget(MilitarySite * military_site)135 explicit AttackTarget(MilitarySite* military_site) : military_site_(military_site) { 136 } 137 138 bool can_be_attacked() const override; 139 void enemy_soldier_approaches(const Soldier&) const override; 140 Widelands::AttackTarget::AttackResult attack(Soldier*) const override; 141 142 private: 143 MilitarySite* const military_site_; 144 }; 145 146 class SoldierControl : public Widelands::SoldierControl { 147 public: SoldierControl(MilitarySite * military_site)148 explicit SoldierControl(MilitarySite* military_site) : military_site_(military_site) { 149 } 150 151 std::vector<Soldier*> present_soldiers() const override; 152 std::vector<Soldier*> stationed_soldiers() const override; 153 Quantity min_soldier_capacity() const override; 154 Quantity max_soldier_capacity() const override; 155 Quantity soldier_capacity() const override; 156 void set_soldier_capacity(Quantity capacity) override; 157 void drop_soldier(Soldier&) override; 158 int incorporate_soldier(EditorGameBase& game, Soldier& s) override; 159 160 private: 161 MilitarySite* const military_site_; 162 }; 163 164 AttackTarget attack_target_; 165 SoldierControl soldier_control_; 166 Requirements soldier_requirements_; // This is used to grab a bunch of soldiers: Anything goes 167 RequireAttribute soldier_upgrade_requirements_; // This is used when exchanging soldiers. 168 std::unique_ptr<Request> normal_soldier_request_; // filling the site 169 std::unique_ptr<Request> upgrade_soldier_request_; // seeking for better soldiers 170 bool didconquer_; 171 Quantity capacity_; 172 173 /** 174 * Next gametime where we should heal something. 175 */ 176 int32_t nexthealtime_; 177 178 struct SoldierJob { 179 Soldier* soldier; 180 ObjectPointer enemy; 181 bool stayhome; 182 }; 183 std::vector<SoldierJob> soldierjobs_; 184 SoldierPreference soldier_preference_; 185 int32_t next_swap_soldiers_time_; 186 bool soldier_upgrade_try_; // optimization -- if everybody is zero-level, do not downgrade 187 bool doing_upgrade_request_; 188 }; 189 } // namespace Widelands 190 191 #endif // end of include guard: WL_LOGIC_MAP_OBJECTS_TRIBES_MILITARYSITE_H 192