-
Автор темы
- #1
Код:
static std::optional<Vector> GetIntersectionPoint(const Vector& start, const Vector& end, const Vector& mins, const Vector& maxs, float radius)
{
auto sphereRayIntersection = [start, end, radius](auto&& center) -> std::optional<Vector>
{
auto direction = (end - start).Normalize();
auto q = center - start;
auto v = q.DotProduct(direction);
auto d = radius * radius - (q.LengthSqr() - v * v);
if (d < FLT_EPSILON)
return {};
return start + direction * (v - std::sqrt(d));
};
auto delta = (maxs - mins).Normalize();
for (size_t i{}; i < std::floor(mins.Dist(maxs)); ++i)
{
if (auto intersection = sphereRayIntersection(mins + delta * float(i)); intersection)
return intersection;
}
if (auto intersection = sphereRayIntersection(maxs); intersection)
return intersection;
return {};
}
static std::optional<LagRecord> GetTargetRecord(CEntity* entity, const Vector& start, const Vector& end)
{
auto hdr = Interfaces::ModelInfo->GetStudioModel(entity->GetModel());
if (!hdr)
return {};
auto set = hdr->GetHitboxSet(0);
if (!set)
return {};
for (auto& record : LagCompensation.GetRecordsForEntity(entity))
{
for (size_t i{}; i < set->numhitboxes; ++i)
{
auto hitbox = set->GetHitbox(i);
if (!hitbox || hitbox->radius == -1.f)
continue;
Vector mins, maxs;
VectorTransform(hitbox->bbmin, record.matrix[hitbox->bone], mins);
VectorTransform(hitbox->bbmax, record.matrix[hitbox->bone], maxs);
if (auto intersection = GetIntersectionPoint(start, end, mins, maxs, hitbox->radius); intersection)
{
Ray_t ray;
CGameTrace trace;
CTraceFilter filter;
filter.pSkip = CEntity::GetLocalPlayer();
ray.Init(start, *intersection);
Interfaces::Trace->TraceRay(ray, MASK_SHOT | CONTENTS_GRATE, &filter, &trace);
if (!trace.DidHit()) //position isn't behind wall
return record;
}
}
}
return {};
}
void BacktrackTrigger(CUserCmd* cmd)
{
auto local = CEntity::GetLocalPlayer();
auto weapon = local->GetWeapon();
auto data = weapon->GetWeaponData();
Vector viewangles;
Vector start = local->GetEyePos();
Vector end;
Interfaces::Engine->GetViewAngles(viewangles);
AngleVectors(viewangles + local->GetAimPunch(), &end);
end = start + (end * data->range);
for (size_t i{}; i <= Interfaces::GlobalVars->maxClients; ++i)
{
auto entity = Interfaces::EntityList->GetClientEntity(i);
if (!entity || !entity->IsEnemy() || !entity->GetHealth() || entity->IsDormant() || entity->IsImmune())
continue;
if (auto record = GetTargetRecord(entity, start, end); record)
{
if (!data->full_auto)
{
if (cmd->tick_count % 2) cmd->buttons |= IN_ATTACK;
else cmd->buttons &= ~IN_ATTACK;
}
else cmd->buttons |= IN_ATTACK;
//backtrack your target entity
break;
}
}
}