@@ -59,7 +59,7 @@ CClientEntity* CBuildingsPoolSA::GetClientBuilding(CBuildingSAInterface* pGameIn
5959 return m_buildingPool.entities [poolIndex].pClientEntity ;
6060}
6161
62- CBuilding* CBuildingsPoolSA::AddBuilding (CClientBuilding* pClientBuilding, uint16_t modelId, CVector* vPos, CVector4D * vRot, uint8_t interior)
62+ CBuilding* CBuildingsPoolSA::AddBuilding (CClientBuilding* pClientBuilding, uint16_t modelId, CVector* vPos, CVector * vRot, uint8_t interior)
6363{
6464 if (!HasFreeBuildingSlot ())
6565 return nullptr ;
@@ -72,15 +72,12 @@ CBuilding* CBuildingsPoolSA::AddBuilding(CClientBuilding* pClientBuilding, uint1
7272 modelInfo->SetObjectPropertiesGroup (MODEL_PROPERTIES_GROUP_STATIC);
7373
7474 // Load building
75- SFileObjectInstance instance;
75+ SFileObjectInstance instance{} ;
7676 instance.modelID = modelId;
7777 instance.lod = -1 ;
7878 instance.interiorID = interior;
7979 instance.position = *vPos;
80- instance.rotation = *vRot;
81-
82- // Fix strange SA rotation
83- instance.rotation .fW = -instance.rotation .fW ;
80+ instance.rotation = {};
8481
8582 auto pBuilding = static_cast <CBuildingSAInterface*>(CFileLoaderSA::LoadObjectInstance (&instance));
8683
@@ -98,6 +95,22 @@ CBuilding* CBuildingsPoolSA::AddBuilding(CClientBuilding* pClientBuilding, uint1
9895
9996 // Add building in world
10097 auto pBuildingSA = new CBuildingSA (pBuilding);
98+
99+ if (pBuilding->HasMatrix ())
100+ {
101+ // Edge case for the traincross2 (1374) model
102+ // LoadObjectInstance allocates a matrix for the model
103+ // We need allocate our own matrix and put the old matrix in the original pool
104+ pBuildingSA->ReallocateMatrix ();
105+ }
106+ else if (vRot->fX != 0 || vRot->fY != 0 )
107+ {
108+ // Allocate matrix in our unlimited storage instead of using the shared pool.
109+ pBuildingSA->AllocateMatrix ();
110+ }
111+
112+ pBuilding->SetOrientation (vRot->fX , vRot->fY , vRot->fZ );
113+
101114 pGame->GetWorld ()->Add (pBuildingSA, CBuildingPool_Constructor);
102115
103116 // Add CBuildingSA object in pool
@@ -116,6 +129,10 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding)
116129 if (dwElementIndexInPool == UINT_MAX)
117130 return ;
118131
132+ // Remove references to allocated matrix
133+ auto * pBuildingSA = m_buildingPool.entities [dwElementIndexInPool].pEntity ;
134+ pBuildingSA->RemoveAllocatedMatrix ();
135+
119136 // Remove building from cover list
120137 pGame->GetCoverManager ()->RemoveCover (pInterface);
121138
@@ -128,23 +145,24 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding)
128145 // Remove building from world
129146 pGame->GetWorld ()->Remove (pInterface, CBuildingPool_Destructor);
130147
148+ std::uint16_t modelId = pInterface->m_nModelIndex ;
149+
131150 // Call virtual destructor
132151 ((void *(__thiscall*)(void *, char ))pInterface->vtbl ->SCALAR_DELETING_DESTRUCTOR )(pInterface, 0 );
133152
134153 // Remove col reference
135- auto modelInfo = pGame->GetModelInfo (pBuilding-> GetModelIndex () );
154+ auto modelInfo = pGame->GetModelInfo (modelId );
136155 modelInfo->RemoveColRef ();
137156
157+ // Remove building from SA pool
158+ (*m_ppBuildingPoolInterface)->Release (dwElementIndexInPool);
159+
138160 // Remove from BuildingSA pool
139- auto * pBuildingSA = m_buildingPool.entities [dwElementIndexInPool].pEntity ;
140161 m_buildingPool.entities [dwElementIndexInPool] = {nullptr , nullptr };
141162
142163 // Delete it from memory
143164 delete pBuildingSA;
144165
145- // Remove building from SA pool
146- (*m_ppBuildingPoolInterface)->Release (dwElementIndexInPool);
147-
148166 // Decrease the count of elements in the pool
149167 --m_buildingPool.count ;
150168}
0 commit comments