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.
This commit is contained in:
gir489 2023-08-28 05:35:17 -04:00 committed by GitHub
parent cf333d0611
commit 100de3fee5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 12 deletions

View File

@ -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);
}
}
}
};

View File

@ -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);
}
};

View File

@ -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);
}

View File

@ -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");

View File

@ -1630,6 +1630,16 @@ namespace big
{
g_pointers->m_gta.m_activate_special_ability_patch = ptr.as<PVOID>();
}
},
// 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<PVOID>();
g_pointers->m_gta.m_decal_manager_remove = ptr.add(0xC).rip().as<functions::decal_manager_remove>();
}
}
>(); // don't leave a trailing comma at the end

View File

@ -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);