diff --git a/Client/mods/deathmatch/logic/CClientPed.h b/Client/mods/deathmatch/logic/CClientPed.h index 7d87e1a193..65df08efff 100644 --- a/Client/mods/deathmatch/logic/CClientPed.h +++ b/Client/mods/deathmatch/logic/CClientPed.h @@ -552,8 +552,9 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule std::unique_ptr GetAnimAssociation(CAnimBlendHierarchySAInterface* pHierarchyInterface); - void SetHasSyncedAnim(bool synced) noexcept { m_hasSyncedAnim = synced; }; - bool HasSyncedAnim() const noexcept { return m_hasSyncedAnim; }; + void SetHasSyncedAnim(bool synced) noexcept { m_hasSyncedAnim = synced; } + bool HasSyncedAnim() const noexcept { return m_hasSyncedAnim; } + protected: // This constructor is for peds managed by a player. These are unknown to the ped manager. CClientPed(CClientManager* pManager, unsigned long ulModelID, ElementID ID, bool bIsLocalPlayer); @@ -792,6 +793,6 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule std::shared_ptr m_clientModel; - bool m_hasSyncedAnim; - bool m_animationOverridedByClient; + bool m_hasSyncedAnim{}; + bool m_animationOverridedByClient{}; }; diff --git a/Server/mods/deathmatch/logic/CPed.h b/Server/mods/deathmatch/logic/CPed.h index c4de0bf11c..daa5c8e0c0 100644 --- a/Server/mods/deathmatch/logic/CPed.h +++ b/Server/mods/deathmatch/logic/CPed.h @@ -105,8 +105,8 @@ enum eBone struct SPlayerAnimData { - std::string blockName; - std::string animName; + std::string blockName{}; + std::string animName{}; int time{-1}; bool loop{true}; bool updatePosition{true}; @@ -120,22 +120,7 @@ struct SPlayerAnimData float progress{0.0f}; float speed{1.0f}; - SPlayerAnimData() = default; - - SPlayerAnimData(const std::string& block, const std::string& anim, int time, bool loop, bool updatePos, bool interrupt, bool freeze, int blend, - bool taskRestore, std::int64_t tick) - : blockName(block), - animName(anim), - time(time), - loop(loop), - updatePosition(updatePos), - interruptable(interrupt), - freezeLastFrame(freeze), - blendTime(blend), - taskToBeRestoredOnAnimEnd(taskRestore), - startedTick(tick), - progress(0.0f), - speed(1.0f){}; + bool IsAnimating() const noexcept { return !blockName.empty() && !animName.empty(); } }; class CWeapon @@ -356,7 +341,7 @@ class CPed : public CElement bool m_bFrozen; bool m_bStealthAiming; CVehicle* m_pJackingVehicle; - SPlayerAnimData m_animData; + SPlayerAnimData m_animData{}; CVehicle* m_pVehicle; unsigned int m_uiVehicleSeat; diff --git a/Server/mods/deathmatch/logic/CPedSync.cpp b/Server/mods/deathmatch/logic/CPedSync.cpp index b9936afb89..f911ab027c 100644 --- a/Server/mods/deathmatch/logic/CPedSync.cpp +++ b/Server/mods/deathmatch/logic/CPedSync.cpp @@ -82,9 +82,20 @@ void CPedSync::OverrideSyncer(CPed* pPed, CPlayer* pPlayer, bool bPersist) void CPedSync::UpdateAllSyncer() { + auto currentTick = GetTickCount64_(); + // Update all the ped's sync states for (auto iter = m_pPedManager->IterBegin(); iter != m_pPedManager->IterEnd(); iter++) { + // Has the duration of the ped's animation already elapsed? + const SPlayerAnimData& animData = (*iter)->GetAnimationData(); + if (animData.IsAnimating()) + { + float deltaTime = currentTick - animData.startedTick; + if (!animData.freezeLastFrame && animData.time > 0 && deltaTime >= animData.time) + (*iter)->SetAnimationData({}); + } + // It is a ped, yet not a player if (IS_PED(*iter) && !IS_PLAYER(*iter)) UpdateSyncer(*iter); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index dd2467da6b..b2db8fe9e8 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -4366,7 +4366,7 @@ bool CStaticFunctionDefinitions::SetPedAnimation(CElement* pElement, const SStri pPed->SetChoking(false); // Store anim data - pPed->SetAnimationData({blockName, animName, iTime, bLoop, bUpdatePosition, bInterruptable, bFreezeLastFrame, iBlend, bTaskToBeRestoredOnAnimEnd, GetTickCount64_()}); + pPed->SetAnimationData(SPlayerAnimData{blockName, animName, iTime, bLoop, bUpdatePosition, bInterruptable, bFreezeLastFrame, iBlend, bTaskToBeRestoredOnAnimEnd, GetTickCount64_()}); BitStream.pBitStream->WriteString(blockName); BitStream.pBitStream->WriteString(animName); diff --git a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp index a8a036ff6f..6a77404f59 100644 --- a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp @@ -983,16 +983,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const const SPlayerAnimData& animData = pPed->GetAnimationData(); // Contains animation data? - bool animRunning = !animData.blockName.empty() && !animData.animName.empty(); - - // Is animation still running? - float deltaTime = GetTickCount64_() - animData.startedTick; - if (!animData.freezeLastFrame && animData.time > 0 && deltaTime >= animData.time) - { - animRunning = false; - pPed->SetAnimationData({}); - } - + bool animRunning = animData.IsAnimating(); BitStream.WriteBit(animRunning); if (animRunning) @@ -1008,6 +999,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteBit(animData.taskToBeRestoredOnAnimEnd); // Write progress & speed + float deltaTime = GetTickCount64_() - animData.startedTick; BitStream.Write((deltaTime / animData.time) * animData.speed); BitStream.Write(animData.speed); } diff --git a/Shared/sdk/net/bitstream.h b/Shared/sdk/net/bitstream.h index 0538d59972..aa442ba1b6 100644 --- a/Shared/sdk/net/bitstream.h +++ b/Shared/sdk/net/bitstream.h @@ -556,10 +556,6 @@ enum class eBitStreamVersion : unsigned short // 2024-06-16 PedSync_Revision, - // Ped animations synchronization - // 2024-06-29 - AnimationsSync, - // Add "extendedwatercannons" to setWorldSpecialPropertyEnabled // 2024-06-30 WorldSpecialProperty_TunnelWeatherBlend, @@ -596,6 +592,10 @@ enum class eBitStreamVersion : unsigned short // 2024-30-12 SetElementOnFire, + // Ped animations synchronization + // 2025-01-01 + AnimationsSync, + // This allows us to automatically increment the BitStreamVersion when things are added to this enum. // Make sure you only add things above this comment. Next,