extensions/sdktools/trnatives.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Fri Jul 08 07:53:31 2011 -0400 (2011-07-08)
changeset 3348 fcae86e8cb8f
parent 3099 1b7bf8509625
permissions -rw-r--r--
Backed out changeset: 9007dacc012d
dvander@1859
     1
/**
dvander@1859
     2
 * vim: set ts=4 :
dvander@1859
     3
 * =============================================================================
dvander@1859
     4
 * SourceMod SDKTools Extension
ds@3099
     5
 * Copyright (C) 2004-2010 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;
pred@2746
    41
		m_pFunc->PushCell(gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(pEntity)));
dvander@1859
    42
		m_pFunc->PushCell(contentsMask);
dvander@1859
    43
		m_pFunc->PushCell(m_Data);
dvander@1859
    44
		m_pFunc->Execute(&res);
dvander@1859
    45
dvander@1859
    46
		return (res) ? true : false;
dvander@1859
    47
	}
dvander@1859
    48
	void SetFunctionPtr(IPluginFunction *pFunc, cell_t data)
dvander@1859
    49
	{
dvander@1859
    50
		m_pFunc = pFunc;
dvander@1859
    51
		m_Data = data;
dvander@1859
    52
	}
dvander@1859
    53
private:
dvander@1859
    54
	IPluginFunction *m_pFunc;
dvander@1859
    55
	cell_t m_Data;
dvander@1859
    56
};
dvander@1859
    57
dvander@1859
    58
/* Used for the global trace version */
dvander@1859
    59
Ray_t g_Ray;
dvander@1859
    60
trace_t g_Trace;
dvander@1859
    61
Vector g_StartVec;
dvander@1859
    62
Vector g_EndVec;
dvander@2089
    63
Vector g_HullMins;
dvander@2089
    64
Vector g_HullMaxs;
dvander@1859
    65
QAngle g_DirAngles;
dvander@1859
    66
CTraceFilterHitAll g_HitAllFilter;
dvander@1859
    67
CSMTraceFilter g_SMTraceFilter;
dvander@1859
    68
dvander@1859
    69
enum
dvander@1859
    70
{
dvander@1859
    71
	RayType_EndPoint,
dvander@1859
    72
	RayType_Infinite
dvander@1859
    73
};
dvander@1859
    74
dvander@1859
    75
static cell_t smn_TRTraceRay(IPluginContext *pContext, const cell_t *params)
dvander@1859
    76
{
dvander@1859
    77
	cell_t *startaddr, *endaddr;
dvander@1859
    78
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859
    79
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859
    80
dvander@1859
    81
	g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859
    82
dvander@1859
    83
	switch (params[4])
dvander@1859
    84
	{
dvander@1859
    85
	case RayType_EndPoint:
dvander@1859
    86
		{
dvander@1859
    87
			g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
    88
			break;
dvander@1859
    89
		}
dvander@1859
    90
	case RayType_Infinite:
dvander@1859
    91
		{
dvander@1859
    92
			g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
    93
			AngleVectors(g_DirAngles, &g_EndVec);
dvander@1859
    94
dvander@1859
    95
			/* Make it unitary and get the ending point */
dvander@1859
    96
			g_EndVec.NormalizeInPlace();
dvander@1859
    97
			g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH;
dvander@1859
    98
			break;
dvander@1859
    99
		}
dvander@1859
   100
	}
dvander@1859
   101
dvander@1859
   102
	g_Ray.Init(g_StartVec, g_EndVec);
dvander@1859
   103
	enginetrace->TraceRay(g_Ray, params[3], &g_HitAllFilter, &g_Trace);
dvander@1859
   104
dvander@1859
   105
	return 1;
dvander@1859
   106
}
dvander@1859
   107
dvander@2089
   108
static cell_t smn_TRTraceHull(IPluginContext *pContext, const cell_t *params)
dvander@2089
   109
{
dvander@2089
   110
	cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089
   111
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089
   112
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089
   113
	pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089
   114
	pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089
   115
dvander@2089
   116
	g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089
   117
	g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089
   118
	g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089
   119
	g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089
   120
dvander@2089
   121
	g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs);
dvander@2089
   122
	enginetrace->TraceRay(g_Ray, params[5], &g_HitAllFilter, &g_Trace);
dvander@2089
   123
dvander@2089
   124
	return 1;
dvander@2089
   125
}
dvander@2089
   126
dvander@1859
   127
static cell_t smn_TRTraceRayFilter(IPluginContext *pContext, const cell_t *params)
dvander@1859
   128
{
dvander@1859
   129
	cell_t *startaddr, *endaddr;
dvander@1859
   130
	IPluginFunction *pFunc;
dvander@1859
   131
	cell_t data;
dvander@1859
   132
dvander@1859
   133
	pFunc = pContext->GetFunctionById(params[5]);
dvander@1859
   134
	if (!pFunc)
dvander@1859
   135
	{
dvander@1859
   136
		return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@1859
   137
	}
dvander@1859
   138
dvander@1859
   139
	if (params[0] >= 6)
dvander@1859
   140
	{
dvander@1859
   141
		data = params[6];
dvander@1859
   142
	}
dvander@1859
   143
	else
dvander@1859
   144
	{
dvander@1859
   145
		data = 0;
dvander@1859
   146
	}
dvander@1859
   147
dvander@1859
   148
	g_SMTraceFilter.SetFunctionPtr(pFunc, data);
dvander@1859
   149
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859
   150
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859
   151
dvander@1859
   152
	g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859
   153
dvander@1859
   154
	switch (params[4])
dvander@1859
   155
	{
dvander@1859
   156
	case RayType_EndPoint:
dvander@1859
   157
		{
dvander@1859
   158
			g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   159
			break;
dvander@1859
   160
		}
dvander@1859
   161
	case RayType_Infinite:
dvander@1859
   162
		{
dvander@1859
   163
			g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   164
			AngleVectors(g_DirAngles, &g_EndVec);
dvander@1859
   165
dvander@1859
   166
			/* Make it unitary and get the ending point */
dvander@1859
   167
			g_EndVec.NormalizeInPlace();
dvander@1859
   168
			g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH;
dvander@1859
   169
			break;
dvander@1859
   170
		}
dvander@1859
   171
	}
dvander@1859
   172
dvander@1859
   173
	g_Ray.Init(g_StartVec, g_EndVec);
dvander@1859
   174
	enginetrace->TraceRay(g_Ray, params[3], &g_SMTraceFilter, &g_Trace);
dvander@1859
   175
dvander@1859
   176
	return 1;
dvander@1859
   177
}
dvander@1859
   178
dvander@2089
   179
static cell_t smn_TRTraceHullFilter(IPluginContext *pContext, const cell_t *params)
dvander@2089
   180
{
dvander@2089
   181
	cell_t data;
dvander@2089
   182
	IPluginFunction *pFunc;
dvander@2089
   183
	cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089
   184
dvander@2089
   185
	pFunc = pContext->GetFunctionById(params[6]);
dvander@2089
   186
	if (!pFunc)
dvander@2089
   187
	{
dvander@2089
   188
		return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@2089
   189
	}
dvander@2089
   190
dvander@2089
   191
	data = params[7];
dvander@2089
   192
dvander@2089
   193
	g_SMTraceFilter.SetFunctionPtr(pFunc, data);
dvander@2089
   194
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089
   195
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089
   196
	pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089
   197
	pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089
   198
dvander@2089
   199
	g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089
   200
	g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089
   201
	g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089
   202
	g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089
   203
dvander@2089
   204
	g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs);
dvander@2089
   205
	enginetrace->TraceRay(g_Ray, params[5], &g_SMTraceFilter, &g_Trace);
dvander@2089
   206
dvander@2089
   207
	return 1;
dvander@2089
   208
}
dvander@2089
   209
dvander@2089
   210
dvander@1859
   211
static cell_t smn_TRTraceRayEx(IPluginContext *pContext, const cell_t *params)
dvander@1859
   212
{
dvander@1859
   213
	cell_t *startaddr, *endaddr;
dvander@1859
   214
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859
   215
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859
   216
dvander@1859
   217
	Vector StartVec, EndVec;
dvander@1859
   218
	Ray_t ray;
dvander@1859
   219
dvander@1859
   220
	StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859
   221
dvander@1859
   222
	switch (params[4])
dvander@1859
   223
	{
dvander@1859
   224
	case RayType_EndPoint:
dvander@1859
   225
		{
dvander@1859
   226
			EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   227
			break;
dvander@1859
   228
		}
dvander@1859
   229
	case RayType_Infinite:
dvander@1859
   230
		{
dvander@1859
   231
			QAngle DirAngles;
dvander@1859
   232
			DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   233
			AngleVectors(DirAngles, &EndVec);
dvander@1859
   234
dvander@1859
   235
			/* Make it unitary and get the ending point */
dvander@1859
   236
			EndVec.NormalizeInPlace();
dvander@1859
   237
			EndVec = StartVec + EndVec * MAX_TRACE_LENGTH;
dvander@1859
   238
			break;
dvander@1859
   239
		}
dvander@1859
   240
	}
dvander@1859
   241
dvander@1859
   242
	trace_t *tr = new trace_t;
dvander@1859
   243
	ray.Init(StartVec, EndVec);
dvander@1859
   244
	enginetrace->TraceRay(ray, params[3], &g_HitAllFilter, tr);
dvander@1859
   245
dvander@1859
   246
	HandleError herr;
dvander@1859
   247
	Handle_t hndl;
dvander@1859
   248
	if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@1859
   249
	{
dvander@1859
   250
		delete tr;
dvander@1859
   251
		return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@1859
   252
	}
dvander@1859
   253
dvander@1859
   254
	return hndl;
dvander@1859
   255
}
dvander@1859
   256
dvander@2089
   257
static cell_t smn_TRTraceHullEx(IPluginContext *pContext, const cell_t *params)
dvander@2089
   258
{
dvander@2089
   259
	cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089
   260
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089
   261
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089
   262
	pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089
   263
	pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089
   264
dvander@2089
   265
	Ray_t ray;
dvander@2089
   266
	Vector StartVec, EndVec, vmins, vmaxs;
dvander@2089
   267
dvander@2089
   268
	StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089
   269
	vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089
   270
	vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089
   271
	EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089
   272
dvander@2089
   273
	ray.Init(StartVec, EndVec, vmins, vmaxs);
dvander@2089
   274
dvander@2089
   275
	trace_t *tr = new trace_t;
dvander@2089
   276
	enginetrace->TraceRay(ray, params[5], &g_HitAllFilter, tr);
dvander@2089
   277
dvander@2089
   278
	HandleError herr;
dvander@2089
   279
	Handle_t hndl;
dvander@2089
   280
	if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@2089
   281
	{
dvander@2089
   282
		delete tr;
dvander@2089
   283
		return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@2089
   284
	}
dvander@2089
   285
dvander@2089
   286
	return hndl;
dvander@2089
   287
}
dvander@2089
   288
dvander@1859
   289
static cell_t smn_TRTraceRayFilterEx(IPluginContext *pContext, const cell_t *params)
dvander@1859
   290
{
dvander@1859
   291
	IPluginFunction *pFunc;
dvander@1859
   292
	cell_t *startaddr, *endaddr;
dvander@1859
   293
	cell_t data;
dvander@1859
   294
dvander@1859
   295
	pFunc = pContext->GetFunctionById(params[5]);
dvander@1859
   296
	if (!pFunc)
dvander@1859
   297
	{
dvander@1859
   298
		return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@1859
   299
	}
dvander@1859
   300
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859
   301
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859
   302
dvander@1859
   303
	Vector StartVec, EndVec;
dvander@1859
   304
	CSMTraceFilter smfilter;
dvander@1859
   305
	Ray_t ray;
dvander@1859
   306
dvander@1859
   307
	if (params[0] >= 6)
dvander@1859
   308
	{
dvander@1859
   309
		data = params[6];
dvander@1859
   310
	}
dvander@1859
   311
	else
dvander@1859
   312
	{
dvander@1859
   313
		data = 0;
dvander@1859
   314
	}
dvander@1859
   315
dvander@1859
   316
	smfilter.SetFunctionPtr(pFunc, data);
dvander@1859
   317
	StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859
   318
dvander@1859
   319
	switch (params[4])
dvander@1859
   320
	{
dvander@1859
   321
	case RayType_EndPoint:
dvander@1859
   322
		{
dvander@1859
   323
			EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   324
			break;
dvander@1859
   325
		}
dvander@1859
   326
	case RayType_Infinite:
dvander@1859
   327
		{
dvander@1859
   328
			QAngle DirAngles;
dvander@1859
   329
			DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859
   330
			AngleVectors(DirAngles, &EndVec);
dvander@1859
   331
dvander@1859
   332
			/* Make it unitary and get the ending point */
dvander@1859
   333
			EndVec.NormalizeInPlace();
dvander@1859
   334
			EndVec = StartVec + EndVec * MAX_TRACE_LENGTH;
dvander@1859
   335
			break;
dvander@1859
   336
		}
dvander@1859
   337
	}
dvander@1859
   338
dvander@1859
   339
	trace_t *tr = new trace_t;
dvander@1859
   340
	ray.Init(StartVec, EndVec);
dvander@1859
   341
	enginetrace->TraceRay(ray, params[3], &smfilter, tr);
dvander@1859
   342
dvander@1859
   343
	HandleError herr;
dvander@1859
   344
	Handle_t hndl;
dvander@1859
   345
	if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@1859
   346
	{
dvander@1859
   347
		delete tr;
dvander@1859
   348
		return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@1859
   349
	}
dvander@1859
   350
dvander@1859
   351
	return hndl;
dvander@1859
   352
}
dvander@1859
   353
dvander@2089
   354
static cell_t smn_TRTraceHullFilterEx(IPluginContext *pContext, const cell_t *params)
dvander@2089
   355
{
dvander@2089
   356
	IPluginFunction *pFunc;
dvander@2089
   357
	cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089
   358
	cell_t data;
dvander@2089
   359
dvander@2089
   360
	pFunc = pContext->GetFunctionById(params[6]);
dvander@2089
   361
	if (!pFunc)
dvander@2089
   362
	{
dvander@2089
   363
		return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@2089
   364
	}
dvander@2089
   365
	pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089
   366
	pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089
   367
	pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089
   368
	pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089
   369
dvander@2089
   370
	Vector StartVec, EndVec, vmins, vmaxs;
dvander@2089
   371
	CSMTraceFilter smfilter;
dvander@2089
   372
	Ray_t ray;
dvander@2089
   373
dvander@2089
   374
	data = params[7];
dvander@2089
   375
dvander@2089
   376
	smfilter.SetFunctionPtr(pFunc, data);
dvander@2089
   377
	StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089
   378
	vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089
   379
	vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089
   380
	EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089
   381
dvander@2089
   382
	ray.Init(StartVec, EndVec, vmins, vmaxs);
dvander@2089
   383
dvander@2089
   384
	trace_t *tr = new trace_t;
dvander@2089
   385
	enginetrace->TraceRay(ray, params[5], &smfilter, tr);
dvander@2089
   386
dvander@2089
   387
	HandleError herr;
dvander@2089
   388
	Handle_t hndl;
dvander@2089
   389
	if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@2089
   390
	{
dvander@2089
   391
		delete tr;
dvander@2089
   392
		return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@2089
   393
	}
dvander@2089
   394
dvander@2089
   395
	return hndl;
dvander@2089
   396
}
dvander@2089
   397
dvander@1859
   398
static cell_t smn_TRGetFraction(IPluginContext *pContext, const cell_t *params)
dvander@1859
   399
{
dvander@1859
   400
	trace_t *tr;
dvander@1859
   401
	HandleError err;
dvander@1859
   402
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   403
dvander@1859
   404
	if (params[1] == BAD_HANDLE)
dvander@1859
   405
	{
dvander@1859
   406
		tr = &g_Trace;
dvander@1859
   407
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   408
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   409
	}
dvander@1859
   410
dvander@1859
   411
	return sp_ftoc(tr->fraction);
dvander@1859
   412
}
dvander@1859
   413
dvander@1859
   414
static cell_t smn_TRGetPlaneNormal(IPluginContext *pContext, const cell_t *params)
dvander@1859
   415
{
dvander@1859
   416
	trace_t *tr;
dvander@1859
   417
	HandleError err;
dvander@1859
   418
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   419
dvander@1859
   420
	if (params[1] == BAD_HANDLE)
dvander@1859
   421
	{
dvander@1859
   422
		tr = &g_Trace;
dvander@1859
   423
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   424
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   425
	}
dvander@1859
   426
dvander@1859
   427
	Vector *normal = &tr->plane.normal;
dvander@1859
   428
dvander@1859
   429
	cell_t *r;
dvander@1859
   430
	pContext->LocalToPhysAddr(params[2], &r);
dvander@1859
   431
	r[0] = sp_ftoc(normal->x);
dvander@1859
   432
	r[1] = sp_ftoc(normal->y);
dvander@1859
   433
	r[2] = sp_ftoc(normal->z);
dvander@1859
   434
dvander@1859
   435
	return 1;
dvander@1859
   436
}
dvander@1859
   437
dvander@1859
   438
dvander@1859
   439
static cell_t smn_TRGetEndPosition(IPluginContext *pContext, const cell_t *params)
dvander@1859
   440
{
dvander@1859
   441
	trace_t *tr;
dvander@1859
   442
	HandleError err;
dvander@1859
   443
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   444
dvander@1859
   445
	if (params[2] == BAD_HANDLE)
dvander@1859
   446
	{
dvander@1859
   447
		tr = &g_Trace;
dvander@1859
   448
	} else if ((err = handlesys->ReadHandle(params[2], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   449
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[2], err);
dvander@1859
   450
	}
dvander@1859
   451
dvander@1859
   452
	cell_t *addr;
dvander@1859
   453
	pContext->LocalToPhysAddr(params[1], &addr);
dvander@1859
   454
dvander@1859
   455
	addr[0] = sp_ftoc(tr->endpos.x);
dvander@1859
   456
	addr[1] = sp_ftoc(tr->endpos.y);
dvander@1859
   457
	addr[2] = sp_ftoc(tr->endpos.z);
dvander@1859
   458
dvander@1859
   459
	return 1;
dvander@1859
   460
}
dvander@1859
   461
dvander@1859
   462
static cell_t smn_TRDidHit(IPluginContext *pContext, const cell_t *params)
dvander@1859
   463
{
dvander@1859
   464
	trace_t *tr;
dvander@1859
   465
	HandleError err;
dvander@1859
   466
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   467
dvander@1859
   468
	if (params[1] == BAD_HANDLE)
dvander@1859
   469
	{
dvander@1859
   470
		tr = &g_Trace;
dvander@1859
   471
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   472
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   473
	}
dvander@1859
   474
dvander@1859
   475
	return tr->DidHit() ? 1 : 0;
dvander@1859
   476
}
dvander@1859
   477
dvander@1859
   478
static cell_t smn_TRGetHitGroup(IPluginContext *pContext, const cell_t *params)
dvander@1859
   479
{
dvander@1859
   480
	trace_t *tr;
dvander@1859
   481
	HandleError err;
dvander@1859
   482
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   483
dvander@1859
   484
	if (params[1] == BAD_HANDLE)
dvander@1859
   485
	{
dvander@1859
   486
		tr = &g_Trace;
dvander@1859
   487
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   488
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   489
	}
dvander@1859
   490
dvander@1859
   491
	return tr->hitgroup;
dvander@1859
   492
}
dvander@1859
   493
dvander@1859
   494
static cell_t smn_TRGetEntityIndex(IPluginContext *pContext, const cell_t *params)
dvander@1859
   495
{
dvander@1859
   496
	trace_t *tr;
dvander@1859
   497
	HandleError err;
dvander@1859
   498
	HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859
   499
dvander@1859
   500
	if (params[1] == BAD_HANDLE)
dvander@1859
   501
	{
dvander@1859
   502
		tr = &g_Trace;
dvander@1859
   503
	} else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859
   504
		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859
   505
	}
dvander@1859
   506
pred@2794
   507
	if (tr->m_pEnt == NULL)
pred@2794
   508
	{
pred@2794
   509
		return 0;
pred@2794
   510
	}
pred@2794
   511
pred@2746
   512
	return gamehelpers->EntityToBCompatRef(tr->m_pEnt);
dvander@1859
   513
}
dvander@1859
   514
dvander@1859
   515
static cell_t smn_TRGetPointContents(IPluginContext *pContext, const cell_t *params)
dvander@1859
   516
{
dvander@1859
   517
	cell_t *vec, *ent;
dvander@1859
   518
	IHandleEntity *hentity;
dvander@1859
   519
	Vector pos;
dvander@1859
   520
	int mask;
dvander@1859
   521
dvander@1859
   522
	pContext->LocalToPhysAddr(params[1], &vec);
dvander@1859
   523
	pContext->LocalToPhysAddr(params[2], &ent);
dvander@1859
   524
dvander@1859
   525
	pos.x = sp_ctof(vec[0]);
dvander@1859
   526
	pos.y = sp_ctof(vec[1]);
dvander@1859
   527
	pos.z = sp_ctof(vec[2]);
dvander@1859
   528
dvander@1859
   529
	if (*ent == -1)
dvander@1859
   530
	{
dvander@1859
   531
		mask = enginetrace->GetPointContents(pos);
dvander@1859
   532
	} else {
ds@3099
   533
#if SOURCE_ENGINE >= SE_LEFT4DEAD
ds@3099
   534
		mask = enginetrace->GetPointContents(pos, MASK_ALL, &hentity);
ds@2400
   535
#else
dvander@1859
   536
		mask = enginetrace->GetPointContents(pos, &hentity);
ds@2400
   537
#endif
pred@2746
   538
		*ent = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(hentity));
dvander@1859
   539
	}
dvander@1859
   540
dvander@1859
   541
	return mask;
dvander@1859
   542
}
dvander@1859
   543
dvander@1859
   544
static cell_t smn_TRGetPointContentsEnt(IPluginContext *pContext, const cell_t *params)
dvander@1859
   545
{
pred@2746
   546
	/* TODO: See if we can get the collidable with a prop and remove the reliance on edicts */
pred@2746
   547
	edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1]));
dvander@1859
   548
	if (!pEdict || pEdict->IsFree())
dvander@1859
   549
	{
dvander@1859
   550
		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
dvander@1859
   551
	}
dvander@1859
   552
dvander@1859
   553
	cell_t *addr;
dvander@1859
   554
	Vector pos;
dvander@1859
   555
dvander@1859
   556
	pContext->LocalToPhysAddr(params[2], &addr);
dvander@1859
   557
dvander@1859
   558
	pos.x = sp_ctof(addr[0]);
dvander@1859
   559
	pos.y = sp_ctof(addr[1]);
dvander@1859
   560
	pos.z = sp_ctof(addr[2]);
dvander@1859
   561
dvander@1859
   562
	return enginetrace->GetPointContents_Collideable(pEdict->GetCollideable(), pos);
dvander@1859
   563
}
dvander@1859
   564
the_dafox@2780
   565
static cell_t smn_TRPointOutsideWorld(IPluginContext *pContext, const cell_t *params)
the_dafox@2780
   566
{
the_dafox@2780
   567
	cell_t *vec;
the_dafox@2780
   568
	Vector pos;
the_dafox@2780
   569
	
the_dafox@2780
   570
	pContext->LocalToPhysAddr(params[1], &vec);
the_dafox@2780
   571
the_dafox@2780
   572
	pos.x = sp_ctof(vec[0]);
the_dafox@2780
   573
	pos.y = sp_ctof(vec[1]);
the_dafox@2780
   574
	pos.z = sp_ctof(vec[2]);
the_dafox@2780
   575
pred@2781
   576
	return enginetrace->PointOutsideWorld(pos);
the_dafox@2780
   577
}
the_dafox@2780
   578
dvander@1859
   579
sp_nativeinfo_t g_TRNatives[] = 
dvander@1859
   580
{
dvander@1859
   581
	{"TR_TraceRay",				smn_TRTraceRay},
dvander@2089
   582
	{"TR_TraceHull",			smn_TRTraceHull},
dvander@1859
   583
	{"TR_TraceRayEx",			smn_TRTraceRayEx},
dvander@2089
   584
	{"TR_TraceHullEx",			smn_TRTraceHullEx},
dvander@1859
   585
	{"TR_GetFraction",			smn_TRGetFraction},
dvander@1859
   586
	{"TR_GetEndPosition",		smn_TRGetEndPosition},
dvander@1859
   587
	{"TR_GetEntityIndex",		smn_TRGetEntityIndex},
dvander@1859
   588
	{"TR_DidHit",				smn_TRDidHit},
dvander@1859
   589
	{"TR_GetHitGroup",			smn_TRGetHitGroup},
dvander@1859
   590
	{"TR_GetPointContents",		smn_TRGetPointContents},
dvander@1859
   591
	{"TR_GetPointContentsEnt",	smn_TRGetPointContentsEnt},
dvander@1859
   592
	{"TR_TraceRayFilter",		smn_TRTraceRayFilter},
dvander@1859
   593
	{"TR_TraceRayFilterEx",		smn_TRTraceRayFilterEx},
dvander@2089
   594
	{"TR_TraceHullFilter",		smn_TRTraceHullFilter},
dvander@2089
   595
	{"TR_TraceHullFilterEx",	smn_TRTraceHullFilterEx},
dvander@1859
   596
	{"TR_GetPlaneNormal",		smn_TRGetPlaneNormal},
the_dafox@2780
   597
	{"TR_PointOutsideWorld",	smn_TRPointOutsideWorld},
dvander@1859
   598
	{NULL,						NULL}
dvander@1859
   599
};