extensions/tf2/natives.cpp
author Ruben Gonzalez <drifter01620@gmail.com>
Thu May 22 09:49:27 2014 -0400 (2014-05-22)
changeset 4378 568f4497ef4a
parent 4316 c0ffa3405ecd
permissions -rw-r--r--
Update CS:GO team score gamedata.
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Team Fortress 2 Extension
     5  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #include "extension.h"
    33 #include "util.h"
    34 #include "time.h"
    35 #include "RegNatives.h"
    36 
    37 // native TF2_MakeBleed(client, attacker, Float:duration)
    38 cell_t TF2_MakeBleed(IPluginContext *pContext, const cell_t *params)
    39 {
    40 	static ICallWrapper *pWrapper = NULL;
    41 
    42 	// CTFPlayerShared::MakeBleed(CTFPlayer*, CTFWeaponBase*, float, int=4)
    43 	if(!pWrapper)
    44 	{
    45 		REGISTER_NATIVE_ADDR("MakeBleed",
    46 			PassInfo pass[4]; \
    47 			pass[0].flags = PASSFLAG_BYVAL; \
    48 			pass[0].size = sizeof(CBaseEntity *); \
    49 			pass[0].type = PassType_Basic; \
    50 			pass[1].flags = PASSFLAG_BYVAL; \
    51 			pass[1].size = sizeof(CBaseEntity *); \
    52 			pass[1].type = PassType_Basic; \
    53 			pass[2].flags = PASSFLAG_BYVAL; \
    54 			pass[2].size = sizeof(float); \
    55 			pass[2].type = PassType_Basic; \
    56 			pass[3].flags = PASSFLAG_BYVAL; \
    57 			pass[3].size = sizeof(int); \
    58 			pass[3].type = PassType_Basic; \
    59 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 4))
    60 	}
    61 
    62 	CBaseEntity *pEntity;
    63 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
    64 	{
    65 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
    66 	}
    67 
    68 	CBaseEntity *pAttacker;
    69 	if (!(pAttacker = UTIL_GetCBaseEntity(params[2], true)))
    70 	{
    71 		return pContext->ThrowNativeError("Client index %d is not valid", params[2]);
    72 	}
    73 
    74 	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
    75 
    76 	unsigned char vstk[sizeof(void *) + 2*sizeof(CBaseEntity *) + sizeof(float)];
    77 	unsigned char *vptr = vstk;
    78 
    79 	*(void **)vptr = obj;
    80 	vptr += sizeof(void *);
    81 	*(CBaseEntity **)vptr = pAttacker;
    82 	vptr += sizeof(CBaseEntity *);
    83 	*(CBaseEntity **)vptr = NULL;
    84 	vptr += sizeof(CBaseEntity *);
    85 	*(float *)vptr = sp_ctof(params[3]);
    86 	vptr += sizeof(float);
    87 	*(int *)vptr = 4;
    88 
    89 	pWrapper->Execute(vstk, NULL);
    90 
    91 	return 1;
    92 }
    93 
    94 // native TF2_Burn(client, target)
    95 cell_t TF2_Burn(IPluginContext *pContext, const cell_t *params)
    96 {
    97 	static ICallWrapper *pWrapper = NULL;
    98 
    99 	// CTFPlayerShared::Burn(CTFPlayer*, CTFWeaponBase*)
   100 	if (!pWrapper)
   101 	{
   102 		REGISTER_NATIVE_ADDR("Burn", 
   103 			PassInfo pass[3]; \
   104 			pass[0].flags = PASSFLAG_BYVAL; \
   105 			pass[0].size = sizeof(CBaseEntity *); \
   106 			pass[0].type = PassType_Basic; \
   107 			pass[1].flags = PASSFLAG_BYVAL; \
   108 			pass[1].size = sizeof(CBaseEntity *); \
   109 			pass[1].type = PassType_Basic; \
   110 			pass[2].flags = PASSFLAG_BYVAL; \
   111 			pass[2].size = sizeof(float); \
   112 			pass[2].type = PassType_Basic; \
   113 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 3))
   114 	}
   115 
   116 	CBaseEntity *pEntity;
   117 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   118 	{
   119 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   120 	}
   121 
   122 	CBaseEntity *pTarget;
   123 	if (!(pTarget = UTIL_GetCBaseEntity(params[2], true)))
   124 	{
   125 		return pContext->ThrowNativeError("Client index %d is not valid", params[2]);
   126 	}
   127 
   128 	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
   129 
   130 	unsigned char vstk[sizeof(void *) + 2*sizeof(CBaseEntity *)];
   131 	unsigned char *vptr = vstk;
   132 
   133 	*(void **)vptr = obj;
   134 	vptr += sizeof(void *);
   135 	*(CBaseEntity **)vptr = pTarget;
   136 	vptr += sizeof(CBaseEntity *);
   137 	*(CBaseEntity **)vptr = NULL;
   138 	vptr += sizeof(CBaseEntity *);
   139 	*(float *)vptr = -1.0f;
   140 
   141 	pWrapper->Execute(vstk, NULL);
   142 
   143 	return 1;
   144 }
   145 
   146 // native TF2_Invuln(client, bool:enabled)
   147 cell_t TF2_Invuln(IPluginContext *pContext, const cell_t *params)
   148 {
   149 	return pContext->ThrowNativeError("TF2_SetPlayerInvuln is no longer available");
   150 }
   151 
   152 cell_t TF2_Disguise(IPluginContext *pContext, const cell_t *params)
   153 {
   154 	static ICallWrapper *pWrapper = NULL;
   155 
   156 	//CTFPlayerShared::Disguise(int, int, CTFPlayer *)
   157 	if (!pWrapper)
   158 	{
   159 		REGISTER_NATIVE_ADDR("Disguise", 
   160 			PassInfo pass[4]; \
   161 			pass[0].flags = PASSFLAG_BYVAL; \
   162 			pass[0].size = sizeof(int); \
   163 			pass[0].type = PassType_Basic; \
   164 			pass[1].flags = PASSFLAG_BYVAL; \
   165 			pass[1].size = sizeof(int); \
   166 			pass[1].type = PassType_Basic; \
   167 			pass[2].flags = PASSFLAG_BYVAL; \
   168 			pass[2].size = sizeof(CBaseEntity *); \
   169 			pass[2].type = PassType_Basic; \
   170 			pass[3].flags = PASSFLAG_BYVAL; \
   171 			pass[3].size = sizeof(bool); \
   172 			pass[3].type = PassType_Basic; \
   173 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 4))
   174 	}
   175 
   176 	CBaseEntity *pEntity;
   177 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   178 	{
   179 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   180 	}
   181 
   182 	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
   183 	
   184 	CBaseEntity *pTarget = NULL;
   185 	// Compatibility fix for the newly-added target parameter
   186 	if (params[0] >= 4 && params[4] > 0 && !(pTarget = UTIL_GetCBaseEntity(params[4], true)))
   187 	{
   188 		return pContext->ThrowNativeError("Target client index %d is not valid", params[4]);
   189 	}
   190 
   191 	unsigned char vstk[sizeof(void *) + 2*sizeof(int) + sizeof(bool)];
   192 	unsigned char *vptr = vstk;
   193 
   194 
   195 	*(void **)vptr = obj;
   196 	vptr += sizeof(void *);
   197 	*(int *)vptr = params[2];
   198 	vptr += sizeof(int);
   199 	*(int *)vptr = params[3];
   200 	vptr += sizeof(int);
   201 	*(CBaseEntity **)vptr = pTarget;
   202 	vptr += sizeof(CBaseEntity *);
   203 	*(bool *)vptr = true;
   204 	
   205 	pWrapper->Execute(vstk, NULL);
   206 
   207 	return 1;
   208 }
   209 
   210 cell_t TF2_RemoveDisguise(IPluginContext *pContext, const cell_t *params)
   211 {
   212 	static ICallWrapper *pWrapper = NULL;
   213 
   214 	//CTFPlayerShared::RemoveDisguise()
   215 	if (!pWrapper)
   216 	{
   217 		REGISTER_NATIVE_ADDR("RemoveDisguise", 
   218 				pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, NULL, 0))
   219 	}
   220 
   221 	CBaseEntity *pEntity;
   222 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   223 	{
   224 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   225 	}
   226 
   227 	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
   228 
   229 	unsigned char vstk[sizeof(void *)];
   230 	unsigned char *vptr = vstk;
   231 
   232 
   233 	*(void **)vptr = obj;
   234 
   235 	pWrapper->Execute(vstk, NULL);
   236 
   237 	return 1;
   238 }
   239 
   240 cell_t TF2_AddCondition(IPluginContext *pContext, const cell_t *params)
   241 {
   242 	static ICallWrapper *pWrapper = NULL;
   243 
   244 	// CTFPlayerShared::AddCond(int, float, CBaseEntity *)
   245 	if (!pWrapper)
   246 	{
   247 		REGISTER_NATIVE_ADDR("AddCondition", 
   248 			PassInfo pass[3]; \
   249 			pass[0].flags = PASSFLAG_BYVAL; \
   250 			pass[0].size = sizeof(int); \
   251 			pass[0].type = PassType_Basic; \
   252 			pass[1].flags = PASSFLAG_BYVAL; \
   253 			pass[1].size = sizeof(float); \
   254 			pass[1].type = PassType_Basic; \
   255 			pass[2].flags = PASSFLAG_BYVAL; \
   256 			pass[2].size = sizeof(CBaseEntity *); \
   257 			pass[2].type = PassType_Basic; \
   258 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 3))
   259 	}
   260 
   261 	CBaseEntity *pEntity;
   262 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   263 	{
   264 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   265 	}
   266 
   267 	CBaseEntity *pInflictor = NULL;
   268 	// Compatibility fix for the new inflictor parameter; TF2 seems to only use player entities in it
   269 	if (params[0] >= 4 && params[4] > 0 && !(pInflictor = UTIL_GetCBaseEntity(params[4], true)))
   270 	{
   271 		return pContext->ThrowNativeError("Inflictor index %d is not valid", params[4]);
   272 	}
   273 
   274 	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
   275 
   276 	unsigned char vstk[sizeof(void *) + sizeof(int) + sizeof(float) + sizeof(CBaseEntity *)];
   277 	unsigned char *vptr = vstk;
   278 
   279 	*(void **)vptr = obj;
   280 	vptr += sizeof(void *);
   281 	*(int *)vptr = params[2];
   282 	vptr += sizeof(int);
   283 	*(float *)vptr = *(float *)&params[3];
   284 	vptr += sizeof(float);
   285 	*(CBaseEntity **)vptr = pInflictor;
   286 
   287 	pWrapper->Execute(vstk, NULL);
   288 
   289 	return 1;
   290 }
   291 
   292 cell_t TF2_RemoveCondition(IPluginContext *pContext, const cell_t *params)
   293 {
   294 	static ICallWrapper *pWrapper = NULL;
   295 
   296 	// CTFPlayerShared::RemoveCond(int, bool)
   297 	if (!pWrapper)
   298 	{
   299 		REGISTER_NATIVE_ADDR("RemoveCondition", 
   300 			PassInfo pass[2]; \
   301 			pass[0].flags = PASSFLAG_BYVAL; \
   302 			pass[0].size = sizeof(int); \
   303 			pass[0].type = PassType_Basic; \
   304 			pass[1].flags = PASSFLAG_BYVAL; \
   305 			pass[1].size = sizeof(bool); \
   306 			pass[1].type = PassType_Basic; \
   307 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2))
   308 	}
   309 
   310 	CBaseEntity *pEntity;
   311 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   312 	{
   313 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   314 	}
   315 
   316 	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
   317 
   318 	unsigned char vstk[sizeof(void *) + sizeof(int) + sizeof(bool)];
   319 	unsigned char *vptr = vstk;
   320 
   321 	*(void **)vptr = obj;
   322 	vptr += sizeof(void *);
   323 	*(int *)vptr = params[2];
   324 	vptr += sizeof(int);
   325 	*(bool *)vptr = true;
   326 
   327 	pWrapper->Execute(vstk, NULL);
   328 
   329 	return 1;
   330 }
   331 
   332 cell_t TF2_StunPlayer(IPluginContext *pContext, const cell_t *params)
   333 {
   334 	static ICallWrapper *pWrapper = NULL;
   335 
   336 	// CTFPlayerShared::StunPlayer(float, float, int, CTFPlayer *)
   337 	if (!pWrapper)
   338 	{
   339 		REGISTER_NATIVE_ADDR("StunPlayer", 
   340 			PassInfo pass[4]; \
   341 			pass[0].flags = PASSFLAG_BYVAL; \
   342 			pass[0].size = sizeof(float); \
   343 			pass[0].type = PassType_Basic; \
   344 			pass[1].flags = PASSFLAG_BYVAL; \
   345 			pass[1].size = sizeof(float); \
   346 			pass[1].type = PassType_Basic; \
   347 			pass[2].flags = PASSFLAG_BYVAL; \
   348 			pass[2].size = sizeof(int); \
   349 			pass[2].type = PassType_Basic; \
   350 			pass[3].flags = PASSFLAG_BYVAL; \
   351 			pass[3].size = sizeof(CBaseEntity *); \
   352 			pass[3].type = PassType_Basic; \
   353 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 4))
   354 	}
   355 
   356 	CBaseEntity *pEntity;
   357 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   358 	{
   359 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   360 	}
   361 
   362 	bool bByPlayer = (params[5] != 0);
   363 	CBaseEntity *pAttacker = NULL;
   364 	if (bByPlayer && !(pAttacker = UTIL_GetCBaseEntity(params[5], true)))
   365 	{
   366 		return pContext->ThrowNativeError("Attacker index %d is not valid", params[5]);
   367 	}
   368 
   369 	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
   370 
   371 	unsigned char vstk[sizeof(void *) + 2*sizeof(float) + sizeof(int) + sizeof(CBaseEntity *)];
   372 	unsigned char *vptr = vstk;
   373 
   374 	*(void **)vptr = obj;
   375 	vptr += sizeof(void *);
   376 	*(float *)vptr = sp_ctof(params[2]);
   377 	vptr += sizeof(float);
   378 	*(float *)vptr = sp_ctof(params[3]);
   379 	vptr += sizeof(float);
   380 	*(int *)vptr = params[4];
   381 	vptr += sizeof(int);
   382 	*(CBaseEntity **)vptr = pAttacker;
   383 
   384 	pWrapper->Execute(vstk, NULL);
   385 
   386 	return 1;
   387 }
   388 
   389 cell_t TF2_SetPowerplayEnabled(IPluginContext *pContext, const cell_t *params)
   390 {
   391 	static ICallWrapper *pWrapper = NULL;
   392 
   393 	// CTFPlayer::SetPowerPlayEnabled(bool)
   394 	if (!pWrapper)
   395 	{
   396 		REGISTER_NATIVE_ADDR("SetPowerplayEnabled", 
   397 			PassInfo pass[1]; \
   398 			pass[0].flags = PASSFLAG_BYVAL; \
   399 			pass[0].size = sizeof(bool); \
   400 			pass[0].type = PassType_Basic; \
   401 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 1))
   402 	}
   403 
   404 	CBaseEntity *pEntity;
   405 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   406 	{
   407 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   408 	}
   409 
   410 	bool bEnablePP = false;
   411 	if (params[2] != 0)
   412 	{
   413 		bEnablePP = true;
   414 	}
   415 
   416 	unsigned char vstk[sizeof(void *) + sizeof(bool)];
   417 	unsigned char *vptr = vstk;
   418 
   419 	*(void **)vptr = (void *)pEntity;
   420 	vptr += sizeof(void *);
   421 	*(bool *)vptr = bEnablePP;
   422 
   423 	pWrapper->Execute(vstk, NULL);
   424 
   425 	return 1;
   426 }
   427 
   428 cell_t TF2_Respawn(IPluginContext *pContext, const cell_t *params)
   429 {
   430 	static ICallWrapper *pWrapper = NULL;
   431 
   432 	//CTFPlayer::ForceRespawn()
   433 
   434 	if (!pWrapper)
   435 	{
   436 		int offset;
   437 
   438 		if (!g_pGameConf->GetOffset("ForceRespawn", &offset))
   439 		{
   440 			return pContext->ThrowNativeError("Failed to locate function");
   441 		}
   442 
   443 		pWrapper = g_pBinTools->CreateVCall(offset,
   444 											0,
   445 											0,
   446 											NULL,
   447 											NULL,
   448 											0);
   449 
   450 		g_RegNatives.Register(pWrapper);
   451 	}
   452 
   453 	CBaseEntity *pEntity;
   454 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   455 	{
   456 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   457 	}
   458 
   459 	unsigned char vstk[sizeof(void *)];
   460 	unsigned char *vptr = vstk;
   461 
   462 
   463 	*(void **)vptr = (void *)pEntity;
   464 
   465 	pWrapper->Execute(vstk, NULL);
   466 
   467 	return 1;
   468 }
   469 
   470 cell_t TF2_Regenerate(IPluginContext *pContext, const cell_t *params)
   471 {
   472 	static ICallWrapper *pWrapper = NULL;
   473 
   474 	//CTFPlayer::Regenerate( bool=true )
   475 
   476 	if (!pWrapper)
   477 	{
   478 		REGISTER_NATIVE_ADDR("Regenerate", 
   479 			PassInfo pass[1]; \
   480 			pass[0].flags = PASSFLAG_BYVAL; \
   481 			pass[0].size = sizeof(bool); \
   482 			pass[0].type = PassType_Basic; \
   483 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 1))
   484 	}
   485 
   486 	CBaseEntity *pEntity;
   487 	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
   488 	{
   489 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   490 	}
   491 	
   492 	unsigned char vstk[sizeof(void *) + sizeof(bool)];
   493 	unsigned char *vptr = vstk;
   494 
   495 	*(void **)vptr = (void *)pEntity;
   496 	vptr += sizeof(void *);
   497 	*(bool *)vptr = true;
   498 
   499 	pWrapper->Execute(vstk, NULL);
   500 
   501 	return 1;
   502 }
   503 
   504 cell_t TF2_GetResourceEntity(IPluginContext *pContext, const cell_t *params)
   505 {
   506 	return g_resourceEntity;
   507 }
   508 
   509 cell_t TF2_GetClass(IPluginContext *pContext, const cell_t *params)
   510 {
   511 	char *str;
   512 	pContext->LocalToString(params[1], &str);
   513 
   514 	return (cell_t)ClassnameToType(str);
   515 }
   516 
   517 // native TF2_IsPlayerInDuel(client)
   518 cell_t TF2_IsPlayerInDuel(IPluginContext *pContext, const cell_t *params)
   519 {
   520 	static ICallWrapper *pWrapper = NULL;
   521 
   522 	// DuelMiniGame_IsPlayerInDuel(CTFPlayer *)
   523 	if (!pWrapper)
   524 	{
   525 		REGISTER_NATIVE_ADDR("IsPlayerInDuel", 
   526 			PassInfo pass[1]; \
   527 			pass[0].flags = PASSFLAG_BYVAL; \
   528 			pass[0].size = sizeof(CBaseEntity *); \
   529 			pass[0].type = PassType_Basic; \
   530 			PassInfo ret; \
   531 			ret.flags = PASSFLAG_BYVAL; \
   532 			ret.size = sizeof(bool); \
   533 			ret.type = PassType_Basic; \
   534 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &ret, pass, 1))
   535 	}
   536 
   537 	CBaseEntity *pPlayer;
   538 	if (!(pPlayer = UTIL_GetCBaseEntity(params[1], true)))
   539 	{
   540 		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
   541 	}
   542 
   543 	unsigned char vstk[sizeof(CBaseEntity *)];
   544 	unsigned char *vptr = vstk;
   545 	*(CBaseEntity **)vptr = pPlayer;
   546 
   547 	bool retValue;
   548 	pWrapper->Execute(vstk, &retValue);
   549 
   550 	return (retValue) ? 1 : 0;
   551 }
   552 
   553 // native bool:TF2_IsHolidayActive(TFHoliday:holiday);
   554 cell_t TF2_IsHolidayActive(IPluginContext *pContext, const cell_t *params)
   555 {
   556 	static ICallWrapper *pWrapper = NULL;
   557 
   558 	// UTIL_IsHolidayActive(int)
   559 	if (!pWrapper)
   560 	{
   561 		REGISTER_NATIVE_ADDR("IsHolidayActive", 
   562 			PassInfo pass[1]; \
   563 			pass[0].flags = PASSFLAG_BYVAL; \
   564 			pass[0].size = sizeof(int); \
   565 			pass[0].type = PassType_Basic; \
   566 			PassInfo ret; \
   567 			ret.flags = PASSFLAG_BYVAL; \
   568 			ret.size = sizeof(bool); \
   569 			ret.type = PassType_Basic; \
   570 			pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &ret, pass, 1))
   571 	}
   572 
   573 	unsigned char vstk[sizeof(int)];
   574 	unsigned char *vptr = vstk;
   575 	*(int *)vptr = params[1];
   576 	
   577 	bool retValue;
   578 
   579 	pWrapper->Execute(vstk, &retValue);
   580 
   581 	return (retValue) ? 1 : 0;
   582 }
   583 
   584 sp_nativeinfo_t g_TFNatives[] = 
   585 {
   586 	{"TF2_IgnitePlayer",			TF2_Burn},
   587 	{"TF2_SetPlayerInvuln",			TF2_Invuln},
   588 	{"TF2_RespawnPlayer",			TF2_Respawn},
   589 	{"TF2_DisguisePlayer",			TF2_Disguise},
   590 	{"TF2_RemovePlayerDisguise",	TF2_RemoveDisguise},
   591 	{"TF2_GetResourceEntity",		TF2_GetResourceEntity},
   592 	{"TF2_GetClass",				TF2_GetClass},
   593 	{"TF2_RegeneratePlayer",		TF2_Regenerate},
   594 	{"TF2_AddCondition",			TF2_AddCondition},
   595 	{"TF2_RemoveCondition",			TF2_RemoveCondition},
   596 	{"TF2_SetPlayerPowerPlay",		TF2_SetPowerplayEnabled},
   597 	{"TF2_StunPlayer",				TF2_StunPlayer},
   598 	{"TF2_MakeBleed",				TF2_MakeBleed},
   599 	{"TF2_IsPlayerInDuel",				TF2_IsPlayerInDuel},
   600 	{"TF2_IsHolidayActive",				TF2_IsHolidayActive},
   601 	{NULL,							NULL}
   602 };