From b37e1f6892895e438aa7974e1144a6269d94e4aa Mon Sep 17 00:00:00 2001 From: salmonik Date: Mon, 26 Oct 2026 17:16:35 +0100 Subject: Aimbot v3: world-only vischeck - resolve EngineTraceClient003; TraceRay (slot 4) from the eye to the exact selected hitbox/bone point with MASK_VISIBLE - TRACE_WORLD_ONLY filter as requested (static props are not tested, per SDK) - Aimbot -> Vischeck toggle, persisted as vischeck=1; when on, blocked targets are skipped and the next-nearest candidate is tried - target candidates are ranked by angle; on each target the nearest visible selected hitbox point wins --- src/vischeck.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/vischeck.cpp (limited to 'src/vischeck.cpp') diff --git a/src/vischeck.cpp b/src/vischeck.cpp new file mode 100644 index 0000000..92d194b --- /dev/null +++ b/src/vischeck.cpp @@ -0,0 +1,98 @@ +// vischeck.cpp — world-only line-of-sight test via EngineTraceClient003. +// +// IEngineTrace::TraceRay (vtable slot 4) is given a ray from the eye to the +// aim point and a TRACE_WORLD_ONLY filter. MASK_VISIBLE ignores glass/windows +// (you can see through them) while still hitting opaque world geometry. +// Per the SDK, TRACE_WORLD_ONLY does not test static props; that is the +// deliberate trade-off for this build. + +#include "hl2h.h" +#include +#include + +namespace { + +struct alignas(16) VectorAlignedCompat { + float x, y, z, w; +}; + +// Ray_t: four VectorAligned (16 bytes each) followed by two bools. +struct alignas(16) RayCompat { + VectorAlignedCompat start; + VectorAlignedCompat delta; + VectorAlignedCompat startOffset; + VectorAlignedCompat extents; + bool isRay; + bool isSwept; +}; + +static_assert(sizeof(VectorAlignedCompat) == 16, "VectorAligned layout"); +static_assert(offsetof(RayCompat, delta) == 16, "Ray_t delta offset"); +static_assert(offsetof(RayCompat, isRay) == 64, "Ray_t isRay offset"); + +// trace_t / CBaseTrace prefix. cplane_t is Vector + float + type + signbits +// + 2 pad bytes, so fraction lands at 0x2C and startsolid at 0x37. +struct TraceCompat { + Vector startpos; + Vector endpos; + Vector normal; + float dist; + uint8_t type; + uint8_t signbits; + uint8_t pad[2]; + float fraction; + int contents; + uint16_t dispFlags; + bool allsolid; + bool startsolid; + uint8_t rest[128]; // CGameTrace tail (surface, ent, hitbox, ...) +}; + +static_assert(offsetof(TraceCompat, fraction) == 44, "trace_t fraction"); +static_assert(offsetof(TraceCompat, startsolid) == 55, "trace_t startsolid"); + +// ITraceFilter has no virtual destructor: vtable[0] = ShouldHitEntity, +// vtable[1] = GetTraceType. +struct ITraceFilterCompat { + virtual bool ShouldHitEntity(void *pEntity, int contentsMask) = 0; + virtual int GetTraceType() const = 0; +}; + +struct WorldOnlyFilter : ITraceFilterCompat { + bool ShouldHitEntity(void *, int) override { return false; } + int GetTraceType() const override { return 1; } // TRACE_WORLD_ONLY +}; + +// MASK_VISIBLE = CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_OPAQUE | +// CONTENTS_IGNORE_NODRAW_OPAQUE +constexpr unsigned MASK_VISIBLE = 0x1u | 0x4000u | 0x80u | 0x2000u; + +} // namespace + +bool is_visible(const Vector &eye, const Vector &point) { + static bool warned = false; + if (!g_iface.enginetrace) { + if (!warned) { + warned = true; + logf("vischeck: EngineTraceClient003 unavailable; failing open"); + } + return true; + } + + float dx = point.x - eye.x, dy = point.y - eye.y, dz = point.z - eye.z; + RayCompat ray{}; + ray.start = {eye.x, eye.y, eye.z, 0.0f}; + ray.delta = {dx, dy, dz, 0.0f}; + ray.startOffset = {0.0f, 0.0f, 0.0f, 0.0f}; + ray.extents = {0.0f, 0.0f, 0.0f, 0.0f}; + ray.isRay = true; + ray.isSwept = (dx * dx + dy * dy + dz * dz) > 0.0f; + + TraceCompat tr{}; + WorldOnlyFilter filter; + using TraceRayFn = void (*)(void *, const RayCompat *, unsigned, void *, + TraceCompat *); + vfunc(g_iface.enginetrace, 4)(g_iface.enginetrace, &ray, + MASK_VISIBLE, &filter, &tr); + return tr.fraction > 0.97f && !tr.startsolid; +} -- cgit v1.2.3