The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
game_lua_kernel.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2016 by Guillaume Melquiond <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Provides a Lua interpreter, to be embedded in WML.
18  *
19  * @note Naming conventions:
20  * - intf_ functions are exported in the wesnoth domain,
21  * - impl_ functions are hidden inside metatables,
22  * - cfun_ functions are closures,
23  * - luaW_ functions are helpers in Lua style.
24  */
25 
27 
28 #include "global.hpp"
29 
30 #include "actions/attack.hpp" // for battle_context_unit_stats, etc
31 #include "actions/move.hpp" // for clear_shroud
32 #include "actions/vision.hpp" // for clear_shroud
33 #include "ai/composite/ai.hpp" // for ai_composite
34 #include "ai/composite/component.hpp" // for component, etc
35 #include "ai/composite/contexts.hpp" // for ai_context
36 #include "ai/lua/engine_lua.hpp" // for engine_lua
37 #include "ai/composite/rca.hpp" // for candidate_action
38 #include "ai/composite/stage.hpp" // for stage
39 #include "ai/configuration.hpp" // for configuration
40 #include "ai/lua/core.hpp" // for lua_ai_context, etc
41 #include "ai/manager.hpp" // for manager, holder
42 #include "attack_prediction.hpp" // for combatant
43 #include "chat_events.hpp" // for chat_handler, etc
44 #include "config.hpp" // for config, etc
45 #include "display_chat_manager.hpp" // for clear_chat_messages
46 #include "formatter.hpp"
47 #include "game_board.hpp" // for game_board
48 #include "game_classification.hpp" // for game_classification, etc
49 #include "game_config.hpp" // for debug, base_income, etc
50 #include "game_config_manager.hpp" // for game_config_manager
51 #include "game_data.hpp" // for game_data, etc
52 #include "game_display.hpp" // for game_display
53 #include "game_errors.hpp" // for game_error
54 #include "game_events/conditional_wml.hpp" // for conditional_passed
56 #include "game_events/manager.hpp" // for add_event_handler
57 #include "game_events/pump.hpp" // for queued_event
58 #include "game_preferences.hpp" // for encountered_units
59 #include "help/help.hpp"
60 #include "image.hpp" // for get_image, locator
61 #include "log.hpp" // for LOG_STREAM, logger, etc
62 #include "utils/make_enum.hpp" // for operator<<
63 #include "map/map.hpp" // for gamemap
64 #include "map/label.hpp"
65 #include "map/location.hpp" // for map_location
66 #include "mouse_events.hpp" // for mouse_handler
67 #include "mp_game_settings.hpp" // for mp_game_settings
68 #include "pathfind/pathfind.hpp" // for full_cost_map, plain_route, etc
69 #include "pathfind/teleport.hpp" // for get_teleport_locations, etc
70 #include "play_controller.hpp" // for play_controller
71 #include "recall_list_manager.hpp" // for recall_list_manager
72 #include "replay.hpp" // for get_user_choice, etc
73 #include "reports.hpp" // for register_generator, etc
74 #include "scripting/lua_api.hpp" // for luaW_toboolean, etc
75 #include "scripting/lua_common.hpp"
77 #include "scripting/lua_gui2.hpp" // for show_gamestate_inspector
79 #include "scripting/lua_race.hpp"
80 #include "scripting/lua_team.hpp"
81 #include "scripting/lua_types.hpp" // for getunitKey, dlgclbkKey, etc
83 #include "scripting/push_check.hpp"
84 #include "sdl/utils.hpp" // for surface
85 #include "side_filter.hpp" // for side_filter
86 #include "sound.hpp" // for commit_music_changes, etc
87 #include "soundsource.hpp"
88 #include "synced_context.hpp" // for synced_context, etc
89 #include "synced_user_choice.hpp"
90 #include "team.hpp" // for team, village_owner
91 #include "terrain/terrain.hpp" // for terrain_type
92 #include "terrain/filter.hpp" // for terrain_filter
93 #include "terrain/translation.hpp" // for read_terrain_code, etc
94 #include "terrain/type_data.hpp"
95 #include "time_of_day.hpp" // for time_of_day, tod_color
96 #include "tod_manager.hpp" // for tod_manager
97 #include "tstring.hpp" // for t_string, operator+
98 #include "units/unit.hpp" // for unit, intrusive_ptr_add_ref, etc
99 #include "units/animation_component.hpp" // for unit_animation_component
100 #include "units/udisplay.hpp"
101 #include "units/filter.hpp"
102 #include "units/map.hpp" // for unit_map, etc
103 #include "units/ptr.hpp" // for unit_const_ptr, unit_ptr
104 #include "units/types.hpp" // for unit_type_data, unit_types, etc
105 #include "util.hpp" // for lexical_cast
106 #include "variable.hpp" // for vconfig, etc
107 #include "variable_info.hpp"
108 #include "wml_exception.hpp"
109 
110 #include "utils/functional.hpp" // for bind_t, bind
111 #include <boost/intrusive_ptr.hpp> // for intrusive_ptr
112 #include <boost/optional.hpp>
113 #include <boost/range/algorithm/copy.hpp> // boost::copy
114 #include <boost/range/adaptors.hpp> // boost::adaptors::filtered
115 #include <boost/tuple/tuple.hpp> // for tuple
116 #include <cassert> // for assert
117 #include <cstring> // for strcmp
118 #include <iterator> // for distance, advance
119 #include <map> // for map, map<>::value_type, etc
120 #include <new> // for operator new
121 #include <set> // for set
122 #include <sstream> // for operator<<, basic_ostream, etc
123 #include <utility> // for pair
124 #include <algorithm>
125 #include <vector> // for vector, etc
126 #include <SDL_timer.h> // for SDL_GetTicks
127 #include <SDL_video.h> // for SDL_Color, SDL_Surface
128 #include "lua/lauxlib.h" // for luaL_checkinteger, etc
129 #include "lua/lua.h" // for lua_setfield, etc
130 
131 class CVideo;
132 
133 #ifdef DEBUG_LUA
134 #include "scripting/debug_lua.hpp"
135 #endif
136 
137 // Suppress uninitialized variables warnings, because of boost::optional constructors in this file which apparently confuses gcc
138 #if defined(__GNUC__) && !defined(__clang__) // we shouldn't need this for clang, but for gcc and tdm-gcc we probably do
139 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) // "GCC diagnostic ignored" is apparently not available at version 4.5.2
140 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
141 #endif
142 #endif
143 
144 static lg::log_domain log_scripting_lua("scripting/lua");
145 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
146 #define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
147 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
148 
149 std::vector<config> game_lua_kernel::preload_scripts;
151 
153 {
154  map_locker(game_lua_kernel* kernel) : kernel_(kernel)
155  {
156  ++kernel_->map_locked_;
157  }
159  {
160  --kernel_->map_locked_;
161  }
163 };
164 
165 
167 {
168  game_lua_kernel::preload_scripts.clear();
169  for (config const &cfg : game_config.child_range("lua")) {
170  game_lua_kernel::preload_scripts.push_back(cfg);
171  }
172  game_lua_kernel::preload_config = game_config.child("game_config");
173 }
174 
175 void game_lua_kernel::log_error(char const * msg, char const * context)
176 {
177  lua_kernel_base::log_error(msg, context);
178  lua_chat(context, msg);
179 }
180 
182 {
183  if (game_display_) {
184  game_display_->get_chat_manager().add_chat_message(time(nullptr), caption, 0, msg,
186  }
187 }
188 
189 /**
190  * Gets a vector of sides from side= attribute in a given config node.
191  * Promotes consistent behavior.
192  */
193 std::vector<int> game_lua_kernel::get_sides_vector(const vconfig& cfg)
194 {
195  const config::attribute_value sides = cfg["side"];
196  const vconfig &ssf = cfg.child("filter_side");
197 
198  if (!ssf.null()) {
199  if(!sides.empty()) { WRN_LUA << "ignoring duplicate side filter information (inline side=)" << std::endl; }
201  return filter.get_teams();
202  }
203 
204  side_filter filter(sides.str(), &game_state_);
205  return filter.get_teams();
206 }
207 
208 
209 
211 {
212  lua_pushnumber(L, lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).map().special_locations().size());
213  return 1;
214 }
215 
217 {
218  const t_translation::tstarting_positions::left_map& left = lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).map().special_locations().left;
219 
220  t_translation::tstarting_positions::left_const_iterator it;
221  if (lua_isnoneornil(L, 2)) {
222  it = left.begin();
223  }
224  else {
225  it = left.find(luaL_checkstring(L, 2));
226  if (it == left.end()) {
227  return 0;
228  }
229  ++it;
230  }
231  if (it == left.end()) {
232  return 0;
233  }
234  lua_pushstring(L, it->first.c_str());
235  lua_createtable(L, 2, 0);
236  lua_pushnumber(L, it->second.x + 1);
237  lua_rawseti(L, -2, 1);
238  lua_pushnumber(L, it->second.y + 1);
239  lua_rawseti(L, -2, 2);
240  return 2;
241 }
242 
244 {
246  lua_pushvalue(L, -2);
247  lua_pushnil(L);
248  return 3;
249 }
250 
252 {
253  const t_translation::tstarting_positions::left_map& left = lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).map().special_locations().left;
254  auto it = left.find(luaL_checkstring(L, 2));
255  if (it == left.end()) {
256  return 0;
257  }
258  else {
259  lua_createtable(L, 2, 0);
260  lua_pushnumber(L, it->second.x + 1);
261  lua_rawseti(L, -2, 1);
262  lua_pushnumber(L, it->second.y + 1);
263  lua_rawseti(L, -2, 2);
264  return 1;
265  }
266 }
267 
269 {
270  lua_pushstring(L, "special locations cannot be modified uwing wesnoth.special_locations");
271  return lua_error(L);
272 }
273 
275 {
276  lua_newtable(L); // The functor table
277  lua_newtable(L); // The functor metatable
278  lua_pushstring(L, "__len");
280  lua_rawset(L, -3);
281  lua_pushstring(L, "__index");
283  lua_rawset(L, -3);
284  lua_pushstring(L, "__newindex");
286  lua_rawset(L, -3);
287  lua_pushstring(L, "__pairs");
289  lua_rawset(L, -3);
290  lua_setmetatable(L, -2); // Apply the metatable to the functor table
291 }
292 
293 namespace {
294  /**
295  * Temporary entry to a queued_event stack
296  */
297  struct queued_event_context
298  {
299  typedef game_events::queued_event qe;
300  std::stack<qe const *> & stack_;
301 
302  queued_event_context(qe const *new_qe, std::stack<qe const*> & stack)
303  : stack_(stack)
304  {
305  stack_.push(new_qe);
306  }
307 
308  ~queued_event_context()
309  {
310  stack_.pop();
311  }
312  };
313 }//unnamed namespace for queued_event_context
314 
315 /**
316  * Destroys a unit object before it is collected (__gc metamethod).
317  */
319 {
320  lua_unit *u = static_cast<lua_unit *>(lua_touserdata(L, 1));
321  u->lua_unit::~lua_unit();
322  return 0;
323 }
324 
325 /**
326  * Checks two lua proxy units for equality. (__eq metamethod)
327  */
329 {
330  unit& left = luaW_checkunit(L, 1);
331  unit& right = luaW_checkunit(L, 2);
332  const bool equal = left.underlying_id() == right.underlying_id();
333  lua_pushboolean(L, equal);
334  return 1;
335 }
336 
337 /**
338  * Gets some data on a unit (__index metamethod).
339  * - Arg 1: full userdata containing the unit id.
340  * - Arg 2: string containing the name of the property.
341  * - Ret 1: something containing the attribute.
342  */
343 static int impl_unit_get(lua_State *L)
344 {
345  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
346  char const *m = luaL_checkstring(L, 2);
347  const unit* pu = lu->get();
348 
349  if (strcmp(m, "valid") == 0)
350  {
351  if (!pu) return 0;
352  if (lu->on_map())
353  lua_pushstring(L, "map");
354  else if (lu->on_recall_list())
355  lua_pushstring(L, "recall");
356  else
357  lua_pushstring(L, "private");
358  return 1;
359  }
360 
361  if (!pu) return luaL_argerror(L, 1, "unknown unit");
362  unit const &u = *pu;
363 
364  // Find the corresponding attribute.
365  return_int_attrib("x", u.get_location().x + 1);
366  return_int_attrib("y", u.get_location().y + 1);
367  if (strcmp(m, "loc") == 0) {
368  lua_pushinteger(L, u.get_location().x + 1);
369  lua_pushinteger(L, u.get_location().y + 1);
370  return 2;
371  }
372  return_int_attrib("side", u.side());
373  return_string_attrib("id", u.id());
374  return_string_attrib("type", u.type_id());
375  return_string_attrib("image_mods", u.effect_image_mods());
376  return_string_attrib("usage", u.usage());
377  return_int_attrib("hitpoints", u.hitpoints());
378  return_int_attrib("max_hitpoints", u.max_hitpoints());
379  return_int_attrib("experience", u.experience());
380  return_int_attrib("max_experience", u.max_experience());
381  return_int_attrib("recall_cost", u.recall_cost());
382  return_int_attrib("moves", u.movement_left());
383  return_int_attrib("max_moves", u.total_movement());
384  return_int_attrib("max_attacks", u.max_attacks());
385  return_int_attrib("attacks_left", u.attacks_left());
386  return_tstring_attrib("name", u.name());
387  return_bool_attrib("canrecruit", u.can_recruit());
388  return_int_attrib("level", u.level());
389  return_int_attrib("cost", u.cost());
390 
391  return_vector_string_attrib("extra_recruit", u.recruits());
392  return_vector_string_attrib("advances_to", u.advances_to());
393 
394  if (strcmp(m, "alignment") == 0) {
395  lua_push(L, u.alignment());
396  return 1;
397  }
398 
399  if (strcmp(m, "upkeep") == 0) {
400  unit::t_upkeep upkeep = u.upkeep_raw();
401  if(boost::get<unit::upkeep_full>(&upkeep) != nullptr){
402  lua_pushstring(L, "full");
403  }
404  else if(boost::get<unit::upkeep_loyal>(&upkeep) != nullptr){
405  lua_pushstring(L, "loyal");
406  }
407  else {
408  lua_push(L, boost::get<int>(upkeep));
409  }
410  return 1;
411  }
412  if (strcmp(m, "advancements") == 0) {
414  return 1;
415  }
416  if (strcmp(m, "overlays") == 0) {
417  lua_push(L, u.overlays());
418  return 1;
419  }
420  if (strcmp(m, "traits") == 0) {
421  lua_push(L, u.get_traits_list());
422  return 1;
423  }
424  if (strcmp(m, "abilities") == 0) {
425  lua_push(L, u.get_ability_list());
426  return 1;
427  }
428  if (strcmp(m, "status") == 0) {
429  lua_createtable(L, 1, 0);
430  lua_pushvalue(L, 1);
431  lua_rawseti(L, -2, 1);
433  , ustatusKey);
435  lua_setmetatable(L, -2);
436  return 1;
437  }
438  if (strcmp(m, "variables") == 0) {
439  lua_createtable(L, 1, 0);
440  lua_pushvalue(L, 1);
441  lua_rawseti(L, -2, 1);
443  , unitvarKey);
445  lua_setmetatable(L, -2);
446  return 1;
447  }
448  if (strcmp(m, "attacks") == 0) {
449  lua_createtable(L, 1, 0);
450  lua_pushvalue(L, 1);
451  // hack: store the unit at -1 becasue we want positive indexes to refers to the attacks.
452  lua_rawseti(L, -2, -1);
455  lua_setmetatable(L, -2);
456  return 1;
457  }
458  return_bool_attrib("hidden", u.get_hidden());
459  return_bool_attrib("petrified", u.incapacitated());
460  return_bool_attrib("resting", u.resting());
461  return_string_attrib("role", u.get_role());
462  return_string_attrib("race", u.race()->id());
463  return_string_attrib("gender", gender_string(u.gender()));
464  return_string_attrib("variation", u.variation());
465  return_bool_attrib("zoc", u.get_emit_zoc());
467  return_string_attrib("portrait", u.big_profile() == u.absolute_image() ? u.absolute_image() + u.image_mods() : u.big_profile());
468  return_cfg_attrib("__cfg", u.write(cfg); u.get_location().write(cfg));
469 
470  return lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).return_unit_method(L, m);
471 }
472 
473 /**
474  * Sets some data on a unit (__newindex metamethod).
475  * - Arg 1: full userdata containing the unit id.
476  * - Arg 2: string containing the name of the property.
477  * - Arg 3: something containing the attribute.
478  */
479 static int impl_unit_set(lua_State *L)
480 {
481  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
482  char const *m = luaL_checkstring(L, 2);
483  unit* pu = lu->get();
484  if (!pu) return luaL_argerror(L, 1, "unknown unit");
485  unit &u = *pu;
486 
487  // Find the corresponding attribute.
488  //modify_int_attrib_check_range("side", u.set_side(value), 1, static_cast<int>(teams().size())); TODO: Figure out if this is a good idea, to refer to teams() and make this depend on having a gamestate
489  modify_int_attrib("side", u.set_side(value));
490  modify_int_attrib("moves", u.set_movement(value));
491  modify_int_attrib("hitpoints", u.set_hitpoints(value));
492  modify_int_attrib("experience", u.set_experience(value));
493  modify_int_attrib("recall_cost", u.set_recall_cost(value));
494  modify_int_attrib("attacks_left", u.set_attacks(value));
495  modify_int_attrib("level", u.set_level(value));
496  modify_bool_attrib("resting", u.set_resting(value));
498  modify_string_attrib("role", u.set_role(value));
500  modify_bool_attrib("hidden", u.set_hidden(value));
502  modify_bool_attrib("canrecruit", u.set_can_recruit(value));
503 
504  modify_vector_string_attrib("extra_recruit", u.set_recruits(vector));
505  modify_vector_string_attrib("advances_to", u.set_advances_to(vector));
506  if (strcmp(m, "alignment") == 0) {
507  u.set_alignment(lua_check<unit_type::ALIGNMENT>(L, 3));
508  return 0;
509  }
510 
511 
512  if (strcmp(m, "advancements") == 0) {
513  u.set_advancements(lua_check<std::vector<config> >(L, 3));
514  return 0;
515  }
516 
517  if (strcmp(m, "upkeep") == 0) {
518  if(lua_isnumber(L, 3)) {
519  u.set_upkeep(luaL_checkint(L, 3));
520  return 0;
521  }
522  const char* v = luaL_checkstring(L, 3);
523  if(strcmp(m, "loyal") == 0) {
525  }
526  else if(strcmp(m, "full") == 0) {
528  }
529  else {
530 
531  std::string err_msg = "unknown upkeep value of unit: ";
532  err_msg += v;
533  return luaL_argerror(L, 2, err_msg.c_str());
534  }
535  return 0;
536  }
537  if (!lu->on_map()) {
538  map_location loc = u.get_location();
539  modify_int_attrib("x", loc.x = value - 1; u.set_location(loc));
540  modify_int_attrib("y", loc.y = value - 1; u.set_location(loc));
541  }
542 
543  std::string err_msg = "unknown modifiable property of unit: ";
544  err_msg += m;
545  return luaL_argerror(L, 2, err_msg.c_str());
546 }
547 
548 /**
549  * Gets the status of a unit (__index metamethod).
550  * - Arg 1: table containing the userdata containing the unit id.
551  * - Arg 2: string containing the name of the status.
552  * - Ret 1: boolean.
553  */
555 {
556  if (!lua_istable(L, 1))
557  return luaL_typerror(L, 1, "unit status");
558  lua_rawgeti(L, 1, 1);
559  const unit* u = luaW_tounit(L, -1);
560  if (!u) return luaL_argerror(L, 1, "unknown unit");
561  char const *m = luaL_checkstring(L, 2);
562  lua_pushboolean(L, u->get_state(m));
563  return 1;
564 }
565 
566 /**
567  * Sets the status of a unit (__newindex metamethod).
568  * - Arg 1: table containing the userdata containing the unit id.
569  * - Arg 2: string containing the name of the status.
570  * - Arg 3: boolean.
571  */
573 {
574  if (!lua_istable(L, 1))
575  return luaL_typerror(L, 1, "unit status");
576  lua_rawgeti(L, 1, 1);
577  unit* u = luaW_tounit(L, -1);
578  if (!u) return luaL_argerror(L, 1, "unknown unit");
579  char const *m = luaL_checkstring(L, 2);
580  u->set_state(m, luaW_toboolean(L, 3));
581  return 0;
582 }
583 
584 /**
585  * Gets the variable of a unit (__index metamethod).
586  * - Arg 1: table containing the userdata containing the unit id.
587  * - Arg 2: string containing the name of the status.
588  * - Ret 1: boolean.
589  */
591 {
592  if (!lua_istable(L, 1))
593  return luaL_typerror(L, 1, "unit variables");
594  lua_rawgeti(L, 1, 1);
595  const unit* u = luaW_tounit(L, -1);
596  if (!u) return luaL_argerror(L, 1, "unknown unit");
597  char const *m = luaL_checkstring(L, 2);
598  return_cfgref_attrib("__cfg", u->variables());
599 
601  return luaW_pushvariable(L, v) ? 1 : 0;
602 }
603 /**
604  * Gets the attacks of a unit or unit type (__index metamethod).
605  * - Arg 1: table containing the userdata containing the unit or unit type.
606  * - Arg 2: index (int) or id (string) identifying a particular attack.
607  * - Ret 1: the unit's attacks.
608  */
610 {
611  if (!lua_istable(L, 1)) {
612  return luaL_typerror(L, 1, "unit attacks");
613  }
614  lua_rawgeti(L, 1, -1);
615  const unit* u = luaW_tounit(L, -1);
616  const unit_type* ut = static_cast<const unit_type*>(luaL_testudata(L, -1, "unit type"));
617  if (!u && !ut) {
618  return luaL_argerror(L, 1, "unknown unit");
619  }
620  const attack_type* attack = nullptr;
621  const std::vector<attack_type>& attacks = u ? u->attacks() : ut->attacks();
622  if(!lua_isnumber(L,2)) {
623  std::string attack_id = luaL_checkstring(L, 2);
624  for (const attack_type& at : attacks) {
625  if(at.id() == attack_id) {
626  attack = &at;
627  break;
628  }
629  }
630  if (attack == nullptr) {
631  //return nil on invalid index, just like lua tables do.
632  return 0;
633  }
634  }
635  else
636  {
637  //
638  size_t index = luaL_checkinteger(L, 2) - 1;
639  if (index >= attacks.size()) {
640  //return nil on invalid index, just like lua tables do.
641  return 0;
642  }
643  attack = &attacks[index];
644  }
645 
646  // stack { lua_unit }, id/index, lua_unit
647  lua_createtable(L, 2, 0);
648  // stack { lua_unit }, id/index, lua_unit, table
649  lua_pushvalue(L, -2);
650  // stack { lua_unit }, id/index, lua_unit, table, lua_unit
651  lua_rawseti(L, -2, 1);
652  // stack { lua_unit }, id/index, lua_unit, table
653  lua_pushstring(L, attack->id().c_str());
654  // stack { lua_unit }, id/index, lua_unit, table, attack id
655  lua_rawseti(L, -2, 2);
656  // stack { lua_unit }, id/index, lua_unit, table
659  lua_setmetatable(L, -2);
660  return 1;
661 }
662 
663 /**
664  * Counts the attacks of a unit (__len metamethod).
665  * - Arg 1: table containing the userdata containing the unit id.
666  * - Ret 1: size of unit attacks vector.
667  */
669 {
670  if (!lua_istable(L, 1)) {
671  return luaL_typerror(L, 1, "unit attacks");
672  }
673  lua_rawgeti(L, 1, -1);
674  const unit* u = luaW_tounit(L, -1);
675  if (!u) {
676  return luaL_argerror(L, 1, "unknown unit");
677  }
678  lua_pushinteger(L, u->attacks().size());
679  return 1;
680 }
681 
682 /**
683  * Gets a propoerty of a units attack (__index metamethod).
684  * - Arg 1: table containing the userdata containing the unit id. and a string identyfying the attack.
685  * - Arg 2: string
686  * - Ret 1:
687  */
689 {
690  if (!lua_istable(L, 1)) {
691  return luaL_typerror(L, 1, "unit attack");
692  }
693  lua_rawgeti(L, 1, 1);
694  const unit* u = luaW_tounit(L, -1);
695  if (!u) {
696  return luaL_argerror(L, 1, "unknown unit");
697  }
698  lua_rawgeti(L, 1, 2);
699  std::string attack_id = luaL_checkstring(L, -1);
700  char const *m = luaL_checkstring(L, 2);
701  for (const attack_type& attack : u->attacks())
702  {
703  if(attack.id() == attack_id)
704  {
705 
706  return_string_attrib("description", attack.name());
707  return_string_attrib("name", attack.id());
708  return_string_attrib("type", attack.type());
709  return_string_attrib("icon", attack.icon());
710  return_string_attrib("range", attack.range());
711  // "min_range"
712  // "max_range"
713  return_int_attrib("damage", attack.damage());
714  return_int_attrib("number", attack.num_attacks());
715  return_int_attrib("attack_weight", attack.attack_weight());
716  return_int_attrib("defense_weight", attack.defense_weight());
717  return_int_attrib("accuracy", attack.accuracy());
718  return_int_attrib("movement_used", attack.movement_used());
719  return_int_attrib("parry", attack.parry());
720  return_cfgref_attrib("specials", attack.specials());
721  std::string err_msg = "unknown property of attack: ";
722  err_msg += m;
723  return luaL_argerror(L, 2, err_msg.c_str());
724  }
725  }
726  return luaL_argerror(L, 1, "invalid attack id");
727 }
728 
729 /**
730  * Gets a propoerty of a units attack (__index metamethod).
731  * - Arg 1: table containing the userdata containing the unit id. and a string identyfying the attack.
732  * - Arg 2: string
733  * - Ret 1:
734  */
736 {
737  if (!lua_istable(L, 1)) {
738  return luaL_typerror(L, 1, "unit attack");
739  }
740  lua_rawgeti(L, 1, 1);
741  unit* u = luaW_tounit(L, -1);
742  if (!u) {
743  return luaL_argerror(L, 1, "unknown unit");
744  }
745  lua_rawgeti(L, 1, 2);
746  std::string attack_id = luaL_checkstring(L, -1);
747  char const *m = luaL_checkstring(L, 2);
748  for (attack_type& attack : u->attacks())
749  {
750  if(attack.id() == attack_id)
751  {
752 
753  modify_tstring_attrib("description", attack.set_name(value));
754  // modify_string_attrib("name", attack.set_id(value));
755  modify_string_attrib("type", attack.set_type(value));
756  modify_string_attrib("icon", attack.set_icon(value));
757  modify_string_attrib("range", attack.set_range(value));
758  // "min_range"
759  // "max_range"
760  modify_int_attrib("damage", attack.set_damage(value));
761  modify_int_attrib("number", attack.set_num_attacks(value));
762  modify_int_attrib("attack_weight", attack.set_attack_weight(value));
763  modify_int_attrib("defense_weight", attack.set_defense_weight(value));
764  modify_int_attrib("accuracy", attack.set_accuracy(value));
765  modify_int_attrib("movement_used", attack.set_movement_used(value));
766  modify_int_attrib("parry", attack.set_parry(value));
767 
768  if (strcmp(m, "specials") == 0) { \
769  attack.set_specials(luaW_checkconfig(L, 3));
770  return 0;
771  }
772  return_cfgref_attrib("specials", attack.specials());
773  std::string err_msg = "unknown modifyable property of attack: ";
774  err_msg += m;
775  return luaL_argerror(L, 2, err_msg.c_str());
776  }
777  }
778  return luaL_argerror(L, 1, "invalid attack id");
779 }
780 
781 /**
782  * Sets the variable of a unit (__newindex metamethod).
783  * - Arg 1: table containing the userdata containing the unit id.
784  * - Arg 2: string containing the name of the status.
785  * - Arg 3: scalar.
786  */
788 {
789  if (!lua_istable(L, 1))
790  return luaL_typerror(L, 1, "unit variables");
791  lua_rawgeti(L, 1, 1);
792  unit* u = luaW_tounit(L, -1);
793  if (!u) return luaL_argerror(L, 1, "unknown unit");
794  char const *m = luaL_checkstring(L, 2);
795  if (strcmp(m, "__cfg") == 0) {
796  u->variables() = luaW_checkconfig(L, 3);
797  return 0;
798  }
800  luaW_checkvariable(L, v, 3);
801  return 0;
802 }
803 
804 /**
805  * Gets currently viewing side.
806  * - Ret 1: integer specifying the currently viewing side
807  * - Ret 2: Bool whether the vision is not limited to that team, this can for example be true during replays.
808  */
810 {
811  if(const display* disp = display::get_singleton()) {
812  lua_pushinteger(L, disp->viewing_side());
813  lua_pushboolean(L, disp->show_everything());
814  return 2;
815  }
816  else {
817  return 0;
818  }
819 }
820 
822 {
823  // if (game_display_)
824  {
825  events::command_disabler disable_commands;
827  }
828  return 0;
829 }
830 
832 {
833  if (game_display_) {
835  }
836  return 0;
837 }
838 
839 /**
840  * Gets the unit at the given location or with the given id.
841  * - Arg 1: location
842  * OR
843  * - Arg 1: string ID
844  * - Ret 1: full userdata with __index pointing to impl_unit_get and
845  * __newindex pointing to impl_unit_set.
846  */
848 {
849  map_location loc;
850  if(lua_isstring(L, 1) && !lua_isnumber(L, 1)) {
851  std::string id = luaL_checkstring(L, 1);
852  for(const unit& u : units()) {
853  if(u.id() == id) {
854  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(u.underlying_id());
857  lua_setmetatable(L, -2);
858  return 1;
859  }
860  }
861  return 0;
862  }
863  if(!luaW_tolocation(L, 1, loc)) {
864  return luaL_argerror(L, 1, "expected string or location");
865  }
866  unit_map::const_iterator ui = units().find(loc);
867 
868  if (!ui.valid()) return 0;
869 
870  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(ui->underlying_id());
872  , getunitKey);
874  lua_setmetatable(L, -2);
875  return 1;
876 }
877 
878 /**
879  * Gets the unit displayed in the sidebar.
880  * - Ret 1: full userdata with __index pointing to impl_unit_get and
881  * __newindex pointing to impl_unit_set.
882  */
884 {
885  if (!game_display_) {
886  return 0;
887  }
888 
893  if (!ui.valid()) return 0;
894 
895  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(ui->underlying_id());
897  , getunitKey);
899  lua_setmetatable(L, -2);
900  return 1;
901 }
902 
903 /**
904  * Gets all the units matching a given filter.
905  * - Arg 1: optional table containing a filter
906  * - Ret 1: table containing full userdata with __index pointing to
907  * impl_unit_get and __newindex pointing to impl_unit_set.
908  */
910 {
911  vconfig filter = luaW_checkvconfig(L, 1, true);
912 
913  // Go through all the units while keeping the following stack:
914  // 1: metatable, 2: return table, 3: userdata, 4: metatable copy
915  lua_settop(L, 0);
917  , getunitKey);
919  lua_newtable(L);
920  int i = 1;
921 
922  // note that if filter is null, this yields a null filter matching everything (and doing no work)
924  for (const unit * ui : unit_filter(filter, &fc).all_matches_on_map()) {
925  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(ui->underlying_id());
926  lua_pushvalue(L, 1);
927  lua_setmetatable(L, 3);
928  lua_rawseti(L, 2, i);
929  ++i;
930  }
931  return 1;
932 }
933 
934 /**
935  * Matches a unit against the given filter.
936  * - Arg 1: full userdata.
937  * - Arg 2: table containing a filter
938  * - Arg 3: optional location OR optional "adjacent" unit
939  * - Ret 1: boolean.
940  */
942 {
943  if (!luaW_hasmetatable(L, 1, getunitKey))
944  return luaL_typerror(L, 1, "unit");
945 
946  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
947  unit* u = lu->get();
948  if (!u) return luaL_argerror(L, 1, "unit not found");
949 
950  vconfig filter = luaW_checkvconfig(L, 2, true);
951 
952  if (filter.null()) {
953  lua_pushboolean(L, true);
954  return 1;
955  }
956 
958 
959  if (luaW_hasmetatable(L, 3, getunitKey)) {
960  if (int side = lu->on_recall_list()) {
961  WRN_LUA << "wesnoth.match_unit called with a secondary unit (3rd argument), ";
962  WRN_LUA << "but unit to match was on recall list. ";
963  WRN_LUA << "Thus the 3rd argument is ignored.\n";
964  team &t = (teams())[side - 1];
965  scoped_recall_unit auto_store("this_unit", t.save_id(), t.recall_list().find_index(u->id()));
966  lua_pushboolean(L, unit_filter(filter, &fc).matches(*u, map_location()));
967  return 1;
968  }
969  lua_unit *lu_adj = static_cast<lua_unit *>(lua_touserdata(L, 1));
970  unit* u_adj = lu_adj->get();
971  if (!u_adj) {
972  return luaL_argerror(L, 3, "unit not found");
973  }
974  lua_pushboolean(L, unit_filter(filter, &fc).matches(*u, *u_adj));
975  } else if (int side = lu->on_recall_list()) {
976  map_location loc;
977  luaW_tolocation(L, 3, loc); // If argument 3 isn't a location, loc is unchanged
978  team &t = (teams())[side - 1];
979  scoped_recall_unit auto_store("this_unit", t.save_id(), t.recall_list().find_index(u->id()));
980  lua_pushboolean(L, unit_filter(filter, &fc).matches(*u, loc));
981  return 1;
982  } else {
983  map_location loc = u->get_location();
984  luaW_tolocation(L, 3, loc); // If argument 3 isn't a location, loc is unchanged
985  lua_pushboolean(L, unit_filter(filter, &fc).matches(*u, loc));
986  }
987  return 1;
988 }
989 
990 /**
991  * Gets the numeric ids of all the units matching a given filter on the recall lists.
992  * - Arg 1: optional table containing a filter
993  * - Ret 1: table containing full userdata with __index pointing to
994  * impl_unit_get and __newindex pointing to impl_unit_set.
995  */
997 {
998  vconfig filter = luaW_checkvconfig(L, 1, true);
999 
1000  // Go through all the units while keeping the following stack:
1001  // 1: metatable, 2: return table, 3: userdata, 4: metatable copy
1002  lua_settop(L, 0);
1004  , getunitKey);
1006  lua_newtable(L);
1007  int i = 1, s = 1;
1008  filter_context & fc = game_state_;
1009  const unit_filter ufilt(filter, &fc);
1010  for (team &t : teams())
1011  {
1012  for (unit_ptr & u : t.recall_list())
1013  {
1014  if (!filter.null()) {
1015  scoped_recall_unit auto_store("this_unit",
1016  t.save_id(), t.recall_list().find_index(u->id()));
1017  if (!ufilt( *u, map_location() ))
1018  continue;
1019  }
1020  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(s, u->underlying_id());
1021  lua_pushvalue(L, 1);
1022  lua_setmetatable(L, 3);
1023  lua_rawseti(L, 2, i);
1024  ++i;
1025  }
1026  ++s;
1027  }
1028  return 1;
1029 }
1030 
1031 /**
1032  * Fires an event.
1033  * - Arg 1: string containing the event name.
1034  * - Arg 2: optional first location.
1035  * - Arg 3: optional second location.
1036  * - Arg 4: optional WML table used as the [weapon] tag.
1037  * - Arg 5: optional WML table used as the [second_weapon] tag.
1038  * - Ret 1: boolean indicating whether the event was processed or not.
1039  */
1041 {
1042  char const *m = luaL_checkstring(L, 1);
1043 
1044  int pos = 2;
1045  map_location l1, l2;
1046  config data;
1047 
1048  if (luaW_tolocation(L, 2, l1)) {
1049  if (luaW_tolocation(L, 3, l2)) {
1050  pos = 4;
1051  } else {
1052  pos = 3;
1053  }
1054  }
1055 
1056  if (!lua_isnoneornil(L, pos)) {
1057  data.add_child("first", luaW_checkconfig(L, pos));
1058  }
1059  ++pos;
1060  if (!lua_isnoneornil(L, pos)) {
1061  data.add_child("second", luaW_checkconfig(L, pos));
1062  }
1063 
1064  bool b = play_controller_.pump().fire(m, l1, l2, data);
1065  lua_pushboolean(L, b);
1066  return 1;
1067 }
1068 
1069 /**
1070  * Fires a wml menu item.
1071  * - Arg 1: id of the item. it is not possible to fire items that don't have ids with this function.
1072  * - Arg 2: optional first location.
1073  * - Ret 1: boolean, true indicating that the event was fired successfully
1074  *
1075  * NOTE: This is not an "official" feature, it may currently cause assertion failures if used with
1076  * menu items which have "needs_select". It is not supported right now to use it this way.
1077  * The purpose of this function right now is to make it possible to have automated sanity tests for
1078  * the wml menu items system.
1079  */
1081 {
1082  char const *m = luaL_checkstring(L, 1);
1083 
1084  map_location l1 = luaW_checklocation(L, 2);
1085 
1087  lua_pushboolean(L, b);
1088  return 1;
1089 }
1090 
1091 /**
1092  * Gets a WML variable.
1093  * - Arg 1: string containing the variable name.
1094  * - Arg 2: optional bool indicating if tables for containers should be left empty.
1095  * - Ret 1: value of the variable, if any.
1096  */
1098 {
1099  char const *m = luaL_checkstring(L, 1);
1101  return luaW_pushvariable(L, v) ? 1 : 0;
1102 }
1103 
1104 /**
1105  * Gets a side specific WML variable.
1106  * - Arg 1: integer side number.
1107  * - Arg 2: string containing the variable name.
1108  * - Ret 1: value of the variable, if any.
1109  */
1111 {
1112 
1113  unsigned side_index = luaL_checkinteger(L, 1) - 1;
1114  if(side_index >= teams().size()) {
1115  return luaL_argerror(L, 1, "invalid side number");
1116  }
1117  char const *m = luaL_checkstring(L, 2);
1118  variable_access_const v(m, teams()[side_index].variables());
1119  return luaW_pushvariable(L, v) ? 1 : 0;
1120 }
1121 
1122 /**
1123  * Gets a side specific WML variable.
1124  * - Arg 1: integer side number.
1125  * - Arg 2: string containing the variable name.
1126  * - Arg 3: boolean/integer/string/table containing the value.
1127  */
1129 {
1130  unsigned side_index = luaL_checkinteger(L, 1) - 1;
1131  if(side_index >= teams().size()) {
1132  return luaL_argerror(L, 1, "invalid side number");
1133  }
1134  char const *m = luaL_checkstring(L, 2);
1135  //TODO: maybe support removing values with an empty arg3.
1136  variable_access_create v(m, teams()[side_index].variables());
1137  luaW_checkvariable(L, v, 3);
1138  return 0;
1139 }
1140 
1141 /**
1142  * Sets a WML variable.
1143  * - Arg 1: string containing the variable name.
1144  * - Arg 2: boolean/integer/string/table containing the value.
1145  */
1147 {
1148  const std::string m = luaL_checkstring(L, 1);
1149  if(m.empty()) return luaL_argerror(L, 1, "empty variable name");
1150  if (lua_isnoneornil(L, 2)) {
1151  gamedata().clear_variable(m);
1152  return 0;
1153  }
1155  luaW_checkvariable(L, v, 2);
1156  return 0;
1157 }
1158 
1159 /**
1160  * Returns a random numer, same interface as math.random.
1161  */
1163 {
1164  if(lua_isnoneornil(L, 1)) {
1165  double r = double (random_new::generator->next_random());
1166  double r_max = double (std::numeric_limits<uint32_t>::max());
1167  lua_push(L, r / (r_max + 1));
1168  return 1;
1169  }
1170  else {
1171  int32_t min;
1172  int32_t max;
1173  if(lua_isnumber(L, 2)) {
1174  min = lua_check<int32_t>(L, 1);
1175  max = lua_check<int32_t>(L, 2);
1176  }
1177  else {
1178  min = 1;
1179  max = lua_check<int32_t>(L, 1);
1180  }
1181  if(min > max) {
1182  return luaL_argerror(L, 1, "min > max");
1183  }
1184  lua_push(L, random_new::generator->get_random_int(min, max));
1185  return 1;
1186  }
1187 }
1188 
1190 {
1192  return 0;
1193 }
1194 
1196 {
1198  for(const std::string& id : utils::split(ids, ',', utils::STRIP_SPACES)) {
1199  if(id.empty()) {
1200  WRN_LUA << "[clear_menu_item] has been given an empty id=, ignoring" << std::endl;
1201  continue;
1202  }
1204  }
1205  return 0;
1206 }
1207 
1209 {
1211  classification.end_credits = luaW_toboolean(L, 1);
1212  return 0;
1213 }
1214 
1216 {
1218  classification.end_text = luaW_checktstring(L, 1);
1219  if (lua_isnumber(L, 2)) {
1220  classification.end_text_duration = static_cast<int> (lua_tonumber(L, 2));
1221  }
1222 
1223  return 0;
1224 }
1225 
1227 {
1229  return 0;
1230 }
1231 
1232 int game_lua_kernel::intf_shroud_op(lua_State *L, bool place_shroud)
1233 {
1234  vconfig cfg = luaW_checkvconfig(L, 1);
1235 
1236  // Filter the sides.
1237  std::vector<int> sides = get_sides_vector(cfg);
1238  size_t index;
1239 
1240  // Filter the locations.
1241  std::set<map_location> locs;
1242  const terrain_filter filter(cfg, &game_state_);
1243  filter.get_locations(locs, true);
1244 
1245  for (const int &side_num : sides)
1246  {
1247  index = side_num - 1;
1248  team &t = teams()[index];
1249 
1250  for (map_location const &loc : locs)
1251  {
1252  if (place_shroud) {
1253  t.place_shroud(loc);
1254  } else {
1255  t.clear_shroud(loc);
1256  }
1257  }
1258  }
1259 
1263 
1264  return 0;
1265 }
1266 
1267 
1268 /**
1269  * Highlights the given location on the map.
1270  * - Arg 1: location.
1271  */
1273 {
1274  if (!game_display_) {
1275  return 0;
1276  }
1277 
1278  const map_location loc = luaW_checklocation(L, 1);
1279  if(!map().on_board(loc)) return luaL_argerror(L, 1, "not on board");
1282 
1283  return 0;
1284 }
1285 
1286 /**
1287  * Returns whether the first side is an enemy of the second one.
1288  * - Args 1,2: side numbers.
1289  * - Ret 1: boolean.
1290  */
1292 {
1293  unsigned side_1 = luaL_checkint(L, 1) - 1;
1294  unsigned side_2 = luaL_checkint(L, 2) - 1;
1295  if (side_1 >= teams().size() || side_2 >= teams().size()) return 0;
1296  lua_pushboolean(L, teams()[side_1].is_enemy(side_2 + 1));
1297  return 1;
1298 }
1299 
1300 /**
1301  * Gets whether gamemap scrolling is disabled for the user.
1302  * - Ret 1: boolean.
1303  */
1305 {
1306  if (!game_display_) {
1307  return 0;
1308  }
1309 
1311  return 1;
1312 }
1313 
1314 /**
1315  * Sets whether gamemap scrolling is disabled for the user.
1316  * - Arg 1: boolean, specifying the new locked/unlocked status.
1317  */
1319 {
1320  bool lock = luaW_toboolean(L, 1);
1321  if (game_display_) {
1323  }
1324  return 0;
1325 }
1326 
1327 /**
1328  * Gets a terrain code.
1329  * - Arg 1: map location.
1330  * - Ret 1: string.
1331  */
1333 {
1334  map_location loc = luaW_checklocation(L, 1);
1335 
1336  t_translation::t_terrain const &t = board().map().
1337  get_terrain(loc);
1339  return 1;
1340 }
1341 
1342 /**
1343  * Sets a terrain code.
1344  * - Arg 1: map location.
1345  * - Arg 2: terrain code string.
1346  * - Arg 3: layer: (overlay|base|both, default=both)
1347  * - Arg 4: replace_if_failed, default = no
1348  */
1350 {
1351  map_location loc = luaW_checklocation(L, 1);
1352  std::string t_str(luaL_checkstring(L, 2));
1353 
1354  std::string mode_str = "both";
1355  bool replace_if_failed = false;
1356  if (!lua_isnone(L, 3)) {
1357  if (!lua_isnil(L, 3)) {
1358  mode_str = luaL_checkstring(L, 3);
1359  }
1360 
1361  if(!lua_isnoneornil(L, 4)) {
1362  replace_if_failed = luaW_toboolean(L, 4);
1363  }
1364  }
1365 
1366  bool result = board().change_terrain(loc, t_str, mode_str, replace_if_failed);
1367 
1368  if (game_display_) {
1369  game_display_->needs_rebuild(result);
1370  }
1371 
1372  return 0;
1373 }
1374 
1375 /**
1376  * Gets details about a terrain.
1377  * - Arg 1: terrain code string.
1378  * - Ret 1: table.
1379  */
1381 {
1382  char const *m = luaL_checkstring(L, 1);
1384  if (t == t_translation::NONE_TERRAIN) return 0;
1385  terrain_type const &info = board().map().tdata()->get_terrain_info(t);
1386 
1387  lua_newtable(L);
1388  lua_pushstring(L, info.id().c_str());
1389  lua_setfield(L, -2, "id");
1390  luaW_pushtstring(L, info.name());
1391  lua_setfield(L, -2, "name");
1392  luaW_pushtstring(L, info.editor_name());
1393  lua_setfield(L, -2, "editor_name");
1394  luaW_pushtstring(L, info.description());
1395  lua_setfield(L, -2, "description");
1396  lua_push(L, info.icon_image());
1397  lua_setfield(L, -2, "icon");
1398  lua_push(L, info.editor_image());
1399  lua_setfield(L, -2, "editor_image");
1400  lua_pushinteger(L, info.light_bonus(0));
1401  lua_setfield(L, -2, "light");
1402  lua_pushboolean(L, info.is_village());
1403  lua_setfield(L, -2, "village");
1404  lua_pushboolean(L, info.is_castle());
1405  lua_setfield(L, -2, "castle");
1406  lua_pushboolean(L, info.is_keep());
1407  lua_setfield(L, -2, "keep");
1408  lua_pushinteger(L, info.gives_healing());
1409  lua_setfield(L, -2, "healing");
1410 
1411  return 1;
1412 }
1413 
1414 /**
1415  * Gets time of day information.
1416  * - Arg 1: optional turn number
1417  * - Arg 2: optional location
1418  * - Arg 3: optional boolean (consider_illuminates)
1419  * - Ret 1: table.
1420  */
1422 {
1423  unsigned arg = 1;
1424 
1425  int for_turn = tod_man().turn();
1426  map_location loc = map_location();
1427  bool consider_illuminates = false;
1428 
1429  if(lua_isnumber(L, arg)) {
1430  ++arg;
1431  for_turn = luaL_checkint(L, 1);
1432  int number_of_turns = tod_man().number_of_turns();
1433  if(for_turn < 1 || (number_of_turns != -1 && for_turn > number_of_turns)) {
1434  return luaL_argerror(L, 1, "turn number out of range");
1435  }
1436  }
1437  else if(lua_isnil(L, arg)) ++arg;
1438 
1439  if(luaW_tolocation(L, arg, loc)) {
1440  if(!board().map().on_board(loc)) return luaL_argerror(L, arg, "coordinates are not on board");
1441 
1442  if(lua_istable(L, arg)) {
1443  lua_rawgeti(L, arg, 3);
1444  consider_illuminates = luaW_toboolean(L, -1);
1445  lua_pop(L, 1);
1446  } else if(lua_isboolean(L, arg + 1)) {
1447  consider_illuminates = luaW_toboolean(L, arg + 1);
1448  }
1449  }
1450 
1451  const time_of_day& tod = consider_illuminates ?
1452  tod_man().get_illuminated_time_of_day(board().units(), board().map(), loc, for_turn) :
1453  tod_man().get_time_of_day(loc, for_turn);
1454 
1455  lua_newtable(L);
1456  lua_pushstring(L, tod.id.c_str());
1457  lua_setfield(L, -2, "id");
1458  lua_pushinteger(L, tod.lawful_bonus);
1459  lua_setfield(L, -2, "lawful_bonus");
1461  lua_setfield(L, -2, "bonus_modified");
1462  lua_pushstring(L, tod.image.c_str());
1463  lua_setfield(L, -2, "image");
1464  luaW_pushtstring(L, tod.name);
1465  lua_setfield(L, -2, "name");
1466 
1467  lua_pushinteger(L, tod.color.r);
1468  lua_setfield(L, -2, "red");
1469  lua_pushinteger(L, tod.color.g);
1470  lua_setfield(L, -2, "green");
1471  lua_pushinteger(L, tod.color.b);
1472  lua_setfield(L, -2, "blue");
1473 
1474  return 1;
1475 }
1476 
1477 /**
1478  * Gets the side of a village owner.
1479  * - Arg 1: map location.
1480  * - Ret 1: integer.
1481  */
1483 {
1484  map_location loc = luaW_checklocation(L, 1);
1485  if (!board().map().is_village(loc))
1486  return 0;
1487 
1488  int side = board().village_owner(loc) + 1;
1489  if (!side) return 0;
1490  lua_pushinteger(L, side);
1491  return 1;
1492 }
1493 
1494 /**
1495  * Sets the owner of a village.
1496  * - Arg 1: map location.
1497  * - Arg 2: integer for the side or empty to remove ownership.
1498  */
1500 {
1501  map_location loc = luaW_checklocation(L, 1);
1502  int new_side = lua_isnoneornil(L, 2) ? 0 : luaL_checkint(L, 2);
1503 
1504  if (!board().map().is_village(loc))
1505  return 0;
1506 
1507  int old_side = board().village_owner(loc) + 1;
1508 
1509  if (new_side == old_side || new_side < 0 || new_side > static_cast<int>(teams().size()) || board().team_is_defeated(teams()[new_side - 1])) {
1510  return 0;
1511  }
1512 
1513  if (old_side) {
1514  teams()[old_side - 1].lose_village(loc);
1515  }
1516  if (new_side) {
1517  teams()[new_side - 1].get_village(loc, old_side, (luaW_toboolean(L, 4) ? &gamedata() : nullptr) );
1518  }
1519  return 0;
1520 }
1521 
1522 
1523 /**
1524  * Returns the map size.
1525  * - Ret 1: width.
1526  * - Ret 2: height.
1527  * - Ret 3: border size.
1528  */
1530 {
1531  const gamemap &map = board().map();
1532  lua_pushinteger(L, map.w());
1533  lua_pushinteger(L, map.h());
1534  lua_pushinteger(L, map.border_size());
1535  return 3;
1536 }
1537 
1538 /**
1539  * Returns the currently overed tile.
1540  * - Ret 1: x.
1541  * - Ret 2: y.
1542  */
1544 {
1545  if (!game_display_) {
1546  return 0;
1547  }
1548 
1549  const map_location &loc = game_display_->mouseover_hex();
1550  if (!board().map().on_board(loc)) return 0;
1551  lua_pushinteger(L, loc.x + 1);
1552  lua_pushinteger(L, loc.y + 1);
1553  return 2;
1554 }
1555 
1556 /**
1557  * Returns the currently selected tile.
1558  * - Ret 1: x.
1559  * - Ret 2: y.
1560  */
1562 {
1563  if (!game_display_) {
1564  return 0;
1565  }
1566 
1567  const map_location &loc = game_display_->selected_hex();
1568  if (!board().map().on_board(loc)) return 0;
1569  lua_pushinteger(L, loc.x + 1);
1570  lua_pushinteger(L, loc.y + 1);
1571  return 2;
1572 }
1573 
1574 /**
1575  * Returns the starting position of a side.
1576  * Arg 1: side number
1577  * Ret 1: table with unnamed indices holding wml coordinates x and y
1578 */
1580 {
1581  const int side = luaL_checkint(L, 1);
1582  if(side < 1 || static_cast<int>(teams().size()) < side)
1583  return luaL_argerror(L, 1, "out of bounds");
1584  const map_location& starting_pos = board().map().starting_position(side);
1585  if(!board().map().on_board(starting_pos)) return 0;
1586 
1587  lua_createtable(L, 2, 0);
1588  lua_pushinteger(L, starting_pos.x + 1);
1589  lua_rawseti(L, -2, 1);
1590  lua_pushinteger(L, starting_pos.y + 1);
1591  lua_rawseti(L, -2, 2);
1592 
1593  return 1;
1594 }
1595 
1596 /**
1597  * Gets a table for an era tag.
1598  * - Arg 1: userdata (ignored).
1599  * - Arg 2: string containing id of the desired era
1600  * - Ret 1: config for the era
1601  */
1602 static int intf_get_era(lua_State *L)
1603 {
1604  char const *m = luaL_checkstring(L, 1);
1605  luaW_pushconfig(L, game_config_manager::get()->game_config().find_child("era","id",m));
1606  return 1;
1607 }
1608 
1609 /**
1610  * Gets some game_config data (__index metamethod).
1611  * - Arg 1: userdata (ignored).
1612  * - Arg 2: string containing the name of the property.
1613  * - Ret 1: something containing the attribute.
1614  */
1616 {
1617  LOG_LUA << "impl_game_config_get\n";
1618  char const *m = luaL_checkstring(L, 2);
1619 
1620  // Find the corresponding attribute.
1623  return_int_attrib("village_support", game_config::village_support);
1625  return_int_attrib("rest_heal_amount", game_config::rest_heal_amount);
1627  return_int_attrib("kill_experience", game_config::kill_experience);
1628  return_int_attrib("last_turn", tod_man().number_of_turns());
1633 
1636 
1637  return_string_attrib("campaign_type", classification.campaign_type.to_string());
1638  if(classification.campaign_type==game_classification::CAMPAIGN_TYPE::MULTIPLAYER) {
1639  return_cfgref_attrib("mp_settings", mp_settings.to_config());
1640  return_cfgref_attrib("era", game_config_manager::get()->game_config().find_child("era","id",mp_settings.mp_era));
1641  //^ finds the era with name matching mp_era, and creates a lua reference from the config of that era.
1642 
1643  //This code for SigurdFD, not the cleanest implementation but seems to work just fine.
1645  std::string eras_list((*(its.first))["id"]);
1646  ++its.first;
1647  for(; its.first != its.second; ++its.first) {
1648  eras_list = eras_list + "," + (*(its.first))["id"];
1649  }
1650  return_string_attrib("eras", eras_list);
1651  }
1652  return 0;
1653 }
1654 
1655 /**
1656  * Sets some game_config data (__newindex metamethod).
1657  * - Arg 1: userdata (ignored).
1658  * - Arg 2: string containing the name of the property.
1659  * - Arg 3: something containing the attribute.
1660  */
1662 {
1663  LOG_LUA << "impl_game_config_set\n";
1664  char const *m = luaL_checkstring(L, 2);
1665 
1666  // Find the corresponding attribute.
1671  modify_int_attrib("rest_heal_amount", game_config::rest_heal_amount = value);
1674  modify_int_attrib("last_turn", tod_man().set_number_of_turns_by_wml(value));
1675 
1676  std::string err_msg = "unknown modifiable property of game_config: ";
1677  err_msg += m;
1678  return luaL_argerror(L, 2, err_msg.c_str());
1679 }
1680 
1681 /**
1682  converts synced_context::get_synced_state() to a string.
1683 */
1685 {
1686  //maybe return "initial" for game_data::INITIAL?
1687  if(gamedata().phase() == game_data::PRELOAD || gamedata().phase() == game_data::INITIAL)
1688  {
1689  return "preload";
1690  }
1692  {
1694  return "local_choice";
1696  return "synced";
1698  return "unsynced";
1699  default:
1700  throw game::game_error("Found corrupt synced_context::synced_state");
1701  }
1702 }
1703 
1704 
1705 /**
1706  * Gets some data about current point of game (__index metamethod).
1707  * - Arg 1: userdata (ignored).
1708  * - Arg 2: string containing the name of the property.
1709  * - Ret 1: something containing the attribute.
1710  */
1712 {
1713  char const *m = luaL_checkstring(L, 2);
1714 
1715  // Find the corresponding attribute.
1718  return_string_attrib("synced_state", synced_state());
1719 
1720  if (strcmp(m, "event_context") == 0)
1721  {
1723  config cfg;
1724  cfg["name"] = ev.name;
1725  if (const config &weapon = ev.data.child("first")) {
1726  cfg.add_child("weapon", weapon);
1727  }
1728  if (const config &weapon = ev.data.child("second")) {
1729  cfg.add_child("second_weapon", weapon);
1730  }
1731  if (ev.loc1.valid()) {
1732  cfg["x1"] = ev.loc1.filter_x() + 1;
1733  cfg["y1"] = ev.loc1.filter_y() + 1;
1734  // The position of the unit involved in this event, currently the only case where this is different from x1/y1 are enter/exit_hex events
1735  cfg["unit_x"] = ev.loc1.x + 1;
1736  cfg["unit_y"] = ev.loc1.y + 1;
1737  }
1738  if (ev.loc2.valid()) {
1739  cfg["x2"] = ev.loc2.filter_x() + 1;
1740  cfg["y2"] = ev.loc2.filter_y() + 1;
1741  }
1742  luaW_pushconfig(L, cfg);
1743  return 1;
1744  }
1745 
1746  return 0;
1747 }
1748 
1749 /**
1750  * Displays a message in the chat window and in the logs.
1751  * - Arg 1: optional message header.
1752  * - Arg 2 (or 1): message.
1753  */
1755 {
1756  t_string m = luaW_checktstring(L, 1);
1757  t_string h = m;
1758  if (lua_isnone(L, 2)) {
1759  h = "Lua";
1760  } else {
1761  m = luaW_checktstring(L, 2);
1762  }
1763  lua_chat(h, m);
1764  LOG_LUA << "Script says: \"" << m << "\"\n";
1765  return 0;
1766 }
1767 
1769 {
1770  if (game_display_) {
1772  }
1773  return 0;
1774 }
1775 
1776 /**
1777  * Dumps a wml table or userdata wml object into a pretty string.
1778  * - Arg 1: wml table or vconfig userdata
1779  * - Ret 1: string
1780  */
1781 static int intf_debug(lua_State* L)
1782 {
1783  const config& arg = luaW_checkconfig(L, 1);
1784  const std::string& result = arg.debug();
1785  lua_pushstring(L, result.c_str());
1786  return 1;
1787 }
1788 
1790 {
1792  return 1;
1793 }
1794 
1795 /**
1796  * Removes all messages from the chat window.
1797  */
1799 {
1800  if (game_display_) {
1802  }
1803  return 0;
1804 }
1805 
1807 {
1808  vconfig cfg(luaW_checkvconfig(L, 1));
1809 
1810 
1812  return 0;
1813  }
1815 
1816  data.proceed_to_next_level = cfg["proceed_to_next_level"].to_bool(true);
1817  data.transient.custom_endlevel_music = cfg["music"].str();
1818  data.transient.carryover_report = cfg["carryover_report"].to_bool(true);
1819  data.prescenario_save = cfg["save"].to_bool(true);
1820  data.replay_save = cfg["replay_save"].to_bool(true);
1821  data.transient.linger_mode = cfg["linger_mode"].to_bool(true) && !teams().empty();
1822  data.transient.reveal_map = cfg["reveal_map"].to_bool(true);
1823  data.is_victory = cfg["result"] == "victory";
1825  return 0;
1826 }
1827 
1829 {
1831  return 0;
1832 }
1833 
1834 /**
1835  * Evaluates a boolean WML conditional.
1836  * - Arg 1: WML table.
1837  * - Ret 1: boolean.
1838  */
1840 {
1841  vconfig cond = luaW_checkvconfig(L, 1);
1842  bool b = game_events::conditional_passed(cond);
1843  lua_pushboolean(L, b);
1844  return 1;
1845 }
1846 
1847 
1848 /**
1849  * Finds a path between two locations.
1850  * - Arg 1: source location. (Or Arg 1: unit.)
1851  * - Arg 2: destination.
1852  * - Arg 3: optional cost function or
1853  * table (optional fields: ignore_units, ignore_teleport, max_cost, viewing_side).
1854  * - Ret 1: array of pairs containing path steps.
1855  * - Ret 2: path cost.
1856  */
1858 {
1859  int arg = 1;
1860  map_location src, dst;
1861  const unit* u = nullptr;
1862 
1863  if (lua_isuserdata(L, arg))
1864  {
1865  u = &luaW_checkunit(L, arg);
1866  src = u->get_location();
1867  ++arg;
1868  }
1869  else
1870  {
1871  src = luaW_checklocation(L, arg);
1873  if (ui.valid()) {
1874  u = ui.get_shared_ptr().get();
1875  }
1876  ++arg;
1877  }
1878 
1879  dst = luaW_checklocation(L, arg);
1880  ++arg;
1881 
1882  if (!board().map().on_board(src))
1883  return luaL_argerror(L, 1, "invalid location");
1884  if (!board().map().on_board(dst))
1885  return luaL_argerror(L, arg - 2, "invalid location");
1886 
1887  const gamemap &map = board().map();
1888  int viewing_side = 0;
1889  bool ignore_units = false, see_all = false, ignore_teleport = false;
1890  double stop_at = 10000;
1891  pathfind::cost_calculator *calc = nullptr;
1892 
1893  if (lua_istable(L, arg))
1894  {
1895  lua_pushstring(L, "ignore_units");
1896  lua_rawget(L, arg);
1897  ignore_units = luaW_toboolean(L, -1);
1898  lua_pop(L, 1);
1899 
1900  lua_pushstring(L, "ignore_teleport");
1901  lua_rawget(L, arg);
1902  ignore_teleport = luaW_toboolean(L, -1);
1903  lua_pop(L, 1);
1904 
1905  lua_pushstring(L, "max_cost");
1906  lua_rawget(L, arg);
1907  if (!lua_isnil(L, -1))
1908  stop_at = luaL_checknumber(L, -1);
1909  lua_pop(L, 1);
1910 
1911  lua_pushstring(L, "viewing_side");
1912  lua_rawget(L, arg);
1913  if (!lua_isnil(L, -1)) {
1914  int i = luaL_checkinteger(L, -1);
1915  if (i >= 1 && i <= int(teams().size())) viewing_side = i;
1916  else see_all = true;
1917  }
1918  lua_pop(L, 1);
1919  }
1920  else if (lua_isfunction(L, arg))
1921  {
1922  calc = new lua_pathfind_cost_calculator(L, arg);
1923  }
1924 
1925  pathfind::teleport_map teleport_locations;
1926 
1927  if (!calc) {
1928  if (!u) return luaL_argerror(L, 1, "unit not found");
1929 
1930  const team &viewing_team = board().teams()[(viewing_side ? viewing_side : u->side()) - 1];
1931  if (!ignore_teleport) {
1932  teleport_locations = pathfind::get_teleport_locations(
1933  *u, viewing_team, see_all, ignore_units);
1934  }
1935  calc = new pathfind::shortest_path_calculator(*u, viewing_team,
1936  teams(), map, ignore_units, false, see_all);
1937  }
1938 
1939  pathfind::plain_route res = pathfind::a_star_search(src, dst, stop_at, calc, map.w(), map.h(),
1940  &teleport_locations);
1941  delete calc;
1942 
1943  int nb = res.steps.size();
1944  lua_createtable(L, nb, 0);
1945  for (int i = 0; i < nb; ++i)
1946  {
1947  lua_createtable(L, 2, 0);
1948  lua_pushinteger(L, res.steps[i].x + 1);
1949  lua_rawseti(L, -2, 1);
1950  lua_pushinteger(L, res.steps[i].y + 1);
1951  lua_rawseti(L, -2, 2);
1952  lua_rawseti(L, -2, i + 1);
1953  }
1954  lua_pushinteger(L, res.move_cost);
1955 
1956  return 2;
1957 }
1958 
1959 /**
1960  * Finds all the locations reachable by a unit.
1961  * - Arg 1: source location OR unit.
1962  * - Arg 2: optional table (optional fields: ignore_units, ignore_teleport, additional_turns, viewing_side).
1963  * - Ret 1: array of triples (coordinates + remaining movement).
1964  */
1966 {
1967  int arg = 1;
1968  const unit* u = nullptr;
1969 
1970  if (lua_isuserdata(L, arg))
1971  {
1972  u = &luaW_checkunit(L, arg);
1973  ++arg;
1974  }
1975  else
1976  {
1979  if (!ui.valid())
1980  return luaL_argerror(L, 1, "unit not found");
1981  u = ui.get_shared_ptr().get();
1982  ++arg;
1983  }
1984 
1985  int viewing_side = 0;
1986  bool ignore_units = false, see_all = false, ignore_teleport = false;
1987  int additional_turns = 0;
1988 
1989  if (lua_istable(L, arg))
1990  {
1991  lua_pushstring(L, "ignore_units");
1992  lua_rawget(L, arg);
1993  ignore_units = luaW_toboolean(L, -1);
1994  lua_pop(L, 1);
1995 
1996  lua_pushstring(L, "ignore_teleport");
1997  lua_rawget(L, arg);
1998  ignore_teleport = luaW_toboolean(L, -1);
1999  lua_pop(L, 1);
2000 
2001  lua_pushstring(L, "additional_turns");
2002  lua_rawget(L, arg);
2003  additional_turns = lua_tointeger(L, -1);
2004  lua_pop(L, 1);
2005 
2006  lua_pushstring(L, "viewing_side");
2007  lua_rawget(L, arg);
2008  if (!lua_isnil(L, -1)) {
2009  int i = luaL_checkinteger(L, -1);
2010  if (i >= 1 && i <= int(teams().size())) viewing_side = i;
2011  else see_all = true;
2012  }
2013  lua_pop(L, 1);
2014  }
2015 
2016  const team &viewing_team = board().teams()[(viewing_side ? viewing_side : u->side()) - 1];
2017  pathfind::paths res(*u, ignore_units, !ignore_teleport,
2018  viewing_team, additional_turns, see_all, ignore_units);
2019 
2020  int nb = res.destinations.size();
2021  lua_createtable(L, nb, 0);
2022  for (int i = 0; i < nb; ++i)
2023  {
2025  lua_createtable(L, 2, 0);
2026  lua_pushinteger(L, s.curr.x + 1);
2027  lua_rawseti(L, -2, 1);
2028  lua_pushinteger(L, s.curr.y + 1);
2029  lua_rawseti(L, -2, 2);
2030  lua_pushinteger(L, s.move_left);
2031  lua_rawseti(L, -2, 3);
2032  lua_rawseti(L, -2, i + 1);
2033  }
2034 
2035  return 1;
2036 }
2037 
2038 static bool intf_find_cost_map_helper(const unit * ptr) {
2039  return ptr->get_location().valid();
2040 }
2041 
2042 template<typename T> // This is only a template so I can avoid typing out the long typename. >_>
2043 static int load_fake_units(lua_State* L, int arg, T& fake_units)
2044 {
2045  for (int i = 1, i_end = lua_rawlen(L, arg); i <= i_end; ++i)
2046  {
2047  map_location src;
2048  lua_rawgeti(L, arg, i);
2049  int entry = lua_gettop(L);
2050  if (!lua_istable(L, entry)) {
2051  goto error;
2052  }
2053 
2054  if (!luaW_tolocation(L, entry, src)) {
2055  goto error;
2056  }
2057 
2058  lua_rawgeti(L, entry, 3);
2059  if (!lua_isnumber(L, -1)) {
2060  lua_getfield(L, entry, "side");
2061  if (!lua_isnumber(L, -1)) {
2062  goto error;
2063  }
2064  }
2065  int side = lua_tointeger(L, -1);
2066 
2067  lua_rawgeti(L, entry, 4);
2068  if (!lua_isstring(L, -1)) {
2069  lua_getfield(L, entry, "type");
2070  if (!lua_isstring(L, -1)) {
2071  goto error;
2072  }
2073  }
2075 
2076  boost::tuple<map_location, int, std::string> tuple(src, side, unit_type);
2077  fake_units.push_back(tuple);
2078 
2079  lua_settop(L, entry - 1);
2080  }
2081  return 0;
2082 error:
2083  return luaL_argerror(L, arg, "unit type table malformed - each entry should be either array of 4 elements or table with keys x, y, side, type");
2084 }
2085 
2086 /**
2087  * Is called with one or more units and builds a cost map.
2088  * - Arg 1: source location. (Or Arg 1: unit. Or Arg 1: table containing a filter)
2089  * - Arg 2: optional array of tables with 4 elements (coordinates + side + unit type string)
2090  * - Arg 3: optional table (optional fields: ignore_units, ignore_teleport, viewing_side, debug).
2091  * - Arg 4: optional table: standard location filter.
2092  * - Ret 1: array of triples (coordinates + array of tuples(summed cost + reach counter)).
2093  */
2095 {
2096  int arg = 1;
2097  unit* u = luaW_tounit(L, arg, true);
2099  luaW_tovconfig(L, arg, filter);
2100 
2101  std::vector<const unit*> real_units;
2102  typedef std::vector<boost::tuple<map_location, int, std::string> > unit_type_vector;
2103  unit_type_vector fake_units;
2104 
2105 
2106  if (u) // 1. arg - unit
2107  {
2108  real_units.push_back(u);
2109  }
2110  else if (!filter.null()) // 1. arg - filter
2111  {
2112  filter_context & fc = game_state_;
2113  boost::copy(unit_filter(filter, &fc).all_matches_on_map() | boost::adaptors::filtered(&intf_find_cost_map_helper), std::back_inserter(real_units));
2114  }
2115  else // 1. arg - coordinates
2116  {
2119  if (ui.valid())
2120  {
2121  real_units.push_back(&(*ui));
2122  }
2123  }
2124  ++arg;
2125 
2126  if (lua_istable(L, arg)) // 2. arg - optional types
2127  {
2128  load_fake_units(L, arg, fake_units);
2129  ++arg;
2130  }
2131 
2132  if(real_units.empty() && fake_units.empty())
2133  {
2134  return luaL_argerror(L, 1, "unit(s) not found");
2135  }
2136 
2137  int viewing_side = 0;
2138  bool ignore_units = true, see_all = true, ignore_teleport = false, debug = false, use_max_moves = false;
2139 
2140  if (lua_istable(L, arg)) // 4. arg - options
2141  {
2142  lua_pushstring(L, "ignore_units");
2143  lua_rawget(L, arg);
2144  if (!lua_isnil(L, -1))
2145  {
2146  ignore_units = luaW_toboolean(L, -1);
2147  }
2148  lua_pop(L, 1);
2149 
2150  lua_pushstring(L, "ignore_teleport");
2151  lua_rawget(L, arg);
2152  if (!lua_isnil(L, -1))
2153  {
2154  ignore_teleport = luaW_toboolean(L, -1);
2155  }
2156  lua_pop(L, 1);
2157 
2158  lua_pushstring(L, "viewing_side");
2159  lua_rawget(L, arg);
2160  if (!lua_isnil(L, -1))
2161  {
2162  int i = luaL_checkinteger(L, -1);
2163  if (i >= 1 && i <= int(teams().size()))
2164  {
2165  viewing_side = i;
2166  see_all = false;
2167  }
2168  }
2169 
2170  lua_pushstring(L, "debug");
2171  lua_rawget(L, arg);
2172  if (!lua_isnil(L, -1))
2173  {
2174  debug = luaW_toboolean(L, -1);
2175  }
2176  lua_pop(L, 1);
2177 
2178  lua_pushstring(L, "use_max_moves");
2179  lua_rawget(L, arg);
2180  if (!lua_isnil(L, -1))
2181  {
2182  use_max_moves = luaW_toboolean(L, -1);
2183  }
2184  lua_pop(L, 1);
2185  ++arg;
2186  }
2187 
2188  // 5. arg - location filter
2189  filter = vconfig::unconstructed_vconfig();
2190  std::set<map_location> location_set;
2191  luaW_tovconfig(L, arg, filter);
2192  if (filter.null())
2193  {
2194  filter = vconfig(config(), true);
2195  }
2196  filter_context & fc = game_state_;
2197  const terrain_filter t_filter(filter, &fc);
2198  t_filter.get_locations(location_set, true);
2199  ++arg;
2200 
2201  // build cost_map
2202  const team &viewing_team = board().teams()[(viewing_side ? viewing_side : 1) - 1];
2203  pathfind::full_cost_map cost_map(
2204  ignore_units, !ignore_teleport, viewing_team, see_all, ignore_units);
2205 
2206  for (const unit* const u : real_units)
2207  {
2208  cost_map.add_unit(*u, use_max_moves);
2209  }
2210  for (const unit_type_vector::value_type& fu : fake_units)
2211  {
2212  const unit_type* ut = unit_types.find(fu.get<2>());
2213  cost_map.add_unit(fu.get<0>(), ut, fu.get<1>());
2214  }
2215 
2216  if (debug)
2217  {
2218  if (game_display_) {
2220  for (const map_location& loc : location_set)
2221  {
2222  std::stringstream s;
2223  s << cost_map.get_pair_at(loc.x, loc.y).first;
2224  s << " / ";
2225  s << cost_map.get_pair_at(loc.x, loc.y).second;
2226  game_display_->labels().set_label(loc, s.str());
2227  }
2228  }
2229  }
2230 
2231  // create return value
2232  lua_createtable(L, location_set.size(), 0);
2233  int counter = 1;
2234  for (const map_location& loc : location_set)
2235  {
2236  lua_createtable(L, 4, 0);
2237 
2238  lua_pushinteger(L, loc.x + 1);
2239  lua_rawseti(L, -2, 1);
2240 
2241  lua_pushinteger(L, loc.y + 1);
2242  lua_rawseti(L, -2, 2);
2243 
2244  lua_pushinteger(L, cost_map.get_pair_at(loc.x, loc.y).first);
2245  lua_rawseti(L, -2, 3);
2246 
2247  lua_pushinteger(L, cost_map.get_pair_at(loc.x, loc.y).second);
2248  lua_rawseti(L, -2, 4);
2249 
2250  lua_rawseti(L, -2, counter);
2251  ++counter;
2252  }
2253  return 1;
2254 }
2255 
2257 {
2258  vconfig cfg(luaW_checkvconfig(L, 1));
2259 
2260  const game_events::queued_event &event_info = get_event_info();
2261 
2262  unit_map & temp = units();
2263  unit_map* units = & temp;
2264 
2265  const vconfig & healers_filter = cfg.child("filter_second");
2266  std::vector<unit*> healers;
2267  if (!healers_filter.null()) {
2268  const unit_filter ufilt(healers_filter, &game_state_);
2269  for (unit& u : *units) {
2270  if ( ufilt(u) && u.has_ability_type("heals") ) {
2271  healers.push_back(&u);
2272  }
2273  }
2274  }
2275 
2276  const config::attribute_value amount = cfg["amount"];
2277  const config::attribute_value moves = cfg["moves"];
2278  const bool restore_attacks = cfg["restore_attacks"].to_bool(false);
2279  const bool restore_statuses = cfg["restore_statuses"].to_bool(true);
2280  const bool animate = cfg["animate"].to_bool(false);
2281 
2282  const vconfig & healed_filter = cfg.child("filter");
2283  bool only_unit_at_loc1 = healed_filter.null();
2284  bool heal_amount_to_set = true;
2285 
2286  const unit_filter ufilt(healed_filter, &game_state_);
2287  for(unit_map::unit_iterator u = units->begin(); u != units->end(); ++u) {
2288  if (only_unit_at_loc1)
2289  {
2290  u = units->find(event_info.loc1);
2291  if(!u.valid()) return 0;
2292  }
2293  else if ( !ufilt(*u) ) continue;
2294 
2295  int heal_amount = u->max_hitpoints() - u->hitpoints();
2296  if(amount.blank() || amount == "full") u->set_hitpoints(u->max_hitpoints());
2297  else {
2298  heal_amount = lexical_cast_default<int, config::attribute_value> (amount, heal_amount);
2299  const int new_hitpoints = std::max(1, std::min(u->max_hitpoints(), u->hitpoints() + heal_amount));
2300  heal_amount = new_hitpoints - u->hitpoints();
2301  u->set_hitpoints(new_hitpoints);
2302  }
2303 
2304  if(!moves.blank()) {
2305  if(moves == "full") u->set_movement(u->total_movement());
2306  else {
2307  // set_movement doesn't set below 0
2308  u->set_movement(std::min<int>(
2309  u->total_movement(),
2310  u->movement_left() + lexical_cast_default<int, config::attribute_value> (moves, 0)
2311  ));
2312  }
2313  }
2314 
2315  if(restore_attacks) u->set_attacks(u->max_attacks());
2316 
2317  if(restore_statuses)
2318  {
2319  u->set_state(unit::STATE_POISONED, false);
2320  u->set_state(unit::STATE_SLOWED, false);
2321  u->set_state(unit::STATE_PETRIFIED, false);
2322  u->set_state(unit::STATE_UNHEALABLE, false);
2323  u->anim_comp().set_standing();
2324  }
2325 
2326  if (heal_amount_to_set)
2327  {
2328  heal_amount_to_set = false;
2329  gamedata().get_variable("heal_amount") = heal_amount;
2330  }
2331 
2332  if(animate) unit_display::unit_healing(*u, healers, heal_amount);
2333  if(only_unit_at_loc1) return 0;
2334  }
2335  return 0;
2336 }
2337 
2339  vconfig cfg(luaW_checkvconfig(L, 1));
2340 
2341  // Remove any old message.
2342  static int floating_label = 0;
2343  if (floating_label)
2344  font::remove_floating_label(floating_label);
2345 
2346  // Display a message on-screen
2347  std::string text = cfg["text"];
2348  if(text.empty() || !game_display_)
2349  return 0;
2350 
2351  int size = cfg["size"].to_int(font::SIZE_SMALL);
2352  int lifetime = cfg["duration"].to_int(50);
2353 
2354  SDL_Color color = font::LABEL_COLOR;
2355 
2356  if(!cfg["color"].empty()) {
2357  color = string_to_color(cfg["color"]);
2358  } else if(cfg.has_attribute("red") || cfg.has_attribute("green") || cfg.has_attribute("blue")) {
2359  color = create_color(cfg["red"], cfg["green"], cfg["blue"]);
2360  }
2361 
2362  const SDL_Rect& rect = game_display_->map_outside_area();
2363 
2364  font::floating_label flabel(text);
2365  flabel.set_font_size(size);
2366  flabel.set_color(color);
2367  flabel.set_position(rect.w/2,rect.h/2);
2368  flabel.set_lifetime(lifetime);
2369  flabel.set_clip_rect(rect);
2370 
2371  floating_label = font::add_floating_label(flabel);
2372 
2373  return 0;
2374 }
2375 
2376 /**
2377  * Places a unit on the map.
2378  * - Arg 1: (optional) location.
2379  * - Arg 2: Unit (WML table or proxy), or nothing/nil to delete.
2380  * OR
2381  * - Arg 1: Unit (WML table or proxy)
2382  * - Arg 2: (optional) location
2383  * - Arg 3: (optional) boolean
2384  */
2386 {
2387  if(map_locked_) {
2388  return luaL_error(L, "Attempted to move a unit while the map is locked");
2389  }
2390  int unit_arg = 1;
2391 
2392  lua_unit *lu = nullptr;
2393  unit_ptr u = unit_ptr();
2394  map_location loc;
2395  if (lua_isnumber(L, 1)) {
2396  // Since this form is deprecated, I didn't bother updating it to luaW_tolocation.
2397  unit_arg = 3;
2398  loc.x = lua_tointeger(L, 1) - 1;
2399  loc.y = luaL_checkinteger(L, 2) - 1;
2400  if (!map().on_board(loc)) {
2401  return luaL_argerror(L, 1, "invalid location");
2402  }
2403  } else if (luaW_tolocation(L, 2, loc)) {
2404  if (!map().on_board(loc)) {
2405  return luaL_argerror(L, 2, "invalid location");
2406  }
2407  }
2408 
2409  if (luaW_hasmetatable(L, unit_arg, getunitKey))
2410  {
2411  lu = static_cast<lua_unit *>(lua_touserdata(L, unit_arg));
2412  u = lu->get_shared();
2413  if (!u) return luaL_argerror(L, unit_arg, "unit not found");
2414  if (lu->on_map() && (unit_arg == 1 || u->get_location() == loc)) {
2415  return 0;
2416  }
2417  if (!loc.valid()) {
2418  loc = u->get_location();
2419  if (!map().on_board(loc))
2420  return luaL_argerror(L, 1, "invalid location");
2421  } else if (unit_arg != 1) {
2422  WRN_LUA << "wesnoth.put_unit(x, y, unit) is deprecated. Use wesnoth.put_unit(unit, x, y) instead\n";
2423  }
2424  }
2425  else if (!lua_isnoneornil(L, unit_arg))
2426  {
2427  config cfg = luaW_checkconfig(L, unit_arg);
2428  if (unit_arg == 1 && !map().on_board(loc)) {
2429  loc.x = cfg["x"] - 1;
2430  loc.y = cfg["y"] - 1;
2431  if (!map().on_board(loc))
2432  return luaL_argerror(L, 2, "invalid location");
2433  } else if (unit_arg != 1) {
2434  WRN_LUA << "wesnoth.put_unit(x, y, unit) is deprecated. Use wesnoth.put_unit(unit, x, y) instead\n";
2435  }
2436  u = unit_ptr (new unit(cfg, true));
2437  }
2438 
2439  if (game_display_) {
2440  game_display_->invalidate(loc);
2441  }
2442 
2443  if (!u) {
2444  if (unit_arg == 3) {
2445  WRN_LUA << "wesnoth.put_unit(x, y) is deprecated. Use wesnoth.erase_unit(x, y) instead\n";
2446  units().erase(loc);
2447  }
2448  return 0;
2449  }
2450  units().erase(loc);
2451 
2452  if (lu) {
2453  lu->put_map(loc);
2454  lu->get_shared()->anim_comp().set_standing();
2455  } else {
2456  u->set_location(loc);
2457  units().insert(u);
2458  }
2459  if(unit_arg != 1 || luaW_toboolean(L, 3)) {
2460  play_controller_.pump().fire("unit placed", loc);
2461  }
2462  return 0;
2463 }
2464 
2465 /**
2466  * Erases a unit from the map
2467  * - Arg 1: Unit to erase OR Location to erase unit
2468  */
2470 {
2471  if(map_locked_) {
2472  return luaL_error(L, "Attempted to remove a unit while the map is locked");
2473  }
2474  map_location loc;
2475 
2476  if (luaW_hasmetatable(L, 1, getunitKey)) {
2477  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
2478  unit_ptr u = lu->get_shared();
2479  if (!lu->get()) {
2480  return luaL_argerror(L, 1, "unit not found");
2481  }
2482  if (lu->on_map()) {
2483  loc = u->get_location();
2484  if (!map().on_board(loc)) {
2485  return luaL_argerror(L, 1, "invalid location");
2486  }
2487  } else if (int side = lu->on_recall_list()) {
2488  team &t = teams()[side - 1];
2489  // Should it use underlying ID instead?
2490  t.recall_list().erase_if_matches_id(u->id());
2491  } else {
2492  return luaL_argerror(L, 1, "can't erase private units");
2493  }
2494  } else if (luaW_tolocation(L, 1, loc)) {
2495  if (!map().on_board(loc)) {
2496  return luaL_argerror(L, 1, "invalid location");
2497  }
2498  } else if (!lua_isnoneornil(L, 1)) {
2499  config cfg = luaW_checkconfig(L, 1);
2500  loc.x = cfg["x"] - 1;
2501  loc.y = cfg["y"] - 1;
2502  if (!map().on_board(loc)) {
2503  return luaL_argerror(L, 1, "invalid location");
2504  }
2505  } else {
2506  return luaL_argerror(L, 1, "expected unit or integer");
2507  }
2508 
2509  units().erase(loc);
2510  return 0;
2511 }
2512 
2513 /**
2514  * Puts a unit on a recall list.
2515  * - Arg 1: WML table or unit.
2516  * - Arg 2: (optional) side.
2517  */
2519 {
2520  if(map_locked_) {
2521  return luaL_error(L, "Attempted to move a unit while the map is locked");
2522  }
2523  lua_unit *lu = nullptr;
2524  unit_ptr u = unit_ptr();
2525  int side = lua_tointeger(L, 2);
2526  if (unsigned(side) > teams().size()) side = 0;
2527 
2528  if (luaW_hasmetatable(L, 1, getunitKey))
2529  {
2530  lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
2531  u = lu->get_shared();
2532  if (!u || lu->on_recall_list())
2533  return luaL_argerror(L, 1, "unit not found");
2534  }
2535  else
2536  {
2537  config cfg = luaW_checkconfig(L, 1);
2538  u = unit_ptr(new unit(cfg, true));
2539  }
2540 
2541  if (!side) side = u->side();
2542  team &t = teams()[side - 1];
2543  // Avoid duplicates in the recall list.
2544  size_t uid = u->underlying_id();
2546  t.recall_list().add(u);
2547  if (lu) {
2548  if (lu->on_map())
2549  units().erase(u->get_location());
2550  lu->lua_unit::~lua_unit();
2551  new(lu) lua_unit(side, uid);
2552  }
2553 
2554  return 0;
2555 }
2556 
2557 /**
2558  * Extracts a unit from the map or a recall list and gives it to Lua.
2559  * - Arg 1: unit userdata.
2560  */
2562 {
2563  if(map_locked_) {
2564  return luaL_error(L, "Attempted to remove a unit while the map is locked");
2565  }
2566  if (!luaW_hasmetatable(L, 1, getunitKey))
2567  return luaL_typerror(L, 1, "unit");
2568  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
2569  unit_ptr u = lu->get_shared();
2570  if (!u) return luaL_argerror(L, 1, "unit not found");
2571 
2572  if (lu->on_map()) {
2573  u = units().extract(u->get_location());
2574  assert(u);
2575  u->anim_comp().clear_haloes();
2576  } else if (int side = lu->on_recall_list()) {
2577  team &t = teams()[side - 1];
2578  unit_ptr v = unit_ptr(new unit(*u));
2579  t.recall_list().erase_if_matches_id(u->id());
2580  u = v;
2581  } else {
2582  return 0;
2583  }
2584 
2585  lu->lua_unit::~lua_unit();
2586  new(lu) lua_unit(u);
2587  return 0;
2588 }
2589 
2590 /**
2591  * Finds a vacant tile.
2592  * - Arg 1: location.
2593  * - Arg 2: optional unit for checking movement type.
2594  * - Rets 1,2: location.
2595  */
2597 {
2598  map_location loc = luaW_checklocation(L, 1);
2599 
2600  unit_ptr u = unit_ptr();
2601  if (!lua_isnoneornil(L, 2)) {
2602  if (luaW_hasmetatable(L, 2, getunitKey)) {
2603  u = static_cast<lua_unit *>(lua_touserdata(L, 2))->get_shared();
2604  } else {
2605  config cfg = luaW_checkconfig(L, 2);
2606  u.reset(new unit(cfg, false));
2607  }
2608  }
2609 
2611 
2612  if (!res.valid()) return 0;
2613  lua_pushinteger(L, res.x + 1);
2614  lua_pushinteger(L, res.y + 1);
2615  return 2;
2616 }
2617 
2618 /**
2619  * Floats some text on the map.
2620  * - Arg 1: location.
2621  * - Arg 2: string.
2622  * - Arg 3: color.
2623  */
2625 {
2626  map_location loc = luaW_checklocation(L, 1);
2627  SDL_Color color = font::LABEL_COLOR;
2628 
2629  t_string text = luaW_checktstring(L, 2);
2630  if (!lua_isnoneornil(L, 3)) {
2631  color = string_to_color(luaL_checkstring(L, 3));
2632  }
2633 
2634  if (game_display_) {
2635  game_display_->float_label(loc, text, color);
2636  }
2637  return 0;
2638 }
2639 
2640 /**
2641  * Creates a unit from its WML description.
2642  * - Arg 1: WML table.
2643  * - Ret 1: unit userdata.
2644  */
2646 {
2647  config cfg = luaW_checkconfig(L, 1);
2648  unit_ptr u = unit_ptr(new unit(cfg, true));
2649  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(u);
2651  , getunitKey);
2653  lua_setmetatable(L, -2);
2654  return 1;
2655 }
2656 
2657 /**
2658  * Copies a unit.
2659  * - Arg 1: unit userdata.
2660  * - Ret 1: unit userdata.
2661  */
2663 {
2664  unit& u = luaW_checkunit(L, 1);
2665  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(unit_ptr(new unit(u)));
2667  , getunitKey);
2669  lua_setmetatable(L, -2);
2670  return 1;
2671 }
2672 
2673 /**
2674  * Returns unit resistance against a given attack type.
2675  * - Arg 1: unit userdata.
2676  * - Arg 2: string containing the attack type.
2677  * - Arg 3: boolean indicating if attacker.
2678  * - Arg 4: optional location.
2679  * - Ret 1: integer.
2680  */
2682 {
2683  const unit& u = luaW_checkunit(L, 1);
2684  char const *m = luaL_checkstring(L, 2);
2685  bool a = luaW_toboolean(L, 3);
2686 
2687  map_location loc = u.get_location();
2688  if (!lua_isnoneornil(L, 4)) {
2689  loc = luaW_checklocation(L, 4);
2690  }
2691 
2692  lua_pushinteger(L, u.resistance_against(m, a, loc));
2693  return 1;
2694 }
2695 
2696 /**
2697  * Returns unit movement cost on a given terrain.
2698  * - Arg 1: unit userdata.
2699  * - Arg 2: string containing the terrain type.
2700  * - Ret 1: integer.
2701  */
2703 {
2704  const unit& u = luaW_checkunit(L, 1);
2705  char const *m = luaL_checkstring(L, 2);
2707  lua_pushinteger(L, u.movement_cost(t));
2708  return 1;
2709 }
2710 
2711 /**
2712  * Returns unit vision cost on a given terrain.
2713  * - Arg 1: unit userdata.
2714  * - Arg 2: string containing the terrain type.
2715  * - Ret 1: integer.
2716  */
2718 {
2719  const unit& u = luaW_checkunit(L, 1);
2720  char const *m = luaL_checkstring(L, 2);
2722  lua_pushinteger(L, u.vision_cost(t));
2723  return 1;
2724 }
2725 
2726 /**
2727  * Returns unit jamming cost on a given terrain.
2728  * - Arg 1: unit userdata.
2729  * - Arg 2: string containing the terrain type.
2730  * - Ret 1: integer.
2731  */
2733 {
2734  const unit& u = luaW_checkunit(L, 1);
2735  char const *m = luaL_checkstring(L, 2);
2737  lua_pushinteger(L, u.jamming_cost(t));
2738  return 1;
2739 }
2740 
2741 /**
2742  * Returns unit defense on a given terrain.
2743  * - Arg 1: unit userdata.
2744  * - Arg 2: string containing the terrain type.
2745  * - Ret 1: integer.
2746  */
2748 {
2749  const unit& u = luaW_checkunit(L, 1);
2750  char const *m = luaL_checkstring(L, 2);
2753  return 1;
2754 }
2755 
2756 /**
2757  * Returns true if the unit has the given ability enabled.
2758  * - Arg 1: unit userdata.
2759  * - Arg 2: string.
2760  * - Ret 1: boolean.
2761  */
2763 {
2764  const unit& u = luaW_checkunit(L, 1);
2765  char const *m = luaL_checkstring(L, 2);
2767  return 1;
2768 }
2769 
2770 /**
2771  * Changes a unit to the given unit type.
2772  * - Arg 1: unit userdata.
2773  * - Arg 2: string.
2774  */
2776 {
2777  unit& u = luaW_checkunit(L, 1);
2778  char const *m = luaL_checkstring(L, 2);
2779  const unit_type *utp = unit_types.find(m);
2780  if (!utp) return luaL_argerror(L, 2, "unknown unit type");
2781  u.advance_to(*utp);
2782 
2783  return 0;
2784 }
2785 
2786 /**
2787  * Puts a table at the top of the stack with some combat result.
2788  */
2789 static void luaW_pushsimdata(lua_State *L, const combatant &cmb)
2790 {
2791  int n = cmb.hp_dist.size();
2792  lua_createtable(L, 0, 4);
2793  lua_pushnumber(L, cmb.poisoned);
2794  lua_setfield(L, -2, "poisoned");
2795  lua_pushnumber(L, cmb.slowed);
2796  lua_setfield(L, -2, "slowed");
2797  lua_pushnumber(L, cmb.average_hp());
2798  lua_setfield(L, -2, "average_hp");
2799  lua_createtable(L, n, 0);
2800  for (int i = 0; i < n; ++i) {
2801  lua_pushnumber(L, cmb.hp_dist[i]);
2802  lua_rawseti(L, -2, i);
2803  }
2804  lua_setfield(L, -2, "hp_chance");
2805 }
2806 
2807 /**
2808  * Puts a table at the top of the stack with information about the combatants' weapons.
2809  */
2811 {
2812 
2813  lua_createtable(L, 0, 16);
2814 
2815  lua_pushnumber(L, bcustats.num_blows);
2816  lua_setfield(L, -2, "num_blows");
2817  lua_pushnumber(L, bcustats.damage);
2818  lua_setfield(L, -2, "damage");
2819  lua_pushnumber(L, bcustats.chance_to_hit);
2820  lua_setfield(L, -2, "chance_to_hit");
2821  lua_pushboolean(L, bcustats.poisons);
2822  lua_setfield(L, -2, "poisons");
2823  lua_pushboolean(L, bcustats.slows);
2824  lua_setfield(L, -2, "slows");
2825  lua_pushboolean(L, bcustats.petrifies);
2826  lua_setfield(L, -2, "petrifies");
2827  lua_pushboolean(L, bcustats.plagues);
2828  lua_setfield(L, -2, "plagues");
2829  lua_pushstring(L, bcustats.plague_type.c_str());
2830  lua_setfield(L, -2, "plague_type");
2831  lua_pushboolean(L, bcustats.backstab_pos);
2832  lua_setfield(L, -2, "backstabs");
2833  lua_pushnumber(L, bcustats.rounds);
2834  lua_setfield(L, -2, "rounds");
2835  lua_pushboolean(L, bcustats.firststrike);
2836  lua_setfield(L, -2, "firststrike");
2837  lua_pushboolean(L, bcustats.drains);
2838  lua_setfield(L, -2, "drains");
2839  lua_pushnumber(L, bcustats.drain_constant);
2840  lua_setfield(L, -2, "drain_constant");
2841  lua_pushnumber(L, bcustats.drain_percent);
2842  lua_setfield(L, -2, "drain_percent");
2843 
2844 
2845  //if we called simulate_combat without giving an explicit weapon this can be useful.
2846  lua_pushnumber(L, bcustats.attack_num);
2847  lua_setfield(L, -2, "attack_num");
2848  //this is nullptr when there is no counter weapon
2849  if(bcustats.weapon != nullptr)
2850  {
2851  lua_pushstring(L, bcustats.weapon->id().c_str());
2852  lua_setfield(L, -2, "name");
2853  }
2854 
2855 }
2856 
2857 /**
2858  * Simulates a combat between two units.
2859  * - Arg 1: attacker userdata.
2860  * - Arg 2: optional weapon index.
2861  * - Arg 3: defender userdata.
2862  * - Arg 4: optional weapon index.
2863  * - Ret 1: attacker results.
2864  * - Ret 2: defender results.
2865  * - Ret 3: info about the attacker weapon.
2866  * - Ret 4: info about the defender weapon.
2867  */
2869 {
2870  int arg_num = 1, att_w = -1, def_w = -1;
2871 
2872  const unit& att = luaW_checkunit(L, arg_num);
2873  ++arg_num;
2874  if (lua_isnumber(L, arg_num)) {
2875  att_w = lua_tointeger(L, arg_num) - 1;
2876  if (att_w < 0 || att_w >= int(att.attacks().size()))
2877  return luaL_argerror(L, arg_num, "weapon index out of bounds");
2878  ++arg_num;
2879  }
2880 
2881  const unit& def = luaW_checkunit(L, arg_num, true);
2882  ++arg_num;
2883  if (lua_isnumber(L, arg_num)) {
2884  def_w = lua_tointeger(L, arg_num) - 1;
2885  if (def_w < 0 || def_w >= int(def.attacks().size()))
2886  return luaL_argerror(L, arg_num, "weapon index out of bounds");
2887  ++arg_num;
2888  }
2889 
2890  battle_context context(units(), att.get_location(),
2891  def.get_location(), att_w, def_w, 0.0, nullptr, &att);
2892 
2893  luaW_pushsimdata(L, context.get_attacker_combatant());
2894  luaW_pushsimdata(L, context.get_defender_combatant());
2895  luaW_pushsimweapon(L, context.get_attacker_stats());
2896  luaW_pushsimweapon(L, context.get_defender_stats());
2897  return 4;
2898 }
2899 
2900 /**
2901  * Modifies the music playlist.
2902  * - Arg 1: WML table, or nil to force changes.
2903  */
2905 {
2906  if (lua_isnoneornil(L, 1)) {
2908  return 0;
2909  }
2910 
2911  config cfg = luaW_checkconfig(L, 1);
2913  return 0;
2914 }
2915 
2916 /**
2917  * Plays a sound, possibly repeated.
2918  * - Arg 1: string.
2919  * - Arg 2: optional integer.
2920  */
2922 {
2923  char const *m = luaL_checkstring(L, 1);
2924  if (play_controller_.is_skipping_replay()) return 0;
2925  int repeats = lua_tointeger(L, 2);
2926  sound::play_sound(m, sound::SOUND_FX, repeats);
2927  return 0;
2928 }
2929 
2930 /**
2931  * Scrolls to given tile.
2932  * - Arg 1: location.
2933  * - Arg 2: boolean preventing scroll to fog.
2934  * - Arg 3: boolean specifying whether to warp instantly.
2935  */
2937 {
2938  map_location loc = luaW_checklocation(L, 1);
2939  bool check_fogged = luaW_toboolean(L, 2);
2940  bool immediate = luaW_toboolean(L, 3);
2941  if (game_display_) {
2943  immediate ? game_display::WARP : game_display::SCROLL, check_fogged);
2944  }
2945  return 0;
2946 }
2947 
2949 {
2950  ERR_LUA << "wesnoth.select_hex is deprecated, use wesnoth.select_unit and/or wesnoth.highlight_hex" << std::endl;
2951 
2952  // Need this because check_location may change the stack
2953  // By doing this now, we ensure that it won't do so when
2954  // intf_select_unit and intf_highlight_hex call it.
2955  const map_location loc = luaW_checklocation(L, 1);
2956  luaW_pushlocation(L, loc);
2957  lua_replace(L, 1);
2958 
2959  intf_select_unit(L);
2960  if(!lua_isnoneornil(L, 2) && luaW_toboolean(L,2)) {
2961  intf_highlight_hex(L);
2962  }
2963  return 0;
2964 }
2965 
2966 /**
2967  * Selects and highlights the given location on the map.
2968  * - Arg 1: location.
2969  * - Args 2,3: booleans
2970  */
2972 {
2973  const map_location loc = luaW_checklocation(L, 1);
2974  if(!map().on_board(loc)) return luaL_argerror(L, 1, "not on board");
2975  bool highlight = true;
2976  if(!lua_isnoneornil(L, 2))
2977  highlight = luaW_toboolean(L, 2);
2978  const bool fire_event = luaW_toboolean(L, 3);
2980  loc, false, highlight, fire_event);
2981  return 0;
2982 }
2983 
2984 /**
2985  * Deselects any highlighted hex on the map.
2986  * No arguments or return values
2987  */
2989 {
2990  const map_location loc;
2992  loc, false, false, false);
2993  if (game_display_) {
2995  }
2996  return 0;
2997 }
2998 
2999 /**
3000  * Return true if a replay is in progress but the player has chosen to skip it
3001  */
3003 {
3004  bool skipping = play_controller_.is_skipping_replay();
3005  if (!skipping) {
3006  skipping = game_state_.events_manager_->pump().context_skip_messages();
3007  }
3008  lua_pushboolean(L, skipping);
3009  return 1;
3010 }
3011 
3012 /**
3013  * Set whether to skip messages
3014  * Arg 1 (optional) - boolean
3015  */
3017 {
3018  bool skip = true;
3019  if (!lua_isnone(L, 1)) {
3020  skip = luaW_toboolean(L, 1);
3021  }
3022  game_state_.events_manager_->pump().context_skip_messages(skip);
3023  return 0;
3024 }
3025 
3026 namespace
3027 {
3028  struct lua_synchronize : mp_sync::user_choice
3029  {
3030  lua_State *L;
3031  int user_choice_index;
3032  int random_choice_index;
3033  int ai_choice_index;
3034  std::string desc;
3035  lua_synchronize(lua_State *l, const std::string& descr, int user_index, int random_index = 0, int ai_index = 0)
3036  : L(l)
3037  , user_choice_index(user_index)
3038  , random_choice_index(random_index)
3039  , ai_choice_index(ai_index != 0 ? ai_index : user_index)
3040  , desc(descr)
3041  {}
3042 
3043  virtual config query_user(int side) const
3044  {
3045  bool is_local_ai = lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).teams()[side - 1].is_local_ai();
3046  config cfg;
3047  query_lua(side, is_local_ai ? ai_choice_index : user_choice_index, cfg);
3048  return cfg;
3049  }
3050 
3051  virtual config random_choice(int side) const
3052  {
3053  config cfg;
3054  if(random_choice_index != 0 && lua_isfunction(L, random_choice_index)) {
3055  query_lua(side, random_choice_index, cfg);
3056  }
3057  return cfg;
3058  }
3059 
3060  virtual std::string description() const override
3061  {
3062  return desc;
3063  }
3064 
3065  void query_lua(int side, int function_index, config& cfg) const
3066  {
3067  assert(cfg.empty());
3068  lua_pushvalue(L, function_index);
3069  lua_pushnumber(L, side);
3070  if (luaW_pcall(L, 1, 1, false)) {
3071  if(!luaW_toconfig(L, -1, cfg)) {
3072  lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).log_error("function returned to wesnoth.synchronize_choice a table which was partially invalid");
3073  }
3074  }
3075  }
3076  //Although luas sync_choice can show a dialog, (and will in most cases)
3077  //we return false to enable other possible things that do not contain UI things.
3078  //it's in the responsibility of the umc dev to not show dialogs during prestart events.
3079  virtual bool is_visible() const { return false; }
3080  };
3081 }//unnamed namespace for lua_synchronize
3082 
3083 /**
3084  * Ensures a value is synchronized among all the clients.
3085  * - Arg 1: optional string specifying the type id of the choice.
3086  * - Arg 2: function to compute the value, called if the client is the master.
3087  * - Arg 3: optional function, called instead of the first function if the user is not human.
3088  * - Arg 4: optional integer specifying, on which side the function should be evaluated.
3089  * - Ret 1: WML table returned by the function.
3090  */
3092 {
3093  std::string tagname = "input";
3094  t_string desc = _("input");
3095  int human_func = 0;
3096  int ai_func = 0;
3097  int side_for;
3098 
3099  int nextarg = 1;
3100  if(!lua_isfunction(L, nextarg) && luaW_totstring(L, nextarg, desc) ) {
3101  ++nextarg;
3102  }
3103  if(lua_isfunction(L, nextarg)) {
3104  human_func = nextarg++;
3105  }
3106  else {
3107  return luaL_argerror(L, nextarg, "expected a function");
3108  }
3109  if(lua_isfunction(L, nextarg)) {
3110  ai_func = nextarg++;
3111  }
3112  side_for = lua_tointeger(L, nextarg);
3113 
3114  config cfg = mp_sync::get_user_choice(tagname, lua_synchronize(L, desc, human_func, 0, ai_func), side_for);
3115  luaW_pushconfig(L, cfg);
3116  return 1;
3117 }
3118 /**
3119  * Ensures a value is synchronized among all the clients.
3120  * - Arg 1: optional string the id of this type of user input, may only contain chracters a-z and '_'
3121  * - Arg 2: function to compute the value, called if the client is the master.
3122  * - Arg 3: an optional function to compute the value, if the side was null/empty controlled.
3123  * - Arg 4: an array of integers specifying, on which side the function should be evaluated.
3124  * - Ret 1: a map int -> WML tabls.
3125  */
3127 {
3128  std::string tagname = "input";
3129  t_string desc = _("input");
3130  int human_func = 0;
3131  int null_func = 0;
3132  std::vector<int> sides_for;
3133 
3134  int nextarg = 1;
3135  if(!lua_isfunction(L, nextarg) && luaW_totstring(L, nextarg, desc) ) {
3136  ++nextarg;
3137  }
3138  if(lua_isfunction(L, nextarg)) {
3139  human_func = nextarg++;
3140  }
3141  else {
3142  return luaL_argerror(L, nextarg, "expected a function");
3143  }
3144  if(lua_isfunction(L, nextarg)) {
3145  null_func = nextarg++;
3146  };
3147  sides_for = lua_check<std::vector<int> >(L, nextarg++);
3148 
3149  lua_push(L, mp_sync::get_user_choice_multiple_sides(tagname, lua_synchronize(L, desc, human_func, null_func), std::set<int>(sides_for.begin(), sides_for.end())));
3150  return 1;
3151 }
3152 
3153 
3154 /**
3155  * Calls a function in an unsynced context (this specially means that all random calls used by that function will be unsynced).
3156  * This is usualy used together with an unsynced if like 'if controller != network'
3157  * - Arg 1: function that will be called during the unsynced context.
3158  */
3160 {
3161  set_scontext_unsynced sync;
3162  lua_pushvalue(L, 1);
3163  luaW_pcall(L, 0, 0, false);
3164  return 0;
3165 }
3166 
3167 /**
3168  * Gets all the locations matching a given filter.
3169  * - Arg 1: WML table.
3170  * - Ret 1: array of integer pairs.
3171  */
3173 {
3175 
3176  std::set<map_location> res;
3177  filter_context & fc = game_state_;
3178  const terrain_filter t_filter(filter, &fc);
3179  t_filter.get_locations(res, true);
3180 
3181  lua_createtable(L, res.size(), 0);
3182  int i = 1;
3183  for (map_location const &loc : res)
3184  {
3185  lua_createtable(L, 2, 0);
3186  lua_pushinteger(L, loc.x + 1);
3187  lua_rawseti(L, -2, 1);
3188  lua_pushinteger(L, loc.y + 1);
3189  lua_rawseti(L, -2, 2);
3190  lua_rawseti(L, -2, i);
3191  ++i;
3192  }
3193  return 1;
3194 }
3195 
3196 /**
3197  * Gets all the villages matching a given filter, or all the villages on the map if no filter is given.
3198  * - Arg 1: WML table (optional).
3199  * - Ret 1: array of integer pairs.
3200  */
3202 {
3203  std::vector<map_location> locs = map().villages();
3204  lua_newtable(L);
3205  int i = 1;
3206 
3208 
3209  filter_context & fc = game_state_;
3210  for(std::vector<map_location>::const_iterator it = locs.begin(); it != locs.end(); ++it) {
3211  bool matches = terrain_filter(filter, &fc).match(*it);
3212  if (matches) {
3213  lua_createtable(L, 2, 0);
3214  lua_pushinteger(L, it->x + 1);
3215  lua_rawseti(L, -2, 1);
3216  lua_pushinteger(L, it->y + 1);
3217  lua_rawseti(L, -2, 2);
3218  lua_rawseti(L, -2, i);
3219  ++i;
3220  }
3221  }
3222  return 1;
3223 }
3224 
3225 /**
3226  * Matches a location against the given filter.
3227  * - Arg 1: location.
3228  * - Arg 2: WML table.
3229  * - Ret 1: boolean.
3230  */
3232 {
3233  map_location loc = luaW_checklocation(L, 1);
3234  vconfig filter = luaW_checkvconfig(L, 2, true);
3235 
3236  if (filter.null()) {
3237  lua_pushboolean(L, true);
3238  return 1;
3239  }
3240 
3241  filter_context & fc = game_state_;
3242  const terrain_filter t_filter(filter, &fc);
3243  lua_pushboolean(L, t_filter.match(loc));
3244  return 1;
3245 }
3246 
3247 
3248 
3249 /**
3250  * Matches a side against the given filter.
3251  * - Args 1: side number.
3252  * - Arg 2: WML table.
3253  * - Ret 1: boolean.
3254  */
3256 {
3257  unsigned side = luaL_checkinteger(L, 1) - 1;
3258  if (side >= teams().size()) return 0;
3259  vconfig filter = luaW_checkvconfig(L, 2, true);
3260 
3261  if (filter.null()) {
3262  lua_pushboolean(L, true);
3263  return 1;
3264  }
3265 
3266  filter_context & fc = game_state_;
3267  side_filter s_filter(filter, &fc);
3268  lua_pushboolean(L, s_filter.match(side + 1));
3269  return 1;
3270 }
3271 
3273 {
3274  vconfig cfg(luaW_checkvconfig(L, 1));
3275 
3276  side_filter ssf(cfg, &game_state_);
3277  std::vector<int> sides = ssf.get_teams();
3278  for (const int &side_num : sides)
3279  {
3281  }
3282  return 0;
3283 }
3284 
3286 {
3287  vconfig cfg(luaW_checkvconfig(L, 1));
3288 
3289  bool invalidate_screen = false;
3290 
3291  std::string team_name = cfg["team_name"];
3292  std::string user_team_name = cfg["user_team_name"];
3293  std::string controller = cfg["controller"];
3294  std::string defeat_condition = cfg["defeat_condition"];
3295  std::string recruit_str = cfg["recruit"];
3296  std::string shroud_data = cfg["shroud_data"];
3297  std::string village_support = cfg["village_support"];
3298  const config& parsed = cfg.get_parsed_config();
3299  const config::const_child_itors &ai = parsed.child_range("ai");
3300  std::string switch_ai = cfg["switch_ai"];
3301 
3302  std::vector<int> sides = get_sides_vector(cfg);
3303  size_t team_index;
3304 
3305  for(const int &side_num : sides)
3306  {
3307  team_index = side_num - 1;
3308 
3309  team & tm = teams()[team_index];
3310 
3311  LOG_LUA << "modifying side: " << side_num << "\n";
3312  if(!team_name.empty()) {
3313  LOG_LUA << "change side's team to team_name '" << team_name << "'\n";
3314  tm.change_team(team_name,
3315  user_team_name);
3316  } else if(!user_team_name.empty()) {
3317  LOG_LUA << "change side's user_team_name to '" << user_team_name << "'\n";
3318  tm.change_team(tm.team_name(),
3319  user_team_name);
3320  }
3321  // Modify recruit list (override)
3322  if (!recruit_str.empty()) {
3323  tm.set_recruits(utils::set_split(recruit_str));
3324  }
3325  // Modify income
3326  config::attribute_value income = cfg["income"];
3327  if (!income.empty()) {
3329  }
3330  // Modify total gold
3331  config::attribute_value gold = cfg["gold"];
3332  if (!gold.empty()) {
3333  tm.set_gold(gold);
3334  }
3335  // Set controller
3336  if (!controller.empty()) {
3337  tm.change_controller_by_wml(controller);
3338  }
3339  // Set defeat_condition
3340  if (!defeat_condition.empty()) {
3341  tm.set_defeat_condition_string(defeat_condition);
3342  }
3343  // Set shroud
3344  config::attribute_value shroud = cfg["shroud"];
3345  if (!shroud.empty()) {
3346  tm.set_shroud(shroud.to_bool(true));
3347  invalidate_screen = true;
3348  }
3349  // Reset shroud
3350  if ( cfg["reset_maps"].to_bool(false) ) {
3351  tm.reshroud();
3352  invalidate_screen = true;
3353  }
3354  // Merge shroud data
3355  if (!shroud_data.empty()) {
3356  tm.merge_shroud_map_data(shroud_data);
3357  invalidate_screen = true;
3358  }
3359  // Set whether team is hidden in status table
3360  config::attribute_value hidden = cfg["hidden"];
3361  if (!hidden.empty()) {
3362  tm.set_hidden(hidden.to_bool(true));
3363  }
3364  // Set fog
3365  config::attribute_value fog = cfg["fog"];
3366  if (!fog.empty()) {
3367  tm.set_fog(fog.to_bool(true));
3368  invalidate_screen = true;
3369  }
3370  // Reset fog
3371  if ( cfg["reset_view"].to_bool(false) ) {
3372  tm.refog();
3373  invalidate_screen = true;
3374  }
3375  // Set income per village
3376  config::attribute_value village_gold = cfg["village_gold"];
3377  if (!village_gold.empty()) {
3378  tm.set_village_gold(village_gold);
3379  }
3380  // Set support (unit levels supported per village, for upkeep purposes)
3381  if (!village_support.empty()) {
3382  tm.set_village_support(lexical_cast_default<int>(village_support, game_config::village_support));
3383  }
3384  // Redeploy ai from location (this ignores current AI parameters)
3385  if (!switch_ai.empty()) {
3386  ai::manager::add_ai_for_side_from_file(side_num,switch_ai,true);
3387  }
3388  // Override AI parameters
3389  if (ai.first != ai.second) {
3391  }
3392  // Change team color
3393  config::attribute_value color = cfg["color"];
3394  if(!color.empty()) {
3395  tm.set_color(color);
3396  invalidate_screen = true;
3397  }
3398  // Change flag imageset
3399  config::attribute_value flag = cfg["flag"];
3400  if(!flag.empty()) {
3401  tm.set_flag(flag);
3402  // Needed especially when map isn't animated.
3403  invalidate_screen = true;
3404  }
3405  // If either the flag set or the team color changed, we need to
3406  // rebuild the team's flag cache to reflect the changes. Note that
3407  // this is not required for flag icons (used by the theme UI only).
3408  if((!color.empty() || !flag.empty()) && game_display_) {
3409  game_display_->reinit_flags_for_side(team_index);
3410  }
3411  // Change flag icon
3412  config::attribute_value flag_icon = cfg["flag_icon"];
3413  if(!flag_icon.empty()) {
3414  tm.set_flag_icon(flag_icon);
3415  // Not needed.
3416  //invalidate_screen = true;
3417  }
3419  // Suppress end turn confirmations?
3420  config::attribute_value setc = cfg["suppress_end_turn_confirmation"];
3421  if ( !setc.empty() ) {
3422  tm.set_no_turn_confirmation(setc.to_bool());
3423  }
3424 
3425  // Change leader scrolling options
3426  config::attribute_value stl = cfg["scroll_to_leader"];
3427  if ( !stl.empty()) {
3428  tm.set_scroll_to_leader(stl.to_bool(true));
3429  }
3430  }
3431 
3432  // Flag an update of the screen, if needed.
3433  if ( invalidate_screen && game_display_) {
3436  }
3437 
3438 
3439  return 0;
3440 }
3441 
3442 /**
3443  * Returns a proxy table array for all sides matching the given SSF.
3444  * - Arg 1: SSF
3445  * - Ret 1: proxy table array
3446  */
3448 {
3449  LOG_LUA << "intf_get_sides called: this = " << (formatter() << std::hex << this).str() << " myname = " << my_name() << std::endl;
3450  std::vector<int> sides;
3451  const vconfig ssf = luaW_checkvconfig(L, 1, true);
3452  if(ssf.null()){
3453  for(unsigned side_number = 1; side_number <= teams().size(); ++side_number)
3454  sides.push_back(side_number);
3455  } else {
3456  filter_context & fc = game_state_;
3457 
3458  side_filter filter(ssf, &fc);
3459  sides = filter.get_teams();
3460  }
3461 
3462  lua_settop(L, 0);
3463  lua_createtable(L, sides.size(), 0);
3464  unsigned index = 1;
3465  for(int side : sides) {
3466  luaW_pushteam(L, teams()[side - 1]);
3467  lua_rawseti(L, -2, index);
3468  ++index;
3469  }
3470 
3471  return 1;
3472 }
3473 
3474 /**
3475  * .Returns information about the global traits known to the engine.
3476  * - Ret 1: Table with named fields holding wml tables describing the traits.
3477  */
3479 {
3480  lua_newtable(L);
3481  for(const config& trait : unit_types.traits()) {
3482  const std::string& id = trait["id"];
3483  //It seems the engine does nowhere check the id field for emptyness or duplicates
3484  //(also not later on).
3485  //However, the worst thing to happen is that the trait read later overwrites the older one,
3486  //and this is not the right place for such checks.
3487  lua_pushstring(L, id.c_str());
3488  luaW_pushconfig(L, trait);
3489  lua_rawset(L, -3);
3490  }
3491  return 1;
3492 }
3493 
3494 /**
3495  * Adds a modification to a unit.
3496  * - Arg 1: unit.
3497  * - Arg 2: string.
3498  * - Arg 3: WML table.
3499  * - Arg 4: (optional) Whether to add to [modifications] - default true
3500  */
3502 {
3503  unit& u = luaW_checkunit(L, 1);
3504  char const *m = luaL_checkstring(L, 2);
3505  std::string sm = m;
3506  if (sm == "advance") { // Maintain backwards compatibility
3507  sm = "advancement";
3508  lg::wml_error() << "(Lua) Modifications of type \"advance\" are deprecated, use \"advancement\" instead\n";
3509  }
3510  if (sm != "advancement" && sm != "object" && sm != "trait") {
3511  return luaL_argerror(L, 2, "unknown modification type");
3512  }
3513  bool write_to_mods = true;
3514  if (!lua_isnone(L, 4)) {
3515  write_to_mods = luaW_toboolean(L, 4);
3516  }
3517 
3518  config cfg = luaW_checkconfig(L, 3);
3519  u.add_modification(sm, cfg, !write_to_mods);
3520  return 0;
3521 }
3522 
3523 /**
3524  * Advances a unit if the unit has enough xp.
3525  * - Arg 1: unit.
3526  * - Arg 2: optional boolean whether to animate the advancement.
3527  * - Arg 3: optional boolean whether to fire advancement events.
3528  */
3530 {
3531  //TODO: check whether the unit is on the map.
3532  unit& u = luaW_checkunit(L, 1, true);
3534  if(lua_isboolean(L, 2)) {
3535  par.animate(luaW_toboolean(L, 2));
3536  }
3537  if(lua_isboolean(L, 3)) {
3538  par.fire_events(luaW_toboolean(L, 3));
3539  }
3540  advance_unit_at(par);
3541  return 0;
3542 }
3543 
3544 
3545 /**
3546  * Adds a new known unit type to the help system.
3547  * - Arg 1: string.
3548  */
3550 {
3551  char const *ty = luaL_checkstring(L, 1);
3552  if(!unit_types.find(ty))
3553  {
3554  std::stringstream ss;
3555  ss << "unknown unit type: '" << ty << "'";
3556  return luaL_argerror(L, 1, ss.str().c_str());
3557  }
3558  preferences::encountered_units().insert(ty);
3559  return 0;
3560 }
3561 
3562 /**
3563  * Adds an overlay on a tile.
3564  * - Arg 1: location.
3565  * - Arg 2: WML table.
3566  */
3568 {
3569  map_location loc = luaW_checklocation(L, 1);
3570  config cfg = luaW_checkconfig(L, 2);
3571 
3572  if (game_display_) {
3573  game_display_->add_overlay(loc, cfg["image"], cfg["halo"],
3574  cfg["team_name"], cfg["name"], cfg["visible_in_fog"].to_bool(true));
3575  }
3576  return 0;
3577 }
3578 
3579 /**
3580  * Removes an overlay from a tile.
3581  * - Arg 1: location.
3582  * - Arg 2: optional string.
3583  */
3585 {
3586  map_location loc = luaW_checklocation(L, 1);
3587  char const *m = lua_tostring(L, 2);
3588 
3589  if (m) {
3590  if (game_display_) {
3592  }
3593  } else {
3594  if (game_display_) {
3596  }
3597  }
3598  return 0;
3599 }
3600 
3601 /// Adding new events
3603 {
3604  vconfig cfg(luaW_checkvconfig(L, 1));
3606 
3607  if (!cfg["delayed_variable_substitution"].to_bool(true)) {
3609  } else {
3610  man.add_event_handler(cfg.get_config());
3611  }
3612  return 0;
3613 }
3614 
3616 {
3617  game_state_.events_manager_->remove_event_handler(luaL_checkstring(L, 1));
3618  return 0;
3619 }
3620 
3622 {
3623  if (game_display_) {
3624  vconfig cfg(luaW_checkvconfig(L, 1));
3625 
3626  game_display_->adjust_color_overlay(cfg["red"], cfg["green"], cfg["blue"]);
3628  game_display_->draw(true,true);
3629  }
3630  return 0;
3631 }
3632 
3633 /**
3634  * Delays engine for a while.
3635  * - Arg 1: integer.
3636  * - Arg 2: boolean (optional).
3637  */
3639 {
3640  lua_Integer delay = luaL_checkinteger(L, 1);
3641  if(delay == 0) {
3643  return 0;
3644  }
3645  if(luaW_toboolean(L, 2) && game_display_ && game_display_->turbo_speed() > 0) {
3646  delay /= game_display_->turbo_speed();
3647  }
3648  const unsigned final = SDL_GetTicks() + delay;
3649  do {
3651  CVideo::delay(10);
3652  } while (int(final - SDL_GetTicks()) > 0);
3653  return 0;
3654 }
3655 
3656 namespace { // Types
3657 
3658  class recursion_preventer {
3659  typedef std::map<map_location, int> t_counter;
3660  static t_counter counter_;
3661  static const int max_recursion = 10;
3662 
3664  bool too_many_recursions_;
3665 
3666  public:
3667  recursion_preventer(map_location& loc) :
3668  loc_(loc),
3669  too_many_recursions_(false)
3670  {
3671  t_counter::iterator inserted = counter_.insert(std::make_pair(loc_, 0)).first;
3672  ++inserted->second;
3673  too_many_recursions_ = inserted->second >= max_recursion;
3674  }
3675  ~recursion_preventer()
3676  {
3677  t_counter::iterator itor = counter_.find(loc_);
3678  if (--itor->second == 0)
3679  {
3680  counter_.erase(itor);
3681  }
3682  }
3683  bool too_many_recursions() const
3684  {
3685  return too_many_recursions_;
3686  }
3687  };
3688  recursion_preventer::t_counter recursion_preventer::counter_;
3689  typedef boost::scoped_ptr<recursion_preventer> recursion_preventer_ptr;
3690 } // end anonymouse namespace (types)
3691 
3693 {
3694  vconfig cfg(luaW_checkvconfig(L, 1));
3695 
3696  const game_events::queued_event &event_info = get_event_info();
3697 
3698  size_t number_killed = 0;
3699 
3700  bool secondary_unit = cfg.has_child("secondary_unit");
3701  game_events::entity_location killer_loc(map_location(0, 0));
3702  if(cfg["fire_event"].to_bool() && secondary_unit)
3703  {
3704  secondary_unit = false;
3705  const unit_filter ufilt(cfg.child("secondary_unit"), &game_state_);
3707  if ( ufilt( *unit) )
3708  {
3709  killer_loc = game_events::entity_location(*unit);
3710  secondary_unit = true;
3711  break;
3712  }
3713  }
3714  if(!secondary_unit) {
3715  WRN_LUA << "failed to match [secondary_unit] in [kill] with a single on-board unit" << std::endl;
3716  }
3717  }
3718 
3719  //Find all the dead units first, because firing events ruins unit_map iteration
3720  std::vector<unit *> dead_men_walking;
3721  const unit_filter ufilt(cfg, &game_state_);
3722  for (unit & u : units()){
3723  if ( ufilt(u) ) {
3724  dead_men_walking.push_back(&u);
3725  }
3726  }
3727 
3728  for(unit * un : dead_men_walking) {
3729  map_location loc(un->get_location());
3730  bool fire_event = false;
3731  game_events::entity_location death_loc(*un);
3732  if(!secondary_unit) {
3733  killer_loc = game_events::entity_location(*un);
3734  }
3735 
3736  if (cfg["fire_event"].to_bool())
3737  {
3738  // Prevent infinite recursion of 'die' events
3739  fire_event = true;
3740  recursion_preventer_ptr recursion_prevent;
3741 
3742  if (event_info.loc1 == death_loc && (event_info.name == "die" || event_info.name == "last breath"))
3743  {
3744  recursion_prevent.reset(new recursion_preventer(death_loc));
3745 
3746  if(recursion_prevent->too_many_recursions())
3747  {
3748  fire_event = false;
3749 
3750  ERR_LUA << "tried to fire 'die' or 'last breath' event on primary_unit inside its own 'die' or 'last breath' event with 'first_time_only' set to false!" << std::endl;
3751  }
3752  }
3753  }
3754  if (fire_event) {
3755  play_controller_.pump().fire("last breath", death_loc, killer_loc);
3756  }
3757 
3758  // Visual consequences of the kill.
3759  if (game_display_) {
3760  if (cfg["animate"].to_bool()) {
3762  if (unit_map::iterator iun = units().find(loc)) {
3763  unit_display::unit_die(loc, *iun);
3764  }
3765  } else {
3766  // Make sure the unit gets (fully) cleaned off the screen.
3767  game_display_->invalidate(loc);
3768  if (unit_map::iterator iun = units().find(loc)) {
3769  iun->anim_comp().invalidate(*game_display_);
3770  }
3771  }
3773  }
3774 
3775  if (fire_event) {
3776  play_controller_.pump().fire("die", death_loc, killer_loc);
3777  unit_map::iterator iun = units().find(death_loc);
3778  if ( death_loc.matches_unit(iun) ) {
3779  units().erase(iun);
3780  }
3781  }
3782  else units().erase(loc);
3783 
3784  ++number_killed;
3785  }
3786 
3787  // If the filter doesn't contain positional information,
3788  // then it may match units on all recall lists.
3789  const config::attribute_value cfg_x = cfg["x"];
3790  const config::attribute_value cfg_y = cfg["y"];
3791  if((cfg_x.empty() || cfg_x == "recall")
3792  && (cfg_y.empty() || cfg_y == "recall"))
3793  {
3794  const unit_filter ufilt(cfg, &game_state_);
3795  //remove the unit from the corresponding team's recall list
3796  for(std::vector<team>::iterator pi = teams().begin();
3797  pi!=teams().end(); ++pi)
3798  {
3799  for(std::vector<unit_ptr>::iterator j = pi->recall_list().begin(); j != pi->recall_list().end();) { //TODO: This block is really messy, cleanup somehow...
3800  scoped_recall_unit auto_store("this_unit", pi->save_id(), j - pi->recall_list().begin());
3801  if (ufilt( *(*j), map_location() )) {
3802  j = pi->recall_list().erase(j);
3803  ++number_killed;
3804  } else {
3805  ++j;
3806  }
3807  }
3808  }
3809  }
3810 
3811  lua_pushinteger(L, number_killed);
3812 
3813  return 1;
3814 }
3815 
3817 {
3818  if (game_display_) {
3819  vconfig cfg(luaW_checkvconfig(L, 1));
3820 
3822 
3823  terrain_label label(screen.labels(), cfg.get_config());
3824 
3825  screen.labels().set_label(label.location(), label.text(), label.creator(), label.team_name(), label.color(),
3826  label.visible_in_fog(), label.visible_in_shroud(), label.immutable(), label.category(), label.tooltip());
3827  }
3828  return 0;
3829 }
3830 
3832 {
3833  if (game_display_) {
3835 
3836  vconfig cfg(luaW_checkvconfig(L, 1));
3837  bool clear_shroud(luaW_toboolean(L, 2));
3838 
3839  // We do this twice so any applicable redraws happen both before and after
3840  // any events caused by redrawing shroud are fired
3841  bool result = screen.maybe_rebuild();
3842  if (!result) {
3843  screen.invalidate_all();
3844  }
3845 
3846  if (clear_shroud) {
3848  for (const int side : filter.get_teams()){
3849  actions::clear_shroud(side);
3850  }
3851  screen.recalculate_minimap();
3852  }
3853 
3854  result = screen.maybe_rebuild();
3855  if (!result) {
3856  screen.invalidate_all();
3857  }
3858 
3859  screen.draw(true,true);
3860  }
3861  return 0;
3862 }
3863 
3864 /**
3865  * Gets the dimension of an image.
3866  * - Arg 1: string.
3867  * - Ret 1: width.
3868  * - Ret 2: height.
3869  */
3871 {
3872  char const *m = luaL_checkstring(L, 1);
3873  image::locator img(m);
3874  if (!img.file_exists()) return 0;
3875  surface s = get_image(img);
3876  lua_pushinteger(L, s->w);
3877  lua_pushinteger(L, s->h);
3878  return 2;
3879 }
3880 
3881 /**
3882  * Returns the time stamp, exactly as [set_variable] time=stamp does.
3883  * - Ret 1: integer
3884  */
3886 {
3887  lua_pushinteger(L, SDL_GetTicks());
3888  return 1;
3889 }
3890 
3891 /**
3892  * Lua frontend to the modify_ai functionality
3893  * - Arg 1: config.
3894  */
3896 {
3897  config cfg;
3898  luaW_toconfig(L, 1, cfg);
3899  int side = cfg["side"];
3901  return 0;
3902 }
3903 
3905 {
3906  bool exec = luaW_toboolean(L, -1);
3907  lua_pop(L, 1);
3908 
3909  lua_getfield(L, -1, "ca_ptr");
3910 
3911  ai::candidate_action *ca = static_cast<ai::candidate_action*>(lua_touserdata(L, -1));
3912  lua_pop(L, 2);
3913  if (exec) {
3914  ca->execute();
3915  return 0;
3916  }
3917  lua_pushinteger(L, ca->evaluate());
3918  return 1;
3919 }
3920 
3922 {
3923  lua_getfield(L, -1, "stg_ptr");
3924  ai::stage *stg = static_cast<ai::stage*>(lua_touserdata(L, -1));
3925  lua_pop(L, 2);
3926  stg->play_stage();
3927  return 0;
3928 }
3929 
3930 static void push_component(lua_State *L, ai::component* c, const std::string &ct = "")
3931 {
3932  lua_createtable(L, 0, 0); // Table for a component
3933 
3934  lua_pushstring(L, "name");
3935  lua_pushstring(L, c->get_name().c_str());
3936  lua_rawset(L, -3);
3937 
3938  lua_pushstring(L, "engine");
3939  lua_pushstring(L, c->get_engine().c_str());
3940  lua_rawset(L, -3);
3941 
3942  lua_pushstring(L, "id");
3943  lua_pushstring(L, c->get_id().c_str());
3944  lua_rawset(L, -3);
3945 
3946  if (ct == "candidate_action") {
3947  lua_pushstring(L, "ca_ptr");
3948  lua_pushlightuserdata(L, c);
3949  lua_rawset(L, -3);
3950 
3951  lua_pushstring(L, "exec");
3953  lua_rawset(L, -3);
3954  }
3955 
3956  if (ct == "stage") {
3957  lua_pushstring(L, "stg_ptr");
3958  lua_pushlightuserdata(L, c);
3959  lua_rawset(L, -3);
3960 
3961  lua_pushstring(L, "exec");
3963  lua_rawset(L, -3);
3964  }
3965 
3966 
3967  std::vector<std::string> c_types = c->get_children_types();
3968 
3969  for (std::vector<std::string>::const_iterator t = c_types.begin(); t != c_types.end(); ++t)
3970  {
3971  std::vector<ai::component*> children = c->get_children(*t);
3972  std::string type = *t;
3973  if (type == "aspect" || type == "goal" || type == "engine")
3974  {
3975  continue;
3976  }
3977 
3978  lua_pushstring(L, type.c_str());
3979  lua_createtable(L, 0, 0); // this table will be on top of the stack during recursive calls
3980 
3981  for (std::vector<ai::component*>::const_iterator i = children.begin(); i != children.end(); ++i)
3982  {
3983  lua_pushstring(L, (*i)->get_name().c_str());
3984  push_component(L, *i, type);
3985  lua_rawset(L, -3);
3986 
3987  //if (type == "candidate_action")
3988  //{
3989  // ai::candidate_action *ca = dynamic_cast<ai::candidate_action*>(*i);
3990  // ca->execute();
3991  //}
3992  }
3993 
3994  lua_rawset(L, -3); // setting the child table
3995  }
3996 
3997 
3998 }
3999 
4000 /**
4001  * Debug access to the ai tables
4002  * - Arg 1: int
4003  * - Ret 1: ai table
4004  */
4005 static int intf_debug_ai(lua_State *L)
4006 {
4007  if (!game_config::debug) { // This function works in debug mode only
4008  return 0;
4009  }
4010  int side = lua_tointeger(L, 1);
4011  lua_pop(L, 1);
4012 
4014 
4015  // Bad, but works
4016  std::vector<ai::component*> engines = c->get_children("engine");
4017  ai::engine_lua* lua_engine = nullptr;
4018  for (std::vector<ai::component*>::const_iterator i = engines.begin(); i != engines.end(); ++i)
4019  {
4020  if ((*i)->get_name() == "lua")
4021  {
4022  lua_engine = dynamic_cast<ai::engine_lua *>(*i);
4023  }
4024  }
4025 
4026  // Better way, but doesn't work
4027  //ai::component* e = ai::manager::get_active_ai_holder_for_side_dbg(side).get_component(c, "engine[lua]");
4028  //ai::engine_lua* lua_engine = dynamic_cast<ai::engine_lua *>(e);
4029 
4030  if (lua_engine == nullptr)
4031  {
4032  //no lua engine is defined for this side.
4033  //so set up a dummy engine
4034 
4035  ai::ai_composite * ai_ptr = dynamic_cast<ai::ai_composite *>(c);
4036 
4037  assert(ai_ptr);
4038 
4039  ai::ai_context& ai_context = ai_ptr->get_ai_context();
4041 
4042  lua_engine = new ai::engine_lua(ai_context, cfg);
4043  LOG_LUA << "Created new dummy lua-engine for debug_ai(). \n";
4044 
4045  //and add the dummy engine as a component
4046  //to the manager, so we could use it later
4047  cfg.add_child("engine", lua_engine->to_config());
4048  ai::component_manager::add_component(c, "engine[]", cfg);
4049  }
4050 
4051  lua_engine->push_ai_table(); // stack: [-1: ai_context]
4052 
4053  lua_pushstring(L, "components");
4054  push_component(L, c); // stack: [-1: component tree; -2: ai context]
4055  lua_rawset(L, -3);
4056 
4057  return 1;
4058 }
4059 
4060 /// Allow undo sets the flag saying whether the event has mutated the game to false.
4062 {
4064  return 0;
4065 }
4066 
4067 /// Allow undo sets the flag saying whether the event has mutated the game to false.
4069 {
4070  if(lua_isboolean(L, 1)) {
4072  }
4073  else {
4075  }
4076  return 0;
4077 }
4078 
4079 /// Adding new time_areas dynamically with Standard Location Filters.
4081 {
4082  log_scope("time_area");
4083 
4084  vconfig cfg(luaW_checkvconfig(L, 1));
4085  const std::string id = cfg["id"];
4086 
4087  std::set<map_location> locs;
4088  const terrain_filter filter(cfg, &game_state_);
4089  filter.get_locations(locs, true);
4090  config parsed_cfg = cfg.get_parsed_config();
4091  tod_man().add_time_area(id, locs, parsed_cfg);
4092  LOG_LUA << "Lua inserted time_area '" << id << "'\n";
4093  return 0;
4094 }
4095 
4096 /// Removing new time_areas dynamically with Standard Location Filters.
4098 {
4099  log_scope("remove_time_area");
4100 
4101  const char * id = luaL_checkstring(L, 1);
4102  tod_man().remove_time_area(id);
4103  LOG_LUA << "Lua removed time_area '" << id << "'\n";
4104 
4105  return 0;
4106 }
4107 
4108 /// Replacing the current time of day schedule.
4110 {
4111  vconfig cfg = luaW_checkvconfig(L, 1);
4112 
4113  if(cfg.get_children("time").empty()) {
4114  ERR_LUA << "attempted to to replace ToD schedule with empty schedule" << std::endl;
4115  } else {
4117  if (game_display_) {
4119  }
4120  LOG_LUA << "replaced ToD schedule\n";
4121  }
4122  return 0;
4123 }
4124 
4126 {
4127  if(!game_display_) {
4128  return 0;
4129  }
4130  std::string area_id;
4131  size_t area_i = 0;
4132  if (lua_isstring(L, 2)) {
4133  area_id = lua_tostring(L, 1);
4134  std::vector<std::string> area_ids = tod_man().get_area_ids();
4135  area_i = std::find(area_ids.begin(), area_ids.end(), area_id) - area_ids.begin();
4136  if(area_i >= area_ids.size()) {
4137  return luaL_argerror(L, 1, "invalid time area ID");
4138  }
4139  }
4140  int is_num = false;
4141  int new_time = lua_tonumberx(L, 1, &is_num) - 1;
4142  const std::vector<time_of_day>& times = area_id.empty()
4143  ? tod_man().times()
4144  : tod_man().times(area_i);
4145  int num_times = times.size();
4146  if(!is_num) {
4147  std::string time_id = luaL_checkstring(L, 1);
4148  new_time = 0;
4149  for(const time_of_day& time : times) {
4150  if(time_id == time.id) {
4151  break;
4152  }
4153  new_time++;
4154  }
4155  if(new_time >= num_times) {
4156  return luaL_argerror(L, 1, "invalid time of day ID");
4157  }
4158  }
4159  if(new_time < 0 || new_time >= num_times) {
4160  return luaL_argerror(L, 1, "invalid time of day index");
4161  }
4162 
4163  if(area_id.empty()) {
4164  tod_man().set_current_time(new_time);
4165  } else {
4166  tod_man().set_current_time(new_time, area_i);
4167  }
4168  return 0;
4169 }
4170 
4172 {
4173  vconfig cfg = luaW_checkvconfig(L, 1);
4174 
4175  if (game_display_) {
4176  const std::vector<int> side_list = get_sides_vector(cfg);
4177  bool side_match = false;
4178  for (int side : side_list) {
4179  if(teams()[side-1].is_local_human()) {
4180  side_match = true;
4181  break;
4182  }
4183  }
4184  if ((cfg["side"].empty() && !cfg.has_child("filter_side")) || side_match) {
4185  game_display_->scroll(cfg["x"], cfg["y"], true);
4186  game_display_->draw(true,true);
4187  }
4188  }
4189 
4190  return 0;
4191 }
4192 
4193 namespace {
4194  struct lua_report_generator : reports::generator
4195  {
4196  lua_State *mState;
4197  std::string name;
4198  lua_report_generator(lua_State *L, const std::string &n)
4199  : mState(L), name(n) {}
4200  virtual config generate(reports::context & rc);
4201  };
4202 
4203  config lua_report_generator::generate(reports::context & /*rc*/)
4204  {
4205  lua_State *L = mState;
4206  config cfg;
4207  if (!luaW_getglobal(L, "wesnoth", "theme_items", name))
4208  return cfg;
4209  if (!luaW_pcall(L, 0, 1)) return cfg;
4210  luaW_toconfig(L, -1, cfg);
4211  lua_pop(L, 1);
4212  return cfg;
4213  }
4214 }//unnamed namespace for lua_report_generator
4215 
4216 /**
4217  * Executes its upvalue as a theme item generator.
4218  */
4220 {
4222  luaW_pushconfig(L, reports_.generate_report(m.c_str(), temp_context , true));
4223  return 1;
4224 }
4225 
4226 /**
4227  * Creates a field of the theme_items table and returns it (__index metamethod).
4228  */
4230 {
4231  char const *m = luaL_checkstring(L, 2);
4232  lua_cpp::push_closure(L, std::bind(&game_lua_kernel::impl_theme_item, this, _1, std::string(m)), 0);
4233  lua_pushvalue(L, 2);
4234  lua_pushvalue(L, -2);
4235  lua_rawset(L, 1);
4236  reports_.register_generator(m, new lua_report_generator(L, m));
4237  return 1;
4238 }
4239 
4240 /**
4241  * Sets a field of the theme_items table (__newindex metamethod).
4242  */
4244 {
4245  char const *m = luaL_checkstring(L, 2);
4246  lua_pushvalue(L, 2);
4247  lua_pushvalue(L, 3);
4248  lua_rawset(L, 1);
4249  reports_.register_generator(m, new lua_report_generator(L, m));
4250  return 0;
4251 }
4252 
4253 /**
4254  * Gets all the WML variables currently set.
4255  * - Ret 1: WML table
4256  */
4258  luaW_pushconfig(L, gamedata().get_variables());
4259  return 1;
4260 }
4261 
4262 /**
4263  * Teeleports a unit to a location.
4264  * Arg 1: unit
4265  * Arg 2: target location
4266  * Arg 3: bool (ignore_passability)
4267  * Arg 4: bool (clear_shroud)
4268  * Arg 5: bool (animate)
4269  */
4271 {
4272  unit_ptr u = luaW_checkunit_ptr(L, 1, true);
4274  bool check_passability = !luaW_toboolean(L, 3);
4275  bool clear_shroud = luaW_toboolean(L, 4);
4276  bool animate = luaW_toboolean(L, 5);
4277 
4278  if (dst == u->get_location() || !map().on_board(dst)) {
4279  return 0;
4280  }
4281  const map_location vacant_dst = find_vacant_tile(dst, pathfind::VACANT_ANY, check_passability ? u.get() : nullptr);
4282  if (!map().on_board(vacant_dst)) {
4283  return 0;
4284  }
4285  // Clear the destination hex before the move (so the animation can be seen).
4286  actions::shroud_clearer clearer;
4287  if ( clear_shroud ) {
4288  clearer.clear_dest(vacant_dst, *u);
4289  }
4290 
4291  map_location src_loc = u->get_location();
4292 
4293  std::vector<map_location> teleport_path;
4294  teleport_path.push_back(src_loc);
4295  teleport_path.push_back(vacant_dst);
4296  unit_display::move_unit(teleport_path, u, animate);
4297 
4298  units().move(src_loc, vacant_dst);
4300 
4301  u = &*units().find(vacant_dst);
4302  u->anim_comp().set_standing();
4303 
4304  if ( clear_shroud ) {
4305  // Now that the unit is visibly in position, clear the shroud.
4306  clearer.clear_unit(vacant_dst, *u);
4307  }
4308 
4309  if (map().is_village(vacant_dst)) {
4310  actions::get_village(vacant_dst, u->side());
4311  }
4312 
4313  game_display_->invalidate_unit_after_move(src_loc, vacant_dst);
4314  game_display_->draw();
4315 
4316  // Sighted events.
4317  clearer.fire_events();
4318  return 0;
4319 }
4320 
4321 /**
4322  * Removes a sound source by its ID
4323  * Arg 1: sound source ID
4324  */
4326 {
4328  std::string id = luaL_checkstring(L, 1);
4329  man->remove(id);
4330  return 0;
4331 }
4332 
4333 /**
4334  * Add a new sound source
4335  * Arg 1: Table containing keyword arguments
4336  */
4338 {
4340  config cfg = luaW_checkconfig(L, 1);
4341  try {
4342  soundsource::sourcespec spec(cfg);
4343  man->add(spec);
4344  } catch (bad_lexical_cast &) {
4345  ERR_LUA << "Error when parsing sound_source config: invalid parameter." << std::endl;
4346  ERR_LUA << "sound_source config was: " << cfg.debug() << std::endl;
4347  ERR_LUA << "Skipping this sound source..." << std::endl;
4348  }
4349  return 0;
4350 }
4351 
4352 /**
4353  * Get an existing sound source
4354  * Arg 1: The sound source ID
4355  * Return: Config of sound source info, or nil if it didn't exist
4356  * This is a copy of the sound source info, so you need to call
4357  * add_sound_source again after changing it.
4358  */
4360 {
4362  std::string id = luaL_checkstring(L, 1);
4363  config cfg = man->get(id);
4364  if(cfg.empty()) {
4365  return 0;
4366  }
4367  // Sound sources do not know their own string ID
4368  // Thus, we need to add this manually
4369  cfg["id"] = id;
4370  luaW_pushconfig(L, cfg);
4371  return 1;
4372 }
4373 
4374 /**
4375  * Logs a message
4376  * Arg 1: (optional) Logger; "wml" for WML errors or deprecations
4377  * Arg 2: Message
4378  * Arg 3: Whether to print to chat (always true if arg 1 is "wml")
4379  */
4381 {
4382  const std::string& logger = lua_isstring(L, 2) ? luaL_checkstring(L, 1) : "";
4383  const std::string& msg = lua_isstring(L, 2) ? luaL_checkstring(L, 2) : luaL_checkstring(L, 1);
4384 
4385  if(logger == "wml" || logger == "WML") {
4386  lg::wml_error() << msg << '\n';
4387  } else {
4388  bool in_chat = luaW_toboolean(L, -1);
4389  game_state_.events_manager_->pump().put_wml_message(logger,msg,in_chat);
4390  }
4391  return 0;
4392 }
4393 
4394 /**
4395  * Implements the lifting and resetting of fog via WML.
4396  * Keeping affect_normal_fog as false causes only the fog override to be affected.
4397  * Otherwise, fog lifting will be implemented similar to normal sight (cannot be
4398  * individually reset and ends at the end of the turn), and fog resetting will, in
4399  * addition to removing overrides, extend the specified teams' normal fog to all
4400  * hexes.
4401  *
4402  * Arg 1: (optional) Side number, or list of side numbers
4403  * Arg 2: List of locations; each is a two-element array or a table with x and y keys
4404  * Arg 3: (optional) boolean
4405  */
4407 {
4408  bool affect_normal_fog = false;
4409  if(lua_isboolean(L, -1)) {
4410  affect_normal_fog = luaW_toboolean(L, -1);
4411  }
4412  std::set<int> sides;
4413  if(lua_isnumber(L, 1)) {
4414  sides.insert(lua_tonumber(L, 1));
4415  } else if(lua_istable(L, 2)) {
4416  const auto& v = lua_check<std::vector<int>>(L, 1);
4417  sides.insert(v.begin(), v.end());
4418  } else {
4419  for(const team& t : teams()) {
4420  sides.insert(t.side()+1);
4421  }
4422  }
4423  const auto& v_locs = lua_check<std::vector<map_location>>(L, lua_istable(L, 2) ? 2 : 1);
4424  std::set<map_location> locs(v_locs.begin(), v_locs.end());
4425 
4426  for(const int &side_num : sides) {
4427  if(side_num < 1 || static_cast<size_t>(side_num) > teams().size()) {
4428  continue;
4429  }
4430  team &t = teams()[side_num-1];
4431  if(!clear) {
4432  // Extend fog.
4433  t.remove_fog_override(locs);
4434  if(affect_normal_fog) {
4435  t.refog();
4436  }
4437  } else if(!affect_normal_fog) {
4438  // Force the locations clear of fog.
4439  t.add_fog_override(locs);
4440  } else {
4441  // Simply clear fog from the locations.
4442  for(const map_location &hex : locs) {
4443  t.clear_fog(hex);
4444  }
4445  }
4446  }
4447 
4448  // Flag a screen update.
4451  return 0;
4452 }
4453 
4454 // END CALLBACK IMPLEMENTATION
4455 
4457  return game_state_.board_;
4458 }
4459 
4461  return game_state_.board_.units_;
4462 }
4463 
4464 std::vector<team> & game_lua_kernel::teams() {
4465  return game_state_.board_.teams_;
4466 }
4467 
4469  return game_state_.board_.map();
4470 }
4471 
4473  return game_state_.gamedata_;
4474 }
4475 
4477  return game_state_.tod_manager_;
4478 }
4479 
4481  return *queued_events_.top();
4482 }
4483 
4484 // Template which allows to push member functions to the lua kernel base into lua as C functions, using a shim
4486 
4487 template <member_callback method>
4489  return ((lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)).*method)(L);
4490 }
4491 
4492 // Pass a const bool also...
4494 
4495 template <member_callback2 method, bool b>
4496 int dispatch2(lua_State *L) {
4497  return ((lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)).*method)(L, b);
4498 }
4499 
4500 
4502  : lua_kernel_base(video)
4503  , game_display_(nullptr)
4504  , game_state_(gs)
4505  , play_controller_(pc)
4506  , reports_(reports_object)
4507  , level_lua_()
4508  , queued_events_()
4509  , map_locked_(0)
4510 {
4511  static game_events::queued_event default_queued_event("_from_lua", map_location(), map_location(), config());
4512  queued_events_.push(&default_queued_event);
4513 
4514  lua_State *L = mState;
4515 
4516  cmd_log_ << "Registering game-specific wesnoth lib functions...\n";
4517 
4518  // Put some callback functions in the scripting environment.
4519  static luaL_Reg const callbacks[] = {
4520  { "add_known_unit", &intf_add_known_unit },
4521  { "add_modification", &intf_add_modification },
4522  { "advance_unit", &intf_advance_unit },
4523  { "copy_unit", &intf_copy_unit },
4524  { "create_unit", &intf_create_unit },
4525  { "debug", &intf_debug },
4526  { "debug_ai", &intf_debug_ai },
4527  { "eval_conditional", &intf_eval_conditional },
4528  { "get_era", &intf_get_era },
4529  { "get_image_size", &intf_get_image_size },
4530  { "get_time_stamp", &intf_get_time_stamp },
4531  { "get_traits", &intf_get_traits },
4532  { "get_viewing_side", &intf_get_viewing_side },
4533  { "modify_ai", &intf_modify_ai },
4534  { "set_music", &intf_set_music },
4535  { "transform_unit", &intf_transform_unit },
4536  { "unit_ability", &intf_unit_ability },
4537  { "unit_defense", &intf_unit_defense },
4538  { "unit_movement_cost", &intf_unit_movement_cost },
4539  { "unit_vision_cost", &intf_unit_vision_cost },
4540  { "unit_jamming_cost", &intf_unit_jamming_cost },
4541  { "unit_resistance", &intf_unit_resistance },
4542  { "unsynced", &intf_do_unsynced },
4543  { "add_event_handler", &dispatch<&game_lua_kernel::intf_add_event > },
4544  { "add_fog", &dispatch2<&game_lua_kernel::intf_toggle_fog, true > },
4545  { "add_tile_overlay", &dispatch<&game_lua_kernel::intf_add_tile_overlay > },
4546  { "add_time_area", &dispatch<&game_lua_kernel::intf_add_time_area > },
4547  { "add_sound_source", &dispatch<&game_lua_kernel::intf_add_sound_source > },
4548  { "allow_end_turn", &dispatch<&game_lua_kernel::intf_allow_end_turn > },
4549  { "allow_undo", &dispatch<&game_lua_kernel::intf_allow_undo > },
4550  { "animate_unit", &dispatch<&game_lua_kernel::intf_animate_unit > },
4551  { "check_end_level_disabled", &dispatch<&game_lua_kernel::intf_check_end_level_disabled > },
4552  { "clear_menu_item", &dispatch<&game_lua_kernel::intf_clear_menu_item > },
4553  { "clear_messages", &dispatch<&game_lua_kernel::intf_clear_messages > },
4554  { "color_adjust", &dispatch<&game_lua_kernel::intf_color_adjust > },
4555  { "delay", &dispatch<&game_lua_kernel::intf_delay > },
4556  { "end_turn", &dispatch<&game_lua_kernel::intf_end_turn > },
4557  { "end_level", &dispatch<&game_lua_kernel::intf_end_level > },
4558  { "erase_unit", &dispatch<&game_lua_kernel::intf_erase_unit > },
4559  { "extract_unit", &dispatch<&game_lua_kernel::intf_extract_unit > },
4560  { "find_cost_map", &dispatch<&game_lua_kernel::intf_find_cost_map > },
4561  { "find_path", &dispatch<&game_lua_kernel::intf_find_path > },
4562  { "find_reach", &dispatch<&game_lua_kernel::intf_find_reach > },
4563  { "find_vacant_tile", &dispatch<&game_lua_kernel::intf_find_vacant_tile > },
4564  { "fire_event", &dispatch<&game_lua_kernel::intf_fire_event > },
4565  { "fire_wml_menu_item", &dispatch<&game_lua_kernel::intf_fire_wml_menu_item > },
4566  { "float_label", &dispatch<&game_lua_kernel::intf_float_label > },
4567  { "gamestate_inspector", &dispatch<&game_lua_kernel::intf_gamestate_inspector > },
4568  { "get_all_vars", &dispatch<&game_lua_kernel::intf_get_all_vars > },
4569  { "get_locations", &dispatch<&game_lua_kernel::intf_get_locations > },
4570  { "get_map_size", &dispatch<&game_lua_kernel::intf_get_map_size > },
4571  { "get_mouseover_tile", &dispatch<&game_lua_kernel::intf_get_mouseover_tile > },
4572  { "get_recall_units", &dispatch<&game_lua_kernel::intf_get_recall_units > },
4573  { "get_selected_tile", &dispatch<&game_lua_kernel::intf_get_selected_tile > },
4574  { "get_sides", &dispatch<&game_lua_kernel::intf_get_sides > },
4575  { "get_sound_source", &dispatch<&game_lua_kernel::intf_get_sound_source > },
4576  { "get_starting_location", &dispatch<&game_lua_kernel::intf_get_starting_location > },
4577  { "get_terrain", &dispatch<&game_lua_kernel::intf_get_terrain > },
4578  { "get_terrain_info", &dispatch<&game_lua_kernel::intf_get_terrain_info > },
4579  { "get_time_of_day", &dispatch<&game_lua_kernel::intf_get_time_of_day > },
4580  { "get_unit", &dispatch<&game_lua_kernel::intf_get_unit > },
4581  { "get_units", &dispatch<&game_lua_kernel::intf_get_units > },
4582  { "get_variable", &dispatch<&game_lua_kernel::intf_get_variable > },
4583  { "get_side_variable", &dispatch<&game_lua_kernel::intf_get_side_variable > },
4584  { "get_villages", &dispatch<&game_lua_kernel::intf_get_villages > },
4585  { "get_village_owner", &dispatch<&game_lua_kernel::intf_get_village_owner > },
4586  { "get_displayed_unit", &dispatch<&game_lua_kernel::intf_get_displayed_unit > },
4587  { "heal_unit", &dispatch<&game_lua_kernel::intf_heal_unit > },
4588  { "highlight_hex", &dispatch<&game_lua_kernel::intf_highlight_hex > },
4589  { "is_enemy", &dispatch<&game_lua_kernel::intf_is_enemy > },
4590  { "kill", &dispatch<&game_lua_kernel::intf_kill > },
4591  { "label", &dispatch<&game_lua_kernel::intf_label > },
4592  { "lock_view", &dispatch<&game_lua_kernel::intf_lock_view > },
4593  { "log", &dispatch<&game_lua_kernel::intf_log > },
4594  { "match_location", &dispatch<&game_lua_kernel::intf_match_location > },
4595  { "match_side", &dispatch<&game_lua_kernel::intf_match_side > },
4596  { "match_unit", &dispatch<&game_lua_kernel::intf_match_unit > },
4597  { "message", &dispatch<&game_lua_kernel::intf_message > },
4598  { "modify_ai_wml", &dispatch<&game_lua_kernel::intf_modify_ai_wml > },
4599  { "modify_side", &dispatch<&game_lua_kernel::intf_modify_side > },
4600  { "open_help", &dispatch<&game_lua_kernel::intf_open_help > },
4601  { "play_sound", &dispatch<&game_lua_kernel::intf_play_sound > },
4602  { "print", &dispatch<&game_lua_kernel::intf_print > },
4603  { "put_recall_unit", &dispatch<&game_lua_kernel::intf_put_recall_unit > },
4604  { "put_unit", &dispatch<&game_lua_kernel::intf_put_unit > },
4605  { "random", &dispatch<&game_lua_kernel::intf_random > },
4606  { "redraw", &dispatch<&game_lua_kernel::intf_redraw > },
4607  { "remove_event_handler", &dispatch<&game_lua_kernel::intf_remove_event > },
4608  { "remove_fog", &dispatch2<&game_lua_kernel::intf_toggle_fog, false > },
4609  { "remove_tile_overlay", &dispatch<&game_lua_kernel::intf_remove_tile_overlay > },
4610  { "remove_time_area", &dispatch<&game_lua_kernel::intf_remove_time_area > },
4611  { "remove_sound_source", &dispatch<&game_lua_kernel::intf_remove_sound_source > },
4612  { "replace_schedule", &dispatch<&game_lua_kernel::intf_replace_schedule > },
4613  { "scroll", &dispatch<&game_lua_kernel::intf_scroll > },
4614  { "scroll_to_tile", &dispatch<&game_lua_kernel::intf_scroll_to_tile > },
4615  { "select_hex", &dispatch<&game_lua_kernel::intf_select_hex > },
4616  { "set_time_of_day", &dispatch<&game_lua_kernel::intf_set_time_of_day > },
4617  { "deselect_hex", &dispatch<&game_lua_kernel::intf_deselect_hex > },
4618  { "select_unit", &dispatch<&game_lua_kernel::intf_select_unit > },
4619  { "skip_messages", &dispatch<&game_lua_kernel::intf_skip_messages > },
4620  { "is_skipping_messages", &dispatch<&game_lua_kernel::intf_is_skipping_messages > },
4621  { "set_end_campaign_credits", &dispatch<&game_lua_kernel::intf_set_end_campaign_credits > },
4622  { "set_end_campaign_text", &dispatch<&game_lua_kernel::intf_set_end_campaign_text > },
4623  { "set_menu_item", &dispatch<&game_lua_kernel::intf_set_menu_item > },
4624  { "set_next_scenario", &dispatch<&game_lua_kernel::intf_set_next_scenario > },
4625  { "set_terrain", &dispatch<&game_lua_kernel::intf_set_terrain > },
4626  { "set_variable", &dispatch<&game_lua_kernel::intf_set_variable > },
4627  { "set_side_variable", &dispatch<&game_lua_kernel::intf_set_side_variable > },
4628  { "set_village_owner", &dispatch<&game_lua_kernel::intf_set_village_owner > },
4629  { "simulate_combat", &dispatch<&game_lua_kernel::intf_simulate_combat > },
4630  { "synchronize_choice", &intf_synchronize_choice },
4631  { "synchronize_choices", &intf_synchronize_choices },
4632  { "teleport", &dispatch<&game_lua_kernel::intf_teleport > },
4633  { "view_locked", &dispatch<&game_lua_kernel::intf_view_locked > },
4634  { "place_shroud", &dispatch2<&game_lua_kernel::intf_shroud_op, true > },
4635  { "remove_shroud", &dispatch2<&game_lua_kernel::intf_shroud_op, false > },
4636  { nullptr, nullptr }
4637  };
4638  /*
4639  lua_cpp::Reg const cpp_callbacks[] = {
4640  };
4641  */
4642  lua_getglobal(L, "wesnoth");
4643  if (!lua_istable(L,-1)) {
4644  lua_newtable(L);
4645  }
4646  luaL_setfuncs(L, callbacks, 0);
4647  //lua_cpp::set_functions(L, cpp_callbacks);
4648  lua_setglobal(L, "wesnoth");
4649 
4650  // Create the getside metatable.
4652 
4653  // Create the gettype metatable.
4655 
4656  //Create the getrace metatable
4658 
4659  // Create the getunit metatable.
4660  cmd_log_ << "Adding getunit metatable...\n";
4661 
4663  , getunitKey);
4664  lua_createtable(L, 0, 5);
4666  lua_setfield(L, -2, "__gc");
4668  lua_setfield(L, -2, "__eq");
4670  lua_setfield(L, -2, "__index");
4672  lua_setfield(L, -2, "__newindex");
4673  lua_pushstring(L, "unit");
4674  lua_setfield(L, -2, "__metatable");
4676 
4677  // Create the unit status metatable.
4678  cmd_log_ << "Adding unit status metatable...\n";
4679 
4681  , ustatusKey);
4682  lua_createtable(L, 0, 3);
4684  lua_setfield(L, -2, "__index");
4686  lua_setfield(L, -2, "__newindex");
4687  lua_pushstring(L, "unit status");
4688  lua_setfield(L, -2, "__metatable");
4690 
4691  // Create the unit attacks metatable.
4692  cmd_log_ << "Adding unit attacks metatable...\n";
4693 
4695  lua_createtable(L, 0, 3);
4697  lua_setfield(L, -2, "__index");
4699  lua_setfield(L, -2, "__len");
4700  lua_pushstring(L, "unit attacks");
4701  lua_setfield(L, -2, "__metatable");
4703 
4704 
4706  lua_createtable(L, 0, 3);
4708  lua_setfield(L, -2, "__index");
4710  lua_setfield(L, -2, "__newindex");
4711  lua_pushstring(L, "unit attack");
4712  lua_setfield(L, -2, "__metatable");
4714 
4715  // Create the unit variables metatable.
4716  cmd_log_ << "Adding unit variables metatable...\n";
4717 
4719  , unitvarKey);
4720  lua_createtable(L, 0, 3);
4722  lua_setfield(L, -2, "__index");
4724  lua_setfield(L, -2, "__newindex");
4725  lua_pushstring(L, "unit variables");
4726  lua_setfield(L, -2, "__metatable");
4728 
4729  // Create the vconfig metatable.
4731 
4732  // Create the ai elements table.
4733  cmd_log_ << "Adding ai elements table...\n";
4734 
4736 
4737  // Create the game_config variable with its metatable.
4738  cmd_log_ << "Adding game_config table...\n";
4739 
4740  lua_getglobal(L, "wesnoth");
4741  lua_newuserdata(L, 0);
4742  lua_createtable(L, 0, 3);
4743  lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_game_config_get>);
4744  lua_setfield(L, -2, "__index");
4745  lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_game_config_set>);
4746  lua_setfield(L, -2, "__newindex");
4747  lua_pushstring(L, "game config");
4748  lua_setfield(L, -2, "__metatable");
4749  lua_setmetatable(L, -2);
4750  lua_setfield(L, -2, "game_config");
4751  lua_pop(L, 1);
4752 
4753  // Create the current variable with its metatable.
4754  cmd_log_ << "Adding wesnoth current table...\n";
4755 
4756  lua_getglobal(L, "wesnoth");
4757  lua_newuserdata(L, 0);
4758  lua_createtable(L, 0, 2);
4759  lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_current_get>);
4760  lua_setfield(L, -2, "__index");
4761  lua_pushstring(L, "current config");
4762  lua_setfield(L, -2, "__metatable");
4763  lua_setmetatable(L, -2);
4764  lua_setfield(L, -2, "current");
4765  lua_pop(L, 1);
4766 
4767  // Create the wml_actions table.
4768  cmd_log_ << "Adding wml_actions table...\n";
4769 
4770  lua_getglobal(L, "wesnoth");
4771  lua_newtable(L);
4772  lua_setfield(L, -2, "wml_actions");
4773  lua_pop(L, 1);
4774 
4775  // Create the wml_conditionals table.
4776  cmd_log_ << "Adding wml_conditionals table...\n";
4777 
4778  lua_getglobal(L, "wesnoth");
4779  lua_newtable(L);
4780  lua_setfield(L, -2, "wml_conditionals");
4781  lua_pop(L, 1);
4782 
4783  // Create the effects table.
4784  cmd_log_ << "Adding effects table...\n";
4785 
4786  lua_getglobal(L, "wesnoth");
4787  lua_newtable(L);
4788  lua_setfield(L, -2, "effects");
4789  lua_pop(L, 1);
4790 
4791  // Create the game_events table.
4792  cmd_log_ << "Adding game_events table...\n";
4793 
4794  lua_getglobal(L, "wesnoth");
4795  lua_newtable(L);
4796  lua_setfield(L, -2, "game_events");
4798  lua_setfield(L, -2, "special_locations");
4799  lua_pop(L, 1);
4800 
4801  // Create the theme_items table.
4802  cmd_log_ << "Adding theme_items table...\n";
4803 
4804  lua_getglobal(L, "wesnoth");
4805  lua_newtable(L);
4806  lua_createtable(L, 0, 2);
4807  lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_get>);
4808  lua_setfield(L, -2, "__index");
4809  lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_set>);
4810  lua_setfield(L, -2, "__newindex");
4811  lua_setmetatable(L, -2);
4812  lua_setfield(L, -2, "theme_items");
4813  lua_pop(L, 1);
4814 
4815  lua_settop(L, 0);
4816 
4817  for(const auto& handler : game_events::wml_action::registry())
4818  {
4819  set_wml_action(handler.first, handler.second);
4820  }
4821  luaW_getglobal(L, "wesnoth", "effects");
4822  for(const std::string& effect : unit::builtin_effects) {
4823  lua_pushstring(L, effect.c_str());
4825  lua_rawset(L, -3);
4826  }
4827  lua_settop(L, 0);
4828 }
4829 
4831 {
4832  lua_State *L = mState;
4833  assert(level_lua_.empty());
4834  level_lua_.append_children(level, "lua");
4835  // Create the sides table.
4836  // note:
4837  // This table is redundant to the return value of wesnoth.get_sides({}).
4838  // Still needed for backwards compatibility.
4839  lua_settop(L, 0);
4840  lua_getglobal(L, "wesnoth");
4841 
4842  lua_pushstring(L, "get_sides");
4843  lua_rawget(L, -2);
4844  lua_createtable(L, 0, 0);
4845 
4846  if (!protected_call(1, 1, std::bind(&lua_kernel_base::log_error, this, _1, _2))) {
4847  cmd_log_ << "Failed to compute wesnoth.sides\n";
4848  } else {
4849  lua_setfield(L, -2, "sides");
4850  cmd_log_ << "Added wesnoth.sides\n";
4851  }
4852 
4853  // Create the unit_types table.
4854  cmd_log_ << "Adding unit_types table...\n";
4855 
4856  lua_settop(L, 0);
4857  lua_getglobal(L, "wesnoth");
4858  lua_newtable(L);
4859  for (const unit_type_data::unit_type_map::value_type &ut : unit_types.types())
4860  {
4861  luaW_pushunittype(L, ut.first);
4862  lua_setfield(L, -2, ut.first.c_str());
4863  }
4864  lua_setfield(L, -2, "unit_types");
4865 
4866  //Create the races table.
4867  cmd_log_ << "Adding races table...\n";
4868 
4869  lua_settop(L, 0);
4870  lua_getglobal(L, "wesnoth");
4871  luaW_pushracetable(L);
4872  lua_setfield(L, -2, "races");
4873  lua_pop(L, 1);
4874 
4875  // Execute the preload scripts.
4876  cmd_log_ << "Running preload scripts...\n";
4877 
4878  game_config::load_config(game_lua_kernel::preload_config);
4879  for (const config &cfg : game_lua_kernel::preload_scripts) {
4880  run_lua_tag(cfg);
4881  }
4882  for (const config &cfg : level_lua_.child_range("lua")) {
4883  run_lua_tag(cfg);
4884  }
4885 
4886  load_game(level);
4887 }
4888 
4889 int game_lua_kernel::return_unit_method(lua_State *L, char const *m) {
4890  static luaL_Reg const methods[] = {
4891  {"matches", &dispatch<&game_lua_kernel::intf_match_unit>},
4892  {"to_recall", &dispatch<&game_lua_kernel::intf_put_recall_unit>},
4893  {"to_map", &dispatch<&game_lua_kernel::intf_put_unit>},
4894  {"erase", &dispatch<&game_lua_kernel::intf_erase_unit>},
4895  {"clone", intf_copy_unit},
4896  {"extract", &dispatch<&game_lua_kernel::intf_extract_unit>},
4897  {"advance", intf_advance_unit},
4898  {"add_modification", intf_add_modification},
4899  {"resistance", intf_unit_resistance},
4900  {"defense", intf_unit_defense},
4901  {"movement", intf_unit_movement_cost},
4902  {"vision", intf_unit_vision_cost},
4903  {"jamming", intf_unit_jamming_cost},
4904  {"ability", intf_unit_ability},
4905  {"transform", intf_transform_unit},
4906  {"select", &dispatch<&game_lua_kernel::intf_select_unit>},
4907  };
4908 
4909  for (const luaL_Reg& r : methods) {
4910  if (strcmp(m, r.name) == 0) {
4911  lua_pushcfunction(L, r.func);
4912  return 1;
4913  }
4914  }
4915 
4916  return 0;
4917 }
4918 
4920  game_display_ = gd;
4921  if (gd) {
4922  set_video(&gd->video());
4923  }
4924 }
4925 
4926 /// These are the child tags of [scenario] (and the like) that are handled
4927 /// elsewhere (in the C++ code).
4928 /// Any child tags not in this list will be passed to Lua's on_load event.
4929 static char const *handled_file_tags[] = {
4930  "color_palette", "color_range", "display", "end_level_data", "era",
4931  "event", "generator", "label", "lua", "map", "menu_item",
4932  "modification", "music", "options", "side", "sound_source",
4933  "story", "terrain_graphics", "time", "time_area", "tunnel",
4934  "undo_stack", "variables"
4935 };
4936 
4937 static bool is_handled_file_tag(const std::string &s)
4938 {
4939  for (char const *t : handled_file_tags) {
4940  if (s == t) return true;
4941  }
4942  return false;
4943 }
4944 
4945 /**
4946  * Executes the game_events.on_load function and passes to it all the
4947  * scenario tags not yet handled.
4948  */
4950 {
4951  lua_State *L = mState;
4952 
4953  if (!luaW_getglobal(L, "wesnoth", "game_events", "on_load"))
4954  return;
4955 
4956  lua_newtable(L);
4957  int k = 1;
4958  for (const config::any_child &v : level.all_children_range())
4959  {
4960  if (is_handled_file_tag(v.key)) continue;
4961  lua_createtable(L, 2, 0);
4962  lua_pushstring(L, v.key.c_str());
4963  lua_rawseti(L, -2, 1);
4964  luaW_pushconfig(L, v.cfg);
4965  lua_rawseti(L, -2, 2);
4966  lua_rawseti(L, -2, k++);
4967  }
4968 
4969  luaW_pcall(L, 1, 0, true);
4970 }
4971 
4972 /**
4973  * Executes the game_events.on_save function and adds to @a cfg the
4974  * returned tags. Also flushes the [lua] tags.
4975  */
4977 {
4978  lua_State *L = mState;
4979 
4980  if (!luaW_getglobal(L, "wesnoth", "game_events", "on_save"))
4981  return;
4982 
4983  if (!luaW_pcall(L, 0, 1, false))
4984  return;
4985 
4986  config v;
4987  luaW_toconfig(L, -1, v);
4988  lua_pop(L, 1);
4989 
4990  for (;;)
4991  {
4993  if (i == v.ordered_end()) break;
4994  if (is_handled_file_tag(i->key))
4995  {
4996  /*
4997  * It seems the only tags appearing in the config v variable here
4998  * are the core-lua-handled (currently [item] and [objectives])
4999  * and the extra UMC ones.
5000  */
5001  const std::string m = "Tag is already used: [" + i->key + "]";
5002  log_error(m.c_str());
5003  v.erase(i);
5004  continue;
5005  }
5006  cfg.splice_children(v, i->key);
5007  }
5008 }
5009 
5010 /**
5011  * Executes the game_events.on_event function.
5012  * Returns false if there was no lua handler for this event
5013  */
5015 {
5016  lua_State *L = mState;
5017 
5018  if (!luaW_getglobal(L, "wesnoth", "game_events", "on_event"))
5019  return false;
5020 
5021  queued_event_context dummy(&ev, queued_events_);
5022  lua_pushstring(L, ev.name.c_str());
5023  luaW_pcall(L, 1, 0, false);
5024  return true;
5025 }
5026 
5027 /**
5028  * Applies its upvalue as an effect
5029  * Arg 1: The unit to apply to
5030  * Arg 3: The [effect] tag contents
5031  * Arg 3: If false, only build description
5032  * Return: The description of the effect
5033  */
5035 {
5036  std::string which_effect = lua_tostring(L, lua_upvalueindex(1));
5037  bool need_apply = luaW_toboolean(L, lua_upvalueindex(2));
5038  // Argument 1 is the implicit "self" argument, which isn't needed here
5039  lua_unit u(luaW_checkunit(L, 2));
5040  config cfg = luaW_checkconfig(L, 3);
5041 
5042  // The times= key is supposed to be ignored by the effect function.
5043  // However, just in case someone doesn't realize this, we will set it to 1 here.
5044  cfg["times"] = 1;
5045 
5046  if(need_apply) {
5047  u.get()->apply_builtin_effect(which_effect, cfg);
5048  return 0;
5049  } else {
5050  std::string description = u.get()->describe_builtin_effect(which_effect, cfg);
5051  lua_pushstring(L, description.c_str());
5052  return 1;
5053  }
5054 }
5055 
5056 /**
5057 * Registers a function for use as an effect handler.
5058 */
5060 {
5061  lua_State *L = mState;
5062 
5063  // The effect name is at the top of the stack
5064  int str_i = lua_gettop(L);
5065  lua_newtable(L); // The functor table
5066  lua_newtable(L); // The functor metatable
5067  lua_pushstring(L, "__call");
5068  lua_pushvalue(L, str_i);
5069  lua_pushboolean(L, true);
5070  lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_builtin_effect>, 2);
5071  lua_rawset(L, -3); // Set the call metafunction
5072  lua_pushstring(L, "__descr");
5073  lua_pushvalue(L, str_i);
5074  lua_pushboolean(L, false);
5075  lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_builtin_effect>, 2);
5076  lua_rawset(L, -3); // Set the descr "metafunction"
5077  lua_setmetatable(L, -2); // Apply the metatable to the functor table
5078 }
5079 
5080 
5081 /**
5082  * Executes its upvalue as a wml action.
5083  */
5085 {
5088 
5089  vconfig vcfg = luaW_checkvconfig(L, 1);
5090  h(get_event_info(), vcfg);
5091  return 0;
5092 }
5093 
5094 /**
5095  * Registers a function for use as an action handler.
5096  */
5098 {
5099  lua_State *L = mState;
5100 
5101  lua_getglobal(L, "wesnoth");
5102  lua_pushstring(L, "wml_actions");
5103  lua_rawget(L, -2);
5104  lua_pushstring(L, cmd.c_str());
5105  lua_pushlightuserdata(L, reinterpret_cast<void *>(h));
5106  lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_wml_action>, 1);
5107  lua_rawset(L, -3);
5108  lua_pop(L, 2);
5109 }
5110 
5111 /**
5112  * Runs a command from an event handler.
5113  * @return true if there is a handler for the command.
5114  * @note @a cfg should be either volatile or long-lived since the Lua
5115  * code may grab it for an arbitrary long time.
5116  */
5118  game_events::queued_event const &ev)
5119 {
5120  lua_State *L = mState;
5121 
5122 
5123  if (!luaW_getglobal(L, "wesnoth", "wml_actions", cmd))
5124  return false;
5125 
5126  queued_event_context dummy(&ev, queued_events_);
5127  luaW_pushvconfig(L, cfg);
5128  luaW_pcall(L, 1, 0, true);
5129  return true;
5130 }
5131 
5132 
5133 /**
5134  * Runs a command from an event handler.
5135  * @return true if there is a handler for the command.
5136  * @note @a cfg should be either volatile or long-lived since the Lua
5137  * code may grab it for an arbitrary long time.
5138  */
5140 {
5141  lua_State *L = mState;
5142 
5143 
5144  if (!luaW_getglobal(L, "wesnoth", "wml_conditionals", cmd)) {
5145  std::string err_msg = "unknown conditional wml: [";
5146  err_msg += cmd;
5147  err_msg += "]";
5148  luaL_argerror(L, 1, err_msg.c_str());
5149  }
5150 
5151  luaW_pushvconfig(L, cfg);
5152  luaW_pcall(L, 1, 1, true);
5153 
5154  bool b = luaW_toboolean(L, -1);
5155  lua_pop(L, 1);
5156  return b;
5157 }
5158 
5159 
5160 /**
5161 * Runs a script from a location filter.
5162 * The script is an already compiled function given by its name.
5163 */
5165 {
5166  lua_pushinteger(mState, l.x + 1);
5167  lua_pushinteger(mState, l.y + 1);
5168  return run_filter(name, 2);
5169 }
5170 /**
5171 * Runs a script from a unit filter.
5172 * The script is an already compiled function given by its name.
5173 */
5174 bool game_lua_kernel::run_filter(char const *name, unit const &u)
5175 {
5176  lua_State *L = mState;
5178  if (!ui.valid()) return false;
5179  // Pass the unit as argument.
5180  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(ui->underlying_id());
5183  lua_setmetatable(L, -2);
5184 
5185  return run_filter(name, 1);
5186 }
5187 /**
5188 * Runs a script from a filter.
5189 * The script is an already compiled function given by its name.
5190 */
5191 bool game_lua_kernel::run_filter(char const *name, int nArgs)
5192 {
5193  map_locker(this);
5194  lua_State *L = mState;
5195  // Get the user filter by name.
5196  const std::vector<std::string>& path = utils::split(name, '.', utils::STRIP_SPACES);
5197  if (!luaW_getglobal(L, path))
5198  {
5199  std::string message = std::string() + "function " + name + " not found";
5200  log_error(message.c_str(), "Lua SUF Error");
5201  //we pushed nothing and can safeley return.
5202  return false;
5203  }
5204  lua_insert(L, -nArgs - 1);
5205 
5206  if (!luaW_pcall(L, nArgs, 1)) return false;
5207 
5208  bool b = luaW_toboolean(L, -1);
5209  lua_pop(L, 1);
5210  return b;
5211 }
5212 
5213 std::string game_lua_kernel::apply_effect(const std::string& name, unit& u, const config& cfg, bool need_apply)
5214 {
5215  lua_State *L = mState;
5216  int top = lua_gettop(L);
5217  std::string descr;
5218  // Stack: nothing
5219  lua_unit* lu = luaW_pushlocalunit(L, u);
5220  // Stack: unit
5221  // (Note: The unit needs to be on the stack twice to prevent untimely GC.)
5222  luaW_pushconfig(L, cfg);
5223  // Stack: unit, cfg
5224  if(luaW_getglobal(L, "wesnoth", "effects", name)) {
5225  map_locker(this);
5226  // Stack: unit, cfg, effect
5227  if(lua_istable(L, -1)) {
5228  // Effect is implemented by a table with __call and __descr
5229  if(need_apply) {
5230  lua_pushvalue(L, -1);
5231  // Stack: unit, cfg, effect, effect
5232  lua_pushvalue(L, top + 1);
5233  // Stack: unit, cfg, effect, effect, unit
5234  lua_pushvalue(L, top + 2);
5235  // Stack: unit, cfg, effect, effect, unit, cfg
5236  luaW_pcall(L, 2, 0);
5237  // Stack: unit, cfg, effect
5238  }
5239  if(luaL_getmetafield(L, -1, "__descr")) {
5240  // Stack: unit, cfg, effect, __descr
5241  if(lua_isstring(L, -1)) {
5242  // __descr was a static string
5243  descr = lua_tostring(L, -1);
5244  } else {
5245  lua_pushvalue(L, -2);
5246  // Stack: unit, cfg, effect, __descr, effect
5247  lua_pushvalue(L, top + 1);
5248  // Stack: unit, cfg, effect, __descr, effect, unit
5249  lua_pushvalue(L, top + 2);
5250  // Stack: unit, cfg, effect, __descr, effect, unit, cfg
5251  luaW_pcall(L, 3, 1);
5252  if(lua_isstring(L, -1) && !lua_isnumber(L, -1)) {
5253  descr = lua_tostring(L, -1);
5254  } else {
5255  ERR_LUA << "Effect __descr metafunction should have returned a string, but instead returned ";
5256  if(lua_isnone(L, -1)) {
5257  ERR_LUA << "nothing";
5258  } else {
5259  ERR_LUA << lua_typename(L, lua_type(L, -1));
5260  }
5261  }
5262  }
5263  }
5264  } else if(need_apply) {
5265  // Effect is assumed to be a simple function; no description is provided
5266  lua_pushvalue(L, top + 1);
5267  // Stack: unit, cfg, effect, unit
5268  lua_pushvalue(L, top + 2);
5269  // Stack: unit, cfg, effect, unit, cfg
5270  luaW_pcall(L, 2, 0);
5271  // Stack: unit, cfg
5272  }
5273  }
5274  lua_settop(L, top);
5275  lu->clear_ref();
5276  return descr;
5277 }
5278 
5280 {
5281  return ai::lua_ai_context::create(mState,code,engine);
5282 }
5283 
5285 {
5286  return ai::lua_ai_action_handler::create(mState,code,context);
5287 }
5288 
5290 {
5291  lua_State *L = mState;
5292 
5293  if (!luaW_getglobal(L, "wesnoth", "game_events", "on_mouse_move")) {
5294  return;
5295  }
5296  lua_push(L, loc.x + 1);
5297  lua_push(L, loc.y + 1);
5298  luaW_pcall(L, 2, 0, false);
5299  return;
5300 }
5301 
5303 {
5304  lua_State *L = mState;
5305 
5306  if (!luaW_getglobal(L, "wesnoth", "game_events", "on_mouse_action")) {
5307  return;
5308  }
5309  lua_push(L, loc.x + 1);
5310  lua_push(L, loc.y + 1);
5311  luaW_pcall(L, 2, 0, false);
5312  return;
5313 }
std::string image_mods() const
Definition: unit.cpp:2430
bool luaW_checkvariable(lua_State *L, variable_access_create &v, int n)
Definition: lua_common.cpp:845
void set_resting(bool rest)
Definition: unit.hpp:243
std::vector< int > get_teams() const
Definition: side_filter.cpp:72
int dispatch(lua_State *L)
#define modify_bool_attrib(name, accessor)
Definition: lua_common.hpp:252
LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
Definition: lapi.cpp:643
void luaW_pushvconfig(lua_State *L, vconfig const &cfg)
Pushes a vconfig on the top of the stack.
Definition: lua_common.cpp:456
int intf_get_terrain_info(lua_State *L)
Gets details about a terrain.
static int intf_transform_unit(lua_State *L)
Changes a unit to the given unit type.
int intf_kill(lua_State *L)
#define lua_isnoneornil(L, n)
Definition: lua.h:337
virtual std::string description() const
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:878
child_itors child_range(const std::string &key)
Definition: config.cpp:613
const gamemap & map() const
virtual void highlight_hex(map_location hex)
Function to highlight a location.
unsigned int end_text_duration
for how long the end-of-campaign text is shown
static const std::set< std::string > builtin_effects
Definition: unit.hpp:342
int total_movement() const
Definition: unit.hpp:218
void invalidate_unit_after_move(const map_location &src, const map_location &dst)
Same as invalidate_unit() if moving the displayed unit.
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
Definition: lapi.cpp:579
void recalculate_shroud()
Definition: label.cpp:285
config get_user_choice(const std::string &name, const user_choice &uch, int side=0)
events::mouse_handler & get_mouse_handler_base()
Get a reference to a mouse handler member a derived class uses.
std::stack< game_events::queued_event const * > queued_events_
Game board class.
Definition: game_board.hpp:55
const std::string & id() const
Definition: unit.hpp:148
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:667
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator *calc, const size_t width, const size_t height, const teleport_map *teleports, bool border)
#define lua_pushcfunction(L, f)
Definition: lua.h:328
static int intf_advance_unit(lua_State *L)
Advances a unit if the unit has enough xp.
static int intf_get_era(lua_State *L)
Gets a table for an era tag.
static int special_locations_pairs(lua_State *L)
virtual std::string get_id() const =0
std::string str() const
Definition: config.cpp:353
int map_locked_
A value != 0 means that the shouldn't remove any units from the map, usually because we are currently...
std::string apply_effect(const std::string &name, unit &u, const config &cfg, bool need_apply)
static DIRECTION parse_direction(const std::string &str)
Definition: location.cpp:69
LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:622
void show_help(CVideo &video, const std::string &show_topic, int xloc, int yloc)
Open the help browser, show topic with id show_topic.
Definition: help.cpp:117
static thandler * handler
Definition: handler.cpp:60
LUA_API void lua_replace(lua_State *L, int idx)
Definition: lapi.cpp:211
bool end_credits
whether to show the standard credits at the end
void set_shroud(bool shroud)
Definition: team.hpp:323
void apply_builtin_effect(std::string type, const config &effect)
Definition: unit.cpp:1800
std::vector< double > hp_dist
Resulting probability distribution (might be not as large as max_hp)
unit_iterator end()
Definition: map.hpp:311
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg)
Definition: lauxlib.cpp:391
GLuint counter
Definition: glew.h:2584
const map_location & get_location() const
Definition: unit.hpp:286
static char const * handled_file_tags[]
These are the child tags of [scenario] (and the like) that are handled elsewhere (in the C++ code)...
entity_location loc2
Definition: pump.hpp:56
void(* handler)(const queued_event &, const vconfig &)
Definition: action_wml.hpp:51
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:88
int intf_remove_sound_source(lua_State *L)
Removes a sound source by its ID Arg 1: sound source ID.
int intf_allow_end_turn(lua_State *)
Allow undo sets the flag saying whether the event has mutated the game to false.
std::string const & gender_string(unit_race::GENDER gender)
Definition: race.cpp:151
void set_hidden(bool state) const
Definition: unit.cpp:2460
std::string absolute_image() const
The name of the file to game_display (used in menus).
Definition: unit.cpp:2262
int intf_find_path(lua_State *L)
Finds a path between two locations.
bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg)
Gets an optional vconfig from either a table or a userdata.
Definition: lua_common.cpp:757
std::pair< int, int > get_pair_at(int x, int y) const
Accessor for the cost/reach-amount pairs.
Definition: pathfind.cpp:924
void set_hitpoints(int hp)
Definition: unit.hpp:170
void adjust_color_overlay(int r, int g, int b)
Add r,g,b to the colors for all images displayed on the map.
Definition: display.cpp:452
int intf_set_end_campaign_credits(lua_State *L)
#define return_tstring_attrib(name, accessor)
Definition: lua_common.hpp:163
void reshroud()
Definition: team.hpp:321
game_display * game_display_
all_children_iterator ordered_end() const
Definition: config.cpp:1122
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.cpp:159
static int impl_unit_set(lua_State *L)
Sets some data on a unit (__newindex metamethod).
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3536
int max_hitpoints() const
Definition: unit.hpp:169
#define lua_isnone(L, n)
Definition: lua.h:336
bool get_state(const std::string &state) const
Definition: unit.cpp:1289
int intf_get_time_of_day(lua_State *L)
Gets time of day information.
int intf_get_unit(lua_State *)
Gets the unit at the given location or with the given id.
LUA_API int lua_type(lua_State *L, int idx)
Definition: lapi.cpp:243
int village_support
Definition: game_config.cpp:39
void luaW_pushteam(lua_State *L, team &tm)
Definition: lua_team.cpp:173
std::string plague_type
The plague type used by the attack, if any.
Definition: attack.hpp:83
bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error)
Calls a Lua function stored below its nArgs arguments at the top of the stack.
Definition: lua_api.cpp:59
Definition: unit.hpp:95
SDL_Color create_color(const unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
Definition: utils.cpp:89
void luaW_pushunittype(lua_State *L, const std::string &id)
Create a lua object containing a reference to a unittype, and a metatable to access the properties...
size_t underlying_id() const
The unique internal ID of the unit.
Definition: unit.hpp:150
bool clear_unit(const map_location &view_loc, team &view_team, size_t viewer_id, int sight_range, bool slowed, const movetype::terrain_costs &costs, const map_location &real_loc, const std::set< map_location > *known_units=nullptr, size_t *enemy_count=nullptr, size_t *friend_count=nullptr, move_unit_spectator *spectator=nullptr, bool instant=true)
Clears shroud (and fog) around the provided location for view_team based on sight_range, costs, and slowed.
Definition: vision.cpp:331
game_classification * classification
Definition: resources.cpp:37
GLint level
Definition: glew.h:1220
int intf_get_variable(lua_State *L)
Gets a WML variable.
tod_color color
The color modifications that should be made to the game board to reflect the time of day...
Definition: time_of_day.hpp:89
const t_string & name() const
The unit name for display.
Definition: unit.hpp:158
int intf_modify_ai_wml(lua_State *L)
void replace_schedule(const config &time_cfg)
Replace the time of day schedule.
int intf_match_location(lua_State *L)
Matches a location against the given filter.
int experience() const
Definition: unit.hpp:171
std::vector< int > get_sides_vector(const vconfig &cfg)
Gets a vector of sides from side= attribute in a given config node.
Various functions implementing vision (through fog of war and shroud).
const mp_game_settings & get_mp_settings()
int impl_theme_items_get(lua_State *L)
Creates a field of the theme_items table and returns it (__index metamethod).
bool match(const team &t) const
static int impl_unit_attack_set(lua_State *L)
Gets a propoerty of a units attack (__index metamethod).
bool get_village(const map_location &loc, int side, bool *action_timebonus, bool fire_event)
Makes it so the village at the given location is owned by the given side.
Definition: move.cpp:140
int intf_replace_schedule(lua_State *l)
Replacing the current time of day schedule.
static int special_locations_len(lua_State *L)
bool play_stage()
Play the turn - strategy.
Definition: stage.cpp:56
void set_clip_rect(const SDL_Rect &r)
static int impl_unit_collect(lua_State *L)
Destroys a unit object before it is collected (__gc metamethod).
int movement_cost(const t_translation::t_terrain &terrain) const
Definition: unit.hpp:308
config to_config() const
const GLfloat * c
Definition: glew.h:12741
int pos
Definition: formula.cpp:800
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:571
const mp_game_settings * mp_settings
Definition: resources.cpp:38
Various functions that implement attacks and attack calculations.
bool run_wml_action(std::string const &, vconfig const &, game_events::queued_event const &)
Runs a command from an event handler.
int intf_view_locked(lua_State *L)
Gets whether gamemap scrolling is disabled for the user.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
void set_next_scenario(const std::string &next_scenario)
Definition: game_data.hpp:90
vconfig child(const std::string &key) const
Returns a child of *this whose key is key.
Definition: variable.cpp:243
bool clear_fog(const map_location &loc)
Definition: team.hpp:320
void set_wml_action(std::string const &, game_events::wml_action::handler)
Registers a function for use as an action handler.
virtual std::vector< component * > get_children(const std::string &type)
Definition: component.cpp:112
bool to_bool(bool def=false) const
Definition: config.cpp:275
rng * generator
This generator is automatically synced during synced context.
Definition: random_new.cpp:52
config get_parsed_config() const
Definition: variable.cpp:131
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
int hitpoints() const
Definition: unit.hpp:168
std::vector< team > & teams()
const t_terrain NONE_TERRAIN
Definition: translation.hpp:56
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
int intf_set_terrain(lua_State *L)
Sets a terrain code.
bool fire_item(const std::string &id, const map_location &hex, game_data &gamedata, filter_context &fc, unit_map &units) const
Fires the menu item with the given id.
static int impl_unit_status_get(lua_State *L)
Gets the status of a unit (__index metamethod).
void advance_unit_at(const advance_unit_params &params)
Definition: attack.cpp:1478
int intf_log(lua_State *L)
Logs a message Arg 1: (optional) Logger; "wml" for WML errors or deprecations Arg 2: Message Arg 3: W...
logger & info()
Definition: log.cpp:91
void handle_legacy_share_vision(const config &cfg)
Definition: team.hpp:397
int intf_clear_messages(lua_State *)
Removes all messages from the chat window.
lua_check_impl::remove_constref< T >::type lua_check(lua_State *L, int n)
Definition: push_check.hpp:307
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
Definition: tod_manager.hpp:56
Definition: video.hpp:58
void set_recall_cost(int recall_cost)
Definition: unit.hpp:174
void refog()
Definition: team.hpp:322
int intf_play_sound(lua_State *L)
Plays a sound, possibly repeated.
LUA_API void lua_getglobal(lua_State *L, const char *var)
Definition: lapi.cpp:602
boost::shared_ptr< ai_composite > ai_ptr
Definition: game_info.hpp:52
game_display * screen
Definition: resources.cpp:27
int intf_label(lua_State *L)
Extends variable_info with methods that can only be applied if vit != vit_const.
static int special_locations_newindex(lua_State *L)
bool file_exists() const
Tests whether the file the locater points at exists.
Definition: image.cpp:628
map_location find_vacant_tile(const map_location &loc, VACANT_TILE_TYPE vacancy, const unit *pass_check, const team *shroud_check, const game_board *board)
Function that will find a location on the board that is as near to loc as possible, but which is unoccupied by any units.
Definition: pathfind.cpp:56
LUALIB_API int luaL_getmetafield(lua_State *L, int obj, const char *event)
Definition: lauxlib.cpp:701
LUA_API int lua_gettop(lua_State *L)
Definition: lapi.cpp:154
std::string id
Definition: time_of_day.hpp:77
int intf_extract_unit(lua_State *L)
Extracts a unit from the map or a recall list and gives it to Lua.
std::string usage() const
Definition: unit.hpp:360
bool luaW_pushvariable(lua_State *L, variable_access_const &v)
Definition: lua_common.cpp:816
static int intf_copy_unit(lua_State *L)
Copies a unit.
void remove_floating_label(int handle)
removes the floating label given by 'handle' from the screen
std::string register_metatable(lua_State *L)
static int special_locations_next(lua_State *L)
int intf_get_all_vars(lua_State *L)
Gets all the WML variables currently set.
int intf_find_cost_map(lua_State *L)
Is called with one or more units and builds a cost map.
static int impl_unit_get(lua_State *L)
Gets some data on a unit (__index metamethod).
void clear(const std::string &key)
const std::string & id() const
Definition: race.hpp:33
int lawful_bonus
The % bonus lawful units receive.
Definition: time_of_day.hpp:70
#define return_string_attrib(name, accessor)
Definition: lua_common.hpp:175
void float_label(const map_location &loc, const std::string &text, const SDL_Color &color)
Function to float a label above a tile.
dest_vect destinations
Definition: pathfind.hpp:100
#define lua_tointeger(L, i)
Definition: lua.h:319
int intf_set_time_of_day(lua_State *L)
unit_iterator begin()
Definition: map.hpp:308
const t_string & name() const
Definition: terrain.hpp:33
static int special_locations_index(lua_State *L)
void advance_to(const unit_type &t, bool use_traits=false)
Advances this unit to another type.
Definition: unit.cpp:904
static lua_ai_context * create(lua_State *L, char const *code, engine_lua *engine)
Definition: core.cpp:979
Composite AI stages.
std::string image
The image to be displayed in the game status.
Definition: time_of_day.hpp:74
unit_type_data unit_types
Definition: types.cpp:1314
const std::string & id() const
Definition: terrain.hpp:37
bool prescenario_save
Should a prescenario be created the next game?
bool fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
Definition: pump.cpp:471
int intf_set_village_owner(lua_State *L)
Sets the owner of a village.
int intf_match_unit(lua_State *L)
Matches a unit against the given filter.
int intf_set_next_scenario(lua_State *L)
void play_slice(bool is_delay_enabled=true)
void push_builtin_effect()
Registers a function for use as an effect handler.
int village_owner(const map_location &loc) const
Given the location of a village, will return the 0-based index of the team that currently owns it...
std::string name
Definition: pump.hpp:54
virtual const std::vector< team > & teams() const
Definition: game_board.hpp:97
Replay control code.
#define h
const attack_type * weapon
The weapon used by the unit to attack the opponent, or nullptr if there is none.
Definition: attack.hpp:51
#define lua_tonumber(L, i)
Definition: lua.h:318
void set_alignment(unit_type::ALIGNMENT alignment)
Definition: unit.hpp:369
advance_unit_params & fire_events(bool value)
Definition: attack.hpp:219
bool replay_save
Should a replay save be made?
int side() const
Definition: unit.hpp:201
void remove(const std::string &id)
Definition: soundsource.cpp:79
void write(config &cfg) const
Definition: unit.cpp:1379
bool slows
Attack slows opponent when it hits.
Definition: attack.hpp:56
int intf_skip_messages(lua_State *L)
Set whether to skip messages Arg 1 (optional) - boolean.
void set_font_size(int font_size)
GLenum src
Definition: glew.h:2392
LUA_API int lua_isuserdata(lua_State *L, int idx)
Definition: lapi.cpp:274
LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)
Definition: lapi.cpp:549
bool is_skipping_replay() const
unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map)
Definition: lua_api.cpp:199
int intf_scroll(lua_State *L)
virtual void draw()
Draws invalidated items.
Definition: display.cpp:2706
int impl_theme_items_set(lua_State *L)
Sets a field of the theme_items table (__newindex metamethod).
void set_state(const std::string &state, bool value)
Definition: unit.cpp:1337
void append_children(const config &cfg)
Adds children from cfg.
Definition: config.cpp:540
#define return_vector_string_attrib(name, accessor)
Definition: lua_common.hpp:210
luatypekey const getunitKey
Definition: lua_types.cpp:28
int light_bonus(int base) const
Returns the light (lawful) bonus for this terrain when the time of day gives a base bonus...
Definition: terrain.hpp:55
int max_attacks() const
Definition: unit.hpp:231
void set_defeat_condition_string(const std::string &value)
sets the defeat condition if
Definition: team.hpp:342
static bool is_handled_file_tag(const std::string &s)
unit_ptr get_shared()
Definition: lua_api.cpp:128
int intf_get_sides(lua_State *L)
Returns a proxy table array for all sides matching the given SSF.
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:314
void add_unit(const unit &u, bool use_max_moves=true)
Adds a units cost map to cost_map (increments the elements in cost_map)
Definition: pathfind.cpp:879
int drain_constant
Base HP drained regardless of damage dealt.
Definition: attack.hpp:78
an object to leave the synced context during draw or unsynced wml items when we don’t know whether w...
std::string debug() const
Definition: config.cpp:1438
void lua_chat(std::string const &caption, std::string const &msg)
int intf_gamestate_inspector(lua_State *)
bool get_ability_bool(const std::string &tag_name, const map_location &loc) const
Returns true if the unit is currently under effect by an ability with this given TAG NAME...
Definition: abilities.cpp:129
-file sdl_utils.hpp
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
bool run_wml_conditional(std::string const &, vconfig const &)
Runs a command from an event handler.
bool empty() const
Definition: config.cpp:1105
bool empty() const
Tests for an attribute that either was never set or was set to "".
Definition: config.cpp:375
map_location luaW_checklocation(lua_State *L, int index)
Converts an optional table or pair of integers to a map location object.
Definition: lua_common.cpp:655
void set_hidden(bool value)
Definition: team.hpp:345
GLdouble GLdouble t
Definition: glew.h:1366
void select_hex(const map_location &hex, const bool browse, const bool highlight=true, const bool fire_event=true)
Definitions for the interface to Wesnoth Markup Language (WML).
const t_string & editor_name() const
Definition: terrain.hpp:34
t_terrain read_terrain_code(const std::string &str, const t_layer filler)
Reads a single terrain from a string.
void redraw_minimap()
Schedule the minimap to be redrawn.
Definition: display.hpp:629
const game_events::queued_event & get_event_info()
void load_config(const config &v)
static synced_state get_synced_state()
unsigned int chance_to_hit
Effective chance to hit as a percentage (all factors accounted for).
Definition: attack.hpp:74
void new_turn()
Update lighting settings.
int rest_heal_amount
Definition: game_config.cpp:41
bool get_hidden() const
Definition: unit.hpp:304
std::map< int, config > get_user_choice_multiple_sides(const std::string &name, const user_choice &uch, std::set< int > sides)
Performs a choice for mutiple sides for WML events.
std::pair< const_child_iterator, const_child_iterator > const_child_itors
Definition: config.hpp:214
virtual config random_choice(int side) const =0
LUA_API void * lua_newuserdata(lua_State *L, size_t size)
Definition: lapi.cpp:1169
Variant for storing WML attributes.
Definition: config.hpp:223
int defense_modifier(const t_translation::t_terrain &terrain) const
Definition: unit.cpp:1520
int intf_get_locations(lua_State *L)
Gets all the locations matching a given filter.
config::attribute_value & get_variable(const std::string &varname)
throws invalid_variablename_exception if varname is no valid variable name.
Definition: game_data.cpp:70
advance_unit_params & animate(bool value)
Definition: attack.hpp:220
void set_scroll_to_leader(bool value)
Definition: team.hpp:226
Unit and team statistics.
bool match(const map_location &loc) const
Definition: filter.cpp:364
#define lua_pop(L, n)
Definition: lua.h:322
const tdata_cache & tdata() const
Definition: map.hpp:70
virtual config to_config() const
Serialize to config.
Definition: engine_lua.cpp:385
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
Definition: lua_api.cpp:183
std::string describe_builtin_effect(std::string type, const config &effect)
Definition: unit.cpp:1720
GLdouble l
Definition: glew.h:6966
void wml_animation(const vconfig &cfg, const map_location &default_location)
Parse a standard WML for animations and play the corresponding animation.
Definition: udisplay.cpp:771
void play_sound(const std::string &files, channel_group group, unsigned int repeats)
Definition: sound.cpp:818
#define return_cfgref_attrib(name, accessor)
Definition: lua_common.hpp:204
const terrain_label * set_label(const map_location &loc, const t_string &text, const int creator=-1, const std::string &team="", const SDL_Color color=font::NORMAL_COLOR, const bool visible_in_fog=true, const bool visible_in_shroud=false, const bool immutable=false, const std::string &category="", const t_string &tooltip="")
Definition: label.cpp:145
bool clear_dest(const map_location &dest, const unit &viewer)
Clears shroud (and fog) at the provided location and its immediate neighbors.
Definition: vision.cpp:495
bool reveal_map
Should we reveal map when game is ended? (Multiplayer only)
const std::vector< std::string > & recruits() const
Definition: unit.hpp:209
std::string flag_icon
Definition: game_config.cpp:84
bool blank() const
Tests for an attribute that was never set.
Definition: config.cpp:367
map_location loc_
static void extract_preload_scripts(config const &game_config)
static int impl_unit_status_set(lua_State *L)
Sets the status of a unit (__newindex metamethod).
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
int intf_find_reach(lua_State *L)
Finds all the locations reachable by a unit.
void set_game_display(game_display *gd)
bool poisons
Attack poisons opponent when it hits.
Definition: attack.hpp:60
static int intf_unit_ability(lua_State *L)
Returns true if the unit has the given ability enabled.
int intf_set_variable(lua_State *L)
Sets a WML variable.
int(game_lua_kernel::* member_callback2)(lua_State *, bool)
void set_no_turn_confirmation(bool value)
Definition: team.hpp:363
std::string register_metatable(lua_State *L)
Definition: lua_team.cpp:155
void set_flag(const std::string &flag)
Definition: team.hpp:304
STRIP_SPACES : strips leading and trailing blank spaces.
void set_role(const std::string &role)
Definition: unit.hpp:264
int intf_delay(lua_State *L)
Delays engine for a while.
t_string name
Definition: time_of_day.hpp:75
static bool add_ai_for_side_from_file(side_number side, const std::string &file, bool replace=true)
Adds active AI for specified side from file.
Definition: manager.cpp:640
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:48
void set_current_time(int time)
static std::vector< team > *& teams
Definition: team.cpp:50
lua_unit * luaW_pushlocalunit(lua_State *L, unit &u)
Definition: lua_api.cpp:212
#define lua_upvalueindex(i)
Definition: lua.h:40
bool backstab_pos
True if the attacker is in position to backstab the defender (this is used to determine whether to ap...
Definition: attack.hpp:61
const std::string & type_id() const
The id of the type of the unit.
Definition: unit.hpp:142
static void clear_status_caches()
Clear the unit status cache for all units.
Definition: unit.cpp:610
LUA_INTEGER lua_Integer
Definition: lua.h:106
unit_map units_
Definition: game_board.hpp:63
game_events::t_pump & pump()
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
static int intf_eval_conditional(lua_State *L)
Evaluates a boolean WML conditional.
static game_config_manager * get()
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:57
static std::string at(const std::string &file, int line)
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
#define modify_tstring_attrib(name, accessor)
Definition: lua_common.hpp:223
void select_hex_callback(const map_location &loc)
int intf_get_map_size(lua_State *L)
Returns the map size.
bool incapacitated() const
Definition: unit.hpp:215
LUA_API void lua_setglobal(lua_State *L, const char *var)
Definition: lapi.cpp:728
void set_facing(map_location::DIRECTION dir) const
Definition: unit.cpp:1491
int damage
Effective damage of the weapon (all factors accounted for).
Definition: attack.hpp:75
static int intf_get_viewing_side(lua_State *L)
Gets currently viewing side.
GLsizei const char ** path
Definition: glew.h:4654
boost::variant< upkeep_full, upkeep_loyal, int > t_upkeep
Definition: unit.hpp:297
std::string register_vconfig_metatable(lua_State *L)
Adds the vconfig metatable.
Definition: lua_common.cpp:419
const map_location & mouseover_hex() const
Definition: display.hpp:293
bool null() const
Definition: variable.hpp:66
GLuint64EXT * result
Definition: glew.h:10727
#define modify_string_attrib(name, accessor)
Definition: lua_common.hpp:230
bool linger_mode
Should linger mode be invoked?
std::vector< map_location > steps
Definition: pathfind.hpp:135
int intf_simulate_combat(lua_State *L)
Simulates a combat between two units.
int intf_select_unit(lua_State *L)
Selects and highlights the given location on the map.
int intf_remove_tile_overlay(lua_State *L)
Removes an overlay from a tile.
int current_side() const
Returns the number of the side whose turn it is.
int gives_healing() const
Definition: terrain.hpp:61
void splice_children(config &src, const std::string &key)
Moves all the children with tag key from src to this.
Definition: config.cpp:837
const std::vector< std::string > & overlays() const
Definition: unit.hpp:260
GLuint id
Definition: glew.h:1647
#define return_int_attrib(name, accessor)
Definition: lua_common.hpp:178
int intf_remove_time_area(lua_State *)
Removing new time_areas dynamically with Standard Location Filters.
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil...
Definition: lua_common.cpp:792
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:268
map_location starting_position(int side) const
Definition: map.cpp:421
std::vector< team > teams_
Definition: game_board.hpp:58
tod_manager & tod_man()
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:811
component * get_component(component *root, const std::string &path)
Definition: manager.cpp:302
pointer get_shared_ptr() const
Definition: map.hpp:180
const unit_type_map & types() const
Definition: types.hpp:313
unit_type::ALIGNMENT alignment() const
Definition: unit.hpp:368
Structure which holds a single route between one location and another.
Definition: pathfind.hpp:132
bool valid() const
Definition: location.hpp:69
bool is_regular_game_end() const
void register_generator(const std::string &name, generator *)
Definition: reports.cpp:1564
void set_emit_zoc(bool val)
Definition: unit.hpp:267
unsigned int rounds
Berserk special can force us to fight more than one round.
Definition: attack.hpp:71
child_list get_children(const std::string &key) const
Definition: variable.cpp:181
std::ostringstream wrapper.
Definition: formatter.hpp:32
void set_lifetime(int lifetime)
std::pair< unit_iterator, bool > insert(unit_ptr p)
Adds the unit to the map.
Definition: map.cpp:126
map_location curr
Definition: pathfind.hpp:88
Proxy table for the AI context.
Definition: core.hpp:35
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition: display.hpp:623
virtual std::string get_engine() const =0
static lua_ai_action_handler * create(lua_State *L, char const *code, lua_ai_context &context)
Definition: core.cpp:1022
boost::scoped_ptr< game_events::manager > events_manager_
Definition: game_state.hpp:54
const std::string & editor_image() const
Definition: terrain.hpp:32
size_t turn() const
variable_access_create get_variable_access_write(const std::string &varname)
returns a variable_access that can be used to change the game variables
Definition: game_data.hpp:55
const GLdouble * v
Definition: glew.h:1359
GLsizei const GLfloat * value
Definition: glew.h:1817
all_children_itors all_children_range() const
In-order iteration over all children.
Definition: config.cpp:1127
int intf_get_villages(lua_State *L)
Gets all the villages matching a given filter, or all the villages on the map if no filter is given...
void set_can_recruit(bool canrecruit)
Definition: unit.hpp:208
int intf_fire_wml_menu_item(lua_State *L)
Fires a wml menu item.
GLenum GLenum dst
Definition: glew.h:2392
void luaW_pushtstring(lua_State *L, t_string const &v)
Pushes a t_string on the top of the stack.
Definition: lua_common.cpp:462
void push_closure(lua_State *L, const lua_function &f, int nup)
Pushes a closure which retains a std::function object as its first up-value.
void remove_time_area(const std::string &id)
Removes a time area from config, making it follow the scenario's normal time-of-day sequence...
virtual bool is_visible() const
whether the choice is visible for the user like an advacement choice a non-visible choice is for exam...
A component of the AI framework.
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
Definition: lua_common.cpp:562
int vision_cost(const t_translation::t_terrain &terrain) const
Definition: unit.hpp:310
int w() const
Effective map width.
Definition: map.hpp:105
int intf_set_end_campaign_text(lua_State *L)
int intf_get_displayed_unit(lua_State *)
Gets the unit displayed in the sidebar.
void set_recruits(const std::vector< std::string > &recruits)
Definition: unit.cpp:1112
Composite AI with turn sequence which is a vector of stages.
static int intf_unit_resistance(lua_State *L)
Returns unit resistance against a given attack type.
Interface for querying local choices.
std::string synced_state()
converts synced_context::get_synced_state() to a string.
virtual void log_error(char const *msg, char const *context="Lua error")
config generate_report(const std::string &name, context &ct, bool only_static=false)
Definition: reports.cpp:1569
int intf_get_recall_units(lua_State *L)
Gets the numeric ids of all the units matching a given filter on the recall lists.
bool has_child(const std::string &key) const
Returns whether or not *this has a child whose key is key.
Definition: variable.cpp:270
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
bool plagues
Attack turns opponent into a zombie when fatal.
Definition: attack.hpp:59
static int intf_synchronize_choices(lua_State *L)
Ensures a value is synchronized among all the clients.
void play_music_config(const config &music_node)
Definition: sound.cpp:552
Encapsulates the map of the game.
Definition: map.hpp:37
virtual ai_context & get_ai_context()
unwrap
Definition: ai.cpp:208
bool protected_call(int nArgs, int nRets, error_handler)
int(game_lua_kernel::* member_callback)(lua_State *)
bool can_recruit() const
Definition: unit.hpp:207
#define WRN_LUA
void set_color(const SDL_Color &color)
Computes the statistics of a battle between an attacker and a defender unit.
Definition: attack.hpp:135
unit & luaW_checkunit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
Definition: lua_api.cpp:205
void initialize(const config &level)
int kill_experience
Definition: game_config.cpp:43
luatypekey const ustatusKey
Definition: lua_types.cpp:30
const std::string & team_name() const
Definition: team.hpp:297
config & add_child(const std::string &key)
Definition: config.cpp:743
std::string end_text
end-of-campaign text
const map_location & displayed_unit_hex() const
Virtual functions shadowed in game_display.
const t_advancements & modification_advancements() const
Definition: unit.hpp:333
void set_village_support(int support)
Definition: team.hpp:206
fake_unit_manager * fake_units
Definition: resources.cpp:32
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg)
Definition: lauxlib.cpp:377
tod_manager tod_manager_
Definition: game_state.hpp:50
unit_race::GENDER gender() const
Definition: unit.hpp:203
LUA_API int lua_setmetatable(lua_State *L, int objindex)
Definition: lapi.cpp:806
int intf_teleport(lua_State *L)
Teeleports a unit to a location.
int intf_get_village_owner(lua_State *L)
Gets the side of a village owner.
int border_size() const
Size of the map border.
Definition: map.hpp:111
void set_position(double xpos, double ypos)
int cfun_builtin_effect(lua_State *L)
Applies its upvalue as an effect Arg 1: The unit to apply to Arg 3: The [effect] tag contents Arg 3: ...
void unit_healing(unit &healed, const std::vector< unit * > &healers, int healing, const std::string &extra_text)
This will use a poisoning anim if healing<0.
Definition: udisplay.cpp:731
Managing the AIs lifecycle - headers.
int attack_num
Index into unit->attacks() or -1 for none.
Definition: attack.hpp:52
int intf_is_enemy(lua_State *L)
Returns whether the first side is an enemy of the second one.
Structure describing the statistics of a unit involved in the battle.
Definition: attack.hpp:49
bool carryover_report
Should a summary of the scenario outcome be displayed?
static void modify_active_ai_for_side(ai::side_number side, const config &cfg)
Modifies AI parameters for active AI of the given side.
Definition: manager.cpp:722
int intf_is_skipping_messages(lua_State *L)
Return true if a replay is in progress but the player has chosen to skip it.
int intf_get_sound_source(lua_State *L)
Get an existing sound source Arg 1: The sound source ID Return: Config of sound source info...
LUALIB_API void * luaL_testudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:292
int intf_put_unit(lua_State *L)
Places a unit on the map.
static void push_component(lua_State *L, ai::component *c, const std::string &ct="")
static int intf_unit_vision_cost(lua_State *L)
Returns unit vision cost on a given terrain.
void needs_rebuild(bool b)
Sets whether the screen (map visuals) needs to be rebuilt. This is typically after the map has been c...
static void push_locations_talbe(lua_State *L)
Error used for any general game error, e.g.
Definition: game_errors.hpp:46
int movement_left() const
Returns how far a unit can move this turn (zero if incapacitated).
Definition: unit.hpp:220
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3525
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
bool is_village() const
Definition: terrain.hpp:62
int intf_redraw(lua_State *L)
Templates and utility-routines for strings and numbers.
void set_fog(bool fog)
Definition: team.hpp:324
LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *isnum)
Definition: lapi.cpp:329
#define lua_newtable(L)
Definition: lua.h:324
const std::string & id() const
Definition: attack_type.hpp:36
void remove_fog_override(const std::set< map_location > &hexes)
Removes the record of hexes that were cleared of fog via WML.
Definition: team.cpp:644
int intf_add_tile_overlay(lua_State *L)
Adds an overlay on a tile.
void place_shroud(const map_location &loc)
Definition: team.hpp:319
virtual config query_user(int side) const =0
int impl_current_get(lua_State *L)
Gets some data about current point of game (__index metamethod).
static int intf_set_music(lua_State *L)
Modifies the music playlist.
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.cpp:459
all_children_iterator erase(const all_children_iterator &i)
Definition: config.cpp:894
#define modify_vector_string_attrib(name, accessor)
Definition: lua_common.hpp:259
GLuint color
Definition: glew.h:5801
void erase_if_matches_id(const std::string &unit_id)
Erase any unit with this id.
const std::vector< attack_type > & attacks() const
Definition: unit.hpp:271
void load_game(const config &level)
Executes the game_events.on_load function and passes to it all the scenario tags not yet handled...
LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
Definition: lapi.cpp:467
advances the unit at loc if it has enough experience, maximum 20 times.
Definition: attack.hpp:214
int move_cost
Movement cost for reaching the end of the route.
Definition: pathfind.hpp:137
void write(config &cfg) const
Definition: location.cpp:205
const std::string & save_id() const
Definition: team.hpp:236
const std::string &parameters float amount
Definition: filter.cpp:132
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:47
static int impl_unit_equality(lua_State *L)
Checks two lua proxy units for equality.
static int intf_get_time_stamp(lua_State *L)
Returns the time stamp, exactly as [set_variable] time=stamp does.
virtual void force_end_turn()=0
lu_byte right
Definition: lparser.cpp:1020
play_controller & play_controller_
int intf_modify_side(lua_State *L)
void set_allow_end_turn(bool value)
Definition: game_data.hpp:82
double slowed
Resulting chance we are slowed.
int impl_theme_item(lua_State *L, std::string name)
Executes its upvalue as a theme item generator.
void save_game(config &level)
Executes the game_events.on_save function and adds to cfg the returned tags.
Encapsulates the map of the game.
Definition: location.hpp:38
ai::lua_ai_context * create_lua_ai_context(char const *code, ai::engine_lua *engine)
void set_village_gold(int income)
Definition: team.hpp:199
int intf_add_event(lua_State *L)
Adding new events.
Various functions related to moving units.
#define lua_isboolean(L, n)
Definition: lua.h:334
double turbo_speed() const
Definition: display.cpp:2631
void unit_die(const map_location &loc, unit &loser, const attack_type *attack, const attack_type *secondary_attack, const map_location &winner_loc, unit *winner)
Show a unit fading out.
Definition: udisplay.cpp:548
int jamming_cost(const t_translation::t_terrain &terrain) const
Definition: unit.hpp:312
Storage for a unit, either owned by the Lua code (ptr != 0), a local variable unit (c_ptr != 0)...
Definition: lua_api.hpp:62
virtual std::string get_name() const =0
int intf_message(lua_State *L)
Displays a message in the chat window and in the logs.
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:675
All combat-related info.
Define conditionals for the game's events mechanism, a.k.a.
bool luaW_totstring(lua_State *L, int index, t_string &str)
Converts a scalar to a translatable string.
Definition: lua_common.cpp:537
#define return_cfg_attrib(name, accessor)
Definition: lua_common.hpp:196
int intf_heal_unit(lua_State *L)
Sound source info class.
void set_end_level_data(const end_level_data &data)
int on_recall_list() const
Definition: lua_api.hpp:77
GLuint res
Definition: glew.h:9258
LUA_API void * lua_touserdata(lua_State *L, int idx)
Definition: lapi.cpp:421
void erase_by_underlying_id(size_t uid)
Erase any unit with this underlying id.
void add_modification(const std::string &type, const config &modification, bool no_add=false)
Definition: unit.cpp:2133
static void init(lua_State *L)
Definition: core.cpp:59
int impl_game_config_set(lua_State *L)
Sets some game_config data (__newindex metamethod).
bool luaW_hasmetatable(lua_State *L, int index, luatypekey key)
Returns true if the metatable of the object is the one found in the registry.
Definition: lua_common.cpp:524
game_data & gamedata()
transient_end_level transient
#define lua_isnil(L, n)
Definition: lua.h:333
void luaW_pushracetable(lua_State *L)
Definition: lua_race.cpp:121
static bool add_component(component *root, const std::string &path, const config &cfg)
Definition: component.cpp:190
const std::vector< std::string > & advances_to() const
Definition: unit.hpp:133
void get_locations(std::set< map_location > &locs, bool with_border=false) const
Definition: filter.cpp:495
std::vector< std::string > get_area_ids() const
void set_video(CVideo *ptr)
Cost function object relying on a Lua function.
void set_gold(int amount)
Definition: team.hpp:211
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
GLint left
Definition: glew.h:5907
unit * get()
Definition: lua_api.cpp:117
virtual void push_ai_table()
Method that pushes the AI table of the lua_context on the stack for debugging purposes.
Definition: engine_lua.cpp:287
bool clear_shroud(const map_location &loc)
Definition: team.hpp:318
game_board & board()
std::stringstream & wml_error()
Use this logger to send errors due to deprecated WML.
Definition: log.cpp:262
int intf_end_turn(lua_State *)
int h() const
Effective map height.
Definition: map.hpp:108
int intf_remove_event(lua_State *L)
void scroll_to_tile(const map_location &loc, SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true, bool force=true)
Scroll such that location loc is on-screen.
Definition: display.cpp:2434
map_location::DIRECTION facing() const
Definition: unit.hpp:278
LUA_API void lua_rawset(lua_State *L, int idx)
Definition: lapi.cpp:764
static int impl_unit_variables_get(lua_State *L)
Gets the variable of a unit (__index metamethod).
void add(const sourcespec &source)
Definition: soundsource.cpp:57
void add_event_handler(const config &handler, bool is_menu_item=false)
Create an event handler.
Definition: manager.cpp:50
void set_name(const t_string &name)
Definition: unit.hpp:159
static int intf_synchronize_choice(lua_State *L)
Ensures a value is synchronized among all the clients.
int intf_get_units(lua_State *)
Gets all the units matching a given filter.
bool is_keep() const
Definition: terrain.hpp:64
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:749
static int intf_unit_movement_cost(lua_State *L)
Returns unit movement cost on a given terrain.
config & variables()
Definition: unit.hpp:366
void set_location(const map_location &loc)
To be called by unit_map or for temporary units only.
Definition: unit.hpp:288
Game configuration data as global variables.
Definition: build_info.cpp:38
int village_income
Definition: game_config.cpp:38
#define lua_isfunction(L, n)
Definition: lua.h:330
const config & get_config() const
Definition: variable.hpp:68
const config & game_config() const
GLuint index
Definition: glew.h:1782
const SDL_Color LABEL_COLOR
Definition: font.cpp:574
int intf_set_side_variable(lua_State *L)
Gets a side specific WML variable.
int attacks_left() const
Definition: unit.hpp:230
static int intf_debug_ai(lua_State *L)
Debug access to the ai tables.
int turn() const
Structure which uses find_routes() to build a cost map This maps each hex to a the movements a unit w...
Definition: pathfind.hpp:267
static int impl_unit_attacks_len(lua_State *L)
Counts the attacks of a unit (__len metamethod).
static int cfun_exec_stage(lua_State *L)
int intf_animate_unit(lua_State *)
Define the game's event mechanism.
#define log_scope(description)
Definition: log.hpp:185
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:5910
int intf_scroll_to_tile(lua_State *L)
Scrolls to given tile.
LUALIB_API int luaL_argerror(lua_State *L, int narg, const char *extramsg)
Definition: lauxlib.cpp:152
bool resting() const
Definition: unit.hpp:242
size_t i
Definition: function.cpp:1057
void set_movement(int moves, bool unit_action=false)
Set the unit's remaining movement to moves.
Definition: unit.cpp:1148
bool firststrike
Attack has firststrike special.
Definition: attack.hpp:66
const std::string & variation() const
Definition: unit.hpp:155
static int impl_unit_attack_get(lua_State *L)
Gets a propoerty of a units attack (__index metamethod).
#define lua_tostring(L, i)
Definition: lua.h:345
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
int add_floating_label(const floating_label &flabel)
add a label floating on the screen above everything else.
LUA_API void lua_rawseti(lua_State *L, int idx, int n)
Definition: lapi.cpp:778
ai::lua_ai_action_handler * create_lua_ai_action_handler(char const *code, ai::lua_ai_context &context)
bool run_filter(char const *name, unit const &u)
Runs a script from a unit filter.
variable_access_const get_variable_access_read(const std::string &varname) const
returns a variable_access that cannot be used to change the game variables
Definition: game_data.hpp:49
void set_side(unsigned int new_side)
Definition: unit.hpp:204
int intf_lock_view(lua_State *L)
Sets whether gamemap scrolling is disabled for the user.
bool proceed_to_next_level
whether to proceed to the next scenario, equals is_victory in sp.
int intf_add_time_area(lua_State *)
Adding new time_areas dynamically with Standard Location Filters.
static int intf_debug(lua_State *L)
Dumps a wml table or userdata wml object into a pretty string.
void set_upkeep(t_upkeep v)
Definition: unit.hpp:300
bool change_terrain(const map_location &loc, const std::string &t, const std::string &mode, bool replace_if_failed)
Definition: game_board.cpp:298
void set_flag_icon(const std::string &flag_icon)
Definition: team.hpp:305
int intf_get_starting_location(lua_State *L)
Returns the starting position of a side.
static int intf_get_image_size(lua_State *L)
Gets the dimension of an image.
int level() const
Definition: unit.hpp:175
bool on_map() const
Definition: lua_api.hpp:76
game_data gamedata_
Definition: game_state.hpp:48
LUA_API void lua_insert(lua_State *L, int idx)
Definition: lapi.cpp:187
Additional information on the game outcome which can be provided by WML.
std::set< std::string > & encountered_units()
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.cpp:229
static int intf_get_traits(lua_State *L)
.Returns information about the global traits known to the engine.
#define debug(x)
int impl_game_config_get(lua_State *L)
Gets some game_config data (__index metamethod).
int intf_get_selected_tile(lua_State *L)
Returns the currently selected tile.
The game event manager loads the scenario configuration object, and ensures that events are handled a...
Definition: manager.hpp:47
std::string register_metatable(lua_State *L)
Definition: lua_race.cpp:96
bool context_mutated()
Context: The general environment within which events are processed.
Definition: pump.cpp:430
LUA_API int lua_isnumber(lua_State *L, int idx)
Definition: lapi.cpp:261
void set_view_locked(bool value)
Sets whether the map view is locked (e.g.
Definition: display.hpp:549
int intf_set_menu_item(lua_State *L)
static vconfig unconstructed_vconfig()
This is just a wrapper for the default constructor; it exists for historical reasons and to make it c...
Definition: variable.cpp:108
bool fire_event(const tevent event, std::vector< std::pair< twidget *, tevent > > &event_chain, twidget *dispatcher, twidget *widget, F functor)
Helper function for fire_event.
static int intf_add_known_unit(lua_State *L)
Adds a new known unit type to the help system.
virtual void log_error(char const *msg, char const *context="Lua error")
int intf_add_sound_source(lua_State *L)
Add a new sound source Arg 1: Table containing keyword arguments.
static int intf_unit_jamming_cost(lua_State *L)
Returns unit jamming cost on a given terrain.
std::pair< unit_iterator, bool > move(const map_location &src, const map_location &dst)
Moves a unit from location src to location dst.
Definition: map.cpp:79
int intf_shroud_op(lua_State *L, bool place_shroud)
void change_controller_by_wml(const std::string &new_controller)
Definition: team.cpp:512
LUALIB_API int luaL_error(lua_State *L, const char *fmt,...)
Definition: lauxlib.cpp:198
std::string write_terrain_code(const t_terrain &tcode)
Writes a single terrain code to a string.
int resistance_against(const std::string &damage_name, bool attacker, const map_location &loc) const
Definition: unit.cpp:1559
Proxy class for calling AI action handlers defined in Lua.
Definition: core.hpp:71
const config::const_child_itors traits() const
Definition: types.hpp:315
std::string big_profile() const
Definition: unit.cpp:1012
int intf_allow_undo(lua_State *)
Allow undo sets the flag saying whether the event has mutated the game to false.
static int load_fake_units(lua_State *L, int arg, T &fake_units)
int drain_percent
Percentage of damage recovered as health.
Definition: attack.hpp:77
virtual std::vector< std::string > get_children_types()
Definition: component.cpp:123
int intf_match_side(lua_State *L)
Matches a side against the given filter.
GLuint const GLchar * name
Definition: glew.h:1782
virtual const gamemap & map() const
Definition: game_board.hpp:98
std::set< std::string > set_split(std::string const &val, const char c= ',', const int flags=REMOVE_EMPTY|STRIP_SPACES)
Splits a (comma-)separated string into a set of pieces.
size_t erase(const map_location &l)
Erases the unit at location l, if any.
Definition: map.cpp:277
entity_location loc1
Definition: pump.hpp:55
int intf_toggle_fog(lua_State *L, const bool clear)
Implements the lifting and resetting of fog via WML.
const game_classification & get_classification()
LUA_API size_t lua_rawlen(lua_State *L, int idx)
Definition: lapi.cpp:401
bool clear_shroud(int side, bool reset_fog, bool fire_events)
Function that will clear shroud (and fog) based on current unit positions.
Definition: vision.cpp:754
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:467
virtual double evaluate()=0
Evaluate the candidate action, resetting the internal state of the action.
bool run_event(game_events::queued_event const &)
Executes the game_events.on_event function.
bool fire_events()
Fires the sighted events that were earlier recorded by fog/shroud clearing.
Definition: vision.cpp:547
const time_of_day get_illuminated_time_of_day(const unit_map &units, const gamemap &map, const map_location &loc, int for_turn=0) const
Returns time of day object for the passed turn at a location.
command_log cmd_log_
GLsizeiptr size
Definition: glew.h:1649
void add_overlay(const map_location &loc, const std::string &image, const std::string &halo="", const std::string &team_name="", const std::string &item_id="", bool visible_under_fog=true)
Functions to add and remove overlays from locations.
Definition: display.cpp:97
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:3448
display_chat_manager & get_chat_manager()
virtual std::string my_name()
const std::string & effect_image_mods() const
Definition: unit.cpp:2439
size_t find_index(const std::string &unit_id) const
Find the index of a unit by its id.
bool conditional_passed(const vconfig &cond)
#define LUA_REGISTRYINDEX
Definition: lua.h:39
#define return_bool_attrib(name, accessor)
Definition: lua_common.hpp:190
bool matches_unit(const unit_map::const_iterator &un_it) const
Determines if un_it matches (using underlying ID) the unit that was supplied when this was constructe...
To store label data Class implements logic for rendering.
Definition: label.hpp:103
boost::intrusive_ptr< unit > unit_ptr
Definition: ptr.hpp:29
GLclampd n
Definition: glew.h:5903
#define luaL_checkint(L, n)
Definition: lauxlib.h:117
LUA_API int lua_error(lua_State *L)
Definition: lapi.cpp:1099
void set_advancements(std::vector< config > advancements)
Definition: unit.cpp:1685
int intf_erase_unit(lua_State *L)
Erases a unit from the map.
boost::shared_ptr< wb::manager > get_whiteboard()
static const config & get_default_ai_parameters()
get default AI parameters
bool put_map(const map_location &loc)
Definition: lua_api.cpp:143
int max_experience() const
Definition: unit.hpp:172
map_locker(game_lua_kernel *kernel)
int intf_color_adjust(lua_State *L)
const GLdouble * m
Definition: glew.h:6968
int recall_cost() const
Definition: unit.hpp:177
int intf_open_help(lua_State *L)
#define lua_istable(L, n)
Definition: lua.h:331
static int intf_modify_ai(lua_State *L)
Lua frontend to the modify_ai functionality.
int intf_clear_menu_item(lua_State *L)
bool find(E event, F functor)
Tests whether an event handler is available.
void add_time_area(const gamemap &map, const config &cfg)
Adds a new local time area from config, making it follow its own time-of-day sequence.
void luaW_pushconfig(lua_State *L, config const &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:663
int intf_get_mouseover_tile(lua_State *L)
Returns the currently overed tile.
void merge_shroud_map_data(const std::string &shroud_data)
Merge a WML shroud map with the shroud data of this player.
Definition: team.hpp:327
void luaW_pushlocation(lua_State *L, const map_location &ml)
Converts a map location object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:593
#define ERR_LUA
Managing the AIs configuration - headers.
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
game_board board_
Definition: game_state.hpp:49
static int cond(LexState *ls)
Definition: lparser.cpp:1168
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
int cost() const
Definition: unit.hpp:284
std::vector< attack_type > attacks() const
Definition: types.cpp:484
Composite AI contexts.
GLint GLvoid * img
Definition: glew.h:1353
A variable-expanding proxy for the config class.
Definition: variable.hpp:36
bool show_everything() const
Definition: display.hpp:90
unit_ptr extract(const map_location &loc)
Extracts a unit from the map.
Definition: map.cpp:249
Standard logging facilities (interface).
static void luaW_pushsimweapon(lua_State *L, const battle_context_unit_stats &bcustats)
Puts a table at the top of the stack with information about the combatants' weapons.
static config preload_config
const SDL_Rect & map_outside_area() const
Returns the available area for a map, this may differ from the above.
Definition: display.hpp:248
CVideo & video()
Gets the underlying screen object.
Definition: display.hpp:202
Object which contains all the possible locations a unit can move to, with associated best routes to t...
Definition: pathfind.hpp:71
static int intf_unit_defense(lua_State *L)
Returns unit defense on a given terrain.
recall_list_manager & recall_list()
Definition: team.hpp:220
void add(const unit_ptr &ptr)
Add a unit to the list.
void add_fog_override(const std::set< map_location > &hexes)
Records hexes that were cleared of fog via WML.
Definition: team.hpp:331
Container associating units to locations.
Definition: map.hpp:90
static void delay(unsigned int milliseconds)
Definition: video.cpp:490
#define LOG_LUA
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
#define c
Definition: glew.h:12743
void reinit_flags_for_side(size_t side)
Rebuild the flag list (not team colors) for a single side.
Definition: display.cpp:282
game_lua_kernel * kernel_
void set_attacks(int left)
Definition: unit.hpp:233
int intf_print(lua_State *L)
int to_int(int def=0) const
Definition: config.cpp:308
void set_item(const std::string &id, const vconfig &menu_item)
Updates or creates (as appropriate) the menu item with the given id.
void mouse_over_hex_callback(const map_location &loc)
static int cfun_exec_candidate_action(lua_State *L)
void change_team(const std::string &name, const t_string &user_name)
Definition: team.cpp:534
Class to encapsulate fog/shroud clearing and the resultant sighted events.
Definition: vision.hpp:58
void set_level(int level)
Definition: unit.hpp:176
unsigned int num_blows
Effective number of blows, takes swarm into account.
Definition: attack.hpp:79
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
Definition: types.cpp:1155
vconfig luaW_checkvconfig(lua_State *L, int index, bool allow_missing)
Gets an optional vconfig from either a table or a userdata.
Definition: lua_common.cpp:784
luatypekey const uattackKey
Definition: lua_types.cpp:32
double average_hp(unsigned int healing=0) const
What's the average hp (weighted average of hp_dist).
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
map_labels & labels()
Definition: display.cpp:2773
int side_number
Definition: game_info.hpp:44
static const map & registry()
Definition: action_wml.hpp:62
luatypekey const uattacksKey
Definition: lua_types.cpp:31
static int intf_do_unsynced(lua_State *L)
Calls a function in an unsynced context (this specially means that all random calls used by that func...
int intf_put_recall_unit(lua_State *L)
Puts a unit on a recall list.
int cfun_wml_action(lua_State *L)
Executes its upvalue as a wml action.
SDL_Color string_to_color(const std::string &cmp_str)
Return the color the string represents.
Definition: help_impl.cpp:1206
static int intf_add_modification(lua_State *L)
Adds a modification to a unit.
void set_base_income(int amount)
Definition: team.hpp:214
void clear_variable(const std::string &varname)
Clears attributes config children does nothing if varname is no valid variable name.
Definition: game_data.cpp:122
size_t viewing_team() const
The viewing team is the team currently viewing the game.
Definition: display.hpp:102
unit_iterator find(size_t id)
Definition: map.cpp:285
void commit_music_changes()
Definition: sound.cpp:621
int intf_get_side_variable(lua_State *L)
Gets a side specific WML variable.
void clear_all()
Definition: label.cpp:246
void set_recruits(const std::set< std::string > &recruits)
Definition: team.cpp:406
bool valid() const
Definition: map.hpp:229
int intf_get_terrain(lua_State *L)
Gets a terrain code.
const teleport_map get_teleport_locations(const unit &u, const team &viewing_team, bool see_all, bool ignore_units)
Definition: teleport.cpp:233
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
Definition: lauxlib.cpp:850
virtual soundsource::manager * get_soundsource_man()
Get (optionally) a soundsources manager a derived class uses.
static void luaW_pushsimdata(lua_State *L, const combatant &cmb)
Puts a table at the top of the stack with some combat result.
std::string custom_endlevel_music
Custom short music played at the end.
const std::string & get_role() const
Definition: unit.hpp:265
const std::string weapon
static bool intf_find_cost_map_helper(const unit *ptr)
int show_gamestate_inspector(CVideo &video, const vconfig &cfg)
Definition: lua_gui2.cpp:743
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
int intf_deselect_hex(lua_State *L)
Deselects any highlighted hex on the map.
bool petrifies
Attack petrifies opponent when it hits.
Definition: attack.hpp:58
bool get_emit_zoc() const
Definition: unit.hpp:268
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
int intf_check_end_level_disabled(lua_State *L)
void add_chat_message(const time_t &time, const std::string &speaker, int side, const std::string &msg, events::chat_handler::MESSAGE_TYPE type, bool bell)
bool is_castle() const
Definition: terrain.hpp:63
static ai::holder & get_active_ai_holder_for_side_dbg(side_number side)
Gets the active AI holder for debug purposes.
Definition: manager.cpp:749
void remove_single_overlay(const map_location &loc, const std::string &toDelete)
remove_single_overlay will remove a single overlay from a tile
Definition: display.cpp:124
int intf_find_vacant_tile(lua_State *L)
Finds a vacant tile.
LUA AI Support engine - creating specific ai components from config.
bool view_locked() const
Definition: display.hpp:546
lua_State * mState
config get(const std::string &id)
Definition: soundsource.cpp:69
GLdouble s
Definition: glew.h:1358
const t_string & description() const
Definition: terrain.hpp:35
static int impl_unit_attacks_get(lua_State *L)
Gets the attacks of a unit or unit type (__index metamethod).
void clear_ref()
Definition: lua_api.hpp:81
const std::vector< map_location > & villages() const
Return a list of the locations of villages on the map.
Definition: map.hpp:163
void set_experience(int xp)
Definition: unit.hpp:173
luatypekey const unitvarKey
Definition: lua_types.cpp:29
static int impl_unit_variables_set(lua_State *L)
Sets the variable of a unit (__newindex metamethod).
int dispatch2(lua_State *L)
const unit_race * race() const
Never returns nullptr, but may point to the null race.
Definition: unit.hpp:371
const GLuint * ids
Definition: glew.h:1652
int bonus_modified
Definition: time_of_day.hpp:71
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:477
bool scroll(int xmov, int ymov, bool force=false)
Scrolls the display by xmov,ymov pixels.
Definition: display.cpp:2206
Thrown when a lexical_cast fails.
void remove_overlay(const map_location &loc)
remove_overlay will remove all overlays on a tile.
Definition: display.cpp:108
This module contains various pathfinding functions and utilities.
LUALIB_API int luaL_typerror(lua_State *L, int narg, const char *tname)
Definition: lauxlib.cpp:176
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:144
std::vector< std::string > get_ability_list() const
Definition: abilities.cpp:210
const std::string version
Definition: game_config.cpp:48
LUA_API void lua_rawget(lua_State *L, int idx)
Definition: lapi.cpp:633
Defines the MAKE_ENUM macro.
bool drains
Attack drains opponent when it hits.
Definition: attack.hpp:57
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void display_unit_hex(map_location hex)
Change the unit to be displayed in the sidebar.
int intf_fire_event(lua_State *L)
Fires an event.
Define locations as used by the game's events mechanism.
void run_lua_tag(const config &cfg)
Runs a [lua] tag.
bool has_attribute(const std::string &key) const
< Synonym for operator[]
Definition: variable.hpp:92
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:507
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:752
const std::string & icon_image() const
Definition: terrain.hpp:29
unit_map::iterator find_visible_unit(const map_location &loc, const team &current_team, bool see_all=false)
Definition: game_board.cpp:173
Display units performing various actions: moving, attacking, and dying.
size_type erase(const std::string &id)
Erases the item with the provided id.
void move_unit(const std::vector< map_location > &path, unit_ptr u, bool animate, map_location::DIRECTION dir, bool force_scroll)
Display a unit moving along a given path.
Definition: udisplay.cpp:486
const map_location & selected_hex() const
Definition: display.hpp:292
bool luaW_tolocation(lua_State *L, int index, map_location &loc)
Converts an optional table or pair of integers to a map location object.
Definition: lua_common.cpp:606
void set_advances_to(const std::vector< std::string > &advances_to)
Definition: unit.cpp:1136
LUA_API const char * lua_typename(lua_State *L, int t)
Definition: lapi.cpp:249
double poisoned
Resulting chance we are poisoned.
static lg::log_domain log_scripting_lua("scripting/lua")
int intf_random(lua_State *L)
Returns a random numer, same interface as math.random.
const int SIZE_SMALL
Definition: font.hpp:62
static void modify_active_ai_config_old_for_side(side_number side, const config::const_child_itors &ai_parameters)
Modifies AI parameters for active AI of the given side.
Definition: manager.cpp:714
virtual void execute()=0
Execute the candidate action.
game_state & game_state_
all_children_iterator ordered_begin() const
Definition: config.cpp:1117
int number_of_turns() const
candidate action framework
t_upkeep upkeep_raw() const
Definition: unit.hpp:299
bool maybe_rebuild()
Rebuilds the screen if needs_rebuild(true) was previously called, and resets the flag.
int intf_select_hex(lua_State *L)
static std::vector< config > preload_scripts
int return_unit_method(lua_State *L, char const *m)
#define modify_int_attrib(name, accessor)
Definition: lua_common.hpp:237
int intf_float_label(lua_State *L)
Floats some text on the map.
int intf_end_level(lua_State *)
void set_color(const std::string &color)
Definition: team.hpp:258
game_events::wmi_container & get_wml_menu_items()
Definition: game_state.cpp:385
std::vector< std::string > get_traits_list() const
Definition: unit.cpp:883
virtual config generate(context &ct)=0
static int intf_create_unit(lua_State *L)
Creates a unit from its WML description.
#define luaL_checkstring(L, n)
Definition: lauxlib.h:115
int intf_highlight_hex(lua_State *L)
Highlights the given location on the map.
game_lua_kernel(CVideo *, game_state &, play_controller &, reports &)