extensions/sdktools/vnatives.cpp
author David Anderson <dvander@alliedmods.net>
Mon Jun 18 17:02:42 2007 +0000 (2007-06-18)
changeset 980 2fc38d36ee63
parent 955 c59162dec673
child 985 1a45317b1d44
permissions -rw-r--r--
A few sdktools functions now accept all entities and the Player versions are deprecated
dvander@954
     1
#include "extension.h"
dvander@954
     2
#include "vcallbuilder.h"
dvander@954
     3
#include "vnatives.h"
dvander@954
     4
dvander@954
     5
List<ValveCall *> g_RegCalls;
dvander@954
     6
dvander@954
     7
inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags)
dvander@954
     8
{
dvander@954
     9
	info.decflags = 0;
dvander@954
    10
	info.encflags = 0;
dvander@954
    11
	info.flags = flags;
dvander@954
    12
	info.type = type;
dvander@954
    13
	info.vtype = vtype;
dvander@954
    14
}
dvander@954
    15
dvander@954
    16
#define START_CALL() \
dvander@954
    17
	unsigned char *vptr = pCall->stk_get();
dvander@954
    18
dvander@954
    19
#define FINISH_CALL_SIMPLE(vret) \
dvander@954
    20
	pCall->call->Execute(vptr, vret); \
dvander@954
    21
	pCall->stk_put(vptr);
dvander@954
    22
dvander@954
    23
#define ENCODE_VALVE_PARAM(num, which, vnum) \
dvander@954
    24
	if (EncodeValveParam(pContext, \
dvander@954
    25
			params[num], \
dvander@954
    26
			&pCall->which[vnum], \
dvander@954
    27
			vptr + pCall->which[vnum].offset) \
dvander@954
    28
		== Data_Fail) \
dvander@954
    29
	{ \
dvander@954
    30
		return 0; \
dvander@954
    31
	}
dvander@954
    32
dvander@954
    33
#define DECODE_VALVE_PARAM(num, which, vnum) \
dvander@954
    34
	if (DecodeValveParam(pContext, \
dvander@954
    35
			params[num], \
dvander@954
    36
			&pCall->which[vnum], \
dvander@954
    37
			vptr + pCall->which[vnum].offset) \
dvander@954
    38
		== Data_Fail) \
dvander@954
    39
	{ \
dvander@954
    40
		return 0; \
dvander@954
    41
	}
dvander@954
    42
dvander@954
    43
bool CreateBaseCall(const char *name,
dvander@954
    44
						  ValveCallType vcalltype,
dvander@954
    45
						  const ValvePassInfo *retinfo,
dvander@954
    46
						  const ValvePassInfo params[],
dvander@954
    47
						  unsigned int numParams,
dvander@954
    48
						  ValveCall **vaddr)
dvander@954
    49
{
dvander@954
    50
	int offset;
dvander@954
    51
	ValveCall *call;
dvander@954
    52
	if (g_pGameConf->GetOffset(name, &offset))
dvander@954
    53
	{
dvander@954
    54
		call = CreateValveVCall(offset, vcalltype, retinfo, params, numParams);
dvander@954
    55
		if (call)
dvander@954
    56
		{
dvander@954
    57
			g_RegCalls.push_back(call);
dvander@954
    58
		}
dvander@954
    59
		*vaddr = call;
dvander@954
    60
		return true;
dvander@954
    61
	} else {
dvander@954
    62
		void *addr;
dvander@954
    63
		if (g_pGameConf->GetMemSig(name, &addr))
dvander@954
    64
		{
dvander@954
    65
			call = CreateValveCall(addr, vcalltype, retinfo, params, numParams);
dvander@954
    66
			if (call)
dvander@954
    67
			{
dvander@954
    68
				g_RegCalls.push_back(call);
dvander@954
    69
			}
dvander@954
    70
			*vaddr = call;
dvander@954
    71
			return true;
dvander@954
    72
		}
dvander@954
    73
	}
dvander@954
    74
	return false;
dvander@954
    75
}
dvander@954
    76
dvander@954
    77
dvander@954
    78
static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
dvander@954
    79
{
dvander@954
    80
	static ValveCall *pCall = NULL;
dvander@954
    81
	if (!pCall)
dvander@954
    82
	{
dvander@954
    83
		ValvePassInfo pass[2];
dvander@954
    84
		InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, 0);
dvander@954
    85
		InitPass(pass[1], Valve_Bool, PassType_Basic, 0);
dvander@954
    86
		if (!CreateBaseCall("RemovePlayerItem", ValveCall_Player, &pass[1], &pass[0], 1, &pCall))
dvander@954
    87
		{
dvander@954
    88
			return pContext->ThrowNativeError("\"RemovePlayerItem\" not supported by this mod");
dvander@954
    89
		} else if (!pCall) {
dvander@954
    90
			return pContext->ThrowNativeError("\"RemovePlayerItem\" wrapper failed to initialized");
dvander@954
    91
		}
dvander@954
    92
	}
dvander@954
    93
dvander@954
    94
	bool ret;
dvander@954
    95
	START_CALL();
dvander@954
    96
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@954
    97
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@954
    98
	FINISH_CALL_SIMPLE(&ret);
dvander@954
    99
	return ret ? 1 : 0;
dvander@954
   100
}
dvander@954
   101
dvander@954
   102
static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
dvander@954
   103
{
dvander@954
   104
	static ValveCall *pCall = NULL;
dvander@954
   105
	if (!pCall)
dvander@954
   106
	{
dvander@954
   107
		ValvePassInfo pass[3];
dvander@954
   108
		InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   109
		InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   110
		InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   111
		if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[2], pass, 2, &pCall))
dvander@954
   112
		{
dvander@954
   113
			return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod");
dvander@954
   114
		} else if (!pCall) {
dvander@954
   115
			return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialized");
dvander@954
   116
		}
dvander@954
   117
	}
dvander@954
   118
dvander@954
   119
	CBaseEntity *pEntity = NULL;
dvander@954
   120
	START_CALL();
dvander@954
   121
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@954
   122
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@954
   123
	DECODE_VALVE_PARAM(3, vparams, 1);
dvander@954
   124
	FINISH_CALL_SIMPLE(&pEntity);
dvander@954
   125
dvander@954
   126
	if (pEntity == NULL)
dvander@954
   127
	{
dvander@954
   128
		return -1;
dvander@954
   129
	}
dvander@954
   130
dvander@954
   131
	edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
dvander@954
   132
	if (!pEdict)
dvander@954
   133
	{
dvander@954
   134
		return -1;
dvander@954
   135
	}
dvander@954
   136
dvander@954
   137
	return engine->IndexOfEdict(pEdict);
dvander@954
   138
}
dvander@954
   139
dvander@954
   140
static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params)
dvander@954
   141
{
dvander@954
   142
	static ValveCall *pCall = NULL;
dvander@954
   143
	if (!pCall)
dvander@954
   144
	{
dvander@954
   145
		ValvePassInfo pass[2];
dvander@954
   146
		InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   147
		InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
dvander@954
   148
		if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall))
dvander@954
   149
		{
dvander@954
   150
			return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod");
dvander@954
   151
		} else if (!pCall) {
dvander@954
   152
			return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized");
dvander@954
   153
		}
dvander@954
   154
	}
dvander@954
   155
dvander@954
   156
	CBaseEntity *pEntity;
dvander@954
   157
	START_CALL();
dvander@954
   158
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@954
   159
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@954
   160
	FINISH_CALL_SIMPLE(&pEntity);
dvander@954
   161
dvander@954
   162
	if (pEntity == NULL)
dvander@954
   163
	{
dvander@954
   164
		return -1;
dvander@954
   165
	}
dvander@954
   166
dvander@954
   167
	edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
dvander@954
   168
	if (!pEdict)
dvander@954
   169
	{
dvander@954
   170
		return -1;
dvander@954
   171
	}
dvander@954
   172
dvander@954
   173
	return engine->IndexOfEdict(pEdict);
dvander@954
   174
}
dvander@954
   175
dvander@955
   176
static cell_t IgnitePlayer(IPluginContext *pContext, const cell_t *params)
dvander@955
   177
{
dvander@955
   178
	static ValveCall *pCall = NULL;
dvander@955
   179
	if (!pCall)
dvander@955
   180
	{
dvander@955
   181
		ValvePassInfo pass[4];
dvander@955
   182
		InitPass(pass[0], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
dvander@955
   183
		InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
dvander@955
   184
		InitPass(pass[2], Valve_Float, PassType_Float, PASSFLAG_BYVAL);
dvander@955
   185
		InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
dvander@980
   186
		if (!CreateBaseCall("Ignite", ValveCall_Entity, NULL, pass, 4, &pCall))
dvander@955
   187
		{
dvander@955
   188
			return pContext->ThrowNativeError("\"Ignite\" not supported by this mod");
dvander@955
   189
		} else if (!pCall) {
dvander@955
   190
			return pContext->ThrowNativeError("\"Ignite\" wrapper failed to initialized");
dvander@955
   191
		}
dvander@955
   192
	}
dvander@955
   193
dvander@955
   194
	START_CALL();
dvander@955
   195
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@955
   196
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@955
   197
	DECODE_VALVE_PARAM(3, vparams, 1);
dvander@955
   198
	DECODE_VALVE_PARAM(4, vparams, 2);
dvander@955
   199
	DECODE_VALVE_PARAM(5, vparams, 3);
dvander@955
   200
	FINISH_CALL_SIMPLE(NULL);
dvander@955
   201
dvander@955
   202
	return 1;
dvander@955
   203
}
dvander@955
   204
dvander@955
   205
static cell_t ExtinguishPlayer(IPluginContext *pContext, const cell_t *params)
dvander@955
   206
{
dvander@955
   207
	static ValveCall *pCall = NULL;
dvander@955
   208
	if (!pCall)
dvander@955
   209
	{
dvander@980
   210
		if (!CreateBaseCall("Extinguish", ValveCall_Entity, NULL, NULL, 0, &pCall))
dvander@955
   211
		{
dvander@955
   212
			return pContext->ThrowNativeError("\"Extinguish\" not supported by this mod");
dvander@955
   213
		} else if (!pCall) {
dvander@955
   214
			return pContext->ThrowNativeError("\"Extinguish\" wrapper failed to initialized");
dvander@955
   215
		}
dvander@955
   216
	}
dvander@955
   217
dvander@955
   218
	START_CALL();
dvander@955
   219
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@955
   220
	FINISH_CALL_SIMPLE(NULL);
dvander@955
   221
dvander@955
   222
	return 1;
dvander@955
   223
}
dvander@955
   224
dvander@955
   225
static cell_t TeleportPlayer(IPluginContext *pContext, const cell_t *params)
dvander@955
   226
{
dvander@955
   227
	static ValveCall *pCall = NULL;
dvander@955
   228
	if (!pCall)
dvander@955
   229
	{
dvander@955
   230
		ValvePassInfo pass[3];
dvander@955
   231
		InitPass(pass[0], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL);
dvander@955
   232
		InitPass(pass[1], Valve_QAngle, PassType_Basic, PASSFLAG_BYVAL);
dvander@955
   233
		InitPass(pass[2], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL);
dvander@980
   234
		if (!CreateBaseCall("Teleport", ValveCall_Entity, NULL, pass, 3, &pCall))
dvander@955
   235
		{
dvander@955
   236
			return pContext->ThrowNativeError("\"Teleport\" not supported by this mod");
dvander@955
   237
		} else if (!pCall) {
dvander@955
   238
			return pContext->ThrowNativeError("\"Teleport\" wrapper failed to initialized");
dvander@955
   239
		}
dvander@955
   240
	}
dvander@955
   241
dvander@955
   242
	START_CALL();
dvander@955
   243
	DECODE_VALVE_PARAM(1, thisinfo, 0);
dvander@955
   244
	DECODE_VALVE_PARAM(2, vparams, 0);
dvander@955
   245
	DECODE_VALVE_PARAM(3, vparams, 1);
dvander@955
   246
	DECODE_VALVE_PARAM(4, vparams, 2);
dvander@955
   247
	FINISH_CALL_SIMPLE(NULL);
dvander@955
   248
dvander@955
   249
	return 1;
dvander@955
   250
}
dvander@955
   251
dvander@954
   252
sp_nativeinfo_t g_Natives[] = 
dvander@954
   253
{
dvander@955
   254
	{"ExtinguishPlayer",	ExtinguishPlayer},
dvander@980
   255
	{"ExtinguishEntity",	ExtinguishPlayer},
dvander@954
   256
	{"GivePlayerItem",		GiveNamedItem},
dvander@954
   257
	{"GetPlayerWeaponSlot",	GetPlayerWeaponSlot},
dvander@955
   258
	{"IgnitePlayer",		IgnitePlayer},
dvander@980
   259
	{"IgniteEntity",		IgnitePlayer},
dvander@955
   260
	{"RemovePlayerItem",	RemovePlayerItem},
dvander@955
   261
	{"TeleportPlayer",		TeleportPlayer},
dvander@980
   262
	{"TeleportEntity",		TeleportPlayer},
dvander@954
   263
	{NULL,					NULL},
dvander@954
   264
};
dvander@980
   265