mirror of
https://github.com/XLabsProject/s1x-client.git
synced 2023-08-02 15:02:12 +02:00
Merge pull request #42 from fedddddd/scripting
Player killed/damage callbacks
This commit is contained in:
commit
c02c41b882
@ -4,13 +4,136 @@
|
||||
|
||||
#include "game/scripting/entity.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
#include "game/scripting/lua/value_conversion.hpp"
|
||||
#include "game/scripting/lua/error.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
#include "logfile.hpp"
|
||||
|
||||
namespace logfile
|
||||
{
|
||||
namespace
|
||||
{
|
||||
utils::hook::detour scr_player_killed_hook;
|
||||
utils::hook::detour scr_player_damage_hook;
|
||||
|
||||
std::vector<sol::protected_function> player_killed_callbacks;
|
||||
std::vector<sol::protected_function> player_damage_callbacks;
|
||||
|
||||
sol::lua_value convert_entity(lua_State* state, const game::mp::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**>(0x1409B5360)[meansOfDeath];
|
||||
const auto string = game::SL_ConvertToString(*value);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
void scr_player_killed_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, game::mp::gentity_s* attacker, int damage,
|
||||
int meansOfDeath, const unsigned int weapon, bool isAlternate, const float* vDir, const unsigned int hitLoc, int psTimeOffset, int deathAnimDuration)
|
||||
{
|
||||
const std::string _hitLoc = reinterpret_cast<const char**>(0x1409B5400)[hitLoc];
|
||||
const auto _mod = convert_mod(meansOfDeath);
|
||||
|
||||
const auto _weapon = get_weapon_name(weapon, isAlternate);
|
||||
|
||||
for (const auto& callback : player_killed_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, psTimeOffset, deathAnimDuration);
|
||||
|
||||
scripting::lua::handle_error(result);
|
||||
|
||||
if (result.valid() && result.get_type() == sol::type::number)
|
||||
{
|
||||
damage = result.get<int>();
|
||||
}
|
||||
}
|
||||
|
||||
if (damage == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
scr_player_killed_hook.invoke<void>(self, inflictor, attacker, damage, meansOfDeath, weapon, isAlternate, vDir, hitLoc, psTimeOffset, deathAnimDuration);
|
||||
}
|
||||
|
||||
void scr_player_damage_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, game::mp::gentity_s* attacker, int damage, int dflags,
|
||||
int meansOfDeath, const unsigned int weapon, bool isAlternate, const float* vPoint, const float* vDir, const unsigned int hitLoc, int timeOffset)
|
||||
{
|
||||
const std::string _hitLoc = reinterpret_cast<const char**>(0x1409B5400)[hitLoc];
|
||||
const auto _mod = convert_mod(meansOfDeath);
|
||||
|
||||
const auto _weapon = get_weapon_name(weapon, isAlternate);
|
||||
|
||||
for (const auto& callback : player_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 _vPoint = convert_vector(state, vPoint);
|
||||
const auto _vDir = convert_vector(state, vDir);
|
||||
|
||||
const auto result = callback(_self, _inflictor, _attacker, damage, dflags, _mod, _weapon, _vPoint, _vDir, _hitLoc);
|
||||
|
||||
scripting::lua::handle_error(result);
|
||||
|
||||
if (result.valid() && result.get_type() == sol::type::number)
|
||||
{
|
||||
damage = result.get<int>();
|
||||
}
|
||||
}
|
||||
|
||||
if (damage == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
scr_player_damage_hook.invoke<void>(self, inflictor, attacker, damage, dflags, meansOfDeath, weapon, isAlternate, vPoint, vDir, hitLoc, timeOffset);
|
||||
}
|
||||
|
||||
bool evaluate_say(char* text, game::mp::gentity_s* ent)
|
||||
{
|
||||
auto hidden = false;
|
||||
@ -39,6 +162,22 @@ namespace logfile
|
||||
}
|
||||
}
|
||||
|
||||
void add_player_damage_callback(const sol::protected_function& callback)
|
||||
{
|
||||
player_damage_callbacks.push_back(callback);
|
||||
}
|
||||
|
||||
void add_player_killed_callback(const sol::protected_function& callback)
|
||||
{
|
||||
player_killed_callbacks.push_back(callback);
|
||||
}
|
||||
|
||||
void clear_callbacks()
|
||||
{
|
||||
player_damage_callbacks.clear();
|
||||
player_killed_callbacks.clear();
|
||||
}
|
||||
|
||||
const auto say_stub = utils::hook::assemble([](utils::hook::assembler& a)
|
||||
{
|
||||
const auto hidden = a.newLabel();
|
||||
@ -73,6 +212,9 @@ namespace logfile
|
||||
}
|
||||
|
||||
utils::hook::jump(0x1402E99CC, say_stub, true);
|
||||
|
||||
scr_player_damage_hook.create(0x140332150, scr_player_damage_stub);
|
||||
scr_player_killed_hook.create(0x1403323D0, scr_player_killed_stub);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
8
src/client/component/logfile.hpp
Normal file
8
src/client/component/logfile.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
namespace logfile
|
||||
{
|
||||
void add_player_damage_callback(const sol::protected_function& callback);
|
||||
void add_player_killed_callback(const sol::protected_function& callback);
|
||||
void clear_callbacks();
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
#include "../functions.hpp"
|
||||
|
||||
#include "../../../component/command.hpp"
|
||||
#include "../../../component/logfile.hpp"
|
||||
|
||||
#include <utils/string.hpp>
|
||||
|
||||
@ -248,6 +249,16 @@ namespace scripting::lua
|
||||
{
|
||||
command::execute(command, false);
|
||||
};
|
||||
|
||||
game_type["onplayerdamage"] = [](const game&, const sol::protected_function& callback)
|
||||
{
|
||||
logfile::add_player_damage_callback(callback);
|
||||
};
|
||||
|
||||
game_type["onplayerkilled"] = [](const game&, const sol::protected_function& callback)
|
||||
{
|
||||
logfile::add_player_killed_callback(callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "context.hpp"
|
||||
|
||||
#include "../execution.hpp"
|
||||
#include "../../../component/logfile.hpp"
|
||||
|
||||
#include <utils/io.hpp>
|
||||
|
||||
@ -52,6 +53,7 @@ namespace scripting::lua::engine
|
||||
|
||||
void stop()
|
||||
{
|
||||
logfile::clear_callbacks();
|
||||
get_scripts().clear();
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ namespace scripting::lua
|
||||
|
||||
table[sol::metatable_key] = metatable;
|
||||
|
||||
return { state, table };
|
||||
return {state, table};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ namespace game
|
||||
|
||||
WEAK symbol<void(void*, void*)> AimAssist_AddToTargetList{0, 0x140001730};
|
||||
|
||||
WEAK symbol<void(unsigned int weapon, bool isAlternate, char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x0, 0x140165580};
|
||||
|
||||
WEAK symbol<void(errorParm code, const char* message, ...)> Com_Error{0x1402F7570, 0x1403CE480};
|
||||
WEAK symbol<void()> Com_Frame_Try_Block_Function{0x1402F7E10, 0x1403CEF30};
|
||||
WEAK symbol<CodPlayMode()> Com_GetCurrentCoDPlayMode{0, 0x1404C9690};
|
||||
@ -45,9 +47,9 @@ namespace game
|
||||
WEAK symbol<void(XAssetType type, void (__cdecl* func)(XAssetHeader, void*), void* inData, bool includeOverride)>
|
||||
DB_EnumXAssets_FastFile{0x14017D7C0, 0x14026EC10};
|
||||
WEAK symbol<void(XAssetType type, void(__cdecl* func)(game::XAssetHeader, void*), const void* inData, bool includeOverride)>
|
||||
DB_EnumXAssets_Internal{ 0x14017D830, 0x14026EC80 };
|
||||
DB_EnumXAssets_Internal{0x14017D830, 0x14026EC80};
|
||||
WEAK symbol<game::XAssetEntry(game::XAssetType type, const char* name)>
|
||||
DB_FindXAssetEntry{ 0x14017D830, 0x14026F020 };
|
||||
DB_FindXAssetEntry{0x14017D830, 0x14026F020};
|
||||
WEAK symbol<const char* (const XAsset* asset)> DB_GetXAssetName{0x140151C00, 0x140240DD0};
|
||||
WEAK symbol<int(XAssetType type)> DB_GetXAssetTypeSize{0x140151C20, 0x140240DF0};
|
||||
WEAK symbol<void(XZoneInfo* zoneInfo, unsigned int zoneCount, DBSyncMode syncMode)> DB_LoadXAssets{
|
||||
@ -219,7 +221,7 @@ namespace game
|
||||
WEAK symbol<jmp_buf> g_script_error{0x14A1917B0, 0x1487FA0C0};
|
||||
WEAK symbol<scr_classStruct_t> g_classMap{0x14080A840, 0x1409BE1B0};
|
||||
|
||||
WEAK symbol<scrVarGlob_t> scr_VarGlob{ 0x149B1D680, 0x148185F80 };
|
||||
WEAK symbol<scrVarGlob_t> scr_VarGlob{0x149B1D680, 0x148185F80};
|
||||
WEAK symbol<scrVmPub_t> scr_VmPub{0x14A1938C0, 0x1487FC1C0};
|
||||
|
||||
WEAK symbol<const char*> command_whitelist{0x140808EF0, 0x1409B8DC0};
|
||||
|
Loading…
Reference in New Issue
Block a user