From bae7998b9bba7202f8478cc6f96d7bbc948e400f Mon Sep 17 00:00:00 2001 From: richard Date: Wed, 4 Nov 2009 21:37:26 +0100 Subject: [PATCH] Made support for SDK Hooks 1.1 Extension (enabled by default). Comment USE_SDKHOOKS define to use ZR Tools. --- env/include/sdkhooks.inc | 163 +++++++++++++++++++++++++++++++++ src/zombiereloaded.sp | 20 +++- src/zr/antistick.inc | 20 +++- src/zr/damage.inc | 101 ++++++++++++++------ src/zr/napalm.inc | 6 +- src/zr/weapons/restrict.inc | 49 +++++++--- src/zr/weapons/weaponalpha.inc | 20 +++- 7 files changed, 329 insertions(+), 50 deletions(-) create mode 100644 env/include/sdkhooks.inc diff --git a/env/include/sdkhooks.inc b/env/include/sdkhooks.inc new file mode 100644 index 0000000..0bc6463 --- /dev/null +++ b/env/include/sdkhooks.inc @@ -0,0 +1,163 @@ +#if defined _sdkhooks_included + #endinput +#endif +#define _sdkhooks_included + +#define DMG_GENERIC 0 // generic damage was done +#define DMG_CRUSH (1 << 0) // crushed by falling or moving object. + // NOTE: It's assumed crush damage is occurring as a result of physics collision, so no extra physics force is generated by crush damage. + // DON'T use DMG_CRUSH when damaging entities unless it's the result of a physics collision. You probably want DMG_CLUB instead. +#define DMG_BULLET (1 << 1) // shot +#define DMG_SLASH (1 << 2) // cut, clawed, stabbed +#define DMG_BURN (1 << 3) // heat burned +#define DMG_VEHICLE (1 << 4) // hit by a vehicle +#define DMG_FALL (1 << 5) // fell too far +#define DMG_BLAST (1 << 6) // explosive blast damage +#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt +#define DMG_SHOCK (1 << 8) // electric shock +#define DMG_SONIC (1 << 9) // sound pulse shockwave +#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam +#define DMG_PREVENT_PHYSICS_FORCE (1 << 11) // Prevent a physics force +#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death +#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. +#define DMG_DROWN (1 << 14) // Drowning +#define DMG_PARALYZE (1 << 15) // slows affected creature down +#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad +#define DMG_POISON (1 << 17) // blood poisoning - heals over time like drowning damage +#define DMG_RADIATION (1 << 18) // radiation exposure +#define DMG_DROWNRECOVER (1 << 19) // drowning recovery +#define DMG_ACID (1 << 20) // toxic chemicals or acid burns +#define DMG_SLOWBURN (1 << 21) // in an oven +#define DMG_REMOVENORAGDOLL (1 << 22) // with this bit OR'd in, no ragdoll will be created, and the target will be quietly removed. + // use this to kill an entity that you've already got a server-side ragdoll for +#define DMG_PHYSGUN (1 << 23) // Hit by manipulator. Usually doesn't do any damage. +#define DMG_PLASMA (1 << 24) // Shot by Cremator +#define DMG_AIRBOAT (1 << 25) // Hit by the airboat's gun +#define DMG_DISSOLVE (1 << 26) // Dissolving! +#define DMG_BLAST_SURFACE (1 << 27) // A blast on the surface of water that cannot harm things underwater +#define DMG_DIRECT (1 << 28) +#define DMG_BUCKSHOT (1 << 29) // not quite a bullet. Little, rounder, different. + + +enum SDKHookType +{ + SDKHook_EndTouch, + SDKHook_FireBulletsPost, + SDKHook_OnTakeDamage, + SDKHook_OnTakeDamagePost, + SDKHook_PreThink, + SDKHook_PostThink, + SDKHook_SetTransmit, + SDKHook_Spawn, + SDKHook_StartTouch, + SDKHook_Think, + SDKHook_Touch, + SDKHook_TraceAttack, + SDKHook_TraceAttackPost, + SDKHook_WeaponDrop, + SDKHook_WeaponEquip, + SDKHook_WeaponSwitch +} + +funcenum SDKHookCB +{ + // PreThink + // PostThink + public(client), + // Spawn + // Think + public(entity), + // EndTouch + // StartTouch + // Touch + public(entity, other), + // SetTransmit + Action:public(entity, client), + // WeaponDrop + // WeaponEquip + // WeaponSwitch + Action:public(client, weapon), + // OnTakeDamage + Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype), + // OnTakeDamagePost + public(victim, attacker, inflictor, Float:damage, damagetype), + // FireBullets + public(client, shots, String:weaponname[]), + // TraceAttack + Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup), + // TraceAttackPost + public(victim, attacker, inflictor, Float:damage, damagetype, ammotype, hitbox, hitgroup) +} + + +/** + * @brief When an entity is created + * + * @param entity Entity index + * @param classname Class name + * @noreturn + */ +forward OnEntityCreated(entity, const String:classname[]); + +/** + * @brief When an entity is destroyed + * + * @param entity Entity index + * @noreturn + */ +forward OnEntityDestroyed(entity); + +/** + * @brief When the game description is retrieved + * + * @param gameDesc Game description + * @noreturn + */ +forward Action:OnGetGameDescription(String:gameDesc[64]); + +/** + * @brief When the level is initialized + * + * @param mapName Name of the map + * @param mapEntities Entities of the map + * @noreturn + */ +forward Action:OnLevelInit(const String:mapName[], String:mapEntities[2097152]); + +/** + * @brief Hooks an entity + * + * @param entity Entity index + * @param type Type of function to hook + * @param callback Function to call when hook is called + * @noreturn + */ +native SDKHook(entity, SDKHookType:type, SDKHookCB:callback); + +/** + * @brief Unhooks an entity + * + * @param entity Entity index + * @param type Type of function to unhook + * @param callback Callback function to unhook + * @noreturn + */ +native SDKUnhook(entity, SDKHookType:type, SDKHookCB:callback); + +/** Do Not Edit Below This Line **/ + +public Extension:__ext_sdkhooks = +{ + name = "sdkhooks", + file = "sdkhooks.ext", +#if defined AUTOLOAD_EXTENSIONS + autoload = 1, +#else + autoload = 0, +#endif +#if defined REQUIRE_EXTENSIONS + required = 1, +#else + required = 0, +#endif +}; \ No newline at end of file diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index d6056bc..57f8ec1 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -25,17 +25,31 @@ * ============================================================================ */ +// Comment to use ZR Tools Extension, otherwise SDK Hooks Extension will be used. +#define USE_SDKHOOKS + #pragma semicolon 1 #include #include #include #include -#include + +#if defined USE_SDKHOOKS + #include + + #define ACTION_CONTINUE Plugin_Continue + #define ACTION_HANDLED Plugin_Handled +#else + #include + + #define ACTION_CONTINUE ZRTools_Continue + #define ACTION_HANDLED ZRTools_Handled +#endif #define VERSION "3.0.0-b2-dev" -// Comment this line to exclude version info command. Temporary solution until -// there is a windows script for updating hgversion.h.inc. +// Comment this line to exclude version info command. Enable this if you have +// the repository and HG installed (Mercurial or TortoiseHG). #define ADD_VERSION_INFO // Header includes. diff --git a/src/zr/antistick.inc b/src/zr/antistick.inc index 8e8de79..191027b 100644 --- a/src/zr/antistick.inc +++ b/src/zr/antistick.inc @@ -130,7 +130,14 @@ AntiStickLoad() AntiStickClientInit(client) { // Hook "StartTouch" and "EndTouch" on client. - g_iStartTouchHookID[client] = ZRTools_HookStartTouch(client, AntiStickStartTouch); + #if defined USE_SDKHOOKS + SDKHook(client, SDKHook_StartTouch, AntiStickStartTouch); + + // Set dummy value so it think it's hooked. + g_iStartTouchHookID[client] = 1; + #else + g_iStartTouchHookID[client] = ZRTools_HookStartTouch(client, AntiStickStartTouch); + #endif } /** @@ -143,7 +150,12 @@ AntiStickOnClientDisconnect(client) // Unhook "StartTouch" callback, and reset variable. if (g_iStartTouchHookID[client] != -1) { - ZRTools_UnhookStartTouch(g_iStartTouchHookID[client]); + #if defined USE_SDKHOOKS + SDKUnhook(client, SDKHook_StartTouch, AntiStickStartTouch); + #else + ZRTools_UnhookStartTouch(g_iStartTouchHookID[client]); + #endif + g_iStartTouchHookID[client] = -1; } } @@ -268,7 +280,11 @@ stock AntiStickSetModelHullWidth(client, const String:model[] = "", Float:hull_w * @param client The client index. * @param entity The entity index of the entity being touched. */ +#if defined USE_SDKHOOKS +public AntiStickStartTouch(client, entity) +#else public ZRTools_Action:AntiStickStartTouch(client, entity) +#endif { // If antistick is disabled, then stop. new bool:antistick = GetConVarBool(g_hCvarsList[CVAR_ANTISTICK]); diff --git a/src/zr/damage.inc b/src/zr/damage.inc index 1919db5..6d7d194 100644 --- a/src/zr/damage.inc +++ b/src/zr/damage.inc @@ -25,9 +25,19 @@ * ============================================================================ */ -/** - * @endsection - */ +#if defined USE_SDKHOOKS + /** + * @section Counter Strike: Source specific damage flags. + */ + #define DMG_CSS_FALL (DMG_FALL) // Client was damaged by falling. + #define DMG_CSS_BLAST (DMG_BLAST) // Client was damaged by explosion. + #define DMG_CSS_BURN (DMG_DIRECT) // Client was damaged by fire. + #define DMG_CSS_BULLET (DMG_NEVERGIB) // Client was shot or knifed. + #define DMG_CSS_HEADSHOT (1 << 30) // Client was shot in the head. + /** + * @endsection + */ +#endif /** * @section Suicide intercept defines. @@ -88,8 +98,17 @@ DamageOnCommandsHook() DamageClientInit(client) { // Hook damage callbacks. - g_iDamageTraceAttackHookID[client] = ZRTools_HookTraceAttack(client, DamageTraceAttack); - g_iDamageOnTakeDamageHookID[client] = ZRTools_HookOnTakeDamage(client, DamageOnTakeDamage); + #if defined USE_SDKHOOKS + SDKHook(client, SDKHook_TraceAttack, DamageTraceAttack); + SDKHook(client, SDKHook_OnTakeDamage, DamageOnTakeDamage); + + // Set dummy values so it think it's hooked. + g_iDamageTraceAttackHookID[client] = 1; + g_iDamageOnTakeDamageHookID[client] = 1; + #else + g_iDamageTraceAttackHookID[client] = ZRTools_HookTraceAttack(client, DamageTraceAttack); + g_iDamageOnTakeDamageHookID[client] = ZRTools_HookOnTakeDamage(client, DamageOnTakeDamage); + #endif } /** @@ -103,13 +122,23 @@ DamageOnClientDisconnect(client) if (g_iDamageTraceAttackHookID[client] != -1) { - ZRTools_UnhookTraceAttack(g_iDamageTraceAttackHookID[client]); + #if defined USE_SDKHOOKS + SDKUnhook(client, SDKHook_TraceAttack, DamageTraceAttack); + #else + ZRTools_UnhookTraceAttack(g_iDamageTraceAttackHookID[client]); + #endif + g_iDamageTraceAttackHookID[client] = -1; } if (g_iDamageOnTakeDamageHookID[client] != -1) { - ZRTools_UnhookOnTakeDamage(g_iDamageOnTakeDamageHookID[client]); + #if defined USE_SDKHOOKS + SDKUnhook(client, SDKHook_OnTakeDamage, DamageOnTakeDamage); + #else + ZRTools_UnhookOnTakeDamage(g_iDamageOnTakeDamageHookID[client]); + #endif + g_iDamageOnTakeDamageHookID[client] = -1; } } @@ -139,18 +168,22 @@ DamageOnClientInfected(client, bool:motherinfect) * @return Return ZRTools_Handled to stop bullet from hitting client. * ZRTools_Continue to allow bullet to hit client. */ +#if defined USE_SDKHOOKS +public Action:DamageTraceAttack(client, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup) +#else public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damage, hitbox, hitgroup) +#endif { // If attacker isn't valid, then stop. if (!ZRIsClientValid(attacker)) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // If client is attacking himself, then stop. if(attacker == client) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // Get zombie flag for each client. @@ -164,11 +197,11 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag new bool:damageblockff = GetConVarBool(g_hCvarsList[CVAR_DAMAGE_BLOCK_FF]); if (!damageblockff) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // Stop bullet from hurting client. - return ZRTools_Handled; + return ACTION_HANDLED; } // Here we know that attacker and client are different teams. @@ -177,7 +210,7 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag if (InfectIsClientHuman(client)) { // Allow damage. - return ZRTools_Continue; + return ACTION_CONTINUE; } // If damage hitgroups cvar is disabled, then allow damage. @@ -185,7 +218,7 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag if (!damagehitgroups) { // Allow damage. - return ZRTools_Continue; + return ACTION_CONTINUE; } // If damage is disabled for this hitgroup, then stop. @@ -195,18 +228,18 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag if (index == -1) { // Allow damage. - return ZRTools_Continue; + return ACTION_CONTINUE; } new bool:candamage = HitgroupsCanDamage(index); if (!candamage) { // Stop bullet from hurting client. - return ZRTools_Handled; + return ACTION_HANDLED; } // Allow damage. - return ZRTools_Continue; + return ACTION_CONTINUE; } /** @@ -222,7 +255,11 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag * @return Return ZRTools_Handled to stop the damage to client. * ZRTools_Continue to allow damage to client. */ +#if defined USE_SDKHOOKS +public Action:DamageOnTakeDamage(client, &attacker, &inflictor, &Float:damage, &damagetype) +#else public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:damage, damagetype, ammotype) +#endif { // Get classname of the inflictor. decl String:classname[64]; @@ -231,7 +268,7 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama // If entity is a trigger, then allow damage. (Map is damaging client) if (StrContains(classname, "trigger") > -1) { - return ZRTools_Continue; + return ACTION_CONTINUE; } new action; @@ -239,10 +276,14 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama // Forward this hook to another module an return (or not) what it wants. action = NapalmOnTakeDamage(client, damagetype); - // If the napalm module wants to return here, then return the int casted into the ZRTools_Action type. + // If the napalm module wants to return here, then return the int casted into the action type. if (action > -1) { - return ZRTools_Action:action; + #if defined USE_SDKHOOKS + return Action:action; + #else + return ZRTools_Action:action; + #endif } // Client was shot or knifed. @@ -251,7 +292,7 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama // If attacker isn't valid, then allow damage. if (!ZRIsClientValid(attacker)) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // Get zombie flag for each client. @@ -261,7 +302,7 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama // If client and attacker are on the same team, then let CS:S handle the rest. if (clientzombie == attackerzombie) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // We know that clientzombie is the opposite of attacker zombie. @@ -269,7 +310,7 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama // If the client is a zombie, then allow damage. if (clientzombie) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // Client is about to be infected, re-add HP so they aren't killed by knife. @@ -277,7 +318,7 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama SetEntityHealth(client, health + RoundToNearest(damage)); // Allow damage. - return ZRTools_Continue; + return ACTION_CONTINUE; } // Client was damaged by explosion. else if (damagetype & DMG_CSS_BLAST) @@ -286,23 +327,23 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama new bool:damageblockblast = GetConVarBool(g_hCvarsList[CVAR_DAMAGE_BLOCK_BLAST]); if (!damageblockblast) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // If attacker isn't valid, then allow damage. if (!ZRIsClientValid(attacker)) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // If client is a zombie, then allow damage. if (InfectIsClientInfected(client)) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // Stop damage. - return ZRTools_Handled; + return ACTION_HANDLED; } // Client was damaged by falling. else if (damagetype & DMG_CSS_FALL) @@ -311,15 +352,15 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama new bool:blockfalldamage = ClassGetNoFallDamage(client); if (!blockfalldamage) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // Stop damage. - return ZRTools_Handled; + return ACTION_HANDLED; } // Allow damage. - return ZRTools_Continue; + return ACTION_CONTINUE; } /** diff --git a/src/zr/napalm.inc b/src/zr/napalm.inc index f5eaf66..8648874 100644 --- a/src/zr/napalm.inc +++ b/src/zr/napalm.inc @@ -86,7 +86,11 @@ NapalmOnTakeDamage(client, damagetype) ExtinguishEntity(client); // Stop the last bit of inflicted burn damage. - return _:ZRTools_Handled; + #if defined USE_SDKHOOKS + return _:Plugin_Handled; + #else + return _:ZRTools_Handled; + #endif } } } diff --git a/src/zr/weapons/restrict.inc b/src/zr/weapons/restrict.inc index 4502f5a..98a1f97 100644 --- a/src/zr/weapons/restrict.inc +++ b/src/zr/weapons/restrict.inc @@ -138,7 +138,17 @@ RestrictOnCommandsCreate() RestrictClientInit(client) { // Hook "Weapon_CanUse" on client. - g_iCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse); + #if defined USE_SDKHOOKS + SDKHook(client, SDKHook_WeaponEquip, RestrictCanUse); + + // Note: Do we need to use WeaponSwitch too? On infection all weapons + // are removed anyways. + + // Set dummy value so it think it's hooked. + g_iCanUseHookID[client] = 1; + #else + g_iCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse); + #endif // Reset block weapons flag. g_bRestrictBlockWeapon[client] = false; @@ -154,7 +164,12 @@ RestrictOnClientDisconnect(client) // Unhook "Weapon_CanUse" callback, and reset variable. if (g_iCanUseHookID[client] != -1) { - ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]); + #if defined USE_SDKHOOKS + SDKUnhook(client, SDKHook_WeaponEquip, RestrictCanUse); + #else + ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]); + #endif + g_iCanUseHookID[client] = -1; } } @@ -167,8 +182,14 @@ RestrictOnClientDisconnect(client) RestrictOnClientSpawn(client) { // Re-hook "canuse" on client. - ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]); - g_iCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse); + #if defined USE_SDKHOOKS + SDKUnhook(client, SDKHook_WeaponEquip, RestrictCanUse); // <--- What happens if it's not already hooked??? + SDKHook(client, SDKHook_WeaponEquip, RestrictCanUse); + g_iCanUseHookID[client] = 1; + #else + ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]); + g_iCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse); + #endif // H4x. Unfortunately I can't disable this flag early enough for CS:S to give start USP/Glock. // So I have to give BOOTLEG weapons. (Sorry Valve) @@ -583,7 +604,11 @@ stock bool:RestrictIsTypeUniform(bool:restricted, index) * @return Return ZRTools_Handled to stop weapon pickup. * ZRTools_Continue to allow weapon pickup. */ +#if defined USE_SDKHOOKS +public Action:RestrictCanUse(client, weapon) +#else public ZRTools_Action:RestrictCanUse(client, weapon) +#endif { new String:weaponentity[WEAPONS_MAX_LENGTH]; GetEdictClassname(weapon, weaponentity, sizeof(weaponentity)); @@ -591,33 +616,33 @@ public ZRTools_Action:RestrictCanUse(client, weapon) // If weapon is a knife, then allow pickup. if (StrEqual(weaponentity, "weapon_knife")) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // If the player is a zombie, then prevent pickup. if (InfectIsClientInfected(client)) { - return ZRTools_Handled; + return ACTION_HANDLED; } // If client is flagged for not picking up weapons, then stop. if (g_bRestrictBlockWeapon[client]) { - return ZRTools_Handled; + return ACTION_HANDLED; } // If weapons module is disabled, then stop. new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]); if (!weapons) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // If restrict module is disabled, then stop. new bool:restrict = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_RESTRICT]); if (!restrict) { - return ZRTools_Continue; + return ACTION_CONTINUE; } // If the weapon is restricted, then prevent pickup. @@ -628,20 +653,20 @@ public ZRTools_Action:RestrictCanUse(client, weapon) if (weaponindex == -1) { // Allow pickup. - return ZRTools_Continue; + return ACTION_CONTINUE; } // If weapon is restricted, then stop. if (RestrictIsWeaponRestricted(weaponindex)) { - return ZRTools_Handled; + return ACTION_HANDLED; } // Forward event to weapons module. WeaponsOnItemPickup(client, weapon); // Allow pickup. - return ZRTools_Continue; + return ACTION_CONTINUE; } /** diff --git a/src/zr/weapons/weaponalpha.inc b/src/zr/weapons/weaponalpha.inc index f428b9f..2db8ce8 100644 --- a/src/zr/weapons/weaponalpha.inc +++ b/src/zr/weapons/weaponalpha.inc @@ -43,7 +43,14 @@ new g_iWeaponDropHookID[MAXPLAYERS + 1] = {-1, ...}; WeaponAlphaClientInit(client) { // Hook "Weapon_Drop" on client. - g_iWeaponDropHookID[client] = ZRTools_HookWeapon_Drop(client, WeaponAlphaDrop); + #if defined USE_SDKHOOKS + SDKHook(client, SDKHook_WeaponDrop, WeaponAlphaDrop); + + // Set dummy value so it think it's hooked. + g_iWeaponDropHookID[client] = 1; + #else + g_iWeaponDropHookID[client] = ZRTools_HookWeapon_Drop(client, WeaponAlphaDrop); + #endif } /** @@ -56,7 +63,12 @@ WeaponAlphaOnClientDisconnect(client) // Unhook "Weapon_Drop" callback, and reset variable. if (g_iWeaponDropHookID[client] != -1) { - ZRTools_UnhookWeapon_Drop(g_iWeaponDropHookID[client]); + #if defined USE_SDKHOOKS + SDKUnhook(client, SDKHook_WeaponDrop, WeaponAlphaDrop); + #else + ZRTools_UnhookWeapon_Drop(g_iWeaponDropHookID[client]); + #endif + g_iWeaponDropHookID[client] = -1; } } @@ -83,7 +95,11 @@ WeaponAlphaOnItemPickupPost(client, weapon) * @param client The client index. * @param weapon The weapon index. */ +#if defined USE_SDKHOOKS +public Action:WeaponAlphaDrop(client, weapon) +#else public ZRTools_Action:WeaponAlphaDrop(client, weapon) +#endif { // If weapon isn't a valid entity, then stop. if (weapon < MaxClients)