@@ -314,15 +314,15 @@ void MagicService::OnAddTargetEvent(const AddTargetEvent& acEvent) noexcept
314
314
if (it == std::end (view))
315
315
{
316
316
spdlog::warn (" Form id not found for magic add target, form id: {:X}" , acEvent.TargetID );
317
- m_queuedEffects[acEvent.TargetID ] = request;
317
+ m_queuedEffects[acEvent.TargetID ] = std::pair ( 0 , request) ;
318
318
return ;
319
319
}
320
320
321
321
std::optional<uint32_t > serverIdRes = Utils::GetServerId (*it);
322
322
if (!serverIdRes.has_value ())
323
323
{
324
324
spdlog::warn (" Server id not found for magic add target, form id: {:X}" , acEvent.TargetID );
325
- m_queuedEffects[acEvent.TargetID ] = request;
325
+ m_queuedEffects[acEvent.TargetID ] = std::pair ( 0 , request) ;
326
326
return ;
327
327
}
328
328
@@ -333,7 +333,7 @@ void MagicService::OnAddTargetEvent(const AddTargetEvent& acEvent) noexcept
333
333
if (casterIt == std::end (view))
334
334
{
335
335
spdlog::warn (" Form id not found for magic add target, form id: {:X}" , acEvent.CasterID );
336
- m_queuedEffects[acEvent.TargetID ] = request;
336
+ m_queuedEffects[acEvent.TargetID ] = std::pair ( 0 , request) ;
337
337
return ;
338
338
}
339
339
@@ -356,7 +356,7 @@ void MagicService::OnNotifyAddTarget(const NotifyAddTarget& acMessage) noexcept
356
356
if (!pActor)
357
357
{
358
358
spdlog::warn (__FUNCTION__ " : could not find actor server id {:X}" , acMessage.TargetId );
359
- m_queuedRemoteEffects[acMessage.TargetId ] = acMessage;
359
+ m_queuedRemoteEffects[acMessage.TargetId ] = std::pair ( 0 , acMessage) ;
360
360
return ;
361
361
}
362
362
@@ -496,10 +496,19 @@ void MagicService::ApplyQueuedEffects() noexcept
496
496
497
497
Vector<uint32_t > markedForRemoval{};
498
498
499
- for (auto [formId, request ] : m_queuedEffects)
499
+ for (auto [targetId, attemptsRequestPair ] : m_queuedEffects)
500
500
{
501
+ // Target might never be found, it may be both created and destroyed while we are between polls.
502
+ // Why is Map().second so stubbornly const? Doesn't work even with iterator, and it should, so this hack.
503
+ if (++(m_queuedEffects[targetId].first ) >= 5 )
504
+ {
505
+ spdlog::warn (__FUNCTION__ " : cancelling queued magic effect after repeated failure to find targetId {:X}" , targetId);
506
+ markedForRemoval.push_back (targetId);
507
+ continue ;
508
+ }
509
+
501
510
auto view = m_world.view <FormIdComponent>();
502
- const auto it = std::find_if (std::begin (view), std::end (view), [id = formId , view](auto entity) { return view.get <FormIdComponent>(entity).Id == id; });
511
+ const auto it = std::find_if (std::begin (view), std::end (view), [id = targetId , view](auto entity) { return view.get <FormIdComponent>(entity).Id == id; });
503
512
504
513
if (it == std::end (view))
505
514
continue ;
@@ -510,25 +519,35 @@ void MagicService::ApplyQueuedEffects() noexcept
510
519
if (!serverIdRes.has_value ())
511
520
continue ;
512
521
513
- request .TargetId = serverIdRes.value ();
522
+ attemptsRequestPair. second .TargetId = serverIdRes.value ();
514
523
515
- m_transport.Send (request );
524
+ m_transport.Send (attemptsRequestPair. second );
516
525
517
- markedForRemoval.push_back (formId );
526
+ markedForRemoval.push_back (targetId );
518
527
}
519
528
520
- for (uint32_t formId : markedForRemoval)
521
- m_queuedEffects.erase (formId );
529
+ for (uint32_t targetId : markedForRemoval)
530
+ m_queuedEffects.erase (targetId );
522
531
523
532
markedForRemoval.clear ();
524
533
525
- for (const auto & [serverId, notify ] : m_queuedRemoteEffects)
534
+ for (auto [serverId, attemptsRequestPair ] : m_queuedRemoteEffects)
526
535
{
536
+ if (++(m_queuedRemoteEffects[serverId].first ) >= 5 )
537
+ {
538
+ spdlog::warn (__FUNCTION__ " : cancelling queued magic effect after repeated failure to find Actor for serverId {:X}" , serverId);
539
+ markedForRemoval.push_back (serverId);
540
+ continue ;
541
+ }
542
+
527
543
Actor* pActor = Utils::GetByServerId<Actor>(serverId);
528
544
if (!pActor)
545
+ {
546
+ spdlog::warn (__FUNCTION__ " : could not find actor for server id {:X}" , serverId);
529
547
continue ;
548
+ }
530
549
531
- OnNotifyAddTarget (notify );
550
+ OnNotifyAddTarget (attemptsRequestPair. second );
532
551
533
552
markedForRemoval.push_back (serverId);
534
553
}
0 commit comments