mirror of
https://github.com/fedddddd/iw5-gsc-utils.git
synced 2025-07-09 04:31:53 +00:00
Initial commit
This commit is contained in:
6
src/game/game.cpp
Normal file
6
src/game/game.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include <stdinc.hpp>
|
||||
|
||||
namespace game
|
||||
{
|
||||
|
||||
}
|
34
src/game/game.hpp
Normal file
34
src/game/game.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
namespace game
|
||||
{
|
||||
template <typename T>
|
||||
class symbol
|
||||
{
|
||||
public:
|
||||
symbol(const size_t dedi)
|
||||
: dedi_(reinterpret_cast<T*>(dedi))
|
||||
{
|
||||
}
|
||||
|
||||
T* get() const
|
||||
{
|
||||
return dedi_;
|
||||
}
|
||||
|
||||
operator T* () const
|
||||
{
|
||||
return this->get();
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
return this->get();
|
||||
}
|
||||
|
||||
private:
|
||||
T* dedi_;
|
||||
};
|
||||
}
|
||||
|
||||
#include "symbols.hpp"
|
115
src/game/scripting/entity.cpp
Normal file
115
src/game/scripting/entity.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "entity.hpp"
|
||||
#include "script_value.hpp"
|
||||
#include "execution.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
entity::entity()
|
||||
: entity(0)
|
||||
{
|
||||
}
|
||||
|
||||
entity::entity(const entity& other) : entity(other.entity_id_)
|
||||
{
|
||||
}
|
||||
|
||||
entity::entity(entity&& other) noexcept
|
||||
{
|
||||
this->entity_id_ = other.entity_id_;
|
||||
other.entity_id_ = 0;
|
||||
}
|
||||
|
||||
entity::entity(const unsigned int entity_id)
|
||||
: entity_id_(entity_id)
|
||||
{
|
||||
this->add();
|
||||
}
|
||||
|
||||
entity::~entity()
|
||||
{
|
||||
this->release();
|
||||
}
|
||||
|
||||
entity& entity::operator=(const entity& other)
|
||||
{
|
||||
if (&other != this)
|
||||
{
|
||||
this->release();
|
||||
this->entity_id_ = other.entity_id_;
|
||||
this->add();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
entity& entity::operator=(entity&& other) noexcept
|
||||
{
|
||||
if (&other != this)
|
||||
{
|
||||
this->release();
|
||||
this->entity_id_ = other.entity_id_;
|
||||
other.entity_id_ = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned int entity::get_entity_id() const
|
||||
{
|
||||
return this->entity_id_;
|
||||
}
|
||||
|
||||
game::scr_entref_t entity::get_entity_reference() const
|
||||
{
|
||||
if (!this->entity_id_)
|
||||
{
|
||||
const auto not_null = static_cast<uint16_t>(~0ui16);
|
||||
return game::scr_entref_t{not_null, not_null};
|
||||
}
|
||||
|
||||
return game::Scr_GetEntityIdRef(this->get_entity_id());
|
||||
}
|
||||
|
||||
bool entity::operator==(const entity& other) const noexcept
|
||||
{
|
||||
return this->get_entity_id() == other.get_entity_id();
|
||||
}
|
||||
|
||||
bool entity::operator!=(const entity& other) const noexcept
|
||||
{
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
void entity::add() const
|
||||
{
|
||||
if (this->entity_id_)
|
||||
{
|
||||
game::AddRefToValue(game::SCRIPT_OBJECT, {static_cast<int>(this->entity_id_)});
|
||||
}
|
||||
}
|
||||
|
||||
void entity::release() const
|
||||
{
|
||||
if (this->entity_id_)
|
||||
{
|
||||
game::RemoveRefToValue(game::SCRIPT_OBJECT, {static_cast<int>(this->entity_id_)});
|
||||
}
|
||||
}
|
||||
|
||||
void entity::set(const std::string& field, const script_value& value) const
|
||||
{
|
||||
set_entity_field(*this, field, value);
|
||||
}
|
||||
|
||||
template <>
|
||||
script_value entity::get<script_value>(const std::string& field) const
|
||||
{
|
||||
return get_entity_field(*this, field);
|
||||
}
|
||||
|
||||
script_value entity::call(const std::string& name, const std::vector<script_value>& arguments) const
|
||||
{
|
||||
return call_function(name, *this, arguments);
|
||||
}
|
||||
}
|
49
src/game/scripting/entity.hpp
Normal file
49
src/game/scripting/entity.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include "game/game.hpp"
|
||||
#include "script_value.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
class entity final
|
||||
{
|
||||
public:
|
||||
entity();
|
||||
entity(unsigned int entity_id);
|
||||
|
||||
entity(const entity& other);
|
||||
entity(entity&& other) noexcept;
|
||||
|
||||
~entity();
|
||||
|
||||
entity& operator=(const entity& other);
|
||||
entity& operator=(entity&& other) noexcept;
|
||||
|
||||
void set(const std::string& field, const script_value& value) const;
|
||||
|
||||
template <typename T = script_value>
|
||||
T get(const std::string& field) const;
|
||||
|
||||
script_value call(const std::string& name, const std::vector<script_value>& arguments = {}) const;
|
||||
|
||||
unsigned int get_entity_id() const;
|
||||
game::scr_entref_t get_entity_reference() const;
|
||||
|
||||
bool operator ==(const entity& other) const noexcept;
|
||||
bool operator !=(const entity& other) const noexcept;
|
||||
|
||||
private:
|
||||
unsigned int entity_id_;
|
||||
|
||||
void add() const;
|
||||
void release() const;
|
||||
};
|
||||
|
||||
template <>
|
||||
script_value entity::get(const std::string& field) const;
|
||||
|
||||
template <typename T>
|
||||
T entity::get(const std::string& field) const
|
||||
{
|
||||
return this->get<script_value>(field).as<T>();
|
||||
}
|
||||
}
|
13
src/game/scripting/event.hpp
Normal file
13
src/game/scripting/event.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "script_value.hpp"
|
||||
#include "entity.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
struct event
|
||||
{
|
||||
std::string name;
|
||||
entity entity{};
|
||||
std::vector<script_value> arguments;
|
||||
};
|
||||
}
|
278
src/game/scripting/execution.cpp
Normal file
278
src/game/scripting/execution.cpp
Normal file
@ -0,0 +1,278 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "execution.hpp"
|
||||
#include "safe_execution.hpp"
|
||||
#include "stack_isolation.hpp"
|
||||
#include "event.hpp"
|
||||
|
||||
#include "component/scripting.hpp"
|
||||
#include "component/scheduler.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
namespace
|
||||
{
|
||||
game::VariableValue* allocate_argument()
|
||||
{
|
||||
game::VariableValue* value_ptr = ++game::scr_VmPub->top;
|
||||
++game::scr_VmPub->inparamcount;
|
||||
return value_ptr;
|
||||
}
|
||||
|
||||
script_value get_return_value()
|
||||
{
|
||||
if (game::scr_VmPub->inparamcount == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
game::Scr_ClearOutParams();
|
||||
game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount;
|
||||
game::scr_VmPub->inparamcount = 0;
|
||||
|
||||
return script_value(game::scr_VmPub->top[1 - game::scr_VmPub->outparamcount]);
|
||||
}
|
||||
|
||||
int get_field_id(const int classnum, const std::string& field)
|
||||
{
|
||||
if (scripting::fields_table[classnum].find(field) != scripting::fields_table[classnum].end())
|
||||
{
|
||||
return scripting::fields_table[classnum][field];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void scr_notify_id(int id, unsigned int stringValue, unsigned int paramcount)
|
||||
{
|
||||
if (game::scr_VmPub->outparamcount)
|
||||
{
|
||||
game::Scr_ClearOutParams();
|
||||
}
|
||||
|
||||
auto v6 = game::scr_VmPub->top;
|
||||
auto v7 = game::scr_VmPub->inparamcount - paramcount;
|
||||
auto v8 = &game::scr_VmPub->top[-paramcount];
|
||||
|
||||
if (id)
|
||||
{
|
||||
const auto v9 = v8->type;
|
||||
v8->type = game::scriptType_e::SCRIPT_END;
|
||||
|
||||
game::scr_VmPub->inparamcount = 0;
|
||||
game::VM_Notify(id, stringValue, game::scr_VmPub->top);
|
||||
|
||||
v8->type = v9;
|
||||
v6 = game::scr_VmPub->top;
|
||||
}
|
||||
|
||||
for (; v6 != v8; game::scr_VmPub->top = v6)
|
||||
{
|
||||
game::RemoveRefToValue(v6->type, v6->u);
|
||||
v6 = game::scr_VmPub->top - 1;
|
||||
}
|
||||
|
||||
game::scr_VmPub->inparamcount = v7;
|
||||
}
|
||||
}
|
||||
|
||||
void push_value(const script_value& value)
|
||||
{
|
||||
auto* value_ptr = allocate_argument();
|
||||
*value_ptr = value.get_raw();
|
||||
|
||||
game::AddRefToValue(value_ptr->type, value_ptr->u);
|
||||
}
|
||||
|
||||
void notify(const entity& entity, const std::string& event, const std::vector<script_value>& arguments)
|
||||
{
|
||||
stack_isolation _;
|
||||
for (auto i = arguments.rbegin(); i != arguments.rend(); ++i)
|
||||
{
|
||||
push_value(*i);
|
||||
}
|
||||
|
||||
const auto event_id = game::SL_GetString(event.data(), 0);
|
||||
scr_notify_id(entity.get_entity_id(), event_id, game::scr_VmPub->inparamcount);
|
||||
}
|
||||
|
||||
script_value call_function(const std::string& name, const entity& entity,
|
||||
const std::vector<script_value>& arguments)
|
||||
{
|
||||
const auto entref = entity.get_entity_reference();
|
||||
|
||||
const auto is_method_call = *reinterpret_cast<const int*>(&entref) != -1;
|
||||
const auto function = find_function(name, !is_method_call);
|
||||
if (!function)
|
||||
{
|
||||
throw std::runtime_error("Unknown function '" + name + "'");
|
||||
}
|
||||
|
||||
stack_isolation _;
|
||||
|
||||
for (auto i = arguments.rbegin(); i != arguments.rend(); ++i)
|
||||
{
|
||||
push_value(*i);
|
||||
}
|
||||
|
||||
game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount;
|
||||
game::scr_VmPub->inparamcount = 0;
|
||||
|
||||
if (!safe_execution::call(function, entref))
|
||||
{
|
||||
throw std::runtime_error("Error executing function '" + name + "'");
|
||||
}
|
||||
|
||||
return get_return_value();
|
||||
}
|
||||
|
||||
script_value call_function(const std::string& name, const std::vector<script_value>& arguments)
|
||||
{
|
||||
return call_function(name, entity(), arguments);
|
||||
}
|
||||
|
||||
template <>
|
||||
script_value call(const std::string& name, const std::vector<script_value>& 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();
|
||||
|
||||
for (auto i = arguments.rbegin(); i != arguments.rend(); ++i)
|
||||
{
|
||||
push_value(*i);
|
||||
}
|
||||
|
||||
game::AddReftoObject(id);
|
||||
|
||||
const auto local_id = game::AllocThread(id);
|
||||
const auto result = game::VM_Execute(local_id, pos, arguments.size());
|
||||
|
||||
const auto value = get_return_value();
|
||||
|
||||
game::RemoveRefToValue(game::scr_VmPub->top->type, game::scr_VmPub->top->u);
|
||||
game::scr_VmPub->top->type = (game::scriptType_e)0;
|
||||
|
||||
--game::scr_VmPub->top;
|
||||
--game::scr_VmPub->inparamcount;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
script_value call_script_function(const entity& entity, const std::string& filename,
|
||||
const std::string& function, const std::vector<script_value>& arguments)
|
||||
{
|
||||
if (scripting::script_function_table.find(filename) == scripting::script_function_table.end())
|
||||
{
|
||||
throw std::runtime_error("File '" + filename + "' not found");
|
||||
};
|
||||
|
||||
const auto functions = scripting::script_function_table[filename];
|
||||
|
||||
if (functions.find(function) == functions.end())
|
||||
{
|
||||
throw std::runtime_error("Function '" + function + "' in file '" + filename + "' not found");
|
||||
}
|
||||
|
||||
const auto pos = functions.at(function);
|
||||
|
||||
return exec_ent_thread(entity, pos, arguments);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
auto fields = custom_fields[entity.get_entity_id()];
|
||||
const auto _field = fields.find(field);
|
||||
if (_field != fields.end())
|
||||
{
|
||||
return _field->second;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void set_custom_field(const entity& entity, const std::string& field, const script_value& value)
|
||||
{
|
||||
const auto id = entity.get_entity_id();
|
||||
|
||||
if (custom_fields[id].find(field) != custom_fields[id].end())
|
||||
{
|
||||
custom_fields[id][field] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
custom_fields[id].insert(std::make_pair(field, value));
|
||||
}
|
||||
|
||||
void clear_entity_fields(const entity& entity)
|
||||
{
|
||||
const auto id = entity.get_entity_id();
|
||||
|
||||
if (custom_fields.find(id) != custom_fields.end())
|
||||
{
|
||||
custom_fields[id].clear();
|
||||
}
|
||||
}
|
||||
|
||||
void clear_custom_fields()
|
||||
{
|
||||
custom_fields.clear();
|
||||
}
|
||||
|
||||
void set_entity_field(const entity& entity, const std::string& field, const script_value& value)
|
||||
{
|
||||
const auto entref = entity.get_entity_reference();
|
||||
const int id = get_field_id(entref.classnum, field);
|
||||
|
||||
if (id != -1)
|
||||
{
|
||||
stack_isolation _;
|
||||
push_value(value);
|
||||
|
||||
game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount;
|
||||
game::scr_VmPub->inparamcount = 0;
|
||||
|
||||
if (!safe_execution::set_entity_field(entref, id))
|
||||
{
|
||||
throw std::runtime_error("Failed to set value for field '" + field + "'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
set_custom_field(entity, field, value);
|
||||
}
|
||||
}
|
||||
|
||||
script_value get_entity_field(const entity& entity, const std::string& field)
|
||||
{
|
||||
const auto entref = entity.get_entity_reference();
|
||||
const auto id = get_field_id(entref.classnum, field);
|
||||
|
||||
if (id != -1)
|
||||
{
|
||||
stack_isolation _;
|
||||
|
||||
game::VariableValue value{};
|
||||
if (!safe_execution::get_entity_field(entref, id, &value))
|
||||
{
|
||||
throw std::runtime_error("Failed to get value for field '" + field + "'");
|
||||
}
|
||||
|
||||
const auto __ = gsl::finally([value]()
|
||||
{
|
||||
game::RemoveRefToValue(value.type, value.u);
|
||||
});
|
||||
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_custom_field(entity, field);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
37
src/game/scripting/execution.hpp
Normal file
37
src/game/scripting/execution.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include "game/game.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "script_value.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
void push_value(const script_value& value);
|
||||
|
||||
script_value call_function(const std::string& name, const std::vector<script_value>& arguments);
|
||||
script_value call_function(const std::string& name, const entity& entity,
|
||||
const std::vector<script_value>& arguments);
|
||||
|
||||
template <typename T = script_value>
|
||||
T call(const std::string& name, const std::vector<script_value>& arguments = {});
|
||||
|
||||
template <>
|
||||
script_value call(const std::string& name, const std::vector<script_value>& arguments);
|
||||
|
||||
template <typename T>
|
||||
T call(const std::string& name, const std::vector<script_value>& arguments)
|
||||
{
|
||||
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);
|
||||
script_value call_script_function(const entity& entity, const std::string& filename,
|
||||
const std::string& function, const std::vector<script_value>& arguments);
|
||||
|
||||
void clear_entity_fields(const entity& entity);
|
||||
void clear_custom_fields();
|
||||
|
||||
void set_entity_field(const entity& entity, const std::string& field, const script_value& value);
|
||||
script_value get_entity_field(const entity& entity, const std::string& field);
|
||||
|
||||
void notify(const entity& entity, const std::string& event, const std::vector<script_value>& arguments);
|
||||
}
|
7483
src/game/scripting/function_tables.cpp
Normal file
7483
src/game/scripting/function_tables.cpp
Normal file
File diff suppressed because it is too large
Load Diff
93
src/game/scripting/functions.cpp
Normal file
93
src/game/scripting/functions.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "functions.hpp"
|
||||
|
||||
#include <utils/string.hpp>
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::unordered_map<std::string, unsigned> lowercase_map(
|
||||
const std::unordered_map<std::string, unsigned>& old_map)
|
||||
{
|
||||
std::unordered_map<std::string, unsigned> new_map{};
|
||||
for (auto& entry : old_map)
|
||||
{
|
||||
new_map[utils::string::to_lower(entry.first)] = entry.second;
|
||||
}
|
||||
|
||||
return new_map;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, unsigned>& get_methods()
|
||||
{
|
||||
static auto methods = lowercase_map(method_map);
|
||||
return methods;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, unsigned>& get_functions()
|
||||
{
|
||||
static auto function = lowercase_map(function_map);
|
||||
return function;
|
||||
}
|
||||
|
||||
int find_function_index(const std::string& name, const bool prefer_global)
|
||||
{
|
||||
const auto target = utils::string::to_lower(name);
|
||||
|
||||
const auto& primary_map = prefer_global
|
||||
? get_functions()
|
||||
: get_methods();
|
||||
const auto& secondary_map = !prefer_global
|
||||
? get_functions()
|
||||
: get_methods();
|
||||
|
||||
auto function_entry = primary_map.find(target);
|
||||
if (function_entry != primary_map.end())
|
||||
{
|
||||
return function_entry->second;
|
||||
}
|
||||
|
||||
function_entry = secondary_map.find(target);
|
||||
if (function_entry != secondary_map.end())
|
||||
{
|
||||
return function_entry->second;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
script_function get_function_by_index(const unsigned index)
|
||||
{
|
||||
static const auto function_table = 0x1D6EB34;
|
||||
static const auto method_table = 0x1D4F258;
|
||||
|
||||
if (index < 0x1C7)
|
||||
{
|
||||
return reinterpret_cast<script_function*>(function_table)[index];
|
||||
}
|
||||
|
||||
return reinterpret_cast<script_function*>(method_table)[index];
|
||||
}
|
||||
}
|
||||
|
||||
int find_token_id(const std::string& name)
|
||||
{
|
||||
const auto result = token_map.find(name);
|
||||
|
||||
if (result != token_map.end())
|
||||
{
|
||||
return result->second;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
script_function find_function(const std::string& name, const bool prefer_global)
|
||||
{
|
||||
const auto index = find_function_index(name, prefer_global);
|
||||
if (index < 0) return nullptr;
|
||||
|
||||
return get_function_by_index(index);
|
||||
}
|
||||
}
|
15
src/game/scripting/functions.hpp
Normal file
15
src/game/scripting/functions.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "game/game.hpp"
|
||||
|
||||
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;
|
||||
extern std::unordered_map<unsigned, std::string> file_list;
|
||||
|
||||
using script_function = void(*)(game::scr_entref_t);
|
||||
|
||||
script_function find_function(const std::string& name, const bool prefer_global);
|
||||
int find_token_id(const std::string& name);
|
||||
}
|
74
src/game/scripting/safe_execution.cpp
Normal file
74
src/game/scripting/safe_execution.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "safe_execution.hpp"
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4611)
|
||||
|
||||
namespace scripting::safe_execution
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool execute_with_seh(const script_function function, const game::scr_entref_t& entref)
|
||||
{
|
||||
__try
|
||||
{
|
||||
function(entref);
|
||||
return true;
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool call(const script_function function, const game::scr_entref_t& entref)
|
||||
{
|
||||
*game::g_script_error_level += 1;
|
||||
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level]))
|
||||
{
|
||||
*game::g_script_error_level -= 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto result = execute_with_seh(function, entref);
|
||||
*game::g_script_error_level -= 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool set_entity_field(const game::scr_entref_t& entref, const int offset)
|
||||
{
|
||||
*game::g_script_error_level += 1;
|
||||
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level]))
|
||||
{
|
||||
*game::g_script_error_level -= 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
game::Scr_SetObjectField(entref.classnum, entref.entnum, offset);
|
||||
|
||||
*game::g_script_error_level -= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_entity_field(const game::scr_entref_t& entref, const int offset, game::VariableValue* value)
|
||||
{
|
||||
*game::g_script_error_level += 1;
|
||||
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level]))
|
||||
{
|
||||
value->type = game::SCRIPT_NONE;
|
||||
value->u.intValue = 0;
|
||||
*game::g_script_error_level -= 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto _value = game::GetEntityFieldValue(entref.classnum, entref.entnum, offset);
|
||||
value->type = _value.type;
|
||||
value->u = _value.u;
|
||||
|
||||
*game::g_script_error_level -= 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
10
src/game/scripting/safe_execution.hpp
Normal file
10
src/game/scripting/safe_execution.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "functions.hpp"
|
||||
|
||||
namespace scripting::safe_execution
|
||||
{
|
||||
bool call(script_function function, const game::scr_entref_t& entref);
|
||||
|
||||
bool set_entity_field(const game::scr_entref_t& entref, int offset);
|
||||
bool get_entity_field(const game::scr_entref_t& entref, int offset, game::VariableValue* value);
|
||||
}
|
287
src/game/scripting/script_value.cpp
Normal file
287
src/game/scripting/script_value.cpp
Normal file
@ -0,0 +1,287 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "script_value.hpp"
|
||||
#include "entity.hpp"
|
||||
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
/***************************************************************
|
||||
* Constructors
|
||||
**************************************************************/
|
||||
|
||||
script_value::script_value(const game::VariableValue& value)
|
||||
: value_(value)
|
||||
{
|
||||
}
|
||||
|
||||
script_value::script_value(void* value)
|
||||
{
|
||||
game::VariableValue variable{};
|
||||
variable.type = game::SCRIPT_INTEGER;
|
||||
variable.u.intValue = reinterpret_cast<uintptr_t>(value);
|
||||
|
||||
this->value_ = variable;
|
||||
}
|
||||
|
||||
script_value::script_value(const int value)
|
||||
{
|
||||
game::VariableValue variable{};
|
||||
variable.type = game::SCRIPT_INTEGER;
|
||||
variable.u.intValue = value;
|
||||
|
||||
this->value_ = variable;
|
||||
}
|
||||
|
||||
script_value::script_value(const unsigned int value)
|
||||
{
|
||||
game::VariableValue variable{};
|
||||
variable.type = game::SCRIPT_INTEGER;
|
||||
variable.u.uintValue = value;
|
||||
|
||||
this->value_ = variable;
|
||||
}
|
||||
|
||||
script_value::script_value(const bool value)
|
||||
: script_value(static_cast<unsigned>(value))
|
||||
{
|
||||
}
|
||||
|
||||
script_value::script_value(const float value)
|
||||
{
|
||||
game::VariableValue variable{};
|
||||
variable.type = game::SCRIPT_FLOAT;
|
||||
variable.u.floatValue = value;
|
||||
|
||||
this->value_ = variable;
|
||||
}
|
||||
|
||||
script_value::script_value(const double value)
|
||||
: script_value(static_cast<float>(value))
|
||||
{
|
||||
}
|
||||
|
||||
script_value::script_value(const char* value)
|
||||
{
|
||||
game::VariableValue variable{};
|
||||
variable.type = game::SCRIPT_STRING;
|
||||
variable.u.stringValue = game::SL_GetString(value, 0);
|
||||
|
||||
const auto _ = gsl::finally([&variable]()
|
||||
{
|
||||
game::RemoveRefToValue(variable.type, variable.u);
|
||||
});
|
||||
|
||||
this->value_ = variable;
|
||||
}
|
||||
|
||||
script_value::script_value(const std::string& value)
|
||||
: script_value(value.data())
|
||||
{
|
||||
}
|
||||
|
||||
script_value::script_value(const entity& value)
|
||||
{
|
||||
game::VariableValue variable{};
|
||||
variable.type = game::SCRIPT_OBJECT;
|
||||
variable.u.pointerValue = value.get_entity_id();
|
||||
|
||||
this->value_ = variable;
|
||||
}
|
||||
|
||||
script_value::script_value(const vector& value)
|
||||
{
|
||||
game::VariableValue variable{};
|
||||
variable.type = game::SCRIPT_VECTOR;
|
||||
variable.u.vectorValue = game::Scr_AllocVector(value);
|
||||
|
||||
const auto _ = gsl::finally([&variable]()
|
||||
{
|
||||
game::RemoveRefToValue(variable.type, variable.u);
|
||||
});
|
||||
|
||||
this->value_ = variable;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Integer
|
||||
**************************************************************/
|
||||
|
||||
template <>
|
||||
bool script_value::is<int>() const
|
||||
{
|
||||
return this->get_raw().type == game::SCRIPT_INTEGER;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool script_value::is<unsigned int>() const
|
||||
{
|
||||
return this->is<int>();
|
||||
}
|
||||
|
||||
template <>
|
||||
bool script_value::is<bool>() const
|
||||
{
|
||||
return this->is<int>();
|
||||
}
|
||||
|
||||
template <>
|
||||
int script_value::get() const
|
||||
{
|
||||
return this->get_raw().u.intValue;
|
||||
}
|
||||
|
||||
template <>
|
||||
unsigned int script_value::get() const
|
||||
{
|
||||
return this->get_raw().u.uintValue;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool script_value::get() const
|
||||
{
|
||||
return this->get_raw().u.uintValue != 0;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Float
|
||||
**************************************************************/
|
||||
|
||||
template <>
|
||||
bool script_value::is<float>() const
|
||||
{
|
||||
return this->get_raw().type == game::SCRIPT_FLOAT;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool script_value::is<double>() const
|
||||
{
|
||||
return this->is<float>();
|
||||
}
|
||||
|
||||
template <>
|
||||
float script_value::get() const
|
||||
{
|
||||
return this->get_raw().u.floatValue;
|
||||
}
|
||||
|
||||
template <>
|
||||
double script_value::get() const
|
||||
{
|
||||
return static_cast<double>(this->get_raw().u.floatValue);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* String
|
||||
**************************************************************/
|
||||
|
||||
template <>
|
||||
bool script_value::is<const char*>() const
|
||||
{
|
||||
return this->get_raw().type == game::SCRIPT_STRING;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool script_value::is<std::string>() const
|
||||
{
|
||||
return this->is<const char*>();
|
||||
}
|
||||
|
||||
template <>
|
||||
const char* script_value::get() const
|
||||
{
|
||||
return game::SL_ConvertToString(static_cast<unsigned int>(this->get_raw().u.stringValue));
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string script_value::get() const
|
||||
{
|
||||
return this->get<const char*>();
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Entity
|
||||
**************************************************************/
|
||||
|
||||
template <>
|
||||
bool script_value::is<entity>() const
|
||||
{
|
||||
return this->get_raw().type == game::SCRIPT_OBJECT;
|
||||
}
|
||||
|
||||
template <>
|
||||
entity script_value::get() const
|
||||
{
|
||||
return entity(this->get_raw().u.pointerValue);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* Vector
|
||||
**************************************************************/
|
||||
|
||||
template <>
|
||||
bool script_value::is<vector>() const
|
||||
{
|
||||
return this->get_raw().type == game::SCRIPT_VECTOR;
|
||||
}
|
||||
|
||||
template <>
|
||||
vector script_value::get() const
|
||||
{
|
||||
return this->get_raw().u.vectorValue;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
const game::VariableValue& script_value::get_raw() const
|
||||
{
|
||||
return this->value_.get();
|
||||
}
|
||||
}
|
65
src/game/scripting/script_value.hpp
Normal file
65
src/game/scripting/script_value.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
#include "game/game.hpp"
|
||||
#include "variable_value.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
class entity;
|
||||
|
||||
class script_value
|
||||
{
|
||||
public:
|
||||
script_value() = default;
|
||||
script_value(const game::VariableValue& value);
|
||||
|
||||
script_value(void* value);
|
||||
|
||||
script_value(int value);
|
||||
script_value(unsigned int value);
|
||||
script_value(bool value);
|
||||
|
||||
script_value(float value);
|
||||
script_value(double value);
|
||||
|
||||
script_value(const char* value);
|
||||
script_value(const std::string& value);
|
||||
|
||||
script_value(const entity& value);
|
||||
|
||||
script_value(const vector& value);
|
||||
|
||||
template <typename T>
|
||||
bool is() const;
|
||||
|
||||
template <typename T>
|
||||
T as() const
|
||||
{
|
||||
if (!this->is<T>())
|
||||
{
|
||||
throw std::runtime_error("Invalid type");
|
||||
}
|
||||
|
||||
return get<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* as_ptr()
|
||||
{
|
||||
if (!this->is<int>())
|
||||
{
|
||||
throw std::runtime_error("Invalid type");
|
||||
}
|
||||
|
||||
return reinterpret_cast<T*>(this->get<int>());
|
||||
}
|
||||
|
||||
const game::VariableValue& get_raw() const;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
T get() const;
|
||||
|
||||
variable_value value_{};
|
||||
};
|
||||
}
|
27
src/game/scripting/stack_isolation.cpp
Normal file
27
src/game/scripting/stack_isolation.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "stack_isolation.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
stack_isolation::stack_isolation()
|
||||
{
|
||||
this->in_param_count_ = game::scr_VmPub->inparamcount;
|
||||
this->out_param_count_ = game::scr_VmPub->outparamcount;
|
||||
this->top_ = game::scr_VmPub->top;
|
||||
this->max_stack_ = game::scr_VmPub->maxstack;
|
||||
|
||||
game::scr_VmPub->top = this->stack_;
|
||||
game::scr_VmPub->maxstack = &this->stack_[ARRAYSIZE(this->stack_) - 1];
|
||||
game::scr_VmPub->inparamcount = 0;
|
||||
game::scr_VmPub->outparamcount = 0;
|
||||
}
|
||||
|
||||
stack_isolation::~stack_isolation()
|
||||
{
|
||||
game::Scr_ClearOutParams();
|
||||
game::scr_VmPub->inparamcount = this->in_param_count_;
|
||||
game::scr_VmPub->outparamcount = this->out_param_count_;
|
||||
game::scr_VmPub->top = this->top_;
|
||||
game::scr_VmPub->maxstack = this->max_stack_;
|
||||
}
|
||||
}
|
25
src/game/scripting/stack_isolation.hpp
Normal file
25
src/game/scripting/stack_isolation.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "game/game.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
class stack_isolation final
|
||||
{
|
||||
public:
|
||||
stack_isolation();
|
||||
~stack_isolation();
|
||||
|
||||
stack_isolation(stack_isolation&&) = delete;
|
||||
stack_isolation(const stack_isolation&) = delete;
|
||||
stack_isolation& operator=(stack_isolation&&) = delete;
|
||||
stack_isolation& operator=(const stack_isolation&) = delete;
|
||||
|
||||
private:
|
||||
game::VariableValue stack_[512]{};
|
||||
|
||||
game::VariableValue* max_stack_;
|
||||
game::VariableValue* top_;
|
||||
unsigned int in_param_count_;
|
||||
unsigned int out_param_count_;
|
||||
};
|
||||
}
|
68
src/game/scripting/variable_value.cpp
Normal file
68
src/game/scripting/variable_value.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "variable_value.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
variable_value::variable_value(const game::VariableValue& value)
|
||||
{
|
||||
this->assign(value);
|
||||
}
|
||||
|
||||
variable_value::variable_value(const variable_value& other) noexcept
|
||||
{
|
||||
this->operator=(other);
|
||||
}
|
||||
|
||||
variable_value::variable_value(variable_value&& other) noexcept
|
||||
{
|
||||
this->operator=(std::move(other));
|
||||
}
|
||||
|
||||
variable_value& variable_value::operator=(const variable_value& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
this->release();
|
||||
this->assign(other.value_);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
variable_value& variable_value::operator=(variable_value&& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
this->release();
|
||||
this->value_ = other.value_;
|
||||
other.value_.type = game::SCRIPT_NONE;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
variable_value::~variable_value()
|
||||
{
|
||||
this->release();
|
||||
}
|
||||
|
||||
const game::VariableValue& variable_value::get() const
|
||||
{
|
||||
return this->value_;
|
||||
}
|
||||
|
||||
void variable_value::assign(const game::VariableValue& value)
|
||||
{
|
||||
this->value_ = value;
|
||||
game::AddRefToValue(this->value_.type, this->value_.u);
|
||||
}
|
||||
|
||||
void variable_value::release()
|
||||
{
|
||||
if (this->value_.type != game::SCRIPT_NONE)
|
||||
{
|
||||
game::RemoveRefToValue(this->value_.type, this->value_.u);
|
||||
this->value_.type = game::SCRIPT_NONE;
|
||||
}
|
||||
}
|
||||
}
|
27
src/game/scripting/variable_value.hpp
Normal file
27
src/game/scripting/variable_value.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "game/game.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
class variable_value
|
||||
{
|
||||
public:
|
||||
variable_value() = default;
|
||||
variable_value(const game::VariableValue& value);
|
||||
variable_value(const variable_value& other) noexcept;
|
||||
variable_value(variable_value&& other) noexcept;
|
||||
|
||||
variable_value& operator=(const variable_value& other) noexcept;
|
||||
variable_value& operator=(variable_value&& other) noexcept;
|
||||
|
||||
~variable_value();
|
||||
|
||||
const game::VariableValue& get() const;
|
||||
|
||||
private:
|
||||
void assign(const game::VariableValue& value);
|
||||
void release();
|
||||
|
||||
game::VariableValue value_{{0}, game::SCRIPT_NONE};
|
||||
};
|
||||
}
|
85
src/game/scripting/vector.cpp
Normal file
85
src/game/scripting/vector.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "vector.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
vector::vector(const float* value)
|
||||
{
|
||||
for (auto i = 0; i < 3; ++i)
|
||||
{
|
||||
this->value_[i] = value[i];
|
||||
}
|
||||
}
|
||||
|
||||
vector::vector(const game::vec3_t& value)
|
||||
: vector(&value[0])
|
||||
{
|
||||
}
|
||||
|
||||
vector::vector(const float x, const float y, const float z)
|
||||
{
|
||||
this->value_[0] = x;
|
||||
this->value_[1] = y;
|
||||
this->value_[2] = z;
|
||||
}
|
||||
|
||||
vector::operator game::vec3_t& ()
|
||||
{
|
||||
return this->value_;
|
||||
}
|
||||
|
||||
vector::operator const game::vec3_t& () const
|
||||
{
|
||||
return this->value_;
|
||||
}
|
||||
|
||||
game::vec_t& vector::operator[](const size_t i)
|
||||
{
|
||||
if (i >= 3)
|
||||
{
|
||||
throw std::runtime_error("Out of bounds.");
|
||||
}
|
||||
|
||||
return this->value_[i];
|
||||
}
|
||||
|
||||
const game::vec_t& vector::operator[](const size_t i) const
|
||||
{
|
||||
if (i >= 3)
|
||||
{
|
||||
throw std::runtime_error("Out of bounds.");
|
||||
}
|
||||
|
||||
return this->value_[i];
|
||||
}
|
||||
|
||||
float vector::get_x() const
|
||||
{
|
||||
return this->operator[](0);
|
||||
}
|
||||
|
||||
float vector::get_y() const
|
||||
{
|
||||
return this->operator[](1);
|
||||
}
|
||||
|
||||
float vector::get_z() const
|
||||
{
|
||||
return this->operator[](2);
|
||||
}
|
||||
|
||||
void vector::set_x(const float value)
|
||||
{
|
||||
this->operator[](0) = value;
|
||||
}
|
||||
|
||||
void vector::set_y(const float value)
|
||||
{
|
||||
this->operator[](1) = value;
|
||||
}
|
||||
|
||||
void vector::set_z(const float value)
|
||||
{
|
||||
this->operator[](2) = value;
|
||||
}
|
||||
}
|
31
src/game/scripting/vector.hpp
Normal file
31
src/game/scripting/vector.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "game/game.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
class vector final
|
||||
{
|
||||
public:
|
||||
vector() = default;
|
||||
vector(const float* value);
|
||||
vector(const game::vec3_t& value);
|
||||
vector(float x, float y, float z);
|
||||
|
||||
operator game::vec3_t& ();
|
||||
operator const game::vec3_t& () const;
|
||||
|
||||
game::vec_t& operator[](size_t i);
|
||||
const game::vec_t& operator[](size_t i) const;
|
||||
|
||||
float get_x() const;
|
||||
float get_y() const;
|
||||
float get_z() const;
|
||||
|
||||
void set_x(float value);
|
||||
void set_y(float value);
|
||||
void set_z(float value);
|
||||
|
||||
private:
|
||||
game::vec3_t value_{ 0 };
|
||||
};
|
||||
}
|
301
src/game/structs.hpp
Normal file
301
src/game/structs.hpp
Normal file
@ -0,0 +1,301 @@
|
||||
#pragma once
|
||||
|
||||
namespace game
|
||||
{
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4];
|
||||
|
||||
struct cmd_function_t
|
||||
{
|
||||
cmd_function_t* next;
|
||||
const char* name;
|
||||
const char* autoCompleteDir;
|
||||
const char* autoCompleteExt;
|
||||
void(__cdecl* function)();
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct msg_t
|
||||
{
|
||||
int overflowed;
|
||||
int readOnly;
|
||||
char* data;
|
||||
char* splitData;
|
||||
int maxsize;
|
||||
int cursize;
|
||||
int splitSize;
|
||||
int readcount;
|
||||
int bit;
|
||||
int lastEntityRef;
|
||||
};
|
||||
|
||||
struct XZoneInfo
|
||||
{
|
||||
const char* name;
|
||||
int allocFlags;
|
||||
int freeFlags;
|
||||
};
|
||||
|
||||
struct scr_entref_t
|
||||
{
|
||||
unsigned __int16 entnum;
|
||||
unsigned __int16 classnum;
|
||||
};
|
||||
|
||||
typedef void(__cdecl* scr_call_t)(int entref);
|
||||
|
||||
enum MeansOfDeath
|
||||
{
|
||||
MOD_UNKNOWN = 0,
|
||||
MOD_PISTOL_BULLET = 1,
|
||||
MOD_RIFLE_BULLET = 2,
|
||||
MOD_EXPLOSIVE_BULLET = 3,
|
||||
MOD_GRENADE = 4,
|
||||
MOD_GRENADE_SPLASH = 5,
|
||||
MOD_PROJECTILE = 6,
|
||||
MOD_PROJECTILE_SPLASH = 7,
|
||||
MOD_MELEE = 8,
|
||||
MOD_HEAD_SHOT = 9,
|
||||
MOD_CRUSH = 10,
|
||||
MOD_FALLING = 11,
|
||||
MOD_SUICIDE = 12,
|
||||
MOD_TRIGGER_HURT = 13,
|
||||
MOD_EXPLOSIVE = 14,
|
||||
MOD_IMPACT = 15,
|
||||
MOD_NUM = 16
|
||||
};
|
||||
|
||||
enum scriptType_e
|
||||
{
|
||||
SCRIPT_NONE = 0,
|
||||
SCRIPT_OBJECT = 1,
|
||||
SCRIPT_STRING = 2,
|
||||
SCRIPT_ISTRING = 3,
|
||||
SCRIPT_VECTOR = 4,
|
||||
SCRIPT_FLOAT = 5,
|
||||
SCRIPT_INTEGER = 6,
|
||||
SCRIPT_END = 8,
|
||||
SCRIPT_FUNCTION = 9,
|
||||
SCRIPT_STRUCT = 19,
|
||||
SCRIPT_ARRAY = 22,
|
||||
};
|
||||
|
||||
struct VariableStackBuffer
|
||||
{
|
||||
const char* pos;
|
||||
unsigned __int16 size;
|
||||
unsigned __int16 bufLen;
|
||||
unsigned __int16 localId;
|
||||
char time;
|
||||
char buf[1];
|
||||
};
|
||||
|
||||
union VariableUnion
|
||||
{
|
||||
int intValue;
|
||||
float floatValue;
|
||||
unsigned int stringValue;
|
||||
const float* vectorValue;
|
||||
const char* codePosValue;
|
||||
unsigned int pointerValue;
|
||||
VariableStackBuffer* stackValue;
|
||||
unsigned int entityId;
|
||||
unsigned int uintValue;
|
||||
};
|
||||
|
||||
struct VariableValue
|
||||
{
|
||||
VariableUnion u;
|
||||
scriptType_e type;
|
||||
};
|
||||
|
||||
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 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];
|
||||
};
|
||||
|
||||
struct scr_classStruct_t
|
||||
{
|
||||
unsigned __int16 id;
|
||||
unsigned __int16 entArrayId;
|
||||
char charId;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
struct ObjectVariableChildren
|
||||
{
|
||||
unsigned __int16 firstChild;
|
||||
unsigned __int16 lastChild;
|
||||
};
|
||||
|
||||
struct ObjectVariableValue_u_f
|
||||
{
|
||||
unsigned __int16 prev;
|
||||
unsigned __int16 next;
|
||||
};
|
||||
|
||||
union ObjectVariableValue_u_o_u
|
||||
{
|
||||
unsigned __int16 size;
|
||||
unsigned __int16 entnum;
|
||||
unsigned __int16 nextEntId;
|
||||
unsigned __int16 self;
|
||||
};
|
||||
|
||||
struct ObjectVariableValue_u_o
|
||||
{
|
||||
unsigned __int16 refCount;
|
||||
ObjectVariableValue_u_o_u u;
|
||||
};
|
||||
|
||||
union ObjectVariableValue_w
|
||||
{
|
||||
unsigned int type;
|
||||
unsigned int classnum;
|
||||
unsigned int notifyName;
|
||||
unsigned int waitTime;
|
||||
unsigned int parentLocalId;
|
||||
};
|
||||
|
||||
struct ChildVariableValue_u_f
|
||||
{
|
||||
unsigned __int16 prev;
|
||||
unsigned __int16 next;
|
||||
};
|
||||
|
||||
union ChildVariableValue_u
|
||||
{
|
||||
ChildVariableValue_u_f f;
|
||||
VariableUnion u;
|
||||
};
|
||||
|
||||
struct ChildBucketMatchKeys_keys
|
||||
{
|
||||
unsigned __int16 name_hi;
|
||||
unsigned __int16 parentId;
|
||||
};
|
||||
|
||||
union ChildBucketMatchKeys
|
||||
{
|
||||
ChildBucketMatchKeys_keys keys;
|
||||
unsigned int match;
|
||||
};
|
||||
|
||||
struct ChildVariableValue
|
||||
{
|
||||
ChildVariableValue_u u;
|
||||
unsigned __int16 next;
|
||||
char type;
|
||||
char name_lo;
|
||||
ChildBucketMatchKeys k;
|
||||
unsigned __int16 nextSibling;
|
||||
unsigned __int16 prevSibling;
|
||||
};
|
||||
|
||||
union ObjectVariableValue_u
|
||||
{
|
||||
ObjectVariableValue_u_f f;
|
||||
ObjectVariableValue_u_o o;
|
||||
};
|
||||
|
||||
struct ObjectVariableValue
|
||||
{
|
||||
ObjectVariableValue_u u;
|
||||
ObjectVariableValue_w w;
|
||||
};
|
||||
|
||||
struct scrVarGlob_t
|
||||
{
|
||||
ObjectVariableValue objectVariableValue[36864];
|
||||
ObjectVariableChildren objectVariableChildren[36864];
|
||||
unsigned __int16 childVariableBucket[65536];
|
||||
ChildVariableValue childVariableValue[102400];
|
||||
};
|
||||
|
||||
union DvarValue
|
||||
{
|
||||
bool enabled;
|
||||
int integer;
|
||||
unsigned int unsignedInt;
|
||||
float value;
|
||||
float vector[4];
|
||||
const char* string;
|
||||
char color[4];
|
||||
};
|
||||
|
||||
struct enum_limit
|
||||
{
|
||||
int stringCount;
|
||||
const char** strings;
|
||||
};
|
||||
|
||||
struct int_limit
|
||||
{
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
struct float_limit
|
||||
{
|
||||
float min;
|
||||
float max;
|
||||
};
|
||||
|
||||
union DvarLimits
|
||||
{
|
||||
enum_limit enumeration;
|
||||
int_limit integer;
|
||||
float_limit value;
|
||||
float_limit vector;
|
||||
};
|
||||
|
||||
struct dvar_t
|
||||
{
|
||||
const char* name;
|
||||
unsigned int flags;
|
||||
char type;
|
||||
bool modified;
|
||||
DvarValue current;
|
||||
DvarValue latched;
|
||||
DvarValue reset;
|
||||
DvarLimits domain;
|
||||
bool(__cdecl* domainFunc)(dvar_t*, DvarValue);
|
||||
dvar_t* hashNext;
|
||||
};
|
||||
|
||||
struct gentity_s
|
||||
{
|
||||
int entnum;
|
||||
};
|
||||
}
|
69
src/game/symbols.hpp
Normal file
69
src/game/symbols.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#define WEAK __declspec(selectany)
|
||||
|
||||
namespace game
|
||||
{
|
||||
// Functions
|
||||
|
||||
WEAK symbol<void(int type, VariableUnion u)> AddRefToValue{0x5656E0};
|
||||
WEAK symbol<void(unsigned int id)> AddReftoObject{0x5655F0};
|
||||
WEAK symbol<unsigned int(unsigned int id)> AllocThread{0x565580};
|
||||
WEAK symbol<unsigned int()> AllocObject{0x565530};
|
||||
WEAK symbol<void(int type, VariableUnion u)> RemoveRefToValue{0x565730};
|
||||
|
||||
WEAK symbol<void(unsigned int weapon, bool isAlternate, char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x42F760};
|
||||
|
||||
WEAK symbol<const char*(int index)> ConcatArgs{0x502150};
|
||||
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x545680};
|
||||
WEAK symbol<void(const char* cmdName, void(), cmd_function_t* allocedCmd)> Cmd_AddCommandInternal{0x0};
|
||||
WEAK symbol<const char*(int index)> Cmd_Argv{0x0};
|
||||
|
||||
WEAK symbol<const dvar_t*(const char*)> Dvar_FindVar{0x5BDCC0};
|
||||
|
||||
WEAK symbol<char*(const char*)> I_CleanStr{0x0};
|
||||
|
||||
WEAK symbol<VariableValue(unsigned int classnum, int entnum, int offset)> GetEntityFieldValue{0x56AF20};
|
||||
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindVariable{0x5651F0};
|
||||
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindObject{0x565BD0};
|
||||
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> GetVariable{0x5663E0};
|
||||
|
||||
WEAK symbol<const float* (const float* v)> Scr_AllocVector{0x565680};
|
||||
WEAK symbol<void()> Scr_ClearOutParams{0x569010};
|
||||
WEAK symbol<scr_entref_t(unsigned int entId)> Scr_GetEntityIdRef{0x565F60};
|
||||
WEAK symbol<void(unsigned int classnum, int entnum, int offset)> Scr_SetObjectField{0x52BCC0};
|
||||
WEAK symbol<void(int id, unsigned int stringValue, unsigned int paramcount)> Scr_NotifyId{0x56B5E0};
|
||||
WEAK symbol<int(const char* filename, unsigned int str)> Scr_GetFunctionHandle{0x5618A0};
|
||||
WEAK symbol<unsigned int(int handle, unsigned int objId, unsigned int paramcount)> Scr_ExecThreadInternal{0x56E1C0};
|
||||
|
||||
WEAK symbol<unsigned int(const char* str, unsigned int user)> SL_GetString{0x5649E0};
|
||||
WEAK symbol<const char*(unsigned int stringValue)> SL_ConvertToString{0x564270};
|
||||
|
||||
WEAK symbol<void(int clientNum, int type, const char* command)> SV_GameSendServerCommand{0x573220};
|
||||
WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x5459F0};
|
||||
|
||||
WEAK symbol<void(unsigned int notifyListOwnerId, unsigned int stringValue, VariableValue* top)> VM_Notify{0x569720};
|
||||
WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x56DFE0};
|
||||
|
||||
WEAK symbol<void* (jmp_buf* Buf, int Value)> longjmp{0x7363BC};
|
||||
WEAK symbol<int(jmp_buf* Buf)> _setjmp{0x734CF8};
|
||||
|
||||
// Variables
|
||||
|
||||
WEAK symbol<int> g_script_error_level{0x20B21FC};
|
||||
WEAK symbol<jmp_buf> g_script_error{0x20B4218};
|
||||
|
||||
WEAK symbol<scrVmPub_t> scr_VmPub{0x20B4A80};
|
||||
WEAK symbol<scrVarGlob_t> scr_VarGlob{0x1E72180};
|
||||
|
||||
WEAK symbol<scr_classStruct_t*> g_classMap{0x8B4300};
|
||||
|
||||
WEAK symbol<gentity_s> g_entities{0x0};
|
||||
WEAK symbol<unsigned int> levelEntityId{0x208E1A4};
|
||||
|
||||
namespace plutonium
|
||||
{
|
||||
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> function_map_rev{0x205862C0};
|
||||
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> method_map_rev{0x205862E0};
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user