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