3333#include < Games/Primitives.h>
3434#include < ExtraData/ExtraContainerChanges.h>
3535
36+ namespace
37+ {
38+ const char * DescribeReadiness (InventoryService::ActorReadinessStatus aStatus) noexcept
39+ {
40+ switch (aStatus)
41+ {
42+ case InventoryService::ActorReadinessStatus::MissingActor:
43+ return " actor reference" ;
44+ case InventoryService::ActorReadinessStatus::Missing3D:
45+ return " 3D data" ;
46+ case InventoryService::ActorReadinessStatus::MissingContainerData:
47+ return " inventory data" ;
48+ default :
49+ return " ready state" ;
50+ }
51+ }
52+ }
53+
3654InventoryService::InventoryService (World& aWorld, entt::dispatcher& aDispatcher, TransportService& aTransport) noexcept
3755 : m_world(aWorld)
3856 , m_dispatcher(aDispatcher)
@@ -217,7 +235,8 @@ void InventoryService::OnNotifyEquipmentChanges(const NotifyEquipmentChanges& ac
217235 return ;
218236 }
219237
220- if (!pActor->GetNiNode ())
238+ const auto readiness = EvaluateActorReadiness (pActor);
239+ if (readiness != ActorReadinessStatus::Ready)
221240 {
222241 auto view = m_world.view <FormIdComponent>();
223242 const auto itor = std::find_if (std::begin (view), std::end (view), [formId = pActor->formID , view](entt::entity entity) { return view.get <FormIdComponent>(entity).Id == formId; });
@@ -229,7 +248,7 @@ void InventoryService::OnNotifyEquipmentChanges(const NotifyEquipmentChanges& ac
229248 pPending = &m_world.emplace <PendingEquipmentComponent>(*itor);
230249
231250 pPending->PendingChanges .push_back (acMessage);
232- spdlog::debug (" Queued equipment change for actor {:X} until 3D is ready " , pActor->formID );
251+ spdlog::debug (" Queued equipment change for actor {:X} (waiting for {}) " , pActor->formID , DescribeReadiness (readiness) );
233252 }
234253 else
235254 {
@@ -331,8 +350,13 @@ void InventoryService::ProcessPendingEquipment() noexcept
331350 auto & pending = view.get <PendingEquipmentComponent>(entity);
332351
333352 Actor* pActor = Cast<Actor>(TESForm::GetById (formIdComponent.Id ));
334- if (!pActor || !pActor->GetNiNode ())
353+ const auto readiness = EvaluateActorReadiness (pActor);
354+ if (readiness != ActorReadinessStatus::Ready)
355+ {
356+ if (readiness == ActorReadinessStatus::MissingActor)
357+ toClear.push_back (entity);
335358 continue ;
359+ }
336360
337361 for (const auto & change : pending.PendingChanges )
338362 ApplyEquipmentChange (pActor, change);
@@ -384,22 +408,10 @@ bool InventoryService::SendEquipmentChange(const EquipmentChangeEvent& acEvent)
384408 }
385409
386410 Actor* pActor = Cast<Actor>(TESForm::GetById (acEvent.ActorId ));
387- if (!pActor)
388- {
389- spdlog::debug (" {}: actor {:X} not ready, postponing equipment sync" , __FUNCTION__, acEvent.ActorId );
390- return false ;
391- }
392-
393- if (!pActor->GetNiNode ())
411+ const auto readiness = EvaluateActorReadiness (pActor);
412+ if (readiness != ActorReadinessStatus::Ready)
394413 {
395- spdlog::debug (" {}: actor {:X} missing 3D, postponing equipment sync" , __FUNCTION__, acEvent.ActorId );
396- return false ;
397- }
398-
399- ExtraContainerChanges::Data* pContainerChanges = pActor->GetContainerChanges ();
400- if (!pContainerChanges || !pContainerChanges->entries )
401- {
402- spdlog::debug (" {}: actor {:X} missing container data, postponing equipment sync" , __FUNCTION__, acEvent.ActorId );
414+ spdlog::debug (" {}: actor {:X} not ready (waiting for {}), postponing equipment sync" , __FUNCTION__, acEvent.ActorId , DescribeReadiness (readiness));
403415 return false ;
404416 }
405417
@@ -428,6 +440,21 @@ bool InventoryService::SendEquipmentChange(const EquipmentChangeEvent& acEvent)
428440 return true ;
429441}
430442
443+ InventoryService::ActorReadinessStatus InventoryService::EvaluateActorReadiness (Actor* pActor) const noexcept
444+ {
445+ if (!pActor)
446+ return ActorReadinessStatus::MissingActor;
447+
448+ if (!pActor->GetNiNode ())
449+ return ActorReadinessStatus::Missing3D;
450+
451+ if (ExtraContainerChanges::Data* pContainerChanges = pActor->GetContainerChanges ();
452+ !pContainerChanges || !pContainerChanges->entries )
453+ return ActorReadinessStatus::MissingContainerData;
454+
455+ return ActorReadinessStatus::Ready;
456+ }
457+
431458void InventoryService::RunWeaponStateUpdates () noexcept
432459{
433460 if (!m_transport.IsConnected ())
0 commit comments