More Windows build fix.
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:
61 const char * pClassname = gamehelpers->GetEntityClassname(PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1])));
64 pContext->ThrowNativeError("Hook type not valid for this type of entity (%i).", entity);
68 pContext->ThrowNativeError("Hook type not valid for this type of entity (%s)", pClassname);
78 cell_t Native_HookEx(IPluginContext *pContext, const cell_t *params)
80 int entity = (int)params[1];
81 SDKHookType type = (SDKHookType)params[2];
82 IPluginFunction *callback = pContext->GetFunctionById(params[3]);
83 HookReturn ret = g_Interface.Hook(entity, type, callback);
84 if (ret == HookRet_Successful)
90 cell_t Native_Unhook(IPluginContext *pContext, const cell_t *params)
92 int entity = (int)params[1];
93 SDKHookType type = (SDKHookType)params[2];
94 IPluginFunction *callback = pContext->GetFunctionById(params[3]);
96 for(int i = g_HookList.Count() - 1; i >= 0; i--)
98 if(g_HookList[i].entity == entity && g_HookList[i].type == type && g_HookList[i].callback == callback)
99 g_Interface.Unhook(i);
105 cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
107 // todo: fix code to not require this >.<
108 #if !defined SH_DECL_MANUALEXTERN1
109 pContext->ThrowNativeError("SDKHooks_TakeDamage is not supported on this engine.");
111 CBaseEntity *pVictim = UTIL_GetCBaseEntity(params[1]);
113 return pContext->ThrowNativeError("Invalid entity index %d for victim", params[1]);
115 CBaseEntity *pInflictor = UTIL_GetCBaseEntity(params[2]);
117 return pContext->ThrowNativeError("Invalid entity index %d for inflictor", params[2]);
119 CBaseEntity *pAttacker = NULL;
122 pAttacker = UTIL_GetCBaseEntity(params[3]);
125 return pContext->ThrowNativeError("Invalid entity index %d for attackerr", params[3]);
129 float flDamage = sp_ctof(params[4]);
130 int iDamageType = params[5];
132 CBaseEntity *pWeapon = NULL;
135 pAttacker = UTIL_GetCBaseEntity(params[6]);
138 return pContext->ThrowNativeError("Invalid entity index %d for weapon", params[6]);
142 Vector vecDamageForce = Vector(0.0f, 0.0f, 0.0f);
145 if ((err = pContext->LocalToPhysAddr(params[7], &addr)) != SP_ERROR_NONE)
147 return pContext->ThrowNativeError("Could not read damageForce vector");
150 if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
152 vecDamageForce = Vector(
158 Vector vecDamagePosition = vec3_origin;
159 if ((err = pContext->LocalToPhysAddr(params[8], &addr)) != SP_ERROR_NONE)
161 return pContext->ThrowNativeError("Could not read damagePosition vector");
164 if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
166 vecDamagePosition = Vector(
172 CTakeDamageInfoHack info(pInflictor, pAttacker, flDamage, iDamageType, pWeapon, vecDamageForce, vecDamagePosition);
173 SH_MCALL(pVictim, OnTakeDamage)((CTakeDamageInfoHack &)info);
179 cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
181 // todo: fix code to not require this >.<
182 #if !defined SH_DECL_MANUALEXTERN1
183 pContext->ThrowNativeError("SDKHooks_DropWeapon is not supported on this engine.");
185 CBaseEntity *pPlayer = UTIL_GetCBaseEntity(params[1], true);
187 return pContext->ThrowNativeError("Invalid client index %d", params[1]);
189 CBaseEntity *pWeapon = UTIL_GetCBaseEntity(params[2]);
191 return pContext->ThrowNativeError("Invalid entity index %d for weapon", params[2]);
193 sm_sendprop_info_t spi;
194 IServerUnknown *pUnk = (IServerUnknown *)pWeapon;
195 IServerNetworkable *pNet = pUnk->GetNetworkable();
197 if (!UTIL_FindDataTable(pNet->GetServerClass()->m_pTable, "DT_BaseCombatWeapon", &spi, 0))
198 return pContext->ThrowNativeError("Entity index %d is not a weapon", params[2]);
200 if (!gamehelpers->FindSendPropInfo("CBaseCombatWeapon", "m_hOwnerEntity", &spi))
201 return pContext->ThrowNativeError("Invalid entity index %d for weapon", params[2]);
203 CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pWeapon + spi.actual_offset);
204 if (params[1] != hndl.GetEntryIndex())
205 return pContext->ThrowNativeError("Weapon %d is not owned by client %d", params[2], params[1]);
210 if ((err = pContext->LocalToPhysAddr(params[3], &addr)) != SP_ERROR_NONE)
212 return pContext->ThrowNativeError("Could not read vecTarget vector");
215 if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
224 SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, NULL, NULL);
229 if ((err = pContext->LocalToPhysAddr(params[8], &addr)) != SP_ERROR_NONE)
231 return pContext->ThrowNativeError("Could not read vecVelocity vector");
234 if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
236 vecVelocity = Vector(
243 SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, NULL);
247 SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, &vecVelocity);