diff --git a/SAFix/SilentPatchSA.cpp b/SAFix/SilentPatchSA.cpp index 4d7f2df..39ff847 100644 --- a/SAFix/SilentPatchSA.cpp +++ b/SAFix/SilentPatchSA.cpp @@ -1406,6 +1406,18 @@ __forceinline void Patch_SA_10() Patch(0x6B4EC0, bEnableMouseSteering); Patch(0x6CE827, bEnableMouseSteering); + // Patched CAutomobile::Fix + // misc_x parts don't get reset (Bandito fix), Towtruck's bouncing panel is not reset + //Patch(0x6A34C9, 0x5EEB); + Patch(0x6A34D0, 10); + Patch(0x6A3555, 0x5E5FCF8B); + Patch(0x6A3559, 0x448B5B5D); + Patch(0x6A355D, 0x89644824); + Patch(0x6A3561, 5); + Patch(0x6A3565, 0x54C48300); + InjectHook(0x6A3569, &CAutomobile::Fix_SilentPatch, PATCH_JUMP); + + // Zones fix InjectHook(0x572130, GetCurrentZoneLockedOrUnlocked, PATCH_JUMP); diff --git a/SAFix/VehicleSA.cpp b/SAFix/VehicleSA.cpp index f51cfc1..54486b5 100644 --- a/SAFix/VehicleSA.cpp +++ b/SAFix/VehicleSA.cpp @@ -98,8 +98,8 @@ void CVehicle::CustomCarPlate_BeforeRenderingStart(CVehicleModelInfo* pModelInfo void CHeli::Render() { double dRotorsSpeed, dMovingRotorSpeed; - bool bHasMovingRotor = m_pCarNode[12] != nullptr; - bool bHasMovingRotor2 = m_pCarNode[14] != nullptr; + bool bHasMovingRotor = m_pCarNode[13] != nullptr; + bool bHasMovingRotor2 = m_pCarNode[15] != nullptr; m_nTimeTillWeNeedThisCar = CTimer::m_snTimeInMilliseconds + 3000; @@ -115,18 +115,18 @@ void CHeli::Render() int nStaticRotorAlpha = static_cast(min((1.5-dRotorsSpeed) * 255.0, 255)); int nMovingRotorAlpha = static_cast(min(dMovingRotorSpeed * 175.0, 175)); - if ( m_pCarNode[11] ) + if ( m_pCarNode[12] ) { RpAtomic* pOutAtomic = nullptr; - RwFrameForAllObjects(m_pCarNode[11], GetCurrentAtomicObjectCB, &pOutAtomic); + RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor ? nStaticRotorAlpha : 255); } - if ( m_pCarNode[13] ) + if ( m_pCarNode[14] ) { RpAtomic* pOutAtomic = nullptr; - RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic); + RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor2 ? nStaticRotorAlpha : 255); } @@ -134,7 +134,7 @@ void CHeli::Render() if ( bHasMovingRotor ) { RpAtomic* pOutAtomic = nullptr; - RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic); + RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) SetComponentAtomicAlpha(pOutAtomic, nMovingRotorAlpha); } @@ -142,7 +142,7 @@ void CHeli::Render() if ( bHasMovingRotor2 ) { RpAtomic* pOutAtomic = nullptr; - RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic); + RwFrameForAllObjects(m_pCarNode[15], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) SetComponentAtomicAlpha(pOutAtomic, nMovingRotorAlpha); } @@ -153,8 +153,8 @@ void CHeli::Render() void CPlane::Render() { double dRotorsSpeed, dMovingRotorSpeed; - bool bHasMovingProp = m_pCarNode[12] != nullptr; - bool bHasMovingProp2 = m_pCarNode[14] != nullptr; + bool bHasMovingProp = m_pCarNode[13] != nullptr; + bool bHasMovingProp2 = m_pCarNode[15] != nullptr; m_nTimeTillWeNeedThisCar = CTimer::m_snTimeInMilliseconds + 3000; @@ -170,18 +170,18 @@ void CPlane::Render() int nStaticRotorAlpha = static_cast(min((1.5-dRotorsSpeed) * 255.0, 255)); int nMovingRotorAlpha = static_cast(min(dMovingRotorSpeed * 175.0, 175)); - if ( m_pCarNode[11] ) + if ( m_pCarNode[12] ) { RpAtomic* pOutAtomic = nullptr; - RwFrameForAllObjects(m_pCarNode[11], GetCurrentAtomicObjectCB, &pOutAtomic); + RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp ? nStaticRotorAlpha : 255); } - if ( m_pCarNode[13] ) + if ( m_pCarNode[14] ) { RpAtomic* pOutAtomic = nullptr; - RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic); + RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp2 ? nStaticRotorAlpha : 255); } @@ -189,7 +189,7 @@ void CPlane::Render() if ( bHasMovingProp ) { RpAtomic* pOutAtomic = nullptr; - RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic); + RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) SetComponentAtomicAlpha(pOutAtomic, nMovingRotorAlpha); } @@ -197,10 +197,22 @@ void CPlane::Render() if ( bHasMovingProp2 ) { RpAtomic* pOutAtomic = nullptr; - RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic); + RwFrameForAllObjects(m_pCarNode[15], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) SetComponentAtomicAlpha(pOutAtomic, nMovingRotorAlpha); } CVehicle::Render(); +} + +void CAutomobile::Fix_SilentPatch() +{ + // Reset bouncing panels + for ( int i = 0; i < 3; i++ ) + { + // Towtruck/Tractor fix + if ( i == 0 && (m_nModelIndex == 525 && m_pCarNode[21]) || (m_nModelIndex == 531 && m_pCarNode[17]) ) + continue; + m_aBouncingPanel[i].m_nNodeIndex = -1; + } } \ No newline at end of file diff --git a/SAFix/VehicleSA.h b/SAFix/VehicleSA.h index dafed0d..01da4b3 100644 --- a/SAFix/VehicleSA.h +++ b/SAFix/VehicleSA.h @@ -86,6 +86,16 @@ struct CVehicleFlags unsigned char bUsedForReplay: 1; // This car is controlled by replay and should be removed when replay is done. }; +class CBouncingPanel +{ +public: + short m_nNodeIndex; + short m_nBouncingType; + float m_fBounceRange; + CVector field_8; + CVector m_vecBounceVector; +}; + class NOVMT CVehicle : public CPhysical { protected: @@ -121,13 +131,15 @@ public: class NOVMT CAutomobile : public CVehicle { public: - BYTE paddd[172]; - RwFrame* m_pCarNode[20]; // May be wrong? - BYTE padding[432]; - float m_fRotorSpeed; - BYTE __moarpad[312]; + BYTE paddd[168]; + RwFrame* m_pCarNode[25]; + CBouncingPanel m_aBouncingPanel[3]; + BYTE padding[320]; + float m_fRotorSpeed; + BYTE __moarpad[312]; public: + void Fix_SilentPatch(); }; class NOVMT CHeli : public CAutomobile @@ -152,6 +164,7 @@ public: virtual void Render() override; }; +static_assert(sizeof(CBouncingPanel) == 0x20, "Wrong size: CBouncingPanel"); static_assert(sizeof(CVehicle) == 0x5A0, "Wrong size: CVehicle"); static_assert(sizeof(CAutomobile) == 0x988, "Wrong size: CAutomobile");