diff --git a/extensions/sdktools/trnatives.cpp b/extensions/sdktools/trnatives.cpp index fc9dcfb9..555319d1 100644 --- a/extensions/sdktools/trnatives.cpp +++ b/extensions/sdktools/trnatives.cpp @@ -8,7 +8,7 @@ * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, version 3.0, as published by the * Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -74,6 +74,28 @@ private: cell_t m_Data; }; +class CSMTraceEnumerator : public IEntityEnumerator +{ +public: + bool EnumEntity(IHandleEntity *pEntity) override + { + cell_t res = 1; + m_pFunc->PushCell(gamehelpers->EntityToBCompatRef(reinterpret_cast(pEntity))); + m_pFunc->PushCell(m_Data); + m_pFunc->Execute(&res); + + return (res) ? true : false; + } + void SetFunctionPtr(IPluginFunction *pFunc, cell_t data) + { + m_pFunc = pFunc; + m_Data = data; + } +private: + IPluginFunction *m_pFunc; + cell_t m_Data; +}; + /* Used for the global trace version */ Ray_t g_Ray; sm_trace_t g_Trace; @@ -84,6 +106,7 @@ Vector g_HullMaxs; QAngle g_DirAngles; CTraceFilterHitAll g_HitAllFilter; CSMTraceFilter g_SMTraceFilter; +CSMTraceEnumerator g_SMTraceEnumerator; enum { @@ -145,6 +168,175 @@ static cell_t smn_TRTraceHull(IPluginContext *pContext, const cell_t *params) return 1; } +static cell_t smn_TREnumerateEntities(IPluginContext *pContext, const cell_t *params) +{ + IPluginFunction *pFunc = pContext->GetFunctionById(params[5]); + if (!pFunc) + { + return pContext->ThrowNativeError("Invalid function id (%X)", params[5]); + } + + cell_t data = 0; + if (params[0] >= 6) + { + data = params[6]; + } + + g_SMTraceEnumerator.SetFunctionPtr(pFunc, data); + + cell_t *startaddr, *endaddr; + pContext->LocalToPhysAddr(params[1], &startaddr); + pContext->LocalToPhysAddr(params[2], &endaddr); + + g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); + + switch (params[4]) + { + case RayType_EndPoint: + { + g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + break; + } + case RayType_Infinite: + { + g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + AngleVectors(g_DirAngles, &g_EndVec); + + /* Make it unitary and get the ending point */ + g_EndVec.NormalizeInPlace(); + g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH; + break; + } + } + + g_Ray.Init(g_StartVec, g_EndVec); + + bool triggers = (params[3]) ? true : false; + enginetrace->EnumerateEntities(g_Ray, triggers, &g_SMTraceEnumerator); + + return 1; +} + +static cell_t smn_TREnumerateEntitiesHull(IPluginContext *pContext, const cell_t *params) +{ + IPluginFunction *pFunc = pContext->GetFunctionById(params[6]); + if (!pFunc) + { + return pContext->ThrowNativeError("Invalid function id (%X)", params[6]); + } + + cell_t data = 0; + if (params[0] >= 7) + { + data = params[7]; + } + + g_SMTraceEnumerator.SetFunctionPtr(pFunc, data); + + cell_t *startaddr, *endaddr, *mins, *maxs; + pContext->LocalToPhysAddr(params[1], &startaddr); + pContext->LocalToPhysAddr(params[2], &endaddr); + pContext->LocalToPhysAddr(params[3], &mins); + pContext->LocalToPhysAddr(params[4], &maxs); + + g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); + g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2])); + g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2])); + g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + + g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs); + + bool triggers = (params[5]) ? true : false; + enginetrace->EnumerateEntities(g_Ray, triggers, &g_SMTraceEnumerator); + + return 1; +} + +static cell_t smn_TRClipRayToEntity(IPluginContext *pContext, const cell_t *params) +{ + cell_t *startaddr; + pContext->LocalToPhysAddr(params[1], &startaddr); + cell_t *endaddr; + pContext->LocalToPhysAddr(params[2], &endaddr); + + g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); + + switch (params[4]) + { + case RayType_EndPoint: + { + g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + break; + } + case RayType_Infinite: + { + g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + AngleVectors(g_DirAngles, &g_EndVec); + + /* Make it unitary and get the ending point */ + g_EndVec.NormalizeInPlace(); + g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH; + break; + } + } + + edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[5])); + if (!pEdict || pEdict->IsFree()) + { + return pContext->ThrowNativeError("Entity %d is invalid", params[5]); + } + + IHandleEntity *pEnt = reinterpret_cast(pEdict->GetUnknown()->GetBaseEntity()); + g_Ray.Init(g_StartVec, g_EndVec); + enginetrace->ClipRayToEntity(g_Ray, params[3], pEnt, &g_Trace); + g_Trace.UpdateEntRef(); + + return 1; +} + +static cell_t smn_TRClipRayHullToEntity(IPluginContext *pContext, const cell_t *params) +{ + cell_t *startaddr, *endaddr, *mins, *maxs; + pContext->LocalToPhysAddr(params[1], &startaddr); + pContext->LocalToPhysAddr(params[2], &endaddr); + pContext->LocalToPhysAddr(params[3], &mins); + pContext->LocalToPhysAddr(params[4], &maxs); + + edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[6])); + if (!pEdict || pEdict->IsFree()) + { + return pContext->ThrowNativeError("Entity %d is invalid", params[6]); + } + + IHandleEntity *pEnt = reinterpret_cast(pEdict->GetUnknown()->GetBaseEntity()); + + g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); + g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2])); + g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2])); + g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + + g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs); + enginetrace->ClipRayToEntity(g_Ray, params[5], pEnt, &g_Trace); + g_Trace.UpdateEntRef(); + + return 1; +} + +static cell_t smn_TRClipCurrentRayToEntity(IPluginContext *pContext, const cell_t *params) +{ + edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[2])); + if (!pEdict || pEdict->IsFree()) + { + return pContext->ThrowNativeError("Entity %d is invalid", params[2]); + } + + IHandleEntity *pEnt = reinterpret_cast(pEdict->GetUnknown()->GetBaseEntity()); + enginetrace->ClipRayToEntity(g_Ray, params[1], pEnt, &g_Trace); + g_Trace.UpdateEntRef(); + + return 1; +} + static cell_t smn_TRTraceRayFilter(IPluginContext *pContext, const cell_t *params) { cell_t *startaddr, *endaddr; @@ -311,6 +503,128 @@ static cell_t smn_TRTraceHullEx(IPluginContext *pContext, const cell_t *params) return hndl; } +static cell_t smn_TRClipRayToEntityEx(IPluginContext *pContext, const cell_t *params) +{ + cell_t *startaddr; + pContext->LocalToPhysAddr(params[1], &startaddr); + cell_t *endaddr; + pContext->LocalToPhysAddr(params[2], &endaddr); + + Vector StartVec, EndVec; + + StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); + + switch (params[4]) + { + case RayType_EndPoint: + { + EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + break; + } + case RayType_Infinite: + { + QAngle DirAngles; + DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + AngleVectors(DirAngles, &EndVec); + + /* Make it unitary and get the ending point */ + EndVec.NormalizeInPlace(); + EndVec = StartVec + EndVec * MAX_TRACE_LENGTH; + break; + } + } + + edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[5])); + if (!pEdict || pEdict->IsFree()) + { + return pContext->ThrowNativeError("Entity %d is invalid", params[5]); + } + + Ray_t ray; + sm_trace_t *tr = new sm_trace_t; + + IHandleEntity *pEnt = reinterpret_cast(pEdict->GetUnknown()->GetBaseEntity()); + ray.Init(StartVec, EndVec); + enginetrace->ClipRayToEntity(ray, params[3], pEnt, tr); + tr->UpdateEntRef(); + + HandleError herr; + Handle_t hndl; + if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr))) + { + delete tr; + return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr); + } + + return hndl; +} + +static cell_t smn_TRClipRayHullToEntityEx(IPluginContext *pContext, const cell_t *params) +{ + cell_t *startaddr, *endaddr, *mins, *maxs; + pContext->LocalToPhysAddr(params[1], &startaddr); + pContext->LocalToPhysAddr(params[2], &endaddr); + pContext->LocalToPhysAddr(params[3], &mins); + pContext->LocalToPhysAddr(params[4], &maxs); + + edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[6])); + if (!pEdict || pEdict->IsFree()) + { + return pContext->ThrowNativeError("Entity %d is invalid", params[6]); + } + + IHandleEntity *pEnt = reinterpret_cast(pEdict->GetUnknown()->GetBaseEntity()); + + Ray_t ray; + Vector StartVec, EndVec, vmins, vmaxs; + + StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); + vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2])); + vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2])); + EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); + + ray.Init(StartVec, EndVec, vmins, vmaxs); + + sm_trace_t *tr = new sm_trace_t; + enginetrace->ClipRayToEntity(ray, params[5], pEnt, tr); + tr->UpdateEntRef(); + + HandleError herr; + Handle_t hndl; + if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr))) + { + delete tr; + return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr); + } + + return hndl; +} + +static cell_t smn_TRClipCurrentRayToEntityEx(IPluginContext *pContext, const cell_t *params) +{ + edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[2])); + if (!pEdict || pEdict->IsFree()) + { + return pContext->ThrowNativeError("Entity %d is invalid", params[2]); + } + + sm_trace_t *tr = new sm_trace_t; + + IHandleEntity *pEnt = reinterpret_cast(pEdict->GetUnknown()->GetBaseEntity()); + enginetrace->ClipRayToEntity(g_Ray, params[1], pEnt, tr); + tr->UpdateEntRef(); + + HandleError herr; + Handle_t hndl; + if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr))) + { + delete tr; + return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr); + } + + return hndl; +} + static cell_t smn_TRTraceRayFilterEx(IPluginContext *pContext, const cell_t *params) { IPluginFunction *pFunc; @@ -586,38 +900,46 @@ static cell_t smn_TRGetPointContentsEnt(IPluginContext *pContext, const cell_t * return enginetrace->GetPointContents_Collideable(pEdict->GetCollideable(), pos); } -static cell_t smn_TRPointOutsideWorld(IPluginContext *pContext, const cell_t *params) -{ - cell_t *vec; - Vector pos; - - pContext->LocalToPhysAddr(params[1], &vec); - - pos.x = sp_ctof(vec[0]); - pos.y = sp_ctof(vec[1]); - pos.z = sp_ctof(vec[2]); - - return enginetrace->PointOutsideWorld(pos); -} - -sp_nativeinfo_t g_TRNatives[] = +static cell_t smn_TRPointOutsideWorld(IPluginContext *pContext, const cell_t *params) { - {"TR_TraceRay", smn_TRTraceRay}, - {"TR_TraceHull", smn_TRTraceHull}, - {"TR_TraceRayEx", smn_TRTraceRayEx}, - {"TR_TraceHullEx", smn_TRTraceHullEx}, - {"TR_GetFraction", smn_TRGetFraction}, - {"TR_GetEndPosition", smn_TRGetEndPosition}, - {"TR_GetEntityIndex", smn_TRGetEntityIndex}, - {"TR_DidHit", smn_TRDidHit}, - {"TR_GetHitGroup", smn_TRGetHitGroup}, - {"TR_GetPointContents", smn_TRGetPointContents}, - {"TR_GetPointContentsEnt", smn_TRGetPointContentsEnt}, - {"TR_TraceRayFilter", smn_TRTraceRayFilter}, - {"TR_TraceRayFilterEx", smn_TRTraceRayFilterEx}, - {"TR_TraceHullFilter", smn_TRTraceHullFilter}, - {"TR_TraceHullFilterEx", smn_TRTraceHullFilterEx}, - {"TR_GetPlaneNormal", smn_TRGetPlaneNormal}, - {"TR_PointOutsideWorld", smn_TRPointOutsideWorld}, - {NULL, NULL} + cell_t *vec; + Vector pos; + + pContext->LocalToPhysAddr(params[1], &vec); + + pos.x = sp_ctof(vec[0]); + pos.y = sp_ctof(vec[1]); + pos.z = sp_ctof(vec[2]); + + return enginetrace->PointOutsideWorld(pos); +} + +sp_nativeinfo_t g_TRNatives[] = +{ + {"TR_TraceRay", smn_TRTraceRay}, + {"TR_TraceHull", smn_TRTraceHull}, + {"TR_EnumerateEntities", smn_TREnumerateEntities}, + {"TR_EnumerateEntitiesHull", smn_TREnumerateEntitiesHull}, + {"TR_TraceRayEx", smn_TRTraceRayEx}, + {"TR_TraceHullEx", smn_TRTraceHullEx}, + {"TR_GetFraction", smn_TRGetFraction}, + {"TR_GetEndPosition", smn_TRGetEndPosition}, + {"TR_GetEntityIndex", smn_TRGetEntityIndex}, + {"TR_DidHit", smn_TRDidHit}, + {"TR_GetHitGroup", smn_TRGetHitGroup}, + {"TR_ClipRayToEntity", smn_TRClipRayToEntity}, + {"TR_ClipRayToEntityEx", smn_TRClipRayToEntityEx}, + {"TR_ClipRayHullToEntity", smn_TRClipRayHullToEntity}, + {"TR_ClipRayHullToEntityEx", smn_TRClipRayHullToEntityEx}, + {"TR_ClipCurrentRayToEntity", smn_TRClipCurrentRayToEntity}, + {"TR_ClipCurrentRayToEntityEx", smn_TRClipCurrentRayToEntityEx}, + {"TR_GetPointContents", smn_TRGetPointContents}, + {"TR_GetPointContentsEnt", smn_TRGetPointContentsEnt}, + {"TR_TraceRayFilter", smn_TRTraceRayFilter}, + {"TR_TraceRayFilterEx", smn_TRTraceRayFilterEx}, + {"TR_TraceHullFilter", smn_TRTraceHullFilter}, + {"TR_TraceHullFilterEx", smn_TRTraceHullFilterEx}, + {"TR_GetPlaneNormal", smn_TRGetPlaneNormal}, + {"TR_PointOutsideWorld", smn_TRPointOutsideWorld}, + {NULL, NULL} }; diff --git a/plugins/include/sdktools_trace.inc b/plugins/include/sdktools_trace.inc index 3b9d5ee1..afa1541f 100644 --- a/plugins/include/sdktools_trace.inc +++ b/plugins/include/sdktools_trace.inc @@ -9,7 +9,7 @@ * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, version 3.0, as published by the * Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -116,22 +116,41 @@ typeset TraceEntityFilter * Called on entity filtering. * * @param entity Entity index. - * @param contentsMask Contents Mask. - * @return True to allow the current entity to be hit, otherwise false. - */ + * @param contentsMask Contents Mask. + * @return True to allow the current entity to be hit, otherwise false. + */ function bool (int entity, int contentsMask); - + /** * Called on entity filtering. * * @param entity Entity index. - * @param contentsMask Contents Mask. - * @param data Data value, if used. - * @return True to allow the current entity to be hit, otherwise false. - */ + * @param contentsMask Contents Mask. + * @param data Data value, if used. + * @return True to allow the current entity to be hit, otherwise false. + */ function bool (int entity, int contentsMask, any data); }; +typeset TraceEntityEnumerator +{ + /** + * Called for each entity enumerated with EnumerateEntities*. + * + * @param entity Entity index. + * @return True to continue enumerating, otherwise false. + */ + function bool (int entity); + + /** + * Called for each entity enumerated with EnumerateEntities*. + * + * @param entity Entity index. + * @param data Data value, if used. + * @return True to continue enumerating, otherwise false. */ + function bool (int entity, any data); +} + /** * Get the contents mask and the entity index at the given position. * @@ -163,7 +182,7 @@ native void TR_TraceRay(const float pos[3], const float vec[3], int flags, RayType rtype); - + /** * Starts up a new trace hull using a global trace result. * @@ -180,19 +199,64 @@ native void TR_TraceHull(const float pos[3], int flags); /** - * Starts up a new trace ray using a global trace result and a customized + * Enumerates over entities along a ray. This may find entities that are + * close to the ray but do not actually intersect it. Use TR_Clip*RayToEntity + * with TR_DidHit to check if the ray actually intersects the entity. + * + * @param pos Starting position of the ray. + * @param vec Depending on RayType, it will be used as the ending + * point, or the direction angle. + * @param triggers If true, enumerate only triggers. Otherwise, enumerate + * only non-triggers. + * @param rtype Method to calculate the ray direction. + * @param enumerator Function to use as enumerator. For each entity found + * along the ray, this function is called. + * @param data Arbitrary data value to pass through to the enumerator. + */ +native void TR_EnumerateEntities(const float pos[3], + const float vec[3], + bool triggers, + RayType rtype, + TraceEntityEnumerator enumerator, + any data=0); + +/** + * Enumerates over entities along a ray hull. This may find entities that are + * close to the ray but do not actually intersect it. Use TR_Clip*RayToEntity + * with TR_DidHit to check if the ray actually intersects the entity. + * + * @param pos Starting position of the ray. + * @param vec Ending position of the ray. + * @param mins Hull minimum size. + * @param maxs Hull maximum size. + * @param triggers If true, enumerate only triggers. Otherwise, enumerate + * only non-triggers. + * @param enumerator Function to use as enumerator. For each entity found + * along the ray, this function is called. + * @param data Arbitrary data value to pass through to the enumerator. + */ +native void TR_EnumerateEntitiesHull(const float pos[3], + const float vec[3], + const float mins[3], + const float maxs[3], + bool triggers, + TraceEntityEnumerator enumerator, + any data=0); + +/** + * Starts up a new trace ray using a global trace result and a customized * trace ray filter. * - * Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter + * Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter * function is currently not allowed and may not work. * * @param pos Starting position of the ray. - * @param vec Depending on RayType, it will be used as the ending + * @param vec Depending on RayType, it will be used as the ending * point, or the direction angle. * @param flags Trace flags. * @param rtype Method to calculate the ray direction. * @param filter Function to use as a filter. - * @param data Arbitrary data value to pass through to the filter + * @param data Arbitrary data value to pass through to the filter * function. */ native void TR_TraceRayFilter(const float pos[3], @@ -201,22 +265,21 @@ native void TR_TraceRayFilter(const float pos[3], RayType rtype, TraceEntityFilter filter, any data=0); - + /** - * Starts up a new trace hull using a global trace result and a customized + * Starts up a new trace hull using a global trace result and a customized * trace ray filter. * - * Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter + * Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter * function is currently not allowed and may not work. * * @param pos Starting position of the ray. - * @param vec Depending on RayType, it will be used as the ending - * point, or the direction angle. + * @param vec Ending position of the ray. * @param mins Hull minimum size. * @param maxs Hull maximum size. * @param flags Trace flags. * @param filter Function to use as a filter. - * @param data Arbitrary data value to pass through to the filter + * @param data Arbitrary data value to pass through to the filter * function. */ native void TR_TraceHullFilter(const float pos[3], @@ -227,11 +290,52 @@ native void TR_TraceHullFilter(const float pos[3], TraceEntityFilter filter, any data=0); +/** + * Clips a ray to a particular entity. + * + * @param pos Starting position of the ray. + * @param vec Depending on RayType, it will be used as the ending + * point, or the direction angle. + * @param flags Trace flags. + * @param rtype Method to calculate the ray direction. + * @param entity Entity to clip to. + */ +native void TR_ClipRayToEntity(const float pos[3], + const float vec[3], + int flags, + RayType rtype, + int entity); + +/** + * Clips a ray hull to a particular entity. + * + * @param pos Starting position of the ray. + * @param vec Ending position of the ray. + * @param mins Hull minimum size. + * @param maxs Hull maximum size. + * @param flags Trace flags. + * @param entity Entity to clip to. + */ +native void TR_ClipRayHullToEntity(const float pos[3], + const float vec[3], + const float mins[3], + const float maxs[3], + int flags, + int entity); + +/** + * Clips the current global ray (or hull) to a particular entity. + * + * @param flags Trace flags. + * @param entity Entity to clip to. + */ +native void TR_ClipCurrentRayToEntity(int flags, int entity); + /** * Starts up a new trace ray using a new trace result. * * @param pos Starting position of the ray. - * @param vec Depending on RayType, it will be used as the ending + * @param vec Depending on RayType, it will be used as the ending * point, or the direction angle. * @param flags Trace flags. * @param rtype Method to calculate the ray direction. @@ -241,7 +345,7 @@ native Handle TR_TraceRayEx(const float pos[3], const float vec[3], int flags, RayType rtype); - + /** * Starts up a new trace hull using a new trace result. * @@ -259,14 +363,14 @@ native Handle TR_TraceHullEx(const float pos[3], int flags); /** - * Starts up a new trace ray using a new trace result and a customized + * Starts up a new trace ray using a new trace result and a customized * trace ray filter. * - * Calling TR_Trace*Filter or TR_TraceRay*Ex from inside a filter + * Calling TR_Trace*Filter or TR_TraceRay*Ex from inside a filter * function is currently not allowed and may not work. * * @param pos Starting position of the ray. - * @param vec Depending on RayType, it will be used as the ending + * @param vec Depending on RayType, it will be used as the ending * point, or the direction angle. * @param flags Trace flags. * @param rtype Method to calculate the ray direction. @@ -274,18 +378,18 @@ native Handle TR_TraceHullEx(const float pos[3], * @param data Arbitrary data value to pass through to the filter function. * @return Ray trace handle, which must be closed via CloseHandle(). */ -native Handle TR_TraceRayFilterEx(const float pos[3], +native Handle TR_TraceRayFilterEx(const float pos[3], const float vec[3], - int flags, - RayType rtype, + int flags, + RayType rtype, TraceEntityFilter filter, any data=0); - + /** - * Starts up a new trace hull using a new trace result and a customized + * Starts up a new trace hull using a new trace result and a customized * trace ray filter. * - * Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter + * Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter * function is currently not allowed and may not work. * * @param pos Starting position of the ray. @@ -297,14 +401,58 @@ native Handle TR_TraceRayFilterEx(const float pos[3], * @param data Arbitrary data value to pass through to the filter function. * @return Ray trace handle, which must be closed via CloseHandle(). */ -native Handle TR_TraceHullFilterEx(const float pos[3], +native Handle TR_TraceHullFilterEx(const float pos[3], const float vec[3], const float mins[3], const float maxs[3], - int flags, + int flags, TraceEntityFilter filter, any data=0); +/** + * Clips a ray to a particular entity. + * + * @param pos Starting position of the ray. + * @param vec Depending on RayType, it will be used as the ending + * point, or the direction angle. + * @param flags Trace flags. + * @param rtype Method to calculate the ray direction. + * @param entity Entity to clip to. + * @return Ray trace handle, which must be closed via CloseHandle(). + */ +native Handle TR_ClipRayToEntityEx(const float pos[3], + const float vec[3], + int flags, + RayType rtype, + int entity); + +/** + * Clips a ray hull to a particular entity. + * + * @param pos Starting position of the ray. + * @param vec Ending position of the ray. + * @param mins Hull minimum size. + * @param maxs Hull maximum size. + * @param flags Trace flags. + * @param entity Entity to clip to. + * @return Ray trace handle, which must be closed via CloseHandle(). + */ +native Handle TR_ClipRayHullToEntityEx(const float pos[3], + const float vec[3], + const float mins[3], + const float maxs[3], + int flags, + int entity); + +/** + * Clips the current global ray (or hull) to a particular entity. + * + * @param flags Trace flags. + * @param entity Entity to clip to. + * @return Ray trace handle, which must be closed via CloseHandle(). + */ +native Handle TR_ClipCurrentRayToEntityEx(int flags, int entity); + /** * Returns the time fraction from a trace result (1.0 means no collision). * @@ -363,6 +511,6 @@ native void TR_GetPlaneNormal(Handle hndl, float normal[3]); * Tests a point to see if it's outside any playable area * * @param pos Vector buffer to store data in. - * @return True if outside world, otherwise false. + * @return True if outside world, otherwise false. */ native bool TR_PointOutsideWorld(float pos[3]);