1 /*
2  * Copyright (C) 2006-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 #include "scripting/lua_map.h"
21 
22 #include "base/log.h"
23 #include "base/macros.h"
24 #include "base/wexception.h"
25 #include "economy/input_queue.h"
26 #include "logic/map_objects/checkstep.h"
27 #include "logic/map_objects/findimmovable.h"
28 #include "logic/map_objects/immovable.h"
29 #include "logic/map_objects/terrain_affinity.h"
30 #include "logic/map_objects/tribes/carrier.h"
31 #include "logic/map_objects/tribes/market.h"
32 #include "logic/map_objects/tribes/ship.h"
33 #include "logic/map_objects/tribes/soldier.h"
34 #include "logic/map_objects/tribes/tribe_basic_info.h"
35 #include "logic/map_objects/tribes/tribes.h"
36 #include "logic/map_objects/tribes/warelist.h"
37 #include "logic/map_objects/world/editor_category.h"
38 #include "logic/map_objects/world/resource_description.h"
39 #include "logic/map_objects/world/terrain_description.h"
40 #include "logic/map_objects/world/world.h"
41 #include "logic/maphollowregion.h"
42 #include "logic/mapregion.h"
43 #include "logic/player.h"
44 #include "logic/widelands_geometry.h"
45 #include "scripting/factory.h"
46 #include "scripting/globals.h"
47 #include "scripting/lua_errors.h"
48 #include "scripting/lua_game.h"
49 #include "wui/mapviewpixelfunctions.h"
50 
51 using namespace Widelands;
52 
53 namespace LuaMaps {
54 
55 /* RST
56 :mod:`wl.map`
57 =============
58 
59 .. module:: wl.map
60    :synopsis: Provides access to Fields and Objects on the map
61 
62 .. moduleauthor:: The Widelands development team
63 
64 .. currentmodule:: wl.map
65 
66 */
67 
68 namespace {
69 
70 // Checks if a field has the desired caps
check_has_caps(lua_State * L,const std::string & query,const FCoords & f,const NodeCaps & caps,const Widelands::Map & map)71 bool check_has_caps(lua_State* L,
72                     const std::string& query,
73                     const FCoords& f,
74                     const NodeCaps& caps,
75                     const Widelands::Map& map) {
76 	if (query == "walkable") {
77 		return caps & MOVECAPS_WALK;
78 	}
79 	if (query == "swimmable") {
80 		return caps & MOVECAPS_SWIM;
81 	}
82 	if (query == "small") {
83 		return caps & BUILDCAPS_SMALL;
84 	}
85 	if (query == "medium") {
86 		return caps & BUILDCAPS_MEDIUM;
87 	}
88 	if (query == "big") {
89 		return (caps & BUILDCAPS_BIG) == BUILDCAPS_BIG;
90 	}
91 	if (query == "port") {
92 		return (caps & BUILDCAPS_PORT) && map.is_port_space(f);
93 	}
94 	if (query == "mine") {
95 		return caps & BUILDCAPS_MINE;
96 	}
97 	if (query == "flag") {
98 		return caps & BUILDCAPS_FLAG;
99 	}
100 	report_error(L, "Unknown caps queried: %s!", query.c_str());
101 }
102 
103 // Pushes a lua table with (name, count) pairs for the given 'ware_amount_container' on the
104 // stack. The 'type' needs to be WARE or WORKER. Returns 1.
wares_or_workers_map_to_lua(lua_State * L,const Buildcost & ware_amount_map,MapObjectType type)105 int wares_or_workers_map_to_lua(lua_State* L,
106                                 const Buildcost& ware_amount_map,
107                                 MapObjectType type) {
108 	lua_newtable(L);
109 	for (const auto& ware_amount : ware_amount_map) {
110 		switch (type) {
111 		case MapObjectType::WORKER:
112 			lua_pushstring(L, get_egbase(L).tribes().get_worker_descr(ware_amount.first)->name());
113 			break;
114 		case MapObjectType::WARE:
115 			lua_pushstring(L, get_egbase(L).tribes().get_ware_descr(ware_amount.first)->name());
116 			break;
117 		default:
118 			throw wexception("wares_or_workers_map_to_lua needs a ware or worker");
119 		}
120 		lua_pushuint32(L, ware_amount.second);
121 		lua_settable(L, -3);
122 	}
123 	return 1;
124 }
125 
126 // Pushes a lua table of tables with food ware names on the stack. Returns 1.
127 // Resulting table will look e.g. like {{"barbarians_bread"}, {"fish", "meat"}}
food_list_to_lua(lua_State * L,const std::vector<std::vector<std::string>> & table)128 int food_list_to_lua(lua_State* L, const std::vector<std::vector<std::string>>& table) {
129 	lua_newtable(L);
130 	int counter = 0;
131 	for (const std::vector<std::string>& foodlist : table) {
132 		lua_pushuint32(L, ++counter);
133 		lua_newtable(L);
134 		int counter2 = 0;
135 		for (const std::string& foodname : foodlist) {
136 			lua_pushuint32(L, ++counter2);
137 			lua_pushstring(L, foodname);
138 			lua_settable(L, -3);
139 		}
140 		lua_settable(L, -3);
141 	}
142 	return 1;
143 }
144 
145 struct SoldierMapDescr {
SoldierMapDescrLuaMaps::__anon101ba5a60111::SoldierMapDescr146 	SoldierMapDescr(uint8_t init_health,
147 	                uint8_t init_attack,
148 	                uint8_t init_defense,
149 	                uint8_t init_evade)
150 	   : health(init_health), attack(init_attack), defense(init_defense), evade(init_evade) {
151 	}
SoldierMapDescrLuaMaps::__anon101ba5a60111::SoldierMapDescr152 	SoldierMapDescr() : health(0), attack(0), defense(0), evade(0) {
153 	}
154 
155 	uint8_t health;
156 	uint8_t attack;
157 	uint8_t defense;
158 	uint8_t evade;
159 
operator <LuaMaps::__anon101ba5a60111::SoldierMapDescr160 	bool operator<(const SoldierMapDescr& ot) const {
161 		bool equal_health = health == ot.health;
162 		bool equal_attack = attack == ot.attack;
163 		bool equal_defense = defense == ot.defense;
164 		if (equal_health && equal_attack && equal_defense) {
165 			return evade < ot.evade;
166 		}
167 		if (equal_health && equal_attack) {
168 			return defense < ot.defense;
169 		}
170 		if (equal_health) {
171 			return attack < ot.attack;
172 		}
173 		return health < ot.health;
174 	}
operator ==LuaMaps::__anon101ba5a60111::SoldierMapDescr175 	bool operator==(const SoldierMapDescr& ot) const {
176 		if (health == ot.health && attack == ot.attack && defense == ot.defense &&
177 		    evade == ot.evade) {
178 			return true;
179 		}
180 		return false;
181 	}
182 };
183 
184 using SoldiersMap = std::map<SoldierMapDescr, Widelands::Quantity>;
185 using WaresWorkersMap = std::map<Widelands::DescriptionIndex, Widelands::Quantity>;
186 using SoldierAmount = std::pair<SoldierMapDescr, Widelands::Quantity>;
187 using WorkerAmount = std::pair<Widelands::DescriptionIndex, Widelands::Quantity>;
188 using PlrInfluence = std::pair<Widelands::PlayerNumber, Widelands::MilitaryInfluence>;
189 using WaresSet = std::set<Widelands::DescriptionIndex>;
190 using InputSet = std::set<std::pair<Widelands::DescriptionIndex, Widelands::WareWorker>>;
191 using WorkersSet = std::set<Widelands::DescriptionIndex>;
192 using SoldiersList = std::vector<Widelands::Soldier*>;
193 
194 // Versions of the above macros which accept wares and workers
parse_get_input_arguments(lua_State * L,const TribeDescr & tribe,bool * return_number)195 InputSet parse_get_input_arguments(lua_State* L, const TribeDescr& tribe, bool* return_number) {
196 	/* takes either "all", a name or an array of names */
197 	int32_t nargs = lua_gettop(L);
198 	if (nargs != 2) {
199 		report_error(L, "Wrong number of arguments to get_inputs!");
200 	}
201 	*return_number = false;
202 	InputSet rv;
203 	if (lua_isstring(L, 2)) {
204 		std::string what = luaL_checkstring(L, -1);
205 		if (what == "all") {
206 			for (const DescriptionIndex& i : tribe.wares()) {
207 				rv.insert(std::make_pair(i, wwWARE));
208 			}
209 			for (const DescriptionIndex& i : tribe.workers()) {
210 				rv.insert(std::make_pair(i, wwWORKER));
211 			}
212 		} else {
213 			/* Only one item requested */
214 			DescriptionIndex index = tribe.ware_index(what);
215 			if (tribe.has_ware(index)) {
216 				rv.insert(std::make_pair(index, wwWARE));
217 				*return_number = true;
218 			} else {
219 				index = tribe.worker_index(what);
220 				if (tribe.has_worker(index)) {
221 					rv.insert(std::make_pair(index, wwWORKER));
222 					*return_number = true;
223 				} else {
224 					report_error(L, "Invalid input: <%s>", what.c_str());
225 				}
226 			}
227 		}
228 	} else {
229 		/* array of names */
230 		luaL_checktype(L, 2, LUA_TTABLE);
231 		lua_pushnil(L);
232 		while (lua_next(L, 2) != 0) {
233 			std::string what = luaL_checkstring(L, -1);
234 			DescriptionIndex index = tribe.ware_index(what);
235 			if (tribe.has_ware(index)) {
236 				rv.insert(std::make_pair(index, wwWARE));
237 			} else {
238 				index = tribe.worker_index(what);
239 				if (tribe.has_worker(index)) {
240 					rv.insert(std::make_pair(index, wwWORKER));
241 				} else {
242 					report_error(L, "Invalid input: <%s>", what.c_str());
243 				}
244 			}
245 			lua_pop(L, 1);
246 		}
247 	}
248 	return rv;
249 }
250 
parse_set_input_arguments(lua_State * L,const TribeDescr & tribe)251 InputMap parse_set_input_arguments(lua_State* L, const TribeDescr& tribe) {
252 	int32_t nargs = lua_gettop(L);
253 	if (nargs != 2 && nargs != 3) {
254 		report_error(L, "Wrong number of arguments to set_inputs!");
255 	}
256 	InputMap rv;
257 	if (nargs == 3) {
258 		/* name amount */
259 		std::string what = luaL_checkstring(L, 2);
260 		DescriptionIndex index = tribe.ware_index(what);
261 		if (tribe.has_ware(index)) {
262 			rv.insert(std::make_pair(std::make_pair(index, wwWARE), luaL_checkuint32(L, 3)));
263 		} else {
264 			index = tribe.worker_index(what);
265 			if (tribe.has_worker(index)) {
266 				rv.insert(std::make_pair(std::make_pair(index, wwWORKER), luaL_checkuint32(L, 3)));
267 			} else {
268 				report_error(L, "Invalid input: <%s>", what.c_str());
269 			}
270 		}
271 	} else {
272 		/* array of (name, count) */
273 		luaL_checktype(L, 2, LUA_TTABLE);
274 		lua_pushnil(L);
275 		while (lua_next(L, 2) != 0) {
276 			std::string what = luaL_checkstring(L, -2);
277 			DescriptionIndex index = tribe.ware_index(what);
278 			if (tribe.has_ware(index)) {
279 				rv.insert(std::make_pair(std::make_pair(index, wwWARE), luaL_checkuint32(L, -1)));
280 			} else {
281 				index = tribe.worker_index(what);
282 				if (tribe.has_worker(index)) {
283 					rv.insert(std::make_pair(std::make_pair(index, wwWORKER), luaL_checkuint32(L, -1)));
284 				} else {
285 					report_error(L, "Invalid input: <%s>", what.c_str());
286 				}
287 			}
288 			lua_pop(L, 1);
289 		}
290 	}
291 	return rv;
292 }
293 
count_wares_on_flag_(Flag & f,const Tribes & tribes)294 WaresWorkersMap count_wares_on_flag_(Flag& f, const Tribes& tribes) {
295 	WaresWorkersMap rv;
296 
297 	for (const WareInstance* ware : f.get_wares()) {
298 		DescriptionIndex i = tribes.ware_index(ware->descr().name());
299 		if (!rv.count(i)) {
300 			rv.insert(Widelands::WareAmount(i, 1));
301 		} else {
302 			++rv[i];
303 		}
304 	}
305 	return rv;
306 }
307 
308 // Sort functor to sort the owners claiming a field by their influence.
sort_claimers(const PlrInfluence & first,const PlrInfluence & second)309 static int sort_claimers(const PlrInfluence& first, const PlrInfluence& second) {
310 	return first.second > second.second;
311 }
312 
313 // Return the valid workers for a Road.
get_valid_workers_for(const RoadBase & r)314 WaresWorkersMap get_valid_workers_for(const RoadBase& r) {
315 	WaresWorkersMap valid_workers;
316 	if (r.descr().type() == MapObjectType::WATERWAY) {
317 		valid_workers.insert(WorkerAmount(r.owner().tribe().ferry(), 1));
318 	} else {
319 		valid_workers.insert(WorkerAmount(r.owner().tribe().carrier(), 1));
320 		upcast(const Road, road, &r);
321 		assert(road);
322 		if (road->is_busy()) {
323 			valid_workers.insert(WorkerAmount(r.owner().tribe().carrier2(), 1));
324 		}
325 	}
326 
327 	return valid_workers;
328 }
329 
330 // Returns the valid workers allowed in 'pi'.
get_valid_workers_for(const ProductionSite & ps)331 WaresWorkersMap get_valid_workers_for(const ProductionSite& ps) {
332 	WaresWorkersMap rv;
333 	for (const auto& item : ps.descr().working_positions()) {
334 		rv.insert(WorkerAmount(item.first, item.second));
335 	}
336 	return rv;
337 }
338 
339 // Translate the given Workers map into a (string, count) Lua table.
workers_map_to_lua(lua_State * L,const WaresWorkersMap & valid_workers)340 int workers_map_to_lua(lua_State* L, const WaresWorkersMap& valid_workers) {
341 	lua_newtable(L);
342 	for (const WaresWorkersMap::value_type& item : valid_workers) {
343 		lua_pushstring(L, get_egbase(L).tribes().get_worker_descr(item.first)->name());
344 		lua_pushuint32(L, item.second);
345 		lua_rawset(L, -3);
346 	}
347 	return 1;
348 }
349 
350 // Does most of the work of get_workers for player immovables (buildings and roads mainly).
do_get_workers(lua_State * L,const PlayerImmovable & pi,const WaresWorkersMap & valid_workers)351 int do_get_workers(lua_State* L, const PlayerImmovable& pi, const WaresWorkersMap& valid_workers) {
352 	const TribeDescr& tribe = pi.owner().tribe();
353 
354 	DescriptionIndex worker_index = INVALID_INDEX;
355 	std::vector<DescriptionIndex> workers_list;
356 
357 	RequestedWareWorker parse_output =
358 	   parse_wares_workers_list(L, tribe, &worker_index, &workers_list, false);
359 
360 	// c_workers is map (index:count) of all workers at the immovable
361 	WaresWorkersMap c_workers;
362 	for (const Worker* w : pi.get_workers()) {
363 		DescriptionIndex i = tribe.worker_index(w->descr().name());
364 		if (!c_workers.count(i)) {
365 			c_workers.insert(WorkerAmount(i, 1));
366 		} else {
367 			++c_workers[i];
368 		}
369 	}
370 
371 	// We return quantity for asked worker
372 	if (worker_index != INVALID_INDEX) {
373 		if (c_workers.count(worker_index)) {
374 			lua_pushuint32(L, c_workers[worker_index]);
375 		} else {
376 			lua_pushuint32(L, 0);
377 		}
378 	} else {
379 		// or array of worker:quantity
380 		if (parse_output == RequestedWareWorker::kAll) {  // 'all' was required, otherwise we return
381 			                                               // only asked workers
382 			workers_list.clear();
383 			for (const WaresWorkersMap::value_type& v : valid_workers) {
384 				workers_list.push_back(v.first);
385 			}
386 		}
387 		lua_newtable(L);
388 		for (const DescriptionIndex& i : workers_list) {
389 			Widelands::Quantity cnt = 0;
390 			if (c_workers.count(i)) {
391 				cnt = c_workers[i];
392 			}
393 			lua_pushstring(L, tribe.get_worker_descr(i)->name());
394 			lua_pushuint32(L, cnt);
395 			lua_settable(L, -3);
396 		}
397 	}
398 	return 1;
399 }
400 
401 // Does most of the work of set_workers for player immovables (buildings and roads mainly).
402 template <typename T>
do_set_workers(lua_State * L,PlayerImmovable * pi,const WaresWorkersMap & valid_workers)403 int do_set_workers(lua_State* L, PlayerImmovable* pi, const WaresWorkersMap& valid_workers) {
404 	EditorGameBase& egbase = get_egbase(L);
405 	const TribeDescr& tribe = pi->owner().tribe();
406 
407 	// setpoints is map of index:quantity
408 	InputMap setpoints;
409 	parse_wares_workers_counted(L, tribe, &setpoints, false);
410 
411 	// c_workers is actual statistics, the map index:quantity
412 	WaresWorkersMap c_workers;
413 	for (const Worker* w : pi->get_workers()) {
414 		DescriptionIndex i = tribe.worker_index(w->descr().name());
415 		if (!valid_workers.count(i)) {
416 			// Ignore workers that will be consumed as inputs
417 			continue;
418 		}
419 		if (!c_workers.count(i)) {
420 			c_workers.insert(WorkerAmount(i, 1));
421 		} else {
422 			++c_workers[i];
423 		}
424 		if (!setpoints.count(std::make_pair(i, Widelands::WareWorker::wwWORKER))) {
425 			setpoints.insert(std::make_pair(std::make_pair(i, Widelands::WareWorker::wwWORKER), 0));
426 		}
427 	}
428 
429 	// The idea is to change as little as possible
430 	for (const auto& sp : setpoints) {
431 		const Widelands::DescriptionIndex& index = sp.first.first;
432 		const WorkerDescr* wdes = tribe.get_worker_descr(index);
433 		if (sp.second != 0 && !valid_workers.count(index)) {
434 			report_error(L, "<%s> can't be employed here!", wdes->name().c_str());
435 		}
436 
437 		Widelands::Quantity cur = 0;
438 		WaresWorkersMap::iterator i = c_workers.find(index);
439 		if (i != c_workers.end()) {
440 			cur = i->second;
441 		}
442 
443 		int d = sp.second - cur;
444 		if (d < 0) {
445 			while (d) {
446 				for (const Worker* w : pi->get_workers()) {
447 					if (tribe.worker_index(w->descr().name()) == index) {
448 						const_cast<Worker*>(w)->remove(egbase);
449 						++d;
450 						break;
451 					}
452 				}
453 			}
454 		} else if (d > 0) {
455 			for (; d; --d) {
456 				if (T::create_new_worker(*pi, egbase, wdes)) {
457 					report_error(L, "No space left for this worker");
458 				}
459 			}
460 		}
461 	}
462 	return 0;
463 }
464 
465 // Unpacks the Lua table of the form {health, attack, defense, evade} at the stack index
466 // 'table_index' into a SoldierMapDescr struct.
467 SoldierMapDescr
unbox_lua_soldier_description(lua_State * L,int table_index,const SoldierDescr & sd)468 unbox_lua_soldier_description(lua_State* L, int table_index, const SoldierDescr& sd) {
469 	SoldierMapDescr soldier_descr;
470 
471 	lua_pushuint32(L, 1);
472 	lua_rawget(L, table_index);
473 	soldier_descr.health = luaL_checkuint32(L, -1);
474 	lua_pop(L, 1);
475 	if (soldier_descr.health > sd.get_max_health_level()) {
476 		report_error(L, "health level (%i) > max health level (%i)", soldier_descr.health,
477 		             sd.get_max_health_level());
478 	}
479 
480 	lua_pushuint32(L, 2);
481 	lua_rawget(L, table_index);
482 	soldier_descr.attack = luaL_checkuint32(L, -1);
483 	lua_pop(L, 1);
484 	if (soldier_descr.attack > sd.get_max_attack_level()) {
485 		report_error(L, "attack level (%i) > max attack level (%i)", soldier_descr.attack,
486 		             sd.get_max_attack_level());
487 	}
488 
489 	lua_pushuint32(L, 3);
490 	lua_rawget(L, table_index);
491 	soldier_descr.defense = luaL_checkuint32(L, -1);
492 	lua_pop(L, 1);
493 	if (soldier_descr.defense > sd.get_max_defense_level()) {
494 		report_error(L, "defense level (%i) > max defense level (%i)", soldier_descr.defense,
495 		             sd.get_max_defense_level());
496 	}
497 
498 	lua_pushuint32(L, 4);
499 	lua_rawget(L, table_index);
500 	soldier_descr.evade = luaL_checkuint32(L, -1);
501 	lua_pop(L, 1);
502 	if (soldier_descr.evade > sd.get_max_evade_level()) {
503 		report_error(L, "evade level (%i) > max evade level (%i)", soldier_descr.evade,
504 		             sd.get_max_evade_level());
505 	}
506 
507 	return soldier_descr;
508 }
509 
510 // Parser the arguments of set_soldiers() into a setpoint. See the
511 // documentation in HasSoldiers to understand the valid arguments.
parse_set_soldiers_arguments(lua_State * L,const SoldierDescr & soldier_descr)512 SoldiersMap parse_set_soldiers_arguments(lua_State* L, const SoldierDescr& soldier_descr) {
513 	SoldiersMap rv;
514 	if (lua_gettop(L) > 2) {
515 		// STACK: cls, descr, count
516 		const Widelands::Quantity count = luaL_checkuint32(L, 3);
517 		const SoldierMapDescr d = unbox_lua_soldier_description(L, 2, soldier_descr);
518 		rv.insert(SoldierAmount(d, count));
519 	} else {
520 		lua_pushnil(L);
521 		while (lua_next(L, 2) != 0) {
522 			const SoldierMapDescr d = unbox_lua_soldier_description(L, 3, soldier_descr);
523 			const Widelands::Quantity count = luaL_checkuint32(L, -1);
524 			rv.insert(SoldierAmount(d, count));
525 			lua_pop(L, 1);
526 		}
527 	}
528 	return rv;
529 }
530 
531 // Does most of the work of get_soldiers for buildings.
do_get_soldiers(lua_State * L,const Widelands::SoldierControl & sc,const TribeDescr & tribe)532 int do_get_soldiers(lua_State* L, const Widelands::SoldierControl& sc, const TribeDescr& tribe) {
533 	if (lua_gettop(L) != 2) {
534 		report_error(L, "Invalid arguments!");
535 	}
536 
537 	const SoldiersList soldiers = sc.stationed_soldiers();
538 	if (lua_isstring(L, -1)) {
539 		if (std::string(luaL_checkstring(L, -1)) != "all") {
540 			report_error(L, "Invalid arguments!");
541 		}
542 
543 		// Return All Soldiers
544 		SoldiersMap hist;
545 		for (const Soldier* s : soldiers) {
546 			SoldierMapDescr sd(s->get_health_level(), s->get_attack_level(), s->get_defense_level(),
547 			                   s->get_evade_level());
548 
549 			SoldiersMap::iterator i = hist.find(sd);
550 			if (i == hist.end()) {
551 				hist[sd] = 1;
552 			} else {
553 				++i->second;
554 			}
555 		}
556 
557 		// Get this to Lua.
558 		lua_newtable(L);
559 		for (const SoldiersMap::value_type& i : hist) {
560 			lua_createtable(L, 4, 0);
561 #define PUSHLEVEL(idx, name)                                                                       \
562 	lua_pushuint32(L, idx);                                                                         \
563 	lua_pushuint32(L, i.first.name);                                                                \
564 	lua_rawset(L, -3);
565 			PUSHLEVEL(1, health)
566 			PUSHLEVEL(2, attack)
567 			PUSHLEVEL(3, defense)
568 			PUSHLEVEL(4, evade)
569 #undef PUSHLEVEL
570 
571 			lua_pushuint32(L, i.second);
572 			lua_rawset(L, -3);
573 		}
574 	} else {
575 		const SoldierDescr& soldier_descr =
576 		   dynamic_cast<const SoldierDescr&>(*tribe.get_worker_descr(tribe.soldier()));
577 
578 		// Only return the number of those requested
579 		const SoldierMapDescr wanted = unbox_lua_soldier_description(L, 2, soldier_descr);
580 		Widelands::Quantity rv = 0;
581 		for (const Soldier* s : soldiers) {
582 			SoldierMapDescr sd(s->get_health_level(), s->get_attack_level(), s->get_defense_level(),
583 			                   s->get_evade_level());
584 			if (sd == wanted) {
585 				++rv;
586 			}
587 		}
588 		lua_pushuint32(L, rv);
589 	}
590 	return 1;
591 }
592 
593 // Does most of the work of set_soldiers for buildings.
do_set_soldiers(lua_State * L,const Coords & building_position,SoldierControl * sc,Player * owner)594 int do_set_soldiers(lua_State* L,
595                     const Coords& building_position,
596                     SoldierControl* sc,
597                     Player* owner) {
598 	assert(sc != nullptr);
599 	assert(owner != nullptr);
600 
601 	const TribeDescr& tribe = owner->tribe();
602 	const SoldierDescr& soldier_descr =  //  soldiers
603 	   dynamic_cast<const SoldierDescr&>(*tribe.get_worker_descr(tribe.soldier()));
604 	SoldiersMap setpoints = parse_set_soldiers_arguments(L, soldier_descr);
605 
606 	// Get information about current soldiers
607 	const std::vector<Soldier*> curs = sc->stationed_soldiers();
608 	SoldiersMap hist;
609 	for (const Soldier* s : curs) {
610 		SoldierMapDescr sd(s->get_health_level(), s->get_attack_level(), s->get_defense_level(),
611 		                   s->get_evade_level());
612 
613 		SoldiersMap::iterator i = hist.find(sd);
614 		if (i == hist.end()) {
615 			hist[sd] = 1;
616 		} else {
617 			++i->second;
618 		}
619 		if (!setpoints.count(sd)) {
620 			setpoints[sd] = 0;
621 		}
622 	}
623 
624 	// Now adjust them
625 	EditorGameBase& egbase = get_egbase(L);
626 	for (const SoldiersMap::value_type& sp : setpoints) {
627 		Widelands::Quantity cur = 0;
628 		SoldiersMap::iterator i = hist.find(sp.first);
629 		if (i != hist.end()) {
630 			cur = i->second;
631 		}
632 
633 		int d = sp.second - cur;
634 		if (d < 0) {
635 			while (d) {
636 				for (Soldier* s : sc->stationed_soldiers()) {
637 					SoldierMapDescr is(s->get_health_level(), s->get_attack_level(),
638 					                   s->get_defense_level(), s->get_evade_level());
639 
640 					if (is == sp.first) {
641 						sc->outcorporate_soldier(*s);
642 						s->remove(egbase);
643 						++d;
644 						break;
645 					}
646 				}
647 			}
648 		} else if (d > 0) {
649 			for (; d; --d) {
650 				Soldier& soldier = dynamic_cast<Soldier&>(
651 				   soldier_descr.create(egbase, owner, nullptr, building_position));
652 				soldier.set_level(sp.first.health, sp.first.attack, sp.first.defense, sp.first.evade);
653 				if (sc->incorporate_soldier(egbase, soldier)) {
654 					soldier.remove(egbase);
655 					report_error(L, "No space left for soldier!");
656 				}
657 			}
658 		}
659 	}
660 	return 0;
661 }
662 
663 // Parses a table of name/count pairs as given from Lua.
parse_wares_workers(lua_State * L,int table_index,const TribeDescr & tribe,InputMap * ware_workers_list,bool is_ware)664 void parse_wares_workers(lua_State* L,
665                          int table_index,
666                          const TribeDescr& tribe,
667                          InputMap* ware_workers_list,
668                          bool is_ware) {
669 	luaL_checktype(L, table_index, LUA_TTABLE);
670 	lua_pushnil(L);
671 	while (lua_next(L, table_index) != 0) {
672 		if (is_ware) {
673 			if (tribe.ware_index(luaL_checkstring(L, -2)) == INVALID_INDEX) {
674 				report_error(L, "Illegal ware %s", luaL_checkstring(L, -2));
675 			}
676 			ware_workers_list->insert(
677 			   std::make_pair(std::make_pair(tribe.ware_index(luaL_checkstring(L, -2)),
678 			                                 Widelands::WareWorker::wwWARE),
679 			                  luaL_checkuint32(L, -1)));
680 		} else {
681 			if (tribe.worker_index(luaL_checkstring(L, -2)) == INVALID_INDEX) {
682 				report_error(L, "Illegal worker %s", luaL_checkstring(L, -2));
683 			}
684 			ware_workers_list->insert(
685 			   std::make_pair(std::make_pair(tribe.worker_index(luaL_checkstring(L, -2)),
686 			                                 Widelands::WareWorker::wwWORKER),
687 			                  luaL_checkuint32(L, -1)));
688 		}
689 		lua_pop(L, 1);
690 	}
691 }
692 
693 BillOfMaterials
parse_wares_as_bill_of_material(lua_State * L,int table_index,const TribeDescr & tribe)694 parse_wares_as_bill_of_material(lua_State* L, int table_index, const TribeDescr& tribe) {
695 	InputMap input_map;
696 	parse_wares_workers(L, table_index, tribe, &input_map, true /* is_ware */);
697 	BillOfMaterials result;
698 	for (const auto& pair : input_map) {
699 		result.push_back(std::make_pair(pair.first.first, pair.second));
700 	}
701 	return result;
702 }
703 
get_tribe_descr(lua_State * L,const std::string & tribename)704 const Widelands::TribeDescr& get_tribe_descr(lua_State* L, const std::string& tribename) {
705 	if (!Widelands::tribe_exists(tribename)) {
706 		report_error(L, "Tribe '%s' does not exist", tribename.c_str());
707 	}
708 	const Tribes& tribes = get_egbase(L).tribes();
709 	return *tribes.get_tribe_descr(tribes.tribe_index(tribename));
710 }
711 
712 }  // namespace
713 
714 /*
715  * Upcast the given map object description to a higher type and hand this
716  * to Lua. We use this so that scripters always work with the highest class
717  * object available.
718  */
719 #define CAST_TO_LUA(klass, lua_klass)                                                              \
720 	to_lua<lua_klass>(L, new lua_klass(static_cast<const klass*>(descr)))
upcasted_map_object_descr_to_lua(lua_State * L,const MapObjectDescr * const descr)721 int upcasted_map_object_descr_to_lua(lua_State* L, const MapObjectDescr* const descr) {
722 	assert(descr != nullptr);
723 
724 	if (descr->type() >= MapObjectType::BUILDING) {
725 		switch (descr->type()) {
726 		case MapObjectType::CONSTRUCTIONSITE:
727 			return CAST_TO_LUA(ConstructionSiteDescr, LuaConstructionSiteDescription);
728 		case MapObjectType::DISMANTLESITE:
729 			return CAST_TO_LUA(DismantleSiteDescr, LuaDismantleSiteDescription);
730 		case MapObjectType::PRODUCTIONSITE:
731 			return CAST_TO_LUA(ProductionSiteDescr, LuaProductionSiteDescription);
732 		case MapObjectType::MILITARYSITE:
733 			return CAST_TO_LUA(MilitarySiteDescr, LuaMilitarySiteDescription);
734 		case MapObjectType::WAREHOUSE:
735 			return CAST_TO_LUA(WarehouseDescr, LuaWarehouseDescription);
736 		case MapObjectType::MARKET:
737 			return CAST_TO_LUA(MarketDescr, LuaMarketDescription);
738 		case MapObjectType::TRAININGSITE:
739 			return CAST_TO_LUA(TrainingSiteDescr, LuaTrainingSiteDescription);
740 		default:
741 			return CAST_TO_LUA(BuildingDescr, LuaBuildingDescription);
742 		}
743 	} else {
744 		switch (descr->type()) {
745 		case MapObjectType::WARE:
746 			return CAST_TO_LUA(WareDescr, LuaWareDescription);
747 		case MapObjectType::WORKER:
748 			return CAST_TO_LUA(WorkerDescr, LuaWorkerDescription);
749 		case MapObjectType::CARRIER:
750 			return CAST_TO_LUA(WorkerDescr, LuaWorkerDescription);
751 		case MapObjectType::FERRY:
752 			return CAST_TO_LUA(WorkerDescr, LuaWorkerDescription);
753 		case MapObjectType::SOLDIER:
754 			return CAST_TO_LUA(SoldierDescr, LuaSoldierDescription);
755 		case MapObjectType::IMMOVABLE:
756 			return CAST_TO_LUA(ImmovableDescr, LuaImmovableDescription);
757 		default:
758 			return CAST_TO_LUA(MapObjectDescr, LuaMapObjectDescription);
759 		}
760 	}
761 }
762 #undef CAST_TO_LUA
763 
764 /*
765  * Upcast the given map object to a higher type and hand this to
766  * Lua. We use this so that scripters always work with the highest class
767  * object available.
768  */
769 #define CAST_TO_LUA(k) to_lua<Lua##k>(L, new Lua##k(*static_cast<k*>(mo)))
upcasted_map_object_to_lua(lua_State * L,MapObject * mo)770 int upcasted_map_object_to_lua(lua_State* L, MapObject* mo) {
771 	if (!mo) {
772 		return 0;
773 	}
774 
775 	switch (mo->descr().type()) {
776 	case MapObjectType::CRITTER:
777 		return CAST_TO_LUA(Bob);
778 	case MapObjectType::SHIP:
779 		return CAST_TO_LUA(Ship);
780 	case MapObjectType::WORKER:
781 		return CAST_TO_LUA(Worker);
782 	case MapObjectType::CARRIER:
783 		// TODO(sirver): not yet implemented
784 		return CAST_TO_LUA(Worker);
785 	case MapObjectType::FERRY:
786 		// TODO(Nordfriese): not yet implemented
787 		return CAST_TO_LUA(Worker);
788 	case MapObjectType::SOLDIER:
789 		return CAST_TO_LUA(Soldier);
790 
791 	case MapObjectType::IMMOVABLE:
792 		return CAST_TO_LUA(BaseImmovable);
793 
794 	case MapObjectType::FLAG:
795 		return CAST_TO_LUA(Flag);
796 	case MapObjectType::ROAD:
797 		return CAST_TO_LUA(Road);
798 	case MapObjectType::WATERWAY:
799 		// TODO(Nordfriese): not yet implemented
800 		return CAST_TO_LUA(Road);
801 	case MapObjectType::ROADBASE:
802 		// TODO(Nordfriese): not yet implemented
803 		return CAST_TO_LUA(Road);
804 	case MapObjectType::PORTDOCK:
805 		return CAST_TO_LUA(PortDock);
806 
807 	case MapObjectType::BUILDING:
808 		return CAST_TO_LUA(Building);
809 	case MapObjectType::CONSTRUCTIONSITE:
810 		return CAST_TO_LUA(ConstructionSite);
811 	case MapObjectType::DISMANTLESITE:
812 		// TODO(sirver): not yet implemented.
813 		return CAST_TO_LUA(Building);
814 	case MapObjectType::WAREHOUSE:
815 		return CAST_TO_LUA(Warehouse);
816 	case MapObjectType::MARKET:
817 		return CAST_TO_LUA(Market);
818 	case MapObjectType::PRODUCTIONSITE:
819 		return CAST_TO_LUA(ProductionSite);
820 	case MapObjectType::MILITARYSITE:
821 		return CAST_TO_LUA(MilitarySite);
822 	case MapObjectType::TRAININGSITE:
823 		return CAST_TO_LUA(TrainingSite);
824 	case MapObjectType::MAPOBJECT:
825 	case MapObjectType::BATTLE:
826 	case MapObjectType::BOB:
827 	case MapObjectType::SHIP_FLEET:
828 	case MapObjectType::FERRY_FLEET:
829 	case MapObjectType::WARE:
830 		throw LuaError((boost::format("upcasted_map_object_to_lua: Unknown %i") %
831 		                static_cast<int>(mo->descr().type()))
832 		                  .str());
833 	}
834 	NEVER_HERE();
835 }
836 
837 // This is used for get_ware/workers functions, when argument can be
838 // 'all', single ware/worker, or array of ware/workers
parse_wares_workers_list(lua_State * L,const TribeDescr & tribe,Widelands::DescriptionIndex * single_item,std::vector<Widelands::DescriptionIndex> * item_list,bool is_ware)839 RequestedWareWorker parse_wares_workers_list(lua_State* L,
840                                              const TribeDescr& tribe,
841                                              Widelands::DescriptionIndex* single_item,
842                                              std::vector<Widelands::DescriptionIndex>* item_list,
843                                              bool is_ware) {
844 	RequestedWareWorker result = RequestedWareWorker::kUndefined;
845 	int32_t nargs = lua_gettop(L);
846 	if (nargs != 2) {
847 		report_error(L, "One argument is required for produced_wares_count()");
848 	}
849 
850 	/* If we have single string as an argument */
851 	if (lua_isstring(L, 2)) {
852 
853 		std::string what = luaL_checkstring(L, -1);
854 		if (what != "all") {
855 			result = RequestedWareWorker::kSingle;
856 			// This is name of ware/worker
857 			if (is_ware) {
858 				*single_item = tribe.ware_index(what);
859 			} else {
860 				*single_item = tribe.worker_index(what);
861 			}
862 			if (*single_item == INVALID_INDEX) {
863 				report_error(L, "Unrecognized ware/worker %s", what.c_str());
864 			}
865 		} else {
866 			// we collect all wares/workers and push it to item_list
867 			result = RequestedWareWorker::kAll;
868 			if (is_ware) {
869 				for (auto idx : tribe.wares()) {
870 					item_list->push_back(idx);
871 				}
872 			} else {
873 				for (auto idx : tribe.workers()) {
874 					item_list->push_back(idx);
875 				}
876 			}
877 		}
878 	} else {
879 		result = RequestedWareWorker::kList;
880 		/* we got array of names, and so fill the indexes into item_list */
881 		luaL_checktype(L, 2, LUA_TTABLE);
882 		lua_pushnil(L);
883 		while (lua_next(L, 2) != 0) {
884 			std::string what = luaL_checkstring(L, -1);
885 			lua_pop(L, 1);
886 			if (is_ware) {
887 				item_list->push_back(tribe.ware_index(what));
888 			} else {
889 				item_list->push_back(tribe.worker_index(what));
890 			}
891 			if (item_list->back() == INVALID_INDEX) {
892 				report_error(L, "Unrecognized ware %s", what.c_str());
893 			}
894 		}
895 	}
896 	assert((*single_item == INVALID_INDEX) != item_list->empty());
897 	return result;
898 }
899 
900 // Very similar to above function, but expects numbers for every received ware/worker
parse_wares_workers_counted(lua_State * L,const TribeDescr & tribe,InputMap * ware_workers_list,bool is_ware)901 RequestedWareWorker parse_wares_workers_counted(lua_State* L,
902                                                 const TribeDescr& tribe,
903                                                 InputMap* ware_workers_list,
904                                                 bool is_ware) {
905 	RequestedWareWorker result = RequestedWareWorker::kUndefined;
906 	int32_t nargs = lua_gettop(L);
907 	if (nargs != 2 && nargs != 3) {
908 		report_error(L, "Wrong number of arguments to set ware/worker method!");
909 	}
910 
911 	// We either received, two items string,int:
912 	if (nargs == 3) {
913 		result = RequestedWareWorker::kSingle;
914 		if (is_ware) {
915 			if (tribe.ware_index(luaL_checkstring(L, 2)) == INVALID_INDEX) {
916 				report_error(L, "Illegal ware %s", luaL_checkstring(L, 2));
917 			}
918 			ware_workers_list->insert(std::make_pair(
919 			   std::make_pair(tribe.ware_index(luaL_checkstring(L, 2)), Widelands::WareWorker::wwWARE),
920 			   luaL_checkuint32(L, 3)));
921 		} else {
922 			if (tribe.worker_index(luaL_checkstring(L, 2)) == INVALID_INDEX) {
923 				report_error(L, "Illegal worker %s", luaL_checkstring(L, 2));
924 			}
925 			ware_workers_list->insert(
926 			   std::make_pair(std::make_pair(tribe.worker_index(luaL_checkstring(L, 2)),
927 			                                 Widelands::WareWorker::wwWORKER),
928 			                  luaL_checkuint32(L, 3)));
929 		}
930 	} else {
931 		result = RequestedWareWorker::kList;
932 		// or we got a table with name:quantity
933 		parse_wares_workers(L, 2, tribe, ware_workers_list, is_ware);
934 	}
935 	return result;
936 }
937 
938 #undef CAST_TO_LUA
939 
940 /*
941  * ========================================================================
942  *                         MODULE CLASSES
943  * ========================================================================
944  */
945 
946 /* RST
947 Module Interfaces
948 ^^^^^^^^^^^^^^^^^
949 
950 */
951 
952 /* RST
953 HasWares
954 --------
955 
956 .. class:: HasWares
957 
958    HasWares is an interface that most :class:`PlayerImmovable` objects
959    that can contain wares implement. This is at the time of this writing
960    :class:`~wl.map.Flag` and :class:`~wl.map.Warehouse`.
961 */
962 
963 /* RST
964    .. method:: get_wares(which)
965 
966       Gets the number of wares that currently reside here.
967 
968       :arg which:  can be either of
969 
970       * the string :const:`all`.
971            In this case the function will return a
972            :class:`table` of (ware name,amount) pairs that gives information
973            about all ware information available for this object.
974       * a ware name.
975          In this case a single integer is returned. No check is made
976          if this ware makes sense for this location, you can for example ask a
977          :const:`lumberjacks_hut` for the number of :const:`granite` he has
978          and he will return 0.
979       * an :class:`array` of ware names.
980          In this case a :class:`table` of
981          (ware name,amount) pairs is returned where only the requested wares
982          are listed. All other entries are :const:`nil`.
983 
984       :returns: :class:`integer` or :class:`table`
985 */
986 
987 /* RST
988    .. method:: set_wares(which[, amount])
989 
990       Sets the wares available in this location. Either takes two arguments,
991       a ware name and an amount to set it to. Or it takes a table of
992       (ware name, amount) pairs. Wares are created and added to an economy out
993       of thin air.
994 
995       :arg which: name of ware or (ware_name, amount) table
996       :type which: :class:`string` or :class:`table`
997       :arg amount: this many units will be available after the call
998       :type amount: :class:`integer`
999 */
1000 
1001 /* RST
1002    .. attribute:: valid_wares
1003 
1004       (RO) A :class:`table` of (ware_name, count) if storage is somehow
1005       constrained in this location. For example for a
1006       :class:`~wl.map.ProductionSite` this is the information what wares
1007       and how much can be stored as inputs. For unconstrained storage (like
1008       :class:`~wl.map.Warehouse`) this is :const:`nil`.
1009 
1010       You can use this to quickly fill a building:
1011 
1012       .. code-block:: lua
1013 
1014          if b.valid_wares then b:set_wares(b.valid_wares) end
1015 */
1016 
1017 /* RST
1018 HasInputs
1019 ---------
1020 
1021 .. class:: HasInputs
1022 
1023    HasInputs is an interface that some :class:`PlayerImmovable` objects
1024    implement. At the time of this writing these are
1025    :class:`~wl.map.ProductionSite` and :class:`~wl.map.TrainingSite`.
1026    This interface is similar to :class:`HasWares` but additionally allows
1027    to set workers as inputs. These workers are consumed by the production
1028    or trainings programm.
1029 */
1030 
1031 /* RST
1032    .. method:: get_inputs(which)
1033 
1034       Gets the number of wares and workers that currently reside here
1035       for consumption.
1036 
1037       :arg which:  can be either of
1038 
1039       * the string :const:`all`.
1040            In this case the function will return a
1041            :class:`table` of (ware/worker name,amount) pairs that gives
1042            information about all ware information available for this object.
1043       * a ware or worker name.
1044            In this case a single integer is returned. No check is made
1045            if this ware/worker makes sense for this location, you can for example ask a
1046            :const:`lumberjacks_hut` for the number of :const:`granite` he has
1047            and he will return 0.
1048       * an :class:`array` of ware and worker names.
1049            In this case a :class:`table` of
1050            (ware/worker name,amount) pairs is returned where only the requested
1051            wares/workers are listed. All other entries are :const:`nil`.
1052 
1053       :returns: :class:`integer` or :class:`table`
1054 */
1055 
1056 /* RST
1057    .. method:: set_inputs(which[, amount])
1058 
1059       Sets the wares/workers available in this location which will
1060       be consumed by the production/training programm. Either takes two arguments,
1061       a ware/worker name and an amount to set it to. Or it takes a table of
1062       (ware/worker name, amount) pairs. Wares are created and added to an
1063       economy out of thin air.
1064 
1065       :arg which: name of ware/worker or (ware/worker name, amount) table
1066       :type which: :class:`string` or :class:`table`
1067       :arg amount: this many units will be available after the call
1068       :type amount: :class:`integer`
1069 */
1070 
1071 /* RST
1072    .. attribute:: valid_inputs
1073 
1074       (RO) A :class:`table` of (ware/worker name, count) which describes how
1075       many wares/workers can be stored here for consumption. For example for a
1076       :class:`~wl.map.ProductionSite` this is the information what wares/workers
1077       and can be stored in which amount as inputs.
1078 
1079       You can use this to quickly fill a building:
1080 
1081       .. code-block:: lua
1082 
1083          if b.valid_inputs then b:set_inputs(b.valid_inputs) end
1084 */
1085 
1086 /* RST
1087 HasWorkers
1088 ----------
1089 
1090 .. class:: HasWorkers
1091 
1092    Analogon to :class:`HasWares`, but for Workers. Supported at the time
1093    of this writing by :class:`~wl.map.Road`, :class:`~wl.map.Warehouse`
1094    and :class:`~wl.map.ProductionSite`. In the case of ProductionSites,
1095    these methods allow access to the workers which do the work instead of
1096    workers which are consumed as accessed by the methods of :class:`HasInputs`.
1097 */
1098 
1099 /* RST
1100    .. method:: get_workers(which)
1101 
1102       Similar to :meth:`HasWares.get_wares`.
1103 */
1104 
1105 /* RST
1106    .. method:: set_workers(which[, amount])
1107 
1108       Similar to :meth:`HasWares.set_wares`.
1109 */
1110 
1111 /* RST
1112    .. attribute:: valid_workers
1113 
1114       (RO) Similar to :attr:`HasWares.valid_wares` but for workers in this
1115       location.
1116 */
1117 
1118 /* RST
1119 HasSoldiers
1120 ------------
1121 
1122 .. class:: HasSoldiers
1123 
1124    Analogon to :class:`HasWorkers`, but for Soldiers. Due to differences in
1125    Soldiers and implementation details in Lua this class has a slightly
1126    different interface than :class:`HasWorkers`. Supported at the time of this
1127    writing by :class:`~wl.map.Warehouse`, :class:`~wl.map.MilitarySite` and
1128    :class:`~wl.map.TrainingSite`.
1129 */
1130 
1131 /* RST
1132    .. method:: get_soldiers(descr)
1133 
1134       Gets information about the soldiers in a location.
1135 
1136       :arg descr: can be either of
1137 
1138       * a soldier description.
1139          Returns an :class:`integer` which is the number of soldiers of this
1140          kind in this building.
1141 
1142          A soldier description is a :class:`array` that contains the level for
1143          health, attack, defense and evade (in this order). A usage example:
1144 
1145          .. code-block:: lua
1146 
1147             w:get_soldiers({0,0,0,0})
1148 
1149          would return the number of soldiers of level 0 in this location.
1150 
1151       * the string :const:`all`.
1152          In this case a :class:`table` of (soldier descriptions, count) is
1153          returned. Note that the following will not work, because Lua indexes
1154          tables by identity:
1155 
1156          .. code-block:: lua
1157 
1158             w:set_soldiers({0,0,0,0}, 100)
1159             w:get_soldiers({0,0,0,0}) -- works, returns 100
1160             w:get_soldiers("all")[{0,0,0,0}] -- works not, this is nil
1161 
1162             -- Following is a working way to check for a {0,0,0,0} soldier
1163             for descr,count in pairs(w:get_soldiers("all")) do
1164                if descr[1] == 0 and descr[2] == 0 and
1165                   descr[3] == 0 and descr[4] == 0 then
1166                      print(count)
1167                end
1168             end
1169 
1170       :returns: Number of soldiers that match descr or the :class:`table`
1171          containing all soldiers
1172       :rtype: :class:`integer` or :class:`table`.
1173 */
1174 
1175 /* RST
1176    .. method:: set_soldiers(which[, amount])
1177 
1178       Analogous to :meth:`HasWorkers.set_workers`, but for soldiers. Instead of
1179       a name a :class:`array` is used to define the soldier. See
1180       :meth:`get_soldiers` for an example.
1181 
1182       Usage example:
1183 
1184       .. code-block:: lua
1185 
1186          l:set_soldiers({0,0,0,0}, 100)
1187 
1188       would add 100 level 0 soldiers. While
1189 
1190       .. code-block:: lua
1191 
1192          l:set_soldiers({
1193            [{0,0,0,0}] = 10,
1194            [{1,2,3,4}] = 5,
1195          })
1196 
1197       would add 10 level 0 soldier and 5 soldiers with hit point level 1,
1198       attack level 2, defense level 3 and evade level 4 (as long as this is
1199       legal for the players tribe).
1200 
1201       :arg which: either a table of (description, count) pairs or one
1202          description. In that case amount has to be specified as well.
1203       :type which: :class:`table` or :class:`array`.
1204 */
1205 
1206 /* RST
1207    .. attribute:: max_soldiers
1208 
1209       (RO) The maximum number of soldiers that can be inside this building at
1210       one time. If it is not constrained, like for :class:`~wl.map.Warehouse`
1211       this will be :const:`nil`.
1212 */
1213 
1214 /* RST
1215 Module Classes
1216 ^^^^^^^^^^^^^^
1217 
1218 */
1219 
1220 /* RST
1221 Map
1222 ---
1223 
1224 .. class:: Map
1225 
1226    Access to the map and its objects. You cannot instantiate this directly,
1227    instead access it via :attr:`wl.Game.map`.
1228 */
1229 const char LuaMap::className[] = "Map";
1230 const MethodType<LuaMap> LuaMap::Methods[] = {
1231    METHOD(LuaMap, count_conquerable_fields),
1232    METHOD(LuaMap, count_terrestrial_fields),
1233    METHOD(LuaMap, count_owned_valuable_fields),
1234    METHOD(LuaMap, place_immovable),
1235    METHOD(LuaMap, get_field),
1236    METHOD(LuaMap, recalculate),
1237    METHOD(LuaMap, recalculate_seafaring),
1238    METHOD(LuaMap, set_port_space),
1239    METHOD(LuaMap, sea_route_exists),
1240    METHOD(LuaMap, find_ocean_fields),
1241    {nullptr, nullptr},
1242 };
1243 const PropertyType<LuaMap> LuaMap::Properties[] = {
1244    PROP_RO(LuaMap, allows_seafaring), PROP_RO(LuaMap, number_of_port_spaces),
1245    PROP_RO(LuaMap, port_spaces),      PROP_RO(LuaMap, width),
1246    PROP_RO(LuaMap, height),           PROP_RO(LuaMap, player_slots),
1247    {nullptr, nullptr, nullptr},
1248 };
1249 
__persist(lua_State *)1250 void LuaMap::__persist(lua_State* /* L */) {
1251 }
1252 
__unpersist(lua_State *)1253 void LuaMap::__unpersist(lua_State* /* L */) {
1254 }
1255 
1256 /*
1257  ==========================================================
1258  PROPERTIES
1259  ==========================================================
1260  */
1261 /* RST
1262    .. attribute:: allows_seafaring
1263 
1264       (RO) Whether the map currently allows seafaring.
1265 
1266       :returns: True if there are at least two port spaces that can be reached from each other.
1267 */
get_allows_seafaring(lua_State * L)1268 int LuaMap::get_allows_seafaring(lua_State* L) {
1269 	lua_pushboolean(L, get_egbase(L).map().allows_seafaring());
1270 	return 1;
1271 }
1272 /* RST
1273    .. attribute:: number_of_port_spaces
1274 
1275       (RO) The amount of port spaces on the map.
1276 
1277       :returns: An integer with the number of port spaces.
1278 */
get_number_of_port_spaces(lua_State * L)1279 int LuaMap::get_number_of_port_spaces(lua_State* L) {
1280 	lua_pushuint32(L, get_egbase(L).map().get_port_spaces().size());
1281 	return 1;
1282 }
1283 
1284 /* RST
1285    .. attribute:: port_spaces
1286 
1287       (RO) A list of coordinates for all port spaces on the map.
1288 
1289       :returns: A table of port space coordinates,
1290         like this: ``{{x = 0, y = 2}, {x = 54, y = 23}}``.
1291 */
get_port_spaces(lua_State * L)1292 int LuaMap::get_port_spaces(lua_State* L) {
1293 	lua_newtable(L);
1294 	int counter = 0;
1295 	for (const Coords& space : get_egbase(L).map().get_port_spaces()) {
1296 		lua_pushinteger(L, ++counter);
1297 		lua_newtable(L);
1298 		lua_pushstring(L, "x");
1299 		lua_pushint32(L, space.x);
1300 		lua_settable(L, -3);
1301 		lua_pushstring(L, "y");
1302 		lua_pushint32(L, space.y);
1303 		lua_settable(L, -3);
1304 		lua_settable(L, -3);
1305 	}
1306 	return 1;
1307 }
1308 
1309 /* RST
1310    .. attribute:: width
1311 
1312       (RO) The width of the map in fields.
1313 */
get_width(lua_State * L)1314 int LuaMap::get_width(lua_State* L) {
1315 	lua_pushuint32(L, get_egbase(L).map().get_width());
1316 	return 1;
1317 }
1318 /* RST
1319    .. attribute:: height
1320 
1321       (RO) The height of the map in fields.
1322 */
get_height(lua_State * L)1323 int LuaMap::get_height(lua_State* L) {
1324 	lua_pushuint32(L, get_egbase(L).map().get_height());
1325 	return 1;
1326 }
1327 
1328 /* RST
1329    .. attribute:: player_slots
1330 
1331       (RO) This is an :class:`array` that contains :class:`~wl.map.PlayerSlots`
1332       for each player defined in the map.
1333 */
get_player_slots(lua_State * L)1334 int LuaMap::get_player_slots(lua_State* L) {
1335 	const Map& map = get_egbase(L).map();
1336 
1337 	lua_createtable(L, map.get_nrplayers(), 0);
1338 	for (Widelands::PlayerNumber i = 0; i < map.get_nrplayers(); i++) {
1339 		lua_pushuint32(L, i + 1);
1340 		to_lua<LuaMaps::LuaPlayerSlot>(L, new LuaMaps::LuaPlayerSlot(i + 1));
1341 		lua_settable(L, -3);
1342 	}
1343 
1344 	return 1;
1345 }
1346 
1347 /*
1348  ==========================================================
1349  LUA METHODS
1350  ==========================================================
1351  */
1352 
1353 /* RST
1354    .. method:: count_conquerable_fields()
1355 
1356       (RO) Counts all reachable fields that a player could build on.
1357 
1358       **Note:** The fields are only calculated afresh when this is called for the first time.
1359 
1360      :returns: An integer with the amount of fields.
1361 */
count_conquerable_fields(lua_State * L)1362 int LuaMap::count_conquerable_fields(lua_State* L) {
1363 	lua_pushinteger(L, get_egbase(L).mutable_map()->count_all_conquerable_fields());
1364 	return 1;
1365 }
1366 
1367 /* RST
1368    .. method:: count_terrestrial_fields()
1369 
1370       (RO) Counts all fields that are not swimmable.
1371 
1372      **Note:** The fields are only calculated afresh when this is called for the first time.
1373 
1374      :returns: An integer with the amount of fields.
1375 */
count_terrestrial_fields(lua_State * L)1376 int LuaMap::count_terrestrial_fields(lua_State* L) {
1377 	lua_pushinteger(L, get_egbase(L).mutable_map()->count_all_fields_excluding_caps(MOVECAPS_SWIM));
1378 	return 1;
1379 }
1380 
1381 /* RST
1382    .. method:: count_owned_valuable_fields([immovable_attribute])
1383 
1384       (RO) Counts the number of owned valuable fields for all players.
1385 
1386       :arg name: *Optional*. If this is set, only count fields that have an
1387         immovable with the given atttribute.
1388       :type name: :class:`string`
1389 
1390      :returns: A table mapping player numbers to their number of owned fields.
1391 */
count_owned_valuable_fields(lua_State * L)1392 int LuaMap::count_owned_valuable_fields(lua_State* L) {
1393 	if (lua_gettop(L) > 2) {
1394 		report_error(L, "Does not take more than one argument.");
1395 	}
1396 	const std::string attribute = lua_gettop(L) == 2 ? luaL_checkstring(L, -1) : "";
1397 
1398 	lua_newtable(L);
1399 	for (const auto& fieldinfo : get_egbase(L).map().count_owned_valuable_fields(attribute)) {
1400 		lua_pushinteger(L, fieldinfo.first);
1401 		lua_pushinteger(L, fieldinfo.second);
1402 		lua_settable(L, -3);
1403 	}
1404 	return 1;
1405 }
1406 
1407 /* RST
1408    .. method:: find_ocean_fields(number)
1409 
1410       Returns an array with the given number of Fields so that every field is swimmable,
1411       and from each field a sea route to any port space exists.
1412 
1413       :arg number: The number of fields to find.
1414 
1415      :returns: :class:`array` of :class:`wl.map.Field`
1416 */
find_ocean_fields(lua_State * L)1417 int LuaMap::find_ocean_fields(lua_State* L) {
1418 	upcast(Game, game, &get_egbase(L));
1419 	assert(game);
1420 	const Map& map = game->map();
1421 
1422 	std::vector<LuaMaps::LuaField*> result;
1423 	for (uint32_t i = luaL_checkuint32(L, 2); i;) {
1424 		const uint32_t x = game->logic_rand() % map.get_width();
1425 		const uint32_t y = game->logic_rand() % map.get_width();
1426 		Widelands::Coords field(x, y);
1427 		bool success = false;
1428 		if (map[field].maxcaps() & Widelands::MOVECAPS_SWIM) {
1429 			for (Widelands::Coords port : map.get_port_spaces()) {
1430 				for (const Widelands::Coords& c : map.find_portdock(port)) {
1431 					Widelands::Path p;
1432 					if (map.findpath(field, c, 0, p, CheckStepDefault(MOVECAPS_SWIM)) >= 0) {
1433 						success = true;
1434 						break;
1435 					}
1436 				}
1437 				if (success) {
1438 					break;
1439 				}
1440 			}
1441 		}
1442 		if (success) {
1443 			result.push_back(new LuaMaps::LuaField(x, y));
1444 			--i;
1445 		}
1446 	}
1447 
1448 	lua_newtable(L);
1449 	int counter = 0;
1450 	for (auto& f : result) {
1451 		lua_pushinteger(L, ++counter);
1452 		to_lua<LuaMaps::LuaField>(L, f);
1453 		lua_settable(L, -3);
1454 	}
1455 	return 1;
1456 }
1457 
1458 /* RST
1459    .. method:: place_immovable(name, field, from_where)
1460 
1461       Creates an immovable that is defined by the world (e.g. trees, rocks...)
1462       or a tribe (field) on a given field. If there is already an immovable on
1463       the field, an error is reported.
1464 
1465       :arg name: The name of the immovable to create
1466       :type name: :class:`string`
1467       :arg field: The immovable is created on this field.
1468       :type field: :class:`wl.map.Field`
1469       :arg from_where: "world" if the immovable is defined in the world,
1470          "tribes" if it is defined in the tribes.
1471       :type from_where: :class:`string`
1472 
1473       :returns: The created immovable.
1474 */
place_immovable(lua_State * const L)1475 int LuaMap::place_immovable(lua_State* const L) {
1476 	std::string from_where;
1477 
1478 	const std::string objname = luaL_checkstring(L, 2);
1479 	LuaMaps::LuaField* c = *get_user_class<LuaMaps::LuaField>(L, 3);
1480 	if (lua_gettop(L) > 3 && !lua_isnil(L, 4)) {
1481 		from_where = luaL_checkstring(L, 4);
1482 	}
1483 
1484 	// Check if the map is still free here
1485 	if (BaseImmovable const* const imm = c->fcoords(L).field->get_immovable()) {
1486 		if (imm->get_size() >= BaseImmovable::SMALL) {
1487 			report_error(L, "Node is no longer free!");
1488 		}
1489 	}
1490 
1491 	EditorGameBase& egbase = get_egbase(L);
1492 
1493 	BaseImmovable* m = nullptr;
1494 	if (from_where == "world") {
1495 		DescriptionIndex const imm_idx = egbase.world().get_immovable_index(objname);
1496 		if (imm_idx == Widelands::INVALID_INDEX) {
1497 			report_error(L, "Unknown world immovable <%s>", objname.c_str());
1498 		}
1499 
1500 		m = &egbase.create_immovable(
1501 		   c->coords(), imm_idx, MapObjectDescr::OwnerType::kWorld, nullptr /* owner */);
1502 	} else if (from_where == "tribes") {
1503 		DescriptionIndex const imm_idx = egbase.tribes().immovable_index(objname);
1504 		if (imm_idx == Widelands::INVALID_INDEX) {
1505 			report_error(L, "Unknown tribes immovable <%s>", objname.c_str());
1506 		}
1507 
1508 		m = &egbase.create_immovable(
1509 		   c->coords(), imm_idx, MapObjectDescr::OwnerType::kTribe, nullptr /* owner */);
1510 	} else {
1511 		report_error(
1512 		   L, "There are no immovables for <%s>. Use \"world\" or \"tribes\"", from_where.c_str());
1513 	}
1514 
1515 	return LuaMaps::upcasted_map_object_to_lua(L, m);
1516 }
1517 
1518 /* RST
1519    .. method:: get_field(x, y)
1520 
1521       Returns a :class:`wl.map.Field` object of the given index.
1522 */
get_field(lua_State * L)1523 int LuaMap::get_field(lua_State* L) {
1524 	uint32_t x = luaL_checkuint32(L, 2);
1525 	uint32_t y = luaL_checkuint32(L, 3);
1526 
1527 	const Map& map = get_egbase(L).map();
1528 
1529 	if (x >= static_cast<uint32_t>(map.get_width())) {
1530 		report_error(L, "x coordinate out of range!");
1531 	}
1532 	if (y >= static_cast<uint32_t>(map.get_height())) {
1533 		report_error(L, "y coordinate out of range!");
1534 	}
1535 
1536 	return to_lua<LuaMaps::LuaField>(L, new LuaMaps::LuaField(x, y));
1537 }
1538 
1539 /* RST
1540    .. method:: recalculate()
1541 
1542       This map recalculates the whole map state: height of fields, buildcaps,
1543       whether the map allows seafaring and so on. You only need to call this
1544       function if you changed :any:`raw_height` in any way.
1545 */
1546 // TODO(unknown): do we really want this function?
recalculate(lua_State * L)1547 int LuaMap::recalculate(lua_State* L) {
1548 	EditorGameBase& egbase = get_egbase(L);
1549 	egbase.mutable_map()->recalc_whole_map(egbase);
1550 	return 0;
1551 }
1552 
1553 /* RST
1554    .. method:: recalculate_seafaring()
1555 
1556       This method recalculates whether the map allows seafaring.
1557       You only need to call this function if you have been changing terrains to/from
1558       water and wanted to defer recalculating whether the map allows seafaring.
1559 */
recalculate_seafaring(lua_State * L)1560 int LuaMap::recalculate_seafaring(lua_State* L) {
1561 	get_egbase(L).mutable_map()->recalculate_allows_seafaring();
1562 	return 0;
1563 }
1564 
1565 /* RST
1566    .. method:: set_port_space(x, y, allowed)
1567 
1568       Sets whether a port space is allowed at the coordinates (x, y).
1569       Returns false if the port space couldn't be set.
1570 
1571       :arg x: The x coordinate of the port space to set/unset.
1572       :type x: :class:`int`
1573       :arg y: The y coordinate of the port space to set/unset.
1574       :type y: :class:`int`
1575       :arg allowed: Whether building a port will be allowed here.
1576       :type allowed: :class:`bool`
1577 
1578       :returns: :const:`true` on success, or :const:`false` otherwise
1579       :rtype: :class:`bool`
1580 */
set_port_space(lua_State * L)1581 int LuaMap::set_port_space(lua_State* L) {
1582 	const int x = luaL_checkint32(L, 2);
1583 	const int y = luaL_checkint32(L, 3);
1584 	const bool allowed = luaL_checkboolean(L, 4);
1585 	const bool success = get_egbase(L).mutable_map()->set_port_space(
1586 	   get_egbase(L), Widelands::Coords(x, y), allowed, false, true);
1587 	lua_pushboolean(L, success);
1588 	return 1;
1589 }
1590 
1591 /* RST
1592    .. method:: sea_route_exists(field, port)
1593 
1594       Returns whether a sea route exists from the given field to the given port space.
1595 
1596       :arg field: The field where to start
1597       :type field: :class:`wl.map.Field`
1598       :arg port: The port space to find
1599       :type port: :class:`wl.map.Field`
1600 
1601       :rtype: :class:`bool`
1602 */
sea_route_exists(lua_State * L)1603 int LuaMap::sea_route_exists(lua_State* L) {
1604 	const Widelands::Map& map = get_egbase(L).map();
1605 	const Widelands::FCoords f_start = (*get_user_class<LuaMaps::LuaField>(L, 2))->fcoords(L);
1606 	const Widelands::FCoords f_port = (*get_user_class<LuaMaps::LuaField>(L, 3))->fcoords(L);
1607 	for (const Widelands::Coords& c : map.find_portdock(f_port)) {
1608 		Widelands::Path p;
1609 		if (map.findpath(f_start, c, 0, p, CheckStepDefault(MOVECAPS_SWIM)) >= 0) {
1610 			lua_pushboolean(L, true);
1611 			return 1;
1612 		}
1613 	}
1614 	lua_pushboolean(L, false);
1615 	return 1;
1616 }
1617 
1618 /*
1619  ==========================================================
1620  C METHODS
1621  ==========================================================
1622  */
1623 
1624 /* RST
1625 TribeDescription
1626 --------------------
1627 .. class:: TribeDescription
1628 
1629    A static description of a tribe.
1630    This class contains information about which buildings, wares, workers etc. a tribe uses.
1631 */
1632 const char LuaTribeDescription::className[] = "TribeDescription";
1633 const MethodType<LuaTribeDescription> LuaTribeDescription::Methods[] = {
1634    METHOD(LuaTribeDescription, has_building),
1635    METHOD(LuaTribeDescription, has_ware),
1636    METHOD(LuaTribeDescription, has_worker),
1637    {nullptr, nullptr},
1638 };
1639 const PropertyType<LuaTribeDescription> LuaTribeDescription::Properties[] = {
1640    PROP_RO(LuaTribeDescription, buildings),
1641    PROP_RO(LuaTribeDescription, carrier),
1642    PROP_RO(LuaTribeDescription, carrier2),
1643    PROP_RO(LuaTribeDescription, descname),
1644    PROP_RO(LuaTribeDescription, geologist),
1645    PROP_RO(LuaTribeDescription, immovables),
1646    PROP_RO(LuaTribeDescription, resource_indicators),
1647    PROP_RO(LuaTribeDescription, name),
1648    PROP_RO(LuaTribeDescription, port),
1649    PROP_RO(LuaTribeDescription, ship),
1650    PROP_RO(LuaTribeDescription, soldier),
1651    PROP_RO(LuaTribeDescription, wares),
1652    PROP_RO(LuaTribeDescription, workers),
1653    {nullptr, nullptr, nullptr},
1654 };
1655 
__persist(lua_State * L)1656 void LuaTribeDescription::__persist(lua_State* L) {
1657 	const TribeDescr* descr = get();
1658 	PERS_STRING("name", descr->name());
1659 }
1660 
__unpersist(lua_State * L)1661 void LuaTribeDescription::__unpersist(lua_State* L) {
1662 	std::string name;
1663 	UNPERS_STRING("name", name)
1664 	const Tribes& tribes = get_egbase(L).tribes();
1665 	DescriptionIndex idx = tribes.safe_tribe_index(name);
1666 	set_description_pointer(tribes.get_tribe_descr(idx));
1667 }
1668 
1669 /*
1670  ==========================================================
1671  PROPERTIES
1672  ==========================================================
1673  */
1674 
1675 /* RST
1676    .. attribute:: buildings
1677 
1678       (RO) an array of :class:`LuaBuildingDescription` with all the buildings that the tribe can
1679       use, casted to their appropriate subclasses.
1680 */
get_buildings(lua_State * L)1681 int LuaTribeDescription::get_buildings(lua_State* L) {
1682 	const TribeDescr& tribe = *get();
1683 	lua_newtable(L);
1684 	int counter = 0;
1685 	for (DescriptionIndex building : tribe.buildings()) {
1686 		lua_pushinteger(L, ++counter);
1687 		upcasted_map_object_descr_to_lua(L, tribe.get_building_descr(building));
1688 		lua_settable(L, -3);
1689 	}
1690 	return 1;
1691 }
1692 
1693 /* RST
1694    .. attribute:: carrier
1695 
1696          (RO) the :class:`string` internal name of the carrier type that this tribe uses
1697 */
1698 
get_carrier(lua_State * L)1699 int LuaTribeDescription::get_carrier(lua_State* L) {
1700 	lua_pushstring(L, get_egbase(L).tribes().get_worker_descr(get()->carrier())->name());
1701 	return 1;
1702 }
1703 
1704 /* RST
1705    .. attribute:: carrier2
1706 
1707          (RO) the :class:`string` internal name of the carrier2 type that this tribe uses.
1708               e.g. 'atlanteans_horse'
1709 */
1710 
get_carrier2(lua_State * L)1711 int LuaTribeDescription::get_carrier2(lua_State* L) {
1712 	lua_pushstring(L, get_egbase(L).tribes().get_worker_descr(get()->carrier2())->name());
1713 	return 1;
1714 }
1715 
1716 /* RST
1717    .. attribute:: descname
1718 
1719          (RO) a :class:`string` with the tribe's localized name
1720 */
1721 
get_descname(lua_State * L)1722 int LuaTribeDescription::get_descname(lua_State* L) {
1723 	lua_pushstring(L, get()->descname());
1724 	return 1;
1725 }
1726 
1727 /* RST
1728    .. attribute:: geologist
1729 
1730          (RO) the :class:`string` internal name of the geologist type that this tribe uses
1731 */
1732 
get_geologist(lua_State * L)1733 int LuaTribeDescription::get_geologist(lua_State* L) {
1734 	lua_pushstring(L, get_egbase(L).tribes().get_worker_descr(get()->geologist())->name());
1735 	return 1;
1736 }
1737 
1738 /* RST
1739    .. attribute:: immovables
1740 
1741       (RO) an array of :class:`LuaImmovableDescription` with all the immovables that the tribe can
1742       use.
1743 */
get_immovables(lua_State * L)1744 int LuaTribeDescription::get_immovables(lua_State* L) {
1745 	const TribeDescr& tribe = *get();
1746 	lua_newtable(L);
1747 	int counter = 0;
1748 	for (DescriptionIndex immovable : tribe.immovables()) {
1749 		lua_pushinteger(L, ++counter);
1750 		to_lua<LuaImmovableDescription>(
1751 		   L, new LuaImmovableDescription(tribe.get_immovable_descr(immovable)));
1752 		lua_settable(L, -3);
1753 	}
1754 	return 1;
1755 }
1756 
1757 /* RST
1758    .. attribute:: resource_indicators
1759 
1760       (RO) the table `resource_indicators` as defined in the tribe's `tribename.lua`.
1761       See `data/tribes/atlanteans.lua` for more information on the table structure.
1762 */
get_resource_indicators(lua_State * L)1763 int LuaTribeDescription::get_resource_indicators(lua_State* L) {
1764 	const TribeDescr& tribe = *get();
1765 	lua_newtable(L);
1766 	const ResourceIndicatorSet resis = tribe.resource_indicators();
1767 	for (const auto& resilist : resis) {
1768 		lua_pushstring(L, resilist.first);
1769 		lua_newtable(L);
1770 		for (const auto& resi : resilist.second) {
1771 			lua_pushinteger(L, resi.first);
1772 			lua_pushstring(L, tribe.get_immovable_descr(resi.second)->name());
1773 			lua_settable(L, -3);
1774 		}
1775 		lua_settable(L, -3);
1776 	}
1777 	return 1;
1778 }
1779 
1780 /* RST
1781    .. attribute:: name
1782 
1783          (RO) a :class:`string` with the tribe's internal name
1784 */
1785 
get_name(lua_State * L)1786 int LuaTribeDescription::get_name(lua_State* L) {
1787 	lua_pushstring(L, get()->name());
1788 	return 1;
1789 }
1790 
1791 /* RST
1792    .. attribute:: port
1793 
1794          (RO) the :class:`string` internal name of the port type that this tribe uses
1795 */
1796 
get_port(lua_State * L)1797 int LuaTribeDescription::get_port(lua_State* L) {
1798 	lua_pushstring(L, get_egbase(L).tribes().get_building_descr(get()->port())->name());
1799 	return 1;
1800 }
1801 
1802 /* RST
1803    .. attribute:: ship
1804 
1805          (RO) the :class:`string` internal name of the ship type that this tribe uses
1806 */
1807 
get_ship(lua_State * L)1808 int LuaTribeDescription::get_ship(lua_State* L) {
1809 	lua_pushstring(L, get_egbase(L).tribes().get_ship_descr(get()->ship())->name());
1810 	return 1;
1811 }
1812 
1813 /* RST
1814    .. attribute:: soldier
1815 
1816          (RO) the :class:`string` internal name of the soldier type that this tribe uses
1817 */
1818 
get_soldier(lua_State * L)1819 int LuaTribeDescription::get_soldier(lua_State* L) {
1820 	lua_pushstring(L, get_egbase(L).tribes().get_worker_descr(get()->soldier())->name());
1821 	return 1;
1822 }
1823 
1824 /* RST
1825    .. attribute:: wares
1826 
1827          (RO) an array of :class:`LuaWareDescription` with all the wares that the tribe can use.
1828 */
get_wares(lua_State * L)1829 int LuaTribeDescription::get_wares(lua_State* L) {
1830 	const TribeDescr& tribe = *get();
1831 	lua_newtable(L);
1832 	int counter = 0;
1833 	for (DescriptionIndex ware : tribe.wares()) {
1834 		lua_pushinteger(L, ++counter);
1835 		to_lua<LuaWareDescription>(L, new LuaWareDescription(tribe.get_ware_descr(ware)));
1836 		lua_settable(L, -3);
1837 	}
1838 	return 1;
1839 }
1840 
1841 /* RST
1842    .. attribute:: workers
1843 
1844          (RO) an array of :class:`LuaWorkerDescription` with all the workers that the tribe can use,
1845               casted to their appropriate subclasses.
1846 */
get_workers(lua_State * L)1847 int LuaTribeDescription::get_workers(lua_State* L) {
1848 	const TribeDescr& tribe = *get();
1849 	lua_newtable(L);
1850 	int counter = 0;
1851 	for (DescriptionIndex worker : tribe.workers()) {
1852 		lua_pushinteger(L, ++counter);
1853 		upcasted_map_object_descr_to_lua(L, tribe.get_worker_descr(worker));
1854 		lua_settable(L, -3);
1855 	}
1856 	return 1;
1857 }
1858 
1859 /* RST
1860    .. method:: has_building(buildingname)
1861 
1862       Returns true if buildingname is a building and the tribe can use it.
1863 
1864       :returns: :const:`true` or :const:`false`
1865       :rtype: :class:`bool`
1866 */
has_building(lua_State * L)1867 int LuaTribeDescription::has_building(lua_State* L) {
1868 	const std::string buildingname = luaL_checkstring(L, 2);
1869 	const DescriptionIndex index = get_egbase(L).tribes().building_index(buildingname);
1870 	lua_pushboolean(L, get()->has_building(index));
1871 	return 1;
1872 }
1873 
1874 /* RST
1875    .. method:: has_ware(warename)
1876 
1877       Returns true if warename is a ware and the tribe uses it.
1878 
1879       :returns: :const:`true` or :const:`false`
1880       :rtype: :class:`bool`
1881 */
has_ware(lua_State * L)1882 int LuaTribeDescription::has_ware(lua_State* L) {
1883 	const std::string warename = luaL_checkstring(L, 2);
1884 	const DescriptionIndex index = get_egbase(L).tribes().ware_index(warename);
1885 	lua_pushboolean(L, get()->has_ware(index));
1886 	return 1;
1887 }
1888 
1889 /* RST
1890    .. method:: has_worker(workername)
1891 
1892       Returns true if workername is a worker and the tribe can use it.
1893 
1894       :returns: :const:`true` or :const:`false`
1895       :rtype: :class:`bool`
1896 */
has_worker(lua_State * L)1897 int LuaTribeDescription::has_worker(lua_State* L) {
1898 	const std::string workername = luaL_checkstring(L, 2);
1899 	const DescriptionIndex index = get_egbase(L).tribes().worker_index(workername);
1900 	lua_pushboolean(L, get()->has_worker(index));
1901 	return 1;
1902 }
1903 
1904 /* RST
1905 MapObjectDescription
1906 --------------------
1907 
1908 .. class:: MapObjectDescription
1909 
1910    A static description of a tribe's map object, so it can be used in help files
1911    without having to access an actual object on the map.
1912    This class contains the properties that are common to all map objects such as buildings or wares.
1913 
1914    The dynamic MapObject class corresponding to this class is the base class for all Objects in
1915    widelands, including immovables and Bobs. This class can't be instantiated directly, but provides
1916    the base for all others.
1917 */
1918 const char LuaMapObjectDescription::className[] = "MapObjectDescription";
1919 const MethodType<LuaMapObjectDescription> LuaMapObjectDescription::Methods[] = {
1920    {nullptr, nullptr},
1921 };
1922 const PropertyType<LuaMapObjectDescription> LuaMapObjectDescription::Properties[] = {
1923    PROP_RO(LuaMapObjectDescription, descname),  PROP_RO(LuaMapObjectDescription, helptext_script),
1924    PROP_RO(LuaMapObjectDescription, icon_name), PROP_RO(LuaMapObjectDescription, name),
1925    PROP_RO(LuaMapObjectDescription, type_name), {nullptr, nullptr, nullptr},
1926 };
1927 
1928 // Only base classes can be persisted.
__persist(lua_State *)1929 void LuaMapObjectDescription::__persist(lua_State*) {
1930 	NEVER_HERE();
1931 }
1932 
__unpersist(lua_State *)1933 void LuaMapObjectDescription::__unpersist(lua_State*) {
1934 	NEVER_HERE();
1935 }
1936 
1937 /*
1938  ==========================================================
1939  PROPERTIES
1940  ==========================================================
1941  */
1942 
1943 /* RST
1944    .. attribute:: descname
1945 
1946          (RO) a :class:`string` with the map object's localized name
1947 */
1948 
get_descname(lua_State * L)1949 int LuaMapObjectDescription::get_descname(lua_State* L) {
1950 	lua_pushstring(L, get()->descname());
1951 	return 1;
1952 }
1953 
1954 /* RST
1955    .. attribute:: helptext_script
1956 
1957          (RO) The path and filename to the helptext script. Can be empty.
1958 */
get_helptext_script(lua_State * L)1959 int LuaMapObjectDescription::get_helptext_script(lua_State* L) {
1960 	lua_pushstring(L, get()->helptext_script());
1961 	return 1;
1962 }
1963 
1964 /* RST
1965    .. attribute:: icon_name
1966 
1967          (RO) the filename for the menu icon.
1968 */
get_icon_name(lua_State * L)1969 int LuaMapObjectDescription::get_icon_name(lua_State* L) {
1970 	lua_pushstring(L, get()->icon_filename());
1971 	return 1;
1972 }
1973 
1974 /* RST
1975    .. attribute:: name
1976 
1977          (RO) a :class:`string` with the map object's internal name
1978 */
1979 
get_name(lua_State * L)1980 int LuaMapObjectDescription::get_name(lua_State* L) {
1981 	lua_pushstring(L, get()->name());
1982 	return 1;
1983 }
1984 
1985 /* RST
1986    .. attribute:: type_name
1987 
1988          (RO) the map object's type as a string. Map object types are
1989          organized in a hierarchy, where an element that's lower in the
1990          hierarchy has all the properties of the higher-placed types,
1991          as well as its own additional properties. Any map object's
1992          description that isn't linked below can be accessed via its
1993          higher types, e.g. a ``bob`` is a
1994          :class:`general map object <MapObjectDescription>`, and a
1995          ``carrier`` is a :class:`worker <WorkerDescription>` as well as a
1996          general map object. Possible values are:
1997 
1998          * **Bobs:** Bobs are map objects that can move around the map.
1999            Bob types are:
2000 
2001            * :class:`bob <BobDescription>`, the abstract base type for
2002              all bobs,
2003            * :class:`critter <CritterDescription>`, animals that aren't
2004              controlled by any tribe,
2005            * :class:`ship <ShipDescription>`, a sea-going vessel
2006              belonging to a tribe that can ferry wares or an expedition,
2007            * :class:`worker <WorkerDescription>`, a worker belonging to
2008              a tribe,
2009            * :class:`carrier <CarrierDescription>`, a specialized
2010              worker for carrying items along a road,
2011            * :class:`soldier <SoldierDescription>`, a specialized worker
2012              that will fight for its tribe.
2013 
2014          * **Wares:** :class:`ware <WareDescription>`, a ware used by
2015            buildings to produce other wares, workers or ships
2016          * **Immovables:** Immovables are map objects that have a fixed
2017            position on the map, like buildings or trees. Immovable types are:
2018 
2019            * :class:`immovable <ImmovableDescription>` General immovables
2020              that can belong to a tribe (e.g. a wheat field) or to the
2021              world (e.g. trees or rocks).
2022 
2023            * **Buildings:** Buildings always belong to a tribe. Building
2024              types are:
2025 
2026              * :class:`building <BuildingDescription>`, the base class
2027                for all buildings
2028              * :class:`constructionsite <ConstructionSiteDescription>`,
2029                an actual building is being constructed here,
2030              * :class:`dismantlesite <DismantleSiteDescription>`, an
2031                actual building is being dismantled here,
2032              * :class:`warehouse <WarehouseDescription>`, a warehouse
2033                can store wares and workers. Headquarters and ports are
2034                special tapes of warehouses, but they belong to the same
2035                class,
2036              * :class:`militarysite <MilitarySiteDescription>`, a
2037                building manned by soldiers to expand a tribe's territory,
2038              * :class:`productionsite <ProductionSiteDescription>`, the
2039                most common type of building, which can produce wares,
2040              * :class:`trainingsite <TrainingSiteDescription>`, a
2041                specialized productionsite for improving soldiers.
2042 
2043            * **Other Immovables:** Specialized immovables that aren't buildings:
2044 
2045              * :class:`flag <FlagDescription>`, a flag that can hold
2046                wares for transport,
2047              * :class:`road <RoadDescription>`, a road or waterway
2048                connecting two flags,
2049              * :class:`portdock <PortdockDescription>`, a 'parking space'
2050                on water terrain where ships can load/unload wares and
2051                workers. A portdock is invisible to the player and one is
2052                automatically placed next to each port building.
2053 
2054          * **Abstract:** These types are abstract map objects that are used by the engine and are
2055            not visible on the map.
2056 
2057            * :class:`battle <BattleDescription>`, holds information
2058              about two soldiers in a fight,
2059            * :class:`fleet <FleetDescription>`, holds information for
2060              managing ships.
2061 */
get_type_name(lua_State * L)2062 int LuaMapObjectDescription::get_type_name(lua_State* L) {
2063 	lua_pushstring(L, to_string(get()->type()));
2064 	return 1;
2065 }
2066 
2067 /* RST
2068 ImmovableDescription
2069 --------------------
2070 
2071 .. class:: ImmovableDescription
2072 
2073    Child of: :class:`MapObjectDescription`
2074 
2075    A static description of a :class:`base immovable <BaseImmovable>`, so it can be used in help
2076    files without having to access an actual immovable on the map. See also
2077    :class:`MapObjectDescription` for more properties.
2078 */
2079 const char LuaImmovableDescription::className[] = "ImmovableDescription";
2080 const MethodType<LuaImmovableDescription> LuaImmovableDescription::Methods[] = {
2081    METHOD(LuaImmovableDescription, has_attribute),
2082    METHOD(LuaImmovableDescription, probability_to_grow),
2083    {nullptr, nullptr},
2084 };
2085 const PropertyType<LuaImmovableDescription> LuaImmovableDescription::Properties[] = {
2086    PROP_RO(LuaImmovableDescription, species),
2087    PROP_RO(LuaImmovableDescription, buildcost),
2088    PROP_RO(LuaImmovableDescription, editor_category),
2089    PROP_RO(LuaImmovableDescription, terrain_affinity),
2090    PROP_RO(LuaImmovableDescription, owner_type),
2091    PROP_RO(LuaImmovableDescription, size),
2092    {nullptr, nullptr, nullptr},
2093 };
2094 
__persist(lua_State * L)2095 void LuaImmovableDescription::__persist(lua_State* L) {
2096 	const ImmovableDescr* descr = get();
2097 	PERS_STRING("name", descr->name());
2098 }
2099 
__unpersist(lua_State * L)2100 void LuaImmovableDescription::__unpersist(lua_State* L) {
2101 	std::string name;
2102 	UNPERS_STRING("name", name)
2103 	const World& world = get_egbase(L).world();
2104 	DescriptionIndex idx = world.get_immovable_index(name);
2105 	if (idx != INVALID_INDEX) {
2106 		set_description_pointer(world.get_immovable_descr(idx));
2107 	} else {
2108 		const Tribes& tribes = get_egbase(L).tribes();
2109 		idx = tribes.safe_immovable_index(name);
2110 		set_description_pointer(tribes.get_immovable_descr(idx));
2111 	}
2112 }
2113 
2114 /* RST
2115    .. attribute:: species
2116 
2117          the species name of a tree for editor lists
2118 
2119          (RO) the localized species name of the immovable, or an empty string if it has none.
2120 */
get_species(lua_State * L)2121 int LuaImmovableDescription::get_species(lua_State* L) {
2122 	lua_pushstring(L, get()->species());
2123 	return 1;
2124 }
2125 
2126 /* RST
2127    .. attribute:: buildcost
2128 
2129          (RO) a table of ware-to-count pairs, describing the build cost for the
2130          immovable.
2131 */
get_buildcost(lua_State * L)2132 int LuaImmovableDescription::get_buildcost(lua_State* L) {
2133 	return wares_or_workers_map_to_lua(L, get()->buildcost(), MapObjectType::WARE);
2134 }
2135 
2136 /* RST
2137    .. attribute:: editor_category
2138 
2139          the name and descname of the editor category of this immovable
2140 
2141          (RO) a table with "name" and "descname" entries for the editor category, or nil if it has
2142          none.
2143 */
get_editor_category(lua_State * L)2144 int LuaImmovableDescription::get_editor_category(lua_State* L) {
2145 	const EditorCategory* editor_category = get()->editor_category();
2146 	if (editor_category != nullptr) {
2147 		lua_newtable(L);
2148 		lua_pushstring(L, "name");
2149 		lua_pushstring(L, editor_category->name());
2150 		lua_settable(L, -3);
2151 		lua_pushstring(L, "descname");
2152 		lua_pushstring(L, editor_category->descname());
2153 		lua_settable(L, -3);
2154 	} else {
2155 		lua_pushnil(L);
2156 	}
2157 	return 1;
2158 }
2159 
2160 /* RST
2161    .. attribute:: terrain_affinity
2162 
2163          returns the terrain affinity values for this immovable
2164 
2165          (RO) a table containing numbers labeled as pickiness (uint), preferred_fertility (uint),
2166          preferred_humidity (uint), and preferred_temperature (uint),
2167          or nil if the immovable has no terrain affinity.
2168 */
get_terrain_affinity(lua_State * L)2169 int LuaImmovableDescription::get_terrain_affinity(lua_State* L) {
2170 	if (get()->has_terrain_affinity()) {
2171 		const TerrainAffinity& affinity = get()->terrain_affinity();
2172 		lua_newtable(L);
2173 		lua_pushstring(L, "pickiness");
2174 		lua_pushuint32(L, affinity.pickiness());
2175 		lua_settable(L, -3);
2176 		lua_pushstring(L, "preferred_fertility");
2177 		lua_pushuint32(L, affinity.preferred_fertility());
2178 		lua_settable(L, -3);
2179 		lua_pushstring(L, "preferred_humidity");
2180 		lua_pushuint32(L, affinity.preferred_humidity());
2181 		lua_settable(L, -3);
2182 		lua_pushstring(L, "preferred_temperature");
2183 		lua_pushuint32(L, affinity.preferred_temperature());
2184 		lua_settable(L, -3);
2185 	} else {
2186 		lua_pushnil(L);
2187 	}
2188 	return 1;
2189 }
2190 
2191 /* RST
2192    .. attribute:: owner_type
2193 
2194          the owner type of this immovable
2195 
2196          (RO) "world" for world immovables and "tribe" for tribe immovables.
2197 */
get_owner_type(lua_State * L)2198 int LuaImmovableDescription::get_owner_type(lua_State* L) {
2199 	switch (get()->owner_type()) {
2200 	case MapObjectDescr::OwnerType::kWorld:
2201 		lua_pushstring(L, "world");
2202 		break;
2203 	case MapObjectDescr::OwnerType::kTribe:
2204 		lua_pushstring(L, "tribe");
2205 		break;
2206 	}
2207 	return 1;
2208 }
2209 
2210 /* RST
2211    .. attribute:: size
2212 
2213       (RO) The size of this immovable. Can be either of
2214 
2215       * :const:`none` -- Example: mushrooms. Immovables will be destroyed when
2216          something else is built on this field.
2217       * :const:`small` -- Example: trees or flags
2218       * :const:`medium` -- Example: Medium sized buildings
2219       * :const:`big` -- Example: Big sized buildings or rocks
2220 */
get_size(lua_State * L)2221 int LuaImmovableDescription::get_size(lua_State* L) {
2222 	try {
2223 		lua_pushstring(L, BaseImmovable::size_to_string(get()->get_size()));
2224 	} catch (std::exception&) {
2225 		report_error(L, "Unknown size %i in LuaImmovableDescription::get_size: %s", get()->get_size(),
2226 		             get()->name().c_str());
2227 	}
2228 	return 1;
2229 }
2230 
2231 /*
2232  ==========================================================
2233  METHODS
2234  ==========================================================
2235  */
2236 
2237 /* RST
2238    .. method:: has_attribute
2239 
2240       whether the immovable has the given attribute
2241 
2242       :arg attribute_name: The attribute that we are checking for.
2243       :type attribute_name: :class:`string`
2244 
2245          (RO) true if the immovable has the attribute, false otherwise.
2246 */
has_attribute(lua_State * L)2247 int LuaImmovableDescription::has_attribute(lua_State* L) {
2248 	if (lua_gettop(L) != 2) {
2249 		report_error(L, "Takes only one argument.");
2250 	}
2251 	const uint32_t attribute_id = get()->get_attribute_id(luaL_checkstring(L, 2));
2252 	lua_pushboolean(L, get()->has_attribute(attribute_id));
2253 	return 1;
2254 }
2255 
2256 /* RST
2257    .. method:: probability_to_grow
2258 
2259       :arg terrain: The terrain that we are checking the probability for.
2260       :type terrain: :class:`wl.map.TerrainDescription`
2261 
2262       (RO) A double describing the probability that this tree will grow on the given terrain.
2263            Returns nil if this immovable tree has no terrain affinity (all trees should have one).
2264 */
probability_to_grow(lua_State * L)2265 int LuaImmovableDescription::probability_to_grow(lua_State* L) {
2266 	if (lua_gettop(L) != 2) {
2267 		report_error(L, "Takes only one argument.");
2268 	}
2269 	if (get()->has_terrain_affinity()) {
2270 		const TerrainDescription* terrain =
2271 		   (*get_user_class<LuaMaps::LuaTerrainDescription>(L, 2))->get();
2272 		lua_pushdouble(L, Widelands::probability_to_grow(get()->terrain_affinity(), *terrain) /
2273 		                     static_cast<double>(Widelands::TerrainAffinity::kPrecisionFactor));
2274 	} else {
2275 		lua_pushnil(L);
2276 	}
2277 	return 1;
2278 }
2279 
2280 /* RST
2281 BuildingDescription
2282 -------------------
2283 
2284 .. class:: BuildingDescription
2285 
2286    Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`
2287 
2288    A static description of a tribe's building, so it can be used in help files
2289    without having to access an actual building on the map.
2290    This class contains the properties that are common to all buildings.
2291    Further properties are implemented in the subclasses.
2292    See the parent classes for more properties.
2293 */
2294 const char LuaBuildingDescription::className[] = "BuildingDescription";
2295 const MethodType<LuaBuildingDescription> LuaBuildingDescription::Methods[] = {
2296    {nullptr, nullptr},
2297 };
2298 const PropertyType<LuaBuildingDescription> LuaBuildingDescription::Properties[] = {
2299    PROP_RO(LuaBuildingDescription, buildcost),
2300    PROP_RO(LuaBuildingDescription, buildable),
2301    PROP_RO(LuaBuildingDescription, conquers),
2302    PROP_RO(LuaBuildingDescription, destructible),
2303    PROP_RO(LuaBuildingDescription, enhanced),
2304    PROP_RO(LuaBuildingDescription, enhanced_from),
2305    PROP_RO(LuaBuildingDescription, enhancement_cost),
2306    PROP_RO(LuaBuildingDescription, enhancement),
2307    PROP_RO(LuaBuildingDescription, is_mine),
2308    PROP_RO(LuaBuildingDescription, is_port),
2309    PROP_RO(LuaBuildingDescription, size),
2310    PROP_RO(LuaBuildingDescription, returned_wares),
2311    PROP_RO(LuaBuildingDescription, returned_wares_enhanced),
2312    PROP_RO(LuaBuildingDescription, vision_range),
2313    PROP_RO(LuaBuildingDescription, workarea_radius),
2314    {nullptr, nullptr, nullptr},
2315 };
2316 
__persist(lua_State * L)2317 void LuaBuildingDescription::__persist(lua_State* L) {
2318 	const BuildingDescr* descr = get();
2319 	PERS_STRING("name", descr->name());
2320 }
2321 
__unpersist(lua_State * L)2322 void LuaBuildingDescription::__unpersist(lua_State* L) {
2323 	std::string name;
2324 	UNPERS_STRING("name", name)
2325 	const Tribes& tribes = get_egbase(L).tribes();
2326 	DescriptionIndex idx = tribes.safe_building_index(name.c_str());
2327 	set_description_pointer(tribes.get_building_descr(idx));
2328 }
2329 
2330 /*
2331  ==========================================================
2332  PROPERTIES
2333  ==========================================================
2334  */
2335 
2336 /* RST
2337    .. attribute:: buildcost
2338 
2339          (RO) a list of ware build cost for the building.
2340 */
get_buildcost(lua_State * L)2341 int LuaBuildingDescription::get_buildcost(lua_State* L) {
2342 	return wares_or_workers_map_to_lua(L, get()->buildcost(), MapObjectType::WARE);
2343 }
2344 
2345 /* RST
2346    .. attribute:: buildable
2347 
2348          (RO) true if the building can be built.
2349 */
get_buildable(lua_State * L)2350 int LuaBuildingDescription::get_buildable(lua_State* L) {
2351 	lua_pushboolean(L, get()->is_buildable());
2352 	return 1;
2353 }
2354 
2355 /* RST
2356    .. attribute:: conquers
2357 
2358          (RO) the conquer range of the building as an int.
2359 */
get_conquers(lua_State * L)2360 int LuaBuildingDescription::get_conquers(lua_State* L) {
2361 	lua_pushinteger(L, get()->get_conquers());
2362 	return 1;
2363 }
2364 
2365 /* RST
2366    .. attribute:: destructible
2367 
2368          (RO) true if the building is destructible.
2369 */
get_destructible(lua_State * L)2370 int LuaBuildingDescription::get_destructible(lua_State* L) {
2371 	lua_pushboolean(L, get()->is_destructible());
2372 	return 1;
2373 }
2374 
2375 /* RST
2376    .. attribute:: enhanced
2377 
2378          (RO) true if the building is enhanced from another building.
2379 */
get_enhanced(lua_State * L)2380 int LuaBuildingDescription::get_enhanced(lua_State* L) {
2381 	lua_pushboolean(L, get()->is_enhanced());
2382 	return 1;
2383 }
2384 
2385 /* RST
2386    .. attribute:: enhanced_from
2387 
2388          (RO) returns the building that this was enhanced from, or nil if this isn't an enhanced
2389          building.
2390 */
get_enhanced_from(lua_State * L)2391 int LuaBuildingDescription::get_enhanced_from(lua_State* L) {
2392 	if (get()->is_enhanced()) {
2393 		const DescriptionIndex& enhanced_from = get()->enhanced_from();
2394 		EditorGameBase& egbase = get_egbase(L);
2395 		assert(egbase.tribes().building_exists(enhanced_from));
2396 		return upcasted_map_object_descr_to_lua(L, egbase.tribes().get_building_descr(enhanced_from));
2397 	}
2398 	lua_pushnil(L);
2399 	return 0;
2400 }
2401 
2402 /* RST
2403    .. attribute:: enhancement_cost
2404 
2405          (RO) a list of ware cost for enhancing to this building type.
2406 */
get_enhancement_cost(lua_State * L)2407 int LuaBuildingDescription::get_enhancement_cost(lua_State* L) {
2408 	return wares_or_workers_map_to_lua(L, get()->enhancement_cost(), MapObjectType::WARE);
2409 }
2410 
2411 /* RST
2412    .. attribute:: enhancement
2413 
2414       (RO) a building description that this building can enhance to.
2415 */
get_enhancement(lua_State * L)2416 int LuaBuildingDescription::get_enhancement(lua_State* L) {
2417 	const DescriptionIndex enhancement = get()->enhancement();
2418 	if (enhancement == INVALID_INDEX) {
2419 		return 0;
2420 	}
2421 	return upcasted_map_object_descr_to_lua(
2422 	   L, get_egbase(L).tribes().get_building_descr(enhancement));
2423 }
2424 
2425 /* RST
2426    .. attribute:: is_mine
2427 
2428          (RO) true if the building is a mine.
2429 */
get_is_mine(lua_State * L)2430 int LuaBuildingDescription::get_is_mine(lua_State* L) {
2431 	lua_pushboolean(L, get()->get_ismine());
2432 	return 1;
2433 }
2434 
2435 /* RST
2436    .. attribute:: is_port
2437 
2438          (RO) true if the building is a port.
2439 */
get_is_port(lua_State * L)2440 int LuaBuildingDescription::get_is_port(lua_State* L) {
2441 	lua_pushboolean(L, get()->get_isport());
2442 	return 1;
2443 }
2444 
2445 /* RST
2446    .. attribute:: size
2447 
2448       (RO) The size of this building. Can be either of
2449 
2450       * :const:`small` -- Small sized buildings
2451       * :const:`medium` -- Medium sized buildings
2452       * :const:`big` -- Big sized buildings
2453 */
get_size(lua_State * L)2454 int LuaBuildingDescription::get_size(lua_State* L) {
2455 	try {
2456 		lua_pushstring(L, BaseImmovable::size_to_string(get()->get_size()));
2457 	} catch (std::exception&) {
2458 		report_error(L, "Unknown size %i in LuaBuildingDescription::get_size: %s", get()->get_size(),
2459 		             get()->name().c_str());
2460 	}
2461 	return 1;
2462 }
2463 
2464 /* RST
2465    .. attribute:: returned_wares
2466 
2467          (RO) a list of wares returned upon dismantling.
2468 */
get_returned_wares(lua_State * L)2469 int LuaBuildingDescription::get_returned_wares(lua_State* L) {
2470 	return wares_or_workers_map_to_lua(L, get()->returned_wares(), MapObjectType::WARE);
2471 }
2472 
2473 /* RST
2474    .. attribute:: returned_wares_enhanced
2475 
2476          (RO) a list of wares returned upon dismantling an enhanced building.
2477 */
get_returned_wares_enhanced(lua_State * L)2478 int LuaBuildingDescription::get_returned_wares_enhanced(lua_State* L) {
2479 	return wares_or_workers_map_to_lua(L, get()->returned_wares_enhanced(), MapObjectType::WARE);
2480 }
2481 
2482 /* RST
2483    .. attribute:: vision range
2484 
2485          (RO) the vision_range of the building as an int.
2486 */
get_vision_range(lua_State * L)2487 int LuaBuildingDescription::get_vision_range(lua_State* L) {
2488 	lua_pushinteger(L, get()->vision_range());
2489 	return 1;
2490 }
2491 
2492 /* RST
2493    .. attribute:: workarea_radius
2494 
2495          (RO) the first workarea_radius of the building as an int,
2496               nil in case bulding has no workareas
2497 */
get_workarea_radius(lua_State * L)2498 int LuaBuildingDescription::get_workarea_radius(lua_State* L) {
2499 	const WorkareaInfo& workareaInfo = get()->workarea_info();
2500 	if (!workareaInfo.empty()) {
2501 		lua_pushinteger(L, workareaInfo.begin()->first);
2502 	} else {
2503 		lua_pushnil(L);
2504 	}
2505 	return 1;
2506 }
2507 
2508 /* RST
2509 ConstructionSiteDescription
2510 ---------------------------
2511 
2512 .. class:: ConstructionSiteDescription
2513 
2514    Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`,
2515    :class:`BuildingDescription`
2516 
2517    A static description of a tribe's constructionsite, so it can be used in help files
2518    without having to access an actual building on the map.
2519    See the parent classes for more properties.
2520 */
2521 const char LuaConstructionSiteDescription::className[] = "ConstructionSiteDescription";
2522 const MethodType<LuaConstructionSiteDescription> LuaConstructionSiteDescription::Methods[] = {
2523    {nullptr, nullptr},
2524 };
2525 const PropertyType<LuaConstructionSiteDescription> LuaConstructionSiteDescription::Properties[] = {
2526    {nullptr, nullptr, nullptr},
2527 };
2528 
2529 /* RST
2530 DismantleSiteDescription
2531 ---------------------------
2532 
2533 .. class:: DismantleSiteDescription
2534 
2535    Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`,
2536    :class:`BuildingDescription`
2537 
2538    A static description of a tribe's dismantlesite, so it can be used in help files
2539    without having to access an actual building on the map.
2540    See the parent classes for more properties.
2541 */
2542 const char LuaDismantleSiteDescription::className[] = "DismantleSiteDescription";
2543 const MethodType<LuaDismantleSiteDescription> LuaDismantleSiteDescription::Methods[] = {
2544    {nullptr, nullptr},
2545 };
2546 const PropertyType<LuaDismantleSiteDescription> LuaDismantleSiteDescription::Properties[] = {
2547    {nullptr, nullptr, nullptr},
2548 };
2549 
2550 /* RST
2551 ProductionSiteDescription
2552 -------------------------
2553 
2554 .. class:: ProductionSiteDescription
2555 
2556    Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`,
2557    :class:`BuildingDescription`
2558 
2559    A static description of a tribe's productionsite, so it can be used in help files
2560    without having to access an actual building on the map.
2561    This class contains the properties for productionsites that have workers.
2562    For militarysites and trainingsites, please use the subclasses.
2563    See the parent classes for more properties.
2564 */
2565 const char LuaProductionSiteDescription::className[] = "ProductionSiteDescription";
2566 const MethodType<LuaProductionSiteDescription> LuaProductionSiteDescription::Methods[] = {
2567    METHOD(LuaProductionSiteDescription, consumed_wares_workers),
2568    METHOD(LuaProductionSiteDescription, produced_wares),
2569    METHOD(LuaProductionSiteDescription, recruited_workers),
2570    {nullptr, nullptr},
2571 };
2572 const PropertyType<LuaProductionSiteDescription> LuaProductionSiteDescription::Properties[] = {
2573    PROP_RO(LuaProductionSiteDescription, inputs),
2574    PROP_RO(LuaProductionSiteDescription, output_ware_types),
2575    PROP_RO(LuaProductionSiteDescription, output_worker_types),
2576    PROP_RO(LuaProductionSiteDescription, production_programs),
2577    PROP_RO(LuaProductionSiteDescription, working_positions),
2578    {nullptr, nullptr, nullptr},
2579 };
2580 
2581 /*
2582  ==========================================================
2583  PROPERTIES
2584  ==========================================================
2585  */
2586 
2587 /* RST
2588    .. attribute:: inputs
2589 
2590       (RO) An array with :class:`LuaWareDescription` containing the wares that
2591       the productionsite needs for its production.
2592 */
get_inputs(lua_State * L)2593 int LuaProductionSiteDescription::get_inputs(lua_State* L) {
2594 	lua_newtable(L);
2595 	int index = 1;
2596 	for (const auto& input_ware : get()->input_wares()) {
2597 		lua_pushint32(L, index++);
2598 		const WareDescr* descr = get_egbase(L).tribes().get_ware_descr(input_ware.first);
2599 		to_lua<LuaWareDescription>(L, new LuaWareDescription(descr));
2600 		lua_settable(L, -3);
2601 	}
2602 	return 1;
2603 }
2604 
2605 /* RST
2606    .. attribute:: output_ware_types
2607 
2608       (RO) An array with :class:`LuaWareDescription` containing the wares that
2609       the productionsite can produce.
2610 */
get_output_ware_types(lua_State * L)2611 int LuaProductionSiteDescription::get_output_ware_types(lua_State* L) {
2612 	lua_newtable(L);
2613 	int index = 1;
2614 	for (const auto& ware_index : get()->output_ware_types()) {
2615 		lua_pushint32(L, index++);
2616 		const WareDescr* descr = get_egbase(L).tribes().get_ware_descr(ware_index);
2617 		to_lua<LuaWareDescription>(L, new LuaWareDescription(descr));
2618 		lua_rawset(L, -3);
2619 	}
2620 
2621 	return 1;
2622 }
2623 
2624 /* RST
2625    .. attribute:: output_worker_types
2626 
2627       (RO) An array with :class:`LuaWorkerDescription` containing the workers that
2628       the productionsite can produce.
2629 */
get_output_worker_types(lua_State * L)2630 int LuaProductionSiteDescription::get_output_worker_types(lua_State* L) {
2631 	lua_newtable(L);
2632 	int index = 1;
2633 	for (const auto& worker_index : get()->output_worker_types()) {
2634 		lua_pushint32(L, index++);
2635 		const WorkerDescr* descr = get_egbase(L).tribes().get_worker_descr(worker_index);
2636 		to_lua<LuaWorkerDescription>(L, new LuaWorkerDescription(descr));
2637 		lua_rawset(L, -3);
2638 	}
2639 
2640 	return 1;
2641 }
2642 
2643 /* RST
2644    .. attribute:: production_programs
2645 
2646       (RO) An array with the production program names as string.
2647 */
get_production_programs(lua_State * L)2648 int LuaProductionSiteDescription::get_production_programs(lua_State* L) {
2649 	lua_newtable(L);
2650 	int index = 1;
2651 	for (const auto& program : get()->programs()) {
2652 		lua_pushint32(L, index++);
2653 		lua_pushstring(L, program.first);
2654 		lua_settable(L, -3);
2655 	}
2656 	return 1;
2657 }
2658 
2659 /* RST
2660    .. attribute:: working_positions
2661 
2662       (RO) An array with :class:`WorkerDescription` containing the workers that
2663       can work here with their multiplicity, i.e. for a atlantean mine this
2664       would be { miner, miner, miner }.
2665 */
get_working_positions(lua_State * L)2666 int LuaProductionSiteDescription::get_working_positions(lua_State* L) {
2667 	lua_newtable(L);
2668 	int index = 1;
2669 	for (const auto& positions_pair : get()->working_positions()) {
2670 		int amount = positions_pair.second;
2671 		while (amount > 0) {
2672 			lua_pushint32(L, index++);
2673 			const WorkerDescr* descr = get_egbase(L).tribes().get_worker_descr(positions_pair.first);
2674 			to_lua<LuaWorkerDescription>(L, new LuaWorkerDescription(descr));
2675 			lua_settable(L, -3);
2676 			--amount;
2677 		}
2678 	}
2679 	return 1;
2680 }
2681 
2682 /* RST
2683    .. attribute:: consumed_wares_workers
2684 
2685       :arg program_name: the name of the production program that we want to get the consumed wares
2686          for :type tribename: :class:`string`
2687 
2688       (RO) Returns a table of {{ware name}, ware amount} for the wares consumed by this production
2689       program. Multiple entries in {ware name} are alternatives (OR logic)).
2690 */
consumed_wares_workers(lua_State * L)2691 int LuaProductionSiteDescription::consumed_wares_workers(lua_State* L) {
2692 	std::string program_name = luaL_checkstring(L, -1);
2693 	const Widelands::ProductionSiteDescr::Programs& programs = get()->programs();
2694 	if (programs.count(program_name) == 1) {
2695 		const ProductionProgram& program = *programs.at(program_name);
2696 		lua_newtable(L);
2697 		int counter = 0;
2698 		for (const auto& group : program.consumed_wares_workers()) {
2699 			lua_pushuint32(L, ++counter);
2700 			lua_newtable(L);
2701 			for (const auto& entry : group.first) {
2702 				const DescriptionIndex& index = entry.first;
2703 				if (entry.second == wwWARE) {
2704 					lua_pushstring(L, get_egbase(L).tribes().get_ware_descr(index)->name());
2705 				} else {
2706 					lua_pushstring(L, get_egbase(L).tribes().get_worker_descr(index)->name());
2707 				}
2708 				lua_pushuint32(L, group.second);
2709 				lua_settable(L, -3);
2710 			}
2711 			lua_settable(L, -3);
2712 		}
2713 	}
2714 	return 1;
2715 }
2716 
2717 /* RST
2718    .. attribute:: produced_wares
2719 
2720       :arg program_name: the name of the production program that we want to get the produced wares
2721          for :type tribename: :class:`string`
2722 
2723          (RO) Returns a table of {ware name, ware amount} for the wares produced by this production
2724          program
2725 */
produced_wares(lua_State * L)2726 int LuaProductionSiteDescription::produced_wares(lua_State* L) {
2727 	std::string program_name = luaL_checkstring(L, -1);
2728 	const Widelands::ProductionSiteDescr::Programs& programs = get()->programs();
2729 	if (programs.count(program_name) == 1) {
2730 		const ProductionProgram& program = *programs.at(program_name);
2731 		return wares_or_workers_map_to_lua(L, program.produced_wares(), MapObjectType::WARE);
2732 	}
2733 	return 1;
2734 }
2735 
2736 /* RST
2737    .. attribute:: recruited_workers
2738 
2739       :arg program_name: the name of the production program that we want to get the recruited
2740          workers for :type tribename: :class:`string`
2741 
2742          (RO) Returns a table of {worker name, worker amount} for the workers recruited
2743          by this production program
2744 */
recruited_workers(lua_State * L)2745 int LuaProductionSiteDescription::recruited_workers(lua_State* L) {
2746 	std::string program_name = luaL_checkstring(L, -1);
2747 	const Widelands::ProductionSiteDescr::Programs& programs = get()->programs();
2748 	if (programs.count(program_name) == 1) {
2749 		const ProductionProgram& program = *programs.at(program_name);
2750 		return wares_or_workers_map_to_lua(L, program.recruited_workers(), MapObjectType::WORKER);
2751 	}
2752 	return 1;
2753 }
2754 
2755 /* RST
2756 MilitarySiteDescription
2757 -----------------------
2758 
2759 .. class:: MilitarySiteDescription
2760 
2761    Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`,
2762    :class:`BuildingDescription`
2763 
2764    A static description of a tribe's militarysite, so it can be used in help files
2765    without having to access an actual building on the map.
2766    A militarysite can garrison and heal soldiers, and it will expand your territory.
2767    See the parent classes for more properties.
2768 */
2769 const char LuaMilitarySiteDescription::className[] = "MilitarySiteDescription";
2770 const MethodType<LuaMilitarySiteDescription> LuaMilitarySiteDescription::Methods[] = {
2771    {nullptr, nullptr},
2772 };
2773 const PropertyType<LuaMilitarySiteDescription> LuaMilitarySiteDescription::Properties[] = {
2774    PROP_RO(LuaMilitarySiteDescription, heal_per_second),
2775    PROP_RO(LuaMilitarySiteDescription, max_number_of_soldiers),
2776    {nullptr, nullptr, nullptr},
2777 };
2778 
2779 /*
2780  ==========================================================
2781  PROPERTIES
2782  ==========================================================
2783  */
2784 
2785 /* RST
2786    .. attribute:: heal_per_second
2787 
2788       (RO) The number of health healed per second by the militarysite
2789 */
get_heal_per_second(lua_State * L)2790 int LuaMilitarySiteDescription::get_heal_per_second(lua_State* L) {
2791 	const MilitarySiteDescr* descr = get();
2792 	lua_pushinteger(L, descr->get_heal_per_second());
2793 	return 1;
2794 }
2795 
2796 /* RST
2797    .. attribute:: max_number_of_soldiers
2798 
2799       (RO) The number of soldiers that can be garrisoned at the militarysite
2800 */
get_max_number_of_soldiers(lua_State * L)2801 int LuaMilitarySiteDescription::get_max_number_of_soldiers(lua_State* L) {
2802 	const MilitarySiteDescr* descr = get();
2803 	lua_pushinteger(L, descr->get_max_number_of_soldiers());
2804 	return 1;
2805 }
2806 
2807 /* RST
2808 TrainingSiteDescription
2809 -----------------------
2810 
2811 .. class:: TrainingSiteDescription
2812 
2813    Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`,
2814    :class:`BuildingDescription`, :class:`ProductionSiteDescription`
2815 
2816    A static description of a tribe's trainingsite, so it can be used in help files
2817    without having to access an actual building on the map.
2818    A training site can train some or all of a soldier's properties (Attack, Defense, Evade and
2819    Health). See the parent classes for more properties.
2820 */
2821 const char LuaTrainingSiteDescription::className[] = "TrainingSiteDescription";
2822 const MethodType<LuaTrainingSiteDescription> LuaTrainingSiteDescription::Methods[] = {
2823    {nullptr, nullptr},
2824 };
2825 const PropertyType<LuaTrainingSiteDescription> LuaTrainingSiteDescription::Properties[] = {
2826    PROP_RO(LuaTrainingSiteDescription, food_attack),
2827    PROP_RO(LuaTrainingSiteDescription, food_defense),
2828    PROP_RO(LuaTrainingSiteDescription, food_evade),
2829    PROP_RO(LuaTrainingSiteDescription, food_health),
2830    PROP_RO(LuaTrainingSiteDescription, max_attack),
2831    PROP_RO(LuaTrainingSiteDescription, max_defense),
2832    PROP_RO(LuaTrainingSiteDescription, max_evade),
2833    PROP_RO(LuaTrainingSiteDescription, max_health),
2834    PROP_RO(LuaTrainingSiteDescription, max_number_of_soldiers),
2835    PROP_RO(LuaTrainingSiteDescription, min_attack),
2836    PROP_RO(LuaTrainingSiteDescription, min_defense),
2837    PROP_RO(LuaTrainingSiteDescription, min_evade),
2838    PROP_RO(LuaTrainingSiteDescription, min_health),
2839    PROP_RO(LuaTrainingSiteDescription, weapons_attack),
2840    PROP_RO(LuaTrainingSiteDescription, weapons_defense),
2841    PROP_RO(LuaTrainingSiteDescription, weapons_evade),
2842    PROP_RO(LuaTrainingSiteDescription, weapons_health),
2843    {nullptr, nullptr, nullptr},
2844 };
2845 
2846 /*
2847  ==========================================================
2848  PROPERTIES
2849  ==========================================================
2850  */
2851 
2852 /* RST
2853    .. attribute:: food_attack
2854 
2855       (RO) A table of tables with food ware names used for Attack training,
2856            e.g. {{"barbarians_bread"}, {"fish", "meat"}}
2857 */
get_food_attack(lua_State * L)2858 int LuaTrainingSiteDescription::get_food_attack(lua_State* L) {
2859 	return food_list_to_lua(L, get()->get_food_attack());
2860 }
2861 
2862 /* RST
2863    .. attribute:: food_defense
2864 
2865       (RO) A table of tables with food ware names used for Defense training,
2866            e.g. {{"barbarians_bread"}, {"fish", "meat"}}
2867 */
get_food_defense(lua_State * L)2868 int LuaTrainingSiteDescription::get_food_defense(lua_State* L) {
2869 	return food_list_to_lua(L, get()->get_food_defense());
2870 }
2871 
2872 /* RST
2873    .. attribute:: food_evade
2874 
2875       (RO) A table of tables with food ware names used for Evade training,
2876            e.g. {{"barbarians_bread"}, {"fish", "meat"}}
2877 */
get_food_evade(lua_State * L)2878 int LuaTrainingSiteDescription::get_food_evade(lua_State* L) {
2879 	return food_list_to_lua(L, get()->get_food_evade());
2880 }
2881 
2882 /* RST
2883    .. attribute:: food_health
2884 
2885       (RO) A table of tables with food ware names used for Health training,
2886            e.g. {{"barbarians_bread"}, {"fish", "meat"}}
2887 */
get_food_health(lua_State * L)2888 int LuaTrainingSiteDescription::get_food_health(lua_State* L) {
2889 	return food_list_to_lua(L, get()->get_food_health());
2890 }
2891 
2892 /* RST
2893    .. attribute:: max_attack
2894 
2895       (RO) The number of attack points that a soldier can train
2896 */
get_max_attack(lua_State * L)2897 int LuaTrainingSiteDescription::get_max_attack(lua_State* L) {
2898 	const TrainingSiteDescr* descr = get();
2899 	if (descr->get_train_attack()) {
2900 		lua_pushinteger(L, descr->get_max_level(TrainingAttribute::kAttack));
2901 	} else {
2902 		lua_pushnil(L);
2903 	}
2904 	return 1;
2905 }
2906 
2907 /* RST
2908    .. attribute:: max_defense
2909 
2910       (RO) The number of defense points that a soldier can train
2911 */
get_max_defense(lua_State * L)2912 int LuaTrainingSiteDescription::get_max_defense(lua_State* L) {
2913 	const TrainingSiteDescr* descr = get();
2914 	if (descr->get_train_defense()) {
2915 		lua_pushinteger(L, descr->get_max_level(TrainingAttribute::kDefense));
2916 	} else {
2917 		lua_pushnil(L);
2918 	}
2919 	return 1;
2920 }
2921 
2922 /* RST
2923    .. attribute:: max_evade
2924 
2925       (RO) The number of evade points that a soldier can train
2926 */
get_max_evade(lua_State * L)2927 int LuaTrainingSiteDescription::get_max_evade(lua_State* L) {
2928 	const TrainingSiteDescr* descr = get();
2929 	if (descr->get_train_evade()) {
2930 		lua_pushinteger(L, descr->get_max_level(TrainingAttribute::kEvade));
2931 	} else {
2932 		lua_pushnil(L);
2933 	}
2934 	return 1;
2935 }
2936 
2937 /* RST
2938    .. attribute:: max_health
2939 
2940       (RO) The number of health points that a soldier can train
2941 */
get_max_health(lua_State * L)2942 int LuaTrainingSiteDescription::get_max_health(lua_State* L) {
2943 	const TrainingSiteDescr* descr = get();
2944 	if (descr->get_train_health()) {
2945 		lua_pushinteger(L, descr->get_max_level(TrainingAttribute::kHealth));
2946 	} else {
2947 		lua_pushnil(L);
2948 	}
2949 	return 1;
2950 }
2951 
2952 /* RST
2953    .. attribute:: max_number_of_soldiers
2954 
2955       (RO) The number of soldiers that can be garrisoned at the trainingsite
2956 */
get_max_number_of_soldiers(lua_State * L)2957 int LuaTrainingSiteDescription::get_max_number_of_soldiers(lua_State* L) {
2958 	const TrainingSiteDescr* descr = get();
2959 	lua_pushinteger(L, descr->get_max_number_of_soldiers());
2960 	return 1;
2961 }
2962 
2963 /* RST
2964    .. attribute:: min_attack
2965 
2966       (RO) The number of attack points that a soldier starts training with
2967 */
get_min_attack(lua_State * L)2968 int LuaTrainingSiteDescription::get_min_attack(lua_State* L) {
2969 	const TrainingSiteDescr* descr = get();
2970 	if (descr->get_train_attack()) {
2971 		lua_pushinteger(L, descr->get_min_level(TrainingAttribute::kAttack));
2972 	} else {
2973 		lua_pushnil(L);
2974 	}
2975 	return 1;
2976 }
2977 
2978 /* RST
2979    .. attribute:: min_defense
2980 
2981       (RO) The number of defense points that a soldier starts training with
2982 */
get_min_defense(lua_State * L)2983 int LuaTrainingSiteDescription::get_min_defense(lua_State* L) {
2984 	const TrainingSiteDescr* descr = get();
2985 	if (descr->get_train_defense()) {
2986 		lua_pushinteger(L, descr->get_min_level(TrainingAttribute::kDefense));
2987 	} else {
2988 		lua_pushnil(L);
2989 	}
2990 	return 1;
2991 }
2992 
2993 /* RST
2994    .. attribute:: min_evade
2995 
2996       (RO) The number of evade points that a soldier starts training with
2997 */
get_min_evade(lua_State * L)2998 int LuaTrainingSiteDescription::get_min_evade(lua_State* L) {
2999 	const TrainingSiteDescr* descr = get();
3000 	if (descr->get_train_evade()) {
3001 		lua_pushinteger(L, descr->get_min_level(TrainingAttribute::kEvade));
3002 	} else {
3003 		lua_pushnil(L);
3004 	}
3005 	return 1;
3006 }
3007 
3008 /* RST
3009    .. attribute:: min_health
3010 
3011       (RO) The number of health points that a soldier starts training with
3012 */
get_min_health(lua_State * L)3013 int LuaTrainingSiteDescription::get_min_health(lua_State* L) {
3014 	const TrainingSiteDescr* descr = get();
3015 	if (descr->get_train_health()) {
3016 		lua_pushinteger(L, descr->get_min_level(TrainingAttribute::kHealth));
3017 	} else {
3018 		lua_pushnil(L);
3019 	}
3020 	return 1;
3021 }
3022 
3023 /* RST
3024    .. attribute:: weapons_attack
3025 
3026       (RO) A table with weapon ware names used for Attack training
3027 */
get_weapons_attack(lua_State * L)3028 int LuaTrainingSiteDescription::get_weapons_attack(lua_State* L) {
3029 	lua_newtable(L);
3030 	int counter = 0;
3031 	for (const std::string& weaponname : get()->get_weapons_attack()) {
3032 		lua_pushuint32(L, ++counter);
3033 		lua_pushstring(L, weaponname);
3034 		lua_settable(L, -3);
3035 	}
3036 	return 1;
3037 }
3038 
3039 /* RST
3040    .. attribute:: weapons_defense
3041 
3042       (RO) A table with weapon ware names used for Defense training
3043 */
get_weapons_defense(lua_State * L)3044 int LuaTrainingSiteDescription::get_weapons_defense(lua_State* L) {
3045 	lua_newtable(L);
3046 	int counter = 0;
3047 	for (const std::string& weaponname : get()->get_weapons_defense()) {
3048 		lua_pushuint32(L, ++counter);
3049 		lua_pushstring(L, weaponname);
3050 		lua_settable(L, -3);
3051 	}
3052 	return 1;
3053 }
3054 
3055 /* RST
3056    .. attribute:: weapons_evade
3057 
3058       (RO) A table with weapon ware names used for Evade training
3059 */
get_weapons_evade(lua_State * L)3060 int LuaTrainingSiteDescription::get_weapons_evade(lua_State* L) {
3061 	lua_newtable(L);
3062 	int counter = 0;
3063 	for (const std::string& weaponname : get()->get_weapons_evade()) {
3064 		lua_pushuint32(L, ++counter);
3065 		lua_pushstring(L, weaponname);
3066 		lua_settable(L, -3);
3067 	}
3068 	return 1;
3069 }
3070 
3071 /* RST
3072    .. attribute:: weapons_health
3073 
3074       (RO) A table with weapon ware names used for Health training
3075 */
get_weapons_health(lua_State * L)3076 int LuaTrainingSiteDescription::get_weapons_health(lua_State* L) {
3077 	lua_newtable(L);
3078 	int counter = 0;
3079 	for (const std::string& weaponname : get()->get_weapons_health()) {
3080 		lua_pushuint32(L, ++counter);
3081 		lua_pushstring(L, weaponname);
3082 		lua_settable(L, -3);
3083 	}
3084 	return 1;
3085 }
3086 
3087 /* RST
3088 WarehouseDescription
3089 --------------------
3090 
3091 .. class:: WarehouseDescription
3092 
3093    Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`,
3094    :class:`BuildingDescription`
3095 
3096    A static description of a tribe's warehouse, so it can be used in help files
3097    without having to access an actual building on the map.
3098    Note that headquarters are also warehouses.
3099    A warehouse keeps people, animals and wares.
3100    See the parent classes for more properties.
3101 */
3102 const char LuaWarehouseDescription::className[] = "WarehouseDescription";
3103 const MethodType<LuaWarehouseDescription> LuaWarehouseDescription::Methods[] = {
3104    {nullptr, nullptr},
3105 };
3106 const PropertyType<LuaWarehouseDescription> LuaWarehouseDescription::Properties[] = {
3107    PROP_RO(LuaWarehouseDescription, heal_per_second), {nullptr, nullptr, nullptr},
3108 };
3109 
3110 /*
3111  ==========================================================
3112  PROPERTIES
3113  ==========================================================
3114  */
3115 
3116 /* RST
3117    .. attribute:: heal_per_second
3118 
3119       (RO) The number of health healed per second by the warehouse
3120 */
get_heal_per_second(lua_State * L)3121 int LuaWarehouseDescription::get_heal_per_second(lua_State* L) {
3122 	const WarehouseDescr* descr = get();
3123 	lua_pushinteger(L, descr->get_heal_per_second());
3124 	return 1;
3125 }
3126 
3127 /* RST
3128 MarketDescription
3129 -----------------
3130 
3131 .. class:: MarketDescription
3132 
3133    Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`,
3134    :class:`BuildingDescription`
3135 
3136    A static description of a tribe's market, so it can be used in help files
3137    without having to access an actual building on the map. A Market is used for
3138    trading over land with other players. See the parent classes for more
3139    properties.
3140 */
3141 // TODO(sirver,trading): Expose the properties of MarketDescription here once
3142 // the interface settles.
3143 const char LuaMarketDescription::className[] = "MarketDescription";
3144 const MethodType<LuaMarketDescription> LuaMarketDescription::Methods[] = {
3145    {nullptr, nullptr},
3146 };
3147 const PropertyType<LuaMarketDescription> LuaMarketDescription::Properties[] = {
3148    {nullptr, nullptr, nullptr},
3149 };
3150 
3151 /*
3152  ==========================================================
3153  PROPERTIES
3154  ==========================================================
3155  */
3156 
3157 /* RST
3158 WareDescription
3159 ---------------
3160 
3161 .. class:: WareDescription
3162 
3163    Child of: :class:`MapObjectDescription`
3164 
3165    A static description of a tribe's ware, so it can be used in help files
3166    without having to access an actual instance of the ware on the map.
3167    See also :class:`MapObjectDescription` for more properties.
3168 */
3169 const char LuaWareDescription::className[] = "WareDescription";
3170 const MethodType<LuaWareDescription> LuaWareDescription::Methods[] = {
3171    METHOD(LuaWareDescription, consumers),
3172    METHOD(LuaWareDescription, is_construction_material),
3173    METHOD(LuaWareDescription, producers),
3174    {nullptr, nullptr},
3175 };
3176 const PropertyType<LuaWareDescription> LuaWareDescription::Properties[] = {
3177    {nullptr, nullptr, nullptr},
3178 };
3179 
__persist(lua_State * L)3180 void LuaWareDescription::__persist(lua_State* L) {
3181 	const WareDescr* descr = get();
3182 	PERS_STRING("name", descr->name());
3183 }
3184 
__unpersist(lua_State * L)3185 void LuaWareDescription::__unpersist(lua_State* L) {
3186 	std::string name;
3187 	UNPERS_STRING("name", name)
3188 	const Tribes& tribes = get_egbase(L).tribes();
3189 	DescriptionIndex idx = tribes.safe_ware_index(name.c_str());
3190 	set_description_pointer(tribes.get_ware_descr(idx));
3191 }
3192 
3193 /*
3194  ==========================================================
3195  PROPERTIES
3196  ==========================================================
3197  */
3198 
3199 /* RST
3200    .. method:: consumers(tribename)
3201 
3202       :arg tribename: the name of the tribe that this ware gets checked for
3203       :type tribename: :class:`string`
3204 
3205       (RO) An array with :class:`LuaBuildingDescription` with buildings that
3206       need this ware for their production.
3207 */
consumers(lua_State * L)3208 int LuaWareDescription::consumers(lua_State* L) {
3209 	if (lua_gettop(L) != 2) {
3210 		report_error(L, "Takes only one argument.");
3211 	}
3212 	const Widelands::TribeDescr& tribe = get_tribe_descr(L, luaL_checkstring(L, 2));
3213 
3214 	lua_newtable(L);
3215 	int index = 1;
3216 	for (const DescriptionIndex& building_index : get()->consumers()) {
3217 		if (tribe.has_building(building_index)) {
3218 			lua_pushint32(L, index++);
3219 			upcasted_map_object_descr_to_lua(
3220 			   L, get_egbase(L).tribes().get_building_descr(building_index));
3221 			lua_rawset(L, -3);
3222 		}
3223 	}
3224 	return 1;
3225 }
3226 
3227 /* RST
3228    .. method:: is_construction_material(tribename)
3229 
3230       :arg tribename: the name of the tribe that this ware gets checked for
3231       :type tribename: :class:`string`
3232 
3233       (RO) A bool that is true if this ware is used by the tribe's construction sites.
3234 */
is_construction_material(lua_State * L)3235 int LuaWareDescription::is_construction_material(lua_State* L) {
3236 	std::string tribename = luaL_checkstring(L, -1);
3237 	const Tribes& tribes = get_egbase(L).tribes();
3238 	if (Widelands::tribe_exists(tribename)) {
3239 		const DescriptionIndex& ware_index = tribes.safe_ware_index(get()->name());
3240 		int tribeindex = tribes.tribe_index(tribename);
3241 		lua_pushboolean(L, tribes.get_tribe_descr(tribeindex)->is_construction_material(ware_index));
3242 	} else {
3243 		lua_pushboolean(L, false);
3244 	}
3245 	return 1;
3246 }
3247 
3248 /* RST
3249    .. method:: producers(tribename)
3250 
3251       :arg tribename: the name of the tribe that this ware gets checked for
3252       :type tribename: :class:`string`
3253 
3254       (RO) An array with :class:`LuaBuildingDescription` with buildings that
3255       can procude this ware.
3256 */
producers(lua_State * L)3257 int LuaWareDescription::producers(lua_State* L) {
3258 	if (lua_gettop(L) != 2) {
3259 		report_error(L, "Takes only one argument.");
3260 	}
3261 	const Widelands::TribeDescr& tribe = get_tribe_descr(L, luaL_checkstring(L, 2));
3262 
3263 	lua_newtable(L);
3264 	int index = 1;
3265 	for (const DescriptionIndex& building_index : get()->producers()) {
3266 		if (tribe.has_building(building_index)) {
3267 			lua_pushint32(L, index++);
3268 			upcasted_map_object_descr_to_lua(
3269 			   L, get_egbase(L).tribes().get_building_descr(building_index));
3270 			lua_rawset(L, -3);
3271 		}
3272 	}
3273 	return 1;
3274 }
3275 
3276 /* RST
3277 WorkerDescription
3278 -----------------
3279 
3280 .. class:: WorkerDescription
3281 
3282    Child of: :class:`MapObjectDescription`
3283 
3284    A static description of a tribe's worker, so it can be used in help files
3285    without having to access an actual instance of the worker on the map.
3286    See also :class:`MapObjectDescription` for more properties.
3287 */
3288 const char LuaWorkerDescription::className[] = "WorkerDescription";
3289 const MethodType<LuaWorkerDescription> LuaWorkerDescription::Methods[] = {
3290    {nullptr, nullptr},
3291 };
3292 const PropertyType<LuaWorkerDescription> LuaWorkerDescription::Properties[] = {
3293    PROP_RO(LuaWorkerDescription, becomes),           PROP_RO(LuaWorkerDescription, buildcost),
3294    PROP_RO(LuaWorkerDescription, employers),         PROP_RO(LuaWorkerDescription, buildable),
3295    PROP_RO(LuaWorkerDescription, needed_experience), {nullptr, nullptr, nullptr},
3296 };
3297 
__persist(lua_State * L)3298 void LuaWorkerDescription::__persist(lua_State* L) {
3299 	const WorkerDescr* descr = get();
3300 	PERS_STRING("name", descr->name());
3301 }
3302 
__unpersist(lua_State * L)3303 void LuaWorkerDescription::__unpersist(lua_State* L) {
3304 	std::string name;
3305 	UNPERS_STRING("name", name)
3306 	const Tribes& tribes = get_egbase(L).tribes();
3307 	DescriptionIndex idx = tribes.safe_worker_index(name.c_str());
3308 	set_description_pointer(tribes.get_worker_descr(idx));
3309 }
3310 
3311 /*
3312  ==========================================================
3313  PROPERTIES
3314  ==========================================================
3315  */
3316 
3317 /* RST
3318    .. attribute:: becomes
3319 
3320       (RO) The :class:`WorkerDescription` of the worker this one will level up
3321       to or :const:`nil` if it never levels up.
3322 */
get_becomes(lua_State * L)3323 int LuaWorkerDescription::get_becomes(lua_State* L) {
3324 	const DescriptionIndex becomes_index = get()->becomes();
3325 	if (becomes_index == INVALID_INDEX) {
3326 		lua_pushnil(L);
3327 		return 1;
3328 	}
3329 	return to_lua<LuaWorkerDescription>(
3330 	   L, new LuaWorkerDescription(get_egbase(L).tribes().get_worker_descr(becomes_index)));
3331 }
3332 
3333 /* RST
3334    .. attribute:: buildcost
3335 
3336       (RO) a list of building requirements, e.g. {"atlanteans_carrier", "ax"}
3337 */
get_buildcost(lua_State * L)3338 int LuaWorkerDescription::get_buildcost(lua_State* L) {
3339 	lua_newtable(L);
3340 	int index = 1;
3341 	if (get()->is_buildable()) {
3342 		for (const auto& buildcost_pair : get()->buildcost()) {
3343 			lua_pushint32(L, index++);
3344 			lua_pushstring(L, buildcost_pair.first);
3345 			lua_settable(L, -3);
3346 		}
3347 	}
3348 	return 1;
3349 }
3350 
3351 /* RST
3352    .. attribute:: employers
3353 
3354       (RO) An array with :class:`LuaBuildingDescription` with buildings where
3355       this worker can be employed.
3356 */
get_employers(lua_State * L)3357 int LuaWorkerDescription::get_employers(lua_State* L) {
3358 	lua_newtable(L);
3359 	int index = 1;
3360 	for (const DescriptionIndex& building_index : get()->employers()) {
3361 		lua_pushint32(L, index++);
3362 		upcasted_map_object_descr_to_lua(
3363 		   L, get_egbase(L).tribes().get_building_descr(building_index));
3364 		lua_rawset(L, -3);
3365 	}
3366 	return 1;
3367 }
3368 
3369 /* RST
3370    .. attribute:: buildable
3371 
3372       (RO) returns true if this worker is buildable
3373 */
get_buildable(lua_State * L)3374 int LuaWorkerDescription::get_buildable(lua_State* L) {
3375 	lua_pushboolean(L, get()->is_buildable());
3376 	return 1;
3377 }
3378 
3379 /* RST
3380    .. attribute:: needed_experience
3381 
3382          (RO) the experience the worker needs to reach this level.
3383 */
get_needed_experience(lua_State * L)3384 int LuaWorkerDescription::get_needed_experience(lua_State* L) {
3385 	lua_pushinteger(L, get()->get_needed_experience());
3386 	return 1;
3387 }
3388 
3389 /* RST
3390 SoldierDescription
3391 --------------------
3392 
3393 .. class:: SoldierDescription
3394 
3395    Child of: :class:`MapObjectDescription`, :class:`WorkerDescription`
3396 
3397    A static description of a tribe's soldier, so it can be used in help files
3398    without having to access an actual instance of the worker on the map.
3399    See the parent classes for more properties.
3400 */
3401 const char LuaSoldierDescription::className[] = "SoldierDescription";
3402 const MethodType<LuaSoldierDescription> LuaSoldierDescription::Methods[] = {
3403    {nullptr, nullptr},
3404 };
3405 const PropertyType<LuaSoldierDescription> LuaSoldierDescription::Properties[] = {
3406    PROP_RO(LuaSoldierDescription, max_health_level),
3407    PROP_RO(LuaSoldierDescription, max_attack_level),
3408    PROP_RO(LuaSoldierDescription, max_defense_level),
3409    PROP_RO(LuaSoldierDescription, max_evade_level),
3410    PROP_RO(LuaSoldierDescription, base_health),
3411    PROP_RO(LuaSoldierDescription, base_min_attack),
3412    PROP_RO(LuaSoldierDescription, base_max_attack),
3413    PROP_RO(LuaSoldierDescription, base_defense),
3414    PROP_RO(LuaSoldierDescription, base_evade),
3415    PROP_RO(LuaSoldierDescription, health_incr_per_level),
3416    PROP_RO(LuaSoldierDescription, attack_incr_per_level),
3417    PROP_RO(LuaSoldierDescription, defense_incr_per_level),
3418    PROP_RO(LuaSoldierDescription, evade_incr_per_level),
3419    {nullptr, nullptr, nullptr},
3420 };
3421 
3422 /*
3423  ==========================================================
3424  PROPERTIES
3425  ==========================================================
3426  */
3427 
3428 /* RST
3429    .. attribute:: get_max_health_level
3430 
3431       (RO) The maximum health level that the soldier can have.
3432 */
get_max_health_level(lua_State * L)3433 int LuaSoldierDescription::get_max_health_level(lua_State* L) {
3434 	lua_pushinteger(L, get()->get_max_health_level());
3435 	return 1;
3436 }
3437 
3438 /* RST
3439    .. attribute:: max_attack_level
3440 
3441       (RO) The maximum attack level that the soldier can have.
3442 */
get_max_attack_level(lua_State * L)3443 int LuaSoldierDescription::get_max_attack_level(lua_State* L) {
3444 	lua_pushinteger(L, get()->get_max_attack_level());
3445 	return 1;
3446 }
3447 
3448 /* RST
3449    .. attribute:: max_defense_level
3450 
3451       (RO) The maximum defense level that the soldier can have.
3452 */
get_max_defense_level(lua_State * L)3453 int LuaSoldierDescription::get_max_defense_level(lua_State* L) {
3454 	lua_pushinteger(L, get()->get_max_defense_level());
3455 	return 1;
3456 }
3457 
3458 /* RST
3459    .. attribute:: max_evade_level
3460 
3461       (RO) The maximum evade level that the soldier can have.
3462 */
get_max_evade_level(lua_State * L)3463 int LuaSoldierDescription::get_max_evade_level(lua_State* L) {
3464 	lua_pushinteger(L, get()->get_max_evade_level());
3465 	return 1;
3466 }
3467 
3468 /* RST
3469    .. attribute:: get_base_health
3470 
3471       (RO) The health points that the soldier starts with
3472 */
get_base_health(lua_State * L)3473 int LuaSoldierDescription::get_base_health(lua_State* L) {
3474 	lua_pushinteger(L, get()->get_base_health());
3475 	return 1;
3476 }
3477 
3478 /* RST
3479    .. attribute:: base_min_attack
3480 
3481       (RO) The minimum random attack points that get added to a soldier's attack
3482 */
get_base_min_attack(lua_State * L)3483 int LuaSoldierDescription::get_base_min_attack(lua_State* L) {
3484 	lua_pushinteger(L, get()->get_base_min_attack());
3485 	return 1;
3486 }
3487 
3488 /* RST
3489    .. attribute:: base_max_attack
3490 
3491       (RO) The maximum random attack points that get added to a soldier's attack
3492 */
get_base_max_attack(lua_State * L)3493 int LuaSoldierDescription::get_base_max_attack(lua_State* L) {
3494 	lua_pushinteger(L, get()->get_base_max_attack());
3495 	return 1;
3496 }
3497 
3498 /* RST
3499    .. attribute:: base_defense
3500 
3501       (RO) The defense % that the soldier starts with
3502 */
get_base_defense(lua_State * L)3503 int LuaSoldierDescription::get_base_defense(lua_State* L) {
3504 	lua_pushinteger(L, get()->get_base_defense());
3505 	return 1;
3506 }
3507 
3508 /* RST
3509    .. attribute:: base_evade
3510 
3511       (RO) The evade % that the soldier starts with
3512 */
get_base_evade(lua_State * L)3513 int LuaSoldierDescription::get_base_evade(lua_State* L) {
3514 	lua_pushinteger(L, get()->get_base_evade());
3515 	return 1;
3516 }
3517 
3518 /* RST
3519    .. attribute:: get_health_incr_per_level
3520 
3521       (RO) The health points that the soldier will gain with each level.
3522 */
get_health_incr_per_level(lua_State * L)3523 int LuaSoldierDescription::get_health_incr_per_level(lua_State* L) {
3524 	lua_pushinteger(L, get()->get_health_incr_per_level());
3525 	return 1;
3526 }
3527 
3528 /* RST
3529    .. attribute:: attack_incr_per_level
3530 
3531       (RO) The attack points that the soldier will gain with each level.
3532 */
get_attack_incr_per_level(lua_State * L)3533 int LuaSoldierDescription::get_attack_incr_per_level(lua_State* L) {
3534 	lua_pushinteger(L, get()->get_attack_incr_per_level());
3535 	return 1;
3536 }
3537 
3538 /* RST
3539    .. attribute:: defense_incr_per_level
3540 
3541       (RO) The defense % that the soldier will gain with each level.
3542 */
get_defense_incr_per_level(lua_State * L)3543 int LuaSoldierDescription::get_defense_incr_per_level(lua_State* L) {
3544 	lua_pushinteger(L, get()->get_defense_incr_per_level());
3545 	return 1;
3546 }
3547 
3548 /* RST
3549    .. attribute:: evade_incr_per_level
3550 
3551       (RO) The evade % that the soldier will gain with each level.
3552 */
get_evade_incr_per_level(lua_State * L)3553 int LuaSoldierDescription::get_evade_incr_per_level(lua_State* L) {
3554 	lua_pushinteger(L, get()->get_evade_incr_per_level());
3555 	return 1;
3556 }
3557 
3558 /* RST
3559 ResourceDescription
3560 --------------------
3561 .. class:: ResourceDescription
3562 
3563    A static description of a resource.
3564 */
3565 const char LuaResourceDescription::className[] = "ResourceDescription";
3566 const MethodType<LuaResourceDescription> LuaResourceDescription::Methods[] = {
3567    METHOD(LuaResourceDescription, editor_image), {nullptr, nullptr},
3568 };
3569 const PropertyType<LuaResourceDescription> LuaResourceDescription::Properties[] = {
3570    PROP_RO(LuaResourceDescription, name),
3571    PROP_RO(LuaResourceDescription, descname),
3572    PROP_RO(LuaResourceDescription, is_detectable),
3573    PROP_RO(LuaResourceDescription, max_amount),
3574    PROP_RO(LuaResourceDescription, representative_image),
3575    {nullptr, nullptr, nullptr},
3576 };
3577 
__persist(lua_State * L)3578 void LuaResourceDescription::__persist(lua_State* L) {
3579 	const Widelands::ResourceDescription* descr = get();
3580 	PERS_STRING("name", descr->name());
3581 }
3582 
__unpersist(lua_State * L)3583 void LuaResourceDescription::__unpersist(lua_State* L) {
3584 	std::string name;
3585 	UNPERS_STRING("name", name)
3586 	const World& world = get_egbase(L).world();
3587 	const ResourceDescription* descr = world.get_resource(world.safe_resource_index(name.c_str()));
3588 	set_description_pointer(descr);
3589 }
3590 
3591 /*
3592  ==========================================================
3593  PROPERTIES
3594  ==========================================================
3595  */
3596 
3597 /* RST
3598    .. attribute:: name
3599 
3600          (RO) the :class:`string` internal name of this resource
3601 */
3602 
get_name(lua_State * L)3603 int LuaResourceDescription::get_name(lua_State* L) {
3604 	lua_pushstring(L, get()->name());
3605 	return 1;
3606 }
3607 
3608 /* RST
3609    .. attribute:: descname
3610 
3611          (RO) the :class:`string` display name of this resource
3612 */
3613 
get_descname(lua_State * L)3614 int LuaResourceDescription::get_descname(lua_State* L) {
3615 	lua_pushstring(L, get()->descname());
3616 	return 1;
3617 }
3618 
3619 /* RST
3620    .. attribute:: is_detectable
3621 
3622          (RO) true if geologists can find this resource
3623 */
3624 
get_is_detectable(lua_State * L)3625 int LuaResourceDescription::get_is_detectable(lua_State* L) {
3626 	lua_pushboolean(L, get()->detectable());
3627 	return 1;
3628 }
3629 
3630 /* RST
3631    .. attribute:: max_amount
3632 
3633          (RO) the maximum amount of this resource that a terrain can have
3634 */
3635 
get_max_amount(lua_State * L)3636 int LuaResourceDescription::get_max_amount(lua_State* L) {
3637 	lua_pushinteger(L, get()->max_amount());
3638 	return 1;
3639 }
3640 
3641 /* RST
3642    .. attribute:: representative_image
3643 
3644          (RO) the :class:`string` path to the image representing this resource in the GUI
3645 */
get_representative_image(lua_State * L)3646 int LuaResourceDescription::get_representative_image(lua_State* L) {
3647 	lua_pushstring(L, get()->representative_image());
3648 	return 1;
3649 }
3650 
3651 /*
3652  ==========================================================
3653  METHODS
3654  ==========================================================
3655  */
3656 
3657 /* RST
3658    .. method:: editor_image(amount)
3659 
3660       :arg amount: The amount of the resource what we want an overlay image for
3661 
3662          (RO) the :class:`string` path to the image representing the specified amount of this
3663          resource
3664 */
editor_image(lua_State * L)3665 int LuaResourceDescription::editor_image(lua_State* L) {
3666 	if (lua_gettop(L) != 2) {
3667 		report_error(L, "Takes only one argument.");
3668 	}
3669 	const uint32_t amount = luaL_checkuint32(L, 2);
3670 	lua_pushstring(L, get()->editor_image(amount));
3671 	return 1;
3672 }
3673 
3674 /* RST
3675 TerrainDescription
3676 --------------------
3677 .. class:: TerrainDescription
3678 
3679    A static description of a terrain.
3680 */
3681 const char LuaTerrainDescription::className[] = "TerrainDescription";
3682 const MethodType<LuaTerrainDescription> LuaTerrainDescription::Methods[] = {
3683    {nullptr, nullptr},
3684 };
3685 const PropertyType<LuaTerrainDescription> LuaTerrainDescription::Properties[] = {
3686    PROP_RO(LuaTerrainDescription, name),
3687    PROP_RO(LuaTerrainDescription, descname),
3688    PROP_RO(LuaTerrainDescription, default_resource),
3689    PROP_RO(LuaTerrainDescription, default_resource_amount),
3690    PROP_RO(LuaTerrainDescription, editor_category),
3691    PROP_RO(LuaTerrainDescription, fertility),
3692    PROP_RO(LuaTerrainDescription, humidity),
3693    PROP_RO(LuaTerrainDescription, representative_image),
3694    PROP_RO(LuaTerrainDescription, temperature),
3695    PROP_RO(LuaTerrainDescription, valid_resources),
3696    {nullptr, nullptr, nullptr},
3697 };
3698 
__persist(lua_State * L)3699 void LuaTerrainDescription::__persist(lua_State* L) {
3700 	const Widelands::TerrainDescription* descr = get();
3701 	PERS_STRING("name", descr->name());
3702 }
3703 
__unpersist(lua_State * L)3704 void LuaTerrainDescription::__unpersist(lua_State* L) {
3705 	std::string name;
3706 	UNPERS_STRING("name", name)
3707 	set_description_pointer(get_egbase(L).world().terrain_descr(name));
3708 }
3709 
3710 /*
3711  ==========================================================
3712  PROPERTIES
3713  ==========================================================
3714  */
3715 
3716 /* RST
3717    .. attribute:: name
3718 
3719          (RO) the :class:`string` internal name of this terrain
3720 */
3721 
get_name(lua_State * L)3722 int LuaTerrainDescription::get_name(lua_State* L) {
3723 	lua_pushstring(L, get()->name());
3724 	return 1;
3725 }
3726 
3727 /* RST
3728    .. attribute:: descname
3729 
3730          (RO) the :class:`string` display name of this terrain
3731 */
3732 
get_descname(lua_State * L)3733 int LuaTerrainDescription::get_descname(lua_State* L) {
3734 	lua_pushstring(L, get()->descname());
3735 	return 1;
3736 }
3737 
3738 /* RST
3739    .. attribute:: get_default_resource
3740 
3741          (RO) the :class:`wl.map.ResourceDescription` for the default resource provided by this
3742          terrain, or nil if the terrain has no default resource.
3743 */
3744 
get_default_resource(lua_State * L)3745 int LuaTerrainDescription::get_default_resource(lua_State* L) {
3746 	DescriptionIndex res_index = get()->get_default_resource();
3747 	const World& world = get_egbase(L).world();
3748 	if (res_index != Widelands::kNoResource && res_index < world.get_nr_resources()) {
3749 		to_lua<LuaMaps::LuaResourceDescription>(
3750 		   L, new LuaMaps::LuaResourceDescription(world.get_resource(res_index)));
3751 	} else {
3752 		lua_pushnil(L);
3753 	}
3754 	return 1;
3755 }
3756 
3757 /* RST
3758    .. attribute:: default_resource_amount
3759 
3760       (RO) the int amount of the default resource provided by this terrain.
3761 */
3762 
get_default_resource_amount(lua_State * L)3763 int LuaTerrainDescription::get_default_resource_amount(lua_State* L) {
3764 	lua_pushinteger(L, get()->get_default_resource_amount());
3765 	return 1;
3766 }
3767 
3768 /* RST
3769    .. attribute:: the name and descname of the editor category of this terrain
3770 
3771       (RO) a table with "name" and "descname" entries for the editor category, or nil if it has
3772       none.
3773 */
get_editor_category(lua_State * L)3774 int LuaTerrainDescription::get_editor_category(lua_State* L) {
3775 	const EditorCategory* editor_category = get()->editor_category();
3776 	if (editor_category != nullptr) {
3777 		lua_newtable(L);
3778 		lua_pushstring(L, "name");
3779 		lua_pushstring(L, editor_category->name());
3780 		lua_settable(L, -3);
3781 		lua_pushstring(L, "descname");
3782 		lua_pushstring(L, editor_category->descname());
3783 		lua_settable(L, -3);
3784 	} else {
3785 		lua_pushnil(L);
3786 	}
3787 	return 1;
3788 }
3789 
3790 /* RST
3791    .. attribute:: fertility
3792 
3793          (RO) the :class:`uint` fertility value for this terrain
3794 */
3795 
get_fertility(lua_State * L)3796 int LuaTerrainDescription::get_fertility(lua_State* L) {
3797 	lua_pushuint32(L, get()->fertility());
3798 	return 1;
3799 }
3800 
3801 /* RST
3802    .. attribute:: humidity
3803 
3804          (RO) the :class:`uint` humidity value for this terrain
3805 */
3806 
get_humidity(lua_State * L)3807 int LuaTerrainDescription::get_humidity(lua_State* L) {
3808 	lua_pushuint32(L, get()->humidity());
3809 	return 1;
3810 }
3811 
3812 /* RST
3813    .. attribute:: representative_image
3814 
3815          (RO) the :class:`string` file path to a representative image
3816 */
get_representative_image(lua_State * L)3817 int LuaTerrainDescription::get_representative_image(lua_State* L) {
3818 	lua_pushstring(L, get()->texture_paths().front());
3819 	return 1;
3820 }
3821 
3822 /* RST
3823    .. attribute:: temperature
3824 
3825          (RO) the :class:`uint` temperature value for this terrain
3826 */
3827 
get_temperature(lua_State * L)3828 int LuaTerrainDescription::get_temperature(lua_State* L) {
3829 	lua_pushuint32(L, get()->temperature());
3830 	return 1;
3831 }
3832 
3833 /* RST
3834    .. attribute:: valid_resources
3835 
3836          (RO) a list of :class:`wl.map.ResourceDescription` with all valid resources for this
3837          terrain.
3838 */
3839 
get_valid_resources(lua_State * L)3840 int LuaTerrainDescription::get_valid_resources(lua_State* L) {
3841 	const World& world = get_egbase(L).world();
3842 	lua_newtable(L);
3843 	int index = 1;
3844 	for (DescriptionIndex res_index : get()->valid_resources()) {
3845 		if (res_index != Widelands::kNoResource && res_index < world.get_nr_resources()) {
3846 			lua_pushint32(L, index++);
3847 			to_lua<LuaMaps::LuaResourceDescription>(
3848 			   L, new LuaMaps::LuaResourceDescription(world.get_resource(res_index)));
3849 			lua_settable(L, -3);
3850 		}
3851 	}
3852 	return 1;
3853 }
3854 
3855 /*
3856  ==========================================================
3857  METHODS
3858  ==========================================================
3859  */
3860 
3861 /* RST
3862 Economy
3863 -------
3864 .. class:: LuaEconomy
3865 
3866    Provides access to an economy. A player can have multiple economies;
3867    you can get an economy from a :class:`Flag`.
3868 */
3869 const char LuaEconomy::className[] = "Economy";
3870 const MethodType<LuaEconomy> LuaEconomy::Methods[] = {
3871    METHOD(LuaEconomy, target_quantity), METHOD(LuaEconomy, set_target_quantity), {nullptr, nullptr},
3872 };
3873 const PropertyType<LuaEconomy> LuaEconomy::Properties[] = {
3874    {nullptr, nullptr, nullptr},
3875 };
3876 
__persist(lua_State * L)3877 void LuaEconomy::__persist(lua_State* L) {
3878 	const Widelands::Economy* economy = get();
3879 	const Widelands::Player& player = economy->owner();
3880 	PERS_UINT32("player", player.player_number());
3881 	PERS_UINT32("economy", economy->serial());
3882 }
3883 
__unpersist(lua_State * L)3884 void LuaEconomy::__unpersist(lua_State* L) {
3885 	Widelands::PlayerNumber player_number;
3886 	Widelands::Serial economy_serial;
3887 	UNPERS_UINT32("player", player_number)
3888 	UNPERS_UINT32("economy", economy_serial)
3889 	const Widelands::Player& player = get_egbase(L).player(player_number);
3890 	set_economy_pointer(player.get_economy(economy_serial));
3891 }
3892 
3893 /* RST
3894    .. method:: target_quantity(name)
3895 
3896       Returns the amount of the given ware or worker that should be kept in stock for this economy.
3897       Whether this works only for wares or only for workers is determined by the type of this
3898       economy.
3899 
3900       **Warning**: Since economies can disappear when a player merges them
3901       through placing/deleting roads and flags, you must get a fresh economy
3902       object every time you use this function.
3903 
3904       :arg name: the name of the ware or worker.
3905       :type name: :class:`string`
3906 */
target_quantity(lua_State * L)3907 int LuaEconomy::target_quantity(lua_State* L) {
3908 	const std::string wname = luaL_checkstring(L, 2);
3909 	switch (get()->type()) {
3910 	case Widelands::wwWARE: {
3911 		const Widelands::DescriptionIndex index = get_egbase(L).tribes().ware_index(wname);
3912 		if (get_egbase(L).tribes().ware_exists(index)) {
3913 			const Widelands::Economy::TargetQuantity& quantity = get()->target_quantity(index);
3914 			lua_pushinteger(L, quantity.permanent);
3915 		} else {
3916 			report_error(L, "There is no ware '%s'.", wname.c_str());
3917 		}
3918 		break;
3919 	}
3920 	case Widelands::wwWORKER: {
3921 		const Widelands::DescriptionIndex index = get_egbase(L).tribes().worker_index(wname);
3922 		if (get_egbase(L).tribes().worker_exists(index)) {
3923 			const Widelands::Economy::TargetQuantity& quantity = get()->target_quantity(index);
3924 			lua_pushinteger(L, quantity.permanent);
3925 		} else {
3926 			report_error(L, "There is no worker '%s'.", wname.c_str());
3927 		}
3928 		break;
3929 	}
3930 	}
3931 	return 1;
3932 }
3933 
3934 /* RST
3935    .. method:: set_target_quantity(name)
3936 
3937       Sets the amount of the given ware or worker type that should be kept in stock for this
3938       economy. Whether this works only for wares or only for workers is determined by the type of
3939       this economy.
3940 
3941       **Warning**: Since economies can disappear when a player merges them
3942       through placing/deleting roads and flags, you must get a fresh economy
3943       object every time you use this function.
3944 
3945       :arg workername: the name of the worker type.
3946       :type workername: :class:`string`
3947 
3948       :arg amount: the new target amount for the worker. Needs to be >= 0.
3949       :type amount: :class:`integer`
3950 */
set_target_quantity(lua_State * L)3951 int LuaEconomy::set_target_quantity(lua_State* L) {
3952 	const std::string wname = luaL_checkstring(L, 2);
3953 	switch (get()->type()) {
3954 	case Widelands::wwWARE: {
3955 		const Widelands::DescriptionIndex index = get_egbase(L).tribes().ware_index(wname);
3956 		if (get_egbase(L).tribes().ware_exists(index)) {
3957 			const int quantity = luaL_checkinteger(L, 3);
3958 			if (quantity < 0) {
3959 				report_error(L, "Target ware quantity needs to be >= 0 but was '%d'.", quantity);
3960 			}
3961 			get()->set_target_quantity(index, quantity, get_egbase(L).get_gametime());
3962 		} else {
3963 			report_error(L, "There is no ware '%s'.", wname.c_str());
3964 		}
3965 		break;
3966 	}
3967 	case Widelands::wwWORKER: {
3968 		const Widelands::DescriptionIndex index = get_egbase(L).tribes().worker_index(wname);
3969 		if (get_egbase(L).tribes().worker_exists(index)) {
3970 			const int quantity = luaL_checkinteger(L, 3);
3971 			if (quantity < 0) {
3972 				report_error(L, "Target worker quantity needs to be >= 0 but was '%d'.", quantity);
3973 			}
3974 			get()->set_target_quantity(index, quantity, get_egbase(L).get_gametime());
3975 		} else {
3976 			report_error(L, "There is no worker '%s'.", wname.c_str());
3977 		}
3978 		break;
3979 	}
3980 	}
3981 	return 1;
3982 }
3983 
3984 /* RST
3985 MapObject
3986 ---------
3987 
3988 .. class:: MapObject
3989 
3990    This is the base class for all objects in Widelands, including
3991    :class:`immovables <BaseImmovable>` and :class:`bobs <Bob>`. This
3992    class can't be instantiated directly, but provides the base for all
3993    others.
3994 
3995    More properties are available through this object's
3996    :class:`MapObjectDescription`, which you can access via :any:`MapObject.descr`.
3997 */
3998 const char LuaMapObject::className[] = "MapObject";
3999 const MethodType<LuaMapObject> LuaMapObject::Methods[] = {
4000    METHOD(LuaMapObject, remove), METHOD(LuaMapObject, destroy),
4001    METHOD(LuaMapObject, __eq),   METHOD(LuaMapObject, has_attribute),
4002    {nullptr, nullptr},
4003 };
4004 const PropertyType<LuaMapObject> LuaMapObject::Properties[] = {
4005    PROP_RO(LuaMapObject, __hash),
4006    PROP_RO(LuaMapObject, descr),
4007    PROP_RO(LuaMapObject, serial),
4008    {nullptr, nullptr, nullptr},
4009 };
4010 
__persist(lua_State * L)4011 void LuaMapObject::__persist(lua_State* L) {
4012 	MapObjectSaver& mos = *get_mos(L);
4013 	Game& game = get_game(L);
4014 
4015 	uint32_t idx = 0;
4016 	if (MapObject* obj = ptr_.get(game)) {
4017 		idx = mos.get_object_file_index(*obj);
4018 	}
4019 
4020 	PERS_UINT32("file_index", idx);
4021 }
__unpersist(lua_State * L)4022 void LuaMapObject::__unpersist(lua_State* L) {
4023 	uint32_t idx;
4024 	UNPERS_UINT32("file_index", idx)
4025 
4026 	if (!idx) {
4027 		ptr_ = nullptr;
4028 	} else {
4029 		MapObjectLoader& mol = *get_mol(L);
4030 		ptr_ = &mol.get<MapObject>(idx);
4031 	}
4032 }
4033 
4034 /*
4035  ==========================================================
4036  PROPERTIES
4037  ==========================================================
4038  */
4039 /* RST
4040    .. attribute:: __hash
4041 
4042       (RO) The map object's serial. Used to identify a class in a Set.
4043 */
get___hash(lua_State * L)4044 int LuaMapObject::get___hash(lua_State* L) {
4045 	lua_pushuint32(L, get(L, get_egbase(L))->serial());
4046 	return 1;
4047 }
4048 
4049 /* RST
4050    .. attribute:: serial
4051 
4052       (RO) The serial number of this object. Note that this value does not stay
4053       constant after saving/loading.
4054 */
get_serial(lua_State * L)4055 int LuaMapObject::get_serial(lua_State* L) {
4056 	lua_pushuint32(L, get(L, get_egbase(L))->serial());
4057 	return 1;
4058 }
4059 
4060 // use the dynamic type of BuildingDescription
4061 #define CAST_TO_LUA(klass, lua_klass)                                                              \
4062 	to_lua<lua_klass>(L, new lua_klass(static_cast<const klass*>(desc)))
4063 
4064 /* RST
4065    .. attribute:: descr
4066 
4067       (RO) The description object for this immovable, e.g. BuildingDescription.
4068 */
get_descr(lua_State * L)4069 int LuaMapObject::get_descr(lua_State* L) {
4070 	const MapObjectDescr* desc = &get(L, get_egbase(L))->descr();
4071 	assert(desc != nullptr);
4072 
4073 	switch (desc->type()) {
4074 	case MapObjectType::BUILDING:
4075 		return CAST_TO_LUA(BuildingDescr, LuaBuildingDescription);
4076 	case MapObjectType::CONSTRUCTIONSITE:
4077 		return CAST_TO_LUA(ConstructionSiteDescr, LuaConstructionSiteDescription);
4078 	case MapObjectType::DISMANTLESITE:
4079 		return CAST_TO_LUA(DismantleSiteDescr, LuaDismantleSiteDescription);
4080 	case MapObjectType::PRODUCTIONSITE:
4081 		return CAST_TO_LUA(ProductionSiteDescr, LuaProductionSiteDescription);
4082 	case MapObjectType::MILITARYSITE:
4083 		return CAST_TO_LUA(MilitarySiteDescr, LuaMilitarySiteDescription);
4084 	case MapObjectType::TRAININGSITE:
4085 		return CAST_TO_LUA(TrainingSiteDescr, LuaTrainingSiteDescription);
4086 	case MapObjectType::WAREHOUSE:
4087 		return CAST_TO_LUA(WarehouseDescr, LuaWarehouseDescription);
4088 	case MapObjectType::MARKET:
4089 		return CAST_TO_LUA(MarketDescr, LuaMarketDescription);
4090 	case MapObjectType::IMMOVABLE:
4091 		return CAST_TO_LUA(ImmovableDescr, LuaImmovableDescription);
4092 	case MapObjectType::WORKER:
4093 	case MapObjectType::CARRIER:
4094 	case MapObjectType::FERRY:
4095 	case MapObjectType::SOLDIER:
4096 		return CAST_TO_LUA(WorkerDescr, LuaWorkerDescription);
4097 	case MapObjectType::MAPOBJECT:
4098 	case MapObjectType::BATTLE:
4099 	case MapObjectType::BOB:
4100 	case MapObjectType::CRITTER:
4101 	case MapObjectType::FERRY_FLEET:
4102 	case MapObjectType::SHIP_FLEET:
4103 	case MapObjectType::SHIP:
4104 	case MapObjectType::FLAG:
4105 	case MapObjectType::ROAD:
4106 	case MapObjectType::WATERWAY:
4107 	case MapObjectType::ROADBASE:
4108 	case MapObjectType::PORTDOCK:
4109 	case MapObjectType::WARE:
4110 		return CAST_TO_LUA(MapObjectDescr, LuaMapObjectDescription);
4111 	}
4112 	NEVER_HERE();
4113 }
4114 
4115 #undef CAST_TO_LUA
4116 
4117 /*
4118  ==========================================================
4119  LUA METHODS
4120  ==========================================================
4121  */
__eq(lua_State * L)4122 int LuaMapObject::__eq(lua_State* L) {
4123 	EditorGameBase& egbase = get_egbase(L);
4124 	LuaMapObject* other = *get_base_user_class<LuaMapObject>(L, -1);
4125 
4126 	MapObject* me = get_or_zero(egbase);
4127 	MapObject* you = other->get_or_zero(egbase);
4128 
4129 	// Both objects are destroyed (nullptr) or equal: they are equal
4130 	if (me == you) {
4131 		lua_pushboolean(L, true);
4132 	} else if (me == nullptr ||
4133 	           you == nullptr) {  // One of the objects is destroyed: they are distinct
4134 		lua_pushboolean(L, false);
4135 	} else {  // Compare their serial number.
4136 		lua_pushboolean(L, other->get(L, egbase)->serial() == get(L, egbase)->serial());
4137 	}
4138 
4139 	return 1;
4140 }
4141 
4142 /* RST
4143    .. method:: remove()
4144 
4145       Removes this object immediately. If you want to destroy an
4146       object as if the player had see :func:`destroy`.
4147 */
remove(lua_State * L)4148 int LuaMapObject::remove(lua_State* L) {
4149 	EditorGameBase& egbase = get_egbase(L);
4150 	MapObject* o = get(L, egbase);
4151 	if (!o) {
4152 		return 0;
4153 	}
4154 
4155 	o->remove(egbase);
4156 	return 0;
4157 }
4158 
4159 /* RST
4160    .. method:: destroy()
4161 
4162       Removes this object immediately. Might do special actions (like leaving a
4163       burning fire). If you want to remove an object without side effects, see
4164       :func:`remove`.
4165 */
destroy(lua_State * L)4166 int LuaMapObject::destroy(lua_State* L) {
4167 	EditorGameBase& egbase = get_egbase(L);
4168 	MapObject* o = get(L, egbase);
4169 	if (!o) {
4170 		return 0;
4171 	}
4172 
4173 	o->destroy(egbase);
4174 	return 0;
4175 }
4176 
4177 /* RST
4178    .. method:: has_attribute(string)
4179 
4180       returns true, if the map object has this attribute, else false
4181 */
has_attribute(lua_State * L)4182 int LuaMapObject::has_attribute(lua_State* L) {
4183 	EditorGameBase& egbase = get_egbase(L);
4184 	MapObject* obj = get_or_zero(egbase);
4185 	if (!obj) {
4186 		lua_pushboolean(L, false);
4187 		return 1;
4188 	}
4189 
4190 	// Check if object has the attribute
4191 	std::string attrib = luaL_checkstring(L, 2);
4192 	if (obj->has_attribute(MapObjectDescr::get_attribute_id(attrib))) {
4193 		lua_pushboolean(L, true);
4194 	} else {
4195 		lua_pushboolean(L, false);
4196 	}
4197 	return 1;
4198 }
4199 
4200 /*
4201  ==========================================================
4202  C METHODS
4203  ==========================================================
4204  */
get(lua_State * L,EditorGameBase & egbase,std::string name)4205 MapObject* LuaMapObject::get(lua_State* L, EditorGameBase& egbase, std::string name) {
4206 	MapObject* o = get_or_zero(egbase);
4207 	if (!o) {
4208 		report_error(L, "%s no longer exists!", name.c_str());
4209 	}
4210 	return o;
4211 }
get_or_zero(EditorGameBase & egbase)4212 MapObject* LuaMapObject::get_or_zero(EditorGameBase& egbase) {
4213 	return ptr_.get(egbase);
4214 }
4215 
4216 /* RST
4217 BaseImmovable
4218 -------------
4219 
4220 .. class:: BaseImmovable
4221 
4222    Child of: :class:`MapObject`
4223 
4224    This is the base class for all immovables in Widelands.
4225 
4226    More properties are available through this object's
4227    :class:`ImmovableDescription`, which you can access via :any:`MapObject.descr`.
4228 */
4229 const char LuaBaseImmovable::className[] = "BaseImmovable";
4230 const MethodType<LuaBaseImmovable> LuaBaseImmovable::Methods[] = {
4231    {nullptr, nullptr},
4232 };
4233 const PropertyType<LuaBaseImmovable> LuaBaseImmovable::Properties[] = {
4234    PROP_RO(LuaBaseImmovable, fields), {nullptr, nullptr, nullptr},
4235 };
4236 
4237 /*
4238  ==========================================================
4239  PROPERTIES
4240  ==========================================================
4241  */
4242 
4243 /* RST
4244    .. attribute:: fields
4245 
4246       (RO) An :class:`array` of :class:`~wl.map.Field` that is occupied by this
4247       Immovable. If the immovable occupies more than one field (roads or big
4248       buildings for example) the first entry in this list will be the main field
4249 */
get_fields(lua_State * L)4250 int LuaBaseImmovable::get_fields(lua_State* L) {
4251 	EditorGameBase& egbase = get_egbase(L);
4252 
4253 	BaseImmovable::PositionList pl = get(L, egbase)->get_positions(egbase);
4254 
4255 	lua_createtable(L, pl.size(), 0);
4256 	uint32_t idx = 1;
4257 	for (const Coords& coords : pl) {
4258 		lua_pushuint32(L, idx++);
4259 		to_lua<LuaField>(L, new LuaField(coords.x, coords.y));
4260 		lua_rawset(L, -3);
4261 	}
4262 	return 1;
4263 }
4264 
4265 /*
4266  ==========================================================
4267  LUA METHODS
4268  ==========================================================
4269  */
4270 
4271 /*
4272  ==========================================================
4273  C METHODS
4274  ==========================================================
4275  */
4276 
4277 /* RST
4278 PlayerImmovable
4279 ---------------
4280 
4281 .. class:: PlayerImmovable
4282 
4283    Child of: :class:`BaseImmovable`
4284 
4285    All Immovables that belong to a Player (Buildings, Flags, ...) are based on
4286    this Class.
4287 
4288    More properties are available through this object's
4289    :class:`ImmovableDescription`, which you can access via :any:`MapObject.descr`.
4290 */
4291 const char LuaPlayerImmovable::className[] = "PlayerImmovable";
4292 const MethodType<LuaPlayerImmovable> LuaPlayerImmovable::Methods[] = {
4293    {nullptr, nullptr},
4294 };
4295 const PropertyType<LuaPlayerImmovable> LuaPlayerImmovable::Properties[] = {
4296    PROP_RO(LuaPlayerImmovable, owner),
4297    PROP_RO(LuaPlayerImmovable, debug_ware_economy),
4298    PROP_RO(LuaPlayerImmovable, debug_worker_economy),
4299    {nullptr, nullptr, nullptr},
4300 };
4301 
4302 /*
4303  ==========================================================
4304  PROPERTIES
4305  ==========================================================
4306  */
4307 /* RST
4308    .. attribute:: owner
4309 
4310       (RO) The :class:`wl.game.Player` who owns this object.
4311 */
get_owner(lua_State * L)4312 int LuaPlayerImmovable::get_owner(lua_State* L) {
4313 	get_factory(L).push_player(L, get(L, get_egbase(L))->get_owner()->player_number());
4314 	return 1;
4315 }
4316 
4317 // UNTESTED, for debug only
get_debug_ware_economy(lua_State * L)4318 int LuaPlayerImmovable::get_debug_ware_economy(lua_State* L) {
4319 	lua_pushlightuserdata(L, get(L, get_egbase(L))->get_economy(wwWARE));
4320 	return 1;
4321 }
get_debug_worker_economy(lua_State * L)4322 int LuaPlayerImmovable::get_debug_worker_economy(lua_State* L) {
4323 	lua_pushlightuserdata(L, get(L, get_egbase(L))->get_economy(wwWORKER));
4324 	return 1;
4325 }
4326 
4327 /*
4328  ==========================================================
4329  LUA METHODS
4330  ==========================================================
4331  */
4332 
4333 /*
4334  ==========================================================
4335  C METHODS
4336  ==========================================================
4337  */
4338 
4339 /* RST
4340 Flag
4341 --------
4342 
4343 .. class:: Flag
4344 
4345    Child of: :class:`PlayerImmovable`, :class:`HasWares`
4346 
4347    One flag in the economy of this Player.
4348 
4349    More properties are available through this object's
4350    :class:`ImmovableDescription`, which you can access via :any:`MapObject.descr`.
4351 */
4352 const char LuaFlag::className[] = "Flag";
4353 const MethodType<LuaFlag> LuaFlag::Methods[] = {
4354    METHOD(LuaFlag, set_wares), METHOD(LuaFlag, get_wares), {nullptr, nullptr},
4355 };
4356 const PropertyType<LuaFlag> LuaFlag::Properties[] = {
4357    PROP_RO(LuaFlag, ware_economy), PROP_RO(LuaFlag, worker_economy), PROP_RO(LuaFlag, roads),
4358    PROP_RO(LuaFlag, building),     {nullptr, nullptr, nullptr},
4359 };
4360 
4361 /*
4362  ==========================================================
4363  PROPERTIES
4364  ==========================================================
4365  */
4366 /* RST
4367    .. attribute:: ware_economy
4368 
4369       (RO) Returns the ware economy that this flag belongs to.
4370 
4371       **Warning**: Since economies can disappear when a player merges them
4372       through placing/deleting roads and flags, you must get a fresh economy
4373       object every time you call another function on the resulting economy object.
4374 
4375       :returns: The :class:`Economy` associated with the flag to handle wares.
4376 */
get_ware_economy(lua_State * L)4377 int LuaFlag::get_ware_economy(lua_State* L) {
4378 	const Flag* f = get(L, get_egbase(L));
4379 	return to_lua<LuaEconomy>(L, new LuaEconomy(f->get_economy(wwWARE)));
4380 }
4381 
4382 /* RST
4383    .. attribute:: worker_economy
4384 
4385       (RO) Returns the worker economy that this flag belongs to.
4386 
4387       **Warning**: Since economies can disappear when a player merges them
4388       through placing/deleting roads and flags, you must get a fresh economy
4389       object every time you call another function on the resulting economy object.
4390 
4391       :returns: The :class:`Economy` associated with the flag to handle workers.
4392 */
get_worker_economy(lua_State * L)4393 int LuaFlag::get_worker_economy(lua_State* L) {
4394 	const Flag* f = get(L, get_egbase(L));
4395 	return to_lua<LuaEconomy>(L, new LuaEconomy(f->get_economy(wwWORKER)));
4396 }
4397 
4398 /* RST
4399    .. attribute:: roads
4400 
4401       (RO) Array of roads leading to the flag. Directions
4402       can be tr,r,br,bl,l and tl
4403       Note that waterways are currently treated like roads.
4404 
4405       :returns: The array of 'direction:road', if any
4406 */
get_roads(lua_State * L)4407 int LuaFlag::get_roads(lua_State* L) {
4408 
4409 	const std::vector<std::string> directions = {"tr", "r", "br", "bl", "l", "tl"};
4410 
4411 	lua_newtable(L);
4412 
4413 	EditorGameBase& egbase = get_egbase(L);
4414 	Flag* f = get(L, egbase);
4415 
4416 	for (uint32_t i = 1; i <= 6; i++) {
4417 		if (f->get_roadbase(i) != nullptr) {
4418 			lua_pushstring(L, directions.at(i - 1));
4419 			upcasted_map_object_to_lua(L, f->get_roadbase(i));
4420 			lua_rawset(L, -3);
4421 		}
4422 	}
4423 	return 1;
4424 }
4425 
4426 /* RST
4427    .. attribute:: building
4428 
4429       (RO) building belonging to the flag
4430 */
get_building(lua_State * L)4431 int LuaFlag::get_building(lua_State* L) {
4432 
4433 	EditorGameBase& egbase = get_egbase(L);
4434 	Flag* f = get(L, egbase);
4435 
4436 	PlayerImmovable* building = f->get_building();
4437 	if (!building) {
4438 		return 0;
4439 	} else {
4440 		upcasted_map_object_to_lua(L, building);
4441 	}
4442 	return 1;
4443 }
4444 /*
4445  ==========================================================
4446  LUA METHODS
4447  ==========================================================
4448  */
4449 // Documented in ParentClass
set_wares(lua_State * L)4450 int LuaFlag::set_wares(lua_State* L) {
4451 	EditorGameBase& egbase = get_egbase(L);
4452 	Flag* f = get(L, egbase);
4453 	const Tribes& tribes = egbase.tribes();
4454 
4455 	InputMap setpoints;
4456 	parse_wares_workers_counted(L, f->owner().tribe(), &setpoints, true);
4457 	WaresWorkersMap c_wares = count_wares_on_flag_(*f, tribes);
4458 
4459 	Widelands::Quantity nwares = 0;
4460 
4461 	for (const auto& ware : c_wares) {
4462 		// all wares currently on the flag without a setpoint should be removed
4463 		if (!setpoints.count(std::make_pair(ware.first, Widelands::WareWorker::wwWARE))) {
4464 			setpoints.insert(
4465 			   std::make_pair(std::make_pair(ware.first, Widelands::WareWorker::wwWARE), 0));
4466 		}
4467 		nwares += ware.second;
4468 	}
4469 
4470 	// The idea is to change as little as possible on this flag
4471 	for (const auto& sp : setpoints) {
4472 		uint32_t cur = 0;
4473 		const Widelands::DescriptionIndex& index = sp.first.first;
4474 		WaresWorkersMap::iterator i = c_wares.find(index);
4475 		if (i != c_wares.end()) {
4476 			cur = i->second;
4477 		}
4478 
4479 		int d = sp.second - cur;
4480 		nwares += d;
4481 
4482 		if (f->total_capacity() < nwares) {
4483 			report_error(L, "Flag has no capacity left!");
4484 		}
4485 
4486 		if (d < 0) {
4487 			while (d) {
4488 				for (const WareInstance* ware : f->get_wares()) {
4489 					if (tribes.ware_index(ware->descr().name()) == index) {
4490 						const_cast<WareInstance*>(ware)->remove(egbase);
4491 						++d;
4492 						break;
4493 					}
4494 				}
4495 			}
4496 		} else if (d > 0) {
4497 			// add wares
4498 			const WareDescr& wd = *tribes.get_ware_descr(index);
4499 			for (int32_t j = 0; j < d; j++) {
4500 				WareInstance& ware = *new WareInstance(index, &wd);
4501 				ware.init(egbase);
4502 				f->add_ware(egbase, ware);
4503 			}
4504 		}
4505 #ifndef NDEBUG
4506 		if (sp.second > 0) {
4507 			c_wares = count_wares_on_flag_(*f, tribes);
4508 			assert(c_wares.count(index) == 1);
4509 			assert(c_wares.at(index) == sp.second);
4510 		}
4511 #endif
4512 	}
4513 	return 0;
4514 }
4515 
4516 // Documented in parent Class
get_wares(lua_State * L)4517 int LuaFlag::get_wares(lua_State* L) {
4518 	EditorGameBase& egbase = get_egbase(L);
4519 	const Tribes& tribes = egbase.tribes();
4520 	Flag* flag = get(L, egbase);
4521 	const TribeDescr& tribe = flag->owner().tribe();
4522 
4523 	DescriptionIndex ware_index = INVALID_INDEX;
4524 	std::vector<DescriptionIndex> ware_list;
4525 	RequestedWareWorker parse_output =
4526 	   parse_wares_workers_list(L, tribe, &ware_index, &ware_list, true);
4527 
4528 	WaresWorkersMap wares = count_wares_on_flag_(*flag, tribes);
4529 
4530 	// Here we create the output - either a single integer of table of pairs
4531 	if (ware_index != INVALID_INDEX) {
4532 		uint32_t wares_here = 0;
4533 		if (wares.count(ware_index)) {
4534 			wares_here = wares[ware_index];
4535 		}
4536 		lua_pushuint32(L, wares_here);
4537 	} else {
4538 		// or it is a list of wares
4539 		assert(!ware_list.empty());
4540 		lua_newtable(L);
4541 		// iterating over list of queryied wares
4542 		for (auto idx : ware_list) {
4543 
4544 			uint32_t cnt = 0;
4545 			if (wares.count(idx)) {
4546 				cnt = wares[idx];
4547 			}
4548 			// the information is pushed if count > 0, or the ware was explicitely asked for
4549 			if (parse_output != RequestedWareWorker::kAll || cnt > 0) {
4550 				lua_pushstring(L, tribe.get_ware_descr(idx)->name());
4551 				lua_pushuint32(L, cnt);
4552 				lua_settable(L, -3);
4553 			}
4554 		}
4555 	}
4556 
4557 	return 1;
4558 }
4559 
4560 /*
4561  ==========================================================
4562  C METHODS
4563  ==========================================================
4564  */
4565 
4566 /* RST
4567 Road
4568 ----
4569 
4570 .. class:: Road
4571 
4572    Child of: :class:`PlayerImmovable`, :class:`HasWorkers`
4573 
4574    A road connecting two flags in the economy of this Player.
4575    Waterways are currently treated like roads in scripts; however,
4576    there are significant differences. You can check whether an
4577    instance of Road is a road or waterway using `get_road_type()`.
4578 
4579    More properties are available through this object's
4580    :class:`ImmovableDescription`, which you can access via :any:`MapObject.descr`.
4581 */
4582 const char LuaRoad::className[] = "Road";
4583 const MethodType<LuaRoad> LuaRoad::Methods[] = {
4584    METHOD(LuaRoad, get_workers), METHOD(LuaRoad, set_workers), {nullptr, nullptr},
4585 };
4586 const PropertyType<LuaRoad> LuaRoad::Properties[] = {
4587    PROP_RO(LuaRoad, length),        PROP_RO(LuaRoad, start_flag), PROP_RO(LuaRoad, end_flag),
4588    PROP_RO(LuaRoad, valid_workers), PROP_RO(LuaRoad, road_type),  {nullptr, nullptr, nullptr},
4589 };
4590 
4591 /*
4592  ==========================================================
4593  PROPERTIES
4594  ==========================================================
4595  */
4596 /* RST
4597    .. attribute:: length
4598 
4599       (RO) The length of the roads in number of edges.
4600 */
get_length(lua_State * L)4601 int LuaRoad::get_length(lua_State* L) {
4602 	lua_pushuint32(L, get(L, get_egbase(L))->get_path().get_nsteps());
4603 	return 1;
4604 }
4605 
4606 /* RST
4607    .. attribute:: start_flag
4608 
4609       (RO) The flag were this road starts
4610 */
get_start_flag(lua_State * L)4611 int LuaRoad::get_start_flag(lua_State* L) {
4612 	return to_lua<LuaFlag>(L, new LuaFlag(get(L, get_egbase(L))->get_flag(RoadBase::FlagStart)));
4613 }
4614 
4615 /* RST
4616    .. attribute:: end_flag
4617 
4618       (RO) The flag were this road ends
4619 */
get_end_flag(lua_State * L)4620 int LuaRoad::get_end_flag(lua_State* L) {
4621 	return to_lua<LuaFlag>(L, new LuaFlag(get(L, get_egbase(L))->get_flag(RoadBase::FlagEnd)));
4622 }
4623 
4624 /* RST
4625    .. attribute:: road_type
4626 
4627       (RO) Type of road. Can be any either of:
4628 
4629       * normal
4630       * busy
4631       * waterway
4632 */
get_road_type(lua_State * L)4633 int LuaRoad::get_road_type(lua_State* L) {
4634 	RoadBase* r = get(L, get_egbase(L));
4635 	if (r->descr().type() == MapObjectType::WATERWAY) {
4636 		lua_pushstring(L, "waterway");
4637 	} else if (upcast(Road, road, r)) {
4638 		lua_pushstring(L, road->is_busy() ? "busy" : "normal");
4639 	} else {
4640 		report_error(L, "Unknown road type! Please report as a bug!");
4641 	}
4642 	return 1;
4643 }
4644 
4645 // documented in parent class
get_valid_workers(lua_State * L)4646 int LuaRoad::get_valid_workers(lua_State* L) {
4647 	RoadBase* road = get(L, get_egbase(L));
4648 	return workers_map_to_lua(L, get_valid_workers_for(*road));
4649 }
4650 
4651 /*
4652  ==========================================================
4653  LUA METHODS
4654  ==========================================================
4655  */
4656 
4657 // documented in parent class
get_workers(lua_State * L)4658 int LuaRoad::get_workers(lua_State* L) {
4659 	RoadBase* road = get(L, get_egbase(L));
4660 	return do_get_workers(L, *road, get_valid_workers_for(*road));
4661 }
4662 
set_workers(lua_State * L)4663 int LuaRoad::set_workers(lua_State* L) {
4664 	RoadBase* road = get(L, get_egbase(L));
4665 	return do_set_workers<LuaRoad>(L, road, get_valid_workers_for(*road));
4666 }
4667 
4668 /*
4669  ==========================================================
4670  C METHODS
4671  ==========================================================
4672  */
4673 
create_new_worker(PlayerImmovable & pi,EditorGameBase & egbase,const WorkerDescr * wdes)4674 int LuaRoad::create_new_worker(PlayerImmovable& pi,
4675                                EditorGameBase& egbase,
4676                                const WorkerDescr* wdes) {
4677 	RoadBase& r = static_cast<RoadBase&>(pi);
4678 
4679 	if (r.get_workers().size()) {
4680 		return -1;  // No space
4681 	}
4682 
4683 	// Determine Idle position.
4684 	Flag& start = r.get_flag(RoadBase::FlagStart);
4685 	Coords idle_position = start.get_position();
4686 	const Path& path = r.get_path();
4687 	Path::StepVector::size_type idle_index = r.get_idle_index();
4688 	for (Path::StepVector::size_type i = 0; i < idle_index; ++i) {
4689 		egbase.map().get_neighbour(idle_position, path[i], &idle_position);
4690 	}
4691 
4692 	Carrier& carrier =
4693 	   dynamic_cast<Carrier&>(wdes->create(egbase, r.get_owner(), &r, idle_position));
4694 
4695 	if (upcast(Game, game, &egbase)) {
4696 		carrier.start_task_road(*game);
4697 	}
4698 
4699 	r.assign_carrier(carrier, 0);
4700 	return 0;
4701 }
4702 
4703 /* RST
4704 PortDock
4705 --------
4706 
4707 .. class:: PortDock
4708 
4709    Child of: :class:`PlayerImmovable`
4710 
4711    Each :class:`Warehouse` that is a port has a dock attached to
4712    it. The PortDock is an immovable that also occupies a field on
4713    the water near the port.
4714 
4715    More properties are available through this object's
4716    :class:`ImmovableDescription`, which you can access via :any:`MapObject.descr`.
4717 */
4718 
4719 const char LuaPortDock::className[] = "PortDock";
4720 const MethodType<LuaPortDock> LuaPortDock::Methods[] = {
4721    {nullptr, nullptr},
4722 };
4723 const PropertyType<LuaPortDock> LuaPortDock::Properties[] = {
4724    {nullptr, nullptr, nullptr},
4725 };
4726 
4727 /*
4728  ==========================================================
4729  PROPERTIES
4730  ==========================================================
4731  */
4732 
4733 /*
4734  ==========================================================
4735  LUA METHODS
4736  ==========================================================
4737  */
4738 
4739 /*
4740  ==========================================================
4741  C METHODS
4742  ==========================================================
4743  */
4744 
4745 /* RST
4746 Building
4747 --------
4748 
4749 .. class:: Building
4750 
4751    Child of: :class:`PlayerImmovable`
4752 
4753    This represents a building owned by a player.
4754 
4755    More properties are available through this object's
4756    :class:`BuildingDescription`, which you can access via :any:`MapObject.descr`.
4757 */
4758 const char LuaBuilding::className[] = "Building";
4759 const MethodType<LuaBuilding> LuaBuilding::Methods[] = {
4760    {nullptr, nullptr},
4761 };
4762 const PropertyType<LuaBuilding> LuaBuilding::Properties[] = {
4763    PROP_RO(LuaBuilding, flag), {nullptr, nullptr, nullptr},
4764 };
4765 
4766 /*
4767  ==========================================================
4768  PROPERTIES
4769  ==========================================================
4770  */
4771 
4772 /* RST
4773    .. attribute:: flag
4774 
4775       (RO) The flag that belongs to this building (that is to the bottom right
4776       of it's main location).
4777 */
4778 // UNTESTED
get_flag(lua_State * L)4779 int LuaBuilding::get_flag(lua_State* L) {
4780 	return upcasted_map_object_to_lua(L, &get(L, get_egbase(L))->base_flag());
4781 }
4782 
4783 /*
4784  ==========================================================
4785  LUA METHODS
4786  ==========================================================
4787  */
4788 
4789 /*
4790  ==========================================================
4791  C METHODS
4792  ==========================================================
4793  */
4794 
4795 /* RST
4796 ConstructionSite
4797 -----------------
4798 
4799 .. class:: ConstructionSite
4800 
4801    Child of: :class:`Building`
4802 
4803    A ConstructionSite as it appears in Game. This is only a minimal wrapping at
4804    the moment.
4805 
4806    More properties are available through this object's
4807    :class:`ConstructionSiteDescription`, which you can access via :any:`MapObject.descr`.
4808 */
4809 const char LuaConstructionSite::className[] = "ConstructionSite";
4810 const MethodType<LuaConstructionSite> LuaConstructionSite::Methods[] = {
4811    {nullptr, nullptr},
4812 };
4813 const PropertyType<LuaConstructionSite> LuaConstructionSite::Properties[] = {
4814    PROP_RO(LuaConstructionSite, building), {nullptr, nullptr, nullptr},
4815 };
4816 
4817 /*
4818  ==========================================================
4819  PROPERTIES
4820  ==========================================================
4821  */
4822 /* RST
4823    .. attribute:: building
4824 
4825       (RO) The name of the building that is constructed here
4826 */
get_building(lua_State * L)4827 int LuaConstructionSite::get_building(lua_State* L) {
4828 	lua_pushstring(L, get(L, get_egbase(L))->building().name());
4829 	return 1;
4830 }
4831 
4832 /*
4833  ==========================================================
4834  LUA METHODS
4835  ==========================================================
4836  */
4837 
4838 /*
4839  ==========================================================
4840  C METHODS
4841  ==========================================================
4842  */
4843 
4844 /* RST
4845 Warehouse
4846 ---------
4847 
4848 .. class:: Warehouse
4849 
4850    Child of: :class:`Building`, :class:`HasWares`, :class:`HasWorkers`,
4851    :class:`HasSoldiers`
4852 
4853    Every Headquarter, Port or Warehouse on the Map is of this type.
4854 
4855    More properties are available through this object's
4856    :class:`WarehouseDescription`, which you can access via :any:`MapObject.descr`.
4857 */
4858 const char LuaWarehouse::className[] = "Warehouse";
4859 const MethodType<LuaWarehouse> LuaWarehouse::Methods[] = {
4860    METHOD(LuaWarehouse, set_wares),
4861    METHOD(LuaWarehouse, get_wares),
4862    METHOD(LuaWarehouse, set_workers),
4863    METHOD(LuaWarehouse, get_workers),
4864    METHOD(LuaWarehouse, set_soldiers),
4865    METHOD(LuaWarehouse, get_soldiers),
4866    METHOD(LuaWarehouse, set_warehouse_policies),
4867    METHOD(LuaWarehouse, get_warehouse_policies),
4868    METHOD(LuaWarehouse, start_expedition),
4869    METHOD(LuaWarehouse, cancel_expedition),
4870    {nullptr, nullptr},
4871 };
4872 const PropertyType<LuaWarehouse> LuaWarehouse::Properties[] = {
4873    PROP_RO(LuaWarehouse, portdock),
4874    PROP_RO(LuaWarehouse, expedition_in_progress),
4875    {nullptr, nullptr, nullptr},
4876 };
4877 
4878 /*
4879  ==========================================================
4880  PROPERTIES
4881  ==========================================================
4882  */
4883 // UNTESTED
4884 /* RST
4885    .. attribute:: portdock
4886 
4887       (RO) If this Warehouse is a port, returns the
4888       :class:`PortDock` attached to it, otherwise nil.
4889 */
get_portdock(lua_State * L)4890 int LuaWarehouse::get_portdock(lua_State* L) {
4891 	return upcasted_map_object_to_lua(L, get(L, get_egbase(L))->get_portdock());
4892 }
4893 
4894 /* RST
4895    .. attribute:: expedition_in_progress
4896 
4897       (RO) If this Warehouse is a port, and an expedition is in
4898       progress, returns true, otherwise nil
4899 */
get_expedition_in_progress(lua_State * L)4900 int LuaWarehouse::get_expedition_in_progress(lua_State* L) {
4901 
4902 	EditorGameBase& egbase = get_egbase(L);
4903 
4904 	if (is_a(Game, &egbase)) {
4905 		const PortDock* pd = get(L, egbase)->get_portdock();
4906 		if (pd) {
4907 			if (pd->expedition_started()) {
4908 				return 1;
4909 			}
4910 		}
4911 	}
4912 	return 0;
4913 }
4914 
4915 /*
4916  ==========================================================
4917  LUA METHODS
4918  ==========================================================
4919  */
4920 
get_workers(lua_State * L)4921 int LuaWarehouse::get_workers(lua_State* L) {
4922 	Warehouse* wh = get(L, get_egbase(L));
4923 	const TribeDescr& tribe = wh->owner().tribe();
4924 
4925 	// Parsing the argument(s), result will be either single index
4926 	// or list of indexes
4927 	DescriptionIndex worker_index = INVALID_INDEX;
4928 	std::vector<DescriptionIndex> workers_list;
4929 	parse_wares_workers_list(L, tribe, &worker_index, &workers_list, false);
4930 
4931 	// Here we create the output - either a single integer of table of pairs
4932 	if (worker_index != INVALID_INDEX) {
4933 		lua_pushuint32(L, wh->get_workers().stock(worker_index));
4934 	} else if (!workers_list.empty()) {
4935 		lua_newtable(L);
4936 		for (auto idx : workers_list) {
4937 			lua_pushstring(L, tribe.get_worker_descr(idx)->name());
4938 			lua_pushuint32(L, wh->get_workers().stock(idx));
4939 			lua_settable(L, -3);
4940 		}
4941 	} else {
4942 		NEVER_HERE();
4943 	}
4944 	return 1;
4945 }
4946 
get_wares(lua_State * L)4947 int LuaWarehouse::get_wares(lua_State* L) {
4948 	Warehouse* wh = get(L, get_egbase(L));
4949 	const TribeDescr& tribe = wh->owner().tribe();
4950 
4951 	// Parsing the argument(s), result will be either single index
4952 	// or list of indexes
4953 	DescriptionIndex ware_index = INVALID_INDEX;
4954 	std::vector<DescriptionIndex> ware_list;
4955 	parse_wares_workers_list(L, tribe, &ware_index, &ware_list, true);
4956 
4957 	// Here we create the output - either a single integer of table of pairs
4958 	if (ware_index != INVALID_INDEX) {
4959 		lua_pushuint32(L, wh->get_wares().stock(ware_index));
4960 	} else if (!ware_list.empty()) {
4961 		lua_newtable(L);
4962 		for (auto idx : ware_list) {
4963 			lua_pushstring(L, tribe.get_ware_descr(idx)->name());
4964 			lua_pushuint32(L, wh->get_wares().stock(idx));
4965 			lua_settable(L, -3);
4966 		}
4967 	} else {
4968 		NEVER_HERE();
4969 	}
4970 	return 1;
4971 }
4972 
set_wares(lua_State * L)4973 int LuaWarehouse::set_wares(lua_State* L) {
4974 	Warehouse* wh = get(L, get_egbase(L));
4975 	const TribeDescr& tribe = wh->owner().tribe();
4976 	InputMap setpoints;
4977 	parse_wares_workers_counted(L, tribe, &setpoints, true);
4978 
4979 	for (const auto& ware : setpoints) {
4980 		const Widelands::DescriptionIndex& index = ware.first.first;
4981 		int32_t d = ware.second - wh->get_wares().stock(index);
4982 		if (d < 0) {
4983 			wh->remove_wares(index, -d);
4984 		} else if (d > 0) {
4985 			wh->insert_wares(index, d);
4986 		}
4987 	}
4988 	return 0;
4989 }
4990 
set_workers(lua_State * L)4991 int LuaWarehouse::set_workers(lua_State* L) {
4992 	Warehouse* wh = get(L, get_egbase(L));
4993 	const TribeDescr& tribe = wh->owner().tribe();
4994 	InputMap setpoints;
4995 	parse_wares_workers_counted(L, tribe, &setpoints, false);
4996 
4997 	for (const auto& worker : setpoints) {
4998 		const Widelands::DescriptionIndex& index = worker.first.first;
4999 		int32_t d = worker.second - wh->get_workers().stock(index);
5000 		if (d < 0) {
5001 			wh->remove_workers(index, -d);
5002 		} else if (d > 0) {
5003 			wh->insert_workers(index, d);
5004 		}
5005 	}
5006 	return 0;
5007 }
5008 
5009 // Transforms the given warehouse policy to a string which is used by the lua code
wh_policy_to_string(lua_State * L,StockPolicy p)5010 inline void wh_policy_to_string(lua_State* L, StockPolicy p) {
5011 	switch (p) {
5012 	case StockPolicy::kNormal:
5013 		lua_pushstring(L, "normal");
5014 		break;
5015 	case StockPolicy::kPrefer:
5016 		lua_pushstring(L, "prefer");
5017 		break;
5018 	case StockPolicy::kDontStock:
5019 		lua_pushstring(L, "dontstock");
5020 		break;
5021 	case StockPolicy::kRemove:
5022 		lua_pushstring(L, "remove");
5023 		break;
5024 	}
5025 }
5026 // Transforms the given string from the lua code to a warehouse policy
string_to_wh_policy(lua_State * L,uint32_t index)5027 inline StockPolicy string_to_wh_policy(lua_State* L, uint32_t index) {
5028 	std::string str = luaL_checkstring(L, index);
5029 	if (str == "normal") {
5030 		return StockPolicy::kNormal;
5031 	} else if (str == "prefer") {
5032 		return StockPolicy::kPrefer;
5033 	} else if (str == "dontstock") {
5034 		return StockPolicy::kDontStock;
5035 	} else if (str == "remove") {
5036 		return StockPolicy::kRemove;
5037 	} else {
5038 		report_error(L, "<%s> is no valid warehouse policy!", str.c_str());
5039 	}
5040 }
5041 
do_set_ware_policy(Warehouse * wh,const DescriptionIndex idx,const StockPolicy p)5042 inline bool do_set_ware_policy(Warehouse* wh, const DescriptionIndex idx, const StockPolicy p) {
5043 	wh->set_ware_policy(idx, p);
5044 	return true;
5045 }
5046 
5047 /**
5048  * Sets the given policy for the given ware in the given warehouse and return true.
5049  * If the no ware with the given name exists for the tribe of the warehouse, return false.
5050  */
do_set_ware_policy(Warehouse * wh,const std::string & name,const StockPolicy p)5051 inline bool do_set_ware_policy(Warehouse* wh, const std::string& name, const StockPolicy p) {
5052 	const TribeDescr& tribe = wh->owner().tribe();
5053 	DescriptionIndex idx = tribe.ware_index(name);
5054 	if (!tribe.has_ware(idx)) {
5055 		return false;
5056 	}
5057 	return do_set_ware_policy(wh, idx, p);
5058 }
5059 
do_set_worker_policy(Warehouse * wh,const DescriptionIndex idx,const StockPolicy p)5060 inline bool do_set_worker_policy(Warehouse* wh, const DescriptionIndex idx, const StockPolicy p) {
5061 	const TribeDescr& tribe = wh->owner().tribe();
5062 	// If the worker does not cost anything, ignore it
5063 	// Otherwise, an unlimited stream of carriers might leave the warehouse
5064 	if (tribe.get_worker_descr(idx)->is_buildable() &&
5065 	    tribe.get_worker_descr(idx)->buildcost().empty()) {
5066 		return true;
5067 	}
5068 	wh->set_worker_policy(idx, p);
5069 	return true;
5070 }
5071 
5072 /**
5073  * Sets the given policy for the given worker in the given warehouse and returns true.
5074  * Also returns true if the given worker does not cost anything but in this case does not set its
5075  * policy.
5076  * If no worker with the given name exists for the tribe of the warehouse, return false.
5077  */
do_set_worker_policy(Warehouse * wh,const std::string & name,const StockPolicy p)5078 inline bool do_set_worker_policy(Warehouse* wh, const std::string& name, const StockPolicy p) {
5079 	const TribeDescr& tribe = wh->owner().tribe();
5080 	DescriptionIndex idx = tribe.worker_index(name);
5081 	if (!tribe.has_worker(idx)) {
5082 		return false;
5083 	}
5084 	return do_set_worker_policy(wh, idx, p);
5085 }
5086 /* RST
5087    .. method:: set_warehouse_policies(which, policy)
5088 
5089       Sets the policies how the warehouse should handle the given wares and workers.
5090 
5091       Usage example:
5092 
5093       .. code-block:: lua
5094 
5095          wh:set_warehouse_policies("coal", "prefer")
5096 
5097       :arg which: behaves like for :meth:`HasWares.get_wares`.
5098 
5099       :arg policy: the policy to apply for all the wares and workers given in `which`.
5100       :type policy: a string out of "normal", "prefer", "dontstock", "remove".
5101 */
set_warehouse_policies(lua_State * L)5102 int LuaWarehouse::set_warehouse_policies(lua_State* L) {
5103 	int32_t nargs = lua_gettop(L);
5104 	if (nargs != 3) {
5105 		report_error(L, "Wrong number of arguments to set_warehouse_policies!");
5106 	}
5107 
5108 	Warehouse* wh = get(L, get_egbase(L));
5109 	StockPolicy p = string_to_wh_policy(L, -1);
5110 	lua_pop(L, 1);
5111 	const TribeDescr& tribe = wh->owner().tribe();
5112 
5113 	// takes either "all", a name or an array of names
5114 	if (lua_isstring(L, 2)) {
5115 		const std::string& what = luaL_checkstring(L, -1);
5116 		if (what == "all") {
5117 			for (const DescriptionIndex& i : tribe.wares()) {
5118 				do_set_ware_policy(wh, i, p);
5119 			}
5120 			for (const DescriptionIndex& i : tribe.workers()) {
5121 				do_set_worker_policy(wh, i, p);
5122 			}
5123 		} else {
5124 			// Only one item requested
5125 			if (!do_set_ware_policy(wh, what, p) && !do_set_worker_policy(wh, what, p)) {
5126 				// Unknown whatever, abort
5127 				report_error(L, "Unknown name: <%s>", what.c_str());
5128 			}
5129 		}
5130 	} else {
5131 		// array of names
5132 		luaL_checktype(L, 2, LUA_TTABLE);
5133 		lua_pushnil(L);
5134 		while (lua_next(L, 2) != 0) {
5135 			const std::string& what = luaL_checkstring(L, -1);
5136 			if (!do_set_ware_policy(wh, what, p) && !do_set_worker_policy(wh, what, p)) {
5137 				// Note that this will change the policy for entries earlier in the list
5138 				// but when the user provides broken data its his own fault
5139 				report_error(L, "Unknown name: <%s>", what.c_str());
5140 			}
5141 			lua_pop(L, 1);
5142 		}
5143 	}
5144 
5145 	return 0;
5146 }
5147 
5148 // Gets the warehouse policy by ware/worker-name or id
5149 #define WH_GET_POLICY(type)                                                                        \
5150 	inline void do_get_##type##_policy(lua_State* L, Warehouse* wh, const DescriptionIndex idx) {   \
5151 		wh_policy_to_string(L, wh->get_##type##_policy(idx));                                        \
5152 	}                                                                                               \
5153                                                                                                    \
5154 	inline bool do_get_##type##_policy(lua_State* L, Warehouse* wh, const std::string& name) {      \
5155 		const TribeDescr& tribe = wh->owner().tribe();                                               \
5156 		DescriptionIndex idx = tribe.type##_index(name);                                             \
5157 		if (!tribe.has_##type(idx)) {                                                                \
5158 			return false;                                                                             \
5159 		}                                                                                            \
5160 		do_get_##type##_policy(L, wh, idx);                                                          \
5161 		return true;                                                                                 \
5162 	}
5163 
5164 WH_GET_POLICY(ware)
WH_GET_POLICY(worker)5165 WH_GET_POLICY(worker)
5166 #undef WH_GET_POLICY
5167 
5168 /* RST
5169    .. method:: get_warehouse_policies(which)
5170 
5171       Gets the policies how the warehouse should handle the given wares and workers.
5172       The method to handle is one of the strings "normal", "prefer", "dontstock", "remove".
5173 
5174       Usage example:
5175 
5176       .. code-block:: lua
5177 
5178          wh:get_warehouse_policies({"ax", "coal"})
5179          -- Returns a table like {ax="normal", coal="prefer"}
5180 
5181       :arg which: behaves like for :meth:`HasWares.get_wares`.
5182 
5183       :returns: :class:`string` or :class:`table`
5184 */
5185 int LuaWarehouse::get_warehouse_policies(lua_State* L) {
5186 	int32_t nargs = lua_gettop(L);
5187 	if (nargs != 2) {
5188 		report_error(L, "Wrong number of arguments to get_warehouse_policies!");
5189 	}
5190 	Warehouse* wh = get(L, get_egbase(L));
5191 	const TribeDescr& tribe = wh->owner().tribe();
5192 	// takes either "all", a single name or an array of names
5193 	if (lua_isstring(L, 2)) {
5194 		std::string what = luaL_checkstring(L, -1);
5195 		if (what == "all") {
5196 			lua_newtable(L);
5197 			for (const DescriptionIndex& i : tribe.wares()) {
5198 				std::string name = tribe.get_ware_descr(i)->name();
5199 				lua_pushstring(L, name.c_str());
5200 				do_get_ware_policy(L, wh, i);
5201 				lua_rawset(L, -3);
5202 			}
5203 			for (const DescriptionIndex& i : tribe.workers()) {
5204 				std::string name = tribe.get_worker_descr(i)->name();
5205 				lua_pushstring(L, name.c_str());
5206 				do_get_worker_policy(L, wh, i);
5207 				lua_rawset(L, -3);
5208 			}
5209 		} else {
5210 			// Only one item requested
5211 			if (!do_get_ware_policy(L, wh, what) && !do_get_worker_policy(L, wh, what)) {
5212 				// Unknown whatever, abort
5213 				report_error(L, "Unknown name: <%s>", what.c_str());
5214 			}
5215 		}
5216 	} else {
5217 		// array of names
5218 		luaL_checktype(L, 2, LUA_TTABLE);
5219 		lua_newtable(L);
5220 		lua_pushnil(L);
5221 		while (lua_next(L, 2) != 0) {
5222 			// Stack is: ... input_table new_table nil input_key input_value
5223 			// input_value is the name of the ware or worker and will be added into the new table
5224 			// input_key is an index and is dropped by the next call of lua_next()
5225 			const std::string& what = luaL_checkstring(L, -1);
5226 			if (!do_get_ware_policy(L, wh, what) && !do_get_worker_policy(L, wh, what)) {
5227 				// Note that this will change the policy for entries earlier in the list
5228 				// but when the user provides broken data its his own fault
5229 				report_error(L, "Unknown name: <%s>", what.c_str());
5230 			}
5231 			lua_rawset(L, -4);
5232 		}
5233 	}
5234 	return 1;
5235 }
5236 
5237 // documented in parent class
get_soldiers(lua_State * L)5238 int LuaWarehouse::get_soldiers(lua_State* L) {
5239 	Warehouse* wh = get(L, get_egbase(L));
5240 	return do_get_soldiers(L, *wh->soldier_control(), wh->owner().tribe());
5241 }
5242 
5243 // documented in parent class
set_soldiers(lua_State * L)5244 int LuaWarehouse::set_soldiers(lua_State* L) {
5245 	Warehouse* wh = get(L, get_egbase(L));
5246 	return do_set_soldiers(L, wh->get_position(), wh->mutable_soldier_control(), wh->get_owner());
5247 }
5248 
5249 /* RST
5250    .. method:: start_expedition()
5251 
5252       Starts preparation for expedition
5253 
5254 */
start_expedition(lua_State * L)5255 int LuaWarehouse::start_expedition(lua_State* L) {
5256 
5257 	EditorGameBase& egbase = get_egbase(L);
5258 	Warehouse* wh = get(L, egbase);
5259 
5260 	if (!wh) {
5261 		return 0;
5262 	}
5263 
5264 	if (upcast(Game, game, &egbase)) {
5265 		const PortDock* pd = wh->get_portdock();
5266 		if (!pd) {
5267 			return 0;
5268 		}
5269 		if (!pd->expedition_started()) {
5270 			game->send_player_start_or_cancel_expedition(*wh);
5271 			return 1;
5272 		}
5273 	}
5274 
5275 	return 0;
5276 }
5277 
5278 /* RST
5279    .. method:: cancel_expedition()
5280 
5281       Cancels an expedition if in progress
5282 
5283 */
cancel_expedition(lua_State * L)5284 int LuaWarehouse::cancel_expedition(lua_State* L) {
5285 
5286 	EditorGameBase& egbase = get_egbase(L);
5287 	Warehouse* wh = get(L, egbase);
5288 
5289 	if (!wh) {
5290 		return 0;
5291 	}
5292 
5293 	if (upcast(Game, game, &egbase)) {
5294 		const PortDock* pd = wh->get_portdock();
5295 		if (!pd) {
5296 			return 0;
5297 		}
5298 		if (pd->expedition_started()) {
5299 			game->send_player_start_or_cancel_expedition(*wh);
5300 			return 1;
5301 		}
5302 	}
5303 
5304 	return 0;
5305 }
5306 
5307 /*
5308  ==========================================================
5309  C METHODS
5310  ==========================================================
5311  */
5312 
5313 /* RST
5314 ProductionSite
5315 --------------
5316 
5317 .. class:: ProductionSite
5318 
5319    Child of: :class:`Building`, :class:`HasInputs`, :class:`HasWorkers`
5320 
5321    Every building that produces anything.
5322 
5323    More properties are available through this object's
5324    :class:`ProductionSiteDescription`, which you can access via :any:`MapObject.descr`.
5325 */
5326 const char LuaProductionSite::className[] = "ProductionSite";
5327 const MethodType<LuaProductionSite> LuaProductionSite::Methods[] = {
5328    METHOD(LuaProductionSite, set_inputs),
5329    METHOD(LuaProductionSite, get_inputs),
5330    METHOD(LuaProductionSite, get_workers),
5331    METHOD(LuaProductionSite, set_workers),
5332    METHOD(LuaProductionSite, toggle_start_stop),
5333 
5334    {nullptr, nullptr},
5335 };
5336 const PropertyType<LuaProductionSite> LuaProductionSite::Properties[] = {
5337    PROP_RO(LuaProductionSite, valid_workers),
5338    PROP_RO(LuaProductionSite, valid_inputs),
5339    PROP_RO(LuaProductionSite, is_stopped),
5340    {nullptr, nullptr, nullptr},
5341 };
5342 
5343 /*
5344  ==========================================================
5345  PROPERTIES
5346  ==========================================================
5347  */
5348 // documented in parent class
get_valid_inputs(lua_State * L)5349 int LuaProductionSite::get_valid_inputs(lua_State* L) {
5350 	EditorGameBase& egbase = get_egbase(L);
5351 	ProductionSite* ps = get(L, egbase);
5352 
5353 	lua_newtable(L);
5354 	for (const auto& input_ware : ps->descr().input_wares()) {
5355 		const WareDescr* descr = egbase.tribes().get_ware_descr(input_ware.first);
5356 		lua_pushstring(L, descr->name());
5357 		lua_pushuint32(L, input_ware.second);
5358 		lua_rawset(L, -3);
5359 	}
5360 	for (const auto& input_worker : ps->descr().input_workers()) {
5361 		const WorkerDescr* descr = egbase.tribes().get_worker_descr(input_worker.first);
5362 		lua_pushstring(L, descr->name());
5363 		lua_pushuint32(L, input_worker.second);
5364 		lua_rawset(L, -3);
5365 	}
5366 	return 1;
5367 }
5368 
5369 // documented in parent class
get_valid_workers(lua_State * L)5370 int LuaProductionSite::get_valid_workers(lua_State* L) {
5371 	ProductionSite* ps = get(L, get_egbase(L));
5372 	return workers_map_to_lua(L, get_valid_workers_for(*ps));
5373 }
5374 
5375 /* RST
5376    .. attribute:: is_stopped
5377 
5378       (RO) Returns whether this productionsite is currently active or stopped
5379 
5380       :returns: true if the productionsite has been started,
5381          false if it has been stopped.
5382 */
get_is_stopped(lua_State * L)5383 int LuaProductionSite::get_is_stopped(lua_State* L) {
5384 	ProductionSite* ps = get(L, get_egbase(L));
5385 	lua_pushboolean(L, ps->is_stopped());
5386 	return 1;
5387 }
5388 
5389 /*
5390  ==========================================================
5391  LUA METHODS
5392  ==========================================================
5393  */
5394 // documented in parent class
set_inputs(lua_State * L)5395 int LuaProductionSite::set_inputs(lua_State* L) {
5396 	ProductionSite* ps = get(L, get_egbase(L));
5397 	const TribeDescr& tribe = ps->owner().tribe();
5398 	InputMap setpoints = parse_set_input_arguments(L, tribe);
5399 
5400 	InputSet valid_inputs;
5401 	for (const auto& input_ware : ps->descr().input_wares()) {
5402 		valid_inputs.insert(std::make_pair(input_ware.first, wwWARE));
5403 	}
5404 	for (const auto& input_worker : ps->descr().input_workers()) {
5405 		valid_inputs.insert(std::make_pair(input_worker.first, wwWORKER));
5406 	}
5407 	for (const auto& sp : setpoints) {
5408 		if (!valid_inputs.count(sp.first)) {
5409 			report_error(L, "<%s> can't be stored in this building: %s!",
5410 			             sp.first.second == wwWARE ?
5411 			                tribe.get_ware_descr(sp.first.first)->name().c_str() :
5412 			                tribe.get_worker_descr(sp.first.first)->name().c_str(),
5413 			             ps->descr().name().c_str());
5414 		}
5415 		InputQueue& iq = ps->inputqueue(sp.first.first, sp.first.second);
5416 		if (sp.second > iq.get_max_size()) {
5417 			report_error(
5418 			   L, "Not enough space for %u inputs, only for %i", sp.second, iq.get_max_size());
5419 		}
5420 		iq.set_filled(sp.second);
5421 	}
5422 
5423 	return 0;
5424 }
5425 
5426 // documented in parent class
get_inputs(lua_State * L)5427 int LuaProductionSite::get_inputs(lua_State* L) {
5428 	ProductionSite* ps = get(L, get_egbase(L));
5429 	const TribeDescr& tribe = ps->owner().tribe();
5430 
5431 	bool return_number = false;
5432 	InputSet input_set = parse_get_input_arguments(L, tribe, &return_number);
5433 
5434 	InputSet valid_inputs;
5435 	for (const auto& input_ware : ps->descr().input_wares()) {
5436 		valid_inputs.insert(std::make_pair(input_ware.first, wwWARE));
5437 	}
5438 	for (const auto& input_worker : ps->descr().input_workers()) {
5439 		valid_inputs.insert(std::make_pair(input_worker.first, wwWORKER));
5440 	}
5441 
5442 	if (input_set.size() == tribe.get_nrwares() + tribe.get_nrworkers()) {  // Want all returned
5443 		input_set = valid_inputs;
5444 	}
5445 
5446 	if (!return_number) {
5447 		lua_newtable(L);
5448 	}
5449 
5450 	for (const auto& input : input_set) {
5451 		uint32_t cnt = 0;
5452 		if (valid_inputs.count(input)) {
5453 			cnt = ps->inputqueue(input.first, input.second).get_filled();
5454 		}
5455 
5456 		if (return_number) {  // this is the only thing the customer wants to know
5457 			lua_pushuint32(L, cnt);
5458 			break;
5459 		} else {
5460 			lua_pushstring(L, input.second == wwWARE ? tribe.get_ware_descr(input.first)->name() :
5461 			                                           tribe.get_worker_descr(input.first)->name());
5462 			lua_pushuint32(L, cnt);
5463 			lua_settable(L, -3);
5464 		}
5465 	}
5466 	return 1;
5467 }
5468 
5469 // documented in parent class
get_workers(lua_State * L)5470 int LuaProductionSite::get_workers(lua_State* L) {
5471 	ProductionSite* ps = get(L, get_egbase(L));
5472 	return do_get_workers(L, *ps, get_valid_workers_for(*ps));
5473 }
5474 
5475 // documented in parent class
set_workers(lua_State * L)5476 int LuaProductionSite::set_workers(lua_State* L) {
5477 	ProductionSite* ps = get(L, get_egbase(L));
5478 	return do_set_workers<LuaProductionSite>(L, ps, get_valid_workers_for(*ps));
5479 }
5480 
5481 /* RST
5482    .. method:: toggle_start_stop()
5483 
5484       If :any:`ProductionSite.is_stopped`, sends a command to start this productionsite.
5485       Otherwise, sends a command to stop this productionsite.
5486 */
toggle_start_stop(lua_State * L)5487 int LuaProductionSite::toggle_start_stop(lua_State* L) {
5488 	Game& game = get_game(L);
5489 	ProductionSite* ps = get(L, game);
5490 	game.send_player_start_stop_building(*ps);
5491 	return 1;
5492 }
5493 
5494 /*
5495  ==========================================================
5496  C METHODS
5497  ==========================================================
5498  */
5499 
create_new_worker(PlayerImmovable & pi,EditorGameBase & egbase,const WorkerDescr * wdes)5500 int LuaProductionSite::create_new_worker(PlayerImmovable& pi,
5501                                          EditorGameBase& egbase,
5502                                          const WorkerDescr* wdes) {
5503 	ProductionSite& ps = static_cast<ProductionSite&>(pi);
5504 	return ps.warp_worker(egbase, *wdes);
5505 }
5506 
5507 /* RST
5508 Market
5509 ---------
5510 
5511 .. class:: Market
5512 
5513    Child of: :class:`Building`, :class:`HasWares`, :class:`HasWorkers`
5514 
5515    A Market used for trading with other players.
5516 
5517    More properties are available through this object's
5518    :class:`MarketDescription`, which you can access via :any:`MapObject.descr`.
5519 */
5520 const char LuaMarket::className[] = "Market";
5521 const MethodType<LuaMarket> LuaMarket::Methods[] = {
5522    METHOD(LuaMarket, propose_trade),
5523    // TODO(sirver,trading): Implement and fix documentation.
5524    // METHOD(LuaMarket, set_wares),
5525    // METHOD(LuaMarket, get_wares),
5526    // METHOD(LuaMarket, set_workers),
5527    // METHOD(LuaMarket, get_workers),
5528    {nullptr, nullptr},
5529 };
5530 const PropertyType<LuaMarket> LuaMarket::Properties[] = {
5531    {nullptr, nullptr, nullptr},
5532 };
5533 
5534 /*
5535  ==========================================================
5536  PROPERTIES
5537  ==========================================================
5538  */
5539 
5540 /*
5541  ==========================================================
5542  LUA METHODS
5543  ==========================================================
5544  */
5545 
5546 /* RST
5547    .. method:: propose_trade(other_market, num_batches, items_to_send, items_to_receive)
5548 
5549       TODO(sirver,trading): document
5550 
5551       :returns: :const:`nil`
5552 */
propose_trade(lua_State * L)5553 int LuaMarket::propose_trade(lua_State* L) {
5554 	if (lua_gettop(L) != 5) {
5555 		report_error(L, "Takes 4 arguments.");
5556 	}
5557 	Game& game = get_game(L);
5558 	Market* self = get(L, game);
5559 	Market* other_market = (*get_user_class<LuaMarket>(L, 2))->get(L, game);
5560 	const int num_batches = luaL_checkinteger(L, 3);
5561 
5562 	const BillOfMaterials items_to_send =
5563 	   parse_wares_as_bill_of_material(L, 4, self->owner().tribe());
5564 	// TODO(sirver,trading): unsure if correct. Test inter-tribe trading, i.e.
5565 	// barbarians trading with empire, but shipping atlantean only wares.
5566 	const BillOfMaterials items_to_receive =
5567 	   parse_wares_as_bill_of_material(L, 5, self->owner().tribe());
5568 	const int trade_id = game.propose_trade(
5569 	   Trade{items_to_send, items_to_receive, num_batches, self->serial(), other_market->serial()});
5570 
5571 	// TODO(sirver,trading): Wrap 'Trade' into its own Lua class?
5572 	lua_pushint32(L, trade_id);
5573 	return 1;
5574 }
5575 
5576 /*
5577  ==========================================================
5578  C METHODS
5579  ==========================================================
5580  */
5581 
5582 /* RST
5583 MilitarySite
5584 --------------
5585 
5586 .. class:: MilitarySite
5587 
5588    Child of: :class:`Building`, :class:`HasSoldiers`
5589 
5590    Miltary Buildings
5591 
5592    More properties are available through this object's
5593    :class:`MilitarySiteDescription`, which you can access via :any:`MapObject.descr`.
5594 */
5595 const char LuaMilitarySite::className[] = "MilitarySite";
5596 const MethodType<LuaMilitarySite> LuaMilitarySite::Methods[] = {
5597    METHOD(LuaMilitarySite, get_soldiers), METHOD(LuaMilitarySite, set_soldiers), {nullptr, nullptr},
5598 };
5599 const PropertyType<LuaMilitarySite> LuaMilitarySite::Properties[] = {
5600    PROP_RO(LuaMilitarySite, max_soldiers), {nullptr, nullptr, nullptr},
5601 };
5602 
5603 /*
5604  ==========================================================
5605  PROPERTIES
5606  ==========================================================
5607  */
5608 
5609 // documented in parent class
get_max_soldiers(lua_State * L)5610 int LuaMilitarySite::get_max_soldiers(lua_State* L) {
5611 	lua_pushuint32(L, get(L, get_egbase(L))->soldier_control()->soldier_capacity());
5612 	return 1;
5613 }
5614 
5615 /*
5616  ==========================================================
5617  LUA METHODS
5618  ==========================================================
5619  */
5620 
5621 // documented in parent class
get_soldiers(lua_State * L)5622 int LuaMilitarySite::get_soldiers(lua_State* L) {
5623 	MilitarySite* ms = get(L, get_egbase(L));
5624 	return do_get_soldiers(L, *ms->soldier_control(), ms->owner().tribe());
5625 }
5626 
5627 // documented in parent class
set_soldiers(lua_State * L)5628 int LuaMilitarySite::set_soldiers(lua_State* L) {
5629 	MilitarySite* ms = get(L, get_egbase(L));
5630 	return do_set_soldiers(L, ms->get_position(), ms->mutable_soldier_control(), ms->get_owner());
5631 }
5632 
5633 /*
5634  ==========================================================
5635  C METHODS
5636  ==========================================================
5637  */
5638 
5639 /* RST
5640 TrainingSite
5641 --------------
5642 
5643 .. class:: TrainingSite
5644 
5645    Child of: :class:`ProductionSite`, :class:`HasSoldiers`
5646 
5647    A specialized production site for training soldiers.
5648 
5649    More properties are available through this object's
5650    :class:`TrainingSiteDescription`, which you can access via :any:`MapObject.descr`.
5651 */
5652 const char LuaTrainingSite::className[] = "TrainingSite";
5653 const MethodType<LuaTrainingSite> LuaTrainingSite::Methods[] = {
5654    METHOD(LuaTrainingSite, get_soldiers), METHOD(LuaTrainingSite, set_soldiers), {nullptr, nullptr},
5655 };
5656 const PropertyType<LuaTrainingSite> LuaTrainingSite::Properties[] = {
5657    PROP_RO(LuaTrainingSite, max_soldiers), {nullptr, nullptr, nullptr},
5658 };
5659 
5660 /*
5661  ==========================================================
5662  PROPERTIES
5663  ==========================================================
5664  */
5665 
5666 // documented in parent class
get_max_soldiers(lua_State * L)5667 int LuaTrainingSite::get_max_soldiers(lua_State* L) {
5668 	lua_pushuint32(L, get(L, get_egbase(L))->soldier_control()->soldier_capacity());
5669 	return 1;
5670 }
5671 
5672 /*
5673  ==========================================================
5674  LUA METHODS
5675  ==========================================================
5676  */
5677 
5678 // documented in parent class
get_soldiers(lua_State * L)5679 int LuaTrainingSite::get_soldiers(lua_State* L) {
5680 	TrainingSite* ts = get(L, get_egbase(L));
5681 	return do_get_soldiers(L, *ts->soldier_control(), ts->owner().tribe());
5682 }
5683 
5684 // documented in parent class
set_soldiers(lua_State * L)5685 int LuaTrainingSite::set_soldiers(lua_State* L) {
5686 	TrainingSite* ts = get(L, get_egbase(L));
5687 	return do_set_soldiers(L, ts->get_position(), ts->mutable_soldier_control(), ts->get_owner());
5688 }
5689 
5690 /*
5691  ==========================================================
5692  C METHODS
5693  ==========================================================
5694  */
5695 
5696 /* RST
5697 Bob
5698 ---
5699 
5700 .. class:: Bob
5701 
5702    Child of: :class:`MapObject`
5703 
5704    This is the base class for all Bobs in widelands.
5705 
5706    More properties are available through this object's
5707    :class:`MapObjectDescription`, which you can access via :any:`MapObject.descr`.
5708 */
5709 const char LuaBob::className[] = "Bob";
5710 const MethodType<LuaBob> LuaBob::Methods[] = {
5711    METHOD(LuaBob, has_caps), {nullptr, nullptr},
5712 };
5713 const PropertyType<LuaBob> LuaBob::Properties[] = {
5714    PROP_RO(LuaBob, field), {nullptr, nullptr, nullptr},
5715 };
5716 
5717 /*
5718  ==========================================================
5719  PROPERTIES
5720  ==========================================================
5721  */
5722 
5723 /* RST
5724    .. attribute:: field
5725 
5726       (RO) The field the bob is located on
5727 */
5728 // UNTESTED
get_field(lua_State * L)5729 int LuaBob::get_field(lua_State* L) {
5730 
5731 	EditorGameBase& egbase = get_egbase(L);
5732 
5733 	Coords coords = get(L, egbase)->get_position();
5734 
5735 	return to_lua<LuaMaps::LuaField>(L, new LuaMaps::LuaField(coords.x, coords.y));
5736 }
5737 
5738 /*
5739  ==========================================================
5740  LUA METHODS
5741  ==========================================================
5742  */
5743 /* RST
5744    .. method:: has_caps(capname)
5745 
5746       Similar to :meth:`Field::has_caps`.
5747 
5748       :arg capname: can be either of
5749 
5750       * :const:`swims`: This bob can swim.
5751       * :const:`walks`: This bob can walk.
5752 */
5753 // UNTESTED
has_caps(lua_State * L)5754 int LuaBob::has_caps(lua_State* L) {
5755 	std::string query = luaL_checkstring(L, 2);
5756 
5757 	uint32_t movecaps = get(L, get_egbase(L))->descr().movecaps();
5758 
5759 	if (query == "swims") {
5760 		lua_pushboolean(L, movecaps & MOVECAPS_SWIM);
5761 	} else if (query == "walks") {
5762 		lua_pushboolean(L, movecaps & MOVECAPS_WALK);
5763 	} else {
5764 		report_error(L, "Unknown caps queried: %s!", query.c_str());
5765 	}
5766 
5767 	return 1;
5768 }
5769 
5770 /*
5771  ==========================================================
5772  C METHODS
5773  ==========================================================
5774  */
5775 
5776 /* RST
5777 Ship
5778 ----
5779 
5780 .. class:: Ship
5781 
5782    This represents a ship in game.
5783 
5784    More properties are available through this object's
5785    :class:`MapObjectDescription`, which you can access via :any:`MapObject.descr`.
5786 */
5787 
5788 const char LuaShip::className[] = "Ship";
5789 const MethodType<LuaShip> LuaShip::Methods[] = {
5790    METHOD(LuaShip, get_wares),
5791    METHOD(LuaShip, get_workers),
5792    METHOD(LuaShip, build_colonization_port),
5793    METHOD(LuaShip, make_expedition),
5794    {nullptr, nullptr},
5795 };
5796 const PropertyType<LuaShip> LuaShip::Properties[] = {
5797    PROP_RO(LuaShip, debug_ware_economy),
5798    PROP_RO(LuaShip, debug_worker_economy),
5799    PROP_RO(LuaShip, last_portdock),
5800    PROP_RO(LuaShip, destination),
5801    PROP_RO(LuaShip, state),
5802    PROP_RW(LuaShip, scouting_direction),
5803    PROP_RW(LuaShip, island_explore_direction),
5804    PROP_RO(LuaShip, shipname),
5805    PROP_RW(LuaShip, capacity),
5806    {nullptr, nullptr, nullptr},
5807 };
5808 
5809 /*
5810  ==========================================================
5811  PROPERTIES
5812  ==========================================================
5813  */
5814 // UNTESTED, for debug only
get_debug_ware_economy(lua_State * L)5815 int LuaShip::get_debug_ware_economy(lua_State* L) {
5816 	lua_pushlightuserdata(L, get(L, get_egbase(L))->get_economy(wwWARE));
5817 	return 1;
5818 }
get_debug_worker_economy(lua_State * L)5819 int LuaShip::get_debug_worker_economy(lua_State* L) {
5820 	lua_pushlightuserdata(L, get(L, get_egbase(L))->get_economy(wwWORKER));
5821 	return 1;
5822 }
5823 
5824 /* RST
5825    .. attribute:: destination
5826 
5827       (RO) Either :const:`nil` if there is no current destination, otherwise
5828       the :class:`PortDock`.
5829 */
5830 // UNTESTED
get_destination(lua_State * L)5831 int LuaShip::get_destination(lua_State* L) {
5832 	return upcasted_map_object_to_lua(L, get(L, get_egbase(L))->get_destination());
5833 }
5834 
5835 /* RST
5836    .. attribute:: last_portdock
5837 
5838       (RO) Either :const:`nil` if no port was ever visited or the last portdock
5839       was destroyed, otherwise the :class:`PortDock` of the last visited port.
5840 */
5841 // UNTESTED
get_last_portdock(lua_State * L)5842 int LuaShip::get_last_portdock(lua_State* L) {
5843 	EditorGameBase& egbase = get_egbase(L);
5844 	return upcasted_map_object_to_lua(L, get(L, egbase)->get_lastdock(egbase));
5845 }
5846 
5847 /* RST
5848    .. attribute:: state
5849 
5850    Query which state the ship is in:
5851 
5852    - transport,
5853    - exp_waiting, exp_scouting, exp_found_port_space, exp_colonizing,
5854    - sink_request, sink_animation
5855 
5856       (RW) returns the :class:`string` ship's state, or :const:`nil` if there is no valid state.
5857 
5858 
5859 */
5860 // UNTESTED sink states
get_state(lua_State * L)5861 int LuaShip::get_state(lua_State* L) {
5862 	EditorGameBase& egbase = get_egbase(L);
5863 	if (is_a(Game, &egbase)) {
5864 		switch (get(L, egbase)->get_ship_state()) {
5865 		case Ship::ShipStates::kTransport:
5866 			lua_pushstring(L, "transport");
5867 			break;
5868 		case Ship::ShipStates::kExpeditionWaiting:
5869 			lua_pushstring(L, "exp_waiting");
5870 			break;
5871 		case Ship::ShipStates::kExpeditionScouting:
5872 			lua_pushstring(L, "exp_scouting");
5873 			break;
5874 		case Ship::ShipStates::kExpeditionPortspaceFound:
5875 			lua_pushstring(L, "exp_found_port_space");
5876 			break;
5877 		case Ship::ShipStates::kExpeditionColonizing:
5878 			lua_pushstring(L, "exp_colonizing");
5879 			break;
5880 		case Ship::ShipStates::kSinkRequest:
5881 			lua_pushstring(L, "sink_request");
5882 			break;
5883 		case Ship::ShipStates::kSinkAnimation:
5884 			lua_pushstring(L, "sink_animation");
5885 		}
5886 		return 1;
5887 	}
5888 	return 0;
5889 }
5890 
get_scouting_direction(lua_State * L)5891 int LuaShip::get_scouting_direction(lua_State* L) {
5892 	EditorGameBase& egbase = get_egbase(L);
5893 	if (is_a(Game, &egbase)) {
5894 		switch (get(L, egbase)->get_scouting_direction()) {
5895 		case WalkingDir::WALK_NE:
5896 			lua_pushstring(L, "ne");
5897 			break;
5898 		case WalkingDir::WALK_E:
5899 			lua_pushstring(L, "e");
5900 			break;
5901 		case WalkingDir::WALK_SE:
5902 			lua_pushstring(L, "se");
5903 			break;
5904 		case WalkingDir::WALK_SW:
5905 			lua_pushstring(L, "sw");
5906 			break;
5907 		case WalkingDir::WALK_W:
5908 			lua_pushstring(L, "w");
5909 			break;
5910 		case WalkingDir::WALK_NW:
5911 			lua_pushstring(L, "nw");
5912 			break;
5913 		case WalkingDir::IDLE:
5914 			return 0;
5915 		}
5916 		return 1;
5917 	}
5918 	return 0;
5919 }
5920 
set_scouting_direction(lua_State * L)5921 int LuaShip::set_scouting_direction(lua_State* L) {
5922 	EditorGameBase& egbase = get_egbase(L);
5923 	if (upcast(Game, game, &egbase)) {
5924 		std::string dirname = luaL_checkstring(L, 3);
5925 		WalkingDir dir = WalkingDir::IDLE;
5926 
5927 		if (dirname == "ne") {
5928 			dir = WalkingDir::WALK_NE;
5929 		} else if (dirname == "e") {
5930 			dir = WalkingDir::WALK_E;
5931 		} else if (dirname == "se") {
5932 			dir = WalkingDir::WALK_SE;
5933 		} else if (dirname == "sw") {
5934 			dir = WalkingDir::WALK_SW;
5935 		} else if (dirname == "w") {
5936 			dir = WalkingDir::WALK_W;
5937 		} else if (dirname == "nw") {
5938 			dir = WalkingDir::WALK_NW;
5939 		} else {
5940 			return 0;
5941 		}
5942 		game->send_player_ship_scouting_direction(*get(L, egbase), dir);
5943 		return 1;
5944 	}
5945 	return 0;
5946 }
5947 
5948 /* RST
5949    .. attribute:: island_explore_direction
5950 
5951       (RW) actual direction if the ship sails around an island.
5952       Sets/returns cw, ccw or nil
5953 
5954 */
get_island_explore_direction(lua_State * L)5955 int LuaShip::get_island_explore_direction(lua_State* L) {
5956 	EditorGameBase& egbase = get_egbase(L);
5957 	if (is_a(Game, &egbase)) {
5958 		switch (get(L, egbase)->get_island_explore_direction()) {
5959 		case IslandExploreDirection::kCounterClockwise:
5960 			lua_pushstring(L, "ccw");
5961 			break;
5962 		case IslandExploreDirection::kClockwise:
5963 			lua_pushstring(L, "cw");
5964 			break;
5965 		case IslandExploreDirection::kNotSet:
5966 			return 0;
5967 		}
5968 		return 1;
5969 	}
5970 	return 0;
5971 }
5972 
set_island_explore_direction(lua_State * L)5973 int LuaShip::set_island_explore_direction(lua_State* L) {
5974 	EditorGameBase& egbase = get_egbase(L);
5975 	if (upcast(Game, game, &egbase)) {
5976 		Ship* ship = get(L, egbase);
5977 		std::string dir = luaL_checkstring(L, 3);
5978 		if (dir == "ccw") {
5979 			game->send_player_ship_explore_island(*ship, IslandExploreDirection::kCounterClockwise);
5980 		} else if (dir == "cw") {
5981 			game->send_player_ship_explore_island(*ship, IslandExploreDirection::kClockwise);
5982 		} else {
5983 			return 0;
5984 		}
5985 		return 1;
5986 	}
5987 	return 0;
5988 }
5989 
5990 /* RST
5991    .. attribute:: shipname
5992 
5993    Get name of ship:
5994 
5995       (RO) returns the :class:`string` ship's name.
5996 
5997 
5998 */
get_shipname(lua_State * L)5999 int LuaShip::get_shipname(lua_State* L) {
6000 	EditorGameBase& egbase = get_egbase(L);
6001 	Ship* ship = get(L, egbase);
6002 	lua_pushstring(L, ship->get_shipname().c_str());
6003 	return 1;
6004 }
6005 
6006 /* RST
6007    .. attribute:: capacity
6008 
6009    The ship's current capacity. Defaults to the capacity defined in the tribe's singleton ship description.
6010 
6011    Do not change this value if the ship is currently shipping more items than the new capacity allows.
6012 
6013       (RW) returns the current capacity of this ship
6014 
6015 */
get_capacity(lua_State * L)6016 int LuaShip::get_capacity(lua_State* L) {
6017 	lua_pushuint32(L, get(L, get_egbase(L))->get_capacity());
6018 	return 1;
6019 }
set_capacity(lua_State * L)6020 int LuaShip::set_capacity(lua_State* L) {
6021 	Widelands::Ship& s = *get(L, get_egbase(L));
6022 	const uint32_t c = luaL_checkuint32(L, -1);
6023 	if (s.get_nritems() > c) {
6024 		report_error(L, "Ship is currently transporting %u items – cannot set capacity to %u",
6025 		             s.get_nritems(), c);
6026 	}
6027 	s.set_capacity(c);
6028 	return 0;
6029 }
6030 
6031 /*
6032  ==========================================================
6033  LUA METHODS
6034  ==========================================================
6035  */
6036 
6037 /* RST
6038    .. method:: get_wares()
6039 
6040       Returns the number of wares on this ship. This does not implement
6041       everything that :class:`HasWares` offers.
6042 
6043       :returns: the number of wares
6044 */
6045 // UNTESTED
get_wares(lua_State * L)6046 int LuaShip::get_wares(lua_State* L) {
6047 	EditorGameBase& egbase = get_egbase(L);
6048 	int nwares = 0;
6049 	WareInstance* ware;
6050 	Ship* ship = get(L, egbase);
6051 	for (uint32_t i = 0; i < ship->get_nritems(); ++i) {
6052 		const ShippingItem& item = ship->get_item(i);
6053 		item.get(egbase, &ware, nullptr);
6054 		if (ware != nullptr) {
6055 			++nwares;
6056 		}
6057 	}
6058 	lua_pushint32(L, nwares);
6059 	return 1;
6060 }
6061 
6062 /* RST
6063    .. method:: get_workers()
6064 
6065       Returns the number of workers on this ship. This does not implement
6066       everything that :class:`HasWorkers` offers.
6067 
6068       :returns: the number of workers
6069 */
6070 // UNTESTED
get_workers(lua_State * L)6071 int LuaShip::get_workers(lua_State* L) {
6072 	EditorGameBase& egbase = get_egbase(L);
6073 	int nworkers = 0;
6074 	Worker* worker;
6075 	Ship* ship = get(L, egbase);
6076 	for (uint32_t i = 0; i < ship->get_nritems(); ++i) {
6077 		const ShippingItem& item = ship->get_item(i);
6078 		item.get(egbase, nullptr, &worker);
6079 		if (worker != nullptr) {
6080 			++nworkers;
6081 		}
6082 	}
6083 	lua_pushint32(L, nworkers);
6084 	return 1;
6085 }
6086 
6087 /* RST
6088    .. method:: build_colonization_port()
6089 
6090       Returns true if port space construction was started (ship was in adequate
6091       status and a found portspace was nearby)
6092 
6093       :returns: true/false
6094 */
build_colonization_port(lua_State * L)6095 int LuaShip::build_colonization_port(lua_State* L) {
6096 	EditorGameBase& egbase = get_egbase(L);
6097 	Ship* ship = get(L, egbase);
6098 	if (ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionPortspaceFound) {
6099 		if (upcast(Game, game, &egbase)) {
6100 			game->send_player_ship_construct_port(*ship, ship->exp_port_spaces().front());
6101 			return 1;
6102 		}
6103 	}
6104 	return 0;
6105 }
6106 
6107 /* RST
6108    .. method:: make_expedition([items])
6109 
6110       Turns this ship into an expedition ship without a base port. Creates all necessary
6111       wares and a builder plus, if desired, the specified additional items.
6112       Any items previously present in the ship will be deleted.
6113 
6114       The ship must be empty and not an expedition ship when this method is called.
6115 
6116       :returns: nil
6117 */
make_expedition(lua_State * L)6118 int LuaShip::make_expedition(lua_State* L) {
6119 	upcast(Game, game, &get_egbase(L));
6120 	assert(game);
6121 	Ship* ship = get(L, *game);
6122 	assert(ship);
6123 	if (ship->get_ship_state() != Widelands::Ship::ShipStates::kTransport ||
6124 	    ship->get_nritems() > 0) {
6125 		report_error(L, "Ship.make_expedition can be used only on empty transport ships!");
6126 	}
6127 
6128 	const Widelands::TribeDescr& tribe = ship->owner().tribe();
6129 	for (const auto& pair : tribe.get_building_descr(tribe.port())->buildcost()) {
6130 		for (size_t i = pair.second; i > 0; --i) {
6131 			Widelands::WareInstance& w =
6132 			   *new Widelands::WareInstance(pair.first, tribe.get_ware_descr(pair.first));
6133 			w.init(*game);
6134 			ship->add_item(*game, Widelands::ShippingItem(w));
6135 		}
6136 	}
6137 	ship->add_item(*game, Widelands::ShippingItem(
6138 	                         tribe.get_worker_descr(tribe.builder())
6139 	                            ->create(*game, ship->get_owner(), nullptr, ship->get_position())));
6140 	std::map<Widelands::DescriptionIndex, uint32_t>
6141 	   workers_to_create;  // Lua table sorting order is not deterministic and may cause desyncs
6142 	if (lua_gettop(L) > 1) {
6143 		luaL_checktype(L, 2, LUA_TTABLE);
6144 		lua_pushnil(L);
6145 		while (lua_next(L, 2) != 0) {
6146 			uint32_t amount = luaL_checkuint32(L, -1);
6147 			lua_pop(L, 1);
6148 			std::string what = luaL_checkstring(L, -1);
6149 			Widelands::DescriptionIndex index = game->tribes().ware_index(what);
6150 			if (tribe.has_ware(index)) {
6151 				while (amount > 0) {
6152 					Widelands::WareInstance& w =
6153 					   *new Widelands::WareInstance(index, tribe.get_ware_descr(index));
6154 					w.init(*game);
6155 					ship->add_item(*game, Widelands::ShippingItem(w));
6156 					--amount;
6157 				}
6158 			} else {
6159 				index = tribe.worker_index(what);
6160 				if (tribe.has_worker(index)) {
6161 					workers_to_create[index] = amount;
6162 				} else {
6163 					report_error(L, "Invalid ware or worker: %s", what.c_str());
6164 				}
6165 			}
6166 		}
6167 	}
6168 
6169 	for (auto& pair : workers_to_create) {
6170 		for (; pair.second; --pair.second) {
6171 			ship->add_item(*game, Widelands::ShippingItem(tribe.get_worker_descr(pair.first)
6172 			                                                 ->create(*game, ship->get_owner(),
6173 			                                                          nullptr, ship->get_position())));
6174 		}
6175 	}
6176 
6177 	ship->set_destination(*game, nullptr);
6178 	ship->start_task_expedition(*game);
6179 
6180 	return 0;
6181 }
6182 
6183 /*
6184  ==========================================================
6185  C METHODS
6186  ==========================================================
6187  */
6188 
6189 /* RST
6190 Worker
6191 ------
6192 
6193 .. class:: Worker
6194 
6195    Child of: :class:`Bob`
6196 
6197    All workers that are visible on the map are of this kind.
6198 
6199    More properties are available through this object's
6200    :class:`WorkerDescription`, which you can access via :any:`MapObject.descr`.
6201 */
6202 
6203 const char LuaWorker::className[] = "Worker";
6204 const MethodType<LuaWorker> LuaWorker::Methods[] = {
6205    {nullptr, nullptr},
6206 };
6207 const PropertyType<LuaWorker> LuaWorker::Properties[] = {
6208    PROP_RO(LuaWorker, owner), PROP_RO(LuaWorker, location), {nullptr, nullptr, nullptr},
6209 };
6210 
6211 /*
6212  ==========================================================
6213  PROPERTIES
6214  ==========================================================
6215  */
6216 /* RST
6217    .. attribute:: owner
6218 
6219       (RO) The :class:`wl.game.Player` who owns this worker.
6220 */
6221 // UNTESTED
get_owner(lua_State * L)6222 int LuaWorker::get_owner(lua_State* L) {
6223 	get_factory(L).push_player(L, get(L, get_egbase(L))->get_owner()->player_number());
6224 	return 1;
6225 }
6226 
6227 /* RST
6228    .. attribute:: location
6229 
6230       (RO) The location where this worker is situated. This will be either a
6231       :class:`Building`, :class:`Road`, :class:`Flag` or :const:`nil`. Note
6232       that a worker that is stored in a warehouse has a location :const:`nil`.
6233       A worker that is out working (e.g. hunter) has as a location his
6234       building. A stationed soldier has his military building as location.
6235       Workers on transit usually have the Road they are currently on as
6236       location.
6237 */
6238 // UNTESTED
get_location(lua_State * L)6239 int LuaWorker::get_location(lua_State* L) {
6240 	EditorGameBase& egbase = get_egbase(L);
6241 	return upcasted_map_object_to_lua(
6242 	   L, static_cast<BaseImmovable*>(get(L, egbase)->get_location(egbase)));
6243 }
6244 
6245 /*
6246  ==========================================================
6247  LUA METHODS
6248  ==========================================================
6249  */
6250 
6251 /*
6252  ==========================================================
6253  C METHODS
6254  ==========================================================
6255  */
6256 
6257 /* RST
6258 Soldier
6259 -------
6260 
6261 .. class:: Soldier
6262 
6263    Child of: :class:`Worker`
6264 
6265    All soldiers that are on the map are represented by this class.
6266 
6267    More properties are available through this object's
6268    :class:`SoldierDescription`, which you can access via :any:`MapObject.descr`.
6269 */
6270 
6271 const char LuaSoldier::className[] = "Soldier";
6272 const MethodType<LuaSoldier> LuaSoldier::Methods[] = {
6273    {nullptr, nullptr},
6274 };
6275 const PropertyType<LuaSoldier> LuaSoldier::Properties[] = {
6276    PROP_RO(LuaSoldier, attack_level), PROP_RO(LuaSoldier, defense_level),
6277    PROP_RO(LuaSoldier, health_level), PROP_RO(LuaSoldier, evade_level),
6278    {nullptr, nullptr, nullptr},
6279 };
6280 
6281 /*
6282  ==========================================================
6283  PROPERTIES
6284  ==========================================================
6285  */
6286 /* RST
6287    .. attribute:: attack_level
6288 
6289       (RO) The current attack level of this soldier
6290 */
6291 // UNTESTED
get_attack_level(lua_State * L)6292 int LuaSoldier::get_attack_level(lua_State* L) {
6293 	lua_pushuint32(L, get(L, get_egbase(L))->get_attack_level());
6294 	return 1;
6295 }
6296 
6297 /* RST
6298    .. attribute:: defense_level
6299 
6300       (RO) The current defense level of this soldier
6301 */
6302 // UNTESTED
get_defense_level(lua_State * L)6303 int LuaSoldier::get_defense_level(lua_State* L) {
6304 	lua_pushuint32(L, get(L, get_egbase(L))->get_defense_level());
6305 	return 1;
6306 }
6307 
6308 /* RST
6309    .. attribute:: health_level
6310 
6311       (RO) The current health level of this soldier
6312 */
6313 // UNTESTED
get_health_level(lua_State * L)6314 int LuaSoldier::get_health_level(lua_State* L) {
6315 	lua_pushuint32(L, get(L, get_egbase(L))->get_health_level());
6316 	return 1;
6317 }
6318 
6319 /* RST
6320    .. attribute:: evade_level
6321 
6322       (RO) The current evade level of this soldier
6323 */
6324 // UNTESTED
get_evade_level(lua_State * L)6325 int LuaSoldier::get_evade_level(lua_State* L) {
6326 	lua_pushuint32(L, get(L, get_egbase(L))->get_evade_level());
6327 	return 1;
6328 }
6329 
6330 /*
6331  ==========================================================
6332  LUA METHODS
6333  ==========================================================
6334  */
6335 
6336 /*
6337  ==========================================================
6338  C METHODS
6339  ==========================================================
6340  */
6341 
6342 /* RST
6343 Field
6344 -----
6345 
6346 .. class:: Field
6347 
6348    This class represents one Field in Widelands. The field may contain
6349    immovables like Flags or Buildings and can be connected via Roads. Every
6350    Field has two Triangles associated with itself: the right and the down one.
6351 
6352    You cannot instantiate this directly, access it via
6353    wl.Game().map.get_field() instead.
6354 */
6355 
6356 const char LuaField::className[] = "Field";
6357 const MethodType<LuaField> LuaField::Methods[] = {
6358    METHOD(LuaField, __eq),     METHOD(LuaField, __tostring),   METHOD(LuaField, region),
6359    METHOD(LuaField, has_caps), METHOD(LuaField, has_max_caps), {nullptr, nullptr},
6360 };
6361 const PropertyType<LuaField> LuaField::Properties[] = {
6362    PROP_RO(LuaField, __hash),
6363    PROP_RO(LuaField, x),
6364    PROP_RO(LuaField, y),
6365    PROP_RO(LuaField, rn),
6366    PROP_RO(LuaField, ln),
6367    PROP_RO(LuaField, trn),
6368    PROP_RO(LuaField, tln),
6369    PROP_RO(LuaField, bln),
6370    PROP_RO(LuaField, brn),
6371    PROP_RO(LuaField, immovable),
6372    PROP_RO(LuaField, bobs),
6373    PROP_RW(LuaField, terr),
6374    PROP_RW(LuaField, terd),
6375    PROP_RW(LuaField, height),
6376    PROP_RW(LuaField, raw_height),
6377    PROP_RO(LuaField, viewpoint_x),
6378    PROP_RO(LuaField, viewpoint_y),
6379    PROP_RW(LuaField, resource),
6380    PROP_RW(LuaField, resource_amount),
6381    PROP_RO(LuaField, initial_resource_amount),
6382    PROP_RO(LuaField, claimers),
6383    PROP_RO(LuaField, owner),
6384    PROP_RO(LuaField, buildable),
6385    {nullptr, nullptr, nullptr},
6386 };
6387 
__persist(lua_State * L)6388 void LuaField::__persist(lua_State* L) {
6389 	PERS_INT32("x", coords_.x);
6390 	PERS_INT32("y", coords_.y);
6391 }
6392 
__unpersist(lua_State * L)6393 void LuaField::__unpersist(lua_State* L) {
6394 	UNPERS_INT32("x", coords_.x)
6395 	UNPERS_INT32("y", coords_.y)
6396 }
6397 
6398 /*
6399  ==========================================================
6400  PROPERTIES
6401  ==========================================================
6402  */
6403 /* RST
6404    .. attribute:: __hash
6405 
6406       (RO) The hashed coordinates of the field's position. Used to identify a class in a Set.
6407 */
get___hash(lua_State * L)6408 int LuaField::get___hash(lua_State* L) {
6409 	lua_pushuint32(L, coords_.hash());
6410 	return 1;
6411 }
6412 
6413 /* RST
6414    .. attribute:: x, y
6415 
6416       (RO) The x/y coordinate of this field
6417 */
get_x(lua_State * L)6418 int LuaField::get_x(lua_State* L) {
6419 	lua_pushuint32(L, coords_.x);
6420 	return 1;
6421 }
get_y(lua_State * L)6422 int LuaField::get_y(lua_State* L) {
6423 	lua_pushuint32(L, coords_.y);
6424 	return 1;
6425 }
6426 
6427 /* RST
6428    .. attribute:: height
6429 
6430       (RW) The height of this field. The default height is 10, you can increase
6431       or decrease this value to build mountains. Note though that if you change
6432       this value too much, all surrounding fields will also change their
6433       heights because the slope is constrained. If you are changing the height
6434       of many terrains at once, use :attr:`raw_height` instead and then call
6435       :any:`recalculate` afterwards.
6436 */
get_height(lua_State * L)6437 int LuaField::get_height(lua_State* L) {
6438 	lua_pushuint32(L, fcoords(L).field->get_height());
6439 	return 1;
6440 }
set_height(lua_State * L)6441 int LuaField::set_height(lua_State* L) {
6442 	uint32_t height = luaL_checkuint32(L, -1);
6443 	FCoords f = fcoords(L);
6444 
6445 	if (f.field->get_height() == height) {
6446 		return 0;
6447 	}
6448 
6449 	if (height > MAX_FIELD_HEIGHT) {
6450 		report_error(L, "height must be <= %i", MAX_FIELD_HEIGHT);
6451 	}
6452 
6453 	EditorGameBase& egbase = get_egbase(L);
6454 	egbase.mutable_map()->set_height(egbase, f, height);
6455 
6456 	return 0;
6457 }
6458 
6459 /* RST
6460    .. attribute:: raw_height
6461 
6462       (RW) The same as :attr:`height`, but setting this will not trigger a
6463       recalculation of the surrounding fields. You can use this field to
6464       change the height of many fields on a map quickly, then use
6465       :any:`recalculate` to make sure that everything is in order.
6466 */
6467 // UNTESTED
get_raw_height(lua_State * L)6468 int LuaField::get_raw_height(lua_State* L) {
6469 	lua_pushuint32(L, fcoords(L).field->get_height());
6470 	return 1;
6471 }
set_raw_height(lua_State * L)6472 int LuaField::set_raw_height(lua_State* L) {
6473 	uint32_t height = luaL_checkuint32(L, -1);
6474 	FCoords f = fcoords(L);
6475 
6476 	if (f.field->get_height() == height) {
6477 		return 0;
6478 	}
6479 
6480 	if (height > MAX_FIELD_HEIGHT) {
6481 		report_error(L, "height must be <= %i", MAX_FIELD_HEIGHT);
6482 	}
6483 
6484 	f.field->set_height(height);
6485 
6486 	return 0;
6487 }
6488 
6489 /* RST
6490    .. attribute:: viewpoint_x, viewpoint_y
6491 
6492       (RO) Returns the position in pixels to move the view to to center
6493       this field for the current interactive player
6494 */
get_viewpoint_x(lua_State * L)6495 int LuaField::get_viewpoint_x(lua_State* L) {
6496 	Vector2f point =
6497 	   MapviewPixelFunctions::to_map_pixel_with_normalization(get_egbase(L).map(), coords_);
6498 	lua_pushdouble(L, point.x);
6499 	return 1;
6500 }
get_viewpoint_y(lua_State * L)6501 int LuaField::get_viewpoint_y(lua_State* L) {
6502 	Vector2f point =
6503 	   MapviewPixelFunctions::to_map_pixel_with_normalization(get_egbase(L).map(), coords_);
6504 	lua_pushdouble(L, point.y);
6505 	return 1;
6506 }
6507 
6508 /* RST
6509    .. attribute:: resource
6510 
6511       (RW) The name of the resource that is available in this field or
6512       :const:`nil`
6513 
6514       :see also: :attr:`resource_amount`
6515 */
get_resource(lua_State * L)6516 int LuaField::get_resource(lua_State* L) {
6517 
6518 	const ResourceDescription* rDesc =
6519 	   get_egbase(L).world().get_resource(fcoords(L).field->get_resources());
6520 
6521 	lua_pushstring(L, rDesc ? rDesc->name().c_str() : "none");
6522 
6523 	return 1;
6524 }
set_resource(lua_State * L)6525 int LuaField::set_resource(lua_State* L) {
6526 	auto& egbase = get_egbase(L);
6527 	DescriptionIndex res = egbase.world().resource_index(luaL_checkstring(L, -1));
6528 
6529 	if (res == Widelands::INVALID_INDEX) {
6530 		report_error(L, "Illegal resource: '%s'", luaL_checkstring(L, -1));
6531 	}
6532 
6533 	auto c = fcoords(L);
6534 	const auto current_amount = c.field->get_resources_amount();
6535 	auto* map = egbase.mutable_map();
6536 	map->initialize_resources(c, res, c.field->get_initial_res_amount());
6537 	map->set_resources(c, current_amount);
6538 	return 0;
6539 }
6540 
6541 /* RST
6542    .. attribute:: resource_amount
6543 
6544       (RW) How many items of the resource is available in this field.
6545 
6546       :see also: :attr:`resource`
6547 */
get_resource_amount(lua_State * L)6548 int LuaField::get_resource_amount(lua_State* L) {
6549 	lua_pushuint32(L, fcoords(L).field->get_resources_amount());
6550 	return 1;
6551 }
set_resource_amount(lua_State * L)6552 int LuaField::set_resource_amount(lua_State* L) {
6553 	EditorGameBase& egbase = get_egbase(L);
6554 	auto c = fcoords(L);
6555 	DescriptionIndex res = c.field->get_resources();
6556 	auto amount = luaL_checkint32(L, -1);
6557 	const ResourceDescription* resDesc = egbase.world().get_resource(res);
6558 	ResourceAmount max_amount = resDesc ? resDesc->max_amount() : 0;
6559 
6560 	if (amount < 0 || amount > max_amount) {
6561 		report_error(L, "Illegal amount: %i, must be >= 0 and <= %i", amount,
6562 		             static_cast<unsigned int>(max_amount));
6563 	}
6564 
6565 	auto* map = egbase.mutable_map();
6566 	if (is_a(Game, &egbase)) {
6567 		map->set_resources(c, amount);
6568 	} else {
6569 		// in editor, reset also initial amount
6570 		map->initialize_resources(c, res, amount);
6571 	}
6572 	return 0;
6573 }
6574 /* RST
6575    .. attribute:: initial_resource_amount
6576 
6577       (RO) Starting value of resource. It is set be resource_amount
6578 
6579       :see also: :attr:`resource`
6580 */
get_initial_resource_amount(lua_State * L)6581 int LuaField::get_initial_resource_amount(lua_State* L) {
6582 	lua_pushuint32(L, fcoords(L).field->get_initial_res_amount());
6583 	return 1;
6584 }
6585 /* RST
6586    .. attribute:: immovable
6587 
6588       (RO) The immovable that stands on this field or :const:`nil`. If you want
6589       to remove an immovable, you can use :func:`wl.map.MapObject.remove`.
6590 */
get_immovable(lua_State * L)6591 int LuaField::get_immovable(lua_State* L) {
6592 	BaseImmovable* bi = get_egbase(L).map().get_immovable(coords_);
6593 
6594 	if (!bi) {
6595 		return 0;
6596 	} else {
6597 		upcasted_map_object_to_lua(L, bi);
6598 	}
6599 	return 1;
6600 }
6601 
6602 /* RST
6603    .. attribute:: bobs
6604 
6605       (RO) An :class:`array` of :class:`~wl.map.Bob` that are associated
6606       with this field
6607 */
6608 // UNTESTED
get_bobs(lua_State * L)6609 int LuaField::get_bobs(lua_State* L) {
6610 	Bob* b = fcoords(L).field->get_first_bob();
6611 
6612 	lua_newtable(L);
6613 	uint32_t cidx = 1;
6614 	while (b) {
6615 		lua_pushuint32(L, cidx++);
6616 		upcasted_map_object_to_lua(L, b);
6617 		lua_rawset(L, -3);
6618 		b = b->get_next_bob();
6619 	}
6620 	return 1;
6621 }
6622 
6623 /* RST
6624    .. attribute:: terr, terd
6625 
6626       (RW) The terrain of the right/down triangle. This is a string value
6627       containing the name of the terrain as it is defined in the world
6628       configuration. You can change the terrain by simply assigning another
6629       valid name to these variables. If you are changing the terrain from or to
6630       water, the map will not recalculate whether it allows seafaring, because
6631       this recalculation can take up a lot of performance. If you need this
6632       recalculated, you can do so by calling :any:`recalculate_seafaring` after
6633       you're done changing terrains.
6634 */
get_terr(lua_State * L)6635 int LuaField::get_terr(lua_State* L) {
6636 	TerrainDescription& td = get_egbase(L).world().terrain_descr(fcoords(L).field->terrain_r());
6637 	lua_pushstring(L, td.name().c_str());
6638 	return 1;
6639 }
set_terr(lua_State * L)6640 int LuaField::set_terr(lua_State* L) {
6641 	const char* name = luaL_checkstring(L, -1);
6642 	EditorGameBase& egbase = get_egbase(L);
6643 	const DescriptionIndex td = egbase.world().terrains().get_index(name);
6644 	if (td == static_cast<DescriptionIndex>(Widelands::INVALID_INDEX)) {
6645 		report_error(L, "Unknown terrain '%s'", name);
6646 	}
6647 
6648 	egbase.mutable_map()->change_terrain(egbase, TCoords<FCoords>(fcoords(L), TriangleIndex::R), td);
6649 
6650 	lua_pushstring(L, name);
6651 	return 1;
6652 }
6653 
get_terd(lua_State * L)6654 int LuaField::get_terd(lua_State* L) {
6655 	TerrainDescription& td = get_egbase(L).world().terrain_descr(fcoords(L).field->terrain_d());
6656 	lua_pushstring(L, td.name().c_str());
6657 	return 1;
6658 }
set_terd(lua_State * L)6659 int LuaField::set_terd(lua_State* L) {
6660 	const char* name = luaL_checkstring(L, -1);
6661 	EditorGameBase& egbase = get_egbase(L);
6662 	const DescriptionIndex td = egbase.world().terrains().get_index(name);
6663 	if (td == static_cast<DescriptionIndex>(INVALID_INDEX)) {
6664 		report_error(L, "Unknown terrain '%s'", name);
6665 	}
6666 
6667 	egbase.mutable_map()->change_terrain(egbase, TCoords<FCoords>(fcoords(L), TriangleIndex::D), td);
6668 
6669 	lua_pushstring(L, name);
6670 	return 1;
6671 }
6672 
6673 /* RST
6674    .. attribute:: rn, ln, brn, bln, trn, tln
6675 
6676       (RO) The neighbour fields of this field. The abbreviations stand for:
6677 
6678       * rn -- Right neighbour
6679       * ln -- Left neighbour
6680       * brn -- Bottom right neighbour
6681       * bln -- Bottom left neighbour
6682       * trn -- Top right neighbour
6683       * tln -- Top left neighbour
6684 
6685       Note that the widelands map wraps at its borders, that is the following
6686       holds:
6687 
6688       .. code-block:: lua
6689 
6690          wl.map.Field(wl.map.get_width()-1, 10).rn == wl.map.Field(0, 10)
6691 */
6692 #define GET_X_NEIGHBOUR(X)                                                                         \
6693 	int LuaField::get_##X(lua_State* L) {                                                           \
6694 		Coords n;                                                                                    \
6695 		get_egbase(L).map().get_##X(coords_, &n);                                                    \
6696 		to_lua<LuaField>(L, new LuaField(n.x, n.y));                                                 \
6697 		return 1;                                                                                    \
6698 	}
6699 GET_X_NEIGHBOUR(rn)
GET_X_NEIGHBOUR(ln)6700 GET_X_NEIGHBOUR(ln)
6701 GET_X_NEIGHBOUR(trn)
6702 GET_X_NEIGHBOUR(tln)
6703 GET_X_NEIGHBOUR(bln)
6704 GET_X_NEIGHBOUR(brn)
6705 
6706 /* RST
6707    .. attribute:: owner
6708 
6709       (RO) The current owner of the field or :const:`nil` if noone owns it. See
6710       also :attr:`claimers`.
6711 */
6712 int LuaField::get_owner(lua_State* L) {
6713 	PlayerNumber current_owner = fcoords(L).field->get_owned_by();
6714 	if (current_owner) {
6715 		get_factory(L).push_player(L, current_owner);
6716 		return 1;
6717 	}
6718 	return 0;
6719 }
6720 
6721 /* RST
6722    .. attribute:: buildable
6723 
6724       (RO) Returns :const:`true` if a flag or building could be built on this field,
6725       independently of whether anybody currently owns this field.
6726 */
get_buildable(lua_State * L)6727 int LuaField::get_buildable(lua_State* L) {
6728 	const NodeCaps caps = fcoords(L).field->nodecaps();
6729 	const bool is_buildable = (caps & BUILDCAPS_FLAG) || (caps & BUILDCAPS_SMALL) ||
6730 	                          (caps & BUILDCAPS_MEDIUM) || (caps & BUILDCAPS_BIG) ||
6731 	                          (caps & BUILDCAPS_MINE);
6732 	lua_pushboolean(L, is_buildable);
6733 	return 1;
6734 }
6735 
6736 /* RST
6737    .. attribute:: claimers
6738 
6739       (RO) An :class:`array` of players that have military influence over this
6740       field sorted by the amount of influence they have. Note that this does
6741       not necessarily mean that claimers[1] is also the owner of the field, as
6742       a field that houses a surrounded military building is owned by the
6743       surrounded player, but others have more military influence over it.
6744 
6745       Note: The one currently owning the field is in :attr:`owner`.
6746 */
get_claimers(lua_State * L)6747 int LuaField::get_claimers(lua_State* L) {
6748 	EditorGameBase& egbase = get_egbase(L);
6749 	const Map& map = egbase.map();
6750 
6751 	std::vector<PlrInfluence> claimers;
6752 
6753 	iterate_players_existing(other_p, map.get_nrplayers(), egbase, plr)
6754 	   claimers.push_back(PlrInfluence(
6755 	      plr->player_number(), plr->military_influence(map.get_index(coords_, map.get_width()))));
6756 
6757 	std::stable_sort(claimers.begin(), claimers.end(), sort_claimers);
6758 
6759 	lua_createtable(L, 1, 0);  // We mostly expect one claimer per field.
6760 
6761 	// Push the players with military influence
6762 	uint32_t cidx = 1;
6763 	for (const PlrInfluence& claimer : claimers) {
6764 		if (claimer.second <= 0) {
6765 			continue;
6766 		}
6767 		lua_pushuint32(L, cidx++);
6768 		get_factory(L).push_player(L, claimer.first);
6769 		lua_rawset(L, -3);
6770 	}
6771 
6772 	return 1;
6773 }
6774 
6775 /*
6776  ==========================================================
6777  LUA METHODS
6778  ==========================================================
6779  */
__eq(lua_State * L)6780 int LuaField::__eq(lua_State* L) {
6781 	lua_pushboolean(L, (*get_user_class<LuaField>(L, -1))->coords_ == coords_);
6782 	return 1;
6783 }
6784 
__tostring(lua_State * L)6785 int LuaField::__tostring(lua_State* L) {
6786 	const std::string pushme = (boost::format("Field(%i,%i)") % coords_.x % coords_.y).str();
6787 	lua_pushstring(L, pushme);
6788 	return 1;
6789 }
6790 
6791 /* RST
6792    .. function:: region(r1[, r2])
6793 
6794       Returns an array of all Fields inside the given region. If one argument
6795       is given it defines the radius of the region. If both arguments are
6796       specified, the first one defines the outer radius and the second one the
6797       inner radius and a hollow region is returned, that is all fields in the
6798       outer radius region minus all fields in the inner radius region.
6799 
6800       A small example:
6801 
6802       .. code-block:: lua
6803 
6804          f:region(1)
6805 
6806       will return an array with the following entries (Note: Ordering of the
6807       fields inside the array is not guaranteed):
6808 
6809       .. code-block:: lua
6810 
6811          {f, f.rn, f.ln, f.brn, f.bln, f.tln, f.trn}
6812 
6813       :returns: The array of the given fields.
6814       :rtype: :class:`array`
6815 */
region(lua_State * L)6816 int LuaField::region(lua_State* L) {
6817 	uint32_t n = lua_gettop(L);
6818 
6819 	if (n == 3) {
6820 		uint32_t radius = luaL_checkuint32(L, -2);
6821 		uint32_t inner_radius = luaL_checkuint32(L, -1);
6822 		return hollow_region(L, radius, inner_radius);
6823 	}
6824 
6825 	uint32_t radius = luaL_checkuint32(L, -1);
6826 	return region(L, radius);
6827 }
6828 
6829 /* RST
6830    .. method:: has_caps(capname)
6831 
6832       Returns :const:`true` if the field has this caps associated
6833       with it, otherwise returns false.
6834       Note: Immovables will hide the caps. If you want to have the caps
6835       without immovables use has_max_caps instead
6836 
6837       :arg capname: can be either of
6838 
6839       * :const:`small`: Can a small building be built here?
6840       * :const:`medium`: Can a medium building be built here?
6841       * :const:`big`: Can a big building be built here?
6842       * :const:`mine`: Can a mine be built here?
6843       * :const:`port`: Can a port be built here?
6844       * :const:`flag`: Can a flag be built here?
6845       * :const:`walkable`: Is this field passable for walking bobs?
6846       * :const:`swimmable`: Is this field passable for swimming bobs?
6847 */
has_caps(lua_State * L)6848 int LuaField::has_caps(lua_State* L) {
6849 	const FCoords& f = fcoords(L);
6850 	std::string query = luaL_checkstring(L, 2);
6851 	lua_pushboolean(L, check_has_caps(L, query, f, f.field->nodecaps(), get_egbase(L).map()));
6852 	return 1;
6853 }
6854 
6855 /* RST
6856    .. method:: has_max_caps(capname)
6857 
6858       Returns :const:`true` if the field has this maximum caps (not taking immovables into account)
6859       associated with it, otherwise returns false.
6860 
6861       :arg capname: can be either of
6862 
6863       * :const:`small`: Can a small building be built here?
6864       * :const:`medium`: Can a medium building be built here?
6865       * :const:`big`: Can a big building be built here?
6866       * :const:`mine`: Can a mine be built here?
6867       * :const:`port`: Can a port be built here?
6868       * :const:`flag`: Can a flag be built here?
6869       * :const:`walkable`: Is this field passable for walking bobs?
6870       * :const:`swimmable`: Is this field passable for swimming bobs?
6871 */
has_max_caps(lua_State * L)6872 int LuaField::has_max_caps(lua_State* L) {
6873 	const FCoords& f = fcoords(L);
6874 	std::string query = luaL_checkstring(L, 2);
6875 	lua_pushboolean(
6876 	   L, check_has_caps(L, luaL_checkstring(L, 2), f, f.field->maxcaps(), get_egbase(L).map()));
6877 	return 1;
6878 }
6879 
6880 /*
6881  ==========================================================
6882  C METHODS
6883  ==========================================================
6884  */
region(lua_State * L,uint32_t radius)6885 int LuaField::region(lua_State* L, uint32_t radius) {
6886 	const Map& map = get_egbase(L).map();
6887 	MapRegion<Area<FCoords>> mr(map, Area<FCoords>(fcoords(L), radius));
6888 
6889 	lua_newtable(L);
6890 	uint32_t idx = 1;
6891 	do {
6892 		lua_pushuint32(L, idx++);
6893 		const FCoords& loc = mr.location();
6894 		to_lua<LuaField>(L, new LuaField(loc.x, loc.y));
6895 		lua_settable(L, -3);
6896 	} while (mr.advance(map));
6897 
6898 	return 1;
6899 }
6900 
hollow_region(lua_State * L,uint32_t radius,uint32_t inner_radius)6901 int LuaField::hollow_region(lua_State* L, uint32_t radius, uint32_t inner_radius) {
6902 	const Map& map = get_egbase(L).map();
6903 	HollowArea<Area<>> har(Area<>(coords_, radius), inner_radius);
6904 
6905 	MapHollowRegion<Area<>> mr(map, har);
6906 
6907 	lua_newtable(L);
6908 	uint32_t idx = 1;
6909 	do {
6910 		lua_pushuint32(L, idx++);
6911 		to_lua<LuaField>(L, new LuaField(mr.location()));
6912 		lua_settable(L, -3);
6913 	} while (mr.advance(map));
6914 
6915 	return 1;
6916 }
6917 
fcoords(lua_State * L)6918 const Widelands::FCoords LuaField::fcoords(lua_State* L) {
6919 	return get_egbase(L).map().get_fcoords(coords_);
6920 }
6921 
6922 /* RST
6923 PlayerSlot
6924 ----------
6925 
6926 .. class:: PlayerSlot
6927 
6928    A player description as it is in the map. This contains information
6929    about the start position, the name of the player if this map is played
6930    as scenario and it's tribe. Note that these information can be different
6931    than the players actually valid in the game as in single player games,
6932    the player can choose most parameters freely.
6933 */
6934 const char LuaPlayerSlot::className[] = "PlayerSlot";
6935 const MethodType<LuaPlayerSlot> LuaPlayerSlot::Methods[] = {
6936    {nullptr, nullptr},
6937 };
6938 const PropertyType<LuaPlayerSlot> LuaPlayerSlot::Properties[] = {
6939    PROP_RO(LuaPlayerSlot, tribe_name),
6940    PROP_RO(LuaPlayerSlot, name),
6941    PROP_RO(LuaPlayerSlot, starting_field),
6942    {nullptr, nullptr, nullptr},
6943 };
6944 
__persist(lua_State * L)6945 void LuaPlayerSlot::__persist(lua_State* L) {
6946 	PERS_UINT32("player", player_number_);
6947 }
6948 
__unpersist(lua_State * L)6949 void LuaPlayerSlot::__unpersist(lua_State* L) {
6950 	UNPERS_UINT32("player", player_number_)
6951 }
6952 
6953 /*
6954  ==========================================================
6955  PROPERTIES
6956  ==========================================================
6957  */
6958 /* RST
6959    .. attribute:: tribe_name
6960 
6961       (RO) The name of the tribe suggested for this player in this map
6962 */
get_tribe_name(lua_State * L)6963 int LuaPlayerSlot::get_tribe_name(lua_State* L) {
6964 	lua_pushstring(L, get_egbase(L).map().get_scenario_player_tribe(player_number_));
6965 	return 1;
6966 }
6967 
6968 /* RST
6969    .. attribute:: name
6970 
6971       (RO) The name for this player as suggested in this map
6972 */
get_name(lua_State * L)6973 int LuaPlayerSlot::get_name(lua_State* L) {
6974 	lua_pushstring(L, get_egbase(L).map().get_scenario_player_name(player_number_));
6975 	return 1;
6976 }
6977 
6978 /* RST
6979    .. attribute:: starting_field
6980 
6981       (RO) The starting_field for this player as set in the map.
6982       Note that it is not guaranteed that the HQ of the player is on this
6983       field as scenarios and starting conditions are free to place the HQ
6984       wherever it want. This field is only centered when the game starts.
6985 */
get_starting_field(lua_State * L)6986 int LuaPlayerSlot::get_starting_field(lua_State* L) {
6987 	to_lua<LuaField>(L, new LuaField(get_egbase(L).map().get_starting_pos(player_number_)));
6988 	return 1;
6989 }
6990 
6991 /*
6992  ==========================================================
6993  LUA METHODS
6994  ==========================================================
6995  */
6996 
6997 /*
6998  ==========================================================
6999  C METHODS
7000  ==========================================================
7001  */
7002 
7003 /*
7004  * ========================================================================
7005  *                            MODULE FUNCTIONS
7006  * ========================================================================
7007  */
7008 
7009 const static struct luaL_Reg wlmap[] = {{nullptr, nullptr}};
7010 
luaopen_wlmap(lua_State * L)7011 void luaopen_wlmap(lua_State* L) {
7012 	lua_getglobal(L, "wl");    // S: wl_table
7013 	lua_pushstring(L, "map");  // S: wl_table "map"
7014 	luaL_newlib(L, wlmap);     // S: wl_table "map" wl.map_table
7015 	lua_settable(L, -3);       // S: wl_table
7016 	lua_pop(L, 1);             // S:
7017 
7018 	register_class<LuaMap>(L, "map");
7019 	register_class<LuaTribeDescription>(L, "map");
7020 	register_class<LuaMapObjectDescription>(L, "map");
7021 
7022 	register_class<LuaImmovableDescription>(L, "map", true);
7023 	add_parent<LuaImmovableDescription, LuaMapObjectDescription>(L);
7024 	lua_pop(L, 1);  // Pop the meta table
7025 
7026 	register_class<LuaBuildingDescription>(L, "map", true);
7027 	add_parent<LuaBuildingDescription, LuaMapObjectDescription>(L);
7028 	lua_pop(L, 1);  // Pop the meta table
7029 
7030 	register_class<LuaConstructionSiteDescription>(L, "map", true);
7031 	add_parent<LuaConstructionSiteDescription, LuaBuildingDescription>(L);
7032 	add_parent<LuaConstructionSiteDescription, LuaMapObjectDescription>(L);
7033 	lua_pop(L, 1);  // Pop the meta table
7034 
7035 	register_class<LuaDismantleSiteDescription>(L, "map", true);
7036 	add_parent<LuaDismantleSiteDescription, LuaBuildingDescription>(L);
7037 	add_parent<LuaDismantleSiteDescription, LuaMapObjectDescription>(L);
7038 	lua_pop(L, 1);  // Pop the meta table
7039 
7040 	register_class<LuaProductionSiteDescription>(L, "map", true);
7041 	add_parent<LuaProductionSiteDescription, LuaBuildingDescription>(L);
7042 	add_parent<LuaProductionSiteDescription, LuaMapObjectDescription>(L);
7043 	lua_pop(L, 1);  // Pop the meta table
7044 
7045 	register_class<LuaMilitarySiteDescription>(L, "map", true);
7046 	add_parent<LuaMilitarySiteDescription, LuaBuildingDescription>(L);
7047 	add_parent<LuaMilitarySiteDescription, LuaMapObjectDescription>(L);
7048 	lua_pop(L, 1);  // Pop the meta table
7049 
7050 	register_class<LuaTrainingSiteDescription>(L, "map", true);
7051 	add_parent<LuaTrainingSiteDescription, LuaProductionSiteDescription>(L);
7052 	add_parent<LuaTrainingSiteDescription, LuaBuildingDescription>(L);
7053 	add_parent<LuaTrainingSiteDescription, LuaMapObjectDescription>(L);
7054 	lua_pop(L, 1);  // Pop the meta table
7055 
7056 	register_class<LuaWarehouseDescription>(L, "map", true);
7057 	add_parent<LuaWarehouseDescription, LuaBuildingDescription>(L);
7058 	add_parent<LuaWarehouseDescription, LuaMapObjectDescription>(L);
7059 	lua_pop(L, 1);  // Pop the meta table
7060 
7061 	register_class<LuaMarketDescription>(L, "map", true);
7062 	add_parent<LuaMarketDescription, LuaBuildingDescription>(L);
7063 	add_parent<LuaMarketDescription, LuaMapObjectDescription>(L);
7064 	lua_pop(L, 1);  // Pop the meta table
7065 
7066 	register_class<LuaWareDescription>(L, "map", true);
7067 	add_parent<LuaWareDescription, LuaMapObjectDescription>(L);
7068 	lua_pop(L, 1);  // Pop the meta table
7069 
7070 	register_class<LuaWorkerDescription>(L, "map", true);
7071 	add_parent<LuaWorkerDescription, LuaMapObjectDescription>(L);
7072 	lua_pop(L, 1);  // Pop the meta table
7073 
7074 	register_class<LuaSoldierDescription>(L, "map", true);
7075 	add_parent<LuaSoldierDescription, LuaWorkerDescription>(L);
7076 	add_parent<LuaSoldierDescription, LuaMapObjectDescription>(L);
7077 	lua_pop(L, 1);  // Pop the meta table
7078 
7079 	register_class<LuaResourceDescription>(L, "map");
7080 	register_class<LuaTerrainDescription>(L, "map");
7081 
7082 	register_class<LuaField>(L, "map");
7083 	register_class<LuaPlayerSlot>(L, "map");
7084 	register_class<LuaEconomy>(L, "map");
7085 	register_class<LuaMapObject>(L, "map");
7086 
7087 	register_class<LuaBob>(L, "map", true);
7088 	add_parent<LuaBob, LuaMapObject>(L);
7089 	lua_pop(L, 1);  // Pop the meta table
7090 
7091 	register_class<LuaWorker>(L, "map", true);
7092 	add_parent<LuaWorker, LuaBob>(L);
7093 	add_parent<LuaWorker, LuaMapObject>(L);
7094 	lua_pop(L, 1);  // Pop the meta table
7095 
7096 	register_class<LuaSoldier>(L, "map", true);
7097 	add_parent<LuaSoldier, LuaWorker>(L);
7098 	add_parent<LuaSoldier, LuaBob>(L);
7099 	add_parent<LuaSoldier, LuaMapObject>(L);
7100 	lua_pop(L, 1);  // Pop the meta table
7101 
7102 	register_class<LuaShip>(L, "map", true);
7103 	add_parent<LuaShip, LuaBob>(L);
7104 	add_parent<LuaShip, LuaMapObject>(L);
7105 	lua_pop(L, 1);  // Pop the meta table
7106 
7107 	register_class<LuaBaseImmovable>(L, "map", true);
7108 	add_parent<LuaBaseImmovable, LuaMapObject>(L);
7109 	lua_pop(L, 1);  // Pop the meta table
7110 
7111 	register_class<LuaPlayerImmovable>(L, "map", true);
7112 	add_parent<LuaPlayerImmovable, LuaBaseImmovable>(L);
7113 	add_parent<LuaPlayerImmovable, LuaMapObject>(L);
7114 	lua_pop(L, 1);  // Pop the meta table
7115 
7116 	register_class<LuaBuilding>(L, "map", true);
7117 	add_parent<LuaBuilding, LuaPlayerImmovable>(L);
7118 	add_parent<LuaBuilding, LuaBaseImmovable>(L);
7119 	add_parent<LuaBuilding, LuaMapObject>(L);
7120 	lua_pop(L, 1);  // Pop the meta table
7121 
7122 	register_class<LuaPortDock>(L, "map", true);
7123 	add_parent<LuaPortDock, LuaPlayerImmovable>(L);
7124 	add_parent<LuaPortDock, LuaBaseImmovable>(L);
7125 	add_parent<LuaPortDock, LuaMapObject>(L);
7126 	lua_pop(L, 1);  // Pop the meta table
7127 
7128 	register_class<LuaFlag>(L, "map", true);
7129 	add_parent<LuaFlag, LuaPlayerImmovable>(L);
7130 	add_parent<LuaFlag, LuaBaseImmovable>(L);
7131 	add_parent<LuaFlag, LuaMapObject>(L);
7132 	lua_pop(L, 1);  // Pop the meta table
7133 
7134 	register_class<LuaRoad>(L, "map", true);
7135 	add_parent<LuaRoad, LuaPlayerImmovable>(L);
7136 	add_parent<LuaRoad, LuaBaseImmovable>(L);
7137 	add_parent<LuaRoad, LuaMapObject>(L);
7138 	lua_pop(L, 1);  // Pop the meta table
7139 
7140 	register_class<LuaConstructionSite>(L, "map", true);
7141 	add_parent<LuaConstructionSite, LuaBuilding>(L);
7142 	add_parent<LuaConstructionSite, LuaPlayerImmovable>(L);
7143 	add_parent<LuaConstructionSite, LuaBaseImmovable>(L);
7144 	add_parent<LuaConstructionSite, LuaMapObject>(L);
7145 	lua_pop(L, 1);  // Pop the meta table
7146 
7147 	register_class<LuaWarehouse>(L, "map", true);
7148 	add_parent<LuaWarehouse, LuaBuilding>(L);
7149 	add_parent<LuaWarehouse, LuaPlayerImmovable>(L);
7150 	add_parent<LuaWarehouse, LuaBaseImmovable>(L);
7151 	add_parent<LuaWarehouse, LuaMapObject>(L);
7152 	lua_pop(L, 1);  // Pop the meta table
7153 
7154 	register_class<LuaMarket>(L, "map", true);
7155 	add_parent<LuaMarket, LuaBuilding>(L);
7156 	add_parent<LuaMarket, LuaPlayerImmovable>(L);
7157 	add_parent<LuaMarket, LuaBaseImmovable>(L);
7158 	add_parent<LuaMarket, LuaMapObject>(L);
7159 	lua_pop(L, 1);  // Pop the meta table
7160 
7161 	register_class<LuaProductionSite>(L, "map", true);
7162 	add_parent<LuaProductionSite, LuaBuilding>(L);
7163 	add_parent<LuaProductionSite, LuaPlayerImmovable>(L);
7164 	add_parent<LuaProductionSite, LuaBaseImmovable>(L);
7165 	add_parent<LuaProductionSite, LuaMapObject>(L);
7166 	lua_pop(L, 1);  // Pop the meta table
7167 
7168 	register_class<LuaMilitarySite>(L, "map", true);
7169 	add_parent<LuaMilitarySite, LuaBuilding>(L);
7170 	add_parent<LuaMilitarySite, LuaPlayerImmovable>(L);
7171 	add_parent<LuaMilitarySite, LuaBaseImmovable>(L);
7172 	add_parent<LuaMilitarySite, LuaMapObject>(L);
7173 	lua_pop(L, 1);  // Pop the meta table
7174 
7175 	register_class<LuaTrainingSite>(L, "map", true);
7176 	add_parent<LuaTrainingSite, LuaProductionSite>(L);
7177 	add_parent<LuaTrainingSite, LuaBuilding>(L);
7178 	add_parent<LuaTrainingSite, LuaPlayerImmovable>(L);
7179 	add_parent<LuaTrainingSite, LuaBaseImmovable>(L);
7180 	add_parent<LuaTrainingSite, LuaMapObject>(L);
7181 	lua_pop(L, 1);  // Pop the meta table
7182 }
7183 }  // namespace LuaMaps
7184