extensions/cstrike/natives.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Fri Feb 07 22:11:31 2014 -0500 (2014-02-07)
changeset 4231 84b709f4103a
parent 4121 49eed675bafd
child 4237 5e3965aa4498
permissions -rw-r--r--
Fix SDKHooks load issue and reliance on gEntList ptr on CS:GO and Dota 2 on Windows.
faluco@1441
     1
/**
faluco@1441
     2
 * vim: set ts=4 :
faluco@1441
     3
 * =============================================================================
faluco@1441
     4
 * SourceMod Counter-Strike:Source Extension
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
faluco@1441
     6
 * =============================================================================
faluco@1441
     7
 *
faluco@1441
     8
 * This program is free software; you can redistribute it and/or modify it under
faluco@1441
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
faluco@1441
    10
 * Free Software Foundation.
faluco@1441
    11
 * 
faluco@1441
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
faluco@1441
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
faluco@1441
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
faluco@1441
    15
 * details.
faluco@1441
    16
 *
faluco@1441
    17
 * You should have received a copy of the GNU General Public License along with
faluco@1441
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
faluco@1441
    19
 *
faluco@1441
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
faluco@1441
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
faluco@1441
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
faluco@1441
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
faluco@1441
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
faluco@1441
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
faluco@1441
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
faluco@1441
    27
 * or <http://www.sourcemod.net/license.php>.
faluco@1441
    28
 *
faluco@1441
    29
 * Version: $Id$
faluco@1441
    30
 */
faluco@1441
    31
faluco@1441
    32
#include "extension.h"
faluco@1441
    33
#include "RegNatives.h"
rgr_02@3519
    34
#include "forwards.h"
rgr_02@3519
    35
#include "util_cstrike.h"
rgr_02@3313
    36
#include <server_class.h>
faluco@1441
    37
rgr_02@3519
    38
int g_iPriceOffset = -1;
rgr_02@3519
    39
faluco@1441
    40
#define REGISTER_NATIVE_ADDR(name, code) \
faluco@1441
    41
	void *addr; \
rgr_02@3313
    42
	if (!g_pGameConf->GetMemSig(name, &addr) || !addr) \
faluco@1441
    43
	{ \
faluco@1441
    44
		return pContext->ThrowNativeError("Failed to locate function"); \
faluco@1441
    45
	} \
faluco@1441
    46
	code; \
faluco@1441
    47
	g_RegNatives.Register(pWrapper);
faluco@1441
    48
faluco@1441
    49
inline CBaseEntity *GetCBaseEntity(int num, bool isplayer)
faluco@1441
    50
{
rgr_02@3519
    51
	edict_t *pEdict = gamehelpers->EdictOfIndex(num);
faluco@1441
    52
	if (!pEdict || pEdict->IsFree())
faluco@1441
    53
	{
faluco@1441
    54
		return NULL;
faluco@1441
    55
	}
faluco@1441
    56
dvander@1857
    57
	if (num > 0 && num <= playerhelpers->GetMaxClients())
faluco@1441
    58
	{
faluco@1441
    59
		IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(pEdict);
faluco@1441
    60
		if (!pPlayer || !pPlayer->IsConnected())
faluco@1441
    61
		{
faluco@1441
    62
			return NULL;
faluco@1441
    63
		}
dvander@1857
    64
	}
dvander@1857
    65
	else if (isplayer) 
dvander@1857
    66
	{
faluco@1441
    67
		return NULL;
faluco@1441
    68
	}
faluco@1441
    69
faluco@1441
    70
	IServerUnknown *pUnk;
faluco@1441
    71
	if ((pUnk=pEdict->GetUnknown()) == NULL)
faluco@1441
    72
	{
faluco@1441
    73
		return NULL;
faluco@1441
    74
	}
faluco@1441
    75
faluco@1441
    76
	return pUnk->GetBaseEntity();
faluco@1441
    77
}
faluco@1441
    78
rgr_02@3313
    79
bool UTIL_FindDataTable(SendTable *pTable, const char *name, sm_sendprop_info_t *info, unsigned int offset)
rgr_02@3313
    80
{
rgr_02@3313
    81
	const char *pname;
rgr_02@3313
    82
	int props = pTable->GetNumProps();
rgr_02@3313
    83
	SendProp *prop;
rgr_02@3313
    84
	SendTable *table;
rgr_02@3313
    85
rgr_02@3313
    86
	for (int i=0; i<props; i++)
rgr_02@3313
    87
	{
rgr_02@3313
    88
		prop = pTable->GetProp(i);
rgr_02@3313
    89
rgr_02@3313
    90
		if ((table = prop->GetDataTable()) != NULL)
rgr_02@3313
    91
		{
rgr_02@3313
    92
			pname = table->GetName();
rgr_02@3313
    93
			if (pname && strcmp(name, pname) == 0)
rgr_02@3313
    94
			{
rgr_02@3313
    95
				info->prop = prop;
rgr_02@3313
    96
				info->actual_offset = offset + info->prop->GetOffset();
rgr_02@3313
    97
				return true;
rgr_02@3313
    98
			}
rgr_02@3313
    99
rgr_02@3313
   100
			if (UTIL_FindDataTable(table, 
rgr_02@3313
   101
				name,
rgr_02@3313
   102
				info,
rgr_02@3313
   103
				offset + prop->GetOffset())
rgr_02@3313
   104
				)
rgr_02@3313
   105
			{
rgr_02@3313
   106
				return true;
rgr_02@3313
   107
			}
rgr_02@3313
   108
		}
rgr_02@3313
   109
	}
rgr_02@3313
   110
rgr_02@3313
   111
	return false;
rgr_02@3313
   112
}
rgr_02@3313
   113
rgr_02@3313
   114
//Taken From Sourcemod Core
rgr_02@3313
   115
unsigned int strncopy(char *dest, const char *src, size_t count)
rgr_02@3313
   116
{
rgr_02@3313
   117
	if (!count)
rgr_02@3313
   118
	{
rgr_02@3313
   119
		return 0;
rgr_02@3313
   120
	}
rgr_02@3313
   121
rgr_02@3313
   122
	char *start = dest;
rgr_02@3313
   123
	while ((*src) && (--count))
rgr_02@3313
   124
	{
rgr_02@3313
   125
		*dest++ = *src++;
rgr_02@3313
   126
	}
rgr_02@3313
   127
	*dest = '\0';
rgr_02@3313
   128
rgr_02@3313
   129
	return (dest - start);
rgr_02@3313
   130
}
rgr_02@3313
   131
faluco@1441
   132
static cell_t CS_RespawnPlayer(IPluginContext *pContext, const cell_t *params)
faluco@1441
   133
{
faluco@1441
   134
	static ICallWrapper *pWrapper = NULL;
faluco@1441
   135
	if (!pWrapper)
faluco@1441
   136
	{
faluco@1441
   137
		REGISTER_NATIVE_ADDR("RoundRespawn", 
faluco@1441
   138
			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, NULL, 0));
faluco@1441
   139
	}
faluco@1441
   140
faluco@1441
   141
	CBaseEntity *pEntity;
faluco@1441
   142
	if (!(pEntity=GetCBaseEntity(params[1], true)))
faluco@1441
   143
	{
faluco@1441
   144
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
faluco@1441
   145
	}
faluco@1441
   146
	pWrapper->Execute(&pEntity, NULL);
faluco@1441
   147
faluco@1441
   148
	return 1;
faluco@1441
   149
}
faluco@1441
   150
faluco@1441
   151
static cell_t CS_SwitchTeam(IPluginContext *pContext, const cell_t *params)
faluco@1441
   152
{
faluco@1441
   153
	static ICallWrapper *pWrapper = NULL;
faluco@1441
   154
	if (!pWrapper)
faluco@1441
   155
	{
faluco@1441
   156
		REGISTER_NATIVE_ADDR("SwitchTeam", 
faluco@1441
   157
			PassInfo pass[1]; \
faluco@1441
   158
			pass[0].flags = PASSFLAG_BYVAL; \
faluco@1441
   159
			pass[0].size = sizeof(int); \
faluco@1441
   160
			pass[0].type = PassType_Basic; \
faluco@1441
   161
			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 1))
faluco@1441
   162
	}
faluco@1441
   163
faluco@1441
   164
	CBaseEntity *pEntity;
faluco@1441
   165
	if (!(pEntity=GetCBaseEntity(params[1], true)))
faluco@1441
   166
	{
faluco@1441
   167
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
faluco@1441
   168
	}
faluco@1441
   169
faluco@1441
   170
	unsigned char vstk[sizeof(CBaseEntity *) + sizeof(int)];
faluco@1441
   171
	unsigned char *vptr = vstk;
faluco@1441
   172
faluco@1441
   173
	*(CBaseEntity **)vptr = pEntity;
faluco@1441
   174
	vptr += sizeof(CBaseEntity *);
faluco@1441
   175
	*(int *)vptr = params[2];
faluco@1441
   176
	pWrapper->Execute(vstk, NULL);
faluco@1441
   177
faluco@1441
   178
	return 1;
faluco@1441
   179
}
faluco@1441
   180
rgr_02@3313
   181
static cell_t CS_DropWeapon(IPluginContext *pContext, const cell_t *params)
rgr_02@3313
   182
{
rgr_02@3313
   183
	static ICallWrapper *pWrapper = NULL;
rgr_02@3313
   184
	if (!pWrapper)
rgr_02@3313
   185
	{
rgr_02@3313
   186
		REGISTER_NATIVE_ADDR("CSWeaponDrop",
rgr_02@3313
   187
			PassInfo pass[3]; \
rgr_02@3313
   188
			pass[0].flags = PASSFLAG_BYVAL; \
rgr_02@3313
   189
			pass[0].type  = PassType_Basic; \
rgr_02@3313
   190
			pass[0].size  = sizeof(CBaseEntity *); \
rgr_02@3313
   191
			pass[1].flags = PASSFLAG_BYVAL; \
rgr_02@3313
   192
			pass[1].type  = PassType_Basic; \
rgr_02@3313
   193
			pass[1].size  = sizeof(bool); \
rgr_02@3313
   194
			pass[2].flags = PASSFLAG_BYVAL; \
rgr_02@3313
   195
			pass[2].type  = PassType_Basic; \
rgr_02@3313
   196
			pass[2].size  = sizeof(bool); \
rgr_02@3313
   197
			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 3))
rgr_02@3313
   198
	}
rgr_02@3313
   199
rgr_02@3313
   200
	CBaseEntity *pEntity;
rgr_02@3313
   201
	if (!(pEntity = GetCBaseEntity(params[1], true)))
rgr_02@3313
   202
	{
rgr_02@3313
   203
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
rgr_02@3313
   204
	}
rgr_02@3313
   205
rgr_02@3313
   206
	CBaseEntity *pWeapon;
rgr_02@3313
   207
	if (!(pWeapon = GetCBaseEntity(params[2], false)))
rgr_02@3313
   208
	{
rgr_02@3313
   209
		return pContext->ThrowNativeError("Weapon index %d is not valid", params[2]);
rgr_02@3313
   210
	}
rgr_02@3313
   211
rgr_02@3313
   212
	//Psychonic is awesome for this
kyle@3634
   213
	sm_sendprop_info_t spi;
rgr_02@3313
   214
	IServerUnknown *pUnk = (IServerUnknown *)pWeapon;
rgr_02@3313
   215
	IServerNetworkable *pNet = pUnk->GetNetworkable();
rgr_02@3313
   216
kyle@3634
   217
	if (!UTIL_FindDataTable(pNet->GetServerClass()->m_pTable, "DT_WeaponCSBase", &spi, 0))
rgr_02@3313
   218
		return pContext->ThrowNativeError("Entity index %d is not a weapon", params[2]);
rgr_02@3313
   219
kyle@3634
   220
	if (!gamehelpers->FindSendPropInfo("CBaseCombatWeapon", "m_hOwnerEntity", &spi))
rgr_02@3313
   221
		return pContext->ThrowNativeError("Invalid entity index %d for weapon", params[2]);
rgr_02@3313
   222
kyle@3634
   223
	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pWeapon + spi.actual_offset);
skamonkey@3710
   224
	if (params[1] != hndl.GetEntryIndex() || hndl != ((IServerEntity *)pEntity)->GetRefEHandle())
rgr_02@3313
   225
		return pContext->ThrowNativeError("Weapon %d is not owned by client %d", params[2], params[1]);
rgr_02@3313
   226
rgr_02@3313
   227
	if (params[4] == 1 && g_pCSWeaponDropDetoured)
rgr_02@3313
   228
		g_pIgnoreCSWeaponDropDetour = true;
rgr_02@3313
   229
rgr_02@3313
   230
	unsigned char vstk[sizeof(CBaseEntity *) * 2 + sizeof(bool) * 2];
rgr_02@3313
   231
	unsigned char *vptr = vstk;
rgr_02@3313
   232
rgr_02@3313
   233
	// <psychonic> first one is always false. second is true to toss, false to just drop
rgr_02@3313
   234
	*(CBaseEntity **)vptr = pEntity;
rgr_02@3313
   235
	vptr += sizeof(CBaseEntity *);
rgr_02@3313
   236
	*(CBaseEntity **)vptr = pWeapon;
rgr_02@3313
   237
	vptr += sizeof(CBaseEntity *);
rgr_02@3313
   238
	*(bool *)vptr = false;
rgr_02@3313
   239
	vptr += sizeof(bool);
rgr_02@3313
   240
	*(bool *)vptr = (params[3]) ? true : false;
rgr_02@3313
   241
rgr_02@3313
   242
 	pWrapper->Execute(vstk, NULL);
rgr_02@3313
   243
rgr_02@3313
   244
	return 1;
rgr_02@3313
   245
}
rgr_02@3313
   246
rgr_02@3313
   247
static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
rgr_02@3313
   248
{
rgr_02@3313
   249
	if (g_pSDKTools == NULL)
rgr_02@3313
   250
	{
rgr_02@3313
   251
		smutils->LogError(myself, "SDKTools interface not found. TerminateRound native disabled.");
rgr_02@3313
   252
	}
rgr_02@3313
   253
	else if (g_pSDKTools->GetInterfaceVersion() < 2)
rgr_02@3313
   254
	{
rgr_02@3313
   255
		//<psychonic> THIS ISN'T DA LIMBO STICK. LOW IS BAD
rgr_02@3313
   256
		return pContext->ThrowNativeError("SDKTools interface is outdated. TerminateRound native disabled.");
rgr_02@3313
   257
	}
rgr_02@3313
   258
rgr_02@3313
   259
	static ICallWrapper *pWrapper = NULL;
rgr_02@3313
   260
rgr_02@3313
   261
	if (!pWrapper)
rgr_02@3313
   262
	{
rgr_02@3313
   263
		REGISTER_NATIVE_ADDR("TerminateRound",
rgr_02@3313
   264
			PassInfo pass[2]; \
rgr_02@3313
   265
			pass[0].flags = PASSFLAG_BYVAL; \
rgr_02@3313
   266
			pass[0].type = PassType_Basic; \
rgr_02@3313
   267
			pass[0].size = sizeof(float); \
rgr_02@3313
   268
			pass[1].flags = PASSFLAG_BYVAL; \
rgr_02@3313
   269
			pass[1].type = PassType_Basic; \
rgr_02@3313
   270
			pass[1].size = sizeof(int); \
rgr_02@3313
   271
			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2))
rgr_02@3313
   272
	}
rgr_02@3313
   273
rgr_02@3313
   274
	void *gamerules = g_pSDKTools->GetGameRules();
rgr_02@3313
   275
	if (gamerules == NULL)
rgr_02@3313
   276
	{
rgr_02@3313
   277
		return pContext->ThrowNativeError("GameRules not available. TerminateRound native disabled.");
rgr_02@3313
   278
	}
rgr_02@3313
   279
rgr_02@3313
   280
	if (params[3] == 1 && g_pTerminateRoundDetoured)
rgr_02@3313
   281
		g_pIgnoreTerminateDetour = true;
rgr_02@3313
   282
rgr_02@3313
   283
	unsigned char vstk[sizeof(void *) + sizeof(float)+ sizeof(int)];
rgr_02@3313
   284
	unsigned char *vptr = vstk;
rgr_02@3313
   285
rgr_02@3313
   286
	*(void **)vptr = gamerules;
rgr_02@3313
   287
	vptr += sizeof(void *);
rgr_02@3313
   288
	*(float *)vptr = sp_ctof(params[1]);
rgr_02@3313
   289
	vptr += sizeof(float);
rgr_02@3313
   290
	*(int*)vptr = params[2];
rgr_02@3313
   291
rgr_02@3313
   292
	pWrapper->Execute(vstk, NULL);
rgr_02@3313
   293
rgr_02@3313
   294
	return 1;
rgr_02@3313
   295
}
rgr_02@3313
   296
kyle@3702
   297
static cell_t CS_WeaponIDToAlias(IPluginContext *pContext, const cell_t *params)
kyle@3702
   298
{
drifter01620@3965
   299
	if (!IsValidWeaponID(params[1]))
drifter01620@3965
   300
		return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
drifter01620@3965
   301
kyle@3702
   302
	char *dest;
kyle@3702
   303
kyle@3702
   304
	pContext->LocalToString(params[2], &dest);
kyle@3702
   305
kyle@3702
   306
	const char *ret = WeaponIDToAlias(params[1]);
kyle@3702
   307
	
kyle@3702
   308
	if (ret == NULL)
kyle@3702
   309
	{
kyle@3702
   310
		return 0;
kyle@3702
   311
	}
kyle@3702
   312
	
kyle@3702
   313
	return strncopy(dest, ret, params[3]);
kyle@3702
   314
}
kyle@3702
   315
rgr_02@3313
   316
static cell_t CS_GetTranslatedWeaponAlias(IPluginContext *pContext, const cell_t *params)
rgr_02@3313
   317
{
rgr_02@3519
   318
	char *weapon;
rgr_02@3519
   319
	char *dest;
rgr_02@3313
   320
rgr_02@3313
   321
	pContext->LocalToString(params[2], &dest);
rgr_02@3313
   322
	pContext->LocalToString(params[1], &weapon);
rgr_02@3313
   323
rgr_02@3519
   324
	const char *ret = GetTranslatedWeaponAlias(weapon);
rgr_02@3313
   325
	strncopy(dest, ret, params[3]);
rgr_02@3313
   326
	
rgr_02@3313
   327
	return 1;
rgr_02@3313
   328
}
skamonkey@3405
   329
rgr_02@3324
   330
static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
rgr_02@3324
   331
{
drifter01620@3965
   332
	if (!IsValidWeaponID(params[2]))
drifter01620@3965
   333
		return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
drifter01620@3964
   334
drifter01620@3964
   335
	int id = GetRealWeaponID(params[2]);
drifter01620@3964
   336
rgr_02@3359
   337
	//Hard code return values for weapons that dont call GetWeaponPrice and always use default value.
rgr_02@3519
   338
#if SOURCE_ENGINE == SE_CSGO
rgr_02@3519
   339
	if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_KNIFE_GG)
drifter01620@3964
   340
		return 0;
rgr_02@3519
   341
#else
rgr_02@3519
   342
 	if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_SHIELD)
rgr_02@3359
   343
		return 0;
drifter01620@3964
   344
	else if (id == WEAPON_KEVLAR)
rgr_02@3359
   345
		return 650;
drifter01620@3964
   346
	else if (id == WEAPON_ASSAULTSUIT)
rgr_02@3359
   347
		return 1000;
drifter01620@3964
   348
#endif
drifter01620@3964
   349
	else if (id == WEAPON_NIGHTVISION)
rgr_02@3359
   350
		return 1250;
rgr_02@3519
   351
#if SOURCE_ENGINE == SE_CSGO
drifter01620@3964
   352
	else if (id == WEAPON_DEFUSER)
drifter01620@3964
   353
		return 400;
rgr_02@3519
   354
#endif
rgr_02@3359
   355
drifter01620@4016
   356
	void *info = GetWeaponInfo(id);
drifter01620@4016
   357
		
drifter01620@4016
   358
	if (!info)
drifter01620@4016
   359
	{
drifter01620@4016
   360
		return pContext->ThrowNativeError("Failed to get weaponinfo");
drifter01620@4016
   361
	}
drifter01620@4016
   362
drifter01620@4016
   363
#if SOURCE_ENGINE == SE_CSGO
drifter01620@4016
   364
	static ICallWrapper *pWrapper = NULL;
drifter01620@4016
   365
drifter01620@4016
   366
	if (!pWrapper)
drifter01620@4016
   367
	{
drifter01620@4016
   368
		REGISTER_NATIVE_ADDR("GetAttributeInt",
drifter01620@4016
   369
		PassInfo pass[2]; \
drifter01620@4016
   370
		PassInfo ret; \
drifter01620@4016
   371
		pass[0].flags = PASSFLAG_BYVAL; \
drifter01620@4016
   372
		pass[0].type = PassType_Basic; \
drifter01620@4016
   373
		pass[0].size = sizeof(char *); \
drifter01620@4016
   374
		pass[1].flags = PASSFLAG_BYVAL; \
drifter01620@4016
   375
		pass[1].type = PassType_Basic; \
drifter01620@4016
   376
		pass[1].size = sizeof(CEconItemView *); \
drifter01620@4016
   377
		ret.flags = PASSFLAG_BYVAL; \
drifter01620@4016
   378
		ret.type = PassType_Basic; \
drifter01620@4016
   379
		ret.size = sizeof(int); \
drifter01620@4016
   380
		pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &ret, pass, 2))
drifter01620@4016
   381
	}
drifter01620@4016
   382
drifter01620@4016
   383
	unsigned char vstk[sizeof(void *) * 2 + sizeof(char *)];
drifter01620@4016
   384
	unsigned char *vptr = vstk;
drifter01620@4016
   385
drifter01620@4016
   386
	*(void **)vptr = info;
drifter01620@4016
   387
	vptr += sizeof(void *);
skamonkey@4019
   388
	*(const char **)vptr = "in_game_price";
skamonkey@4019
   389
	vptr += sizeof(const char **);
drifter01620@4016
   390
	*(CEconItemView **)vptr = NULL;
drifter01620@4016
   391
drifter01620@4016
   392
	int price = 0;
drifter01620@4016
   393
 	pWrapper->Execute(vstk, &price);
drifter01620@4016
   394
#else
rgr_02@3519
   395
	if (g_iPriceOffset == -1)
rgr_02@3324
   396
	{
rgr_02@3519
   397
		if (!g_pGameConf->GetOffset("WeaponPrice", &g_iPriceOffset))
rgr_02@3324
   398
		{
rgr_02@3519
   399
			g_iPriceOffset = -1;
rgr_02@3324
   400
			return pContext->ThrowNativeError("Failed to get WeaponPrice offset");
rgr_02@3324
   401
		}
rgr_02@3324
   402
	}
rgr_02@3324
   403
drifter01620@4016
   404
	int price = *(int *)((intptr_t)info + g_iPriceOffset);
drifter01620@4016
   405
#endif
drifter01620@4016
   406
rgr_02@3324
   407
	CBaseEntity *pEntity;
rgr_02@3324
   408
	if (!(pEntity = GetCBaseEntity(params[1], true)))
rgr_02@3324
   409
	{
rgr_02@3324
   410
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
rgr_02@3324
   411
	}
rgr_02@3324
   412
rgr_02@3324
   413
	if (params[3] || weaponNameOffset == -1)
rgr_02@3324
   414
		return price;
rgr_02@3324
   415
rgr_02@3324
   416
	const char *weapon_name = (const char *)((intptr_t)info + weaponNameOffset);
rgr_02@3324
   417
rgr_02@3324
   418
	return CallPriceForward(params[1], weapon_name, price);
rgr_02@3324
   419
}
rgr_02@3313
   420
skamonkey@3405
   421
static cell_t CS_GetClientClanTag(IPluginContext *pContext, const cell_t *params)
skamonkey@3405
   422
{
skamonkey@3405
   423
	static void *addr;
skamonkey@3405
   424
	if (!addr)
skamonkey@3405
   425
	{
skamonkey@3405
   426
		if (!g_pGameConf->GetMemSig("SetClanTag", &addr) || !addr)
skamonkey@3405
   427
		{
skamonkey@3405
   428
			return pContext->ThrowNativeError("Failed to locate function");
skamonkey@3405
   429
		}
skamonkey@3405
   430
	}
skamonkey@3405
   431
skamonkey@3405
   432
	CBaseEntity *pEntity;
skamonkey@3405
   433
	if (!(pEntity = GetCBaseEntity(params[1], true)))
skamonkey@3405
   434
	{
skamonkey@3405
   435
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
skamonkey@3405
   436
	}
skamonkey@3405
   437
skamonkey@3405
   438
	static int tagOffsetOffset = -1;
skamonkey@3405
   439
	static int tagOffset;
skamonkey@3405
   440
skamonkey@3405
   441
	if (tagOffsetOffset == -1)
skamonkey@3405
   442
	{
skamonkey@3405
   443
		if (!g_pGameConf->GetOffset("ClanTagOffset", &tagOffsetOffset))
skamonkey@3405
   444
		{
skamonkey@3405
   445
			tagOffsetOffset = -1;
skamonkey@3405
   446
			return pContext->ThrowNativeError("Unable to find ClanTagOffset gamedata");
skamonkey@3405
   447
		}
skamonkey@3405
   448
skamonkey@3405
   449
		tagOffset = *(int *)((intptr_t)addr + tagOffsetOffset);
skamonkey@3405
   450
	}
skamonkey@3405
   451
skamonkey@3405
   452
	size_t len;
skamonkey@3405
   453
skamonkey@3405
   454
	const char *src = (char *)((intptr_t)pEntity + tagOffset);
skamonkey@3405
   455
	pContext->StringToLocalUTF8(params[2], params[3], src, &len);
skamonkey@3405
   456
skamonkey@3405
   457
	return len;
skamonkey@3405
   458
}
skamonkey@3405
   459
skamonkey@3405
   460
static cell_t CS_SetClientClanTag(IPluginContext *pContext, const cell_t *params)
skamonkey@3405
   461
{
skamonkey@3405
   462
	static ICallWrapper *pWrapper = NULL;
skamonkey@3405
   463
skamonkey@3405
   464
	if (!pWrapper)
skamonkey@3405
   465
	{
skamonkey@3405
   466
		REGISTER_NATIVE_ADDR("SetClanTag",
skamonkey@3405
   467
			PassInfo pass[2]; \
skamonkey@3405
   468
			pass[0].flags = PASSFLAG_BYVAL; \
skamonkey@3405
   469
			pass[0].type  = PassType_Basic; \
skamonkey@3405
   470
			pass[0].size  = sizeof(CBaseEntity *); \
skamonkey@3405
   471
			pass[1].flags = PASSFLAG_BYVAL; \
skamonkey@3405
   472
			pass[1].type  = PassType_Basic; \
skamonkey@3405
   473
			pass[1].size  = sizeof(char *); \
skamonkey@3405
   474
			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2))
skamonkey@3405
   475
	}
skamonkey@3405
   476
skamonkey@3405
   477
	CBaseEntity *pEntity;
skamonkey@3405
   478
	if (!(pEntity = GetCBaseEntity(params[1], true)))
skamonkey@3405
   479
	{
skamonkey@3405
   480
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
skamonkey@3405
   481
	}
skamonkey@3405
   482
skamonkey@3405
   483
	char *szNewTag;
skamonkey@3405
   484
	pContext->LocalToString(params[2], &szNewTag);
skamonkey@3405
   485
skamonkey@3405
   486
	unsigned char vstk[sizeof(CBaseEntity *) + sizeof(char *)];
skamonkey@3405
   487
	unsigned char *vptr = vstk;
skamonkey@3405
   488
skamonkey@3405
   489
	*(CBaseEntity **)vptr = pEntity;
skamonkey@3405
   490
	vptr += sizeof(CBaseEntity *);
skamonkey@3405
   491
	*(char **)vptr = szNewTag;
skamonkey@3405
   492
skamonkey@3405
   493
	pWrapper->Execute(vstk, NULL);
skamonkey@3405
   494
skamonkey@3405
   495
	return 1;
rgr_02@3519
   496
}
rgr_02@3519
   497
rgr_02@3519
   498
static cell_t CS_AliasToWeaponID(IPluginContext *pContext, const cell_t *params)
rgr_02@3519
   499
{
rgr_02@3519
   500
	char *weapon;
rgr_02@3519
   501
rgr_02@3519
   502
	pContext->LocalToString(params[1], &weapon);
rgr_02@3519
   503
drifter01620@4016
   504
#if SOURCE_ENGINE == SE_CSGO
drifter01620@4016
   505
	if (strstr(weapon, "usp_silencer") != NULL)
drifter01620@4016
   506
	{
drifter01620@4016
   507
		return SMCSWeapon_HKP2000;
drifter01620@4016
   508
	}
drifter01620@4016
   509
#endif
drifter01620@4016
   510
drifter01620@3965
   511
	int id = GetFakeWeaponID(AliasToWeaponID(weapon));
drifter01620@3965
   512
drifter01620@3965
   513
	if (!IsValidWeaponID(id))
drifter01620@3965
   514
		return SMCSWeapon_NONE;
drifter01620@3965
   515
drifter01620@3965
   516
	return id;
skamonkey@3405
   517
}
skamonkey@3405
   518
rgr_02@3530
   519
static cell_t CS_SetTeamScore(IPluginContext *pContext, const cell_t *params)
rgr_02@3530
   520
{
rgr_02@3530
   521
	if (g_pSDKTools == NULL)
rgr_02@3530
   522
	{
rgr_02@3530
   523
		smutils->LogError(myself, "SDKTools interface not found. CS_SetTeamScore native disabled.");
rgr_02@3530
   524
	}
rgr_02@3530
   525
	else if (g_pSDKTools->GetInterfaceVersion() < 2)
rgr_02@3530
   526
	{
rgr_02@3530
   527
		//<psychonic> THIS ISN'T DA LIMBO STICK. LOW IS BAD
rgr_02@3530
   528
		return pContext->ThrowNativeError("SDKTools interface is outdated. CS_SetTeamScore native disabled.");
rgr_02@3530
   529
	}
rgr_02@3530
   530
rgr_02@3530
   531
	static void *addr;
rgr_02@3530
   532
	if (!addr)
rgr_02@3530
   533
	{
rgr_02@3530
   534
		if (!g_pGameConf->GetMemSig("CheckWinLimit", &addr) || !addr)
rgr_02@3530
   535
		{
rgr_02@3530
   536
			return pContext->ThrowNativeError("Failed to locate CheckWinLimit function");
rgr_02@3530
   537
		}
rgr_02@3530
   538
	}
rgr_02@3530
   539
rgr_02@3530
   540
	static int ctTeamOffsetOffset = -1;
rgr_02@3530
   541
	static int ctTeamOffset;
rgr_02@3530
   542
rgr_02@3530
   543
	static int tTeamOffsetOffset = -1;
rgr_02@3530
   544
	static int tTeamOffset;
rgr_02@3530
   545
rgr_02@3530
   546
	if (ctTeamOffsetOffset == -1)
rgr_02@3530
   547
	{
rgr_02@3530
   548
		if (!g_pGameConf->GetOffset("CTTeamScoreOffset", &ctTeamOffsetOffset))
rgr_02@3530
   549
		{
rgr_02@3530
   550
			ctTeamOffsetOffset = -1;
rgr_02@3530
   551
			return pContext->ThrowNativeError("Unable to find CTTeamOffset gamedata");
rgr_02@3530
   552
		}
rgr_02@3530
   553
rgr_02@3530
   554
		ctTeamOffset = *(int *)((intptr_t)addr + ctTeamOffsetOffset);
rgr_02@3530
   555
	}
rgr_02@3530
   556
rgr_02@3530
   557
	if (tTeamOffsetOffset == -1)
rgr_02@3530
   558
	{
rgr_02@3530
   559
		if (!g_pGameConf->GetOffset("TTeamScoreOffset", &tTeamOffsetOffset))
rgr_02@3530
   560
		{
rgr_02@3530
   561
			tTeamOffsetOffset = -1;
rgr_02@3530
   562
			return pContext->ThrowNativeError("Unable to find CTTeamOffset gamedata");
rgr_02@3530
   563
		}
rgr_02@3530
   564
rgr_02@3530
   565
		tTeamOffset = *(int *)((intptr_t)addr + tTeamOffsetOffset);
rgr_02@3530
   566
	}
rgr_02@3530
   567
rgr_02@3530
   568
	void *gamerules = g_pSDKTools->GetGameRules();
rgr_02@3530
   569
	if (gamerules == NULL)
rgr_02@3530
   570
	{
rgr_02@3530
   571
		return pContext->ThrowNativeError("GameRules not available. CS_SetTeamScore native disabled.");
rgr_02@3530
   572
	}
rgr_02@3530
   573
rgr_02@3530
   574
	if (params[1] == 3)
rgr_02@3530
   575
	{
rgr_02@3530
   576
		*(int16_t *)((intptr_t)gamerules+ctTeamOffset) = params[2];
rgr_02@3530
   577
		return 1;
rgr_02@3530
   578
	}
rgr_02@3530
   579
	else if (params[1] == 2)
rgr_02@3530
   580
	{
rgr_02@3530
   581
		*(int16_t *)((intptr_t)gamerules+tTeamOffset) = params[2];
rgr_02@3530
   582
		return 1;
rgr_02@3530
   583
	}
rgr_02@3530
   584
	return pContext->ThrowNativeError("Invalid team index passed (%i).", params[1]);
rgr_02@3530
   585
}
rgr_02@3530
   586
rgr_02@3530
   587
static cell_t CS_GetTeamScore(IPluginContext *pContext, const cell_t *params)
rgr_02@3530
   588
{
rgr_02@3530
   589
	if (g_pSDKTools == NULL)
rgr_02@3530
   590
	{
rgr_02@3530
   591
		smutils->LogError(myself, "SDKTools interface not found. CS_GetTeamScore native disabled.");
rgr_02@3530
   592
	}
rgr_02@3530
   593
	else if (g_pSDKTools->GetInterfaceVersion() < 2)
rgr_02@3530
   594
	{
rgr_02@3530
   595
		//<psychonic> THIS ISN'T DA LIMBO STICK. LOW IS BAD
rgr_02@3530
   596
		return pContext->ThrowNativeError("SDKTools interface is outdated. CS_GetTeamScore native disabled.");
rgr_02@3530
   597
	}
rgr_02@3530
   598
rgr_02@3530
   599
	static void *addr;
rgr_02@3530
   600
	if (!addr)
rgr_02@3530
   601
	{
rgr_02@3530
   602
		if (!g_pGameConf->GetMemSig("CheckWinLimit", &addr) || !addr)
rgr_02@3530
   603
		{
rgr_02@3530
   604
			return pContext->ThrowNativeError("Failed to locate CheckWinLimit function");
rgr_02@3530
   605
		}
rgr_02@3530
   606
	}
rgr_02@3530
   607
rgr_02@3530
   608
	static int ctTeamOffsetOffset = -1;
rgr_02@3530
   609
	static int ctTeamOffset;
rgr_02@3530
   610
rgr_02@3530
   611
	static int tTeamOffsetOffset = -1;
rgr_02@3530
   612
	static int tTeamOffset;
rgr_02@3530
   613
rgr_02@3530
   614
	if (ctTeamOffsetOffset == -1)
rgr_02@3530
   615
	{
rgr_02@3530
   616
		if (!g_pGameConf->GetOffset("CTTeamScoreOffset", &ctTeamOffsetOffset))
rgr_02@3530
   617
		{
rgr_02@3530
   618
			ctTeamOffsetOffset = -1;
rgr_02@3530
   619
			return pContext->ThrowNativeError("Unable to find CTTeamOffset gamedata");
rgr_02@3530
   620
		}
rgr_02@3530
   621
rgr_02@3530
   622
		ctTeamOffset = *(int *)((intptr_t)addr + ctTeamOffsetOffset);
rgr_02@3530
   623
	}
rgr_02@3530
   624
rgr_02@3530
   625
	if (tTeamOffsetOffset == -1)
rgr_02@3530
   626
	{
rgr_02@3530
   627
		if (!g_pGameConf->GetOffset("TTeamScoreOffset", &tTeamOffsetOffset))
rgr_02@3530
   628
		{
rgr_02@3530
   629
			tTeamOffsetOffset = -1;
rgr_02@3530
   630
			return pContext->ThrowNativeError("Unable to find CTTeamOffset gamedata");
rgr_02@3530
   631
		}
rgr_02@3530
   632
rgr_02@3530
   633
		tTeamOffset = *(int *)((intptr_t)addr + tTeamOffsetOffset);
rgr_02@3530
   634
	}
rgr_02@3530
   635
rgr_02@3530
   636
	void *gamerules = g_pSDKTools->GetGameRules();
rgr_02@3530
   637
	if (gamerules == NULL)
rgr_02@3530
   638
	{
rgr_02@3530
   639
		return pContext->ThrowNativeError("GameRules not available. CS_GetTeamScore native disabled.");
rgr_02@3530
   640
	}
rgr_02@3530
   641
rgr_02@3530
   642
	if (params[1] == 3)
rgr_02@3530
   643
	{
rgr_02@3530
   644
		return *(int16_t *)((intptr_t)gamerules+ctTeamOffset);
rgr_02@3530
   645
	}
rgr_02@3530
   646
	else if (params[1] == 2)
rgr_02@3530
   647
	{
rgr_02@3530
   648
		return *(int16_t *)((intptr_t)gamerules+tTeamOffset);
rgr_02@3530
   649
	}
rgr_02@3530
   650
	return pContext->ThrowNativeError("Invalid team index passed (%i).", params[1]);
rgr_02@3530
   651
}
rgr_02@3530
   652
drifter01620@3965
   653
static cell_t CS_IsValidWeaponID(IPluginContext *pContext, const cell_t *params)
drifter01620@3965
   654
{
drifter01620@3965
   655
	return IsValidWeaponID(params[1]) ? 1 : 0;
drifter01620@3965
   656
}
drifter01620@3965
   657
skamonkey@3706
   658
template <typename T>
skamonkey@3706
   659
static inline T *GetPlayerVarAddressOrError(const char *pszGamedataName, IPluginContext *pContext, CBaseEntity *pPlayerEntity)
rgr_02@3530
   660
{
skamonkey@3706
   661
	char szBaseName[128];
skamonkey@3706
   662
	g_pSM->Format(szBaseName, sizeof(szBaseName), "%sBase", pszGamedataName);
skamonkey@3706
   663
skamonkey@3706
   664
	const char *pszBaseVar = g_pGameConf->GetKeyValue(szBaseName);
skamonkey@3706
   665
	if (pszBaseVar == NULL)
skamonkey@3706
   666
	{
skamonkey@3706
   667
		pContext->ThrowNativeError("Failed to locate %s key in gamedata", szBaseName);
skamonkey@3706
   668
		return NULL;
skamonkey@3706
   669
	}
skamonkey@3706
   670
skamonkey@3706
   671
	int interimOffset = 0;
skamonkey@3706
   672
	sm_sendprop_info_t info;
skamonkey@3706
   673
	if (gamehelpers->FindSendPropInfo("CCSPlayer", pszBaseVar, &info))
rgr_02@3530
   674
	{
skamonkey@3706
   675
		interimOffset = info.actual_offset;
skamonkey@3706
   676
	}
skamonkey@3706
   677
	else
skamonkey@3706
   678
	{
skamonkey@3706
   679
		datamap_t *pMap = gamehelpers->GetDataMap(pPlayerEntity);
skamonkey@3706
   680
		typedescription_t *td = gamehelpers->FindInDataMap(pMap, pszBaseVar);
skamonkey@3706
   681
		if (td)
rgr_02@3530
   682
		{
skamonkey@3706
   683
#if SOURCE_ENGINE >= SE_LEFT4DEAD
skamonkey@3706
   684
			interimOffset = td->fieldOffset;
skamonkey@3706
   685
#else
skamonkey@3706
   686
			interimOffset = td->fieldOffset[TD_OFFSET_NORMAL];
skamonkey@3706
   687
#endif
rgr_02@3530
   688
		}
rgr_02@3530
   689
	}
rgr_02@3530
   690
skamonkey@3706
   691
	if (interimOffset == 0)
skamonkey@3706
   692
	{
skamonkey@3706
   693
		pContext->ThrowNativeError("Failed to find property \"%s\" on player.", pszBaseVar);
skamonkey@3706
   694
		return NULL;
skamonkey@3706
   695
	}
skamonkey@3706
   696
		
skamonkey@3706
   697
skamonkey@3706
   698
	int tempOffset;
skamonkey@3706
   699
	if (!g_pGameConf->GetOffset(pszGamedataName, &tempOffset))
skamonkey@3706
   700
	{
skamonkey@3706
   701
		pContext->ThrowNativeError("Failed to locate %s offset in gamedata", pszGamedataName);
skamonkey@3706
   702
		return NULL;
skamonkey@3706
   703
	}
skamonkey@3706
   704
skamonkey@3706
   705
	return (T *)((intptr_t)pPlayerEntity + interimOffset + tempOffset);
skamonkey@3706
   706
}
skamonkey@3706
   707
skamonkey@3706
   708
template <typename T>
skamonkey@3706
   709
static inline cell_t GetPlayerVar(IPluginContext *pContext, const cell_t *params, const char *varName)
skamonkey@3706
   710
{
skamonkey@3706
   711
	CBaseEntity *pPlayer = GetCBaseEntity(params[1], true);
skamonkey@3706
   712
	if (!pPlayer)
rgr_02@3530
   713
	{
rgr_02@3530
   714
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
rgr_02@3530
   715
	}
rgr_02@3530
   716
skamonkey@3706
   717
	T *pVar = GetPlayerVarAddressOrError<T>(varName, pContext, pPlayer);
skamonkey@3706
   718
	if (pVar)
skamonkey@3706
   719
	{	
skamonkey@3706
   720
		return (cell_t)*pVar;
rgr_02@3530
   721
	}
rgr_02@3530
   722
skamonkey@3706
   723
	return 0;
skamonkey@3706
   724
}
skamonkey@3706
   725
skamonkey@3706
   726
template <typename T>
skamonkey@3706
   727
static inline cell_t SetPlayerVar(IPluginContext *pContext, const cell_t *params, const char *varName)
skamonkey@3706
   728
{
skamonkey@3706
   729
	CBaseEntity *pPlayer = GetCBaseEntity(params[1], true);
skamonkey@3706
   730
	if (!pPlayer)
skamonkey@3706
   731
	{
skamonkey@3706
   732
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
skamonkey@3706
   733
	}
rgr_02@3530
   734
skamonkey@3706
   735
	T *pVar = GetPlayerVarAddressOrError<T>(varName, pContext, pPlayer);
skamonkey@3706
   736
	if (pVar)
skamonkey@3706
   737
	{
skamonkey@3706
   738
		*pVar = (T)params[2];
skamonkey@3706
   739
	}
skamonkey@3706
   740
skamonkey@3706
   741
	return 0;
skamonkey@3706
   742
}
skamonkey@3706
   743
skamonkey@3706
   744
static cell_t CS_SetMVPCount(IPluginContext *pContext, const cell_t *params)
skamonkey@3706
   745
{
skamonkey@3706
   746
	return SetPlayerVar<int>(pContext, params, "MVPs");
rgr_02@3530
   747
}
rgr_02@3530
   748
rgr_02@3530
   749
static cell_t CS_GetMVPCount(IPluginContext *pContext, const cell_t *params)
rgr_02@3530
   750
{
skamonkey@3706
   751
	return GetPlayerVar<int>(pContext, params, "MVPs");
skamonkey@3706
   752
}
rgr_02@3530
   753
skamonkey@3706
   754
static cell_t CS_SetClientContributionScore(IPluginContext *pContext, const cell_t *params)
skamonkey@3706
   755
{
skamonkey@3706
   756
#if SOURCE_ENGINE == SE_CSGO
skamonkey@3706
   757
	return SetPlayerVar<int>(pContext, params, "CScore");
skamonkey@3706
   758
#else
skamonkey@3706
   759
	return pContext->ThrowNativeError("SetClientContributionScore is not supported on this game");
skamonkey@3706
   760
#endif
skamonkey@3706
   761
}
rgr_02@3530
   762
skamonkey@3706
   763
static cell_t CS_GetClientContributionScore(IPluginContext *pContext, const cell_t *params)
skamonkey@3706
   764
{
skamonkey@3706
   765
#if SOURCE_ENGINE == SE_CSGO
skamonkey@3706
   766
	return GetPlayerVar<int>(pContext, params, "CScore");
skamonkey@3706
   767
#else
skamonkey@3706
   768
	return pContext->ThrowNativeError("GetClientContributionScore is not supported on this game");
skamonkey@3706
   769
#endif
skamonkey@3706
   770
}
rgr_02@3530
   771
skamonkey@3706
   772
static cell_t CS_SetClientAssists(IPluginContext *pContext, const cell_t *params)
skamonkey@3706
   773
{
skamonkey@3706
   774
#if SOURCE_ENGINE == SE_CSGO
skamonkey@3706
   775
	return SetPlayerVar<int>(pContext, params, "Assists");
skamonkey@3706
   776
#else
skamonkey@3706
   777
	return pContext->ThrowNativeError("SetClientAssists is not supported on this game");
skamonkey@3706
   778
#endif
skamonkey@3706
   779
}
rgr_02@3530
   780
skamonkey@3706
   781
static cell_t CS_GetClientAssists(IPluginContext *pContext, const cell_t *params)
skamonkey@3706
   782
{
skamonkey@3706
   783
#if SOURCE_ENGINE == SE_CSGO
skamonkey@3706
   784
	return GetPlayerVar<int>(pContext, params, "Assists");
skamonkey@3706
   785
#else
skamonkey@3706
   786
	return pContext->ThrowNativeError("GetClientAssists is not supported on this game");
skamonkey@3706
   787
#endif
rgr_02@3530
   788
}
rgr_02@3530
   789
drifter01620@4121
   790
static cell_t CS_UpdateClientModel(IPluginContext *pContext, const cell_t *params)
drifter01620@4121
   791
{
drifter01620@4121
   792
	static ICallWrapper *pWrapper = NULL;
drifter01620@4121
   793
	if (!pWrapper)
drifter01620@4121
   794
	{
drifter01620@4121
   795
		REGISTER_NATIVE_ADDR("SetModelFromClass", 
drifter01620@4121
   796
			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, NULL, 0));
drifter01620@4121
   797
	}
drifter01620@4121
   798
drifter01620@4121
   799
	CBaseEntity *pEntity;
drifter01620@4121
   800
	if (!(pEntity=GetCBaseEntity(params[1], true)))
drifter01620@4121
   801
	{
drifter01620@4121
   802
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
drifter01620@4121
   803
	}
drifter01620@4121
   804
drifter01620@4121
   805
	pWrapper->Execute(&pEntity, NULL);
drifter01620@4121
   806
drifter01620@4121
   807
	return 1;
drifter01620@4121
   808
}
faluco@1441
   809
sp_nativeinfo_t g_CSNatives[] = 
faluco@1441
   810
{
faluco@1441
   811
	{"CS_RespawnPlayer",			CS_RespawnPlayer}, 
rgr_02@3313
   812
	{"CS_SwitchTeam",				CS_SwitchTeam},
rgr_02@3313
   813
	{"CS_DropWeapon",				CS_DropWeapon},
rgr_02@3313
   814
	{"CS_TerminateRound",			CS_TerminateRound},
rgr_02@3313
   815
	{"CS_GetTranslatedWeaponAlias",	CS_GetTranslatedWeaponAlias},
rgr_02@3324
   816
	{"CS_GetWeaponPrice",			CS_GetWeaponPrice},
skamonkey@3405
   817
	{"CS_GetClientClanTag",			CS_GetClientClanTag},
skamonkey@3405
   818
	{"CS_SetClientClanTag",			CS_SetClientClanTag},
rgr_02@3519
   819
	{"CS_AliasToWeaponID",			CS_AliasToWeaponID},
rgr_02@3530
   820
	{"CS_GetTeamScore",				CS_GetTeamScore},
rgr_02@3530
   821
	{"CS_SetTeamScore",				CS_SetTeamScore},
rgr_02@3530
   822
	{"CS_GetMVPCount",				CS_GetMVPCount},
rgr_02@3530
   823
	{"CS_SetMVPCount",				CS_SetMVPCount},
kyle@3702
   824
	{"CS_WeaponIDToAlias",			CS_WeaponIDToAlias},
skamonkey@3706
   825
	{"CS_GetClientContributionScore",	CS_GetClientContributionScore},
skamonkey@3706
   826
	{"CS_SetClientContributionScore",	CS_SetClientContributionScore},
skamonkey@3706
   827
	{"CS_GetClientAssists",			CS_GetClientAssists},
skamonkey@3706
   828
	{"CS_SetClientAssists",			CS_SetClientAssists},
drifter01620@4121
   829
	{"CS_UpdateClientModel",		CS_UpdateClientModel},
drifter01620@3965
   830
	{"CS_IsValidWeaponID",			CS_IsValidWeaponID},
faluco@1441
   831
	{NULL,							NULL}
faluco@1441
   832
};
dvander@1692
   833