Skip to content

Commit 86d8d22

Browse files
committed
Fix ExtData allocation
- Now allocated in CTOR, loading game fetches existing extdata pointers and allocates if missing for any reason - Because AbstractClass::Load() overrides pointer data stored at 0x18, the ExtData pointer is stored in Container<T> in PrepareStream() and restored in LoadStatic()
1 parent 04d099b commit 86d8d22

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

src/Ext/Anim/Body.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,10 @@ DEFINE_HOOK_AGAIN(0x422126, AnimClass_CTOR, 0x5)
281281
DEFINE_HOOK_AGAIN(0x422707, AnimClass_CTOR, 0x5)
282282
DEFINE_HOOK(0x4228D2, AnimClass_CTOR, 0x5)
283283
{
284+
GET(AnimClass*, pItem, ESI);
285+
284286
if (!Phobos::IsLoadingSaveGame)
285287
{
286-
GET(AnimClass*, pItem, ESI);
287-
288288
auto const callerAddress = CTORTemp::callerAddress;
289289

290290
// Do this here instead of using a duplicate hook in SyncLogger.cpp
@@ -296,10 +296,10 @@ DEFINE_HOOK(0x4228D2, AnimClass_CTOR, 0x5)
296296
Debug::Log("Attempting to create animation with null Type (Caller: %08x)!\n", callerAddress);
297297
return 0;
298298
}
299-
300-
AnimExt::ExtMap.Allocate(pItem);
301299
}
302300

301+
AnimExt::ExtMap.Allocate(pItem);
302+
303303
return 0;
304304
}
305305

src/Utilities/Container.h

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ class Container
286286
map_type Items;
287287

288288
base_type* SavingObject;
289+
extension_type_ptr SavingExtPointer;
289290
IStream* SavingStream;
290291
const char* Name;
291292

@@ -361,10 +362,6 @@ class Container
361362

362363
extension_type_ptr TryAllocate(base_type_ptr key, bool bCond, const std::string_view& nMessage)
363364
{
364-
// Do not allow allocation when loading save games.
365-
if (Phobos::IsLoadingSaveGame)
366-
return nullptr;
367-
368365
if (!key || (!bCond && !nMessage.empty()))
369366
{
370367
Debug::Log("%s \n", nMessage.data());
@@ -376,10 +373,6 @@ class Container
376373

377374
extension_type_ptr TryAllocate(base_type_ptr key)
378375
{
379-
// Do not allow allocation when loading save games.
380-
if (Phobos::IsLoadingSaveGame)
381-
return nullptr;
382-
383376
if (!key)
384377
{
385378
Debug::Log("Attempted to allocate %s from nullptr!\n", typeid(extension_type).name());
@@ -400,6 +393,22 @@ class Container
400393
return this->Items.find(key);
401394
}
402395

396+
// Only used on loading, does not check if key is nullptr.
397+
extension_type_ptr FindOrAllocate(base_type_ptr key)
398+
{
399+
extension_type_ptr value = nullptr;
400+
401+
if constexpr (HasOffset<T>)
402+
value = GetExtensionPointer(key);
403+
else
404+
value = this->Items.find(key);
405+
406+
if (!value)
407+
value = Allocate(key);
408+
409+
return value;
410+
}
411+
403412
void Remove(base_type_ptr key)
404413
{
405414
if (auto Item = Find(key))
@@ -442,6 +451,10 @@ class Container
442451

443452
this->SavingObject = key;
444453
this->SavingStream = pStm;
454+
455+
// Loading the base type data might override the ext pointer stored on it so it needs to be saved.
456+
if constexpr (HasOffset<T>)
457+
this->SavingExtPointer = GetExtensionPointer(key);
445458
}
446459

447460
void SaveStatic()
@@ -466,6 +479,10 @@ class Container
466479
{
467480
if (this->SavingObject && this->SavingStream)
468481
{
482+
// Restore stored ext pointer data.
483+
if constexpr (HasOffset<T>)
484+
SetExtensionPointer(this->SavingObject, this->SavingExtPointer);
485+
469486
//Debug::Log("[LoadStatic] Loading object %p as '%s'\n", this->SavingObject, this->Name);
470487
if (!this->Load(this->SavingObject, this->SavingStream))
471488
Debug::FatalErrorAndExit("LoadStatic - Loading object %p as '%s' failed!\n", this->SavingObject, this->Name);
@@ -550,8 +567,8 @@ class Container
550567
return nullptr;
551568
}
552569

553-
extension_type_ptr buffer = this->Allocate(key);
554-
570+
// get or allocate the value data
571+
extension_type_ptr buffer = this->FindOrAllocate(key);
555572
if (!buffer)
556573
{
557574
Debug::Log("LoadKey - Could not find or allocate value.\n");

0 commit comments

Comments
 (0)