From 07d0f3d43efe1460d2d0e60abc8e431e2e619717 Mon Sep 17 00:00:00 2001 From: objir <31658029+objir@users.noreply.github.com> Date: Thu, 2 May 2024 01:20:22 +0800 Subject: [PATCH] Reapply #1543 on EventHandler.cpp and Add Is3DLoaded() check. --- .../skyrim_platform/EventHandler.cpp | 125 ++++++++++++++---- 1 file changed, 96 insertions(+), 29 deletions(-) diff --git a/skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp b/skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp index f46121308c..87ff7e4fbb 100644 --- a/skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp +++ b/skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp @@ -108,48 +108,115 @@ EventResult EventHandler::ProcessEvent( return EventResult::kContinue; } - auto e = CopyEventPtr(event); + auto targetPtr = event->target.get(); + if (!targetPtr) { + return EventResult::kContinue; + } + + - /** - * this is a workaround - * at the moment of writing if you try to create new instance of - * RE::ActiveEffect the game crashes either at instance construction or - * deconstruction, but since we really need copies of those classes here we - * have to manually manage memory to avoid leaks - */ - auto effectList = std::make_shared>>>(); - - for (const auto& eff : - *event->target.get()->As()->GetActiveEffectList()) { - if (eff->usUniqueID != 0) { - auto activeEffect = RE::malloc(); - std::memcpy(activeEffect, eff, sizeof(*eff)); - effectList->emplace_back(activeEffect, - game_type_pointer_deleter()); + auto targetActorPtr = targetPtr->As(); + if (!targetActorPtr) { + return EventResult::kContinue; } + + + + auto effectsListPtr = targetActorPtr->GetActiveEffectList(); + if (!effectsListPtr) { + return EventResult::kContinue; } - SkyrimPlatform::GetSingleton()->AddUpdateTask([e, effectList] { - for (const auto& effect : *effectList.get()) { - if (effect->usUniqueID == e->activeEffectUniqueID) { - auto obj = JsValue::Object(); + uint32_t baseId = 0; + + for (auto effectPtr : *effectsListPtr) { + if (effectPtr && effectPtr->usUniqueID == event->activeEffectUniqueID) { + auto baseEffect = effectPtr->GetBaseObject(); + if (baseEffect) { + baseId = baseEffect->GetFormID(); + break; + } + } + } - AddObjProperty(&obj, "effect", effect->GetBaseObject(), "MagicEffect"); - AddObjProperty(&obj, "caster", e->caster.get(), "ObjectReference"); - AddObjProperty(&obj, "target", e->target.get(), "ObjectReference"); + if (!baseId) { + return EventResult::kContinue; + } - if (e->isApplied) { - SendEvent("effectStart", obj); - } else { - SendEvent("effectFinish", obj); + uint32_t casterId = + event->caster.get() ? event->caster.get()->GetFormID() : 0; + uint32_t targetId = + event->target.get() ? event->target.get()->GetFormID() : 0; + + + bool isApplied = event->isApplied; + + SkyrimPlatform::GetSingleton()->AddUpdateTask( + [casterId, targetId, baseId, isApplied] { + auto caster = RE::TESForm::LookupByID(casterId); + auto target = RE::TESForm::LookupByID(targetId); + auto base = RE::TESForm::LookupByID(baseId); + + if (!base) { + return; + } + + if ((!caster && casterId != 0) || !caster->Is3DLoaded()) { + return; } + if ((!target && targetId != 0) || !target->Is3DLoaded()) { return; } + + auto obj = JsValue::Object(); + + AddObjProperty(&obj, "effect", base, "MagicEffect"); + AddObjProperty(&obj, "caster", caster, "ObjectReference"); + AddObjProperty(&obj, "target", target, "ObjectReference"); + + if (isApplied) { + SendEvent("effectStart", obj); + } else { + SendEvent("effectFinish", obj); } }); + // auto e = CopyEventPtr(event); + + // auto effectList = std::make_shared>>>(); + + // for (const auto& eff : + //*event->target.get()->As()->GetActiveEffectList()) { + // if (eff->usUniqueID != 0) { + // auto activeEffect = RE::malloc(); + // std::memcpy(activeEffect, eff, sizeof(*eff)); + // effectList->emplace_back(activeEffect, + // game_type_pointer_deleter()); + //} + //} + + // SkyrimPlatform::GetSingleton()->AddUpdateTask([e, effectList] { + // for (const auto& effect : *effectList.get()) { + // if (effect->usUniqueID == e->activeEffectUniqueID) { + // auto obj = JsValue::Object(); + + // AddObjProperty(&obj, "effect", effect->GetBaseObject(), "MagicEffect"); + // AddObjProperty(&obj, "caster", e->caster.get(), "ObjectReference"); + // AddObjProperty(&obj, "target", e->target.get(), "ObjectReference"); + + // if (e->isApplied) { + // SendEvent("effectStart", obj); + //} else { + // SendEvent("effectFinish", obj); + //} + + // return; + //} + //} + //}); + return EventResult::kContinue; }