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);
|
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;
|
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)
|
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>();
|
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_entity_fields(const entity& entity);
|
||||||
void clear_custom_fields();
|
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)
|
script_function find_function(const std::string& name, const bool prefer_global)
|
||||||
{
|
{
|
||||||
const auto index = find_function_index(name, 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> method_map;
|
||||||
extern std::unordered_map<std::string, unsigned> function_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);
|
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);
|
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));
|
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
|
struct game
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include <stdinc.hpp>
|
#include <stdinc.hpp>
|
||||||
#include "value_conversion.hpp"
|
#include "value_conversion.hpp"
|
||||||
|
#include "../functions.hpp"
|
||||||
|
#include "../execution.hpp"
|
||||||
|
|
||||||
namespace scripting::lua
|
namespace scripting::lua
|
||||||
{
|
{
|
||||||
@ -18,7 +20,7 @@ namespace scripting::lua
|
|||||||
|
|
||||||
std::unordered_map<std::string, array_value> values;
|
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 current = game::scr_VarGlob->objectVariableChildren[id].firstChild;
|
||||||
auto idx = 1;
|
auto idx = 1;
|
||||||
@ -137,6 +139,89 @@ namespace scripting::lua
|
|||||||
|
|
||||||
return script_value(variable);
|
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)
|
script_value convert(const sol::lua_value& value)
|
||||||
@ -206,11 +291,21 @@ namespace scripting::lua
|
|||||||
return {state, value.as<std::string>()};
|
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>>())
|
if (value.is<std::vector<script_value>>())
|
||||||
{
|
{
|
||||||
return entity_to_array(state, value.get_raw().u.uintValue);
|
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>())
|
if (value.is<entity>())
|
||||||
{
|
{
|
||||||
return {state, value.as<entity>()};
|
return {state, value.as<entity>()};
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
namespace scripting::lua
|
namespace scripting::lua
|
||||||
{
|
{
|
||||||
|
sol::lua_value entity_to_struct(lua_State* state, unsigned int parent_id);
|
||||||
|
|
||||||
script_value convert(const sol::lua_value& value);
|
script_value convert(const sol::lua_value& value);
|
||||||
sol::lua_value convert(lua_State* state, const script_value& value);
|
sol::lua_value convert(lua_State* state, const script_value& value);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "script_value.hpp"
|
#include "script_value.hpp"
|
||||||
#include "entity.hpp"
|
#include "entity.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace scripting
|
namespace scripting
|
||||||
{
|
{
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
@ -207,6 +206,34 @@ namespace scripting
|
|||||||
return type == game::SCRIPT_ARRAY;
|
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
|
* Entity
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
@ -611,7 +611,9 @@ namespace game
|
|||||||
SCRIPT_FLOAT = 5,
|
SCRIPT_FLOAT = 5,
|
||||||
SCRIPT_INTEGER = 6,
|
SCRIPT_INTEGER = 6,
|
||||||
SCRIPT_END = 8,
|
SCRIPT_END = 8,
|
||||||
SCRIPT_ARRAY = 22
|
SCRIPT_FUNCTION = 9,
|
||||||
|
SCRIPT_STRUCT = 19,
|
||||||
|
SCRIPT_ARRAY = 22,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariableStackBuffer
|
struct VariableStackBuffer
|
||||||
|
@ -7,7 +7,10 @@ namespace game
|
|||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
WEAK symbol<void(int type, VariableUnion u)> AddRefToValue{0x5C0EB0};
|
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(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};
|
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<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<unsigned int(int entnum, unsigned int classnum)> FindEntityId{0x5C1C50};
|
||||||
WEAK symbol<void(VariableValue* result, unsigned int classnum, int entnum, int offset)> GetEntityFieldValue{0x5C6100};
|
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<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<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,
|
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};
|
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,
|
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 <csetjmp>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#ifdef max
|
#ifdef max
|
||||||
#undef max
|
#undef max
|
||||||
|
Loading…
Reference in New Issue
Block a user