extensions/sdktools/trnatives.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
dvander@1859
     1
/**
dvander@1859
     2
 * vim: set ts=4 :
dvander@1859
     3
 * =============================================================================
dvander@1859
     4
 * SourceMod SDKTools Extension
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
dvander@1859
     6
 * =============================================================================
dvander@1859
     7
 *
dvander@1859
     8
 * This program is free software; you can redistribute it and/or modify it under
dvander@1859
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
dvander@1859
    10
 * Free Software Foundation.
dvander@1859
    11
 * 
dvander@1859
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
dvander@1859
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@1859
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
dvander@1859
    15
 * details.
dvander@1859
    16
 *
dvander@1859
    17
 * You should have received a copy of the GNU General Public License along with
dvander@1859
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1859
    19
 *
dvander@1859
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
dvander@1859
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
dvander@1859
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
dvander@1859
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
dvander@1859
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
dvander@1859
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
dvander@1859
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
dvander@1859
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@1859
    28
 *
dvander@1859
    29
 * Version: $Id$
dvander@1859
    30
 */
dvander@1859
    31
dvander@1859
    32
#include "extension.h"
dvander@1859
    33
#include <worldsize.h>
dvander@1859
    34
dvander@1859
    35
class CSMTraceFilter : public CTraceFilter
dvander@1859
    36
{
dvander@1859
    37
public:
dvander@1859
    38
	bool ShouldHitEntity(IHandleEntity *pEntity, int contentsMask)
dvander@1859
    39
	{
dvander@1859
    40
		cell_t res = 1;
dvander@1859
    41
		edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(pEntity));
dvander@1859
    42
		m_pFunc->PushCell(engine->IndexOfEdict(pEdict));
dvander@1859
    43
		m_pFunc->PushCell(contentsMask);
dvander@1859
    44
		m_pFunc->PushCell(m_Data);
dvander@1859
    45
		m_pFunc->Execute(&res);
dvander@1859
    46
dvander@1859
    47
		return (res) ? true : false;
dvander@1859
    48
	}
dvander@1859
    49
	void SetFunctionPtr(IPluginFunction *pFunc, cell_t data)
dvander@1859
    50
	{
dvander@1859
    51
		m_pFunc = pFunc;
dvander@1859
    52
		m_Data = data;
dvander@1859
    53
	}
dvander@1859
    54
private:
dvander@1859
    55
	IPluginFunction *m_pFunc;
dvander@1859
    56
	cell_t m_Data;
dvander@1859
    57
};
dvander@1859
    58
dvander@1859
    59
/* Used for the global trace version */
dvander@1859
    60
Ray_t g_Ray;
dvander@1859
    61
trace_t g_Trace;
dvander@1859
    62
Vector g_StartVec;
dvander@1859
    63
Vector g_EndVec;
dvander@2089
    64
Vector g_HullMins;
dvander@2089
    65
Vector g_HullMaxs;
dvander@1859
    66
QAngle g_DirAngles;
dvander@1859
    67
CTraceFilterHitAll g_HitAllFilter;
dvander@1859
    68
CSMTraceFilter g_SMTraceFilter;
dvander@1859
    69
dvander@1859
    70
enum
dvander@1859
    71
{
dvander@1859
    72
	RayType_EndPoint,
dvander@1859
    73
	RayType_Infinite
dvander@1859
    74
};
dvander@1859
    75
dvander@1859
    76
static cell_t smn_TRTraceRay(IPluginContext *pContext, const cell_t *params)
dvander@1859
    77
{
dvander@1859
    78
	cell_t *startaddr, *endaddr;
dvander@1859
    79
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859
    80
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859
    81
dvander@1859
    82
	g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859
    83
dvander@1859
    84
	switch (params[4])
dvander@1859
    85
	{
dvander@1859
    86
	case RayType_EndPoint:
dvander@1859
    87
		{
dvander@1859
    88
			g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
    89
			break;
dvander@1859
    90
		}
dvander@1859
    91
	case RayType_Infinite:
dvander@1859
    92
		{
dvander@1859
    93
			g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
    94
			AngleVectors(g_DirAngles, &g_EndVec);
dvander@1859
    95
dvander@1859
    96
			/* Make it unitary and get the ending point */
dvander@1859
    97
			g_EndVec.NormalizeInPlace();
dvander@1859
    98
			g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH;
dvander@1859
    99
			break;
dvander@1859
   100
		}
dvander@1859
   101
	}
dvander@1859
   102
dvander@1859
   103
	g_Ray.Init(g_StartVec, g_EndVec);
dvander@1859
   104
	enginetrace->TraceRay(g_Ray, params[3], &g_HitAllFilter, &g_Trace);
dvander@1859
   105
dvander@1859
   106
	return 1;
dvander@1859
   107
}
dvander@1859
   108
dvander@2089
   109
static cell_t smn_TRTraceHull(IPluginContext *pContext, const cell_t *params)
dvander@2089
   110
{
dvander@2089
   111
	cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089
   112
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089
   113
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089
   114
	pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089
   115
	pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089
   116
dvander@2089
   117
	g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089
   118
	g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089
   119
	g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089
   120
	g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089
   121
dvander@2089
   122
	g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs);
dvander@2089
   123
	enginetrace->TraceRay(g_Ray, params[5], &g_HitAllFilter, &g_Trace);
dvander@2089
   124
dvander@2089
   125
	return 1;
dvander@2089
   126
}
dvander@2089
   127
dvander@1859
   128
static cell_t smn_TRTraceRayFilter(IPluginContext *pContext, const cell_t *params)
dvander@1859
   129
{
dvander@1859
   130
	cell_t *startaddr, *endaddr;
dvander@1859
   131
	IPluginFunction *pFunc;
dvander@1859
   132
	cell_t data;
dvander@1859
   133
dvander@1859
   134
	pFunc = pContext->GetFunctionById(params[5]);
dvander@1859
   135
	if (!pFunc)
dvander@1859
   136
	{
dvander@1859
   137
		return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@1859
   138
	}
dvander@1859
   139
dvander@1859
   140
	if (params[0] >= 6)
dvander@1859
   141
	{
dvander@1859
   142
		data = params[6];
dvander@1859
   143
	}
dvander@1859
   144
	else
dvander@1859
   145
	{
dvander@1859
   146
		data = 0;
dvander@1859
   147
	}
dvander@1859
   148
dvander@1859
   149
	g_SMTraceFilter.SetFunctionPtr(pFunc, data);
dvander@1859
   150
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859
   151
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859
   152
dvander@1859
   153
	g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859
   154
dvander@1859
   155
	switch (params[4])
dvander@1859
   156
	{
dvander@1859
   157
	case RayType_EndPoint:
dvander@1859
   158
		{
dvander@1859
   159
			g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   160
			break;
dvander@1859
   161
		}
dvander@1859
   162
	case RayType_Infinite:
dvander@1859
   163
		{
dvander@1859
   164
			g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   165
			AngleVectors(g_DirAngles, &g_EndVec);
dvander@1859
   166
dvander@1859
   167
			/* Make it unitary and get the ending point */
dvander@1859
   168
			g_EndVec.NormalizeInPlace();
dvander@1859
   169
			g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH;
dvander@1859
   170
			break;
dvander@1859
   171
		}
dvander@1859
   172
	}
dvander@1859
   173
dvander@1859
   174
	g_Ray.Init(g_StartVec, g_EndVec);
dvander@1859
   175
	enginetrace->TraceRay(g_Ray, params[3], &g_SMTraceFilter, &g_Trace);
dvander@1859
   176
dvander@1859
   177
	return 1;
dvander@1859
   178
}
dvander@1859
   179
dvander@2089
   180
static cell_t smn_TRTraceHullFilter(IPluginContext *pContext, const cell_t *params)
dvander@2089
   181
{
dvander@2089
   182
	cell_t data;
dvander@2089
   183
	IPluginFunction *pFunc;
dvander@2089
   184
	cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089
   185
dvander@2089
   186
	pFunc = pContext->GetFunctionById(params[6]);
dvander@2089
   187
	if (!pFunc)
dvander@2089
   188
	{
dvander@2089
   189
		return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@2089
   190
	}
dvander@2089
   191
dvander@2089
   192
	data = params[7];
dvander@2089
   193
dvander@2089
   194
	g_SMTraceFilter.SetFunctionPtr(pFunc, data);
dvander@2089
   195
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089
   196
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089
   197
	pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089
   198
	pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089
   199
dvander@2089
   200
	g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089
   201
	g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089
   202
	g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089
   203
	g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089
   204
dvander@2089
   205
	g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs);
dvander@2089
   206
	enginetrace->TraceRay(g_Ray, params[5], &g_SMTraceFilter, &g_Trace);
dvander@2089
   207
dvander@2089
   208
	return 1;
dvander@2089
   209
}
dvander@2089
   210
dvander@2089
   211
dvander@1859
   212
static cell_t smn_TRTraceRayEx(IPluginContext *pContext, const cell_t *params)
dvander@1859
   213
{
dvander@1859
   214
	cell_t *startaddr, *endaddr;
dvander@1859
   215
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859
   216
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859
   217
dvander@1859
   218
	Vector StartVec, EndVec;
dvander@1859
   219
	Ray_t ray;
dvander@1859
   220
dvander@1859
   221
	StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859
   222
dvander@1859
   223
	switch (params[4])
dvander@1859
   224
	{
dvander@1859
   225
	case RayType_EndPoint:
dvander@1859
   226
		{
dvander@1859
   227
			EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   228
			break;
dvander@1859
   229
		}
dvander@1859
   230
	case RayType_Infinite:
dvander@1859
   231
		{
dvander@1859
   232
			QAngle DirAngles;
dvander@1859
   233
			DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   234
			AngleVectors(DirAngles, &EndVec);
dvander@1859
   235
dvander@1859
   236
			/* Make it unitary and get the ending point */
dvander@1859
   237
			EndVec.NormalizeInPlace();
dvander@1859
   238
			EndVec = StartVec + EndVec * MAX_TRACE_LENGTH;
dvander@1859
   239
			break;
dvander@1859
   240
		}
dvander@1859
   241
	}
dvander@1859
   242
dvander@1859
   243
	trace_t *tr = new trace_t;
dvander@1859
   244
	ray.Init(StartVec, EndVec);
dvander@1859
   245
	enginetrace->TraceRay(ray, params[3], &g_HitAllFilter, tr);
dvander@1859
   246
dvander@1859
   247
	HandleError herr;
dvander@1859
   248
	Handle_t hndl;
dvander@1859
   249
	if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@1859
   250
	{
dvander@1859
   251
		delete tr;
dvander@1859
   252
		return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@1859
   253
	}
dvander@1859
   254
dvander@1859
   255
	return hndl;
dvander@1859
   256
}
dvander@1859
   257
dvander@2089
   258
static cell_t smn_TRTraceHullEx(IPluginContext *pContext, const cell_t *params)
dvander@2089
   259
{
dvander@2089
   260
	cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089
   261
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089
   262
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089
   263
	pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089
   264
	pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089
   265
dvander@2089
   266
	Ray_t ray;
dvander@2089
   267
	Vector StartVec, EndVec, vmins, vmaxs;
dvander@2089
   268
dvander@2089
   269
	StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089
   270
	vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089
   271
	vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089
   272
	EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089
   273
dvander@2089
   274
	ray.Init(StartVec, EndVec, vmins, vmaxs);
dvander@2089
   275
dvander@2089
   276
	trace_t *tr = new trace_t;
dvander@2089
   277
	enginetrace->TraceRay(ray, params[5], &g_HitAllFilter, tr);
dvander@2089
   278
dvander@2089
   279
	HandleError herr;
dvander@2089
   280
	Handle_t hndl;
dvander@2089
   281
	if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@2089
   282
	{
dvander@2089
   283
		delete tr;
dvander@2089
   284
		return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@2089
   285
	}
dvander@2089
   286
dvander@2089
   287
	return hndl;
dvander@2089
   288
}
dvander@2089
   289
dvander@1859
   290
static cell_t smn_TRTraceRayFilterEx(IPluginContext *pContext, const cell_t *params)
dvander@1859
   291
{
dvander@1859
   292
	IPluginFunction *pFunc;
dvander@1859
   293
	cell_t *startaddr, *endaddr;
dvander@1859
   294
	cell_t data;
dvander@1859
   295
dvander@1859
   296
	pFunc = pContext->GetFunctionById(params[5]);
dvander@1859
   297
	if (!pFunc)
dvander@1859
   298
	{
dvander@1859
   299
		return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@1859
   300
	}
dvander@1859
   301
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859
   302
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859
   303
dvander@1859
   304
	Vector StartVec, EndVec;
dvander@1859
   305
	CSMTraceFilter smfilter;
dvander@1859
   306
	Ray_t ray;
dvander@1859
   307
dvander@1859
   308
	if (params[0] >= 6)
dvander@1859
   309
	{
dvander@1859
   310
		data = params[6];
dvander@1859
   311
	}
dvander@1859
   312
	else
dvander@1859
   313
	{
dvander@1859
   314
		data = 0;
dvander@1859
   315
	}
dvander@1859
   316
dvander@1859
   317
	smfilter.SetFunctionPtr(pFunc, data);
dvander@1859
   318
	StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859
   319
dvander@1859
   320
	switch (params[4])
dvander@1859
   321
	{
dvander@1859
   322
	case RayType_EndPoint:
dvander@1859
   323
		{
dvander@1859
   324
			EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   325
			break;
dvander@1859
   326
		}
dvander@1859
   327
	case RayType_Infinite:
dvander@1859
   328
		{
dvander@1859
   329
			QAngle DirAngles;
dvander@1859
   330
			DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   331
			AngleVectors(DirAngles, &EndVec);
dvander@1859
   332
dvander@1859
   333
			/* Make it unitary and get the ending point */
dvander@1859
   334
			EndVec.NormalizeInPlace();
dvander@1859
   335
			EndVec = StartVec + EndVec * MAX_TRACE_LENGTH;
dvander@1859
   336
			break;
dvander@1859
   337
		}
dvander@1859
   338
	}
dvander@1859
   339
dvander@1859
   340
	trace_t *tr = new trace_t;
dvander@1859
   341
	ray.Init(StartVec, EndVec);
dvander@1859
   342
	enginetrace->TraceRay(ray, params[3], &smfilter, tr);
dvander@1859
   343
dvander@1859
   344
	HandleError herr;
dvander@1859
   345
	Handle_t hndl;
dvander@1859
   346
	if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@1859
   347
	{
dvander@1859
   348
		delete tr;
dvander@1859
   349
		return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@1859
   350
	}
dvander@1859
   351
dvander@1859
   352
	return hndl;
dvander@1859
   353
}
dvander@1859
   354
dvander@2089
   355
static cell_t smn_TRTraceHullFilterEx(IPluginContext *pContext, const cell_t *params)
dvander@2089
   356
{
dvander@2089
   357
	IPluginFunction *pFunc;
dvander@2089
   358
	cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089
   359
	cell_t data;
dvander@2089
   360
dvander@2089
   361
	pFunc = pContext->GetFunctionById(params[6]);
dvander@2089
   362
	if (!pFunc)
dvander@2089
   363
	{
dvander@2089
   364
		return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@2089
   365
	}
dvander@2089
   366
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089
   367
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089
   368
	pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089
   369
	pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089
   370
dvander@2089
   371
	Vector StartVec, EndVec, vmins, vmaxs;
dvander@2089
   372
	CSMTraceFilter smfilter;
dvander@2089
   373
	Ray_t ray;
dvander@2089
   374
dvander@2089
   375
	data = params[7];
dvander@2089
   376
dvander@2089
   377
	smfilter.SetFunctionPtr(pFunc, data);
dvander@2089
   378
	StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089
   379
	vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089
   380
	vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089
   381
	EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089
   382
dvander@2089
   383
	ray.Init(StartVec, EndVec, vmins, vmaxs);
dvander@2089
   384
dvander@2089
   385
	trace_t *tr = new trace_t;
dvander@2089
   386
	enginetrace->TraceRay(ray, params[5], &smfilter, tr);
dvander@2089
   387
dvander@2089
   388
	HandleError herr;
dvander@2089
   389
	Handle_t hndl;
dvander@2089
   390
	if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@2089
   391
	{
dvander@2089
   392
		delete tr;
dvander@2089
   393
		return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@2089
   394
	}
dvander@2089
   395
dvander@2089
   396
	return hndl;
dvander@2089
   397
}
dvander@2089
   398
dvander@1859
   399
static cell_t smn_TRGetFraction(IPluginContext *pContext, const cell_t *params)
dvander@1859
   400
{
dvander@1859
   401
	trace_t *tr;
dvander@1859
   402
	HandleError err;
dvander@1859
   403
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   404
dvander@1859
   405
	if (params[1] == BAD_HANDLE)
dvander@1859
   406
	{
dvander@1859
   407
		tr = &g_Trace;
dvander@1859
   408
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   409
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   410
	}
dvander@1859
   411
dvander@1859
   412
	return sp_ftoc(tr->fraction);
dvander@1859
   413
}
dvander@1859
   414
dvander@1859
   415
static cell_t smn_TRGetPlaneNormal(IPluginContext *pContext, const cell_t *params)
dvander@1859
   416
{
dvander@1859
   417
	trace_t *tr;
dvander@1859
   418
	HandleError err;
dvander@1859
   419
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   420
dvander@1859
   421
	if (params[1] == BAD_HANDLE)
dvander@1859
   422
	{
dvander@1859
   423
		tr = &g_Trace;
dvander@1859
   424
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   425
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   426
	}
dvander@1859
   427
dvander@1859
   428
	Vector *normal = &tr->plane.normal;
dvander@1859
   429
dvander@1859
   430
	cell_t *r;
dvander@1859
   431
	pContext->LocalToPhysAddr(params[2], &r);
dvander@1859
   432
	r[0] = sp_ftoc(normal->x);
dvander@1859
   433
	r[1] = sp_ftoc(normal->y);
dvander@1859
   434
	r[2] = sp_ftoc(normal->z);
dvander@1859
   435
dvander@1859
   436
	return 1;
dvander@1859
   437
}
dvander@1859
   438
dvander@1859
   439
dvander@1859
   440
static cell_t smn_TRGetEndPosition(IPluginContext *pContext, const cell_t *params)
dvander@1859
   441
{
dvander@1859
   442
	trace_t *tr;
dvander@1859
   443
	HandleError err;
dvander@1859
   444
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   445
dvander@1859
   446
	if (params[2] == BAD_HANDLE)
dvander@1859
   447
	{
dvander@1859
   448
		tr = &g_Trace;
dvander@1859
   449
	} else if ((err = handlesys->ReadHandle(params[2], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   450
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[2], err);
dvander@1859
   451
	}
dvander@1859
   452
dvander@1859
   453
	cell_t *addr;
dvander@1859
   454
	pContext->LocalToPhysAddr(params[1], &addr);
dvander@1859
   455
dvander@1859
   456
	addr[0] = sp_ftoc(tr->endpos.x);
dvander@1859
   457
	addr[1] = sp_ftoc(tr->endpos.y);
dvander@1859
   458
	addr[2] = sp_ftoc(tr->endpos.z);
dvander@1859
   459
dvander@1859
   460
	return 1;
dvander@1859
   461
}
dvander@1859
   462
dvander@1859
   463
static cell_t smn_TRDidHit(IPluginContext *pContext, const cell_t *params)
dvander@1859
   464
{
dvander@1859
   465
	trace_t *tr;
dvander@1859
   466
	HandleError err;
dvander@1859
   467
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   468
dvander@1859
   469
	if (params[1] == BAD_HANDLE)
dvander@1859
   470
	{
dvander@1859
   471
		tr = &g_Trace;
dvander@1859
   472
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   473
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   474
	}
dvander@1859
   475
dvander@1859
   476
	return tr->DidHit() ? 1 : 0;
dvander@1859
   477
}
dvander@1859
   478
dvander@1859
   479
static cell_t smn_TRGetHitGroup(IPluginContext *pContext, const cell_t *params)
dvander@1859
   480
{
dvander@1859
   481
	trace_t *tr;
dvander@1859
   482
	HandleError err;
dvander@1859
   483
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   484
dvander@1859
   485
	if (params[1] == BAD_HANDLE)
dvander@1859
   486
	{
dvander@1859
   487
		tr = &g_Trace;
dvander@1859
   488
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   489
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   490
	}
dvander@1859
   491
dvander@1859
   492
	return tr->hitgroup;
dvander@1859
   493
}
dvander@1859
   494
dvander@1859
   495
static cell_t smn_TRGetEntityIndex(IPluginContext *pContext, const cell_t *params)
dvander@1859
   496
{
dvander@1859
   497
	trace_t *tr;
dvander@1859
   498
	HandleError err;
dvander@1859
   499
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   500
dvander@1859
   501
	if (params[1] == BAD_HANDLE)
dvander@1859
   502
	{
dvander@1859
   503
		tr = &g_Trace;
dvander@1859
   504
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   505
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   506
	}
dvander@1859
   507
dvander@1859
   508
	edict_t *pEdict = gameents->BaseEntityToEdict(tr->m_pEnt);
dvander@1859
   509
	return engine->IndexOfEdict(pEdict);
dvander@1859
   510
}
dvander@1859
   511
dvander@1859
   512
static cell_t smn_TRGetPointContents(IPluginContext *pContext, const cell_t *params)
dvander@1859
   513
{
dvander@1859
   514
	cell_t *vec, *ent;
dvander@1859
   515
	IHandleEntity *hentity;
dvander@1859
   516
	Vector pos;
dvander@1859
   517
	int mask;
dvander@1859
   518
dvander@1859
   519
	pContext->LocalToPhysAddr(params[1], &vec);
dvander@1859
   520
	pContext->LocalToPhysAddr(params[2], &ent);
dvander@1859
   521
dvander@1859
   522
	pos.x = sp_ctof(vec[0]);
dvander@1859
   523
	pos.y = sp_ctof(vec[1]);
dvander@1859
   524
	pos.z = sp_ctof(vec[2]);
dvander@1859
   525
dvander@1859
   526
	if (*ent == -1)
dvander@1859
   527
	{
dvander@1859
   528
		mask = enginetrace->GetPointContents(pos);
dvander@1859
   529
	} else {
dvander@1859
   530
		mask = enginetrace->GetPointContents(pos, &hentity);
dvander@1859
   531
		edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(hentity));
dvander@1859
   532
		*ent = engine->IndexOfEdict(pEdict);
dvander@1859
   533
	}
dvander@1859
   534
dvander@1859
   535
	return mask;
dvander@1859
   536
}
dvander@1859
   537
dvander@1859
   538
static cell_t smn_TRGetPointContentsEnt(IPluginContext *pContext, const cell_t *params)
dvander@1859
   539
{
dvander@1859
   540
	edict_t *pEdict = engine->PEntityOfEntIndex(params[1]);
dvander@1859
   541
	if (!pEdict || pEdict->IsFree())
dvander@1859
   542
	{
dvander@1859
   543
		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
dvander@1859
   544
	}
dvander@1859
   545
dvander@1859
   546
	cell_t *addr;
dvander@1859
   547
	Vector pos;
dvander@1859
   548
dvander@1859
   549
	pContext->LocalToPhysAddr(params[2], &addr);
dvander@1859
   550
dvander@1859
   551
	pos.x = sp_ctof(addr[0]);
dvander@1859
   552
	pos.y = sp_ctof(addr[1]);
dvander@1859
   553
	pos.z = sp_ctof(addr[2]);
dvander@1859
   554
dvander@1859
   555
	return enginetrace->GetPointContents_Collideable(pEdict->GetCollideable(), pos);
dvander@1859
   556
}
dvander@1859
   557
dvander@1859
   558
sp_nativeinfo_t g_TRNatives[] = 
dvander@1859
   559
{
dvander@1859
   560
	{"TR_TraceRay",				smn_TRTraceRay},
dvander@2089
   561
	{"TR_TraceHull",			smn_TRTraceHull},
dvander@1859
   562
	{"TR_TraceRayEx",			smn_TRTraceRayEx},
dvander@2089
   563
	{"TR_TraceHullEx",			smn_TRTraceHullEx},
dvander@1859
   564
	{"TR_GetFraction",			smn_TRGetFraction},
dvander@1859
   565
	{"TR_GetEndPosition",		smn_TRGetEndPosition},
dvander@1859
   566
	{"TR_GetEntityIndex",		smn_TRGetEntityIndex},
dvander@1859
   567
	{"TR_DidHit",				smn_TRDidHit},
dvander@1859
   568
	{"TR_GetHitGroup",			smn_TRGetHitGroup},
dvander@1859
   569
	{"TR_GetPointContents",		smn_TRGetPointContents},
dvander@1859
   570
	{"TR_GetPointContentsEnt",	smn_TRGetPointContentsEnt},
dvander@1859
   571
	{"TR_TraceRayFilter",		smn_TRTraceRayFilter},
dvander@1859
   572
	{"TR_TraceRayFilterEx",		smn_TRTraceRayFilterEx},
dvander@2089
   573
	{"TR_TraceHullFilter",		smn_TRTraceHullFilter},
dvander@2089
   574
	{"TR_TraceHullFilterEx",	smn_TRTraceHullFilterEx},
dvander@1859
   575
	{"TR_GetPlaneNormal",		smn_TRGetPlaneNormal},
dvander@1859
   576
	{NULL,						NULL}
dvander@1859
   577
};