Updated for latest hl2sdk-dota changes.
3 * =============================================================================
4 * Source SDK Hooks Extension
5 * Copyright (C) 2010-2012 Nicholas Hastings
6 * Copyright (C) 2009-2010 Erik Minekus
7 * =============================================================================
9 * This program is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, version 3.0, as published by the
11 * Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
21 * As a special exception, AlliedModders LLC gives you permission to link the
22 * code of this program (as well as its derivative works) to "Half-Life 2," the
23 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
24 * by the Valve Corporation. You must obey the GNU General Public License in
25 * all respects for all other code used. Additionally, AlliedModders LLC grants
26 * this exception to all derivative works. AlliedModders LLC defines further
27 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
28 * or <http://www.sourcemod.net/license.php>.
33 #include "extension.h"
35 #include <compat_wrappers.h>
37 #if defined SH_DECL_MANUALEXTERN1
38 SH_DECL_MANUALEXTERN1(OnTakeDamage, int, CTakeDamageInfoHack &);
39 SH_DECL_MANUALEXTERN3_void(Weapon_Drop, CBaseCombatWeapon *, const Vector *, const Vector *);
42 cell_t Native_Hook(IPluginContext *pContext, const cell_t *params)
44 int entity = (int)params[1];
45 SDKHookType type = (SDKHookType)params[2];
46 IPluginFunction *callback = pContext->GetFunctionById(params[3]);
47 HookReturn ret = g_Interface.Hook(entity, type, callback);
50 case HookRet_InvalidEntity:
51 pContext->ThrowNativeError("Entity %d is invalid", entity);
53 case HookRet_InvalidHookType:
54 pContext->ThrowNativeError("Invalid hook type specified");
56 case HookRet_NotSupported:
57 pContext->ThrowNativeError("Hook type not supported on this game");
59 case HookRet_BadEntForHookType:
60 pContext->ThrowNativeError("Hook type not valid for this type of entity (%s)",
61 PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1]))->GetClassName()
69 cell_t Native_HookEx(IPluginContext *pContext, const cell_t *params)
71 int entity = (int)params[1];
72 SDKHookType type = (SDKHookType)params[2];
73 IPluginFunction *callback = pContext->GetFunctionById(params[3]);
74 HookReturn ret = g_Interface.Hook(entity, type, callback);
75 if (ret == HookRet_Successful)
81 cell_t Native_Unhook(IPluginContext *pContext, const cell_t *params)
83 int entity = (int)params[1];
84 SDKHookType type = (SDKHookType)params[2];
85 IPluginFunction *callback = pContext->GetFunctionById(params[3]);
87 for(int i = g_HookList.Count() - 1; i >= 0; i--)
89 if(g_HookList[i].entity == entity && g_HookList[i].type == type && g_HookList[i].callback == callback)
90 g_Interface.Unhook(i);
96 cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
98 // todo: fix code to not require this >.<
99 #if !defined SH_DECL_MANUALEXTERN1
100 pContext->ThrowNativeError("SDKHooks_TakeDamage is not supported on this engine.");
102 CBaseEntity *pVictim = UTIL_GetCBaseEntity(params[1]);
104 return pContext->ThrowNativeError("Invalid entity index %d for victim", params[1]);
106 CBaseEntity *pInflictor = UTIL_GetCBaseEntity(params[2]);
108 return pContext->ThrowNativeError("Invalid entity index %d for inflictor", params[2]);
110 CBaseEntity *pAttacker = NULL;
113 pAttacker = UTIL_GetCBaseEntity(params[3]);
116 return pContext->ThrowNativeError("Invalid entity index %d for attackerr", params[3]);
120 float flDamage = sp_ctof(params[4]);
121 int iDamageType = params[5];
123 CBaseEntity *pWeapon = NULL;
126 pAttacker = UTIL_GetCBaseEntity(params[6]);
129 return pContext->ThrowNativeError("Invalid entity index %d for weapon", params[6]);
133 Vector vecDamageForce = Vector(0.0f, 0.0f, 0.0f);
136 if ((err = pContext->LocalToPhysAddr(params[7], &addr)) != SP_ERROR_NONE)
138 return pContext->ThrowNativeError("Could not read damageForce vector");
141 if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
143 vecDamageForce = Vector(
149 Vector vecDamagePosition = vec3_origin;
150 if ((err = pContext->LocalToPhysAddr(params[8], &addr)) != SP_ERROR_NONE)
152 return pContext->ThrowNativeError("Could not read damagePosition vector");
155 if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
157 vecDamagePosition = Vector(
163 CTakeDamageInfoHack info(pInflictor, pAttacker, flDamage, iDamageType, pWeapon, vecDamageForce, vecDamagePosition);
164 SH_MCALL(pVictim, OnTakeDamage)((CTakeDamageInfoHack &)info);
170 cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
172 // todo: fix code to not require this >.<
173 #if !defined SH_DECL_MANUALEXTERN1
174 pContext->ThrowNativeError("SDKHooks_DropWeapon is not supported on this engine.");
176 CBaseEntity *pPlayer = UTIL_GetCBaseEntity(params[1], true);
178 return pContext->ThrowNativeError("Invalid client index %d", params[1]);
180 CBaseEntity *pWeapon = UTIL_GetCBaseEntity(params[2]);
182 return pContext->ThrowNativeError("Invalid entity index %d for weapon", params[2]);
184 sm_sendprop_info_t spi;
185 IServerUnknown *pUnk = (IServerUnknown *)pWeapon;
186 IServerNetworkable *pNet = pUnk->GetNetworkable();
188 if (!UTIL_FindDataTable(pNet->GetServerClass()->m_pTable, "DT_BaseCombatWeapon", &spi, 0))
189 return pContext->ThrowNativeError("Entity index %d is not a weapon", params[2]);
191 if (!gamehelpers->FindSendPropInfo("CBaseCombatWeapon", "m_hOwnerEntity", &spi))
192 return pContext->ThrowNativeError("Invalid entity index %d for weapon", params[2]);
194 CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pWeapon + spi.actual_offset);
195 if (params[1] != hndl.GetEntryIndex())
196 return pContext->ThrowNativeError("Weapon %d is not owned by client %d", params[2], params[1]);
201 if ((err = pContext->LocalToPhysAddr(params[3], &addr)) != SP_ERROR_NONE)
203 return pContext->ThrowNativeError("Could not read vecTarget vector");
206 if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
215 SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, NULL, NULL);
220 if ((err = pContext->LocalToPhysAddr(params[8], &addr)) != SP_ERROR_NONE)
222 return pContext->ThrowNativeError("Could not read vecVelocity vector");
225 if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
227 vecVelocity = Vector(
234 SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, NULL);
238 SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, &vecVelocity);