extensions/sdktools/inputnatives.cpp
author David Anderson <dvander@alliedmods.net>
Wed Feb 25 20:07:12 2009 -0500 (2009-02-25)
changeset 2607 f3b8bbe17f85
parent 2289 44045ead61cd
child 2400 76b7b4575e21
permissions -rw-r--r--
Backed out changeset fa286305bd3f
faluco@1498
     1
/**
faluco@1498
     2
 * vim: set ts=4 :
faluco@1498
     3
 * =============================================================================
faluco@1498
     4
 * SourceMod SDKTools Extension
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
faluco@1498
     6
 * =============================================================================
faluco@1498
     7
 *
faluco@1498
     8
 * This program is free software; you can redistribute it and/or modify it under
faluco@1498
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
faluco@1498
    10
 * Free Software Foundation.
faluco@1498
    11
 * 
faluco@1498
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
faluco@1498
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
faluco@1498
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
faluco@1498
    15
 * details.
faluco@1498
    16
 *
faluco@1498
    17
 * You should have received a copy of the GNU General Public License along with
faluco@1498
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
faluco@1498
    19
 *
faluco@1498
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
faluco@1498
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
faluco@1498
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
faluco@1498
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
faluco@1498
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
faluco@1498
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
faluco@1498
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
faluco@1498
    27
 * or <http://www.sourcemod.net/license.php>.
faluco@1498
    28
 *
faluco@1498
    29
 * Version: $Id$
faluco@1498
    30
 */
faluco@1498
    31
faluco@1498
    32
#include "extension.h"
faluco@1498
    33
#include <datamap.h>
faluco@1498
    34
faluco@1498
    35
#define SIZEOF_VARIANT_T		20
faluco@1498
    36
faluco@1498
    37
ICallWrapper *g_pAcceptInput = NULL;
faluco@1498
    38
unsigned char g_Variant_t[SIZEOF_VARIANT_T] = {0};
faluco@1498
    39
faluco@1498
    40
#define ENTINDEX_TO_CBASEENTITY(index, buffer) \
faluco@1498
    41
	pEdict = engine->PEntityOfEntIndex(index); \
faluco@1498
    42
	if (!pEdict || pEdict->IsFree()) \
faluco@1498
    43
	{ \
faluco@1498
    44
		return pContext->ThrowNativeError("Entity %d is not valid or is freed", index); \
faluco@1498
    45
	} \
faluco@1498
    46
	pUnk = pEdict->GetUnknown(); \
faluco@1498
    47
	if (!pUnk) \
faluco@1498
    48
	{ \
faluco@1498
    49
		return pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", index); \
faluco@1498
    50
	} \
faluco@1498
    51
	buffer = pUnk->GetBaseEntity(); \
faluco@1498
    52
	if (!buffer) \
faluco@1498
    53
	{ \
faluco@1498
    54
		return pContext->ThrowNativeError("Entity %d is not a CBaseEntity", index); \
faluco@1498
    55
	}
faluco@1498
    56
faluco@1498
    57
/* Hack to init the variant_t object for the first time */
faluco@1498
    58
class VariantFirstTimeInit
faluco@1498
    59
{
faluco@1498
    60
public:
faluco@1498
    61
	VariantFirstTimeInit()
faluco@1498
    62
	{
faluco@1498
    63
		*(unsigned int *)(&g_Variant_t[12]) = INVALID_EHANDLE_INDEX;
faluco@1498
    64
	}
faluco@1498
    65
} g_VariantFirstTimeInit;
faluco@1498
    66
faluco@1498
    67
inline void _init_variant_t()
faluco@1498
    68
{
faluco@1498
    69
	unsigned char *vptr = g_Variant_t;
faluco@1498
    70
faluco@1498
    71
	*(int *)vptr = 0;
faluco@1498
    72
	vptr += sizeof(int)*3;
faluco@1498
    73
	*(unsigned long *)vptr = INVALID_EHANDLE_INDEX;
faluco@1498
    74
	vptr += sizeof(unsigned long);
faluco@1498
    75
	*(fieldtype_t *)vptr = FIELD_VOID;
faluco@1498
    76
}
faluco@1498
    77
faluco@1498
    78
static cell_t AcceptEntityInput(IPluginContext *pContext, const cell_t *params)
faluco@1498
    79
{
faluco@1498
    80
	if (!g_pAcceptInput)
faluco@1498
    81
	{
faluco@1498
    82
		int offset;
faluco@1498
    83
		if (!g_pGameConf->GetOffset("AcceptInput", &offset))
faluco@1498
    84
		{
faluco@1498
    85
			return pContext->ThrowNativeError("\"AcceptEntityInput\" not supported by this mod");
faluco@1498
    86
		}
faluco@1498
    87
faluco@1498
    88
		PassInfo pass[6];
faluco@1498
    89
		pass[0].type = PassType_Basic;
faluco@1498
    90
		pass[0].flags = PASSFLAG_BYVAL;
faluco@1498
    91
		pass[0].size = sizeof(const char *);
faluco@1498
    92
		pass[1].type = pass[2].type = PassType_Basic;
faluco@1498
    93
		pass[1].flags = pass[2].flags = PASSFLAG_BYVAL;
faluco@1498
    94
		pass[1].size = pass[2].size = sizeof(CBaseEntity *);
faluco@1498
    95
		pass[3].type = PassType_Object;
faluco@1515
    96
		pass[3].flags = PASSFLAG_BYVAL|PASSFLAG_OCTOR|PASSFLAG_ODTOR|PASSFLAG_OASSIGNOP;
faluco@1498
    97
		pass[3].size = SIZEOF_VARIANT_T;
faluco@1498
    98
		pass[4].type = PassType_Basic;
faluco@1498
    99
		pass[4].flags = PASSFLAG_BYVAL;
faluco@1498
   100
		pass[4].size = sizeof(int);
faluco@1498
   101
		pass[5].type = PassType_Basic;
faluco@1498
   102
		pass[5].flags = PASSFLAG_BYVAL;
faluco@1498
   103
		pass[5].size = sizeof(bool);
faluco@1498
   104
faluco@1498
   105
		if (!(g_pAcceptInput=g_pBinTools->CreateVCall(offset, 0, 0, &pass[5], pass, 5)))
faluco@1498
   106
		{
faluco@1498
   107
			pContext->ThrowNativeError("\"AcceptEntityInput\" wrapper failed to initialized");
faluco@1498
   108
		}
faluco@1498
   109
	}
faluco@1498
   110
faluco@1498
   111
	CBaseEntity *pActivator, *pCaller, *pDest;
faluco@1498
   112
	edict_t *pEdict;
faluco@1498
   113
	IServerUnknown *pUnk;
faluco@1498
   114
faluco@1498
   115
	char *inputname;
faluco@1498
   116
	unsigned char vstk[sizeof(void *) + sizeof(const char *) + sizeof(CBaseEntity *)*2 + SIZEOF_VARIANT_T + sizeof(int)];
faluco@1498
   117
	unsigned char *vptr = vstk;
faluco@1498
   118
faluco@1498
   119
	ENTINDEX_TO_CBASEENTITY(params[1], pDest);
faluco@1498
   120
	pContext->LocalToString(params[2], &inputname);
faluco@1498
   121
	if (params[3] == -1)
faluco@1498
   122
	{
faluco@1498
   123
		pActivator = NULL;
faluco@1498
   124
	} else {
faluco@1498
   125
		ENTINDEX_TO_CBASEENTITY(params[3], pActivator);
faluco@1498
   126
	}
faluco@1498
   127
	if (params[4] == -1)
faluco@1498
   128
	{
faluco@1498
   129
		pCaller = NULL;
faluco@1498
   130
	} else {
faluco@1498
   131
		ENTINDEX_TO_CBASEENTITY(params[4], pCaller);
faluco@1498
   132
	}
faluco@1498
   133
faluco@1498
   134
	*(void **)vptr = pDest;
faluco@1498
   135
	vptr += sizeof(void *);
faluco@1498
   136
	*(const char **)vptr = inputname;
faluco@1498
   137
	vptr += sizeof(const char *);
faluco@1498
   138
	*(CBaseEntity **)vptr = pActivator;
faluco@1498
   139
	vptr += sizeof(CBaseEntity *);
faluco@1498
   140
	*(CBaseEntity **)vptr = pCaller;
faluco@1498
   141
	vptr += sizeof(CBaseEntity *);
faluco@1498
   142
	memcpy(vptr, g_Variant_t, SIZEOF_VARIANT_T);
faluco@1498
   143
	vptr += SIZEOF_VARIANT_T;
faluco@1498
   144
	*(int *)vptr = params[5];
faluco@1498
   145
faluco@1498
   146
	bool ret;
faluco@1498
   147
	g_pAcceptInput->Execute(vstk, &ret);
faluco@1498
   148
faluco@1498
   149
	_init_variant_t();
faluco@1498
   150
faluco@1498
   151
	return (ret) ? 1 : 0;
faluco@1498
   152
}
faluco@1498
   153
faluco@1498
   154
static cell_t SetVariantBool(IPluginContext *pContext, const cell_t *params)
faluco@1498
   155
{
faluco@1498
   156
	unsigned char *vptr = g_Variant_t;
faluco@1498
   157
faluco@1498
   158
	*(bool *)vptr = (params[1]) ? true : false;
faluco@1498
   159
	vptr += sizeof(int)*3 + sizeof(unsigned long);
faluco@1498
   160
	*(fieldtype_t *)vptr = FIELD_BOOLEAN;
faluco@1498
   161
faluco@1498
   162
	return 1;
faluco@1498
   163
}
faluco@1498
   164
faluco@1498
   165
static cell_t SetVariantString(IPluginContext *pContext, const cell_t *params)
faluco@1498
   166
{
faluco@1498
   167
	char *str;
faluco@1498
   168
	unsigned char *vptr = g_Variant_t;
faluco@1498
   169
faluco@1498
   170
	pContext->LocalToString(params[1], &str);
faluco@1498
   171
faluco@1498
   172
	*(string_t *)vptr = MAKE_STRING(str);
faluco@1498
   173
	vptr += sizeof(int)*3 + sizeof(unsigned long);
faluco@1498
   174
	*(fieldtype_t *)vptr = FIELD_STRING;
faluco@1498
   175
faluco@1498
   176
	return 1;
faluco@1498
   177
}
faluco@1498
   178
faluco@1498
   179
static cell_t SetVariantInt(IPluginContext *pContext, const cell_t *params)
faluco@1498
   180
{
faluco@1498
   181
	unsigned char *vptr = g_Variant_t;
faluco@1498
   182
faluco@1498
   183
	*(int *)vptr = params[1];
faluco@1498
   184
	vptr += sizeof(int)*3 + sizeof(unsigned long);
faluco@1498
   185
	*(fieldtype_t *)vptr = FIELD_INTEGER;
faluco@1498
   186
faluco@1498
   187
	return 1;
faluco@1498
   188
}
faluco@1498
   189
faluco@1498
   190
static cell_t SetVariantFloat(IPluginContext *pContext, const cell_t *params)
faluco@1498
   191
{
faluco@1498
   192
	unsigned char *vptr = g_Variant_t;
faluco@1498
   193
faluco@1498
   194
	*(float *)vptr = sp_ctof(params[1]);
faluco@1498
   195
	vptr += sizeof(int)*3 + sizeof(unsigned long);
faluco@1498
   196
	*(fieldtype_t *)vptr = FIELD_FLOAT;
faluco@1498
   197
faluco@1498
   198
	return 1;
faluco@1498
   199
}
faluco@1498
   200
faluco@1498
   201
static cell_t SetVariantVector3D(IPluginContext *pContext, const cell_t *params)
faluco@1498
   202
{
faluco@1498
   203
	cell_t *val;
faluco@1498
   204
	unsigned char *vptr = g_Variant_t;
faluco@1498
   205
faluco@1498
   206
	pContext->LocalToPhysAddr(params[1], &val);
faluco@1498
   207
faluco@1498
   208
	*(float *)vptr = sp_ctof(val[0]);
faluco@1498
   209
	vptr += sizeof(float);
faluco@1498
   210
	*(float *)vptr = sp_ctof(val[1]);
faluco@1498
   211
	vptr += sizeof(float);
faluco@1498
   212
	*(float *)vptr = sp_ctof(val[2]);
faluco@1498
   213
	vptr += sizeof(float) + sizeof(unsigned long);
faluco@1498
   214
	*(fieldtype_t *)vptr = FIELD_VECTOR;
faluco@1498
   215
faluco@1498
   216
	return 1;
faluco@1498
   217
}
faluco@1498
   218
faluco@1498
   219
static cell_t SetVariantPosVector3D(IPluginContext *pContext, const cell_t *params)
faluco@1498
   220
{
faluco@1498
   221
	cell_t *val;
faluco@1498
   222
	unsigned char *vptr = g_Variant_t;
faluco@1498
   223
faluco@1498
   224
	pContext->LocalToPhysAddr(params[1], &val);
faluco@1498
   225
faluco@1498
   226
	*(float *)vptr = sp_ctof(val[0]);
faluco@1498
   227
	vptr += sizeof(float);
faluco@1498
   228
	*(float *)vptr = sp_ctof(val[1]);
faluco@1498
   229
	vptr += sizeof(float);
faluco@1498
   230
	*(float *)vptr = sp_ctof(val[2]);
faluco@1498
   231
	vptr += sizeof(float) + sizeof(unsigned long);
faluco@1498
   232
	*(fieldtype_t *)vptr = FIELD_POSITION_VECTOR;
faluco@1498
   233
faluco@1498
   234
	return 1;
faluco@1498
   235
}
faluco@1498
   236
faluco@1498
   237
static cell_t SetVariantColor(IPluginContext *pContext, const cell_t *params)
faluco@1498
   238
{
faluco@1498
   239
	cell_t *val;
faluco@1498
   240
	unsigned char *vptr = g_Variant_t;
faluco@1498
   241
faluco@1498
   242
	pContext->LocalToPhysAddr(params[1], &val);
faluco@1498
   243
faluco@1498
   244
	*(unsigned char *)vptr = val[0];
faluco@1498
   245
	vptr += sizeof(unsigned char);
faluco@1498
   246
	*(unsigned char *)vptr = val[1];
faluco@1498
   247
	vptr += sizeof(unsigned char);
faluco@1498
   248
	*(unsigned char *)vptr = val[2];
faluco@1498
   249
	vptr += sizeof(unsigned char);
faluco@1498
   250
	*(unsigned char *)vptr = val[3];
faluco@1498
   251
	vptr += sizeof(unsigned char) + sizeof(int)*2 + sizeof(unsigned long);
faluco@1498
   252
	*(fieldtype_t *)vptr = FIELD_COLOR32;
faluco@1498
   253
faluco@1498
   254
	return 1;
faluco@1498
   255
}
faluco@1498
   256
faluco@1498
   257
static cell_t SetVariantEntity(IPluginContext *pContext, const cell_t *params)
faluco@1498
   258
{
faluco@1498
   259
	CBaseEntity *pEntity;
faluco@1498
   260
	edict_t *pEdict;
faluco@1498
   261
	IServerUnknown *pUnk;
faluco@1498
   262
	unsigned char *vptr = g_Variant_t;
faluco@1498
   263
	CBaseHandle bHandle;
faluco@1498
   264
faluco@1498
   265
	ENTINDEX_TO_CBASEENTITY(params[1], pEntity);
faluco@1498
   266
	bHandle = reinterpret_cast<IHandleEntity *>(pEntity)->GetRefEHandle();
faluco@1498
   267
faluco@1498
   268
	vptr += sizeof(int)*3;
faluco@1498
   269
	*(unsigned long *)vptr = (unsigned long)(bHandle.ToInt());
faluco@1498
   270
	vptr += sizeof(unsigned long);
faluco@1498
   271
	*(fieldtype_t *)vptr = FIELD_EHANDLE;
faluco@1498
   272
faluco@1498
   273
	return 1;
faluco@1498
   274
}
faluco@1498
   275
faluco@1498
   276
sp_nativeinfo_t g_EntInputNatives[] =
faluco@1498
   277
{
faluco@1498
   278
	{"AcceptEntityInput",			AcceptEntityInput},
faluco@1498
   279
	{"SetVariantBool",				SetVariantBool},
faluco@1498
   280
	{"SetVariantString",			SetVariantString},
faluco@1498
   281
	{"SetVariantInt",				SetVariantInt},
faluco@1498
   282
	{"SetVariantFloat",				SetVariantFloat},
faluco@1498
   283
	{"SetVariantVector3D",			SetVariantVector3D},
faluco@1498
   284
	{"SetVariantPosVector3D",		SetVariantPosVector3D},
faluco@1498
   285
	{"SetVariantColor",				SetVariantColor},
faluco@1498
   286
	{"SetVariantEntity",			SetVariantEntity},
faluco@1498
   287
	{NULL,							NULL},
faluco@1498
   288
};