From d6027e5935cbe32fb6ad9a758dc81ab4a95845af Mon Sep 17 00:00:00 2001 From: Quentin <837334+xiaoxiao921@users.noreply.github.com> Date: Wed, 17 Jul 2024 23:17:18 +0200 Subject: [PATCH] refactor: aimbot (#2902) * Fixed ped flags system not allowing Michael's flag to be set. * Refactored is_a_ped_type_we_dont_care_about logic to not be extraneous and inefficient. * Fixed completely broken and wrong FoV calculations. * No Sway patch. Co-authored-by: gir489 <100792176+gir489returns@users.noreply.github.com> --- src/backend/commands/weapons/no_sway.cpp | 21 ++ src/backend/commands/weapons/no_sway.hpp | 9 + src/backend/looped/weapons/aimbot.cpp | 427 ++++++++++++++++------- src/backend/looped/weapons/no_recoil.cpp | 54 ++- src/backend/looped/weapons/no_spread.cpp | 35 +- src/byte_patch_manager.cpp | 3 + src/core/enums.hpp | 50 +++ src/core/settings.hpp | 29 +- src/function_types.hpp | 7 +- src/gta/enums.hpp | 32 ++ src/gta_pointers.hpp | 5 + src/hooking/hooking.cpp | 2 + src/hooking/hooking.hpp | 2 + src/pointers.cpp | 27 ++ src/views/self/view_weapons.cpp | 61 +++- 15 files changed, 585 insertions(+), 179 deletions(-) create mode 100644 src/backend/commands/weapons/no_sway.cpp create mode 100644 src/backend/commands/weapons/no_sway.hpp diff --git a/src/backend/commands/weapons/no_sway.cpp b/src/backend/commands/weapons/no_sway.cpp new file mode 100644 index 00000000..48da55e9 --- /dev/null +++ b/src/backend/commands/weapons/no_sway.cpp @@ -0,0 +1,21 @@ +#include "backend/bool_command.hpp" +#include "no_sway.hpp" + +namespace big +{ + class no_sway : bool_command + { + using bool_command::bool_command; + + virtual void on_enable() override + { + weapons::m_no_sway_patch->apply(); + } + + virtual void on_disable() override + { + weapons::m_no_sway_patch->restore(); + } + }; + no_sway g_veh_no_collision("nosway", "NO_SWAY", "NO_SWAY_DESC", g.weapons.no_sway); +} \ No newline at end of file diff --git a/src/backend/commands/weapons/no_sway.hpp b/src/backend/commands/weapons/no_sway.hpp new file mode 100644 index 00000000..3d401419 --- /dev/null +++ b/src/backend/commands/weapons/no_sway.hpp @@ -0,0 +1,9 @@ +#include "memory/byte_patch.hpp" + +namespace big +{ + struct weapons + { + inline static memory::byte_patch* m_no_sway_patch; + }; +} \ No newline at end of file diff --git a/src/backend/looped/weapons/aimbot.cpp b/src/backend/looped/weapons/aimbot.cpp index 10dd4e98..32db26ef 100644 --- a/src/backend/looped/weapons/aimbot.cpp +++ b/src/backend/looped/weapons/aimbot.cpp @@ -1,156 +1,333 @@ +#include "backend/int_command.hpp" #include "backend/looped_command.hpp" #include "gta/enums.hpp" +#include "hooking/hooking.hpp" #include "natives.hpp" #include "util/entity.hpp" #include "util/math.hpp" +#include "util/misc.hpp" +#include "util/pools.hpp" + #include namespace big { + bool_command g_aimbot_only_on_player("aimonlyatplayer", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_PLAYER", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_PLAYER_DESC", + g.weapons.aimbot.only_on_player); + + bool_command g_aimbot_only_on_enemy("aimonlyatenemy", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_ENEMY", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_ENEMY_DESC", + g.weapons.aimbot.only_on_enemy); + class aimbot : looped_command { - static inline Vector3 aim_lock; - static inline Vector3 smooth_factor; - static inline bool initalized; - static inline Entity target_entity; - using looped_command::looped_command; - virtual void on_tick() override + + public: + static inline CPed* m_target{}; + + static inline bool should_aimbot = false; + + static bool is_a_ped_type_we_dont_care_about(const Ped ped_handle) { - float local_fov_change = g.weapons.aimbot.fov; - for (auto ped : entity::get_entities(false, true)) + const auto ped_type = PED::GET_PED_TYPE(ped_handle); + + auto config_value = g.weapons.aimbot.only_on_ped_type; + + switch (ped_type) { - if (!ENTITY::IS_ENTITY_DEAD(ped, 0)) + case ePedType::PED_TYPE_PLAYER_0: + case ePedType::PED_TYPE_PLAYER_1: + case ePedType::PED_TYPE_NETWORK_PLAYER: + case ePedType::PED_TYPE_PLAYER_2: + case ePedType::PED_TYPE_CIVMALE: + case ePedType::PED_TYPE_CIVFEMALE: + case ePedType::PED_TYPE_COP: + case ePedType::PED_TYPE_GANG_ALBANIAN: + case ePedType::PED_TYPE_GANG_BIKER_1: + case ePedType::PED_TYPE_GANG_BIKER_2: + case ePedType::PED_TYPE_GANG_ITALIAN: + case ePedType::PED_TYPE_GANG_RUSSIAN: + case ePedType::PED_TYPE_GANG_RUSSIAN_2: + case ePedType::PED_TYPE_GANG_IRISH: + case ePedType::PED_TYPE_GANG_JAMAICAN: + case ePedType::PED_TYPE_GANG_AFRICAN_AMERICAN: + case ePedType::PED_TYPE_GANG_KOREAN: + case ePedType::PED_TYPE_GANG_CHINESE_JAPANESE: + case ePedType::PED_TYPE_GANG_PUERTO_RICAN: + case ePedType::PED_TYPE_DEALER: + case ePedType::PED_TYPE_MEDIC: + case ePedType::PED_TYPE_FIREMAN: + case ePedType::PED_TYPE_CRIMINAL: + case ePedType::PED_TYPE_BUM: + case ePedType::PED_TYPE_PROSTITUTE: + case ePedType::PED_TYPE_SPECIAL: + case ePedType::PED_TYPE_MISSION: + case ePedType::PED_TYPE_SWAT: + case ePedType::PED_TYPE_ANIMAL: + case ePedType::PED_TYPE_ARMY: { - int relation = PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped, self::ped); // relation for enemy check - int type = PED::GET_PED_TYPE(ped); // for police check, cop types are 6, swat is 27 - Vector3 world_position = ENTITY::GET_ENTITY_COORDS(ped, false); - - if (SYSTEM::VDIST2(self::pos.x, - self::pos.y, - self::pos.z, - world_position.x, - world_position.y, - world_position.z) - > (g.weapons.aimbot.distance * g.weapons.aimbot.distance)) - continue; // If the entity is further than our preset distance then just skip it - - if (PED::IS_PED_A_PLAYER(ped) && g.weapons.aimbot.on_player) // check if its a player - { - goto aimbot_handler; - } - else if (((relation == 4) || (relation == 5)) && g.weapons.aimbot.on_enemy) // relation 4 and 5 are for enemies - { - goto aimbot_handler; - } - else if (((type == 6 && !PED::IS_PED_MODEL(ped, rage::joaat("s_m_y_uscg_01"))) || type == 27 || // s_m_y_uscg_01 = us coast guard 1 (technically military) - PED::IS_PED_MODEL(ped, rage::joaat("s_m_y_ranger_01")) || PED::IS_PED_MODEL(ped, rage::joaat("s_f_y_ranger_01"))) // ranger models - && g.weapons.aimbot.on_police) - { - goto aimbot_handler; - } - else if (g.weapons.aimbot.on_npc && !PED::IS_PED_A_PLAYER(ped)) - - // Update aim lock coords - aimbot_handler: - { - if (!ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY_ADJUST_FOR_COVER(self::ped, ped, 17)) - continue; - - // Jump to here to handle instead of continue statements - target_entity = ped; - aim_lock = ENTITY::GET_ENTITY_BONE_POSTION(ped, PED::GET_PED_BONE_INDEX(ped, g.weapons.aimbot.selected_bone)); - } + return (config_value & (1LL << ped_type)) == 0; } } - if (!target_entity || ENTITY::IS_ENTITY_DEAD(target_entity, 0)) + return false; + } + + static uintptr_t get_cam_follow_ped_camera() + { + uintptr_t cam_gameplay_director = *g_pointers->m_gta.m_cam_gameplay_director; + return *reinterpret_cast(cam_gameplay_director + 0x3C0); + } + + static rage::fvector3 get_camera_position() + { + return *reinterpret_cast(get_cam_follow_ped_camera() + 0x60); + } + + static rage::fvector3 get_camera_aim_direction() + { + uintptr_t cam_gameplay_director = *g_pointers->m_gta.m_cam_gameplay_director; + uintptr_t cam_follow_ped_camera = get_cam_follow_ped_camera(); + + uintptr_t cam_follow_ped_camera_metadata = *reinterpret_cast(cam_follow_ped_camera + 0x10); + bool is_first_person = *reinterpret_cast(cam_follow_ped_camera_metadata + 0x30) == 0.0f; + if (is_first_person) { - return; - } - if (PLAYER::IS_PLAYER_FREE_AIMING(self::id)) - { - Vector3 camera_target; - - if (g.weapons.aimbot.smoothing) - { - //Avoid buggy cam - if (!initalized) - { - Vector3 cam_coords = CAM::GET_GAMEPLAY_CAM_COORD(); - Vector3 cam_rot = CAM::GET_GAMEPLAY_CAM_ROT(0); - Vector3 cam_direction = math::rotation_to_direction(cam_rot); - float distance = 150.f; - Vector3 multiply = cam_direction * distance; - Vector3 front_cam = cam_coords + multiply; - camera_target = front_cam - CAM::GET_GAMEPLAY_CAM_COORD(); - smooth_factor = camera_target; - initalized = true; - } - Vector3 target = aim_lock - CAM::GET_GAMEPLAY_CAM_COORD(); - smooth_factor.x += (target.x - smooth_factor.x) * g.weapons.aimbot.smoothing_speed / 10.f; - smooth_factor.y += (target.y - smooth_factor.y) * g.weapons.aimbot.smoothing_speed / 10.f; - smooth_factor.z += (target.z - smooth_factor.z) * g.weapons.aimbot.smoothing_speed / 10.f; - - camera_target = smooth_factor; - } - else - { - camera_target = aim_lock - CAM::GET_GAMEPLAY_CAM_COORD(); - } - // We actually need this. For some unknow reasons it gets entity or something there. - // Then it will start leading to 0,0,0 coords.Aim will start pointing at 0,0,0 as well. - if (aim_lock.x == 0.f && aim_lock.y == 0.f && aim_lock.z == 0.f) - return; - - constexpr float RADPI = 180.0f / std::numbers::pi; - float magnitude = std::hypot(camera_target.x, camera_target.y, camera_target.z); - float camera_heading = atan2f(camera_target.x, camera_target.y) * RADPI; - - float camera_pitch = asinf(camera_target.z / magnitude) * RADPI; - float self_heading = ENTITY::GET_ENTITY_HEADING(self::ped); - float self_pitch = ENTITY::GET_ENTITY_PITCH(self::ped); - if (camera_heading >= 0.0f && camera_heading <= 180.0f) - { - camera_heading = 360.0f - camera_heading; - } - else if (camera_heading <= -0.0f && camera_heading >= -180.0f) - { - camera_heading = -camera_heading; - } - if (CAM::GET_FOLLOW_PED_CAM_VIEW_MODE() == CameraMode::FIRST_PERSON) - { - CAM::SET_FIRST_PERSON_SHOOTER_CAMERA_HEADING(camera_heading - self_heading); - CAM::SET_FIRST_PERSON_SHOOTER_CAMERA_PITCH(camera_pitch - self_pitch); - } - else - { - CAM::SET_GAMEPLAY_CAM_RELATIVE_HEADING(camera_heading - self_heading); - CAM::SET_GAMEPLAY_CAM_RELATIVE_PITCH(camera_pitch - self_pitch, 1.0f); - } + return reinterpret_cast(cam_follow_ped_camera + 0x40)->normalize(); } else { - target_entity = 0; - initalized = false; + return reinterpret_cast(cam_follow_ped_camera + 0x3D0)->normalize(); } } - virtual void on_disable() override + + static float get_fov(const rage::fvector3& object_position) { - initalized = false; + const auto camera_position = get_camera_position(); + auto camera_aim_direction = get_camera_aim_direction(); + + auto direction_to_object = object_position - camera_position; + direction_to_object = direction_to_object.normalize(); + + float dot_product = camera_aim_direction.dot_product(direction_to_object); + dot_product = std::max(-1.0f, std::min(1.0f, dot_product)); + float fov = std::acos(dot_product); + + return fov * 2; } + static void find_best_target(CPed* self_ped, const rage::fvector3& self_pos) + { + m_target = nullptr; + + float best_fov = math::deg_to_rad(g.weapons.aimbot.fov); + float best_distance = g.weapons.aimbot.distance; + + for (rage::CEntity* ped_ : pools::get_all_peds()) + { + CPed* ped = (CPed*)ped_; + + if (ped == self_ped) + { + continue; + } + + if (ped->m_health <= 0) + { + continue; + } + + const auto is_not_a_player_and_we_target_only_players = g_aimbot_only_on_player.is_enabled() && !ped->m_player_info; + if (is_not_a_player_and_we_target_only_players) + { + continue; + } + + const auto ped_handle = g_pointers->m_gta.m_ptr_to_handle(ped); + + bool is_enemy = false; + switch (PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped_handle, self::ped)) + { + case Dislike: + case Wanted: + case Hate: is_enemy = true; + } + + if ((g_aimbot_only_on_enemy.is_enabled() && !is_enemy) || is_a_ped_type_we_dont_care_about(ped_handle)) + { + continue; + } + + const auto my_head_pos = self_ped->get_bone_coords(ePedBoneType::HEAD); + const auto their_head_pos = ped->get_bone_coords((ePedBoneType)g.weapons.aimbot.selected_bone); + + const auto fov = get_fov(their_head_pos); + const auto distance_to_ped = self_pos.distance(their_head_pos); + if (fov < best_fov && distance_to_ped < best_distance) + { + constexpr auto los_flags = (ST_OPTION_IGNORE_GLASS | ST_OPTION_IGNORE_NOTHING | ST_OPTION_IGNORE_TRANSPARENT); + auto shape_test_handle = SHAPETEST::START_EXPENSIVE_SYNCHRONOUS_SHAPE_TEST_LOS_PROBE(my_head_pos.x, + my_head_pos.y, + my_head_pos.z, + their_head_pos.x, + their_head_pos.y, + their_head_pos.z, + ST_INCLUDE_ALL, + self::ped, + los_flags); + BOOL did_shapetest_hit{}; + Vector3 dont_care; + Entity entity_hit{}; + if (SHAPETEST::GET_SHAPE_TEST_RESULT(shape_test_handle, &did_shapetest_hit, &dont_care, &dont_care, &entity_hit)) + { + if (!((did_shapetest_hit == TRUE && entity_hit == ped_handle) || !did_shapetest_hit)) + { + continue; + } + } + best_fov = fov; + best_distance = distance_to_ped; + m_target = ped; + } + } + } + + // Make aimbot works when driving a vehicle. + static void reset_aim_vectors(uintptr_t camera) + { + uintptr_t camera_params = *(uintptr_t*)(camera + 0x10); + { + if (g_local_player->m_vehicle) + { + if (*(float*)(camera_params + 0x2AC) == -2.0f) + { + *(float*)(camera_params + 0x2AC) = 0.0f; + *(float*)(camera_params + 0x2C0) = 111.0f; + *(float*)(camera_params + 0x2C4) = 111.0f; + } + } + else + { + if (*(float*)(camera_params + 0x130) == 8.0f) + { + *(float*)(camera_params + 0x130) = 111.0f; // def 8.0f + *(float*)(camera_params + 0x134) = 111.0f; // def 10.0f + *(float*)(camera_params + 0x4CC) = 0.0f; // def 4.0f + + if (*(float*)(camera_params + 0x49C) == 1.0f) + { + *(float*)(camera_params + 0x49C) = 0.0f; // def 1.0f + } + + *(float*)(camera_params + 0x2AC) = 0.0f; // def -3.0f + *(float*)(camera_params + 0x2B0) = 0.0f; // def -8.0f + } + } + } + } + + static void compute_aim_direction_and_set_gameplay_cam(const rage::fvector3& target_bone_position) + { + uintptr_t cam_follow_ped_camera = get_cam_follow_ped_camera(); + + const auto aim_direction = (target_bone_position - get_camera_position()).normalize(); + + reset_aim_vectors(cam_follow_ped_camera); + + *reinterpret_cast(cam_follow_ped_camera + 0x40) = aim_direction; + *reinterpret_cast(cam_follow_ped_camera + 0x3D0) = aim_direction; + } + + static inline CPed* last_target_pos_target{}; + static inline rage::fvector3 last_target_pos{}; + + static inline rage::fvector3 last_my_pos{}; + + static rage::fvector3 get_velocity(CPed* ped) + { + if (ped == g_local_player) + { + const auto velocity = *ped->get_position() - last_my_pos; + last_my_pos = *ped->get_position(); + + return velocity; + } + + if (ped == last_target_pos_target) + { + const auto velocity = *ped->get_position() - last_target_pos; + last_target_pos = *ped->get_position(); + + return velocity; + } + else + { + last_target_pos_target = ped; + last_target_pos = *ped->get_position(); + + return {}; + } + } + + static void adjust_position_for_target_velocity(rage::fvector3& target_position) + { + const auto target_velocity = get_velocity(m_target); + const auto my_velocity = get_velocity(g_local_player); + + target_position += (target_velocity - my_velocity); + } + + virtual void on_tick() override + { + should_aimbot = PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_AIM); + + if (!should_aimbot) + { + return; + } + + CAM::STOP_SCRIPT_GLOBAL_SHAKING(true); + CAM::SET_GAMEPLAY_CAM_SHAKE_AMPLITUDE(0); + } }; aimbot g_aimbot("aimbot", "VIEW_OVERLAY_AIMBOT", "BACKEND_LOOPED_WEAPONS_AIMBOT_DESC", g.weapons.aimbot.enable); - bool_command g_smoothing("smoothing", "BACKEND_LOOPED_WEAPONS_SMOOTHING", "BACKEND_LOOPED_WEAPONS_SMOOTHING_DESC", - g.weapons.aimbot.smoothing); - bool_command - g_aimbot_on_player("aimatplayer", "PLAYER", "BACKEND_LOOPED_WEAPONS_AIM_AT_PLAYER_DESC", g.weapons.aimbot.on_player); - bool_command - g_aimbot_on_npc("aimatnpc", "NPC", "BACKEND_LOOPED_WEAPONS_AIM_AT_NPC_DESC", g.weapons.aimbot.on_npc); - bool_command - g_aimbot_on_police("aimatpolice", "POLICE", "BACKEND_LOOPED_WEAPONS_AIM_AT_POLICE_DESC", g.weapons.aimbot.on_police); - bool_command g_aimbot_on_enemy("aimatenemy", "BACKEND_LOOPED_WEAPONS_AIM_AT_ENEMY", "BACKEND_LOOPED_WEAPONS_AIM_AT_ENEMY_DESC", - g.weapons.aimbot.on_enemy); + bool hooks::aimbot_cam_gameplay_director_update(uintptr_t this_) + { + const auto res = big::hooking::get_original()(this_); + + CPed* self_ped; + rage::fvector3 self_pos; + + rage::fvector3 target_bone_position; + + if (!aimbot::should_aimbot) + { + goto exit; + } + + self_ped = g_local_player; + if (!self_ped) + { + goto exit; + } + + self_pos = *self_ped->get_position(); + + aimbot::find_best_target(self_ped, self_pos); + if (!aimbot::m_target) + { + goto exit; + } + + target_bone_position = aimbot::m_target->get_bone_coords((ePedBoneType)g.weapons.aimbot.selected_bone); + + // Take into account the target velocity. + aimbot::adjust_position_for_target_velocity(target_bone_position); + + aimbot::compute_aim_direction_and_set_gameplay_cam(target_bone_position); + + exit: + return res; + } } diff --git a/src/backend/looped/weapons/no_recoil.cpp b/src/backend/looped/weapons/no_recoil.cpp index 754e4460..263f4acf 100644 --- a/src/backend/looped/weapons/no_recoil.cpp +++ b/src/backend/looped/weapons/no_recoil.cpp @@ -9,8 +9,23 @@ namespace big using looped_command::looped_command; CWeaponInfo* p_modified_weapon = nullptr; - uint32_t og_recoil_hash = 0; - uint32_t og_recoil_hash_fp = 0; + + float og_bullet_speed = 0; + + float og_recoil_shake_amplitude = 0; + + uint32_t og_recoil_hash = 0; + uint32_t og_recoil_hash_fp = 0; + + void reset_to_og() + { + p_modified_weapon->m_speed = og_bullet_speed; + + p_modified_weapon->m_recoil_shake_amplitude = og_recoil_shake_amplitude; + + p_modified_weapon->m_recoil_shake_hash = og_recoil_hash; + p_modified_weapon->m_recoil_shake_hash_first_person = og_recoil_hash_fp; + } virtual void on_tick() override { @@ -26,18 +41,32 @@ namespace big { if (p_modified_weapon) { - p_modified_weapon->m_recoil_shake_hash = og_recoil_hash; - p_modified_weapon->m_recoil_shake_hash_first_person = og_recoil_hash_fp; + reset_to_og(); } p_modified_weapon = weapon_mgr->m_weapon_info; if (weapon_mgr->m_weapon_info) { - og_recoil_hash = weapon_mgr->m_weapon_info->m_recoil_shake_hash; - og_recoil_hash_fp = weapon_mgr->m_weapon_info->m_recoil_shake_hash_first_person; - weapon_mgr->m_weapon_info->m_recoil_shake_hash = 0; - weapon_mgr->m_weapon_info->m_recoil_shake_hash_first_person = 0; + // Backup + { + og_bullet_speed = weapon_mgr->m_weapon_info->m_speed; + + og_recoil_shake_amplitude = weapon_mgr->m_weapon_info->m_recoil_shake_amplitude; + + og_recoil_hash = weapon_mgr->m_weapon_info->m_recoil_shake_hash; + og_recoil_hash_fp = weapon_mgr->m_weapon_info->m_recoil_shake_hash_first_person; + } + + // Set to the good stuff + { + weapon_mgr->m_weapon_info->m_speed = 9999999999.0f; + + weapon_mgr->m_weapon_info->m_recoil_shake_amplitude = 0; + + weapon_mgr->m_weapon_info->m_recoil_shake_hash = 0; + weapon_mgr->m_weapon_info->m_recoil_shake_hash_first_person = 0; + } } } } @@ -47,12 +76,13 @@ namespace big { if (g_local_player && p_modified_weapon) { - p_modified_weapon->m_recoil_shake_hash = og_recoil_hash; - p_modified_weapon->m_recoil_shake_hash_first_person = og_recoil_hash_fp; - p_modified_weapon = nullptr; + reset_to_og(); + + p_modified_weapon = nullptr; } } }; - no_recoil g_no_recoil("norecoil", "BACKEND_LOOPED_WEAPONS_NO_RECOIL", "BACKEND_LOOPED_WEAPONS_NO_RECOIL_DESC", g.weapons.no_recoil); + no_recoil + g_no_recoil("norecoil", "BACKEND_LOOPED_WEAPONS_NO_RECOIL", "BACKEND_LOOPED_WEAPONS_NO_RECOIL_DESC", g.weapons.no_recoil); } diff --git a/src/backend/looped/weapons/no_spread.cpp b/src/backend/looped/weapons/no_spread.cpp index b017c587..e0e4833a 100644 --- a/src/backend/looped/weapons/no_spread.cpp +++ b/src/backend/looped/weapons/no_spread.cpp @@ -9,7 +9,15 @@ namespace big using looped_command::looped_command; CWeaponInfo* p_modified_weapon = nullptr; - float og_spread_value = 0.0f; + + float og_accuracy_spread = 0; + uint32_t og_accuracy_offset_hash = 0; + + void reset_to_og() + { + p_modified_weapon->m_accuracy_spread = og_accuracy_spread; + p_modified_weapon->m_accuracy_offset_shake_hash = og_accuracy_offset_hash; + } virtual void on_tick() override { @@ -24,14 +32,25 @@ namespace big if (p_modified_weapon != weapon_mgr->m_weapon_info) { if (p_modified_weapon) - p_modified_weapon->m_accuracy_spread = og_spread_value; + { + reset_to_og(); + } p_modified_weapon = weapon_mgr->m_weapon_info; if (weapon_mgr->m_weapon_info) { - og_spread_value = weapon_mgr->m_weapon_info->m_accuracy_spread; - weapon_mgr->m_weapon_info->m_accuracy_spread = 0.0f; + // Backup + { + og_accuracy_spread = weapon_mgr->m_weapon_info->m_accuracy_spread; + og_accuracy_offset_hash = weapon_mgr->m_weapon_info->m_accuracy_offset_shake_hash; + } + + // Set to the good stuff + { + weapon_mgr->m_weapon_info->m_accuracy_spread = 0; + weapon_mgr->m_weapon_info->m_accuracy_offset_shake_hash = 0; + } } } } @@ -41,11 +60,13 @@ namespace big { if (g_local_player && p_modified_weapon) { - p_modified_weapon->m_accuracy_spread = og_spread_value; - p_modified_weapon = nullptr; + reset_to_og(); + + p_modified_weapon = nullptr; } } }; - no_spread g_no_spread("nospread", "BACKEND_LOOPED_WEAPONS_NO_SPREAD", "BACKEND_LOOPED_WEAPONS_NO_SPREAD_DESC", g.weapons.no_spread); + no_spread + g_no_spread("nospread", "BACKEND_LOOPED_WEAPONS_NO_SPREAD", "BACKEND_LOOPED_WEAPONS_NO_SPREAD_DESC", g.weapons.no_spread); } diff --git a/src/byte_patch_manager.cpp b/src/byte_patch_manager.cpp index 24596588..e01673c3 100644 --- a/src/byte_patch_manager.cpp +++ b/src/byte_patch_manager.cpp @@ -7,6 +7,7 @@ #include "util/explosion_anti_cheat_bypass.hpp" #include "util/vehicle.hpp" #include "util/world_model.hpp" +#include "backend/commands/weapons/no_sway.hpp" extern "C" void sound_overload_detour(); uint64_t g_sound_overload_ret_addr; @@ -79,6 +80,8 @@ namespace big // Always send the special ability event memory::byte_patch::make(g_pointers->m_gta.m_activate_special_ability_patch, std::to_array({0xB0, 0x01, 0xC3}))->apply(); + + weapons::m_no_sway_patch = memory::byte_patch::make(g_pointers->m_gta.m_scope_sway_function, std::vector{0xEB}).get(); } byte_patch_manager::byte_patch_manager() diff --git a/src/core/enums.hpp b/src/core/enums.hpp index 2d0fb8ec..267c1d9b 100644 --- a/src/core/enums.hpp +++ b/src/core/enums.hpp @@ -296,6 +296,41 @@ namespace big STEAM = 1 << 15, WATER = 1 << 16, }; + + enum class ePedTypeFlag : int64_t + { + PED_TYPE_PLAYER_0 = 1 << 0, + PED_TYPE_PLAYER_1 = 1 << 1, + PED_TYPE_NETWORK_PLAYER = 1 << 2, + PED_TYPE_PLAYER_2 = 1 << 3, + PED_TYPE_CIVMALE = 1 << 4, + PED_TYPE_CIVFEMALE = 1 << 5, + PED_TYPE_COP = 1 << 6, + PED_TYPE_GANG_ALBANIAN = 1 << 7, + PED_TYPE_GANG_BIKER_1 = 1 << 8, + PED_TYPE_GANG_BIKER_2 = 1 << 9, + PED_TYPE_GANG_ITALIAN = 1 << 10, + PED_TYPE_GANG_RUSSIAN = 1 << 11, + PED_TYPE_GANG_RUSSIAN_2 = 1 << 12, + PED_TYPE_GANG_IRISH = 1 << 13, + PED_TYPE_GANG_JAMAICAN = 1 << 14, + PED_TYPE_GANG_AFRICAN_AMERICAN = 1 << 15, + PED_TYPE_GANG_KOREAN = 1 << 16, + PED_TYPE_GANG_CHINESE_JAPANESE = 1 << 17, + PED_TYPE_GANG_PUERTO_RICAN = 1 << 18, + PED_TYPE_DEALER = 1 << 19, + PED_TYPE_MEDIC = 1 << 20, + PED_TYPE_FIREMAN = 1 << 21, + PED_TYPE_CRIMINAL = 1 << 22, + PED_TYPE_BUM = 1 << 23, + PED_TYPE_PROSTITUTE = 1 << 24, + PED_TYPE_SPECIAL = 1 << 25, + PED_TYPE_MISSION = 1 << 26, + PED_TYPE_SWAT = 1 << 27, + PED_TYPE_ANIMAL = 1 << 28, + PED_TYPE_ARMY = 1 << 29, + }; + enum ePedType : uint32_t { PED_TYPE_PLAYER_0, @@ -385,4 +420,19 @@ namespace big STATIC_DETECTION, TIMER_DETECTION }; + + enum eTraceFlags : uint32_t + { + IntersectNone = 0, + IntersectWorld = 1 << 0, + IntersectVehicle = 1 << 1, + IntersectPedSimpleCollision = 1 << 2, + IntersectPed = 1 << 3, + IntersectObject = 1 << 4, + IntersectPickup = 1 << 5, + IntersectGlass = 1 << 6, + IntersectWater = 1 << 7, + IntersectFoliage = 1 << 8, + IntersectEverything = eTraceFlags(-1), + }; } diff --git a/src/core/settings.hpp b/src/core/settings.hpp index 5fef84a1..0b544ad7 100644 --- a/src/core/settings.hpp +++ b/src/core/settings.hpp @@ -7,6 +7,7 @@ #include "file_manager.hpp" #include +#include #include #include #include @@ -149,7 +150,7 @@ namespace big } fuzzer{}; bool external_console = true; - bool window_hook = false; + bool window_hook = false; bool block_all_metrics = false; NLOHMANN_DEFINE_TYPE_INTRUSIVE(debug, logs, external_console, window_hook, block_all_metrics) @@ -369,7 +370,7 @@ namespace big bool auto_tp = false; bool super_jump = false; bool beast_jump = false; - bool graceful_landing = false; + bool graceful_landing = false; bool healthregen = false; float healthregenrate = 1.0f; bool superman = false; @@ -501,7 +502,7 @@ namespace big struct settings { bool onboarding_complete = false; - bool dev_dlc = false; + bool dev_dlc = false; struct hotkeys { @@ -898,22 +899,19 @@ namespace big struct aimbot { - bool enable = false; - bool smoothing = true; - float smoothing_speed = 2.f; - bool on_player = true; - bool on_enemy = false; - bool on_police = false; - bool on_npc = false; - float fov = 90.f; - float distance = 200.f; - uint32_t selected_bone = 0x796E; // Default to head - NLOHMANN_DEFINE_TYPE_INTRUSIVE(aimbot, enable, smoothing, smoothing_speed, on_player, on_enemy, on_police, on_npc, fov, distance) + bool enable = false; + int64_t only_on_ped_type = -1; + bool only_on_player = false; + bool only_on_enemy = false; + float fov = 60.f; + float distance = 200.f; + int32_t selected_bone = (int32_t)ePedBoneType::HEAD; + NLOHMANN_DEFINE_TYPE_INTRUSIVE(aimbot, enable, only_on_ped_type, only_on_player, only_on_enemy, fov, distance, selected_bone) } aimbot{}; struct flying_axe { - bool enable = false; + bool enable = false; NLOHMANN_DEFINE_TYPE_INTRUSIVE(flying_axe, enable) } flying_axe{}; @@ -927,6 +925,7 @@ namespace big bool modify_explosion_radius = false; bool no_recoil = false; bool no_spread = false; + bool no_sway = false; std::string vehicle_gun_model = "bus"; bool increased_c4_limit = false; bool increased_flare_limit = false; diff --git a/src/function_types.hpp b/src/function_types.hpp index 0df65cd7..b6682bb8 100644 --- a/src/function_types.hpp +++ b/src/function_types.hpp @@ -208,12 +208,15 @@ namespace big::functions using remove_player_from_sender_list = bool (*)(void* list, uint64_t* rockstar_id); - using get_ped_seat = CGetPedSeatReturnClass*(*)(PVOID seat_info, CPed* ped); - + using get_ped_seat = CGetPedSeatReturnClass* (*)(PVOID seat_info, CPed* ped); + using received_clone_remove = void (*)(CNetworkObjectMgr*, CNetGamePlayer*, CNetGamePlayer*, int16_t, uint32_t); using can_create_vehicle = bool (*)(); + + using cam_gameplay_directory_update = bool (*)(uintptr_t this_); + using get_searchlight = void* (*) (CPed*); using get_sector_data = void (*) (rage::fvector3* coords, std::uint16_t* x, std::uint16_t* y, std::uint16_t* z, rage::fvector3* sector_pos); diff --git a/src/gta/enums.hpp b/src/gta/enums.hpp index e11ca33b..9b20cf10 100644 --- a/src/gta/enums.hpp +++ b/src/gta/enums.hpp @@ -2089,4 +2089,36 @@ enum ComponentId : int ACCESSORIES_2, DECALS, AUXILIARY +}; + +enum ShapeTestIncludeFlags : int +{ + ST_INCLUDE_MOVER = 1, + ST_INCLUDE_VEHICLE = 2, + ST_INCLUDE_PED = 4, + ST_INCLUDE_RAGDOLL = 8, + ST_INCLUDE_OBJECT = 16, + ST_INCLUDE_PICKUP = 32, + ST_INCLUDE_GLASS = 64, + ST_INCLUDE_RIVER = 128, + ST_INCLUDE_FOLIAGE = 256, + ST_INCLUDE_ALL = 511, +}; + +enum ShapeTestOptionFlag : int +{ + ST_OPTION_IGNORE_GLASS = (1 << 0), + ST_OPTION_IGNORE_TRANSPARENT = (1 << 1), + ST_OPTION_IGNORE_NOTHING = (1 << 2), +}; + +enum PedRelationships : int +{ + Companion, + Like, + Nothing, + Dislike, + Wanted, + Hate, + Indifferent = 255 }; \ No newline at end of file diff --git a/src/gta_pointers.hpp b/src/gta_pointers.hpp index 283b6f5f..b5c8d290 100644 --- a/src/gta_pointers.hpp +++ b/src/gta_pointers.hpp @@ -358,6 +358,9 @@ namespace big functions::can_create_vehicle m_can_create_vehicle; + uintptr_t* m_cam_gameplay_director; + functions::cam_gameplay_directory_update m_cam_gameplay_director_update; + PVOID m_format_int; PVOID m_searchlight_crash; @@ -393,6 +396,8 @@ namespace big PVOID m_error_packet_memmove; PVOID m_create_pool_item; + + PVOID m_scope_sway_function; }; #pragma pack(pop) static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned"); diff --git a/src/hooking/hooking.cpp b/src/hooking/hooking.cpp index 230184ad..81b81c64 100644 --- a/src/hooking/hooking.cpp +++ b/src/hooking/hooking.cpp @@ -136,6 +136,8 @@ namespace big detour_hook_helper::add("CCV", g_pointers->m_gta.m_can_create_vehicle); + detour_hook_helper::add("CGDU", g_pointers->m_gta.m_cam_gameplay_director_update); + detour_hook_helper::add("FI", g_pointers->m_gta.m_format_int); detour_hook_helper::add("SLC", g_pointers->m_gta.m_searchlight_crash); diff --git a/src/hooking/hooking.hpp b/src/hooking/hooking.hpp index b7a48807..d16d9677 100644 --- a/src/hooking/hooking.hpp +++ b/src/hooking/hooking.hpp @@ -193,6 +193,8 @@ namespace big static bool can_create_vehicle(); + static bool aimbot_cam_gameplay_director_update(uintptr_t this_); + static void format_int(int64_t integer_to_format, char* format_string, size_t size_always_64, bool use_commas); static void write_node_data(void* data_node, rage::netObject* net_object, rage::datBitBuffer* buffer, void* log, bool update); diff --git a/src/pointers.cpp b/src/pointers.cpp index 27ad95fa..016d3ae0 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -1686,6 +1686,24 @@ namespace big g_pointers->m_gta.m_can_create_vehicle = ptr.as(); } }, + // Cam Gameplay Director + { + "CGD", + "48 8B 05 ? ? ? ? 38 98 ? ? ? ? 8A C3", + [](memory::handle ptr) + { + g_pointers->m_gta.m_cam_gameplay_director = ptr.add(3).rip().as(); + } + }, + // Cam Gameplay Director Update + { + "CGDU", + "E9 CD 09 00 00", + [](memory::handle ptr) + { + g_pointers->m_gta.m_cam_gameplay_director_update = ptr.sub(0x32).as(); + } + }, // Format Integer { "FI", @@ -1867,6 +1885,15 @@ namespace big { g_pointers->m_gta.m_create_pool_item = ptr.sub(0x6).as(); } + }, + // Scope Sway Function + { + "SSF", + "74 ? F3 0F 10 15 ? ? ? ? 41 B9 ? ? ? ? 48 8B D0 48 8B CF 44 89 7C 24", + [](memory::handle ptr) + { + g_pointers->m_gta.m_scope_sway_function = ptr.as(); + } } >(); // don't leave a trailing comma at the end diff --git a/src/views/self/view_weapons.cpp b/src/views/self/view_weapons.cpp index 97d4efd7..98d67542 100644 --- a/src/views/self/view_weapons.cpp +++ b/src/views/self/view_weapons.cpp @@ -1,8 +1,10 @@ #include "core/data/bullet_impact_types.hpp" #include "core/data/special_ammo_types.hpp" #include "fiber_pool.hpp" +#include "gta/enums.hpp" #include "gta/joaat.hpp" #include "gta/weapons.hpp" +#include "imgui_internal.h" #include "natives.hpp" #include "pointers.hpp" #include "services/gta_data/gta_data_service.hpp" @@ -100,6 +102,8 @@ namespace big components::command_checkbox<"norecoil">(); ImGui::SameLine(); components::command_checkbox<"nospread">(); + ImGui::SameLine(); + components::command_checkbox<"nosway">(); components::button("GET_ALL_WEAPONS"_T, [] { for (const auto& [_, weapon] : g_gta_data_service->weapons()) @@ -135,7 +139,8 @@ namespace big ImGui::Checkbox("VIEW_WEAPON_CUSTOM_GUN_ONLY_FIRES_WHEN_THE_WEAPON_IS_OUT"_T.data(), &g.self.custom_weapon_stop); CustomWeapon selected = g.weapons.custom_weapon; - if (ImGui::BeginCombo("WEAPON"_T.data(), g_translation_service.get_translation(custom_weapons[(int)selected].name).data())) + if (ImGui::BeginCombo("WEAPON"_T.data(), + g_translation_service.get_translation(custom_weapons[(int)selected].name).data())) { for (const custom_weapon& weapon : custom_weapons) { @@ -173,7 +178,10 @@ namespace big case CustomWeapon::PAINT_GUN: ImGui::Checkbox("RAINBOW_PAINT"_T.data(), &g.weapons.paintgun.rainbow); ImGui::SliderFloat("VIEW_WEAPON_RAINBOW_SPEED"_T.data(), &g.weapons.paintgun.speed, 0.f, 10.f); - if (!g.weapons.paintgun.rainbow) { ImGui::ColorEdit4("VIEW_WEAPON_PAINT_GUN_COLOR"_T.data(), g.weapons.paintgun.col); } + if (!g.weapons.paintgun.rainbow) + { + ImGui::ColorEdit4("VIEW_WEAPON_PAINT_GUN_COLOR"_T.data(), g.weapons.paintgun.col); + } } ImGui::SeparatorText("VIEW_WEAPON_AIM_ASSISTANCE"_T.data()); @@ -183,22 +191,38 @@ namespace big if (g.weapons.aimbot.enable) { - components::command_checkbox<"aimatplayer">(); + components::command_checkbox<"aimonlyatplayer">(); ImGui::SameLine(); - components::command_checkbox<"aimatnpc">(); - ImGui::SameLine(); - components::command_checkbox<"aimatpolice">(); - ImGui::SameLine(); - components::command_checkbox<"aimatenemy">(); + components::command_checkbox<"aimonlyatenemy">(); + + ImGui::CheckboxFlags("PLAYERS"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_NETWORK_PLAYER); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_CIVMALE"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_CIVMALE); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_CIVFEMALE"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_CIVFEMALE); + + ImGui::CheckboxFlags("PED_TYPE_DEALER"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_DEALER); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_PROSTITUTE"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_PROSTITUTE); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_BUM"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_BUM); + + ImGui::CheckboxFlags("PED_TYPE_MEDIC"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_MEDIC); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_FIREMAN"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_FIREMAN); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_ARMY"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_ARMY); + + ImGui::CheckboxFlags("POLICE"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_COP); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_SWAT"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_SWAT); + + ImGui::CheckboxFlags("GUI_TAB_MISSIONS"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_MISSION); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_ANIMAL"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_ANIMAL); + ImGui::SameLine(); + ImGui::CheckboxFlags("PED_TYPE_SPECIAL"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_SPECIAL); - components::command_checkbox<"smoothing">(); - if (g.weapons.aimbot.smoothing) - { - ImGui::SameLine(); - ImGui::PushItemWidth(220); - ImGui::SliderFloat("VIEW_WEAPON_AIM_SPEED"_T.data(), &g.weapons.aimbot.smoothing_speed, 1.f, 8.f, "%.1f"); - ImGui::PopItemWidth(); - } ImGui::PushItemWidth(350); ImGui::SliderFloat("VIEW_WEAPON_AIM_FOV"_T.data(), &g.weapons.aimbot.fov, 1.f, 360.f, "%.0f"); ImGui::SliderFloat("VIEW_SELF_CUSTOM_TELEPORT_DISTANCE"_T.data(), &g.weapons.aimbot.distance, 1.f, 1000.f, "%.0f"); @@ -252,7 +276,7 @@ namespace big { for (std::string attachment : weapon.m_attachments) { - weapon_component attachment_component = g_gta_data_service->weapon_component_by_name(attachment); + weapon_component attachment_component = g_gta_data_service->weapon_component_by_name(attachment); std::string attachment_name = attachment_component.m_display_name; Hash attachment_hash = attachment_component.m_hash; if (attachment_hash == NULL) @@ -338,7 +362,8 @@ namespace big components::button("VIEW_WEAPON_PERSIST_WEAPONS_SET_LOADOUT"_T, [] { persist_weapons::set_weapon_loadout(selected_loadout); }); - ImGui::Text(std::format("{}: {}:", "VIEW_WEAPON_PERSIST_WEAPONS_CURRENT_LOADOUT"_T, g.persist_weapons.weapon_loadout_file).data()); + ImGui::Text(std::format("{}: {}:", "VIEW_WEAPON_PERSIST_WEAPONS_CURRENT_LOADOUT"_T, g.persist_weapons.weapon_loadout_file) + .data()); ImGui::EndGroup(); ImGui::PopItemWidth(); }