Lua API: Add __dir metamethod to unit variables and unit statuses

This commit is contained in:
Celtic Minstrel 2024-09-10 22:38:34 -04:00 committed by Celtic Minstrel
parent d4278fa1be
commit c32ae8146e
3 changed files with 72 additions and 0 deletions

View File

@ -832,6 +832,32 @@ static int impl_unit_status_set(lua_State *L)
return 0;
}
/**
* List statuses on a unit (__dir metamethod)
* This returns all known statuses (regardless of state) plus any currently set to true.
*/
static int impl_unit_status_dir(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaW_type_error(L, 1, "unit status");
}
lua_rawgeti(L, 1, 1);
unit* u = luaW_tounit(L, -1);
if(!u) {
return luaL_argerror(L, 1, "unknown unit");
}
std::vector<std::string> states;
states.reserve(unit::NUMBER_OF_STATES);
for(unit::state_t s = unit::STATE_SLOWED; s < unit::NUMBER_OF_STATES; s = unit::state_t(s + 1)) {
states.push_back(unit::get_known_boolean_state_name(s));
}
for(auto s : u->get_states()) {
states.push_back(s);
}
lua_push(L, states);
return 1;
}
/**
* Gets the variable of a unit (__index metamethod).
* - Arg 1: table containing the userdata containing the unit id.
@ -886,6 +912,32 @@ static int impl_unit_variables_set(lua_State *L)
return 0;
}
/**
* List variables on a unit (__dir metamethod)
*/
static int impl_unit_variables_dir(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaW_type_error(L, 1, "unit variables");
}
lua_rawgeti(L, 1, 1);
unit* u = luaW_tounit(L, -1);
if(!u) {
return luaL_argerror(L, 2, "unknown unit");
}
config& vars = u->variables();
std::vector<std::string> variables;
variables.reserve(vars.attribute_count() + vars.all_children_count());
for(const auto& attr : vars.attribute_range()) {
variables.push_back(attr.first);
}
for(auto attr : vars.all_children_range()) {
variables.push_back(attr.key);
}
lua_push(L, variables);
return 1;
}
namespace lua_units {
std::string register_metatables(lua_State* L)
{
@ -918,6 +970,8 @@ namespace lua_units {
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, impl_unit_status_set);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, impl_unit_status_dir);
lua_setfield(L, -2, "__dir");
lua_pushstring(L, "unit status");
lua_setfield(L, -2, "__metatable");
@ -929,6 +983,8 @@ namespace lua_units {
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, impl_unit_variables_set);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, impl_unit_variables_dir);
lua_setfield(L, -2, "__dir");
lua_pushstring(L, "unit variables");
lua_setfield(L, -2, "__metatable");

View File

@ -1357,6 +1357,16 @@ unit::state_t unit::get_known_boolean_state_id(const std::string& state)
return STATE_UNKNOWN;
}
std::string unit::get_known_boolean_state_name(state_t state)
{
for(const auto& p : known_boolean_state_names_) {
if(p.second == state) {
return p.first;
}
}
return "";
}
std::map<std::string, unit::state_t> unit::known_boolean_state_names_ {
{"slowed", STATE_SLOWED},
{"poisoned", STATE_POISONED},

View File

@ -889,6 +889,12 @@ public:
*/
static state_t get_known_boolean_state_id(const std::string& state);
/**
* Convert a built-in status effect ID to a string status effect ID
* @returns the string representing the status, or an empty string for STATE_UNKNOWN
*/
static std::string get_known_boolean_state_name(state_t state);
/**
* Check if the unit has been poisoned
* @returns true if it's poisoned