From 46715169a9e44d91532521ff83f5b374dd555155 Mon Sep 17 00:00:00 2001 From: Robbe Bryssinck Date: Fri, 24 May 2024 22:07:10 +0200 Subject: [PATCH] fix: spell damage --- Code/client/Events/AddTargetEvent.h | 1 + Code/client/Games/Skyrim/Effects/ActiveEffect.h | 4 +++- Code/client/Games/Skyrim/Magic/MagicTarget.cpp | 1 + .../client/Games/Skyrim/Projectiles/Projectile.h | 6 +++++- Code/client/Services/Generic/MagicService.cpp | 16 ++++++++++++++++ Code/encoding/Messages/AddTargetRequest.cpp | 2 ++ Code/encoding/Messages/AddTargetRequest.h | 3 ++- Code/encoding/Messages/NotifyAddTarget.cpp | 2 ++ Code/encoding/Messages/NotifyAddTarget.h | 3 ++- Code/server/Services/MagicService.cpp | 1 + 10 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Code/client/Events/AddTargetEvent.h b/Code/client/Events/AddTargetEvent.h index f0cd2477f..fc7baf831 100644 --- a/Code/client/Events/AddTargetEvent.h +++ b/Code/client/Events/AddTargetEvent.h @@ -8,6 +8,7 @@ struct AddTargetEvent AddTargetEvent() = default; uint32_t TargetID{}; + uint32_t CasterID{}; uint32_t SpellID{}; uint32_t EffectID{}; float Magnitude{}; diff --git a/Code/client/Games/Skyrim/Effects/ActiveEffect.h b/Code/client/Games/Skyrim/Effects/ActiveEffect.h index 8582f1980..3852b0991 100644 --- a/Code/client/Games/Skyrim/Effects/ActiveEffect.h +++ b/Code/client/Games/Skyrim/Effects/ActiveEffect.h @@ -40,7 +40,9 @@ struct ActiveEffect static ActiveEffect* Instantiate(Actor* apCaster, MagicItem* apSpell, EffectItem* apEffect); - uint8_t pad8[0x38]; + uint8_t pad8[0x34 - 0x8]; + uint32_t hCaster; + NiNode* pSourceNode; MagicItem* pSpell; void* pEffect; MagicTarget* pTarget; diff --git a/Code/client/Games/Skyrim/Magic/MagicTarget.cpp b/Code/client/Games/Skyrim/Magic/MagicTarget.cpp index c6bae5c6e..c61ece6b1 100644 --- a/Code/client/Games/Skyrim/Magic/MagicTarget.cpp +++ b/Code/client/Games/Skyrim/Magic/MagicTarget.cpp @@ -91,6 +91,7 @@ bool TP_MAKE_THISCALL(HookAddTarget, MagicTarget, MagicTarget::AddTargetData& ar AddTargetEvent addTargetEvent{}; addTargetEvent.TargetID = pTargetActor->formID; + addTargetEvent.CasterID = arData.pCaster ? arData.pCaster->formID : 0; addTargetEvent.SpellID = arData.pSpell->formID; addTargetEvent.EffectID = arData.pEffectItem->pEffectSetting->formID; addTargetEvent.Magnitude = arData.fMagnitude; diff --git a/Code/client/Games/Skyrim/Projectiles/Projectile.h b/Code/client/Games/Skyrim/Projectiles/Projectile.h index 56cf43e7a..50eda2e6b 100644 --- a/Code/client/Games/Skyrim/Projectiles/Projectile.h +++ b/Code/client/Games/Skyrim/Projectiles/Projectile.h @@ -49,7 +49,10 @@ struct Projectile : TESObjectREFR bool bForceConeOfFire; // unsure // usually false }; - uint8_t unk98[0xF0]; + uint8_t unkA0[0x120 - sizeof(TESObjectREFR)]; + void* pActorCause; + uint32_t hShooter; + uint8_t unk[0x190 - 0x12C]; float fPower; float fSpeedMult; float fRange; @@ -60,3 +63,4 @@ struct Projectile : TESObjectREFR }; static_assert(sizeof(Projectile::LaunchData) == 0xA8); +static_assert(offsetof(Projectile, fPower) == 0x190); diff --git a/Code/client/Services/Generic/MagicService.cpp b/Code/client/Services/Generic/MagicService.cpp index 5dd7d5b6f..26eefb476 100644 --- a/Code/client/Services/Generic/MagicService.cpp +++ b/Code/client/Services/Generic/MagicService.cpp @@ -339,6 +339,20 @@ void MagicService::OnAddTargetEvent(const AddTargetEvent& acEvent) noexcept } request.TargetId = serverIdRes.value(); + + const auto casterIt = std::find_if(std::begin(view), std::end(view), [id = acEvent.CasterID, view](auto entity) { return view.get(entity).Id == id; }); + + if (casterIt == std::end(view)) + { + spdlog::warn("Form id not found for magic add target, form id: {:X}", acEvent.CasterID); + m_queuedEffects[acEvent.TargetID] = request; + return; + } + + serverIdRes = Utils::GetServerId(*casterIt); + if (serverIdRes.has_value()) + request.CasterId = serverIdRes.value(); + request.IsDualCasting = acEvent.IsDualCasting; request.ApplyHealPerkBonus = acEvent.ApplyHealPerkBonus; request.ApplyStaminaPerkBonus = acEvent.ApplyStaminaPerkBonus; @@ -411,6 +425,8 @@ void MagicService::OnNotifyAddTarget(const NotifyAddTarget& acMessage) noexcept if (pEffect->IsSlowEffect()) pActor = PlayerCharacter::Get(); + data.pCaster = Utils::GetByServerId(acMessage.CasterId); + pActor->magicTarget.AddTarget(data, acMessage.ApplyHealPerkBonus, acMessage.ApplyStaminaPerkBonus); spdlog::debug("Applied remote magic effect"); diff --git a/Code/encoding/Messages/AddTargetRequest.cpp b/Code/encoding/Messages/AddTargetRequest.cpp index 306283b47..7bf413fa0 100644 --- a/Code/encoding/Messages/AddTargetRequest.cpp +++ b/Code/encoding/Messages/AddTargetRequest.cpp @@ -3,6 +3,7 @@ void AddTargetRequest::SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept { Serialization::WriteVarInt(aWriter, TargetId); + Serialization::WriteVarInt(aWriter, CasterId); SpellId.Serialize(aWriter); EffectId.Serialize(aWriter); Serialization::WriteFloat(aWriter, Magnitude); @@ -16,6 +17,7 @@ void AddTargetRequest::DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) no ClientMessage::DeserializeRaw(aReader); TargetId = Serialization::ReadVarInt(aReader) & 0xFFFFFFFF; + CasterId = Serialization::ReadVarInt(aReader) & 0xFFFFFFFF; SpellId.Deserialize(aReader); EffectId.Deserialize(aReader); Magnitude = Serialization::ReadFloat(aReader); diff --git a/Code/encoding/Messages/AddTargetRequest.h b/Code/encoding/Messages/AddTargetRequest.h index 7ce3ad7b1..72bddd348 100644 --- a/Code/encoding/Messages/AddTargetRequest.h +++ b/Code/encoding/Messages/AddTargetRequest.h @@ -17,12 +17,13 @@ struct AddTargetRequest final : ClientMessage bool operator==(const AddTargetRequest& acRhs) const noexcept { - return GetOpcode() == acRhs.GetOpcode() && TargetId == acRhs.TargetId && SpellId == acRhs.SpellId && + return GetOpcode() == acRhs.GetOpcode() && TargetId == acRhs.TargetId && CasterId == acRhs.CasterId && SpellId == acRhs.SpellId && EffectId == acRhs.EffectId && Magnitude == acRhs.Magnitude && IsDualCasting == acRhs.IsDualCasting && ApplyHealPerkBonus == acRhs.ApplyHealPerkBonus && ApplyStaminaPerkBonus == acRhs.ApplyStaminaPerkBonus; } uint32_t TargetId{}; + uint32_t CasterId{}; GameId SpellId{}; GameId EffectId{}; float Magnitude{}; diff --git a/Code/encoding/Messages/NotifyAddTarget.cpp b/Code/encoding/Messages/NotifyAddTarget.cpp index 798aa3cf2..0d2041deb 100644 --- a/Code/encoding/Messages/NotifyAddTarget.cpp +++ b/Code/encoding/Messages/NotifyAddTarget.cpp @@ -3,6 +3,7 @@ void NotifyAddTarget::SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept { Serialization::WriteVarInt(aWriter, TargetId); + Serialization::WriteVarInt(aWriter, CasterId); SpellId.Serialize(aWriter); EffectId.Serialize(aWriter); Serialization::WriteFloat(aWriter, Magnitude); @@ -16,6 +17,7 @@ void NotifyAddTarget::DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noe ServerMessage::DeserializeRaw(aReader); TargetId = Serialization::ReadVarInt(aReader) & 0xFFFFFFFF; + CasterId = Serialization::ReadVarInt(aReader) & 0xFFFFFFFF; SpellId.Deserialize(aReader); EffectId.Deserialize(aReader); Magnitude = Serialization::ReadFloat(aReader); diff --git a/Code/encoding/Messages/NotifyAddTarget.h b/Code/encoding/Messages/NotifyAddTarget.h index 2efe2a915..1cf02c843 100644 --- a/Code/encoding/Messages/NotifyAddTarget.h +++ b/Code/encoding/Messages/NotifyAddTarget.h @@ -17,12 +17,13 @@ struct NotifyAddTarget final : ServerMessage bool operator==(const NotifyAddTarget& acRhs) const noexcept { - return GetOpcode() == acRhs.GetOpcode() && TargetId == acRhs.TargetId && SpellId == acRhs.SpellId && + return GetOpcode() == acRhs.GetOpcode() && TargetId == acRhs.TargetId && CasterId == acRhs.CasterId && SpellId == acRhs.SpellId && EffectId == acRhs.EffectId && Magnitude == acRhs.Magnitude && IsDualCasting == acRhs.IsDualCasting && ApplyHealPerkBonus == acRhs.ApplyHealPerkBonus && ApplyStaminaPerkBonus == acRhs.ApplyStaminaPerkBonus; } uint32_t TargetId{}; + uint32_t CasterId{}; GameId SpellId{}; GameId EffectId{}; float Magnitude{}; diff --git a/Code/server/Services/MagicService.cpp b/Code/server/Services/MagicService.cpp index 33d5f4ed7..435b9aa59 100644 --- a/Code/server/Services/MagicService.cpp +++ b/Code/server/Services/MagicService.cpp @@ -54,6 +54,7 @@ void MagicService::OnAddTargetRequest(const PacketEvent& acMes NotifyAddTarget notify; notify.TargetId = message.TargetId; + notify.CasterId = message.CasterId; notify.SpellId = message.SpellId; notify.EffectId = message.EffectId; notify.Magnitude = message.Magnitude;