28 #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);
277 std::string err_msg =
"unknown property of attack: ";
279 return luaL_argerror(L, 2, err_msg.c_str());
291 char const *m = luaL_checkstring(L, 2);
309 if(strcmp(m,
"specials") == 0) {
314 std::string err_msg =
"unknown modifiable property of attack: ";
316 return luaL_argerror(L, 2, err_msg.c_str());
323 lua_pushboolean(L, ut1 == ut2);
333 std::ostringstream str;
334 str <<
"weapon: <" << atk->id() <<
'>';
344 return luaL_argerror(L, 1,
"invalid attack");
346 lua_pushboolean(L, atk->matches_filter(cfg));
367 std::ostringstream cmd_out;
370 cmd_out <<
"Adding unit attacks metatable...\n";
374 lua_setfield(L, -2,
"__index");
376 lua_setfield(L, -2,
"__newindex");
378 lua_setfield(L, -2,
"__len");
380 lua_setfield(L, -2,
"__ipairs");
382 lua_setfield(L, -2,
"__metatable");
387 lua_setfield(L, -2,
"__index");
389 lua_setfield(L, -2,
"__newindex");
391 lua_setfield(L, -2,
"__eq");
393 lua_setfield(L, -2,
"__tostring");
395 lua_setfield(L, -2,
"__gc");
397 lua_setfield(L, -2,
"__metatable");
399 lua_setfield(L, -2,
"matches");
401 return cmd_out.str();
const config & specials() const
std::string alignment_str() const
Returns alignment specified by alignment() for filtering when exist.
void set_min_range(int value)
double defense_weight() const
void set_num_attacks(int value)
double attack_weight() const
const std::string & range() const
void set_attacks_used(int value)
int movement_used() const
void set_accuracy(int value)
const std::string & type() const
void set_movement_used(int value)
void set_specials(config value)
void set_defense_weight(double value)
void set_parry(int value)
void set_attack_weight(double value)
void set_damage(int value)
const t_string & name() const
const std::string & id() const
void set_icon(const std::string &value)
void set_id(const std::string &value)
void set_max_range(int value)
void set_type(const std::string &value)
void set_range(const std::string &value)
const std::string & icon() const
void set_name(const t_string &value)
A config object defines a single node in a WML file, with access to child nodes.
Storage for a unit, either owned by the Lua code (ptr != 0), a local variable unit (c_ptr !...
A single unit type that the player may recruit.
const_attack_itors attacks() const
This class represents a single unit of a specific type.
attack_ptr add_attack(attack_itors::iterator position, Args &&... args)
Adds a new attack to the unit.
bool remove_attack(const attack_ptr &atk)
Remove an attack from the unit.
attack_itors attacks()
Gets an iterator over this unit's attacks.
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
int luaW_type_error(lua_State *L, int narg, const char *tname)
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.
#define return_float_attrib(name, accessor)
#define return_string_attrib(name, accessor)
#define return_cfgref_attrib(name, accessor)
#define return_int_attrib(name, accessor)
#define return_bool_attrib(name, accessor)
#define modify_int_attrib(name, accessor)
#define modify_tstring_attrib(name, accessor)
#define modify_string_attrib(name, accessor)
unit & luaW_checkunit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
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...
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
int intf_create_attack(lua_State *L)
static int impl_unit_attacks_iter(lua_State *L)
static int impl_unit_attacks_len(lua_State *L)
Counts the attacks of a unit (__len metamethod).
static const char uattackKey[]
static attack_ref & luaW_checkweapon_ref(lua_State *L, int idx)
static const char uattacksKey[]
static int impl_unit_attack_match(lua_State *L)
static int impl_unit_attack_collect(lua_State *L)
const_attack_ptr luaW_toweapon(lua_State *L, int idx)
void luaW_pushweapon(lua_State *L, const attack_ptr &weapon)
auto find_attack(T *u, const std::string &id) -> attack_ptr_in< T >
static int impl_unit_attacks_get(lua_State *L)
Gets the attacks of a unit or unit type (__index metamethod).
static int impl_unit_attack_get(lua_State *L)
Gets a property of a units attack (__index metamethod).
static int impl_unit_attack_set(lua_State *L)
Gets a property of a units attack (__index metamethod).
static attack_itors::iterator get_attack_iter(unit &u, attack_ptr atk)
static int impl_unit_attack_equal(lua_State *L)
static int impl_unit_attack_tostring(lua_State *L)
Turns a lua proxy attack to string.
static int impl_unit_attacks_next(lua_State *L)
static int impl_unit_attacks_set(lua_State *L)
void push_unit_attacks_table(lua_State *L, int idx)
attack_type & luaW_checkweapon(lua_State *L, int idx)
std::shared_ptr< utils::const_clone_t< attack_type, std::remove_pointer_t< T > >> attack_ptr_in
const unit_type * luaW_tounittype(lua_State *L, int idx)
Test if a stack element is a unit type, and return it if so.
std::string register_attacks_metatables(lua_State *L)
static std::string at(const std::string &file, int line)
std::string::const_iterator iterator
std::shared_ptr< const attack_type > const_attack_ptr
std::shared_ptr< attack_type > attack_ptr
void lua_push(lua_State *L, const T &val)
attack_ref(const_attack_ptr atk)
attack_ref(const attack_ptr &atk)
static map_location::direction n