The Battle for Wesnoth  1.15.1+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 
31 #include "lua/lauxlib.h"
32 #include "lua/lua.h" // for lua_State, lua_settop, etc
33 
34 static lg::log_domain log_scripting_lua("scripting/lua");
35 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
36 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
37 
38 static const char getunitKey[] = "unit";
39 static const char ustatusKey[] = "unit status";
40 static const char unitvarKey[] = "unit variables";
41 
43 {
44 }
45 
47 {
48  if (ptr) return ptr.get();
49  if (c_ptr) return c_ptr;
50  if (side) {
52  }
54  if (!ui.valid()) return nullptr;
55  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.
56 }
58 {
59  if (ptr) return ptr;
60  if (side) {
62  }
64  if (!ui.valid()) return unit_ptr();
65  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.
66 }
67 
68 // Having this function here not only simplifies other code, it allows us to move
69 // pointers around from one structure to another.
70 // This makes bare pointer->map in particular about 2 orders of magnitude faster,
71 // as benchmarked from Lua code.
73 {
74  if (ptr) {
76  bool success = false;
77 
78  std::tie(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  * Gets some data on a unit (__index metamethod).
244  * - Arg 1: full userdata containing the unit id.
245  * - Arg 2: string containing the name of the property.
246  * - Ret 1: something containing the attribute.
247  */
248 static int impl_unit_get(lua_State *L)
249 {
250  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
251  char const *m = luaL_checkstring(L, 2);
252  const unit* pu = lu->get();
253 
254  if(strcmp(m, "valid") == 0) {
255  if(!pu) {
256  return 0;
257  }
258  if(lu->on_map()) {
259  lua_pushstring(L, "map");
260  } else if(lu->on_recall_list()) {
261  lua_pushstring(L, "recall");
262  } else {
263  lua_pushstring(L, "private");
264  }
265  return 1;
266  }
267 
268  if(!pu) {
269  return luaL_argerror(L, 1, "unknown unit");
270  }
271 
272  const unit& u = *pu;
273 
274  // Find the corresponding attribute.
277  if(strcmp(m, "loc") == 0) {
280  return 2;
281  }
282  if(strcmp(m, "goto") == 0) {
283  lua_pushinteger(L, u.get_goto().wml_x());
284  lua_pushinteger(L, u.get_goto().wml_y());
285  return 2;
286  }
287  return_int_attrib("side", u.side());
288  return_string_attrib("id", u.id());
289  return_string_attrib("type", u.type_id());
290  return_string_attrib("image_mods", u.effect_image_mods());
291  return_string_attrib("usage", u.usage());
292  return_int_attrib("hitpoints", u.hitpoints());
293  return_int_attrib("max_hitpoints", u.max_hitpoints());
294  return_int_attrib("experience", u.experience());
295  return_int_attrib("max_experience", u.max_experience());
296  return_int_attrib("recall_cost", u.recall_cost());
297  return_int_attrib("moves", u.movement_left());
298  return_int_attrib("max_moves", u.total_movement());
299  return_int_attrib("max_attacks", u.max_attacks());
300  return_int_attrib("attacks_left", u.attacks_left());
301  return_tstring_attrib("name", u.name());
302  return_bool_attrib("canrecruit", u.can_recruit());
303  return_int_attrib("level", u.level());
304  return_int_attrib("cost", u.cost());
305 
306  return_vector_string_attrib("extra_recruit", u.recruits());
307  return_vector_string_attrib("advances_to", u.advances_to());
308 
309  if(strcmp(m, "alignment") == 0) {
310  lua_push(L, u.alignment());
311  return 1;
312  }
313 
314  if(strcmp(m, "upkeep") == 0) {
315  unit::upkeep_t upkeep = u.upkeep_raw();
316 
317  // Need to keep these separate in order to ensure an int value is always used if applicable.
318  if(int* v = boost::get<int>(&upkeep)) {
319  lua_push(L, *v);
320  } else {
321  const std::string type = boost::apply_visitor(unit::upkeep_type_visitor(), upkeep);
322  lua_push(L, type);
323  }
324 
325  return 1;
326  }
327  if(strcmp(m, "advancements") == 0) {
329  return 1;
330  }
331  if(strcmp(m, "overlays") == 0) {
332  lua_push(L, u.overlays());
333  return 1;
334  }
335  if(strcmp(m, "traits") == 0) {
336  lua_push(L, u.get_traits_list());
337  return 1;
338  }
339  if(strcmp(m, "abilities") == 0) {
340  lua_push(L, u.get_ability_list());
341  return 1;
342  }
343  if(strcmp(m, "status") == 0) {
344  lua_createtable(L, 1, 0);
345  lua_pushvalue(L, 1);
346  lua_rawseti(L, -2, 1);
348  return 1;
349  }
350  if(strcmp(m, "variables") == 0) {
351  lua_createtable(L, 1, 0);
352  lua_pushvalue(L, 1);
353  lua_rawseti(L, -2, 1);
355  return 1;
356  }
357  if(strcmp(m, "attacks") == 0) {
359  return 1;
360  }
361  return_vector_string_attrib("animations", u.anim_comp().get_flags());
362  return_cfg_attrib("recall_filter", cfg = u.recall_filter());
363  return_bool_attrib("hidden", u.get_hidden());
364  return_bool_attrib("petrified", u.incapacitated());
365  return_bool_attrib("resting", u.resting());
366  return_string_attrib("role", u.get_role());
367  return_string_attrib("race", u.race()->id());
368  return_string_attrib("gender", gender_string(u.gender()));
369  return_string_attrib("variation", u.variation());
370  return_bool_attrib("zoc", u.get_emit_zoc());
372  return_string_attrib("portrait", u.big_profile() == u.absolute_image()
373  ? u.absolute_image() + u.image_mods() + "~XBRZ(2)"
374  : u.big_profile());
375  return_cfg_attrib("__cfg", u.write(cfg); u.get_location().write(cfg));
376 
377  if(luaW_getmetafield(L, 1, m)) {
378  return 1;
379  }
380  return 0;
381 }
382 
383 /**
384  * Sets some data on a unit (__newindex metamethod).
385  * - Arg 1: full userdata containing the unit id.
386  * - Arg 2: string containing the name of the property.
387  * - Arg 3: something containing the attribute.
388  */
389 static int impl_unit_set(lua_State *L)
390 {
391  lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, 1));
392  char const *m = luaL_checkstring(L, 2);
393  unit* pu = lu->get();
394  if (!pu) return luaL_argerror(L, 1, "unknown unit");
395  unit &u = *pu;
396 
397  // Find the corresponding attribute.
398  //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
399  modify_int_attrib("side", u.set_side(value));
400  modify_int_attrib("moves", u.set_movement(value));
401  modify_int_attrib("max_moves", u.set_total_movement(value));
402  modify_int_attrib("max_attacks", u.set_max_attacks(value));
403  modify_int_attrib("hitpoints", u.set_hitpoints(value));
404  modify_int_attrib("max_hitpoints", u.set_max_hitpoints(value));
405  modify_int_attrib("experience", u.set_experience(value));
406  modify_int_attrib("max_experience", u.set_max_experience(value));
407  modify_int_attrib("recall_cost", u.set_recall_cost(value));
408  modify_int_attrib("attacks_left", u.set_attacks(value));
409  modify_int_attrib("level", u.set_level(value));
410  modify_bool_attrib("resting", u.set_resting(value));
411  modify_tstring_attrib("name", u.set_name(value));
412  modify_string_attrib("role", u.set_role(value));
414  modify_string_attrib("usage", u.set_usage(value));
415  modify_string_attrib("undead_variation", u.set_undead_variation(value));
416  modify_bool_attrib("hidden", u.set_hidden(value));
417  modify_bool_attrib("zoc", u.set_emit_zoc(value));
418  modify_bool_attrib("canrecruit", u.set_can_recruit(value));
419 
420  modify_vector_string_attrib("extra_recruit", u.set_recruits(value));
421  modify_vector_string_attrib("advances_to", u.set_advances_to(value));
422  if(strcmp(m, "alignment") == 0) {
423  u.set_alignment(lua_check<unit_type::ALIGNMENT>(L, 3));
424  return 0;
425  }
426 
427  if(strcmp(m, "advancements") == 0) {
428  u.set_advancements(lua_check<std::vector<config>>(L, 3));
429  return 0;
430  }
431 
432  if(strcmp(m, "upkeep") == 0) {
433  if(lua_isnumber(L, 3)) {
434  u.set_upkeep(luaL_checkinteger(L, 3));
435  return 0;
436  }
437  const char* v = luaL_checkstring(L, 3);
438  if((strcmp(v, "loyal") == 0) || (strcmp(v, "free") == 0)) {
440  } else if(strcmp(v, "full") == 0) {
442  } else {
443  std::string err_msg = "unknown upkeep value of unit: ";
444  err_msg += v;
445  return luaL_argerror(L, 2, err_msg.c_str());
446  }
447  return 0;
448  }
449 
450  if(!lu->on_map()) {
451  map_location loc = u.get_location();
452  modify_int_attrib("x", loc.set_wml_x(value); u.set_location(loc));
453  modify_int_attrib("y", loc.set_wml_y(value); u.set_location(loc));
454  modify_string_attrib("id", u.set_id(value));
455  } else {
456  const bool is_key_x = strcmp(m, "x") == 0;
457  const bool is_key_y = strcmp(m, "y") == 0;
458  const bool is_loc_key = strcmp(m, "loc") == 0;
459 
460  // Handle moving an on-map unit
461  if(is_key_x || is_key_y || is_loc_key) {
463 
464  if(!gb) {
465  return 0;
466  }
467 
468  map_location src = u.get_location();
469  map_location dst = src;
470 
471  if(is_key_x) {
472  dst.set_wml_x(luaL_checkinteger(L, 3));
473  } else if(is_key_y) {
474  dst.set_wml_y(luaL_checkinteger(L, 3));
475  } else {
476  dst = luaW_checklocation(L, 3);
477  }
478 
479  // TODO: could probably be relegated to a helper function.
480  if(src != dst) {
481  // If the dst isn't on the map, the unit will be clobbered. Guard against that.
482  if(!gb->map().on_board(dst)) {
483  std::string err_msg = formatter() << "destination hex not on map (excluding border): " << dst;
484  return luaL_argerror(L, 2, err_msg.c_str());
485  }
486 
487  unit_map::iterator unit_iterator = gb->units().end();
488  bool success = false;
489 
490  std::tie(unit_iterator, success) = gb->units().move(src, dst);
491 
492  if(success) {
493  unit_iterator->anim_comp().set_standing();
494  }
495  }
496 
497  return 0;
498  }
499  }
500 
501  if(strcmp(m, "goto") == 0) {
502  u.set_goto(luaW_checklocation(L, 3));
503  return 0;
504  }
505 
506  std::string err_msg = "unknown modifiable property of unit: ";
507  err_msg += m;
508  return luaL_argerror(L, 2, err_msg.c_str());
509 }
510 
511 /**
512  * Gets the status of a unit (__index metamethod).
513  * - Arg 1: table containing the userdata containing the unit id.
514  * - Arg 2: string containing the name of the status.
515  * - Ret 1: boolean.
516  */
518 {
519  if(!lua_istable(L, 1)) {
520  return luaW_type_error(L, 1, "unit status");
521  }
522  lua_rawgeti(L, 1, 1);
523  const unit* u = luaW_tounit(L, -1);
524  if(!u) {
525  return luaL_argerror(L, 1, "unknown unit");
526  }
527  char const *m = luaL_checkstring(L, 2);
528  lua_pushboolean(L, u->get_state(m));
529  return 1;
530 }
531 
532 /**
533  * Sets the status of a unit (__newindex metamethod).
534  * - Arg 1: table containing the userdata containing the unit id.
535  * - Arg 2: string containing the name of the status.
536  * - Arg 3: boolean.
537  */
539 {
540  if(!lua_istable(L, 1)) {
541  return luaW_type_error(L, 1, "unit status");
542  }
543  lua_rawgeti(L, 1, 1);
544  unit* u = luaW_tounit(L, -1);
545  if(!u) {
546  return luaL_argerror(L, 1, "unknown unit");
547  }
548  char const *m = luaL_checkstring(L, 2);
549  u->set_state(m, luaW_toboolean(L, 3));
550  return 0;
551 }
552 
553 /**
554  * Gets the variable of a unit (__index metamethod).
555  * - Arg 1: table containing the userdata containing the unit id.
556  * - Arg 2: string containing the name of the status.
557  * - Ret 1: boolean.
558  */
560 {
561  if(!lua_istable(L, 1)) {
562  return luaW_type_error(L, 1, "unit variables");
563  }
564  lua_rawgeti(L, 1, 1);
565  const unit* u = luaW_tounit(L, -1);
566  if(!u) {
567  return luaL_argerror(L, 2, "unknown unit");
568  }
569  char const *m = luaL_checkstring(L, 2);
570  return_cfgref_attrib("__cfg", u->variables());
571 
572  variable_access_const v(m, u->variables());
573  return luaW_pushvariable(L, v) ? 1 : 0;
574 }
575 
576 /**
577  * Sets the variable of a unit (__newindex metamethod).
578  * - Arg 1: table containing the userdata containing the unit id.
579  * - Arg 2: string containing the name of the status.
580  * - Arg 3: scalar.
581  */
583 {
584  if(!lua_istable(L, 1)) {
585  return luaW_type_error(L, 1, "unit variables");
586  }
587  lua_rawgeti(L, 1, 1);
588  unit* u = luaW_tounit(L, -1);
589  if(!u) {
590  return luaL_argerror(L, 2, "unknown unit");
591  }
592  char const *m = luaL_checkstring(L, 2);
593  if(strcmp(m, "__cfg") == 0) {
594  u->variables() = luaW_checkconfig(L, 3);
595  return 0;
596  }
597  config& vars = u->variables();
598  if(lua_isnoneornil(L, 3)) {
599  try {
600  variable_access_throw(m, vars).clear(false);
601  } catch(const invalid_variablename_exception&) {
602  }
603  return 0;
604  }
605  variable_access_create v(m, vars);
606  luaW_checkvariable(L, v, 3);
607  return 0;
608 }
609 
610 namespace lua_units {
612  {
613  std::ostringstream cmd_out;
614 
615  // Create the getunit metatable.
616  cmd_out << "Adding getunit metatable...\n";
617 
620  lua_setfield(L, -2, "__gc");
622  lua_setfield(L, -2, "__eq");
624  lua_setfield(L, -2, "__index");
626  lua_setfield(L, -2, "__newindex");
627  lua_pushstring(L, "unit");
628  lua_setfield(L, -2, "__metatable");
629  // Unit methods
630  luaW_getglobal(L, "wesnoth", "match_unit");
631  lua_setfield(L, -2, "matches");
632  luaW_getglobal(L, "wesnoth", "put_recall_unit");
633  lua_setfield(L, -2, "to_recall");
634  luaW_getglobal(L, "wesnoth", "put_unit");
635  lua_setfield(L, -2, "to_map");
636  luaW_getglobal(L, "wesnoth", "erase_unit");
637  lua_setfield(L, -2, "erase");
638  luaW_getglobal(L, "wesnoth", "copy_unit");
639  lua_setfield(L, -2, "clone");
640  luaW_getglobal(L, "wesnoth", "extract_unit");
641  lua_setfield(L, -2, "extract");
642  luaW_getglobal(L, "wesnoth", "advance_unit");
643  lua_setfield(L, -2, "advance");
644  luaW_getglobal(L, "wesnoth", "add_modification");
645  lua_setfield(L, -2, "add_modification");
646  luaW_getglobal(L, "wesnoth", "unit_resistance");
647  lua_setfield(L, -2, "resistance");
648  luaW_getglobal(L, "wesnoth", "remove_modifications");
649  lua_setfield(L, -2, "remove_modifications");
650  luaW_getglobal(L, "wesnoth", "unit_defense");
651  lua_setfield(L, -2, "defense");
652  luaW_getglobal(L, "wesnoth", "unit_movement_cost");
653  lua_setfield(L, -2, "movement");
654  luaW_getglobal(L, "wesnoth", "unit_vision_cost");
655  lua_setfield(L, -2, "vision");
656  luaW_getglobal(L, "wesnoth", "unit_jamming_cost");
657  lua_setfield(L, -2, "jamming");
658  luaW_getglobal(L, "wesnoth", "unit_ability");
659  lua_setfield(L, -2, "ability");
660  luaW_getglobal(L, "wesnoth", "transform_unit");
661  lua_setfield(L, -2, "transform");
662  luaW_getglobal(L, "wesnoth", "select_unit");
663  lua_setfield(L, -2, "select");
664 
665  // Create the unit status metatable.
666  cmd_out << "Adding unit status metatable...\n";
667 
670  lua_setfield(L, -2, "__index");
672  lua_setfield(L, -2, "__newindex");
673  lua_pushstring(L, "unit status");
674  lua_setfield(L, -2, "__metatable");
675 
676  // Create the unit variables metatable.
677  cmd_out << "Adding unit variables metatable...\n";
678 
681  lua_setfield(L, -2, "__index");
683  lua_setfield(L, -2, "__newindex");
684  lua_pushstring(L, "unit variables");
685  lua_setfield(L, -2, "__metatable");
686 
687  return cmd_out.str();
688  }
689 }
static lg::log_domain log_scripting_lua("scripting/lua")
void set_wml_y(int v)
Definition: location.hpp:161
void set_experience(int xp)
Sets the current experience point amount.
Definition: unit.hpp:507
bool luaW_checkvariable(lua_State *L, variable_access_create &v, int n)
Definition: lua_common.cpp:903
#define modify_bool_attrib(name, accessor)
Definition: lua_common.hpp:339
#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.
int attacks_left() const
Gets the remaining number of attacks this unit can perform this turn.
Definition: unit.hpp:942
Game board class.
Definition: game_board.hpp:50
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:684
void set_movement(int moves, bool unit_action=false)
Set this unit&#39;s remaining movement to moves.
Definition: unit.cpp:1193
#define lua_pushcfunction(L, f)
Definition: lua.h:350
static DIRECTION parse_direction(const std::string &str)
Definition: location.cpp:64
void set_can_recruit(bool canrecruit)
Sets whether this unit can recruit other units.
Definition: unit.hpp:576
unit_iterator end()
Definition: map.hpp:415
V::result_t apply_visitor(typename V::param_t state, T &&... args)
Helper function to apply the result of a specified visitor to a variable_info object.
static void setmetatable(lua_State *L)
Definition: lua_unit.cpp:208
std::string register_metatables(lua_State *L)
Definition: lua_unit.cpp:611
#define return_tstring_attrib(name, accessor)
Definition: lua_common.hpp:201
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:99
std::string big_profile() const
An optional profile image displays when this unit is &#39;speaking&#39; via [message].
Definition: unit.cpp:1039
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
void set_usage(const std::string &usage)
Sets this unit&#39;s usage.
Definition: unit.hpp:643
const std::string & effect_image_mods() const
Gets any IPF image mods applied by effects.
Definition: unit.hpp:1487
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
const std::string & id() const
Definition: race.hpp:34
~lua_unit()
Definition: lua_unit.cpp:42
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
Definition: unit.cpp:1328
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
unit_race::GENDER gender() const
The gender of this unit.
Definition: unit.hpp:419
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:39
int hitpoints() const
The current number of hitpoints this unit has.
Definition: unit.hpp:453
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
LUA_API void lua_rawseti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:817
config & variables()
Gets any user-defined variables this unit &#39;owns&#39;.
Definition: unit.hpp:654
bool luaW_pushvariable(lua_State *L, variable_access_const &v)
Definition: lua_common.cpp:875
#define ERR_LUA
Definition: lua_unit.cpp:36
virtual const gamemap & map() const override
Definition: game_board.hpp:109
const std::string & variation() const
The ID of the variation of this unit&#39;s type.
Definition: unit.hpp:526
#define return_string_attrib(name, accessor)
Definition: lua_common.hpp:217
static int impl_unit_variables_get(lua_State *L)
Gets the variable of a unit (__index metamethod).
Definition: lua_unit.cpp:559
int wml_x() const
Definition: location.hpp:157
void set_location(const map_location &loc)
Sets this unit&#39;s map location.
Definition: unit.hpp:1268
void set_wml_x(int v)
Definition: location.hpp:160
static int impl_unit_variables_set(lua_State *L)
Sets the variable of a unit (__newindex metamethod).
Definition: lua_unit.cpp:582
map_location::DIRECTION facing() const
The current directin this unit is facing within its hex.
Definition: unit.hpp:1274
std::string absolute_image() const
The name of the file to game_display (used in menus).
Definition: unit.cpp:2359
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:377
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:38
const std::string & type_id() const
The id of this unit&#39;s type.
Definition: unit.hpp:326
static int impl_unit_get(lua_State *L)
Gets some data on a unit (__index metamethod).
Definition: lua_unit.cpp:248
#define return_vector_string_attrib(name, accessor)
Definition: lua_common.hpp:268
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:312
bool resting() const
Checks whether this unit is &#39;resting&#39;.
Definition: unit.hpp:1227
unit_ptr get_shared()
Definition: lua_unit.cpp:57
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:371
static int impl_unit_status_set(lua_State *L)
Sets the status of a unit (__newindex metamethod).
Definition: lua_unit.cpp:538
bool get_emit_zoc() const
Gets the raw zone-of-control flag, disregarding incapacitated.
Definition: unit.hpp:1245
void set_facing(map_location::DIRECTION dir) const
The this unit&#39;s facing.
Definition: unit.cpp:1593
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:704
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
Definition: unit.hpp:671
unit_type::ALIGNMENT alignment() const
The alignment of this unit.
Definition: unit.hpp:429
int cost() const
How much gold is required to recruit this unit.
Definition: unit.hpp:591
void set_total_movement(int value)
Definition: unit.hpp:1172
void set_id(const std::string &id)
Sets this unit&#39;s string ID.
Definition: unit.hpp:349
void write(config &cfg, bool write_all=true) const
Serializes the current unit metadata values.
Definition: unit.cpp:1433
static const char unitvarKey[]
Definition: lua_unit.cpp:40
#define return_cfgref_attrib(name, accessor)
Definition: lua_common.hpp:260
void set_name(const t_string &name)
Sets this unit&#39;s translatable display name.
Definition: unit.hpp:376
void set_level(int level)
Sets the current level of this unit.
Definition: unit.hpp:519
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
void set_advances_to(const std::vector< std::string > &advances_to)
Sets this unit&#39;s advancement options.
Definition: unit.cpp:1186
void set_max_attacks(int value)
Definition: unit.hpp:931
static int impl_unit_equality(lua_State *L)
Checks two lua proxy units for equality.
Definition: lua_unit.cpp:233
#define modify_tstring_attrib(name, accessor)
Definition: lua_common.hpp:283
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
#define modify_string_attrib(name, accessor)
Definition: lua_common.hpp:292
const std::string & id() const
Gets this unit&#39;s id.
Definition: unit.hpp:343
#define return_int_attrib(name, accessor)
Definition: lua_common.hpp:226
void set_state(const std::string &state, bool value)
Set whether the unit is affected by a status effect.
Definition: unit.cpp:1376
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:851
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:870
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
void set_recruits(const std::vector< std::string > &recruits)
Sets the recruit list.
Definition: unit.cpp:1162
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:143
unit * c_ptr
Definition: lua_unit.hpp:84
int wml_y() const
Definition: location.hpp:158
const config & recall_filter() const
Gets the filter constraints upon which units this unit may recall, if able.
Definition: unit.hpp:609
void set_max_experience(int value)
Definition: unit.hpp:488
void set_recall_cost(int recall_cost)
Sets the cost of recalling this unit.
Definition: unit.hpp:603
game_board * gameboard
Definition: resources.cpp:20
upkeep_t upkeep_raw() const
Gets the raw variant controlling the upkeep value.
Definition: unit.hpp:1133
const t_string & name() const
Gets this unit&#39;s translatable display name.
Definition: unit.hpp:366
int max_experience() const
The max number of experience points this unit can have.
Definition: unit.hpp:483
const map_location & get_goto() const
The map location to which this unit is moving over multiple turns, if any.
Definition: unit.hpp:1289
int level() const
The current level of this unit.
Definition: unit.hpp:513
void set_alignment(unit_type::ALIGNMENT alignment)
Sets the alignment of this unit.
Definition: unit.hpp:435
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
void set_hidden(bool state) const
Sets whether the unit is hidden on the map.
Definition: unit.cpp:2582
const std::vector< std::string > & overlays() const
Get the unit&#39;s overlay images.
Definition: unit.hpp:1500
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
void set_advancements(std::vector< config > advancements)
Sets the raw modification advancement option data.
Definition: unit.cpp:1802
void set_hitpoints(int hp)
Sets the current hitpoint amount.
Definition: unit.hpp:471
#define modify_vector_string_attrib(name, accessor)
Definition: lua_common.hpp:348
const std::string & gender_string(unit_race::GENDER gender)
Definition: race.cpp:131
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
const advancements_list & modification_advancements() const
The raw, unparsed data for modification advancements.
Definition: unit.hpp:283
#define return_cfg_attrib(name, accessor)
Definition: lua_common.hpp:250
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
std::vector< std::string > get_flags()
Get the flags of all registered animations.
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
unit_animation_component & anim_comp() const
Definition: unit.hpp:1445
unit * get()
Definition: lua_unit.cpp:46
static void unit_show_error(lua_State *L, int index, int error)
Definition: lua_unit.cpp:169
void set_undead_variation(const std::string &value)
The ID of the undead variation (ie, dwarf, swimmer) of this unit.
Definition: unit.hpp:532
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int arg)
Definition: lauxlib.cpp:430
void set_attacks(int left)
Sets the number of attacks this unit has left this turn.
Definition: unit.hpp:963
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition: unit.hpp:459
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:223
const std::string & get_role() const
Gets this unit&#39;s role.
Definition: unit.hpp:620
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:799
static lua_unit * internal_get_unit(lua_State *L, int index, bool only_on_map, int &error)
Definition: lua_unit.cpp:126
void set_emit_zoc(bool val)
Sets the raw zone-of-control flag.
Definition: unit.hpp:1251
lua_check_impl::remove_constref< T > lua_check(lua_State *L, int n)
Definition: push_check.hpp:357
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
Definition: unit.hpp:570
std::string usage() const
Gets this unit&#39;s usage.
Definition: unit.hpp:637
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
lua_unit(const lua_unit &)=delete
std::vector< std::string > get_traits_list() const
Gets a list of the traits this unit currently has.
Definition: unit.cpp:890
const unit_race * race() const
Gets this unit&#39;s race.
Definition: unit.hpp:447
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.cpp:237
boost::variant< upkeep_full, upkeep_loyal, int > upkeep_t
Definition: unit.hpp:1126
void set_max_hitpoints(int value)
Definition: unit.hpp:464
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
LUA_API int lua_isnumber(lua_State *L, int idx)
Definition: lapi.cpp:276
void set_goto(const map_location &new_goto)
Sets this unit&#39;s long term destination.
Definition: unit.hpp:1295
const std::vector< std::string > & recruits() const
The type IDs of the other units this unit may recruit, if possible.
Definition: unit.hpp:582
void set_role(const std::string &role)
Sets a unit&#39;s role.
Definition: unit.hpp:626
#define return_bool_attrib(name, accessor)
Definition: lua_common.hpp:242
bool luaW_getmetafield(lua_State *L, int idx, const char *key)
Like luaL_getmetafield, but returns false if key is an empty string or begins with two underscores...
Definition: lua_common.cpp:494
boost::intrusive_ptr< unit > unit_ptr
Definition: ptr.hpp:29
Information on a WML variable.
bool put_map(const map_location &loc)
Definition: lua_unit.cpp:72
int experience() const
The current number of experience points this unit has.
Definition: unit.hpp:477
#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:1258
void set_upkeep(upkeep_t v)
Sets the upkeep value to a specific value value.
Definition: unit.hpp:1139
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).
void set_side(unsigned int new_side)
Sets the side this unit belongs to.
Definition: unit.hpp:309
recall_list_manager & recall_list()
Definition: team.hpp:215
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:854
unit_ptr ptr
Definition: lua_unit.hpp:82
int total_movement() const
The maximum moves this unit has.
Definition: unit.hpp:1167
static int impl_unit_status_get(lua_State *L)
Gets the status of a unit (__index metamethod).
Definition: lua_unit.cpp:517
void set_resting(bool rest)
Sets this unit&#39;s resting status.
Definition: unit.hpp:1233
int side() const
The side this unit belongs to.
Definition: unit.hpp:303
std::vector< std::string > get_ability_list() const
Get a list of all abilities by ID.
Definition: abilities.cpp:228
static const char ustatusKey[]
Definition: lua_unit.cpp:39
void push_unit_attacks_table(lua_State *L, int idx)
Visitor helper struct to fetch the upkeep type flag if applicable, or the the value otherwise...
Definition: unit.hpp:1110
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:92
bool valid() const
Definition: map.hpp:276
const advances_to_t & advances_to() const
Gets the possible types this unit can advance to on level-up.
Definition: unit.hpp:203
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:466
int recall_cost() const
How much gold it costs to recall this unit.
Definition: unit.hpp:597
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:139
static int impl_unit_set(lua_State *L)
Sets some data on a unit (__newindex metamethod).
Definition: lua_unit.cpp:389
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
Definition: unit.hpp:1183
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:355
std::string image_mods() const
Gets an IPF string containing all IPF image mods.
Definition: unit.cpp:2543
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
Definition: unit.hpp:926
void write(config &cfg) const
Definition: location.cpp:210
#define modify_int_attrib(name, accessor)
Definition: lua_common.hpp:301
#define luaL_checkstring(L, n)
Definition: lauxlib.h:124