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