diff --git a/src/server/game/Entities/Object/MovementInfo.cpp b/src/server/game/Entities/Object/MovementInfo.cpp
new file mode 100644
index 0000000000..ce3a44068c
--- /dev/null
+++ b/src/server/game/Entities/Object/MovementInfo.cpp
@@ -0,0 +1,134 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include "MovementInfo.h"
+#include "GameTime.h"
+#include "Log.h"
+#include "UnitDefines.h"
+#include "G3DPosition.hpp"
+
+void MovementInfo::ResetTransport()
+{
+ transport.Reset();
+}
+
+void MovementInfo::ResetJump()
+{
+ jump.Reset();
+}
+
+bool MovementInfo::HasFallDirection() const
+{
+ return HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR);
+}
+
+bool MovementInfo::HasFallData() const
+{
+ return (HasFallDirection() || jump.fallTime != 0);
+}
+
+bool MovementInfo::HasMovementFlags() const
+{
+ return GetMovementFlags() != 0;
+};
+
+bool MovementInfo::HasExtraMovementFlags() const
+{
+ return GetExtraMovementFlags() != 0;
+};
+
+bool MovementInfo::HasSpline() const
+{
+ // Todo: handle this
+ return false;
+};
+
+bool MovementInfo::HasHeightChangeFailed() const
+{
+ // Todo: handle this
+ return false;
+}
+
+bool MovementInfo::HasTime() const
+{
+ return time != 0;
+}
+
+bool MovementInfo::HasOrientation() const
+{
+ return !G3D::fuzzyEq(pos.GetOrientation(), 0.0f);
+}
+
+bool MovementInfo::HasSplineElevation() const
+{
+ return HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
+}
+
+bool MovementInfo::HasPitch() const
+{
+ return (HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING));
+}
+
+bool MovementInfo::HasTransportData() const
+{
+ return !transport.guid.IsEmpty();
+}
+
+bool MovementInfo::HasTransportVehicleId() const
+{
+ return HasTransportData() && transport.vehicleId != 0;
+}
+
+bool MovementInfo::HasTransportTime2() const
+{
+ return HasTransportData() && transport.time2 != 0;
+}
+
+void MovementInfo::OutDebug()
+{
+ TC_LOG_DEBUG("misc", "MOVEMENT INFO");
+ TC_LOG_DEBUG("misc", "%s", guid.ToString().c_str());
+ TC_LOG_DEBUG("misc", "flags %u", flags);
+ TC_LOG_DEBUG("misc", "flags2 %u", flags2);
+ TC_LOG_DEBUG("misc", "time %u current time " UI64FMTD "", flags2, uint64(::GameTime::GetGameTime()));
+ TC_LOG_DEBUG("misc", "position: `%s`", pos.ToString().c_str());
+ if (transport.guid)
+ {
+ TC_LOG_DEBUG("misc", "TRANSPORT:");
+ TC_LOG_DEBUG("misc", "%s", transport.guid.ToString().c_str());
+ TC_LOG_DEBUG("misc", "position: `%s`", transport.pos.ToString().c_str());
+ TC_LOG_DEBUG("misc", "seat: %i", transport.seat);
+ TC_LOG_DEBUG("misc", "time: %u", transport.time);
+ if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
+ TC_LOG_DEBUG("misc", "time2: %u", transport.time2);
+ if (transport.vehicleId)
+ TC_LOG_INFO("misc", "vehicleId: %u", transport.vehicleId);
+ }
+
+ if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
+ TC_LOG_DEBUG("misc", "pitch: %f", pitch);
+
+ if (flags & MOVEMENTFLAG_FALLING || jump.fallTime)
+ {
+ TC_LOG_INFO("misc", "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed);
+ if (flags & MOVEMENTFLAG_FALLING)
+ TC_LOG_DEBUG("misc", "j_zspeed: %f j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.zspeed, jump.sinAngle, jump.cosAngle, jump.xyspeed);
+ }
+
+ if (flags & MOVEMENTFLAG_SPLINE_ELEVATION)
+ TC_LOG_DEBUG("misc", "splineElevation: %f", splineElevation);
+}
diff --git a/src/server/game/Entities/Object/MovementInfo.h b/src/server/game/Entities/Object/MovementInfo.h
index a1283a779f..4edb9dee00 100644
--- a/src/server/game/Entities/Object/MovementInfo.h
+++ b/src/server/game/Entities/Object/MovementInfo.h
@@ -95,15 +95,21 @@ struct MovementInfo
uint32 GetFallTime() const { return jump.fallTime; }
void SetFallTime(uint32 time) { jump.fallTime = time; }
- void ResetTransport()
- {
- transport.Reset();
- }
-
- void ResetJump()
- {
- jump.Reset();
- }
+ void ResetTransport();
+ void ResetJump();
+ bool HasFallDirection() const;
+ bool HasFallData() const;
+ bool HasMovementFlags() const;
+ bool HasExtraMovementFlags() const;
+ bool HasSpline() const;
+ bool HasHeightChangeFailed() const;
+ bool HasTime() const;
+ bool HasOrientation() const;
+ bool HasSplineElevation() const;
+ bool HasPitch() const;
+ bool HasTransportData() const;
+ bool HasTransportVehicleId() const;
+ bool HasTransportTime2() const;
void OutDebug();
};
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index b867676684..a62d6e713c 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1151,41 +1151,6 @@ bool Object::PrintIndexError(uint32 index, bool set) const
return false;
}
-void MovementInfo::OutDebug()
-{
- TC_LOG_DEBUG("misc", "MOVEMENT INFO");
- TC_LOG_DEBUG("misc", "%s", guid.ToString().c_str());
- TC_LOG_DEBUG("misc", "flags %u", flags);
- TC_LOG_DEBUG("misc", "flags2 %u", flags2);
- TC_LOG_DEBUG("misc", "time %u current time " UI64FMTD "", flags2, uint64(::GameTime::GetGameTime()));
- TC_LOG_DEBUG("misc", "position: `%s`", pos.ToString().c_str());
- if (transport.guid)
- {
- TC_LOG_DEBUG("misc", "TRANSPORT:");
- TC_LOG_DEBUG("misc", "%s", transport.guid.ToString().c_str());
- TC_LOG_DEBUG("misc", "position: `%s`", transport.pos.ToString().c_str());
- TC_LOG_DEBUG("misc", "seat: %i", transport.seat);
- TC_LOG_DEBUG("misc", "time: %u", transport.time);
- if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
- TC_LOG_DEBUG("misc", "time2: %u", transport.time2);
- if (transport.vehicleId)
- TC_LOG_INFO("misc", "vehicleId: %u", transport.vehicleId);
- }
-
- if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
- TC_LOG_DEBUG("misc", "pitch: %f", pitch);
-
- if (flags & MOVEMENTFLAG_FALLING || jump.fallTime)
- {
- TC_LOG_INFO("misc", "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed);
- if (flags & MOVEMENTFLAG_FALLING)
- TC_LOG_DEBUG("misc", "j_zspeed: %f j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.zspeed, jump.sinAngle, jump.cosAngle, jump.xyspeed);
- }
-
- if (flags & MOVEMENTFLAG_SPLINE_ELEVATION)
- TC_LOG_DEBUG("misc", "splineElevation: %f", splineElevation);
-}
-
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0),
m_name(""), m_isActive(false), m_isFarVisible(false), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
m_transport(nullptr), m_zoneId(0), m_areaId(0), m_staticFloorZ(VMAP_INVALID_HEIGHT), m_outdoors(true), m_liquidStatus(LIQUID_MAP_NO_WATER),
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 32f58b2e44..d816e64bcc 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -27775,6 +27775,94 @@ bool Player::CanUseMastery() const
return HasSpell(MasterySpells[getClass()]);
}
+void Player::ValidateMovementInfo(MovementInfo* mi)
+{
+ //! Anti-cheat checks. Please keep them in seperate if () blocks to maintain a clear overview.
+ //! Might be subject to latency, so just remove improper flags.
+ #ifdef TRINITY_DEBUG
+ #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
+ { \
+ if (check) \
+ { \
+ TC_LOG_DEBUG("entities.unit", "Player::ValidateMovementInfo: Violation of MovementFlags found (%s). " \
+ "MovementFlags: %u, MovementFlags2: %u for player %s. Mask %u will be removed.", \
+ STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetGUID().ToString().c_str(), maskToRemove); \
+ mi->RemoveMovementFlag((maskToRemove)); \
+ } \
+ }
+ #else
+ #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
+ if (check) \
+ mi->RemoveMovementFlag((maskToRemove));
+ #endif
+
+ if (!m_unitMovedByMe->GetVehicleBase() || !(m_unitMovedByMe->GetVehicle()->GetVehicleInfo()->Flags & VEHICLE_FLAG_FIXED_POSITION))
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), MOVEMENTFLAG_ROOT);
+
+ /*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
+ in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD.
+ It will freeze clients that receive this player's movement info.
+ */
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT) && mi->HasMovementFlag(MOVEMENTFLAG_MASK_MOVING),
+ MOVEMENTFLAG_MASK_MOVING);
+
+ //! Cannot hover without SPELL_AURA_HOVER
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !m_unitMovedByMe->HasAuraType(SPELL_AURA_HOVER),
+ MOVEMENTFLAG_HOVER);
+
+ //! Cannot ascend and descend at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING),
+ MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
+
+ //! Cannot move left and right at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT),
+ MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
+
+ //! Cannot strafe left and right at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT),
+ MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
+
+ //! Cannot pitch up and down at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN),
+ MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
+
+ //! Cannot move forwards and backwards at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD),
+ MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
+
+ //! Cannot walk on water without SPELL_AURA_WATER_WALK except for ghosts
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) &&
+ !m_unitMovedByMe->HasAuraType(SPELL_AURA_WATER_WALK) &&
+ !m_unitMovedByMe->HasAuraType(SPELL_AURA_GHOST),
+ MOVEMENTFLAG_WATERWALKING);
+
+ //! Cannot feather fall without SPELL_AURA_FEATHER_FALL
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !m_unitMovedByMe->HasAuraType(SPELL_AURA_FEATHER_FALL),
+ MOVEMENTFLAG_FALLING_SLOW);
+
+ /*! Cannot fly if no fly auras present. Exception is being a GM.
+ Note that we check for account level instead of Player::IsGameMaster() because in some
+ situations it may be feasable to use .gm fly on as a GM without having .gm on,
+ e.g. aerial combat.
+ */
+
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSession()->GetSecurity() == SEC_PLAYER &&
+ !m_unitMovedByMe->HasAuraType(SPELL_AURA_FLY) &&
+ !m_unitMovedByMe->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED),
+ MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
+
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY) && mi->HasMovementFlag(MOVEMENTFLAG_FALLING),
+ MOVEMENTFLAG_FALLING);
+
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION) && G3D::fuzzyEq(mi->splineElevation, 0.0f), MOVEMENTFLAG_SPLINE_ELEVATION);
+
+ // Client first checks if spline elevation != 0, then verifies flag presence
+ if (G3D::fuzzyNe(mi->splineElevation, 0.0f))
+ mi->AddMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
+
+ #undef REMOVE_VIOLATING_FLAGS
+}
+
void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::ExtraMovementStatusElement* extras /*= nullptr*/)
{
MovementStatusElements const* sequence = GetMovementStatusElementsSequence(static_cast(data.GetOpcode()));
@@ -27990,89 +28078,7 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
mi->guid = guid;
mi->transport.guid = tguid;
- //! Anti-cheat checks. Please keep them in seperate if () blocks to maintain a clear overview.
- //! Might be subject to latency, so just remove improper flags.
- #ifdef TRINITY_DEBUG
- #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
- { \
- if (check) \
- { \
- TC_LOG_DEBUG("entities.unit", "Player::ReadMovementInfo: Violation of MovementFlags found (%s). " \
- "MovementFlags: %u, MovementFlags2: %u for player GUID: %u. Mask %u will be removed.", \
- STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetGUID().GetCounter(), maskToRemove); \
- mi->RemoveMovementFlag((maskToRemove)); \
- } \
- }
- #else
- #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
- if (check) \
- mi->RemoveMovementFlag((maskToRemove));
- #endif
-
- /*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
- in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD.
- It will freeze clients that receive this player's movement info.
- */
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT) && mi->HasMovementFlag(MOVEMENTFLAG_MASK_MOVING),
- MOVEMENTFLAG_MASK_MOVING);
-
- //! Cannot hover without SPELL_AURA_HOVER
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !HasAuraType(SPELL_AURA_HOVER),
- MOVEMENTFLAG_HOVER);
-
- //! Cannot ascend and descend at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING),
- MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
-
- //! Cannot move left and right at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT),
- MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
-
- //! Cannot strafe left and right at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT),
- MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
-
- //! Cannot pitch up and down at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN),
- MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
-
- //! Cannot move forwards and backwards at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD),
- MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
-
- //! Cannot walk on water without SPELL_AURA_WATER_WALK except for ghosts
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) &&
- !HasAuraType(SPELL_AURA_WATER_WALK) &&
- !HasAuraType(SPELL_AURA_GHOST),
- MOVEMENTFLAG_WATERWALKING);
-
- //! Cannot feather fall without SPELL_AURA_FEATHER_FALL
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !HasAuraType(SPELL_AURA_FEATHER_FALL),
- MOVEMENTFLAG_FALLING_SLOW);
-
- /*! Cannot fly if no fly auras present. Exception is being a GM.
- Note that we check for account level instead of Player::IsGameMaster() because in some
- situations it may be feasable to use .gm fly on as a GM without having .gm on,
- e.g. aerial combat.
- */
-
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && ToPlayer()->GetSession()->GetSecurity() == SEC_PLAYER &&
- !ToPlayer()->m_unitMovedByMe->HasAuraType(SPELL_AURA_FLY) &&
- !ToPlayer()->m_unitMovedByMe->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED),
- MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
-
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY) && mi->HasMovementFlag(MOVEMENTFLAG_FALLING),
- MOVEMENTFLAG_FALLING);
-
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING) && (!hasFallData || !hasFallDirection), MOVEMENTFLAG_FALLING);
-
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION) && G3D::fuzzyEq(mi->splineElevation, 0.0f), MOVEMENTFLAG_SPLINE_ELEVATION);
-
- // Client first checks if spline elevation != 0, then verifies flag presence
- if (hasSplineElevation)
- mi->AddMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
-
- #undef REMOVE_VIOLATING_FLAGS
+ ValidateMovementInfo(mi);
}
void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index d95989810a..9619de89cd 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2356,6 +2356,9 @@ class TC_GAME_API Player : public Unit, public GridObject
/*! These methods send different packets to the client in apply and unapply case.
These methods are only sent to the current unit.
*/
+
+ void ValidateMovementInfo(MovementInfo* mi);
+
void SendMovementSetCanTransitionBetweenSwimAndFly(bool apply);
void SendMovementSetCollisionHeight(float height, UpdateCollisionHeightReason reason);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 38a38ea55a..72ddf5821d 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -13823,7 +13823,7 @@ void Unit::WriteMovementInfo(WorldPacket& data, Movement::ExtraMovementStatusEle
break;
case MSETimestamp:
if (hasTimestamp)
- data << getMSTime();
+ data << mi.time;
break;
case MSEPositionX:
data << GetPositionX();
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 5001468d47..3b162c717a 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -682,16 +682,14 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData)
_player->SummonIfPossible(agree);
}
-void WorldSession::HandleSetCollisionHeightAck(WorldPacket& recvPacket)
+void WorldSession::HandleSetCollisionHeightAck(WorldPackets::Movement::MoveSetCollisionHeightAck& packet)
{
- TC_LOG_DEBUG("network", "CMSG_MOVE_SET_COLLISION_HEIGHT_ACK");
+ _player->ValidateMovementInfo(&packet.Data.Status);
- static MovementStatusElements const heightElement = MSEExtraFloat;
- Movement::ExtraMovementStatusElement extra(&heightElement);
- MovementInfo movementInfo;
- GetPlayer()->ReadMovementInfo(recvPacket, &movementInfo, &extra);
-
- Movement::PacketSender(_player, NULL_OPCODE, NULL_OPCODE, SMSG_MOVE_UPDATE_COLLISION_HEIGHT, &extra).Send();
+ WorldPackets::Movement::MoveUpdateCollisionHeight updateCollisionHeight;
+ updateCollisionHeight.Height = packet.Height;
+ updateCollisionHeight.Status = &_player->m_movementInfo;
+ _player->SendMessageToSet(updateCollisionHeight.Write(), false);
}
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData)
diff --git a/src/server/game/Movement/MovementStructures.cpp b/src/server/game/Movement/MovementStructures.cpp
index 2d0494410c..770a437f0f 100644
--- a/src/server/game/Movement/MovementStructures.cpp
+++ b/src/server/game/Movement/MovementStructures.cpp
@@ -2503,77 +2503,6 @@ MovementStatusElements const MovementUpdateFlightSpeed[] =
MSEEnd
};
-MovementStatusElements const MovementUpdateCollisionHeight[] =
-{
- MSEPositionZ,
- MSEExtraElement,
- MSEPositionX,
- MSEPositionY,
- MSEHasGuidByte6,
- MSEHasGuidByte7,
- MSEHasSplineElevation,
- MSEHasTransportData,
- MSEHasTransportGuidByte6,
- MSEHasTransportGuidByte4,
- MSEHasTransportGuidByte3,
- MSEHasTransportGuidByte7,
- MSEHasTransportGuidByte5,
- MSEHasTransportGuidByte1,
- MSEHasTransportGuidByte0,
- MSEHasTransportGuidByte2,
- MSEHasGuidByte3,
- MSEHasOrientation,
- MSEHasGuidByte4,
- MSEHasGuidByte5,
- MSEHasTimestamp,
- MSEHasFallData,
- MSEHasGuidByte0,
- MSEHasPitch,
- MSEZeroBit,
- MSEHasGuidByte2,
- MSEHasMovementFlags,
- MSEHasFallDirection,
- MSEHasGuidByte1,
- MSEHasMovementFlags2,
- MSEHasSpline,
- MSEMovementFlags2,
- MSEMovementFlags,
- MSEGuidByte3,
- MSETransportGuidByte7,
- MSETransportTime,
- MSETransportGuidByte4,
- MSETransportVehicleId,
- MSETransportTime2,
- MSETransportGuidByte5,
- MSETransportOrientation,
- MSETransportPositionX,
- MSETransportGuidByte6,
- MSETransportGuidByte0,
- MSETransportPositionY,
- MSETransportGuidByte2,
- MSETransportPositionZ,
- MSETransportGuidByte3,
- MSETransportGuidByte1,
- MSETransportSeat,
- MSEPitch,
- MSEGuidByte6,
- MSEFallCosAngle,
- MSEFallSinAngle,
- MSEFallHorizontalSpeed,
- MSEFallVerticalSpeed,
- MSEFallTime,
- MSEGuidByte7,
- MSEOrientation,
- MSEGuidByte0,
- MSEGuidByte5,
- MSEGuidByte4,
- MSESplineElevation,
- MSETimestamp,
- MSEGuidByte2,
- MSEGuidByte1,
- MSEEnd,
-};
-
MovementStatusElements const MovementForceRunSpeedChangeAck[] =
{
MSECounter,
@@ -2648,82 +2577,6 @@ MovementStatusElements const MovementForceRunSpeedChangeAck[] =
MSEEnd,
};
-MovementStatusElements const MovementSetCollisionHeightAck[] =
-{
- MSEExtraElement,
- MSEPositionX,
- MSEPositionZ,
- MSECounter,
- MSEPositionY,
- MSEHasGuidByte6,
- MSEHasGuidByte4,
- MSEZeroBit,
- MSEZeroBit,
- MSEHasPitch,
- MSEHasGuidByte5,
- MSEZeroBit,
- MSEHasGuidByte2,
- MSEHasGuidByte1,
- MSEHasFallData,
- MSEHasGuidByte3,
- MSEHasSpline,
- MSEHasGuidByte7,
- MSEHasMovementFlags,
- MSEHasTransportData,
- MSEHasTimestamp,
- MSEHasSplineElevation,
- MSEHasMovementFlags2,
- MSEHasOrientation,
- MSEHasGuidByte0,
- MSEHasTransportGuidByte4,
- MSEHasTransportGuidByte3,
- MSEHasTransportTime2,
- MSEHasVehicleId,
- MSEHasTransportGuidByte5,
- MSEHasTransportGuidByte1,
- MSEHasTransportGuidByte7,
- MSEHasTransportGuidByte2,
- MSEHasTransportGuidByte6,
- MSEHasTransportGuidByte0,
- MSEMovementFlags2,
- MSEMovementFlags,
- MSEHasFallDirection,
- MSEGuidByte0,
- MSEGuidByte3,
- MSEGuidByte1,
- MSEGuidByte5,
- MSEGuidByte7,
- MSEGuidByte6,
- MSEGuidByte2,
- MSEGuidByte4,
- MSETransportPositionX,
- MSETransportGuidByte4,
- MSETransportTime2,
- MSETransportGuidByte0,
- MSETransportOrientation,
- MSETransportPositionY,
- MSETransportGuidByte7,
- MSETransportSeat,
- MSETransportGuidByte5,
- MSETransportGuidByte2,
- MSETransportTime,
- MSETransportGuidByte6,
- MSETransportGuidByte3,
- MSETransportGuidByte1,
- MSETransportVehicleId,
- MSETransportPositionZ,
- MSEFallVerticalSpeed,
- MSEFallTime,
- MSEFallCosAngle,
- MSEFallSinAngle,
- MSEFallHorizontalSpeed,
- MSETimestamp,
- MSESplineElevation,
- MSEOrientation,
- MSEPitch,
- MSEEnd,
-};
-
MovementStatusElements const MovementForceFlightSpeedChangeAck[] =
{
MSECounter,
@@ -5684,10 +5537,6 @@ MovementStatusElements const* GetMovementStatusElementsSequence(uint32 opcode)
return MovementSetCanFlyAck;
case CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK:
return MovementSetCanTransitionBetweenSwimAndFlyAck;
- case CMSG_MOVE_SET_COLLISION_HEIGHT_ACK:
- return MovementSetCollisionHeightAck;
- case SMSG_MOVE_UPDATE_COLLISION_HEIGHT:
- return MovementUpdateCollisionHeight;
case CMSG_MOVE_WATER_WALK_ACK:
return MovementWaterWalkAck;
case MSG_MOVE_SET_RUN_MODE:
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index 1be22695f9..20c8f0485d 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -24,73 +24,59 @@
WorldPacket const* WorldPackets::Movement::MoveUpdate::Write()
{
- bool hasFallDirection = Status->HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR);
- bool hasFallData = hasFallDirection || Status->jump.fallTime != 0;
- bool hasMovementFlags = Status->GetMovementFlags() != 0;
- bool hasExtraMovementFlags = Status->GetExtraMovementFlags() != 0;
- bool hasSpline = false; // todo 4.x send this info
- bool heightChangeFailed = false; // todo 4.x send this info
- bool hasTime = Status->time != 0;
- bool hasOrientation = !G3D::fuzzyEq(Status->pos.GetOrientation(), 0.0f);
- bool hasSplineElevation = Status->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
- bool hasPitch = Status->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || Status->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
- bool hasTransportData = !Status->transport.guid.IsEmpty();
- bool hasTransportVehicleId = hasTransportData && Status->transport.vehicleId != 0;
- bool hasTransportTime2 = hasTransportData && Status->transport.time2 != 0;
-
ObjectGuid guid = Status->guid;
ObjectGuid transportGuid = Status->transport.guid;
- _worldPacket.WriteBit(hasFallData);
+ _worldPacket.WriteBit(Status->HasFallData());
_worldPacket.WriteBit(guid[3]);
_worldPacket.WriteBit(guid[6]);
- _worldPacket.WriteBit(!hasExtraMovementFlags);
- _worldPacket.WriteBit(hasSpline);
- _worldPacket.WriteBit(!hasTime);
+ _worldPacket.WriteBit(!Status->HasExtraMovementFlags());
+ _worldPacket.WriteBit(Status->HasSpline());
+ _worldPacket.WriteBit(!Status->HasTime());
_worldPacket.WriteBit(guid[0]);
_worldPacket.WriteBit(guid[1]);
- if (hasExtraMovementFlags)
+ if (Status->HasExtraMovementFlags())
_worldPacket.WriteBits(Status->GetExtraMovementFlags(), 12);
_worldPacket.WriteBit(guid[7]);
- _worldPacket.WriteBit(!hasMovementFlags);
- _worldPacket.WriteBit(!hasOrientation);
+ _worldPacket.WriteBit(!Status->HasMovementFlags());
+ _worldPacket.WriteBit(!Status->HasOrientation());
_worldPacket.WriteBit(guid[2]);
- _worldPacket.WriteBit(!hasSplineElevation);
- _worldPacket.WriteBit(heightChangeFailed);
+ _worldPacket.WriteBit(!Status->HasSplineElevation());
+ _worldPacket.WriteBit(Status->HasHeightChangeFailed());
_worldPacket.WriteBit(guid[4]);
- if (hasFallData)
- _worldPacket.WriteBit(hasFallDirection);
+ if (Status->HasFallData())
+ _worldPacket.WriteBit(Status->HasFallDirection());
_worldPacket.WriteBit(guid[5]);
- _worldPacket.WriteBit(hasTransportData);
- if (hasMovementFlags)
+ _worldPacket.WriteBit(Status->HasTransportData());
+ if (Status->HasMovementFlags())
_worldPacket.WriteBits(Status->GetMovementFlags(), 30);
- if (hasTransportData)
+ if (Status->HasTransportData())
{
_worldPacket.WriteBit(transportGuid[3]);
- _worldPacket.WriteBit(hasTransportVehicleId);
+ _worldPacket.WriteBit(Status->HasTransportVehicleId());
_worldPacket.WriteBit(transportGuid[6]);
_worldPacket.WriteBit(transportGuid[1]);
_worldPacket.WriteBit(transportGuid[7]);
_worldPacket.WriteBit(transportGuid[0]);
_worldPacket.WriteBit(transportGuid[4]);
- _worldPacket.WriteBit(hasTransportTime2);
+ _worldPacket.WriteBit(Status->HasTransportTime2());
_worldPacket.WriteBit(transportGuid[5]);
_worldPacket.WriteBit(transportGuid[2]);
}
- _worldPacket.WriteBit(!hasPitch);
+ _worldPacket.WriteBit(!Status->HasPitch());
_worldPacket.FlushBits();
_worldPacket.WriteByteSeq(guid[5]);
- if (hasFallData)
+ if (Status->HasFallData())
{
- if (hasFallDirection)
+ if (Status->HasFallDirection())
{
_worldPacket << float(Status->jump.xyspeed);
_worldPacket << float(Status->jump.sinAngle);
@@ -101,27 +87,27 @@ WorldPacket const* WorldPackets::Movement::MoveUpdate::Write()
_worldPacket << uint32(Status->jump.fallTime);
}
- if (hasSplineElevation)
+ if (Status->HasSplineElevation())
_worldPacket << float(Status->splineElevation);
_worldPacket.WriteByteSeq(guid[7]);
_worldPacket << float(Status->pos.GetPositionY());
_worldPacket.WriteByteSeq(guid[3]);
- if (hasTransportData)
+ if (Status->HasTransportData())
{
- if (hasTransportVehicleId)
+ if (Status->HasTransportVehicleId())
_worldPacket << uint32(Status->transport.vehicleId);
_worldPacket.WriteByteSeq(transportGuid[6]);
- _worldPacket << uint8(Status->transport.seat);
+ _worldPacket << int8(Status->transport.seat);
_worldPacket.WriteByteSeq(transportGuid[5]);
_worldPacket << float(Status->transport.pos.GetPositionX());
_worldPacket.WriteByteSeq(transportGuid[1]);
_worldPacket << float(Status->transport.pos.GetOrientation());
_worldPacket.WriteByteSeq(transportGuid[2]);
- if (hasTransportTime2)
+ if (Status->HasTransportTime2())
_worldPacket << uint32(Status->transport.time2);
_worldPacket.WriteByteSeq(transportGuid[0]);
@@ -138,16 +124,16 @@ WorldPacket const* WorldPackets::Movement::MoveUpdate::Write()
_worldPacket.WriteByteSeq(guid[6]);
_worldPacket << float(Status->pos.GetPositionZ());
- if (hasTime)
+ if (Status->HasTime())
_worldPacket << uint32(Status->time);
_worldPacket.WriteByteSeq(guid[2]);
- if (hasPitch)
+ if (Status->HasPitch())
_worldPacket << float(Status->pitch);
_worldPacket.WriteByteSeq(guid[0]);
- if (hasOrientation)
+ if (Status->HasOrientation())
_worldPacket << float(Status->pos.GetOrientation());
_worldPacket.WriteByteSeq(guid[1]);
@@ -155,6 +141,126 @@ WorldPacket const* WorldPackets::Movement::MoveUpdate::Write()
return &_worldPacket;
}
+void WorldPackets::Movement::MoveSetCollisionHeightAck::Read()
+{
+ _worldPacket >> Height;
+ _worldPacket >> Data.Status.pos.m_positionX;
+ _worldPacket >> Data.Status.pos.m_positionZ;
+ _worldPacket >> Data.AckIndex;
+ _worldPacket >> Data.Status.pos.m_positionY;
+ Data.Status.guid[6] = _worldPacket.ReadBit();
+ Data.Status.guid[4] = _worldPacket.ReadBit();
+
+ Reason = UpdateCollisionHeightReason(_worldPacket.ReadBits(2));
+
+ bool hasPitch = !_worldPacket.ReadBit();
+ Data.Status.guid[5] = _worldPacket.ReadBit();
+ _worldPacket.ReadBit(); // HeightChangeFailed
+ Data.Status.guid[2] = _worldPacket.ReadBit();
+ Data.Status.guid[1] = _worldPacket.ReadBit();
+ bool hasFallData = _worldPacket.ReadBit();
+ Data.Status.guid[3] = _worldPacket.ReadBit();
+ _worldPacket.ReadBit(); // HasSpline
+ Data.Status.guid[7] = _worldPacket.ReadBit();
+ bool hasMovementFlags = !_worldPacket.ReadBit();
+ bool hasTransportData = _worldPacket.ReadBit();
+ bool hasTime = !_worldPacket.ReadBit();
+ bool hasSplineElevation = !_worldPacket.ReadBit();
+ bool hasExtraMovementFlags = !_worldPacket.ReadBit();
+ bool hasOrientation = !_worldPacket.ReadBit();
+
+ Data.Status.guid[0] = _worldPacket.ReadBit();
+
+ bool hasTransportTime2 = false;
+ bool hasVehicleId = false;
+ if (hasTransportData)
+ {
+ Data.Status.transport.guid[4] = _worldPacket.ReadBit();
+ Data.Status.transport.guid[3] = _worldPacket.ReadBit();
+ hasTransportTime2 = _worldPacket.ReadBit();
+ hasVehicleId = _worldPacket.ReadBit();
+ Data.Status.transport.guid[5] = _worldPacket.ReadBit();
+ Data.Status.transport.guid[1] = _worldPacket.ReadBit();
+ Data.Status.transport.guid[7] = _worldPacket.ReadBit();
+ Data.Status.transport.guid[2] = _worldPacket.ReadBit();
+ Data.Status.transport.guid[6] = _worldPacket.ReadBit();
+ Data.Status.transport.guid[0] = _worldPacket.ReadBit();
+ }
+
+ if (hasExtraMovementFlags)
+ Data.Status.flags2 = _worldPacket.ReadBits(12);
+
+ if (hasMovementFlags)
+ Data.Status.flags = _worldPacket.ReadBits(30);
+
+ bool hasFallDirection = false;
+ if (hasFallData)
+ hasFallDirection = _worldPacket.ReadBit();
+
+ _worldPacket.ReadByteSeq(Data.Status.guid[0]);
+ _worldPacket.ReadByteSeq(Data.Status.guid[3]);
+ _worldPacket.ReadByteSeq(Data.Status.guid[1]);
+ _worldPacket.ReadByteSeq(Data.Status.guid[5]);
+ _worldPacket.ReadByteSeq(Data.Status.guid[7]);
+ _worldPacket.ReadByteSeq(Data.Status.guid[6]);
+ _worldPacket.ReadByteSeq(Data.Status.guid[2]);
+ _worldPacket.ReadByteSeq(Data.Status.guid[4]);
+
+ if (hasTransportData)
+ {
+ _worldPacket >> Data.Status.transport.pos.m_positionX;
+ _worldPacket.ReadByteSeq(Data.Status.transport.guid[4]);
+
+ if (hasTransportTime2)
+ _worldPacket >> Data.Status.transport.time2;
+
+ _worldPacket.ReadByteSeq(Data.Status.transport.guid[0]);
+ float o = 0.f;
+ _worldPacket >> o;
+ Data.Status.transport.pos.SetOrientation(o);
+ _worldPacket >> Data.Status.transport.pos.m_positionY;
+ _worldPacket.ReadByteSeq(Data.Status.transport.guid[7]);
+ _worldPacket >> Data.Status.transport.seat;
+ _worldPacket.ReadByteSeq(Data.Status.transport.guid[5]);
+ _worldPacket.ReadByteSeq(Data.Status.transport.guid[2]);
+ _worldPacket >> Data.Status.transport.time;
+ _worldPacket.ReadByteSeq(Data.Status.transport.guid[6]);
+ _worldPacket.ReadByteSeq(Data.Status.transport.guid[3]);
+ _worldPacket.ReadByteSeq(Data.Status.transport.guid[1]);
+
+ if (hasVehicleId)
+ _worldPacket >> Data.Status.transport.vehicleId;
+
+ _worldPacket >> Data.Status.transport.pos.m_positionZ;
+ }
+
+ if (hasFallData)
+ {
+ _worldPacket >> Data.Status.jump.zspeed;
+ _worldPacket >> Data.Status.jump.fallTime;
+
+ if (hasFallDirection)
+ {
+ _worldPacket >> Data.Status.jump.cosAngle;
+ _worldPacket >> Data.Status.jump.sinAngle;
+ _worldPacket >> Data.Status.jump.xyspeed;
+ }
+ }
+
+ if (hasTime)
+ _worldPacket >> Data.Status.time;
+ if (hasSplineElevation)
+ _worldPacket >> Data.Status.splineElevation;
+ if (hasOrientation)
+ {
+ float o = 0.f;
+ _worldPacket >> o;
+ Data.Status.pos.SetOrientation(o);
+ }
+ if (hasPitch)
+ _worldPacket >> Data.Status.pitch;
+}
+
WorldPacket const* WorldPackets::Movement::TransferPending::Write()
{
_worldPacket.WriteBit(TransferSpellID.is_initialized());
@@ -229,6 +335,125 @@ WorldPacket const* WorldPackets::Movement::MoveSetCollisionHeight::Write()
return &_worldPacket;
}
+WorldPacket const* WorldPackets::Movement::MoveUpdateCollisionHeight::Write()
+{
+ _worldPacket << float(Status->pos.GetPositionZ());
+ _worldPacket << float(Height);
+ _worldPacket << float(Status->pos.GetPositionX());
+ _worldPacket << float(Status->pos.GetPositionY());
+
+ _worldPacket.WriteBit(Status->guid[6]);
+ _worldPacket.WriteBit(Status->guid[7]);
+ _worldPacket.WriteBit(!Status->HasSplineElevation());
+ _worldPacket.WriteBit(Status->HasTransportData());
+
+ if (Status->HasTransportData())
+ {
+ _worldPacket.WriteBit(Status->transport.guid[6]);
+ _worldPacket.WriteBit(Status->transport.guid[4]);
+ _worldPacket.WriteBit(Status->transport.guid[3]);
+ _worldPacket.WriteBit(Status->transport.guid[7]);
+ _worldPacket.WriteBit(Status->transport.guid[5]);
+ _worldPacket.WriteBit(Status->HasTransportVehicleId());
+ _worldPacket.WriteBit(Status->transport.guid[1]);
+ _worldPacket.WriteBit(Status->transport.guid[0]);
+ _worldPacket.WriteBit(Status->transport.guid[2]);
+ _worldPacket.WriteBit(Status->HasTransportTime2());
+ }
+
+ _worldPacket.WriteBit(Status->guid[3]);
+ _worldPacket.WriteBit(!Status->HasOrientation());
+ _worldPacket.WriteBit(Status->guid[4]);
+ _worldPacket.WriteBit(Status->guid[5]);
+ _worldPacket.WriteBit(!Status->HasTime());
+ _worldPacket.WriteBit(Status->HasFallData());
+ _worldPacket.WriteBit(Status->guid[0]);
+ _worldPacket.WriteBit(!Status->HasPitch());
+ _worldPacket.WriteBit(Status->HasHeightChangeFailed());
+ _worldPacket.WriteBit(Status->guid[2]);
+ _worldPacket.WriteBit(!Status->HasMovementFlags());
+
+ if (Status->HasFallData())
+ _worldPacket.WriteBit(Status->HasFallDirection());
+
+ _worldPacket.WriteBit(Status->guid[1]);
+ _worldPacket.WriteBit(!Status->HasExtraMovementFlags());
+ _worldPacket.WriteBit(Status->HasSpline());
+
+ if (Status->HasExtraMovementFlags())
+ _worldPacket.WriteBits(Status->GetExtraMovementFlags(), 12);
+
+ if (Status->HasMovementFlags())
+ _worldPacket.WriteBits(Status->GetMovementFlags(), 30);
+
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteByteSeq(Status->guid[3]);
+
+ if (Status->HasTransportData())
+ {
+ _worldPacket.WriteByteSeq(Status->transport.guid[7]);
+ _worldPacket << uint32(Status->transport.time);
+ _worldPacket.WriteByteSeq(Status->transport.guid[4]);
+
+ if (Status->HasTransportVehicleId())
+ _worldPacket << uint32(Status->transport.vehicleId);
+
+ if (Status->HasTransportTime2())
+ _worldPacket << uint32(Status->transport.time2);
+
+ _worldPacket.WriteByteSeq(Status->transport.guid[5]);
+ _worldPacket << float(Status->transport.pos.GetOrientation());
+ _worldPacket << float(Status->transport.pos.GetPositionX());
+ _worldPacket.WriteByteSeq(Status->transport.guid[6]);
+ _worldPacket.WriteByteSeq(Status->transport.guid[0]);
+ _worldPacket << float(Status->transport.pos.GetPositionY());
+ _worldPacket.WriteByteSeq(Status->transport.guid[2]);
+ _worldPacket << float(Status->transport.pos.GetPositionZ());
+ _worldPacket.WriteByteSeq(Status->transport.guid[3]);
+ _worldPacket.WriteByteSeq(Status->transport.guid[1]);
+ _worldPacket << int8(Status->transport.seat);
+ }
+
+ if (Status->HasPitch())
+ _worldPacket << float(Status->pitch);
+
+ _worldPacket.WriteByteSeq(Status->guid[6]);
+
+ if (Status->HasFallData())
+ {
+ if (Status->HasFallDirection())
+ {
+ _worldPacket << float(Status->jump.cosAngle);
+ _worldPacket << float(Status->jump.sinAngle);
+ _worldPacket << float(Status->jump.xyspeed);
+ }
+
+ _worldPacket << float(Status->jump.zspeed);
+ _worldPacket << uint32(Status->jump.fallTime);
+ }
+
+ _worldPacket.WriteByteSeq(Status->guid[7]);
+
+ if (Status->HasOrientation())
+ _worldPacket << float(Status->pos.GetOrientation());
+
+ _worldPacket.WriteByteSeq(Status->guid[0]);
+ _worldPacket.WriteByteSeq(Status->guid[5]);
+ _worldPacket.WriteByteSeq(Status->guid[4]);
+
+ if (Status->HasSplineElevation())
+ _worldPacket << float(Status->splineElevation);
+
+ if (Status->HasTime())
+ _worldPacket << uint32(Status->time);
+
+ _worldPacket.WriteByteSeq(Status->guid[2]);
+ _worldPacket.WriteByteSeq(Status->guid[1]);
+
+ return &_worldPacket;
+}
+
WorldPacket const* WorldPackets::Movement::MoveKnockBack::Write()
{
_worldPacket.WriteBit(MoverGUID[0]);
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index 5463273d1d..fad25dbeef 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -26,6 +26,12 @@ namespace WorldPackets
{
namespace Movement
{
+ struct MovementAck
+ {
+ MovementInfo Status;
+ int32 AckIndex = 0;
+ };
+
class TC_GAME_API MoveUpdate final : public ServerPacket
{
public:
@@ -36,6 +42,20 @@ namespace WorldPackets
MovementInfo* Status = nullptr;
};
+ class MoveSetCollisionHeightAck final : public ClientPacket
+ {
+ public:
+ MoveSetCollisionHeightAck(WorldPacket&& packet) : ClientPacket(CMSG_MOVE_SET_COLLISION_HEIGHT_ACK, std::move(packet)) { }
+
+ void Read() override;
+
+ MovementAck Data;
+ UpdateCollisionHeightReason Reason = UPDATE_COLLISION_HEIGHT_MOUNT;
+ float Height = 1.0f;
+ };
+
+
+
class TransferPending final : public ServerPacket
{
struct ShipTransferPending
@@ -99,6 +119,17 @@ namespace WorldPackets
UpdateCollisionHeightReason Reason = UPDATE_COLLISION_HEIGHT_MOUNT;
};
+ class MoveUpdateCollisionHeight final : public ServerPacket
+ {
+ public:
+ MoveUpdateCollisionHeight() : ServerPacket(SMSG_MOVE_UPDATE_COLLISION_HEIGHT) { }
+
+ WorldPacket const* Write() override;
+
+ MovementInfo* Status = nullptr;
+ float Height = 1.0f;
+ };
+
struct MoveKnockBackSpeeds
{
float HorzSpeed = 0.0f;
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 10e2f33658..117d1b42b0 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -143,6 +143,7 @@ namespace WorldPackets
namespace Movement
{
+ class MoveSetCollisionHeightAck;
class SuspendTokenResponse;
}
@@ -651,7 +652,7 @@ class TC_GAME_API WorldSession
void HandleGravityAckMessage(WorldPacket & recvData);
void HandleMoveTeleportAck(WorldPacket& recvPacket);
void HandleForceSpeedChangeAck(WorldPacket& recvData);
- void HandleSetCollisionHeightAck(WorldPacket& recvPacket);
+ void HandleSetCollisionHeightAck(WorldPackets::Movement::MoveSetCollisionHeightAck& packet);
void HandlePingOpcode(WorldPacket& recvPacket);
void HandleRepopRequestOpcode(WorldPacket& recvPacket);