extensions/sdkhooks/extension.cpp
author David Anderson <dvander@alliedmods.net>
Thu Aug 08 22:02:42 2013 -0700 (2013-08-08)
changeset 3980 dc7dfcd855dc
parent 3971 d2e8100b2814
child 4054 0964336bb978
permissions -rw-r--r--
More Windows build fix.
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@3961
   151
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
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");
aangione@3971
   188
	sharesys->AddInterface(myself, &g_Interface);
skamonkey@3767
   189
	sharesys->AddCapabilityProvider(myself, this, "SDKHook_DmgCustomInOTD");
skamonkey@3767
   190
	sharesys->AddCapabilityProvider(myself, this, "SDKHook_LogicalEntSupport");
skamonkey@3767
   191
skamonkey@3767
   192
	playerhelpers->AddClientListener(&g_Interface);
skamonkey@3767
   193
	
skamonkey@3767
   194
	plsys->AddPluginsListener(&g_Interface);
skamonkey@3767
   195
skamonkey@3767
   196
	g_pOnEntityCreated = forwards->CreateForward("OnEntityCreated", ET_Ignore, 2, NULL, Param_Cell, Param_String);
skamonkey@3767
   197
	g_pOnEntityDestroyed = forwards->CreateForward("OnEntityDestroyed", ET_Ignore, 1, NULL, Param_Cell);
skamonkey@3767
   198
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   199
	g_pOnGetGameNameDescription = forwards->CreateForward("OnGetGameDescription", ET_Hook, 2, NULL, Param_String);
skamonkey@3767
   200
#endif
skamonkey@3767
   201
	g_pOnLevelInit = forwards->CreateForward("OnLevelInit", ET_Hook, 2, NULL, Param_String, Param_String);
skamonkey@3767
   202
skamonkey@3767
   203
	buffer[0] = '\0';
skamonkey@3767
   204
	if (!gameconfs->LoadGameConfigFile("sdkhooks.games", &g_pGameConf, buffer, sizeof(buffer)))
skamonkey@3767
   205
	{
skamonkey@3767
   206
		if (buffer[0])
skamonkey@3767
   207
		{
skamonkey@3767
   208
			g_pSM->Format(error, maxlength, "Could not read sdkhooks.games gamedata: %s", buffer);
skamonkey@3767
   209
		}
skamonkey@3767
   210
		
skamonkey@3767
   211
		return false;
skamonkey@3767
   212
	}
skamonkey@3767
   213
skamonkey@3767
   214
	void *gEntList = gamehelpers->GetGlobalEntityList();
skamonkey@3767
   215
	if (!gEntList)
skamonkey@3767
   216
	{
skamonkey@3767
   217
		g_pSM->Format(error, maxlength, "Cannot find gEntList pointer");
skamonkey@3767
   218
		return false;
skamonkey@3767
   219
	}
skamonkey@3767
   220
skamonkey@3767
   221
	int offset = -1; /* 65572 */
skamonkey@3767
   222
	if (!g_pGameConf->GetOffset("EntityListeners", &offset))
skamonkey@3767
   223
	{
skamonkey@3767
   224
		g_pSM->Format(error, maxlength, "Cannot find EntityListeners offset");
skamonkey@3767
   225
		return false;
skamonkey@3767
   226
	}
skamonkey@3767
   227
skamonkey@3767
   228
	CUtlVector<IEntityListener *> *pListeners = (CUtlVector<IEntityListener *> *)((intptr_t)gEntList + offset);
skamonkey@3767
   229
	pListeners->AddToTail(this);
skamonkey@3767
   230
skamonkey@3767
   231
	SetupHooks();
skamonkey@3767
   232
skamonkey@3767
   233
#if SOURCE_ENGINE >= SE_ORANGEBOX
skamonkey@3767
   234
	int index;
skamonkey@3767
   235
	CBaseHandle hndl;
skamonkey@3767
   236
	for (IHandleEntity *pEnt = (IHandleEntity *)servertools->FirstEntity(); pEnt; pEnt = (IHandleEntity *)servertools->NextEntity((CBaseEntity *)pEnt))
skamonkey@3767
   237
	{
skamonkey@3767
   238
		hndl = pEnt->GetRefEHandle();
skamonkey@3767
   239
		if (hndl == INVALID_EHANDLE_INDEX || !hndl.IsValid())
skamonkey@3767
   240
			continue;
skamonkey@3767
   241
		
skamonkey@3767
   242
		index = hndl.GetEntryIndex();
skamonkey@3767
   243
		m_EntityExists.Set(index);
skamonkey@3767
   244
	}
skamonkey@3767
   245
#else
skamonkey@3767
   246
	for (int i = 0; i < NUM_ENT_ENTRIES; i++)
skamonkey@3767
   247
	{
skamonkey@3767
   248
		if (gamehelpers->ReferenceToEntity(i) != NULL)
skamonkey@3767
   249
			m_EntityExists.Set(i);
skamonkey@3767
   250
	}
skamonkey@3767
   251
#endif
skamonkey@3767
   252
skamonkey@3767
   253
	return true;
skamonkey@3767
   254
}
skamonkey@3767
   255
skamonkey@3767
   256
inline void HookLevelInit()
skamonkey@3767
   257
{
skamonkey@3767
   258
	assert(g_hookOnLevelInit == 0);
kyle@3819
   259
	g_hookOnLevelInit = SH_ADD_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(&g_Interface, &SDKHooks::Hook_LevelInit), false);
skamonkey@3767
   260
	assert(g_hookOnGetMapEntitiesString == 0);
kyle@3819
   261
	g_hookOnGetMapEntitiesString = SH_ADD_HOOK(IVEngineServer, GetMapEntitiesString, engine, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GetMapEntitiesString), false);
skamonkey@3767
   262
}
skamonkey@3767
   263
skamonkey@3767
   264
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   265
inline void HookGetGameDescription()
skamonkey@3767
   266
{
skamonkey@3767
   267
	assert(g_hookOnGetGameDescription == 0);
kyle@3819
   268
	g_hookOnGetGameDescription = SH_ADD_HOOK(IServerGameDLL, GetGameDescription, gamedll, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GetGameDescription), false);
skamonkey@3767
   269
}
skamonkey@3767
   270
#endif
skamonkey@3767
   271
skamonkey@3767
   272
void SDKHooks::SDK_OnAllLoaded()
skamonkey@3767
   273
{
skamonkey@3767
   274
	SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
skamonkey@3767
   275
skamonkey@3767
   276
	if (!g_pBinTools)
skamonkey@3767
   277
	{
skamonkey@3767
   278
		g_pSM->LogError(myself, "Could not find interface: " SMINTERFACE_BINTOOLS_NAME);
skamonkey@3767
   279
		return;
skamonkey@3767
   280
	}
skamonkey@3767
   281
skamonkey@3767
   282
	if (g_pOnLevelInit->GetFunctionCount() > 0)
skamonkey@3767
   283
		HookLevelInit();
skamonkey@3767
   284
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   285
	if (g_pOnGetGameNameDescription->GetFunctionCount() > 0)
skamonkey@3767
   286
		HookGetGameDescription();
skamonkey@3767
   287
#endif
skamonkey@3767
   288
}
skamonkey@3767
   289
skamonkey@3767
   290
#define KILL_HOOK_IF_ACTIVE(hook) \
skamonkey@3767
   291
	if (hook != 0) \
skamonkey@3767
   292
	{ \
skamonkey@3767
   293
		SH_REMOVE_HOOK_ID(hook); \
skamonkey@3767
   294
	}
skamonkey@3767
   295
skamonkey@3767
   296
void SDKHooks::SDK_OnUnload()
skamonkey@3767
   297
{
skamonkey@3767
   298
	// Remove left over hooks
skamonkey@3767
   299
	HOOKLOOP
skamonkey@3767
   300
		Unhook(i);
skamonkey@3767
   301
skamonkey@3767
   302
	KILL_HOOK_IF_ACTIVE(g_hookOnLevelInit);
skamonkey@3767
   303
	KILL_HOOK_IF_ACTIVE(g_hookOnGetMapEntitiesString);
skamonkey@3767
   304
skamonkey@3767
   305
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   306
	KILL_HOOK_IF_ACTIVE(g_hookOnGetGameDescription);
skamonkey@3767
   307
#endif
skamonkey@3767
   308
skamonkey@3767
   309
	forwards->ReleaseForward(g_pOnEntityCreated);
skamonkey@3767
   310
	forwards->ReleaseForward(g_pOnEntityDestroyed);
skamonkey@3767
   311
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   312
	forwards->ReleaseForward(g_pOnGetGameNameDescription);
skamonkey@3767
   313
#endif
skamonkey@3767
   314
	forwards->ReleaseForward(g_pOnLevelInit);
skamonkey@3767
   315
skamonkey@3767
   316
	plsys->RemovePluginsListener(&g_Interface);
skamonkey@3767
   317
skamonkey@3767
   318
	playerhelpers->RemoveClientListener(&g_Interface);
skamonkey@3767
   319
skamonkey@3767
   320
	sharesys->DropCapabilityProvider(myself, this, "SDKHook_DmgCustomInOTD");
skamonkey@3767
   321
	sharesys->DropCapabilityProvider(myself, this, "SDKHook_LogicalEntSupport");
skamonkey@3767
   322
skamonkey@3767
   323
	void *gEntList = gamehelpers->GetGlobalEntityList();
skamonkey@3767
   324
	if (gEntList)
skamonkey@3767
   325
	{
skamonkey@3767
   326
		int offset = -1; /* 65572 */
skamonkey@3767
   327
		if (g_pGameConf->GetOffset("EntityListeners", &offset))
skamonkey@3767
   328
		{
skamonkey@3767
   329
			CUtlVector<IEntityListener *> *pListeners = (CUtlVector<IEntityListener *> *)((intptr_t)gEntList + offset);
skamonkey@3767
   330
			pListeners->FindAndRemove(this);
skamonkey@3767
   331
		}
skamonkey@3767
   332
	}
skamonkey@3767
   333
skamonkey@3767
   334
	gameconfs->CloseGameConfigFile(g_pGameConf);
skamonkey@3767
   335
}
skamonkey@3767
   336
skamonkey@3767
   337
bool SDKHooks::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late)
skamonkey@3767
   338
{
skamonkey@3767
   339
	GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
skamonkey@3767
   340
skamonkey@3767
   341
#if SOURCE_ENGINE >= SE_ORANGEBOX
skamonkey@3767
   342
	g_pCVar = icvar;
skamonkey@3767
   343
#endif
skamonkey@3767
   344
	CONVAR_REGISTER(this);
skamonkey@3767
   345
	
skamonkey@3767
   346
	gpGlobals = ismm->GetCGlobals();
skamonkey@3767
   347
skamonkey@3767
   348
	return true;
skamonkey@3767
   349
}
skamonkey@3767
   350
januk@3774
   351
const char *SDKHooks::GetExtensionVerString()
januk@3774
   352
{
januk@3774
   353
	return SM_VERSION_STRING;
januk@3774
   354
}
januk@3774
   355
januk@3774
   356
const char *SDKHooks::GetExtensionDateString()
januk@3774
   357
{
januk@3774
   358
	return SM_BUILD_TIMESTAMP;
januk@3774
   359
}
januk@3774
   360
skamonkey@3767
   361
void SDKHooks::OnPluginLoaded(IPlugin *plugin)
skamonkey@3767
   362
{
skamonkey@3767
   363
	if (g_pOnLevelInit->GetFunctionCount() > 0 && g_hookOnLevelInit == 0)
skamonkey@3767
   364
		HookLevelInit();
skamonkey@3767
   365
skamonkey@3767
   366
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   367
	if (g_pOnGetGameNameDescription->GetFunctionCount() > 0 && g_hookOnGetGameDescription == 0)
skamonkey@3767
   368
		HookGetGameDescription();
skamonkey@3767
   369
#endif
skamonkey@3767
   370
}
skamonkey@3767
   371
skamonkey@3767
   372
void SDKHooks::OnPluginUnloaded(IPlugin *plugin)
skamonkey@3767
   373
{
skamonkey@3767
   374
	IPluginContext *plugincontext = plugin->GetBaseContext();
skamonkey@3767
   375
	HOOKLOOP
skamonkey@3767
   376
	{
skamonkey@3767
   377
		if(g_HookList[i].callback->GetParentContext() == plugincontext)
skamonkey@3767
   378
			Unhook(i);
skamonkey@3767
   379
	}
skamonkey@3767
   380
skamonkey@3767
   381
	if (g_pOnLevelInit->GetFunctionCount() == 0)
skamonkey@3767
   382
	{
skamonkey@3767
   383
		KILL_HOOK_IF_ACTIVE(g_hookOnLevelInit);
skamonkey@3767
   384
		KILL_HOOK_IF_ACTIVE(g_hookOnGetMapEntitiesString);
skamonkey@3767
   385
	}
skamonkey@3767
   386
skamonkey@3767
   387
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   388
	if (g_pOnGetGameNameDescription->GetFunctionCount() == 0)
skamonkey@3767
   389
		KILL_HOOK_IF_ACTIVE(g_hookOnGetGameDescription);
skamonkey@3767
   390
#endif
skamonkey@3767
   391
}
skamonkey@3767
   392
skamonkey@3767
   393
void SDKHooks::OnClientPutInServer(int client)
skamonkey@3767
   394
{
aangione@3971
   395
	CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client);
aangione@3971
   396
	const char *pName = gamehelpers->GetEntityClassname(pPlayer);
skamonkey@3767
   397
aangione@3971
   398
	// Send OnEntityCreated to SM listeners
aangione@3971
   399
	SourceHook::List<ISMEntityListener *>::iterator iter;
aangione@3971
   400
	ISMEntityListener *pListener = NULL;
aangione@3971
   401
	for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++)
aangione@3971
   402
	{
aangione@3971
   403
		pListener = (*iter);
aangione@3971
   404
		pListener->OnEntityCreated(pPlayer, pName ? pName : "");
aangione@3971
   405
	}
skamonkey@3767
   406
aangione@3971
   407
	// Call OnEntityCreated forward
aangione@3971
   408
	g_pOnEntityCreated->PushCell(client);
skamonkey@3767
   409
	g_pOnEntityCreated->PushString(pName ? pName : "");
skamonkey@3767
   410
	g_pOnEntityCreated->Execute(NULL);
skamonkey@3767
   411
skamonkey@3767
   412
	m_EntityExists.Set(client);
skamonkey@3767
   413
}
skamonkey@3767
   414
aangione@3971
   415
void SDKHooks::AddEntityListener(ISMEntityListener *listener)
aangione@3971
   416
{
aangione@3971
   417
	m_EntListeners.push_back(listener);
aangione@3971
   418
}
aangione@3971
   419
aangione@3971
   420
void SDKHooks::RemoveEntityListener(ISMEntityListener *listener)
aangione@3971
   421
{
aangione@3971
   422
	m_EntListeners.remove(listener);
aangione@3971
   423
}
aangione@3971
   424
skamonkey@3767
   425
bool SDKHooks::RegisterConCommandBase(ConCommandBase *pVar)
skamonkey@3767
   426
{
skamonkey@3767
   427
	/* Always call META_REGCVAR instead of going through the engine. */
skamonkey@3767
   428
	return META_REGCVAR(pVar);
skamonkey@3767
   429
}
skamonkey@3767
   430
skamonkey@3767
   431
FeatureStatus SDKHooks::GetFeatureStatus(FeatureType type, const char *name)
skamonkey@3767
   432
{
skamonkey@3767
   433
	return FeatureStatus_Available;
skamonkey@3767
   434
}
skamonkey@3767
   435
skamonkey@3767
   436
/**
skamonkey@3767
   437
 * Functions
skamonkey@3767
   438
 */
skamonkey@3767
   439
cell_t SDKHooks::Call(int entity, SDKHookType type, int other)
skamonkey@3767
   440
{
skamonkey@3767
   441
	IPluginFunction *callback = NULL;
skamonkey@3767
   442
	cell_t res, ret = Pl_Continue;
skamonkey@3767
   443
skamonkey@3767
   444
	HOOKLOOP
skamonkey@3767
   445
	{
skamonkey@3767
   446
		if(g_HookList[i].entity != entity || g_HookList[i].type != type)
skamonkey@3767
   447
			continue;
skamonkey@3767
   448
skamonkey@3767
   449
		callback = g_HookList[i].callback;
skamonkey@3767
   450
		callback->PushCell(entity);
skamonkey@3767
   451
		if(other > -2)
skamonkey@3767
   452
			callback->PushCell(other);
skamonkey@3767
   453
skamonkey@3767
   454
		callback->Execute(&res);
skamonkey@3767
   455
		if(res > ret)
skamonkey@3767
   456
			ret = res;
skamonkey@3767
   457
	}
skamonkey@3767
   458
skamonkey@3767
   459
	return ret;
skamonkey@3767
   460
}
skamonkey@3767
   461
skamonkey@3767
   462
cell_t SDKHooks::Call(CBaseEntity *pEnt, SDKHookType type, int other)
skamonkey@3767
   463
{
skamonkey@3767
   464
	return Call(gamehelpers->EntityToBCompatRef(pEnt), type, other);
skamonkey@3767
   465
}
skamonkey@3767
   466
skamonkey@3767
   467
cell_t SDKHooks::Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *other)
skamonkey@3767
   468
{
skamonkey@3767
   469
	return Call(gamehelpers->EntityToBCompatRef(pEnt), type, gamehelpers->EntityToBCompatRef(other));
skamonkey@3767
   470
}
skamonkey@3767
   471
skamonkey@3767
   472
void SDKHooks::SetupHooks()
skamonkey@3767
   473
{
skamonkey@3767
   474
	int offset;
skamonkey@3767
   475
skamonkey@3767
   476
	//			gamedata          pre    post
skamonkey@3767
   477
	// (pre is not necessarily a prehook, just named without "Post" appeneded)
skamonkey@3767
   478
skamonkey@3767
   479
	CHECKOFFSET(EndTouch,         true,  true);
skamonkey@3767
   480
	CHECKOFFSET(FireBullets,      false, true);
skamonkey@3767
   481
	CHECKOFFSET(GroundEntChanged, false, true);
skamonkey@3767
   482
	CHECKOFFSET(OnTakeDamage,     true,  true);
skamonkey@3767
   483
	CHECKOFFSET(PreThink,         true,  true);
skamonkey@3767
   484
	CHECKOFFSET(PostThink,        true,  true);
skamonkey@3767
   485
	CHECKOFFSET(Reload,           true,  true);
skamonkey@3767
   486
	CHECKOFFSET(SetTransmit,      true,  false);
skamonkey@3767
   487
	CHECKOFFSET(ShouldCollide,    true,  false);
skamonkey@3767
   488
	CHECKOFFSET(Spawn,            true,  true);
skamonkey@3767
   489
	CHECKOFFSET(StartTouch,       true,  true);
skamonkey@3767
   490
	CHECKOFFSET(Think,            true,  true);
skamonkey@3767
   491
	CHECKOFFSET(Touch,            true,  true);
skamonkey@3767
   492
	CHECKOFFSET(TraceAttack,      true,  true);
skamonkey@3767
   493
	CHECKOFFSET(Use,              true,  true);
skamonkey@3767
   494
	CHECKOFFSET_W(CanSwitchTo,    true,  true);
skamonkey@3767
   495
	CHECKOFFSET_W(CanUse,         true,  true);
skamonkey@3767
   496
	CHECKOFFSET_W(Drop,           true,  true);
skamonkey@3767
   497
	CHECKOFFSET_W(Equip,          true,  true);
skamonkey@3767
   498
	CHECKOFFSET_W(Switch,         true,  true);
skamonkey@3767
   499
	CHECKOFFSET(VPhysicsUpdate,   true,  true);
skamonkey@3767
   500
skamonkey@3767
   501
	// this one is in a class all its own -_-
skamonkey@3767
   502
	offset = 0;
skamonkey@3767
   503
	g_pGameConf->GetOffset("GroundEntChanged", &offset);
skamonkey@3767
   504
	if (offset > 0)
skamonkey@3767
   505
	{
skamonkey@3767
   506
		SH_MANUALHOOK_RECONFIGURE(GroundEntChanged, offset, 0, 0);
skamonkey@3767
   507
		g_HookTypes[SDKHook_GroundEntChangedPost].supported = true;
skamonkey@3767
   508
	}
skamonkey@3767
   509
skamonkey@3767
   510
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   511
	CHECKOFFSET(GetMaxHealth,	true,	false);
skamonkey@3767
   512
#endif
skamonkey@3767
   513
}
skamonkey@3767
   514
skamonkey@3767
   515
HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callback)
skamonkey@3767
   516
{
skamonkey@3767
   517
	if(!g_HookTypes[type].supported)
skamonkey@3767
   518
		return HookRet_NotSupported;
skamonkey@3767
   519
skamonkey@3767
   520
	CBaseEntity *pEnt = UTIL_GetCBaseEntity(entity);
skamonkey@3767
   521
	if(!pEnt)
skamonkey@3767
   522
		return HookRet_InvalidEntity;
skamonkey@3767
   523
	if(type < 0 || type >= SDKHook_MAXHOOKS)
skamonkey@3767
   524
		return HookRet_InvalidHookType;
skamonkey@3767
   525
skamonkey@3767
   526
	if (!!strcmp(g_HookTypes[type].dtReq, ""))
skamonkey@3767
   527
	{
skamonkey@3767
   528
		sm_sendprop_info_t spi;
skamonkey@3767
   529
		IServerUnknown *pUnk = (IServerUnknown *)pEnt;
skamonkey@3767
   530
skamonkey@3767
   531
		IServerNetworkable *pNet = pUnk->GetNetworkable();
skamonkey@3767
   532
		if (pNet && !UTIL_FindDataTable(pNet->GetServerClass()->m_pTable, g_HookTypes[type].dtReq, &spi, 0))
skamonkey@3767
   533
			return HookRet_BadEntForHookType;
skamonkey@3767
   534
	}
skamonkey@3767
   535
skamonkey@3767
   536
	bool bHooked = false;
skamonkey@3767
   537
	HOOKLOOP
skamonkey@3767
   538
	{
skamonkey@3767
   539
		if (g_HookList[i].entity == entity && g_HookList[i].type == type)
skamonkey@3767
   540
		{
skamonkey@3767
   541
			bHooked = true;
skamonkey@3767
   542
			break;
skamonkey@3767
   543
		}
skamonkey@3767
   544
	}
skamonkey@3767
   545
	if (!bHooked)
skamonkey@3767
   546
	{
skamonkey@3767
   547
		switch(type)
skamonkey@3767
   548
		{
skamonkey@3767
   549
			case SDKHook_EndTouch:
kyle@3819
   550
				SH_ADD_MANUALHOOK(EndTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_EndTouch), false);
skamonkey@3767
   551
				break;
skamonkey@3767
   552
			case SDKHook_EndTouchPost:
kyle@3819
   553
				SH_ADD_MANUALHOOK(EndTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_EndTouchPost), true);
skamonkey@3767
   554
				break;
skamonkey@3767
   555
			case SDKHook_FireBulletsPost:
kyle@3819
   556
				SH_ADD_MANUALHOOK(FireBullets, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_FireBulletsPost), true);
skamonkey@3767
   557
				break;
skamonkey@3767
   558
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   559
			case SDKHook_GetMaxHealth:
kyle@3819
   560
				SH_ADD_MANUALHOOK(GetMaxHealth, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GetMaxHealth), false);
skamonkey@3767
   561
				break;
skamonkey@3767
   562
#endif
skamonkey@3767
   563
			case SDKHook_GroundEntChangedPost:
kyle@3819
   564
				SH_ADD_MANUALHOOK(GroundEntChanged, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GroundEntChangedPost), true);
skamonkey@3767
   565
				break;
skamonkey@3767
   566
			case SDKHook_OnTakeDamage:
kyle@3819
   567
				SH_ADD_MANUALHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamage), false);
skamonkey@3767
   568
				break;
skamonkey@3767
   569
			case SDKHook_OnTakeDamagePost:
kyle@3819
   570
				SH_ADD_MANUALHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true);
skamonkey@3767
   571
				break;
skamonkey@3767
   572
			case SDKHook_PreThink:
kyle@3819
   573
				SH_ADD_MANUALHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false);
skamonkey@3767
   574
				break;
skamonkey@3767
   575
			case SDKHook_PreThinkPost:
kyle@3819
   576
				SH_ADD_MANUALHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThinkPost), true);
skamonkey@3767
   577
				break;
skamonkey@3767
   578
			case SDKHook_PostThink:
kyle@3819
   579
				SH_ADD_MANUALHOOK(PostThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PostThink), false);
skamonkey@3767
   580
				break;
skamonkey@3767
   581
			case SDKHook_PostThinkPost:
kyle@3819
   582
				SH_ADD_MANUALHOOK(PostThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PostThinkPost), true);
skamonkey@3767
   583
				break;
skamonkey@3767
   584
			case SDKHook_Reload:
kyle@3819
   585
				SH_ADD_MANUALHOOK(Reload, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Reload), false);
skamonkey@3767
   586
				break;
skamonkey@3767
   587
			case SDKHook_ReloadPost:
kyle@3819
   588
				SH_ADD_MANUALHOOK(Reload, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ReloadPost), true);
skamonkey@3767
   589
				break;
skamonkey@3767
   590
			case SDKHook_SetTransmit:
kyle@3819
   591
				SH_ADD_MANUALHOOK(SetTransmit, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_SetTransmit), false);
skamonkey@3767
   592
				break;
skamonkey@3767
   593
			case SDKHook_Spawn:
kyle@3819
   594
				SH_ADD_MANUALHOOK(Spawn, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Spawn), false);
skamonkey@3767
   595
				break;
skamonkey@3767
   596
			case SDKHook_SpawnPost:
kyle@3819
   597
				SH_ADD_MANUALHOOK(Spawn, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_SpawnPost), true);
skamonkey@3767
   598
				break;
skamonkey@3767
   599
			case SDKHook_StartTouch:
kyle@3819
   600
				SH_ADD_MANUALHOOK(StartTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_StartTouch), false);
skamonkey@3767
   601
				break;
skamonkey@3767
   602
			case SDKHook_StartTouchPost:
kyle@3819
   603
				SH_ADD_MANUALHOOK(StartTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_StartTouchPost), true);
skamonkey@3767
   604
				break;
skamonkey@3767
   605
			case SDKHook_Think:
kyle@3819
   606
				SH_ADD_MANUALHOOK(Think, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Think), false);
skamonkey@3767
   607
				break;
skamonkey@3767
   608
			case SDKHook_ThinkPost:
kyle@3819
   609
				SH_ADD_MANUALHOOK(Think, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ThinkPost), true);
skamonkey@3767
   610
				break;
skamonkey@3767
   611
			case SDKHook_Touch:
kyle@3819
   612
				SH_ADD_MANUALHOOK(Touch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Touch), false);
skamonkey@3767
   613
				break;
skamonkey@3767
   614
			case SDKHook_TouchPost:
kyle@3819
   615
				SH_ADD_MANUALHOOK(Touch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TouchPost), true);
skamonkey@3767
   616
				break;
skamonkey@3767
   617
			case SDKHook_TraceAttack:
kyle@3819
   618
				SH_ADD_MANUALHOOK(TraceAttack, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TraceAttack), false);
skamonkey@3767
   619
				break;
skamonkey@3767
   620
			case SDKHook_TraceAttackPost:
kyle@3819
   621
				SH_ADD_MANUALHOOK(TraceAttack, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TraceAttackPost), true);
skamonkey@3767
   622
				break;
skamonkey@3767
   623
			case SDKHook_Use:
kyle@3819
   624
				SH_ADD_MANUALHOOK(Use, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Use), false);
skamonkey@3767
   625
				break;
skamonkey@3767
   626
			case SDKHook_UsePost:
kyle@3819
   627
				SH_ADD_MANUALHOOK(Use, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_UsePost), true);
skamonkey@3767
   628
				break;
skamonkey@3767
   629
			case SDKHook_VPhysicsUpdate:
kyle@3819
   630
				SH_ADD_MANUALHOOK(VPhysicsUpdate, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_VPhysicsUpdate), false);
skamonkey@3767
   631
				break;
skamonkey@3767
   632
			case SDKHook_VPhysicsUpdatePost:
kyle@3819
   633
				SH_ADD_MANUALHOOK(VPhysicsUpdate, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_VPhysicsUpdatePost), true);
skamonkey@3767
   634
				break;
skamonkey@3767
   635
			case SDKHook_WeaponCanSwitchTo:
kyle@3819
   636
				SH_ADD_MANUALHOOK(Weapon_CanSwitchTo, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanSwitchTo), false);
skamonkey@3767
   637
				break;
skamonkey@3767
   638
			case SDKHook_WeaponCanSwitchToPost:
kyle@3819
   639
				SH_ADD_MANUALHOOK(Weapon_CanSwitchTo, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanSwitchToPost), true);
skamonkey@3767
   640
				break;
skamonkey@3767
   641
			case SDKHook_WeaponCanUse:
kyle@3819
   642
				SH_ADD_MANUALHOOK(Weapon_CanUse, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanUse), false);
skamonkey@3767
   643
				break;
skamonkey@3767
   644
			case SDKHook_WeaponCanUsePost:
kyle@3819
   645
				SH_ADD_MANUALHOOK(Weapon_CanUse, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanUsePost), true);
skamonkey@3767
   646
				break;
skamonkey@3767
   647
			case SDKHook_WeaponDrop:
kyle@3819
   648
				SH_ADD_MANUALHOOK(Weapon_Drop, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponDrop), false);
skamonkey@3767
   649
				break;
skamonkey@3767
   650
			case SDKHook_WeaponDropPost:
kyle@3819
   651
				SH_ADD_MANUALHOOK(Weapon_Drop, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponDropPost), true);
skamonkey@3767
   652
				break;
skamonkey@3767
   653
			case SDKHook_WeaponEquip:
kyle@3819
   654
				SH_ADD_MANUALHOOK(Weapon_Equip, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponEquip), false);
skamonkey@3767
   655
				break;
skamonkey@3767
   656
			case SDKHook_WeaponEquipPost:
kyle@3819
   657
				SH_ADD_MANUALHOOK(Weapon_Equip, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponEquipPost), true);
skamonkey@3767
   658
				break;
skamonkey@3767
   659
			case SDKHook_WeaponSwitch:
kyle@3819
   660
				SH_ADD_MANUALHOOK(Weapon_Switch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponSwitch), false);
skamonkey@3767
   661
				break;
skamonkey@3767
   662
			case SDKHook_WeaponSwitchPost:
kyle@3819
   663
				SH_ADD_MANUALHOOK(Weapon_Switch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponSwitchPost), true);
skamonkey@3767
   664
				break;
skamonkey@3767
   665
			case SDKHook_ShouldCollide:
kyle@3819
   666
				SH_ADD_MANUALHOOK(ShouldCollide, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ShouldCollide), false);
skamonkey@3767
   667
				break;
skamonkey@3767
   668
		}
skamonkey@3767
   669
	}
skamonkey@3767
   670
skamonkey@3767
   671
	// Add hook to hook list
skamonkey@3767
   672
	HookList hook;
skamonkey@3767
   673
	hook.entity = entity;
skamonkey@3767
   674
	hook.type = type;
skamonkey@3767
   675
	hook.callback = callback;
skamonkey@3767
   676
	g_HookList.AddToTail(hook);
skamonkey@3767
   677
#ifdef SDKHOOKSDEBUG
skamonkey@3767
   678
	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
   679
#endif
skamonkey@3767
   680
	return HookRet_Successful;
skamonkey@3767
   681
}
skamonkey@3767
   682
skamonkey@3767
   683
void SDKHooks::Unhook(int index)
skamonkey@3767
   684
{
skamonkey@3767
   685
	CBaseEntity *pEnt = gamehelpers->ReferenceToEntity(g_HookList[index].entity);
skamonkey@3767
   686
	if(!pEnt)
skamonkey@3767
   687
		return;
skamonkey@3767
   688
skamonkey@3767
   689
	int iHooks = 0;
skamonkey@3767
   690
	HOOKLOOP
skamonkey@3767
   691
	{
skamonkey@3767
   692
		if (g_HookList[i].entity == g_HookList[index].entity && g_HookList[i].type == g_HookList[index].type)
skamonkey@3767
   693
		{
skamonkey@3767
   694
			iHooks++;
skamonkey@3767
   695
#ifdef SDKHOOKSDEBUG
skamonkey@3767
   696
			META_CONPRINTF("DEBUG: Found hook %d on entity %d\n", i, g_HookList[index].entity);
skamonkey@3767
   697
#endif
skamonkey@3767
   698
		}
skamonkey@3767
   699
	}
skamonkey@3767
   700
	if (iHooks == 1)
skamonkey@3767
   701
	{
skamonkey@3767
   702
#ifdef SDKHOOKSDEBUG
skamonkey@3767
   703
		META_CONPRINTF("DEBUG: Removing hook for hooktype %d\n", g_HookList[index].type);
skamonkey@3767
   704
#endif
skamonkey@3767
   705
		switch(g_HookList[index].type)
skamonkey@3767
   706
		{
skamonkey@3767
   707
			case SDKHook_EndTouch:
kyle@3819
   708
				SH_REMOVE_MANUALHOOK(EndTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_EndTouch), false);
skamonkey@3767
   709
				break;
skamonkey@3767
   710
			case SDKHook_EndTouchPost:
kyle@3819
   711
				SH_REMOVE_MANUALHOOK(EndTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_EndTouchPost), true);
skamonkey@3767
   712
				break;
skamonkey@3767
   713
			case SDKHook_FireBulletsPost:
kyle@3819
   714
				SH_REMOVE_MANUALHOOK(FireBullets, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_FireBulletsPost), true);
skamonkey@3767
   715
				break;
skamonkey@3767
   716
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   717
			case SDKHook_GetMaxHealth:
kyle@3819
   718
				SH_REMOVE_MANUALHOOK(GetMaxHealth, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GetMaxHealth), false);
skamonkey@3767
   719
				break;
skamonkey@3767
   720
#endif
skamonkey@3767
   721
			case SDKHook_GroundEntChangedPost:
kyle@3819
   722
				SH_REMOVE_MANUALHOOK(GroundEntChanged, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_GroundEntChangedPost), true);
skamonkey@3767
   723
				break;
skamonkey@3767
   724
			case SDKHook_OnTakeDamage:
kyle@3819
   725
				SH_REMOVE_MANUALHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamage), false);
skamonkey@3767
   726
				break;
skamonkey@3767
   727
			case SDKHook_OnTakeDamagePost:
kyle@3819
   728
				SH_REMOVE_MANUALHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true);
skamonkey@3767
   729
				break;
skamonkey@3767
   730
			case SDKHook_PreThink:
kyle@3819
   731
				SH_REMOVE_MANUALHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false);
skamonkey@3767
   732
				break;
skamonkey@3767
   733
			case SDKHook_PreThinkPost:
kyle@3819
   734
				SH_REMOVE_MANUALHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThinkPost), true);
skamonkey@3767
   735
				break;
skamonkey@3767
   736
			case SDKHook_PostThink:
kyle@3819
   737
				SH_REMOVE_MANUALHOOK(PostThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PostThink), false);
skamonkey@3767
   738
				break;
skamonkey@3767
   739
			case SDKHook_PostThinkPost:
kyle@3819
   740
				SH_REMOVE_MANUALHOOK(PostThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PostThinkPost), true);
skamonkey@3767
   741
				break;
skamonkey@3767
   742
			case SDKHook_Reload:
kyle@3819
   743
				SH_REMOVE_MANUALHOOK(Reload, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Reload), false);
skamonkey@3767
   744
				break;
skamonkey@3767
   745
			case SDKHook_ReloadPost:
kyle@3819
   746
				SH_REMOVE_MANUALHOOK(Reload, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ReloadPost), true);
skamonkey@3767
   747
				break;
skamonkey@3767
   748
			case SDKHook_SetTransmit:
kyle@3819
   749
				SH_REMOVE_MANUALHOOK(SetTransmit, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_SetTransmit), false);
skamonkey@3767
   750
				break;
skamonkey@3767
   751
			case SDKHook_Spawn:
kyle@3819
   752
				SH_REMOVE_MANUALHOOK(Spawn, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Spawn), false);
skamonkey@3767
   753
				break;
skamonkey@3767
   754
			case SDKHook_SpawnPost:
kyle@3819
   755
				SH_REMOVE_MANUALHOOK(Spawn, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_SpawnPost), true);
skamonkey@3767
   756
				break;
skamonkey@3767
   757
			case SDKHook_StartTouch:
kyle@3819
   758
				SH_REMOVE_MANUALHOOK(StartTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_StartTouch), false);
skamonkey@3767
   759
				break;
skamonkey@3767
   760
			case SDKHook_StartTouchPost:
kyle@3819
   761
				SH_REMOVE_MANUALHOOK(StartTouch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_StartTouchPost), true);
skamonkey@3767
   762
				break;
skamonkey@3767
   763
			case SDKHook_Think:
kyle@3819
   764
				SH_REMOVE_MANUALHOOK(Think, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Think), false);
skamonkey@3767
   765
				break;
skamonkey@3767
   766
			case SDKHook_ThinkPost:
kyle@3819
   767
				SH_REMOVE_MANUALHOOK(Think, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ThinkPost), true);
skamonkey@3767
   768
				break;
skamonkey@3767
   769
			case SDKHook_Touch:
kyle@3819
   770
				SH_REMOVE_MANUALHOOK(Touch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Touch), false);
skamonkey@3767
   771
				break;
skamonkey@3767
   772
			case SDKHook_TouchPost:
kyle@3819
   773
				SH_REMOVE_MANUALHOOK(Touch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TouchPost), true);
skamonkey@3767
   774
				break;
skamonkey@3767
   775
			case SDKHook_TraceAttack:
kyle@3819
   776
				SH_REMOVE_MANUALHOOK(TraceAttack, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TraceAttack), false);
skamonkey@3767
   777
				break;
skamonkey@3767
   778
			case SDKHook_TraceAttackPost:
kyle@3819
   779
				SH_REMOVE_MANUALHOOK(TraceAttack, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_TraceAttackPost), true);
skamonkey@3767
   780
				break;
skamonkey@3767
   781
			case SDKHook_Use:
kyle@3819
   782
				SH_REMOVE_MANUALHOOK(Use, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Use), false);
skamonkey@3767
   783
				break;
skamonkey@3767
   784
			case SDKHook_UsePost:
kyle@3819
   785
				SH_REMOVE_MANUALHOOK(Use, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_UsePost), true);
skamonkey@3767
   786
				break;
skamonkey@3767
   787
			case SDKHook_VPhysicsUpdate:
kyle@3819
   788
				SH_REMOVE_MANUALHOOK(VPhysicsUpdate, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_VPhysicsUpdate), false);
skamonkey@3767
   789
				break;
skamonkey@3767
   790
			case SDKHook_VPhysicsUpdatePost:
kyle@3819
   791
				SH_REMOVE_MANUALHOOK(VPhysicsUpdate, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_VPhysicsUpdatePost), true);
skamonkey@3767
   792
				break;
skamonkey@3767
   793
			case SDKHook_WeaponCanSwitchTo:
kyle@3819
   794
				SH_REMOVE_MANUALHOOK(Weapon_CanSwitchTo, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanSwitchTo), false);
skamonkey@3767
   795
				break;
skamonkey@3767
   796
			case SDKHook_WeaponCanSwitchToPost:
kyle@3819
   797
				SH_REMOVE_MANUALHOOK(Weapon_CanSwitchTo, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanSwitchToPost), true);
skamonkey@3767
   798
				break;
skamonkey@3767
   799
			case SDKHook_WeaponCanUse:
kyle@3819
   800
				SH_REMOVE_MANUALHOOK(Weapon_CanUse, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanUse), false);
skamonkey@3767
   801
				break;
skamonkey@3767
   802
			case SDKHook_WeaponCanUsePost:
kyle@3819
   803
				SH_REMOVE_MANUALHOOK(Weapon_CanUse, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponCanUsePost), true);
skamonkey@3767
   804
				break;
skamonkey@3767
   805
			case SDKHook_WeaponDrop:
kyle@3819
   806
				SH_REMOVE_MANUALHOOK(Weapon_Drop, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponDrop), false);
skamonkey@3767
   807
				break;
skamonkey@3767
   808
			case SDKHook_WeaponDropPost:
kyle@3819
   809
				SH_REMOVE_MANUALHOOK(Weapon_Drop, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponDropPost), true);
skamonkey@3767
   810
				break;
skamonkey@3767
   811
			case SDKHook_WeaponEquip:
kyle@3819
   812
				SH_REMOVE_MANUALHOOK(Weapon_Equip, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponEquip), false);
skamonkey@3767
   813
				break;
skamonkey@3767
   814
			case SDKHook_WeaponEquipPost:
kyle@3819
   815
				SH_REMOVE_MANUALHOOK(Weapon_Equip, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponEquipPost), true);
skamonkey@3767
   816
				break;
skamonkey@3767
   817
			case SDKHook_WeaponSwitch:
kyle@3819
   818
				SH_REMOVE_MANUALHOOK(Weapon_Switch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponSwitch), false);
skamonkey@3767
   819
				break;
skamonkey@3767
   820
			case SDKHook_WeaponSwitchPost:
kyle@3819
   821
				SH_REMOVE_MANUALHOOK(Weapon_Switch, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_WeaponSwitchPost), true);
skamonkey@3767
   822
				break;
skamonkey@3767
   823
			case SDKHook_ShouldCollide:
kyle@3819
   824
				SH_REMOVE_MANUALHOOK(ShouldCollide, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ShouldCollide), false);
skamonkey@3767
   825
				break;
skamonkey@3767
   826
			default:
skamonkey@3767
   827
				return;
skamonkey@3767
   828
		}
skamonkey@3767
   829
	}
skamonkey@3767
   830
	g_HookList.Remove(index);
skamonkey@3767
   831
}
skamonkey@3767
   832
skamonkey@3767
   833
skamonkey@3767
   834
/**
skamonkey@3767
   835
 * IEntityFactoryDictionary, IServerGameDLL & IVEngineServer Hook Handlers
skamonkey@3767
   836
 */
skamonkey@3767
   837
void SDKHooks::OnEntityCreated(CBaseEntity *pEntity)
skamonkey@3767
   838
{
skamonkey@3767
   839
	// Call OnEntityCreated forward
skamonkey@3767
   840
	int entity = gamehelpers->ReferenceToIndex(gamehelpers->EntityToBCompatRef(pEntity));
skamonkey@3767
   841
	if (m_EntityExists.IsBitSet(entity) || (entity > 0 && entity <= playerhelpers->GetMaxClients()))
skamonkey@3767
   842
	{
skamonkey@3767
   843
		return;
skamonkey@3767
   844
	}
skamonkey@3767
   845
aangione@3971
   846
	const char *pName = gamehelpers->GetEntityClassname(pEntity);
skamonkey@3767
   847
aangione@3971
   848
	// Send OnEntityCreated to SM listeners
aangione@3971
   849
	SourceHook::List<ISMEntityListener *>::iterator iter;
aangione@3971
   850
	ISMEntityListener *pListener = NULL;
aangione@3971
   851
	for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++)
aangione@3971
   852
	{
aangione@3971
   853
		pListener = (*iter);
aangione@3971
   854
		pListener->OnEntityCreated(pEntity, pName ? pName : "");
aangione@3971
   855
	}
aangione@3971
   856
aangione@3971
   857
	g_pOnEntityCreated->PushCell(gamehelpers->EntityToBCompatRef(pEntity));
skamonkey@3767
   858
	g_pOnEntityCreated->PushString(pName ? pName : "");
skamonkey@3767
   859
	g_pOnEntityCreated->Execute(NULL);
skamonkey@3767
   860
skamonkey@3767
   861
	m_EntityExists.Set(entity);
skamonkey@3767
   862
}
skamonkey@3767
   863
skamonkey@3767
   864
#ifdef GAMEDESC_CAN_CHANGE
skamonkey@3767
   865
const char *SDKHooks::Hook_GetGameDescription()
skamonkey@3767
   866
{
skamonkey@3767
   867
	static char szGameDesc[64];
skamonkey@3767
   868
	cell_t result = Pl_Continue;
skamonkey@3767
   869
skamonkey@3767
   870
	g_pSM->Format(szGameDesc, sizeof(szGameDesc), "%s",
skamonkey@3767
   871
		SH_CALL(gamedll, &IServerGameDLL::GetGameDescription)());
skamonkey@3767
   872
skamonkey@3767
   873
	// Call OnGetGameDescription forward
skamonkey@3767
   874
	g_pOnGetGameNameDescription->PushStringEx(szGameDesc, sizeof(szGameDesc), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
skamonkey@3767
   875
	g_pOnGetGameNameDescription->Execute(&result);
skamonkey@3767
   876
skamonkey@3767
   877
	if(result == Pl_Changed)
skamonkey@3767
   878
		RETURN_META_VALUE(MRES_SUPERCEDE, szGameDesc);
skamonkey@3767
   879
skamonkey@3767
   880
	RETURN_META_VALUE(MRES_IGNORED, NULL);
skamonkey@3767
   881
}
skamonkey@3767
   882
#endif
skamonkey@3767
   883
skamonkey@3767
   884
const char *SDKHooks::Hook_GetMapEntitiesString()
skamonkey@3767
   885
{
skamonkey@3767
   886
	if(g_szMapEntities[0])
skamonkey@3767
   887
		RETURN_META_VALUE(MRES_SUPERCEDE, g_szMapEntities);
skamonkey@3767
   888
skamonkey@3767
   889
	RETURN_META_VALUE(MRES_IGNORED, NULL);
skamonkey@3767
   890
}
skamonkey@3767
   891
skamonkey@3767
   892
bool SDKHooks::Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
skamonkey@3767
   893
{
skamonkey@3767
   894
	strcpy(g_szMapEntities, pMapEntities);
skamonkey@3767
   895
	cell_t result = Pl_Continue;
skamonkey@3767
   896
skamonkey@3767
   897
	// Call OnLevelInit forward
skamonkey@3767
   898
	g_pOnLevelInit->PushString(pMapName);
skamonkey@3767
   899
	g_pOnLevelInit->PushStringEx(g_szMapEntities, sizeof(g_szMapEntities), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
skamonkey@3767
   900
	g_pOnLevelInit->Execute(&result);
skamonkey@3767
   901
skamonkey@3767
   902
	if(result >= Pl_Handled)
skamonkey@3767
   903
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
   904
skamonkey@3767
   905
	if(result == Pl_Changed)
skamonkey@3767
   906
		RETURN_META_VALUE_NEWPARAMS(MRES_HANDLED, true, &IServerGameDLL::LevelInit, (pMapName, g_szMapEntities, pOldLevel, pLandmarkName, loadGame, background));
skamonkey@3767
   907
skamonkey@3767
   908
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
   909
}
skamonkey@3767
   910
skamonkey@3767
   911
skamonkey@3767
   912
/**
skamonkey@3767
   913
 * CBaseEntity Hook Handlers
skamonkey@3767
   914
 */
skamonkey@3767
   915
void SDKHooks::Hook_EndTouch(CBaseEntity *pOther)
skamonkey@3767
   916
{
skamonkey@3767
   917
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_EndTouch, pOther);
skamonkey@3767
   918
	if(result >= Pl_Handled)
skamonkey@3767
   919
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
   920
skamonkey@3767
   921
	RETURN_META(MRES_IGNORED);
skamonkey@3767
   922
}
skamonkey@3767
   923
skamonkey@3767
   924
void SDKHooks::Hook_EndTouchPost(CBaseEntity *pOther)
skamonkey@3767
   925
{
skamonkey@3767
   926
	Call(META_IFACEPTR(CBaseEntity), SDKHook_EndTouchPost, pOther);
skamonkey@3767
   927
	RETURN_META(MRES_IGNORED);
skamonkey@3767
   928
}
skamonkey@3767
   929
skamonkey@3767
   930
void SDKHooks::Hook_FireBulletsPost(const FireBulletsInfo_t &info)
skamonkey@3767
   931
{
skamonkey@3767
   932
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
   933
skamonkey@3767
   934
	IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(entity);
skamonkey@3767
   935
	if(!pPlayer)
skamonkey@3767
   936
		RETURN_META(MRES_IGNORED);
skamonkey@3767
   937
skamonkey@3767
   938
	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
skamonkey@3767
   939
	if(!pInfo)
skamonkey@3767
   940
		RETURN_META(MRES_IGNORED);
skamonkey@3767
   941
skamonkey@3767
   942
	const char *weapon = pInfo->GetWeaponName();
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_FireBulletsPost)
skamonkey@3767
   948
			continue;
skamonkey@3767
   949
skamonkey@3767
   950
		callback = g_HookList[i].callback;
skamonkey@3767
   951
		callback->PushCell(entity);
skamonkey@3767
   952
		callback->PushCell(info.m_iShots);
skamonkey@3767
   953
		callback->PushString(weapon?weapon:"");
skamonkey@3767
   954
		callback->Execute(NULL);
skamonkey@3767
   955
	}
skamonkey@3767
   956
skamonkey@3767
   957
	RETURN_META(MRES_IGNORED);
skamonkey@3767
   958
}
skamonkey@3767
   959
skamonkey@3767
   960
#ifdef GETMAXHEALTH_IS_VIRTUAL
skamonkey@3767
   961
int SDKHooks::Hook_GetMaxHealth()
skamonkey@3767
   962
{
skamonkey@3767
   963
	CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
skamonkey@3767
   964
	int original_max = SH_MCALL(pEntity, GetMaxHealth)();
skamonkey@3767
   965
	int entity = gamehelpers->EntityToBCompatRef(pEntity);
skamonkey@3767
   966
skamonkey@3767
   967
	int new_max = original_max;
skamonkey@3767
   968
skamonkey@3767
   969
	cell_t res;
skamonkey@3767
   970
	IPluginFunction *callback = NULL;
skamonkey@3767
   971
skamonkey@3767
   972
	HOOKLOOP
skamonkey@3767
   973
	{
skamonkey@3767
   974
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_GetMaxHealth)
skamonkey@3767
   975
			continue;
skamonkey@3767
   976
skamonkey@3767
   977
		callback = g_HookList[i].callback;
skamonkey@3807
   978
		callback->PushCell(entity);
skamonkey@3767
   979
		callback->PushCellByRef(&new_max);
skamonkey@3767
   980
		callback->Execute(&res);
skamonkey@3767
   981
	}
skamonkey@3767
   982
skamonkey@3767
   983
	if (res >= Pl_Changed)
skamonkey@3767
   984
		RETURN_META_VALUE(MRES_SUPERCEDE, new_max);
skamonkey@3767
   985
skamonkey@3767
   986
	RETURN_META_VALUE(MRES_IGNORED, original_max);
skamonkey@3767
   987
}
skamonkey@3767
   988
#endif
skamonkey@3767
   989
skamonkey@3767
   990
void SDKHooks::Hook_GroundEntChangedPost()
skamonkey@3767
   991
{
skamonkey@3767
   992
	Call(META_IFACEPTR(CBaseEntity), SDKHook_GroundEntChangedPost);
skamonkey@3767
   993
}
skamonkey@3767
   994
skamonkey@3767
   995
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
skamonkey@3767
   996
{
skamonkey@3767
   997
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
   998
	int attacker = info.GetAttacker();
skamonkey@3767
   999
	int inflictor = info.GetInflictor();
skamonkey@3767
  1000
	float damage = info.GetDamage();
skamonkey@3767
  1001
	int damagetype = info.GetDamageType();
skamonkey@3767
  1002
	int weapon = info.GetWeapon();
skamonkey@3767
  1003
skamonkey@3767
  1004
	Vector force = info.GetDamageForce();
skamonkey@3767
  1005
	cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
skamonkey@3767
  1006
skamonkey@3767
  1007
	Vector pos = info.GetDamagePosition();
skamonkey@3767
  1008
	cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
skamonkey@3767
  1009
skamonkey@3767
  1010
	IPluginFunction *callback = NULL;
skamonkey@3767
  1011
	cell_t res, ret = Pl_Continue;
skamonkey@3767
  1012
skamonkey@3767
  1013
	HOOKLOOP
skamonkey@3767
  1014
	{
skamonkey@3767
  1015
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_OnTakeDamage)
skamonkey@3767
  1016
			continue;
skamonkey@3767
  1017
skamonkey@3767
  1018
		callback = g_HookList[i].callback;
skamonkey@3767
  1019
		callback->PushCell(entity);
skamonkey@3767
  1020
		callback->PushCellByRef(&attacker);
skamonkey@3767
  1021
		callback->PushCellByRef(&inflictor);
skamonkey@3767
  1022
		callback->PushFloatByRef(&damage);
skamonkey@3767
  1023
		callback->PushCellByRef(&damagetype);
skamonkey@3767
  1024
		callback->PushCellByRef(&weapon);
skamonkey@3767
  1025
		callback->PushArray(damageForce, 3, SM_PARAM_COPYBACK);
skamonkey@3767
  1026
		callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);	
skamonkey@3767
  1027
		callback->PushCell(info.GetDamageCustom());
skamonkey@3767
  1028
		callback->Execute(&res);
skamonkey@3767
  1029
skamonkey@3767
  1030
		if(res > ret)
skamonkey@3767
  1031
			ret = res;
skamonkey@3767
  1032
	}
skamonkey@3767
  1033
skamonkey@3767
  1034
	if(ret >= Pl_Handled)
skamonkey@3767
  1035
		RETURN_META_VALUE(MRES_SUPERCEDE, 1);
skamonkey@3767
  1036
skamonkey@3767
  1037
	if(ret == Pl_Changed)
skamonkey@3767
  1038
	{
skamonkey@3767
  1039
		CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker);
skamonkey@3767
  1040
		if(!pEntAttacker)
skamonkey@3767
  1041
		{
skamonkey@3767
  1042
			callback->GetParentContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker);
skamonkey@3767
  1043
			RETURN_META_VALUE(MRES_IGNORED, 0);
skamonkey@3767
  1044
		}
skamonkey@3767
  1045
		CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor);
skamonkey@3767
  1046
		if(!pEntInflictor)
skamonkey@3767
  1047
		{
skamonkey@3767
  1048
			callback->GetParentContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor);
skamonkey@3767
  1049
			RETURN_META_VALUE(MRES_IGNORED, 0);
skamonkey@3767
  1050
		}
skamonkey@3767
  1051
skamonkey@3767
  1052
		info.SetAttacker(pEntAttacker);
skamonkey@3767
  1053
		info.SetInflictor(pEntInflictor);
skamonkey@3767
  1054
		info.SetDamage(damage);
skamonkey@3767
  1055
		info.SetDamageType(damagetype);
skamonkey@3767
  1056
		info.SetWeapon(gamehelpers->ReferenceToEntity(weapon));
skamonkey@3767
  1057
		info.SetDamageForce(
skamonkey@3767
  1058
			sp_ctof(damageForce[0]),
skamonkey@3767
  1059
			sp_ctof(damageForce[1]),
skamonkey@3767
  1060
			sp_ctof(damageForce[2]));
skamonkey@3767
  1061
		info.SetDamagePosition(
skamonkey@3767
  1062
			sp_ctof(damagePosition[0]),
skamonkey@3767
  1063
			sp_ctof(damagePosition[1]),
skamonkey@3767
  1064
			sp_ctof(damagePosition[2]));
skamonkey@3767
  1065
skamonkey@3767
  1066
		RETURN_META_VALUE(MRES_HANDLED, 1); 
skamonkey@3767
  1067
	}
skamonkey@3767
  1068
skamonkey@3767
  1069
	RETURN_META_VALUE(MRES_IGNORED, 0);
skamonkey@3767
  1070
}
skamonkey@3767
  1071
skamonkey@3767
  1072
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
skamonkey@3767
  1073
{
skamonkey@3767
  1074
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1075
	IPluginFunction *callback = NULL;
skamonkey@3767
  1076
skamonkey@3767
  1077
	HOOKLOOP
skamonkey@3767
  1078
	{
skamonkey@3767
  1079
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_OnTakeDamagePost)
skamonkey@3767
  1080
			continue;
skamonkey@3767
  1081
skamonkey@3767
  1082
		callback = g_HookList[i].callback;
skamonkey@3767
  1083
		callback->PushCell(entity);
skamonkey@3767
  1084
		callback->PushCell(info.GetAttacker());
skamonkey@3767
  1085
		callback->PushCell(info.GetInflictor());
skamonkey@3767
  1086
		callback->PushFloat(info.GetDamage());
skamonkey@3767
  1087
		callback->PushCell(info.GetDamageType());
skamonkey@3767
  1088
		callback->PushCell(info.GetWeapon());
skamonkey@3767
  1089
skamonkey@3767
  1090
		Vector force = info.GetDamageForce();
skamonkey@3767
  1091
		cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
skamonkey@3767
  1092
		callback->PushArray(damageForce, 3);
skamonkey@3767
  1093
skamonkey@3767
  1094
		Vector pos = info.GetDamagePosition();
skamonkey@3767
  1095
		cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
skamonkey@3767
  1096
		callback->PushArray(damagePosition, 3);
skamonkey@3767
  1097
skamonkey@3767
  1098
		callback->PushCell(info.GetDamageCustom());
skamonkey@3767
  1099
skamonkey@3767
  1100
		callback->Execute(NULL);
skamonkey@3767
  1101
	}
skamonkey@3767
  1102
skamonkey@3767
  1103
	RETURN_META_VALUE(MRES_IGNORED, 0);
skamonkey@3767
  1104
}
skamonkey@3767
  1105
skamonkey@3767
  1106
void SDKHooks::Hook_PreThink()
skamonkey@3767
  1107
{
skamonkey@3767
  1108
	Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThink);
skamonkey@3767
  1109
}
skamonkey@3767
  1110
skamonkey@3767
  1111
void SDKHooks::Hook_PreThinkPost()
skamonkey@3767
  1112
{
skamonkey@3767
  1113
	Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThinkPost);
skamonkey@3767
  1114
}
skamonkey@3767
  1115
skamonkey@3767
  1116
void SDKHooks::Hook_PostThink()
skamonkey@3767
  1117
{
skamonkey@3767
  1118
	Call(META_IFACEPTR(CBaseEntity), SDKHook_PostThink);
skamonkey@3767
  1119
}
skamonkey@3767
  1120
skamonkey@3767
  1121
void SDKHooks::Hook_PostThinkPost()
skamonkey@3767
  1122
{
skamonkey@3767
  1123
	Call(META_IFACEPTR(CBaseEntity), SDKHook_PostThinkPost);
skamonkey@3767
  1124
}
skamonkey@3767
  1125
skamonkey@3767
  1126
bool SDKHooks::Hook_Reload()
skamonkey@3767
  1127
{
skamonkey@3767
  1128
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1129
	cell_t res;
skamonkey@3767
  1130
	IPluginFunction *callback = NULL;
skamonkey@3767
  1131
skamonkey@3767
  1132
	HOOKLOOP
skamonkey@3767
  1133
	{
skamonkey@3767
  1134
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_Reload)
skamonkey@3767
  1135
			continue;
skamonkey@3767
  1136
skamonkey@3767
  1137
		callback = g_HookList[i].callback;
skamonkey@3767
  1138
		callback->PushCell(entity);
skamonkey@3767
  1139
		callback->Execute(&res);
skamonkey@3767
  1140
	}
skamonkey@3767
  1141
skamonkey@3767
  1142
	if (res >= Pl_Handled)
skamonkey@3767
  1143
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
  1144
skamonkey@3767
  1145
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1146
}
skamonkey@3767
  1147
skamonkey@3767
  1148
bool SDKHooks::Hook_ReloadPost()
skamonkey@3767
  1149
{
skamonkey@3767
  1150
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1151
	IPluginFunction *callback = NULL;
skamonkey@3767
  1152
skamonkey@3767
  1153
	HOOKLOOP
skamonkey@3767
  1154
	{
skamonkey@3767
  1155
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_ReloadPost)
skamonkey@3767
  1156
			continue;
skamonkey@3767
  1157
skamonkey@3767
  1158
		callback = g_HookList[i].callback;
skamonkey@3767
  1159
		callback->PushCell(entity);
skamonkey@3767
  1160
		callback->PushCell(META_RESULT_OVERRIDE_RET(bool) ? 1 : 0);
skamonkey@3767
  1161
		callback->Execute(NULL);
skamonkey@3767
  1162
	}
skamonkey@3767
  1163
skamonkey@3767
  1164
	return true;
skamonkey@3767
  1165
}
skamonkey@3767
  1166
skamonkey@3767
  1167
void SDKHooks::Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways)
skamonkey@3767
  1168
{
skamonkey@3767
  1169
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_SetTransmit, gamehelpers->IndexOfEdict(pInfo->m_pClientEnt));
skamonkey@3767
  1170
skamonkey@3767
  1171
	if(result >= Pl_Handled)
skamonkey@3767
  1172
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1173
skamonkey@3767
  1174
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1175
}
skamonkey@3767
  1176
skamonkey@3767
  1177
bool SDKHooks::Hook_ShouldCollide(int collisionGroup, int contentsMask)
skamonkey@3767
  1178
{
skamonkey@3767
  1179
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1180
	IPluginFunction *callback = NULL;
skamonkey@3767
  1181
	bool origRet = ((META_RESULT_STATUS >= MRES_OVERRIDE)?(META_RESULT_OVERRIDE_RET(bool)):(META_RESULT_ORIG_RET(bool)));
skamonkey@3767
  1182
	cell_t res;
skamonkey@3767
  1183
skamonkey@3767
  1184
	HOOKLOOP
skamonkey@3767
  1185
	{
skamonkey@3767
  1186
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_ShouldCollide)
skamonkey@3767
  1187
			continue;
skamonkey@3767
  1188
skamonkey@3767
  1189
		callback = g_HookList[i].callback;
skamonkey@3767
  1190
		callback->PushCell(entity);
skamonkey@3767
  1191
		callback->PushCell(collisionGroup);
skamonkey@3767
  1192
		callback->PushCell(contentsMask);
skamonkey@3767
  1193
		callback->PushCell(origRet ? 1 : 0);
skamonkey@3767
  1194
		callback->Execute(&res);
skamonkey@3767
  1195
	}
skamonkey@3767
  1196
skamonkey@3767
  1197
	bool ret = false;
skamonkey@3767
  1198
	if (res != 0)
skamonkey@3767
  1199
	{
skamonkey@3767
  1200
		ret = true;
skamonkey@3767
  1201
	}
skamonkey@3767
  1202
skamonkey@3767
  1203
	RETURN_META_VALUE(MRES_SUPERCEDE, ret);
skamonkey@3767
  1204
}
skamonkey@3767
  1205
skamonkey@3767
  1206
void SDKHooks::Hook_Spawn()
skamonkey@3767
  1207
{
skamonkey@3767
  1208
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1209
	IPluginFunction *callback = NULL;
skamonkey@3767
  1210
	cell_t res;
skamonkey@3767
  1211
skamonkey@3767
  1212
	HOOKLOOP
skamonkey@3767
  1213
	{
skamonkey@3767
  1214
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_Spawn)
skamonkey@3767
  1215
			continue;
skamonkey@3767
  1216
skamonkey@3767
  1217
		callback = g_HookList[i].callback;
skamonkey@3767
  1218
		callback->PushCell(entity);
skamonkey@3767
  1219
		callback->Execute(&res);
skamonkey@3767
  1220
	}
skamonkey@3767
  1221
skamonkey@3767
  1222
	if (res >= Pl_Handled)
skamonkey@3767
  1223
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1224
skamonkey@3767
  1225
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1226
}
skamonkey@3767
  1227
skamonkey@3767
  1228
void SDKHooks::Hook_SpawnPost()
skamonkey@3767
  1229
{
skamonkey@3767
  1230
	Call(META_IFACEPTR(CBaseEntity), SDKHook_SpawnPost);
skamonkey@3767
  1231
}
skamonkey@3767
  1232
skamonkey@3767
  1233
void SDKHooks::Hook_StartTouch(CBaseEntity *pOther)
skamonkey@3767
  1234
{
skamonkey@3767
  1235
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_StartTouch, pOther);
skamonkey@3767
  1236
	if(result >= Pl_Handled)
skamonkey@3767
  1237
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1238
skamonkey@3767
  1239
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1240
}
skamonkey@3767
  1241
skamonkey@3767
  1242
void SDKHooks::Hook_StartTouchPost(CBaseEntity *pOther)
skamonkey@3767
  1243
{
skamonkey@3767
  1244
	Call(META_IFACEPTR(CBaseEntity), SDKHook_StartTouchPost, pOther);
skamonkey@3767
  1245
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1246
}
skamonkey@3767
  1247
skamonkey@3767
  1248
void SDKHooks::Hook_Think()
skamonkey@3767
  1249
{
skamonkey@3767
  1250
	Call(META_IFACEPTR(CBaseEntity), SDKHook_Think);
skamonkey@3767
  1251
}
skamonkey@3767
  1252
skamonkey@3767
  1253
void SDKHooks::Hook_ThinkPost()
skamonkey@3767
  1254
{
skamonkey@3767
  1255
	Call(META_IFACEPTR(CBaseEntity), SDKHook_ThinkPost);
skamonkey@3767
  1256
}
skamonkey@3767
  1257
skamonkey@3767
  1258
void SDKHooks::Hook_Touch(CBaseEntity *pOther)
skamonkey@3767
  1259
{
skamonkey@3767
  1260
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_Touch, pOther);
skamonkey@3767
  1261
skamonkey@3767
  1262
	if(result >= Pl_Handled)
skamonkey@3767
  1263
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1264
skamonkey@3767
  1265
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1266
}
skamonkey@3767
  1267
skamonkey@3767
  1268
void SDKHooks::Hook_TouchPost(CBaseEntity *pOther)
skamonkey@3767
  1269
{
skamonkey@3767
  1270
	Call(META_IFACEPTR(CBaseEntity), SDKHook_TouchPost, pOther);
skamonkey@3767
  1271
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1272
}
skamonkey@3767
  1273
skamonkey@3961
  1274
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
skamonkey@3767
  1275
void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, void *pUnknownJK)
skamonkey@3767
  1276
#else
skamonkey@3767
  1277
void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr)
skamonkey@3767
  1278
#endif
skamonkey@3767
  1279
{
skamonkey@3767
  1280
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1281
	int attacker = info.GetAttacker();
skamonkey@3767
  1282
	int inflictor = info.GetInflictor();
skamonkey@3767
  1283
	float damage = info.GetDamage();
skamonkey@3767
  1284
	int damagetype = info.GetDamageType();
skamonkey@3767
  1285
	int ammotype = info.GetAmmoType();
skamonkey@3767
  1286
	IPluginFunction *callback = NULL;
skamonkey@3767
  1287
	cell_t res, ret = Pl_Continue;
skamonkey@3767
  1288
skamonkey@3767
  1289
	HOOKLOOP
skamonkey@3767
  1290
	{
skamonkey@3767
  1291
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_TraceAttack)
skamonkey@3767
  1292
			continue;
skamonkey@3767
  1293
skamonkey@3767
  1294
		callback = g_HookList[i].callback;
skamonkey@3767
  1295
		callback->PushCell(entity);
skamonkey@3767
  1296
		callback->PushCellByRef(&attacker);
skamonkey@3767
  1297
		callback->PushCellByRef(&inflictor);
skamonkey@3767
  1298
		callback->PushFloatByRef(&damage);
skamonkey@3767
  1299
		callback->PushCellByRef(&damagetype);
skamonkey@3767
  1300
		callback->PushCellByRef(&ammotype);
skamonkey@3767
  1301
		callback->PushCell(ptr->hitbox);
skamonkey@3767
  1302
		callback->PushCell(ptr->hitgroup);
skamonkey@3767
  1303
		callback->Execute(&res);
skamonkey@3767
  1304
skamonkey@3767
  1305
		if(res > ret)
skamonkey@3767
  1306
			ret = res;
skamonkey@3767
  1307
	}
skamonkey@3767
  1308
skamonkey@3767
  1309
	if(ret >= Pl_Handled)
skamonkey@3767
  1310
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1311
skamonkey@3767
  1312
	if(ret == Pl_Changed)
skamonkey@3767
  1313
	{
skamonkey@3767
  1314
		CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker);
skamonkey@3767
  1315
		if(!pEntAttacker)
skamonkey@3767
  1316
		{
skamonkey@3767
  1317
			callback->GetParentContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker);
skamonkey@3767
  1318
			RETURN_META(MRES_IGNORED);
skamonkey@3767
  1319
		}
skamonkey@3767
  1320
		CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor);
skamonkey@3767
  1321
		if(!pEntInflictor)
skamonkey@3767
  1322
		{
skamonkey@3767
  1323
			callback->GetParentContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor);
skamonkey@3767
  1324
			RETURN_META(MRES_IGNORED);
skamonkey@3767
  1325
		}
skamonkey@3767
  1326
		
skamonkey@3767
  1327
		info.SetAttacker(gamehelpers->ReferenceToEntity(attacker));
skamonkey@3767
  1328
		info.SetInflictor(gamehelpers->ReferenceToEntity(inflictor));
skamonkey@3767
  1329
		info.SetDamage(damage);
skamonkey@3767
  1330
		info.SetDamageType(damagetype);
skamonkey@3767
  1331
		info.SetAmmoType(ammotype);
skamonkey@3767
  1332
skamonkey@3767
  1333
		RETURN_META(MRES_HANDLED); 
skamonkey@3767
  1334
	}
skamonkey@3767
  1335
skamonkey@3767
  1336
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1337
}
skamonkey@3767
  1338
skamonkey@3961
  1339
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
skamonkey@3767
  1340
void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, void *pUnknownJK)
skamonkey@3767
  1341
#else
skamonkey@3767
  1342
void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr)
skamonkey@3767
  1343
#endif
skamonkey@3767
  1344
{
skamonkey@3767
  1345
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1346
	IPluginFunction *callback = NULL;
skamonkey@3767
  1347
skamonkey@3767
  1348
	HOOKLOOP
skamonkey@3767
  1349
	{
skamonkey@3767
  1350
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_TraceAttackPost)
skamonkey@3767
  1351
			continue;
skamonkey@3767
  1352
skamonkey@3767
  1353
		callback = g_HookList[i].callback;
skamonkey@3767
  1354
		callback->PushCell(entity);
skamonkey@3767
  1355
		callback->PushCell(info.GetAttacker());
skamonkey@3767
  1356
		callback->PushCell(info.GetInflictor());
skamonkey@3767
  1357
		callback->PushFloat(info.GetDamage());
skamonkey@3767
  1358
		callback->PushCell(info.GetDamageType());
skamonkey@3767
  1359
		callback->PushCell(info.GetAmmoType());
skamonkey@3767
  1360
		callback->PushCell(ptr->hitbox);
skamonkey@3767
  1361
		callback->PushCell(ptr->hitgroup);
skamonkey@3767
  1362
		callback->Execute(NULL);
skamonkey@3767
  1363
	}
skamonkey@3767
  1364
skamonkey@3767
  1365
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1366
}
skamonkey@3767
  1367
skamonkey@3767
  1368
void SDKHooks::Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
skamonkey@3767
  1369
{
skamonkey@3767
  1370
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1371
	int activator = gamehelpers->EntityToBCompatRef(pActivator);
skamonkey@3767
  1372
	int caller = gamehelpers->EntityToBCompatRef(pCaller);
skamonkey@3767
  1373
skamonkey@3767
  1374
	cell_t ret;
skamonkey@3767
  1375
	IPluginFunction *callback = NULL;
skamonkey@3767
  1376
skamonkey@3767
  1377
	HOOKLOOP
skamonkey@3767
  1378
	{
skamonkey@3767
  1379
		if(g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_Use)
skamonkey@3767
  1380
			continue;
skamonkey@3767
  1381
skamonkey@3767
  1382
		callback = g_HookList[i].callback;
skamonkey@3767
  1383
		callback->PushCell(entity);
skamonkey@3767
  1384
		callback->PushCell(activator);
skamonkey@3767
  1385
		callback->PushCell(caller);
skamonkey@3767
  1386
		callback->PushCell(useType);
skamonkey@3767
  1387
		callback->PushFloat(value);
skamonkey@3767
  1388
		callback->Execute(&ret);
skamonkey@3767
  1389
	}
skamonkey@3767
  1390
skamonkey@3767
  1391
	if (ret >= Pl_Handled)
skamonkey@3767
  1392
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1393
skamonkey@3767
  1394
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1395
}
skamonkey@3767
  1396
skamonkey@3767
  1397
void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
skamonkey@3767
  1398
{
skamonkey@3767
  1399
	int entity = gamehelpers->EntityToBCompatRef(META_IFACEPTR(CBaseEntity));
skamonkey@3767
  1400
	int activator = gamehelpers->EntityToBCompatRef(pActivator);
skamonkey@3767
  1401
	int caller = gamehelpers->EntityToBCompatRef(pCaller);
skamonkey@3767
  1402
skamonkey@3767
  1403
	IPluginFunction *callback = NULL;
skamonkey@3767
  1404
skamonkey@3767
  1405
	HOOKLOOP
skamonkey@3767
  1406
	{
skamonkey@3767
  1407
		if (g_HookList[i].entity != entity || g_HookList[i].type != SDKHook_UsePost)
skamonkey@3767
  1408
			continue;
skamonkey@3767
  1409
skamonkey@3767
  1410
		callback = g_HookList[i].callback;
skamonkey@3767
  1411
		callback->PushCell(entity);
skamonkey@3767
  1412
		callback->PushCell(activator);
skamonkey@3767
  1413
		callback->PushCell(caller);
skamonkey@3767
  1414
		callback->PushCell(useType);
skamonkey@3767
  1415
		callback->PushFloat(value);
skamonkey@3767
  1416
		callback->Execute(NULL);
skamonkey@3767
  1417
	}
skamonkey@3767
  1418
skamonkey@3767
  1419
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1420
}
skamonkey@3767
  1421
skamonkey@3767
  1422
void SDKHooks::OnEntityDeleted(CBaseEntity *pEntity)
skamonkey@3767
  1423
{
aangione@3971
  1424
	// Send OnEntityDestroyed to SM listeners
aangione@3971
  1425
	SourceHook::List<ISMEntityListener *>::iterator iter;
aangione@3971
  1426
	ISMEntityListener *pListener = NULL;
aangione@3971
  1427
	for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++)
aangione@3971
  1428
	{
aangione@3971
  1429
		pListener = (*iter);
aangione@3971
  1430
		pListener->OnEntityDestroyed(pEntity);
aangione@3971
  1431
	}
aangione@3971
  1432
skamonkey@3767
  1433
	int entity = gamehelpers->EntityToBCompatRef(pEntity);
skamonkey@3767
  1434
skamonkey@3767
  1435
	// Call OnEntityDestroyed forward
skamonkey@3767
  1436
	g_pOnEntityDestroyed->PushCell(entity);
skamonkey@3767
  1437
	g_pOnEntityDestroyed->Execute(NULL);
skamonkey@3767
  1438
	
skamonkey@3767
  1439
	SDKHooks::RemoveEntityHooks(pEntity);
skamonkey@3767
  1440
skamonkey@3767
  1441
	m_EntityExists.Set(gamehelpers->ReferenceToIndex(entity), false);
skamonkey@3767
  1442
}
skamonkey@3767
  1443
skamonkey@3767
  1444
void SDKHooks::Hook_VPhysicsUpdate(IPhysicsObject *pPhysics)
skamonkey@3767
  1445
{
skamonkey@3767
  1446
	Call(META_IFACEPTR(CBaseEntity), SDKHook_VPhysicsUpdate);
skamonkey@3767
  1447
}
skamonkey@3767
  1448
skamonkey@3767
  1449
void SDKHooks::Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics)
skamonkey@3767
  1450
{
skamonkey@3767
  1451
	Call(META_IFACEPTR(CBaseEntity), SDKHook_VPhysicsUpdatePost);
skamonkey@3767
  1452
}
skamonkey@3767
  1453
skamonkey@3767
  1454
bool SDKHooks::Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1455
{
skamonkey@3767
  1456
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanSwitchTo, pWeapon);
skamonkey@3767
  1457
skamonkey@3767
  1458
	if(result >= Pl_Handled)
skamonkey@3767
  1459
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
  1460
skamonkey@3767
  1461
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1462
}
skamonkey@3767
  1463
skamonkey@3767
  1464
bool SDKHooks::Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1465
{
skamonkey@3767
  1466
	Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanSwitchToPost, pWeapon);
skamonkey@3767
  1467
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1468
}
skamonkey@3767
  1469
skamonkey@3767
  1470
bool SDKHooks::Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1471
{
skamonkey@3767
  1472
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanUse, pWeapon);
skamonkey@3767
  1473
skamonkey@3767
  1474
	if(result >= Pl_Handled)
skamonkey@3767
  1475
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
  1476
skamonkey@3767
  1477
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1478
}
skamonkey@3767
  1479
skamonkey@3767
  1480
bool SDKHooks::Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1481
{
skamonkey@3767
  1482
	Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanUsePost, pWeapon);
skamonkey@3767
  1483
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1484
}
skamonkey@3767
  1485
skamonkey@3767
  1486
void SDKHooks::Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity)
skamonkey@3767
  1487
{
skamonkey@3767
  1488
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponDrop, pWeapon);
skamonkey@3767
  1489
skamonkey@3767
  1490
	if(result >= Pl_Handled)
skamonkey@3767
  1491
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1492
skamonkey@3767
  1493
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1494
}
skamonkey@3767
  1495
skamonkey@3767
  1496
void SDKHooks::Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity)
skamonkey@3767
  1497
{
skamonkey@3767
  1498
	Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponDropPost, pWeapon);
skamonkey@3767
  1499
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1500
}
skamonkey@3767
  1501
skamonkey@3767
  1502
void SDKHooks::Hook_WeaponEquip(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1503
{
skamonkey@3767
  1504
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponEquip, pWeapon);
skamonkey@3767
  1505
skamonkey@3767
  1506
	if(result >= Pl_Handled)
skamonkey@3767
  1507
		RETURN_META(MRES_SUPERCEDE);
skamonkey@3767
  1508
skamonkey@3767
  1509
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1510
}
skamonkey@3767
  1511
skamonkey@3767
  1512
void SDKHooks::Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon)
skamonkey@3767
  1513
{
skamonkey@3767
  1514
	Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponEquipPost, pWeapon);
skamonkey@3767
  1515
	RETURN_META(MRES_IGNORED);
skamonkey@3767
  1516
}
skamonkey@3767
  1517
skamonkey@3767
  1518
bool SDKHooks::Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex)
skamonkey@3767
  1519
{
skamonkey@3767
  1520
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponSwitch, pWeapon);
skamonkey@3767
  1521
skamonkey@3767
  1522
	if(result >= Pl_Handled)
skamonkey@3767
  1523
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
skamonkey@3767
  1524
skamonkey@3767
  1525
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1526
}
skamonkey@3767
  1527
skamonkey@3767
  1528
bool SDKHooks::Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex)
skamonkey@3767
  1529
{
skamonkey@3767
  1530
	cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponSwitchPost, pWeapon);
skamonkey@3767
  1531
	RETURN_META_VALUE(MRES_IGNORED, true);
skamonkey@3767
  1532
}
skamonkey@3767
  1533
skamonkey@3767
  1534
skamonkey@3767
  1535
void SDKHooks::RemoveEntityHooks(CBaseEntity *pEnt)
skamonkey@3767
  1536
{
skamonkey@3767
  1537
	int entity = gamehelpers->EntityToBCompatRef(pEnt);
skamonkey@3767
  1538
	
skamonkey@3767
  1539
	// Remove hooks
skamonkey@3767
  1540
	HOOKLOOP
skamonkey@3767
  1541
	{
skamonkey@3767
  1542
		if(g_HookList[i].entity == entity)
skamonkey@3767
  1543
		{
skamonkey@3767
  1544
#ifdef SDKHOOKSDEBUG
skamonkey@3767
  1545
			META_CONPRINTF("DEBUG: Removing hook #%d on entity %d (UpdateOnRemove or clientdisconnect)\n", i, entity);
skamonkey@3767
  1546
#endif
skamonkey@3767
  1547
			Unhook(i);
skamonkey@3767
  1548
		}
skamonkey@3767
  1549
	}
skamonkey@3767
  1550
}
skamonkey@3767
  1551
skamonkey@3767
  1552
CON_COMMAND(sdkhooks_listhooks, "Lists all current hooks")
skamonkey@3767
  1553
{
skamonkey@3767
  1554
	META_CONPRINTF("    %-24.23s %-18.17s %s\n", "Plugin", "Type", "Entity");
skamonkey@3767
  1555
	
skamonkey@3767
  1556
	IPlugin *pPlugin;
skamonkey@3767
  1557
	const sm_plugininfo_t *info;
skamonkey@3767
  1558
	for(int i = g_HookList.Count() - 1; i >= 0; i--)
skamonkey@3767
  1559
	{
skamonkey@3767
  1560
		g_HookList[i].callback->GetParentRuntime()->GetDefaultContext()->GetKey(2, (void **)&pPlugin);
skamonkey@3767
  1561
		info = pPlugin->GetPublicInfo();
skamonkey@3767
  1562
		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
  1563
	}
skamonkey@3767
  1564
}