dvander@1859: /**
dvander@1859: * vim: set ts=4 :
dvander@1859: * =============================================================================
dvander@1859: * SourceMod SDKTools Extension
ds@1947: * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
dvander@1859: * =============================================================================
dvander@1859: *
dvander@1859: * This program is free software; you can redistribute it and/or modify it under
dvander@1859: * the terms of the GNU General Public License, version 3.0, as published by the
dvander@1859: * Free Software Foundation.
dvander@1859: *
dvander@1859: * This program is distributed in the hope that it will be useful, but WITHOUT
dvander@1859: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@1859: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
dvander@1859: * details.
dvander@1859: *
dvander@1859: * You should have received a copy of the GNU General Public License along with
dvander@1859: * this program. If not, see .
dvander@1859: *
dvander@1859: * As a special exception, AlliedModders LLC gives you permission to link the
dvander@1859: * code of this program (as well as its derivative works) to "Half-Life 2," the
dvander@1859: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
dvander@1859: * by the Valve Corporation. You must obey the GNU General Public License in
dvander@1859: * all respects for all other code used. Additionally, AlliedModders LLC grants
dvander@1859: * this exception to all derivative works. AlliedModders LLC defines further
dvander@1859: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
dvander@1859: * or .
dvander@1859: *
dvander@1859: * Version: $Id$
dvander@1859: */
dvander@1859:
dvander@1859: #include "extension.h"
dvander@1859: #include
dvander@1859:
dvander@1859: class CSMTraceFilter : public CTraceFilter
dvander@1859: {
dvander@1859: public:
dvander@1859: bool ShouldHitEntity(IHandleEntity *pEntity, int contentsMask)
dvander@1859: {
dvander@1859: cell_t res = 1;
dvander@1859: edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast(pEntity));
dvander@1859: m_pFunc->PushCell(engine->IndexOfEdict(pEdict));
dvander@1859: m_pFunc->PushCell(contentsMask);
dvander@1859: m_pFunc->PushCell(m_Data);
dvander@1859: m_pFunc->Execute(&res);
dvander@1859:
dvander@1859: return (res) ? true : false;
dvander@1859: }
dvander@1859: void SetFunctionPtr(IPluginFunction *pFunc, cell_t data)
dvander@1859: {
dvander@1859: m_pFunc = pFunc;
dvander@1859: m_Data = data;
dvander@1859: }
dvander@1859: private:
dvander@1859: IPluginFunction *m_pFunc;
dvander@1859: cell_t m_Data;
dvander@1859: };
dvander@1859:
dvander@1859: /* Used for the global trace version */
dvander@1859: Ray_t g_Ray;
dvander@1859: trace_t g_Trace;
dvander@1859: Vector g_StartVec;
dvander@1859: Vector g_EndVec;
dvander@2089: Vector g_HullMins;
dvander@2089: Vector g_HullMaxs;
dvander@1859: QAngle g_DirAngles;
dvander@1859: CTraceFilterHitAll g_HitAllFilter;
dvander@1859: CSMTraceFilter g_SMTraceFilter;
dvander@1859:
dvander@1859: enum
dvander@1859: {
dvander@1859: RayType_EndPoint,
dvander@1859: RayType_Infinite
dvander@1859: };
dvander@1859:
dvander@1859: static cell_t smn_TRTraceRay(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: cell_t *startaddr, *endaddr;
dvander@1859: pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859: pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859:
dvander@1859: g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859:
dvander@1859: switch (params[4])
dvander@1859: {
dvander@1859: case RayType_EndPoint:
dvander@1859: {
dvander@1859: g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859: break;
dvander@1859: }
dvander@1859: case RayType_Infinite:
dvander@1859: {
dvander@1859: g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859: AngleVectors(g_DirAngles, &g_EndVec);
dvander@1859:
dvander@1859: /* Make it unitary and get the ending point */
dvander@1859: g_EndVec.NormalizeInPlace();
dvander@1859: g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH;
dvander@1859: break;
dvander@1859: }
dvander@1859: }
dvander@1859:
dvander@1859: g_Ray.Init(g_StartVec, g_EndVec);
dvander@1859: enginetrace->TraceRay(g_Ray, params[3], &g_HitAllFilter, &g_Trace);
dvander@1859:
dvander@1859: return 1;
dvander@1859: }
dvander@1859:
dvander@2089: static cell_t smn_TRTraceHull(IPluginContext *pContext, const cell_t *params)
dvander@2089: {
dvander@2089: cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089: pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089: pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089: pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089: pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089:
dvander@2089: g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089: g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089: g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089: g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089:
dvander@2089: g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs);
dvander@2089: enginetrace->TraceRay(g_Ray, params[5], &g_HitAllFilter, &g_Trace);
dvander@2089:
dvander@2089: return 1;
dvander@2089: }
dvander@2089:
dvander@1859: static cell_t smn_TRTraceRayFilter(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: cell_t *startaddr, *endaddr;
dvander@1859: IPluginFunction *pFunc;
dvander@1859: cell_t data;
dvander@1859:
dvander@1859: pFunc = pContext->GetFunctionById(params[5]);
dvander@1859: if (!pFunc)
dvander@1859: {
dvander@1859: return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@1859: }
dvander@1859:
dvander@1859: if (params[0] >= 6)
dvander@1859: {
dvander@1859: data = params[6];
dvander@1859: }
dvander@1859: else
dvander@1859: {
dvander@1859: data = 0;
dvander@1859: }
dvander@1859:
dvander@1859: g_SMTraceFilter.SetFunctionPtr(pFunc, data);
dvander@1859: pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859: pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859:
dvander@1859: g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859:
dvander@1859: switch (params[4])
dvander@1859: {
dvander@1859: case RayType_EndPoint:
dvander@1859: {
dvander@1859: g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859: break;
dvander@1859: }
dvander@1859: case RayType_Infinite:
dvander@1859: {
dvander@1859: g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859: AngleVectors(g_DirAngles, &g_EndVec);
dvander@1859:
dvander@1859: /* Make it unitary and get the ending point */
dvander@1859: g_EndVec.NormalizeInPlace();
dvander@1859: g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH;
dvander@1859: break;
dvander@1859: }
dvander@1859: }
dvander@1859:
dvander@1859: g_Ray.Init(g_StartVec, g_EndVec);
dvander@1859: enginetrace->TraceRay(g_Ray, params[3], &g_SMTraceFilter, &g_Trace);
dvander@1859:
dvander@1859: return 1;
dvander@1859: }
dvander@1859:
dvander@2089: static cell_t smn_TRTraceHullFilter(IPluginContext *pContext, const cell_t *params)
dvander@2089: {
dvander@2089: cell_t data;
dvander@2089: IPluginFunction *pFunc;
dvander@2089: cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089:
dvander@2089: pFunc = pContext->GetFunctionById(params[6]);
dvander@2089: if (!pFunc)
dvander@2089: {
dvander@2089: return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@2089: }
dvander@2089:
dvander@2089: data = params[7];
dvander@2089:
dvander@2089: g_SMTraceFilter.SetFunctionPtr(pFunc, data);
dvander@2089: pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089: pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089: pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089: pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089:
dvander@2089: g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089: g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089: g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089: g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089:
dvander@2089: g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs);
dvander@2089: enginetrace->TraceRay(g_Ray, params[5], &g_SMTraceFilter, &g_Trace);
dvander@2089:
dvander@2089: return 1;
dvander@2089: }
dvander@2089:
dvander@2089:
dvander@1859: static cell_t smn_TRTraceRayEx(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: cell_t *startaddr, *endaddr;
dvander@1859: pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859: pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859:
dvander@1859: Vector StartVec, EndVec;
dvander@1859: Ray_t ray;
dvander@1859:
dvander@1859: StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859:
dvander@1859: switch (params[4])
dvander@1859: {
dvander@1859: case RayType_EndPoint:
dvander@1859: {
dvander@1859: EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859: break;
dvander@1859: }
dvander@1859: case RayType_Infinite:
dvander@1859: {
dvander@1859: QAngle DirAngles;
dvander@1859: DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859: AngleVectors(DirAngles, &EndVec);
dvander@1859:
dvander@1859: /* Make it unitary and get the ending point */
dvander@1859: EndVec.NormalizeInPlace();
dvander@1859: EndVec = StartVec + EndVec * MAX_TRACE_LENGTH;
dvander@1859: break;
dvander@1859: }
dvander@1859: }
dvander@1859:
dvander@1859: trace_t *tr = new trace_t;
dvander@1859: ray.Init(StartVec, EndVec);
dvander@1859: enginetrace->TraceRay(ray, params[3], &g_HitAllFilter, tr);
dvander@1859:
dvander@1859: HandleError herr;
dvander@1859: Handle_t hndl;
dvander@1859: if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@1859: {
dvander@1859: delete tr;
dvander@1859: return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@1859: }
dvander@1859:
dvander@1859: return hndl;
dvander@1859: }
dvander@1859:
dvander@2089: static cell_t smn_TRTraceHullEx(IPluginContext *pContext, const cell_t *params)
dvander@2089: {
dvander@2089: cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089: pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089: pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089: pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089: pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089:
dvander@2089: Ray_t ray;
dvander@2089: Vector StartVec, EndVec, vmins, vmaxs;
dvander@2089:
dvander@2089: StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089: vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089: vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089: EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089:
dvander@2089: ray.Init(StartVec, EndVec, vmins, vmaxs);
dvander@2089:
dvander@2089: trace_t *tr = new trace_t;
dvander@2089: enginetrace->TraceRay(ray, params[5], &g_HitAllFilter, tr);
dvander@2089:
dvander@2089: HandleError herr;
dvander@2089: Handle_t hndl;
dvander@2089: if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@2089: {
dvander@2089: delete tr;
dvander@2089: return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@2089: }
dvander@2089:
dvander@2089: return hndl;
dvander@2089: }
dvander@2089:
dvander@1859: static cell_t smn_TRTraceRayFilterEx(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: IPluginFunction *pFunc;
dvander@1859: cell_t *startaddr, *endaddr;
dvander@1859: cell_t data;
dvander@1859:
dvander@1859: pFunc = pContext->GetFunctionById(params[5]);
dvander@1859: if (!pFunc)
dvander@1859: {
dvander@1859: return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@1859: }
dvander@1859: pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@1859: pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@1859:
dvander@1859: Vector StartVec, EndVec;
dvander@1859: CSMTraceFilter smfilter;
dvander@1859: Ray_t ray;
dvander@1859:
dvander@1859: if (params[0] >= 6)
dvander@1859: {
dvander@1859: data = params[6];
dvander@1859: }
dvander@1859: else
dvander@1859: {
dvander@1859: data = 0;
dvander@1859: }
dvander@1859:
dvander@1859: smfilter.SetFunctionPtr(pFunc, data);
dvander@1859: StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@1859:
dvander@1859: switch (params[4])
dvander@1859: {
dvander@1859: case RayType_EndPoint:
dvander@1859: {
dvander@1859: EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859: break;
dvander@1859: }
dvander@1859: case RayType_Infinite:
dvander@1859: {
dvander@1859: QAngle DirAngles;
dvander@1859: DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@1859: AngleVectors(DirAngles, &EndVec);
dvander@1859:
dvander@1859: /* Make it unitary and get the ending point */
dvander@1859: EndVec.NormalizeInPlace();
dvander@1859: EndVec = StartVec + EndVec * MAX_TRACE_LENGTH;
dvander@1859: break;
dvander@1859: }
dvander@1859: }
dvander@1859:
dvander@1859: trace_t *tr = new trace_t;
dvander@1859: ray.Init(StartVec, EndVec);
dvander@1859: enginetrace->TraceRay(ray, params[3], &smfilter, tr);
dvander@1859:
dvander@1859: HandleError herr;
dvander@1859: Handle_t hndl;
dvander@1859: if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@1859: {
dvander@1859: delete tr;
dvander@1859: return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@1859: }
dvander@1859:
dvander@1859: return hndl;
dvander@1859: }
dvander@1859:
dvander@2089: static cell_t smn_TRTraceHullFilterEx(IPluginContext *pContext, const cell_t *params)
dvander@2089: {
dvander@2089: IPluginFunction *pFunc;
dvander@2089: cell_t *startaddr, *endaddr, *mins, *maxs;
dvander@2089: cell_t data;
dvander@2089:
dvander@2089: pFunc = pContext->GetFunctionById(params[6]);
dvander@2089: if (!pFunc)
dvander@2089: {
dvander@2089: return pContext->ThrowNativeError("Invalid function id (%X)", params[5]);
dvander@2089: }
dvander@2089: pContext->LocalToPhysAddr(params[1], &startaddr);
dvander@2089: pContext->LocalToPhysAddr(params[2], &endaddr);
dvander@2089: pContext->LocalToPhysAddr(params[3], &mins);
dvander@2089: pContext->LocalToPhysAddr(params[4], &maxs);
dvander@2089:
dvander@2089: Vector StartVec, EndVec, vmins, vmaxs;
dvander@2089: CSMTraceFilter smfilter;
dvander@2089: Ray_t ray;
dvander@2089:
dvander@2089: data = params[7];
dvander@2089:
dvander@2089: smfilter.SetFunctionPtr(pFunc, data);
dvander@2089: StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2]));
dvander@2089: vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2]));
dvander@2089: vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2]));
dvander@2089: EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2]));
dvander@2089:
dvander@2089: ray.Init(StartVec, EndVec, vmins, vmaxs);
dvander@2089:
dvander@2089: trace_t *tr = new trace_t;
dvander@2089: enginetrace->TraceRay(ray, params[5], &smfilter, tr);
dvander@2089:
dvander@2089: HandleError herr;
dvander@2089: Handle_t hndl;
dvander@2089: if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr)))
dvander@2089: {
dvander@2089: delete tr;
dvander@2089: return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr);
dvander@2089: }
dvander@2089:
dvander@2089: return hndl;
dvander@2089: }
dvander@2089:
dvander@1859: static cell_t smn_TRGetFraction(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: trace_t *tr;
dvander@1859: HandleError err;
dvander@1859: HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859:
dvander@1859: if (params[1] == BAD_HANDLE)
dvander@1859: {
dvander@1859: tr = &g_Trace;
dvander@1859: } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859: return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859: }
dvander@1859:
dvander@1859: return sp_ftoc(tr->fraction);
dvander@1859: }
dvander@1859:
dvander@1859: static cell_t smn_TRGetPlaneNormal(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: trace_t *tr;
dvander@1859: HandleError err;
dvander@1859: HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859:
dvander@1859: if (params[1] == BAD_HANDLE)
dvander@1859: {
dvander@1859: tr = &g_Trace;
dvander@1859: } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859: return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859: }
dvander@1859:
dvander@1859: Vector *normal = &tr->plane.normal;
dvander@1859:
dvander@1859: cell_t *r;
dvander@1859: pContext->LocalToPhysAddr(params[2], &r);
dvander@1859: r[0] = sp_ftoc(normal->x);
dvander@1859: r[1] = sp_ftoc(normal->y);
dvander@1859: r[2] = sp_ftoc(normal->z);
dvander@1859:
dvander@1859: return 1;
dvander@1859: }
dvander@1859:
dvander@1859:
dvander@1859: static cell_t smn_TRGetEndPosition(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: trace_t *tr;
dvander@1859: HandleError err;
dvander@1859: HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859:
dvander@1859: if (params[2] == BAD_HANDLE)
dvander@1859: {
dvander@1859: tr = &g_Trace;
dvander@1859: } else if ((err = handlesys->ReadHandle(params[2], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859: return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[2], err);
dvander@1859: }
dvander@1859:
dvander@1859: cell_t *addr;
dvander@1859: pContext->LocalToPhysAddr(params[1], &addr);
dvander@1859:
dvander@1859: addr[0] = sp_ftoc(tr->endpos.x);
dvander@1859: addr[1] = sp_ftoc(tr->endpos.y);
dvander@1859: addr[2] = sp_ftoc(tr->endpos.z);
dvander@1859:
dvander@1859: return 1;
dvander@1859: }
dvander@1859:
dvander@1859: static cell_t smn_TRDidHit(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: trace_t *tr;
dvander@1859: HandleError err;
dvander@1859: HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859:
dvander@1859: if (params[1] == BAD_HANDLE)
dvander@1859: {
dvander@1859: tr = &g_Trace;
dvander@1859: } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859: return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859: }
dvander@1859:
dvander@1859: return tr->DidHit() ? 1 : 0;
dvander@1859: }
dvander@1859:
dvander@1859: static cell_t smn_TRGetHitGroup(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: trace_t *tr;
dvander@1859: HandleError err;
dvander@1859: HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859:
dvander@1859: if (params[1] == BAD_HANDLE)
dvander@1859: {
dvander@1859: tr = &g_Trace;
dvander@1859: } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859: return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859: }
dvander@1859:
dvander@1859: return tr->hitgroup;
dvander@1859: }
dvander@1859:
dvander@1859: static cell_t smn_TRGetEntityIndex(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: trace_t *tr;
dvander@1859: HandleError err;
dvander@1859: HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
dvander@1859:
dvander@1859: if (params[1] == BAD_HANDLE)
dvander@1859: {
dvander@1859: tr = &g_Trace;
dvander@1859: } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) {
dvander@1859: return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
dvander@1859: }
dvander@1859:
dvander@1859: edict_t *pEdict = gameents->BaseEntityToEdict(tr->m_pEnt);
dvander@1859: return engine->IndexOfEdict(pEdict);
dvander@1859: }
dvander@1859:
dvander@1859: static cell_t smn_TRGetPointContents(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: cell_t *vec, *ent;
dvander@1859: IHandleEntity *hentity;
dvander@1859: Vector pos;
dvander@1859: int mask;
dvander@1859:
dvander@1859: pContext->LocalToPhysAddr(params[1], &vec);
dvander@1859: pContext->LocalToPhysAddr(params[2], &ent);
dvander@1859:
dvander@1859: pos.x = sp_ctof(vec[0]);
dvander@1859: pos.y = sp_ctof(vec[1]);
dvander@1859: pos.z = sp_ctof(vec[2]);
dvander@1859:
dvander@1859: if (*ent == -1)
dvander@1859: {
dvander@1859: mask = enginetrace->GetPointContents(pos);
dvander@1859: } else {
dvander@1859: mask = enginetrace->GetPointContents(pos, &hentity);
dvander@1859: edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast(hentity));
dvander@1859: *ent = engine->IndexOfEdict(pEdict);
dvander@1859: }
dvander@1859:
dvander@1859: return mask;
dvander@1859: }
dvander@1859:
dvander@1859: static cell_t smn_TRGetPointContentsEnt(IPluginContext *pContext, const cell_t *params)
dvander@1859: {
dvander@1859: edict_t *pEdict = engine->PEntityOfEntIndex(params[1]);
dvander@1859: if (!pEdict || pEdict->IsFree())
dvander@1859: {
dvander@1859: return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
dvander@1859: }
dvander@1859:
dvander@1859: cell_t *addr;
dvander@1859: Vector pos;
dvander@1859:
dvander@1859: pContext->LocalToPhysAddr(params[2], &addr);
dvander@1859:
dvander@1859: pos.x = sp_ctof(addr[0]);
dvander@1859: pos.y = sp_ctof(addr[1]);
dvander@1859: pos.z = sp_ctof(addr[2]);
dvander@1859:
dvander@1859: return enginetrace->GetPointContents_Collideable(pEdict->GetCollideable(), pos);
dvander@1859: }
dvander@1859:
dvander@1859: sp_nativeinfo_t g_TRNatives[] =
dvander@1859: {
dvander@1859: {"TR_TraceRay", smn_TRTraceRay},
dvander@2089: {"TR_TraceHull", smn_TRTraceHull},
dvander@1859: {"TR_TraceRayEx", smn_TRTraceRayEx},
dvander@2089: {"TR_TraceHullEx", smn_TRTraceHullEx},
dvander@1859: {"TR_GetFraction", smn_TRGetFraction},
dvander@1859: {"TR_GetEndPosition", smn_TRGetEndPosition},
dvander@1859: {"TR_GetEntityIndex", smn_TRGetEntityIndex},
dvander@1859: {"TR_DidHit", smn_TRDidHit},
dvander@1859: {"TR_GetHitGroup", smn_TRGetHitGroup},
dvander@1859: {"TR_GetPointContents", smn_TRGetPointContents},
dvander@1859: {"TR_GetPointContentsEnt", smn_TRGetPointContentsEnt},
dvander@1859: {"TR_TraceRayFilter", smn_TRTraceRayFilter},
dvander@1859: {"TR_TraceRayFilterEx", smn_TRTraceRayFilterEx},
dvander@2089: {"TR_TraceHullFilter", smn_TRTraceHullFilter},
dvander@2089: {"TR_TraceHullFilterEx", smn_TRTraceHullFilterEx},
dvander@1859: {"TR_GetPlaneNormal", smn_TRGetPlaneNormal},
dvander@1859: {NULL, NULL}
dvander@1859: };