diff --git a/Code/client/Games/Skyrim/Actor.cpp b/Code/client/Games/Skyrim/Actor.cpp index fd9315f01..931c2bdf1 100644 --- a/Code/client/Games/Skyrim/Actor.cpp +++ b/Code/client/Games/Skyrim/Actor.cpp @@ -875,16 +875,16 @@ extern thread_local bool g_forceAnimation; void Actor::FixVampireLordModel() noexcept { - TESBoundObject* pObject = Cast(TESForm::GetById(0x2011a84)); - if (!pObject) + TESBoundObject* pLordArmor = Cast(TESForm::GetById(0x2011a84)); + if (!pLordArmor) return; { ScopedInventoryOverride _; - AddObjectToContainer(pObject, nullptr, 1, nullptr); + AddObjectToContainer(pLordArmor, nullptr, 1, nullptr); } - EquipManager::Get()->Equip(this, pObject, nullptr, 1, nullptr, false, true, false, false); + EquipManager::Get()->Equip(this, pLordArmor, nullptr, 1, nullptr, false, true, false, false); g_forceAnimation = true; diff --git a/Code/server/Game/Animation/ActionReplayCache.cpp b/Code/server/Game/Animation/ActionReplayCache.cpp index 091f88be9..85b8a4cb9 100644 --- a/Code/server/Game/Animation/ActionReplayCache.cpp +++ b/Code/server/Game/Animation/ActionReplayCache.cpp @@ -94,3 +94,8 @@ std::optional ActionReplayCache::FindInstantCounterpartForActi } return std::nullopt; } + +void ActionReplayCache::Clear() noexcept +{ + m_actions.clear(); +} diff --git a/Code/server/Game/Animation/ActionReplayCache.h b/Code/server/Game/Animation/ActionReplayCache.h index d12bd5f6d..53e01dc93 100644 --- a/Code/server/Game/Animation/ActionReplayCache.h +++ b/Code/server/Game/Animation/ActionReplayCache.h @@ -25,6 +25,8 @@ class ActionReplayCache const Vector& GetActions() const noexcept { return m_actions; }; + void Clear() noexcept; + private: // Returns true if clients should reset the animation graph of the Actor before replaying bool RefineReplayCache() noexcept; diff --git a/Code/server/Game/Animation/AnimationEventLists.cpp b/Code/server/Game/Animation/AnimationEventLists.cpp index c16b3dc10..57e367058 100644 --- a/Code/server/Game/Animation/AnimationEventLists.cpp +++ b/Code/server/Game/Animation/AnimationEventLists.cpp @@ -177,6 +177,8 @@ const Set AnimationEventLists::kIgnore = { {"idleChairVar2"}, {"idleChairArmsCrossedVar1"}, {"idleChairArmsCrossedVar2"}, + // See `Actor::FixVampireLordModel` + {"LevitationToggle"}, // Weapon drawing is handled separately in CharacterService {"WeapEquip"}, {"WeapSoloEquip"}, diff --git a/Code/server/Services/CharacterService.cpp b/Code/server/Services/CharacterService.cpp index 80d098b2c..9ec33d9ad 100644 --- a/Code/server/Services/CharacterService.cpp +++ b/Code/server/Services/CharacterService.cpp @@ -497,6 +497,10 @@ void CharacterService::OnRequestRespawn(const PacketEvent& acMes } auto& ownerComponent = view.get(*it); + + // Replay cache needs to be cleared when a character respawns + m_world.try_get(*it)->ActionsReplayCache.Clear(); + if (ownerComponent.GetOwner() == acMessage.pPlayer) { if (!acMessage.Packet.AppearanceBuffer.empty())