The Battle for Wesnoth  1.15.12+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) {
77  auto [unit_it, success] = resources::gameboard->units().replace(loc, ptr);
78 
79  if(success) {
80  ptr.reset();
81  uid = unit_it->underlying_id();
82  } else {
83  ERR_LUA << "Could not move unit " << ptr->underlying_id() << " onto map location " << loc << '\n';
84  return false;
85  }
86  } else if (side) { // recall list
88  if (it) {
89  side = 0;
90  // uid may be changed by unit_map on insertion
91  uid = resources::gameboard->units().replace(loc, it).first->underlying_id();
92  } else {
93  ERR_LUA << "Could not find unit " << uid << " on recall list of side " << side << '\n';
94  return false;
95  }
96  } else { // on map
98  if (ui != resources::gameboard->units().end()) {
99  map_location from = ui->get_location();
100  if (from != loc) { // This check is redundant in current usage
102  resources::gameboard->units().move(from, loc);
103  }
104  // No need to change our contents
105  } else {
106  ERR_LUA << "Could not find unit " << uid << " on the map" << std::endl;
107  return false;
108  }
109  }
110  return true;
111 }
112 
114 {
115  return luaL_testudata(L, index,getunitKey) != nullptr;
116 }
117 
118 enum {
123 };
124 
125 static lua_unit* internal_get_unit(lua_State *L, int index, bool only_on_map, int& error)
126 {
127  error = LU_OK;
128  if(!luaW_isunit(L, index)) {
129  error = LU_NOT_UNIT;
130  return nullptr;
131  }
132  lua_unit* lu = static_cast<lua_unit*>(lua_touserdata(L, index));
133  if(only_on_map && !lu->on_map()) {
134  error = LU_NOT_ON_MAP;
135  }
136  if(!lu->get()) {
137  error = LU_NOT_VALID;
138  }
139  return lu;
140 }
141 
142 unit* luaW_tounit(lua_State *L, int index, bool only_on_map)
143 {
144  int error;
145  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
146  if(error != LU_OK) {
147  return nullptr;
148  }
149  return lu->get();
150 }
151 
152 unit_ptr luaW_tounit_ptr(lua_State *L, int index, bool only_on_map)
153 {
154  int error;
155  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
156  if(error != LU_OK) {
157  return nullptr;
158  }
159  return lu->get_shared();
160 }
161 
163 {
164  int error;
165  return internal_get_unit(L, index, false, error);
166 }
167 
168 static void unit_show_error(lua_State *L, int index, int error)
169 {
170  switch(error) {
171  case LU_NOT_UNIT:
172  luaW_type_error(L, index, "unit");
173  break;
174  case LU_NOT_VALID:
175  luaL_argerror(L, index, "unit not found");
176  break;
177  case LU_NOT_ON_MAP:
178  luaL_argerror(L, index, "unit not found on map");
179  break;
180  }
181 }
182 
183 unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map)
184 {
185  int error;
186  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
187  unit_show_error(L, index, error);
188  return lu->get_shared();
189 }
190 
191 unit& luaW_checkunit(lua_State *L, int index, bool only_on_map)
192 {
193  int error;
194  lua_unit* lu = internal_get_unit(L, index, only_on_map, error);
195  unit_show_error(L, index, error);
196  return *lu->get();
197 }
198 
200 {
201  int error;
202  lua_unit* lu = internal_get_unit(L, index, false, error);
203  unit_show_error(L, index, error);
204  return lu;
205 }
206 
208 {
210 }
211 
213 {
214  lua_unit* res = new(L) lua_unit(u);
216  return res;
217 }
218 
219 /**
220  * Destroys a unit object before it is collected (__gc metamethod).
221  */
223 {
224  lua_unit *u = static_cast<lua_unit *>(lua_touserdata(L, 1));
225  u->lua_unit::~lua_unit();
226  return 0;
227 }
228 
229 /**
230  * Checks two lua proxy units for equality. (__eq metamethod)
231  */
233 {
234  unit& left = luaW_checkunit(L, 1);
235  unit& right = luaW_checkunit(L, 2);
236  const bool equal = left.underlying_id() == right.underlying_id();
237  lua_pushboolean(L, equal);
238  return 1;
239 }
240 
241 /**
242  * Turns a lua proxy unit to string. (__tostring metamethod)
243  */
245 {
246  const lua_unit* lu = luaW_tounit_ref(L, 1);
247  unit &u = *lu->get();
248  std::ostringstream str;
249 
250  str << "unit: <";
251  if(!u.id().empty()) {
252  str << u.id() << " ";
253  } else {
254  str << u.type_id() << " ";
255  }
256  if(int side = lu->on_recall_list()) {
257  str << "at (side " << side << " recall list)";
258  } else {
259  str << "at (" << u.get_location() << ")";
260  }
261  str << '>';
262 
263  lua_push(L, str.str());
264  return 1;
265 }
266 
267 /**
268  * Gets some data on a unit (__index metamethod).
269  * - Arg 1: full userdata containing the unit id.
270  * - Arg 2: string containing the name of the property.
271  * - Ret 1: something containing the attribute.
272  */
273 static int impl_unit_get(lua_State *L)
274 {
275  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
276  char const *m = luaL_checkstring(L, 2);
277  const unit* pu = lu->get();
278 
279  if(strcmp(m, "valid") == 0) {
280  if(!pu) {
281  return 0;
282  }
283  if(lu->on_map()) {
284  lua_pushstring(L, "map");
285  } else if(lu->on_recall_list()) {
286  lua_pushstring(L, "recall");
287  } else {
288  lua_pushstring(L, "private");
289  }
290  return 1;
291  }
292 
293  if(!pu) {
294  return luaL_argerror(L, 1, "unknown unit");
295  }
296 
297  const unit& u = *pu;
298 
299  // Find the corresponding attribute.
300  return_int_attrib("x", u.get_location().wml_x());
301  return_int_attrib("y", u.get_location().wml_y());
302  if(strcmp(m, "loc") == 0) {
303  luaW_pushlocation(L, u.get_location());
304  return 1;
305  }
306  if(strcmp(m, "goto") == 0) {
307  luaW_pushlocation(L, u.get_goto());
308  return 1;
309  }
310  return_int_attrib("side", u.side());
311  return_string_attrib("id", u.id());
312  return_string_attrib("type", u.type_id());
313  return_string_attrib("image_mods", u.effect_image_mods());
314  return_string_attrib("usage", u.usage());
315  return_string_attrib("ellipse", u.image_ellipse());
316  return_string_attrib("halo", u.image_halo());
317  return_int_attrib("hitpoints", u.hitpoints());
318  return_int_attrib("max_hitpoints", u.max_hitpoints());
319  return_int_attrib("experience", u.experience());
320  return_int_attrib("max_experience", u.max_experience());
321  return_int_attrib("recall_cost", u.recall_cost());
322  return_int_attrib("moves", u.movement_left());
323  return_int_attrib("max_moves", u.total_movement());
324  return_int_attrib("max_attacks", u.max_attacks());
325  return_int_attrib("attacks_left", u.attacks_left());
326  return_tstring_attrib("name", u.name());
327  return_tstring_attrib("description", u.unit_description());
328  return_bool_attrib("canrecruit", u.can_recruit());
329  return_bool_attrib("renamable", !u.unrenamable());
330  return_int_attrib("level", u.level());
331  return_int_attrib("cost", u.cost());
332 
333  return_vector_string_attrib("extra_recruit", u.recruits());
334  return_vector_string_attrib("advances_to", u.advances_to());
335 
336  if(strcmp(m, "alignment") == 0) {
337  lua_push(L, u.alignment());
338  return 1;
339  }
340 
341  if(strcmp(m, "upkeep") == 0) {
342  unit::upkeep_t upkeep = u.upkeep_raw();
343 
344  // Need to keep these separate in order to ensure an int value is always used if applicable.
345  if(int* v = utils::get_if<int>(&upkeep)) {
346  lua_push(L, *v);
347  } else {
348  const std::string type = utils::visit(unit::upkeep_type_visitor{}, upkeep);
349  lua_push(L, type);
350  }
351 
352  return 1;
353  }
354  if(strcmp(m, "advancements") == 0) {
355  lua_push(L, u.modification_advancements());
356  return 1;
357  }
358  if(strcmp(m, "overlays") == 0) {
359  lua_push(L, u.overlays());
360  return 1;
361  }
362  if(strcmp(m, "traits") == 0) {
363  lua_push(L, u.get_traits_list());
364  return 1;
365  }
366  if(strcmp(m, "abilities") == 0) {
367  lua_push(L, u.get_ability_list());
368  return 1;
369  }
370  if(strcmp(m, "status") == 0) {
371  lua_createtable(L, 1, 0);
372  lua_pushvalue(L, 1);
373  lua_rawseti(L, -2, 1);
374  luaL_setmetatable(L, ustatusKey);
375  return 1;
376  }
377  if(strcmp(m, "variables") == 0) {
378  lua_createtable(L, 1, 0);
379  lua_pushvalue(L, 1);
380  lua_rawseti(L, -2, 1);
381  luaL_setmetatable(L, unitvarKey);
382  return 1;
383  }
384  if(strcmp(m, "attacks") == 0) {
385  push_unit_attacks_table(L, 1);
386  return 1;
387  }
388  if(strcmp(m, "petrified") == 0) {
389  deprecated_message("(unit).petrified", DEP_LEVEL::INDEFINITE, {1,17,0}, "use (unit).status.petrified instead");
390  lua_pushboolean(L, u.incapacitated());
391  return 1;
392  }
393  return_vector_string_attrib("animations", u.anim_comp().get_flags());
394  return_cfg_attrib("recall_filter", cfg = u.recall_filter());
395  return_bool_attrib("hidden", u.get_hidden());
396  return_bool_attrib("resting", u.resting());
397  return_string_attrib("role", u.get_role());
398  return_string_attrib("race", u.race()->id());
399  return_string_attrib("gender", gender_string(u.gender()));
400  return_string_attrib("variation", u.variation());
401  return_string_attrib("undead_variation", u.undead_variation());
402  return_bool_attrib("zoc", u.get_emit_zoc());
403  return_string_attrib("facing", map_location::write_direction(u.facing()));
404  return_string_attrib("portrait", u.big_profile() == u.absolute_image()
405  ? u.absolute_image() + u.image_mods() + "~XBRZ(2)"
406  : u.big_profile());
407  return_cfg_attrib("__cfg", u.write(cfg); u.get_location().write(cfg));
408 
409  if(luaW_getglobal(L, "wesnoth", "units", m)) {
410  return 1;
411  }
412  return 0;
413 }
414 
415 /**
416  * Sets some data on a unit (__newindex metamethod).
417  * - Arg 1: full userdata containing the unit id.
418  * - Arg 2: string containing the name of the property.
419  * - Arg 3: something containing the attribute.
420  */
421 static int impl_unit_set(lua_State *L)
422 {
423  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
424  char const *m = luaL_checkstring(L, 2);
425  unit* pu = lu->get();
426  if (!pu) return luaL_argerror(L, 1, "unknown unit");
427  unit &u = *pu;
428 
429  // Find the corresponding attribute.
430  //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
431  modify_int_attrib("side", u.set_side(value));
432  modify_int_attrib("moves", u.set_movement(value));
433  modify_int_attrib("max_moves", u.set_total_movement(value));
434  modify_int_attrib("max_attacks", u.set_max_attacks(value));
435  modify_int_attrib("hitpoints", u.set_hitpoints(value));
436  modify_int_attrib("max_hitpoints", u.set_max_hitpoints(value));
437  modify_int_attrib("experience", u.set_experience(value));
438  modify_int_attrib("max_experience", u.set_max_experience(value));
439  modify_int_attrib("recall_cost", u.set_recall_cost(value));
440  modify_int_attrib("attacks_left", u.set_attacks(value));
441  modify_int_attrib("level", u.set_level(value));
442  modify_bool_attrib("resting", u.set_resting(value));
443  modify_tstring_attrib("name", u.set_name(value));
444  modify_tstring_attrib("description", u.set_unit_description(value));
445  modify_string_attrib("portrait", u.set_big_profile(value));
446  modify_string_attrib("role", u.set_role(value));
447  modify_string_attrib("facing", u.set_facing(map_location::parse_direction(value)));
448  modify_string_attrib("usage", u.set_usage(value));
449  modify_string_attrib("undead_variation", u.set_undead_variation(value));
450  modify_string_attrib("ellipse", u.set_image_ellipse(value));
451  modify_string_attrib("halo", u.set_image_halo(value));
452  modify_bool_attrib("hidden", u.set_hidden(value));
453  modify_bool_attrib("zoc", u.set_emit_zoc(value));
454  modify_bool_attrib("canrecruit", u.set_can_recruit(value));
455  modify_bool_attrib("renamable", u.set_unrenamable(!value));
456  modify_cfg_attrib("recall_filter", u.set_recall_filter(cfg));
457 
458  modify_vector_string_attrib("extra_recruit", u.set_recruits(value));
459  modify_vector_string_attrib("advances_to", u.set_advances_to(value));
460  if(strcmp(m, "alignment") == 0) {
461  u.set_alignment(lua_check<UNIT_ALIGNMENT>(L, 3));
462  return 0;
463  }
464 
465  if(strcmp(m, "advancements") == 0) {
466  u.set_advancements(lua_check<std::vector<config>>(L, 3));
467  return 0;
468  }
469 
470  if(strcmp(m, "upkeep") == 0) {
471  if(lua_isnumber(L, 3)) {
472  u.set_upkeep(static_cast<int>(luaL_checkinteger(L, 3)));
473  return 0;
474  }
475  const char* v = luaL_checkstring(L, 3);
476  if((strcmp(v, "loyal") == 0) || (strcmp(v, "free") == 0)) {
477  u.set_upkeep(unit::upkeep_loyal());
478  } else if(strcmp(v, "full") == 0) {
479  u.set_upkeep(unit::upkeep_full());
480  } else {
481  std::string err_msg = "unknown upkeep value of unit: ";
482  err_msg += v;
483  return luaL_argerror(L, 2, err_msg.c_str());
484  }
485  return 0;
486  }
487 
488  if(!lu->on_map()) {
489  map_location loc = u.get_location();
490  modify_int_attrib("x", loc.set_wml_x(value); u.set_location(loc));
491  modify_int_attrib("y", loc.set_wml_y(value); u.set_location(loc));
492  modify_string_attrib("id", u.set_id(value));
493  if(strcmp(m, "loc") == 0) {
494  luaW_tolocation(L, 3, loc);
495  u.set_location(loc);
496  return 0;
497  }
498  } else {
499  const bool is_key_x = strcmp(m, "x") == 0;
500  const bool is_key_y = strcmp(m, "y") == 0;
501  const bool is_loc_key = strcmp(m, "loc") == 0;
502 
503  // Handle moving an on-map unit
504  if(is_key_x || is_key_y || is_loc_key) {
505  game_board* gb = resources::gameboard;
506 
507  if(!gb) {
508  return 0;
509  }
510 
511  map_location src = u.get_location();
512  map_location dst = src;
513 
514  if(is_key_x) {
515  dst.set_wml_x(luaL_checkinteger(L, 3));
516  } else if(is_key_y) {
517  dst.set_wml_y(luaL_checkinteger(L, 3));
518  } else {
519  dst = luaW_checklocation(L, 3);
520  }
521 
522  // TODO: could probably be relegated to a helper function.
523  if(src != dst) {
524  // If the dst isn't on the map, the unit will be clobbered. Guard against that.
525  if(!gb->map().on_board(dst)) {
526  std::string err_msg = formatter() << "destination hex not on map (excluding border): " << dst;
527  return luaL_argerror(L, 2, err_msg.c_str());
528  }
529 
530  auto [unit_iterator, success] = gb->units().move(src, dst);
531 
532  if(success) {
533  unit_iterator->anim_comp().set_standing();
534  }
535  }
536 
537  return 0;
538  }
539  }
540 
541  if(strcmp(m, "goto") == 0) {
542  u.set_goto(luaW_checklocation(L, 3));
543  return 0;
544  }
545 
546  std::string err_msg = "unknown modifiable property of unit: ";
547  err_msg += m;
548  return luaL_argerror(L, 2, err_msg.c_str());
549 }
550 
551 /**
552  * Gets the status of a unit (__index metamethod).
553  * - Arg 1: table containing the userdata containing the unit id.
554  * - Arg 2: string containing the name of the status.
555  * - Ret 1: boolean.
556  */
558 {
559  if(!lua_istable(L, 1)) {
560  return luaW_type_error(L, 1, "unit status");
561  }
562  lua_rawgeti(L, 1, 1);
563  const unit* u = luaW_tounit(L, -1);
564  if(!u) {
565  return luaL_argerror(L, 1, "unknown unit");
566  }
567  char const *m = luaL_checkstring(L, 2);
568  lua_pushboolean(L, u->get_state(m));
569  return 1;
570 }
571 
572 /**
573  * Sets the status of a unit (__newindex metamethod).
574  * - Arg 1: table containing the userdata containing the unit id.
575  * - Arg 2: string containing the name of the status.
576  * - Arg 3: boolean.
577  */
579 {
580  if(!lua_istable(L, 1)) {
581  return luaW_type_error(L, 1, "unit status");
582  }
583  lua_rawgeti(L, 1, 1);
584  unit* u = luaW_tounit(L, -1);
585  if(!u) {
586  return luaL_argerror(L, 1, "unknown unit");
587  }
588  char const *m = luaL_checkstring(L, 2);
589  u->set_state(m, luaW_toboolean(L, 3));
590  return 0;
591 }
592 
593 /**
594  * Gets the variable of a unit (__index metamethod).
595  * - Arg 1: table containing the userdata containing the unit id.
596  * - Arg 2: string containing the name of the status.
597  * - Ret 1: boolean.
598  */
600 {
601  if(!lua_istable(L, 1)) {
602  return luaW_type_error(L, 1, "unit variables");
603  }
604  lua_rawgeti(L, 1, 1);
605  const unit* u = luaW_tounit(L, -1);
606  if(!u) {
607  return luaL_argerror(L, 2, "unknown unit");
608  }
609  char const *m = luaL_checkstring(L, 2);
610  return_cfgref_attrib("__cfg", u->variables());
611 
612  variable_access_const v(m, u->variables());
613  return luaW_pushvariable(L, v) ? 1 : 0;
614 }
615 
616 /**
617  * Sets the variable of a unit (__newindex metamethod).
618  * - Arg 1: table containing the userdata containing the unit id.
619  * - Arg 2: string containing the name of the status.
620  * - Arg 3: scalar.
621  */
623 {
624  if(!lua_istable(L, 1)) {
625  return luaW_type_error(L, 1, "unit variables");
626  }
627  lua_rawgeti(L, 1, 1);
628  unit* u = luaW_tounit(L, -1);
629  if(!u) {
630  return luaL_argerror(L, 2, "unknown unit");
631  }
632  char const *m = luaL_checkstring(L, 2);
633  modify_cfg_attrib("__cfg", u->variables() = cfg);
634  config& vars = u->variables();
635  if(lua_isnoneornil(L, 3)) {
636  try {
637  variable_access_throw(m, vars).clear(false);
638  } catch(const invalid_variablename_exception&) {
639  }
640  return 0;
641  }
642  variable_access_create v(m, vars);
643  luaW_checkvariable(L, v, 3);
644  return 0;
645 }
646 
647 namespace lua_units {
649  {
650  std::ostringstream cmd_out;
651 
652  // Create the getunit metatable.
653  cmd_out << "Adding getunit metatable...\n";
654 
657  lua_setfield(L, -2, "__gc");
659  lua_setfield(L, -2, "__eq");
661  lua_setfield(L, -2, "__tostring");
663  lua_setfield(L, -2, "__index");
665  lua_setfield(L, -2, "__newindex");
666  lua_pushstring(L, "unit");
667  lua_setfield(L, -2, "__metatable");
668 
669  // Create the unit status metatable.
670  cmd_out << "Adding unit status metatable...\n";
671 
674  lua_setfield(L, -2, "__index");
676  lua_setfield(L, -2, "__newindex");
677  lua_pushstring(L, "unit status");
678  lua_setfield(L, -2, "__metatable");
679 
680  // Create the unit variables metatable.
681  cmd_out << "Adding unit variables metatable...\n";
682 
685  lua_setfield(L, -2, "__index");
687  lua_setfield(L, -2, "__newindex");
688  lua_pushstring(L, "unit variables");
689  lua_setfield(L, -2, "__metatable");
690 
691  return cmd_out.str();
692  }
693 }
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:926
#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:207
std::string register_metatables(lua_State *L)
Definition: lua_unit.cpp:648
virtual const unit_map & units() const override
Definition: game_board.hpp:111
This class represents a single unit of a specific type.
Definition: unit.hpp:120
const std::string & type_id() const
The id of this unit&#39;s type.
Definition: unit.cpp:1764
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:191
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:44
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
Definition: unit.cpp:1274
bool luaW_isunit(lua_State *L, int index)
Test if a Lua value is a unit.
Definition: lua_unit.cpp:113
friend lua_unit * luaW_pushlocalunit(lua_State *L, unit &u)
Pushes a private unit on the stack.
Definition: lua_unit.cpp:212
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:162
config & variables()
Gets any user-defined variables this unit &#39;owns&#39;.
Definition: unit.hpp:696
bool luaW_pushvariable(lua_State *L, variable_access_const &v)
Definition: lua_common.cpp:898
#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:599
static int impl_unit_tostring(lua_State *L)
Turns a lua proxy unit to string.
Definition: lua_unit.cpp:244
static int impl_unit_variables_set(lua_State *L)
Sets the variable of a unit (__newindex metamethod).
Definition: lua_unit.cpp:622
std::size_t erase(const map_location &l)
Erases the unit at location l, if any.
Definition: map.cpp:296
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:273
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:578
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:725
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:25
static const char unitvarKey[]
Definition: lua_unit.cpp:42
#define return_cfgref_attrib(name, accessor)
Definition: lua_common.hpp:291
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:223
static int impl_unit_equality(lua_State *L)
Checks two lua proxy units for equality.
Definition: lua_unit.cpp:232
team & get_team(int i)
Definition: game_board.hpp:96
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:370
void set_state(const std::string &state, bool value)
Set whether the unit is affected by a status effect.
Definition: unit.cpp:1322
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:893
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:183
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:142
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:92
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:37
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:309
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:217
static void unit_show_error(lua_State *L, int index, int error)
Definition: lua_unit.cpp:168
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:222
static lua_unit * internal_get_unit(lua_State *L, int index, bool only_on_map, int &error)
Definition: lua_unit.cpp:125
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:199
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:397
#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:1348
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:152
Standard logging facilities (interface).
recall_list_manager & recall_list()
Definition: team.hpp:223
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:557
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:59
bool valid() const
Definition: map.hpp:273
static int impl_unit_set(lua_State *L)
Sets some data on a unit (__newindex metamethod).
Definition: lua_unit.cpp:421
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:382
#define luaL_checkstring(L, n)
Definition: lauxlib.h:138