diff --git a/SilentPatchSA/ModelInfoSA.cpp b/SilentPatchSA/ModelInfoSA.cpp index e04c717..84e47e1 100644 --- a/SilentPatchSA/ModelInfoSA.cpp +++ b/SilentPatchSA/ModelInfoSA.cpp @@ -29,6 +29,16 @@ void RemapDirt( CVehicleModelInfo* modelInfo, uint32_t dirtID ) } } +uint32_t CVehicleModelInfo::GetNumRemaps() const +{ + uint32_t count = 0; + while ( m_awRemapTxds[count].Get() != -1 && count < _countof(m_awRemapTxds) ) + { + count++; + } + return count; +} + void CVehicleModelInfo::Shutdown() { CBaseModelInfo::Shutdown(); diff --git a/SilentPatchSA/ModelInfoSA.h b/SilentPatchSA/ModelInfoSA.h index bb76267..5e934ed 100644 --- a/SilentPatchSA/ModelInfoSA.h +++ b/SilentPatchSA/ModelInfoSA.h @@ -304,7 +304,7 @@ public: signed char m_nTertiaryColor; signed char m_nQuaternaryColor; short m_awUpgrades[18]; - short m_awRemapTxds[5]; + FLAUtils::int16 m_awRemapTxds[4]; class CAnimBlock* m_pAnimBlock; public: @@ -320,6 +320,8 @@ public: void SetCarCustomPlate(); void SetVehicleColour( int32_t color1, int32_t color2, int32_t color3, int32_t color4 ); + uint32_t GetNumRemaps() const; + }; extern CBaseModelInfo** const ms_modelInfoPtrs; diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 35f40aa..78d1009 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -4114,6 +4114,10 @@ void Patch_SA_10() InjectHook( 0x56D220, IsMetric_LocaleBased, PATCH_JUMP ); } + + // Fix paintjobs vanishing after opening/closing garage without rendering the car first + InjectHook( 0x6D0B70, &CVehicle::GetRemapIndex, PATCH_JUMP ); + #if FULL_PRECISION_D3D // Test - full precision D3D device Patch( 0x7F672B+1, *(uint8_t*)(0x7F672B+1) | D3DCREATE_FPU_PRESERVE ); diff --git a/SilentPatchSA/VehicleSA.cpp b/SilentPatchSA/VehicleSA.cpp index a10ebc4..8d4dd94 100644 --- a/SilentPatchSA/VehicleSA.cpp +++ b/SilentPatchSA/VehicleSA.cpp @@ -483,6 +483,30 @@ CPed* CVehicle::PickRandomPassenger() return nullptr; } +int32_t CVehicle::GetRemapIndex() +{ + int32_t remapTxd = m_remapTxdSlot.Get(); + if ( remapTxd == -1 ) + { + // Original code never checked that variable, hence the bug + remapTxd = m_remapTxdSlotToLoad.Get(); + } + if ( remapTxd == -1 ) + { + return -1; + } + + const CVehicleModelInfo* modelInfo = static_cast(ms_modelInfoPtrs[ m_nModelIndex.Get() ]); + for ( int32_t i = 0, j = modelInfo->GetNumRemaps(); i < j; i++ ) + { + if ( modelInfo->m_awRemapTxds[i].Get() == remapTxd ) + { + return i; + } + } + return -1; +} + void CHeli::Render() { double dRotorsSpeed, dMovingRotorSpeed; diff --git a/SilentPatchSA/VehicleSA.h b/SilentPatchSA/VehicleSA.h index 7e4ade2..83c1911 100644 --- a/SilentPatchSA/VehicleSA.h +++ b/SilentPatchSA/VehicleSA.h @@ -183,7 +183,9 @@ protected: BYTE __pad78[4]; uint32_t m_dwVehicleClass; uint32_t m_dwVehicleSubClass; - BYTE __pad5[8]; + FLAUtils::int16 m_remapTxdSlot; + FLAUtils::int16 m_remapTxdSlotToLoad; + RwTexture* m_pRemapTexture; public: CVehicleFlags& GetVehicleFlags() @@ -266,6 +268,8 @@ public: bool IsLawEnforcementVehicle(); CPed* PickRandomPassenger(); + int32_t GetRemapIndex(); + static void SetComponentRotation( RwFrame* component, eRotAxis axis, float angle, bool absolute = true ); static void SetComponentAtomicAlpha(RpAtomic* pAtomic, int nAlpha);