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