29 #include <type_traits> 43 idx = lua_absindex(L, idx);
44 lua_createtable(L, 1, 0);
45 lua_pushvalue(L, idx);
47 lua_rawseti(L, -2, 0);
53 if(weapon !=
nullptr) {
63 if(weapon !=
nullptr) {
88 luaL_argerror(L, idx,
"attack is read-only");
94 using attack_ptr_in = std::shared_ptr<utils::const_clone_t<attack_type, std::remove_pointer_t<T>>>;
100 auto attacks = u->attacks();
101 for(
auto at = attacks.begin();
at != attacks.end(); ++
at) {
112 auto attacks = u->attacks();
113 if(
i < static_cast<std::size_t>(attacks.size())) {
114 auto iter = attacks.begin();
129 if(!lua_istable(L, 1)) {
132 lua_rawgeti(L, 1, 0);
135 if(lu && lu->get()) {
143 return luaL_argerror(L, 1,
"unit not found");
152 return &atk2 == atk.get();
158 if(!lua_istable(L, 1)) {
161 lua_rawgeti(L, 1, 0);
164 return luaL_argerror(L, 1,
"unit type attack table is immutable");
169 if(lua_isnumber(L, 2) && lua_tonumber(L, 2) - 1 > u.
attacks().size()) {
170 return luaL_argerror(L, 2,
"attack can only be added at the end of the list");
173 if(lua_isnil(L, 3)) {
196 if(!lua_isnumber(L, 2)) {
197 atk->set_id(lua_tostring(L, 2));
209 if(!lua_istable(L, 1)) {
212 lua_rawgeti(L, 1, 0);
216 return luaL_argerror(L, 1,
"unknown unit");
225 int n = luaL_checkinteger(L, 2) + 1;
226 int max_n = luaL_checkinteger(L, -1);
230 lua_pushnumber(L, n);
231 lua_pushvalue(L, -1);
240 lua_pushnumber(L, 0);
254 char const *m = luaL_checkstring(L, 2);
274 std::string err_msg =
"unknown property of attack: ";
276 return luaL_argerror(L, 2, err_msg.c_str());
288 char const *m = luaL_checkstring(L, 2);
303 if(strcmp(m,
"specials") == 0) {
308 std::string err_msg =
"unknown modifiable property of attack: ";
310 return luaL_argerror(L, 2, err_msg.c_str());
317 lua_pushboolean(L, ut1 == ut2);
327 std::ostringstream str;
328 str <<
"weapon: <" << atk->id() <<
'>';
338 return luaL_argerror(L, 1,
"invalid attack");
340 lua_pushboolean(L, atk->matches_filter(cfg));
361 std::ostringstream cmd_out;
364 cmd_out <<
"Adding unit attacks metatable...\n";
368 lua_setfield(L, -2,
"__index");
370 lua_setfield(L, -2,
"__newindex");
372 lua_setfield(L, -2,
"__len");
374 lua_setfield(L, -2,
"__ipairs");
376 lua_setfield(L, -2,
"__metatable");
381 lua_setfield(L, -2,
"__index");
383 lua_setfield(L, -2,
"__newindex");
385 lua_setfield(L, -2,
"__eq");
387 lua_setfield(L, -2,
"__tostring");
389 lua_setfield(L, -2,
"__gc");
391 lua_setfield(L, -2,
"__metatable");
393 lua_setfield(L, -2,
"matches");
395 return cmd_out.str();
static int impl_unit_attack_collect(lua_State *L)
const std::string & id() const
This class represents a single unit of a specific type.
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.
static int impl_unit_attacks_get(lua_State *L)
Gets the attacks of a unit or unit type (__index metamethod).
static int impl_unit_attacks_next(lua_State *L)
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...
void set_num_attacks(int value)
#define return_string_attrib(name, accessor)
const std::string & type() const
static int impl_unit_attack_match(lua_State *L)
int intf_create_attack(lua_State *L)
static int impl_unit_attack_set(lua_State *L)
Gets a property of a units attack (__index metamethod).
void lua_push(lua_State *L, const T &val)
attack_ptr add_attack(attack_itors::iterator position, Args &&... args)
Adds a new attack to the unit.
A single unit type that the player may recruit.
static int impl_unit_attack_equal(lua_State *L)
#define return_cfgref_attrib(name, accessor)
static int impl_unit_attack_tostring(lua_State *L)
Turns a lua proxy attack to string.
void set_name(const t_string &value)
static const char uattacksKey[]
static int impl_unit_attack_get(lua_State *L)
Gets a property of a units attack (__index metamethod).
static std::string at(const std::string &file, int line)
#define modify_tstring_attrib(name, accessor)
int movement_used() const
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
#define modify_string_attrib(name, accessor)
#define return_int_attrib(name, accessor)
attack_type & luaW_checkweapon(lua_State *L, int idx)
auto find_attack(T *u, const std::string &id) -> attack_ptr_in< T >
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
const t_string & name() const
void set_attacks_used(int value)
const std::string & range() const
static int impl_unit_attacks_set(lua_State *L)
const std::string & icon() const
attack_ref(const_attack_ptr atk)
void set_defense_weight(double value)
void set_specials(config value)
const unit_type * luaW_tounittype(lua_State *L, int idx)
Test if a stack element is a unit type, and return it if so.
static attack_ref & luaW_checkweapon_ref(lua_State *L, int idx)
Storage for a unit, either owned by the Lua code (ptr != 0), a local variable unit (c_ptr != 0)...
std::string id
Text to match against addon_info.tags()
void set_damage(int value)
std::shared_ptr< utils::const_clone_t< attack_type, std::remove_pointer_t< T > >> attack_ptr_in
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
attack_ref(attack_ptr atk)
const config & specials() const
double attack_weight() const
attack_itors attacks()
Gets an iterator over this unit's attacks.
double defense_weight() const
std::shared_ptr< attack_type > attack_ptr
void set_range(const std::string &value)
void set_parry(int value)
#define return_bool_attrib(name, accessor)
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...
void luaW_pushweapon(lua_State *L, attack_ptr weapon)
std::string register_attacks_metatables(lua_State *L)
#define return_float_attrib(name, accessor)
static int impl_unit_attacks_len(lua_State *L)
Counts the attacks of a unit (__len metamethod).
void set_icon(const std::string &value)
static const char uattackKey[]
void set_id(const std::string &value)
static attack_itors::iterator get_attack_iter(unit &u, attack_ptr atk)
const_attack_itors attacks() const
static int impl_unit_attacks_iter(lua_State *L)
void push_unit_attacks_table(lua_State *L, int idx)
void set_movement_used(int value)
A config object defines a single node in a WML file, with access to child nodes.
std::shared_ptr< const attack_type > const_attack_ptr
static map_location::DIRECTION n
void set_accuracy(int value)
std::string::const_iterator iterator
void set_attack_weight(double value)
const_attack_ptr luaW_toweapon(lua_State *L, int idx)
#define modify_int_attrib(name, accessor)
bool remove_attack(attack_ptr atk)
Remove an attack from the unit.
void set_type(const std::string &value)