extensions/sdktools/vnatives.cpp
author Borja Ferrer <faluco@alliedmods.net>
Fri Dec 07 00:17:24 2007 +0000 (2007-12-07)
changeset 1773 d00a853ec547
parent 1769 7a3f09643820
child 1935 76891077963c
permissions -rw-r--r--
fixed amb1252, GetPlayerInfo wouldnt work for the last player index
fixed iserver crashing on linux
faluco@1031
     1
/**
faluco@1031
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1233
     4
 * SourceMod SDKTools Extension
dvander@1233
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
faluco@1031
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1233
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1233
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1233
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
faluco@1031
    28
 *
faluco@1031
    29
 * Version: $Id$
faluco@1031
    30
 */
faluco@1031
    31
dvander@1169
    32
#include <stdlib.h>
dvander@1152
    33
#include <sh_string.h>
dvander@954
    34
#include "extension.h"
dvander@954
    35
#include "vcallbuilder.h"
dvander@954
    36
#include "vnatives.h"
dvander@1169
    37
#include "vhelpers.h"
ds@1240
    38
#include "vglobals.h"
dvander@1169
    39
#include "CellRecipientFilter.h"
dvander@954
    40
faluco@1560
    41
SourceHook::List<ValveCall *> g_RegCalls;
faluco@1560
    42
SourceHook::List<ICallWrapper *> g_CallWraps;
dvander@954
    43
dvander@985
    44
inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags, unsigned int decflags=0)
dvander@954
    45
{
dvander@985
    46
	info.decflags = decflags;
dvander@954
    47
	info.encflags = 0;
dvander@954
    48
	info.flags = flags;
dvander@954
    49
	info.type = type;
dvander@954
    50
	info.vtype = vtype;
dvander@954
    51
}
dvander@954
    52
dvander@954
    53
#define START_CALL() \
dvander@954
    54
	unsigned char *vptr = pCall->stk_get();
dvander@954
    55
dvander@954
    56
#define FINISH_CALL_SIMPLE(vret) \
dvander@954
    57
	pCall->call->Execute(vptr, vret); \
dvander@954
    58
	pCall->stk_put(vptr);
dvander@954
    59
dvander@954
    60
#define ENCODE_VALVE_PARAM(num, which, vnum) \
dvander@954
    61
	if (EncodeValveParam(pContext, \
dvander@954
    62
			params[num], \
dvander@987
    63
			pCall, \
dvander@954
    64
			&pCall->which[vnum], \
dvander@987
    65
			vptr) \
dvander@954
    66
		== Data_Fail) \
dvander@954
    67
	{ \
dvander@954
    68
		return 0; \
dvander@954
    69
	}
dvander@954
    70
dvander@954
    71
#define DECODE_VALVE_PARAM(num, which, vnum) \
dvander@954
    72
	if (DecodeValveParam(pContext, \
dvander@954
    73
			params[num], \
dvander@987
    74
			pCall, \
dvander@954
    75
			&pCall->which[vnum], \
dvander@987
    76
			vptr) \
dvander@954
    77
		== Data_Fail) \
dvander@954
    78
	{ \
dvander@954
    79
		return 0; \
dvander@954
    80
	}
dvander@954
    81
dvander@954
    82
bool CreateBaseCall(const char *name,
dvander@954
    83
						  ValveCallType vcalltype,
dvander@954
    84
						  const ValvePassInfo *retinfo,
dvander@954
    85
						  const ValvePassInfo params[],
dvander@954
    86
						  unsigned int numParams,
dvander@954
    87
						  ValveCall **vaddr)
dvander@954
    88
{
dvander@954
    89
	int offset;
dvander@954
    90
	ValveCall *call;
dvander@954
    91
	if (g_pGameConf->GetOffset(name, &offset))
dvander@954
    92
	{
dvander@954
    93
		call = CreateValveVCall(offset, vcalltype, retinfo, params, numParams);
dvander@954
    94
		if (call)
dvander@954
    95
		{
dvander@954
    96
			g_RegCalls.push_back(call);
dvander@954
    97
		}
dvander@954
    98
		*vaddr = call;
dvander@954
    99
		return true;
dvander@954
   100
	} else {
dvander@954
   101
		void *addr;
dvander@954
   102
		if (g_pGameConf->GetMemSig(name, &addr))
dvander@954
   103
		{
dvander@954
   104
			call = CreateValveCall(addr, vcalltype, retinfo, params, numParams);
dvander@954
   105
			if (call)
dvander@954
   106
			{
dvander@954
   107
				g_RegCalls.push_back(call);
dvander@954
   108
			}
dvander@954
   109
			*vaddr = call;
dvander@954
   110
			return true;
dvander@954
   111
		}
dvander@954
   112
	}
dvander@954
   113
	return false;
dvander@954
   114
}
dvander@954
   115
dvander@954
   116
static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
dvander@954
   117
{
dvander@954
   118
	static ValveCall *pCall = NULL;
dvander@954
   119
	if (!pCall)
dvander@954
   120
	{
dvander@954
   121
		ValvePassInfo pass[2];
ds@1168
   122
		InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
ds@1168
   123
		InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
ds@1168
   124
		if (!CreateBaseCall("RemovePlayerItem", ValveCall_Player, &pass[1], pass, 1, &pCall))
dvander@954
   125
		{
dvander@954
   126
			return pContext->ThrowNativeError("\"RemovePlayerItem\" not supported by this mod");
dvander@954
   127
		} else if (!pCall) {
dvander@954
   128
			return pContext->ThrowNativeError("\"RemovePlayerItem\" wrapper failed to initialized");
dvander@954
   129
		}
dvander@954
   130
	}
dvander@954
   131
dvander@954
   132
	bool ret;
dvander@954
   133
	START_CALL();
dvander@954
   134
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@954
   135
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@954
   136
	FINISH_CALL_SIMPLE(&ret);
dvander@954
   137
	return ret ? 1 : 0;
dvander@954
   138
}
dvander@954
   139
dvander@954
   140
static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
dvander@954
   141
{
dvander@954
   142
	static ValveCall *pCall = NULL;
dvander@954
   143
	if (!pCall)
dvander@954
   144
	{
dvander@954
   145
		ValvePassInfo pass[3];
dvander@954
   146
		InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   147
		InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   148
		InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   149
		if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[2], pass, 2, &pCall))
dvander@954
   150
		{
dvander@954
   151
			return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod");
dvander@954
   152
		} else if (!pCall) {
dvander@954
   153
			return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialized");
dvander@954
   154
		}
dvander@954
   155
	}
dvander@954
   156
dvander@954
   157
	CBaseEntity *pEntity = NULL;
dvander@954
   158
	START_CALL();
dvander@954
   159
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@954
   160
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@954
   161
	DECODE_VALVE_PARAM(3, vparams, 1);
dvander@954
   162
	FINISH_CALL_SIMPLE(&pEntity);
dvander@954
   163
dvander@954
   164
	if (pEntity == NULL)
dvander@954
   165
	{
dvander@954
   166
		return -1;
dvander@954
   167
	}
dvander@954
   168
dvander@954
   169
	edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
dvander@954
   170
	if (!pEdict)
dvander@954
   171
	{
dvander@954
   172
		return -1;
dvander@954
   173
	}
dvander@954
   174
dvander@954
   175
	return engine->IndexOfEdict(pEdict);
dvander@954
   176
}
dvander@954
   177
dvander@954
   178
static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params)
dvander@954
   179
{
dvander@954
   180
	static ValveCall *pCall = NULL;
dvander@954
   181
	if (!pCall)
dvander@954
   182
	{
dvander@954
   183
		ValvePassInfo pass[2];
dvander@954
   184
		InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   185
		InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   186
		if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall))
dvander@954
   187
		{
dvander@954
   188
			return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod");
dvander@954
   189
		} else if (!pCall) {
dvander@954
   190
			return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized");
dvander@954
   191
		}
dvander@954
   192
	}
dvander@954
   193
dvander@954
   194
	CBaseEntity *pEntity;
dvander@954
   195
	START_CALL();
dvander@954
   196
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@954
   197
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@954
   198
	FINISH_CALL_SIMPLE(&pEntity);
dvander@954
   199
dvander@954
   200
	if (pEntity == NULL)
dvander@954
   201
	{
dvander@954
   202
		return -1;
dvander@954
   203
	}
dvander@954
   204
dvander@954
   205
	edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
dvander@954
   206
	if (!pEdict)
dvander@954
   207
	{
dvander@954
   208
		return -1;
dvander@954
   209
	}
dvander@954
   210
dvander@954
   211
	return engine->IndexOfEdict(pEdict);
dvander@954
   212
}
dvander@954
   213
ds@1240
   214
static cell_t IgniteEntity(IPluginContext *pContext, const cell_t *params)
dvander@955
   215
{
dvander@955
   216
	static ValveCall *pCall = NULL;
dvander@955
   217
	if (!pCall)
dvander@955
   218
	{
dvander@955
   219
		ValvePassInfo pass[4];
dvander@955
   220
		InitPass(pass[0], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
dvander@955
   221
		InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
dvander@955
   222
		InitPass(pass[2], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
dvander@955
   223
		InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
dvander@980
   224
		if (!CreateBaseCall("Ignite", ValveCall_Entity, NULL, pass, 4, &pCall))
dvander@955
   225
		{
dvander@955
   226
			return pContext->ThrowNativeError("\"Ignite\" not supported by this mod");
dvander@955
   227
		} else if (!pCall) {
dvander@955
   228
			return pContext->ThrowNativeError("\"Ignite\" wrapper failed to initialized");
dvander@955
   229
		}
dvander@955
   230
	}
dvander@955
   231
dvander@955
   232
	START_CALL();
dvander@955
   233
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@955
   234
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@955
   235
	DECODE_VALVE_PARAM(3, vparams, 1);
dvander@955
   236
	DECODE_VALVE_PARAM(4, vparams, 2);
dvander@955
   237
	DECODE_VALVE_PARAM(5, vparams, 3);
dvander@955
   238
	FINISH_CALL_SIMPLE(NULL);
dvander@955
   239
dvander@955
   240
	return 1;
dvander@955
   241
}
dvander@955
   242
ds@1240
   243
static cell_t ExtinguishEntity(IPluginContext *pContext, const cell_t *params)
dvander@955
   244
{
dvander@955
   245
	static ValveCall *pCall = NULL;
dvander@955
   246
	if (!pCall)
dvander@955
   247
	{
dvander@980
   248
		if (!CreateBaseCall("Extinguish", ValveCall_Entity, NULL, NULL, 0, &pCall))
dvander@955
   249
		{
dvander@955
   250
			return pContext->ThrowNativeError("\"Extinguish\" not supported by this mod");
dvander@955
   251
		} else if (!pCall) {
dvander@955
   252
			return pContext->ThrowNativeError("\"Extinguish\" wrapper failed to initialized");
dvander@955
   253
		}
dvander@955
   254
	}
dvander@955
   255
dvander@955
   256
	START_CALL();
dvander@955
   257
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@955
   258
	FINISH_CALL_SIMPLE(NULL);
dvander@955
   259
dvander@955
   260
	return 1;
dvander@955
   261
}
dvander@955
   262
ds@1240
   263
static cell_t TeleportEntity(IPluginContext *pContext, const cell_t *params)
dvander@955
   264
{
dvander@955
   265
	static ValveCall *pCall = NULL;
dvander@955
   266
	if (!pCall)
dvander@955
   267
	{
dvander@955
   268
		ValvePassInfo pass[3];
dvander@985
   269
		InitPass(pass[0], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
dvander@985
   270
		InitPass(pass[1], Valve_QAngle, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
dvander@985
   271
		InitPass(pass[2], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL);
dvander@980
   272
		if (!CreateBaseCall("Teleport", ValveCall_Entity, NULL, pass, 3, &pCall))
dvander@955
   273
		{
dvander@955
   274
			return pContext->ThrowNativeError("\"Teleport\" not supported by this mod");
dvander@955
   275
		} else if (!pCall) {
dvander@955
   276
			return pContext->ThrowNativeError("\"Teleport\" wrapper failed to initialized");
dvander@955
   277
		}
dvander@955
   278
	}
dvander@955
   279
dvander@955
   280
	START_CALL();
dvander@955
   281
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@955
   282
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@955
   283
	DECODE_VALVE_PARAM(3, vparams, 1);
dvander@955
   284
	DECODE_VALVE_PARAM(4, vparams, 2);
dvander@955
   285
	FINISH_CALL_SIMPLE(NULL);
dvander@955
   286
dvander@955
   287
	return 1;
dvander@955
   288
}
dvander@955
   289
dvander@1597
   290
#if defined ORANGEBOX_BUILD
dvander@1597
   291
/* :TODO: This is Team Fortress 2 specific */
dvander@1597
   292
static cell_t ForcePlayerSuicide(IPluginContext *pContext, const cell_t *params)
dvander@1597
   293
{
dvander@1597
   294
	static ValveCall *pCall = NULL;
dvander@1597
   295
	if (!pCall)
dvander@1597
   296
	{
dvander@1597
   297
		ValvePassInfo pass[2];
dvander@1597
   298
		InitPass(pass[0], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
dvander@1597
   299
		InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
dvander@1597
   300
		if (!CreateBaseCall("CommitSuicide", ValveCall_Player, NULL, pass, 2, &pCall))
dvander@1597
   301
		{
dvander@1597
   302
			return pContext->ThrowNativeError("\"CommitSuicide\" not supported by this mod");
dvander@1597
   303
		}
dvander@1597
   304
		else if (!pCall)
dvander@1597
   305
		{
dvander@1597
   306
			return pContext->ThrowNativeError("\"CommitSuicide\" wrapper failed to initialized");
dvander@1597
   307
		}
dvander@1597
   308
	}
dvander@1597
   309
dvander@1597
   310
	START_CALL();
dvander@1597
   311
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@1597
   312
	*(bool *)(vptr + 4) = false;
dvander@1597
   313
	*(bool *)(vptr + 5) = false;
dvander@1597
   314
	FINISH_CALL_SIMPLE(NULL);
dvander@1597
   315
dvander@1597
   316
	return 1;
dvander@1597
   317
}
dvander@1597
   318
#else
dvander@1151
   319
static cell_t ForcePlayerSuicide(IPluginContext *pContext, const cell_t *params)
dvander@1151
   320
{
dvander@1151
   321
	static ValveCall *pCall = NULL;
dvander@1151
   322
	if (!pCall)
dvander@1151
   323
	{
dvander@1151
   324
		if (!CreateBaseCall("CommitSuicide", ValveCall_Player, NULL, NULL, 0, &pCall))
dvander@1151
   325
		{
dvander@1151
   326
			return pContext->ThrowNativeError("\"CommitSuicide\" not supported by this mod");
dvander@1151
   327
		} else if (!pCall) {
dvander@1151
   328
			return pContext->ThrowNativeError("\"CommitSuicide\" wrapper failed to initialized");
dvander@1151
   329
		}
dvander@1151
   330
	}
dvander@1151
   331
dvander@1151
   332
	START_CALL();
dvander@1151
   333
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@1151
   334
	FINISH_CALL_SIMPLE(NULL);
dvander@1151
   335
dvander@1151
   336
	return 1;
dvander@1151
   337
}
dvander@1597
   338
#endif
dvander@1151
   339
dvander@1106
   340
static cell_t SetClientViewEntity(IPluginContext *pContext, const cell_t *params)
dvander@1106
   341
{
dvander@1106
   342
	IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
dvander@1106
   343
	if (player == NULL)
dvander@1106
   344
	{
dvander@1106
   345
		return pContext->ThrowNativeError("Invalid client index %d", params[1]);
dvander@1106
   346
	}
dvander@1106
   347
	if (!player->IsInGame())
dvander@1106
   348
	{
dvander@1106
   349
		return pContext->ThrowNativeError("Client %d is not in game", params[1]);
dvander@1106
   350
	}
dvander@1106
   351
dvander@1106
   352
	edict_t *pEdict = engine->PEntityOfEntIndex(params[2]);
dvander@1106
   353
	if (!pEdict || pEdict->IsFree())
dvander@1106
   354
	{
dvander@1106
   355
		return pContext->ThrowNativeError("Entity %d is not valid", params[2]);
dvander@1106
   356
	}
dvander@1106
   357
dvander@1106
   358
	engine->SetView(player->GetEdict(), pEdict);
dvander@1106
   359
dvander@1106
   360
	return 1;
dvander@1106
   361
}
dvander@1106
   362
faluco@1560
   363
static SourceHook::String *g_lightstyle[MAX_LIGHTSTYLES] = {NULL};
dvander@1152
   364
static cell_t SetLightStyle(IPluginContext *pContext, const cell_t *params)
dvander@1152
   365
{
dvander@1152
   366
	int style = params[1];
dvander@1152
   367
	if (style >= MAX_LIGHTSTYLES)
dvander@1152
   368
	{
dvander@1152
   369
		return pContext->ThrowNativeError("Light style %d is invalid (range: 0-%d)", style, MAX_LIGHTSTYLES - 1);
dvander@1152
   370
	}
dvander@1152
   371
dvander@1152
   372
	if (g_lightstyle[style] == NULL)
dvander@1152
   373
	{
dvander@1154
   374
		/* We allocate and never free this because the Engine wants to hold onto it :\
dvander@1154
   375
		 * in theory we could hook light style and know whether we're supposed to free 
dvander@1154
   376
		 * this or not on shutdown, but for ~4K of memory MAX, it doesn't seem worth it yet.
dvander@1154
   377
		 * So, it's a :TODO:!
dvander@1154
   378
		 */
faluco@1560
   379
		g_lightstyle[style] = new SourceHook::String();
dvander@1152
   380
	}
dvander@1152
   381
dvander@1152
   382
	char *str;
dvander@1152
   383
	pContext->LocalToString(params[2], &str);
dvander@1152
   384
dvander@1152
   385
	g_lightstyle[style]->assign(str);
dvander@1152
   386
dvander@1153
   387
	engine->LightStyle(style, g_lightstyle[style]->c_str());
dvander@1152
   388
dvander@1152
   389
	return 1;
dvander@1152
   390
}
dvander@1152
   391
dvander@1169
   392
static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params)
dvander@1169
   393
{
dvander@1169
   394
	static bool s_slap_supported = false;
dvander@1169
   395
	static bool s_slap_setup = false;
dvander@1169
   396
	static ICallWrapper *s_teleport = NULL;
ds@1171
   397
	static int s_health_offs = 0;
dvander@1169
   398
	static int s_sound_count = 0;
dvander@1169
   399
	static int s_frag_offs = 0;
dvander@1169
   400
dvander@1169
   401
	if (!s_slap_setup)
dvander@1169
   402
	{
dvander@1169
   403
		int tries = 0;
dvander@1169
   404
dvander@1169
   405
		s_slap_setup = true;
dvander@1169
   406
dvander@1169
   407
		if (IsTeleportSupported())
dvander@1169
   408
		{
dvander@1169
   409
			tries++;
dvander@1169
   410
		}
dvander@1169
   411
		if (IsGetVelocitySupported())
dvander@1169
   412
		{
dvander@1169
   413
			tries++;
dvander@1169
   414
		}
dvander@1169
   415
dvander@1169
   416
		/* Setup health */
dvander@1169
   417
		if (g_pGameConf->GetOffset("m_iHealth", &s_health_offs) && s_health_offs)
dvander@1169
   418
		{
dvander@1169
   419
			tries++;
dvander@1169
   420
		}
dvander@1169
   421
dvander@1169
   422
		if (tries == 3)
dvander@1169
   423
		{
dvander@1169
   424
			s_slap_supported = true;
dvander@1169
   425
dvander@1169
   426
			const char *key;
dvander@1169
   427
			if ((key = g_pGameConf->GetKeyValue("SlapSoundCount")) != NULL)
dvander@1169
   428
			{
dvander@1169
   429
				s_sound_count = atoi(key);
dvander@1169
   430
			}
dvander@1169
   431
		}
dvander@1169
   432
	}
dvander@1169
   433
dvander@1169
   434
	if (!s_slap_supported)
dvander@1169
   435
	{
dvander@1169
   436
		return pContext->ThrowNativeError("This function is not supported on this mod");
dvander@1169
   437
	}
dvander@1169
   438
dvander@1169
   439
	/* First check if the client is valid */
dvander@1169
   440
	int client = params[1];
dvander@1169
   441
	IGamePlayer *player = playerhelpers->GetGamePlayer(client);
dvander@1169
   442
	if (!player)
dvander@1169
   443
	{
dvander@1169
   444
		return pContext->ThrowNativeError("Client %d is not valid", client);
dvander@1169
   445
	} else if (!player->IsInGame()) {
dvander@1169
   446
		return pContext->ThrowNativeError("Client %d is not in game", client);
dvander@1169
   447
	}
dvander@1169
   448
dvander@1169
   449
	edict_t *pEdict = player->GetEdict();
dvander@1169
   450
	CBaseEntity *pEntity = pEdict->GetUnknown()->GetBaseEntity();
dvander@1169
   451
dvander@1169
   452
	/* See if we should be taking away health */
dvander@1169
   453
	bool should_slay = false;
dvander@1169
   454
	if (params[2])
dvander@1169
   455
	{
dvander@1169
   456
		int *health = (int *)((char *)pEntity + s_health_offs);
dvander@1169
   457
		if (*health - params[2] <= 0)
dvander@1169
   458
		{
dvander@1169
   459
			*health = 1;
dvander@1169
   460
			should_slay = true;
dvander@1169
   461
		} else {
dvander@1169
   462
			*health -= params[2];
dvander@1169
   463
		}
dvander@1169
   464
	}
dvander@1169
   465
dvander@1169
   466
	/* Teleport in a random direction - thank you, Mani!*/
dvander@1169
   467
	Vector velocity;
dvander@1169
   468
	GetVelocity(pEntity, &velocity, NULL);
dvander@1169
   469
	velocity.x += ((rand() % 180) + 50) * (((rand() % 2) == 1) ?  -1 : 1);
dvander@1169
   470
	velocity.y += ((rand() % 180) + 50) * (((rand() % 2) == 1) ?  -1 : 1);
dvander@1169
   471
	velocity.z += rand() % 200 + 100;
dvander@1169
   472
	Teleport(pEntity, NULL, NULL, &velocity);
dvander@1169
   473
dvander@1169
   474
	/* Play a random sound */
dvander@1169
   475
	if (params[3] && s_sound_count > 0)
dvander@1169
   476
	{
dvander@1169
   477
		char name[48];
dvander@1169
   478
		const char *sound_name;
dvander@1169
   479
		cell_t player_list[256], total_players = 0;
dvander@1169
   480
		int maxClients = playerhelpers->GetMaxClients();
dvander@1169
   481
dvander@1169
   482
		int r = (rand() % s_sound_count) + 1;
dvander@1169
   483
		snprintf(name, sizeof(name), "SlapSound%d", r);
dvander@1169
   484
dvander@1169
   485
		if ((sound_name = g_pGameConf->GetKeyValue(name)) != NULL)
dvander@1169
   486
		{
dvander@1169
   487
			IGamePlayer *other;
dvander@1169
   488
			for (int i=1; i<=maxClients; i++)
dvander@1169
   489
			{
dvander@1169
   490
				other = playerhelpers->GetGamePlayer(i);
dvander@1169
   491
				if (other->IsInGame())
dvander@1169
   492
				{
dvander@1169
   493
					player_list[total_players++] = i;
dvander@1169
   494
				}
dvander@1169
   495
			}
dvander@1169
   496
dvander@1169
   497
			const Vector & pos = pEdict->GetCollideable()->GetCollisionOrigin();
dvander@1169
   498
			CellRecipientFilter rf;
dvander@1169
   499
			rf.SetToReliable(true);
dvander@1169
   500
			rf.Initialize(player_list, total_players);
dvander@1169
   501
			engsound->EmitSound(rf, client, CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
dvander@1169
   502
		}
dvander@1169
   503
	}
dvander@1169
   504
dvander@1169
   505
	if (!s_frag_offs)
dvander@1169
   506
	{
dvander@1169
   507
		const char *frag_prop = g_pGameConf->GetKeyValue("m_iFrags");
dvander@1169
   508
		if (frag_prop)
dvander@1169
   509
		{
dvander@1169
   510
			datamap_t *pMap = gamehelpers->GetDataMap(pEntity);
dvander@1169
   511
			typedescription_t *pType = gamehelpers->FindInDataMap(pMap, frag_prop);
dvander@1169
   512
			if (pType != NULL)
dvander@1169
   513
			{
dvander@1169
   514
				s_frag_offs = pType->fieldOffset[TD_OFFSET_NORMAL];
dvander@1169
   515
			}
dvander@1169
   516
		}
dvander@1169
   517
		if (!s_frag_offs)
dvander@1169
   518
		{
dvander@1169
   519
			s_frag_offs = -1;
dvander@1169
   520
		}
dvander@1169
   521
	}
dvander@1169
   522
dvander@1169
   523
	int old_frags = 0;
dvander@1169
   524
	if (s_frag_offs > 0)
dvander@1169
   525
	{
dvander@1169
   526
		old_frags = *(int *)((char *)pEntity + s_frag_offs);
dvander@1169
   527
	}
dvander@1169
   528
	
dvander@1169
   529
	/* Force suicide */
dvander@1169
   530
	if (should_slay)
dvander@1169
   531
	{
dvander@1169
   532
		pluginhelpers->ClientCommand(pEdict, "kill\n");
dvander@1169
   533
	}
dvander@1169
   534
dvander@1169
   535
	if (s_frag_offs > 0)
dvander@1169
   536
	{
dvander@1169
   537
		*(int *)((char *)pEntity + s_frag_offs) = old_frags;
dvander@1169
   538
	}
dvander@1169
   539
dvander@1169
   540
	return 1;
dvander@1169
   541
}
dvander@1169
   542
faluco@1219
   543
static cell_t GetClientEyePosition(IPluginContext *pContext, const cell_t *params)
faluco@1219
   544
{
faluco@1219
   545
	IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
faluco@1219
   546
	if (player == NULL)
faluco@1219
   547
	{
faluco@1219
   548
		return pContext->ThrowNativeError("Invalid client index %d", params[1]);
faluco@1219
   549
	}
faluco@1219
   550
	if (!player->IsInGame())
faluco@1219
   551
	{
faluco@1219
   552
		return pContext->ThrowNativeError("Client %d is not in game", params[1]);
faluco@1219
   553
	}
faluco@1219
   554
faluco@1219
   555
	Vector pos;
faluco@1219
   556
	serverClients->ClientEarPosition(player->GetEdict(), &pos);
faluco@1219
   557
faluco@1219
   558
	cell_t *addr;
faluco@1219
   559
	pContext->LocalToPhysAddr(params[2], &addr);
faluco@1219
   560
	addr[0] = sp_ftoc(pos.x);
faluco@1219
   561
	addr[1] = sp_ftoc(pos.y);
faluco@1219
   562
	addr[2] = sp_ftoc(pos.z);
faluco@1219
   563
faluco@1219
   564
	return 1;
faluco@1219
   565
}
faluco@1219
   566
faluco@1219
   567
static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params)
faluco@1219
   568
{
dvander@1611
   569
	int client = params[1];
dvander@1611
   570
	IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
dvander@1611
   571
dvander@1611
   572
	if (!pPlayer)
faluco@1219
   573
	{
dvander@1611
   574
		return pContext->ThrowNativeError("Invalid client index %d", client);
dvander@1611
   575
	}
dvander@1611
   576
	else if (!pPlayer->IsInGame())
dvander@1611
   577
	{
dvander@1611
   578
		return pContext->ThrowNativeError("Client %d is not in game", client);
faluco@1219
   579
	}
faluco@1219
   580
dvander@1611
   581
	edict_t *pEdict = pPlayer->GetEdict();
dvander@1611
   582
	CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL;
dvander@1611
   583
dvander@1611
   584
	/* We always set the angles for backwards compatibility -- 
dvander@1611
   585
	 * The original function had no return value.
dvander@1611
   586
	 */
dvander@1611
   587
	QAngle angles;
dvander@1611
   588
	bool got_angles = false;
dvander@1611
   589
dvander@1612
   590
	if (pEntity != NULL)
dvander@1611
   591
	{
dvander@1611
   592
		got_angles = GetEyeAngles(pEntity, &angles);
dvander@1611
   593
	}
faluco@1219
   594
	
faluco@1219
   595
	cell_t *addr;
faluco@1219
   596
	pContext->LocalToPhysAddr(params[2], &addr);
dvander@1611
   597
	addr[0] = sp_ftoc(angles.x);
dvander@1611
   598
	addr[1] = sp_ftoc(angles.y);
dvander@1611
   599
	addr[2] = sp_ftoc(angles.z);
faluco@1219
   600
dvander@1611
   601
	return got_angles ? 1 : 0;
faluco@1219
   602
}
faluco@1219
   603
ds@1240
   604
static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
ds@1240
   605
{
ds@1240
   606
	static ValveCall *pCall = NULL;
ds@1240
   607
	if (!pCall)
ds@1240
   608
	{
ds@1240
   609
		ValvePassInfo pass[3];
ds@1240
   610
		InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL|VDECODE_FLAG_ALLOWWORLD);
ds@1240
   611
		InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
ds@1240
   612
		InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
ds@1240
   613
		if (!CreateBaseCall("FindEntityByClassname", ValveCall_EntityList, &pass[2], pass, 2, &pCall))
ds@1240
   614
		{
ds@1240
   615
			return pContext->ThrowNativeError("\"FindEntityByClassname\" not supported by this mod");
ds@1240
   616
		} else if (!pCall) {
ds@1240
   617
			return pContext->ThrowNativeError("\"FindEntityByClassname\" wrapper failed to initialized");
ds@1240
   618
		}
ds@1240
   619
	}
ds@1240
   620
ds@1240
   621
	CBaseEntity *pEntity;
ds@1240
   622
	START_CALL();
ds@1240
   623
	*(void **)vptr = g_EntList; 
ds@1240
   624
	DECODE_VALVE_PARAM(1, vparams, 0);
ds@1240
   625
	DECODE_VALVE_PARAM(2, vparams, 1);
ds@1240
   626
	FINISH_CALL_SIMPLE(&pEntity);
ds@1240
   627
ds@1240
   628
	if (pEntity == NULL)
ds@1240
   629
	{
ds@1240
   630
		return -1;
ds@1240
   631
	}
ds@1240
   632
ds@1240
   633
	edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
ds@1240
   634
	if (!pEdict)
ds@1240
   635
	{
ds@1240
   636
		return -1;
ds@1240
   637
	}
ds@1240
   638
ds@1240
   639
	return engine->IndexOfEdict(pEdict);
ds@1240
   640
}
ds@1240
   641
faluco@1428
   642
static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params)
faluco@1428
   643
{
faluco@1428
   644
	static ValveCall *pCall = NULL;
faluco@1428
   645
	if (!pCall)
faluco@1428
   646
	{
faluco@1428
   647
		ValvePassInfo pass[3];
faluco@1428
   648
		InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
faluco@1428
   649
		InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
faluco@1428
   650
		InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
faluco@1428
   651
		if (!CreateBaseCall("CreateEntityByName", ValveCall_Static, &pass[2], pass, 2, &pCall))
faluco@1428
   652
		{
faluco@1428
   653
			return pContext->ThrowNativeError("\"CreateEntityByName\" not supported by this mod");
faluco@1428
   654
		} else if (!pCall) {
faluco@1428
   655
			return pContext->ThrowNativeError("\"CreateEntityByName\" wrapper failed to initialized");
faluco@1428
   656
		}
faluco@1428
   657
	}
faluco@1428
   658
faluco@1428
   659
	CBaseEntity *pEntity = NULL;
faluco@1428
   660
	START_CALL();
faluco@1428
   661
	DECODE_VALVE_PARAM(1, vparams, 0);
faluco@1428
   662
	DECODE_VALVE_PARAM(2, vparams, 1);
faluco@1428
   663
	FINISH_CALL_SIMPLE(&pEntity);
faluco@1428
   664
faluco@1428
   665
	if (pEntity == NULL)
faluco@1428
   666
	{
faluco@1428
   667
		return -1;
teame06@1239
   668
	}
faluco@1428
   669
faluco@1428
   670
	edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
faluco@1428
   671
	if (!pEdict)
faluco@1428
   672
	{
faluco@1428
   673
		return -1;
faluco@1428
   674
	}
faluco@1428
   675
faluco@1428
   676
	return engine->IndexOfEdict(pEdict);
faluco@1428
   677
}
faluco@1428
   678
faluco@1428
   679
static cell_t DispatchSpawn(IPluginContext *pContext, const cell_t *params)
faluco@1428
   680
{
faluco@1428
   681
	static ValveCall *pCall = NULL;
faluco@1428
   682
	if (!pCall)
faluco@1428
   683
	{
faluco@1428
   684
		ValvePassInfo pass[2];
faluco@1428
   685
		InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
faluco@1428
   686
		InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
faluco@1428
   687
		if (!CreateBaseCall("DispatchSpawn", ValveCall_Static, &pass[1], pass, 1, &pCall))
faluco@1428
   688
		{
faluco@1428
   689
			return pContext->ThrowNativeError("\"DispatchSpawn\" not supported by this mod");
faluco@1428
   690
		} else if (!pCall) {
faluco@1428
   691
			return pContext->ThrowNativeError("\"DispatchSpawn\" wrapper failed to initialized");
faluco@1428
   692
		}
faluco@1428
   693
	}
faluco@1428
   694
faluco@1428
   695
	int ret;
faluco@1428
   696
	START_CALL();
faluco@1428
   697
	DECODE_VALVE_PARAM(1, vparams, 0);
faluco@1428
   698
	FINISH_CALL_SIMPLE(&ret);
faluco@1428
   699
faluco@1428
   700
	return (ret == -1) ? 0 : 1;
teame06@1239
   701
}
teame06@1239
   702
faluco@1504
   703
static cell_t DispatchKeyValue(IPluginContext *pContext, const cell_t *params)
faluco@1504
   704
{
faluco@1504
   705
	static ValveCall *pCall = NULL;
faluco@1504
   706
	if (!pCall)
faluco@1504
   707
	{
faluco@1504
   708
		ValvePassInfo pass[3];
faluco@1504
   709
		InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
faluco@1504
   710
		InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
faluco@1504
   711
		InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
faluco@1504
   712
		if (!CreateBaseCall("DispatchKeyValue", ValveCall_Entity, &pass[2], pass, 2, &pCall))
faluco@1504
   713
		{
faluco@1504
   714
			return pContext->ThrowNativeError("\"DispatchKeyValue\" not supported by this mod");
faluco@1504
   715
		} else if (!pCall) {
faluco@1504
   716
			return pContext->ThrowNativeError("\"DispatchKeyValue\" wrapper failed to initialized");
faluco@1504
   717
		}
faluco@1504
   718
	}
faluco@1504
   719
faluco@1504
   720
	bool ret;
faluco@1504
   721
	START_CALL();
faluco@1504
   722
	DECODE_VALVE_PARAM(1, thisinfo, 0);
faluco@1504
   723
	DECODE_VALVE_PARAM(2, vparams, 0);
faluco@1504
   724
	DECODE_VALVE_PARAM(3, vparams, 1);
faluco@1504
   725
	FINISH_CALL_SIMPLE(&ret);
faluco@1504
   726
faluco@1504
   727
	return (ret) ? 1 : 0;
faluco@1504
   728
}
faluco@1504
   729
faluco@1504
   730
static cell_t DispatchKeyValueFloat(IPluginContext *pContext, const cell_t *params)
faluco@1504
   731
{
faluco@1504
   732
	static ValveCall *pCall = NULL;
faluco@1504
   733
	if (!pCall)
faluco@1504
   734
	{
faluco@1504
   735
		ValvePassInfo pass[3];
faluco@1504
   736
		InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
faluco@1515
   737
		InitPass(pass[1], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
faluco@1504
   738
		InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
faluco@1504
   739
		if (!CreateBaseCall("DispatchKeyValueFloat", ValveCall_Entity, &pass[2], pass, 2, &pCall))
faluco@1504
   740
		{
faluco@1504
   741
			return pContext->ThrowNativeError("\"DispatchKeyValueFloat\" not supported by this mod");
faluco@1504
   742
		} else if (!pCall) {
faluco@1504
   743
			return pContext->ThrowNativeError("\"DispatchKeyValueFloat\" wrapper failed to initialized");
faluco@1504
   744
		}
faluco@1504
   745
	}
faluco@1504
   746
faluco@1504
   747
	bool ret;
faluco@1504
   748
	START_CALL();
faluco@1504
   749
	DECODE_VALVE_PARAM(1, thisinfo, 0);
faluco@1504
   750
	DECODE_VALVE_PARAM(2, vparams, 0);
faluco@1504
   751
	DECODE_VALVE_PARAM(3, vparams, 1);
faluco@1504
   752
	FINISH_CALL_SIMPLE(&ret);
faluco@1504
   753
faluco@1504
   754
	return (ret) ? 1 : 0;
faluco@1504
   755
}
faluco@1504
   756
faluco@1504
   757
static cell_t DispatchKeyValueVector(IPluginContext *pContext, const cell_t *params)
faluco@1504
   758
{
faluco@1504
   759
	static ValveCall *pCall = NULL;
faluco@1504
   760
	if (!pCall)
faluco@1504
   761
	{
faluco@1504
   762
		ValvePassInfo pass[3];
faluco@1504
   763
		InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
faluco@1596
   764
#if defined ORANGEBOX_BUILD
faluco@1596
   765
		InitPass(pass[1], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL);
faluco@1596
   766
#else
faluco@1515
   767
		InitPass(pass[1], Valve_Vector, PassType_Object, PASSFLAG_BYVAL|PASSFLAG_OCTOR|PASSFLAG_OASSIGNOP);
faluco@1596
   768
#endif
faluco@1504
   769
		InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
faluco@1504
   770
		if (!CreateBaseCall("DispatchKeyValueVector", ValveCall_Entity, &pass[2], pass, 2, &pCall))
faluco@1504
   771
		{
faluco@1504
   772
			return pContext->ThrowNativeError("\"DispatchKeyValueVector\" not supported by this mod");
faluco@1504
   773
		} else if (!pCall) {
faluco@1504
   774
			return pContext->ThrowNativeError("\"DispatchKeyValueVector\" wrapper failed to initialized");
faluco@1504
   775
		}
faluco@1504
   776
	}
faluco@1504
   777
faluco@1504
   778
	bool ret;
faluco@1504
   779
	START_CALL();
faluco@1504
   780
	DECODE_VALVE_PARAM(1, thisinfo, 0);
faluco@1504
   781
	DECODE_VALVE_PARAM(2, vparams, 0);
faluco@1504
   782
	DECODE_VALVE_PARAM(3, vparams, 1);
faluco@1504
   783
	FINISH_CALL_SIMPLE(&ret);
faluco@1504
   784
faluco@1504
   785
	return (ret) ? 1 : 0;
faluco@1504
   786
}
faluco@1504
   787
dvander@1628
   788
static cell_t sm_GetClientAimTarget(IPluginContext *pContext, const cell_t *params)
dvander@1611
   789
{
dvander@1611
   790
	int client = params[1];
dvander@1611
   791
	IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
dvander@1611
   792
dvander@1611
   793
	if (!pPlayer)
dvander@1611
   794
	{
dvander@1611
   795
		return pContext->ThrowNativeError("Invalid client index %d", client);
dvander@1611
   796
	}
dvander@1611
   797
	else if (!pPlayer->IsInGame())
dvander@1611
   798
	{
dvander@1611
   799
		return pContext->ThrowNativeError("Client %d is not in game", client);
dvander@1611
   800
	}
dvander@1611
   801
dvander@1628
   802
	return GetClientAimTarget(pPlayer->GetEdict(), params[2] ? true : false);
dvander@1611
   803
}
dvander@1611
   804
faluco@1720
   805
static cell_t sm_SetEntityModel(IPluginContext *pContext, const cell_t *params)
faluco@1720
   806
{
faluco@1720
   807
	static ValveCall *pCall = NULL;
faluco@1720
   808
	if (!pCall)
faluco@1720
   809
	{
faluco@1720
   810
		ValvePassInfo pass[1];
faluco@1720
   811
		InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
faluco@1720
   812
		if (!CreateBaseCall("SetEntityModel", ValveCall_Entity, NULL, pass, 1, &pCall))
faluco@1720
   813
		{
faluco@1720
   814
			return pContext->ThrowNativeError("\"SetEntityModel\" not supported by this mod");
faluco@1720
   815
		} else if (!pCall) {
faluco@1720
   816
			return pContext->ThrowNativeError("\"SetEntityModel\" wrapper failed to initialized");
faluco@1720
   817
		}
faluco@1720
   818
	}
faluco@1720
   819
faluco@1720
   820
	START_CALL();
faluco@1720
   821
	DECODE_VALVE_PARAM(1, thisinfo, 0);
faluco@1720
   822
	DECODE_VALVE_PARAM(2, vparams, 0);
faluco@1720
   823
	FINISH_CALL_SIMPLE(NULL);
faluco@1720
   824
faluco@1720
   825
	return 1;
faluco@1720
   826
}
faluco@1720
   827
faluco@1769
   828
static cell_t GetPlayerDecalFile(IPluginContext *pContext, const cell_t *params)
faluco@1769
   829
{
faluco@1769
   830
	IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
faluco@1769
   831
	if (player == NULL)
faluco@1769
   832
	{
faluco@1769
   833
		return pContext->ThrowNativeError("Invalid client index %d", params[1]);
faluco@1769
   834
	}
faluco@1769
   835
	if (!player->IsInGame())
faluco@1769
   836
	{
faluco@1769
   837
		return pContext->ThrowNativeError("Client %d is not in game", params[1]);
faluco@1769
   838
	}
faluco@1769
   839
faluco@1769
   840
	player_info_t info;
faluco@1769
   841
	char *buffer;
faluco@1769
   842
faluco@1769
   843
	if (!GetPlayerInfo(params[1], &info) || !info.customFiles[0])
faluco@1769
   844
	{
faluco@1769
   845
		return 0;
faluco@1769
   846
	}
faluco@1769
   847
faluco@1769
   848
	pContext->LocalToString(params[2], &buffer);
faluco@1769
   849
	Q_binarytohex((byte *)&info.customFiles[0], sizeof(info.customFiles[0]), buffer, params[3]);
faluco@1769
   850
faluco@1769
   851
	return 1;
faluco@1769
   852
}
faluco@1769
   853
faluco@1769
   854
static cell_t GetServerNetStats(IPluginContext *pContext, const cell_t *params)
faluco@1769
   855
{
faluco@1773
   856
	if (iserver == NULL)
faluco@1773
   857
	{
faluco@1773
   858
		return pContext->ThrowNativeError("IServer interface not supported, file a bug report.");
faluco@1773
   859
	}
faluco@1773
   860
faluco@1769
   861
	float in, out;
faluco@1769
   862
	cell_t *pIn, *pOut;
faluco@1769
   863
faluco@1769
   864
	pContext->LocalToPhysAddr(params[1], &pIn);
faluco@1769
   865
	pContext->LocalToPhysAddr(params[2], &pOut);
faluco@1769
   866
	iserver->GetNetStats(in, out);
faluco@1769
   867
faluco@1769
   868
	*pIn = sp_ftoc(in);
faluco@1769
   869
	*pOut = sp_ftoc(out);
faluco@1769
   870
faluco@1769
   871
	return 1;
faluco@1769
   872
}
faluco@1769
   873
dvander@954
   874
sp_nativeinfo_t g_Natives[] = 
dvander@954
   875
{
ds@1240
   876
	{"ExtinguishPlayer",		ExtinguishEntity},
ds@1240
   877
	{"ExtinguishEntity",		ExtinguishEntity},
faluco@1219
   878
	{"ForcePlayerSuicide",		ForcePlayerSuicide},
faluco@1219
   879
	{"GivePlayerItem",			GiveNamedItem},
faluco@1219
   880
	{"GetPlayerWeaponSlot",		GetPlayerWeaponSlot},
ds@1240
   881
	{"IgnitePlayer",			IgniteEntity},
ds@1240
   882
	{"IgniteEntity",			IgniteEntity},
faluco@1219
   883
	{"RemovePlayerItem",		RemovePlayerItem},
ds@1240
   884
	{"TeleportPlayer",			TeleportEntity},
ds@1240
   885
	{"TeleportEntity",			TeleportEntity},
faluco@1219
   886
	{"SetClientViewEntity",		SetClientViewEntity},
faluco@1219
   887
	{"SetLightStyle",			SetLightStyle},
faluco@1219
   888
	{"SlapPlayer",				SlapPlayer},
faluco@1219
   889
	{"GetClientEyePosition",	GetClientEyePosition},
faluco@1219
   890
	{"GetClientEyeAngles",		GetClientEyeAngles},
ds@1240
   891
	{"FindEntityByClassname",	FindEntityByClassname},
faluco@1428
   892
	{"CreateEntityByName",		CreateEntityByName},
faluco@1428
   893
	{"DispatchSpawn",			DispatchSpawn},
faluco@1504
   894
	{"DispatchKeyValue",		DispatchKeyValue},
faluco@1504
   895
	{"DispatchKeyValueFloat",	DispatchKeyValueFloat},
faluco@1504
   896
	{"DispatchKeyValueVector",	DispatchKeyValueVector},
dvander@1628
   897
	{"GetClientAimTarget",		sm_GetClientAimTarget},
faluco@1720
   898
	{"SetEntityModel",			sm_SetEntityModel},
faluco@1769
   899
	{"GetPlayerDecalFile",		GetPlayerDecalFile},
faluco@1769
   900
	{"GetServerNetStats",		GetServerNetStats},
faluco@1219
   901
	{NULL,						NULL},
dvander@954
   902
};