mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-08 18:31:27 +00:00
add access to unit attacks to lua
This commit is contained in:
parent
f9698dd768
commit
43c10ec0cc
@ -297,6 +297,16 @@ static int impl_unit_get(lua_State *L)
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(m, "attacks") == 0) {
|
||||
lua_createtable(L, 1, 0);
|
||||
lua_pushvalue(L, 1);
|
||||
// hack: store the unit at -1 becasue we want positive indexes to refers to the attacks.
|
||||
lua_rawseti(L, -2, -1);
|
||||
lua_pushlightuserdata(L, uattacksKey);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
return_bool_attrib("hidden", u.get_hidden());
|
||||
return_bool_attrib("petrified", u.incapacitated());
|
||||
return_bool_attrib("resting", u.resting());
|
||||
@ -402,6 +412,182 @@ static int impl_unit_variables_get(lua_State *L)
|
||||
luaW_pushscalar(L, u->variables()[m]);
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
* Gets the attacks of a unit (__index metamethod).
|
||||
* - Arg 1: table containing the userdata containing the unit id.
|
||||
* - Arg 2: index (int) or id (string) identyfying teh units attack.
|
||||
* - Ret 1: the units attack.
|
||||
*/
|
||||
static int impl_unit_attacks_get(lua_State *L)
|
||||
{
|
||||
if (!lua_istable(L, 1)) {
|
||||
return luaL_typerror(L, 1, "unit attacks");
|
||||
}
|
||||
lua_rawgeti(L, 1, -1);
|
||||
const unit_const_ptr u = luaW_tounit(L, -1);
|
||||
if (!u) {
|
||||
return luaL_argerror(L, 1, "unknown unit");
|
||||
}
|
||||
const attack_type* attack = NULL;
|
||||
const std::vector<attack_type>& attacks = u->attacks();
|
||||
if(!lua_isnumber(L,2)) {
|
||||
std::string attack_id = luaL_checkstring(L, 2);
|
||||
BOOST_FOREACH(const attack_type& at, attacks) {
|
||||
if(at.id() == attack_id) {
|
||||
attack = &at;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attack == NULL) {
|
||||
//return nil on invalid index, just like lua tables do.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
size_t index = luaL_checkinteger(L, 2) - 1;
|
||||
if (index >= attacks.size()) {
|
||||
//return nil on invalid index, just like lua tables do.
|
||||
return 0;
|
||||
}
|
||||
attack = &attacks[index];
|
||||
}
|
||||
|
||||
// stack { lua_unit }, id/index, lua_unit
|
||||
lua_createtable(L, 2, 0);
|
||||
// stack { lua_unit }, id/index, lua_unit, table
|
||||
lua_pushvalue(L, -2);
|
||||
// stack { lua_unit }, id/index, lua_unit, table, lua_unit
|
||||
lua_rawseti(L, -2, 1);
|
||||
// stack { lua_unit }, id/index, lua_unit, table
|
||||
lua_pushstring(L, attack->id().c_str());
|
||||
// stack { lua_unit }, id/index, lua_unit, table, attack id
|
||||
lua_rawseti(L, -2, 2);
|
||||
// stack { lua_unit }, id/index, lua_unit, table
|
||||
lua_pushlightuserdata(L, uattackKey);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the attacks of a unit (__len metamethod).
|
||||
* - Arg 1: table containing the userdata containing the unit id.
|
||||
* - Ret 1: size of unit attacks vector.
|
||||
*/
|
||||
static int impl_unit_attacks_len(lua_State *L)
|
||||
{
|
||||
if (!lua_istable(L, 1)) {
|
||||
return luaL_typerror(L, 1, "unit attacks");
|
||||
}
|
||||
lua_rawgeti(L, 1, -1);
|
||||
const unit_const_ptr u = luaW_tounit(L, -1);
|
||||
if (!u) {
|
||||
return luaL_argerror(L, 1, "unknown unit");
|
||||
}
|
||||
lua_pushinteger(L, u->attacks().size());
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a propoerty of a units attack (__index metamethod).
|
||||
* - Arg 1: table containing the userdata containing the unit id. and a string identyfying the attack.
|
||||
* - Arg 2: string
|
||||
* - Ret 1:
|
||||
*/
|
||||
static int impl_unit_attack_get(lua_State *L)
|
||||
{
|
||||
if (!lua_istable(L, 1)) {
|
||||
return luaL_typerror(L, 1, "unit attack");
|
||||
}
|
||||
lua_rawgeti(L, 1, 1);
|
||||
const unit_const_ptr u = luaW_tounit(L, -1);
|
||||
if (!u) {
|
||||
return luaL_argerror(L, 1, "unknown unit");
|
||||
}
|
||||
lua_rawgeti(L, 1, 2);
|
||||
std::string attack_id = luaL_checkstring(L, -1);
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
BOOST_FOREACH(const attack_type& attack, u->attacks())
|
||||
{
|
||||
if(attack.id() == attack_id)
|
||||
{
|
||||
|
||||
return_string_attrib("description", attack.name());
|
||||
return_string_attrib("name", attack.id());
|
||||
return_string_attrib("type", attack.type());
|
||||
return_string_attrib("icon", attack.icon());
|
||||
return_string_attrib("range", attack.range());
|
||||
// "min_range"
|
||||
// "max_range"
|
||||
return_int_attrib("damage", attack.damage());
|
||||
return_int_attrib("number", attack.num_attacks());
|
||||
return_int_attrib("attack_weight", attack.attack_weight());
|
||||
return_int_attrib("defense_weight", attack.defense_weight());
|
||||
//"accuracy"
|
||||
return_int_attrib("movement_used", attack.movement_used());
|
||||
// "parry"
|
||||
return_cfgref_attrib("specials", attack.specials());
|
||||
std::string err_msg = "unknown property of attack: ";
|
||||
err_msg += m;
|
||||
return luaL_argerror(L, 2, err_msg.c_str());
|
||||
}
|
||||
}
|
||||
return luaL_argerror(L, 1, "invalid attack id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a propoerty of a units attack (__index metamethod).
|
||||
* - Arg 1: table containing the userdata containing the unit id. and a string identyfying the attack.
|
||||
* - Arg 2: string
|
||||
* - Ret 1:
|
||||
*/
|
||||
static int impl_unit_attack_set(lua_State *L)
|
||||
{
|
||||
if (!lua_istable(L, 1)) {
|
||||
return luaL_typerror(L, 1, "unit attack");
|
||||
}
|
||||
lua_rawgeti(L, 1, 1);
|
||||
const unit_ptr u = luaW_tounit(L, -1);
|
||||
if (!u) {
|
||||
return luaL_argerror(L, 1, "unknown unit");
|
||||
}
|
||||
lua_rawgeti(L, 1, 2);
|
||||
std::string attack_id = luaL_checkstring(L, -1);
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
BOOST_FOREACH(attack_type& attack, u->attacks())
|
||||
{
|
||||
if(attack.id() == attack_id)
|
||||
{
|
||||
|
||||
modify_tstring_attrib("description", attack.set_name(value));
|
||||
// modify_string_attrib("name", attack.set_id(value));
|
||||
modify_string_attrib("type", attack.set_type(value));
|
||||
modify_string_attrib("icon", attack.set_icon(value));
|
||||
modify_string_attrib("range", attack.set_range(value));
|
||||
// "min_range"
|
||||
// "max_range"
|
||||
modify_int_attrib("damage", attack.set_damage(value));
|
||||
modify_int_attrib("number", attack.set_num_attacks(value));
|
||||
modify_int_attrib("attack_weight", attack.set_attack_weight(value));
|
||||
modify_int_attrib("defense_weight", attack.set_defense_weight(value));
|
||||
//"accuracy"
|
||||
modify_int_attrib("movement_used", attack.set_movement_used(value));
|
||||
// "parry"
|
||||
|
||||
if (strcmp(m, "specials") == 0) { \
|
||||
attack.set_specials(luaW_checkconfig(L, 3));
|
||||
return 0;
|
||||
}
|
||||
return_cfgref_attrib("specials", attack.specials());
|
||||
std::string err_msg = "unknown modifyable property of attack: ";
|
||||
err_msg += m;
|
||||
return luaL_argerror(L, 2, err_msg.c_str());
|
||||
}
|
||||
}
|
||||
return luaL_argerror(L, 1, "invalid attack id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the variable of a unit (__newindex metamethod).
|
||||
@ -3881,6 +4067,31 @@ game_lua_kernel::game_lua_kernel(const config &cfg, CVideo * video, game_state &
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
|
||||
// Create the unit attacks metatable.
|
||||
cmd_log_ << "Adding unit attacks metatable...\n";
|
||||
|
||||
lua_pushlightuserdata(L, uattacksKey);
|
||||
lua_createtable(L, 0, 3);
|
||||
lua_pushcfunction(L, impl_unit_attacks_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pushcfunction(L, impl_unit_attacks_len);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pushstring(L, "unit attacks");
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
|
||||
|
||||
|
||||
lua_pushlightuserdata(L, uattackKey);
|
||||
lua_createtable(L, 0, 3);
|
||||
lua_pushcfunction(L, impl_unit_attack_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pushcfunction(L, impl_unit_attack_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pushstring(L, "unit attack");
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
|
||||
// Create the unit variables metatable.
|
||||
cmd_log_ << "Adding unit variables metatable...\n";
|
||||
|
||||
|
@ -19,9 +19,13 @@ static char const v_executeKey = 0;
|
||||
static char const v_getunitKey = 0;
|
||||
static char const v_unitvarKey = 0;
|
||||
static char const v_ustatusKey = 0;
|
||||
static char const v_uattacksKey = 0;
|
||||
static char const v_uattackKey = 0;
|
||||
|
||||
|
||||
luatypekey const executeKey = static_cast<void *>(const_cast<char *>(&v_executeKey));
|
||||
luatypekey const getunitKey = static_cast<void *>(const_cast<char *>(&v_getunitKey));
|
||||
luatypekey const unitvarKey = static_cast<void *>(const_cast<char *>(&v_unitvarKey));
|
||||
luatypekey const ustatusKey = static_cast<void *>(const_cast<char *>(&v_ustatusKey));
|
||||
luatypekey const uattacksKey = static_cast<void *>(const_cast<char *>(&v_uattacksKey));
|
||||
luatypekey const uattackKey = static_cast<void *>(const_cast<char *>(&v_uattackKey));
|
||||
|
@ -23,5 +23,7 @@ extern luatypekey const executeKey;
|
||||
extern luatypekey const getunitKey;
|
||||
extern luatypekey const unitvarKey;
|
||||
extern luatypekey const ustatusKey;
|
||||
extern luatypekey const uattacksKey;
|
||||
extern luatypekey const uattackKey;
|
||||
|
||||
#endif
|
||||
|
@ -46,6 +46,23 @@ public:
|
||||
int num_attacks() const { return num_attacks_; }
|
||||
double attack_weight() const { return attack_weight_; }
|
||||
double defense_weight() const { return defense_weight_; }
|
||||
const config specials() const { return specials_; }
|
||||
|
||||
void set_name(const t_string& value) { description_ = value; }
|
||||
// void set_id(const std::string& value) { return id = value; }
|
||||
void set_type(const std::string& value) { type_ = value; }
|
||||
void set_icon(const std::string& value) { icon_ = value; }
|
||||
void set_range(const std::string& value) { range_ = value; }
|
||||
// void set_min_range(int value) { min_range_ = value; }
|
||||
// void set_max_range(int value) { max_range_ = value; }
|
||||
// void set_accuracy(int value) { accuracy_ = value; }
|
||||
// void set_parry(int value) { parry_ = value; }
|
||||
void set_damage(int value) { damage_ = value; }
|
||||
void set_num_attacks(int value) { num_attacks_ = value; }
|
||||
void set_attack_weight(double value) { attack_weight_ = value; }
|
||||
void set_defense_weight(double value) { defense_weight_ = value; }
|
||||
void set_specials(config value) { specials_ = value; }
|
||||
|
||||
|
||||
// In unit_abilities.cpp:
|
||||
|
||||
@ -70,6 +87,7 @@ public:
|
||||
bool describe_modification(const config& cfg,std::string* description);
|
||||
|
||||
int movement_used() const { return movement_used_; }
|
||||
void set_movement_used(int value) { movement_used_ = value; }
|
||||
|
||||
void write(config& cfg) const;
|
||||
inline config to_config() const { config c; write(c); return c; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user