aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp46
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp138
-rw-r--r--src/server/game/Entities/Unit/Unit.h12
-rw-r--r--src/server/game/Server/Packets/MailPackets.cpp4
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp86
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h39
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
7 files changed, 202 insertions, 125 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index e2b38a50603..2c030d0c58a 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -4235,7 +4235,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
setDeathState(ALIVE);
- SetWaterWalking(false, true);
+ // add the flag to make sure opcode is always sent
+ AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ SetWaterWalking(false);
if (!HasUnitState(UNIT_STATE_STUNNED))
SetRooted(false);
@@ -23096,9 +23098,31 @@ void Player::SendInitialPacketsAfterAddToMap()
if (HasAuraType(SPELL_AURA_MOD_STUN))
SetRooted(true);
+ WorldPackets::Movement::MoveSetCompoundState setCompoundState;
// manual send package (have code in HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); that must not be re-applied.
if (HasAuraType(SPELL_AURA_MOD_ROOT) || HasAuraType(SPELL_AURA_MOD_ROOT_2))
- SetRooted(true, true);
+ setCompoundState.StateChanges.emplace_back(SMSG_MOVE_ROOT, m_movementCounter++);
+
+ if (HasAuraType(SPELL_AURA_FEATHER_FALL))
+ setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_FEATHER_FALL, m_movementCounter++);
+
+ if (HasAuraType(SPELL_AURA_WATER_WALK))
+ setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_WATER_WALK, m_movementCounter++);
+
+ if (HasAuraType(SPELL_AURA_HOVER))
+ setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_HOVERING, m_movementCounter++);
+
+ if (HasAuraType(SPELL_AURA_CAN_TURN_WHILE_FALLING))
+ setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_CAN_TURN_WHILE_FALLING, m_movementCounter++);
+
+ if (HasAura(SPELL_DH_DOUBLE_JUMP))
+ setCompoundState.StateChanges.emplace_back(SMSG_MOVE_ENABLE_DOUBLE_JUMP, m_movementCounter++);
+
+ if (!setCompoundState.StateChanges.empty())
+ {
+ setCompoundState.MoverGUID = GetGUID();
+ SendDirectMessage(setCompoundState.Write());
+ }
SendAurasForTarget(this);
SendEnchantmentDurations(); // must be after add to map
@@ -23452,24 +23476,6 @@ void Player::SendAurasForTarget(Unit* target) const
if (!target || target->GetVisibleAuras().empty()) // speedup things
return;
- /*! Blizz sends certain movement packets sometimes even before CreateObject
- These movement packets are usually found in SMSG_COMPRESSED_MOVES
- */
- if (target->HasAuraType(SPELL_AURA_FEATHER_FALL))
- target->SetFeatherFall(true, true);
-
- if (target->HasAuraType(SPELL_AURA_WATER_WALK))
- target->SetWaterWalking(true, true);
-
- if (target->HasAuraType(SPELL_AURA_HOVER))
- target->SetHover(true, true);
-
- if (target->HasAuraType(SPELL_AURA_CAN_TURN_WHILE_FALLING))
- target->SetCanTurnWhileFalling(true, true);
-
- if (target->HasAura(SPELL_DH_DOUBLE_JUMP))
- target->SetDoubleJump(true, true);
-
Unit::VisibleAuraContainer const& visibleAuras = target->GetVisibleAuras();
WorldPackets::Spells::AuraUpdate update;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 750643ec126..ca44e62923d 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -15372,25 +15372,22 @@ bool Unit::SetWalk(bool enable)
return true;
}
-bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/)
+bool Unit::SetDisableGravity(bool disable)
{
- if (!packetOnly)
- {
- if (disable == IsLevitating())
- return false;
+ if (disable == IsLevitating())
+ return false;
- if (disable)
- {
- AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION);
- SetFall(false);
- }
- else
- {
- RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
- SetFall(true);
- }
+ if (disable)
+ {
+ AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION);
+ SetFall(false);
+ }
+ else
+ {
+ RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
+ SetFall(true);
}
static OpcodeServer const gravityOpcodeTable[2][2] =
@@ -15503,18 +15500,15 @@ bool Unit::SetCanFly(bool enable)
return true;
}
-bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
+bool Unit::SetWaterWalking(bool enable)
{
- if (!packetOnly)
- {
- if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
- return false;
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
+ return false;
- if (enable)
- AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- else
- RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- }
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
static OpcodeServer const waterWalkingOpcodeTable[2][2] =
{
@@ -15543,18 +15537,15 @@ bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
return true;
}
-bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
+bool Unit::SetFeatherFall(bool enable)
{
- if (!packetOnly)
- {
- if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
- return false;
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
+ return false;
- if (enable)
- AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
- else
- RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
- }
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
static OpcodeServer const featherFallOpcodeTable[2][2] =
{
@@ -15583,31 +15574,28 @@ bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
return true;
}
-bool Unit::SetHover(bool enable, bool packetOnly /*= false*/)
+bool Unit::SetHover(bool enable)
{
- if (!packetOnly)
- {
- if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
- return false;
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
+ return false;
- float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
+ float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
- if (enable)
- {
- //! No need to check height on ascent
- AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (hoverHeight)
- UpdateHeight(GetPositionZ() + hoverHeight);
- }
- else
+ if (enable)
+ {
+ //! No need to check height on ascent
+ AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ if (hoverHeight)
+ UpdateHeight(GetPositionZ() + hoverHeight);
+ }
+ else
+ {
+ RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ if (hoverHeight)
{
- RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (hoverHeight)
- {
- float newZ = GetPositionZ() - hoverHeight;
- UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
- UpdateHeight(newZ);
- }
+ float newZ = GetPositionZ() - hoverHeight;
+ UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
+ UpdateHeight(newZ);
}
}
@@ -15709,18 +15697,15 @@ bool Unit::SetCanTransitionBetweenSwimAndFly(bool enable)
return true;
}
-bool Unit::SetCanTurnWhileFalling(bool enable, bool packetOnly /*= false*/)
+bool Unit::SetCanTurnWhileFalling(bool enable)
{
- if (!packetOnly)
- {
- if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING))
- return false;
+ if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING))
+ return false;
- if (enable)
- AddExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING);
- else
- RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING);
- }
+ if (enable)
+ AddExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING);
+ else
+ RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING);
static OpcodeServer const canTurnWhileFallingOpcodeTable[2] =
{
@@ -15743,18 +15728,15 @@ bool Unit::SetCanTurnWhileFalling(bool enable, bool packetOnly /*= false*/)
return true;
}
-bool Unit::SetDoubleJump(bool enable, bool packetOnly /*= false*/)
+bool Unit::SetDoubleJump(bool enable)
{
- if (!packetOnly)
- {
- if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP))
- return false;
+ if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP))
+ return false;
- if (enable)
- AddExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP);
- else
- RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP);
- }
+ if (enable)
+ AddExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP);
+ else
+ RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP);
static OpcodeServer const doubleJumpOpcodeTable[2] =
{
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 58cab981dfc..a521a782a0d 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1690,17 +1690,17 @@ class TC_GAME_API Unit : public WorldObject
bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); }
bool IsHovering() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_HOVER); }
bool SetWalk(bool enable);
- bool SetDisableGravity(bool disable, bool packetOnly = false);
+ bool SetDisableGravity(bool disable);
bool SetFall(bool enable);
bool SetSwim(bool enable);
bool SetCanFly(bool enable);
- bool SetWaterWalking(bool enable, bool packetOnly = false);
- bool SetFeatherFall(bool enable, bool packetOnly = false);
- bool SetHover(bool enable, bool packetOnly = false);
+ bool SetWaterWalking(bool enable);
+ bool SetFeatherFall(bool enable);
+ bool SetHover(bool enable);
bool SetCollision(bool disable);
bool SetCanTransitionBetweenSwimAndFly(bool enable);
- bool SetCanTurnWhileFalling(bool enable, bool packetOnly = false);
- bool SetDoubleJump(bool enable, bool packetOnly = false);
+ bool SetCanTurnWhileFalling(bool enable);
+ bool SetDoubleJump(bool enable);
void SendSetVehicleRecId(uint32 vehicleId);
void SetInFront(WorldObject const* target);
diff --git a/src/server/game/Server/Packets/MailPackets.cpp b/src/server/game/Server/Packets/MailPackets.cpp
index f8922d5bbaf..472c33503cb 100644
--- a/src/server/game/Server/Packets/MailPackets.cpp
+++ b/src/server/game/Server/Packets/MailPackets.cpp
@@ -128,7 +128,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Mail::MailListEntry const
data.WriteBits(entry.Body.size(), 13);
data.FlushBits();
- for (auto const& att : entry.Attachments)
+ for (WorldPackets::Mail::MailAttachedItem const& att : entry.Attachments)
data << att;
if (entry.SenderCharacter)
@@ -157,7 +157,7 @@ WorldPacket const* WorldPackets::Mail::MailListResult::Write()
_worldPacket << uint32(Mails.size());
_worldPacket << int32(TotalNumRecords);
- for (auto const& mail : Mails)
+ for (MailListEntry const& mail : Mails)
_worldPacket << mail;
return &_worldPacket;
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index 0a77af16b83..1a04aa52a50 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -532,22 +532,27 @@ WorldPacket const* WorldPackets::Movement::MoveTeleport::Write()
return &_worldPacket;
}
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementForce const& movementForce)
+{
+ data << movementForce.ID;
+ data << movementForce.Origin;
+ data << movementForce.Direction;
+ data << movementForce.TransportPosition;
+ data << movementForce.TransportID;
+ data << movementForce.Magnitude;
+ data.WriteBits(movementForce.Type, 2);
+ data.FlushBits();
+
+ return data;
+}
+
WorldPacket const* WorldPackets::Movement::MoveUpdateTeleport::Write()
{
_worldPacket << *movementInfo;
_worldPacket << int32(MovementForces.size());
for (WorldPackets::Movement::MovementForce const& force : MovementForces)
- {
- _worldPacket << force.ID;
- _worldPacket << force.Origin;
- _worldPacket << force.Direction;
- _worldPacket << force.TransportPosition;
- _worldPacket << force.TransportID;
- _worldPacket << force.Magnitude;
- _worldPacket.WriteBits(force.Type, 2);
- _worldPacket.FlushBits();
- }
+ _worldPacket << force;
_worldPacket.WriteBit(WalkSpeed.is_initialized());
_worldPacket.WriteBit(RunSpeed.is_initialized());
@@ -679,14 +684,7 @@ WorldPacket const* WorldPackets::Movement::MoveUpdateRemoveMovementForce::Write(
WorldPacket const* WorldPackets::Movement::MoveUpdateApplyMovementForce::Write()
{
_worldPacket << *movementInfo;
- _worldPacket << Force.ID;
- _worldPacket << Force.Origin;
- _worldPacket << Force.Direction;
- _worldPacket << Force.TransportPosition;
- _worldPacket << Force.TransportID;
- _worldPacket << Force.Magnitude;
- _worldPacket.WriteBits(Force.Type, 2);
- _worldPacket.FlushBits();
+ _worldPacket << Force;
return &_worldPacket;
}
@@ -760,3 +758,55 @@ WorldPacket const* WorldPackets::Movement::ResumeToken::Write()
return &_worldPacket;
}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MoveSetCompoundState::MoveStateChange const& stateChange)
+{
+ data << uint16(stateChange.MessageID);
+ data << uint32(stateChange.SequenceIndex);
+ data.WriteBit(stateChange.Speed.is_initialized());
+ data.WriteBit(stateChange.KnockBack.is_initialized());
+ data.WriteBit(stateChange.VehicleRecID.is_initialized());
+ data.WriteBit(stateChange.CollisionHeight.is_initialized());
+ data.WriteBit(stateChange.MovementForce_.is_initialized());
+ data.WriteBit(stateChange.Unknown.is_initialized());
+ data.FlushBits();
+
+ if (stateChange.CollisionHeight)
+ {
+ data << float(stateChange.CollisionHeight->Height);
+ data << float(stateChange.CollisionHeight->Scale);
+ data.WriteBits(stateChange.CollisionHeight->Reason, 2);
+ data.FlushBits();
+ }
+
+ if (stateChange.Speed)
+ data << float(*stateChange.Speed);
+
+ if (stateChange.KnockBack)
+ {
+ data << float(stateChange.KnockBack->HorzSpeed);
+ data << stateChange.KnockBack->Direction;
+ data << float(stateChange.KnockBack->InitVertSpeed);
+ }
+
+ if (stateChange.VehicleRecID)
+ data << int32(*stateChange.VehicleRecID);
+
+ if (stateChange.MovementForce_)
+ data << *stateChange.MovementForce_;
+
+ if (stateChange.Unknown)
+ data << *stateChange.Unknown;
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Movement::MoveSetCompoundState::Write()
+{
+ _worldPacket << MoverGUID;
+ _worldPacket << uint32(StateChanges.size());
+ for (MoveStateChange const& stateChange : StateChanges)
+ _worldPacket << stateChange;
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index 1c21c034c86..83c53812ea3 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -536,6 +536,45 @@ namespace WorldPackets
uint32 SequenceIndex = 1;
uint32 Reason = 1;
};
+
+ class MoveSetCompoundState final : public ServerPacket
+ {
+ public:
+ struct CollisionHeightInfo
+ {
+ float Height = 0.0f;
+ float Scale = 0.0f;
+ UpdateCollisionHeightReason Reason;
+ };
+
+ struct KnockBackInfo
+ {
+ float HorzSpeed = 0.0f;
+ G3D::Vector2 Direction;
+ float InitVertSpeed = 0.0f;
+ };
+
+ struct MoveStateChange
+ {
+ MoveStateChange(OpcodeServer messageId, uint32 sequenceIndex) : MessageID(messageId), SequenceIndex(sequenceIndex) { }
+
+ uint16 MessageID = 0;
+ uint32 SequenceIndex = 0;
+ Optional<float> Speed;
+ Optional<KnockBackInfo> KnockBack;
+ Optional<int32> VehicleRecID;
+ Optional<CollisionHeightInfo> CollisionHeight;
+ Optional<MovementForce> MovementForce_;
+ Optional<ObjectGuid> Unknown;
+ };
+
+ MoveSetCompoundState() : ServerPacket(SMSG_MOVE_SET_COMPOUND_STATE, 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid MoverGUID;
+ std::vector<MoveStateChange> StateChanges;
+ };
}
ByteBuffer& operator<<(ByteBuffer& data, Movement::MonsterSplineFilterKey const& monsterSplineFilterKey);
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index c242d9ee929..4fbc0b700fd 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1365,7 +1365,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TURN_WHILE_FALLING, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FEATHER_FALL, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);