From e16eb956bf7a575d90638a7e17ed89264f56ff6c Mon Sep 17 00:00:00 2001 From: aa15032261 Date: Thu, 28 Jul 2022 01:42:15 +0800 Subject: [PATCH] Added clone current vehicle feature. (#351) --- BigBaseV2/src/api/remote.hpp | 22 -- .../backend/looped/system/self_globals.cpp | 9 +- BigBaseV2/src/gta/VehicleValues.h | 62 ++- .../vehicle_preview_service.cpp | 90 ++++- .../vehicle_preview_service.hpp | 9 +- BigBaseV2/src/util/vehicle.hpp | 362 +++++++++++++++--- BigBaseV2/src/views/vehicle/view_lsc.cpp | 21 +- BigBaseV2/src/views/vehicle/view_pv.cpp | 52 +-- BigBaseV2/src/views/vehicle/view_spawn.cpp | 98 ++++- 9 files changed, 559 insertions(+), 166 deletions(-) diff --git a/BigBaseV2/src/api/remote.hpp b/BigBaseV2/src/api/remote.hpp index 0addcb26..f682c42f 100644 --- a/BigBaseV2/src/api/remote.hpp +++ b/BigBaseV2/src/api/remote.hpp @@ -3,28 +3,6 @@ namespace big::remote { - inline bool get_remote_file_etag(const std::string_view file_url) - { - try - { - http::Request req(file_url.data()); - http::Response res = req.send("HEAD", "", { "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/6.0" }, 10s); - - for (auto& header : res.headers) - { - LOG(WARNING) << header; - } - } - catch (const std::exception& e) - { - LOG(INFO) << "Failed to download binary, is the host down?: " << e.what(); - - return false; - } - - return true; - } - inline std::string get_etag_from_headers(std::vector headers) { std::string remote_etag = ""; diff --git a/BigBaseV2/src/backend/looped/system/self_globals.cpp b/BigBaseV2/src/backend/looped/system/self_globals.cpp index dee6a333..906ae4a7 100644 --- a/BigBaseV2/src/backend/looped/system/self_globals.cpp +++ b/BigBaseV2/src/backend/looped/system/self_globals.cpp @@ -11,6 +11,13 @@ namespace big self::pos = ENTITY::GET_ENTITY_COORDS(self::ped, false /*Unused*/); - self::veh = PED::GET_VEHICLE_PED_IS_IN(self::ped, false); + if (PED::IS_PED_IN_ANY_VEHICLE(self::ped, 0)) + { + self::veh = PED::GET_VEHICLE_PED_IS_IN(self::ped, false); + } + else + { + self::veh = 0; + } } } diff --git a/BigBaseV2/src/gta/VehicleValues.h b/BigBaseV2/src/gta/VehicleValues.h index 1b07c6b2..d1f64e35 100644 --- a/BigBaseV2/src/gta/VehicleValues.h +++ b/BigBaseV2/src/gta/VehicleValues.h @@ -381,7 +381,9 @@ enum VehicleModType MOD_TANK, MOD_WINDOWS, MOD_DOORS, - MOD_LIVERY + MOD_LIVERY, + MOD_LIGHTBAR, + }; enum CustomVehicleModType @@ -400,30 +402,50 @@ enum CustomVehicleModType MOD_NEON_LEFT_ON = -108, MOD_NEON_RIGHT_ON = -109, MOD_TIRE_CAN_BURST = -110, + MOD_DRIFT_TIRE = -111, - MOD_PRIMARY_COL = -111, - MOD_SECONDARY_COL = -112, - MOD_PEARLESCENT_COL = -113, - MOD_WHEEL_COL = -114, - MOD_INTERIOR_COL = -115, - MOD_DASHBOARD_COL = -116, - MOD_XENON_COL = -117, + MOD_PRIMARY_COL = -112, + MOD_SECONDARY_COL = -113, + MOD_PEARLESCENT_COL = -114, + MOD_WHEEL_COL = -115, + MOD_INTERIOR_COL = -116, + MOD_DASHBOARD_COL = -117, + MOD_XENON_COL = -118, - MOD_PRIMARY_COL_R = -118, - MOD_PRIMARY_COL_G = -119, - MOD_PRIMARY_COL_B = -120, + MOD_PRIMARY_COL_R = -119, + MOD_PRIMARY_COL_G = -120, + MOD_PRIMARY_COL_B = -121, - MOD_SECONDARY_COL_R = -121, - MOD_SECONDARY_COL_G = -122, - MOD_SECONDARY_COL_B = -123, + MOD_SECONDARY_COL_R = -122, + MOD_SECONDARY_COL_G = -123, + MOD_SECONDARY_COL_B = -124, - MOD_TIRESMOKE_COL_R = -124, - MOD_TIRESMOKE_COL_G = -125, - MOD_TIRESMOKE_COL_B = -126, + MOD_TIRESMOKE_COL_R = -125, + MOD_TIRESMOKE_COL_G = -126, + MOD_TIRESMOKE_COL_B = -127, - MOD_NEON_COL_R = -127, - MOD_NEON_COL_G = -128, - MOD_NEON_COL_B = -129, + MOD_NEON_COL_R = -128, + MOD_NEON_COL_G = -129, + MOD_NEON_COL_B = -130, + + MOD_PRIMARY_CUSTOM = -131, + MOD_SECONDARY_CUSTOM = -132, + + MOD_EXTRA_0 = -200, + MOD_EXTRA_1 = -201, + MOD_EXTRA_2 = -202, + MOD_EXTRA_3 = -203, + MOD_EXTRA_4 = -204, + MOD_EXTRA_5 = -205, + MOD_EXTRA_6 = -206, + MOD_EXTRA_7 = -207, + MOD_EXTRA_8 = -208, + MOD_EXTRA_9 = -209, + MOD_EXTRA_10 = -210, + MOD_EXTRA_11 = -211, + MOD_EXTRA_12 = -212, + MOD_EXTRA_13 = -213, + MOD_EXTRA_14 = -214 }; diff --git a/BigBaseV2/src/services/vehicle_preview/vehicle_preview_service.cpp b/BigBaseV2/src/services/vehicle_preview/vehicle_preview_service.cpp index d8f305b9..7f17e6b4 100644 --- a/BigBaseV2/src/services/vehicle_preview/vehicle_preview_service.cpp +++ b/BigBaseV2/src/services/vehicle_preview/vehicle_preview_service.cpp @@ -17,51 +17,94 @@ namespace big g_vehicle_preview_service = nullptr; } - void vehicle_preview_service::set_preview_vehicle(const vehicle_item& item) + void vehicle_preview_service::set_preview_vehicle(const vehicle_item& item, bool spawn_max) { if (item.hash != 0) { - if (m_model_hash != item.hash) + m_owned_mods.clear(); + + if (m_model_hash != item.hash || m_spawn_max != spawn_max) { + m_spawn_max = spawn_max; m_model_hash = item.hash; m_new_model = true; } - if (!m_running) - { - g_thread_pool->push([this] { preview_loop(); }); - } + preview_loop(); + } + } + + void vehicle_preview_service::set_preview_vehicle(const std::map& owned_mods, bool spawn_max) + { + auto hash_item = owned_mods.find(MOD_MODEL_HASH); + + if ( + m_spawn_max != spawn_max || + m_owned_mods.size() != owned_mods.size() || + !std::equal(m_owned_mods.begin(), m_owned_mods.end(), owned_mods.begin()) + ) { + m_owned_mods.clear(); + m_owned_mods.insert(owned_mods.begin(), owned_mods.end()); + + auto hash_item = owned_mods.find(MOD_MODEL_HASH); + + m_spawn_max = spawn_max; + m_model_hash = hash_item->second; + m_new_model = true; + + preview_loop(); } } void vehicle_preview_service::preview_loop() { - if (m_running) + if (m_running || m_loop_running) + { return; + } + m_running = true; g_fiber_pool->queue_job([this] { + m_loop_running = true; + while ( g_running && m_running && g_gui.m_opened && (g->spawn.preview_vehicle || g->clone_pv.preview_vehicle) ) { auto location = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(self::ped, 0.f, 10.f, .5f); - if (m_current_veh == -1) + if (m_current_veh == 0) { m_new_model = false; location.z = -10.f; - m_current_veh = vehicle::spawn(m_model_hash, location, 0.f, false); - ENTITY::FREEZE_ENTITY_POSITION(m_current_veh, true); - ENTITY::SET_ENTITY_ALPHA(m_current_veh, 0, 0); - ENTITY::SET_ENTITY_COLLISION(m_current_veh, false, false); - ENTITY::SET_CAN_CLIMB_ON_ENTITY(m_current_veh, false); - OBJECT::SET_OBJECT_ALLOW_LOW_LOD_BUOYANCY(m_current_veh, false); + + if (m_owned_mods.empty()) + { + m_current_veh = vehicle::spawn(m_model_hash, location, 0.f, false); + } + else + { + m_current_veh = vehicle::clone_from_owned_mods(m_owned_mods, location, 0.f, false); + } + + if (m_current_veh) + { + if (m_spawn_max) + { + vehicle::max_vehicle(m_current_veh); + } + + ENTITY::FREEZE_ENTITY_POSITION(m_current_veh, true); + ENTITY::SET_ENTITY_ALPHA(m_current_veh, 0, 0); + ENTITY::SET_ENTITY_COLLISION(m_current_veh, false, false); + ENTITY::SET_CAN_CLIMB_ON_ENTITY(m_current_veh, false); + OBJECT::SET_OBJECT_ALLOW_LOW_LOD_BUOYANCY(m_current_veh, false); + } } else if (m_new_model) { - entity::delete_entity(m_current_veh); - - m_current_veh = -1; + ENTITY::DETACH_ENTITY(m_current_veh, 1, 1); + ENTITY::DELETE_ENTITY(&m_current_veh); } else { @@ -74,19 +117,26 @@ namespace big ENTITY::SET_ENTITY_COORDS(m_current_veh, location.x, location.y, location.z, 0, 0, 0, 0); } - if (m_heading += 0.5f; m_heading > 359) m_heading = 0; + if (m_heading += 0.5f; m_heading > 359) + { + m_heading = 0; + } - script::get_current()->yield(); + script::get_current()->yield(15ms); } entity::delete_entity(m_current_veh); - m_current_veh = -1; + m_current_veh = 0; + m_model_hash = 0; + m_owned_mods.clear(); m_running = false; + m_loop_running = false; }); } void vehicle_preview_service::stop_preview() { + m_owned_mods.clear(); m_running = false; } } diff --git a/BigBaseV2/src/services/vehicle_preview/vehicle_preview_service.hpp b/BigBaseV2/src/services/vehicle_preview/vehicle_preview_service.hpp index a715e97d..79fa055f 100644 --- a/BigBaseV2/src/services/vehicle_preview/vehicle_preview_service.hpp +++ b/BigBaseV2/src/services/vehicle_preview/vehicle_preview_service.hpp @@ -9,16 +9,21 @@ namespace big std::condition_variable m_cond; std::mutex m_mutex; - Vehicle m_current_veh = -1; + Vehicle m_current_veh = 0; Hash m_model_hash; + std::map m_owned_mods; + bool m_new_model = false; float m_heading = 0.f; + bool m_spawn_max = false; + bool m_loop_running = false; bool m_running = false; public: vehicle_preview_service(); ~vehicle_preview_service(); - void set_preview_vehicle(const vehicle_item& item); + void set_preview_vehicle(const vehicle_item& item, bool spawn_max); + void set_preview_vehicle(const std::map& owned_mods, bool spawn_max); void preview_loop(); void stop_preview(); diff --git a/BigBaseV2/src/util/vehicle.hpp b/BigBaseV2/src/util/vehicle.hpp index df450c78..b9cf1b6f 100644 --- a/BigBaseV2/src/util/vehicle.hpp +++ b/BigBaseV2/src/util/vehicle.hpp @@ -49,6 +49,22 @@ namespace big::vehicle return speed; } + inline Vector3 get_spawn_location(bool spawn_inside) + { + float y_offset = 0; + + if (self::veh != 0) + { + y_offset = 10.f; + } + else if (!spawn_inside) + { + y_offset = 5.f; + } + + return ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(self::ped, 0.f, y_offset, 0.f); + } + inline void set_mp_bitset(Vehicle veh) { DECORATOR::DECOR_SET_INT(veh, "MPBitset", 0); @@ -169,7 +185,7 @@ namespace big::vehicle return true; } - inline int spawn(Hash hash, Vector3 location, float heading, bool is_networked = true) + inline Vehicle spawn(Hash hash, Vector3 location, float heading, bool is_networked = true) { for (uint8_t i = 0; !STREAMING::HAS_MODEL_LOADED(hash) && i < 100; i++) { @@ -179,8 +195,7 @@ namespace big::vehicle if (!STREAMING::HAS_MODEL_LOADED(hash)) { - g_notification_service->push_warning("Spawn", "Failed to spawn model, did you give an incorrect model?"); - return -1; + return 0; } *(unsigned short*)g_pointers->m_model_spawn_bypass = 0x9090; @@ -218,13 +233,10 @@ namespace big::vehicle // permission fix *spawn_global.at(27).at(1).as() = 0; - *spawn_global.at(27).at(19).as() = -1; - *spawn_global.at(27).at(60).as() = 1; - *spawn_global.at(27).at(77).as() = 4030726305; // personal car flag - *spawn_global.at(27).at(94).as() = 0; - *spawn_global.at(27).at(95).as() = 0; + *spawn_global.at(27).at(94).as() = 14; + *spawn_global.at(27).at(95).as() = 2; // mmi *spawn_global.at(27).at(103).as() = 0; @@ -250,14 +262,12 @@ namespace big::vehicle if (*spawn_signal == 1) { - g_notification_service->push_error("Vehicle", "Unable to clone vehicle"); return 0; } auto veh = vehicle::get_closest_to_location(tmpLocation, 200); - if (!ENTITY::IS_ENTITY_A_VEHICLE(veh)) + if (veh == 0) { - g_notification_service->push_error("Vehicle", "Unable to clone vehicle"); return 0; } @@ -276,31 +286,246 @@ namespace big::vehicle veh_data[i] = *vehicle_idx.at(i).as(); } - veh_data.erase(1); veh_data.erase(19); veh_data.erase(60); veh_data.erase(77); - veh_data.erase(94); veh_data.erase(95); veh_data.erase(103); + veh_data.erase(1); veh_data.erase(94); veh_data.erase(95); veh_data.erase(103); return veh_data; } + inline std::map get_owned_mods_from_vehicle_idx(script_global vehicle_idx) + { + std::map owned_mods; + + for (int i = MOD_SECONDARY_CUSTOM; i <= MOD_MODEL_HASH; i++) + { + owned_mods[i] = 0; + } + + int32_t val_32 = *vehicle_idx.at(32).as(); + int32_t val_77 = *vehicle_idx.at(77).as(); + int32_t val_102 = *vehicle_idx.at(102).as(); + + + owned_mods[MOD_MODEL_HASH] = *vehicle_idx.at(66).as(); + + owned_mods[MOD_PLATE_STYLE] = *vehicle_idx.at(0).as(); + owned_mods[MOD_WINDOW_TINT] = *vehicle_idx.at(65).as(); + owned_mods[MOD_WHEEL_TYPE] = *vehicle_idx.at(69).as(); + + + owned_mods[MOD_PRIMARY_COL] = *vehicle_idx.at(5).as(); + owned_mods[MOD_SECONDARY_COL] = *vehicle_idx.at(6).as(); + owned_mods[MOD_PEARLESCENT_COL] = *vehicle_idx.at(7).as(); + owned_mods[MOD_WHEEL_COL] = *vehicle_idx.at(8).as(); + owned_mods[MOD_INTERIOR_COL] = *vehicle_idx.at(97).as(); + owned_mods[MOD_DASHBOARD_COL] = *vehicle_idx.at(99).as(); + + + //CUSTOM PRIMARY + owned_mods[MOD_PRIMARY_CUSTOM] = (val_77 & (1 << 13)) != 0; + if (owned_mods[MOD_PRIMARY_CUSTOM]) + { + owned_mods[MOD_PRIMARY_COL_R] = *vehicle_idx.at(71).as(); + owned_mods[MOD_PRIMARY_COL_G] = *vehicle_idx.at(72).as(); + owned_mods[MOD_PRIMARY_COL_B] = *vehicle_idx.at(73).as(); + } + + + //CUSTOM SECONDARY + owned_mods[MOD_SECONDARY_CUSTOM] = (val_77 & (1 << 12)) != 0; + if (owned_mods[MOD_SECONDARY_CUSTOM]) + { + owned_mods[MOD_SECONDARY_COL_R] = *vehicle_idx.at(71).as(); + owned_mods[MOD_SECONDARY_COL_G] = *vehicle_idx.at(72).as(); + owned_mods[MOD_SECONDARY_COL_B] = *vehicle_idx.at(73).as(); + } + + + // TIRE SMOKE + owned_mods[MOD_TIRESMOKE_COL_R] = *vehicle_idx.at(62).as(); + owned_mods[MOD_TIRESMOKE_COL_G] = *vehicle_idx.at(63).as(); + owned_mods[MOD_TIRESMOKE_COL_B] = *vehicle_idx.at(64).as(); + owned_mods[MOD_TYRE_SMOKE] = !( + owned_mods[MOD_TIRESMOKE_COL_R] == 255 && + owned_mods[MOD_TIRESMOKE_COL_G] == 255 && + owned_mods[MOD_TIRESMOKE_COL_B] == 255 + ); + + + // XENON + if (val_32 > 0) + { + owned_mods[MOD_XENON_LIGHTS] = 1; + owned_mods[MOD_XENON_COL] = val_32 - 2; + } + else + { + owned_mods[MOD_XENON_LIGHTS] = 0; + } + + + // NEON + owned_mods[MOD_NEON_LEFT_ON] = (val_77 & (1 << 30)) != 0; + owned_mods[MOD_NEON_RIGHT_ON] = (val_77 & (1 << 31)) != 0; + owned_mods[MOD_NEON_FRONT_ON] = (val_77 & (1 << 28)) != 0; + owned_mods[MOD_NEON_BACK_ON] = (val_77 & (1 << 29)) != 0; + owned_mods[MOD_NEON_COL_R] = *vehicle_idx.at(74).as(); + owned_mods[MOD_NEON_COL_G] = *vehicle_idx.at(75).as(); + owned_mods[MOD_NEON_COL_B] = *vehicle_idx.at(76).as(); + + // TIRE OPTIONS + owned_mods[MOD_TIRE_CAN_BURST] = (val_77 & (1 << 9)) == 0; + if ((val_102 & 0b11) == 0b11) + { + owned_mods[MOD_DRIFT_TIRE] = 1; + } + + owned_mods[MOD_TURBO] = *vehicle_idx.at(28).as() != 0; + + owned_mods[MOD_FRONTWHEEL_VAR] = *vehicle_idx.at(60).as() != 0; + owned_mods[MOD_REARWHEEL_VAR] = *vehicle_idx.at(61).as() != 0; + + + // OTHER MODS + for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++) + { + if (slot == MOD_TURBO || slot == MOD_TYRE_SMOKE || slot == MOD_XENON_LIGHTS) + { + continue; + } + + int32_t val = *vehicle_idx.at(10 + slot).as() - 1; + if (val != -1) + { + owned_mods[slot] = val; + } + } + + // EXTRA + for (int extra = MOD_EXTRA_9; extra <= MOD_EXTRA_1; extra++) + { + int gta_extra_id = (extra - MOD_EXTRA_0) * -1; + owned_mods[extra] = val_77 >> (gta_extra_id - 1) & 1; + } + + return owned_mods; + } + + + inline Vehicle clone_from_owned_mods(std::map owned_mods, Vector3 location, float heading, bool is_networked = true) + { + auto vehicle = spawn(owned_mods[MOD_MODEL_HASH], location, heading, is_networked); + if (vehicle == 0) + { + return 0; + } + + for (int i = MOD_NEON_COL_B; i <= MOD_MODEL_HASH; i++) + { + if (owned_mods.count(i) == 0) + { + owned_mods[i] = 0; + } + } + + VEHICLE::SET_VEHICLE_MOD_KIT(vehicle, 0); + script::get_current()->yield(10ms); + + VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(vehicle, owned_mods[MOD_PLATE_STYLE]); + VEHICLE::SET_VEHICLE_WINDOW_TINT(vehicle, owned_mods[MOD_WINDOW_TINT]); + VEHICLE::SET_VEHICLE_WHEEL_TYPE(vehicle, owned_mods[MOD_WHEEL_TYPE]); + script::get_current()->yield(10ms); + + VEHICLE::SET_VEHICLE_COLOURS(vehicle, owned_mods[MOD_PRIMARY_COL], owned_mods[MOD_SECONDARY_COL]); + VEHICLE::SET_VEHICLE_EXTRA_COLOURS(vehicle, owned_mods[MOD_PEARLESCENT_COL], owned_mods[MOD_WHEEL_COL]); + VEHICLE::SET_VEHICLE_INTERIOR_COLOR_(vehicle, owned_mods[MOD_INTERIOR_COL]); + VEHICLE::SET_VEHICLE_DASHBOARD_COLOR_(vehicle, owned_mods[MOD_DASHBOARD_COL]); + + if (owned_mods[MOD_PRIMARY_CUSTOM]) + { + VEHICLE::SET_VEHICLE_CUSTOM_PRIMARY_COLOUR( + vehicle, owned_mods[MOD_PRIMARY_COL_R], + owned_mods[MOD_PRIMARY_COL_G], owned_mods[MOD_PRIMARY_COL_B] + ); + } + + if (owned_mods[MOD_SECONDARY_CUSTOM]) + { + VEHICLE::SET_VEHICLE_CUSTOM_SECONDARY_COLOUR( + vehicle, owned_mods[MOD_SECONDARY_COL_R], + owned_mods[MOD_SECONDARY_COL_G], owned_mods[MOD_SECONDARY_COL_B] + ); + } + + if (owned_mods[MOD_TYRE_SMOKE]) + { + VEHICLE::SET_VEHICLE_TYRE_SMOKE_COLOR( + vehicle, owned_mods[MOD_TIRESMOKE_COL_R], + owned_mods[MOD_TIRESMOKE_COL_G], owned_mods[MOD_TIRESMOKE_COL_B] + ); + VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, MOD_TYRE_SMOKE, owned_mods[MOD_TYRE_SMOKE]); + } + + if (owned_mods[MOD_XENON_LIGHTS]) + { + VEHICLE::SET_VEHICLE_XENON_LIGHTS_COLOR_(vehicle, owned_mods[MOD_XENON_COL]); + VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, MOD_XENON_LIGHTS, owned_mods[MOD_XENON_LIGHTS]); + } + + VEHICLE::SET_VEHICLE_NEON_LIGHTS_COLOUR_( + vehicle, owned_mods[MOD_NEON_COL_R], + owned_mods[MOD_NEON_COL_G], owned_mods[MOD_NEON_COL_B] + ); + VEHICLE::SET_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, NEON_LEFT, owned_mods[MOD_NEON_LEFT_ON]); + VEHICLE::SET_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, NEON_RIGHT, owned_mods[MOD_NEON_RIGHT_ON]); + VEHICLE::SET_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, NEON_FRONT, owned_mods[MOD_NEON_FRONT_ON]); + VEHICLE::SET_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, NEON_BACK, owned_mods[MOD_NEON_BACK_ON]); + + + VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(vehicle, owned_mods[MOD_TIRE_CAN_BURST]); + VEHICLE::SET_DRIFT_TYRES_ENABLED_(vehicle, owned_mods[MOD_DRIFT_TIRE]); + VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, MOD_TURBO, owned_mods[MOD_TURBO]); + + for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++) + { + if (owned_mods.count(slot) && owned_mods[slot] != -1) + { + bool custom_tire = false; + + if (slot == MOD_FRONTWHEEL) + { + custom_tire = owned_mods[MOD_FRONTWHEEL_VAR]; + } + else if (slot == MOD_REARWHEEL) + { + custom_tire = owned_mods[MOD_REARWHEEL_VAR]; + } + + VEHICLE::SET_VEHICLE_MOD(vehicle, slot, owned_mods[slot], custom_tire); + } + } + + for (int extra = MOD_EXTRA_14; extra <= MOD_EXTRA_1; extra++) + { + int gta_extra_id = (extra - MOD_EXTRA_0) * -1; + if (owned_mods.count(extra) && VEHICLE::DOES_EXTRA_EXIST(vehicle, gta_extra_id)) + { + VEHICLE::SET_VEHICLE_EXTRA(vehicle, gta_extra_id, owned_mods[extra] == 0); + } + } + + return vehicle; + } + inline std::map get_owned_mods_from_vehicle(Vehicle vehicle) { std::map owned_mods; - owned_mods[MOD_MODEL_HASH] = ENTITY::GET_ENTITY_MODEL(vehicle); - - for (int i = MOD_NEON_COL_B; i <= MOD_MODEL_HASH; i++) + for (int i = MOD_SECONDARY_CUSTOM; i <= MOD_MODEL_HASH; i++) { owned_mods[i] = 0; } - for (int slot = MOD_SPOILERS; slot <= MOD_LIVERY; slot++) - { - int count = VEHICLE::GET_NUM_VEHICLE_MODS(vehicle, slot); - if (count > 0) - { - owned_mods[slot] = VEHICLE::GET_VEHICLE_MOD(vehicle, slot); - } - } + owned_mods[MOD_MODEL_HASH] = ENTITY::GET_ENTITY_MODEL(vehicle); owned_mods[MOD_PLATE_STYLE] = VEHICLE::GET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(vehicle); owned_mods[MOD_WINDOW_TINT] = VEHICLE::GET_VEHICLE_WINDOW_TINT(vehicle); @@ -310,41 +535,79 @@ namespace big::vehicle VEHICLE::GET_VEHICLE_EXTRA_COLOURS(vehicle, &owned_mods[MOD_PEARLESCENT_COL], &owned_mods[MOD_WHEEL_COL]); VEHICLE::GET_VEHICLE_INTERIOR_COLOR_(vehicle, &owned_mods[MOD_INTERIOR_COL]); VEHICLE::GET_VEHICLE_DASHBOARD_COLOR_(vehicle, &owned_mods[MOD_DASHBOARD_COL]); - owned_mods[MOD_XENON_COL] = VEHICLE::GET_VEHICLE_XENON_LIGHTS_COLOR_(vehicle); - VEHICLE::GET_VEHICLE_CUSTOM_PRIMARY_COLOUR( - vehicle, &owned_mods[MOD_PRIMARY_COL_R], - &owned_mods[MOD_PRIMARY_COL_G], &owned_mods[MOD_PRIMARY_COL_B] - ); + owned_mods[MOD_PRIMARY_CUSTOM] = VEHICLE::GET_IS_VEHICLE_PRIMARY_COLOUR_CUSTOM(vehicle); + if (owned_mods[MOD_PRIMARY_CUSTOM]) + { + VEHICLE::GET_VEHICLE_CUSTOM_PRIMARY_COLOUR( + vehicle, &owned_mods[MOD_PRIMARY_COL_R], + &owned_mods[MOD_PRIMARY_COL_G], &owned_mods[MOD_PRIMARY_COL_B] + ); + } - VEHICLE::GET_VEHICLE_CUSTOM_PRIMARY_COLOUR( - vehicle, &owned_mods[MOD_SECONDARY_COL_R], - &owned_mods[MOD_SECONDARY_COL_G], &owned_mods[MOD_SECONDARY_COL_B] - ); + owned_mods[MOD_SECONDARY_CUSTOM] = VEHICLE::GET_IS_VEHICLE_SECONDARY_COLOUR_CUSTOM(vehicle); + if (owned_mods[MOD_SECONDARY_CUSTOM]) + { + VEHICLE::GET_VEHICLE_CUSTOM_SECONDARY_COLOUR( + vehicle, &owned_mods[MOD_SECONDARY_COL_R], + &owned_mods[MOD_SECONDARY_COL_G], &owned_mods[MOD_SECONDARY_COL_B] + ); + } - VEHICLE::GET_VEHICLE_TYRE_SMOKE_COLOR( - vehicle, &owned_mods[MOD_TIRESMOKE_COL_R], - &owned_mods[MOD_TIRESMOKE_COL_G], &owned_mods[MOD_TIRESMOKE_COL_B] - ); - - VEHICLE::GET_VEHICLE_NEON_LIGHTS_COLOUR_( - vehicle, &owned_mods[MOD_NEON_COL_R], - &owned_mods[MOD_NEON_COL_B], &owned_mods[MOD_NEON_COL_B] - ); - - owned_mods[MOD_TIRE_CAN_BURST] = !VEHICLE::GET_VEHICLE_TYRES_CAN_BURST(vehicle); owned_mods[MOD_TYRE_SMOKE] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, MOD_TYRE_SMOKE); - owned_mods[MOD_TURBO] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, MOD_TURBO); + if (owned_mods[MOD_TYRE_SMOKE]) + { + VEHICLE::GET_VEHICLE_TYRE_SMOKE_COLOR( + vehicle, &owned_mods[MOD_TIRESMOKE_COL_R], + &owned_mods[MOD_TIRESMOKE_COL_G], &owned_mods[MOD_TIRESMOKE_COL_B] + ); + } owned_mods[MOD_XENON_LIGHTS] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, MOD_XENON_LIGHTS); + if (owned_mods[MOD_XENON_LIGHTS]) + { + owned_mods[MOD_XENON_COL] = (int8_t)VEHICLE::GET_VEHICLE_XENON_LIGHTS_COLOR_(vehicle); + } + owned_mods[MOD_NEON_LEFT_ON] = VEHICLE::IS_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, NEON_LEFT); owned_mods[MOD_NEON_RIGHT_ON] = VEHICLE::IS_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, NEON_RIGHT); owned_mods[MOD_NEON_FRONT_ON] = VEHICLE::IS_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, NEON_FRONT); owned_mods[MOD_NEON_BACK_ON] = VEHICLE::IS_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, NEON_BACK); + VEHICLE::GET_VEHICLE_NEON_LIGHTS_COLOUR_( + vehicle, &owned_mods[MOD_NEON_COL_R], + &owned_mods[MOD_NEON_COL_G], &owned_mods[MOD_NEON_COL_B] + ); + + owned_mods[MOD_TIRE_CAN_BURST] = VEHICLE::GET_VEHICLE_TYRES_CAN_BURST(vehicle); + owned_mods[MOD_DRIFT_TIRE] = VEHICLE::GET_DRIFT_TYRES_ENABLED_(vehicle); + owned_mods[MOD_TURBO] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, MOD_TURBO); owned_mods[MOD_FRONTWHEEL_VAR] = VEHICLE::GET_VEHICLE_MOD_VARIATION(vehicle, MOD_FRONTWHEEL); owned_mods[MOD_REARWHEEL_VAR] = VEHICLE::GET_VEHICLE_MOD_VARIATION(vehicle, MOD_REARWHEEL); + for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++) + { + int count = VEHICLE::GET_NUM_VEHICLE_MODS(vehicle, slot); + if (count > 0) + { + int32_t val = VEHICLE::GET_VEHICLE_MOD(vehicle, slot); + + if (val != -1) + { + owned_mods[slot] = val; + } + } + } + + for (int extra = MOD_EXTRA_14; extra <= MOD_EXTRA_1; extra++) + { + int gta_extra_id = (extra - MOD_EXTRA_0) * -1; + if (VEHICLE::DOES_EXTRA_EXIST(vehicle, gta_extra_id)) + { + owned_mods[extra] = VEHICLE::IS_VEHICLE_EXTRA_TURNED_ON(vehicle, gta_extra_id); + } + } + return owned_mods; } @@ -358,13 +621,14 @@ namespace big::vehicle Hash model = ENTITY::GET_ENTITY_MODEL(veh); VEHICLE::SET_VEHICLE_MOD_KIT(veh, 0); - VEHICLE::TOGGLE_VEHICLE_MOD(veh, 18 /* Turbo */, TRUE); - VEHICLE::TOGGLE_VEHICLE_MOD(veh, 20 /* Tire Smoke */, TRUE); - VEHICLE::TOGGLE_VEHICLE_MOD(veh, 17 /* Xenon Headlights */, TRUE); + + VEHICLE::TOGGLE_VEHICLE_MOD(veh, MOD_TURBO, TRUE); + VEHICLE::TOGGLE_VEHICLE_MOD(veh, MOD_TYRE_SMOKE, TRUE); + VEHICLE::TOGGLE_VEHICLE_MOD(veh, MOD_XENON_LIGHTS, TRUE); VEHICLE::SET_VEHICLE_WINDOW_TINT(veh, 1); VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(veh, false); - for (int slot = MOD_SPOILERS; slot <= MOD_LIVERY; slot++) + for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++) { if (slot == MOD_LIVERY) { continue; diff --git a/BigBaseV2/src/views/vehicle/view_lsc.cpp b/BigBaseV2/src/views/vehicle/view_lsc.cpp index d1c0b6c4..a291bf7d 100644 --- a/BigBaseV2/src/views/vehicle/view_lsc.cpp +++ b/BigBaseV2/src/views/vehicle/view_lsc.cpp @@ -27,7 +27,7 @@ namespace big if (self::veh == 0 || player_vehicle != self::veh) { - if (self::veh == 0) + if (self::veh == 0 ) { owned_mods.clear(); slot_display_names.clear(); @@ -81,7 +81,7 @@ namespace big owned_mods[MOD_WHEEL_TYPE] == WHEEL_TYPE_STREET || owned_mods[MOD_WHEEL_TYPE] == WHEEL_TYPE_TRACK; - for (int slot = MOD_SPOILERS; slot <= MOD_LIVERY; slot++) + for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++) { int count = VEHICLE::GET_NUM_VEHICLE_MODS(player_vehicle, slot); if (count > 0) @@ -225,12 +225,23 @@ namespace big ImGui::Separator(); components::small_text("Mod Options"); - if (ImGui::Checkbox("Bulletproof Tires", (bool*)&owned_mods[MOD_TIRE_CAN_BURST])) + bool is_bulletproof_tires = !owned_mods[MOD_TIRE_CAN_BURST]; + if (ImGui::Checkbox("Bulletproof Tires", (bool*)&is_bulletproof_tires)) { - g_fiber_pool->queue_job([] { - VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(player_vehicle, !owned_mods[MOD_TIRE_CAN_BURST]); + g_fiber_pool->queue_job([is_bulletproof_tires] { + owned_mods[MOD_TIRE_CAN_BURST] = (int32_t)!is_bulletproof_tires; + VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(player_vehicle, owned_mods[MOD_TIRE_CAN_BURST]); }); } + + ImGui::SameLine(); + if (ImGui::Checkbox("Low Grip Tires", (bool*)&owned_mods[MOD_DRIFT_TIRE])) + { + g_fiber_pool->queue_job([] { + VEHICLE::SET_DRIFT_TYRES_ENABLED_(player_vehicle, owned_mods[MOD_DRIFT_TIRE]); + }); + } + ImGui::SameLine(); if (ImGui::Checkbox("Turbo", (bool*)&owned_mods[MOD_TURBO])) { diff --git a/BigBaseV2/src/views/vehicle/view_pv.cpp b/BigBaseV2/src/views/vehicle/view_pv.cpp index 16e5de90..26197220 100644 --- a/BigBaseV2/src/views/vehicle/view_pv.cpp +++ b/BigBaseV2/src/views/vehicle/view_pv.cpp @@ -106,52 +106,47 @@ namespace big display_name.find(lower_search) != std::string::npos || display_manufacturer.find(lower_search) != std::string::npos )) { - ImGui::PushID('v' << 24 & personal_veh->get_id()); + ImGui::PushID('v' << 24 & personal_veh->get_id()); components::selectable(label, false, [&personal_veh] { if (g->clone_pv.spawn_clone) { - auto vehicle_idx = personal_veh->get_vehicle_idx(); - auto veh_data = vehicle::get_vehicle_data_from_vehicle_idx(vehicle_idx); - - float y_offset = 0; - - if (self::veh != 0) - { - y_offset = 10.f; - } - else if (!g->clone_pv.spawn_inside) - { - y_offset = 5.f; - } - - auto spawn_location = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(self::ped, 0.f, y_offset, 0.f); + Vector3 spawn_location = vehicle::get_spawn_location(g->spawn.spawn_inside); float spawn_heading = ENTITY::GET_ENTITY_HEADING(self::ped); + auto vehicle_idx = personal_veh->get_vehicle_idx(); + auto owned_mods = vehicle::get_owned_mods_from_vehicle_idx(vehicle_idx); + const char* spawn_plate = plate; if (g->clone_pv.clone_plate) { spawn_plate = personal_veh->get_plate(); } - auto veh = vehicle::clone_from_vehicle_data(veh_data, spawn_location, spawn_heading); + auto veh = vehicle::clone_from_owned_mods(owned_mods, spawn_location, spawn_heading); - if (g->clone_pv.spawn_maxed) + if (veh == 0) { - vehicle::max_vehicle(veh); + g_notification_service->push_error("Vehicle", "Unable to spawn vehicle"); } - - vehicle::set_plate(veh, spawn_plate); - - if (g->clone_pv.spawn_inside) + else { - vehicle::teleport_into_vehicle(veh); + if (g->clone_pv.spawn_maxed) + { + vehicle::max_vehicle(veh); + } + + vehicle::set_plate(veh, plate); + + if (g->clone_pv.spawn_inside) + { + vehicle::teleport_into_vehicle(veh); + } } } else { strcpy(search, ""); - personal_veh->summon(); } @@ -161,7 +156,12 @@ namespace big if (g->clone_pv.preview_vehicle && ImGui::IsItemHovered()) { - g_vehicle_preview_service->set_preview_vehicle(item); + g_fiber_pool->queue_job([&personal_veh] { + g_vehicle_preview_service->set_preview_vehicle( + vehicle::get_owned_mods_from_vehicle_idx(personal_veh->get_vehicle_idx()), + g->clone_pv.spawn_maxed + ); + }); } else if (g->clone_pv.preview_vehicle && !ImGui::IsAnyItemHovered()) { diff --git a/BigBaseV2/src/views/vehicle/view_spawn.cpp b/BigBaseV2/src/views/vehicle/view_spawn.cpp index a9eaf02f..98d5a53b 100644 --- a/BigBaseV2/src/views/vehicle/view_spawn.cpp +++ b/BigBaseV2/src/views/vehicle/view_spawn.cpp @@ -58,9 +58,69 @@ namespace big ImGui::SetNextItemWidth(300.f); components::input_text_with_hint("Model Name", "Search", search, sizeof(search), ImGuiInputTextFlags_None); - // arbitrary subtraction this looked nice so idc, works for all resolutions as well + if (ImGui::ListBoxHeader("###vehicles", { 300, static_cast(*g_pointers->m_resolution_y - 184 - 38 * 4) })) { + if (self::veh) + { + static auto veh_hash = 0; + + g_fiber_pool->queue_job([] { + veh_hash = ENTITY::GET_ENTITY_MODEL(self::veh); + }); + + if (veh_hash) + { + auto item = g_gta_data_service->find_vehicle_by_hash(veh_hash); + + components::selectable("Current Vehicle [" + item.display_name + "]", false, [] { + if (self::veh) + { + Vector3 spawn_location = vehicle::get_spawn_location(g->spawn.spawn_inside); + float spawn_heading = ENTITY::GET_ENTITY_HEADING(self::ped); + + auto owned_mods = vehicle::get_owned_mods_from_vehicle(self::veh); + + auto veh = vehicle::clone_from_owned_mods(owned_mods, spawn_location, spawn_heading); + + if (veh == 0) + { + g_notification_service->push_error("Vehicle", "Unable to spawn vehicle"); + } + else + { + if (g->spawn.spawn_maxed) + { + vehicle::max_vehicle(veh); + } + + vehicle::set_plate(veh, plate); + + if (g->spawn.spawn_inside) + { + vehicle::teleport_into_vehicle(veh); + } + } + } + + g_vehicle_preview_service->stop_preview(); + }); + + if (g->spawn.preview_vehicle && ImGui::IsItemHovered()) + { + g_fiber_pool->queue_job([] { + g_vehicle_preview_service->set_preview_vehicle( + vehicle::get_owned_mods_from_vehicle(self::veh), + g->spawn.spawn_maxed + ); + }); + } + else if (g->spawn.preview_vehicle && !ImGui::IsAnyItemHovered()) + { + g_vehicle_preview_service->stop_preview(); + } + } + } auto item_arr = g_gta_data_service->get_vehicle_arr(); @@ -86,32 +146,28 @@ namespace big ImGui::PushID(item.hash); components::selectable(item.display_name, false, [item] { - float y_offset = 0; - - if (self::veh != 0) - { - y_offset = 10.f; - } - else if (!g->spawn.spawn_inside) - { - y_offset = 5.f; - } - - Vector3 spawn_location = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(self::ped, 0.f, y_offset, 0.f); + Vector3 spawn_location = vehicle::get_spawn_location(g->spawn.spawn_inside); float spawn_heading = ENTITY::GET_ENTITY_HEADING(self::ped); const Vehicle veh = vehicle::spawn(item.hash, spawn_location, spawn_heading); - if (g->spawn.spawn_maxed) + if (veh == 0) { - vehicle::max_vehicle(veh); + g_notification_service->push_error("Vehicle", "Unable to spawn vehicle"); } - - vehicle::set_plate(veh, plate); - - if (g->spawn.spawn_inside) + else { - vehicle::teleport_into_vehicle(veh); + if (g->spawn.spawn_maxed) + { + vehicle::max_vehicle(veh); + } + + vehicle::set_plate(veh, plate); + + if (g->spawn.spawn_inside) + { + vehicle::teleport_into_vehicle(veh); + } } g_vehicle_preview_service->stop_preview(); @@ -120,7 +176,7 @@ namespace big if (g->spawn.preview_vehicle && ImGui::IsItemHovered()) { - g_vehicle_preview_service->set_preview_vehicle(item); + g_vehicle_preview_service->set_preview_vehicle(item, g->spawn.spawn_maxed); } else if (g->spawn.preview_vehicle && !ImGui::IsAnyItemHovered()) {