summaryrefslogtreecommitdiffstats
path: root/src/esp.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/esp.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/esp.cpp b/src/esp.cpp
index 4d2345d..06bafaf 100644
--- a/src/esp.cpp
+++ b/src/esp.cpp
@@ -669,6 +669,61 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask,
669 return false; 669 return false;
670} 670}
671 671
672static bool active_weapon_contains(void *local_ent, const char *needle) {
673 if (!local_ent || g_net.activeweapon < 0 || !needle)
674 return false;
675 uint32_t h = *(uint32_t *)((uintptr_t)local_ent + g_net.activeweapon);
676 if (h == 0xFFFFFFFFu)
677 return false;
678 int idx = (int)(h & 0xFFFF);
679 if (idx <= 0 || idx > 4096)
680 return false;
681 void *wep = entitylist_get(idx);
682 void *net = entity_networkable(idx);
683 const char *cls = net ? entity_class_name(net, nullptr) : nullptr;
684 const char *model = wep ? entity_model_name(wep) : nullptr;
685 return (cls && strstr(cls, needle)) || (model && strstr(model, needle));
686}
687
688// Crossbow bolts and RPG rockets are not hitscan. Lead moving targets by the
689// projectile travel time; the crossbow bolt also has gravity 0.05 (30 u/s^2).
690static bool projectile_lead_point(int target_idx, const Vector &point,
691 Vector &out) {
692 int local = engine_get_local_player();
693 if (local <= 0)
694 return false;
695 void *local_ent = entitylist_get(local);
696 if (!local_ent)
697 return false;
698 float speed = 0.0f, gravity = 0.0f;
699 if (active_weapon_contains(local_ent, "crossbow") ||
700 active_weapon_contains(local_ent, "Crossbow")) {
701 speed = 2500.0f;
702 gravity = 30.0f;
703 } else if (active_weapon_contains(local_ent, "rocket_launcher") ||
704 active_weapon_contains(local_ent, "w_rpg") ||
705 active_weapon_contains(local_ent, "RPG")) {
706 speed = 1500.0f;
707 gravity = 0.0f;
708 } else {
709 return false;
710 }
711 void *target = entitylist_get(target_idx);
712 if (!target || g_net.velocity < 0)
713 return false;
714 const float *v = (const float *)((uintptr_t)target + g_net.velocity);
715 float dx = point.x - g_cam_eye.x;
716 float dy = point.y - g_cam_eye.y;
717 float dz = point.z - g_cam_eye.z;
718 float dist = sqrtf(dx * dx + dy * dy + dz * dz);
719 float t = dist / speed;
720 out = point;
721 out.x += v[0] * t;
722 out.y += v[1] * t;
723 out.z += v[2] * t + 0.5f * gravity * t * t;
724 return true;
725}
726
672bool aimbot_apply(CUserCmd *cmd) { 727bool aimbot_apply(CUserCmd *cmd) {
673 unsigned bone_mask = aimbot_bone_mask(); 728 unsigned bone_mask = aimbot_bone_mask();
674 if (!bone_mask) 729 if (!bone_mask)
@@ -684,6 +739,9 @@ bool aimbot_apply(CUserCmd *cmd) {
684 if (!select_aim_target(view, bone_mask, aimbot_vischeck_enabled(), max_fov, 739 if (!select_aim_target(view, bone_mask, aimbot_vischeck_enabled(), max_fov,
685 "aimbot", lock, target, point, fov)) 740 "aimbot", lock, target, point, fov))
686 return false; 741 return false;
742 Vector lead;
743 if (projectile_lead_point(target, point, lead))
744 point = lead;
687 QAngle desired = angle_to(g_cam_eye, point); 745 QAngle desired = angle_to(g_cam_eye, point);
688 static int want_logs = 0; 746 static int want_logs = 0;
689 if (want_logs < 10) { 747 if (want_logs < 10) {
@@ -759,6 +817,9 @@ bool silent_aim_apply(CUserCmd *cmd) {
759 if (!select_aim_target(view, bone_mask, true, max_fov, "silentaim", lock, 817 if (!select_aim_target(view, bone_mask, true, max_fov, "silentaim", lock,
760 target, point, fov)) 818 target, point, fov))
761 return false; 819 return false;
820 Vector lead;
821 if (projectile_lead_point(target, point, lead))
822 point = lead;
762 QAngle desired = angle_to(g_cam_eye, point); 823 QAngle desired = angle_to(g_cam_eye, point);
763 float np = desired.x; 824 float np = desired.x;
764 if (np > 89.0f) np = 89.0f; 825 if (np > 89.0f) np = 89.0f;