diff --git a/Code/client/Events/AddTargetEvent.h b/Code/client/Events/AddTargetEvent.h new file mode 100644 index 000000000..8fad49ee2 --- /dev/null +++ b/Code/client/Events/AddTargetEvent.h @@ -0,0 +1,11 @@ +#pragma once + +struct AddTargetEvent +{ + AddTargetEvent(uint32_t aTargetID, uint32_t aSpellID) + : TargetID(aTargetID), SpellID(aSpellID) + {} + + uint32_t TargetID; + uint32_t SpellID; +}; diff --git a/Code/client/Games/Skyrim/Actor.cpp b/Code/client/Games/Skyrim/Actor.cpp index 26c355dd5..454dedb8d 100644 --- a/Code/client/Games/Skyrim/Actor.cpp +++ b/Code/client/Games/Skyrim/Actor.cpp @@ -476,7 +476,7 @@ bool TP_MAKE_THISCALL(HookDamageActor, Actor, float aDamage, Actor* apHitter) { if (faction.Id.BaseId == 0x00000DB1 && pExHittee->IsRemote()) { - return 0; + return false; } else if (faction.Id.BaseId == 0x00000DB1 && pExHittee->IsLocal()) { @@ -492,7 +492,7 @@ bool TP_MAKE_THISCALL(HookDamageActor, Actor, float aDamage, Actor* apHitter) return ThisCall(RealDamageActor, apThis, aDamage, apHitter); } - return 0; + return false; } TP_THIS_FUNCTION(TApplyActorEffect, void, ActiveEffect, Actor* apTarget, float aEffectValue, unsigned int unk1); diff --git a/Code/client/Games/Skyrim/Actor.h b/Code/client/Games/Skyrim/Actor.h index 93f800573..228ee7c36 100644 --- a/Code/client/Games/Skyrim/Actor.h +++ b/Code/client/Games/Skyrim/Actor.h @@ -308,6 +308,7 @@ struct Actor : TESObjectREFR //void Save_Reversed(uint32_t aChangeFlags, Buffer::Writer& aWriter); }; +constexpr size_t t = offsetof(Actor, magicTarget); static_assert(offsetof(Actor, processManager) == 0xF0); static_assert(offsetof(Actor, flags1) == 0xE0); diff --git a/Code/client/Games/Skyrim/Forms/MagicItem.h b/Code/client/Games/Skyrim/Forms/MagicItem.h index 0d1448458..ce528a0ed 100644 --- a/Code/client/Games/Skyrim/Forms/MagicItem.h +++ b/Code/client/Games/Skyrim/Forms/MagicItem.h @@ -2,11 +2,10 @@ #include +#include #include #include -struct EffectSetting; - struct MagicItem : TESBoundObject { TESFullName fullName; diff --git a/Code/client/Games/Skyrim/Misc/MagicTarget.cpp b/Code/client/Games/Skyrim/Misc/MagicTarget.cpp index ef0c7a13d..93ebbe6dc 100644 --- a/Code/client/Games/Skyrim/Misc/MagicTarget.cpp +++ b/Code/client/Games/Skyrim/Misc/MagicTarget.cpp @@ -2,6 +2,10 @@ #include #include +#include +#include + +#include TP_THIS_FUNCTION(TAddTarget, bool, MagicTarget, MagicTarget::AddTargetData& arData); TP_THIS_FUNCTION(TCheckAddEffect, bool, MagicTarget::AddTargetData, void* arArgs, float afResistance); @@ -19,8 +23,27 @@ bool MagicTarget::AddTarget(AddTargetData& arData) noexcept return result; } +// TODO: don't send continuous, value modifying effects like burning from flames concentration spell +// can't cancel all ValueModifierEffects though bool TP_MAKE_THISCALL(HookAddTarget, MagicTarget, MagicTarget::AddTargetData& arData) { + // TODO: barf + Actor* pTargetActor = (Actor*)((char*)apThis - 0x98); + ActorExtension* pTargetActorEx = pTargetActor->GetExtension(); + + auto factions = pTargetActor->GetFactions(); + for (const auto& faction : factions.NpcFactions) + { + if (faction.Id.BaseId == 0x00000DB1) + { + if (pTargetActorEx->IsRemote()) + return false; + + World::Get().GetRunner().Trigger(AddTargetEvent(pTargetActor->formID, arData.pSpell->formID)); + return ThisCall(RealAddTarget, apThis, arData); + } + } + if (arData.pCaster) { if (auto pExtension = arData.pCaster->GetExtension()) @@ -30,6 +53,7 @@ bool TP_MAKE_THISCALL(HookAddTarget, MagicTarget, MagicTarget::AddTargetData& ar } } + World::Get().GetRunner().Trigger(AddTargetEvent(pTargetActor->formID, arData.pSpell->formID)); return ThisCall(RealAddTarget, apThis, arData); } diff --git a/Code/client/Games/Skyrim/Misc/MagicTarget.h b/Code/client/Games/Skyrim/Misc/MagicTarget.h index b6f8a4ad1..9c0462431 100644 --- a/Code/client/Games/Skyrim/Misc/MagicTarget.h +++ b/Code/client/Games/Skyrim/Misc/MagicTarget.h @@ -2,9 +2,9 @@ #include -struct EffectSetting; struct Actor; struct MagicItem; +struct EffectSetting; struct TESBoundObject; struct MagicTarget diff --git a/Code/client/Services/Generic/TestService.cpp b/Code/client/Services/Generic/TestService.cpp index 938059784..c3c4d96dc 100644 --- a/Code/client/Services/Generic/TestService.cpp +++ b/Code/client/Services/Generic/TestService.cpp @@ -670,18 +670,22 @@ void TestService::OnDraw() noexcept { MagicTarget::AddTargetData data{}; - data.pCaster = PlayerCharacter::Get(); + //data.pCaster = PlayerCharacter::Get(); data.pSpell = pEffectSpell; data.pEffectSetting = effect; data.pSource = nullptr; + /* data.ExplosionLocation.x = -11891.820f; data.ExplosionLocation.y = -56157.960f; data.ExplosionLocation.z = 665.110f; + */ data.fMagnitude = 0.0f; data.fUnkFloat1 = 1.0f; - data.eCastingSource = MagicSystem::CastingSource::RIGHT_HAND; + data.eCastingSource = MagicSystem::CastingSource::CASTING_SOURCE_COUNT; + /* data.bAreaTarget = true; data.bDualCast = false; + */ pFetchActor->magicTarget.AddTarget(data); }