extensions/tf2/natives.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Sep 14 03:01:05 2008 -0500 (2008-09-14)
changeset 2289 44045ead61cd
parent 2097 0a56b8faac9c
parent 1947 e73a1e51833b
child 2673 87d4d9f3cbc3
permissions -rw-r--r--
Eliminated head: da55a80522cf, a remnant of sourcemod-1.1.0 branch
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
dvander@1945
    37
pred@1963
    38
// native TF2_Burn(client, target)
dvander@1945
    39
cell_t TF2_Burn(IPluginContext *pContext, const cell_t *params)
dvander@1945
    40
{
dvander@1945
    41
	static ICallWrapper *pWrapper = NULL;
dvander@1945
    42
dvander@1945
    43
	// CTFPlayerShared::Burn(CTFPlayer*)
dvander@1945
    44
	if (!pWrapper)
dvander@1945
    45
	{
dvander@1945
    46
		REGISTER_NATIVE_ADDR("Burn", 
ds@2097
    47
			PassInfo pass[2]; \
dvander@1945
    48
			pass[0].flags = PASSFLAG_BYVAL; \
dvander@1945
    49
			pass[0].size = sizeof(CBaseEntity *); \
dvander@1945
    50
			pass[0].type = PassType_Basic; \
ds@2097
    51
			pass[1].flags = PASSFLAG_BYVAL; \
ds@2097
    52
			pass[1].size = sizeof(CBaseEntity *); \
ds@2097
    53
			pass[1].type = PassType_Basic; \
ds@2097
    54
			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2))
dvander@1945
    55
	}
dvander@1945
    56
dvander@1945
    57
	CBaseEntity *pEntity;
pred@1963
    58
	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
dvander@1945
    59
	{
dvander@1945
    60
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
dvander@1945
    61
	}
dvander@1945
    62
pred@1963
    63
	CBaseEntity *pTarget;
pred@1963
    64
	if (!(pTarget = UTIL_GetCBaseEntity(params[2], true)))
pred@1963
    65
	{
pred@1963
    66
		return pContext->ThrowNativeError("Client index %d is not valid", params[2]);
pred@1963
    67
	}
pred@1963
    68
pred@1963
    69
	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
dvander@1945
    70
dvander@1945
    71
	unsigned char vstk[sizeof(void *) + sizeof(CBaseEntity *)];
dvander@1945
    72
	unsigned char *vptr = vstk;
dvander@1945
    73
dvander@1945
    74
	*(void **)vptr = obj;
dvander@1945
    75
	vptr += sizeof(void *);
pred@1963
    76
	*(CBaseEntity **)vptr = pTarget;
ds@2097
    77
	vptr += sizeof(CBaseEntity *);
ds@2097
    78
	*(CBaseEntity **)vptr = NULL;
ds@1952
    79
ds@1952
    80
	pWrapper->Execute(vstk, NULL);
ds@1952
    81
ds@1952
    82
	return 1;
ds@1952
    83
}
ds@1952
    84
pred@1963
    85
// native TF2_Invuln(client, bool:enabled)
ds@1952
    86
cell_t TF2_Invuln(IPluginContext *pContext, const cell_t *params)
ds@1952
    87
{
pred@2039
    88
	return pContext->ThrowNativeError("TF2_SetPlayerInvuln is no longer available");
pred@1963
    89
}
pred@1963
    90
pred@1963
    91
cell_t TF2_Disguise(IPluginContext *pContext, const cell_t *params)
pred@1963
    92
{
pred@1963
    93
	static ICallWrapper *pWrapper = NULL;
pred@1963
    94
pred@1963
    95
	//CTFPlayerShared::Disguise(int, int)
pred@1963
    96
	if (!pWrapper)
pred@1963
    97
	{
pred@1963
    98
		REGISTER_NATIVE_ADDR("Disguise", 
pred@1963
    99
			PassInfo pass[2]; \
pred@1963
   100
			pass[0].flags = PASSFLAG_BYVAL; \
pred@1963
   101
			pass[0].size = sizeof(int); \
pred@1963
   102
			pass[0].type = PassType_Basic; \
pred@1963
   103
			pass[1].flags = PASSFLAG_BYVAL; \
pred@1963
   104
			pass[1].size = sizeof(int); \
pred@1963
   105
			pass[1].type = PassType_Basic; \
pred@1963
   106
			pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2))
pred@1963
   107
	}
pred@1963
   108
pred@1963
   109
	CBaseEntity *pEntity;
pred@1963
   110
	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
pred@1963
   111
	{
pred@1963
   112
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
pred@1963
   113
	}
pred@1963
   114
pred@1963
   115
	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
pred@1963
   116
pred@1963
   117
	unsigned char vstk[sizeof(void *) + 2*sizeof(int)];
pred@1963
   118
	unsigned char *vptr = vstk;
pred@1963
   119
pred@1963
   120
pred@1963
   121
	*(void **)vptr = obj;
pred@1963
   122
	vptr += sizeof(void *);
pred@1963
   123
	*(int *)vptr = params[2];
pred@1963
   124
	vptr += sizeof(int);
pred@1963
   125
	*(int *)vptr = params[3];
dvander@1945
   126
dvander@1945
   127
	pWrapper->Execute(vstk, NULL);
dvander@1945
   128
dvander@1945
   129
	return 1;
dvander@1945
   130
}
dvander@1945
   131
pred@1963
   132
cell_t TF2_RemoveDisguise(IPluginContext *pContext, const cell_t *params)
dvander@1945
   133
{
dvander@1945
   134
	static ICallWrapper *pWrapper = NULL;
dvander@1945
   135
pred@1963
   136
	//CTFPlayerShared::RemoveDisguise()
dvander@1945
   137
	if (!pWrapper)
dvander@1945
   138
	{
pred@1963
   139
		REGISTER_NATIVE_ADDR("RemoveDisguise", 
pred@1963
   140
				pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, NULL, 0))
dvander@1945
   141
	}
dvander@1945
   142
dvander@1945
   143
	CBaseEntity *pEntity;
pred@1963
   144
	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
dvander@1945
   145
	{
dvander@1945
   146
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
dvander@1945
   147
	}
dvander@1945
   148
pred@1963
   149
	void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
dvander@1945
   150
pred@1963
   151
	unsigned char vstk[sizeof(void *)];
dvander@1945
   152
	unsigned char *vptr = vstk;
dvander@1945
   153
dvander@1945
   154
dvander@1945
   155
	*(void **)vptr = obj;
dvander@1945
   156
dvander@1945
   157
	pWrapper->Execute(vstk, NULL);
dvander@1945
   158
dvander@1945
   159
	return 1;
dvander@1945
   160
}
dvander@1945
   161
pred@1963
   162
cell_t TF2_Respawn(IPluginContext *pContext, const cell_t *params)
pred@1963
   163
{
pred@1963
   164
	static ICallWrapper *pWrapper = NULL;
pred@1963
   165
pred@1963
   166
	//CTFPlayer::ForceRespawn()
pred@1963
   167
pred@1963
   168
	if (!pWrapper)
pred@1963
   169
	{
pred@1963
   170
		int offset;
pred@1963
   171
pred@1963
   172
		if (!g_pGameConf->GetOffset("ForceRespawn", &offset))
pred@1963
   173
		{
pred@1963
   174
			return pContext->ThrowNativeError("Failed to locate function");
pred@1963
   175
		}
pred@1963
   176
pred@1963
   177
		pWrapper = g_pBinTools->CreateVCall(offset,
pred@1963
   178
											0,
pred@1963
   179
											0,
pred@1963
   180
											NULL,
pred@1963
   181
											NULL,
pred@1963
   182
											0);
pred@1963
   183
pred@1963
   184
		g_RegNatives.Register(pWrapper);
pred@1963
   185
	}
pred@1963
   186
pred@1963
   187
	CBaseEntity *pEntity;
pred@1963
   188
	if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
pred@1963
   189
	{
pred@1963
   190
		return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
pred@1963
   191
	}
pred@1963
   192
pred@1963
   193
	unsigned char vstk[sizeof(void *)];
pred@1963
   194
	unsigned char *vptr = vstk;
pred@1963
   195
pred@1963
   196
pred@1963
   197
	*(void **)vptr = (void *)pEntity;
pred@1963
   198
pred@1963
   199
	pWrapper->Execute(vstk, NULL);
pred@1963
   200
pred@1963
   201
	return 1;
pred@1963
   202
}
pred@1963
   203
pred@1963
   204
cell_t TF2_GetResourceEntity(IPluginContext *pContext, const cell_t *params)
pred@1963
   205
{
pred@1963
   206
	return g_resourceEntity;
pred@1963
   207
}
pred@1963
   208
pred@1963
   209
cell_t TF2_GetClass(IPluginContext *pContext, const cell_t *params)
pred@1963
   210
{
pred@1963
   211
	char *str;
pred@1963
   212
	pContext->LocalToString(params[1], &str);
pred@1963
   213
pred@1963
   214
	return (cell_t)ClassnameToType(str);
pred@1963
   215
}
dvander@1945
   216
dvander@1945
   217
sp_nativeinfo_t g_TFNatives[] = 
dvander@1945
   218
{
pred@1963
   219
	{"TF2_IgnitePlayer",			TF2_Burn},
pred@1963
   220
	{"TF2_SetPlayerInvuln",			TF2_Invuln},
pred@1963
   221
	{"TF2_RespawnPlayer",			TF2_Respawn},
pred@1963
   222
	{"TF2_DisguisePlayer",			TF2_Disguise},
pred@1963
   223
	{"TF2_RemovePlayerDisguise",	TF2_RemoveDisguise},
pred@1963
   224
	{"TF2_GetResourceEntity",		TF2_GetResourceEntity},
pred@1963
   225
	{"TF2_GetClass",				TF2_GetClass},
dvander@1945
   226
	{NULL,							NULL}
dvander@1945
   227
};