aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Object/MovementInfo.h57
-rw-r--r--src/server/game/Entities/Object/Object.cpp26
-rw-r--r--src/server/game/Entities/Player/Player.cpp12
-rw-r--r--src/server/game/Entities/Player/Player.h1
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp128
-rw-r--r--src/server/game/Entities/Unit/Unit.h8
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp86
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp59
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h77
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp16
-rw-r--r--src/server/game/Server/WorldSession.h7
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp27
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h2
14 files changed, 452 insertions, 56 deletions
diff --git a/src/server/game/Entities/Object/MovementInfo.h b/src/server/game/Entities/Object/MovementInfo.h
index 869429851bd..52941d290ec 100644
--- a/src/server/game/Entities/Object/MovementInfo.h
+++ b/src/server/game/Entities/Object/MovementInfo.h
@@ -20,6 +20,8 @@
#include "ObjectGuid.h"
#include "Position.h"
+#include <algorithm>
+#include <vector>
struct MovementInfo
{
@@ -108,4 +110,59 @@ struct MovementInfo
void OutDebug();
};
+struct MovementForce
+{
+ ObjectGuid ID;
+ TaggedPosition<Position::XYZ> Origin;
+ TaggedPosition<Position::XYZ> Direction;
+ uint32 TransportID = 0;
+ float Magnitude = 0.0f;
+ uint8 Type = 0;
+};
+
+class MovementForces
+{
+public:
+ using Container = std::vector<MovementForce>;
+
+ Container const* GetForces() const { return &_forces; }
+ bool Add(MovementForce const& newForce)
+ {
+ auto itr = FindMovementForce(newForce.ID);
+ if (itr == _forces.end())
+ {
+ _forces.push_back(newForce);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool Remove(ObjectGuid id)
+ {
+ auto itr = FindMovementForce(id);
+ if (itr != _forces.end())
+ {
+ _forces.erase(itr);
+ return true;
+ }
+
+ return false;
+ }
+
+ float GetModMagnitude() const { return _modMagnitude; }
+ void SetModMagnitude(float modMagnitude) { _modMagnitude = modMagnitude; }
+
+ bool IsEmpty() const { return _forces.empty() && _modMagnitude == 1.0f; }
+
+private:
+ Container::iterator FindMovementForce(ObjectGuid id)
+ {
+ return std::find_if(_forces.begin(), _forces.end(), [id](MovementForce const& force) { return force.ID == id; });
+ }
+
+ Container _forces;
+ float _modMagnitude = 1.0f;
+};
+
#endif // MovementInfo_h__
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 41e5e62f395..a2b5da60d1c 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -367,23 +367,23 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags) const
*data << float(unit->GetSpeed(MOVE_TURN_RATE));
*data << float(unit->GetSpeed(MOVE_PITCH_RATE));
- *data << uint32(0); // unit->m_movementInfo.forces.size()
-
- *data << float(1.0f); // MovementForcesModMagnitude
+ if (MovementForces const* movementForces = unit->GetMovementForces())
+ {
+ *data << uint32(movementForces->GetForces()->size());
+ *data << float(movementForces->GetModMagnitude()); // MovementForcesModMagnitude
+ }
+ else
+ {
+ *data << uint32(0);
+ *data << float(1.0f); // MovementForcesModMagnitude
+ }
data->WriteBit(HasSpline);
data->FlushBits();
- //for (std::size_t i = 0; i < unit->m_movementInfo.forces.size(); ++i)
- //{
- // *data << ObjectGuid(ID);
- // *data << Vector3(Origin);
- // *data << Vector3(Direction);
- // *data << uint32(TransportID);
- // *data << float(Magnitude);
- // data->WriteBits(Type, 2);
- // data->FlushBits();
- //}
+ if (MovementForces const* movementForces = unit->GetMovementForces())
+ for (MovementForce const& force : *movementForces->GetForces())
+ *data << force;
if (HasSpline)
WorldPackets::Movement::CommonMovement::WriteCreateObjectSplineDataBlock(*unit->movespline, *data);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 2d61bd36c50..3d2acb15a7c 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -251,6 +251,8 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this)
for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i)
m_forced_speed_changes[i] = 0;
+ m_movementForceModMagnitudeChanges = 0;
+
m_stableSlots = 0;
/////////////////// Instance System /////////////////////
@@ -27836,7 +27838,7 @@ void Player::ValidateMovementInfo(MovementInfo* mi)
mi->RemoveMovementFlag((maskToRemove));
#endif
- if (!GetVehicleBase() || !(GetVehicle()->GetVehicleInfo()->Flags & VEHICLE_FLAG_FIXED_POSITION))
+ 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
@@ -27847,7 +27849,7 @@ void Player::ValidateMovementInfo(MovementInfo* mi)
MOVEMENTFLAG_MASK_MOVING);
//! Cannot hover without SPELL_AURA_HOVER
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !HasAuraType(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
@@ -27872,12 +27874,12 @@ void Player::ValidateMovementInfo(MovementInfo* mi)
//! 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),
+ !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) && !HasAuraType(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.
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 879b7499e10..83a0e5fb60c 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2162,6 +2162,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow);
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
+ uint8 m_movementForceModMagnitudeChanges;
bool HasAtLoginFlag(AtLoginFlags f) const { return (m_atLoginFlags & f) != 0; }
void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; }
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 89d545458ca..54d583f0437 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -13110,6 +13110,8 @@ void Unit::SendTeleportPacket(Position const& pos)
WorldPackets::Movement::MoveUpdateTeleport moveUpdateTeleport;
moveUpdateTeleport.Status = &m_movementInfo;
+ if (_movementForces)
+ moveUpdateTeleport.MovementForces = _movementForces->GetForces();
Unit* broadcastSource = this;
if (Player* playerMover = GetPlayerBeingMoved())
@@ -13898,6 +13900,132 @@ void Unit::SendSetVehicleRecId(uint32 vehicleId)
SendMessageToSet(setVehicleRec.Write(), true);
}
+void Unit::ApplyMovementForce(ObjectGuid id, Position origin, float magnitude, uint8 type, Position direction /*= {}*/, ObjectGuid transportGuid /*= ObjectGuid::Empty*/)
+{
+ if (!_movementForces)
+ _movementForces = Trinity::make_unique<MovementForces>();
+
+ MovementForce force;
+ force.ID = id;
+ force.Origin = origin;
+ force.Direction = direction;
+ if (transportGuid.IsMOTransport())
+ force.TransportID = transportGuid.GetCounter();
+
+ force.Magnitude = magnitude;
+ force.Type = type;
+
+ if (_movementForces->Add(force))
+ {
+ if (Player const* movingPlayer = GetPlayerMovingMe())
+ {
+ WorldPackets::Movement::MoveApplyMovementForce applyMovementForce;
+ applyMovementForce.MoverGUID = GetGUID();
+ applyMovementForce.SequenceIndex = m_movementCounter++;
+ applyMovementForce.Force = &force;
+ movingPlayer->SendDirectMessage(applyMovementForce.Write());
+ }
+ else
+ {
+ WorldPackets::Movement::MoveUpdateApplyMovementForce updateApplyMovementForce;
+ updateApplyMovementForce.Status = &m_movementInfo;
+ updateApplyMovementForce.Force = &force;
+ SendMessageToSet(updateApplyMovementForce.Write(), true);
+ }
+ }
+}
+
+void Unit::RemoveMovementForce(ObjectGuid id)
+{
+ if (!_movementForces)
+ return;
+
+ if (_movementForces->Remove(id))
+ {
+ if (Player const* movingPlayer = GetPlayerMovingMe())
+ {
+ WorldPackets::Movement::MoveRemoveMovementForce moveRemoveMovementForce;
+ moveRemoveMovementForce.MoverGUID = GetGUID();
+ moveRemoveMovementForce.SequenceIndex = m_movementCounter++;
+ moveRemoveMovementForce.ID = id;
+ movingPlayer->SendDirectMessage(moveRemoveMovementForce.Write());
+ }
+ else
+ {
+ WorldPackets::Movement::MoveUpdateRemoveMovementForce updateRemoveMovementForce;
+ updateRemoveMovementForce.Status = &m_movementInfo;
+ updateRemoveMovementForce.TriggerGUID = id;
+ SendMessageToSet(updateRemoveMovementForce.Write(), true);
+ }
+ }
+
+ if (_movementForces->IsEmpty())
+ _movementForces.reset();
+}
+
+bool Unit::SetIgnoreMovementForces(bool ignore)
+{
+ if (ignore == HasExtraUnitMovementFlag(MOVEMENTFLAG2_IGNORE_MOVEMENT_FORCES))
+ return false;
+
+ if (ignore)
+ AddExtraUnitMovementFlag(MOVEMENTFLAG2_IGNORE_MOVEMENT_FORCES);
+ else
+ RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_IGNORE_MOVEMENT_FORCES);
+
+ static OpcodeServer const ignoreMovementForcesOpcodeTable[2] =
+ {
+ SMSG_MOVE_UNSET_IGNORE_MOVEMENT_FORCES,
+ SMSG_MOVE_SET_IGNORE_MOVEMENT_FORCES
+ };
+
+ if (Player const* movingPlayer = GetPlayerMovingMe())
+ {
+ WorldPackets::Movement::MoveSetFlag packet(ignoreMovementForcesOpcodeTable[ignore]);
+ packet.MoverGUID = GetGUID();
+ packet.SequenceIndex = m_movementCounter++;
+ movingPlayer->SendDirectMessage(packet.Write());
+
+ WorldPackets::Movement::MoveUpdate moveUpdate;
+ moveUpdate.Status = &m_movementInfo;
+ SendMessageToSet(moveUpdate.Write(), movingPlayer);
+ }
+
+ return true;
+}
+
+void Unit::UpdateMovementForcesModMagnitude()
+{
+ float modMagnitude = GetTotalAuraMultiplier(SPELL_AURA_MOD_MOVEMENT_FORCE_MAGNITUDE);
+
+ if (Player* movingPlayer = GetPlayerMovingMe())
+ {
+ WorldPackets::Movement::MoveSetSpeed setModMovementForceMagnitude(SMSG_MOVE_SET_MOD_MOVEMENT_FORCE_MAGNITUDE);
+ setModMovementForceMagnitude.MoverGUID = GetGUID();
+ setModMovementForceMagnitude.SequenceIndex = m_movementCounter++;
+ setModMovementForceMagnitude.Speed = modMagnitude;
+ movingPlayer->SendDirectMessage(setModMovementForceMagnitude.Write());
+ ++movingPlayer->m_movementForceModMagnitudeChanges;
+ }
+ else
+ {
+ WorldPackets::Movement::MoveUpdateSpeed updateModMovementForceMagnitude(SMSG_MOVE_UPDATE_MOD_MOVEMENT_FORCE_MAGNITUDE);
+ updateModMovementForceMagnitude.Status = &m_movementInfo;
+ updateModMovementForceMagnitude.Speed = modMagnitude;
+ SendMessageToSet(updateModMovementForceMagnitude.Write(), true);
+ }
+
+ if (modMagnitude != 1.0f && !_movementForces)
+ _movementForces = Trinity::make_unique<MovementForces>();
+
+ if (_movementForces)
+ {
+ _movementForces->SetModMagnitude(modMagnitude);
+ if (_movementForces->IsEmpty())
+ _movementForces.reset();
+ }
+}
+
void Unit::SendSetPlayHoverAnim(bool enable)
{
WorldPackets::Misc::SetPlayHoverAnim data;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 14a66db986d..e4b5a803163 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1378,6 +1378,12 @@ class TC_GAME_API Unit : public WorldObject
bool SetCanDoubleJump(bool enable);
void SendSetVehicleRecId(uint32 vehicleId);
+ MovementForces const* GetMovementForces() const { return _movementForces.get(); }
+ void ApplyMovementForce(ObjectGuid id, Position origin, float magnitude, uint8 type, Position direction = {}, ObjectGuid transportGuid = ObjectGuid::Empty);
+ void RemoveMovementForce(ObjectGuid id);
+ bool SetIgnoreMovementForces(bool ignore);
+ void UpdateMovementForcesModMagnitude();
+
void SetInFront(WorldObject const* target);
void SetFacingTo(float ori, bool force = false);
void SetFacingToObject(WorldObject const* object, bool force = false);
@@ -2131,6 +2137,8 @@ class TC_GAME_API Unit : public WorldObject
uint16 _meleeAnimKitId;
SpellHistory* _spellHistory;
+
+ std::unique_ptr<MovementForces> _movementForces;
};
namespace Trinity
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 9ff173b8add..465a1e49239 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -572,6 +572,92 @@ void WorldSession::HandleSetCollisionHeightAck(WorldPackets::Movement::MoveSetCo
GetPlayer()->ValidateMovementInfo(&setCollisionHeightAck.Data.Status);
}
+void WorldSession::HandleMoveApplyMovementForceAck(WorldPackets::Movement::MoveApplyMovementForceAck& moveApplyMovementForceAck)
+{
+ Unit* mover = _player->m_unitMovedByMe;
+ ASSERT(mover != nullptr);
+ _player->ValidateMovementInfo(&moveApplyMovementForceAck.Ack.Status);
+
+ // prevent tampered movement data
+ if (moveApplyMovementForceAck.Ack.Status.guid != mover->GetGUID())
+ {
+ TC_LOG_ERROR("network", "HandleMoveApplyMovementForceAck: guid error, expected %s, got %s",
+ mover->GetGUID().ToString().c_str(), moveApplyMovementForceAck.Ack.Status.guid.ToString().c_str());
+ return;
+ }
+
+ moveApplyMovementForceAck.Ack.Status.time += m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY;
+
+ WorldPackets::Movement::MoveUpdateApplyMovementForce updateApplyMovementForce;
+ updateApplyMovementForce.Status = &moveApplyMovementForceAck.Ack.Status;
+ updateApplyMovementForce.Force = &moveApplyMovementForceAck.Force;
+ mover->SendMessageToSet(updateApplyMovementForce.Write(), false);
+}
+
+void WorldSession::HandleMoveRemoveMovementForceAck(WorldPackets::Movement::MoveRemoveMovementForceAck& moveRemoveMovementForceAck)
+{
+ Unit* mover = _player->m_unitMovedByMe;
+ ASSERT(mover != nullptr);
+ _player->ValidateMovementInfo(&moveRemoveMovementForceAck.Ack.Status);
+
+ // prevent tampered movement data
+ if (moveRemoveMovementForceAck.Ack.Status.guid != mover->GetGUID())
+ {
+ TC_LOG_ERROR("network", "HandleMoveRemoveMovementForceAck: guid error, expected %s, got %s",
+ mover->GetGUID().ToString().c_str(), moveRemoveMovementForceAck.Ack.Status.guid.ToString().c_str());
+ return;
+ }
+
+ moveRemoveMovementForceAck.Ack.Status.time += m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY;
+
+ WorldPackets::Movement::MoveUpdateRemoveMovementForce updateRemoveMovementForce;
+ updateRemoveMovementForce.Status = &moveRemoveMovementForceAck.Ack.Status;
+ updateRemoveMovementForce.TriggerGUID = moveRemoveMovementForceAck.ID;
+ mover->SendMessageToSet(updateRemoveMovementForce.Write(), false);
+}
+
+void WorldSession::HandleMoveSetModMovementForceMagnitudeAck(WorldPackets::Movement::MovementSpeedAck& setModMovementForceMagnitudeAck)
+{
+ Unit* mover = _player->m_unitMovedByMe;
+ ASSERT(mover != nullptr); // there must always be a mover
+ _player->ValidateMovementInfo(&setModMovementForceMagnitudeAck.Ack.Status);
+
+ // prevent tampered movement data
+ if (setModMovementForceMagnitudeAck.Ack.Status.guid != mover->GetGUID())
+ {
+ TC_LOG_ERROR("network", "HandleSetModMovementForceMagnitudeAck: guid error, expected %s, got %s",
+ mover->GetGUID().ToString().c_str(), setModMovementForceMagnitudeAck.Ack.Status.guid.ToString().c_str());
+ return;
+ }
+
+ // skip all except last
+ if (_player->m_movementForceModMagnitudeChanges > 0)
+ {
+ --_player->m_movementForceModMagnitudeChanges;
+ if (!_player->m_movementForceModMagnitudeChanges)
+ {
+ float expectedModMagnitude = 1.0f;
+ if (MovementForces const* movementForces = mover->GetMovementForces())
+ expectedModMagnitude = movementForces->GetModMagnitude();
+
+ if (std::fabs(expectedModMagnitude - setModMovementForceMagnitudeAck.Speed) > 0.01f)
+ {
+ TC_LOG_DEBUG("misc", "Player %s from account id %u kicked for incorrect movement force magnitude (must be %f instead %f)",
+ _player->GetName().c_str(), _player->GetSession()->GetAccountId(), expectedModMagnitude, setModMovementForceMagnitudeAck.Speed);
+ _player->GetSession()->KickPlayer();
+ return;
+ }
+ }
+ }
+
+ setModMovementForceMagnitudeAck.Ack.Status.time += m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY;
+
+ WorldPackets::Movement::MoveUpdateSpeed updateModMovementForceMagnitude(SMSG_MOVE_UPDATE_MOD_MOVEMENT_FORCE_MAGNITUDE);
+ updateModMovementForceMagnitude.Status = &setModMovementForceMagnitudeAck.Ack.Status;
+ updateModMovementForceMagnitude.Speed = setModMovementForceMagnitudeAck.Speed;
+ mover->SendMessageToSet(updateModMovementForceMagnitude.Write(), false);
+}
+
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPackets::Movement::MoveTimeSkipped& /*moveTimeSkipped*/)
{
}
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index c14d96e0964..943d312dffb 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -579,7 +579,7 @@ WorldPacket const* WorldPackets::Movement::MoveTeleport::Write()
return &_worldPacket;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementForce const& movementForce)
+ByteBuffer& operator<<(ByteBuffer& data, MovementForce const& movementForce)
{
data << movementForce.ID;
data << movementForce.Origin;
@@ -592,11 +592,23 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementForce c
return data;
}
+ByteBuffer& operator>>(ByteBuffer& data, MovementForce& movementForce)
+{
+ data >> movementForce.ID;
+ data >> movementForce.Origin;
+ data >> movementForce.Direction;
+ data >> movementForce.TransportID;
+ data >> movementForce.Magnitude;
+ movementForce.Type = data.ReadBits(2);
+
+ return data;
+}
+
WorldPacket const* WorldPackets::Movement::MoveUpdateTeleport::Write()
{
_worldPacket << *Status;
- _worldPacket << uint32(MovementForces.size());
+ _worldPacket << uint32(MovementForces ? MovementForces->size() : 0);
_worldPacket.WriteBit(WalkSpeed.is_initialized());
_worldPacket.WriteBit(RunSpeed.is_initialized());
_worldPacket.WriteBit(RunBackSpeed.is_initialized());
@@ -608,8 +620,9 @@ WorldPacket const* WorldPackets::Movement::MoveUpdateTeleport::Write()
_worldPacket.WriteBit(PitchRate.is_initialized());
_worldPacket.FlushBits();
- for (WorldPackets::Movement::MovementForce const& force : MovementForces)
- _worldPacket << force;
+ if (MovementForces)
+ for (MovementForce const& force : *MovementForces)
+ _worldPacket << force;
if (WalkSpeed)
_worldPacket << *WalkSpeed;
@@ -745,18 +758,48 @@ WorldPacket const* WorldPackets::Movement::MoveUpdateCollisionHeight::Write()
return &_worldPacket;
}
-WorldPacket const* WorldPackets::Movement::MoveUpdateRemoveMovementForce::Write()
+WorldPacket const* WorldPackets::Movement::MoveApplyMovementForce::Write()
{
- _worldPacket << *Status;
- _worldPacket << TriggerGUID;
+ _worldPacket << MoverGUID;
+ _worldPacket << SequenceIndex;
+ _worldPacket << *Force;
return &_worldPacket;
}
+void WorldPackets::Movement::MoveApplyMovementForceAck::Read()
+{
+ _worldPacket >> Ack;
+ _worldPacket >> Force;
+}
+
+WorldPacket const* WorldPackets::Movement::MoveRemoveMovementForce::Write()
+{
+ _worldPacket << MoverGUID;
+ _worldPacket << SequenceIndex;
+ _worldPacket << ID;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Movement::MoveRemoveMovementForceAck::Read()
+{
+ _worldPacket >> Ack;
+ _worldPacket >> ID;
+}
+
WorldPacket const* WorldPackets::Movement::MoveUpdateApplyMovementForce::Write()
{
_worldPacket << *Status;
- _worldPacket << Force;
+ _worldPacket << *Force;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Movement::MoveUpdateRemoveMovementForce::Write()
+{
+ _worldPacket << *Status;
+ _worldPacket << TriggerGUID;
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index f806551c24c..47197949c55 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -33,6 +33,12 @@ namespace WorldPackets
{
namespace Movement
{
+ struct MovementAck
+ {
+ MovementInfo Status;
+ int32 AckIndex = 0;
+ };
+
class ClientPlayerMovement final : public ClientPacket
{
public:
@@ -269,16 +275,6 @@ namespace WorldPackets
uint8 PreloadWorld = 0;
};
- struct MovementForce
- {
- ObjectGuid ID;
- TaggedPosition<Position::XYZ> Origin;
- TaggedPosition<Position::XYZ> Direction;
- uint32 TransportID = 0;
- float Magnitude = 0;
- uint8 Type = 0;
- };
-
class MoveUpdateTeleport final : public ServerPacket
{
public:
@@ -287,7 +283,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
MovementInfo* Status = nullptr;
- std::vector<MovementForce> MovementForces;
+ ::MovementForces::Container const* MovementForces = nullptr;
Optional<float> SwimBackSpeed;
Optional<float> FlightSpeed;
Optional<float> SwimSpeed;
@@ -299,21 +295,67 @@ namespace WorldPackets
Optional<float> PitchRate;
};
+ class MoveApplyMovementForce final : public ServerPacket
+ {
+ public:
+ MoveApplyMovementForce() : ServerPacket(SMSG_MOVE_APPLY_MOVEMENT_FORCE, 16 + 4 + 16 + 12 + 12 + 4 + 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid MoverGUID;
+ int32 SequenceIndex = 0;
+ MovementForce const* Force = nullptr;
+ };
+
+ class MoveApplyMovementForceAck final : public ClientPacket
+ {
+ public:
+ MoveApplyMovementForceAck(WorldPacket&& packet) : ClientPacket(CMSG_MOVE_APPLY_MOVEMENT_FORCE_ACK, std::move(packet)) { }
+
+ void Read() override;
+
+ MovementAck Ack;
+ MovementForce Force;
+ };
+
+ class MoveRemoveMovementForce final : public ServerPacket
+ {
+ public:
+ MoveRemoveMovementForce() : ServerPacket(SMSG_MOVE_REMOVE_MOVEMENT_FORCE, 16 + 4 + 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid MoverGUID;
+ int32 SequenceIndex = 0;
+ ObjectGuid ID;
+ };
+
+ class MoveRemoveMovementForceAck final : public ClientPacket
+ {
+ public:
+ MoveRemoveMovementForceAck(WorldPacket&& packet) : ClientPacket(CMSG_MOVE_REMOVE_MOVEMENT_FORCE_ACK, std::move(packet)) { }
+
+ void Read() override;
+
+ MovementAck Ack;
+ ObjectGuid ID;
+ };
+
class MoveUpdateApplyMovementForce final : public ServerPacket
{
public:
- MoveUpdateApplyMovementForce() : ServerPacket(SMSG_MOVE_UPDATE_APPLY_MOVEMENT_FORCE) { }
+ MoveUpdateApplyMovementForce() : ServerPacket(SMSG_MOVE_UPDATE_APPLY_MOVEMENT_FORCE, sizeof(MovementInfo) + 16 + 12 + 12 + 4 + 4 + 1) { }
WorldPacket const* Write() override;
MovementInfo* Status = nullptr;
- MovementForce Force;
+ MovementForce const* Force = nullptr;
};
class MoveUpdateRemoveMovementForce final : public ServerPacket
{
public:
- MoveUpdateRemoveMovementForce() : ServerPacket(SMSG_MOVE_UPDATE_REMOVE_MOVEMENT_FORCE) { }
+ MoveUpdateRemoveMovementForce() : ServerPacket(SMSG_MOVE_UPDATE_REMOVE_MOVEMENT_FORCE, sizeof(MovementInfo) + 16) { }
WorldPacket const* Write() override;
@@ -333,12 +375,6 @@ namespace WorldPackets
int32 MoveTime = 0;
};
- struct MovementAck
- {
- MovementInfo Status;
- int32 AckIndex = 0;
- };
-
class MovementAckMessage final : public ClientPacket
{
public:
@@ -616,5 +652,6 @@ ByteBuffer& operator<<(ByteBuffer& data, MovementInfo const& movementInfo);
ByteBuffer& operator>>(ByteBuffer& data, MovementInfo::TransportInfo& transportInfo);
ByteBuffer& operator<<(ByteBuffer& data, MovementInfo::TransportInfo const& transportInfo);
ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Movement::MovementAck& movementAck);
+ByteBuffer& operator<<(ByteBuffer& data, MovementForce const& movementForce);
#endif // MovementPackets_h__
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 13306152bcd..0cf5e036ac4 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -542,7 +542,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_MOUNT_CLEAR_FANFARE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_MOUNT_SET_FAVORITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSetFavorite);
DEFINE_HANDLER(CMSG_MOUNT_SPECIAL_ANIM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode);
- DEFINE_HANDLER(CMSG_MOVE_APPLY_MOVEMENT_FORCE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_MOVE_APPLY_MOVEMENT_FORCE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveApplyMovementForceAck);
DEFINE_HANDLER(CMSG_MOVE_CHANGE_TRANSPORT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes);
DEFINE_HANDLER(CMSG_MOVE_CHANGE_VEHICLE_SEATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveChangeVehicleSeats);
DEFINE_HANDLER(CMSG_MOVE_DISMISS_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveDismissVehicle);
@@ -570,7 +570,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_MOVE_JUMP, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes);
DEFINE_HANDLER(CMSG_MOVE_KNOCK_BACK_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveKnockBackAck);
DEFINE_HANDLER(CMSG_MOVE_REMOVE_MOVEMENT_FORCES, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL);
- DEFINE_HANDLER(CMSG_MOVE_REMOVE_MOVEMENT_FORCE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_MOVE_REMOVE_MOVEMENT_FORCE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveRemoveMovementForceAck);
DEFINE_HANDLER(CMSG_MOVE_SEAMLESS_TRANSFER_COMPLETE, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_MOVE_SET_CAN_FLY_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementAckMessage);
DEFINE_HANDLER(CMSG_MOVE_SET_CAN_TURN_WHILE_FALLING_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementAckMessage);
@@ -578,7 +578,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_MOVE_SET_FACING, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes);
DEFINE_HANDLER(CMSG_MOVE_SET_FLY, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes);
DEFINE_HANDLER(CMSG_MOVE_SET_IGNORE_MOVEMENT_FORCES_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementAckMessage);
- DEFINE_HANDLER(CMSG_MOVE_SET_MOD_MOVEMENT_FORCE_MAGNITUDE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_MOVE_SET_MOD_MOVEMENT_FORCE_MAGNITUDE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetModMovementForceMagnitudeAck);
DEFINE_HANDLER(CMSG_MOVE_SET_PITCH, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes);
DEFINE_HANDLER(CMSG_MOVE_SET_RUN_MODE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes);
DEFINE_HANDLER(CMSG_MOVE_SET_VEHICLE_REC_ID_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetVehicleRecAck);
@@ -1444,7 +1444,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNT_EQUIPMENT_APPLY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_APPLY_MOVEMENT_FORCE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_APPLY_MOVEMENT_FORCE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_COLLISION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_DOUBLE_JUMP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_GRAVITY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1454,7 +1454,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_GRAVITY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_REMOVE_MOVEMENT_FORCE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_REMOVE_MOVEMENT_FORCE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ROOT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_ACTIVE_MOVER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1465,9 +1465,9 @@ void OpcodeTable::Initialize()
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);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_HOVERING, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_IGNORE_MOVEMENT_FORCES, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_IGNORE_MOVEMENT_FORCES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_LAND_WALK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_MOD_MOVEMENT_FORCE_MAGNITUDE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_MOD_MOVEMENT_FORCE_MAGNITUDE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_NORMAL_FALL, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_PITCH_RATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1518,7 +1518,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_MOD_MOVEMENT_FORCE_MAGNITUDE,STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_MOD_MOVEMENT_FORCE_MAGNITUDE,STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_REMOVE_MOVEMENT_FORCE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 5607e6c375b..52f6766d7ff 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -479,6 +479,8 @@ namespace WorldPackets
class SummonResponse;
class MoveSplineDone;
class SuspendTokenResponse;
+ class MoveApplyMovementForceAck;
+ class MoveRemoveMovementForceAck;
}
namespace NPC
@@ -1163,6 +1165,11 @@ class TC_GAME_API WorldSession
void HandleForceSpeedChangeAck(WorldPackets::Movement::MovementSpeedAck& packet);
void HandleSetCollisionHeightAck(WorldPackets::Movement::MoveSetCollisionHeightAck& setCollisionHeightAck);
+ // Movement forces
+ void HandleMoveApplyMovementForceAck(WorldPackets::Movement::MoveApplyMovementForceAck& moveApplyMovementForceAck);
+ void HandleMoveRemoveMovementForceAck(WorldPackets::Movement::MoveRemoveMovementForceAck& moveRemoveMovementForceAck);
+ void HandleMoveSetModMovementForceMagnitudeAck(WorldPackets::Movement::MovementSpeedAck& setModMovementForceMagnitudeAck);
+
void HandleRepopRequest(WorldPackets::Misc::RepopRequest& packet);
void HandleAutostoreLootItemOpcode(WorldPackets::Loot::LootItem& packet);
void HandleLootMoneyOpcode(WorldPackets::Loot::LootMoney& packet);
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index 8d83c108304..5590a396a5f 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -555,7 +555,7 @@ enum AuraType : uint32
SPELL_AURA_482 = 482,
SPELL_AURA_SUPPRESS_TRANSFORMS = 483, // NYI
SPELL_AURA_484 = 484,
- SPELL_AURA_485 = 485,
+ SPELL_AURA_MOD_MOVEMENT_FORCE_MAGNITUDE = 485,
SPELL_AURA_486 = 486,
SPELL_AURA_487 = 487,
SPELL_AURA_488 = 488,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 77cc228683b..dd155e91952 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -551,7 +551,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //482
&AuraEffect::HandleNULL, //483 SPELL_AURA_SUPPRESS_TRANSFORMS
&AuraEffect::HandleNULL, //484
- &AuraEffect::HandleNULL, //485
+ &AuraEffect::HandleModMovementForceMagnitude, //485 SPELL_AURA_MOD_MOVEMENT_FORCE_MAGNITUDE
&AuraEffect::HandleNULL, //486
&AuraEffect::HandleNULL, //487
&AuraEffect::HandleNULL, //488
@@ -2693,6 +2693,23 @@ void AuraEffect::HandleAuraCanTurnWhileFalling(AuraApplication const* aurApp, ui
target->SetCanTurnWhileFalling(apply);
}
+void AuraEffect::HandleIgnoreMovementForces(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit* target = aurApp->GetTarget();
+
+ if (!apply)
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if (target->HasAuraType(GetAuraType()))
+ return;
+ }
+
+ target->SetIgnoreMovementForces(apply);
+}
+
/****************************/
/*** THREAT ***/
/****************************/
@@ -3061,6 +3078,14 @@ void AuraEffect::HandleAuraModMinimumSpeedRate(AuraApplication const* aurApp, ui
target->UpdateSpeed(MOVE_RUN);
}
+void AuraEffect::HandleModMovementForceMagnitude(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ aurApp->GetTarget()->UpdateMovementForcesModMagnitude();
+}
+
/*********************************************************/
/*** IMMUNITY ***/
/*********************************************************/
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index a9d8ea4a52c..829cfa4cd26 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -187,6 +187,7 @@ class TC_GAME_API AuraEffect
void HandleWaterBreathing(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleForceMoveForward(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraCanTurnWhileFalling(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleIgnoreMovementForces(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// threat
void HandleModThreat(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModTotalThreat(AuraApplication const* aurApp, uint8 mode, bool apply) const;
@@ -211,6 +212,7 @@ class TC_GAME_API AuraEffect
void HandleAuraModDecreaseSpeed(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModUseNormalSpeed(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModMinimumSpeedRate(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleModMovementForceMagnitude(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// immunity
void HandleModMechanicImmunityMask(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleModMechanicImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const;