Difference between revisions of "SDKHooks"
(Added other hooks) |
(Added more information about how to hook and some hooks and how to use takedamage) |
||
| (8 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
==Introduction== | ==Introduction== | ||
SDKHooks was previously an external extension to Sourcemod. It was rolled in [https://wiki.alliedmods.net/Sourcemod_1.5.0_API_Changes#SDKHooks Sourcemod 1.5] and it does not need to be manually installed anymore. | SDKHooks was previously an external extension to Sourcemod. It was rolled in [https://wiki.alliedmods.net/Sourcemod_1.5.0_API_Changes#SDKHooks Sourcemod 1.5] and it does not need to be manually installed anymore. | ||
| + | SDKHooks extension provides hooks, functions and natives. | ||
| + | |||
| + | ==Take Damage== | ||
| + | Native SDKHooks_TakeDamage allows you to force an entity to take damage: <code>void SDKHooks_TakeDamage(int entity, int inflictor, int attacker, | ||
| + | float damage, int damageType=DMG_GENERIC, int weapon=-1, | ||
| + | const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR, | ||
| + | bool bypassHooks = true);</code><br> | ||
| + | Damage types are available in the sdkhooks.inc file - [https://sm.alliedmods.net/new-api/sdkhooks/__raw sdkhooks.inc]<br> | ||
| + | The weapon parameter is not used by all games and damage sources. | ||
| + | |||
| + | ==Hooking an entity== | ||
| + | SDKHooks provides 3 functions related to hooking entities: '''SDKHook''', '''SDKHookEx''' and '''SDKUnhook'''<br> | ||
| + | |||
| + | ===SDKHook=== | ||
| + | SDKHook is used to hook entities: | ||
| + | <code> | ||
| + | void SDKHook(int entity, SDKHookType type, SDKHookCB callback); | ||
| + | </code><br> | ||
| + | The first parameter is the entity index.<br> | ||
| + | The second parameter is the hook type, some of which are listed in the Hooks section below but you can always find the full list in the sdkhooks.inc file. Online version available [https://sm.alliedmods.net/new-api/sdkhooks/__raw here].<br> | ||
| + | The third parameter is the callback function, that will be run, when the hook is triggered.<br> | ||
| + | |||
| + | The callback function signature changes depending on the hook type. You can see all the callback function signatures in the sdkhooks.inc file - [https://sm.alliedmods.net/new-api/sdkhooks/__raw sdkhooks.inc]<br> | ||
| + | Example callback function signature for the OnTakeDamage hook: | ||
| + | <code> | ||
| + | function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, | ||
| + | float damageForce[3], float damagePosition[3], int damagecustom); | ||
| + | </code><br> | ||
| + | Note the callback return type: | ||
| + | *void - event cannot be changed at this point | ||
| + | *Action - event can be changed or stopped where possible | ||
| + | |||
| + | ===SDKHookEx=== | ||
| + | SDKHookEx is exactly the same as SDKHook, with only 1 difference: | ||
| + | Unlike SDKHook, it has a boolean return value telling you whether the hook was successful. | ||
| + | |||
| + | ===SDKUnhook=== | ||
| + | SDKUnhook removes/unhooks the hook from the entity: | ||
| + | <code> | ||
| + | void SDKUnhook(int entity, SDKHookType type, SDKHookCB callback); | ||
| + | </code><br> | ||
| + | It has the same parameters as SDKHook. | ||
| + | |||
| + | It is rarely used, because: | ||
| + | * SDKHooks blocks hooking the same hook (for the same entity) twice | ||
| + | * Hooks are unhooked automatically upon destruction/removal of the entity | ||
==Hooks== | ==Hooks== | ||
Some information on various hooks below: | Some information on various hooks below: | ||
| − | ==SDKHook_Blocked== | + | ===SDKHook_Blocked=== |
| − | ==SDKHook_BlockedPost== | + | ===SDKHook_BlockedPost=== |
| − | ==SDKHook_CanBeAutobalanced== | + | ===SDKHook_CanBeAutobalanced=== |
| − | ==SDKHook_EndTouch== | + | ===SDKHook_EndTouch=== |
| − | ==SDKHook_EndTouchPost== | + | ===SDKHook_EndTouchPost=== |
| − | ==SDKHook_FireBulletsPost== | + | ===SDKHook_FireBulletsPost=== |
| − | ==SDKHook_GetMaxHealth== | + | Not all games use FireBullets so this hook will not trigger in such games. |
| + | ===SDKHook_GetMaxHealth=== | ||
(ep2v and later) | (ep2v and later) | ||
| − | ==SDKHook_GroundEntChangedPost== | + | ===SDKHook_GroundEntChangedPost=== |
| − | ==SDKHook_OnTakeDamage== | + | ===SDKHook_OnTakeDamage=== |
inflictor (3rd argument) is the entity that inflicts the damage. If a player directly damages another, inflictor should be equal to the attacking player id. An example of an indirect damage would be a grenade. | inflictor (3rd argument) is the entity that inflicts the damage. If a player directly damages another, inflictor should be equal to the attacking player id. An example of an indirect damage would be a grenade. | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | ==Under CSS= | + | ====Under CSS==== |
| − | ===Non-regular cases for SDKHook_OnTakeDamage | + | '''Non-regular cases for SDKHook_OnTakeDamage''' |
In the scenario where a player throw a grenade to another player then quickly disconnect, the attacker (2nd argument) will become the inflictor (3rd argument). | In the scenario where a player throw a grenade to another player then quickly disconnect, the attacker (2nd argument) will become the inflictor (3rd argument). | ||
| Line 62: | Line 71: | ||
In the scenario where a terrorist plants the bomb, when the bomb explodes, the attacker (2nd argument) will be the same as the inflictor (3rd argument) which will have the Classname "planted_c4". | In the scenario where a terrorist plants the bomb, when the bomb explodes, the attacker (2nd argument) will be the same as the inflictor (3rd argument) which will have the Classname "planted_c4". | ||
| − | + | '''Some damage types''' | |
A normal HEGrenade and the C4 inflict damage of type DMG_BLAST. | A normal HEGrenade and the C4 inflict damage of type DMG_BLAST. | ||
| Line 80: | Line 89: | ||
sm_burn will trigger two different callback : an entity with the classname "entityflame" will deal once 0 damage of type DMG_BURN and once 1 damage of type (DMG_BURN | DMG_DIRECT) every tick. | sm_burn will trigger two different callback : an entity with the classname "entityflame" will deal once 0 damage of type DMG_BURN and once 1 damage of type (DMG_BURN | DMG_DIRECT) every tick. | ||
| − | + | '''Regarding SDKHook_OnTakeDamage and SDKHook_OnTakeDamageAlive''' | |
SDKHook_OnTakeDamage/Post is triggered when hitting a teammate with mp_friendlyfire 0 (except in TF2), but not SDKHook_OnTakeDamageAlive. | SDKHook_OnTakeDamage/Post is triggered when hitting a teammate with mp_friendlyfire 0 (except in TF2), but not SDKHook_OnTakeDamageAlive. | ||
| − | ==Under TF2== | + | ====Under TF2==== |
Under TF2, the SDKHook_OnTakeDamage hook isn't 100% accurate, it's damage parameter is the weapon's base damage. the DMG_CRIT flag is for both crits and minicrits. Weapon spread and minicrit/crit damage is calculated after this call (in SDKHook_OnTakeDamageAlive/Post). | Under TF2, the SDKHook_OnTakeDamage hook isn't 100% accurate, it's damage parameter is the weapon's base damage. the DMG_CRIT flag is for both crits and minicrits. Weapon spread and minicrit/crit damage is calculated after this call (in SDKHook_OnTakeDamageAlive/Post). | ||
| − | + | '''Some damage types''' | |
Shotgun = DMG_BUCKSHOT | DMG_SLOWBURN | Shotgun = DMG_BUCKSHOT | DMG_SLOWBURN | ||
| Line 94: | Line 103: | ||
If a crit, |= DMG_CRIT | If a crit, |= DMG_CRIT | ||
| + | ===SDKHook_OnTakeDamagePost=== | ||
| + | Trigged after SDKHook_OnTakeDamage, but before SDKHook_OnTakeDamageAlive | ||
| + | ===SDKHook_OnTakeDamageAlive=== | ||
| + | This hook works in a similar way to SDKHook_OnTakeDamage but it gives the [https://bugs.alliedmods.net/show_bug.cgi?id=6249#c7 actual, calculated damage amount done to the player. The pre-hook will fire after an OnTakeDamage pre-hook, and the post-hook will fire before an OnTakeDamage post-hook. The health is subtracted in between pre and post unless the hook is blocked.] {{pr|149}} | ||
| + | |||
| + | [https://forums.alliedmods.net/showthread.php?p=2309798#post2309798 OnTakeDamageAlive is also only called for players.] | ||
| + | ===SDKHook_OnTakeDamageAlivePost=== | ||
| + | Triggered after the player took damage. | ||
| + | ===SDKHook_PreThink=== | ||
| + | Called before OnGameFrame(), but only for the hooked entity. | ||
| + | ===SDKHook_PreThinkPost=== | ||
| + | ===SDKHook_PostThink=== | ||
| + | ===SDKHook_PostThinkPost=== | ||
| + | ===SDKHook_Reload=== | ||
| + | ===SDKHook_ReloadPost=== | ||
| + | ===SDKHook_SetTransmit=== | ||
| + | ===SDKHook_ShouldCollide=== | ||
| + | ===SDKHook_Spawn=== | ||
| + | Triggers when the hooked entity is about to spawn. Entity creation and spawn are not the same thing. Some entity properties are not available until the entity spawns. | ||
| + | ===SDKHook_SpawnPost=== | ||
| + | Triggers after the hooked entity was spawned. | ||
| + | ===SDKHook_StartTouch=== | ||
| + | Triggers when the hooked entity is about to be touched by another entity. Not all entities can trigger/fire touch events. Adjusting collision groups for the entity can fix that. | ||
| + | ===SDKHook_StartTouchPost=== | ||
| + | ===SDKHook_Think=== | ||
| + | ===SDKHook_ThinkPost=== | ||
| + | ===SDKHook_Touch=== | ||
| + | ===SDKHook_TouchPost=== | ||
| + | ===SDKHook_TraceAttack=== | ||
| + | ===SDKHook_TraceAttackPost=== | ||
| + | ===SDKHook_Use=== | ||
| + | ===SDKHook_UsePost=== | ||
| + | ===SDKHook_VPhysicsUpdate=== | ||
| + | Triggers when the hooked entity is about to update. | ||
| + | ===SDKHook_VPhysicsUpdatePost=== | ||
| + | ===SDKHook_WeaponCanSwitchTo=== | ||
| + | ===SDKHook_WeaponCanSwitchToPost=== | ||
| + | ===SDKHook_WeaponCanUse=== | ||
| + | ===SDKHook_WeaponCanUsePost=== | ||
| + | ===SDKHook_WeaponDrop=== | ||
| + | Triggers when the hooked weapon is about to be dropped. | ||
| + | ====Under TF2==== | ||
| + | When a weapon is dropped in tf2, a new entity is created called tf_dropped_weapon and this new entity is not the same entity as the one that player had equipped nor do they share entity IDs. They share the m_iAccountID property however, which contains the steam ID of the owner of the weapon that dropped it. You cannot prevent weapon drop through this hook in TF2. | ||
| + | ===SDKHook_WeaponDropPost=== | ||
| + | Triggers after the hooked weapon was dropped. | ||
| + | ===SDKHook_WeaponEquip=== | ||
| + | Triggers when the hooked weapon is about to be equipped. | ||
| + | ===SDKHook_WeaponEquipPost=== | ||
| + | Triggers after the hooked weapon was equipped. | ||
| + | ===SDKHook_WeaponSwitch=== | ||
| + | Triggers when the hooked weapon is about to be switched for another one. | ||
| + | ===SDKHook_WeaponSwitchPost=== | ||
| + | Triggers after the hooked weapon was switched for another one. | ||
[[Category:SourceMod Scripting]] | [[Category:SourceMod Scripting]] | ||
Latest revision as of 15:08, 31 March 2026
Contents
- 1 Introduction
- 2 Take Damage
- 3 Hooking an entity
- 4 Hooks
- 4.1 SDKHook_Blocked
- 4.2 SDKHook_BlockedPost
- 4.3 SDKHook_CanBeAutobalanced
- 4.4 SDKHook_EndTouch
- 4.5 SDKHook_EndTouchPost
- 4.6 SDKHook_FireBulletsPost
- 4.7 SDKHook_GetMaxHealth
- 4.8 SDKHook_GroundEntChangedPost
- 4.9 SDKHook_OnTakeDamage
- 4.10 SDKHook_OnTakeDamagePost
- 4.11 SDKHook_OnTakeDamageAlive
- 4.12 SDKHook_OnTakeDamageAlivePost
- 4.13 SDKHook_PreThink
- 4.14 SDKHook_PreThinkPost
- 4.15 SDKHook_PostThink
- 4.16 SDKHook_PostThinkPost
- 4.17 SDKHook_Reload
- 4.18 SDKHook_ReloadPost
- 4.19 SDKHook_SetTransmit
- 4.20 SDKHook_ShouldCollide
- 4.21 SDKHook_Spawn
- 4.22 SDKHook_SpawnPost
- 4.23 SDKHook_StartTouch
- 4.24 SDKHook_StartTouchPost
- 4.25 SDKHook_Think
- 4.26 SDKHook_ThinkPost
- 4.27 SDKHook_Touch
- 4.28 SDKHook_TouchPost
- 4.29 SDKHook_TraceAttack
- 4.30 SDKHook_TraceAttackPost
- 4.31 SDKHook_Use
- 4.32 SDKHook_UsePost
- 4.33 SDKHook_VPhysicsUpdate
- 4.34 SDKHook_VPhysicsUpdatePost
- 4.35 SDKHook_WeaponCanSwitchTo
- 4.36 SDKHook_WeaponCanSwitchToPost
- 4.37 SDKHook_WeaponCanUse
- 4.38 SDKHook_WeaponCanUsePost
- 4.39 SDKHook_WeaponDrop
- 4.40 SDKHook_WeaponDropPost
- 4.41 SDKHook_WeaponEquip
- 4.42 SDKHook_WeaponEquipPost
- 4.43 SDKHook_WeaponSwitch
- 4.44 SDKHook_WeaponSwitchPost
Introduction
SDKHooks was previously an external extension to Sourcemod. It was rolled in Sourcemod 1.5 and it does not need to be manually installed anymore. SDKHooks extension provides hooks, functions and natives.
Take Damage
Native SDKHooks_TakeDamage allows you to force an entity to take damage: void SDKHooks_TakeDamage(int entity, int inflictor, int attacker,
float damage, int damageType=DMG_GENERIC, int weapon=-1,
const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR,
bool bypassHooks = true);
Damage types are available in the sdkhooks.inc file - sdkhooks.inc
The weapon parameter is not used by all games and damage sources.
Hooking an entity
SDKHooks provides 3 functions related to hooking entities: SDKHook, SDKHookEx and SDKUnhook
SDKHook
SDKHook is used to hook entities:
void SDKHook(int entity, SDKHookType type, SDKHookCB callback);
The first parameter is the entity index.
The second parameter is the hook type, some of which are listed in the Hooks section below but you can always find the full list in the sdkhooks.inc file. Online version available here.
The third parameter is the callback function, that will be run, when the hook is triggered.
The callback function signature changes depending on the hook type. You can see all the callback function signatures in the sdkhooks.inc file - sdkhooks.inc
Example callback function signature for the OnTakeDamage hook:
function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon,
float damageForce[3], float damagePosition[3], int damagecustom);
Note the callback return type:
- void - event cannot be changed at this point
- Action - event can be changed or stopped where possible
SDKHookEx
SDKHookEx is exactly the same as SDKHook, with only 1 difference: Unlike SDKHook, it has a boolean return value telling you whether the hook was successful.
SDKUnhook
SDKUnhook removes/unhooks the hook from the entity:
void SDKUnhook(int entity, SDKHookType type, SDKHookCB callback);
It has the same parameters as SDKHook.
It is rarely used, because:
- SDKHooks blocks hooking the same hook (for the same entity) twice
- Hooks are unhooked automatically upon destruction/removal of the entity
Hooks
Some information on various hooks below:
SDKHook_Blocked
SDKHook_BlockedPost
SDKHook_CanBeAutobalanced
SDKHook_EndTouch
SDKHook_EndTouchPost
SDKHook_FireBulletsPost
Not all games use FireBullets so this hook will not trigger in such games.
SDKHook_GetMaxHealth
(ep2v and later)
SDKHook_GroundEntChangedPost
SDKHook_OnTakeDamage
inflictor (3rd argument) is the entity that inflicts the damage. If a player directly damages another, inflictor should be equal to the attacking player id. An example of an indirect damage would be a grenade.
Under CSS
Non-regular cases for SDKHook_OnTakeDamage In the scenario where a player throw a grenade to another player then quickly disconnect, the attacker (2nd argument) will become the inflictor (3rd argument).
In the scenario where a player fall; the attacker, which is also the inflictor, will be 0 (the world).
In the scenario where a terrorist plants the bomb, when the bomb explodes, the attacker (2nd argument) will be the same as the inflictor (3rd argument) which will have the Classname "planted_c4".
Some damage types A normal HEGrenade and the C4 inflict damage of type DMG_BLAST.
A fall inflicts damage of type DMG_FALL.
A grenade impact (for instance a flash hitting a teammate) will inflict damage of type DMG_CLUB.
A normal gun bullet and the knife will inflict damage of type (DMG_BULLET | DMG_NEVERGIB) (non-headshot) or (DMG_BULLET | DMG_NEVERGIB | (1 << 30) ) (headshot).
A single attack can trigger many SDKHook_OnTakeDamage; when a gun throws pullets for instance (shotgun and glock in burst-mode notably).
(Regarding SM/Admin damaged; maybe place this is another section if someone can be sure that this would occur on all mods)
sm_slap does not trigger SDKHook_OnTakeDamage.
sm_burn will trigger two different callback : an entity with the classname "entityflame" will deal once 0 damage of type DMG_BURN and once 1 damage of type (DMG_BURN | DMG_DIRECT) every tick.
Regarding SDKHook_OnTakeDamage and SDKHook_OnTakeDamageAlive
SDKHook_OnTakeDamage/Post is triggered when hitting a teammate with mp_friendlyfire 0 (except in TF2), but not SDKHook_OnTakeDamageAlive.
Under TF2
Under TF2, the SDKHook_OnTakeDamage hook isn't 100% accurate, it's damage parameter is the weapon's base damage. the DMG_CRIT flag is for both crits and minicrits. Weapon spread and minicrit/crit damage is calculated after this call (in SDKHook_OnTakeDamageAlive/Post).
Some damage types Shotgun = DMG_BUCKSHOT | DMG_SLOWBURN
Rocket Launcher = DMG_SLOWBURN | DMG_RADIATION | DMG_BLAST
If a crit, |= DMG_CRIT
SDKHook_OnTakeDamagePost
Trigged after SDKHook_OnTakeDamage, but before SDKHook_OnTakeDamageAlive
SDKHook_OnTakeDamageAlive
This hook works in a similar way to SDKHook_OnTakeDamage but it gives the actual, calculated damage amount done to the player. The pre-hook will fire after an OnTakeDamage pre-hook, and the post-hook will fire before an OnTakeDamage post-hook. The health is subtracted in between pre and post unless the hook is blocked. PR 149
OnTakeDamageAlive is also only called for players.
SDKHook_OnTakeDamageAlivePost
Triggered after the player took damage.
SDKHook_PreThink
Called before OnGameFrame(), but only for the hooked entity.
SDKHook_PreThinkPost
SDKHook_PostThink
SDKHook_PostThinkPost
SDKHook_Reload
SDKHook_ReloadPost
SDKHook_SetTransmit
SDKHook_ShouldCollide
SDKHook_Spawn
Triggers when the hooked entity is about to spawn. Entity creation and spawn are not the same thing. Some entity properties are not available until the entity spawns.
SDKHook_SpawnPost
Triggers after the hooked entity was spawned.
SDKHook_StartTouch
Triggers when the hooked entity is about to be touched by another entity. Not all entities can trigger/fire touch events. Adjusting collision groups for the entity can fix that.
SDKHook_StartTouchPost
SDKHook_Think
SDKHook_ThinkPost
SDKHook_Touch
SDKHook_TouchPost
SDKHook_TraceAttack
SDKHook_TraceAttackPost
SDKHook_Use
SDKHook_UsePost
SDKHook_VPhysicsUpdate
Triggers when the hooked entity is about to update.
SDKHook_VPhysicsUpdatePost
SDKHook_WeaponCanSwitchTo
SDKHook_WeaponCanSwitchToPost
SDKHook_WeaponCanUse
SDKHook_WeaponCanUsePost
SDKHook_WeaponDrop
Triggers when the hooked weapon is about to be dropped.
Under TF2
When a weapon is dropped in tf2, a new entity is created called tf_dropped_weapon and this new entity is not the same entity as the one that player had equipped nor do they share entity IDs. They share the m_iAccountID property however, which contains the steam ID of the owner of the weapon that dropped it. You cannot prevent weapon drop through this hook in TF2.
SDKHook_WeaponDropPost
Triggers after the hooked weapon was dropped.
SDKHook_WeaponEquip
Triggers when the hooked weapon is about to be equipped.
SDKHook_WeaponEquipPost
Triggers after the hooked weapon was equipped.
SDKHook_WeaponSwitch
Triggers when the hooked weapon is about to be switched for another one.
SDKHook_WeaponSwitchPost
Triggers after the hooked weapon was switched for another one.