diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 72f14d7..7abf7e3 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -1446,6 +1446,49 @@ namespace HandlingNameLoadFix }; +// ============= Firela ladder animation ============= +namespace FirelaHook +{ + static uintptr_t UpdateMovingCollisionJmp; + static uintptr_t HydraulicControlJmpBack; + + void __declspec(naked) TestFirelaAndFlags() + { + __asm + { + mov ecx, esi + call CVehicle::HasFirelaLadder + test al, al + jnz TestFirelaAndFlags_UpdateMovingCollision + test [esi].hFlagsLocal, FLAG_HYDRAULICS_INSTALLED + jmp [HydraulicControlJmpBack] + +TestFirelaAndFlags_UpdateMovingCollision: + jmp [UpdateMovingCollisionJmp] + } + } + + static uintptr_t FollowCarCamNoMovement; + static uintptr_t FollowCarCamJmpBack; + + void __declspec(naked) CamControlFirela() + { + __asm + { + mov ecx, edi + call CVehicle::HasFirelaLadder + test al, al + jnz TestFirelaAndFlags_UpdateMovingCollision + mov eax, [edi].m_dwVehicleClass + jmp [FollowCarCamJmpBack] + + TestFirelaAndFlags_UpdateMovingCollision: + jmp [FollowCarCamNoMovement] + } + } +} + + #ifndef NDEBUG // ============= QPC spoof for verifying high timer issues ============= @@ -3671,6 +3714,20 @@ void Patch_SA_10() InjectHook( 0x6F4F58, strncpy_Fix ); InjectHook( 0x6F4F64, strncmp_Fix ); } + + + // Firela animations + { + using namespace FirelaHook; + + UpdateMovingCollisionJmp = 0x6B200F; + HydraulicControlJmpBack = 0x6B1FBF + 10; + InjectHook( 0x6B1FBF, TestFirelaAndFlags, PATCH_JUMP ); + + FollowCarCamNoMovement = 0x52551E; + FollowCarCamJmpBack = 0x5254F6 + 6; + InjectHook( 0x5254F6, CamControlFirela, PATCH_JUMP ); + } } void Patch_SA_11() diff --git a/SilentPatchSA/VehicleSA.cpp b/SilentPatchSA/VehicleSA.cpp index 7e3b69e..f996562 100644 --- a/SilentPatchSA/VehicleSA.cpp +++ b/SilentPatchSA/VehicleSA.cpp @@ -36,6 +36,7 @@ namespace SVF { TOWTRUCK_HOOK, TRACTOR_HOOK, RHINO_WHEELS, + FIRELA_LADDER, // Internal SP use only, formerly "rotor exceptions" // Unreachable from RegisterSpecialVehicleFeature @@ -55,6 +56,7 @@ namespace SVF { { "TOWTRUCK_HOOK", Feature::TOWTRUCK_HOOK }, { "TRACTOR_HOOK", Feature::TRACTOR_HOOK }, { "RHINO_WHEELS", Feature::RHINO_WHEELS }, + { "FIRELA_LADDER", Feature::FIRELA_LADDER }, }; auto it = std::find_if( std::begin(features), std::end(features), [featureName]( const auto& e ) { @@ -92,6 +94,7 @@ namespace SVF { _registerFeatureInternal( 525, Feature::TOWTRUCK_HOOK ), _registerFeatureInternal( 531, Feature::TRACTOR_HOOK ), _registerFeatureInternal( 539, Feature::VORTEX_EXHAUST ), + _registerFeatureInternal( 544, Feature::FIRELA_LADDER ), _registerFeatureInternal( 574, Feature::SWEEPER_BRUSHES ), _registerFeatureInternal( 582, Feature::NEWSVAN_DISH ), _registerFeatureInternal( 603, Feature::PHOENIX_FLUTTER ), @@ -223,6 +226,11 @@ void ReadRotorFixExceptions(const wchar_t* pPath) } } +bool CVehicle::HasFirelaLadder() const +{ + return SVF::ModelHasFeature( m_nModelIndex.Get(), SVF::Feature::FIRELA_LADDER ); +} + void CVehicle::SetComponentAtomicAlpha(RpAtomic* pAtomic, int nAlpha) { RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic); diff --git a/SilentPatchSA/VehicleSA.h b/SilentPatchSA/VehicleSA.h index 6c41df2..1761deb 100644 --- a/SilentPatchSA/VehicleSA.h +++ b/SilentPatchSA/VehicleSA.h @@ -154,10 +154,14 @@ enum eDoor NUM_DOORS }; +#define FLAG_HYDRAULICS_INSTALLED 0x20000 + class NOVMT CVehicle : public CPhysical { protected: - BYTE __pad1[752]; + BYTE __pad0[596]; + uint32_t hFlagsLocal; + BYTE __pad1[152]; CVehicleFlags m_nVehicleFlags; BYTE __pad2[48]; CPed* m_pDriver; @@ -203,6 +207,8 @@ public: void CustomCarPlate_BeforeRenderingStart(CVehicleModelInfo* pModelInfo); //void CustomCarPlate_AfterRenderingStop(CVehicleModelInfo* pModelInfo); + bool HasFirelaLadder() const; + bool IsLawEnforcementVehicle(); static void SetComponentRotation( RwFrame* component, eRotAxis axis, float angle, bool absolute = true );