From 100de3fee55bdd067f5d2022a933709d8a210442 Mon Sep 17 00:00:00 2001 From: gir489 <100792176+gir489returns@users.noreply.github.com> Date: Mon, 28 Aug 2023 05:35:17 -0400 Subject: [PATCH] Rework Keep Vehicle Repaired to remove damage decals properly. (#2044) * Keep Vehicle Repaired now uses CDecalManager to remove damage decals which allows it to ignore clan and livery decals. * Added more conditions to call SET_VEHICLE_FIXED to fix things like the R88 breaking its shell off. Fixed Seatbelt having inverted conditions. * Fixed keep_vehicle_repaired repairing things it doesn't need to repair if godmode/always clean is on already. Fixed spawn_vehicle_json not applying the radio station. * Consolidated signature for CDecalMgr::ClearDecals and its static instance. --- .../looped/vehicle/keep_vehicle_repaired.cpp | 25 +++++++++++++------ src/backend/looped/vehicle/seatbelt.cpp | 8 +++--- src/function_types.hpp | 3 +++ src/gta_pointers.hpp | 3 +++ src/pointers.cpp | 10 ++++++++ src/services/vehicle/persist_car_service.cpp | 2 ++ 6 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/backend/looped/vehicle/keep_vehicle_repaired.cpp b/src/backend/looped/vehicle/keep_vehicle_repaired.cpp index ad46b466..f6311a9f 100644 --- a/src/backend/looped/vehicle/keep_vehicle_repaired.cpp +++ b/src/backend/looped/vehicle/keep_vehicle_repaired.cpp @@ -25,7 +25,15 @@ namespace big } } - if (VEHICLE::IS_VEHICLE_BUMPER_BOUNCING(veh, TRUE) || VEHICLE::GET_VEHICLE_NUM_OF_BROKEN_OFF_PARTS(veh) > 0) + for (int i = 0; i <= 14; i++) + { + if (VEHICLE::DOES_EXTRA_EXIST(veh, i) && VEHICLE::IS_VEHICLE_EXTRA_TURNED_ON(veh, i) && VEHICLE::IS_EXTRA_BROKEN_OFF(veh, i)) + { + VEHICLE::SET_VEHICLE_FIXED(veh); + } + } + + if (VEHICLE::IS_VEHICLE_BUMPER_BOUNCING(veh, TRUE) || VEHICLE::IS_VEHICLE_BUMPER_BOUNCING(veh, FALSE) || VEHICLE::GET_VEHICLE_NUM_OF_BROKEN_LOOSEN_PARTS(veh) > 0) { VEHICLE::SET_VEHICLE_FIXED(veh); } @@ -33,16 +41,17 @@ namespace big if (!VEHICLE::IS_VEHICLE_WINDOW_INTACT(veh, 7)) //Rear window VEHICLE::FIX_VEHICLE_WINDOW(veh, 7); - int clan_logo_counter = GRAPHICS::DOES_VEHICLE_HAVE_CREW_EMBLEM(veh, 0) * 10; - GRAPHICS::REMOVE_DECALS_FROM_VEHICLE(veh); - while (clan_logo_counter-- > 0 && !GRAPHICS::DOES_VEHICLE_HAVE_CREW_EMBLEM(veh, 0)) + g_pointers->m_gta.m_decal_manager_remove(g_pointers->m_gta.m_decal_manager, g_pointers->m_gta.m_handle_to_ptr(veh), -1, 0, 0x0001E000); + + if (!g.vehicle.god_mode) { - vehicle_helper::add_clan_logo_to_vehicle(veh, self::ped); - script::get_current()->yield(10ms); + VEHICLE::SET_VEHICLE_DEFORMATION_FIXED(veh); } - VEHICLE::SET_VEHICLE_DEFORMATION_FIXED(veh); - VEHICLE::SET_VEHICLE_DIRT_LEVEL(veh, 0.f); + if (!g.vehicle.keep_vehicle_clean) + { + VEHICLE::SET_VEHICLE_DIRT_LEVEL(veh, 0.f); + } } } }; diff --git a/src/backend/looped/vehicle/seatbelt.cpp b/src/backend/looped/vehicle/seatbelt.cpp index d35dcff9..faff6f9d 100644 --- a/src/backend/looped/vehicle/seatbelt.cpp +++ b/src/backend/looped/vehicle/seatbelt.cpp @@ -9,14 +9,14 @@ namespace big virtual void on_tick() override { - PED::SET_PED_CONFIG_FLAG(self::ped, 32, true); - PED::SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(self::ped, true); + PED::SET_PED_CONFIG_FLAG(self::ped, 32, false); + PED::SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(self::ped, false); } virtual void on_disable() override { - PED::SET_PED_CONFIG_FLAG(self::ped, 32, false); - PED::SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(self::ped, false); + PED::SET_PED_CONFIG_FLAG(self::ped, 32, true); + PED::SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(self::ped, true); } }; diff --git a/src/function_types.hpp b/src/function_types.hpp index 5dc6aabe..f672a041 100644 --- a/src/function_types.hpp +++ b/src/function_types.hpp @@ -31,6 +31,7 @@ namespace rage enum class eThreadState : uint32_t; class netArrayHandlerBase; class fwRefAwareBase; + class fwEntity; class netGameEvent; class netEventMgr; } @@ -179,4 +180,6 @@ namespace big::functions using delete_ped = bool (*)(CPed* ped); using delete_vehicle = bool (*)(CVehicle* veh); using delete_object = bool (*)(CObject* object, bool unk); + + using decal_manager_remove = void(*)(PVOID manager, rage::fwEntity*, DWORD a3, DWORD64 a4, DWORD ignore_bitset); } diff --git a/src/gta_pointers.hpp b/src/gta_pointers.hpp index 5e64db4d..29748960 100644 --- a/src/gta_pointers.hpp +++ b/src/gta_pointers.hpp @@ -332,6 +332,9 @@ namespace big functions::delete_ped m_delete_ped; functions::delete_vehicle m_delete_vehicle; functions::delete_object m_delete_object; + + functions::decal_manager_remove m_decal_manager_remove; + PVOID m_decal_manager; }; #pragma pack(pop) static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned"); diff --git a/src/pointers.cpp b/src/pointers.cpp index 10089501..f65767f8 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -1630,6 +1630,16 @@ namespace big { g_pointers->m_gta.m_activate_special_ability_patch = ptr.as(); } + }, + // ClearDecals + { + "DCLMGR", + "48 8D 0D ? ? ? ? 41 83 C8 FF E8 ? ? ? ? 4C", + [](memory::handle ptr) + { + g_pointers->m_gta.m_decal_manager = ptr.add(3).rip().as(); + g_pointers->m_gta.m_decal_manager_remove = ptr.add(0xC).rip().as(); + } } >(); // don't leave a trailing comma at the end diff --git a/src/services/vehicle/persist_car_service.cpp b/src/services/vehicle/persist_car_service.cpp index 8b8c8491..de0f88cf 100644 --- a/src/services/vehicle/persist_car_service.cpp +++ b/src/services/vehicle/persist_car_service.cpp @@ -188,6 +188,8 @@ namespace big const auto vehicle = big::vehicle::spawn(vehicle_hash, pos, ENTITY::GET_ENTITY_HEADING(ped)); + script::get_current()->yield(); //This is needed to wait for the engine to instantiate things like the radio station so it won't overwrite it on the next frame. + VEHICLE::SET_VEHICLE_DIRT_LEVEL(vehicle, 0.0f); VEHICLE::SET_VEHICLE_MOD_KIT(vehicle, 0); VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(vehicle, false);