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_root.h"
21
22 #include <memory>
23
24 #include "logic/cmd_luacoroutine.h"
25 #include "logic/game.h"
26 #include "logic/game_controller.h"
27 #include "logic/map_objects/findimmovable.h"
28 #include "logic/map_objects/immovable.h"
29 #include "logic/map_objects/tribes/tribe_descr.h"
30 #include "logic/map_objects/tribes/tribes.h"
31 #include "logic/map_objects/world/critter.h"
32 #include "logic/map_objects/world/world.h"
33 #include "scripting/globals.h"
34 #include "scripting/lua_coroutine.h"
35 #include "scripting/lua_game.h"
36 #include "scripting/lua_map.h"
37 #include "scripting/lua_table.h"
38 #include "wui/interactive_player.h"
39
40 using namespace Widelands;
41
42 namespace LuaRoot {
43
44 /* RST
45 :mod:`wl`
46 ======================
47
48 .. module:: wl
49 :synopsis: Base classes which allow access to all widelands internals.
50
51 .. moduleauthor:: The Widelands development team
52
53 .. currentmodule:: wl
54 */
55
56 /*
57 * ========================================================================
58 * MODULE CLASSES
59 * ========================================================================
60 */
61
62 /* RST
63 Module Classes
64 ^^^^^^^^^^^^^^^^
65
66 */
67
68 /* RST
69 Game
70 -----
71
72 .. class:: Game
73
74 Child of: :class:`wl.bases.EditorGameBase`
75
76 The root class to access the game internals. You can
77 construct as many instances of this class as you like, but
78 they all will access the one game currently running.
79 */
80 const char LuaGame::className[] = "Game";
81 const MethodType<LuaGame> LuaGame::Methods[] = {
82 METHOD(LuaGame, launch_coroutine), METHOD(LuaGame, save), {nullptr, nullptr},
83 };
84 const PropertyType<LuaGame> LuaGame::Properties[] = {
85 PROP_RO(LuaGame, real_speed), PROP_RO(LuaGame, time),
86 PROP_RW(LuaGame, desired_speed), PROP_RW(LuaGame, allow_saving),
87 PROP_RO(LuaGame, last_save_time), PROP_RO(LuaGame, type),
88 PROP_RO(LuaGame, interactive_player), PROP_RO(LuaGame, scenario_difficulty),
89 {nullptr, nullptr, nullptr},
90 };
91
LuaGame(lua_State *)92 LuaGame::LuaGame(lua_State* /* L */) {
93 // Nothing to do.
94 }
95
__persist(lua_State *)96 void LuaGame::__persist(lua_State* /* L */) {
97 }
__unpersist(lua_State *)98 void LuaGame::__unpersist(lua_State* /* L */) {
99 }
100
101 /*
102 ==========================================================
103 PROPERTIES
104 ==========================================================
105 */
106
107 /* RST
108 .. attribute:: real_speed
109
110 (RO) The speed that the current game is running at in ms.
111 For example, for game speed = 2x, this returns 2000.
112 */
get_real_speed(lua_State * L)113 int LuaGame::get_real_speed(lua_State* L) {
114 lua_pushinteger(L, get_game(L).game_controller()->real_speed());
115 return 1;
116 }
117
118 /* RST
119 .. attribute:: time
120
121 (RO) The absolute time elapsed since the game was started in milliseconds.
122 */
get_time(lua_State * L)123 int LuaGame::get_time(lua_State* L) {
124 lua_pushint32(L, get_game(L).get_gametime());
125 return 1;
126 }
127
128 /* RST
129 .. attribute:: desired_speed
130
131 (RW) Sets the desired speed of the game in ms per real second, so a speed of
132 2000 means the game runs at 2x speed. Note that this will not work in
133 network games as expected.
134 */
135 // UNTESTED
set_desired_speed(lua_State * L)136 int LuaGame::set_desired_speed(lua_State* L) {
137 get_game(L).game_controller()->set_desired_speed(luaL_checkuint32(L, -1));
138 return 1;
139 }
140 // UNTESTED
get_desired_speed(lua_State * L)141 int LuaGame::get_desired_speed(lua_State* L) {
142 lua_pushuint32(L, get_game(L).game_controller()->desired_speed());
143 return 1;
144 }
145
146 /* RST
147 .. attribute:: allow_saving
148
149 (RW) Disable or enable saving. When you show off UI features in a
150 tutorial or scenario, you have to disallow saving because UI
151 elements can not be saved and therefore reloading a game saved in the
152 meantime would crash the game.
153 */
154 // UNTESTED
set_allow_saving(lua_State * L)155 int LuaGame::set_allow_saving(lua_State* L) {
156 get_game(L).save_handler().set_allow_saving(luaL_checkboolean(L, -1));
157 return 0;
158 }
159 // UNTESTED
get_allow_saving(lua_State * L)160 int LuaGame::get_allow_saving(lua_State* L) {
161 lua_pushboolean(L, get_game(L).save_handler().get_allow_saving());
162 return 1;
163 }
164
165 /* RST
166 .. attribute:: interactive_player
167
168 (RO) The player number of the interactive player, or 0 for spectator
169 */
get_interactive_player(lua_State * L)170 int LuaGame::get_interactive_player(lua_State* L) {
171 upcast(const InteractivePlayer, p, get_game(L).get_ibase());
172 lua_pushuint32(L, p ? p->player_number() : 0);
173 return 1;
174 }
175
176 /* RST
177 .. attribute:: last_save_time
178
179 (RO) The gametime at which the game was last saved.
180 */
get_last_save_time(lua_State * L)181 int LuaGame::get_last_save_time(lua_State* L) {
182 lua_pushuint32(L, get_game(L).save_handler().last_save_time());
183 return 1;
184 }
185
186 /* RST
187 .. attribute:: type
188
189 (RO) One string out of 'undefined', 'singleplayer', 'netclient', 'nethost', 'replay',
190 describing the type of game that is played.
191 */
get_type(lua_State * L)192 int LuaGame::get_type(lua_State* L) {
193 // enum class GameType : uint8_t { kUndefined = 0, kSingleplayer, kNetClient, kNetHost, kReplay
194 // };
195 switch (get_game(L).game_controller()->get_game_type()) {
196 case GameController::GameType::kSingleplayer:
197 lua_pushstring(L, "singleplayer");
198 break;
199 case GameController::GameType::kNetClient:
200 lua_pushstring(L, "netclient");
201 break;
202 case GameController::GameType::kNetHost:
203 lua_pushstring(L, "nethost");
204 break;
205 case GameController::GameType::kReplay:
206 lua_pushstring(L, "replay");
207 break;
208 default:
209 lua_pushstring(L, "undefined");
210 break;
211 }
212 return 1;
213 }
214
215 /* RST
216 .. attribute:: scenario_difficulty
217 (RO) The difficulty level of the current scenario. Values range from 1 to the number
218 of levels specified in the campaign's configuration in campaigns.lua. By convention
219 higher values mean more difficult. Throws an error if used outside of a scenario.
220 */
get_scenario_difficulty(lua_State * L)221 int LuaGame::get_scenario_difficulty(lua_State* L) {
222 const uint32_t d = get_game(L).get_scenario_difficulty();
223 if (d == kScenarioDifficultyNotSet) {
224 report_error(L, "Scenario difficulty not set");
225 }
226 lua_pushuint32(L, d);
227 return 1;
228 }
229
230 /*
231 ==========================================================
232 LUA METHODS
233 ==========================================================
234 */
235 /* RST
236 .. method:: launch_coroutine(func[, when = now])
237
238 Hands a Lua coroutine object over to widelands for execution. The object
239 must have been created via :func:`coroutine.create`. The coroutine is
240 expected to :func:`coroutine.yield` at regular intervals with the
241 absolute game time on which the function should be awakened again. You
242 should also have a look at :mod:`core.cr`.
243
244 :arg func: coroutine object to run
245 :type func: :class:`thread`
246 :arg when: absolute time when this coroutine should run
247 :type when: :class:`integer`
248
249 :returns: :const:`nil`
250 */
launch_coroutine(lua_State * L)251 int LuaGame::launch_coroutine(lua_State* L) {
252 int nargs = lua_gettop(L);
253 uint32_t runtime = get_game(L).get_gametime();
254 if (nargs < 2) {
255 report_error(L, "Too few arguments!");
256 }
257 if (nargs == 3) {
258 runtime = luaL_checkuint32(L, 3);
259 lua_pop(L, 1);
260 }
261
262 std::unique_ptr<LuaCoroutine> cr(new LuaCoroutine(luaL_checkthread(L, 2)));
263 lua_pop(L, 2); // Remove coroutine and Game object from stack
264
265 get_game(L).enqueue_command(new Widelands::CmdLuaCoroutine(runtime, std::move(cr)));
266
267 return 0;
268 }
269
270 /* RST
271 .. method:: save(name)
272
273 Requests a savegame. Note that the actual save will be performed
274 later, and that you have no control over any error that may happen
275 by then currently.
276
277 :arg name: name of save game, as if entered in the save dialog.
278 If this game already exists, it will be silently overwritten.
279 If empty, the autosave name will be used.
280 :type name: :class:`string`
281 :returns: :const:`nil`
282 */
save(lua_State * L)283 int LuaGame::save(lua_State* L) {
284 const std::string filename = luaL_checkstring(L, -1);
285 get_game(L).save_handler().request_save(filename);
286
287 // DO NOT REMOVE THIS OUTPUT. It is used by the regression test suite to
288 // figure out which files to load after a save was requested in a test.
289 log("Script requests save to: %s\n", filename.c_str());
290
291 return 0;
292 }
293
294 /*
295 ==========================================================
296 C METHODS
297 ==========================================================
298 */
299
300 /* RST
301 Editor
302 ------
303
304 .. class:: Editor
305
306 Child of: :class:`wl.bases.EditorGameBase`
307
308 The Editor object; it is the correspondence of the :class:`wl.Game`
309 that is used in a Game.
310 */
311
312 const char LuaEditor::className[] = "Editor";
313 const MethodType<LuaEditor> LuaEditor::Methods[] = {
314 {nullptr, nullptr},
315 };
316 const PropertyType<LuaEditor> LuaEditor::Properties[] = {
317 {nullptr, nullptr, nullptr},
318 };
319
LuaEditor(lua_State *)320 LuaEditor::LuaEditor(lua_State* /* L */) {
321 // Nothing to do.
322 }
323
__persist(lua_State *)324 void LuaEditor::__persist(lua_State* /* L */) {
325 }
__unpersist(lua_State *)326 void LuaEditor::__unpersist(lua_State* /* L */) {
327 }
328
329 /*
330 ==========================================================
331 PROPERTIES
332 ==========================================================
333 */
334
335 /*
336 ==========================================================
337 LUA METHODS
338 ==========================================================
339 */
340
341 /*
342 ==========================================================
343 C METHODS
344 ==========================================================
345 */
346
347 /* RST
348 World
349 -----
350
351 .. class:: World
352
353 This offers access to the objects in the Widelands world and allows to add new objects.
354 On how to build the world and adding new objects to it, see
355 :ref:`toc_lua_world`.
356 */
357
358 const char LuaWorld::className[] = "World";
359 const MethodType<LuaWorld> LuaWorld::Methods[] = {
360 METHOD(LuaWorld, new_critter_type),
361 METHOD(LuaWorld, new_editor_critter_category),
362 METHOD(LuaWorld, new_editor_immovable_category),
363 METHOD(LuaWorld, new_editor_terrain_category),
364 METHOD(LuaWorld, new_immovable_type),
365 METHOD(LuaWorld, new_resource_type),
366 METHOD(LuaWorld, new_terrain_type),
367 {0, 0},
368 };
369 const PropertyType<LuaWorld> LuaWorld::Properties[] = {
370 PROP_RO(LuaWorld, immovable_descriptions), PROP_RO(LuaWorld, terrain_descriptions), {0, 0, 0},
371 };
372
LuaWorld(lua_State *)373 LuaWorld::LuaWorld(lua_State* /* L */) {
374 // Nothing to do.
375 }
376
__persist(lua_State *)377 void LuaWorld::__persist(lua_State*) {
378 // Nothing to be done.
379 }
__unpersist(lua_State *)380 void LuaWorld::__unpersist(lua_State*) {
381 // Nothing to be done.
382 }
383
384 /*
385 ==========================================================
386 PROPERTIES
387 ==========================================================
388 */
389
390 /*
391 ==========================================================
392 LUA METHODS
393 ==========================================================
394 */
395
396 /* RST
397 .. attribute:: immovable_descriptions
398
399 Returns a list of all the immovables that are available in the world.
400
401 (RO) a list of :class:`LuaImmovableDescription` objects
402 */
get_immovable_descriptions(lua_State * L)403 int LuaWorld::get_immovable_descriptions(lua_State* L) {
404 const World& world = get_egbase(L).world();
405 lua_newtable(L);
406 int index = 1;
407 for (DescriptionIndex i = 0; i < world.get_nr_immovables(); ++i) {
408 lua_pushint32(L, index++);
409 to_lua<LuaMaps::LuaImmovableDescription>(
410 L, new LuaMaps::LuaImmovableDescription(world.get_immovable_descr(i)));
411 lua_settable(L, -3);
412 }
413 return 1;
414 }
415
416 /* RST
417 .. attribute:: terrain_descriptions
418
419 Returns a list of all the terrains that are available in the world.
420
421 (RO) a list of :class:`LuaTerrainDescription` objects
422 */
get_terrain_descriptions(lua_State * L)423 int LuaWorld::get_terrain_descriptions(lua_State* L) {
424 const World& world = get_egbase(L).world();
425 lua_newtable(L);
426 int index = 1;
427 for (DescriptionIndex i = 0; i < world.terrains().size(); ++i) {
428 lua_pushint32(L, index++);
429 to_lua<LuaMaps::LuaTerrainDescription>(
430 L, new LuaMaps::LuaTerrainDescription(&world.terrain_descr(i)));
431 lua_settable(L, -3);
432 }
433 return 1;
434 }
435
436 // Documented in data/world/resources/init.lua.
437 // See also the World and Tribes section in the Widelands Scripting Reference on the website.
new_resource_type(lua_State * L)438 int LuaWorld::new_resource_type(lua_State* L) {
439 if (lua_gettop(L) != 2) {
440 report_error(L, "Takes only one argument.");
441 }
442
443 try {
444 LuaTable table(L); // Will pop the table eventually.
445 get_egbase(L).mutable_world()->add_resource_type(table);
446 } catch (std::exception& e) {
447 report_error(L, "%s", e.what());
448 }
449
450 return 0;
451 }
452
453 // Documented in data/world/terrains/init.lua.
454 // See also the World and Tribes section in the Widelands Scripting Reference on the website.
new_terrain_type(lua_State * L)455 int LuaWorld::new_terrain_type(lua_State* L) {
456 if (lua_gettop(L) != 2) {
457 report_error(L, "Takes only one argument.");
458 }
459 try {
460 LuaTable table(L); // Will pop the table eventually.
461 get_egbase(L).mutable_world()->add_terrain_type(table);
462 } catch (std::exception& e) {
463 report_error(L, "%s", e.what());
464 }
465
466 return 0;
467 }
468
469 // Documented in data/world/critters/badger/init.lua.
470 // See also the World and Tribes section in the Widelands Scripting Reference on the website.
new_critter_type(lua_State * L)471 int LuaWorld::new_critter_type(lua_State* L) {
472 if (lua_gettop(L) != 2) {
473 report_error(L, "Takes only one argument.");
474 }
475 try {
476 LuaTable table(L);
477 get_egbase(L).mutable_world()->add_critter_type(table);
478 } catch (std::exception& e) {
479 report_error(L, "%s", e.what());
480 }
481 return 0;
482 }
483
484 // Documented in data/world/immovables/bush1/init.lua.
485 // See also the World and Tribes section in the Widelands Scripting Reference on the website.
new_immovable_type(lua_State * L)486 int LuaWorld::new_immovable_type(lua_State* L) {
487 if (lua_gettop(L) != 2) {
488 report_error(L, "Takes only one argument.");
489 }
490 try {
491 LuaTable table(L);
492 get_egbase(L).mutable_world()->add_immovable_type(table);
493 } catch (std::exception& e) {
494 report_error(L, "%s", e.what());
495 }
496 return 0;
497 }
498
499 // Documented in data/world/init.lua.
500 // See also the World and Tribes section in the Widelands Scripting Reference on the website.
new_editor_terrain_category(lua_State * L)501 int LuaWorld::new_editor_terrain_category(lua_State* L) {
502 if (lua_gettop(L) != 2) {
503 report_error(L, "Takes only one argument.");
504 }
505 try {
506 LuaTable table(L);
507 get_egbase(L).mutable_world()->add_editor_terrain_category(table);
508 } catch (std::exception& e) {
509 report_error(L, "%s", e.what());
510 }
511 return 0;
512 }
513
514 // Documented in data/world/init.lua.
515 // See also the World and Tribes section in the Widelands Scripting Reference on the website.
new_editor_critter_category(lua_State * L)516 int LuaWorld::new_editor_critter_category(lua_State* L) {
517 if (lua_gettop(L) != 2) {
518 report_error(L, "Takes only one argument.");
519 }
520 try {
521 LuaTable table(L);
522 get_egbase(L).mutable_world()->add_editor_critter_category(table);
523 } catch (std::exception& e) {
524 report_error(L, "%s", e.what());
525 }
526 return 0;
527 }
528
529 // Documented in data/world/init.lua.
530 // See also the World and Tribes section in the Widelands Scripting Reference on the website.
new_editor_immovable_category(lua_State * L)531 int LuaWorld::new_editor_immovable_category(lua_State* L) {
532 if (lua_gettop(L) != 2) {
533 report_error(L, "Takes only one argument.");
534 }
535 try {
536 LuaTable table(L);
537 get_egbase(L).mutable_world()->add_editor_immovable_category(table);
538 } catch (std::exception& e) {
539 report_error(L, "%s", e.what());
540 }
541 return 0;
542 }
543
544 /*
545 ==========================================================
546 C METHODS
547 ==========================================================
548 */
549
550 /* RST
551 Tribes
552 ------
553
554 .. class:: Tribes
555
556 This offers access to the objects available for the tribes and allows to add
557 new objects. See :ref:`lua_tribes` for detailed documentation.
558 */
559
560 const char LuaTribes::className[] = "Tribes";
561 const MethodType<LuaTribes> LuaTribes::Methods[] = {
562 METHOD(LuaTribes, new_carrier_type),
563 METHOD(LuaTribes, new_ferry_type),
564 METHOD(LuaTribes, new_constructionsite_type),
565 METHOD(LuaTribes, new_dismantlesite_type),
566 METHOD(LuaTribes, new_immovable_type),
567 METHOD(LuaTribes, new_market_type),
568 METHOD(LuaTribes, new_militarysite_type),
569 METHOD(LuaTribes, new_productionsite_type),
570 METHOD(LuaTribes, new_ship_type),
571 METHOD(LuaTribes, new_soldier_type),
572 METHOD(LuaTribes, new_trainingsite_type),
573 METHOD(LuaTribes, new_tribe),
574 METHOD(LuaTribes, new_ware_type),
575 METHOD(LuaTribes, new_warehouse_type),
576 METHOD(LuaTribes, new_worker_type),
577 METHOD(LuaTribes, add_custom_building),
578 METHOD(LuaTribes, add_custom_worker),
579 {0, 0},
580 };
581 const PropertyType<LuaTribes> LuaTribes::Properties[] = {
582 {0, 0, 0},
583 };
584
LuaTribes(lua_State *)585 LuaTribes::LuaTribes(lua_State* /* L */) {
586 // Nothing to do.
587 }
588
__persist(lua_State *)589 void LuaTribes::__persist(lua_State*) {
590 // Nothing to be done.
591 }
592
__unpersist(lua_State *)593 void LuaTribes::__unpersist(lua_State*) {
594 // Nothing to be done.
595 }
596
597 /*
598 ==========================================================
599 PROPERTIES
600 ==========================================================
601 */
602
603 /*
604 ==========================================================
605 LUA METHODS
606 ==========================================================
607 */
608
609 /* RST
610 .. method:: new_constructionsite_type{table}
611
612 Adds a new constructionsite building type. Takes a single argument, a table with
613 the descriptions. See :ref:`lua_tribes_buildings_constructionsites` for detailed
614 documentation.
615
616 :returns: :const:`0`
617 */
new_constructionsite_type(lua_State * L)618 int LuaTribes::new_constructionsite_type(lua_State* L) {
619 if (lua_gettop(L) != 2) {
620 report_error(L, "Takes only one argument.");
621 }
622
623 try {
624 LuaTable table(L); // Will pop the table eventually.
625 get_egbase(L).mutable_tribes()->add_constructionsite_type(table);
626 } catch (std::exception& e) {
627 report_error(L, "%s", e.what());
628 }
629 return 0;
630 }
631
632 /* RST
633 .. method:: new_dismantlesite_type{table}
634
635 Adds a new disnamtlesite building type. Takes a single argument, a table with
636 the descriptions. See :ref:`lua_tribes_buildings_dismantlesites` for detailed
637 documentation.
638
639 :returns: :const:`0`
640 */
new_dismantlesite_type(lua_State * L)641 int LuaTribes::new_dismantlesite_type(lua_State* L) {
642 if (lua_gettop(L) != 2) {
643 report_error(L, "Takes only one argument.");
644 }
645
646 try {
647 LuaTable table(L); // Will pop the table eventually.
648 get_egbase(L).mutable_tribes()->add_dismantlesite_type(table);
649 } catch (std::exception& e) {
650 report_error(L, "%s", e.what());
651 }
652 return 0;
653 }
654
655 /* RST
656 .. method:: new_militarysite_type{table}
657
658 Adds a new militarysite building type. Takes a single argument, a table with
659 the descriptions. See :ref:`lua_tribes_buildings_militarysites` for detailed
660 documentation.
661
662 :returns: :const:`0`
663 */
new_militarysite_type(lua_State * L)664 int LuaTribes::new_militarysite_type(lua_State* L) {
665 if (lua_gettop(L) != 2) {
666 report_error(L, "Takes only one argument.");
667 }
668
669 try {
670 LuaTable table(L); // Will pop the table eventually.
671 get_egbase(L).mutable_tribes()->add_militarysite_type(table);
672 } catch (std::exception& e) {
673 report_error(L, "%s", e.what());
674 }
675 return 0;
676 }
677
678 /* RST
679 .. method:: new_productionsite_type{table}
680
681 Adds a new productionsite building type. Takes a single argument, a table with
682 the descriptions. See :ref:`lua_tribes_buildings_productionsites` for detailed
683 documentation.
684
685 :returns: :const:`0`
686 */
new_productionsite_type(lua_State * L)687 int LuaTribes::new_productionsite_type(lua_State* L) {
688 if (lua_gettop(L) != 2) {
689 report_error(L, "Takes only one argument.");
690 }
691
692 try {
693 LuaTable table(L); // Will pop the table eventually.
694 EditorGameBase& egbase = get_egbase(L);
695 egbase.mutable_tribes()->add_productionsite_type(table, egbase.world());
696 } catch (std::exception& e) {
697 report_error(L, "%s", e.what());
698 }
699 return 0;
700 }
701
702 /* RST
703 .. method:: new_trainingsite_type{table}
704
705 Adds a new trainingsite building type. Takes a single argument, a table with
706 the descriptions. See :ref:`lua_tribes_buildings_trainingsites` for detailed
707 documentation.
708
709 :returns: :const:`0`
710 */
new_trainingsite_type(lua_State * L)711 int LuaTribes::new_trainingsite_type(lua_State* L) {
712 if (lua_gettop(L) != 2) {
713 report_error(L, "Takes only one argument.");
714 }
715
716 try {
717 LuaTable table(L); // Will pop the table eventually.
718 EditorGameBase& egbase = get_egbase(L);
719 egbase.mutable_tribes()->add_trainingsite_type(table, egbase.world());
720 } catch (std::exception& e) {
721 report_error(L, "%s", e.what());
722 }
723 return 0;
724 }
725
726 /* RST
727 .. method:: new_warehouse_type{table}
728
729 Adds a new warehouse building type. Takes a single argument, a table with
730 the descriptions. See :ref:`lua_tribes_buildings_warehouses` for detailed
731 documentation.
732
733 :returns: :const:`0`
734 */
new_warehouse_type(lua_State * L)735 int LuaTribes::new_warehouse_type(lua_State* L) {
736 if (lua_gettop(L) != 2) {
737 report_error(L, "Takes only one argument.");
738 }
739
740 try {
741 LuaTable table(L); // Will pop the table eventually.
742 get_egbase(L).mutable_tribes()->add_warehouse_type(table);
743 } catch (std::exception& e) {
744 report_error(L, "%s", e.what());
745 }
746 return 0;
747 }
748
749 // TODO(GunChleoc): add RST marker
750 /*
751 .. method:: new_market_type{table}
752
753 Adds a new market building type. Takes a single argument, a table with
754 the descriptions. See :ref:`lua_tribes_buildings_markets` for detailed
755 documentation.
756
757 :returns: :const:`0`
758 */
new_market_type(lua_State * L)759 int LuaTribes::new_market_type(lua_State* L) {
760 if (lua_gettop(L) != 2) {
761 report_error(L, "Takes only one argument.");
762 }
763
764 try {
765 LuaTable table(L); // Will pop the table eventually.
766 get_egbase(L).mutable_tribes()->add_market_type(table);
767 } catch (std::exception& e) {
768 report_error(L, "%s", e.what());
769 }
770 return 0;
771 }
772
773 /* RST
774 .. method:: new_immovable_type{table}
775
776 Adds a new immovable type. Takes a single argument, a table with
777 the descriptions. See :ref:`lua_tribes_immovables` for detailed
778 documentation.
779
780 :returns: :const:`0`
781 */
new_immovable_type(lua_State * L)782 int LuaTribes::new_immovable_type(lua_State* L) {
783 if (lua_gettop(L) != 2) {
784 report_error(L, "Takes only one argument.");
785 }
786
787 try {
788 LuaTable table(L); // Will pop the table eventually.
789 get_egbase(L).mutable_tribes()->add_immovable_type(table);
790 } catch (std::exception& e) {
791 report_error(L, "%s", e.what());
792 }
793 return 0;
794 }
795
796 /* RST
797 .. method:: new_ship_type{table}
798
799 Adds a new ship type. Takes a single argument, a table with
800 the descriptions. See :ref:`lua_tribes_ships` for detailed
801 documentation.
802
803 :returns: :const:`0`
804 */
new_ship_type(lua_State * L)805 int LuaTribes::new_ship_type(lua_State* L) {
806 if (lua_gettop(L) != 2) {
807 report_error(L, "Takes only one argument.");
808 }
809
810 try {
811 LuaTable table(L); // Will pop the table eventually.
812 get_egbase(L).mutable_tribes()->add_ship_type(table);
813 } catch (std::exception& e) {
814 report_error(L, "%s", e.what());
815 }
816 return 0;
817 }
818
819 /* RST
820 .. method:: new_ware_type{table}
821
822 Adds a new ware type. Takes a single argument, a table with
823 the descriptions. See :ref:`lua_tribes_wares` for detailed
824 documentation.
825
826 :returns: :const:`0`
827 */
new_ware_type(lua_State * L)828 int LuaTribes::new_ware_type(lua_State* L) {
829 if (lua_gettop(L) != 2) {
830 report_error(L, "Takes only one argument.");
831 }
832
833 try {
834 LuaTable table(L); // Will pop the table eventually.
835 get_egbase(L).mutable_tribes()->add_ware_type(table);
836 } catch (std::exception& e) {
837 report_error(L, "%s", e.what());
838 }
839 return 0;
840 }
841
842 /* RST
843 .. method:: new_carrier_type{table}
844
845 Adds a new carrier worker type. Takes a single argument, a table with
846 the descriptions. See the files in tribes/ for usage examples.
847
848 :returns: :const:`nil`
849 */
new_carrier_type(lua_State * L)850 int LuaTribes::new_carrier_type(lua_State* L) {
851 if (lua_gettop(L) != 2) {
852 report_error(L, "Takes only one argument.");
853 }
854
855 try {
856 LuaTable table(L); // Will pop the table eventually.
857 get_egbase(L).mutable_tribes()->add_carrier_type(table);
858 } catch (std::exception& e) {
859 report_error(L, "%s", e.what());
860 }
861 return 0;
862 }
863
864 /* RST
865 .. method:: new_ferry_type{table}
866
867 Adds a new ferry worker type. Takes a single argument, a table with
868 the descriptions. See the files in tribes/ for usage examples.
869
870 :returns: :const:`nil`
871 */
new_ferry_type(lua_State * L)872 int LuaTribes::new_ferry_type(lua_State* L) {
873 if (lua_gettop(L) != 2) {
874 report_error(L, "Takes only one argument.");
875 }
876
877 try {
878 LuaTable table(L); // Will pop the table eventually.
879 EditorGameBase& egbase = get_egbase(L);
880 egbase.mutable_tribes()->add_ferry_type(table);
881 } catch (std::exception& e) {
882 report_error(L, "%s", e.what());
883 }
884 return 0;
885 }
886
887 /* RST
888 .. method:: new_soldier_type{table}
889
890 Adds a new soldier worker type. Takes a single argument, a table with
891 the descriptions. See the files in tribes/ for usage examples.
892
893 :returns: :const:`nil`
894 */
new_soldier_type(lua_State * L)895 int LuaTribes::new_soldier_type(lua_State* L) {
896 if (lua_gettop(L) != 2) {
897 report_error(L, "Takes only one argument.");
898 }
899
900 try {
901 LuaTable table(L); // Will pop the table eventually.
902 get_egbase(L).mutable_tribes()->add_soldier_type(table);
903 } catch (std::exception& e) {
904 report_error(L, "%s", e.what());
905 }
906 return 0;
907 }
908
909 /* RST
910 .. method:: new_worker_type{table}
911
912 Adds a new worker type. Takes a single argument, a table with
913 the descriptions. See the files in tribes/ for usage examples.
914
915 :returns: :const:`nil`
916 */
new_worker_type(lua_State * L)917 int LuaTribes::new_worker_type(lua_State* L) {
918 if (lua_gettop(L) != 2) {
919 report_error(L, "Takes only one argument.");
920 }
921
922 try {
923 LuaTable table(L); // Will pop the table eventually.
924 get_egbase(L).mutable_tribes()->add_worker_type(table);
925 } catch (std::exception& e) {
926 report_error(L, "%s", e.what());
927 }
928 return 0;
929 }
930
931 /* RST
932 .. method:: new_tribe{table}
933
934 Adds a new tribe. Takes a single argument, a table with
935 the descriptions. See :ref:`lua_tribes_<tribename>.lua` for detailed
936 documentation.
937
938 :returns: :const:`0`
939 */
new_tribe(lua_State * L)940 int LuaTribes::new_tribe(lua_State* L) {
941 if (lua_gettop(L) != 2) {
942 report_error(L, "Takes only one argument.");
943 }
944
945 try {
946 LuaTable table(L); // Will pop the table eventually.
947 get_egbase(L).mutable_tribes()->add_tribe(table);
948 } catch (std::exception& e) {
949 report_error(L, "%s", e.what());
950 }
951 return 0;
952 }
953
954 /* RST
955 .. method:: add_custom_building{table}
956
957 Adds a custom building to a tribe, e.g. for use in a scenario.
958 The building must already be known to the tribes and should be defined in
959 the ``map:scripting/tribes/`` directory.
960
961 **Note:** This function *has* to be called from ``map:scripting/tribes/init.lua``.
962
963 The table has the following entries:
964
965 **tribename**
966 *Mandatory*. The name of the tribe that this building will be added to.
967
968 **buildingname**
969 *Mandatory*. The name of the building to be added to the tribe.
970
971 :returns: :const:`0`
972 */
add_custom_building(lua_State * L)973 int LuaTribes::add_custom_building(lua_State* L) {
974 if (lua_gettop(L) != 2) {
975 report_error(L, "Takes only one argument.");
976 }
977
978 try {
979 LuaTable table(L); // Will pop the table eventually.
980 EditorGameBase& egbase = get_egbase(L);
981 egbase.mutable_tribes()->add_custom_building(table);
982 } catch (std::exception& e) {
983 report_error(L, "%s", e.what());
984 }
985 return 0;
986 }
987
988 /* RST
989 .. method:: add_custom_worker{table}
990
991 Adds a worker building to a tribe, e.g. for use in a scenario.
992 The worker must already be known to the tribes and should be defined in
993 the ``map:scripting/tribes/`` directory.
994
995 **Note:** This function *has* to be called from ``map:scripting/tribes/init.lua``.
996
997 The table has the following entries:
998
999 **tribename**
1000 *Mandatory*. The name of the tribe that this worker will be added to.
1001
1002 **workername**
1003 *Mandatory*. The name of the worker to be added to the tribe.
1004
1005 :returns: :const:`0`
1006 */
add_custom_worker(lua_State * L)1007 int LuaTribes::add_custom_worker(lua_State* L) {
1008 if (lua_gettop(L) != 2) {
1009 report_error(L, "Takes only one argument.");
1010 }
1011
1012 try {
1013 LuaTable table(L); // Will pop the table eventually.
1014 EditorGameBase& egbase = get_egbase(L);
1015 egbase.mutable_tribes()->add_custom_worker(table);
1016 } catch (std::exception& e) {
1017 report_error(L, "%s", e.what());
1018 }
1019 return 0;
1020 }
1021
1022 /*
1023 ==========================================================
1024 C METHODS
1025 ==========================================================
1026 */
1027
1028 const static struct luaL_Reg wlroot[] = {{nullptr, nullptr}};
1029
luaopen_wlroot(lua_State * L,bool in_editor)1030 void luaopen_wlroot(lua_State* L, bool in_editor) {
1031 lua_getglobal(L, "wl"); // S: wl
1032 luaL_setfuncs(L, wlroot, 0); // S: wl
1033 lua_pop(L, 1); // S:
1034
1035 if (in_editor) {
1036 register_class<LuaEditor>(L, "", true);
1037 add_parent<LuaEditor, LuaBases::LuaEditorGameBase>(L);
1038 lua_pop(L, 1); // Pop the meta table
1039 } else {
1040 register_class<LuaGame>(L, "", true);
1041 add_parent<LuaGame, LuaBases::LuaEditorGameBase>(L);
1042 lua_pop(L, 1); // Pop the meta table
1043 }
1044 register_class<LuaWorld>(L, "", false);
1045 register_class<LuaTribes>(L, "", false);
1046 }
1047 } // namespace LuaRoot
1048