Entity damage callbacks
This commit is contained in:
parent
ce3cb82c48
commit
e5a0630ad3
@ -17,6 +17,9 @@ namespace notifies
|
||||
|
||||
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
|
||||
|
||||
unsigned int local_id_to_entity(unsigned int local_id)
|
||||
@ -99,11 +102,96 @@ namespace notifies
|
||||
a.mov(r14, (char*)empty_function);
|
||||
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()
|
||||
{
|
||||
vm_execute_hooks.clear();
|
||||
entity_damage_callbacks.clear();
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
@ -112,6 +200,8 @@ namespace notifies
|
||||
void post_unpack() override
|
||||
{
|
||||
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 bool hook_enabled;
|
||||
|
||||
void add_entity_damage_callback(const sol::protected_function&);
|
||||
void clear_callbacks();
|
||||
}
|
@ -1015,7 +1015,7 @@ namespace scripting
|
||||
{"setmotionblurzoomscale", 0x81BA},
|
||||
{"viewkick", 0x81BB},
|
||||
{"sub_4ecfe0", 0x81BC},
|
||||
{"getnodenumber", 0x81BD},
|
||||
{"getentitynumber", 0x81BD},
|
||||
{"sub_4ebbc0", 0x81BE},
|
||||
{"enablegrenadetouchdamage", 0x81BF},
|
||||
{"disablegrenadetouchdamage", 0x81C0},
|
||||
@ -1706,7 +1706,7 @@ namespace scripting
|
||||
{"removecomworld", 0x8587},
|
||||
{"sub_4b8f80", 0x8588},
|
||||
{"sub_4b9270", 0x8589},
|
||||
{"getentitynumber", 0x858C},
|
||||
{"sub_4eab30", 0x858C},
|
||||
{"cleartargetentity", 0x858D},
|
||||
{"nullsub_359", 0x8590},
|
||||
{"sub_4b3f60", 0x8595},
|
||||
|
@ -466,6 +466,11 @@ namespace scripting::lua
|
||||
|
||||
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
|
||||
{
|
||||
char __pad0[0x1C];
|
||||
EntityState s;
|
||||
char __pad0[0x1B];
|
||||
vec3_t origin;
|
||||
char __pad1[0xF0];
|
||||
gclient_s* client;
|
||||
|
@ -12,6 +12,9 @@ namespace game
|
||||
WEAK symbol<void(int type, VariableUnion u)> RemoveRefToValue{0x5C29B0};
|
||||
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* message)> CG_GameMessage{0x37F450};
|
||||
|
Loading…
Reference in New Issue
Block a user