extensions/sdkhooks/extension.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Mon Jul 29 10:03:18 2013 -0400 (2013-07-29)
changeset 3960 d50b36dc6821
parent 3819 d17aed3d46bf
child 3961 0dc477c29792
permissions -rw-r--r--
Updated for latest hl2sdk-dota changes.
skamonkey@3767
     1
/**
skamonkey@3767
     2
 * vim: set ts=4 :
skamonkey@3767
     3
 * =============================================================================
skamonkey@3767
     4
 * Source SDK Hooks Extension
skamonkey@3767
     5
 * Copyright (C) 2010-2012 Nicholas Hastings
skamonkey@3767
     6
 * Copyright (C) 2009-2010 Erik Minekus
skamonkey@3767
     7
 * =============================================================================
skamonkey@3767
     8
 *
skamonkey@3767
     9
 * This program is free software; you can redistribute it and/or modify it under
skamonkey@3767
    10
 * the terms of the GNU General Public License, version 3.0, as published by the
skamonkey@3767
    11
 * Free Software Foundation.
skamonkey@3767
    12
 * 
skamonkey@3767
    13
 * This program is distributed in the hope that it will be useful, but WITHOUT
skamonkey@3767
    14
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
skamonkey@3767
    15
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
skamonkey@3767
    16
 * details.
skamonkey@3767
    17
 *
skamonkey@3767
    18
 * You should have received a copy of the GNU General Public License along with
skamonkey@3767
    19
 * this program.  If not, see <http://www.gnu.org/licenses/>.
skamonkey@3767
    20
 *
skamonkey@3767
    21
 * As a special exception, AlliedModders LLC gives you permission to link the
skamonkey@3767
    22
 * code of this program (as well as its derivative works) to "Half-Life 2," the
skamonkey@3767
    23
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
skamonkey@3767
    24
 * by the Valve Corporation.  You must obey the GNU General Public License in
skamonkey@3767
    25
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
skamonkey@3767
    26
 * this exception to all derivative works.  AlliedModders LLC defines further
skamonkey@3767
    27
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
skamonkey@3767
    28
 * or <http://www.sourcemod.net/license.php>.
skamonkey@3767
    29
 *
skamonkey@3767
    30
 * Version: $Id$
skamonkey@3767
    31
 */
skamonkey@3767
    32
januk@3774
    33
#include <sourcemod_version.h>
skamonkey@3767
    34
#include "extension.h"
skamonkey@3767
    35
#include "compat_wrappers.h"
skamonkey@3767
    36
#include "macros.h"
skamonkey@3767
    37
#include "natives.h"
skamonkey@3767
    38
#include <sm_platform.h>
skamonkey@3767
    39
#include <const.h>
skamonkey@3767
    40
skamonkey@3767
    41
skamonkey@3767
    42
//#define SDKHOOKSDEBUG
skamonkey@3767
    43
skamonkey@3767
    44
/**
skamonkey@3767
    45
 * Globals
skamonkey@3767
    46
 */
skamonkey@3767
    47
skamonkey@3767
    48
// Order MUST match SDKHookType enum
skamonkey@3767
    49
HookTypeData g_HookTypes[SDKHook_MAXHOOKS] = 
skamonkey@3767
    50
{
skamonkey@3767
    51
//   Hook name                DT required               Supported (always false til later)
skamonkey@3767
    52
	{"EndTouch",              "",                       false},
skamonkey@3767
    53
	{"FireBulletsPost",       "",                       false},
skamonkey@3767
    54
	{"OnTakeDamage",          "",                       false},
skamonkey@3767
    55
	{"OnTakeDamagePost",      "",                       false},
skamonkey@3767
    56
	{"PreThink",              "DT_BasePlayer",          false},
skamonkey@3767
    57
	{"PostThink",             "DT_BasePlayer",          false},
skamonkey@3767
    58
	{"SetTransmit",           "",                       false},
skamonkey@3767
    59
	{"Spawn",                 "",                       false},
skamonkey@3767
    60
	{"StartTouch",            "",                       false},
skamonkey@3767
    61
	{"Think",                 "",                       false},
skamonkey@3767
    62
	{"Touch",                 "",                       false},
skamonkey@3767
    63
	{"TraceAttack",           "",                       false},
skamonkey@3767
    64
	{"TraceAttackPost",       "",                       false},
skamonkey@3767
    65
	{"WeaponCanSwitchTo",     "DT_BaseCombatCharacter", false},
skamonkey@3767
    66
	{"WeaponCanUse",          "DT_BaseCombatCharacter", false},
skamonkey@3767
    67
	{"WeaponDrop",            "DT_BaseCombatCharacter", false},
skamonkey@3767
    68
	{"WeaponEquip",           "DT_BaseCombatCharacter", false},
skamonkey@3767
    69
	{"WeaponSwitch",          "DT_BaseCombatCharacter", false},
skamonkey@3767
    70
	{"ShouldCollide",         "",                       false},
skamonkey@3767
    71
	{"PreThinkPost",          "DT_BasePlayer",          false},
skamonkey@3767
    72
	{"PostThinkPost",         "DT_BasePlayer",          false},
skamonkey@3767
    73
	{"ThinkPost",             "",                       false},
skamonkey@3767
    74
	{"EndTouchPost",          "",                       false},
skamonkey@3767
    75
	{"GroundEntChangedPost",  "",                       false},
skamonkey@3767
    76
	{"SpawnPost",             "",                       false},
skamonkey@3767
    77
	{"StartTouchPost",        "",                       false},
skamonkey@3767
    78
	{"TouchPost",             "",                       false},
skamonkey@3767
    79
	{"VPhysicsUpdate",        "",                       false},
skamonkey@3767
    80
	{"VPhysicsUpdatePost",    "",                       false},
skamonkey@3767
    81
	{"WeaponCanSwitchToPost", "DT_BaseCombatCharacter", false},
skamonkey@3767
    82
	{"WeaponCanUsePost",      "DT_BaseCombatCharacter", false},
skamonkey@3767
    83
	{"WeaponDropPost",        "DT_BaseCombatCharacter", false},
skamonkey@3767
    84
	{"WeaponEquipPost",       "DT_BaseCombatCharacter", false},
skamonkey@3767
    85
	{"WeaponSwitchPost",      "DT_BaseCombatCharacter", false},
skamonkey@3767
    86
	{"Use",                   "",                       false},
skamonkey@3767
    87
	{"UsePost",               "",                       false},
skamonkey@3767
    88
	{"Reload",                "DT_BaseCombatWeapon",    false},
skamonkey@3767
    89
	{"ReloadPost",            "DT_BaseCombatWeapon",    false},
skamonkey@3767
    90
	{"GetMaxHealth",          "",                       false},
skamonkey@3767
    91
};
skamonkey@3767
    92
skamonkey@3767
    93
SDKHooks g_Interface;
skamonkey@3767
    94
SMEXT_LINK(&g_Interface);
skamonkey@3767
    95
skamonkey@3767
    96
CGlobalVars *gpGlobals;
skamonkey@3767
    97
CUtlVector<HookList> g_HookList;
skamonkey@3767
    98
skamonkey@3767
    99
CBitVec<NUM_ENT_ENTRIES> m_EntityExists;
skamonkey@3767
   100
skamonkey@3767
   101
IBinTools *g_pBinTools = NULL;
skamonkey@3767
   102
ICvar *icvar = NULL;
skamonkey@3767
   103
skamonkey@3767
   104
// global hooks and forwards
skamonkey@3767
   105
IForward *g_pOnEntityCreated = NULL;
skamonkey@3767
   106
IForward *g_pOnEntityDestroyed = NULL;
skamonkey@3767
   107
skamonkey@3767
   108
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   109
int g_hookOnGetGameDescription = 0;
skamonkey@3767
   110
IForward *g_pOnGetGameNameDescription = NULL;
skamonkey@3767
   111
#endif
skamonkey@3767
   112
skamonkey@3767
   113
int g_hookOnGetMapEntitiesString = 0;
skamonkey@3767
   114
int g_hookOnLevelInit = 0;
skamonkey@3767
   115
IForward *g_pOnLevelInit = NULL;
skamonkey@3767
   116
skamonkey@3767
   117
IGameConfig *g_pGameConf = NULL;
skamonkey@3767
   118
skamonkey@3767
   119
char g_szMapEntities[2097152];
skamonkey@3767
   120
skamonkey@3767
   121
skamonkey@3767
   122
/**
skamonkey@3767
   123
 * IServerGameDLL & IVEngineServer Hooks
skamonkey@3767
   124
 */
skamonkey@3767
   125
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, 0, bool, const char *, const char *, const char *, const char *, bool, bool);
skamonkey@3767
   126
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   127
SH_DECL_HOOK0(IServerGameDLL, GetGameDescription, SH_NOATTRIB, 0, const char *);
skamonkey@3767
   128
#endif
skamonkey@3767
   129
SH_DECL_HOOK0(IVEngineServer, GetMapEntitiesString, SH_NOATTRIB, 0, const char *);
skamonkey@3767
   130
skamonkey@3767
   131
skamonkey@3767
   132
/**
skamonkey@3767
   133
 * CBaseEntity Hooks
skamonkey@3767
   134
 */
skamonkey@3767
   135
SH_DECL_MANUALHOOK1_void(EndTouch, 0, 0, 0, CBaseEntity *);
skamonkey@3767
   136
SH_DECL_MANUALHOOK1_void(FireBullets, 0, 0, 0, FireBulletsInfo_t const&);
skamonkey@3767
   137
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   138
SH_DECL_MANUALHOOK0(GetMaxHealth, 0, 0, 0, int);
skamonkey@3767
   139
#endif
skamonkey@3767
   140
SH_DECL_MANUALHOOK0_void(GroundEntChanged, 0, 0, 0);
skamonkey@3767
   141
SH_DECL_MANUALHOOK1(OnTakeDamage, 0, 0, 0, int, CTakeDamageInfoHack &);
skamonkey@3767
   142
SH_DECL_MANUALHOOK0_void(PreThink, 0, 0, 0);
skamonkey@3767
   143
SH_DECL_MANUALHOOK0_void(PostThink, 0, 0, 0);
skamonkey@3767
   144
SH_DECL_MANUALHOOK0(Reload, 0, 0, 0, bool);
skamonkey@3767
   145
SH_DECL_MANUALHOOK2_void(SetTransmit, 0, 0, 0, CCheckTransmitInfo *, bool);
skamonkey@3767
   146
SH_DECL_MANUALHOOK2(ShouldCollide, 0, 0, 0, bool, int, int);
skamonkey@3767
   147
SH_DECL_MANUALHOOK0_void(Spawn, 0, 0, 0);
skamonkey@3767
   148
SH_DECL_MANUALHOOK1_void(StartTouch, 0, 0, 0, CBaseEntity *);
skamonkey@3767
   149
SH_DECL_MANUALHOOK0_void(Think, 0, 0, 0);
skamonkey@3767
   150
SH_DECL_MANUALHOOK1_void(Touch, 0, 0, 0, CBaseEntity *);
skamonkey@3767
   151
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
skamonkey@3767
   152
SH_DECL_MANUALHOOK4_void(TraceAttack, 0, 0, 0, CTakeDamageInfoHack &, const Vector &, CGameTrace *, void *);
skamonkey@3767
   153
#else
skamonkey@3767
   154
SH_DECL_MANUALHOOK3_void(TraceAttack, 0, 0, 0, CTakeDamageInfoHack &, const Vector &, CGameTrace *);
skamonkey@3767
   155
#endif
skamonkey@3767
   156
SH_DECL_MANUALHOOK4_void(Use, 0, 0, 0, CBaseEntity *, CBaseEntity *, USE_TYPE, float);
skamonkey@3767
   157
SH_DECL_MANUALHOOK1_void(VPhysicsUpdate, 0, 0, 0, IPhysicsObject *);
skamonkey@3767
   158
SH_DECL_MANUALHOOK1(Weapon_CanSwitchTo, 0, 0, 0, bool, CBaseCombatWeapon *);
skamonkey@3767
   159
SH_DECL_MANUALHOOK1(Weapon_CanUse, 0, 0, 0, bool, CBaseCombatWeapon *);
skamonkey@3767
   160
SH_DECL_MANUALHOOK3_void(Weapon_Drop, 0, 0, 0, CBaseCombatWeapon *, const Vector *, const Vector *);
skamonkey@3767
   161
SH_DECL_MANUALHOOK1_void(Weapon_Equip, 0, 0, 0, CBaseCombatWeapon *);
skamonkey@3767
   162
SH_DECL_MANUALHOOK2(Weapon_Switch, 0, 0, 0, bool, CBaseCombatWeapon *, int);
skamonkey@3767
   163
skamonkey@3767
   164
skamonkey@3767
   165
/**
skamonkey@3767
   166
 * Forwards
skamonkey@3767
   167
 */
skamonkey@3767
   168
bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
skamonkey@3767
   169
{
skamonkey@3767
   170
	char buffer[256];
skamonkey@3767
   171
	g_pSM->BuildPath(Path_SM, buffer, sizeof(buffer)-1, "/extensions/sdkhooks.ext." PLATFORM_LIB_EXT);
skamonkey@3767
   172
	if (libsys->PathExists(buffer) && libsys->IsPathFile(buffer))
skamonkey@3767
   173
	{
skamonkey@3767
   174
		g_pSM->Format(error, maxlength-1, "SDKHooks 2.x cannot load while old version (sdkhooks.ext." PLATFORM_LIB_EXT ") is still in extensions dir");
skamonkey@3767
   175
		return false;
skamonkey@3767
   176
	}
skamonkey@3767
   177
skamonkey@3767
   178
	g_pSM->BuildPath(Path_SM, buffer, sizeof(buffer)-1, "/gamedata/sdkhooks.games.txt");
skamonkey@3767
   179
	if (libsys->PathExists(buffer) && libsys->IsPathFile(buffer))
skamonkey@3767
   180
	{
skamonkey@3767
   181
		g_pSM->Format(error, maxlength-1, "SDKHooks 2.x cannot load while old gamedata file (sdkhooks.games.txt) is still in gamedata dir");
skamonkey@3767
   182
		return false;
skamonkey@3767
   183
	}
skamonkey@3767
   184
skamonkey@3767
   185
	sharesys->AddDependency(myself, "bintools.ext", true, true);
skamonkey@3767
   186
	sharesys->AddNatives(myself, g_Natives);
skamonkey@3767
   187
	sharesys->RegisterLibrary(myself, "sdkhooks");
skamonkey@3767
   188
	sharesys->AddCapabilityProvider(myself, this, "SDKHook_DmgCustomInOTD");
skamonkey@3767
   189
	sharesys->AddCapabilityProvider(myself, this, "SDKHook_LogicalEntSupport");
skamonkey@3767
   190
skamonkey@3767
   191
	playerhelpers->AddClientListener(&g_Interface);
skamonkey@3767
   192
	
skamonkey@3767
   193
	plsys->AddPluginsListener(&g_Interface);
skamonkey@3767
   194
skamonkey@3767
   195
	g_pOnEntityCreated = forwards->CreateForward("OnEntityCreated", ET_Ignore, 2, NULL, Param_Cell, Param_String);
skamonkey@3767
   196
	g_pOnEntityDestroyed = forwards->CreateForward("OnEntityDestroyed", ET_Ignore, 1, NULL, Param_Cell);
skamonkey@3767
   197
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   198
	g_pOnGetGameNameDescription = forwards->CreateForward("OnGetGameDescription", ET_Hook, 2, NULL, Param_String);
skamonkey@3767
   199
#endif
skamonkey@3767
   200
	g_pOnLevelInit = forwards->CreateForward("OnLevelInit", ET_Hook, 2, NULL, Param_String, Param_String);
skamonkey@3767
   201
skamonkey@3767
   202
	buffer[0] = '\0';
skamonkey@3767
   203
	if (!gameconfs->LoadGameConfigFile("sdkhooks.games", &g_pGameConf, buffer, sizeof(buffer)))
skamonkey@3767
   204
	{
skamonkey@3767
   205
		if (buffer[0])
skamonkey@3767
   206
		{
skamonkey@3767
   207
			g_pSM->Format(error, maxlength, "Could not read sdkhooks.games gamedata: %s", buffer);
skamonkey@3767
   208
		}
skamonkey@3767
   209
		
skamonkey@3767
   210
		return false;
skamonkey@3767
   211
	}
skamonkey@3767
   212
skamonkey@3767
   213
	void *gEntList = gamehelpers->GetGlobalEntityList();
skamonkey@3767
   214
	if (!gEntList)
skamonkey@3767
   215
	{
skamonkey@3767
   216
		g_pSM->Format(error, maxlength, "Cannot find gEntList pointer");
skamonkey@3767
   217
		return false;
skamonkey@3767
   218
	}
skamonkey@3767
   219
skamonkey@3767
   220
	int offset = -1; /* 65572 */
skamonkey@3767
   221
	if (!g_pGameConf->GetOffset("EntityListeners", &offset))
skamonkey@3767
   222
	{
skamonkey@3767
   223
		g_pSM->Format(error, maxlength, "Cannot find EntityListeners offset");
skamonkey@3767
   224
		return false;
skamonkey@3767
   225
	}
skamonkey@3767
   226
skamonkey@3767
   227
	CUtlVector<IEntityListener *> *pListeners = (CUtlVector<IEntityListener *> *)((intptr_t)gEntList + offset);
skamonkey@3767
   228
	pListeners->AddToTail(this);
skamonkey@3767
   229
skamonkey@3767
   230
	SetupHooks();
skamonkey@3767
   231
skamonkey@3767
   232
#if SOURCE_ENGINE >= SE_ORANGEBOX
skamonkey@3767
   233
	int index;
skamonkey@3767
   234
	CBaseHandle hndl;
skamonkey@3767
   235
	for (IHandleEntity *pEnt = (IHandleEntity *)servertools->FirstEntity(); pEnt; pEnt = (IHandleEntity *)servertools->NextEntity((CBaseEntity *)pEnt))
skamonkey@3767
   236
	{
skamonkey@3767
   237
		hndl = pEnt->GetRefEHandle();
skamonkey@3767
   238
		if (hndl == INVALID_EHANDLE_INDEX || !hndl.IsValid())
skamonkey@3767
   239
			continue;
skamonkey@3767
   240
		
skamonkey@3767
   241
		index = hndl.GetEntryIndex();
skamonkey@3767
   242
		m_EntityExists.Set(index);
skamonkey@3767
   243
	}
skamonkey@3767
   244
#else
skamonkey@3767
   245
	for (int i = 0; i < NUM_ENT_ENTRIES; i++)
skamonkey@3767
   246
	{
skamonkey@3767
   247
		if (gamehelpers->ReferenceToEntity(i) != NULL)
skamonkey@3767
   248
			m_EntityExists.Set(i);
skamonkey@3767
   249
	}
skamonkey@3767
   250
#endif
skamonkey@3767
   251
skamonkey@3767
   252
	return true;
skamonkey@3767
   253
}
skamonkey@3767
   254
skamonkey@3767
   255
inline void HookLevelInit()
skamonkey@3767
   256
{
skamonkey@3767
   257
	assert(g_hookOnLevelInit == 0);
kyle@3819
   258
	g_hookOnLevelInit = SH_ADD_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(&g_Interface, &SDKHooks::Hook_LevelInit), false);
skamonkey@3767
   259
	assert(g_hookOnGetMapEntitiesString == 0);
kyle@3819
   260
	g_hookOnGetMapEntitiesString = SH_ADD_HOOK(IVEngineServer, GetMapEntitiesString, engine, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GetMapEntitiesString), false);
skamonkey@3767
   261
}
skamonkey@3767
   262
skamonkey@3767
   263
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   264
inline void HookGetGameDescription()
skamonkey@3767
   265
{
skamonkey@3767
   266
	assert(g_hookOnGetGameDescription == 0);
kyle@3819
   267
	g_hookOnGetGameDescription = SH_ADD_HOOK(IServerGameDLL, GetGameDescription, gamedll, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GetGameDescription), false);
skamonkey@3767
   268
}
skamonkey@3767
   269
#endif
skamonkey@3767
   270
skamonkey@3767
   271
void SDKHooks::SDK_OnAllLoaded()
skamonkey@3767
   272
{
skamonkey@3767
   273
	SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
skamonkey@3767
   274
skamonkey@3767
   275
	if (!g_pBinTools)
skamonkey@3767
   276
	{
skamonkey@3767
   277
		g_pSM->LogError(myself, "Could not find interface: " SMINTERFACE_BINTOOLS_NAME);
skamonkey@3767
   278
		return;
skamonkey@3767
   279
	}
skamonkey@3767
   280
skamonkey@3767
   281
	if (g_pOnLevelInit->GetFunctionCount() > 0)
skamonkey@3767
   282
		HookLevelInit();
skamonkey@3767
   283
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   284
	if (g_pOnGetGameNameDescription->GetFunctionCount() > 0)
skamonkey@3767
   285
		HookGetGameDescription();
skamonkey@3767
   286
#endif
skamonkey@3767
   287
}
skamonkey@3767
   288
skamonkey@3767
   289
#define KILL_HOOK_IF_ACTIVE(hook) \
skamonkey@3767
   290
	if (hook != 0) \
skamonkey@3767
   291
	{ \
skamonkey@3767
   292
		SH_REMOVE_HOOK_ID(hook); \
skamonkey@3767
   293
	}
skamonkey@3767
   294
skamonkey@3767
   295
void SDKHooks::SDK_OnUnload()
skamonkey@3767
   296
{
skamonkey@3767
   297
	// Remove left over hooks
skamonkey@3767
   298
	HOOKLOOP
skamonkey@3767
   299
		Unhook(i);
skamonkey@3767
   300
skamonkey@3767
   301
	KILL_HOOK_IF_ACTIVE(g_hookOnLevelInit);
skamonkey@3767
   302
	KILL_HOOK_IF_ACTIVE(g_hookOnGetMapEntitiesString);
skamonkey@3767
   303
skamonkey@3767
   304
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   305
	KILL_HOOK_IF_ACTIVE(g_hookOnGetGameDescription);
skamonkey@3767
   306
#endif
skamonkey@3767
   307
skamonkey@3767
   308
	forwards->ReleaseForward(g_pOnEntityCreated);
skamonkey@3767
   309
	forwards->ReleaseForward(g_pOnEntityDestroyed);
skamonkey@3767
   310
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   311
	forwards->ReleaseForward(g_pOnGetGameNameDescription);
skamonkey@3767
   312
#endif
skamonkey@3767
   313
	forwards->ReleaseForward(g_pOnLevelInit);
skamonkey@3767
   314
skamonkey@3767
   315
	plsys->RemovePluginsListener(&g_Interface);
skamonkey@3767
   316
skamonkey@3767
   317
	playerhelpers->RemoveClientListener(&g_Interface);
skamonkey@3767
   318
skamonkey@3767
   319
	sharesys->DropCapabilityProvider(myself, this, "SDKHook_DmgCustomInOTD");
skamonkey@3767
   320
	sharesys->DropCapabilityProvider(myself, this, "SDKHook_LogicalEntSupport");
skamonkey@3767
   321
skamonkey@3767
   322
	void *gEntList = gamehelpers->GetGlobalEntityList();
skamonkey@3767
   323
	if (gEntList)
skamonkey@3767
   324
	{
skamonkey@3767
   325
		int offset = -1; /* 65572 */
skamonkey@3767
   326
		if (g_pGameConf->GetOffset("EntityListeners", &offset))
skamonkey@3767
   327
		{
skamonkey@3767
   328
			CUtlVector<IEntityListener *> *pListeners = (CUtlVector<IEntityListener *> *)((intptr_t)gEntList + offset);
skamonkey@3767
   329
			pListeners->FindAndRemove(this);
skamonkey@3767
   330
		}
skamonkey@3767
   331
	}
skamonkey@3767
   332
skamonkey@3767
   333
	gameconfs->CloseGameConfigFile(g_pGameConf);
skamonkey@3767
   334
}
skamonkey@3767
   335
skamonkey@3767
   336
bool SDKHooks::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late)
skamonkey@3767
   337
{
skamonkey@3767
   338
	GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
skamonkey@3767
   339
skamonkey@3767
   340
#if SOURCE_ENGINE >= SE_ORANGEBOX
skamonkey@3767
   341
	g_pCVar = icvar;
skamonkey@3767
   342
#endif
skamonkey@3767
   343
	CONVAR_REGISTER(this);
skamonkey@3767
   344
	
skamonkey@3767
   345
	gpGlobals = ismm->GetCGlobals();
skamonkey@3767
   346
skamonkey@3767
   347
	return true;
skamonkey@3767
   348
}
skamonkey@3767
   349
januk@3774
   350
const char *SDKHooks::GetExtensionVerString()
januk@3774
   351
{
januk@3774
   352
	return SM_VERSION_STRING;
januk@3774
   353
}
januk@3774
   354
januk@3774
   355
const char *SDKHooks::GetExtensionDateString()
januk@3774
   356
{
januk@3774
   357
	return SM_BUILD_TIMESTAMP;
januk@3774
   358
}
januk@3774
   359
skamonkey@3767
   360
void SDKHooks::OnPluginLoaded(IPlugin *plugin)
skamonkey@3767
   361
{
skamonkey@3767
   362
	if (g_pOnLevelInit->GetFunctionCount() > 0 && g_hookOnLevelInit == 0)
skamonkey@3767
   363
		HookLevelInit();
skamonkey@3767
   364
skamonkey@3767
   365
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   366
	if (g_pOnGetGameNameDescription->GetFunctionCount() > 0 && g_hookOnGetGameDescription == 0)
skamonkey@3767
   367
		HookGetGameDescription();
skamonkey@3767
   368
#endif
skamonkey@3767
   369
}
skamonkey@3767
   370
skamonkey@3767
   371
void SDKHooks::OnPluginUnloaded(IPlugin *plugin)
skamonkey@3767
   372
{
skamonkey@3767
   373
	IPluginContext *plugincontext = plugin->GetBaseContext();
skamonkey@3767
   374
	HOOKLOOP
skamonkey@3767
   375
	{
skamonkey@3767
   376
		if(g_HookList[i].callback->GetParentContext() == plugincontext)
skamonkey@3767
   377
			Unhook(i);
skamonkey@3767
   378
	}
skamonkey@3767
   379
skamonkey@3767
   380
	if (g_pOnLevelInit->GetFunctionCount() == 0)
skamonkey@3767
   381
	{
skamonkey@3767
   382
		KILL_HOOK_IF_ACTIVE(g_hookOnLevelInit);
skamonkey@3767
   383
		KILL_HOOK_IF_ACTIVE(g_hookOnGetMapEntitiesString);
skamonkey@3767
   384
	}
skamonkey@3767
   385
skamonkey@3767
   386
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   387
	if (g_pOnGetGameNameDescription->GetFunctionCount() == 0)
skamonkey@3767
   388
		KILL_HOOK_IF_ACTIVE(g_hookOnGetGameDescription);
skamonkey@3767
   389
#endif
skamonkey@3767
   390
}
skamonkey@3767
   391
skamonkey@3767
   392
void SDKHooks::OnClientPutInServer(int client)
skamonkey@3767
   393
{
skamonkey@3767
   394
	g_pOnEntityCreated->PushCell(client);
skamonkey@3767
   395
skamonkey@3767
   396
	CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client);
skamonkey@3767
   397
skamonkey@3767
   398
	const char * pName = gamehelpers->GetEntityClassname(pPlayer);
skamonkey@3767
   399
skamonkey@3767
   400
	g_pOnEntityCreated->PushString(pName ? pName : "");
skamonkey@3767
   401
	g_pOnEntityCreated->Execute(NULL);
skamonkey@3767
   402
skamonkey@3767
   403
	m_EntityExists.Set(client);
skamonkey@3767
   404
}
skamonkey@3767
   405
skamonkey@3767
   406
bool SDKHooks::RegisterConCommandBase(ConCommandBase *pVar)
skamonkey@3767
   407
{
skamonkey@3767
   408
	/* Always call META_REGCVAR instead of going through the engine. */
skamonkey@3767
   409
	return META_REGCVAR(pVar);
skamonkey@3767
   410
}
skamonkey@3767
   411
skamonkey@3767
   412
FeatureStatus SDKHooks::GetFeatureStatus(FeatureType type, const char *name)
skamonkey@3767
   413
{
skamonkey@3767
   414
	return FeatureStatus_Available;
skamonkey@3767
   415
}
skamonkey@3767
   416
skamonkey@3767
   417
/**
skamonkey@3767
   418
 * Functions
skamonkey@3767
   419
 */
skamonkey@3767
   420
cell_t SDKHooks::Call(int entity, SDKHookType type, int other)
skamonkey@3767
   421
{
skamonkey@3767
   422
	IPluginFunction *callback = NULL;
skamonkey@3767
   423
	cell_t res, ret = Pl_Continue;
skamonkey@3767
   424
skamonkey@3767
   425
	HOOKLOOP
skamonkey@3767
   426
	{
skamonkey@3767
   427
		if(g_HookList[i].entity != entity || g_HookList[i].type != type)
skamonkey@3767
   428
			continue;
skamonkey@3767
   429
skamonkey@3767
   430
		callback = g_HookList[i].callback;
skamonkey@3767
   431
		callback->PushCell(entity);
skamonkey@3767
   432
		if(other > -2)
skamonkey@3767
   433
			callback->PushCell(other);
skamonkey@3767
   434
skamonkey@3767
   435
		callback->Execute(&res);
skamonkey@3767
   436
		if(res > ret)
skamonkey@3767
   437
			ret = res;
skamonkey@3767
   438
	}
skamonkey@3767
   439
skamonkey@3767
   440
	return ret;
skamonkey@3767
   441
}
skamonkey@3767
   442
skamonkey@3767
   443
cell_t SDKHooks::Call(CBaseEntity *pEnt, SDKHookType type, int other)
skamonkey@3767
   444
{
skamonkey@3767
   445
	return Call(gamehelpers->EntityToBCompatRef(pEnt), type, other);
skamonkey@3767
   446
}
skamonkey@3767
   447
skamonkey@3767
   448
cell_t SDKHooks::Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *other)
skamonkey@3767
   449
{
skamonkey@3767
   450
	return Call(gamehelpers->EntityToBCompatRef(pEnt), type, gamehelpers->EntityToBCompatRef(other));
skamonkey@3767
   451
}
skamonkey@3767
   452
skamonkey@3767
   453
void SDKHooks::SetupHooks()
skamonkey@3767
   454
{
skamonkey@3767
   455
	int offset;
skamonkey@3767
   456
skamonkey@3767
   457
	//			gamedata          pre    post
skamonkey@3767
   458
	// (pre is not necessarily a prehook, just named without "Post" appeneded)
skamonkey@3767
   459
skamonkey@3767
   460
	CHECKOFFSET(EndTouch,         true,  true);
skamonkey@3767
   461
	CHECKOFFSET(FireBullets,      false, true);
skamonkey@3767
   462
	CHECKOFFSET(GroundEntChanged, false, true);
skamonkey@3767
   463
	CHECKOFFSET(OnTakeDamage,     true,  true);
skamonkey@3767
   464
	CHECKOFFSET(PreThink,         true,  true);
skamonkey@3767
   465
	CHECKOFFSET(PostThink,        true,  true);
skamonkey@3767
   466
	CHECKOFFSET(Reload,           true,  true);
skamonkey@3767
   467
	CHECKOFFSET(SetTransmit,      true,  false);
skamonkey@3767
   468
	CHECKOFFSET(ShouldCollide,    true,  false);
skamonkey@3767
   469
	CHECKOFFSET(Spawn,            true,  true);
skamonkey@3767
   470
	CHECKOFFSET(StartTouch,       true,  true);
skamonkey@3767
   471
	CHECKOFFSET(Think,            true,  true);
skamonkey@3767
   472
	CHECKOFFSET(Touch,            true,  true);
skamonkey@3767
   473
	CHECKOFFSET(TraceAttack,      true,  true);
skamonkey@3767
   474
	CHECKOFFSET(Use,              true,  true);
skamonkey@3767
   475
	CHECKOFFSET_W(CanSwitchTo,    true,  true);
skamonkey@3767
   476
	CHECKOFFSET_W(CanUse,         true,  true);
skamonkey@3767
   477
	CHECKOFFSET_W(Drop,           true,  true);
skamonkey@3767
   478
	CHECKOFFSET_W(Equip,          true,  true);
skamonkey@3767
   479
	CHECKOFFSET_W(Switch,         true,  true);
skamonkey@3767
   480
	CHECKOFFSET(VPhysicsUpdate,   true,  true);
skamonkey@3767
   481
skamonkey@3767
   482
	// this one is in a class all its own -_-
skamonkey@3767
   483
	offset = 0;
skamonkey@3767
   484
	g_pGameConf->GetOffset("GroundEntChanged", &offset);
skamonkey@3767
   485
	if (offset > 0)
skamonkey@3767
   486
	{
skamonkey@3767
   487
		SH_MANUALHOOK_RECONFIGURE(GroundEntChanged, offset, 0, 0);
skamonkey@3767
   488
		g_HookTypes[SDKHook_GroundEntChangedPost].supported = true;
skamonkey@3767
   489
	}
skamonkey@3767
   490
skamonkey@3767
   491
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   492
	CHECKOFFSET(GetMaxHealth,	true,	false);
skamonkey@3767
   493
#endif
skamonkey@3767
   494
}
skamonkey@3767
   495
skamonkey@3767
   496
HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callback)
skamonkey@3767
   497
{
skamonkey@3767
   498
	if(!g_HookTypes[type].supported)
skamonkey@3767
   499
		return HookRet_NotSupported;
skamonkey@3767
   500
skamonkey@3767
   501
	CBaseEntity *pEnt = UTIL_GetCBaseEntity(entity);
skamonkey@3767
   502
	if(!pEnt)
skamonkey@3767
   503
		return HookRet_InvalidEntity;
skamonkey@3767
   504
	if(type < 0 || type >= SDKHook_MAXHOOKS)
skamonkey@3767
   505
		return HookRet_InvalidHookType;
skamonkey@3767
   506
skamonkey@3767
   507
	if (!!strcmp(g_HookTypes[type].dtReq, ""))
skamonkey@3767
   508
	{
skamonkey@3767
   509
		sm_sendprop_info_t spi;
skamonkey@3767
   510
		IServerUnknown *pUnk = (IServerUnknown *)pEnt;
skamonkey@3767
   511
skamonkey@3767
   512
		IServerNetworkable *pNet = pUnk->GetNetworkable();
skamonkey@3767
   513
		if (pNet && !UTIL_FindDataTable(pNet->GetServerClass()->m_pTable, g_HookTypes[type].dtReq, &spi, 0))
skamonkey@3767
   514
			return HookRet_BadEntForHookType;
skamonkey@3767
   515
	}
skamonkey@3767
   516
skamonkey@3767
   517
	bool bHooked = false;
skamonkey@3767
   518
	HOOKLOOP
skamonkey@3767
   519
	{
skamonkey@3767
   520
		if (g_HookList[i].entity == entity && g_HookList[i].type == type)
skamonkey@3767
   521
		{
skamonkey@3767
   522
			bHooked = true;
skamonkey@3767
   523
			break;
skamonkey@3767
   524
		}
skamonkey@3767
   525
	}
skamonkey@3767
   526
	if (!bHooked)
skamonkey@3767
   527
	{
skamonkey@3767
   528
		switch(type)
skamonkey@3767
   529
		{
skamonkey@3767
   530
			case SDKHook_EndTouch:
kyle@3819
   531
				SH_ADD_MANUALHOOK(EndTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_EndTouch), false);
skamonkey@3767
   532
				break;
skamonkey@3767
   533
			case SDKHook_EndTouchPost:
kyle@3819
   534
				SH_ADD_MANUALHOOK(EndTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_EndTouchPost), true);
skamonkey@3767
   535
				break;
skamonkey@3767
   536
			case SDKHook_FireBulletsPost:
kyle@3819
   537
				SH_ADD_MANUALHOOK(FireBullets, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_FireBulletsPost), true);
skamonkey@3767
   538
				break;
skamonkey@3767
   539
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   540
			case SDKHook_GetMaxHealth:
kyle@3819
   541
				SH_ADD_MANUALHOOK(GetMaxHealth, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GetMaxHealth), false);
skamonkey@3767
   542
				break;
skamonkey@3767
   543
#endif
skamonkey@3767
   544
			case SDKHook_GroundEntChangedPost:
kyle@3819
   545
				SH_ADD_MANUALHOOK(GroundEntChanged, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GroundEntChangedPost), true);
skamonkey@3767
   546
				break;
skamonkey@3767
   547
			case SDKHook_OnTakeDamage:
kyle@3819
   548
				SH_ADD_MANUALHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamage), false);
skamonkey@3767
   549
				break;
skamonkey@3767
   550
			case SDKHook_OnTakeDamagePost:
kyle@3819
   551
				SH_ADD_MANUALHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true);
skamonkey@3767
   552
				break;
skamonkey@3767
   553
			case SDKHook_PreThink:
kyle@3819
   554
				SH_ADD_MANUALHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false);
skamonkey@3767
   555
				break;
skamonkey@3767
   556
			case SDKHook_PreThinkPost:
kyle@3819
   557
				SH_ADD_MANUALHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThinkPost), true);
skamonkey@3767
   558
				break;
skamonkey@3767
   559
			case SDKHook_PostThink:
kyle@3819
   560
				SH_ADD_MANUALHOOK(PostThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PostThink), false);
skamonkey@3767
   561
				break;
skamonkey@3767
   562
			case SDKHook_PostThinkPost:
kyle@3819
   563
				SH_ADD_MANUALHOOK(PostThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PostThinkPost), true);
skamonkey@3767
   564
				break;
skamonkey@3767
   565
			case SDKHook_Reload:
kyle@3819
   566
				SH_ADD_MANUALHOOK(Reload, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Reload), false);
skamonkey@3767
   567
				break;
skamonkey@3767
   568
			case SDKHook_ReloadPost:
kyle@3819
   569
				SH_ADD_MANUALHOOK(Reload, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ReloadPost), true);
skamonkey@3767
   570
				break;
skamonkey@3767
   571
			case SDKHook_SetTransmit:
kyle@3819
   572
				SH_ADD_MANUALHOOK(SetTransmit, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_SetTransmit), false);
skamonkey@3767
   573
				break;
skamonkey@3767
   574
			case SDKHook_Spawn:
kyle@3819
   575
				SH_ADD_MANUALHOOK(Spawn, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Spawn), false);
skamonkey@3767
   576
				break;
skamonkey@3767
   577
			case SDKHook_SpawnPost:
kyle@3819
   578
				SH_ADD_MANUALHOOK(Spawn, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_SpawnPost), true);
skamonkey@3767
   579
				break;
skamonkey@3767
   580
			case SDKHook_StartTouch:
kyle@3819
   581
				SH_ADD_MANUALHOOK(StartTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_StartTouch), false);
skamonkey@3767
   582
				break;
skamonkey@3767
   583
			case SDKHook_StartTouchPost:
kyle@3819
   584
				SH_ADD_MANUALHOOK(StartTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_StartTouchPost), true);
skamonkey@3767
   585
				break;
skamonkey@3767
   586
			case SDKHook_Think:
kyle@3819
   587
				SH_ADD_MANUALHOOK(Think, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Think), false);
skamonkey@3767
   588
				break;
skamonkey@3767
   589
			case SDKHook_ThinkPost:
kyle@3819
   590
				SH_ADD_MANUALHOOK(Think, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ThinkPost), true);
skamonkey@3767
   591
				break;
skamonkey@3767
   592
			case SDKHook_Touch:
kyle@3819
   593
				SH_ADD_MANUALHOOK(Touch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Touch), false);
skamonkey@3767
   594
				break;
skamonkey@3767
   595
			case SDKHook_TouchPost:
kyle@3819
   596
				SH_ADD_MANUALHOOK(Touch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TouchPost), true);
skamonkey@3767
   597
				break;
skamonkey@3767
   598
			case SDKHook_TraceAttack:
kyle@3819
   599
				SH_ADD_MANUALHOOK(TraceAttack, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TraceAttack), false);
skamonkey@3767
   600
				break;
skamonkey@3767
   601
			case SDKHook_TraceAttackPost:
kyle@3819
   602
				SH_ADD_MANUALHOOK(TraceAttack, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TraceAttackPost), true);
skamonkey@3767
   603
				break;
skamonkey@3767
   604
			case SDKHook_Use:
kyle@3819
   605
				SH_ADD_MANUALHOOK(Use, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Use), false);
skamonkey@3767
   606
				break;
skamonkey@3767
   607
			case SDKHook_UsePost:
kyle@3819
   608
				SH_ADD_MANUALHOOK(Use, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_UsePost), true);
skamonkey@3767
   609
				break;
skamonkey@3767
   610
			case SDKHook_VPhysicsUpdate:
kyle@3819
   611
				SH_ADD_MANUALHOOK(VPhysicsUpdate, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_VPhysicsUpdate), false);
skamonkey@3767
   612
				break;
skamonkey@3767
   613
			case SDKHook_VPhysicsUpdatePost:
kyle@3819
   614
				SH_ADD_MANUALHOOK(VPhysicsUpdate, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_VPhysicsUpdatePost), true);
skamonkey@3767
   615
				break;
skamonkey@3767
   616
			case SDKHook_WeaponCanSwitchTo:
kyle@3819
   617
				SH_ADD_MANUALHOOK(Weapon_CanSwitchTo, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanSwitchTo), false);
skamonkey@3767
   618
				break;
skamonkey@3767
   619
			case SDKHook_WeaponCanSwitchToPost:
kyle@3819
   620
				SH_ADD_MANUALHOOK(Weapon_CanSwitchTo, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanSwitchToPost), true);
skamonkey@3767
   621
				break;
skamonkey@3767
   622
			case SDKHook_WeaponCanUse:
kyle@3819
   623
				SH_ADD_MANUALHOOK(Weapon_CanUse, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanUse), false);
skamonkey@3767
   624
				break;
skamonkey@3767
   625
			case SDKHook_WeaponCanUsePost:
kyle@3819
   626
				SH_ADD_MANUALHOOK(Weapon_CanUse, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanUsePost), true);
skamonkey@3767
   627
				break;
skamonkey@3767
   628
			case SDKHook_WeaponDrop:
kyle@3819
   629
				SH_ADD_MANUALHOOK(Weapon_Drop, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponDrop), false);
skamonkey@3767
   630
				break;
skamonkey@3767
   631
			case SDKHook_WeaponDropPost:
kyle@3819
   632
				SH_ADD_MANUALHOOK(Weapon_Drop, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponDropPost), true);
skamonkey@3767
   633
				break;
skamonkey@3767
   634
			case SDKHook_WeaponEquip:
kyle@3819
   635
				SH_ADD_MANUALHOOK(Weapon_Equip, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponEquip), false);
skamonkey@3767
   636
				break;
skamonkey@3767
   637
			case SDKHook_WeaponEquipPost:
kyle@3819
   638
				SH_ADD_MANUALHOOK(Weapon_Equip, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponEquipPost), true);
skamonkey@3767
   639
				break;
skamonkey@3767
   640
			case SDKHook_WeaponSwitch:
kyle@3819
   641
				SH_ADD_MANUALHOOK(Weapon_Switch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponSwitch), false);
skamonkey@3767
   642
				break;
skamonkey@3767
   643
			case SDKHook_WeaponSwitchPost:
kyle@3819
   644
				SH_ADD_MANUALHOOK(Weapon_Switch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponSwitchPost), true);
skamonkey@3767
   645
				break;
skamonkey@3767
   646
			case SDKHook_ShouldCollide:
kyle@3819
   647
				SH_ADD_MANUALHOOK(ShouldCollide, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ShouldCollide), false);
skamonkey@3767
   648
				break;
skamonkey@3767
   649
		}
skamonkey@3767
   650
	}
skamonkey@3767
   651
skamonkey@3767
   652
	// Add hook to hook list
skamonkey@3767
   653
	HookList hook;
skamonkey@3767
   654
	hook.entity = entity;
skamonkey@3767
   655
	hook.type = type;
skamonkey@3767
   656
	hook.callback = callback;
skamonkey@3767
   657
	g_HookList.AddToTail(hook);
skamonkey@3767
   658
#ifdef SDKHOOKSDEBUG
skamonkey@3767
   659
	META_CONPRINTF("DEBUG: Adding to hooklist (ent%d, type%s, cb%d). Total hook count %d\n", entity, g_szHookNames[type], callback, g_HookList.Count());
skamonkey@3767
   660
#endif
skamonkey@3767
   661
	return HookRet_Successful;
skamonkey@3767
   662
}
skamonkey@3767
   663
skamonkey@3767
   664
void SDKHooks::Unhook(int index)
skamonkey@3767
   665
{
skamonkey@3767
   666
	CBaseEntity *pEnt = gamehelpers->ReferenceToEntity(g_HookList[index].entity);
skamonkey@3767
   667
	if(!pEnt)
skamonkey@3767
   668
		return;
skamonkey@3767
   669
skamonkey@3767
   670
	int iHooks = 0;
skamonkey@3767
   671
	HOOKLOOP
skamonkey@3767
   672
	{
skamonkey@3767
   673
		if (g_HookList[i].entity == g_HookList[index].entity && g_HookList[i].type == g_HookList[index].type)
skamonkey@3767
   674
		{
skamonkey@3767
   675
			iHooks++;
skamonkey@3767
   676
#ifdef SDKHOOKSDEBUG
skamonkey@3767
   677
			META_CONPRINTF("DEBUG: Found hook %d on entity %d\n", i, g_HookList[index].entity);
skamonkey@3767
   678
#endif
skamonkey@3767
   679
		}
skamonkey@3767
   680
	}
skamonkey@3767
   681
	if (iHooks == 1)
skamonkey@3767
   682
	{
skamonkey@3767
   683
#ifdef SDKHOOKSDEBUG
skamonkey@3767
   684
		META_CONPRINTF("DEBUG: Removing hook for hooktype %d\n", g_HookList[index].type);
skamonkey@3767
   685
#endif
skamonkey@3767
   686
		switch(g_HookList[index].type)
skamonkey@3767
   687
		{
skamonkey@3767
   688
			case SDKHook_EndTouch:
kyle@3819
   689
				SH_REMOVE_MANUALHOOK(EndTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_EndTouch), false);
skamonkey@3767
   690
				break;
skamonkey@3767
   691
			case SDKHook_EndTouchPost:
kyle@3819
   692
				SH_REMOVE_MANUALHOOK(EndTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_EndTouchPost), true);
skamonkey@3767
   693
				break;
skamonkey@3767
   694
			case SDKHook_FireBulletsPost:
kyle@3819
   695
				SH_REMOVE_MANUALHOOK(FireBullets, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_FireBulletsPost), true);
skamonkey@3767
   696
				break;
skamonkey@3767
   697
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   698
			case SDKHook_GetMaxHealth:
kyle@3819
   699
				SH_REMOVE_MANUALHOOK(GetMaxHealth, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GetMaxHealth), false);
skamonkey@3767
   700
				break;
skamonkey@3767
   701
#endif
skamonkey@3767
   702
			case SDKHook_GroundEntChangedPost:
kyle@3819
   703
				SH_REMOVE_MANUALHOOK(GroundEntChanged, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GroundEntChangedPost), true);
skamonkey@3767
   704
				break;
skamonkey@3767
   705
			case SDKHook_OnTakeDamage:
kyle@3819
   706
				SH_REMOVE_MANUALHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamage), false);
skamonkey@3767
   707
				break;
skamonkey@3767
   708
			case SDKHook_OnTakeDamagePost:
kyle@3819
   709
				SH_REMOVE_MANUALHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true);
skamonkey@3767
   710
				break;
skamonkey@3767
   711
			case SDKHook_PreThink:
kyle@3819
   712
				SH_REMOVE_MANUALHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false);
skamonkey@3767
   713
				break;
skamonkey@3767
   714
			case SDKHook_PreThinkPost:
kyle@3819
   715
				SH_REMOVE_MANUALHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThinkPost), true);
skamonkey@3767
   716
				break;
skamonkey@3767
   717
			case SDKHook_PostThink:
kyle@3819
   718
				SH_REMOVE_MANUALHOOK(PostThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PostThink), false);
skamonkey@3767
   719
				break;
skamonkey@3767
   720
			case SDKHook_PostThinkPost:
kyle@3819
   721
				SH_REMOVE_MANUALHOOK(PostThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PostThinkPost), true);
skamonkey@3767
   722
				break;
skamonkey@3767
   723
			case SDKHook_Reload:
kyle@3819
   724
				SH_REMOVE_MANUALHOOK(Reload, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Reload), false);
skamonkey@3767
   725
				break;
skamonkey@3767
   726
			case SDKHook_ReloadPost:
kyle@3819
   727
				SH_REMOVE_MANUALHOOK(Reload, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ReloadPost), true);
skamonkey@3767
   728
				break;
skamonkey@3767
   729
			case SDKHook_SetTransmit:
kyle@3819
   730
				SH_REMOVE_MANUALHOOK(SetTransmit, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_SetTransmit), false);
skamonkey@3767
   731
				break;
skamonkey@3767
   732
			case SDKHook_Spawn:
kyle@3819
   733
				SH_REMOVE_MANUALHOOK(Spawn, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Spawn), false);
skamonkey@3767
   734
				break;
skamonkey@3767
   735
			case SDKHook_SpawnPost:
kyle@3819
   736
				SH_REMOVE_MANUALHOOK(Spawn, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_SpawnPost), true);
skamonkey@3767
   737
				break;
skamonkey@3767
   738
			case SDKHook_StartTouch:
kyle@3819
   739
				SH_REMOVE_MANUALHOOK(StartTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_StartTouch), false);
skamonkey@3767
   740
				break;
skamonkey@3767
   741
			case SDKHook_StartTouchPost:
kyle@3819
   742
				SH_REMOVE_MANUALHOOK(StartTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_StartTouchPost), true);
skamonkey@3767
   743
				break;
skamonkey@3767
   744
			case SDKHook_Think:
kyle@3819
   745
				SH_REMOVE_MANUALHOOK(Think, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Think), false);
skamonkey@3767
   746
				break;
skamonkey@3767
   747
			case SDKHook_ThinkPost:
kyle@3819
   748
				SH_REMOVE_MANUALHOOK(Think, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ThinkPost), true);
skamonkey@3767
   749
				break;
skamonkey@3767
   750
			case SDKHook_Touch:
kyle@3819
   751
				SH_REMOVE_MANUALHOOK(Touch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Touch), false);
skamonkey@3767
   752
				break;
skamonkey@3767
   753
			case SDKHook_TouchPost:
kyle@3819
   754
				SH_REMOVE_MANUALHOOK(Touch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TouchPost), true);
skamonkey@3767
   755
				break;
skamonkey@3767
   756
			case SDKHook_TraceAttack:
kyle@3819
   757
				SH_REMOVE_MANUALHOOK(TraceAttack, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TraceAttack), false);
skamonkey@3767
   758
				break;
skamonkey@3767
   759
			case SDKHook_TraceAttackPost:
kyle@3819
   760
				SH_REMOVE_MANUALHOOK(TraceAttack, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TraceAttackPost), true);
skamonkey@3767
   761
				break;
skamonkey@3767
   762
			case SDKHook_Use:
kyle@3819
   763
				SH_REMOVE_MANUALHOOK(Use, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Use), false);
skamonkey@3767
   764
				break;
skamonkey@3767
   765
			case SDKHook_UsePost:
kyle@3819
   766
				SH_REMOVE_MANUALHOOK(Use, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_UsePost), true);
skamonkey@3767
   767
				break;
skamonkey@3767
   768
			case SDKHook_VPhysicsUpdate:
kyle@3819
   769
				SH_REMOVE_MANUALHOOK(VPhysicsUpdate, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_VPhysicsUpdate), false);
skamonkey@3767
   770
				break;
skamonkey@3767
   771
			case SDKHook_VPhysicsUpdatePost:
kyle@3819
   772
				SH_REMOVE_MANUALHOOK(VPhysicsUpdate, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_VPhysicsUpdatePost), true);
skamonkey@3767
   773
				break;
skamonkey@3767
   774
			case SDKHook_WeaponCanSwitchTo:
kyle@3819
   775
				SH_REMOVE_MANUALHOOK(Weapon_CanSwitchTo, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanSwitchTo), false);
skamonkey@3767
   776
				break;
skamonkey@3767
   777
			case SDKHook_WeaponCanSwitchToPost:
kyle@3819
   778
				SH_REMOVE_MANUALHOOK(Weapon_CanSwitchTo, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanSwitchToPost), true);
skamonkey@3767
   779
				break;
skamonkey@3767
   780
			case SDKHook_WeaponCanUse:
kyle@3819
   781
				SH_REMOVE_MANUALHOOK(Weapon_CanUse, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanUse), false);
skamonkey@3767
   782
				break;
skamonkey@3767
   783
			case SDKHook_WeaponCanUsePost:
kyle@3819
   784
				SH_REMOVE_MANUALHOOK(Weapon_CanUse, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanUsePost), true);
skamonkey@3767
   785
				break;
skamonkey@3767
   786
			case SDKHook_WeaponDrop:
kyle@3819
   787
				SH_REMOVE_MANUALHOOK(Weapon_Drop, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponDrop), false);
skamonkey@3767
   788
				break;
skamonkey@3767
   789
			case SDKHook_WeaponDropPost:
kyle@3819
   790
				SH_REMOVE_MANUALHOOK(Weapon_Drop, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponDropPost), true);
skamonkey@3767
   791
				break;
skamonkey@3767
   792
			case SDKHook_WeaponEquip:
kyle@3819
   793
				SH_REMOVE_MANUALHOOK(Weapon_Equip, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponEquip), false);
skamonkey@3767
   794
				break;
skamonkey@3767
   795
			case SDKHook_WeaponEquipPost:
kyle@3819
   796
				SH_REMOVE_MANUALHOOK(Weapon_Equip, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponEquipPost), true);
skamonkey@3767
   797
				break;
skamonkey@3767
   798
			case SDKHook_WeaponSwitch:
kyle@3819
   799
				SH_REMOVE_MANUALHOOK(Weapon_Switch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponSwitch), false);
skamonkey@3767
   800
				break;
skamonkey@3767
   801
			case SDKHook_WeaponSwitchPost:
kyle@3819
   802
				SH_REMOVE_MANUALHOOK(Weapon_Switch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponSwitchPost), true);
skamonkey@3767
   803
				break;
skamonkey@3767
   804
			case SDKHook_ShouldCollide:
kyle@3819
   805
				SH_REMOVE_MANUALHOOK(ShouldCollide, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ShouldCollide), false);
skamonkey@3767
   806
				break;
skamonkey@3767
   807
			default:
skamonkey@3767
   808
				return;
skamonkey@3767
   809
		}
skamonkey@3767
   810
	}
skamonkey@3767
   811
	g_HookList.Remove(index);
skamonkey@3767
   812
}
skamonkey@3767
   813
skamonkey@3767
   814
skamonkey@3767
   815
/**
skamonkey@3767
   816
 * IEntityFactoryDictionary, IServerGameDLL & IVEngineServer Hook Handlers
skamonkey@3767
   817
 */
skamonkey@3767
   818
void SDKHooks::OnEntityCreated(CBaseEntity *pEntity)
skamonkey@3767
   819
{
skamonkey@3767
   820
	// Call OnEntityCreated forward
skamonkey@3767
   821
	int entity = gamehelpers->ReferenceToIndex(gamehelpers->EntityToBCompatRef(pEntity));
skamonkey@3767
   822
	if (m_EntityExists.IsBitSet(entity) || (entity > 0 && entity <= playerhelpers->GetMaxClients()))
skamonkey@3767
   823
	{
skamonkey@3767
   824
		return;
skamonkey@3767
   825
	}
skamonkey@3767
   826
skamonkey@3767
   827
	g_pOnEntityCreated->PushCell(gamehelpers->EntityToBCompatRef(pEntity));
skamonkey@3767
   828
skamonkey@3767
   829
	const char * pName = gamehelpers->GetEntityClassname(pEntity);
skamonkey@3767
   830
	g_pOnEntityCreated->PushString(pName ? pName : "");
skamonkey@3767
   831
skamonkey@3767
   832
	g_pOnEntityCreated->Execute(NULL);
skamonkey@3767
   833
skamonkey@3767
   834
	m_EntityExists.Set(entity);
skamonkey@3767
   835
}
skamonkey@3767
   836
skamonkey@3767
   837
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   838
const char *SDKHooks::Hook_GetGameDescription()
skamonkey@3767
   839
{
skamonkey@3767
   840
	static char szGameDesc[64];
skamonkey@3767
   841
	cell_t result = Pl_Continue;
skamonkey@3767
   842
skamonkey@3767
   843
	g_pSM->Format(szGameDesc, sizeof(szGameDesc), "%s",
skamonkey@3767
   844
		SH_CALL(gamedll, &IServerGameDLL::GetGameDescription)());
skamonkey@3767
   845
skamonkey@3767
   846
	// Call OnGetGameDescription forward
skamonkey@3767
   847
	g_pOnGetGameNameDescription->PushStringEx(szGameDesc, sizeof(szGameDesc), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
skamonkey@3767
   848
	g_pOnGetGameNameDescription->Execute(&result);
skamonkey@3767
   849
skamonkey@3767
   850
	if(result == Pl_Changed)
skamonkey@3767
   851
		RETURN_META_VALUE(MRES_SUPERCEDE, szGameDesc);
skamonkey@3767
   852
skamonkey@3767
   853
	RETURN_META_VALUE(MRES_IGNORED, NULL);
skamonkey@3767
   854
}
skamonkey@3767
   855
#endif
skamonkey@3767
   856
skamonkey@3767
   857
const char *SDKHooks::Hook_GetMapEntitiesString()
skamonkey@3767
   858
{
skamonkey@3767
   859
	if(g_szMapEntities[0])
skamonkey@3767
   860
		RETURN_META_VALUE(MRES_SUPERCEDE, g_szMapEntities);
skamonkey@3767
   861
skamonkey@3767
   862
	RETURN_META_VALUE(MRES_IGNORED, NULL);
skamonkey@3767
   863
}
skamonkey@3767
   864
skamonkey@3767
   865
bool SDKHooks::Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
skamonkey@3767
   866
{
skamonkey@3767
   867
	strcpy(g_szMapEntities, pMapEntities);
skamonkey@3767
   868
	cell_t result = Pl_Continue;
skamonkey@3767
   869
skamonkey@3767
   870
	// Call OnLevelInit forward
skamonkey@3767
   871
	g_pOnLevelInit->PushString(pMapName);
skamonkey@3767
   872
	g_pOnLevelInit->PushStringEx(g_szMapEntities, sizeof(g_szMapEntities), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
skamonkey@3767
   873
	g_pOnLevelInit->Execute(&result);
skamonkey@3767
   874
skamonkey@3767
   875
	if(result >= Pl_Handled)
skamonkey@3767
   876
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
   877
skamonkey@3767
   878
	if(result == Pl_Changed)
skamonkey@3767
   879
		RETURN_META_VALUE_NEWPARAMS(MRES_HANDLED, true, &IServerGameDLL::LevelInit, (pMapName, g_szMapEntities, pOldLevel, pLandmarkName, loadGame, background));
skamonkey@3767
   880
skamonkey@3767
   881
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
   882
}
skamonkey@3767
   883
skamonkey@3767
   884
skamonkey@3767
   885
/**
skamonkey@3767
   886
 * CBaseEntity Hook Handlers
skamonkey@3767
   887
 */
skamonkey@3767
   888
void SDKHooks::Hook_EndTouch(CBaseEntity *pOther)
skamonkey@3767
   889
{
skamonkey@3767
   890
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_EndTouch, pOther);
skamonkey@3767
   891
	if(result >= Pl_Handled)
skamonkey@3767
   892
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
   893
skamonkey@3767
   894
	RETURN_META(MRES_IGNORED);
skamonkey@3767
   895
}
skamonkey@3767
   896
skamonkey@3767
   897
void SDKHooks::Hook_EndTouchPost(CBaseEntity *pOther)
skamonkey@3767
   898
{
skamonkey@3767
   899
	Call(META_IFACEPTR(CBaseEntity), SDKHook_EndTouchPost, pOther);
skamonkey@3767
   900
	RETURN_META(MRES_IGNORED);
skamonkey@3767
   901
}
skamonkey@3767
   902
skamonkey@3767
   903
void SDKHooks::Hook_FireBulletsPost(const FireBulletsInfo_t &info)
skamonkey@3767
   904
{
skamonkey@3767
   905
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
   906
skamonkey@3767
   907
	IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(entity);
skamonkey@3767
   908
	if(!pPlayer)
skamonkey@3767
   909
		RETURN_META(MRES_IGNORED);
skamonkey@3767
   910
skamonkey@3767
   911
	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
skamonkey@3767
   912
	if(!pInfo)
skamonkey@3767
   913
		RETURN_META(MRES_IGNORED);
skamonkey@3767
   914
skamonkey@3767
   915
	const char *weapon = pInfo->GetWeaponName();
skamonkey@3767
   916
	IPluginFunction *callback = NULL;
skamonkey@3767
   917
skamonkey@3767
   918
	HOOKLOOP
skamonkey@3767
   919
	{
skamonkey@3767
   920
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_FireBulletsPost)
skamonkey@3767
   921
			continue;
skamonkey@3767
   922
skamonkey@3767
   923
		callback = g_HookList[i].callback;
skamonkey@3767
   924
		callback->PushCell(entity);
skamonkey@3767
   925
		callback->PushCell(info.m_iShots);
skamonkey@3767
   926
		callback->PushString(weapon?weapon:"");
skamonkey@3767
   927
		callback->Execute(NULL);
skamonkey@3767
   928
	}
skamonkey@3767
   929
skamonkey@3767
   930
	RETURN_META(MRES_IGNORED);
skamonkey@3767
   931
}
skamonkey@3767
   932
skamonkey@3767
   933
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   934
int SDKHooks::Hook_GetMaxHealth()
skamonkey@3767
   935
{
skamonkey@3767
   936
	CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
skamonkey@3767
   937
	int original_max = SH_MCALL(pEntity, GetMaxHealth)();
skamonkey@3767
   938
	int entity = gamehelpers->EntityToBCompatRef(pEntity);
skamonkey@3767
   939
skamonkey@3767
   940
	int new_max = original_max;
skamonkey@3767
   941
skamonkey@3767
   942
	cell_t res;
skamonkey@3767
   943
	IPluginFunction *callback = NULL;
skamonkey@3767
   944
skamonkey@3767
   945
	HOOKLOOP
skamonkey@3767
   946
	{
skamonkey@3767
   947
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_GetMaxHealth)
skamonkey@3767
   948
			continue;
skamonkey@3767
   949
skamonkey@3767
   950
		callback = g_HookList[i].callback;
skamonkey@3807
   951
		callback->PushCell(entity);
skamonkey@3767
   952
		callback->PushCellByRef(&new_max);
skamonkey@3767
   953
		callback->Execute(&res);
skamonkey@3767
   954
	}
skamonkey@3767
   955
skamonkey@3767
   956
	if (res >= Pl_Changed)
skamonkey@3767
   957
		RETURN_META_VALUE(MRES_SUPERCEDE, new_max);
skamonkey@3767
   958
skamonkey@3767
   959
	RETURN_META_VALUE(MRES_IGNORED, original_max);
skamonkey@3767
   960
}
skamonkey@3767
   961
#endif
skamonkey@3767
   962
skamonkey@3767
   963
void SDKHooks::Hook_GroundEntChangedPost()
skamonkey@3767
   964
{
skamonkey@3767
   965
	Call(META_IFACEPTR(CBaseEntity), SDKHook_GroundEntChangedPost);
skamonkey@3767
   966
}
skamonkey@3767
   967
skamonkey@3767
   968
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
skamonkey@3767
   969
{
skamonkey@3767
   970
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
   971
	int attacker = info.GetAttacker();
skamonkey@3767
   972
	int inflictor = info.GetInflictor();
skamonkey@3767
   973
	float damage = info.GetDamage();
skamonkey@3767
   974
	int damagetype = info.GetDamageType();
skamonkey@3767
   975
	int weapon = info.GetWeapon();
skamonkey@3767
   976
skamonkey@3767
   977
	Vector force = info.GetDamageForce();
skamonkey@3767
   978
	cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
skamonkey@3767
   979
skamonkey@3767
   980
	Vector pos = info.GetDamagePosition();
skamonkey@3767
   981
	cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
skamonkey@3767
   982
skamonkey@3767
   983
	IPluginFunction *callback = NULL;
skamonkey@3767
   984
	cell_t res, ret = Pl_Continue;
skamonkey@3767
   985
skamonkey@3767
   986
	HOOKLOOP
skamonkey@3767
   987
	{
skamonkey@3767
   988
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_OnTakeDamage)
skamonkey@3767
   989
			continue;
skamonkey@3767
   990
skamonkey@3767
   991
		callback = g_HookList[i].callback;
skamonkey@3767
   992
		callback->PushCell(entity);
skamonkey@3767
   993
		callback->PushCellByRef(&attacker);
skamonkey@3767
   994
		callback->PushCellByRef(&inflictor);
skamonkey@3767
   995
		callback->PushFloatByRef(&damage);
skamonkey@3767
   996
		callback->PushCellByRef(&damagetype);
skamonkey@3767
   997
		callback->PushCellByRef(&weapon);
skamonkey@3767
   998
		callback->PushArray(damageForce, 3, SM_PARAM_COPYBACK);
skamonkey@3767
   999
		callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);	
skamonkey@3767
  1000
		callback->PushCell(info.GetDamageCustom());
skamonkey@3767
  1001
		callback->Execute(&res);
skamonkey@3767
  1002
skamonkey@3767
  1003
		if(res > ret)
skamonkey@3767
  1004
			ret = res;
skamonkey@3767
  1005
	}
skamonkey@3767
  1006
skamonkey@3767
  1007
	if(ret >= Pl_Handled)
skamonkey@3767
  1008
		RETURN_META_VALUE(MRES_SUPERCEDE, 1);
skamonkey@3767
  1009
skamonkey@3767
  1010
	if(ret == Pl_Changed)
skamonkey@3767
  1011
	{
skamonkey@3767
  1012
		CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker);
skamonkey@3767
  1013
		if(!pEntAttacker)
skamonkey@3767
  1014
		{
skamonkey@3767
  1015
			callback->GetParentContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker);
skamonkey@3767
  1016
			RETURN_META_VALUE(MRES_IGNORED, 0);
skamonkey@3767
  1017
		}
skamonkey@3767
  1018
		CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor);
skamonkey@3767
  1019
		if(!pEntInflictor)
skamonkey@3767
  1020
		{
skamonkey@3767
  1021
			callback->GetParentContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor);
skamonkey@3767
  1022
			RETURN_META_VALUE(MRES_IGNORED, 0);
skamonkey@3767
  1023
		}
skamonkey@3767
  1024
skamonkey@3767
  1025
		info.SetAttacker(pEntAttacker);
skamonkey@3767
  1026
		info.SetInflictor(pEntInflictor);
skamonkey@3767
  1027
		info.SetDamage(damage);
skamonkey@3767
  1028
		info.SetDamageType(damagetype);
skamonkey@3767
  1029
		info.SetWeapon(gamehelpers->ReferenceToEntity(weapon));
skamonkey@3767
  1030
		info.SetDamageForce(
skamonkey@3767
  1031
			sp_ctof(damageForce[0]),
skamonkey@3767
  1032
			sp_ctof(damageForce[1]),
skamonkey@3767
  1033
			sp_ctof(damageForce[2]));
skamonkey@3767
  1034
		info.SetDamagePosition(
skamonkey@3767
  1035
			sp_ctof(damagePosition[0]),
skamonkey@3767
  1036
			sp_ctof(damagePosition[1]),
skamonkey@3767
  1037
			sp_ctof(damagePosition[2]));
skamonkey@3767
  1038
skamonkey@3767
  1039
		RETURN_META_VALUE(MRES_HANDLED, 1); 
skamonkey@3767
  1040
	}
skamonkey@3767
  1041
skamonkey@3767
  1042
	RETURN_META_VALUE(MRES_IGNORED, 0);
skamonkey@3767
  1043
}
skamonkey@3767
  1044
skamonkey@3767
  1045
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
skamonkey@3767
  1046
{
skamonkey@3767
  1047
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1048
	IPluginFunction *callback = NULL;
skamonkey@3767
  1049
skamonkey@3767
  1050
	HOOKLOOP
skamonkey@3767
  1051
	{
skamonkey@3767
  1052
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_OnTakeDamagePost)
skamonkey@3767
  1053
			continue;
skamonkey@3767
  1054
skamonkey@3767
  1055
		callback = g_HookList[i].callback;
skamonkey@3767
  1056
		callback->PushCell(entity);
skamonkey@3767
  1057
		callback->PushCell(info.GetAttacker());
skamonkey@3767
  1058
		callback->PushCell(info.GetInflictor());
skamonkey@3767
  1059
		callback->PushFloat(info.GetDamage());
skamonkey@3767
  1060
		callback->PushCell(info.GetDamageType());
skamonkey@3767
  1061
		callback->PushCell(info.GetWeapon());
skamonkey@3767
  1062
skamonkey@3767
  1063
		Vector force = info.GetDamageForce();
skamonkey@3767
  1064
		cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
skamonkey@3767
  1065
		callback->PushArray(damageForce, 3);
skamonkey@3767
  1066
skamonkey@3767
  1067
		Vector pos = info.GetDamagePosition();
skamonkey@3767
  1068
		cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
skamonkey@3767
  1069
		callback->PushArray(damagePosition, 3);
skamonkey@3767
  1070
skamonkey@3767
  1071
		callback->PushCell(info.GetDamageCustom());
skamonkey@3767
  1072
skamonkey@3767
  1073
		callback->Execute(NULL);
skamonkey@3767
  1074
	}
skamonkey@3767
  1075
skamonkey@3767
  1076
	RETURN_META_VALUE(MRES_IGNORED, 0);
skamonkey@3767
  1077
}
skamonkey@3767
  1078
skamonkey@3767
  1079
void SDKHooks::Hook_PreThink()
skamonkey@3767
  1080
{
skamonkey@3767
  1081
	Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThink);
skamonkey@3767
  1082
}
skamonkey@3767
  1083
skamonkey@3767
  1084
void SDKHooks::Hook_PreThinkPost()
skamonkey@3767
  1085
{
skamonkey@3767
  1086
	Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThinkPost);
skamonkey@3767
  1087
}
skamonkey@3767
  1088
skamonkey@3767
  1089
void SDKHooks::Hook_PostThink()
skamonkey@3767
  1090
{
skamonkey@3767
  1091
	Call(META_IFACEPTR(CBaseEntity), SDKHook_PostThink);
skamonkey@3767
  1092
}
skamonkey@3767
  1093
skamonkey@3767
  1094
void SDKHooks::Hook_PostThinkPost()
skamonkey@3767
  1095
{
skamonkey@3767
  1096
	Call(META_IFACEPTR(CBaseEntity), SDKHook_PostThinkPost);
skamonkey@3767
  1097
}
skamonkey@3767
  1098
skamonkey@3767
  1099
bool SDKHooks::Hook_Reload()
skamonkey@3767
  1100
{
skamonkey@3767
  1101
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1102
	cell_t res;
skamonkey@3767
  1103
	IPluginFunction *callback = NULL;
skamonkey@3767
  1104
skamonkey@3767
  1105
	HOOKLOOP
skamonkey@3767
  1106
	{
skamonkey@3767
  1107
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_Reload)
skamonkey@3767
  1108
			continue;
skamonkey@3767
  1109
skamonkey@3767
  1110
		callback = g_HookList[i].callback;
skamonkey@3767
  1111
		callback->PushCell(entity);
skamonkey@3767
  1112
		callback->Execute(&res);
skamonkey@3767
  1113
	}
skamonkey@3767
  1114
skamonkey@3767
  1115
	if (res >= Pl_Handled)
skamonkey@3767
  1116
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
  1117
skamonkey@3767
  1118
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1119
}
skamonkey@3767
  1120
skamonkey@3767
  1121
bool SDKHooks::Hook_ReloadPost()
skamonkey@3767
  1122
{
skamonkey@3767
  1123
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1124
	IPluginFunction *callback = NULL;
skamonkey@3767
  1125
skamonkey@3767
  1126
	HOOKLOOP
skamonkey@3767
  1127
	{
skamonkey@3767
  1128
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_ReloadPost)
skamonkey@3767
  1129
			continue;
skamonkey@3767
  1130
skamonkey@3767
  1131
		callback = g_HookList[i].callback;
skamonkey@3767
  1132
		callback->PushCell(entity);
skamonkey@3767
  1133
		callback->PushCell(META_RESULT_OVERRIDE_RET(bool) ? 1 : 0);
skamonkey@3767
  1134
		callback->Execute(NULL);
skamonkey@3767
  1135
	}
skamonkey@3767
  1136
skamonkey@3767
  1137
	return true;
skamonkey@3767
  1138
}
skamonkey@3767
  1139
skamonkey@3767
  1140
void SDKHooks::Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways)
skamonkey@3767
  1141
{
skamonkey@3767
  1142
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_SetTransmit, gamehelpers->IndexOfEdict(pInfo->m_pClientEnt));
skamonkey@3767
  1143
skamonkey@3767
  1144
	if(result >= Pl_Handled)
skamonkey@3767
  1145
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1146
skamonkey@3767
  1147
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1148
}
skamonkey@3767
  1149
skamonkey@3767
  1150
bool SDKHooks::Hook_ShouldCollide(int collisionGroup, int contentsMask)
skamonkey@3767
  1151
{
skamonkey@3767
  1152
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1153
	IPluginFunction *callback = NULL;
skamonkey@3767
  1154
	bool origRet = ((META_RESULT_STATUS >= MRES_OVERRIDE)?(META_RESULT_OVERRIDE_RET(bool)):(META_RESULT_ORIG_RET(bool)));
skamonkey@3767
  1155
	cell_t res;
skamonkey@3767
  1156
skamonkey@3767
  1157
	HOOKLOOP
skamonkey@3767
  1158
	{
skamonkey@3767
  1159
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_ShouldCollide)
skamonkey@3767
  1160
			continue;
skamonkey@3767
  1161
skamonkey@3767
  1162
		callback = g_HookList[i].callback;
skamonkey@3767
  1163
		callback->PushCell(entity);
skamonkey@3767
  1164
		callback->PushCell(collisionGroup);
skamonkey@3767
  1165
		callback->PushCell(contentsMask);
skamonkey@3767
  1166
		callback->PushCell(origRet ? 1 : 0);
skamonkey@3767
  1167
		callback->Execute(&res);
skamonkey@3767
  1168
	}
skamonkey@3767
  1169
skamonkey@3767
  1170
	bool ret = false;
skamonkey@3767
  1171
	if (res != 0)
skamonkey@3767
  1172
	{
skamonkey@3767
  1173
		ret = true;
skamonkey@3767
  1174
	}
skamonkey@3767
  1175
skamonkey@3767
  1176
	RETURN_META_VALUE(MRES_SUPERCEDE, ret);
skamonkey@3767
  1177
}
skamonkey@3767
  1178
skamonkey@3767
  1179
void SDKHooks::Hook_Spawn()
skamonkey@3767
  1180
{
skamonkey@3767
  1181
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1182
	IPluginFunction *callback = NULL;
skamonkey@3767
  1183
	cell_t res;
skamonkey@3767
  1184
skamonkey@3767
  1185
	HOOKLOOP
skamonkey@3767
  1186
	{
skamonkey@3767
  1187
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_Spawn)
skamonkey@3767
  1188
			continue;
skamonkey@3767
  1189
skamonkey@3767
  1190
		callback = g_HookList[i].callback;
skamonkey@3767
  1191
		callback->PushCell(entity);
skamonkey@3767
  1192
		callback->Execute(&res);
skamonkey@3767
  1193
	}
skamonkey@3767
  1194
skamonkey@3767
  1195
	if (res >= Pl_Handled)
skamonkey@3767
  1196
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1197
skamonkey@3767
  1198
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1199
}
skamonkey@3767
  1200
skamonkey@3767
  1201
void SDKHooks::Hook_SpawnPost()
skamonkey@3767
  1202
{
skamonkey@3767
  1203
	Call(META_IFACEPTR(CBaseEntity), SDKHook_SpawnPost);
skamonkey@3767
  1204
}
skamonkey@3767
  1205
skamonkey@3767
  1206
void SDKHooks::Hook_StartTouch(CBaseEntity *pOther)
skamonkey@3767
  1207
{
skamonkey@3767
  1208
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_StartTouch, pOther);
skamonkey@3767
  1209
	if(result >= Pl_Handled)
skamonkey@3767
  1210
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1211
skamonkey@3767
  1212
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1213
}
skamonkey@3767
  1214
skamonkey@3767
  1215
void SDKHooks::Hook_StartTouchPost(CBaseEntity *pOther)
skamonkey@3767
  1216
{
skamonkey@3767
  1217
	Call(META_IFACEPTR(CBaseEntity), SDKHook_StartTouchPost, pOther);
skamonkey@3767
  1218
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1219
}
skamonkey@3767
  1220
skamonkey@3767
  1221
void SDKHooks::Hook_Think()
skamonkey@3767
  1222
{
skamonkey@3767
  1223
	Call(META_IFACEPTR(CBaseEntity), SDKHook_Think);
skamonkey@3767
  1224
}
skamonkey@3767
  1225
skamonkey@3767
  1226
void SDKHooks::Hook_ThinkPost()
skamonkey@3767
  1227
{
skamonkey@3767
  1228
	Call(META_IFACEPTR(CBaseEntity), SDKHook_ThinkPost);
skamonkey@3767
  1229
}
skamonkey@3767
  1230
skamonkey@3767
  1231
void SDKHooks::Hook_Touch(CBaseEntity *pOther)
skamonkey@3767
  1232
{
skamonkey@3767
  1233
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_Touch, pOther);
skamonkey@3767
  1234
skamonkey@3767
  1235
	if(result >= Pl_Handled)
skamonkey@3767
  1236
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1237
skamonkey@3767
  1238
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1239
}
skamonkey@3767
  1240
skamonkey@3767
  1241
void SDKHooks::Hook_TouchPost(CBaseEntity *pOther)
skamonkey@3767
  1242
{
skamonkey@3767
  1243
	Call(META_IFACEPTR(CBaseEntity), SDKHook_TouchPost, pOther);
skamonkey@3767
  1244
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1245
}
skamonkey@3767
  1246
skamonkey@3767
  1247
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
skamonkey@3767
  1248
void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, void *pUnknownJK)
skamonkey@3767
  1249
#else
skamonkey@3767
  1250
void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr)
skamonkey@3767
  1251
#endif
skamonkey@3767
  1252
{
skamonkey@3767
  1253
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1254
	int attacker = info.GetAttacker();
skamonkey@3767
  1255
	int inflictor = info.GetInflictor();
skamonkey@3767
  1256
	float damage = info.GetDamage();
skamonkey@3767
  1257
	int damagetype = info.GetDamageType();
skamonkey@3767
  1258
	int ammotype = info.GetAmmoType();
skamonkey@3767
  1259
	IPluginFunction *callback = NULL;
skamonkey@3767
  1260
	cell_t res, ret = Pl_Continue;
skamonkey@3767
  1261
skamonkey@3767
  1262
	HOOKLOOP
skamonkey@3767
  1263
	{
skamonkey@3767
  1264
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_TraceAttack)
skamonkey@3767
  1265
			continue;
skamonkey@3767
  1266
skamonkey@3767
  1267
		callback = g_HookList[i].callback;
skamonkey@3767
  1268
		callback->PushCell(entity);
skamonkey@3767
  1269
		callback->PushCellByRef(&attacker);
skamonkey@3767
  1270
		callback->PushCellByRef(&inflictor);
skamonkey@3767
  1271
		callback->PushFloatByRef(&damage);
skamonkey@3767
  1272
		callback->PushCellByRef(&damagetype);
skamonkey@3767
  1273
		callback->PushCellByRef(&ammotype);
skamonkey@3767
  1274
		callback->PushCell(ptr->hitbox);
skamonkey@3767
  1275
		callback->PushCell(ptr->hitgroup);
skamonkey@3767
  1276
		callback->Execute(&res);
skamonkey@3767
  1277
skamonkey@3767
  1278
		if(res > ret)
skamonkey@3767
  1279
			ret = res;
skamonkey@3767
  1280
	}
skamonkey@3767
  1281
skamonkey@3767
  1282
	if(ret >= Pl_Handled)
skamonkey@3767
  1283
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1284
skamonkey@3767
  1285
	if(ret == Pl_Changed)
skamonkey@3767
  1286
	{
skamonkey@3767
  1287
		CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker);
skamonkey@3767
  1288
		if(!pEntAttacker)
skamonkey@3767
  1289
		{
skamonkey@3767
  1290
			callback->GetParentContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker);
skamonkey@3767
  1291
			RETURN_META(MRES_IGNORED);
skamonkey@3767
  1292
		}
skamonkey@3767
  1293
		CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor);
skamonkey@3767
  1294
		if(!pEntInflictor)
skamonkey@3767
  1295
		{
skamonkey@3767
  1296
			callback->GetParentContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor);
skamonkey@3767
  1297
			RETURN_META(MRES_IGNORED);
skamonkey@3767
  1298
		}
skamonkey@3767
  1299
		
skamonkey@3767
  1300
		info.SetAttacker(gamehelpers->ReferenceToEntity(attacker));
skamonkey@3767
  1301
		info.SetInflictor(gamehelpers->ReferenceToEntity(inflictor));
skamonkey@3767
  1302
		info.SetDamage(damage);
skamonkey@3767
  1303
		info.SetDamageType(damagetype);
skamonkey@3767
  1304
		info.SetAmmoType(ammotype);
skamonkey@3767
  1305
skamonkey@3767
  1306
		RETURN_META(MRES_HANDLED); 
skamonkey@3767
  1307
	}
skamonkey@3767
  1308
skamonkey@3767
  1309
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1310
}
skamonkey@3767
  1311
skamonkey@3767
  1312
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
skamonkey@3767
  1313
void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, void *pUnknownJK)
skamonkey@3767
  1314
#else
skamonkey@3767
  1315
void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr)
skamonkey@3767
  1316
#endif
skamonkey@3767
  1317
{
skamonkey@3767
  1318
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1319
	IPluginFunction *callback = NULL;
skamonkey@3767
  1320
skamonkey@3767
  1321
	HOOKLOOP
skamonkey@3767
  1322
	{
skamonkey@3767
  1323
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_TraceAttackPost)
skamonkey@3767
  1324
			continue;
skamonkey@3767
  1325
skamonkey@3767
  1326
		callback = g_HookList[i].callback;
skamonkey@3767
  1327
		callback->PushCell(entity);
skamonkey@3767
  1328
		callback->PushCell(info.GetAttacker());
skamonkey@3767
  1329
		callback->PushCell(info.GetInflictor());
skamonkey@3767
  1330
		callback->PushFloat(info.GetDamage());
skamonkey@3767
  1331
		callback->PushCell(info.GetDamageType());
skamonkey@3767
  1332
		callback->PushCell(info.GetAmmoType());
skamonkey@3767
  1333
		callback->PushCell(ptr->hitbox);
skamonkey@3767
  1334
		callback->PushCell(ptr->hitgroup);
skamonkey@3767
  1335
		callback->Execute(NULL);
skamonkey@3767
  1336
	}
skamonkey@3767
  1337
skamonkey@3767
  1338
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1339
}
skamonkey@3767
  1340
skamonkey@3767
  1341
void SDKHooks::Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
skamonkey@3767
  1342
{
skamonkey@3767
  1343
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1344
	int activator = gamehelpers->EntityToBCompatRef(pActivator);
skamonkey@3767
  1345
	int caller = gamehelpers->EntityToBCompatRef(pCaller);
skamonkey@3767
  1346
skamonkey@3767
  1347
	cell_t ret;
skamonkey@3767
  1348
	IPluginFunction *callback = NULL;
skamonkey@3767
  1349
skamonkey@3767
  1350
	HOOKLOOP
skamonkey@3767
  1351
	{
skamonkey@3767
  1352
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_Use)
skamonkey@3767
  1353
			continue;
skamonkey@3767
  1354
skamonkey@3767
  1355
		callback = g_HookList[i].callback;
skamonkey@3767
  1356
		callback->PushCell(entity);
skamonkey@3767
  1357
		callback->PushCell(activator);
skamonkey@3767
  1358
		callback->PushCell(caller);
skamonkey@3767
  1359
		callback->PushCell(useType);
skamonkey@3767
  1360
		callback->PushFloat(value);
skamonkey@3767
  1361
		callback->Execute(&ret);
skamonkey@3767
  1362
	}
skamonkey@3767
  1363
skamonkey@3767
  1364
	if (ret >= Pl_Handled)
skamonkey@3767
  1365
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1366
skamonkey@3767
  1367
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1368
}
skamonkey@3767
  1369
skamonkey@3767
  1370
void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
skamonkey@3767
  1371
{
skamonkey@3767
  1372
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1373
	int activator = gamehelpers->EntityToBCompatRef(pActivator);
skamonkey@3767
  1374
	int caller = gamehelpers->EntityToBCompatRef(pCaller);
skamonkey@3767
  1375
skamonkey@3767
  1376
	IPluginFunction *callback = NULL;
skamonkey@3767
  1377
skamonkey@3767
  1378
	HOOKLOOP
skamonkey@3767
  1379
	{
skamonkey@3767
  1380
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_UsePost)
skamonkey@3767
  1381
			continue;
skamonkey@3767
  1382
skamonkey@3767
  1383
		callback = g_HookList[i].callback;
skamonkey@3767
  1384
		callback->PushCell(entity);
skamonkey@3767
  1385
		callback->PushCell(activator);
skamonkey@3767
  1386
		callback->PushCell(caller);
skamonkey@3767
  1387
		callback->PushCell(useType);
skamonkey@3767
  1388
		callback->PushFloat(value);
skamonkey@3767
  1389
		callback->Execute(NULL);
skamonkey@3767
  1390
	}
skamonkey@3767
  1391
skamonkey@3767
  1392
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1393
}
skamonkey@3767
  1394
skamonkey@3767
  1395
void SDKHooks::OnEntityDeleted(CBaseEntity *pEntity)
skamonkey@3767
  1396
{
skamonkey@3767
  1397
	int entity = gamehelpers->EntityToBCompatRef(pEntity);
skamonkey@3767
  1398
skamonkey@3767
  1399
	// Call OnEntityDestroyed forward
skamonkey@3767
  1400
	g_pOnEntityDestroyed->PushCell(entity);
skamonkey@3767
  1401
	g_pOnEntityDestroyed->Execute(NULL);
skamonkey@3767
  1402
	
skamonkey@3767
  1403
	SDKHooks::RemoveEntityHooks(pEntity);
skamonkey@3767
  1404
skamonkey@3767
  1405
	m_EntityExists.Set(gamehelpers->ReferenceToIndex(entity), false);
skamonkey@3767
  1406
}
skamonkey@3767
  1407
skamonkey@3767
  1408
void SDKHooks::Hook_VPhysicsUpdate(IPhysicsObject *pPhysics)
skamonkey@3767
  1409
{
skamonkey@3767
  1410
	Call(META_IFACEPTR(CBaseEntity), SDKHook_VPhysicsUpdate);
skamonkey@3767
  1411
}
skamonkey@3767
  1412
skamonkey@3767
  1413
void SDKHooks::Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics)
skamonkey@3767
  1414
{
skamonkey@3767
  1415
	Call(META_IFACEPTR(CBaseEntity), SDKHook_VPhysicsUpdatePost);
skamonkey@3767
  1416
}
skamonkey@3767
  1417
skamonkey@3767
  1418
bool SDKHooks::Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1419
{
skamonkey@3767
  1420
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanSwitchTo, pWeapon);
skamonkey@3767
  1421
skamonkey@3767
  1422
	if(result >= Pl_Handled)
skamonkey@3767
  1423
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
  1424
skamonkey@3767
  1425
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1426
}
skamonkey@3767
  1427
skamonkey@3767
  1428
bool SDKHooks::Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1429
{
skamonkey@3767
  1430
	Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanSwitchToPost, pWeapon);
skamonkey@3767
  1431
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1432
}
skamonkey@3767
  1433
skamonkey@3767
  1434
bool SDKHooks::Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1435
{
skamonkey@3767
  1436
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanUse, pWeapon);
skamonkey@3767
  1437
skamonkey@3767
  1438
	if(result >= Pl_Handled)
skamonkey@3767
  1439
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
  1440
skamonkey@3767
  1441
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1442
}
skamonkey@3767
  1443
skamonkey@3767
  1444
bool SDKHooks::Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1445
{
skamonkey@3767
  1446
	Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanUsePost, pWeapon);
skamonkey@3767
  1447
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1448
}
skamonkey@3767
  1449
skamonkey@3767
  1450
void SDKHooks::Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity)
skamonkey@3767
  1451
{
skamonkey@3767
  1452
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponDrop, pWeapon);
skamonkey@3767
  1453
skamonkey@3767
  1454
	if(result >= Pl_Handled)
skamonkey@3767
  1455
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1456
skamonkey@3767
  1457
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1458
}
skamonkey@3767
  1459
skamonkey@3767
  1460
void SDKHooks::Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity)
skamonkey@3767
  1461
{
skamonkey@3767
  1462
	Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponDropPost, pWeapon);
skamonkey@3767
  1463
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1464
}
skamonkey@3767
  1465
skamonkey@3767
  1466
void SDKHooks::Hook_WeaponEquip(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1467
{
skamonkey@3767
  1468
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponEquip, pWeapon);
skamonkey@3767
  1469
skamonkey@3767
  1470
	if(result >= Pl_Handled)
skamonkey@3767
  1471
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1472
skamonkey@3767
  1473
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1474
}
skamonkey@3767
  1475
skamonkey@3767
  1476
void SDKHooks::Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1477
{
skamonkey@3767
  1478
	Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponEquipPost, pWeapon);
skamonkey@3767
  1479
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1480
}
skamonkey@3767
  1481
skamonkey@3767
  1482
bool SDKHooks::Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex)
skamonkey@3767
  1483
{
skamonkey@3767
  1484
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponSwitch, pWeapon);
skamonkey@3767
  1485
skamonkey@3767
  1486
	if(result >= Pl_Handled)
skamonkey@3767
  1487
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
  1488
skamonkey@3767
  1489
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1490
}
skamonkey@3767
  1491
skamonkey@3767
  1492
bool SDKHooks::Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex)
skamonkey@3767
  1493
{
skamonkey@3767
  1494
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponSwitchPost, pWeapon);
skamonkey@3767
  1495
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1496
}
skamonkey@3767
  1497
skamonkey@3767
  1498
skamonkey@3767
  1499
void SDKHooks::RemoveEntityHooks(CBaseEntity *pEnt)
skamonkey@3767
  1500
{
skamonkey@3767
  1501
	int entity = gamehelpers->EntityToBCompatRef(pEnt);
skamonkey@3767
  1502
	
skamonkey@3767
  1503
	// Remove hooks
skamonkey@3767
  1504
	HOOKLOOP
skamonkey@3767
  1505
	{
skamonkey@3767
  1506
		if(g_HookList[i].entity == entity)
skamonkey@3767
  1507
		{
skamonkey@3767
  1508
#ifdef SDKHOOKSDEBUG
skamonkey@3767
  1509
			META_CONPRINTF("DEBUG: Removing hook #%d on entity %d (UpdateOnRemove or clientdisconnect)\n", i, entity);
skamonkey@3767
  1510
#endif
skamonkey@3767
  1511
			Unhook(i);
skamonkey@3767
  1512
		}
skamonkey@3767
  1513
	}
skamonkey@3767
  1514
}
skamonkey@3767
  1515
skamonkey@3767
  1516
CON_COMMAND(sdkhooks_listhooks, "Lists all current hooks")
skamonkey@3767
  1517
{
skamonkey@3767
  1518
	META_CONPRINTF("    %-24.23s %-18.17s %s\n", "Plugin", "Type", "Entity");
skamonkey@3767
  1519
	
skamonkey@3767
  1520
	IPlugin *pPlugin;
skamonkey@3767
  1521
	const sm_plugininfo_t *info;
skamonkey@3767
  1522
	for(int i = g_HookList.Count() - 1; i >= 0; i--)
skamonkey@3767
  1523
	{
skamonkey@3767
  1524
		g_HookList[i].callback->GetParentRuntime()->GetDefaultContext()->GetKey(2, (void **)&pPlugin);
skamonkey@3767
  1525
		info = pPlugin->GetPublicInfo();
skamonkey@3767
  1526
		META_CONPRINTF("%2d. %-24.23s %-18.17s %d\n", i + 1, info->name[0] ? info->name : pPlugin->GetFilename(), g_HookTypes[g_HookList[i].type].name, g_HookList[i].entity);
skamonkey@3767
  1527
	}
skamonkey@3767
  1528
}