Entity damage callbacks
This commit is contained in:
parent
ce3cb82c48
commit
e5a0630ad3
@ -17,6 +17,9 @@ namespace notifies
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
utils::hook::detour scr_entity_damage_hook;
|
||||||
|
std::vector<sol::protected_function> entity_damage_callbacks;
|
||||||
|
|
||||||
char empty_function[2] = {0x32, 0x34}; // CHECK_CLEAR_PARAMS, END
|
char empty_function[2] = {0x32, 0x34}; // CHECK_CLEAR_PARAMS, END
|
||||||
|
|
||||||
unsigned int local_id_to_entity(unsigned int local_id)
|
unsigned int local_id_to_entity(unsigned int local_id)
|
||||||
@ -99,11 +102,96 @@ namespace notifies
|
|||||||
a.mov(r14, (char*)empty_function);
|
a.mov(r14, (char*)empty_function);
|
||||||
a.jmp(end);
|
a.jmp(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sol::lua_value convert_entity(lua_State* state, const game::gentity_s* ent)
|
||||||
|
{
|
||||||
|
if (!ent)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto player = scripting::call("getentbynum", {ent->s.entityNum});
|
||||||
|
|
||||||
|
return scripting::lua::convert(state, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_weapon_name(unsigned int weapon, bool isAlternate)
|
||||||
|
{
|
||||||
|
char output[1024] = {0};
|
||||||
|
game::BG_GetWeaponNameComplete(weapon, isAlternate, output, 1024);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::lua_value convert_vector(lua_State* state, const float* vec)
|
||||||
|
{
|
||||||
|
if (!vec)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto _vec = scripting::vector(vec);
|
||||||
|
|
||||||
|
return scripting::lua::convert(state, _vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string convert_mod(const int meansOfDeath)
|
||||||
|
{
|
||||||
|
const auto value = reinterpret_cast<game::scr_string_t**>(game::base_address + 0xBF49B0)[meansOfDeath];
|
||||||
|
const auto string = game::SL_ConvertToString(*value);
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scr_entity_damage_stub(game::gentity_s* self, game::gentity_s* inflictor, game::gentity_s* attacker, const float* vDir, const float* vPoint,
|
||||||
|
int damage, int dflags, const unsigned int hitLoc, const unsigned int weapon, bool isAlternate, unsigned int a11, const int meansOfDeath, unsigned int a13, unsigned int a14)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const std::string _hitLoc = reinterpret_cast<const char**>(game::base_address + 0xBF4AA0)[hitLoc];
|
||||||
|
const auto _mod = convert_mod(meansOfDeath);
|
||||||
|
const auto _weapon = get_weapon_name(weapon, isAlternate);
|
||||||
|
|
||||||
|
for (const auto& callback : entity_damage_callbacks)
|
||||||
|
{
|
||||||
|
const auto state = callback.lua_state();
|
||||||
|
|
||||||
|
const auto _self = convert_entity(state, self);
|
||||||
|
const auto _inflictor = convert_entity(state, inflictor);
|
||||||
|
const auto _attacker = convert_entity(state, attacker);
|
||||||
|
const auto _vDir = convert_vector(state, vDir);
|
||||||
|
|
||||||
|
const auto result = callback(_self, _inflictor, _attacker, damage, _mod, _weapon, _vDir, _hitLoc);
|
||||||
|
scripting::lua::handle_error(result);
|
||||||
|
|
||||||
|
if (result.valid())
|
||||||
|
{
|
||||||
|
const auto value = result.get<sol::object>();
|
||||||
|
if (value.is<int>())
|
||||||
|
{
|
||||||
|
damage = value.as<int>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (damage == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scr_entity_damage_hook.invoke<void>(self, inflictor, attacker, vDir, vPoint, damage, dflags, hitLoc, weapon, isAlternate, a11, meansOfDeath, a13, a14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_entity_damage_callback(const sol::protected_function& callback)
|
||||||
|
{
|
||||||
|
entity_damage_callbacks.push_back(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_callbacks()
|
void clear_callbacks()
|
||||||
{
|
{
|
||||||
vm_execute_hooks.clear();
|
vm_execute_hooks.clear();
|
||||||
|
entity_damage_callbacks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
@ -112,6 +200,8 @@ namespace notifies
|
|||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
utils::hook::jump(game::base_address + 0x5C90A5, utils::hook::assemble(vm_execute_stub), true);
|
utils::hook::jump(game::base_address + 0x5C90A5, utils::hook::assemble(vm_execute_stub), true);
|
||||||
|
|
||||||
|
scr_entity_damage_hook.create(game::base_address + 0x4BD2E0, scr_entity_damage_stub);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,6 @@ namespace notifies
|
|||||||
extern std::unordered_map<const char*, sol::protected_function> vm_execute_hooks;
|
extern std::unordered_map<const char*, sol::protected_function> vm_execute_hooks;
|
||||||
extern bool hook_enabled;
|
extern bool hook_enabled;
|
||||||
|
|
||||||
|
void add_entity_damage_callback(const sol::protected_function&);
|
||||||
void clear_callbacks();
|
void clear_callbacks();
|
||||||
}
|
}
|
@ -1015,7 +1015,7 @@ namespace scripting
|
|||||||
{"setmotionblurzoomscale", 0x81BA},
|
{"setmotionblurzoomscale", 0x81BA},
|
||||||
{"viewkick", 0x81BB},
|
{"viewkick", 0x81BB},
|
||||||
{"sub_4ecfe0", 0x81BC},
|
{"sub_4ecfe0", 0x81BC},
|
||||||
{"getnodenumber", 0x81BD},
|
{"getentitynumber", 0x81BD},
|
||||||
{"sub_4ebbc0", 0x81BE},
|
{"sub_4ebbc0", 0x81BE},
|
||||||
{"enablegrenadetouchdamage", 0x81BF},
|
{"enablegrenadetouchdamage", 0x81BF},
|
||||||
{"disablegrenadetouchdamage", 0x81C0},
|
{"disablegrenadetouchdamage", 0x81C0},
|
||||||
@ -1706,7 +1706,7 @@ namespace scripting
|
|||||||
{"removecomworld", 0x8587},
|
{"removecomworld", 0x8587},
|
||||||
{"sub_4b8f80", 0x8588},
|
{"sub_4b8f80", 0x8588},
|
||||||
{"sub_4b9270", 0x8589},
|
{"sub_4b9270", 0x8589},
|
||||||
{"getentitynumber", 0x858C},
|
{"sub_4eab30", 0x858C},
|
||||||
{"cleartargetentity", 0x858D},
|
{"cleartargetentity", 0x858D},
|
||||||
{"nullsub_359", 0x8590},
|
{"nullsub_359", 0x8590},
|
||||||
{"sub_4b3f60", 0x8595},
|
{"sub_4b3f60", 0x8595},
|
||||||
|
@ -423,7 +423,7 @@ namespace scripting::lua
|
|||||||
|
|
||||||
for (auto arg : va)
|
for (auto arg : va)
|
||||||
{
|
{
|
||||||
arguments.push_back(convert({ s, arg }));
|
arguments.push_back(convert({s, arg}));
|
||||||
}
|
}
|
||||||
|
|
||||||
notifies::hook_enabled = false;
|
notifies::hook_enabled = false;
|
||||||
@ -438,7 +438,7 @@ namespace scripting::lua
|
|||||||
|
|
||||||
for (auto arg : va)
|
for (auto arg : va)
|
||||||
{
|
{
|
||||||
arguments.push_back(convert({ s, arg }));
|
arguments.push_back(convert({s, arg}));
|
||||||
}
|
}
|
||||||
|
|
||||||
notifies::hook_enabled = false;
|
notifies::hook_enabled = false;
|
||||||
@ -455,7 +455,7 @@ namespace scripting::lua
|
|||||||
|
|
||||||
for (auto arg : va)
|
for (auto arg : va)
|
||||||
{
|
{
|
||||||
arguments.push_back(convert({ s, arg }));
|
arguments.push_back(convert({s, arg}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto level = entity{*::game::levelEntityId};
|
const auto level = entity{*::game::levelEntityId};
|
||||||
@ -466,6 +466,11 @@ namespace scripting::lua
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
game_type["onentitydamage"] = [](const game&, const sol::protected_function& callback)
|
||||||
|
{
|
||||||
|
notifies::add_entity_damage_callback(callback);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ namespace game
|
|||||||
|
|
||||||
struct gentity_s
|
struct gentity_s
|
||||||
{
|
{
|
||||||
char __pad0[0x1C];
|
EntityState s;
|
||||||
|
char __pad0[0x1B];
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
char __pad1[0xF0];
|
char __pad1[0xF0];
|
||||||
gclient_s* client;
|
gclient_s* client;
|
||||||
|
@ -12,6 +12,9 @@ namespace game
|
|||||||
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(unsigned int id)> RemoveRefToObject{0x5C28A0};
|
||||||
|
|
||||||
|
WEAK symbol<void(unsigned int weapon, bool isAlternate,
|
||||||
|
char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x6A0800};
|
||||||
|
|
||||||
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x59A050};
|
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x59A050};
|
||||||
|
|
||||||
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessage{0x37F450};
|
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessage{0x37F450};
|
||||||
|
Loading…
Reference in New Issue
Block a user