mirror of
https://github.com/XLabsProject/s1x-client.git
synced 2023-08-02 15:02:12 +02:00
Add scripting array support
This commit is contained in:
parent
d04a8fd19e
commit
3957ad2ce9
@ -3,6 +3,114 @@
|
||||
|
||||
namespace scripting::lua
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct array_value
|
||||
{
|
||||
int index;
|
||||
sol::lua_value value{};
|
||||
};
|
||||
|
||||
sol::lua_value entity_to_array(lua_State* state, unsigned int id)
|
||||
{
|
||||
auto table = sol::table::create(state);
|
||||
|
||||
std::unordered_map<std::string, array_value> values;
|
||||
|
||||
const auto offset = 64000 * (id & 3);
|
||||
auto current = game::scr_VarGlob->objectVariableChildren[id].firstChild;
|
||||
|
||||
auto idx = 1;
|
||||
|
||||
for (auto i = offset + current; current; i = offset + current)
|
||||
{
|
||||
const auto var = game::scr_VarGlob->childVariableValue[i];
|
||||
|
||||
if (var.type == game::SCRIPT_NONE)
|
||||
{
|
||||
current = var.nextSibling;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto string_value = (game::scr_string_t)((unsigned __int8)var.name_lo + (var.k.keys.name_hi << 8));
|
||||
const auto* str = game::SL_ConvertToString(string_value);
|
||||
|
||||
std::string key = string_value < 0x40000 && str
|
||||
? str
|
||||
: std::to_string(idx++);
|
||||
|
||||
game::VariableValue variable{};
|
||||
variable.type = var.type;
|
||||
variable.u = var.u.u;
|
||||
|
||||
array_value value;
|
||||
value.index = i;
|
||||
value.value = convert(state, script_value(variable));
|
||||
|
||||
values[key] = value;
|
||||
|
||||
current = var.nextSibling;
|
||||
}
|
||||
|
||||
auto metatable = sol::table::create(state);
|
||||
|
||||
metatable[sol::meta_function::new_index] = [state, values](const sol::table t, const sol::this_state s,
|
||||
const sol::lua_value& key_value, const sol::lua_value& value)
|
||||
{
|
||||
const auto key = key_value.is<int>()
|
||||
? std::to_string(key_value.as<int>())
|
||||
: key_value.as<std::string>();
|
||||
|
||||
if (values.find(key) == values.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto variable = convert(value).get_raw();
|
||||
const auto i = values.at(key).index;
|
||||
|
||||
game::scr_VarGlob->childVariableValue[i].type = (char)variable.type;
|
||||
game::scr_VarGlob->childVariableValue[i].u.u = variable.u;
|
||||
};
|
||||
|
||||
metatable[sol::meta_function::index] = [state, values](const sol::table t, const sol::this_state s,
|
||||
const sol::lua_value& key_value)
|
||||
{
|
||||
const auto key = key_value.is<int>()
|
||||
? std::to_string(key_value.as<int>())
|
||||
: key_value.as<std::string>();
|
||||
|
||||
if (values.find(key) == values.end())
|
||||
{
|
||||
return sol::lua_value{};
|
||||
}
|
||||
|
||||
return values.at(key).value;
|
||||
};
|
||||
|
||||
metatable[sol::meta_function::length] = [values]()
|
||||
{
|
||||
return values.size();
|
||||
};
|
||||
|
||||
table[sol::metatable_key] = metatable;
|
||||
|
||||
table["getkeys"] = [values]()
|
||||
{
|
||||
std::vector<std::string> _keys;
|
||||
|
||||
for (const auto& entry : values)
|
||||
{
|
||||
_keys.push_back(entry.first);
|
||||
}
|
||||
|
||||
return _keys;
|
||||
};
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
||||
|
||||
script_value convert(const sol::lua_value& value)
|
||||
{
|
||||
if (value.is<int>())
|
||||
@ -65,6 +173,11 @@ namespace scripting::lua
|
||||
return {state, value.as<std::string>()};
|
||||
}
|
||||
|
||||
if (value.is<std::vector<script_value>>())
|
||||
{
|
||||
return entity_to_array(state, value.get_raw().u.uintValue);
|
||||
}
|
||||
|
||||
if (value.is<entity>())
|
||||
{
|
||||
return {state, value.as<entity>()};
|
||||
|
@ -189,6 +189,24 @@ namespace scripting
|
||||
return this->get<const char*>();
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Array
|
||||
**************************************************************/
|
||||
|
||||
template <>
|
||||
bool script_value::is<std::vector<script_value>>() const
|
||||
{
|
||||
if (this->get_raw().type != game::SCRIPT_OBJECT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto id = this->get_raw().u.uintValue;
|
||||
const auto type = game::scr_VarGlob->objectVariableValue[id].w.type;
|
||||
|
||||
return type == game::SCRIPT_ARRAY;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Entity
|
||||
**************************************************************/
|
||||
|
@ -214,6 +214,7 @@ namespace game
|
||||
WEAK symbol<jmp_buf> g_script_error{0x14A1917B0, 0x1487FA0C0};
|
||||
WEAK symbol<scr_classStruct_t> g_classMap{0x14080A840, 0x1409BE1B0};
|
||||
|
||||
WEAK symbol<scrVarGlob_t> scr_VarGlob{ 0x149B1D680, 0x148185F80 };
|
||||
WEAK symbol<scrVmPub_t> scr_VmPub{0x14A1938C0, 0x1487FC1C0};
|
||||
|
||||
WEAK symbol<const char*> command_whitelist{0x140808EF0, 0x1409B8DC0};
|
||||
|
Loading…
Reference in New Issue
Block a user