From 630b60eb0dcd3d9ce41582664ab822b049365431 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 25 May 2022 22:14:32 +0200 Subject: Core/GameObjects: Transport (type 11) improvements * Fully synchronize serverside animation progress with client * Implemented updating passenger positions on elevators * Removed visibility hack for elevators that always forced CreateObject packet to be sent to client --- src/server/game/Entities/Object/Object.cpp | 48 +++++----------------- src/server/game/Entities/Object/Object.h | 10 ++--- .../game/Entities/Object/Updates/UpdateFields.cpp | 8 ++-- .../game/Entities/Object/Updates/UpdateFields.h | 2 - .../Object/Updates/ViewerDependentValues.h | 43 ++++--------------- 5 files changed, 28 insertions(+), 83 deletions(-) (limited to 'src/server/game/Entities/Object') diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index fef22d2af9a..5734afb9f3b 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -263,15 +263,8 @@ void Object::SendOutOfRangeForPlayer(Player* target) const void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Player* target) const { std::vector const* PauseTimes = nullptr; - uint32 PauseTimesCount = 0; if (GameObject const* go = ToGameObject()) - { - if (go->GetGoType() == GAMEOBJECT_TYPE_TRANSPORT) - { - PauseTimes = go->GetGOValue()->Transport.StopFrames; - PauseTimesCount = PauseTimes->size(); - } - } + PauseTimes = go->GetPauseTimes(); data->WriteBit(flags.NoBirthAnim); data->WriteBit(flags.EnablePortals); @@ -384,7 +377,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe WorldPackets::Movement::CommonMovement::WriteCreateObjectSplineDataBlock(*unit->movespline, *data); } - *data << uint32(PauseTimesCount); + *data << uint32(PauseTimes ? PauseTimes->size() : 0); if (flags.Stationary) { @@ -399,18 +392,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe *data << ToUnit()->GetVictim()->GetGUID(); // CombatVictim if (flags.ServerTime) - { - GameObject const* go = ToGameObject(); - /** @TODO Use IsTransport() to also handle type 11 (TRANSPORT) - Currently grid objects are not updated if there are no nearby players, - this causes clients to receive different PathProgress - resulting in players seeing the object in a different position - */ - if (go && go->ToTransport()) // ServerTime - *data << uint32(go->GetGOValue()->Transport.PathProgress); - else - *data << uint32(GameTime::GetGameTimeMS()); - } + *data << uint32(GameTime::GetGameTimeMS()); if (flags.Vehicle) { @@ -430,7 +412,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe if (flags.Rotation) *data << uint64(ToGameObject()->GetPackedLocalRotation()); // Rotation - if (PauseTimesCount) + if (PauseTimes && !PauseTimes->empty()) data->append(PauseTimes->data(), PauseTimes->size()); if (flags.MovementTransport) @@ -885,19 +867,9 @@ void WorldObject::setActive(bool on) return; if (on) - { - if (GetTypeId() == TYPEID_UNIT) - map->AddToActive(ToCreature()); - else if (GetTypeId() == TYPEID_DYNAMICOBJECT) - map->AddToActive((DynamicObject*)this); - } + map->AddToActive(this); else - { - if (GetTypeId() == TYPEID_UNIT) - map->RemoveFromActive(ToCreature()); - else if (GetTypeId() == TYPEID_DYNAMICOBJECT) - map->RemoveFromActive((DynamicObject*)this); - } + map->RemoveFromActive(this); } void WorldObject::SetVisibilityDistanceOverride(VisibilityDistanceType type) @@ -922,7 +894,7 @@ void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/) if (IsInWorld()) RemoveFromWorld(); - if (Transport* transport = GetTransport()) + if (TransportBase* transport = GetTransport()) transport->RemovePassenger(this); } @@ -999,7 +971,7 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool Position const* thisOrTransport = this; Position const* objOrObjTransport = obj; - if (GetTransport() && obj->GetTransport() && obj->GetTransport()->GetGUID() == GetTransport()->GetGUID()) + if (GetTransport() && obj->GetTransport() && obj->GetTransport()->GetTransportGUID() == GetTransport()->GetTransportGUID()) { thisOrTransport = &m_movementInfo.transport.pos; objOrObjTransport = &obj->m_movementInfo.transport.pos; @@ -1843,7 +1815,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert return nullptr; } - Transport* transport = summoner ? summoner->GetTransport() : nullptr; + TransportBase* transport = summoner ? summoner->GetTransport() : nullptr; if (transport) { float x, y, z, o; @@ -3606,7 +3578,7 @@ void WorldObject::RemoveFromObjectUpdate() ObjectGuid WorldObject::GetTransGUID() const { if (GetTransport()) - return GetTransport()->GetGUID(); + return GetTransport()->GetTransportGUID(); return ObjectGuid::Empty; } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index db57584c76a..acc4f688fe4 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -54,7 +54,7 @@ class SpellCastTargets; class SpellEffectInfo; class SpellInfo; class TempSummon; -class Transport; +class TransportBase; class Unit; class UpdateData; class WorldObject; @@ -676,7 +676,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation uint32 LastUsedScriptID; // Transports - Transport* GetTransport() const { return m_transport; } + TransportBase* GetTransport() const { return m_transport; } float GetTransOffsetX() const { return m_movementInfo.transport.pos.GetPositionX(); } float GetTransOffsetY() const { return m_movementInfo.transport.pos.GetPositionY(); } float GetTransOffsetZ() const { return m_movementInfo.transport.pos.GetPositionZ(); } @@ -685,7 +685,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation uint32 GetTransTime() const { return m_movementInfo.transport.time; } int8 GetTransSeat() const { return m_movementInfo.transport.seat; } virtual ObjectGuid GetTransGUID() const; - void SetTransport(Transport* t) { m_transport = t; } + void SetTransport(TransportBase* t) { m_transport = t; } MovementInfo m_movementInfo; @@ -728,8 +728,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation bool const m_isWorldObject; ZoneScript* m_zoneScript; - // transports - Transport* m_transport; + // transports (gameobjects only) + TransportBase* m_transport; virtual void ProcessPositionDataChanged(PositionFullTerrainStatus const& data); uint32 m_zoneId; diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index 82a1ca81712..591aeb657ac 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -4264,13 +4264,13 @@ void GameObjectData::WriteCreate(ByteBuffer& data, EnumFlag fie data << float(ParentRotation->z); data << float(ParentRotation->w); data << int32(FactionTemplate); - data << int8(ViewerDependentValue::GetValue(this, owner, receiver)); + data << int8(State); data << int8(TypeID); data << uint8(PercentHealth); data << uint32(ArtKit); data << uint32(EnableDoodadSets.size()); data << uint32(CustomParam); - data << int32(ViewerDependentValue::GetValue(this, owner, receiver)); + data << int32(Level); data << uint32(AnimGroupInstance); for (uint32 i = 0; i < EnableDoodadSets.size(); ++i) { @@ -4371,7 +4371,7 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool } if (changesMask[14]) { - data << int8(ViewerDependentValue::GetValue(this, owner, receiver)); + data << int8(State); } if (changesMask[15]) { @@ -4391,7 +4391,7 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool } if (changesMask[19]) { - data << int32(ViewerDependentValue::GetValue(this, owner, receiver)); + data << int32(Level); } if (changesMask[20]) { diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index a9967827f7a..e3cfb83fa40 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -804,13 +804,11 @@ struct GameObjectData : public IsUpdateFieldStructureTag, public HasChangesMask< UpdateField ParentRotation; UpdateField FactionTemplate; UpdateField State; - struct StateTag : ViewerDependentValueTag {}; UpdateField TypeID; UpdateField PercentHealth; UpdateField ArtKit; UpdateField CustomParam; UpdateField Level; - struct LevelTag : ViewerDependentValueTag {}; UpdateField AnimGroupInstance; void WriteCreate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const; diff --git a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h index 6d8ee14d100..755006262bd 100644 --- a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h +++ b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h @@ -26,6 +26,7 @@ #include "Player.h" #include "SpellInfo.h" #include "SpellMgr.h" +#include "Transport.h" #include "World.h" #include "WorldSession.h" @@ -85,11 +86,17 @@ public: dynFlags |= GO_DYNFLAG_LO_SPARKLE | GO_DYNFLAG_LO_HIGHLIGHT; break; case GAMEOBJECT_TYPE_TRANSPORT: + { + dynFlags = dynamicFlags & 0xFFFF; + pathProgress = dynamicFlags >> 16; + break; + } case GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT: { - if (uint32 transportPeriod = gameObject->GetTransportPeriod()) + Transport const* transport = gameObject->ToTransport(); + if (uint32 transportPeriod = transport->GetTransportPeriod()) { - float timer = float(gameObject->GetGOValue()->Transport.PathProgress % transportPeriod); + float timer = float(transport->GetTimer() % transportPeriod); pathProgress = uint16(timer / float(transportPeriod) * 65535.0f); } break; @@ -256,38 +263,6 @@ public: } }; -template<> -class ViewerDependentValue -{ -public: - using value_type = UF::GameObjectData::LevelTag::value_type; - - static value_type GetValue(UF::GameObjectData const* gameObjectData, GameObject const* gameObject, Player const* /*receiver*/) - { - value_type level = gameObjectData->Level; - bool isStoppableTransport = gameObject->GetGoType() == GAMEOBJECT_TYPE_TRANSPORT && !gameObject->GetGOValue()->Transport.StopFrames->empty(); - return isStoppableTransport ? gameObject->GetGOValue()->Transport.PathProgress : level; - } -}; - -template<> -class ViewerDependentValue -{ -public: - using value_type = UF::GameObjectData::StateTag::value_type; - - static value_type GetValue(UF::GameObjectData const* gameObjectData, GameObject const* gameObject, Player const* /*receiver*/) - { - value_type state = gameObjectData->State; - bool isStoppableTransport = gameObject->GetGoType() == GAMEOBJECT_TYPE_TRANSPORT && !gameObject->GetGOValue()->Transport.StopFrames->empty(); - if (isStoppableTransport && gameObject->GetGoState() == GO_STATE_TRANSPORT_ACTIVE) - if ((gameObject->GetGOValue()->Transport.StateUpdateTimer / 20000) & 1) - state = GO_STATE_TRANSPORT_STOPPED; - - return state; - } -}; - template<> class ViewerDependentValue { -- cgit v1.2.3