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_TRIBE_DESCR_H
21 #define WL_LOGIC_MAP_OBJECTS_TRIBES_TRIBE_DESCR_H
22 
23 #include <memory>
24 
25 #include "base/macros.h"
26 #include "graphic/animation/animation.h"
27 #include "graphic/toolbar_imageset.h"
28 #include "logic/map_objects/immovable.h"
29 #include "logic/map_objects/tribes/building.h"
30 #include "logic/map_objects/tribes/road_textures.h"
31 #include "logic/map_objects/tribes/tribe_basic_info.h"
32 #include "logic/map_objects/tribes/tribes.h"
33 #include "logic/map_objects/tribes/ware_descr.h"
34 #include "logic/map_objects/tribes/worker.h"
35 #include "logic/widelands.h"
36 
37 namespace Widelands {
38 
39 class ResourceDescription;
40 
41 /*
42  * Resource indicators:
43  * A ResourceIndicatorSet maps the resource name to a ResourceIndicatorList.
44  * A ResourceIndicatorList maps resource amounts to the DescriptionIndex of an immovable this player
45  * uses.
46  * Special case: The ResourceIndicatorList mapped to "" contains resis that will be used in
47  * locations
48  * without resources. If it has several entries, result is arbitrary.
49  */
50 using ResourceIndicatorList = std::map<uint32_t, DescriptionIndex>;
51 using ResourceIndicatorSet = std::map<std::string, ResourceIndicatorList>;
52 
53 /*
54 Tribes
55 ------
56 
57 Every player chooses a tribe. A tribe has distinct properties such as the
58 buildings it can build and the associated graphics.
59 Two players can choose the same tribe.
60 */
61 class TribeDescr {
62 public:
63 	TribeDescr(const LuaTable& table,
64 	           const Widelands::TribeBasicInfo& info,
65 	           const Tribes& init_tribes);
66 
67 	const std::string& name() const;
68 	const std::string& descname() const;
69 
70 	size_t get_nrwares() const;
71 	size_t get_nrworkers() const;
72 
73 	const std::vector<DescriptionIndex>& buildings() const;
74 	const std::set<DescriptionIndex>& wares() const;
75 	const std::set<DescriptionIndex>& workers() const;
76 	const std::set<DescriptionIndex>& immovables() const;
77 	const ResourceIndicatorSet& resource_indicators() const;
78 
79 	bool has_building(const DescriptionIndex& index) const;
80 	bool has_ware(const DescriptionIndex& index) const;
81 	bool has_worker(const DescriptionIndex& index) const;
82 	bool has_immovable(const DescriptionIndex& index) const;
83 
84 	// A ware is a construction material if it appears in a building's buildcost or enhancement cost
85 	bool is_construction_material(const DescriptionIndex& ware_index) const;
86 
87 	DescriptionIndex building_index(const std::string& buildingname) const;
88 	DescriptionIndex immovable_index(const std::string& immovablename) const;
89 	DescriptionIndex ware_index(const std::string& warename) const;
90 	DescriptionIndex worker_index(const std::string& workername) const;
91 
92 	/// Return the given building or die trying
93 	DescriptionIndex safe_building_index(const std::string& buildingname) const;
94 	/// Return the given ware or die trying
95 	DescriptionIndex safe_ware_index(const std::string& warename) const;
96 	/// Return the given worker or die trying
97 	DescriptionIndex safe_worker_index(const std::string& workername) const;
98 
99 	BuildingDescr const* get_building_descr(const DescriptionIndex& index) const;
100 	ImmovableDescr const* get_immovable_descr(const DescriptionIndex& index) const;
101 	WareDescr const* get_ware_descr(const DescriptionIndex& index) const;
102 	WorkerDescr const* get_worker_descr(const DescriptionIndex& index) const;
103 
104 	DescriptionIndex builder() const;
105 	DescriptionIndex carrier() const;
106 	DescriptionIndex carrier2() const;
107 	DescriptionIndex geologist() const;
108 	DescriptionIndex soldier() const;
109 	DescriptionIndex ship() const;
110 	DescriptionIndex ferry() const;
111 	DescriptionIndex port() const;
112 
113 	const std::vector<DescriptionIndex>& trainingsites() const;
114 	const std::vector<DescriptionIndex>& worker_types_without_cost() const;
115 
116 	uint32_t frontier_animation() const;
117 	uint32_t flag_animation() const;
118 	uint32_t bridge_animation(uint8_t dir, bool busy) const;
119 
120 	// Bridge height in pixels at 1x scale, for drawing bobs walking over a bridge
121 	uint32_t bridge_height() const;
122 
123 	// A vector of all texture images that can be used for drawing a
124 	// (normal|busy) road or a waterway. The images are guaranteed to exist.
125 	const std::vector<std::string>& normal_road_paths() const;
126 	const std::vector<std::string>& busy_road_paths() const;
127 	const std::vector<std::string>& waterway_paths() const;
128 
129 	// Add the corresponding texture for roads/waterways.
130 	void add_normal_road_texture(const Image* texture);
131 	void add_busy_road_texture(const Image* texture);
132 	void add_waterway_texture(const Image* texture);
133 
134 	// The road textures used for drawing roads and waterways.
135 	const RoadTextures& road_textures() const;
136 
137 	DescriptionIndex get_resource_indicator(const ResourceDescription* const res,
138 	                                        const ResourceAmount amount) const;
139 
140 	// Returns the initalization at 'index' (which must not be out of bounds).
initialization(const uint8_t index)141 	const Widelands::TribeBasicInfo::Initialization& initialization(const uint8_t index) const {
142 		return initializations_.at(index);
143 	}
144 
145 	using WaresOrder = std::vector<std::vector<Widelands::DescriptionIndex>>;
wares_order()146 	const WaresOrder& wares_order() const {
147 		return wares_order_;
148 	}
149 
workers_order()150 	const WaresOrder& workers_order() const {
151 		return workers_order_;
152 	}
153 
get_ship_names()154 	const std::vector<std::string>& get_ship_names() const {
155 		return ship_names_;
156 	}
157 
158 	/// Registers a building with the tribe
159 	void add_building(const std::string& buildingname);
160 	/// Registers a worker with the tribe and adds it to the bottom of the last worker column
161 	void add_worker(const std::string& workername);
162 
163 	// The custom toolbar imageset if any. Can be nullptr.
164 	ToolbarImageset* toolbar_image_set() const;
165 
166 private:
167 	/// Registers a worker with the tribe and adds it to the bottom of the given worker column
168 	void add_worker(const std::string& workername,
169 	                std::vector<DescriptionIndex>& workers_order_column);
170 
171 	// Helper function for adding a special worker type (carriers etc.)
172 	DescriptionIndex add_special_worker(const std::string& workername);
173 	// Helper function for adding a special building type (port etc.)
174 	DescriptionIndex add_special_building(const std::string& buildingname);
175 	// Helper function to identify special wares across tribes (iron ore etc.)
176 	DescriptionIndex add_special_ware(const std::string& warename);
177 
178 	const std::string name_;
179 	const std::string descname_;
180 	const Tribes& tribes_;
181 
182 	uint32_t frontier_animation_id_;
183 	uint32_t flag_animation_id_;
184 	struct BridgeAnimationIDs {
185 		uint32_t e;
186 		uint32_t se;
187 		uint32_t sw;
188 	};
189 	BridgeAnimationIDs bridges_normal_;
190 	BridgeAnimationIDs bridges_busy_;
191 	uint32_t bridge_height_;
192 	std::vector<std::string> normal_road_paths_;
193 	std::vector<std::string> busy_road_paths_;
194 	std::vector<std::string> waterway_paths_;
195 	RoadTextures road_textures_;
196 
197 	std::vector<DescriptionIndex> buildings_;
198 	std::set<DescriptionIndex> immovables_;  // The player immovables
199 	std::vector<std::string> ship_names_;
200 	std::set<DescriptionIndex> workers_;
201 	std::set<DescriptionIndex> wares_;
202 	ResourceIndicatorSet resource_indicators_;
203 	// The wares that are used by construction sites
204 	std::set<DescriptionIndex> construction_materials_;
205 	// Special units. Some of them are used by the engine, some are only used by the AI.
206 	DescriptionIndex builder_;    // The builder for this tribe
207 	DescriptionIndex carrier_;    // The basic carrier for this tribe
208 	DescriptionIndex carrier2_;   // Additional carrier for busy roads
209 	DescriptionIndex geologist_;  // This tribe's geologist worker
210 	DescriptionIndex soldier_;    // The soldier that this tribe uses
211 	DescriptionIndex ship_;       // The ship that this tribe uses
212 	DescriptionIndex ferry_;      // The ferry that this tribe uses
213 	DescriptionIndex port_;       // The port that this tribe uses
214 	std::vector<DescriptionIndex> worker_types_without_cost_;
215 	std::vector<DescriptionIndex> trainingsites_;
216 	// Order and positioning of wares in the warehouse display
217 	WaresOrder wares_order_;
218 	WaresOrder workers_order_;
219 
220 	// An optional custom imageset for the in-game menu toolbar
221 	std::unique_ptr<ToolbarImageset> toolbar_image_set_;
222 
223 	std::vector<Widelands::TribeBasicInfo::Initialization> initializations_;
224 
225 	DISALLOW_COPY_AND_ASSIGN(TribeDescr);
226 };
227 }  // namespace Widelands
228 
229 #endif  // end of include guard: WL_LOGIC_MAP_OBJECTS_TRIBES_TRIBE_DESCR_H
230