Skip to content

Commit

Permalink
Reapply skyrim-multiplayer#1543 on EventHandler.cpp and Add Is3DLoade…
Browse files Browse the repository at this point in the history
…d() check.
  • Loading branch information
objir authored May 1, 2024
1 parent 5f3677d commit 07d0f3d
Showing 1 changed file with 96 additions and 29 deletions.
125 changes: 96 additions & 29 deletions skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::vector<std::unique_ptr<
RE::ActiveEffect, game_type_pointer_deleter<RE::ActiveEffect>>>>();

for (const auto& eff :
*event->target.get()->As<RE::Actor>()->GetActiveEffectList()) {
if (eff->usUniqueID != 0) {
auto activeEffect = RE::malloc<RE::ActiveEffect>();
std::memcpy(activeEffect, eff, sizeof(*eff));
effectList->emplace_back(activeEffect,
game_type_pointer_deleter<RE::ActiveEffect>());
auto targetActorPtr = targetPtr->As<RE::Actor>();
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<RE::TESObjectREFR>(casterId);
auto target = RE::TESForm::LookupByID<RE::TESObjectREFR>(targetId);
auto base = RE::TESForm::LookupByID<RE::TESForm>(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<std::vector<std::unique_ptr<
// RE::ActiveEffect, game_type_pointer_deleter<RE::ActiveEffect>>>>();

// for (const auto& eff :
//*event->target.get()->As<RE::Actor>()->GetActiveEffectList()) {
// if (eff->usUniqueID != 0) {
// auto activeEffect = RE::malloc<RE::ActiveEffect>();
// std::memcpy(activeEffect, eff, sizeof(*eff));
// effectList->emplace_back(activeEffect,
// game_type_pointer_deleter<RE::ActiveEffect>());
//}
//}

// 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;
}

Expand Down

0 comments on commit 07d0f3d

Please sign in to comment.