diff --git a/SilentPatchSA/FireManagerSA.cpp b/SilentPatchSA/FireManagerSA.cpp new file mode 100644 index 0000000..edea1eb --- /dev/null +++ b/SilentPatchSA/FireManagerSA.cpp @@ -0,0 +1,4 @@ +#include "StdAfxSA.h" +#include "FireManagerSA.h" + +void (CFireManager::*CFireManager::orgStartFire)( CEntity* entity, CEntity* attacker, float a3, uint8_t a4, uint32_t a5, int8_t a6 ); diff --git a/SilentPatchSA/FireManagerSA.h b/SilentPatchSA/FireManagerSA.h new file mode 100644 index 0000000..4b7da0a --- /dev/null +++ b/SilentPatchSA/FireManagerSA.h @@ -0,0 +1,22 @@ +#pragma once + +#include "GeneralSA.h" + +class CFireManager +{ +public: + static void (CFireManager::*orgStartFire)( CEntity* entity, CEntity* attacker, float a3, uint8_t a4, uint32_t a5, int8_t a6 ); + + void StartFire( CEntity* entity, CEntity* attacker, float a3, uint8_t a4, uint32_t a5, int8_t a6 ) + { + (this->*orgStartFire)( entity, attacker, a3, a4, a5, a6 ); + } + + void StartFire_NullEntityCheck( CEntity* entity, CEntity* attacker, float a3, uint8_t a4, uint32_t a5, int8_t a6 ) + { + if ( entity != nullptr ) + { + StartFire( entity, attacker, a3, a4, a5, a6 ); + } + } +}; diff --git a/SilentPatchSA/PedSA.cpp b/SilentPatchSA/PedSA.cpp index e6dd0d9..84f20ee 100644 --- a/SilentPatchSA/PedSA.cpp +++ b/SilentPatchSA/PedSA.cpp @@ -14,6 +14,7 @@ static void* varRenderJetPack = AddressByVersion(0x67F6A0, 0x67FEC0, 0x6A WRAPPER void CTaskSimpleJetPack::RenderJetPack(CPed* pPed) { WRAPARG(pPed); VARJMP(varRenderJetPack); } void (CPed::*CPed::orgGiveWeapon)(uint32_t weapon, uint32_t ammo, bool flag); +void (CPlayerPed::*CPlayerPed::orgDoStuffToGoOnFire)(); RwObject* GetFirstObject(RwFrame* pFrame) { diff --git a/SilentPatchSA/PedSA.h b/SilentPatchSA/PedSA.h index 9b78ff9..94079bb 100644 --- a/SilentPatchSA/PedSA.h +++ b/SilentPatchSA/PedSA.h @@ -306,6 +306,9 @@ public: inline void SetTargetHeading(float fVal) { m_fTargetRotation = fVal; } + bool IsPlayer() const + { return pedType == 0 || pedType == 1; } + unsigned char GetWeaponSkill(); void ResetGunFlashAlpha(); void SetGunFlashAlpha(bool bSecondWeapon); @@ -322,6 +325,14 @@ class NOVMT CPlayerPed : public CPed private: CPed* m_pMouseLockOnRecruitPed; int m_iMouseLockOnRecruitTimer; + +public: + static void (CPlayerPed::*orgDoStuffToGoOnFire)(); + + void DoStuffToGoOnFire() + { + (this->*orgDoStuffToGoOnFire)(); + } }; static_assert(sizeof(CPed) == 0x79C, "Wrong size: CPed"); diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 7736d3e..709ff7d 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -15,6 +15,7 @@ #include "LinkListSA.h" #include "PNGFile.h" #include "PlayerInfoSA.h" +#include "FireManagerSA.h" #include "WaveDecoderSA.h" #include "FLACDecoderSA.h" @@ -1394,6 +1395,23 @@ namespace Credits } } +// ============= Bicycle fire fix ============= +namespace BicycleFire +{ + CPed* GetVehicleDriver( const CVehicle* vehicle ) + { + return vehicle->GetDriver(); + } + + void __fastcall DoStuffToGoOnFire_NullAndPlayerCheck( CPed* ped ) + { + if ( ped != nullptr && ped->IsPlayer() ) + { + static_cast(ped)->DoStuffToGoOnFire(); + } + } +} + #ifndef NDEBUG @@ -3515,6 +3533,25 @@ void Patch_SA_10() CPed::orgGiveWeapon = *(decltype(CPed::orgGiveWeapon)*)&pGiveWeapon; InjectHook( 0x47D335, &CPed::GiveWeapon_SP ); } + + // Fixed bicycle on fire - instead of CJ being set on fire, bicycle's driver is + { + using namespace BicycleFire; + + Patch( 0x53A984, { 0x90, 0x57 } ); + Patch( 0x53A9A7, { 0x90, 0x57 } ); + InjectHook( 0x53A986, GetVehicleDriver ); + InjectHook( 0x53A9A9, GetVehicleDriver ); + + void* func; + ReadCall( 0x53A990, func ); + CPlayerPed::orgDoStuffToGoOnFire = *(decltype(CPlayerPed::orgDoStuffToGoOnFire)*)&func; + InjectHook( 0x53A990, DoStuffToGoOnFire_NullAndPlayerCheck ); + + ReadCall( 0x53A9B7, func ); + CFireManager::orgStartFire = *(decltype(CFireManager::orgStartFire)*)&func; + InjectHook( 0x53A9B7, &CFireManager::StartFire_NullEntityCheck ); + } } void Patch_SA_11() diff --git a/SilentPatchSA/SilentPatchSA.vcxproj b/SilentPatchSA/SilentPatchSA.vcxproj index 582bec9..7ba9b8a 100644 --- a/SilentPatchSA/SilentPatchSA.vcxproj +++ b/SilentPatchSA/SilentPatchSA.vcxproj @@ -200,6 +200,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio NotUsing + @@ -233,6 +234,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio + diff --git a/SilentPatchSA/SilentPatchSA.vcxproj.filters b/SilentPatchSA/SilentPatchSA.vcxproj.filters index 6d3dbfb..657cd1d 100644 --- a/SilentPatchSA/SilentPatchSA.vcxproj.filters +++ b/SilentPatchSA/SilentPatchSA.vcxproj.filters @@ -69,6 +69,9 @@ Source Files + + Source Files + @@ -161,6 +164,9 @@ Header Files + + Header Files + diff --git a/SilentPatchSA/VehicleSA.h b/SilentPatchSA/VehicleSA.h index 205f68a..971ec30 100644 --- a/SilentPatchSA/VehicleSA.h +++ b/SilentPatchSA/VehicleSA.h @@ -3,6 +3,7 @@ #include "GeneralSA.h" #include "ModelInfoSA.h" +#include "PedSA.h" enum eVehicleType { @@ -124,7 +125,10 @@ class NOVMT CVehicle : public CPhysical protected: BYTE __pad1[752]; CVehicleFlags m_nVehicleFlags; - BYTE __pad2[108]; + BYTE __pad2[48]; + CPed* m_pDriver; + CPed* m_apPassengers[8]; + BYTE __pad8[24]; float m_fGasPedal; float m_fBrakePedal; uint8_t m_VehicleCreatedBy; @@ -150,6 +154,8 @@ public: { return pDamagingEntity; } uint32_t GetClass() const { return m_dwVehicleClass; } + CPed* GetDriver() const + { return m_pDriver;} void SetBombOnBoard( uint32_t bombOnBoard ) { m_BombOnBoard = bombOnBoard; }