Add OnTakeDamage_Alive hook support to SDKHooks (bug=6249).

This commit is contained in:
Nicholas Hastings 2014-09-03 17:45:34 -04:00
parent 40b1067ef7
commit be55587d70
3 changed files with 407 additions and 362 deletions

View File

@ -90,6 +90,8 @@ HookTypeData g_HookTypes[SDKHook_MAXHOOKS] =
{"GetMaxHealth", "", false}, {"GetMaxHealth", "", false},
{"Blocked", "", false}, {"Blocked", "", false},
{"BlockedPost", "", false}, {"BlockedPost", "", false},
{"OnTakeDamageAlive", "DT_BaseCombatCharacter", false},
{"OnTakeDamageAlivePost", "DT_BaseCombatCharacter", false},
}; };
SDKHooks g_Interface; SDKHooks g_Interface;
@ -168,6 +170,7 @@ SH_DECL_MANUALHOOK0(GetMaxHealth, 0, 0, 0, int);
#endif #endif
SH_DECL_MANUALHOOK1_void(GroundEntChanged, 0, 0, 0, void *); SH_DECL_MANUALHOOK1_void(GroundEntChanged, 0, 0, 0, void *);
SH_DECL_MANUALHOOK1(OnTakeDamage, 0, 0, 0, int, CTakeDamageInfoHack &); SH_DECL_MANUALHOOK1(OnTakeDamage, 0, 0, 0, int, CTakeDamageInfoHack &);
SH_DECL_MANUALHOOK1(OnTakeDamageAlive, 0, 0, 0, int, CTakeDamageInfoHack &);
SH_DECL_MANUALHOOK0_void(PreThink, 0, 0, 0); SH_DECL_MANUALHOOK0_void(PreThink, 0, 0, 0);
SH_DECL_MANUALHOOK0_void(PostThink, 0, 0, 0); SH_DECL_MANUALHOOK0_void(PostThink, 0, 0, 0);
SH_DECL_MANUALHOOK0(Reload, 0, 0, 0, bool); SH_DECL_MANUALHOOK0(Reload, 0, 0, 0, bool);
@ -515,6 +518,7 @@ void SDKHooks::SetupHooks()
CHECKOFFSET(FireBullets, false, true); CHECKOFFSET(FireBullets, false, true);
CHECKOFFSET(GroundEntChanged, false, true); CHECKOFFSET(GroundEntChanged, false, true);
CHECKOFFSET(OnTakeDamage, true, true); CHECKOFFSET(OnTakeDamage, true, true);
CHECKOFFSET(OnTakeDamageAlive,true, true);
CHECKOFFSET(PreThink, true, true); CHECKOFFSET(PreThink, true, true);
CHECKOFFSET(PostThink, true, true); CHECKOFFSET(PostThink, true, true);
CHECKOFFSET(Reload, true, true); CHECKOFFSET(Reload, true, true);
@ -607,6 +611,12 @@ HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callbac
case SDKHook_OnTakeDamagePost: case SDKHook_OnTakeDamagePost:
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true); hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true);
break; break;
case SDKHook_OnTakeDamageAlive:
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamageAlive, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamageAlive), false);
break;
case SDKHook_OnTakeDamageAlivePost:
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamageAlive, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamageAlivePost), true);
break;
case SDKHook_PreThink: case SDKHook_PreThink:
hookid = SH_ADD_MANUALVPHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false); hookid = SH_ADD_MANUALVPHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false);
break; break;
@ -999,12 +1009,12 @@ void SDKHooks::Hook_GroundEntChangedPost(void *pVar)
Call(META_IFACEPTR(CBaseEntity), SDKHook_GroundEntChangedPost); Call(META_IFACEPTR(CBaseEntity), SDKHook_GroundEntChangedPost);
} }
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info) int SDKHooks::HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType)
{ {
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity); CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
CVTableHook vhook(pEntity); CVTableHook vhook(pEntity);
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_OnTakeDamage]; ke::Vector<CVTableList *> &vtablehooklist = g_HookList[hookType];
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry) for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
{ {
if (vhook != vtablehooklist[entry]->vtablehook) if (vhook != vtablehooklist[entry]->vtablehook)
@ -1020,10 +1030,10 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
int weapon = info.GetWeapon(); int weapon = info.GetWeapon();
Vector force = info.GetDamageForce(); Vector force = info.GetDamageForce();
cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)}; cell_t damageForce[3] = { sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z) };
Vector pos = info.GetDamagePosition(); Vector pos = info.GetDamagePosition();
cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)}; cell_t damagePosition[3] = { sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z) };
cell_t res, ret = Pl_Continue; cell_t res, ret = Pl_Continue;
@ -1039,23 +1049,23 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
callback->PushCellByRef(&damagetype); callback->PushCellByRef(&damagetype);
callback->PushCellByRef(&weapon); callback->PushCellByRef(&weapon);
callback->PushArray(damageForce, 3, SM_PARAM_COPYBACK); callback->PushArray(damageForce, 3, SM_PARAM_COPYBACK);
callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK); callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);
callback->PushCell(info.GetDamageCustom()); callback->PushCell(info.GetDamageCustom());
callback->Execute(&res); callback->Execute(&res);
if(res >= ret) if (res >= ret)
{ {
ret = res; ret = res;
if(ret == Pl_Changed) if (ret == Pl_Changed)
{ {
CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker); CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker);
if(!pEntAttacker) if (!pEntAttacker)
{ {
callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker); callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker);
RETURN_META_VALUE(MRES_IGNORED, 0); RETURN_META_VALUE(MRES_IGNORED, 0);
} }
CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor); CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor);
if(!pEntInflictor) if (!pEntInflictor)
{ {
callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor); callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor);
RETURN_META_VALUE(MRES_IGNORED, 0); RETURN_META_VALUE(MRES_IGNORED, 0);
@ -1077,12 +1087,12 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
} }
} }
} }
if(ret >= Pl_Handled) if (ret >= Pl_Handled)
RETURN_META_VALUE(MRES_SUPERCEDE, 1); RETURN_META_VALUE(MRES_SUPERCEDE, 1);
if(ret == Pl_Changed) if (ret == Pl_Changed)
RETURN_META_VALUE(MRES_HANDLED, 1); RETURN_META_VALUE(MRES_HANDLED, 1);
break; break;
} }
@ -1090,12 +1100,12 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
RETURN_META_VALUE(MRES_IGNORED, 0); RETURN_META_VALUE(MRES_IGNORED, 0);
} }
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info) int SDKHooks::HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType)
{ {
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity); CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
CVTableHook vhook(pEntity); CVTableHook vhook(pEntity);
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_OnTakeDamagePost]; ke::Vector<CVTableList *> &vtablehooklist = g_HookList[hookType];
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry) for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
{ {
if (vhook != vtablehooklist[entry]->vtablehook) if (vhook != vtablehooklist[entry]->vtablehook)
@ -1118,11 +1128,11 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
callback->PushCell(info.GetWeapon()); callback->PushCell(info.GetWeapon());
Vector force = info.GetDamageForce(); Vector force = info.GetDamageForce();
cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)}; cell_t damageForce[3] = { sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z) };
callback->PushArray(damageForce, 3); callback->PushArray(damageForce, 3);
Vector pos = info.GetDamagePosition(); Vector pos = info.GetDamagePosition();
cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)}; cell_t damagePosition[3] = { sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z) };
callback->PushArray(damagePosition, 3); callback->PushArray(damagePosition, 3);
callback->PushCell(info.GetDamageCustom()); callback->PushCell(info.GetDamageCustom());
@ -1136,6 +1146,26 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
RETURN_META_VALUE(MRES_IGNORED, 0); RETURN_META_VALUE(MRES_IGNORED, 0);
} }
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
{
return HandleOnTakeDamageHook(info, SDKHook_OnTakeDamage);
}
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
{
return HandleOnTakeDamageHookPost(info, SDKHook_OnTakeDamagePost);
}
int SDKHooks::Hook_OnTakeDamageAlive(CTakeDamageInfoHack &info)
{
return HandleOnTakeDamageHook(info, SDKHook_OnTakeDamageAlive);
}
int SDKHooks::Hook_OnTakeDamageAlivePost(CTakeDamageInfoHack &info)
{
return HandleOnTakeDamageHookPost(info, SDKHook_OnTakeDamageAlivePost);
}
void SDKHooks::Hook_PreThink() void SDKHooks::Hook_PreThink()
{ {
Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThink); Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThink);

View File

@ -1,353 +1,361 @@
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ #ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ #define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#include "smsdk_ext.h" #include "smsdk_ext.h"
#include <ISDKHooks.h> #include <ISDKHooks.h>
#include <IBinTools.h> #include <IBinTools.h>
#include <convar.h> #include <convar.h>
#include <sh_list.h> #include <sh_list.h>
#include <amtl/am-vector.h> #include <amtl/am-vector.h>
#include <vtable_hook_helper.h> #include <vtable_hook_helper.h>
#include <iplayerinfo.h> #include <iplayerinfo.h>
#include <shareddefs.h> #include <shareddefs.h>
#if SOURCE_ENGINE >= SE_ORANGEBOX #if SOURCE_ENGINE >= SE_ORANGEBOX
#include <itoolentity.h> #include <itoolentity.h>
#endif #endif
#include "takedamageinfohack.h" #include "takedamageinfohack.h"
#ifndef METAMOD_PLAPI_VERSION #ifndef METAMOD_PLAPI_VERSION
#define GetCGlobals pGlobals #define GetCGlobals pGlobals
#define GetEngineFactory engineFactory #define GetEngineFactory engineFactory
#define GetServerFactory serverFactory #define GetServerFactory serverFactory
#endif #endif
#if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD #if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD
#define GETMAXHEALTH_IS_VIRTUAL #define GETMAXHEALTH_IS_VIRTUAL
#endif #endif
#if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN #if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN
#define GAMEDESC_CAN_CHANGE #define GAMEDESC_CAN_CHANGE
#endif #endif
#if SOURCE_ENGINE == SE_DOTA #if SOURCE_ENGINE == SE_DOTA
class CEntityKeyValues; class CEntityKeyValues;
#endif #endif
/** /**
* Globals * Globals
*/ */
struct HookTypeData struct HookTypeData
{ {
const char *name; const char *name;
const char *dtReq; const char *dtReq;
bool supported; bool supported;
}; };
enum SDKHookType enum SDKHookType
{ {
SDKHook_EndTouch, SDKHook_EndTouch,
SDKHook_FireBulletsPost, SDKHook_FireBulletsPost,
SDKHook_OnTakeDamage, SDKHook_OnTakeDamage,
SDKHook_OnTakeDamagePost, SDKHook_OnTakeDamagePost,
SDKHook_PreThink, SDKHook_PreThink,
SDKHook_PostThink, SDKHook_PostThink,
SDKHook_SetTransmit, SDKHook_SetTransmit,
SDKHook_Spawn, SDKHook_Spawn,
SDKHook_StartTouch, SDKHook_StartTouch,
SDKHook_Think, SDKHook_Think,
SDKHook_Touch, SDKHook_Touch,
SDKHook_TraceAttack, SDKHook_TraceAttack,
SDKHook_TraceAttackPost, SDKHook_TraceAttackPost,
SDKHook_WeaponCanSwitchTo, SDKHook_WeaponCanSwitchTo,
SDKHook_WeaponCanUse, SDKHook_WeaponCanUse,
SDKHook_WeaponDrop, SDKHook_WeaponDrop,
SDKHook_WeaponEquip, SDKHook_WeaponEquip,
SDKHook_WeaponSwitch, SDKHook_WeaponSwitch,
SDKHook_ShouldCollide, SDKHook_ShouldCollide,
SDKHook_PreThinkPost, SDKHook_PreThinkPost,
SDKHook_PostThinkPost, SDKHook_PostThinkPost,
SDKHook_ThinkPost, SDKHook_ThinkPost,
SDKHook_EndTouchPost, SDKHook_EndTouchPost,
SDKHook_GroundEntChangedPost, SDKHook_GroundEntChangedPost,
SDKHook_SpawnPost, SDKHook_SpawnPost,
SDKHook_StartTouchPost, SDKHook_StartTouchPost,
SDKHook_TouchPost, SDKHook_TouchPost,
SDKHook_VPhysicsUpdate, SDKHook_VPhysicsUpdate,
SDKHook_VPhysicsUpdatePost, SDKHook_VPhysicsUpdatePost,
SDKHook_WeaponCanSwitchToPost, SDKHook_WeaponCanSwitchToPost,
SDKHook_WeaponCanUsePost, SDKHook_WeaponCanUsePost,
SDKHook_WeaponDropPost, SDKHook_WeaponDropPost,
SDKHook_WeaponEquipPost, SDKHook_WeaponEquipPost,
SDKHook_WeaponSwitchPost, SDKHook_WeaponSwitchPost,
SDKHook_Use, SDKHook_Use,
SDKHook_UsePost, SDKHook_UsePost,
SDKHook_Reload, SDKHook_Reload,
SDKHook_ReloadPost, SDKHook_ReloadPost,
SDKHook_GetMaxHealth, SDKHook_GetMaxHealth,
SDKHook_Blocked, SDKHook_Blocked,
SDKHook_BlockedPost, SDKHook_BlockedPost,
SDKHook_MAXHOOKS SDKHook_OnTakeDamageAlive,
}; SDKHook_OnTakeDamageAlivePost,
SDKHook_MAXHOOKS
enum HookReturn };
{
HookRet_Successful, enum HookReturn
HookRet_InvalidEntity, {
HookRet_InvalidHookType, HookRet_Successful,
HookRet_NotSupported, HookRet_InvalidEntity,
HookRet_BadEntForHookType, HookRet_InvalidHookType,
}; HookRet_NotSupported,
HookRet_BadEntForHookType,
#if SOURCE_ENGINE >= SE_CSS };
typedef void *(*ReticulateSplines)();
#endif #if SOURCE_ENGINE >= SE_CSS
typedef void *(*ReticulateSplines)();
/** #endif
* Classes
*/ /**
* Classes
class IPhysicsObject; */
class CDmgAccumulator;
typedef CBaseEntity CBaseCombatWeapon; class IPhysicsObject;
class CDmgAccumulator;
struct HookList typedef CBaseEntity CBaseCombatWeapon;
{
public: struct HookList
int entity; {
IPluginFunction *callback; public:
}; int entity;
IPluginFunction *callback;
class CVTableList };
{
public: class CVTableList
CVTableList() : vtablehook(NULL) {
{ public:
}; CVTableList() : vtablehook(NULL)
{
~CVTableList() };
{
delete vtablehook; ~CVTableList()
}; {
public: delete vtablehook;
CVTableHook *vtablehook; };
ke::Vector<HookList> hooks; public:
}; CVTableHook *vtablehook;
ke::Vector<HookList> hooks;
};
class IEntityListener class IEntityListener
{ {
public: public:
virtual void OnEntityCreated( CBaseEntity *pEntity ) {}; virtual void OnEntityCreated( CBaseEntity *pEntity ) {};
virtual void OnEntitySpawned( CBaseEntity *pEntity ) {}; virtual void OnEntitySpawned( CBaseEntity *pEntity ) {};
virtual void OnEntityDeleted( CBaseEntity *pEntity ) {}; virtual void OnEntityDeleted( CBaseEntity *pEntity ) {};
}; };
class SDKHooks : class SDKHooks :
public SDKExtension, public SDKExtension,
public IConCommandBaseAccessor, public IConCommandBaseAccessor,
public IPluginsListener, public IPluginsListener,
public IFeatureProvider, public IFeatureProvider,
public IEntityListener, public IEntityListener,
public IClientListener, public IClientListener,
public ISDKHooks public ISDKHooks
{ {
public: public:
/** /**
* @brief This is called after the initial loading sequence has been processed. * @brief This is called after the initial loading sequence has been processed.
* *
* @param error Error message buffer. * @param error Error message buffer.
* @param maxlength Size of error message buffer. * @param maxlength Size of error message buffer.
* @param late Whether or not the module was loaded after map load. * @param late Whether or not the module was loaded after map load.
* @return True to succeed loading, false to fail. * @return True to succeed loading, false to fail.
*/ */
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
/** /**
* @brief This is called right before the extension is unloaded. * @brief This is called right before the extension is unloaded.
*/ */
virtual void SDK_OnUnload(); virtual void SDK_OnUnload();
/** /**
* @brief This is called once all known extensions have been loaded. * @brief This is called once all known extensions have been loaded.
* Note: It is is a good idea to add natives here, if any are provided. * Note: It is is a good idea to add natives here, if any are provided.
*/ */
virtual void SDK_OnAllLoaded(); virtual void SDK_OnAllLoaded();
/** /**
* @brief Called when the pause state is changed. * @brief Called when the pause state is changed.
*/ */
//virtual void SDK_OnPauseChange(bool paused); //virtual void SDK_OnPauseChange(bool paused);
/** /**
* @brief this is called when Core wants to know if your extension is working. * @brief this is called when Core wants to know if your extension is working.
* *
* @param error Error message buffer. * @param error Error message buffer.
* @param maxlength Size of error message buffer. * @param maxlength Size of error message buffer.
* @return True if working, false otherwise. * @return True if working, false otherwise.
*/ */
//virtual bool QueryRunning(char *error, size_t maxlength); //virtual bool QueryRunning(char *error, size_t maxlength);
/** Returns version string */ /** Returns version string */
virtual const char *GetExtensionVerString(); virtual const char *GetExtensionVerString();
/** Returns date string */ /** Returns date string */
virtual const char *GetExtensionDateString(); virtual const char *GetExtensionDateString();
public: public:
#if defined SMEXT_CONF_METAMOD #if defined SMEXT_CONF_METAMOD
/** /**
* @brief Called when Metamod is attached, before the extension version is called. * @brief Called when Metamod is attached, before the extension version is called.
* *
* @param error Error buffer. * @param error Error buffer.
* @param maxlength Maximum size of error buffer. * @param maxlength Maximum size of error buffer.
* @param late Whether or not Metamod considers this a late load. * @param late Whether or not Metamod considers this a late load.
* @return True to succeed, false to fail. * @return True to succeed, false to fail.
*/ */
virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
/** /**
* @brief Called when Metamod is detaching, after the extension version is called. * @brief Called when Metamod is detaching, after the extension version is called.
* NOTE: By default this is blocked unless sent from SourceMod. * NOTE: By default this is blocked unless sent from SourceMod.
* *
* @param error Error buffer. * @param error Error buffer.
* @param maxlength Maximum size of error buffer. * @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail. * @return True to succeed, false to fail.
*/ */
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); //virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
/** /**
* @brief Called when Metamod's pause state is changing. * @brief Called when Metamod's pause state is changing.
* NOTE: By default this is blocked unless sent from SourceMod. * NOTE: By default this is blocked unless sent from SourceMod.
* *
* @param paused Pause state being set. * @param paused Pause state being set.
* @param error Error buffer. * @param error Error buffer.
* @param maxlength Maximum size of error buffer. * @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail. * @return True to succeed, false to fail.
*/ */
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
#endif #endif
public: // IPluginsListener public: // IPluginsListener
virtual void OnPluginLoaded(IPlugin *plugin); virtual void OnPluginLoaded(IPlugin *plugin);
virtual void OnPluginUnloaded(IPlugin *plugin); virtual void OnPluginUnloaded(IPlugin *plugin);
public: // IConCommandBaseAccessor public: // IConCommandBaseAccessor
virtual bool RegisterConCommandBase(ConCommandBase *pVar); virtual bool RegisterConCommandBase(ConCommandBase *pVar);
public: // IFeatureProvider public: // IFeatureProvider
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name); virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
public: // IEntityListener public: // IEntityListener
virtual void OnEntityCreated(CBaseEntity *pEntity); virtual void OnEntityCreated(CBaseEntity *pEntity);
virtual void OnEntityDeleted(CBaseEntity *pEntity); virtual void OnEntityDeleted(CBaseEntity *pEntity);
public: // IClientListener public: // IClientListener
virtual void OnClientPutInServer(int client); virtual void OnClientPutInServer(int client);
virtual void OnClientDisconnecting(int client); virtual void OnClientDisconnecting(int client);
public: // ISDKHooks public: // ISDKHooks
virtual void AddEntityListener(ISMEntityListener *listener); virtual void AddEntityListener(ISMEntityListener *listener);
virtual void RemoveEntityListener(ISMEntityListener *listener); virtual void RemoveEntityListener(ISMEntityListener *listener);
private: private:
SourceHook::List<ISMEntityListener *> m_EntListeners; SourceHook::List<ISMEntityListener *> m_EntListeners;
public: public:
/** /**
* Functions * Functions
*/ */
cell_t Call(int entity, SDKHookType type, int other=INVALID_EHANDLE_INDEX); cell_t Call(int entity, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
cell_t Call(CBaseEntity *pEnt, SDKHookType type, int other=INVALID_EHANDLE_INDEX); cell_t Call(CBaseEntity *pEnt, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
cell_t Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther); cell_t Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther);
void SetupHooks(); void SetupHooks();
HookReturn Hook(int entity, SDKHookType type, IPluginFunction *pCallback); HookReturn Hook(int entity, SDKHookType type, IPluginFunction *pCallback);
void Unhook(int entity, SDKHookType type, IPluginFunction *pCallback); void Unhook(int entity, SDKHookType type, IPluginFunction *pCallback);
/** /**
* IServerGameDLL & IVEngineServer Hook Handlers * IServerGameDLL & IVEngineServer Hook Handlers
*/ */
#ifdef GAMEDESC_CAN_CHANGE #ifdef GAMEDESC_CAN_CHANGE
const char *Hook_GetGameDescription(); const char *Hook_GetGameDescription();
#endif #endif
const char *Hook_GetMapEntitiesString(); const char *Hook_GetMapEntitiesString();
bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background); bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
/** /**
* CBaseEntity Hook Handlers * CBaseEntity Hook Handlers
*/ */
void Hook_EndTouch(CBaseEntity *pOther); void Hook_EndTouch(CBaseEntity *pOther);
void Hook_EndTouchPost(CBaseEntity *pOther); void Hook_EndTouchPost(CBaseEntity *pOther);
void Hook_FireBulletsPost(const FireBulletsInfo_t &info); void Hook_FireBulletsPost(const FireBulletsInfo_t &info);
#ifdef GETMAXHEALTH_IS_VIRTUAL #ifdef GETMAXHEALTH_IS_VIRTUAL
int Hook_GetMaxHealth(); int Hook_GetMaxHealth();
#endif #endif
void Hook_GroundEntChangedPost(void *pVar); void Hook_GroundEntChangedPost(void *pVar);
int Hook_OnTakeDamage(CTakeDamageInfoHack &info); int Hook_OnTakeDamage(CTakeDamageInfoHack &info);
int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info); int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info);
void Hook_PreThink(); int Hook_OnTakeDamageAlive(CTakeDamageInfoHack &info);
void Hook_PreThinkPost(); int Hook_OnTakeDamageAlivePost(CTakeDamageInfoHack &info);
void Hook_PostThink(); void Hook_PreThink();
void Hook_PostThinkPost(); void Hook_PreThinkPost();
bool Hook_Reload(); void Hook_PostThink();
bool Hook_ReloadPost(); void Hook_PostThinkPost();
void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways); bool Hook_Reload();
bool Hook_ShouldCollide(int collisonGroup, int contentsMask); bool Hook_ReloadPost();
#if SOURCE_ENGINE == SE_DOTA void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
void Hook_Spawn(CEntityKeyValues *kv); bool Hook_ShouldCollide(int collisonGroup, int contentsMask);
void Hook_SpawnPost(CEntityKeyValues *kv); #if SOURCE_ENGINE == SE_DOTA
#else void Hook_Spawn(CEntityKeyValues *kv);
void Hook_Spawn(); void Hook_SpawnPost(CEntityKeyValues *kv);
void Hook_SpawnPost(); #else
#endif void Hook_Spawn();
void Hook_StartTouch(CBaseEntity *pOther); void Hook_SpawnPost();
void Hook_StartTouchPost(CBaseEntity *pOther); #endif
void Hook_Think(); void Hook_StartTouch(CBaseEntity *pOther);
void Hook_ThinkPost(); void Hook_StartTouchPost(CBaseEntity *pOther);
void Hook_Touch(CBaseEntity *pOther); void Hook_Think();
void Hook_TouchPost(CBaseEntity *pOther); void Hook_ThinkPost();
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013 void Hook_Touch(CBaseEntity *pOther);
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator); void Hook_TouchPost(CBaseEntity *pOther);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator); #if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
#else void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr); void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr); #else
#endif void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
void Hook_UpdateOnRemove(); void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); #endif
void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); void Hook_UpdateOnRemove();
void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics); void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics); void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Hook_Blocked(CBaseEntity *pOther); void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics);
void Hook_BlockedPost(CBaseEntity *pOther); void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics);
bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon); void Hook_Blocked(CBaseEntity *pOther);
bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon); void Hook_BlockedPost(CBaseEntity *pOther);
bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon); bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon); bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon);
void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity); bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon);
void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity); bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon);
void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon); void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon); void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex); void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex); void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex);
private: bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
void HandleEntityCreated(CBaseEntity *pEntity, int ref);
void HandleEntityDeleted(CBaseEntity *pEntity, int ref); private:
void Unhook(CBaseEntity *pEntity); void HandleEntityCreated(CBaseEntity *pEntity, int ref);
void Unhook(IPluginContext *pContext); void HandleEntityDeleted(CBaseEntity *pEntity, int ref);
}; void Unhook(CBaseEntity *pEntity);
void Unhook(IPluginContext *pContext);
extern CGlobalVars *gpGlobals;
extern ke::Vector<CVTableList *> g_HookList[SDKHook_MAXHOOKS]; private:
int HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType);
extern ICvar *icvar; int HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType);
};
#if SOURCE_ENGINE >= SE_ORANGEBOX
extern IServerTools *servertools; extern CGlobalVars *gpGlobals;
#endif extern ke::Vector<CVTableList *> g_HookList[SDKHook_MAXHOOKS];
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ extern ICvar *icvar;
#if SOURCE_ENGINE >= SE_ORANGEBOX
extern IServerTools *servertools;
#endif
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_

View File

@ -119,6 +119,8 @@ enum SDKHookType
SDKHook_GetMaxHealth, /**< ep2v and later */ SDKHook_GetMaxHealth, /**< ep2v and later */
SDKHook_Blocked, SDKHook_Blocked,
SDKHook_BlockedPost, SDKHook_BlockedPost,
SDKHook_OnTakeDamageAlive,
SDKHook_OnTakeDamageAlivePost,
}; };
/* /*
@ -139,6 +141,9 @@ enum SDKHookType
SDKHook_OnTakeDamage, SDKHook_OnTakeDamage,
SDKHook_OnTakeDamagePost, SDKHook_OnTakeDamagePost,
SDKHook_OnTakeDamageAlive,
SDKHook_OnTakeDamageAlivePost,
SDKHook_PreThink, SDKHook_PreThink,
SDKHook_PreThinkPost, SDKHook_PreThinkPost,
@ -244,6 +249,7 @@ union SDKHookCB
function Action (int entity, int &maxhealth); function Action (int entity, int &maxhealth);
// OnTakeDamage // OnTakeDamage
// OnTakeDamagAlive
// Note: The weapon parameter is not used by all games and damage sources. // Note: The weapon parameter is not used by all games and damage sources.
// Note: Force application is dependent on game and damage type(s) // Note: Force application is dependent on game and damage type(s)
// SDKHooks 1.0+ // SDKHooks 1.0+
@ -256,6 +262,7 @@ union SDKHookCB
float[3] damageForce, float[3] damagePosition, int damagecustom); float[3] damageForce, float[3] damagePosition, int damagecustom);
// OnTakeDamagePost // OnTakeDamagePost
// OnTakeDamageAlivePost
function void (int victim, int attacker, int inflictor, float damage, int damagetype); function void (int victim, int attacker, int inflictor, float damage, int damagetype);
function void (int victim, int attacker, int inflictor, float damage, int damagetype, const float[3] damageForce, const float[3] damagePosition); function void (int victim, int attacker, int inflictor, float damage, int damagetype, const float[3] damageForce, const float[3] damagePosition);