diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MoveSplineInit.cpp | 32 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MovementPacketBuilder.cpp | 160 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MovementPacketBuilder.h | 3 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MovementTypedefs.h | 8 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.cpp | 311 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.h | 92 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 26 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.h | 2 |
9 files changed, 415 insertions, 241 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 25179c7b62c..dac142f4044 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -63,6 +63,7 @@ #include "MovementStructures.h" #include "WorldSession.h" #include "ChatPackets.h" +#include "MovementPackets.h" #include <cmath> @@ -10793,11 +10794,22 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) pet->SetSpeed(mtype, m_speed_rate[mtype], forced); } - static MovementStatusElements const speedVal = MSEExtraFloat; - Movement::ExtraMovementStatusElement extra(&speedVal); - extra.Data.floatData = GetSpeed(mtype); - - Movement::PacketSender(this, moveTypeToOpcode[mtype][0], moveTypeToOpcode[mtype][1], moveTypeToOpcode[mtype][2], &extra).Send(); + if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER) + { + /// @todo fix SMSG_MOVE_SET packets (were they removed?) + //_selfOpcode = playerControl; + WorldPackets::Movement::MoveUpdate packet(moveTypeToOpcode[mtype][2]); + packet.movementInfo = m_movementInfo; + packet.Speed = rate; + SendMessageToSet(packet.Write(), false); + } + else + { + WorldPackets::Movement::MoveSplineSet packet(moveTypeToOpcode[mtype][0]); + packet.MoverGUID = GetGUID(); + packet.Speed = rate; + SendMessageToSet(packet.Write(), true); + } } void Unit::setDeathState(DeathState s) diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 749b6be4ee5..560f40143bb 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -24,6 +24,7 @@ #include "Vehicle.h" #include "WorldPacket.h" #include "Opcodes.h" +#include "MovementPackets.h" namespace Movement { @@ -115,17 +116,11 @@ namespace Movement unit->m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); - WorldPacket data(SMSG_MONSTER_MOVE, 64); - data << unit->GetPackGUID(); - if (!unit->GetTransGUID().IsEmpty()) - { - data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - data << unit->GetTransGUID().WriteAsPacked(); - data << int8(unit->GetTransSeat()); - } - - PacketBuilder::WriteMonsterMove(move_spline, data); - unit->SendMessageToSet(&data, true); + WorldPackets::Movement::MonsterMove packet; + packet.MoverGUID = unit->GetGUID(); + packet.Pos = real_position; + PacketBuilder::WriteMonsterMove(move_spline, packet.SplineData); + unit->SendMessageToSet(packet.Write(), true); return move_spline.Duration(); } @@ -161,17 +156,18 @@ namespace Movement move_spline.onTransport = transport; move_spline.Initialize(args); - WorldPacket data(SMSG_MONSTER_MOVE, 64); - data << unit->GetPackGUID(); + WorldPackets::Movement::MonsterMove packet; + packet.MoverGUID = unit->GetGUID(); + packet.Pos = loc; + packet.SplineData.ID = move_spline.GetId(); + if (transport) { - data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - data << unit->GetTransGUID().WriteAsPacked(); - data << int8(unit->GetTransSeat()); + packet.SplineData.Move.TransportGUID = unit->GetTransGUID(); + packet.SplineData.Move.VehicleSeat = unit->GetTransSeat(); } - PacketBuilder::WriteStopMovement(loc, args.splineId, data); - unit->SendMessageToSet(&data, true); + unit->SendMessageToSet(packet.Write(), true); } MoveSplineInit::MoveSplineInit(Unit* m) : unit(m) diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 02fdabb3938..2babbe65cbf 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -21,132 +21,98 @@ #include "MoveSpline.h" #include "WorldPacket.h" #include "Object.h" +#include "MovementPackets.h" namespace Movement { - inline void operator << (ByteBuffer& b, const Vector3& v) - { - b << v.x << v.y << v.z; - } - - inline void operator >> (ByteBuffer& b, Vector3& v) + void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data) { - b >> v.x >> v.y >> v.z; + /*data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40) + data << pos; + data << splineId; + data << uint8(MonsterMoveStop);*/ } - enum MonsterMoveType - { - MonsterMoveNormal = 0, - MonsterMoveStop = 1, - MonsterMoveFacingSpot = 2, - MonsterMoveFacingTarget = 3, - MonsterMoveFacingAngle = 4 - }; - - void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data) + void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline) { + movementMonsterSpline.ID = move_spline.m_Id; + WorldPackets::Movement::MovementSpline& movementSpline = movementMonsterSpline.Move; + MoveSplineFlag splineflags = move_spline.splineflags; - - data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40) - data << move_spline.spline.getPoint(move_spline.spline.first()); - data << move_spline.GetId(); - - switch (splineflags & MoveSplineFlag::Mask_Final_Facing) + splineflags.enter_cycle = move_spline.isCyclic(); + movementSpline.Flags = uint32(splineflags & uint32(~MoveSplineFlag::Mask_No_Monster_Move)); + + switch (move_spline.splineflags & MoveSplineFlag::Mask_Final_Facing) { + case MoveSplineFlag::Final_Point: + movementSpline.Face = MONSTER_MOVE_FACING_SPOT; + movementSpline.FaceSpot = move_spline.facing.f; + break; case MoveSplineFlag::Final_Target: - data << uint8(MonsterMoveFacingTarget); - data << move_spline.facing.target; + movementSpline.Face = MONSTER_MOVE_FACING_TARGET; + movementSpline.FaceGUID = move_spline.facing.target; break; case MoveSplineFlag::Final_Angle: - data << uint8(MonsterMoveFacingAngle); - data << move_spline.facing.angle; - break; - case MoveSplineFlag::Final_Point: - data << uint8(MonsterMoveFacingSpot); - data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z; + movementSpline.Face = MONSTER_MOVE_FACING_ANGLE; + movementSpline.FaceDirection = move_spline.facing.angle; break; default: - data << uint8(MonsterMoveNormal); + movementSpline.Face = MONSTER_MOVE_NORMAL; break; } - - // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done) - splineflags.enter_cycle = move_spline.isCyclic(); - data << uint32(splineflags & uint32(~MoveSplineFlag::Mask_No_Monster_Move)); - + if (splineflags.animation) { - data << splineflags.getAnimationId(); - data << move_spline.effect_start_time; + movementSpline.AnimTier = splineflags.getAnimationId(); + movementSpline.TierTransStartTime = move_spline.effect_start_time; } - - data << move_spline.Duration(); - + + movementSpline.MoveTime = move_spline.Duration(); + if (splineflags.parabolic) { - data << move_spline.vertical_acceleration; - data << move_spline.effect_start_time; + movementSpline.JumpGravity = move_spline.vertical_acceleration; + movementSpline.SpecialTime = move_spline.effect_start_time; } - } - - void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data) - { - data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40) - data << pos; - data << splineId; - data << uint8(MonsterMoveStop); - } - - void WriteLinearPath(Spline<int32> const& spline, ByteBuffer& data) - { - uint32 last_idx = spline.getPointCount() - 3; - Vector3 const* real_path = &spline.getPoint(1); - - data << last_idx; - data << real_path[last_idx]; // destination - if (last_idx > 1) - { - Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; - Vector3 offset; - // first and last points already appended - for (uint32 i = 1; i < last_idx; ++i) - { - offset = middle - real_path[i]; - data.appendPackXYZ(offset.x, offset.y, offset.z); - } - } - } - - void WriteUncompressedPath(Spline<int32> const& spline, ByteBuffer& data) - { - uint32 count = spline.getPointCount() - 3; - data << count; - data.append<Vector3>(&spline.getPoint(2), count); - } - - void WriteUncompressedCyclicPath(Spline<int32> const& spline, ByteBuffer& data) - { - uint32 count = spline.getPointCount() - 3; - data << uint32(count + 1); - data << spline.getPoint(1); // fake point, client will erase it from the spline after first cycle done - data.append<Vector3>(&spline.getPoint(1), count); - } - - void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data) - { - WriteCommonMonsterMovePart(move_spline, data); - + Spline<int32> const& spline = move_spline.spline; - MoveSplineFlag splineflags = move_spline.splineflags; + std::vector<Vector3> const& array = spline.getPoints(); + if (splineflags & MoveSplineFlag::UncompressedPath) { if (!splineflags.cyclic) - WriteUncompressedPath(spline, data); + { + uint32 count = spline.getPointCount() - 3; + for (uint32 i = 2; i < count; ++i) + movementSpline.Points.push_back(array[i]); + } else - WriteUncompressedCyclicPath(spline, data); + { + uint32 count = spline.getPointCount() - 3; + movementSpline.Points.push_back(array[1]); + for (uint32 i = 1; i < count; ++i) + movementSpline.Points.push_back(array[i]); + } } else - WriteLinearPath(spline, data); + { + uint32 last_idx = spline.getPointCount() - 3; + Vector3 const* real_path = &spline.getPoint(1); + + movementSpline.Points.push_back(real_path[last_idx]); + + if (last_idx > 1) + { + Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; + Vector3 offset; + // first and last points already appended + for (uint32 i = 1; i < last_idx; ++i) + { + offset = middle - real_path[i]; + movementSpline.PackedDeltas.push_back(offset); + } + } + } } void PacketBuilder::WriteCreate(MoveSpline const& moveSpline, ByteBuffer& data) diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h index 2878a330f67..83172b2c3e0 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.h +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h @@ -22,6 +22,7 @@ #include "Define.h" // for uint32 #include "G3D/Vector3.h" +#include "MovementPackets.h" using G3D::Vector3; class ByteBuffer; @@ -35,7 +36,7 @@ namespace Movement static void WriteCommonMonsterMovePart(const MoveSpline& mov, WorldPacket& data); public: - static void WriteMonsterMove(const MoveSpline& mov, WorldPacket& data); + static void WriteMonsterMove(const MoveSpline& mov, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline); static void WriteStopMovement(Vector3 const& loc, uint32 splineId, ByteBuffer& data); static void WriteCreate(MoveSpline const& moveSpline, ByteBuffer& data); }; diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h index a69af9e3a83..14c4e19b19b 100644 --- a/src/server/game/Movement/Spline/MovementTypedefs.h +++ b/src/server/game/Movement/Spline/MovementTypedefs.h @@ -21,6 +21,14 @@ #include "Common.h" +enum MonsterMoveType +{ + MONSTER_MOVE_NORMAL = 0, + MONSTER_MOVE_FACING_SPOT = 1, + MONSTER_MOVE_FACING_TARGET = 2, + MONSTER_MOVE_FACING_ANGLE = 3 +}; + namespace G3D { class Vector3; diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index de09acbd37a..010631c0529 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -16,166 +16,265 @@ */ #include "MovementPackets.h" +#include "MovementTypedefs.h" -void WorldPackets::Movement::ClientPlayerMovement::Read() +ByteBuffer& operator << (ByteBuffer& data, const G3D::Vector3& v) { - _worldPacket >> movementInfo.guid; - _worldPacket >> movementInfo.time; - _worldPacket >> movementInfo.pos.m_positionX; - _worldPacket >> movementInfo.pos.m_positionY; - _worldPacket >> movementInfo.pos.m_positionZ; - _worldPacket >> movementInfo.pos.m_orientation; - _worldPacket >> movementInfo.pitch; - _worldPacket >> movementInfo.splineElevation; + data << v.x << v.y << v.z; +} - uint32 removeMovementForcesCount; - _worldPacket >> removeMovementForcesCount; +ByteBuffer& operator >> (ByteBuffer& data, G3D::Vector3& v) +{ + data >> v.x >> v.y >> v.z; +} - uint32 int168; - _worldPacket >> int168; +ByteBuffer& operator<<(ByteBuffer& data, MovementInfo& movementInfo) +{ + bool hasTransportData = !movementInfo.transport.guid.IsEmpty(); + bool hasTransportPrevTime = hasTransportData && movementInfo.transport.prevTime != 0; + bool hasTransportVehicleId = hasTransportData && movementInfo.transport.vehicleId != 0; + bool hasFallDirection = movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR); + bool hasFallData = hasFallDirection || movementInfo.jump.fallTime != 0; - for (uint32 i = 0; i < removeMovementForcesCount; ++i) + data << movementInfo.guid; + data << movementInfo.time; + data << movementInfo.pos.PositionXYZOStream(); + data << movementInfo.pitch; + data << movementInfo.splineElevation; + + uint32 removeMovementForcesCount = 0; + data << removeMovementForcesCount; + + uint32 int168 = 0; + data << int168; + + /*for (uint32 i = 0; i < removeMovementForcesCount; ++i) { - ObjectGuid guid; - _worldPacket >> guid; - } + data << ObjectGuid; + }*/ - // ResetBitReader + data.FlushBits(); - movementInfo.flags = _worldPacket.ReadBits(30); - movementInfo.flags2 = _worldPacket.ReadBits(15); + data.WriteBits(movementInfo.flags, 30); + data.WriteBits(movementInfo.flags2, 15); - bool hasTransport = _worldPacket.ReadBit(); - bool hasFall = _worldPacket.ReadBit(); + data.WriteBit(hasTransportData); + data.WriteBit(hasFallData); - _worldPacket.ReadBit(); // HeightChangeFailed - _worldPacket.ReadBit(); // RemoteTimeValid + data.WriteBit(0); // HeightChangeFailed + data.WriteBit(0); // RemoteTimeValid - if (hasTransport) + if (hasTransportData) { - _worldPacket >> movementInfo.transport.guid; - _worldPacket >> movementInfo.transport.pos.m_positionX; - _worldPacket >> movementInfo.transport.pos.m_positionY; - _worldPacket >> movementInfo.transport.pos.m_positionZ; - _worldPacket >> movementInfo.transport.pos.m_orientation; - _worldPacket >> movementInfo.transport.seat; - _worldPacket >> movementInfo.transport.time; + data << movementInfo.transport.guid; + data << movementInfo.transport.pos.PositionXYZOStream(); + data << movementInfo.transport.seat; + data << movementInfo.transport.time; - bool hasPrevTime = _worldPacket.ReadBit(); - bool hasVehicleId = _worldPacket.ReadBit(); + data.WriteBit(hasTransportPrevTime); + data.WriteBit(hasTransportVehicleId); - if (hasPrevTime) - _worldPacket >> movementInfo.transport.prevTime; + if (hasTransportPrevTime) + data << movementInfo.transport.prevTime; - if (hasVehicleId) - _worldPacket >> movementInfo.transport.vehicleId; + if (hasTransportVehicleId) + data << movementInfo.transport.vehicleId; } - if (hasFall) + if (hasFallData) { - _worldPacket >> movementInfo.jump.fallTime; - _worldPacket >> movementInfo.jump.zspeed; + data << movementInfo.jump.fallTime; + data << movementInfo.jump.zspeed; - // ResetBitReader + data.FlushBits(); - bool hasFallDirection = _worldPacket.ReadBit(); + data.WriteBit(hasFallDirection); if (hasFallDirection) { - _worldPacket >> movementInfo.jump.sinAngle; - _worldPacket >> movementInfo.jump.cosAngle; - _worldPacket >> movementInfo.jump.xyspeed; + data << movementInfo.jump.sinAngle; + data << movementInfo.jump.cosAngle; + data << movementInfo.jump.xyspeed; } } + + data.FlushBits(); } -WorldPacket const* WorldPackets::Movement::ServerPlayerMovement::Write() +ByteBuffer& operator>>(ByteBuffer& data, MovementInfo& movementInfo) { - MovementInfo const movementInfo = mover->m_movementInfo; - - bool hasMovementFlags = mover->GetUnitMovementFlags() != 0; - bool hasMovementFlags2 = mover->GetExtraUnitMovementFlags() != 0; - bool hasTransportData = !mover->GetTransGUID().IsEmpty(); - bool hasSpline = mover->IsSplineEnabled(); - - bool hasTransportPrevTime = hasTransportData && movementInfo.transport.prevTime != 0; - bool hasTransportVehicleId = hasTransportData && movementInfo.transport.vehicleId != 0; - bool hasPitch = mover->HasUnitMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mover->HasExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING); - bool hasFallDirection = mover->HasUnitMovementFlag(MOVEMENTFLAG_FALLING); - bool hasFallData = hasFallDirection || movementInfo.jump.fallTime != 0; - bool hasSplineElevation = mover->HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION); + data >> movementInfo.guid; + data >> movementInfo.time; + data >> movementInfo.pos.PositionXYZOStream(); + data >> movementInfo.pitch; + data >> movementInfo.splineElevation; - _worldPacket << movementInfo.guid; - _worldPacket << movementInfo.time; - _worldPacket << movementInfo.pos.m_positionX; - _worldPacket << movementInfo.pos.m_positionY; - _worldPacket << movementInfo.pos.m_positionZ; - _worldPacket << movementInfo.pos.m_orientation; - _worldPacket << movementInfo.pitch; - _worldPacket << movementInfo.splineElevation; - - uint32 removeMovementForcesCount = 0; - _worldPacket << removeMovementForcesCount; + uint32 removeMovementForcesCount; + data >> removeMovementForcesCount; - uint32 int168 = 0; - _worldPacket << int168; + uint32 int168; + data >> int168; - /*for (uint32 i = 0; i < removeMovementForcesCount; ++i) + for (uint32 i = 0; i < removeMovementForcesCount; ++i) { - _worldPacket << ObjectGuid; - }*/ - - _worldPacket.FlushBits(); + ObjectGuid guid; + data >> guid; + } - _worldPacket.WriteBits(movementInfo.flags, 30); - _worldPacket.WriteBits(movementInfo.flags2, 15); + movementInfo.flags = data.ReadBits(30); + movementInfo.flags2 = data.ReadBits(15); - _worldPacket.WriteBit(hasTransportData); - _worldPacket.WriteBit(hasFallData); + bool hasTransport = data.ReadBit(); + bool hasFall = data.ReadBit(); - _worldPacket.WriteBit(0); // HeightChangeFailed - _worldPacket.WriteBit(0); // RemoteTimeValid + data.ReadBit(); // HeightChangeFailed + data.ReadBit(); // RemoteTimeValid - if (hasTransportData) + if (hasTransport) { - _worldPacket << movementInfo.transport.guid; - _worldPacket << movementInfo.transport.pos.m_positionX; - _worldPacket << movementInfo.transport.pos.m_positionY; - _worldPacket << movementInfo.transport.pos.m_positionZ; - _worldPacket << movementInfo.transport.pos.m_orientation; - _worldPacket << movementInfo.transport.seat; - _worldPacket << movementInfo.transport.time; + data >> movementInfo.transport.guid; + data >> movementInfo.transport.pos.PositionXYZOStream(); + data >> movementInfo.transport.seat; + data >> movementInfo.transport.time; - _worldPacket.WriteBit(hasTransportPrevTime); - _worldPacket.WriteBit(hasTransportVehicleId); + bool hasPrevTime = data.ReadBit(); + bool hasVehicleId = data.ReadBit(); - if (hasTransportPrevTime) - _worldPacket << movementInfo.transport.prevTime; + if (hasPrevTime) + data >> movementInfo.transport.prevTime; - if (hasTransportVehicleId) - _worldPacket << movementInfo.transport.vehicleId; + if (hasVehicleId) + data >> movementInfo.transport.vehicleId; } - if (hasFallData) + if (hasFall) { - _worldPacket << movementInfo.jump.fallTime; - _worldPacket << movementInfo.jump.zspeed; + data >> movementInfo.jump.fallTime; + data >> movementInfo.jump.zspeed; - _worldPacket.FlushBits(); + // ResetBitReader - _worldPacket.WriteBit(hasFallDirection); + bool hasFallDirection = data.ReadBit(); if (hasFallDirection) { - _worldPacket << movementInfo.jump.sinAngle; - _worldPacket << movementInfo.jump.cosAngle; - _worldPacket << movementInfo.jump.xyspeed; + data >> movementInfo.jump.sinAngle; + data >> movementInfo.jump.cosAngle; + data >> movementInfo.jump.xyspeed; } } +} + +void WorldPackets::Movement::ClientPlayerMovement::Read() +{ + _worldPacket >> movementInfo; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilterKey& monsterSplineFilterKey) +{ + data << monsterSplineFilterKey.Idx; + data << monsterSplineFilterKey.Speed; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilter& monsterSplineFilter) +{ + data << uint32(monsterSplineFilter.FilterKeys.size()); + data << monsterSplineFilter.BaseSpeed; + data << monsterSplineFilter.StartOffset; + data << monsterSplineFilter.DistToPrevFilterKey; + for (WorldPackets::Movement::MonsterSplineFilterKey& filterKey : monsterSplineFilter.FilterKeys) + data << filterKey; + data << monsterSplineFilter.AddedToStart; + data.FlushBits(); + data.WriteBits(monsterSplineFilter.FilterFlags, 2); +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementSpline& movementSpline) +{ + data << movementSpline.Flags; + data << movementSpline.AnimTier; + data << movementSpline.TierTransStartTime; + data << movementSpline.Elapsed; + data << movementSpline.MoveTime; + data << movementSpline.JumpGravity; + data << movementSpline.SpecialTime; + data << int32(movementSpline.Points.size()); + data << movementSpline.Mode; + data << movementSpline.VehicleExitVoluntary; + data << movementSpline.TransportGUID; + data << movementSpline.VehicleSeat; + data << int32(movementSpline.PackedDeltas.size()); + for (G3D::Vector3& pos : movementSpline.Points) + data << pos; + for (G3D::Vector3& pos : movementSpline.PackedDeltas) + data.appendPackXYZ(pos.x, pos.y, pos.z); + data.FlushBits(); + data.WriteBits(movementSpline.Face, 2); + data.WriteBit(movementSpline.SplineFilter.HasValue); + switch (movementSpline.Face) + { + case MONSTER_MOVE_FACING_SPOT: + data << movementSpline.FaceSpot; + break; + case MONSTER_MOVE_FACING_TARGET: + data << movementSpline.FaceDirection; + data << movementSpline.FaceGUID; + break; + case MONSTER_MOVE_FACING_ANGLE: + data << movementSpline.FaceDirection; + break; + } + if (movementSpline.SplineFilter.HasValue) + data << movementSpline.SplineFilter.value; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline) +{ + data << movementMonsterSpline.ID; + data << movementMonsterSpline.Destination; + data << movementMonsterSpline.Move; + data.FlushBits(); + data.WriteBit(movementMonsterSpline.CrzTeleport); +} + +WorldPacket const* WorldPackets::Movement::MonsterMove::Write() +{ + _worldPacket << MoverGUID; + _worldPacket << Pos; + _worldPacket << SplineData; + + // Unk bits. 0 if monster is moving, 1 or 2 if stopped + if (SplineData.Move.Flags) + _worldPacket.WriteBits(0, 2); + else + _worldPacket.WriteBits(2, 2); _worldPacket.FlushBits(); return &_worldPacket; } +WorldPacket const* WorldPackets::Movement::MoveSplineSet::Write() +{ + _worldPacket << MoverGUID; + _worldPacket << Speed; + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Movement::MoveUpdate::Write() +{ + _worldPacket << movementInfo; + _worldPacket << Speed; + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Movement::ServerPlayerMovement::Write() +{ + MovementInfo movementInfo = mover->m_movementInfo; + + _worldPacket << movementInfo; + + return &_worldPacket; +} + WorldPacket const* WorldPackets::Movement::NewWorld::Write() { _worldPacket << MapID; diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index bc643e6f3bf..8aebb1db9fc 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -20,6 +20,7 @@ #include "Packet.h" #include "Object.h" +#include <G3D/Vector3.h> namespace WorldPackets { @@ -45,6 +46,86 @@ namespace WorldPackets Unit* mover; }; + struct MonsterSplineFilterKey + { + int16 Idx; + int16 Speed; + }; + + struct MonsterSplineFilter + { + std::vector<MonsterSplineFilterKey> FilterKeys; + uint8 FilterFlags; + float BaseSpeed; + int16 StartOffset; + float DistToPrevFilterKey; + int16 AddedToStart; + }; + + struct MovementSpline + { + uint32 Flags = 0; // Spline flags + uint8 Face = 0; // Movement direction (see MonsterMoveType enum) + uint8 AnimTier = 0; + uint32 TierTransStartTime = 0; + uint32 Elapsed = 0; + uint32 MoveTime = 0; + float JumpGravity = 0.0f; + uint32 SpecialTime = 0; + std::vector<G3D::Vector3> Points; // Spline path + uint8 Mode = 0; + uint8 VehicleExitVoluntary = 0; + ObjectGuid TransportGUID; + uint8 VehicleSeat = 255; + std::vector<G3D::Vector3> PackedDeltas; + Optional<MonsterSplineFilter> SplineFilter; + float FaceDirection = 0.0f; + ObjectGuid FaceGUID; + G3D::Vector3 FaceSpot; + }; + + struct MovementMonsterSpline + { + uint32 ID; + G3D::Vector3 Destination; + bool CrzTeleport = false; + MovementSpline Move; + }; + + class MonsterMove final : public ServerPacket + { + public: + MonsterMove() : ServerPacket(SMSG_MONSTER_MOVE) { } + + WorldPacket const* Write() override; + + MovementMonsterSpline SplineData; + ObjectGuid MoverGUID; + G3D::Vector3 Pos; + }; + + class MoveSplineSet : public ServerPacket + { + public: + MoveSplineSet(OpcodeServer opcode) : ServerPacket(opcode, 12) { } + + WorldPacket const* Write() override; + + ObjectGuid MoverGUID; + float Speed; + }; + + class MoveUpdate : public ServerPacket + { + public: + MoveUpdate(OpcodeServer opcode) : ServerPacket(opcode) { } + + WorldPacket const* Write() override; + + MovementInfo movementInfo; + float Speed; + }; + class NewWorld final : public ServerPacket { public: @@ -67,4 +148,15 @@ namespace WorldPackets } } +ByteBuffer& operator<<(ByteBuffer& data, const G3D::Vector3& v); +ByteBuffer& operator>>(ByteBuffer& data, G3D::Vector3& v); + +ByteBuffer& operator>>(ByteBuffer& data, MovementInfo& movementInfo); +ByteBuffer& operator<<(ByteBuffer& data, MovementInfo& movementInfo); + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilterKey const& monsterSplineFilterKey); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilter const& monsterSplineFilter); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementSpline const& movementSpline); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementMonsterSpline const& movementMonsterSpline); + #endif // MovementPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 9f97e53df42..595e19cd7ef 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1084,7 +1084,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONEY_NOTIFY, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE_TRANSPORT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNTRESULT, STATUS_UNHANDLED); @@ -1124,14 +1124,14 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_SPEED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_BACK_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_SPEED, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_BACK_SPEED, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TELEPORT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TURN_RATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_WALK_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TURN_RATE, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_WALK_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_WATER_WALK, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE, STATUS_NEVER); @@ -1317,20 +1317,20 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_ANIM, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_UNHANDLED); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 3e061cb0192..06654acb0bc 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1102,7 +1102,7 @@ enum OpcodeServer : uint32 SMSG_MISSILE_CANCEL = 0xBADD, SMSG_MODIFY_COOLDOWN = 0xBADD, SMSG_MONEY_NOTIFY = 0xBADD, - SMSG_MONSTER_MOVE = 0xBADD, + SMSG_MONSTER_MOVE = 0x0994, SMSG_MONSTER_MOVE_TRANSPORT = 0xBADD, SMSG_MOTD = 0x0442, SMSG_MOUNTRESULT = 0xBADD, |