16
16
#include < game/CWorld.h>
17
17
#include " CGameSA.h"
18
18
#include " CPtrNodeSingleListSA.h"
19
+ #include " MemSA.h"
20
+ #include " CVehicleSA.h"
19
21
20
22
extern CGameSA* pGame;
21
23
@@ -93,16 +95,13 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding)
93
95
if (dwElementIndexInPool == UINT_MAX)
94
96
return ;
95
97
96
- // Remove building from world
97
- pGame->GetWorld ()->Remove (pInterface, CBuildingPool_Destructor);
98
-
99
98
// Remove building from cover list
100
- CPtrNodeSingleListSAInterface<CBuildingSAInterface>* coverList = reinterpret_cast <CPtrNodeSingleListSAInterface<CBuildingSAInterface>*>(0xC1A2B8 );
101
- coverList->RemoveItem (pInterface);
99
+ pGame->GetCoverManager ()->RemoveCover (pInterface);
102
100
103
101
// Remove plant
104
- using CPlantColEntry_Remove = CEntitySAInterface* (*)(CEntitySAInterface*);
105
- ((CPlantColEntry_Remove)0x5DBEF0 )(pInterface);
102
+ pGame->GetPlantManager ()->RemovePlant (pInterface);
103
+
104
+ RemoveBuildingFromWorld (pInterface);
106
105
107
106
// Remove col reference
108
107
auto modelInfo = pGame->GetModelInfo (pBuilding->GetModelIndex ());
@@ -127,16 +126,23 @@ void CBuildingsPoolSA::RemoveAllBuildings()
127
126
if (m_pOriginalBuildingsBackup)
128
127
return ;
129
128
129
+ pGame->GetCoverManager ()->RemoveAllCovers ();
130
+ pGame->GetPlantManager ()->RemoveAllPlants ();
131
+
132
+ // Remove all shadows
133
+ using CStencilShadowObjects_dtorAll = void * (*)();
134
+ ((CStencilShadowObjects_dtorAll)0x711390 )();
135
+
130
136
m_pOriginalBuildingsBackup = std::make_unique<std::array<std::pair<bool , CBuildingSAInterface>, MAX_BUILDINGS>>();
131
137
132
138
auto pBuildsingsPool = (*m_ppBuildingPoolInterface);
133
139
for (size_t i = 0 ; i < MAX_BUILDINGS; i++)
134
140
{
135
141
if (pBuildsingsPool->IsContains (i))
136
142
{
137
- auto building = pBuildsingsPool->GetObject (i);
143
+ CBuildingSAInterface* building = pBuildsingsPool->GetObject (i);
138
144
139
- pGame-> GetWorld ()-> Remove ( building, CBuildingPool_Destructor );
145
+ RemoveBuildingFromWorld ( building);
140
146
141
147
pBuildsingsPool->Release (i);
142
148
@@ -162,14 +168,146 @@ void CBuildingsPoolSA::RestoreAllBuildings()
162
168
if (originalData[i].first )
163
169
{
164
170
pBuildsingsPool->AllocateAt (i);
165
- auto building = pBuildsingsPool->GetObject (i);
166
- *building = originalData[i].second ;
171
+ auto pBuilding = pBuildsingsPool->GetObject (i);
172
+ *pBuilding = originalData[i].second ;
167
173
168
- pGame->GetWorld ()->Add (building , CBuildingPool_Constructor);
174
+ pGame->GetWorld ()->Add (pBuilding , CBuildingPool_Constructor);
169
175
}
170
176
}
171
177
172
- m_pOriginalBuildingsBackup.release ();
178
+ m_pOriginalBuildingsBackup = nullptr ;
179
+ }
180
+
181
+ void CBuildingsPoolSA::RemoveBuildingFromWorld (CBuildingSAInterface* pBuilding)
182
+ {
183
+ // Remove building from world
184
+ pGame->GetWorld ()->Remove (pBuilding, CBuildingPool_Destructor);
185
+
186
+ pBuilding->DeleteRwObject ();
187
+ pBuilding->ResolveReferences ();
188
+ pBuilding->RemoveShadows ();
189
+ }
190
+
191
+ bool CBuildingsPoolSA::Resize (int size)
192
+ {
193
+ auto * pool = (*m_ppBuildingPoolInterface);
194
+ const int curretnSize = pool->m_nSize ;
195
+
196
+ void * oldPool = pool->m_pObjects ;
197
+
198
+ if (oldPool != nullptr )
199
+ {
200
+ MemSA::free (pool->m_pObjects );
201
+ pool->m_pObjects = nullptr ;
202
+ }
203
+
204
+ if (pool->m_byteMap != nullptr )
205
+ {
206
+ MemSA::free (pool->m_byteMap );
207
+ pool->m_byteMap = nullptr ;
208
+ }
209
+
210
+ CBuildingSAInterface* newObjects = MemSA::malloc_struct<CBuildingSAInterface>(size);
211
+ if (newObjects == nullptr )
212
+ {
213
+ Resize (curretnSize);
214
+ return false ;
215
+ }
216
+
217
+ tPoolObjectFlags* newBytemap = MemSA::malloc_struct<tPoolObjectFlags>(size);
218
+ if (newBytemap == nullptr )
219
+ {
220
+ MemSA::free (newObjects);
221
+ Resize (curretnSize);
222
+ return false ;
223
+ }
224
+
225
+ pool->m_pObjects = newObjects;
226
+ pool->m_byteMap = newBytemap;
227
+ pool->m_nSize = size;
228
+ pool->m_nFirstFree = 0 ;
229
+
230
+ for (auto i = 0 ; i < size; i++)
231
+ {
232
+ newBytemap[i].bEmpty = true ;
233
+ }
234
+
235
+ const uint32_t offset = (uint32_t )newObjects - (uint32_t )oldPool;
236
+ if (oldPool != nullptr )
237
+ {
238
+ UpdateIplEntrysPointers (offset);
239
+ }
240
+
241
+ if (m_pOriginalBuildingsBackup)
242
+ {
243
+ UpdateBackupLodPointers (offset);
244
+ }
245
+
246
+ pGame->GetPools ()->GetDummyPool ().UpdateBuildingLods (oldPool, newObjects);
247
+
248
+ RemoveVehicleDamageLinks ();
249
+
250
+ return true ;
251
+ }
252
+
253
+ void CBuildingsPoolSA::UpdateIplEntrysPointers (uint32_t offset)
254
+ {
255
+ using buildings_array_t = CBuildingSAInterface* [1000 ];
256
+ using ipl_entry_array_t = buildings_array_t * [40 ];
257
+ ipl_entry_array_t * iplEntryArray = (ipl_entry_array_t *)0x8E3F08 ;
258
+
259
+ for (auto i = 0 ; i < 40 ; i++)
260
+ {
261
+ buildings_array_t * ppArray = (*iplEntryArray)[i];
262
+
263
+ if (ppArray == nullptr )
264
+ {
265
+ return ;
266
+ }
267
+ size_t arraySize = MemSA::msize (*ppArray) / sizeof (CBuildingSAInterface*);
268
+ for (auto j = 0 ; j < arraySize; j++)
269
+ {
270
+ CBuildingSAInterface* object = (*ppArray)[j];
271
+
272
+ (*ppArray)[j] = (CBuildingSAInterface*)((uint32_t )object + offset);
273
+ }
274
+ }
275
+ }
276
+
277
+ void CBuildingsPoolSA::UpdateBackupLodPointers (uint32_t offset)
278
+ {
279
+ std::array<std::pair<bool , CBuildingSAInterface>, MAX_BUILDINGS> *arr = m_pOriginalBuildingsBackup.get ();
280
+ for (auto i = 0 ; i < MAX_BUILDINGS; i++)
281
+ {
282
+ std::pair<bool , CBuildingSAInterface>* data = &(*arr)[i];
283
+ if (data->first )
284
+ {
285
+ CBuildingSAInterface* building = &data->second ;
286
+ if (building->m_pLod != nullptr )
287
+ {
288
+ building->m_pLod = (CBuildingSAInterface*)((uint32_t )building->m_pLod + offset);
289
+ }
290
+ }
291
+ }
292
+ }
293
+
294
+ void CBuildingsPoolSA::RemoveVehicleDamageLinks ()
295
+ {
296
+ const int count = pGame->GetPools ()->GetVehicleCount ();
297
+ for (int i = 0 ; i < count; i++)
298
+ {
299
+ auto * vehLinks = pGame->GetPools ()->GetVehicle (i);
300
+ if (vehLinks->pEntity )
301
+ {
302
+ CVehicleSAInterface* vehicle = vehLinks->pEntity ->GetVehicleInterface ();
303
+ vehicle->m_pCollidedEntity = nullptr ;
304
+ vehicle->pLastContactedEntity [0 ] = nullptr ;
305
+ vehicle->pLastContactedEntity [1 ] = nullptr ;
306
+ vehicle->pLastContactedEntity [2 ] = nullptr ;
307
+ vehicle->pLastContactedEntity [3 ] = nullptr ;
308
+ vehicle->m_ucCollisionState = 0 ;
309
+ }
310
+ }
173
311
}
174
312
175
313
bool CBuildingsPoolSA::HasFreeBuildingSlot ()
0 commit comments