The Battle for Wesnoth  1.17.0-dev
lua_unit.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2021
3  by Guillaume Melquiond <guillaume.melquiond@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "scripting/lua_unit.hpp"
17 
18 #include "formatter.hpp"
19 #include "game_board.hpp"
20 #include "log.hpp"
21 #include "map/location.hpp" // for map_location
22 #include "map/map.hpp"
23 #include "resources.hpp"
24 #include "scripting/lua_common.hpp"
26 #include "scripting/push_check.hpp"
28 #include "units/unit.hpp"
29 #include "units/map.hpp"
31 #include "game_version.hpp"
32 #include "deprecation.hpp"
33 
34 #include "lua/lauxlib.h"
35 #include "lua/lua.h" // for lua_State, lua_settop, etc
36 
37 static lg::log_domain log_scripting_lua("scripting/lua");
38 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
39 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
40 
41 static const char getunitKey[] = "unit";
42 static const char ustatusKey[] = "unit status";
43 static const char unitvarKey[] = "unit variables";
44 
46 {
47 }
48 
50 {
51  if (ptr) return ptr.get();
52  if (c_ptr) return c_ptr;
53  if (side) {
55  }
57  if (!ui.valid()) return nullptr;
58  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.
59 }
61 {
62  if (ptr) return ptr;
63  if (side) {
65  }
67  if (!ui.valid()) return unit_ptr();
68  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.
69 }
70 
71 // Having this function here not only simplifies other code, it allows us to move
72 // pointers around from one structure to another.
73 // This makes bare pointer->map in particular about 2 orders of magnitude faster,
74 // as benchmarked from Lua code.
76 {
77  if (ptr) {
78  auto [unit_it, success] = resources::gameboard->units().replace(loc, ptr);
79 
80  if(success) {
81  ptr.reset();
82  uid = unit_it->underlying_id();
83  } else {
84  ERR_LUA << "Could not move unit " << ptr->underlying_id() << " onto map location " << loc << '\n';
85  return false;
86  }
87  } else if (side) { // recall list
89  if (it) {
90  side = 0;
91  // uid may be changed by unit_map on insertion
92  uid = resources::gameboard->units().replace(loc, it).first->underlying_id();
93  } else {
94  ERR_LUA << "Could not find unit " << uid << " on recall list of side " << side << '\n';
95  return false;
96  }
97  } else { // on map
99  if (ui != resources::gameboard->units().end()) {
100  map_location from = ui->get_location();
101  if (from != loc) { // This check is redundant in current usage
103  resources::gameboard->units().move(from, loc);
104  }
105  // No need to change our contents
106  } else {
107  ERR_LUA << "Could not find unit " << uid << " on the map" << std::endl;
108  return false;
109  }
110  }
111  return true;
112 }
113 
115 {
116  return luaL_testudata(L, index,getunitKey) != nullptr;
117 }
118 
119 enum {
124 };
125 
126 static lua_unit* internal_get_unit(lua_State *L, int index, bool only_on_map, int& error)
127 {
128  error = LU_OK;
129  if(!luaW_isunit(L, index)) {
130  error = LU_NOT_UNIT;
131  return nullptr;
132  }
133  lua_unit* lu = static_cast<lua_unit*>(lua_touserdata(L, index));
134  if(only_on_map && !lu->on_map()) {
135  error = LU_NOT_ON_MAP;
136  }
137  if(!lu->get()) {
138  error = LU_NOT_VALID;
139  }
140  return lu;
141 }
142 
143 unit* luaW_tounit(lua_State *L, int index, bool only_on_map)
144 {
145  int error;
146  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
147  if(error != LU_OK) {
148  return nullptr;
149  }
150  return lu->get();
151 }
152 
153 unit_ptr luaW_tounit_ptr(lua_State *L, int index, bool only_on_map)
154 {
155  int error;
156  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
157  if(error != LU_OK) {
158  return nullptr;
159  }
160  return lu->get_shared();
161 }
162 
164 {
165  int error;
166  return internal_get_unit(L, index, false, error);
167 }
168 
169 static void unit_show_error(lua_State *L, int index, int error)
170 {
171  switch(error) {
172  case LU_NOT_UNIT:
173  luaW_type_error(L, index, "unit");
174  break;
175  case LU_NOT_VALID:
176  luaL_argerror(L, index, "unit not found");
177  break;
178  case LU_NOT_ON_MAP:
179  luaL_argerror(L, index, "unit not found on map");
180  break;
181  }
182 }
183 
184 unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map)
185 {
186  int error;
187  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
188  unit_show_error(L, index, error);
189  return lu->get_shared();
190 }
191 
192 unit& luaW_checkunit(lua_State *L, int index, bool only_on_map)
193 {
194  int error;
195  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
196  unit_show_error(L, index, error);
197  return *lu->get();
198 }
199 
201 {
202  int error;
203  lua_unit* lu = internal_get_unit(L, index, false, error);
204  unit_show_error(L, index, error);
205  return lu;
206 }
207 
209 {
211 }
212 
214 {
215  lua_unit* res = new(L) lua_unit(u);
217  return res;
218 }
219 
220 /**
221  * Destroys a unit object before it is collected (__gc metamethod).
222  */
224 {
225  lua_unit *u = static_cast<lua_unit *>(lua_touserdata(L, 1));
226  u->lua_unit::~lua_unit();
227  return 0;
228 }
229 
230 /**
231  * Checks two lua proxy units for equality. (__eq metamethod)
232  */
234 {
235  unit& left = luaW_checkunit(L, 1);
236  unit& right = luaW_checkunit(L, 2);
237  const bool equal = left.underlying_id() == right.underlying_id();
238  lua_pushboolean(L, equal);
239  return 1;
240 }
241 
242 /**
243  * Turns a lua proxy unit to string. (__tostring metamethod)
244  */
246 {
247  const lua_unit* lu = luaW_tounit_ref(L, 1);
248  unit &u = *lu->get();
249  std::ostringstream str;
250 
251  str << "unit: <";
252  if(!u.id().empty()) {
253  str << u.id() << " ";
254  } else {
255  str << u.type_id() << " ";
256  }
257  if(int side = lu->on_recall_list()) {
258  str << "at (side " << side << " recall list)";
259  } else {
260  str << "at (" << u.get_location() << ")";
261  }
262  str << '>';
263 
264  lua_push(L, str.str());
265  return 1;
266 }
267 
268 /**
269  * Gets some data on a unit (__index metamethod).
270  * - Arg 1: full userdata containing the unit id.
271  * - Arg 2: string containing the name of the property.
272  * - Ret 1: something containing the attribute.
273  */
274 static int impl_unit_get(lua_State *L)
275 {
276  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
277  char const *m = luaL_checkstring(L, 2);
278  const unit* pu = lu->get();
279 
280  if(strcmp(m, "valid") == 0) {
281  if(!pu) {
282  return 0;
283  }
284  if(lu->on_map()) {
285  lua_pushstring(L, "map");
286  } else if(lu->on_recall_list()) {
287  lua_pushstring(L, "recall");
288  } else {
289  lua_pushstring(L, "private");
290  }
291  return 1;
292  }
293 
294  if(!pu) {
295  return luaL_argerror(L, 1, "unknown unit");
296  }
297 
298  const unit& u = *pu;
299 
300  // Find the corresponding attribute.
301  return_int_attrib("x", u.get_location().wml_x());
302  return_int_attrib("y", u.get_location().wml_y());
303  if(strcmp(m, "loc") == 0) {
304  luaW_pushlocation(L, u.get_location());
305  return 1;
306  }
307  if(strcmp(m, "goto") == 0) {
308  luaW_pushlocation(L, u.get_goto());
309  return 1;
310  }
311  return_int_attrib("side", u.side());
312  return_string_attrib("id", u.id());
313  return_string_attrib("type", u.type_id());
314  return_string_attrib("image_mods", u.effect_image_mods());
315  return_string_attrib("usage", u.usage());
316  return_string_attrib("ellipse", u.image_ellipse());
317  return_string_attrib("halo", u.image_halo());
318  return_int_attrib("hitpoints", u.hitpoints());
319  return_int_attrib("max_hitpoints", u.max_hitpoints());
320  return_int_attrib("experience", u.experience());
321  return_int_attrib("max_experience", u.max_experience());
322  return_int_attrib("recall_cost", u.recall_cost());
323  return_int_attrib("moves", u.movement_left());
324  return_int_attrib("max_moves", u.total_movement());
325  return_int_attrib("max_attacks", u.max_attacks());
326  return_int_attrib("attacks_left", u.attacks_left());
327  return_int_attrib("vision", u.vision());
328  return_int_attrib("jamming", u.jamming());
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 = utils::get_if<int>(&upkeep)) {
349  lua_push(L, *v);
350  } else {
351  const std::string type = utils::visit(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(static_cast<int>(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  auto [unit_iterator, success] = gb->units().move(src, dst);
534 
535  if(success) {
536  unit_iterator->anim_comp().set_standing();
537  }
538  }
539 
540  return 0;
541  }
542  }
543 
544  if(strcmp(m, "goto") == 0) {
545  u.set_goto(luaW_checklocation(L, 3));
546  return 0;
547  }
548 
549  std::string err_msg = "unknown modifiable property of unit: ";
550  err_msg += m;
551  return luaL_argerror(L, 2, err_msg.c_str());
552 }
553 
554 /**
555  * Gets the status of a unit (__index metamethod).
556  * - Arg 1: table containing the userdata containing the unit id.
557  * - Arg 2: string containing the name of the status.
558  * - Ret 1: boolean.
559  */
561 {
562  if(!lua_istable(L, 1)) {
563  return luaW_type_error(L, 1, "unit status");
564  }
565  lua_rawgeti(L, 1, 1);
566  const unit* u = luaW_tounit(L, -1);
567  if(!u) {
568  return luaL_argerror(L, 1, "unknown unit");
569  }
570  char const *m = luaL_checkstring(L, 2);
571  lua_pushboolean(L, u->get_state(m));
572  return 1;
573 }
574 
575 /**
576  * Sets the status of a unit (__newindex metamethod).
577  * - Arg 1: table containing the userdata containing the unit id.
578  * - Arg 2: string containing the name of the status.
579  * - Arg 3: boolean.
580  */
582 {
583  if(!lua_istable(L, 1)) {
584  return luaW_type_error(L, 1, "unit status");
585  }
586  lua_rawgeti(L, 1, 1);
587  unit* u = luaW_tounit(L, -1);
588  if(!u) {
589  return luaL_argerror(L, 1, "unknown unit");
590  }
591  char const *m = luaL_checkstring(L, 2);
592  u->set_state(m, luaW_toboolean(L, 3));
593  return 0;
594 }
595 
596 /**
597  * Gets the variable of a unit (__index metamethod).
598  * - Arg 1: table containing the userdata containing the unit id.
599  * - Arg 2: string containing the name of the status.
600  * - Ret 1: boolean.
601  */
603 {
604  if(!lua_istable(L, 1)) {
605  return luaW_type_error(L, 1, "unit variables");
606  }
607  lua_rawgeti(L, 1, 1);
608  const unit* u = luaW_tounit(L, -1);
609  if(!u) {
610  return luaL_argerror(L, 2, "unknown unit");
611  }
612  char const *m = luaL_checkstring(L, 2);
613  return_cfgref_attrib("__cfg", u->variables());
614 
615  variable_access_const v(m, u->variables());
616  return luaW_pushvariable(L, v) ? 1 : 0;
617 }
618 
619 /**
620  * Sets the variable of a unit (__newindex metamethod).
621  * - Arg 1: table containing the userdata containing the unit id.
622  * - Arg 2: string containing the name of the status.
623  * - Arg 3: scalar.
624  */
626 {
627  if(!lua_istable(L, 1)) {
628  return luaW_type_error(L, 1, "unit variables");
629  }
630  lua_rawgeti(L, 1, 1);
631  unit* u = luaW_tounit(L, -1);
632  if(!u) {
633  return luaL_argerror(L, 2, "unknown unit");
634  }
635  char const *m = luaL_checkstring(L, 2);
636  modify_cfg_attrib("__cfg", u->variables() = cfg);
637  config& vars = u->variables();
638  if(lua_isnoneornil(L, 3)) {
639  try {
640  variable_access_throw(m, vars).clear(false);
641  } catch(const invalid_variablename_exception&) {
642  }
643  return 0;
644  }
645  variable_access_create v(m, vars);
646  luaW_checkvariable(L, v, 3);
647  return 0;
648 }
649 
650 namespace lua_units {
652  {
653  std::ostringstream cmd_out;
654 
655  // Create the getunit metatable.
656  cmd_out << "Adding getunit metatable...\n";
657 
660  lua_setfield(L, -2, "__gc");
662  lua_setfield(L, -2, "__eq");
664  lua_setfield(L, -2, "__tostring");
666  lua_setfield(L, -2, "__index");
668  lua_setfield(L, -2, "__newindex");
669  lua_pushstring(L, "unit");
670  lua_setfield(L, -2, "__metatable");
671 
672  // Create the unit status metatable.
673  cmd_out << "Adding unit status metatable...\n";
674 
677  lua_setfield(L, -2, "__index");
679  lua_setfield(L, -2, "__newindex");
680  lua_pushstring(L, "unit status");
681  lua_setfield(L, -2, "__metatable");
682 
683  // Create the unit variables metatable.
684  cmd_out << "Adding unit variables metatable...\n";
685 
688  lua_setfield(L, -2, "__index");
690  lua_setfield(L, -2, "__newindex");
691  lua_pushstring(L, "unit variables");
692  lua_setfield(L, -2, "__metatable");
693 
694  return cmd_out.str();
695  }
696 }
static lg::log_domain log_scripting_lua("scripting/lua")
bool luaW_checkvariable(lua_State *L, variable_access_create &v, int n)
#define lua_isnoneornil(L, n)
Definition: lua.h:379
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:370
static void setmetatable(lua_State *L)
Definition: lua_unit.cpp:208
std::string register_metatables(lua_State *L)
Definition: lua_unit.cpp:651
virtual const unit_map & units() const override
Definition: game_board.hpp:112
This class represents a single unit of a specific type.
Definition: unit.hpp:121
const std::string & type_id() const
The id of this unit&#39;s type.
Definition: unit.cpp:1801
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:192
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:581
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:710
~lua_unit()
Definition: lua_unit.cpp:45
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
Definition: unit.cpp:1311
bool luaW_isunit(lua_State *L, int index)
Test if a Lua value is a unit.
Definition: lua_unit.cpp:114
friend lua_unit * luaW_pushlocalunit(lua_State *L, unit &u)
Pushes a private unit on the stack.
Definition: lua_unit.cpp:213
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:40
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:163
config & variables()
Gets any user-defined variables this unit &#39;owns&#39;.
Definition: unit.hpp:694
bool luaW_pushvariable(lua_State *L, variable_access_const &v)
Definition: lua_common.cpp:977
#define ERR_LUA
Definition: lua_unit.cpp:39
static int impl_unit_variables_get(lua_State *L)
Gets the variable of a unit (__index metamethod).
Definition: lua_unit.cpp:602
static int impl_unit_tostring(lua_State *L)
Turns a lua proxy unit to string.
Definition: lua_unit.cpp:245
static int impl_unit_variables_set(lua_State *L)
Sets the variable of a unit (__newindex metamethod).
Definition: lua_unit.cpp:625
std::size_t erase(const map_location &l)
Erases the unit at location l, if any.
Definition: map.cpp:297
Additional functionality for a non-const variable_info.
static const char getunitKey[]
Definition: lua_unit.cpp:41
static int impl_unit_get(lua_State *L)
Gets some data on a unit (__index metamethod).
Definition: lua_unit.cpp:274
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:324
static int impl_unit_status_set(lua_State *L)
Sets the status of a unit (__newindex metamethod).
Definition: lua_unit.cpp:581
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:775
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:26
static const char unitvarKey[]
Definition: lua_unit.cpp:43
#define return_cfgref_attrib(name, accessor)
Definition: lua_common.hpp:309
unit_ptr extract_if_matches_underlying_id(std::size_t uid)
Find a unit by underlying id, and extract if 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:224
static int impl_unit_equality(lua_State *L)
Checks two lua proxy units for equality.
Definition: lua_unit.cpp:233
team & get_team(int i)
Definition: game_board.hpp:97
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
Definition: lauxlib.cpp:175
const std::string & id() const
Gets this unit&#39;s id.
Definition: unit.hpp:371
void set_state(const std::string &state, bool value)
Set whether the unit is affected by a status effect.
Definition: unit.cpp:1359
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:972
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:184
std::ostringstream wrapper.
Definition: formatter.hpp:39
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
Definition: lua_unit.cpp:143
unit * c_ptr
Definition: lua_unit.hpp:85
game_board * gameboard
Definition: resources.cpp:21
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:93
unit_ptr find_if_matches_underlying_id(std::size_t uid)
Find a unit by underlying id.
LUALIB_API void * luaL_testudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:330
lu_byte right
Definition: lparser.cpp:1227
Encapsulates the map of the game.
Definition: location.hpp:38
std::size_t uid
Definition: lua_unit.hpp:82
Storage for a unit, either owned by the Lua code (ptr != 0), a local variable unit (c_ptr != 0)...
Definition: lua_unit.hpp:80
unit_iterator find(std::size_t id)
Definition: map.cpp:310
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:311
LUA_API void * lua_touserdata(lua_State *L, int idx)
Definition: lapi.cpp:432
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:218
static void unit_show_error(lua_State *L, int index, int error)
Definition: lua_unit.cpp:169
int side
Definition: lua_unit.hpp:84
static int impl_unit_collect(lua_State *L)
Destroys a unit object before it is collected (__gc metamethod).
Definition: lua_unit.cpp:223
static lua_unit * internal_get_unit(lua_State *L, int index, bool only_on_map, int &error)
Definition: lua_unit.cpp:126
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:200
unit_ptr get_shared() const
Definition: lua_unit.cpp:60
unit * get() const
Definition: lua_unit.cpp:49
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:72
Information on a WML variable.
bool put_map(const map_location &loc)
Definition: lua_unit.cpp:75
double t
Definition: astarsearch.cpp:65
#define modify_cfg_attrib(name, accessor)
Definition: lua_common.hpp:415
#define lua_istable(L, n)
Definition: lua.h:373
lu_byte left
Definition: lparser.cpp:1226
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1346
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:153
Standard logging facilities (interface).
recall_list_manager & recall_list()
Definition: team.hpp:227
unit_ptr ptr
Definition: lua_unit.hpp:83
static int impl_unit_status_get(lua_State *L)
Gets the status of a unit (__index metamethod).
Definition: lua_unit.cpp:560
static const char ustatusKey[]
Definition: lua_unit.cpp:42
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
bool valid() const
Definition: map.hpp:274
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:514
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:837
std::size_t underlying_id() const
This unit&#39;s unique internal ID.
Definition: unit.hpp:383
#define luaL_checkstring(L, n)
Definition: lauxlib.h:138