diff --git a/src/backend/looped/self/noclip.cpp b/src/backend/looped/self/noclip.cpp index 2fda4af1..cdc6ae11 100644 --- a/src/backend/looped/self/noclip.cpp +++ b/src/backend/looped/self/noclip.cpp @@ -85,7 +85,7 @@ namespace big ENTITY::FREEZE_ENTITY_POSITION(ent, false); const auto is_aiming = PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_AIM); - if (is_aiming) + if (is_aiming || CAM::GET_FOLLOW_PED_CAM_VIEW_MODE() == CameraMode::FIRST_PERSON) { vel = vel * g.self.noclip_aim_speed_multiplier; diff --git a/src/backend/looped/tunables/no_idle_kick.cpp b/src/backend/looped/tunables/no_idle_kick.cpp index d57d0776..7e19ae96 100644 --- a/src/backend/looped/tunables/no_idle_kick.cpp +++ b/src/backend/looped/tunables/no_idle_kick.cpp @@ -1,6 +1,7 @@ #include "backend/looped_command.hpp" #include "services/tunables/tunables_service.hpp" #include "core/scr_globals.hpp" +#include "natives.hpp" namespace big { @@ -10,19 +11,11 @@ namespace big virtual void on_tick() override { - for (int i = 0; i < 4; i++) - { - *scr_globals::tuneables.at(87).at(i).as() = INT_MAX; - } + *scr_globals::session_info.at(1155).as() = -1; + *scr_globals::session_info.at(1171).as() = -1; + CAM::INVALIDATE_IDLE_CAM(); + CAM::INVALIDATE_CINEMATIC_VEHICLE_IDLE_MODE(); } - - virtual void on_disable() override - { - *scr_globals::tuneables.at(87).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("IDLEKICK_WARNING1")); - *scr_globals::tuneables.at(87).at(1).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("IDLEKICK_WARNING2")); - *scr_globals::tuneables.at(87).at(2).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("IDLEKICK_WARNING3")); - *scr_globals::tuneables.at(87).at(3).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("IDLEKICK_KICK")); - } }; no_idle_kick g_no_idle_kick("noidlekick", "NO_IDLE_KICK", "Prevents you from being kicked while idling.", g.tunables.no_idle_kick); diff --git a/src/backend/looped/vehicle/allow_all_vehicles_in_heists.cpp b/src/backend/looped/vehicle/allow_all_vehicles_in_heists.cpp new file mode 100644 index 00000000..52408e57 --- /dev/null +++ b/src/backend/looped/vehicle/allow_all_vehicles_in_heists.cpp @@ -0,0 +1,80 @@ +#include "backend/looped/looped.hpp" +#include "backend/looped_command.hpp" +#include "core/scr_globals.hpp" +#include "services/tunables/tunables_service.hpp" + +namespace big +{ + class allvehsinheists : looped_command + { + using looped_command::looped_command; + + virtual void on_tick() override + { + *scr_globals::tuneables.at(21911).as() = FALSE; //APC + *scr_globals::tuneables.at(21912).as() = FALSE; //ARDENT + *scr_globals::tuneables.at(21913).as() = FALSE; //NIGHTSHARK + *scr_globals::tuneables.at(21914).as() = FALSE; //INSURGENT3 + *scr_globals::tuneables.at(21915).as() = FALSE; //TECHNICAL3 + *scr_globals::tuneables.at(21916).as() = FALSE; //HALFTRACK + *scr_globals::tuneables.at(21917).as() = FALSE; //TRAILERSMALL + *scr_globals::tuneables.at(21918).as() = FALSE; //TAMPA3 + *scr_globals::tuneables.at(21919).as() = FALSE; //DUNE3 + *scr_globals::tuneables.at(21920).as() = FALSE; //OPPRESSOR + *scr_globals::tuneables.at(23026).as() = FALSE; //VIGILANTE + *scr_globals::tuneables.at(23597).as() = FALSE; //THRUSTER + *scr_globals::tuneables.at(23598).as() = FALSE; //DELUXO + *scr_globals::tuneables.at(23599).as() = FALSE; //STROMBERG + *scr_globals::tuneables.at(23600).as() = FALSE; //RCV + *scr_globals::tuneables.at(23601).as() = FALSE; //CHERNOBOG + *scr_globals::tuneables.at(23602).as() = FALSE; //BARRAGE + *scr_globals::tuneables.at(23603).as() = FALSE; //KHANJALI + *scr_globals::tuneables.at(23604).as() = FALSE; //SAFARI + *scr_globals::tuneables.at(23605).as() = FALSE; //SAVESTRA + *scr_globals::tuneables.at(23607).as() = FALSE; //REVOLTER + *scr_globals::tuneables.at(23608).as() = FALSE; //AVENGER + *scr_globals::tuneables.at(23609).as() = FALSE; //VOLATOL + *scr_globals::tuneables.at(23610).as() = FALSE; //AKULA + *scr_globals::tuneables.at(23611).as() = FALSE; //OPPRESSOR2 + *scr_globals::tuneables.at(23612).as() = FALSE; //SCRAMJET + *scr_globals::tuneables.at(23613).as() = FALSE; //HYDRA + *scr_globals::tuneables.at(25952).as() = FALSE; //TOREADOR + *scr_globals::tuneables.at(23606).as() = FALSE; //VISERIS + } + + virtual void on_disable() override + { + *scr_globals::tuneables.at(21911).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_APC_IN_HEISTS")); + *scr_globals::tuneables.at(21912).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_ARDENT_IN_HEISTS")); + *scr_globals::tuneables.at(21913).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_NIGHTSHARK_IN_HEISTS")); + *scr_globals::tuneables.at(21914).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_INSURGENT3_IN_HEISTS")); + *scr_globals::tuneables.at(21915).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_TECHNICAL3_IN_HEISTS")); + *scr_globals::tuneables.at(21916).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_HALFTRACK_IN_HEISTS")); + *scr_globals::tuneables.at(21917).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_TRAILERSMALL_IN_HEISTS")); + *scr_globals::tuneables.at(21918).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_TAMPA3_IN_HEISTS")); + *scr_globals::tuneables.at(21919).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_DUNE3_IN_HEISTS")); + *scr_globals::tuneables.at(21920).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("GR_BLOCK_OPPRESSOR_IN_HEISTS")); + *scr_globals::tuneables.at(23026).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("SMUG_BLOCK_VIGILANTE_IN_HEISTS")); + *scr_globals::tuneables.at(23597).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_THRUSTER_IN_HEISTS")); + *scr_globals::tuneables.at(23598).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_DELUXO_IN_HEISTS")); + *scr_globals::tuneables.at(23599).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_STROMBERG_IN_HEISTS")); + *scr_globals::tuneables.at(23600).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_RCV_IN_HEISTS")); + *scr_globals::tuneables.at(23601).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_CHERNOBOG_IN_HEISTS")); + *scr_globals::tuneables.at(23602).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_BARRAGE_IN_HEISTS")); + *scr_globals::tuneables.at(23603).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_KHANJALI_IN_HEISTS")); + *scr_globals::tuneables.at(23604).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_SAFARI_IN_HEISTS")); + *scr_globals::tuneables.at(23605).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_SAVESTRA_IN_HEISTS")); + *scr_globals::tuneables.at(23607).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_REVOLTER_IN_HEISTS")); + *scr_globals::tuneables.at(23608).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_AVENGER_IN_HEISTS")); + *scr_globals::tuneables.at(23609).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_VOLATOL_IN_HEISTS")); + *scr_globals::tuneables.at(23610).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_AKULA_IN_HEISTS")); + *scr_globals::tuneables.at(23611).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("BB_BLOCK_OPPRESSOR2_IN_HEISTS")); + *scr_globals::tuneables.at(23612).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("BB_BLOCK_SCRAMJET_IN_HEISTS")); + *scr_globals::tuneables.at(23613).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("BLOCK_HYDRA_IN_HEISTS")); + *scr_globals::tuneables.at(25952).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("BLOCK_TOREADOR_IN_HEISTS")); + *scr_globals::tuneables.at(23606).as() = *g_tunables_service->get_tunable(RAGE_JOAAT("H2_BLOCK_VISERIS_IN_HEISTS")); + } + }; + + allvehsinheists g_allvehsinheists("allvehsinheists", "VEHICLE_ALLOW_ALL_IN_HEISTS", "VEHICLE_ALLOW_ALL_IN_HEISTS_DESC", g.vehicle.all_vehs_in_heists); +} \ No newline at end of file diff --git a/src/core/scr_globals.hpp b/src/core/scr_globals.hpp index a8077741..d8557873 100644 --- a/src/core/scr_globals.hpp +++ b/src/core/scr_globals.hpp @@ -38,6 +38,8 @@ namespace big::scr_globals static inline const script_global offradar_time(2672524); + static inline const script_global session_info(1654054); + static inline const script_global tuneables(262145); } diff --git a/src/core/settings.hpp b/src/core/settings.hpp index e1c90c3a..318086de 100644 --- a/src/core/settings.hpp +++ b/src/core/settings.hpp @@ -703,8 +703,9 @@ namespace big bool no_collision = false; bool unlimited_weapons = false; bool siren_mute = false; + bool all_vehs_in_heists = false; - NLOHMANN_DEFINE_TYPE_INTRUSIVE(vehicle, speedo_meter, fly, rainbow_paint, speed_unit, god_mode, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask, auto_drive_destination, auto_drive_style, auto_drive_speed, auto_turn_signals, boost_behavior, drive_on_water, horn_boost, instant_brake, block_homing, seatbelt, turn_signals, vehicle_jump, keep_vehicle_repaired, no_water_collision, disable_engine_auto_start, change_engine_state_immediately, keep_engine_running, keep_vehicle_clean, vehinvisibility, localveh_visibility, keep_on_ground, no_collision, unlimited_weapons, siren_mute) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(vehicle, speedo_meter, fly, rainbow_paint, speed_unit, god_mode, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask, auto_drive_destination, auto_drive_style, auto_drive_speed, auto_turn_signals, boost_behavior, drive_on_water, horn_boost, instant_brake, block_homing, seatbelt, turn_signals, vehicle_jump, keep_vehicle_repaired, no_water_collision, disable_engine_auto_start, change_engine_state_immediately, keep_engine_running, keep_vehicle_clean, vehinvisibility, localveh_visibility, keep_on_ground, no_collision, unlimited_weapons, siren_mute, all_vehs_in_heists) } vehicle{}; struct weapons diff --git a/src/gta/enums.hpp b/src/gta/enums.hpp index 864e9a90..6925a46d 100644 --- a/src/gta/enums.hpp +++ b/src/gta/enums.hpp @@ -2040,4 +2040,13 @@ enum class GameMode : int32_t Golf = 0xB, Tennis = 0xC, ShootingRange = 0xD +}; + +enum CameraMode : int +{ + THIRD_PERSON_NEAR = 0, + THIRD_PERSON_MEDIUM = 1, + THIRD_PERSON_FAR = 2, + CINEMATIC = 3, + FIRST_PERSON = 4, }; \ No newline at end of file diff --git a/src/util/entity.cpp b/src/util/entity.cpp new file mode 100644 index 00000000..2616b39c --- /dev/null +++ b/src/util/entity.cpp @@ -0,0 +1,289 @@ +#include "entity.hpp" + +namespace big::entity +{ + void cage_ped(Ped ped) + { + Hash hash = RAGE_JOAAT("prop_gold_cont_01"); + + Vector3 location = ENTITY::GET_ENTITY_COORDS(ped, true); + OBJECT::CREATE_OBJECT(hash, location.x, location.y, location.z - 1.f, true, false, false); + } + + void clean_ped(Ped ped) + { + Ped player_ped = self::ped; + + PED::CLEAR_PED_BLOOD_DAMAGE(player_ped); + PED::CLEAR_PED_WETNESS(player_ped); + PED::CLEAR_PED_ENV_DIRT(player_ped); + PED::RESET_PED_VISIBLE_DAMAGE(player_ped); + } + + void delete_entity(Entity ent) + { + if (!ENTITY::DOES_ENTITY_EXIST(ent)) + return; + if (!take_control_of(ent)) + { + LOG(VERBOSE) << "Failed to take control of entity before deleting"; + return; + } + + ENTITY::DETACH_ENTITY(ent, 1, 1); + ENTITY::SET_ENTITY_COORDS_NO_OFFSET(ent, 7000.f, 7000.f, 15.f, 0, 0, 0); + if (!ENTITY::IS_ENTITY_A_MISSION_ENTITY(ent)) + { + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(ent, true, true); + } + ENTITY::DELETE_ENTITY(&ent); + } + + bool raycast(Entity* ent) + { + BOOL hit; + Vector3 endCoords; + Vector3 surfaceNormal; + + Vector3 camCoords = CAM::GET_GAMEPLAY_CAM_COORD(); + Vector3 rot = CAM::GET_GAMEPLAY_CAM_ROT(2); + Vector3 dir = math::rotation_to_direction(rot); + Vector3 farCoords; + + farCoords.x = camCoords.x + dir.x * 1000; + farCoords.y = camCoords.y + dir.y * 1000; + farCoords.z = camCoords.z + dir.z * 1000; + + int ray = SHAPETEST::START_EXPENSIVE_SYNCHRONOUS_SHAPE_TEST_LOS_PROBE(camCoords.x, + camCoords.y, + camCoords.z, + farCoords.x, + farCoords.y, + farCoords.z, + -1, + 0, + 7); + SHAPETEST::GET_SHAPE_TEST_RESULT(ray, &hit, &endCoords, &surfaceNormal, ent); + + return (bool)hit; + } + + bool raycast(Vector3* endcoor) + { + Entity ent; + BOOL hit; + Vector3 surfaceNormal; + + Vector3 camCoords = CAM::GET_GAMEPLAY_CAM_COORD(); + Vector3 dir = math::rotation_to_direction(CAM::GET_GAMEPLAY_CAM_ROT(2)); + Vector3 farCoords; + + farCoords.x = camCoords.x + dir.x * 1000; + farCoords.y = camCoords.y + dir.y * 1000; + farCoords.z = camCoords.z + dir.z * 1000; + + int ray = SHAPETEST::START_EXPENSIVE_SYNCHRONOUS_SHAPE_TEST_LOS_PROBE(camCoords.x, + camCoords.y, + camCoords.z, + farCoords.x, + farCoords.y, + farCoords.z, + -1, + 0, + 7); + SHAPETEST::GET_SHAPE_TEST_RESULT(ray, &hit, endcoor, &surfaceNormal, &ent); + + return (bool)hit; + } + + bool network_has_control_of_entity(rage::netObject* net_object) + { + return !net_object || !net_object->m_next_owner_id && (net_object->m_control_id == -1); + } + + bool take_control_of(Entity ent, int timeout) + { + if (!*g_pointers->m_gta.m_is_session_started) + return true; + + auto hnd = g_pointers->m_gta.m_handle_to_ptr(ent); + + if (!hnd || !hnd->m_net_object || !*g_pointers->m_gta.m_is_session_started) + return false; + + if (network_has_control_of_entity(hnd->m_net_object)) + return true; + + for (int i = 0; i < timeout; i++) + { + g_pointers->m_gta.m_request_control(hnd->m_net_object); + + if (network_has_control_of_entity(hnd->m_net_object)) + return true; + + if (timeout != 0) + script::get_current()->yield(); + } + + return false; + } + + std::vector get_entities(bool vehicles, bool peds, bool props, bool include_self_veh) + { + std::vector target_entities; + + if (vehicles) + { + for (auto vehicle : pools::get_all_vehicles()) + { + if (!include_self_veh && vehicle == gta_util::get_local_vehicle()) + continue; + + target_entities.push_back(g_pointers->m_gta.m_ptr_to_handle(vehicle)); + } + } + + if (peds) + { + for (auto ped : pools::get_all_peds()) + { + if (ped == g_local_player) + continue; + + target_entities.push_back(g_pointers->m_gta.m_ptr_to_handle(ped)); + } + } + + if (props) + { + for (auto prop : pools::get_all_props()) + { + target_entities.push_back(g_pointers->m_gta.m_ptr_to_handle(prop)); + } + } + return target_entities; + } + + bool load_ground_at_3dcoord(Vector3& location) + { + float groundZ; + bool done = false; + + for (int i = 0; i < 10; i++) + { + for (int z = 0; z < 1000; z += 25) + { + float ground_iteration = static_cast(z); + // Only request a collision after the first try failed because the location might already be loaded on first attempt. + if (i >= 1 && (z % 100 == 0)) + { + STREAMING::REQUEST_COLLISION_AT_COORD(location.x, location.y, ground_iteration); + script::get_current()->yield(); + } + + if (MISC::GET_GROUND_Z_FOR_3D_COORD(location.x, location.y, ground_iteration, &groundZ, false, false)) + { + location.z = groundZ + 1.f; + done = true; + } + } + + float height; + if (done && WATER::GET_WATER_HEIGHT(location.x, location.y, location.z, &height)) + { + location.z = height + 1.f; + } + + if (done) + { + return true; + } + } + + location.z = 1000.f; + + return false; + } + + double distance_to_middle_of_screen(const rage::fvector2& screen_pos) + { + double cumulative_distance{}; + + if (screen_pos.x > 0.5) + cumulative_distance += screen_pos.x - 0.5; + else + cumulative_distance += 0.5 - screen_pos.x; + + if (screen_pos.y > 0.5) + cumulative_distance += screen_pos.y - 0.5; + else + cumulative_distance += 0.5 - screen_pos.y; + + return cumulative_distance; + } + + Entity get_entity_closest_to_middle_of_screen(rage::fwEntity** pointer, std::vector ignore_entities, bool include_veh, bool include_ped, bool include_prop, bool include_players) + { + Entity closest_entity{}; + rage::fwEntity* closest_entity_ptr = nullptr; + float distance = 1; + + auto ignored_entity = [=](Entity handle) -> bool { + if (handle == self::ped) + return true; + + for (auto ent : ignore_entities) + { + if (handle == ent) + return true; + } + + return false; + }; + + auto update_closest_entity = [&](Entity handle, rage::fwEntity* entity_ptr) { + Vector3 pos = ENTITY::GET_ENTITY_COORDS(handle, 1); + rage::fvector2 screenpos; + HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos.x, pos.y, pos.z, &screenpos.x, &screenpos.y); + + if (distance_to_middle_of_screen(screenpos) < distance && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(self::ped, handle, 17) && !ignored_entity(handle)) + { + closest_entity = handle; + closest_entity_ptr = entity_ptr; + distance = distance_to_middle_of_screen(screenpos); + } + }; + + auto include_pool = [&](auto& pool) { + for (const auto ptr : pool()) + if (ptr) + update_closest_entity(g_pointers->m_gta.m_ptr_to_handle(ptr), ptr); + }; + + if (include_veh) + include_pool(pools::get_all_vehicles); + + if (include_ped) + include_pool(pools::get_all_peds); + + if (include_prop) + include_pool(pools::get_all_props); + + if (include_players) + { + for (auto player : g_player_service->players() | std::ranges::views::values) + { + if (player->get_ped()) + { + Ped handle = g_pointers->m_gta.m_ptr_to_handle(player->get_ped()); + update_closest_entity(handle, player->get_ped()); + } + } + } + + if (pointer) + *pointer = closest_entity_ptr; + + return closest_entity; + } +} \ No newline at end of file diff --git a/src/util/entity.hpp b/src/util/entity.hpp index 81a3511d..0d993b52 100644 --- a/src/util/entity.hpp +++ b/src/util/entity.hpp @@ -9,281 +9,15 @@ namespace big::entity { - inline void cage_ped(Ped ped) - { - Hash hash = RAGE_JOAAT("prop_gold_cont_01"); - - Vector3 location = ENTITY::GET_ENTITY_COORDS(ped, true); - OBJECT::CREATE_OBJECT(hash, location.x, location.y, location.z - 1.f, true, false, false); - } - - inline void clean_ped(Ped ped) - { - Ped player_ped = self::ped; - - PED::CLEAR_PED_BLOOD_DAMAGE(player_ped); - PED::CLEAR_PED_WETNESS(player_ped); - PED::CLEAR_PED_ENV_DIRT(player_ped); - PED::RESET_PED_VISIBLE_DAMAGE(player_ped); - } - + void cage_ped(Ped ped); + void clean_ped(Ped ped); bool take_control_of(Entity ent, int timeout = 300); - inline void delete_entity(Entity ent) - { - if (!ENTITY::DOES_ENTITY_EXIST(ent)) - return; - if (!take_control_of(ent)) - { - LOG(VERBOSE) << "Failed to take control of entity before deleting"; - return; - } - - ENTITY::DETACH_ENTITY(ent, 1, 1); - ENTITY::SET_ENTITY_COORDS_NO_OFFSET(ent, 7000.f, 7000.f, 15.f, 0, 0, 0); - if (!ENTITY::IS_ENTITY_A_MISSION_ENTITY(ent)) - { - ENTITY::SET_ENTITY_AS_MISSION_ENTITY(ent, true, true); - } - ENTITY::DELETE_ENTITY(&ent); - } - - inline bool raycast(Entity* ent) - { - BOOL hit; - Vector3 endCoords; - Vector3 surfaceNormal; - - Vector3 camCoords = CAM::GET_GAMEPLAY_CAM_COORD(); - Vector3 rot = CAM::GET_GAMEPLAY_CAM_ROT(2); - Vector3 dir = math::rotation_to_direction(rot); - Vector3 farCoords; - - farCoords.x = camCoords.x + dir.x * 1000; - farCoords.y = camCoords.y + dir.y * 1000; - farCoords.z = camCoords.z + dir.z * 1000; - - int ray = SHAPETEST::START_EXPENSIVE_SYNCHRONOUS_SHAPE_TEST_LOS_PROBE(camCoords.x, - camCoords.y, - camCoords.z, - farCoords.x, - farCoords.y, - farCoords.z, - -1, - 0, - 7); - SHAPETEST::GET_SHAPE_TEST_RESULT(ray, &hit, &endCoords, &surfaceNormal, ent); - - return (bool)hit; - } - - inline bool raycast(Vector3* endcoor) - { - Entity ent; - BOOL hit; - Vector3 surfaceNormal; - - Vector3 camCoords = CAM::GET_GAMEPLAY_CAM_COORD(); - Vector3 dir = math::rotation_to_direction(CAM::GET_GAMEPLAY_CAM_ROT(2)); - Vector3 farCoords; - - farCoords.x = camCoords.x + dir.x * 1000; - farCoords.y = camCoords.y + dir.y * 1000; - farCoords.z = camCoords.z + dir.z * 1000; - - int ray = SHAPETEST::START_EXPENSIVE_SYNCHRONOUS_SHAPE_TEST_LOS_PROBE(camCoords.x, - camCoords.y, - camCoords.z, - farCoords.x, - farCoords.y, - farCoords.z, - -1, - 0, - 7); - SHAPETEST::GET_SHAPE_TEST_RESULT(ray, &hit, endcoor, &surfaceNormal, &ent); - - return (bool)hit; - } - - inline bool network_has_control_of_entity(rage::netObject* net_object) - { - return !net_object || !net_object->m_next_owner_id && (net_object->m_control_id == -1); - } - - inline bool take_control_of(Entity ent, int timeout) - { - if (!*g_pointers->m_gta.m_is_session_started) - return true; - - auto hnd = g_pointers->m_gta.m_handle_to_ptr(ent); - - if (!hnd || !hnd->m_net_object || !*g_pointers->m_gta.m_is_session_started) - return false; - - if (network_has_control_of_entity(hnd->m_net_object)) - return true; - - for (int i = 0; i < timeout; i++) - { - g_pointers->m_gta.m_request_control(hnd->m_net_object); - - if (network_has_control_of_entity(hnd->m_net_object)) - return true; - - if (timeout != 0) - script::get_current()->yield(); - } - - return false; - } - - inline std::vector get_entities(bool vehicles, bool peds, bool props = false, bool include_self_veh = false) - { - std::vector target_entities; - - if (vehicles) - { - for (auto vehicle : pools::get_all_vehicles()) - { - if (!include_self_veh && vehicle == gta_util::get_local_vehicle()) - continue; - - target_entities.push_back(g_pointers->m_gta.m_ptr_to_handle(vehicle)); - } - } - - if (peds) - { - for (auto ped : pools::get_all_peds()) - { - if (ped == g_local_player) - continue; - - target_entities.push_back(g_pointers->m_gta.m_ptr_to_handle(ped)); - } - } - - if (props) - { - for (auto prop : pools::get_all_props()) - { - target_entities.push_back(g_pointers->m_gta.m_ptr_to_handle(prop)); - } - } - return target_entities; - } - - inline bool load_ground_at_3dcoord(Vector3& location) - { - float groundZ; - const uint8_t attempts = 100; - bool done = true; - - for (uint8_t i = 0; i < attempts; i++) - { - STREAMING::REQUEST_COLLISION_AT_COORD(location.x, location.y, 0.0f); - - if (MISC::GET_GROUND_Z_FOR_3D_COORD(location.x, location.y, 1000.f, &groundZ, false, false)) - { - location.z = groundZ + 1.f; - done = true; - } - - float height; - if (done && WATER::GET_WATER_HEIGHT(location.x, location.y, location.z, &height)) - { - location.z = height + 1.f; - } - - if (done) - return true; - - script::get_current()->yield(); - } - - location.z = 200.0f; - - return false; - } - - inline double distance_to_middle_of_screen(const rage::fvector2& screen_pos) - { - double cumulative_distance{}; - - if (screen_pos.x > 0.5) - cumulative_distance += screen_pos.x - 0.5; - else - cumulative_distance += 0.5 - screen_pos.x; - - if (screen_pos.y > 0.5) - cumulative_distance += screen_pos.y - 0.5; - else - cumulative_distance += 0.5 - screen_pos.y; - - return cumulative_distance; - } - - inline Entity get_entity_closest_to_middle_of_screen(rage::fwEntity** pointer = nullptr, std::vector ignore_entities = {}, bool include_veh = true, bool include_ped = true, bool include_prop = true, bool include_players = true) - { - Entity closest_entity{}; - rage::fwEntity* closest_entity_ptr = nullptr; - float distance = 1; - - auto ignored_entity = [=](Entity handle) -> bool { - if (handle == self::ped) - return true; - - for (auto ent : ignore_entities) - { - if (handle == ent) - return true; - } - - return false; - }; - - auto update_closest_entity = [&](Entity handle, rage::fwEntity* entity_ptr) { - Vector3 pos = ENTITY::GET_ENTITY_COORDS(handle, 1); - rage::fvector2 screenpos; - HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos.x, pos.y, pos.z, &screenpos.x, &screenpos.y); - - if (distance_to_middle_of_screen(screenpos) < distance && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(self::ped, handle, 17) && !ignored_entity(handle)) - { - closest_entity = handle; - closest_entity_ptr = entity_ptr; - distance = distance_to_middle_of_screen(screenpos); - } - }; - - auto include_pool = [&](auto& pool) { - for (const auto ptr : pool()) - if (ptr) - update_closest_entity(g_pointers->m_gta.m_ptr_to_handle(ptr), ptr); - }; - - if (include_veh) - include_pool(pools::get_all_vehicles); - - if (include_ped) - include_pool(pools::get_all_peds); - - if (include_prop) - include_pool(pools::get_all_props); - - if (include_players) - { - for (auto player : g_player_service->players() | std::ranges::views::values) - { - if (player->get_ped()) - { - Ped handle = g_pointers->m_gta.m_ptr_to_handle(player->get_ped()); - update_closest_entity(handle, player->get_ped()); - } - } - } - - if (pointer) - *pointer = closest_entity_ptr; - - return closest_entity; - } + void delete_entity(Entity ent); + bool raycast(Entity* ent); + bool raycast(Vector3* endcoor); + bool network_has_control_of_entity(rage::netObject* net_object); + std::vector get_entities(bool vehicles, bool peds, bool props = false, bool include_self_veh = false); + bool load_ground_at_3dcoord(Vector3& location); + double distance_to_middle_of_screen(const rage::fvector2& screen_pos); + Entity get_entity_closest_to_middle_of_screen(rage::fwEntity** pointer = nullptr, std::vector ignore_entities = {}, bool include_veh = true, bool include_ped = true, bool include_prop = true, bool include_players = true); } diff --git a/src/util/vehicle.hpp b/src/util/vehicle.hpp index cab2ce82..7eff6053 100644 --- a/src/util/vehicle.hpp +++ b/src/util/vehicle.hpp @@ -563,6 +563,21 @@ namespace big::vehicle return owned_mods; } + inline std::map get_vehicle_extras(Vehicle vehicle) + { + std::map extras; + + for (int i = 0; i <= 20; i++) + { + if (VEHICLE::DOES_EXTRA_EXIST(vehicle, i)) + { + extras[i] = VEHICLE::IS_VEHICLE_EXTRA_TURNED_ON(vehicle, i); + } + } + + return extras; + } + inline void teleport_into_vehicle(Vehicle veh) { PED::SET_PED_INTO_VEHICLE(self::ped, veh, -1); diff --git a/src/views/vehicle/view_lsc.cpp b/src/views/vehicle/view_lsc.cpp index 0d6f685f..1ede8879 100644 --- a/src/views/vehicle/view_lsc.cpp +++ b/src/views/vehicle/view_lsc.cpp @@ -18,6 +18,7 @@ namespace big static std::map owned_mods; static std::map slot_display_names; static std::map> mod_display_names; + static std::map vehicle_extras; static std::map> front_wheel_map; static std::map> rear_wheel_map; @@ -61,6 +62,7 @@ namespace big Hash model = ENTITY::GET_ENTITY_MODEL(player_vehicle); owned_mods = vehicle::get_owned_mods_from_vehicle(player_vehicle); + vehicle_extras = vehicle::get_vehicle_extras(player_vehicle); VEHICLE::SET_VEHICLE_MOD_KIT(player_vehicle, 0); std::map tmp_slot_display_names; @@ -90,6 +92,8 @@ namespace big { continue; } + slot_name.append("##"); + slot_name.append(std::to_string(slot)); tmp_slot_display_names[slot] = slot_name; std::map mod_names; @@ -279,6 +283,21 @@ namespace big ImGui::EndListBox(); } + int item_counter = 0; + for (auto& [extra, extra_enabled] : vehicle_extras) + { + if (item_counter % 5 == 0) + ImGui::SameLine(); + auto name = std::format("Extra #{}", extra); + if (ImGui::Checkbox(name.c_str(), &extra_enabled)) + { + g_fiber_pool->queue_job([extra, extra_enabled] { + VEHICLE::SET_VEHICLE_EXTRA(player_vehicle, extra, !extra_enabled); + }); + } + item_counter++; + } + ImGui::EndGroup(); if (selected_slot != -1) diff --git a/src/views/vehicle/view_vehicle.cpp b/src/views/vehicle/view_vehicle.cpp index c3a7e75e..50de03be 100644 --- a/src/views/vehicle/view_vehicle.cpp +++ b/src/views/vehicle/view_vehicle.cpp @@ -77,6 +77,7 @@ namespace big } components::command_checkbox<"vehnocollision">(); components::command_checkbox<"vehallweapons">(); + components::command_checkbox<"allvehsinheists">(); ImGui::EndGroup(); ImGui::SameLine();