diff --git a/src/backend/looped/weapons/gravity_gun.cpp b/src/backend/looped/weapons/gravity_gun.cpp index fb2fe580..d4e24c8a 100644 --- a/src/backend/looped/weapons/gravity_gun.cpp +++ b/src/backend/looped/weapons/gravity_gun.cpp @@ -6,103 +6,120 @@ namespace big { - static Entity ent = 0; + static std::vector ents = { }; static Vector3 location; static Vector3 other; static float dist; + static constexpr double multiplier = 3.0; static const int scroll = 0; + void apply_velocity(Entity e) + { + if (ENTITY::DOES_ENTITY_EXIST(e)) + { + if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_NEXT)) + dist -= 5; + if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_PREV)) + dist += 5; + + if (!entity::take_control_of(e)) + return; // TODO: remove from vector + + ENTITY::SET_ENTITY_COLLISION(e, false, false); + + other = ENTITY::GET_ENTITY_COORDS(e, true); + + Vector3 rot = CAM::GET_GAMEPLAY_CAM_ROT(2); + float pitch = math::deg_to_rad(rot.x); // vertical + // float roll = rot.y; + float yaw = math::deg_to_rad(rot.z + 90); // horizontal + + Vector3 velocity; + + velocity.x = location.x + (dist * cos(pitch) * cos(yaw)) - other.x; + velocity.y = location.y + (dist * sin(yaw) * cos(pitch)) - other.y; + velocity.z = location.z + (dist * sin(pitch)) - other.z; + + ENTITY::SET_ENTITY_VELOCITY(e, velocity.x * (float)multiplier, velocity.y * (float)multiplier, velocity.z * (float)multiplier); + ENTITY::SET_ENTITY_ALPHA(e, 105, 0); + } + } + void looped::weapons_gravity_gun() { bool is_gravity_gun_selected = g.weapons.custom_weapon == CustomWeapon::GRAVITY_GUN; - constexpr double multiplier = 3.0; auto is_zoomed_in = is_gravity_gun_selected && PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_AIM); if (is_zoomed_in) { location = self::pos; - auto is_attack_released = PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK) && ent == 0; - if (is_attack_released) - { - if (entity::raycast(&ent)) - { - if (ENTITY::IS_ENTITY_A_PED(ent) && PED::IS_PED_A_PLAYER(ent)) - { - ent = 0; + auto is_attack_just_pressed = PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK); + if (is_attack_just_pressed) + { + Entity ent_to_add; + + if (entity::raycast(&ent_to_add)) + { + if (ENTITY::IS_ENTITY_A_PED(ent_to_add) && PED::IS_PED_A_PLAYER(ent_to_add)) + { g_notification_service->push_warning("Weapons", "You can't move player entities!"); } else { - other = ENTITY::GET_ENTITY_COORDS(ent, true); - dist = (float)math::distance_between_vectors(location, other); + other = ENTITY::GET_ENTITY_COORDS(ent_to_add, true); + const int temp_dist = (float)math::distance_between_vectors(location, other); - if (dist > 500) + if (ents.size() == 0) { - ent = 0; + dist = temp_dist; + } + if (temp_dist > 500) + { g_notification_service->push_warning("Weapons", "Entity is too far."); } else { - if (entity::take_control_of(ent) && ENTITY::IS_ENTITY_A_PED(ent) && !PED::IS_PED_RAGDOLL(ent)) + if (entity::take_control_of(ent_to_add) && ENTITY::IS_ENTITY_A_PED(ent_to_add) && !PED::IS_PED_RAGDOLL(ent_to_add)) { - TASK::SET_HIGH_FALL_TASK(ent, 0, 0, 0); + TASK::SET_HIGH_FALL_TASK(ent_to_add, 0, 0, 0); g_notification_service->push_warning("Weapons", "Selected entity at crosshair."); } + + ents.push_back(ent_to_add); } } } - else - { - ent = 0; - - g_notification_service->push_warning("Weapons", "No entity found."); - } } - - if (ENTITY::DOES_ENTITY_EXIST(ent)) + if (ents.size() > 0) { - if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_NEXT)) - dist -= 5; - if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_PREV)) - dist += 5; - - if (!entity::take_control_of(ent)) + for (const auto& e: ents) { - ent = 0; - - return g_notification_service->push_warning("Weapons", "Failed to take control of entity."); + apply_velocity(e); } - - ENTITY::SET_ENTITY_COLLISION(ent, false, false); - - other = ENTITY::GET_ENTITY_COORDS(ent, true); - - Vector3 rot = CAM::GET_GAMEPLAY_CAM_ROT(2); - float pitch = math::deg_to_rad(rot.x); // vertical - // float roll = rot.y; - float yaw = math::deg_to_rad(rot.z + 90); // horizontal - - Vector3 velocity; - - velocity.x = location.x + (dist * cos(pitch) * cos(yaw)) - other.x; - velocity.y = location.y + (dist * sin(yaw) * cos(pitch)) - other.y; - velocity.z = location.z + (dist * sin(pitch)) - other.z; - - ENTITY::SET_ENTITY_VELOCITY(ent, velocity.x * (float)multiplier, velocity.y * (float)multiplier, velocity.z * (float)multiplier); - ENTITY::SET_ENTITY_ALPHA(ent, 105, 0); } } - else if (ent != 0 && entity::take_control_of(ent)) + else if (ents.size() > 0) { - ENTITY::SET_ENTITY_COLLISION(ent, true, true); - ENTITY::RESET_ENTITY_ALPHA(ent); + for (const Entity& e: ents) + { + if (entity::take_control_of(e)) + { + if (g.weapons.gravity_gun.launch_on_release) + { + dist += 100; + apply_velocity(e); + } + ENTITY::SET_ENTITY_COLLISION(e, true, true); + ENTITY::RESET_ENTITY_ALPHA(e); + } + } - ent = 0; + ents.clear(); g_notification_service->push("Weapons", "Released entity."); } diff --git a/src/core/globals.hpp b/src/core/globals.hpp index db50eb57..a71654fc 100644 --- a/src/core/globals.hpp +++ b/src/core/globals.hpp @@ -571,6 +571,12 @@ namespace big NLOHMANN_DEFINE_TYPE_INTRUSIVE(ammo_special, toggle, type, explosion_tag) } ammo_special{}; + struct gravity_gun + { + bool launch_on_release = false; + NLOHMANN_DEFINE_TYPE_INTRUSIVE(gravity_gun, launch_on_release) + } gravity_gun; + CustomWeapon custom_weapon = CustomWeapon::NONE; bool force_crosshairs = false; bool infinite_ammo = false; @@ -584,7 +590,7 @@ namespace big NLOHMANN_DEFINE_TYPE_INTRUSIVE(weapons, ammo_special, custom_weapon, force_crosshairs, infinite_ammo, infinite_mag, increased_damage, no_recoil, - no_spread, vehicle_gun_model, bypass_c4_limit, rapid_fire) + no_spread, vehicle_gun_model, bypass_c4_limit, rapid_fire, gravity_gun) } weapons{}; struct window diff --git a/src/views/self/view_weapons.cpp b/src/views/self/view_weapons.cpp index 3356d03e..5affd73a 100644 --- a/src/views/self/view_weapons.cpp +++ b/src/views/self/view_weapons.cpp @@ -135,6 +135,9 @@ namespace big switch (selected) { + case CustomWeapon::GRAVITY_GUN: + ImGui::Checkbox("Launch on release", &g.weapons.gravity_gun.launch_on_release); + break; case CustomWeapon::VEHICLE_GUN: // this some ugly ass looking code static char vehicle_gun[12];