Make pTraceResult as pass arg

This commit is contained in:
SlynxCZ 2026-04-15 17:53:34 +02:00
parent fde876b4e1
commit fb519778e7
5 changed files with 140 additions and 293 deletions

View file

@ -64,133 +64,53 @@ namespace RayTraceAPI
MASK_NPC_MOVE = Solid | Window | NPCClip | PassBullets MASK_NPC_MOVE = Solid | Window | NPCClip | PassBullets
} }
[StructLayout(LayoutKind.Sequential, Pack = 8)] [StructLayout(LayoutKind.Explicit, Size = 24)]
public struct TraceOptions public struct TraceOptions
{ {
public ulong InteractsAs; [FieldOffset(0)] public ulong InteractsWith;
public ulong InteractsWith; [FieldOffset(8)] public ulong InteractsExclude;
public ulong InteractsExclude; [FieldOffset(16)] public int DrawBeam;
public int DrawBeam;
private int _pad;
public TraceOptions() public TraceOptions()
{ {
InteractsAs = 0;
InteractsWith = (ulong)InteractionLayers.MASK_SHOT_PHYSICS; InteractsWith = (ulong)InteractionLayers.MASK_SHOT_PHYSICS;
InteractsExclude = 0; InteractsExclude = 0;
DrawBeam = 0; DrawBeam = 0;
} }
public TraceOptions(InteractionLayers interactsAs, InteractionLayers interactsWith, public TraceOptions(InteractionLayers interactsWith, InteractionLayers interactsExclude = 0, bool drawBeam = false)
InteractionLayers interactsExclude = 0, bool drawBeam = false)
{ {
InteractsAs = (ulong)interactsAs;
InteractsWith = (ulong)interactsWith; InteractsWith = (ulong)interactsWith;
InteractsExclude = (ulong)interactsExclude; InteractsExclude = (ulong)interactsExclude;
DrawBeam = drawBeam ? 1 : 0; DrawBeam = drawBeam ? 1 : 0;
} }
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Explicit, Size = 44)]
public unsafe struct TraceResult public struct TraceResult
{ {
public Vector3 StartPos; [FieldOffset(0)] public float EndPosX;
public Vector3 EndPos; [FieldOffset(4)] public float EndPosY;
public Vector3 HitPoint; [FieldOffset(8)] public float EndPosZ;
public Vector3 Normal; [FieldOffset(16)] public nint HitEntity;
[FieldOffset(24)] public float Fraction;
[FieldOffset(28)] public int AllSolid;
[FieldOffset(32)] public float NormalX;
[FieldOffset(36)] public float NormalY;
[FieldOffset(40)] public float NormalZ;
public float Fraction; public Vector3 EndPos => new(EndPosX, EndPosY, EndPosZ);
public float HitOffset; public Vector3 Normal => new(NormalX, NormalY, NormalZ);
public bool DidHit => Fraction < 1.0f;
public int TriangleIndex; public bool IsAllSolid => AllSolid != 0;
public short HitboxBoneIndex;
private short _pad;
public int Contents;
public int RayType;
public bool StartInSolid;
public bool ExactHitPoint;
public nint HitEntity;
public nint Hitbox;
public nint Surface;
public nint Body;
public nint Shape;
public nint BodyTransform;
public nint ShapeAttributes;
public readonly bool DidHit() => Fraction < 1.0f;
public readonly bool IsAllSolid() => StartInSolid;
public readonly bool HasExactHit() => ExactHitPoint;
public readonly int GetTriangleIndex() => TriangleIndex;
public readonly int GetHitboxBoneIndex() => HitboxBoneIndex;
public readonly int GetContents() => Contents;
public readonly int GetRayType() => RayType;
public readonly Vector3 GetStartPos() => StartPos;
public readonly Vector3 GetEndPos() => EndPos;
public readonly Vector3 GetHitPoint() => HitPoint;
public readonly Vector3 GetNormal() => Normal;
public readonly float GetFraction() => Fraction;
public readonly float GetHitOffset() => HitOffset;
public readonly T* GetPtr<T>(nint ptr) where T : unmanaged
{
return (T*)ptr;
}
public readonly ref T GetRef<T>(nint ptr) where T : unmanaged
{
if (ptr == 0)
throw new NullReferenceException();
return ref *(T*)ptr;
}
public readonly bool TryGetRef<T>(nint ptr, out T* value) where T : unmanaged
{
if (ptr == 0)
{
value = null;
return false;
}
value = (T*)ptr;
return true;
}
public readonly CEntityInstance HitEntityPtr() => new(HitEntity);
public readonly CTransform BodyTransformPtr() => new(BodyTransform);
}
[StructLayout(LayoutKind.Sequential)]
public struct VectorNative
{
public float X;
public float Y;
public float Z;
}
[StructLayout(LayoutKind.Sequential)]
public struct QAngleNative
{
public float X;
public float Y;
public float Z;
} }
#endregion #endregion
public interface CRayTraceInterface public interface CRayTraceInterface
{ {
public TraceResult TraceShape(Vector start, QAngle angles, CEntityInstance ignore, TraceOptions options); public bool TraceShape(Vector start, QAngle angles, CEntityInstance? ignore, TraceOptions options, out TraceResult result);
public TraceResult TraceEndShape(Vector start, Vector end, CEntityInstance ignore, TraceOptions options); public bool TraceEndShape(Vector start, Vector end, CEntityInstance? ignore, TraceOptions options, out TraceResult result);
public TraceResult TraceHullShape(Vector start, Vector end, Vector mins, Vector maxs, CEntityInstance ignore, TraceOptions options); public bool TraceHullShape(Vector start, Vector end, Vector mins, Vector maxs, CEntityInstance? ignore, TraceOptions options, out TraceResult result);
public TraceResult TraceShapeEx(Vector start, Vector end, nint filter, nint ray); public bool TraceShapeEx(Vector start, Vector end, nint filter, nint ray, out TraceResult result);
} }
} }

View file

@ -60,90 +60,100 @@ public class RayTraceImpl : BasePlugin
public class CRayTrace : CRayTraceInterface public class CRayTrace : CRayTraceInterface
{ {
public TraceResult TraceShape(Vector start, QAngle angles, CEntityInstance ignore, TraceOptions options) public bool TraceShape(Vector start, QAngle angles, CEntityInstance? ignore, TraceOptions options, out TraceResult result)
{ {
unsafe unsafe
{ {
result = default;
if (!NativeBridge.Loaded) if (!NativeBridge.Loaded)
return default; return false;
VectorNative startNative = new() { X = start.X, Y = start.Y, Z = start.Z }; TraceResult resultBuffer = default;
QAngleNative angNative = new() { X = angles.X, Y = angles.Y, Z = angles.Z }; TraceOptions optionsBuffer = options;
TraceOptions optCopy = options;
return NativeBridge.TraceShape!( bool success = NativeBridge.TraceShape!(NativeBridge.Handle,
NativeBridge.Handle, start.Handle,
(nint)(&startNative), angles.Handle,
(nint)(&angNative), ignore?.Handle ?? nint.Zero,
ignore.Handle, (nint)(&optionsBuffer),
(nint)(&optCopy) (nint)(&resultBuffer));
);
result = resultBuffer;
return success;
} }
} }
public TraceResult TraceEndShape(Vector start, Vector end, CEntityInstance ignore, TraceOptions options) public bool TraceEndShape(Vector start, Vector end, CEntityInstance? ignore, TraceOptions options, out TraceResult result)
{ {
unsafe unsafe
{ {
result = default;
if (!NativeBridge.Loaded) if (!NativeBridge.Loaded)
return default; return false;
VectorNative s = new() { X = start.X, Y = start.Y, Z = start.Z }; TraceResult resultBuffer = default;
VectorNative e = new() { X = end.X, Y = end.Y, Z = end.Z }; TraceOptions optionsBuffer = options;
TraceOptions opt = options;
return NativeBridge.TraceEndShape!( bool success = NativeBridge.TraceEndShape!(NativeBridge.Handle,
NativeBridge.Handle, start.Handle,
(nint)(&s), end.Handle,
(nint)(&e), ignore?.Handle ?? nint.Zero,
ignore.Handle, (nint)(&optionsBuffer),
(nint)(&opt) (nint)(&resultBuffer));
);
result = resultBuffer;
return success;
} }
} }
public TraceResult TraceHullShape(Vector start, Vector end, Vector mins, Vector maxs, CEntityInstance ignore, TraceOptions options) public bool TraceHullShape(Vector start, Vector end, Vector mins, Vector maxs, CEntityInstance? ignore, TraceOptions options, out TraceResult result)
{ {
unsafe unsafe
{ {
result = default;
if (!NativeBridge.Loaded) if (!NativeBridge.Loaded)
return default; return false;
VectorNative s = new() { X = start.X, Y = start.Y, Z = start.Z }; TraceResult resultBuffer = default;
VectorNative e = new() { X = end.X, Y = end.Y, Z = end.Z }; TraceOptions optionsBuffer = options;
VectorNative mi = new() { X = mins.X, Y = mins.Y, Z = mins.Z };
VectorNative ma = new() { X = maxs.X, Y = maxs.Y, Z = maxs.Z };
TraceOptions opt = options;
return NativeBridge.TraceHullShape!( bool success = NativeBridge.TraceHullShape!(NativeBridge.Handle,
NativeBridge.Handle, start.Handle,
(nint)(&s), end.Handle,
(nint)(&e), mins.Handle,
(nint)(&mi), maxs.Handle,
(nint)(&ma), ignore?.Handle ?? nint.Zero,
ignore.Handle, (nint)(&optionsBuffer),
(nint)(&opt) (nint)(&resultBuffer));
);
result = resultBuffer;
return success;
} }
} }
public TraceResult TraceShapeEx(Vector start, Vector end, nint filter, nint ray) public bool TraceShapeEx(Vector start, Vector end, nint filter, nint ray, out TraceResult result)
{ {
unsafe unsafe
{ {
result = default;
if (!NativeBridge.Loaded) if (!NativeBridge.Loaded)
return default; return false;
VectorNative s = new() { X = start.X, Y = start.Y, Z = start.Z }; TraceResult resultBuffer = default;
VectorNative e = new() { X = end.X, Y = end.Y, Z = end.Z };
return NativeBridge.TraceShapeEx!( bool success = NativeBridge.TraceShapeEx!(NativeBridge.Handle,
NativeBridge.Handle, start.Handle,
(nint)(&s), end.Handle,
(nint)(&e),
filter, filter,
ray ray,
); (nint)(&resultBuffer));
result = resultBuffer;
return success;
} }
} }
} }
@ -153,10 +163,10 @@ public static class NativeBridge
public static nint Handle; public static nint Handle;
public static bool Loaded; public static bool Loaded;
public static unsafe Func<nint, nint, nint, nint, nint, TraceResult>? TraceShape; public static unsafe Func<nint, nint, nint, nint, nint, nint, bool>? TraceShape;
public static unsafe Func<nint, nint, nint, nint, nint, TraceResult>? TraceEndShape; public static unsafe Func<nint, nint, nint, nint, nint, nint, bool>? TraceEndShape;
public static unsafe Func<nint, nint, nint, nint, nint, nint, nint, TraceResult>? TraceHullShape; public static unsafe Func<nint, nint, nint, nint, nint, nint, nint, nint, bool>? TraceHullShape;
public static unsafe Func<nint, nint, nint, nint, nint, TraceResult>? TraceShapeEx; public static unsafe Func<nint, nint, nint, nint, nint, nint, bool>? TraceShapeEx;
public static bool Initialize() public static bool Initialize()
{ {
@ -189,10 +199,10 @@ public static class NativeBridge
ex = 5; ex = 5;
} }
TraceShape = VirtualFunction.Create<nint, nint, nint, nint, nint, TraceResult>(Handle, shape); TraceShape = VirtualFunction.Create<nint, nint, nint, nint, nint, nint, bool>(Handle, shape);
TraceEndShape = VirtualFunction.Create<nint, nint, nint, nint, nint, TraceResult>(Handle, end); TraceEndShape = VirtualFunction.Create<nint, nint, nint, nint, nint, nint, bool>(Handle, end);
TraceHullShape = VirtualFunction.Create<nint, nint, nint, nint, nint, nint, nint, TraceResult>(Handle, hull); TraceHullShape = VirtualFunction.Create<nint, nint, nint, nint, nint, nint, nint, nint, bool>(Handle, hull);
TraceShapeEx = VirtualFunction.Create<nint, nint, nint, nint, nint, TraceResult>(Handle, ex); TraceShapeEx = VirtualFunction.Create<nint, nint, nint, nint, nint, nint, bool>(Handle, ex);
} }
} }

View file

@ -136,7 +136,6 @@ static_assert(
struct TraceOptions struct TraceOptions
{ {
uint64_t InteractsAs = 0;
uint64_t InteractsWith = static_cast<uint64_t>(MASK_SHOT_PHYSICS); uint64_t InteractsWith = static_cast<uint64_t>(MASK_SHOT_PHYSICS);
uint64_t InteractsExclude = 0; uint64_t InteractsExclude = 0;
int DrawBeam = 0; int DrawBeam = 0;
@ -146,104 +145,25 @@ struct TraceResult
{ {
TraceResult() TraceResult()
{ {
m_flFraction = 1.0f; HitEntity = nullptr;
m_bStartInSolid = false; AllSolid = 0;
m_bExactHitPoint = false; Fraction = 1.0F;
m_pEnt = nullptr;
m_pHitbox = nullptr;
m_pSurfaceProperties = nullptr;
} }
explicit TraceResult(const CGameTrace* pTrace, bool bResult) explicit TraceResult(const CGameTrace* pTrace)
{ {
m_bTraceShapeResult = bResult; EndPos = pTrace->m_vEndPos;
m_pSurfaceProperties = pTrace->m_pSurfaceProperties; HitEntity = pTrace->m_pEnt;
m_pEnt = pTrace->m_pEnt; Fraction = pTrace->m_flFraction;
m_pHitbox = pTrace->m_pHitbox; AllSolid = pTrace->m_bStartInSolid;
m_hBody = pTrace->m_hBody; Normal = pTrace->m_vHitNormal;
m_hShape = pTrace->m_hShape;
m_nContents = pTrace->m_nContents;
m_BodyTransform = pTrace->m_BodyTransform;
m_ShapeAttributes = pTrace->m_ShapeAttributes;
m_vStartPos = pTrace->m_vStartPos;
m_vEndPos = pTrace->m_vEndPos;
m_vHitNormal = pTrace->m_vHitNormal;
m_vHitPoint = pTrace->m_vHitPoint;
m_flHitOffset = pTrace->m_flHitOffset;
m_flFraction = pTrace->m_flFraction;
m_nTriangle = pTrace->m_nTriangle;
m_nHitboxBoneIndex = pTrace->m_nHitboxBoneIndex;
m_eRayType = pTrace->m_eRayType;
m_bStartInSolid = pTrace->m_bStartInSolid;
m_bExactHitPoint = pTrace->m_bExactHitPoint;
} }
TraceResult(const TraceResult&) = delete; Vector EndPos;
TraceResult& operator=(const TraceResult&) = delete; CEntityInstance* HitEntity;
float Fraction;
TraceResult(TraceResult&&) = default; int AllSolid;
TraceResult& operator=(TraceResult&&) = default; Vector Normal;
const Vector& StartPos() const { return m_vStartPos; }
const Vector& EndPos() const { return m_vEndPos; }
const Vector& HitPoint() const { return m_vHitPoint; }
const Vector& Normal() const { return m_vHitNormal; }
float Fraction() const { return m_flFraction; }
float HitOffset() const { return m_flHitOffset; }
bool DidHit() const { return m_flFraction < 1.0f; }
bool IsAllSolid() const { return m_bStartInSolid; }
bool HasExactHit() const { return m_bExactHitPoint; }
CEntityInstance* HitEntity() const { return m_pEnt; }
int TriangleIndex() const { return m_nTriangle; }
int HitboxBoneIndex() const { return m_nHitboxBoneIndex; }
CHitBox* Hitbox() const { return const_cast<CHitBox*>(m_pHitbox); }
int Contents() const { return m_nContents; }
RayType_t RayType() const { return m_eRayType; }
IPhysicsBody* Body() const { return m_hBody; }
IPhysicsShape* Shape() const { return m_hShape; }
const CTransform& BodyTransform() const { return m_BodyTransform; }
const RnCollisionAttr_t& ShapeAttributes() const { return m_ShapeAttributes; }
CPhysSurfaceProperties* Surface() const { return const_cast<CPhysSurfaceProperties*>(m_pSurfaceProperties); }
private:
bool m_bTraceShapeResult; // return value from RayTrace::TraceShapeEx
const CPhysSurfaceProperties *m_pSurfaceProperties;
CEntityInstance *m_pEnt;
const CHitBox *m_pHitbox;
HPhysicsBody m_hBody;
HPhysicsShape m_hShape;
uint64 m_nContents; // contents on other side of surface hit
CTransform m_BodyTransform;
RnCollisionAttr_t m_ShapeAttributes;
Vector m_vStartPos; // start position
Vector m_vEndPos; // final position
Vector m_vHitNormal; // surface normal at impact
Vector m_vHitPoint; // exact hit point if m_bExactHitPoint is true, otherwise equal to m_vEndPos
float m_flHitOffset; // surface normal hit offset
float m_flFraction; // time completed, 1.0 = didn't hit anything
int32 m_nTriangle; // the index of the triangle that was hit
int16 m_nHitboxBoneIndex; // the index of the hitbox bone that was hit
RayType_t m_eRayType;
bool m_bStartInSolid; // if true, the initial point was in a solid area
bool m_bExactHitPoint; // if true, then m_vHitPoint is the exact hit point of the query and the shape
}; };
class CRayTraceInterface class CRayTraceInterface
@ -251,25 +171,29 @@ class CRayTraceInterface
public: public:
virtual ~CRayTraceInterface() = default; virtual ~CRayTraceInterface() = default;
virtual TraceResult TraceShape(const Vector& vecStart, virtual bool TraceShape(const Vector& vecStart,
const QAngle& angAngles, const QAngle& angAngles,
CEntityInstance* pIgnoreEntity, CEntityInstance* pIgnoreEntity,
TraceOptions* pTraceOptions) = 0; TraceOptions* pTraceOptions,
TraceResult* pTraceResult) = 0;
virtual TraceResult TraceEndShape(const Vector& vecStart, virtual bool TraceEndShape(const Vector& vecStart,
const Vector& vecEnd, const Vector& vecEnd,
CEntityInstance* pIgnoreEntity, CEntityInstance* pIgnoreEntity,
TraceOptions* pTraceOptions) = 0; TraceOptions* pTraceOptions,
TraceResult* pTraceResult) = 0;
virtual TraceResult TraceHullShape(const Vector& vecStart, virtual bool TraceHullShape(const Vector& vecStart,
const Vector& vecEnd, const Vector& vecEnd,
const Vector& vecMins, const Vector& vecMins,
const Vector& vecMaxs, const Vector& vecMaxs,
CEntityInstance* pIgnoreEntity, CEntityInstance* pIgnoreEntity,
TraceOptions* pTraceOptions) = 0; TraceOptions* pTraceOptions,
TraceResult* pTraceResult) = 0;
virtual TraceResult TraceShapeEx(const Vector& vecStart, virtual bool TraceShapeEx(const Vector& vecStart,
const Vector& vecEnd, const Vector& vecEnd,
CTraceFilter* pTraceFilter, CTraceFilter* pTraceFilter,
Ray_t* pRay) = 0; Ray_t* pRay,
TraceResult* pTraceResult) = 0;
}; };

View file

@ -43,7 +43,7 @@ namespace RayTracePlugin::RayTrace
beam->DispatchSpawn(); beam->DispatchSpawn();
} }
TraceResult CRayTrace::TraceShape(const Vector& vecStart, const QAngle& angAngles, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions) bool CRayTrace::TraceShape(const Vector& vecStart, const QAngle& angAngles, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions, TraceResult* pTraceResult)
{ {
CTraceFilterEx filter = pIgnoreEntity ? CTraceFilterEx(static_cast<CBaseEntity*>(pIgnoreEntity)) : CTraceFilterEx(); CTraceFilterEx filter = pIgnoreEntity ? CTraceFilterEx(static_cast<CBaseEntity*>(pIgnoreEntity)) : CTraceFilterEx();
@ -53,9 +53,6 @@ namespace RayTracePlugin::RayTrace
if (pTraceOptions) if (pTraceOptions)
{ {
if (pTraceOptions->InteractsAs != 0)
filter.m_nInteractsAs = pTraceOptions->InteractsAs;
if (pTraceOptions->InteractsWith != static_cast<uint64_t>(MASK_SHOT_PHYSICS)) if (pTraceOptions->InteractsWith != static_cast<uint64_t>(MASK_SHOT_PHYSICS))
filter.m_nInteractsWith = pTraceOptions->InteractsWith; filter.m_nInteractsWith = pTraceOptions->InteractsWith;
@ -72,18 +69,18 @@ namespace RayTracePlugin::RayTrace
}; };
Ray_t ray; Ray_t ray;
auto res = TraceShapeEx(vecStart, vecEnd, &filter, &ray); auto res = TraceShapeEx(vecStart, vecEnd, &filter, &ray, pTraceResult);
if (pTraceOptions && pTraceOptions->DrawBeam) if (pTraceOptions && pTraceOptions->DrawBeam)
{ {
Color col = res.DidHit() ? colors::Red().ToValveColor() : colors::Green().ToValveColor(); Color col = res ? colors::Red().ToValveColor() : colors::Green().ToValveColor();
DrawBeam(vecStart, res.DidHit() ? res.HitPoint() : vecEnd, col); DrawBeam(vecStart, (res && pTraceResult) ? pTraceResult->EndPos : vecEnd, col);
} }
return res; return res;
} }
TraceResult CRayTrace::TraceEndShape(const Vector& vecStart, const Vector& vecEnd, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions) bool CRayTrace::TraceEndShape(const Vector& vecStart, const Vector& vecEnd, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions, TraceResult* pTraceResult)
{ {
CTraceFilterEx filter = pIgnoreEntity ? CTraceFilterEx(static_cast<CBaseEntity*>(pIgnoreEntity)) : CTraceFilterEx(); CTraceFilterEx filter = pIgnoreEntity ? CTraceFilterEx(static_cast<CBaseEntity*>(pIgnoreEntity)) : CTraceFilterEx();
@ -93,9 +90,6 @@ namespace RayTracePlugin::RayTrace
if (pTraceOptions) if (pTraceOptions)
{ {
if (pTraceOptions->InteractsAs != 0)
filter.m_nInteractsAs = pTraceOptions->InteractsAs;
if (pTraceOptions->InteractsWith != static_cast<uint64_t>(MASK_SHOT_PHYSICS)) if (pTraceOptions->InteractsWith != static_cast<uint64_t>(MASK_SHOT_PHYSICS))
filter.m_nInteractsWith = pTraceOptions->InteractsWith; filter.m_nInteractsWith = pTraceOptions->InteractsWith;
@ -104,19 +98,19 @@ namespace RayTracePlugin::RayTrace
} }
Ray_t ray; Ray_t ray;
auto res = TraceShapeEx(vecStart, vecEnd, &filter, &ray); auto res = TraceShapeEx(vecStart, vecEnd, &filter, &ray, pTraceResult);
if (pTraceOptions && pTraceOptions->DrawBeam) if (pTraceOptions && pTraceOptions->DrawBeam)
{ {
Color col = res.DidHit() ? colors::Red().ToValveColor() : colors::Green().ToValveColor(); Color col = res ? colors::Red().ToValveColor() : colors::Green().ToValveColor();
DrawBeam(vecStart, res.DidHit() ? res.HitPoint() : vecEnd, col); DrawBeam(vecStart, (res && pTraceResult) ? pTraceResult->EndPos : vecEnd, col);
} }
return res; return res;
} }
TraceResult CRayTrace::TraceHullShape(const Vector& vecStart, const Vector& vecEnd, const Vector& vecMins, bool CRayTrace::TraceHullShape(const Vector& vecStart, const Vector& vecEnd, const Vector& vecMins,
const Vector& vecMaxs, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions) const Vector& vecMaxs, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions, TraceResult* pTraceResult)
{ {
CTraceFilterEx filter = pIgnoreEntity ? CTraceFilterEx(static_cast<CBaseEntity*>(pIgnoreEntity)) : CTraceFilterEx(); CTraceFilterEx filter = pIgnoreEntity ? CTraceFilterEx(static_cast<CBaseEntity*>(pIgnoreEntity)) : CTraceFilterEx();
@ -126,9 +120,6 @@ namespace RayTracePlugin::RayTrace
if (pTraceOptions) if (pTraceOptions)
{ {
if (pTraceOptions->InteractsAs != 0)
filter.m_nInteractsAs = pTraceOptions->InteractsAs;
if (pTraceOptions->InteractsWith != static_cast<uint64_t>(MASK_SHOT_PHYSICS)) if (pTraceOptions->InteractsWith != static_cast<uint64_t>(MASK_SHOT_PHYSICS))
filter.m_nInteractsWith = pTraceOptions->InteractsWith; filter.m_nInteractsWith = pTraceOptions->InteractsWith;
@ -139,23 +130,23 @@ namespace RayTracePlugin::RayTrace
Ray_t ray; Ray_t ray;
ray.Init(vecMins, vecMaxs); ray.Init(vecMins, vecMaxs);
auto res = TraceShapeEx(vecStart, vecEnd, &filter, &ray); auto res = TraceShapeEx(vecStart, vecEnd, &filter, &ray, pTraceResult);
if (pTraceOptions && pTraceOptions->DrawBeam) if (pTraceOptions && pTraceOptions->DrawBeam)
{ {
Color col = res.DidHit() ? colors::Red().ToValveColor() : colors::Green().ToValveColor(); Color col = res ? colors::Red().ToValveColor() : colors::Green().ToValveColor();
DrawBeam(vecStart, res.DidHit() ? res.HitPoint() : vecEnd, col); DrawBeam(vecStart, (res && pTraceResult) ? pTraceResult->EndPos : vecEnd, col);
} }
return res; return res;
} }
TraceResult CRayTrace::TraceShapeEx(const Vector& vecStart, const Vector& vecEnd, CTraceFilter* pTraceFilter, Ray_t* pRay) bool CRayTrace::TraceShapeEx(const Vector& vecStart, const Vector& vecEnd, CTraceFilter* pTraceFilter, Ray_t* pRay, TraceResult* pTraceResult)
{ {
if (!m_pCNavPhysicsInterface_TraceShape) if (!m_pCNavPhysicsInterface_TraceShape)
{ {
FP_ERROR("CNavPhysicsInterface::TraceShape is not bound!"); FP_ERROR("CNavPhysicsInterface::TraceShape is not bound!");
return TraceResult(); return false;
} }
Vector vecStartCopy = vecStart; Vector vecStartCopy = vecStart;
@ -166,6 +157,8 @@ namespace RayTracePlugin::RayTrace
bool (*)(void*, Ray_t&, Vector&, Vector&, CTraceFilter*, CGameTrace*)>()( bool (*)(void*, Ray_t&, Vector&, Vector&, CTraceFilter*, CGameTrace*)>()(
nullptr, *pRay, vecStartCopy, vecEndCopy, pTraceFilter, &trace); nullptr, *pRay, vecStartCopy, vecEndCopy, pTraceFilter, &trace);
return TraceResult(&trace, bResult); *pTraceResult = TraceResult(&trace);
return bResult;
} }
} }

View file

@ -31,10 +31,10 @@ namespace RayTracePlugin::RayTrace
public: public:
bool Initialize(); bool Initialize();
public: public:
TraceResult TraceShape(const Vector& vecStart, const QAngle& angAngles, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions) override; bool TraceShape(const Vector& vecStart, const QAngle& angAngles, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions, TraceResult* pTraceResult) override;
TraceResult TraceEndShape(const Vector& vecStart, const Vector& vecEnd, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions) override; bool TraceEndShape(const Vector& vecStart, const Vector& vecEnd, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions, TraceResult* pTraceResult) override;
TraceResult TraceHullShape(const Vector& vecStart, const Vector& vecEnd, const Vector& vecMins, const Vector& vecMaxs, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions) override; bool TraceHullShape(const Vector& vecStart, const Vector& vecEnd, const Vector& vecMins, const Vector& vecMaxs, CEntityInstance* pIgnoreEntity, TraceOptions* pTraceOptions, TraceResult* pTraceResult) override;
TraceResult TraceShapeEx(const Vector& vecStart, const Vector& vecEnd, CTraceFilter* pTraceFilter, Ray_t* pRay) override; bool TraceShapeEx(const Vector& vecStart, const Vector& vecEnd, CTraceFilter* pTraceFilter, Ray_t* pRay, TraceResult* pTraceResult) override;
protected: protected:
DynLibUtils::CMemory m_pCNavPhysicsInterface_TraceShape; DynLibUtils::CMemory m_pCNavPhysicsInterface_TraceShape;
protected: protected: