Script struct & function support + refactor function list
This commit is contained in:
parent
c114cfc81e
commit
7568a91be9
@ -103,6 +103,25 @@ namespace scripting
|
||||
return call_function(name, arguments);
|
||||
}
|
||||
|
||||
script_value exec_ent_thread(const entity& entity, const char* pos, const std::vector<script_value>& arguments)
|
||||
{
|
||||
const auto id = entity.get_entity_id();
|
||||
|
||||
stack_isolation _;
|
||||
for (auto i = arguments.rbegin(); i != arguments.rend(); ++i)
|
||||
{
|
||||
scripting::push_value(*i);
|
||||
}
|
||||
|
||||
game::AddRefToObject(id);
|
||||
|
||||
const auto local_id = game::AllocThread(id);
|
||||
const auto result = game::VM_Execute(local_id, pos, (unsigned int)arguments.size());
|
||||
game::RemoveRefToObject(result);
|
||||
|
||||
return get_return_value();
|
||||
}
|
||||
|
||||
static std::unordered_map<unsigned int, std::unordered_map<std::string, script_value>> custom_fields;
|
||||
|
||||
script_value get_custom_field(const entity& entity, const std::string& field)
|
||||
|
@ -21,6 +21,8 @@ namespace scripting
|
||||
return call<script_value>(name, arguments).as<T>();
|
||||
}
|
||||
|
||||
script_value exec_ent_thread(const entity& entity, const char* pos, const std::vector<script_value>& arguments);
|
||||
|
||||
void clear_entity_fields(const entity& entity);
|
||||
void clear_custom_fields();
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -71,6 +71,18 @@ namespace scripting
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int find_token_id(const std::string& name)
|
||||
{
|
||||
const auto result = token_map.find(name);
|
||||
|
||||
if (result != token_map.end())
|
||||
{
|
||||
return result->second;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
script_function find_function(const std::string& name, const bool prefer_global)
|
||||
{
|
||||
const auto index = find_function_index(name, prefer_global);
|
||||
|
@ -5,8 +5,10 @@ namespace scripting
|
||||
{
|
||||
extern std::unordered_map<std::string, unsigned> method_map;
|
||||
extern std::unordered_map<std::string, unsigned> function_map;
|
||||
extern std::unordered_map<std::string, unsigned> token_map;
|
||||
|
||||
using script_function = void(*)(game::scr_entref_t);
|
||||
|
||||
unsigned int find_token_id(const std::string& name);
|
||||
script_function find_function(const std::string& name, const bool prefer_global);
|
||||
}
|
||||
|
@ -300,6 +300,18 @@ namespace scripting::lua
|
||||
return convert(s, entity.get(field));
|
||||
};
|
||||
|
||||
entity_type["struct"] = sol::property([](const entity& entity, const sol::this_state s)
|
||||
{
|
||||
const auto id = entity.get_entity_id();
|
||||
return scripting::lua::entity_to_struct(s, id);
|
||||
});
|
||||
|
||||
entity_type["getstruct"] = [](const entity& entity, const sol::this_state s)
|
||||
{
|
||||
const auto id = entity.get_entity_id();
|
||||
return scripting::lua::entity_to_struct(s, id);
|
||||
};
|
||||
|
||||
struct game
|
||||
{
|
||||
};
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "value_conversion.hpp"
|
||||
#include "../functions.hpp"
|
||||
#include "../execution.hpp"
|
||||
|
||||
namespace scripting::lua
|
||||
{
|
||||
@ -18,7 +20,7 @@ namespace scripting::lua
|
||||
|
||||
std::unordered_map<std::string, array_value> values;
|
||||
|
||||
const auto offset = 40960 * (id & 3);
|
||||
const auto offset = 0xA000 * (id & 3);
|
||||
|
||||
auto current = game::scr_VarGlob->objectVariableChildren[id].firstChild;
|
||||
auto idx = 1;
|
||||
@ -137,6 +139,89 @@ namespace scripting::lua
|
||||
|
||||
return script_value(variable);
|
||||
}
|
||||
|
||||
sol::lua_value convert_function(lua_State* state, const char* pos)
|
||||
{
|
||||
return [pos](const entity& entity, const sol::this_state s, sol::variadic_args va)
|
||||
{
|
||||
std::vector<script_value> arguments{};
|
||||
|
||||
for (auto arg : va)
|
||||
{
|
||||
arguments.push_back(convert({s, arg}));
|
||||
}
|
||||
|
||||
return convert(s, scripting::exec_ent_thread(entity, pos, arguments));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
sol::lua_value entity_to_struct(lua_State* state, unsigned int parent_id)
|
||||
{
|
||||
auto table = sol::table::create(state);
|
||||
auto metatable = sol::table::create(state);
|
||||
|
||||
const auto offset = 0xA000 * (parent_id & 3);
|
||||
|
||||
metatable[sol::meta_function::new_index] = [offset, parent_id](const sol::table t, const sol::this_state s,
|
||||
const sol::lua_value& field, const sol::lua_value& value)
|
||||
{
|
||||
const auto id = field.is<std::string>()
|
||||
? scripting::find_token_id(field.as<std::string>())
|
||||
: field.as<int>();
|
||||
|
||||
if (!id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto variable_id = game::FindVariable(parent_id, id);
|
||||
if (!variable_id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto variable = &game::scr_VarGlob->childVariableValue[variable_id + offset];
|
||||
|
||||
const auto new_variable = convert({ s, value }).get_raw();
|
||||
|
||||
game::AddRefToValue(new_variable.type, new_variable.u);
|
||||
game::RemoveRefToValue(variable->type, variable->u.u);
|
||||
|
||||
variable->type = (char)new_variable.type;
|
||||
variable->u.u = new_variable.u;
|
||||
};
|
||||
|
||||
metatable[sol::meta_function::index] = [offset, parent_id](const sol::table t, const sol::this_state s,
|
||||
const sol::lua_value& field)
|
||||
{
|
||||
const auto id = field.is<std::string>()
|
||||
? scripting::find_token_id(field.as<std::string>())
|
||||
: field.as<int>();
|
||||
|
||||
if (!id)
|
||||
{
|
||||
return sol::lua_value{s, sol::lua_nil};
|
||||
}
|
||||
|
||||
const auto variable_id = game::FindVariable(parent_id, id);
|
||||
if (!variable_id)
|
||||
{
|
||||
return sol::lua_value{s, sol::lua_nil};
|
||||
}
|
||||
|
||||
const auto variable = game::scr_VarGlob->childVariableValue[variable_id + offset];
|
||||
|
||||
game::VariableValue result{};
|
||||
result.u = variable.u.u;
|
||||
result.type = (game::scriptType_e)variable.type;
|
||||
|
||||
return convert(s, result);
|
||||
};
|
||||
|
||||
table[sol::metatable_key] = metatable;
|
||||
|
||||
return {state, table};
|
||||
}
|
||||
|
||||
script_value convert(const sol::lua_value& value)
|
||||
@ -206,11 +291,21 @@ namespace scripting::lua
|
||||
return {state, value.as<std::string>()};
|
||||
}
|
||||
|
||||
if (value.is<std::map<std::string, script_value>>())
|
||||
{
|
||||
return entity_to_struct(state, value.get_raw().u.uintValue);
|
||||
}
|
||||
|
||||
if (value.is<std::vector<script_value>>())
|
||||
{
|
||||
return entity_to_array(state, value.get_raw().u.uintValue);
|
||||
}
|
||||
|
||||
if (value.is<std::function<void()>>())
|
||||
{
|
||||
return convert_function(state, value.get_raw().u.codePosValue);
|
||||
}
|
||||
|
||||
if (value.is<entity>())
|
||||
{
|
||||
return {state, value.as<entity>()};
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
namespace scripting::lua
|
||||
{
|
||||
sol::lua_value entity_to_struct(lua_State* state, unsigned int parent_id);
|
||||
|
||||
script_value convert(const sol::lua_value& value);
|
||||
sol::lua_value convert(lua_State* state, const script_value& value);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include "script_value.hpp"
|
||||
#include "entity.hpp"
|
||||
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
/***************************************************************
|
||||
@ -207,6 +206,34 @@ namespace scripting
|
||||
return type == game::SCRIPT_ARRAY;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Struct
|
||||
**************************************************************/
|
||||
|
||||
template <>
|
||||
bool script_value::is<std::map<std::string, 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_STRUCT;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Function
|
||||
**************************************************************/
|
||||
|
||||
template <>
|
||||
bool script_value::is<std::function<void()>>() const
|
||||
{
|
||||
return this->get_raw().type == game::SCRIPT_FUNCTION;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Entity
|
||||
**************************************************************/
|
||||
|
@ -611,7 +611,9 @@ namespace game
|
||||
SCRIPT_FLOAT = 5,
|
||||
SCRIPT_INTEGER = 6,
|
||||
SCRIPT_END = 8,
|
||||
SCRIPT_ARRAY = 22
|
||||
SCRIPT_FUNCTION = 9,
|
||||
SCRIPT_STRUCT = 19,
|
||||
SCRIPT_ARRAY = 22,
|
||||
};
|
||||
|
||||
struct VariableStackBuffer
|
||||
|
@ -7,7 +7,10 @@ namespace game
|
||||
// Functions
|
||||
|
||||
WEAK symbol<void(int type, VariableUnion u)> AddRefToValue{0x5C0EB0};
|
||||
WEAK symbol<void(unsigned int id)> AddRefToObject{0x5C0EA0};
|
||||
WEAK symbol<unsigned int(unsigned int id)> AllocThread{0x5C1200};
|
||||
WEAK symbol<void(int type, VariableUnion u)> RemoveRefToValue{0x5C29B0};
|
||||
WEAK symbol<void(unsigned int id)> RemoveRefToObject{0x5C28A0};
|
||||
|
||||
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x59A050};
|
||||
|
||||
@ -44,6 +47,7 @@ namespace game
|
||||
|
||||
WEAK symbol<bool()> CL_IsCgameInitialized{0x3CA0C0};
|
||||
|
||||
WEAK symbol<unsigned int (unsigned int parentId, unsigned int name)> FindVariable{0x5C1D50};
|
||||
WEAK symbol<unsigned int(int entnum, unsigned int classnum)> FindEntityId{0x5C1C50};
|
||||
WEAK symbol<void(VariableValue* result, unsigned int classnum, int entnum, int offset)> GetEntityFieldValue{0x5C6100};
|
||||
|
||||
@ -69,6 +73,8 @@ namespace game
|
||||
WEAK symbol<int(unsigned int classnum, int entnum, int offset)> Scr_SetObjectField{0x512190};
|
||||
WEAK symbol<void(unsigned int id, scr_string_t stringValue, unsigned int paramcount)> Scr_NotifyId{0x5C8240};
|
||||
|
||||
WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x5C8DB0};
|
||||
|
||||
WEAK symbol<void(float x, float y, float width, float height, float s0, float t0, float s1, float t1,
|
||||
float* color, Material* material)> R_AddCmdDrawStretchPic{0x3C9710};
|
||||
WEAK symbol<void(const char* text, int maxChars, Font_s* font, float x, float y, float xScale, float yScale,
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <csetjmp>
|
||||
#include <deque>
|
||||
#include <optional>
|
||||
#include <map>
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
|
Loading…
Reference in New Issue
Block a user