The Battle for Wesnoth  1.15.5+dev
lua_unit.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Guillaume Melquiond <guillaume.melquiond@gmail.com>
3  Part of the Battle for Wesnoth Project https://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 #include "scripting/lua_unit.hpp"
16 
17 #include "formatter.hpp"
18 #include "game_board.hpp"
19 #include "log.hpp"
20 #include "map/location.hpp" // for map_location
21 #include "map/map.hpp"
22 #include "resources.hpp"
23 #include "scripting/lua_common.hpp"
25 #include "scripting/push_check.hpp"
27 #include "units/unit.hpp"
28 #include "units/map.hpp"
30 #include "game_version.hpp"
31 #include "deprecation.hpp"
32 
33 #include "lua/lauxlib.h"
34 #include "lua/lua.h" // for lua_State, lua_settop, etc
35 
36 static lg::log_domain log_scripting_lua("scripting/lua");
37 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
38 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
39 
40 static const char getunitKey[] = "unit";
41 static const char ustatusKey[] = "unit status";
42 static const char unitvarKey[] = "unit variables";
43 
45 {
46 }
47 
49 {
50  if (ptr) return ptr.get();
51  if (c_ptr) return c_ptr;
52  if (side) {
54  }
56  if (!ui.valid()) return nullptr;
57  return ui.get_shared_ptr().get(); //&*ui would not be legal, must get new shared_ptr by copy ctor because the unit_map itself is holding a boost shared pointer.
58 }
60 {
61  if (ptr) return ptr;
62  if (side) {
64  }
66  if (!ui.valid()) return unit_ptr();
67  return ui.get_shared_ptr(); //&*ui would not be legal, must get new shared_ptr by copy ctor because the unit_map itself is holding a boost shared pointer.
68 }
69 
70 // Having this function here not only simplifies other code, it allows us to move
71 // pointers around from one structure to another.
72 // This makes bare pointer->map in particular about 2 orders of magnitude faster,
73 // as benchmarked from Lua code.
75 {
76  if (ptr) {
78  bool success = false;
79 
80  std::tie(unit_it, success) = resources::gameboard->units().replace(loc, ptr);
81 
82  if(success) {
83  ptr.reset();
84  uid = unit_it->underlying_id();
85  } else {
86  ERR_LUA << "Could not move unit " << ptr->underlying_id() << " onto map location " << loc << '\n';
87  return false;
88  }
89  } else if (side) { // recall list
91  if (it) {
92  side = 0;
93  // uid may be changed by unit_map on insertion
94  uid = resources::gameboard->units().replace(loc, it).first->underlying_id();
95  } else {
96  ERR_LUA << "Could not find unit " << uid << " on recall list of side " << side << '\n';
97  return false;
98  }
99  } else { // on map
101  if (ui != resources::gameboard->units().end()) {
102  map_location from = ui->get_location();
103  if (from != loc) { // This check is redundant in current usage
105  resources::gameboard->units().move(from, loc);
106  }
107  // No need to change our contents
108  } else {
109  ERR_LUA << "Could not find unit " << uid << " on the map" << std::endl;
110  return false;
111  }
112  }
113  return true;
114 }
115 
117 {
118  return luaL_testudata(L, index,getunitKey) != nullptr;
119 }
120 
121 enum {
126 };
127 
128 static lua_unit* internal_get_unit(lua_State *L, int index, bool only_on_map, int& error)
129 {
130  error = LU_OK;
131  if(!luaW_isunit(L, index)) {
132  error = LU_NOT_UNIT;
133  return nullptr;
134  }
135  lua_unit* lu = static_cast<lua_unit*>(lua_touserdata(L, index));
136  if(only_on_map && !lu->on_map()) {
137  error = LU_NOT_ON_MAP;
138  }
139  if(!lu->get()) {
140  error = LU_NOT_VALID;
141  }
142  return lu;
143 }
144 
145 unit* luaW_tounit(lua_State *L, int index, bool only_on_map)
146 {
147  int error;
148  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
149  if(error != LU_OK) {
150  return nullptr;
151  }
152  return lu->get();
153 }
154 
155 unit_ptr luaW_tounit_ptr(lua_State *L, int index, bool only_on_map)
156 {
157  int error;
158  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
159  if(error != LU_OK) {
160  return nullptr;
161  }
162  return lu->get_shared();
163 }
164 
166 {
167  int error;
168  return internal_get_unit(L, index, false, error);
169 }
170 
171 static void unit_show_error(lua_State *L, int index, int error)
172 {
173  switch(error) {
174  case LU_NOT_UNIT:
175  luaW_type_error(L, index, "unit");
176  break;
177  case LU_NOT_VALID:
178  luaL_argerror(L, index, "unit not found");
179  break;
180  case LU_NOT_ON_MAP:
181  luaL_argerror(L, index, "unit not found on map");
182  break;
183  }
184 }
185 
186 unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map)
187 {
188  int error;
189  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
190  unit_show_error(L, index, error);
191  return lu->get_shared();
192 }
193 
194 unit& luaW_checkunit(lua_State *L, int index, bool only_on_map)
195 {
196  int error;
197  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
198  unit_show_error(L, index, error);
199  return *lu->get();
200 }
201 
203 {
204  int error;
205  lua_unit* lu = internal_get_unit(L, index, false, error);
206  unit_show_error(L, index, error);
207  return lu;
208 }
209 
211 {
213 }
214 
216 {
217  lua_unit* res = new(L) lua_unit(u);
219  return res;
220 }
221 
222 /**
223  * Destroys a unit object before it is collected (__gc metamethod).
224  */
226 {
227  lua_unit *u = static_cast<lua_unit *>(lua_touserdata(L, 1));
228  u->lua_unit::~lua_unit();
229  return 0;
230 }
231 
232 /**
233  * Checks two lua proxy units for equality. (__eq metamethod)
234  */
236 {
237  unit& left = luaW_checkunit(L, 1);
238  unit& right = luaW_checkunit(L, 2);
239  const bool equal = left.underlying_id() == right.underlying_id();
240  lua_pushboolean(L, equal);
241  return 1;
242 }
243 
244 /**
245  * Turns a lua proxy unit to string. (__tostring metamethod)
246  */
248 {
249  const lua_unit* lu = luaW_tounit_ref(L, 1);
250  unit &u = *lu->get();
251  std::ostringstream str;
252 
253  str << "unit: <";
254  if(!u.id().empty()) {
255  str << u.id() << " ";
256  } else {
257  str << u.type_id() << " ";
258  }
259  if(int side = lu->on_recall_list()) {
260  str << "at (side " << side << " recall list)";
261  } else {
262  str << "at (" << u.get_location() << ")";
263  }
264  str << '>';
265 
266  lua_push(L, str.str());
267  return 1;
268 }
269 
270 /**
271  * Gets some data on a unit (__index metamethod).
272  * - Arg 1: full userdata containing the unit id.
273  * - Arg 2: string containing the name of the property.
274  * - Ret 1: something containing the attribute.
275  */
276 static int impl_unit_get(lua_State *L)
277 {
278  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
279  char const *m = luaL_checkstring(L, 2);
280  const unit* pu = lu->get();
281 
282  if(strcmp(m, "valid") == 0) {
283  if(!pu) {
284  return 0;
285  }
286  if(lu->on_map()) {
287  lua_pushstring(L, "map");
288  } else if(lu->on_recall_list()) {
289  lua_pushstring(L, "recall");
290  } else {
291  lua_pushstring(L, "private");
292  }
293  return 1;
294  }
295 
296  if(!pu) {
297  return luaL_argerror(L, 1, "unknown unit");
298  }
299 
300  const unit& u = *pu;
301 
302  // Find the corresponding attribute.
303  return_int_attrib("x", u.get_location().wml_x());
304  return_int_attrib("y", u.get_location().wml_y());
305  if(strcmp(m, "loc") == 0) {
306  luaW_pushlocation(L, u.get_location());
307  return 1;
308  }
309  if(strcmp(m, "goto") == 0) {
310  luaW_pushlocation(L, u.get_goto());
311  return 1;
312  }
313  return_int_attrib("side", u.side());
314  return_string_attrib("id", u.id());
315  return_string_attrib("type", u.type_id());
316  return_string_attrib("image_mods", u.effect_image_mods());
317  return_string_attrib("usage", u.usage());
318  return_string_attrib("ellipse", u.image_ellipse());
319  return_string_attrib("halo", u.image_halo());
320  return_int_attrib("hitpoints", u.hitpoints());
321  return_int_attrib("max_hitpoints", u.max_hitpoints());
322  return_int_attrib("experience", u.experience());
323  return_int_attrib("max_experience", u.max_experience());
324  return_int_attrib("recall_cost", u.recall_cost());
325  return_int_attrib("moves", u.movement_left());
326  return_int_attrib("max_moves", u.total_movement());
327  return_int_attrib("max_attacks", u.max_attacks());
328  return_int_attrib("attacks_left", u.attacks_left());
329  return_tstring_attrib("name", u.name());
330  return_tstring_attrib("description", u.unit_description());
331  return_bool_attrib("canrecruit", u.can_recruit());
332  return_bool_attrib("renamable", !u.unrenamable());
333  return_int_attrib("level", u.level());
334  return_int_attrib("cost", u.cost());
335 
336  return_vector_string_attrib("extra_recruit", u.recruits());
337  return_vector_string_attrib("advances_to", u.advances_to());
338 
339  if(strcmp(m, "alignment") == 0) {
340  lua_push(L, u.alignment());
341  return 1;
342  }
343 
344  if(strcmp(m, "upkeep") == 0) {
345  unit::upkeep_t upkeep = u.upkeep_raw();
346 
347  // Need to keep these separate in order to ensure an int value is always used if applicable.
348  if(int* v = boost::get<int>(&upkeep)) {
349  lua_push(L, *v);
350  } else {
351  const std::string type = boost::apply_visitor(unit::upkeep_type_visitor(), upkeep);
352  lua_push(L, type);
353  }
354 
355  return 1;
356  }
357  if(strcmp(m, "advancements") == 0) {
358  lua_push(L, u.modification_advancements());
359  return 1;
360  }
361  if(strcmp(m, "overlays") == 0) {
362  lua_push(L, u.overlays());
363  return 1;
364  }
365  if(strcmp(m, "traits") == 0) {
366  lua_push(L, u.get_traits_list());
367  return 1;
368  }
369  if(strcmp(m, "abilities") == 0) {
370  lua_push(L, u.get_ability_list());
371  return 1;
372  }
373  if(strcmp(m, "status") == 0) {
374  lua_createtable(L, 1, 0);
375  lua_pushvalue(L, 1);
376  lua_rawseti(L, -2, 1);
377  luaL_setmetatable(L, ustatusKey);
378  return 1;
379  }
380  if(strcmp(m, "variables") == 0) {
381  lua_createtable(L, 1, 0);
382  lua_pushvalue(L, 1);
383  lua_rawseti(L, -2, 1);
384  luaL_setmetatable(L, unitvarKey);
385  return 1;
386  }
387  if(strcmp(m, "attacks") == 0) {
388  push_unit_attacks_table(L, 1);
389  return 1;
390  }
391  if(strcmp(m, "petrified") == 0) {
392  deprecated_message("(unit).petrified", DEP_LEVEL::INDEFINITE, {1,17,0}, "use (unit).status.petrified instead");
393  lua_pushboolean(L, u.incapacitated());
394  return 1;
395  }
396  return_vector_string_attrib("animations", u.anim_comp().get_flags());
397  return_cfg_attrib("recall_filter", cfg = u.recall_filter());
398  return_bool_attrib("hidden", u.get_hidden());
399  return_bool_attrib("resting", u.resting());
400  return_string_attrib("role", u.get_role());
401  return_string_attrib("race", u.race()->id());
402  return_string_attrib("gender", gender_string(u.gender()));
403  return_string_attrib("variation", u.variation());
404  return_string_attrib("undead_variation", u.undead_variation());
405  return_bool_attrib("zoc", u.get_emit_zoc());
406  return_string_attrib("facing", map_location::write_direction(u.facing()));
407  return_string_attrib("portrait", u.big_profile() == u.absolute_image()
408  ? u.absolute_image() + u.image_mods() + "~XBRZ(2)"
409  : u.big_profile());
410  return_cfg_attrib("__cfg", u.write(cfg); u.get_location().write(cfg));
411 
412  if(luaW_getglobal(L, "wesnoth", "units", m)) {
413  return 1;
414  }
415  return 0;
416 }
417 
418 /**
419  * Sets some data on a unit (__newindex metamethod).
420  * - Arg 1: full userdata containing the unit id.
421  * - Arg 2: string containing the name of the property.
422  * - Arg 3: something containing the attribute.
423  */
424 static int impl_unit_set(lua_State *L)
425 {
426  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
427  char const *m = luaL_checkstring(L, 2);
428  unit* pu = lu->get();
429  if (!pu) return luaL_argerror(L, 1, "unknown unit");
430  unit &u = *pu;
431 
432  // Find the corresponding attribute.
433  //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
434  modify_int_attrib("side", u.set_side(value));
435  modify_int_attrib("moves", u.set_movement(value));
436  modify_int_attrib("max_moves", u.set_total_movement(value));
437  modify_int_attrib("max_attacks", u.set_max_attacks(value));
438  modify_int_attrib("hitpoints", u.set_hitpoints(value));
439  modify_int_attrib("max_hitpoints", u.set_max_hitpoints(value));
440  modify_int_attrib("experience", u.set_experience(value));
441  modify_int_attrib("max_experience", u.set_max_experience(value));
442  modify_int_attrib("recall_cost", u.set_recall_cost(value));
443  modify_int_attrib("attacks_left", u.set_attacks(value));
444  modify_int_attrib("level", u.set_level(value));
445  modify_bool_attrib("resting", u.set_resting(value));
446  modify_tstring_attrib("name", u.set_name(value));
447  modify_tstring_attrib("description", u.set_unit_description(value));
448  modify_string_attrib("portrait", u.set_big_profile(value));
449  modify_string_attrib("role", u.set_role(value));
450  modify_string_attrib("facing", u.set_facing(map_location::parse_direction(value)));
451  modify_string_attrib("usage", u.set_usage(value));
452  modify_string_attrib("undead_variation", u.set_undead_variation(value));
453  modify_string_attrib("ellipse", u.set_image_ellipse(value));
454  modify_string_attrib("halo", u.set_image_halo(value));
455  modify_bool_attrib("hidden", u.set_hidden(value));
456  modify_bool_attrib("zoc", u.set_emit_zoc(value));
457  modify_bool_attrib("canrecruit", u.set_can_recruit(value));
458  modify_bool_attrib("renamable", u.set_unrenamable(!value));
459  modify_cfg_attrib("recall_filter", u.set_recall_filter(cfg));
460 
461  modify_vector_string_attrib("extra_recruit", u.set_recruits(value));
462  modify_vector_string_attrib("advances_to", u.set_advances_to(value));
463  if(strcmp(m, "alignment") == 0) {
464  u.set_alignment(lua_check<UNIT_ALIGNMENT>(L, 3));
465  return 0;
466  }
467 
468  if(strcmp(m, "advancements") == 0) {
469  u.set_advancements(lua_check<std::vector<config>>(L, 3));
470  return 0;
471  }
472 
473  if(strcmp(m, "upkeep") == 0) {
474  if(lua_isnumber(L, 3)) {
475  u.set_upkeep(luaL_checkinteger(L, 3));
476  return 0;
477  }
478  const char* v = luaL_checkstring(L, 3);
479  if((strcmp(v, "loyal") == 0) || (strcmp(v, "free") == 0)) {
480  u.set_upkeep(unit::upkeep_loyal());
481  } else if(strcmp(v, "full") == 0) {
482  u.set_upkeep(unit::upkeep_full());
483  } else {
484  std::string err_msg = "unknown upkeep value of unit: ";
485  err_msg += v;
486  return luaL_argerror(L, 2, err_msg.c_str());
487  }
488  return 0;
489  }
490 
491  if(!lu->on_map()) {
492  map_location loc = u.get_location();
493  modify_int_attrib("x", loc.set_wml_x(value); u.set_location(loc));
494  modify_int_attrib("y", loc.set_wml_y(value); u.set_location(loc));
495  modify_string_attrib("id", u.set_id(value));
496  if(strcmp(m, "loc") == 0) {
497  luaW_tolocation(L, 3, loc);
498  u.set_location(loc);
499  return 0;
500  }
501  } else {
502  const bool is_key_x = strcmp(m, "x") == 0;
503  const bool is_key_y = strcmp(m, "y") == 0;
504  const bool is_loc_key = strcmp(m, "loc") == 0;
505 
506  // Handle moving an on-map unit
507  if(is_key_x || is_key_y || is_loc_key) {
508  game_board* gb = resources::gameboard;
509 
510  if(!gb) {
511  return 0;
512  }
513 
514  map_location src = u.get_location();
515  map_location dst = src;
516 
517  if(is_key_x) {
518  dst.set_wml_x(luaL_checkinteger(L, 3));
519  } else if(is_key_y) {
520  dst.set_wml_y(luaL_checkinteger(L, 3));
521  } else {
522  dst = luaW_checklocation(L, 3);
523  }
524 
525  // TODO: could probably be relegated to a helper function.
526  if(src != dst) {
527  // If the dst isn't on the map, the unit will be clobbered. Guard against that.
528  if(!gb->map().on_board(dst)) {
529  std::string err_msg = formatter() << "destination hex not on map (excluding border): " << dst;
530  return luaL_argerror(L, 2, err_msg.c_str());
531  }
532 
533  unit_map::iterator unit_iterator = gb->units().end();
534  bool success = false;
535 
536  std::tie(unit_iterator, success) = gb->units().move(src, dst);
537 
538  if(success) {
539  unit_iterator->anim_comp().set_standing();
540  }
541  }
542 
543  return 0;
544  }
545  }
546 
547  if(strcmp(m, "goto") == 0) {
548  u.set_goto(luaW_checklocation(L, 3));
549  return 0;
550  }
551 
552  std::string err_msg = "unknown modifiable property of unit: ";
553  err_msg += m;
554  return luaL_argerror(L, 2, err_msg.c_str());
555 }
556 
557 /**
558  * Gets the status of a unit (__index metamethod).
559  * - Arg 1: table containing the userdata containing the unit id.
560  * - Arg 2: string containing the name of the status.
561  * - Ret 1: boolean.
562  */
564 {
565  if(!lua_istable(L, 1)) {
566  return luaW_type_error(L, 1, "unit status");
567  }
568  lua_rawgeti(L, 1, 1);
569  const unit* u = luaW_tounit(L, -1);
570  if(!u) {
571  return luaL_argerror(L, 1, "unknown unit");
572  }
573  char const *m = luaL_checkstring(L, 2);
574  lua_pushboolean(L, u->get_state(m));
575  return 1;
576 }
577 
578 /**
579  * Sets the status of a unit (__newindex metamethod).
580  * - Arg 1: table containing the userdata containing the unit id.
581  * - Arg 2: string containing the name of the status.
582  * - Arg 3: boolean.
583  */
585 {
586  if(!lua_istable(L, 1)) {
587  return luaW_type_error(L, 1, "unit status");
588  }
589  lua_rawgeti(L, 1, 1);
590  unit* u = luaW_tounit(L, -1);
591  if(!u) {
592  return luaL_argerror(L, 1, "unknown unit");
593  }
594  char const *m = luaL_checkstring(L, 2);
595  u->set_state(m, luaW_toboolean(L, 3));
596  return 0;
597 }
598 
599 /**
600  * Gets the variable of a unit (__index metamethod).
601  * - Arg 1: table containing the userdata containing the unit id.
602  * - Arg 2: string containing the name of the status.
603  * - Ret 1: boolean.
604  */
606 {
607  if(!lua_istable(L, 1)) {
608  return luaW_type_error(L, 1, "unit variables");
609  }
610  lua_rawgeti(L, 1, 1);
611  const unit* u = luaW_tounit(L, -1);
612  if(!u) {
613  return luaL_argerror(L, 2, "unknown unit");
614  }
615  char const *m = luaL_checkstring(L, 2);
616  return_cfgref_attrib("__cfg", u->variables());
617 
618  variable_access_const v(m, u->variables());
619  return luaW_pushvariable(L, v) ? 1 : 0;
620 }
621 
622 /**
623  * Sets the variable of a unit (__newindex metamethod).
624  * - Arg 1: table containing the userdata containing the unit id.
625  * - Arg 2: string containing the name of the status.
626  * - Arg 3: scalar.
627  */
629 {
630  if(!lua_istable(L, 1)) {
631  return luaW_type_error(L, 1, "unit variables");
632  }
633  lua_rawgeti(L, 1, 1);
634  unit* u = luaW_tounit(L, -1);
635  if(!u) {
636  return luaL_argerror(L, 2, "unknown unit");
637  }
638  char const *m = luaL_checkstring(L, 2);
639  modify_cfg_attrib("__cfg", u->variables() = cfg);
640  config& vars = u->variables();
641  if(lua_isnoneornil(L, 3)) {
642  try {
643  variable_access_throw(m, vars).clear(false);
644  } catch(const invalid_variablename_exception&) {
645  }
646  return 0;
647  }
648  variable_access_create v(m, vars);
649  luaW_checkvariable(L, v, 3);
650  return 0;
651 }
652 
653 namespace lua_units {
655  {
656  std::ostringstream cmd_out;
657 
658  // Create the getunit metatable.
659  cmd_out << "Adding getunit metatable...\n";
660 
663  lua_setfield(L, -2, "__gc");
665  lua_setfield(L, -2, "__eq");
667  lua_setfield(L, -2, "__tostring");
669  lua_setfield(L, -2, "__index");
671  lua_setfield(L, -2, "__newindex");
672  lua_pushstring(L, "unit");
673  lua_setfield(L, -2, "__metatable");
674 
675  // Create the unit status metatable.
676  cmd_out << "Adding unit status metatable...\n";
677 
680  lua_setfield(L, -2, "__index");
682  lua_setfield(L, -2, "__newindex");
683  lua_pushstring(L, "unit status");
684  lua_setfield(L, -2, "__metatable");
685 
686  // Create the unit variables metatable.
687  cmd_out << "Adding unit variables metatable...\n";
688 
691  lua_setfield(L, -2, "__index");
693  lua_setfield(L, -2, "__newindex");
694  lua_pushstring(L, "unit variables");
695  lua_setfield(L, -2, "__metatable");
696 
697  return cmd_out.str();
698  }
699 }
static lg::log_domain log_scripting_lua("scripting/lua")
bool luaW_checkvariable(lua_State *L, variable_access_create &v, int n)
Definition: lua_common.cpp:923
#define lua_isnoneornil(L, n)
Definition: lua.h:359
variable_info_mutable< variable_info_implementation::vi_policy_throw > variable_access_throw
&#39;Throw if nonexistent&#39; access.
#define lua_pushcfunction(L, f)
Definition: lua.h:350
static void setmetatable(lua_State *L)
Definition: lua_unit.cpp:210
std::string register_metatables(lua_State *L)
Definition: lua_unit.cpp:654
virtual const unit_map & units() const override
Definition: game_board.hpp:114
This class represents a single unit of a specific type.
Definition: unit.hpp:129
const std::string & type_id() const
The id of this unit&#39;s type.
Definition: unit.cpp:1817
Interfaces for manipulating version numbers of engine, add-ons, etc.
int luaW_type_error(lua_State *L, int narg, const char *tname)
unit & luaW_checkunit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
Definition: lua_unit.cpp:194
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:557
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:658
~lua_unit()
Definition: lua_unit.cpp:44
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
Definition: unit.cpp:1323
bool luaW_isunit(lua_State *L, int index)
Test if a Lua value is a unit.
Definition: lua_unit.cpp:116
friend lua_unit * luaW_pushlocalunit(lua_State *L, unit &u)
Pushes a private unit on the stack.
Definition: lua_unit.cpp:215
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:39
lua_unit * luaW_tounit_ref(lua_State *L, int index)
Similar to luaW_tounit but returns a lua_unit; use this if you need to handle map and recall units di...
Definition: lua_unit.cpp:165
config & variables()
Gets any user-defined variables this unit &#39;owns&#39;.
Definition: unit.hpp:704
bool luaW_pushvariable(lua_State *L, variable_access_const &v)
Definition: lua_common.cpp:895
#define ERR_LUA
Definition: lua_unit.cpp:38
static int impl_unit_variables_get(lua_State *L)
Gets the variable of a unit (__index metamethod).
Definition: lua_unit.cpp:605
static int impl_unit_tostring(lua_State *L)
Turns a lua proxy unit to string.
Definition: lua_unit.cpp:247
static int impl_unit_variables_set(lua_State *L)
Sets the variable of a unit (__newindex metamethod).
Definition: lua_unit.cpp:628
std::size_t erase(const map_location &l)
Erases the unit at location l, if any.
Definition: map.cpp:298
Additional functionality for a non-const variable_info.
static const char getunitKey[]
Definition: lua_unit.cpp:40
static int impl_unit_get(lua_State *L)
Gets some data on a unit (__index metamethod).
Definition: lua_unit.cpp:276
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:312
std::string str
Definition: statement.cpp:110
static int impl_unit_status_set(lua_State *L)
Sets the status of a unit (__newindex metamethod).
Definition: lua_unit.cpp:584
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:722
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:28
static const char unitvarKey[]
Definition: lua_unit.cpp:42
#define return_cfgref_attrib(name, accessor)
Definition: lua_common.hpp:260
unit_ptr extract_if_matches_underlying_id(std::size_t uid)
Find a unit by underlying id, and extract if found. Null if not found.
umap_retval_pair_t replace(const map_location &l, unit_ptr p)
Works like unit_map::add; but l is emptied first, if needed.
Definition: map.cpp:225
static int impl_unit_equality(lua_State *L)
Checks two lua proxy units for equality.
Definition: lua_unit.cpp:235
team & get_team(int i)
Definition: game_board.hpp:104
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
Definition: lauxlib.cpp:164
const std::string & id() const
Gets this unit&#39;s id.
Definition: unit.hpp:378
void set_state(const std::string &state, bool value)
Set whether the unit is affected by a status effect.
Definition: unit.cpp:1371
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:890
unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map)
Similar to luaW_checkunit but returns a unit_ptr; use this instead of luaW_checkunit when using an ap...
Definition: lua_unit.cpp:186
std::ostringstream wrapper.
Definition: formatter.hpp:38
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
Definition: lua_unit.cpp:145
unit * c_ptr
Definition: lua_unit.hpp:84
game_board * gameboard
Definition: resources.cpp:20
umap_retval_pair_t move(const map_location &src, const map_location &dst)
Moves a unit from location src to location dst.
Definition: map.cpp:94
unit_ptr find_if_matches_underlying_id(std::size_t uid)
Find a unit by underlying id. Null pointer if not found.
LUALIB_API void * luaL_testudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:318
lu_byte right
Definition: lparser.cpp:1027
Encapsulates the map of the game.
Definition: location.hpp:42
std::size_t uid
Definition: lua_unit.hpp:81
Storage for a unit, either owned by the Lua code (ptr != 0), a local variable unit (c_ptr != 0)...
Definition: lua_unit.hpp:79
unit_iterator find(std::size_t id)
Definition: map.cpp:311
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:299
LUA_API void * lua_touserdata(lua_State *L, int idx)
Definition: lapi.cpp:413
pointer get_shared_ptr() const
This is exactly the same as operator-> but it&#39;s slightly more readable, and can replace &*iter syntax...
Definition: map.hpp:220
static void unit_show_error(lua_State *L, int index, int error)
Definition: lua_unit.cpp:171
int side
Definition: lua_unit.hpp:83
static int impl_unit_collect(lua_State *L)
Destroys a unit object before it is collected (__gc metamethod).
Definition: lua_unit.cpp:225
static lua_unit * internal_get_unit(lua_State *L, int index, bool only_on_map, int &error)
Definition: lua_unit.cpp:128
lua_unit * luaW_checkunit_ref(lua_State *L, int index)
Similar to luaW_checkunit but returns a lua_unit; use this if you need to handle map and recall units...
Definition: lua_unit.cpp:202
unit_ptr get_shared() const
Definition: lua_unit.cpp:59
unit * get() const
Definition: lua_unit.cpp:48
lua_unit(const lua_unit &)=delete
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
Information on a WML variable.
bool put_map(const map_location &loc)
Definition: lua_unit.cpp:74
double t
Definition: astarsearch.cpp:64
#define modify_cfg_attrib(name, accessor)
Definition: lua_common.hpp:348
#define lua_istable(L, n)
Definition: lua.h:353
lu_byte left
Definition: lparser.cpp:1026
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1343
unit_ptr luaW_tounit_ptr(lua_State *L, int index, bool only_on_map)
Similar to luaW_tounit but returns a unit_ptr; use this instead of luaW_tounit when using an api that...
Definition: lua_unit.cpp:155
Standard logging facilities (interface).
recall_list_manager & recall_list()
Definition: team.hpp:215
unit_ptr ptr
Definition: lua_unit.hpp:82
static int impl_unit_status_get(lua_State *L)
Gets the status of a unit (__index metamethod).
Definition: lua_unit.cpp:563
static const char ustatusKey[]
Definition: lua_unit.cpp:41
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
bool valid() const
Definition: map.hpp:276
static int impl_unit_set(lua_State *L)
Sets some data on a unit (__newindex metamethod).
Definition: lua_unit.cpp:424
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:491
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:777
std::size_t underlying_id() const
This unit&#39;s unique internal ID.
Definition: unit.hpp:390
#define luaL_checkstring(L, n)
Definition: lauxlib.h:124