@@ -1541,6 +1541,8 @@ void CModelInfoSA::RestoreOriginalModel()
15411541 if (currentInterface)
15421542 {
15431543 ppModelInfo[m_dwModelID]->usNumberOfRefs = currentInterface->usNumberOfRefs ;
1544+ ppModelInfo[m_dwModelID]->pColModel = currentInterface->pColModel ;
1545+
15441546 delete currentInterface;
15451547 }
15461548
@@ -1818,6 +1820,9 @@ void CModelInfoSA::MakeClumpModel(ushort usBaseID)
18181820
18191821bool CModelInfoSA::ConvertToClump ()
18201822{
1823+ if (GetModelType () == eModelInfoType::CLUMP)
1824+ return false ;
1825+
18211826 // Get current interface
18221827 CBaseModelInfoSAInterface* currentModelInterface = ppModelInfo[m_dwModelID];
18231828 if (!currentModelInterface)
@@ -1838,34 +1843,94 @@ bool CModelInfoSA::ConvertToClump()
18381843 // Set new interface for ModelInfo
18391844 ppModelInfo[m_dwModelID] = newClumpInterface;
18401845
1841- // Store original interface
1842- MapSet (m_convertedModelInterfaces, m_dwModelID, currentModelInterface);
1846+ // Store original (only) interface
1847+ if (!MapContains (m_convertedModelInterfaces, m_dwModelID))
1848+ MapSet (m_convertedModelInterfaces, m_dwModelID, currentModelInterface);
1849+ else
1850+ m_lastConversionInterface = currentModelInterface;
1851+
18431852 return true ;
18441853}
18451854
1846- bool CModelInfoSA::ConvertToAtomic ()
1855+ bool CModelInfoSA::ConvertToAtomic (bool damageable )
18471856{
18481857 // Get current interface
1849- CClumpModelInfoSAInterface* currentClumpInterface = static_cast <CClumpModelInfoSAInterface*>(ppModelInfo[m_dwModelID]);
1850- if (!currentClumpInterface)
1858+ CBaseModelInfoSAInterface* currentModelInterface = ppModelInfo[m_dwModelID];
1859+ if (!currentModelInterface)
1860+ return false ;
1861+
1862+ if (GetModelType () == eModelInfoType::ATOMIC && ((damageable && currentModelInterface->IsDamageAtomicVTBL ()) || (!damageable && currentModelInterface->IsAtomicVTBL ())))
18511863 return false ;
18521864
18531865 // Create new atomic interface
1854- CAtomicModelInfoSAInterface* newAtomicInterface = new CAtomicModelInfoSAInterface () ;
1855- MemCpyFast (newAtomicInterface, currentClumpInterface, sizeof (CAtomicModelInfoSAInterface)) ;
1866+ CAtomicModelInfoSAInterface* newAtomicInterface = nullptr ;
1867+ CDamageableModelInfoSAInterface* newDamageableAtomicInterface = nullptr ;
18561868
18571869 // (FileEX): We do not destroy or set pRwObject to nullptr here
18581870 // because our IsLoaded code expects the RwObject to exist.
18591871 // We destroy the old RwObject in CRenderWareSA::ReplaceAllAtomicsInModel after passing the IsLoaded condition in the SetCustomModel.
18601872
1861- // Set CAtomicModelInfo vtbl after copying data
1862- newAtomicInterface->VFTBL = reinterpret_cast <CBaseModelInfo_SA_VTBL*>(VTBL_CAtomicModelInfo);
1873+ if (damageable)
1874+ {
1875+ newDamageableAtomicInterface = new CDamageableModelInfoSAInterface ();
1876+ MemCpyFast (newDamageableAtomicInterface, currentModelInterface, sizeof (CDamageableModelInfoSAInterface));
1877+ newDamageableAtomicInterface->m_damagedAtomic = nullptr ;
1878+
1879+ // Set CDamageAtomicModelInfo vtbl after copying data
1880+ newDamageableAtomicInterface->VFTBL = reinterpret_cast <CBaseModelInfo_SA_VTBL*>(VTBL_CDamageAtomicModelInfo);
1881+ }
1882+ else
1883+ {
1884+ newAtomicInterface = new CAtomicModelInfoSAInterface ();
1885+ MemCpyFast (newAtomicInterface, currentModelInterface, sizeof (CAtomicModelInfoSAInterface));
1886+
1887+ // Set CAtomicModelInfo vtbl after copying data
1888+ newAtomicInterface->VFTBL = reinterpret_cast <CBaseModelInfo_SA_VTBL*>(VTBL_CAtomicModelInfo);
1889+ }
18631890
18641891 // Set new interface for ModelInfo
1865- ppModelInfo[m_dwModelID] = newAtomicInterface;
1892+ ppModelInfo[m_dwModelID] = damageable ? newDamageableAtomicInterface : newAtomicInterface;
1893+
1894+ // Store original (only) interface
1895+ if (!MapContains (m_convertedModelInterfaces, m_dwModelID))
1896+ MapSet (m_convertedModelInterfaces, m_dwModelID, currentModelInterface);
1897+ else
1898+ m_lastConversionInterface = currentModelInterface;
1899+
1900+ return true ;
1901+ }
1902+
1903+ bool CModelInfoSA::ConvertToTimedObject ()
1904+ {
1905+ if (GetModelType () == eModelInfoType::TIME)
1906+ return false ;
1907+
1908+ // Get current interface
1909+ CBaseModelInfoSAInterface* currentModelInterface = ppModelInfo[m_dwModelID];
1910+ if (!currentModelInterface)
1911+ return false ;
1912+
1913+ // Create new interface
1914+ CTimeModelInfoSAInterface* newTimedInterface = new CTimeModelInfoSAInterface ();
1915+ MemCpyFast (newTimedInterface, currentModelInterface, sizeof (CTimeModelInfoSAInterface));
1916+ newTimedInterface->timeInfo .m_wOtherTimeModel = 0 ;
1917+
1918+ // (FileEX): We do not destroy or set pRwObject to nullptr here
1919+ // because our IsLoaded code expects the RwObject to exist.
1920+ // We destroy the old RwObject in CRenderWareSA::ReplaceAllAtomicsInModel after passing the IsLoaded condition in the SetCustomModel.
1921+
1922+ // Set CTimeModelInfo vtbl after copying data
1923+ newTimedInterface->VFTBL = reinterpret_cast <CBaseModelInfo_SA_VTBL*>(VTBL_CTimeModelInfo);
1924+
1925+ // Set new interface for ModelInfo
1926+ ppModelInfo[m_dwModelID] = newTimedInterface;
1927+
1928+ // Store original (only) interface
1929+ if (!MapContains (m_convertedModelInterfaces, m_dwModelID))
1930+ MapSet (m_convertedModelInterfaces, m_dwModelID, currentModelInterface);
1931+ else
1932+ m_lastConversionInterface = currentModelInterface;
18661933
1867- // Store original interface
1868- MapSet (m_convertedModelInterfaces, m_dwModelID, currentClumpInterface);
18691934 return true ;
18701935}
18711936
0 commit comments