aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIntel <chemicstry@gmail.com>2014-11-18 14:14:28 +0200
committerIntel <chemicstry@gmail.com>2014-11-19 20:18:02 +0200
commit73a7d7c0538b5c791aaa89caae6547c4b330dd80 (patch)
treef98579f7e626d8d10daee8c010693eafe967c6eb
parent718fc9d631b7dfe9825ac6e5c6f56d7c5ce67479 (diff)
Core/Packets: Added SMSG_MONSTER_MOVE and split common packet structures
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp22
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp32
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.cpp160
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.h3
-rw-r--r--src/server/game/Movement/Spline/MovementTypedefs.h8
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp311
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h92
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp26
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h2
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,