Working variable fields
This commit is contained in:
parent
9d83fc2766
commit
5c2e089404
@ -47,6 +47,8 @@ namespace game
|
||||
int* g_script_error_level;
|
||||
jmp_buf* g_script_error;
|
||||
|
||||
scr_classStruct_t* g_classMap;
|
||||
|
||||
void AddRefToValue(VariableValue* value)
|
||||
{
|
||||
if (value->type == SCRIPT_OBJECT)
|
||||
@ -69,15 +71,42 @@ namespace game
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) unsigned int find_variable_dedicated(unsigned int parentId, unsigned int name)
|
||||
{
|
||||
static DWORD func = 0x4E7ED0;
|
||||
|
||||
__asm
|
||||
{
|
||||
mov eax, name
|
||||
mov ecx, parentId
|
||||
call func
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int FindVariable(const unsigned int parentId, const unsigned int name)
|
||||
{
|
||||
if (is_dedi())
|
||||
{
|
||||
return find_variable_dedicated(parentId, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return reinterpret_cast<unsigned int(*)(unsigned int, unsigned int)> //
|
||||
(SELECT_VALUE(0x4C4E70, 0x5651F0, 0x0))(parentId, name);
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) VariableValue get_entity_field_value_dedicated(unsigned int classnum, int entnum, int _offset)
|
||||
{
|
||||
static DWORD func = 0x4F1400;
|
||||
|
||||
__asm
|
||||
{
|
||||
push _offset
|
||||
push entnum
|
||||
mov ecx, classnum
|
||||
mov eax, 4F1400h
|
||||
call eax
|
||||
call func
|
||||
add esp, 8h
|
||||
retn
|
||||
}
|
||||
@ -150,6 +179,34 @@ namespace game
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) int scr_set_object_field_dedicated(unsigned int classnum, int entnum, int _offset)
|
||||
{
|
||||
static DWORD func = 0x4B15C0;
|
||||
|
||||
__asm
|
||||
{
|
||||
mov ecx, _offset
|
||||
mov eax, entnum
|
||||
push classnum
|
||||
call func
|
||||
add esp, 4h
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
int Scr_SetObjectField(const unsigned int classnum, const int entnum, const int offset)
|
||||
{
|
||||
if (is_dedi())
|
||||
{
|
||||
return scr_set_object_field_dedicated(classnum, entnum, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return reinterpret_cast<int(*)(unsigned int, int, int)> //
|
||||
(SELECT_VALUE(0x42CAD0, 0x52BCC0, 0x0))(classnum, entnum, offset);
|
||||
}
|
||||
}
|
||||
|
||||
const char* SL_ConvertToString(const unsigned int stringValue)
|
||||
{
|
||||
if (!stringValue) return nullptr;
|
||||
@ -228,6 +285,8 @@ namespace game
|
||||
native::g_script_error_level = reinterpret_cast<int*>(SELECT_VALUE(0x1BEFCFC, 0x20B21FC, 0x1F5B058));
|
||||
native::g_script_error = reinterpret_cast<jmp_buf*>(SELECT_VALUE(0x1BF1D18, 0x20B4218, 0x1F5A818));
|
||||
|
||||
native::g_classMap = reinterpret_cast<native::scr_classStruct_t*>(SELECT_VALUE(0x92D140, 0x8B4300, 0x7C0408));
|
||||
|
||||
native::levelEntityId = reinterpret_cast<unsigned int*>(SELECT_VALUE(0x1BCBCA4, 0x208E1A4, 0x1CD873C));
|
||||
}
|
||||
}
|
||||
|
@ -62,8 +62,12 @@ namespace game
|
||||
extern int* g_script_error_level;
|
||||
extern jmp_buf* g_script_error;
|
||||
|
||||
extern scr_classStruct_t* g_classMap;
|
||||
|
||||
void AddRefToValue(VariableValue* value);
|
||||
|
||||
unsigned int FindVariable(unsigned int parentId, unsigned int name);
|
||||
|
||||
VariableValue GetEntityFieldValue(unsigned int classnum, int entnum, int offset);
|
||||
|
||||
void* MT_Alloc(int numBytes, int type);
|
||||
@ -72,6 +76,7 @@ namespace game
|
||||
void Scr_ClearOutParams();
|
||||
scr_entref_t Scr_GetEntityIdRef(unsigned int id);
|
||||
scr_call_t Scr_GetFunc(unsigned int index);
|
||||
int Scr_SetObjectField(unsigned int classnum, int entnum, int offset);
|
||||
|
||||
const char* SL_ConvertToString(unsigned int stringValue);
|
||||
unsigned int SL_GetString(const char* str, unsigned int user);
|
||||
|
@ -412,7 +412,7 @@ namespace game
|
||||
scr_entref_raw raw;
|
||||
};
|
||||
|
||||
typedef void(__cdecl * scr_call_t)(int entref);
|
||||
typedef void (__cdecl * scr_call_t)(int entref);
|
||||
|
||||
enum scriptType_e
|
||||
{
|
||||
@ -422,7 +422,8 @@ namespace game
|
||||
SCRIPT_VECTOR = 4,
|
||||
SCRIPT_FLOAT = 5,
|
||||
SCRIPT_INTEGER = 6,
|
||||
SCRIPT_END = 8, // Custom
|
||||
SCRIPT_END = 8,
|
||||
// Custom
|
||||
};
|
||||
|
||||
struct VariableStackBuffer
|
||||
@ -453,38 +454,46 @@ namespace game
|
||||
scriptType_e type;
|
||||
};
|
||||
|
||||
struct function_stack_t
|
||||
{
|
||||
const char *pos;
|
||||
unsigned int localId;
|
||||
unsigned int localVarCount;
|
||||
VariableValue *top;
|
||||
VariableValue *startTop;
|
||||
struct function_stack_t
|
||||
{
|
||||
const char* pos;
|
||||
unsigned int localId;
|
||||
unsigned int localVarCount;
|
||||
VariableValue* top;
|
||||
VariableValue* startTop;
|
||||
};
|
||||
|
||||
struct function_frame_t
|
||||
{
|
||||
function_stack_t fs;
|
||||
int topType;
|
||||
struct function_frame_t
|
||||
{
|
||||
function_stack_t fs;
|
||||
int topType;
|
||||
};
|
||||
|
||||
struct scrVmPub_t
|
||||
{
|
||||
unsigned int *localVars;
|
||||
VariableValue *maxstack;
|
||||
int function_count;
|
||||
function_frame_t *function_frame;
|
||||
VariableValue *top;
|
||||
struct scrVmPub_t
|
||||
{
|
||||
unsigned int* localVars;
|
||||
VariableValue* maxstack;
|
||||
int function_count;
|
||||
function_frame_t* function_frame;
|
||||
VariableValue* top;
|
||||
/*bool debugCode;
|
||||
bool abort_on_error;
|
||||
bool terminal_error;
|
||||
bool block_execution;*/
|
||||
unsigned int inparamcount;
|
||||
unsigned int outparamcount;
|
||||
unsigned int breakpointOutparamcount;
|
||||
bool showError;
|
||||
function_frame_t function_frame_start[32];
|
||||
VariableValue stack[2048];
|
||||
bool block_execution;*/
|
||||
unsigned int inparamcount;
|
||||
unsigned int outparamcount;
|
||||
unsigned int breakpointOutparamcount;
|
||||
bool showError;
|
||||
function_frame_t function_frame_start[32];
|
||||
VariableValue stack[2048];
|
||||
};
|
||||
|
||||
struct scr_classStruct_t
|
||||
{
|
||||
unsigned __int16 id;
|
||||
unsigned __int16 entArrayId;
|
||||
char charId;
|
||||
const char* name;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,16 @@ void scripting::entity::notify(const std::string& event, const std::vector<chais
|
||||
this->environment_->notify(event, this->get_entity_id(), arguments);
|
||||
}
|
||||
|
||||
void scripting::entity::set(const std::string& field, const chaiscript::Boxed_Value& value)
|
||||
{
|
||||
this->environment_->set_entity_field(field, this->get_entity_id(), value);
|
||||
}
|
||||
|
||||
chaiscript::Boxed_Value scripting::entity::get(const std::string& field)
|
||||
{
|
||||
return this->environment_->get_entity_field(field, this->get_entity_id());
|
||||
}
|
||||
|
||||
scripting::variable::variable(game::native::VariableValue value) : value_(value)
|
||||
{
|
||||
game::native::AddRefToValue(&value);
|
||||
@ -90,6 +100,28 @@ scripting::variable::operator game::native::VariableValue() const
|
||||
return this->value_;
|
||||
}
|
||||
|
||||
scripting::stack_context::stack_context()
|
||||
{
|
||||
this->inparamcount_ = game::native::scr_VmPub->inparamcount;
|
||||
this->outparamcount_ = game::native::scr_VmPub->outparamcount;
|
||||
this->top_ = game::native::scr_VmPub->top;
|
||||
this->maxstack_ = game::native::scr_VmPub->maxstack;
|
||||
|
||||
game::native::scr_VmPub->top = this->stack_;
|
||||
game::native::scr_VmPub->maxstack = &this->stack_[ARRAYSIZE(this->stack_) - 1];
|
||||
game::native::scr_VmPub->inparamcount = 0;
|
||||
game::native::scr_VmPub->outparamcount = 0;
|
||||
}
|
||||
|
||||
scripting::stack_context::~stack_context()
|
||||
{
|
||||
game::native::Scr_ClearOutParams();
|
||||
game::native::scr_VmPub->inparamcount = this->inparamcount_;
|
||||
game::native::scr_VmPub->outparamcount = this->outparamcount_;
|
||||
game::native::scr_VmPub->top = this->top_;
|
||||
game::native::scr_VmPub->maxstack = this->maxstack_;
|
||||
}
|
||||
|
||||
void scripting::post_start()
|
||||
{
|
||||
on_start([this]()
|
||||
@ -158,16 +190,16 @@ void scripting::initialize()
|
||||
|
||||
notification::listen([this](notification::event* event)
|
||||
{
|
||||
std::vector<chaiscript::Boxed_Value> arguments;
|
||||
|
||||
for (const auto& argument : event->arguments)
|
||||
try
|
||||
{
|
||||
arguments.push_back(this->make_boxed(argument));
|
||||
}
|
||||
std::vector<chaiscript::Boxed_Value> arguments;
|
||||
|
||||
for (auto listener = this->event_listeners_.begin(); listener.is_valid(); ++listener)
|
||||
{
|
||||
try
|
||||
for (const auto& argument : event->arguments)
|
||||
{
|
||||
arguments.push_back(this->make_boxed(argument));
|
||||
}
|
||||
|
||||
for (auto listener = this->event_listeners_.begin(); listener.is_valid(); ++listener)
|
||||
{
|
||||
if (listener->event == event->name && listener->entity_id == event->entity_id)
|
||||
{
|
||||
@ -179,11 +211,24 @@ void scripting::initialize()
|
||||
listener->callback(arguments);
|
||||
}
|
||||
}
|
||||
catch (chaiscript::exception::eval_error& e)
|
||||
|
||||
for (auto listener = this->generic_event_listeners_.begin(); listener.is_valid(); ++listener)
|
||||
{
|
||||
throw std::runtime_error(e.pretty_print());
|
||||
if (listener->event == event->name)
|
||||
{
|
||||
if (listener->is_volatile)
|
||||
{
|
||||
this->generic_event_listeners_.remove(listener);
|
||||
}
|
||||
|
||||
listener->callback(entity(this, event->entity_id), arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (chaiscript::exception::eval_error& e)
|
||||
{
|
||||
throw std::runtime_error(e.pretty_print());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -193,6 +238,9 @@ void scripting::initialize_entity()
|
||||
this->chai_->add(chaiscript::constructor<entity()>(), "entity");
|
||||
this->chai_->add(chaiscript::constructor<entity(const entity&)>(), "entity");
|
||||
|
||||
this->chai_->add(chaiscript::fun(&entity::get), "get");
|
||||
this->chai_->add(chaiscript::fun(&entity::set), "set");
|
||||
|
||||
this->chai_->add(chaiscript::fun(&entity::on_notify), "onNotify");
|
||||
this->chai_->add(chaiscript::fun([](const entity& ent, const std::string& event,
|
||||
const std::function<void(const std::vector<chaiscript::Boxed_Value>&)>&
|
||||
@ -206,6 +254,32 @@ void scripting::initialize_entity()
|
||||
return lhs = rhs;
|
||||
}), "=");
|
||||
|
||||
this->chai_->add(chaiscript::fun([this](const std::string& event,
|
||||
const std::function<void(const entity&,
|
||||
const std::vector<chaiscript::Boxed_Value>&)>&
|
||||
callback)
|
||||
{
|
||||
generic_event_listener listener;
|
||||
listener.event = event;
|
||||
listener.is_volatile = false;
|
||||
listener.callback = callback;
|
||||
|
||||
this->generic_event_listeners_.add(listener);
|
||||
}), "onNotify");
|
||||
|
||||
this->chai_->add(chaiscript::fun([this](const std::string& event,
|
||||
const std::function<void(const entity&,
|
||||
const std::vector<chaiscript::Boxed_Value>&)>&
|
||||
callback, const bool is_volatile)
|
||||
{
|
||||
generic_event_listener listener;
|
||||
listener.event = event;
|
||||
listener.is_volatile = is_volatile;
|
||||
listener.callback = callback;
|
||||
|
||||
this->generic_event_listeners_.add(listener);
|
||||
}), "onNotify");
|
||||
|
||||
// Notification
|
||||
this->chai_->add(chaiscript::fun(&entity::notify), "vectorNotify");
|
||||
this->chai_->add(chaiscript::fun([](const entity& ent, const std::string& event)
|
||||
@ -469,45 +543,92 @@ void scripting::stop_execution()
|
||||
}
|
||||
}
|
||||
|
||||
int scripting::get_field_id(const int classnum, const std::string& field) const
|
||||
int scripting::get_field_id(const int classnum, const std::string& field)
|
||||
{
|
||||
switch (classnum)
|
||||
const auto field_name = utils::string::to_lower(field);
|
||||
const auto class_id = game::native::g_classMap[classnum].id;
|
||||
const auto field_str = game::native::SL_GetString(field_name.data(), 1);
|
||||
const auto _ = gsl::finally([field_str]()
|
||||
{
|
||||
case 0: // Entity
|
||||
case 1: // HudElem
|
||||
case 2: // Pathnode
|
||||
case 3: // VehPathNode
|
||||
case 4: // VehTrackSegment
|
||||
case 6: // PIPElem
|
||||
game::native::VariableUnion u{};
|
||||
u.stringValue = field_str;
|
||||
game::native::RemoveRefToValue(game::native::SCRIPT_STRING, u);
|
||||
});
|
||||
|
||||
default:
|
||||
return -1;
|
||||
const auto offset = game::native::FindVariable(class_id, field_str);
|
||||
if (offset)
|
||||
{
|
||||
const auto index = 4 * (offset + 0xC800 * (class_id & 1));
|
||||
return PINT(SELECT_VALUE(0x1A3BC80, 0x1EFE180, 0x1DC8800))[index];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void scripting::set_entity_field(const std::string& field, const unsigned int entity_id,
|
||||
const chaiscript::Boxed_Value& value)
|
||||
{
|
||||
const auto entref = game::native::Scr_GetEntityIdRef(entity_id);
|
||||
const int id = get_field_id(entref.raw.classnum, field);
|
||||
|
||||
if (id != -1)
|
||||
{
|
||||
stack_context _;
|
||||
this->push_param(value);
|
||||
|
||||
game::native::scr_VmPub->outparamcount = game::native::scr_VmPub->inparamcount;
|
||||
game::native::scr_VmPub->inparamcount = 0;
|
||||
|
||||
if (!set_entity_field_safe(entref, id))
|
||||
{
|
||||
throw std::runtime_error("Failed to set value for field '" + field + "'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->entity_fields_[entity_id][field] = value;
|
||||
}
|
||||
}
|
||||
|
||||
chaiscript::Boxed_Value scripting::get_entity_field(const std::string& field, const unsigned int entity_id)
|
||||
{
|
||||
const auto entref = game::native::Scr_GetEntityIdRef(entity_id);
|
||||
const auto id = this->get_field_id(entref.raw.classnum, field);
|
||||
|
||||
if (id != -1)
|
||||
{
|
||||
stack_context _;
|
||||
|
||||
game::native::VariableValue value{};
|
||||
if (!get_entity_field_safe(entref, id, &value))
|
||||
{
|
||||
throw std::runtime_error("Failed to get value for field '" + field + "'");
|
||||
}
|
||||
|
||||
const auto $ = gsl::finally([value]()
|
||||
{
|
||||
game::native::RemoveRefToValue(value.type, value.u);
|
||||
});
|
||||
|
||||
return this->make_boxed(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& map = this->entity_fields_[entity_id];
|
||||
const auto value = map.find(field);
|
||||
if (value != map.end())
|
||||
{
|
||||
return value->second;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void scripting::notify(const std::string& event, const unsigned int entity_id,
|
||||
std::vector<chaiscript::Boxed_Value> arguments)
|
||||
{
|
||||
|
||||
const auto old_args = game::native::scr_VmPub->inparamcount;
|
||||
const auto old_params = game::native::scr_VmPub->outparamcount;
|
||||
const auto old_stack_top = game::native::scr_VmPub->top;
|
||||
const auto old_stack_end = game::native::scr_VmPub->maxstack;
|
||||
|
||||
game::native::VariableValue stack[512];
|
||||
game::native::scr_VmPub->top = stack;
|
||||
game::native::scr_VmPub->maxstack = &stack[ARRAYSIZE(stack) - 1];
|
||||
game::native::scr_VmPub->inparamcount = 0;
|
||||
game::native::scr_VmPub->outparamcount = 0;
|
||||
|
||||
const auto cleanup = gsl::finally([=]()
|
||||
{
|
||||
game::native::Scr_ClearOutParams();
|
||||
game::native::scr_VmPub->inparamcount = old_args;
|
||||
game::native::scr_VmPub->outparamcount = old_params;
|
||||
game::native::scr_VmPub->top = old_stack_top;
|
||||
game::native::scr_VmPub->maxstack = old_stack_end;
|
||||
});
|
||||
stack_context _;
|
||||
|
||||
std::reverse(arguments.begin(), arguments.end());
|
||||
for (const auto& argument : arguments)
|
||||
@ -534,25 +655,7 @@ chaiscript::Boxed_Value scripting::call(const std::string& function, const unsig
|
||||
|
||||
const auto function_ptr = game::native::Scr_GetFunc(function_index);
|
||||
|
||||
const auto old_args = game::native::scr_VmPub->inparamcount;
|
||||
const auto old_params = game::native::scr_VmPub->outparamcount;
|
||||
const auto old_stack_top = game::native::scr_VmPub->top;
|
||||
const auto old_stack_end = game::native::scr_VmPub->maxstack;
|
||||
|
||||
game::native::VariableValue stack[512];
|
||||
game::native::scr_VmPub->top = stack;
|
||||
game::native::scr_VmPub->maxstack = &stack[ARRAYSIZE(stack) - 1];
|
||||
game::native::scr_VmPub->inparamcount = 0;
|
||||
game::native::scr_VmPub->outparamcount = 0;
|
||||
|
||||
const auto cleanup = gsl::finally([=]()
|
||||
{
|
||||
game::native::Scr_ClearOutParams();
|
||||
game::native::scr_VmPub->inparamcount = old_args;
|
||||
game::native::scr_VmPub->outparamcount = old_params;
|
||||
game::native::scr_VmPub->top = old_stack_top;
|
||||
game::native::scr_VmPub->maxstack = old_stack_end;
|
||||
});
|
||||
stack_context _;
|
||||
|
||||
std::reverse(arguments.begin(), arguments.end());
|
||||
for (const auto& argument : arguments)
|
||||
@ -589,6 +692,38 @@ bool scripting::call_safe(const game::native::scr_call_t function, const game::n
|
||||
*game::native::g_script_error_level -= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool scripting::set_entity_field_safe(game::native::scr_entref_t entref, int offset)
|
||||
{
|
||||
*game::native::g_script_error_level += 1;
|
||||
if (setjmp(game::native::g_script_error[*game::native::g_script_error_level]))
|
||||
{
|
||||
*game::native::g_script_error_level -= 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
game::native::Scr_SetObjectField(entref.raw.classnum, entref.raw.entnum, offset);
|
||||
|
||||
*game::native::g_script_error_level -= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool scripting::get_entity_field_safe(game::native::scr_entref_t entref, int offset, game::native::VariableValue* value)
|
||||
{
|
||||
*game::native::g_script_error_level += 1;
|
||||
if (setjmp(game::native::g_script_error[*game::native::g_script_error_level]))
|
||||
{
|
||||
value->type = game::native::SCRIPT_NONE;
|
||||
value->u.intValue = 0;
|
||||
*game::native::g_script_error_level -= 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
*value = game::native::GetEntityFieldValue(entref.raw.classnum, entref.raw.entnum, offset);
|
||||
|
||||
*game::native::g_script_error_level -= 1;
|
||||
return true;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
int scripting::find_function_index(const std::string& function, const bool prefer_global)
|
||||
@ -682,7 +817,7 @@ void scripting::push_param(const chaiscript::Boxed_Value& value) const
|
||||
throw std::runtime_error("Invalid vector length. Size must be exactly 3");
|
||||
}
|
||||
|
||||
const auto unbox_float = [&real_value, this](size_t index) -> float
|
||||
const auto unbox_float = [&real_value, this](const size_t index) -> float
|
||||
{
|
||||
const auto value = real_value[index];
|
||||
if (value.get_type_info() == typeid(float))
|
||||
|
@ -25,6 +25,9 @@ public:
|
||||
chaiscript::Boxed_Value call(const std::string& function, const std::vector<chaiscript::Boxed_Value>& arguments) const;
|
||||
void notify(const std::string& event, const std::vector<chaiscript::Boxed_Value>& arguments) const;
|
||||
|
||||
void set(const std::string& field, const chaiscript::Boxed_Value& value);
|
||||
chaiscript::Boxed_Value get(const std::string& field);
|
||||
|
||||
private:
|
||||
scripting* environment_;
|
||||
unsigned int entity_id_;
|
||||
@ -51,6 +54,14 @@ public:
|
||||
bool is_volatile = false;
|
||||
};
|
||||
|
||||
class generic_event_listener final
|
||||
{
|
||||
public:
|
||||
std::string event = {};
|
||||
std::function<void(const entity&, const std::vector<chaiscript::Boxed_Value>&)> callback = {};
|
||||
bool is_volatile = false;
|
||||
};
|
||||
|
||||
void post_start() override;
|
||||
void post_load() override;
|
||||
void pre_destroy() override;
|
||||
@ -61,8 +72,26 @@ public:
|
||||
static void propagate_error(const std::exception& e);
|
||||
|
||||
private:
|
||||
class stack_context final
|
||||
{
|
||||
public:
|
||||
stack_context();
|
||||
~stack_context();
|
||||
|
||||
private:
|
||||
game::native::VariableValue stack_[512]{};
|
||||
|
||||
game::native::VariableValue *maxstack_;
|
||||
game::native::VariableValue *top_;
|
||||
unsigned int inparamcount_;
|
||||
unsigned int outparamcount_;
|
||||
};
|
||||
|
||||
std::unique_ptr<chaiscript::ChaiScript> chai_;
|
||||
utils::chain<event_listener> event_listeners_;
|
||||
utils::chain<generic_event_listener> generic_event_listeners_;
|
||||
|
||||
std::unordered_map<unsigned int, std::unordered_map<std::string, chaiscript::Boxed_Value>> entity_fields_;
|
||||
|
||||
void add_event_listener(const event_listener& listener);
|
||||
|
||||
@ -82,7 +111,12 @@ private:
|
||||
static void start_execution();
|
||||
static void stop_execution();
|
||||
|
||||
int get_field_id(int classnum, const std::string& field) const;
|
||||
int get_field_id(int classnum, const std::string& field);
|
||||
void set_entity_field(const std::string& field, unsigned int entity_id, const chaiscript::Boxed_Value& value);
|
||||
chaiscript::Boxed_Value get_entity_field(const std::string& field, unsigned int entity_id);
|
||||
|
||||
static bool set_entity_field_safe(game::native::scr_entref_t entref, int offset);
|
||||
static bool get_entity_field_safe(game::native::scr_entref_t entref, int offset, game::native::VariableValue* value);
|
||||
|
||||
void notify(const std::string& event, unsigned int entity_id, std::vector<chaiscript::Boxed_Value> arguments);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user