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_bases.h"
21 
22 #include <boost/algorithm/string.hpp>
23 
24 #include "economy/economy.h"
25 #include "economy/road.h"
26 #include "economy/waterway.h"
27 #include "io/filesystem/layered_filesystem.h"
28 #include "io/profile.h"
29 #include "logic/filesystem_constants.h"
30 #include "logic/map_objects/checkstep.h"
31 #include "logic/map_objects/tribes/tribe_descr.h"
32 #include "logic/map_objects/tribes/tribes.h"
33 #include "logic/map_objects/tribes/ware_descr.h"
34 #include "logic/map_objects/world/world.h"
35 #include "logic/player.h"
36 #include "scripting/factory.h"
37 #include "scripting/globals.h"
38 #include "scripting/lua_map.h"
39 #include "ui_basic/progresswindow.h"
40 
41 using namespace Widelands;
42 
43 namespace LuaBases {
44 
45 /* RST
46 :mod:`wl.bases`
47 ==================
48 
49 .. module:: wl.bases
50    :synopsis: Base functions for common features in Game and Editor
51 
52 .. moduleauthor:: The Widelands development team
53 
54 .. currentmodule:: wl.bases
55 
56 The :mod:`wl.bases` module contains Base functions on which the classes
57 of :mod:`wl.game` and :mod:`wl.editor` are based. You will not need
58 to create any of the functions in this module directly, but you might
59 use their functionality via the child classes.
60 */
61 
62 /*
63  * ========================================================================
64  *                         MODULE CLASSES
65  * ========================================================================
66  */
67 
68 /* RST
69 Module Classes
70 ^^^^^^^^^^^^^^^^
71 
72 */
73 
74 /* RST
75 EditorGameBase
76 --------------
77 
78 .. class:: EditorGameBase
79 
80    Common functionality between Editor and Game.
81 */
82 
83 const char LuaEditorGameBase::className[] = "EditorGameBase";
84 const MethodType<LuaEditorGameBase> LuaEditorGameBase::Methods[] = {
85    METHOD(LuaEditorGameBase, get_immovable_description),
86    METHOD(LuaEditorGameBase, get_building_description),
87    METHOD(LuaEditorGameBase, get_tribe_description),
88    METHOD(LuaEditorGameBase, get_ware_description),
89    METHOD(LuaEditorGameBase, get_worker_description),
90    METHOD(LuaEditorGameBase, get_resource_description),
91    METHOD(LuaEditorGameBase, get_terrain_description),
92    METHOD(LuaEditorGameBase, save_campaign_data),
93    METHOD(LuaEditorGameBase, read_campaign_data),
94    METHOD(LuaEditorGameBase, set_loading_message),
95    {nullptr, nullptr},
96 };
97 const PropertyType<LuaEditorGameBase> LuaEditorGameBase::Properties[] = {
98    PROP_RO(LuaEditorGameBase, map),
99    PROP_RO(LuaEditorGameBase, players),
100    {nullptr, nullptr, nullptr},
101 };
102 
__persist(lua_State *)103 void LuaEditorGameBase::__persist(lua_State* /* L */) {
104 }
__unpersist(lua_State *)105 void LuaEditorGameBase::__unpersist(lua_State* /* L */) {
106 }
107 
108 /*
109  ==========================================================
110  PROPERTIES
111  ==========================================================
112  */
113 /* RST
114    .. attribute:: map
115 
116       (RO) The :class:`~wl.map.Map` the game is played on.
117 */
get_map(lua_State * L)118 int LuaEditorGameBase::get_map(lua_State* L) {
119 	to_lua<LuaMaps::LuaMap>(L, new LuaMaps::LuaMap());
120 	return 1;
121 }
122 
123 /* RST
124    .. attribute:: players
125 
126       (RO) An :class:`array` with the defined players. The players are
127       either of type :class:`wl.game.Player` or :class:`wl.editor.Player`.
128 
129       In game, there might be less players then defined in
130       :attr:`wl.map.Map.player_slots` because some slots might not be taken.
131       Also note that for the same reason you cannot index this array with
132       :attr:`wl.bases.PlayerBase.number`, but the players are ordered with
133       increasing number in this array.
134 
135       The editor always creates all players that are defined by the map.
136 */
get_players(lua_State * L)137 int LuaEditorGameBase::get_players(lua_State* L) {
138 	EditorGameBase& egbase = get_egbase(L);
139 
140 	lua_newtable(L);
141 
142 	uint32_t idx = 1;
143 	for (PlayerNumber i = 1; i <= kMaxPlayers; i++) {
144 		Player* rv = egbase.get_player(i);
145 		if (!rv) {
146 			continue;
147 		}
148 
149 		lua_pushuint32(L, idx++);
150 		get_factory(L).push_player(L, i);
151 		lua_settable(L, -3);
152 	}
153 	return 1;
154 }
155 
156 /*
157  ==========================================================
158  LUA METHODS
159  ==========================================================
160  */
161 
162 /* RST
163    .. function:: get_immovable_description(immovable_name)
164 
165       :arg immovable_name: the name of the immovable
166 
167       Returns the ImmovableDescription for the named object.
168 
169       (RO) The :class:`~wl.Game.Immovable_description`.
170 */
get_immovable_description(lua_State * L)171 int LuaEditorGameBase::get_immovable_description(lua_State* L) {
172 	if (lua_gettop(L) != 2) {
173 		report_error(L, "Wrong number of arguments");
174 	}
175 	const std::string immovable_name = luaL_checkstring(L, 2);
176 	EditorGameBase& egbase = get_egbase(L);
177 	const World& world = egbase.world();
178 	DescriptionIndex idx = world.get_immovable_index(immovable_name);
179 	if (idx != INVALID_INDEX) {
180 		const ImmovableDescr* descr = world.get_immovable_descr(idx);
181 		return to_lua<LuaMaps::LuaImmovableDescription>(
182 		   L, new LuaMaps::LuaImmovableDescription(descr));
183 	}
184 	const Tribes& tribes = egbase.tribes();
185 	idx = tribes.immovable_index(immovable_name);
186 	if (!tribes.immovable_exists(idx)) {
187 		report_error(L, "Immovable %s does not exist", immovable_name.c_str());
188 	}
189 	const ImmovableDescr* descr = tribes.get_immovable_descr(idx);
190 	return to_lua<LuaMaps::LuaImmovableDescription>(L, new LuaMaps::LuaImmovableDescription(descr));
191 }
192 
193 /* RST
194    .. function:: get_building_description(building_description.name)
195 
196       :arg building_name: the name of the building
197 
198       Returns the description for the given building.
199 
200       (RO) The :class:`~wl.Game.Building_description`.
201 */
get_building_description(lua_State * L)202 int LuaEditorGameBase::get_building_description(lua_State* L) {
203 	if (lua_gettop(L) != 2) {
204 		report_error(L, "Wrong number of arguments");
205 	}
206 	const Tribes& tribes = get_egbase(L).tribes();
207 	const std::string building_name = luaL_checkstring(L, 2);
208 	const DescriptionIndex building_index = tribes.building_index(building_name);
209 	if (!tribes.building_exists(building_index)) {
210 		report_error(L, "Building %s does not exist", building_name.c_str());
211 	}
212 	const BuildingDescr* building_description = tribes.get_building_descr(building_index);
213 
214 	return LuaMaps::upcasted_map_object_descr_to_lua(L, building_description);
215 }
216 
217 /* RST
218    .. function:: get_tribe_description(tribe_name)
219 
220       :arg tribe_name: the name of the tribe
221 
222       Returns the tribe description of the given tribe.
223 
224       (RO) The :class:`~wl.Game.Tribe_description`.
225 */
get_tribe_description(lua_State * L)226 int LuaEditorGameBase::get_tribe_description(lua_State* L) {
227 	if (lua_gettop(L) != 2) {
228 		report_error(L, "Wrong number of arguments");
229 	}
230 	EditorGameBase& egbase = get_egbase(L);
231 	const std::string tribe_name = luaL_checkstring(L, 2);
232 	if (!Widelands::tribe_exists(tribe_name)) {
233 		report_error(L, "Tribe %s does not exist", tribe_name.c_str());
234 	}
235 	const TribeDescr* descr =
236 	   egbase.tribes().get_tribe_descr(egbase.tribes().tribe_index(tribe_name));
237 	return to_lua<LuaMaps::LuaTribeDescription>(L, new LuaMaps::LuaTribeDescription(descr));
238 }
239 
240 /* RST
241    .. function:: get_ware_description(ware_description.name)
242 
243       :arg ware_name: the name of the ware
244 
245       Returns the ware description for the given ware.
246 
247       (RO) The :class:`~wl.Game.Ware_description`.
248 */
get_ware_description(lua_State * L)249 int LuaEditorGameBase::get_ware_description(lua_State* L) {
250 	if (lua_gettop(L) != 2) {
251 		report_error(L, "Wrong number of arguments");
252 	}
253 	const Tribes& tribes = get_egbase(L).tribes();
254 	const std::string ware_name = luaL_checkstring(L, 2);
255 	DescriptionIndex ware_index = tribes.ware_index(ware_name);
256 	if (!tribes.ware_exists(ware_index)) {
257 		report_error(L, "Ware %s does not exist", ware_name.c_str());
258 	}
259 	const WareDescr* ware_description = tribes.get_ware_descr(ware_index);
260 	return LuaMaps::upcasted_map_object_descr_to_lua(L, ware_description);
261 }
262 
263 /* RST
264    .. function:: get_worker_description(worker_description.name)
265 
266       :arg worker_name: the name of the worker
267 
268       Returs the worker desciption for the given worker.
269 
270       (RO) The :class:`~wl.Game.Worker_description`.
271 */
get_worker_description(lua_State * L)272 int LuaEditorGameBase::get_worker_description(lua_State* L) {
273 	if (lua_gettop(L) != 2) {
274 		report_error(L, "Wrong number of arguments");
275 	}
276 	const Tribes& tribes = get_egbase(L).tribes();
277 	const std::string worker_name = luaL_checkstring(L, 2);
278 	const DescriptionIndex worker_index = tribes.worker_index(worker_name);
279 	if (!tribes.worker_exists(worker_index)) {
280 		report_error(L, "Worker %s does not exist", worker_name.c_str());
281 	}
282 	const WorkerDescr* worker_description = tribes.get_worker_descr(worker_index);
283 	return LuaMaps::upcasted_map_object_descr_to_lua(L, worker_description);
284 }
285 
286 /* RST
287    .. function:: get_resource_description(resource_name)
288 
289       :arg resource_name: the name of the resource
290 
291       Returns the resource description for the given resource.
292 
293       (RO) The :class:`~wl.Game.Resource_description`.
294 */
get_resource_description(lua_State * L)295 int LuaEditorGameBase::get_resource_description(lua_State* L) {
296 	if (lua_gettop(L) != 2) {
297 		report_error(L, "Wrong number of arguments");
298 	}
299 	const std::string resource_name = luaL_checkstring(L, 2);
300 	const World& world = get_egbase(L).world();
301 	const DescriptionIndex idx = world.resource_index(resource_name.c_str());
302 
303 	if (idx == INVALID_INDEX) {
304 		report_error(L, "Resource %s does not exist", resource_name.c_str());
305 	}
306 
307 	const ResourceDescription* descr = world.get_resource(idx);
308 	return to_lua<LuaMaps::LuaResourceDescription>(L, new LuaMaps::LuaResourceDescription(descr));
309 }
310 
311 /* RST
312    .. function:: get_terrain_description(terrain_name)
313 
314       :arg terrain_name: the name of the terrain
315 
316       Returns a given terrain description for the given terrain.
317 
318       (RO) The :class:`~wl.Game.Terrain_description`.
319 */
get_terrain_description(lua_State * L)320 int LuaEditorGameBase::get_terrain_description(lua_State* L) {
321 	if (lua_gettop(L) != 2) {
322 		report_error(L, "Wrong number of arguments");
323 	}
324 	const std::string terrain_name = luaL_checkstring(L, 2);
325 	const TerrainDescription* descr = get_egbase(L).world().terrain_descr(terrain_name);
326 	if (!descr) {
327 		report_error(L, "Terrain %s does not exist", terrain_name.c_str());
328 	}
329 	return to_lua<LuaMaps::LuaTerrainDescription>(L, new LuaMaps::LuaTerrainDescription(descr));
330 }
331 
332 /* Helper function for save_campaign_data()
333 
334    This function reads the lua table from the stack and saves information about its
335    keys, values and data types and its size to the provided maps.
336    This function is recursive so subtables to any depth can be saved.
337    Each value in the table (including all subtables) is uniquely identified by a key_key.
338    The key_key is used as key in all the map.
339    For the topmost table of size x, the key_keys are called '_0' through '_x-1'.
340    For a subtable of size z at key_key '_y', the subtable's key_keys are called '_y_0' through
341    '_y_z-1'.
342    If a table is an array, the map 'keys' will contain no mappings for the array's key_keys.
343 */
save_table_recursively(lua_State * L,const std::string & depth,std::map<std::string,const char * > * data,std::map<std::string,const char * > * keys,std::map<std::string,const char * > * type,std::map<std::string,uint32_t> * size)344 static void save_table_recursively(lua_State* L,
345                                    const std::string& depth,
346                                    std::map<std::string, const char*>* data,
347                                    std::map<std::string, const char*>* keys,
348                                    std::map<std::string, const char*>* type,
349                                    std::map<std::string, uint32_t>* size) {
350 	lua_pushnil(L);
351 	uint32_t i = 0;
352 	while (lua_next(L, -2) != 0) {
353 		const std::string key_key = depth + "_" + std::to_string(i);
354 
355 		// check the value's type
356 		const char* type_name = lua_typename(L, lua_type(L, -1));
357 		const std::string t = std::string(type_name);
358 
359 		(*type)[key_key] = type_name;
360 
361 		if (t == "number" || t == "string") {
362 			// numbers may be treated like strings here
363 			(*data)[key_key] = luaL_checkstring(L, -1);
364 		} else if (t == "boolean") {
365 			(*data)[key_key] = luaL_checkboolean(L, -1) ? "true" : "false";
366 		} else if (t == "table") {
367 			save_table_recursively(L, depth + "_" + std::to_string(i), data, keys, type, size);
368 		} else {
369 			report_error(
370 			   L, "A campaign data value may be a string, integer, boolean, or table; but not a %s!",
371 			   type_name);
372 		}
373 
374 		++i;
375 
376 		// put the key on the stack top
377 		lua_pop(L, 1);
378 		if (lua_type(L, -1) == LUA_TSTRING) {
379 			// this is a table
380 			(*keys)[key_key] = luaL_checkstring(L, -1);
381 		} else if (lua_type(L, -1) == LUA_TNUMBER) {
382 			// this is an array
383 			if (i != luaL_checkuint32(L, -1)) {
384 				// If we get here, the scripter must have set some array values to nil.
385 				// This is forbidden because it causes problems when trying to read the data later.
386 				report_error(L, "A campaign data array entry must not be nil!");
387 			}
388 			// otherwise, this is a normal array, so all is well
389 		} else {
390 			report_error(L, "A campaign data key may be a string or integer; but not a %s!",
391 			             lua_typename(L, lua_type(L, -1)));
392 		}
393 	}
394 	(*size)[depth] = i;
395 }
396 
397 /* RST
398    .. function:: save_campaign_data(campaign_name, scenario_name, data)
399 
400       :arg campaign_name: the name of the current campaign, e.g. "empiretut" or "frisians"
401       :arg scenario_name: the name of the current scenario, e.g. "emp04" or "fri03"
402       :arg data: a table of key-value pairs to save
403 
404       Saves information that can be read by other scenarios.
405 
406       If an array is used, the data will be saved in the correct order. Arrays may not contain nil
407       values. If the table is not an array, all keys have to be strings. Tables may contain
408       subtables of any depth. Cyclic dependencies will cause Widelands to crash. Only tables/arrays,
409       strings, integer numbers and booleans may be used as values.
410 */
save_campaign_data(lua_State * L)411 int LuaEditorGameBase::save_campaign_data(lua_State* L) {
412 
413 	const std::string campaign_name = luaL_checkstring(L, 2);
414 	const std::string scenario_name = luaL_checkstring(L, 3);
415 	luaL_checktype(L, 4, LUA_TTABLE);
416 
417 	std::string dir = kCampaignDataDir + g_fs->file_separator() + campaign_name;
418 	boost::trim(dir);
419 	g_fs->ensure_directory_exists(dir);
420 
421 	std::string complete_filename =
422 	   dir + g_fs->file_separator() + scenario_name + kCampaignDataExtension;
423 	boost::trim(complete_filename);
424 
425 	std::map<std::string, const char*> data;
426 	std::map<std::string, const char*> keys;
427 	std::map<std::string, const char*> type;
428 	std::map<std::string, uint32_t> size;
429 
430 	save_table_recursively(L, "", &data, &keys, &type, &size);
431 
432 	Profile profile;
433 	Section& data_section = profile.create_section("data");
434 	for (const auto& p : data) {
435 		data_section.set_string(p.first.c_str(), p.second);
436 	}
437 	Section& keys_section = profile.create_section("keys");
438 	for (const auto& p : keys) {
439 		keys_section.set_string(p.first.c_str(), p.second);
440 	}
441 	Section& type_section = profile.create_section("type");
442 	for (const auto& p : type) {
443 		type_section.set_string(p.first.c_str(), p.second);
444 	}
445 	Section& size_section = profile.create_section("size");
446 	for (const auto& p : size) {
447 		size_section.set_natural(p.first.c_str(), p.second);
448 	}
449 
450 	profile.write(complete_filename.c_str(), false);
451 
452 	return 0;
453 }
454 
455 /* Helper function for read_campaign_data()
456 
457    This function reads the campaign data file and re-creates the table the data was created from.
458    This function is recursive so subtables to any depth can be created.
459    For information on section structure and key_keys, see the comment for save_table_recursively().
460    This function first newly creates the table to write data to, and the number of items in the
461    table is read.
462    For each item, the unique key_key is created. If the 'keys' section doesn't contain an entry for
463    that key_key,
464    it must be because this table is supposed to be an array. Then the data type is checked
465    and the key-value pair is written to the table as the correct type.
466 */
push_table_recursively(lua_State * L,const std::string & depth,Section * data_section,Section * keys_section,Section * type_section,Section * size_section)467 static void push_table_recursively(lua_State* L,
468                                    const std::string& depth,
469                                    Section* data_section,
470                                    Section* keys_section,
471                                    Section* type_section,
472                                    Section* size_section) {
473 	const uint32_t size = size_section->get_natural(depth.c_str());
474 	lua_newtable(L);
475 	for (uint32_t i = 0; i < size; i++) {
476 		const std::string key_key_str(depth + '_' + std::to_string(i));
477 		const char* key_key = key_key_str.c_str();
478 		if (keys_section->has_val(key_key)) {
479 			// This is a table
480 			lua_pushstring(L, keys_section->get_string(key_key));
481 		} else {
482 			// This must be an array
483 			lua_pushinteger(L, i + 1);
484 		}
485 
486 		// check the data type and push the value
487 		const std::string type = type_section->get_string(key_key);
488 
489 		if (type == "boolean") {
490 			lua_pushboolean(L, data_section->get_bool(key_key));
491 		} else if (type == "number") {
492 			lua_pushinteger(L, data_section->get_int(key_key));
493 		} else if (type == "string") {
494 			lua_pushstring(L, data_section->get_string(key_key));
495 		} else if (type == "table") {
496 			// creates a new (sub-)table at the stacktop, populated with its own key-value-pairs
497 			push_table_recursively(L, depth + "_" + std::to_string(i), data_section, keys_section,
498 			                       type_section, size_section);
499 		} else {
500 			// this code should not be reached unless the user manually edited the .wcd file
501 			log("Illegal data type %s in campaign data file, setting key %s to nil\n", type.c_str(),
502 			    luaL_checkstring(L, -1));
503 			lua_pushnil(L);
504 		}
505 		lua_settable(L, -3);
506 	}
507 }
508 
509 /* RST
510    .. function:: read_campaign_data(campaign_name, scenario_name)
511 
512       :arg campaign_name: the name of the campaign, e.g. "empiretut" or "frisians"
513       :arg scenario_name: the name of the scenario that saved the data, e.g. "emp04" or "fri03"
514 
515       Reads information that was saved by another scenario.
516       The data is returned as a table of key-value pairs.
517       The table is not guaranteed to be in any particular order, unless it is an array,
518       in which case it will be returned in the same order as it was saved.
519       This function returns :const:`nil` if the file cannot be opened for reading.
520 */
read_campaign_data(lua_State * L)521 int LuaEditorGameBase::read_campaign_data(lua_State* L) {
522 	const std::string campaign_name = luaL_checkstring(L, 2);
523 	const std::string scenario_name = luaL_checkstring(L, 3);
524 
525 	std::string complete_filename = kCampaignDataDir + g_fs->file_separator() + campaign_name +
526 	                                g_fs->file_separator() + scenario_name + kCampaignDataExtension;
527 	boost::trim(complete_filename);
528 
529 	Profile profile;
530 	profile.read(complete_filename.c_str());
531 	Section* data_section = profile.get_section("data");
532 	Section* keys_section = profile.get_section("keys");
533 	Section* type_section = profile.get_section("type");
534 	Section* size_section = profile.get_section("size");
535 	if (data_section == nullptr || keys_section == nullptr || type_section == nullptr ||
536 	    size_section == nullptr) {
537 		log("Unable to read campaign data file, returning nil\n");
538 		lua_pushnil(L);
539 	} else {
540 		push_table_recursively(L, "", data_section, keys_section, type_section, size_section);
541 	}
542 
543 	return 1;
544 }
545 
546 /* RST
547    .. function:: set_loading_message(text)
548 
549       :arg text: the text to display
550 
551       Change the progress message on the loading screen.
552       May be used from the init.lua files for tribe/world loading only.
553 */
set_loading_message(lua_State * L)554 int LuaEditorGameBase::set_loading_message(lua_State* L) {
555 	get_egbase(L).step_loader_ui(luaL_checkstring(L, 2));
556 	return 0;
557 }
558 
559 /*
560  ==========================================================
561  C METHODS
562  ==========================================================
563  */
564 
565 /* RST
566 PlayerBase
567 ----------
568 
569 .. class:: PlayerBase
570 
571    The Base class for the Player objects in Editor and Game
572 */
573 
574 const char LuaPlayerBase::className[] = "PlayerBase";
575 const MethodType<LuaPlayerBase> LuaPlayerBase::Methods[] = {
576    METHOD(LuaPlayerBase, __eq),        METHOD(LuaPlayerBase, __tostring),
577    METHOD(LuaPlayerBase, conquer),     METHOD(LuaPlayerBase, get_wares),
578    METHOD(LuaPlayerBase, get_workers), METHOD(LuaPlayerBase, place_building),
579    METHOD(LuaPlayerBase, place_flag),  METHOD(LuaPlayerBase, place_road),
580    METHOD(LuaPlayerBase, place_ship),  {nullptr, nullptr},
581 };
582 const PropertyType<LuaPlayerBase> LuaPlayerBase::Properties[] = {
583    PROP_RO(LuaPlayerBase, number), PROP_RO(LuaPlayerBase, tribe_name), {nullptr, nullptr, nullptr},
584 };
585 
__persist(lua_State * L)586 void LuaPlayerBase::__persist(lua_State* L) {
587 	PERS_UINT32("player", player_number_);
588 }
__unpersist(lua_State * L)589 void LuaPlayerBase::__unpersist(lua_State* L) {
590 	UNPERS_UINT32("player", player_number_)
591 }
592 
593 /*
594  ==========================================================
595  PROPERTIES
596  ==========================================================
597  */
598 /* RST
599    .. attribute:: number
600 
601       (RO) The number of this Player.
602 */
get_number(lua_State * L)603 int LuaPlayerBase::get_number(lua_State* L) {
604 	lua_pushuint32(L, player_number_);
605 	return 1;
606 }
607 
608 /* RST
609    .. attribute:: tribe_name
610 
611       (RO) The name of the tribe of this player.
612 */
get_tribe_name(lua_State * L)613 int LuaPlayerBase::get_tribe_name(lua_State* L) {
614 	lua_pushstring(L, get(L, get_egbase(L)).tribe().name());
615 	return 1;
616 }
617 
618 /*
619  ==========================================================
620  LUA METHODS
621  ==========================================================
622  */
__eq(lua_State * L)623 int LuaPlayerBase::__eq(lua_State* L) {
624 	EditorGameBase& egbase = get_egbase(L);
625 	const Player& me = get(L, egbase);
626 	const Player& you = (*get_base_user_class<LuaPlayerBase>(L, 2))->get(L, egbase);
627 
628 	lua_pushboolean(L, (me.player_number() == you.player_number()));
629 	return 1;
630 }
631 
__tostring(lua_State * L)632 int LuaPlayerBase::__tostring(lua_State* L) {
633 	const std::string pushme = (boost::format("Player(%i)") %
634 	                            static_cast<unsigned int>(get(L, get_egbase(L)).player_number()))
635 	                              .str();
636 	lua_pushstring(L, pushme.c_str());
637 	return 1;
638 }
639 /* RST
640    .. function:: place_flag(field[, force])
641 
642       Builds a flag on a given field if it is legal to do so. If not,
643       reports an error
644 
645       :arg field: where the flag should be created
646       :type field: :class:`wl.map.Field`
647       :arg force: If this is :const:`true` then the map is created with
648          pure force:
649 
650             * if there is an immovable on this field, it will be
651               removed
652             * if there are flags too close by to this field, they will be
653               ripped
654             * if the player does not own the territory, it is conquered
655               for him.
656       :type force: :class:`boolean`
657       :returns: :class:`wl.map.Flag` object created or :const:`nil`.
658 */
place_flag(lua_State * L)659 int LuaPlayerBase::place_flag(lua_State* L) {
660 	uint32_t n = lua_gettop(L);
661 	LuaMaps::LuaField* c = *get_user_class<LuaMaps::LuaField>(L, 2);
662 	bool force = false;
663 	if (n > 2) {
664 		force = luaL_checkboolean(L, 3);
665 	}
666 
667 	Flag* f;
668 	if (!force) {
669 		f = get(L, get_egbase(L)).build_flag(c->fcoords(L));
670 		if (!f) {
671 			report_error(L, "Couldn't build flag!");
672 		}
673 	} else {
674 		f = &get(L, get_egbase(L)).force_flag(c->fcoords(L));
675 	}
676 
677 	return to_lua<LuaMaps::LuaFlag>(L, new LuaMaps::LuaFlag(*f));
678 }
679 
680 /* RST
681    .. method:: place_road(roadtype, f1, dir1, dir2, ...[, force=false])
682 
683       Start a road or waterway at the given field, then walk the directions
684       given. Places a flag at the last field.
685 
686       If the last argument to this function is :const:`true` the road will
687       be created by force: all immovables in the way are removed and land
688       is conquered.
689 
690       :arg roadtype: 'normal', 'busy', or 'waterway'
691       :type roadtype: :class:`string`
692       :arg f1: fields to connect with this road
693       :type f1: :class:`wl.map.Field`
694       :arg dirs: direction, can be either ("r", "l", "br", "bl", "tr", "tl") or
695          ("e", "w", "ne", "nw", "se", "sw").
696       :type dirs: :class:`string`
697 
698       :returns: the road created
699 */
place_road(lua_State * L)700 int LuaPlayerBase::place_road(lua_State* L) {
701 	EditorGameBase& egbase = get_egbase(L);
702 	const Map& map = egbase.map();
703 
704 	const std::string roadtype = luaL_checkstring(L, 2);
705 	Flag* starting_flag = (*get_user_class<LuaMaps::LuaFlag>(L, 3))->get(L, egbase);
706 	Coords current = starting_flag->get_position();
707 	Path path(current);
708 
709 	bool force_road = false;
710 	if (lua_isboolean(L, -1)) {
711 		force_road = luaL_checkboolean(L, -1);
712 		lua_pop(L, 1);
713 	}
714 
715 	// Construct the path
716 	CheckStepLimited cstep;
717 	for (int32_t i = 4; i <= lua_gettop(L); i++) {
718 		std::string d = luaL_checkstring(L, i);
719 
720 		if (d == "ne" || d == "tr") {
721 			path.append(map, 1);
722 			map.get_trn(current, &current);
723 		} else if (d == "e" || d == "r") {
724 			path.append(map, 2);
725 			map.get_rn(current, &current);
726 		} else if (d == "se" || d == "br") {
727 			path.append(map, 3);
728 			map.get_brn(current, &current);
729 		} else if (d == "sw" || d == "bl") {
730 			path.append(map, 4);
731 			map.get_bln(current, &current);
732 		} else if (d == "w" || d == "l") {
733 			path.append(map, 5);
734 			map.get_ln(current, &current);
735 		} else if (d == "nw" || d == "tl") {
736 			path.append(map, 6);
737 			map.get_tln(current, &current);
738 		} else {
739 			report_error(L, "Illegal direction: %s", d.c_str());
740 		}
741 
742 		cstep.add_allowed_location(current);
743 	}
744 
745 	// Make sure that the road cannot cross itself
746 	Path optimal_path;
747 	map.findpath(path.get_start(), path.get_end(), 0, optimal_path, cstep, Map::fpBidiCost);
748 	if (optimal_path.get_nsteps() != path.get_nsteps()) {
749 		report_error(L, "Cannot build a road that crosses itself!");
750 	}
751 
752 	RoadBase* r = nullptr;
753 	if (force_road) {
754 		if (roadtype == "waterway") {
755 			r = &get(L, egbase).force_waterway(path);
756 		} else {
757 			Road& road = get(L, egbase).force_road(path);
758 			if (roadtype == "busy") {
759 				road.set_busy(egbase, true);
760 			} else if (roadtype != "normal") {
761 				report_error(
762 				   L, "Invalid road type '%s' (permitted values are 'normal', 'busy', and 'waterway'",
763 				   roadtype.c_str());
764 			}
765 			r = &road;
766 		}
767 	} else {
768 		BaseImmovable* bi = map.get_immovable(current);
769 		if (!bi || bi->descr().type() != MapObjectType::FLAG) {
770 			if (!get(L, egbase).build_flag(current)) {
771 				report_error(L, "Could not place end flag!");
772 			}
773 		}
774 		if (bi && bi == starting_flag) {
775 			report_error(L, "Cannot build a closed loop!");
776 		}
777 
778 		if (roadtype == "waterway") {
779 			r = get(L, egbase).build_waterway(path);
780 		} else {
781 			Road* road = get(L, egbase).build_road(path);
782 			if (roadtype == "busy") {
783 				if (road) {
784 					road->set_busy(egbase, true);
785 				}
786 			} else if (roadtype != "normal") {
787 				report_error(
788 				   L, "Invalid road type '%s' (permitted values are 'normal', 'busy', and 'waterway'",
789 				   roadtype.c_str());
790 			}
791 			r = road;
792 		}
793 	}
794 
795 	if (!r) {
796 		report_error(L, "Error while creating Road. May be: something is in "
797 		                "the way or you do not own the territory where you want to build "
798 		                "the road");
799 	}
800 
801 	return to_lua<LuaMaps::LuaRoad>(L, new LuaMaps::LuaRoad(*r));
802 }
803 
804 /* RST
805    .. method:: place_building(name, field[, cs = false, force = false])
806 
807       Immediately creates a building on the given field. The building starts
808       out completely empty. If :const:`cs` is set, the building
809       is not created directly, instead a constructionsite for this building is
810       placed.
811 
812       If the :const:`force` argument is set, the building is forced into
813       existence: the same action is taken as for :meth:`place_flag` when force
814       is :const:`true`. Additionally, all buildings that are too close to the
815       new one are ripped.
816 
817       :returns: a subclass of :class:`wl.map.Building`
818 */
place_building(lua_State * L)819 int LuaPlayerBase::place_building(lua_State* L) {
820 	const std::string& name = luaL_checkstring(L, 2);
821 	LuaMaps::LuaField* c = *get_user_class<LuaMaps::LuaField>(L, 3);
822 	bool constructionsite = false;
823 	bool force = false;
824 
825 	if (lua_gettop(L) >= 4) {
826 		constructionsite = luaL_checkboolean(L, 4);
827 	}
828 	if (lua_gettop(L) >= 5) {
829 		force = luaL_checkboolean(L, 5);
830 	}
831 
832 	EditorGameBase& egbase = get_egbase(L);
833 	const Tribes& tribes = egbase.tribes();
834 
835 	if (!tribes.building_exists(name)) {
836 		report_error(L, "Unknown Building: '%s'", name.c_str());
837 	}
838 	DescriptionIndex building_index = tribes.building_index(name);
839 
840 	FormerBuildings former_buildings;
841 	find_former_buildings(tribes, building_index, &former_buildings);
842 	if (constructionsite) {
843 		former_buildings.pop_back();
844 	}
845 
846 	Building* b = nullptr;
847 	if (force) {
848 		if (constructionsite) {
849 			b = &get(L, egbase).force_csite(c->coords(), building_index, former_buildings);
850 		} else {
851 			b = &get(L, egbase).force_building(c->coords(), former_buildings);
852 		}
853 	} else {
854 		b = get(L, egbase).build(c->coords(), building_index, constructionsite, former_buildings);
855 	}
856 	if (!b) {
857 		report_error(L, "Couldn't place building!");
858 	}
859 
860 	LuaMaps::upcasted_map_object_to_lua(L, b);
861 	return 1;
862 }
863 
864 /* RST
865    .. method:: place_ship(field)
866 
867       Places a ship for the player's tribe, which will be
868       owned by the player.
869 
870       :arg field: where the ship should be placed.
871       :type field: :class:`wl.map.Field`
872 
873       :returns: The new ship that was created.
874 */
875 // UNTESTED
place_ship(lua_State * L)876 int LuaPlayerBase::place_ship(lua_State* L) {
877 	LuaMaps::LuaField* c = *get_user_class<LuaMaps::LuaField>(L, 2);
878 
879 	EditorGameBase& egbase = get_egbase(L);
880 	Player& player = get(L, egbase);
881 
882 	const ShipDescr* descr = egbase.tribes().get_ship_descr(player.tribe().ship());
883 	Bob& ship = egbase.create_ship(c->coords(), descr->name(), &player);
884 
885 	LuaMaps::upcasted_map_object_to_lua(L, &ship);
886 
887 	return 1;
888 }
889 
890 /* RST
891    .. method:: conquer(f[, radius=1])
892 
893       Conquer this area around the given field if it does not belong to the
894       player already. This will conquer the fields no matter who owns it at the
895       moment.
896 
897       :arg f: center field for conquering
898       :type f: :class:`wl.map.Field`
899       :arg radius: radius to conquer around. Default value makes this call
900          conquer 7 fields
901       :type radius: :class:`integer`
902       :returns: :const:`nil`
903 */
conquer(lua_State * L)904 int LuaPlayerBase::conquer(lua_State* L) {
905 	uint32_t radius = 1;
906 	if (lua_gettop(L) > 2) {
907 		radius = luaL_checkuint32(L, 3);
908 	}
909 
910 	get_egbase(L).conquer_area_no_building(PlayerArea<Area<FCoords>>(
911 	   player_number_,
912 	   Area<FCoords>((*get_user_class<LuaMaps::LuaField>(L, 2))->fcoords(L), radius)));
913 	return 0;
914 }
915 
916 /* RST
917    .. method:: get_workers(name)
918 
919       Returns the number of workers of this type in the players stock. This does not implement
920       everything that :class:`HasWorkers` offers.
921 
922       :arg name: name of the worker to get
923       :type name: :class:`string`.
924       :returns: the number of workers
925 */
926 // UNTESTED
get_workers(lua_State * L)927 int LuaPlayerBase::get_workers(lua_State* L) {
928 	Player& player = get(L, get_egbase(L));
929 	const std::string workername = luaL_checkstring(L, -1);
930 
931 	const DescriptionIndex worker = player.tribe().worker_index(workername);
932 
933 	uint32_t nworkers = 0;
934 	for (const auto& economy : player.economies()) {
935 		if (economy.second->type() == Widelands::wwWORKER) {
936 			nworkers += economy.second->stock_ware_or_worker(worker);
937 		}
938 	}
939 	lua_pushuint32(L, nworkers);
940 	return 1;
941 }
942 
943 /* RST
944    .. method:: get_wares(name)
945 
946       Returns the number of wares of this type in the players stock. This does not implement
947       everything that :class:`HasWorkers` offers.
948 
949       :arg name: name of the worker to get
950       :type name: :class:`string`.
951       :returns: the number of wares
952 */
953 // UNTESTED
get_wares(lua_State * L)954 int LuaPlayerBase::get_wares(lua_State* L) {
955 	EditorGameBase& egbase = get_egbase(L);
956 	Player& player = get(L, egbase);
957 	const std::string warename = luaL_checkstring(L, -1);
958 
959 	const DescriptionIndex ware = egbase.tribes().ware_index(warename);
960 
961 	uint32_t nwares = 0;
962 	for (const auto& economy : player.economies()) {
963 		if (economy.second->type() == Widelands::wwWARE) {
964 			nwares += economy.second->stock_ware_or_worker(ware);
965 		}
966 	}
967 	lua_pushuint32(L, nwares);
968 	return 1;
969 }
970 
971 /*
972  ==========================================================
973  C METHODS
974  ==========================================================
975  */
get(lua_State * L,Widelands::EditorGameBase & egbase)976 Player& LuaPlayerBase::get(lua_State* L, Widelands::EditorGameBase& egbase) {
977 	if (player_number_ > kMaxPlayers) {
978 		report_error(L, "Illegal player number %i", player_number_);
979 	}
980 	Player* rv = egbase.get_player(player_number_);
981 	if (!rv) {
982 		report_error(L, "Player with the number %i does not exist", player_number_);
983 	}
984 	return *rv;
985 }
986 
987 /*
988  * ========================================================================
989  *                            MODULE FUNCTIONS
990  * ========================================================================
991  */
992 
993 const static struct luaL_Reg wlbases[] = {{nullptr, nullptr}};
994 
luaopen_wlbases(lua_State * const L)995 void luaopen_wlbases(lua_State* const L) {
996 	lua_getglobal(L, "wl");      // S: wl_table
997 	lua_pushstring(L, "bases");  // S: wl_table "bases"
998 	luaL_newlib(L, wlbases);     // S: wl_table "bases" wl.bases_table
999 	lua_settable(L, -3);         // S: wl_table
1000 	lua_pop(L, 1);               // S:
1001 
1002 	register_class<LuaEditorGameBase>(L, "bases");
1003 	register_class<LuaPlayerBase>(L, "bases");
1004 }
1005 }  // namespace LuaBases
1006