Core/Movement: Implemented movement forces
Port From (https://github.com/TrinityCore/TrinityCore/commit/8e98ceb2936842ea0032cbfdc04a510d6b1e5de0)
This commit is contained in:
@@ -506,7 +506,7 @@ namespace Framework.Constants
|
|||||||
Unk482 = 482,
|
Unk482 = 482,
|
||||||
SuppressTransforms = 483, // NYI
|
SuppressTransforms = 483, // NYI
|
||||||
Unk484 = 484,
|
Unk484 = 484,
|
||||||
Unk485 = 485,
|
ModMovementForceMagnitude = 485,
|
||||||
Unk486 = 486,
|
Unk486 = 486,
|
||||||
Unk487 = 487,
|
Unk487 = 487,
|
||||||
Unk488 = 488,
|
Unk488 = 488,
|
||||||
|
|||||||
@@ -336,21 +336,24 @@ namespace Game.Entities
|
|||||||
data.WriteFloat(unit.GetSpeed(UnitMoveType.TurnRate));
|
data.WriteFloat(unit.GetSpeed(UnitMoveType.TurnRate));
|
||||||
data.WriteFloat(unit.GetSpeed(UnitMoveType.PitchRate));
|
data.WriteFloat(unit.GetSpeed(UnitMoveType.PitchRate));
|
||||||
|
|
||||||
data.WriteUInt32(0); // unit.m_movementInfo.forces.size()
|
MovementForces movementForces = unit.GetMovementForces();
|
||||||
data.WriteFloat(1.0f); // MovementForcesModMagnitude
|
if (movementForces != null)
|
||||||
|
{
|
||||||
|
data.WriteInt32(movementForces.GetForces().Count);
|
||||||
|
data.WriteFloat(movementForces.GetModMagnitude()); // MovementForcesModMagnitude
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.WriteUInt32(0);
|
||||||
|
data.WriteFloat(1.0f); // MovementForcesModMagnitude
|
||||||
|
}
|
||||||
|
|
||||||
data.WriteBit(HasSpline);
|
data.WriteBit(HasSpline);
|
||||||
data.FlushBits();
|
data.FlushBits();
|
||||||
|
|
||||||
//for (public uint i = 0; i < unit.m_movementInfo.forces.Count; ++i)
|
if (movementForces != null)
|
||||||
//{
|
foreach (MovementForce force in movementForces.GetForces())
|
||||||
// *data << ObjectGuid(ID);
|
MovementExtensions.WriteMovementForceWithDirection(force, data, unit);
|
||||||
// *data << Vector3(Origin);
|
|
||||||
// *data << Vector3(Direction);
|
|
||||||
// *data << uint32(TransportID);
|
|
||||||
// *data.WriteFloat(Magnitude);
|
|
||||||
// *data.WriteBits(Type, 2);
|
|
||||||
//}
|
|
||||||
|
|
||||||
// HasMovementSpline - marks that spline data is present in packet
|
// HasMovementSpline - marks that spline data is present in packet
|
||||||
if (HasSpline)
|
if (HasSpline)
|
||||||
@@ -2460,6 +2463,74 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MovementForce
|
||||||
|
{
|
||||||
|
public ObjectGuid ID;
|
||||||
|
public Vector3 Origin;
|
||||||
|
public Vector3 Direction;
|
||||||
|
public uint TransportID;
|
||||||
|
public float Magnitude;
|
||||||
|
public byte Type;
|
||||||
|
|
||||||
|
public void Read(WorldPacket data)
|
||||||
|
{
|
||||||
|
ID = data.ReadPackedGuid();
|
||||||
|
Origin = data.ReadVector3();
|
||||||
|
Direction = data.ReadVector3();
|
||||||
|
TransportID = data.ReadUInt32();
|
||||||
|
Magnitude = data.ReadFloat();
|
||||||
|
Type = data.ReadBits<byte>(2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(WorldPacket data)
|
||||||
|
{
|
||||||
|
MovementExtensions.WriteMovementForceWithDirection(this, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MovementForces
|
||||||
|
{
|
||||||
|
List<MovementForce> _forces = new List<MovementForce>();
|
||||||
|
float _modMagnitude = 1.0f;
|
||||||
|
|
||||||
|
public List<MovementForce> GetForces() { return _forces; }
|
||||||
|
|
||||||
|
public bool Add(MovementForce newForce)
|
||||||
|
{
|
||||||
|
var movementForce = FindMovementForce(newForce.ID);
|
||||||
|
if (movementForce == null)
|
||||||
|
{
|
||||||
|
_forces.Add(newForce);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Remove(ObjectGuid id)
|
||||||
|
{
|
||||||
|
var movementForce = FindMovementForce(id);
|
||||||
|
if (movementForce != null)
|
||||||
|
{
|
||||||
|
_forces.Remove(movementForce);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetModMagnitude() { return _modMagnitude; }
|
||||||
|
public void SetModMagnitude(float modMagnitude) { _modMagnitude = modMagnitude; }
|
||||||
|
|
||||||
|
public bool IsEmpty() { return _forces.Empty() && _modMagnitude == 1.0f; }
|
||||||
|
|
||||||
|
MovementForce FindMovementForce(ObjectGuid id)
|
||||||
|
{
|
||||||
|
return _forces.Find(force => force.ID == id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct CreateObjectBits
|
public struct CreateObjectBits
|
||||||
{
|
{
|
||||||
public bool NoBirthAnim;
|
public bool NoBirthAnim;
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ namespace Game.Entities
|
|||||||
//Movement
|
//Movement
|
||||||
public PlayerTaxi m_taxi = new PlayerTaxi();
|
public PlayerTaxi m_taxi = new PlayerTaxi();
|
||||||
public byte[] m_forced_speed_changes = new byte[(int)UnitMoveType.Max];
|
public byte[] m_forced_speed_changes = new byte[(int)UnitMoveType.Max];
|
||||||
|
public byte m_movementForceModMagnitudeChanges;
|
||||||
uint m_lastFallTime;
|
uint m_lastFallTime;
|
||||||
float m_lastFallZ;
|
float m_lastFallZ;
|
||||||
WorldLocation teleportDest;
|
WorldLocation teleportDest;
|
||||||
|
|||||||
@@ -1972,7 +1972,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!GetVehicleBase() || !GetVehicle().GetVehicleInfo().Flags.HasAnyFlag(VehicleFlags.FixedPosition))
|
if (!m_unitMovedByMe.GetVehicleBase() || !m_unitMovedByMe.GetVehicle().GetVehicleInfo().Flags.HasAnyFlag(VehicleFlags.FixedPosition))
|
||||||
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.Root), MovementFlag.Root);
|
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.Root), MovementFlag.Root);
|
||||||
|
|
||||||
/*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
|
/*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
|
||||||
@@ -1982,7 +1982,7 @@ namespace Game.Entities
|
|||||||
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.Root) && mi.HasMovementFlag(MovementFlag.MaskMoving), MovementFlag.MaskMoving);
|
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.Root) && mi.HasMovementFlag(MovementFlag.MaskMoving), MovementFlag.MaskMoving);
|
||||||
|
|
||||||
//! Cannot hover without SPELL_AURA_HOVER
|
//! Cannot hover without SPELL_AURA_HOVER
|
||||||
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.Hover) && !HasAuraType(AuraType.Hover),
|
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.Hover) && !m_unitMovedByMe.HasAuraType(AuraType.Hover),
|
||||||
MovementFlag.Hover);
|
MovementFlag.Hover);
|
||||||
|
|
||||||
//! Cannot ascend and descend at the same time
|
//! Cannot ascend and descend at the same time
|
||||||
@@ -2007,10 +2007,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
//! Cannot walk on water without SPELL_AURA_WATER_WALK except for ghosts
|
//! Cannot walk on water without SPELL_AURA_WATER_WALK except for ghosts
|
||||||
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.WaterWalk) &&
|
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.WaterWalk) &&
|
||||||
!HasAuraType(AuraType.WaterWalk) && !HasAuraType(AuraType.Ghost), MovementFlag.WaterWalk);
|
!m_unitMovedByMe.HasAuraType(AuraType.WaterWalk) && !m_unitMovedByMe.HasAuraType(AuraType.Ghost), MovementFlag.WaterWalk);
|
||||||
|
|
||||||
//! Cannot feather fall without SPELL_AURA_FEATHER_FALL
|
//! Cannot feather fall without SPELL_AURA_FEATHER_FALL
|
||||||
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.FallingSlow) && !HasAuraType(AuraType.FeatherFall),
|
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.FallingSlow) && !m_unitMovedByMe.HasAuraType(AuraType.FeatherFall),
|
||||||
MovementFlag.FallingSlow);
|
MovementFlag.FallingSlow);
|
||||||
|
|
||||||
/*! Cannot fly if no fly auras present. Exception is being a GM.
|
/*! Cannot fly if no fly auras present. Exception is being a GM.
|
||||||
@@ -7443,7 +7443,6 @@ namespace Game.Entities
|
|||||||
public void AddAuraVision(PlayerFieldByte2Flags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AuraVision), (byte)flags); }
|
public void AddAuraVision(PlayerFieldByte2Flags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AuraVision), (byte)flags); }
|
||||||
public void RemoveAuraVision(PlayerFieldByte2Flags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AuraVision), (byte)flags); }
|
public void RemoveAuraVision(PlayerFieldByte2Flags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AuraVision), (byte)flags); }
|
||||||
|
|
||||||
|
|
||||||
public bool CanTameExoticPets() { return IsGameMaster() || HasAuraType(AuraType.AllowTamePetType); }
|
public bool CanTameExoticPets() { return IsGameMaster() || HasAuraType(AuraType.AllowTamePetType); }
|
||||||
|
|
||||||
void SendAttackSwingDeadTarget() { SendPacket(new AttackSwingError(AttackSwingErr.DeadTarget)); }
|
void SendAttackSwingDeadTarget() { SendPacket(new AttackSwingError(AttackSwingErr.DeadTarget)); }
|
||||||
@@ -7528,7 +7527,7 @@ namespace Game.Entities
|
|||||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||||
WorldPacket buffer = new WorldPacket();
|
WorldPacket buffer = new WorldPacket();
|
||||||
|
|
||||||
buffer.WriteUInt32((uint)(m_values.GetChangedObjectTypeMask() & ~((target != this) ? 1 : 0 << (int)TypeId.ActivePlayer)));
|
buffer.WriteUInt32((uint)(m_values.GetChangedObjectTypeMask() & ~((target != this ? 1 : 0) << (int)TypeId.ActivePlayer)));
|
||||||
if (m_values.HasChanged(TypeId.Object))
|
if (m_values.HasChanged(TypeId.Object))
|
||||||
m_objectData.WriteUpdate(buffer, flags, this, target);
|
m_objectData.WriteUpdate(buffer, flags, this, target);
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ namespace Game.Entities
|
|||||||
public uint m_movementCounter; //< Incrementing counter used in movement packets
|
public uint m_movementCounter; //< Incrementing counter used in movement packets
|
||||||
TimeTrackerSmall movesplineTimer;
|
TimeTrackerSmall movesplineTimer;
|
||||||
public Player m_playerMovingMe;
|
public Player m_playerMovingMe;
|
||||||
|
MovementForces _movementForces;
|
||||||
|
|
||||||
//Combat
|
//Combat
|
||||||
protected List<Unit> attackerList = new List<Unit>();
|
protected List<Unit> attackerList = new List<Unit>();
|
||||||
|
|||||||
@@ -1415,6 +1415,138 @@ namespace Game.Entities
|
|||||||
SendMessageToSet(setVehicleRec, true);
|
SendMessageToSet(setVehicleRec, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MovementForces GetMovementForces() { return _movementForces; }
|
||||||
|
|
||||||
|
void ApplyMovementForce(ObjectGuid id, Vector3 origin, float magnitude, byte type, Vector3 direction, ObjectGuid transportGuid = default)
|
||||||
|
{
|
||||||
|
if (_movementForces == null)
|
||||||
|
_movementForces = new MovementForces();
|
||||||
|
|
||||||
|
MovementForce force = new MovementForce();
|
||||||
|
force.ID = id;
|
||||||
|
force.Origin = origin;
|
||||||
|
force.Direction = direction;
|
||||||
|
if (transportGuid.IsMOTransport())
|
||||||
|
force.TransportID = (uint)transportGuid.GetCounter();
|
||||||
|
|
||||||
|
force.Magnitude = magnitude;
|
||||||
|
force.Type = type;
|
||||||
|
|
||||||
|
if (_movementForces.Add(force))
|
||||||
|
{
|
||||||
|
Player movingPlayer = GetPlayerMovingMe();
|
||||||
|
if (movingPlayer != null)
|
||||||
|
{
|
||||||
|
MoveApplyMovementForce applyMovementForce = new MoveApplyMovementForce();
|
||||||
|
applyMovementForce.MoverGUID = GetGUID();
|
||||||
|
applyMovementForce.SequenceIndex = (int)m_movementCounter++;
|
||||||
|
applyMovementForce.Force = force;
|
||||||
|
movingPlayer.SendPacket(applyMovementForce);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MoveUpdateApplyMovementForce updateApplyMovementForce = new MoveUpdateApplyMovementForce();
|
||||||
|
updateApplyMovementForce.Status = m_movementInfo;
|
||||||
|
updateApplyMovementForce.Force = force;
|
||||||
|
SendMessageToSet(updateApplyMovementForce, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveMovementForce(ObjectGuid id)
|
||||||
|
{
|
||||||
|
if (_movementForces == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_movementForces.Remove(id))
|
||||||
|
{
|
||||||
|
Player movingPlayer = GetPlayerMovingMe();
|
||||||
|
if (movingPlayer != null)
|
||||||
|
{
|
||||||
|
MoveRemoveMovementForce moveRemoveMovementForce = new MoveRemoveMovementForce();
|
||||||
|
moveRemoveMovementForce.MoverGUID = GetGUID();
|
||||||
|
moveRemoveMovementForce.SequenceIndex = (int)m_movementCounter++;
|
||||||
|
moveRemoveMovementForce.ID = id;
|
||||||
|
movingPlayer.SendPacket(moveRemoveMovementForce);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MoveUpdateRemoveMovementForce updateRemoveMovementForce = new MoveUpdateRemoveMovementForce();
|
||||||
|
updateRemoveMovementForce.Status = m_movementInfo;
|
||||||
|
updateRemoveMovementForce.TriggerGUID = id;
|
||||||
|
SendMessageToSet(updateRemoveMovementForce, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_movementForces.IsEmpty())
|
||||||
|
_movementForces = new MovementForces();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetIgnoreMovementForces(bool ignore)
|
||||||
|
{
|
||||||
|
if (ignore == HasUnitMovementFlag2(MovementFlag2.IgnoreMovementForces))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ignore)
|
||||||
|
AddUnitMovementFlag2(MovementFlag2.IgnoreMovementForces);
|
||||||
|
else
|
||||||
|
RemoveUnitMovementFlag2(MovementFlag2.IgnoreMovementForces);
|
||||||
|
|
||||||
|
ServerOpcodes[] ignoreMovementForcesOpcodeTable =
|
||||||
|
{
|
||||||
|
ServerOpcodes.MoveUnsetIgnoreMovementForces,
|
||||||
|
ServerOpcodes.MoveSetIgnoreMovementForces
|
||||||
|
};
|
||||||
|
|
||||||
|
Player movingPlayer = GetPlayerMovingMe();
|
||||||
|
if (movingPlayer != null)
|
||||||
|
{
|
||||||
|
MoveSetFlag packet = new MoveSetFlag(ignoreMovementForcesOpcodeTable[ignore ? 1 : 0]);
|
||||||
|
packet.MoverGUID = GetGUID();
|
||||||
|
packet.SequenceIndex = m_movementCounter++;
|
||||||
|
movingPlayer.SendPacket(packet);
|
||||||
|
|
||||||
|
MoveUpdate moveUpdate = new MoveUpdate();
|
||||||
|
moveUpdate.Status = m_movementInfo;
|
||||||
|
SendMessageToSet(moveUpdate, movingPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateMovementForcesModMagnitude()
|
||||||
|
{
|
||||||
|
float modMagnitude = GetTotalAuraMultiplier(AuraType.ModMovementForceMagnitude);
|
||||||
|
|
||||||
|
Player movingPlayer = GetPlayerMovingMe();
|
||||||
|
if (movingPlayer != null)
|
||||||
|
{
|
||||||
|
MoveSetSpeed setModMovementForceMagnitude = new MoveSetSpeed(ServerOpcodes.MoveSetModMovementForceMagnitude);
|
||||||
|
setModMovementForceMagnitude.MoverGUID = GetGUID();
|
||||||
|
setModMovementForceMagnitude.SequenceIndex = m_movementCounter++;
|
||||||
|
setModMovementForceMagnitude.Speed = modMagnitude;
|
||||||
|
movingPlayer.SendPacket(setModMovementForceMagnitude);
|
||||||
|
++movingPlayer.m_movementForceModMagnitudeChanges;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MoveUpdateSpeed updateModMovementForceMagnitude = new MoveUpdateSpeed(ServerOpcodes.MoveUpdateModMovementForceMagnitude);
|
||||||
|
updateModMovementForceMagnitude.Status = m_movementInfo;
|
||||||
|
updateModMovementForceMagnitude.Speed = modMagnitude;
|
||||||
|
SendMessageToSet(updateModMovementForceMagnitude, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modMagnitude != 1.0f && _movementForces == null)
|
||||||
|
_movementForces = new MovementForces();
|
||||||
|
|
||||||
|
if (_movementForces != null)
|
||||||
|
{
|
||||||
|
_movementForces.SetModMagnitude(modMagnitude);
|
||||||
|
if (_movementForces.IsEmpty())
|
||||||
|
_movementForces = new MovementForces();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SendSetPlayHoverAnim(bool enable)
|
void SendSetPlayHoverAnim(bool enable)
|
||||||
{
|
{
|
||||||
SetPlayHoverAnim data = new SetPlayHoverAnim();
|
SetPlayHoverAnim data = new SetPlayHoverAnim();
|
||||||
@@ -1562,6 +1694,8 @@ namespace Game.Entities
|
|||||||
|
|
||||||
MoveUpdateTeleport moveUpdateTeleport = new MoveUpdateTeleport();
|
MoveUpdateTeleport moveUpdateTeleport = new MoveUpdateTeleport();
|
||||||
moveUpdateTeleport.Status = m_movementInfo;
|
moveUpdateTeleport.Status = m_movementInfo;
|
||||||
|
if (_movementForces != null)
|
||||||
|
moveUpdateTeleport.MovementForces = _movementForces.GetForces();
|
||||||
Unit broadcastSource = this;
|
Unit broadcastSource = this;
|
||||||
|
|
||||||
Player playerMover = GetPlayerBeingMoved();
|
Player playerMover = GetPlayerBeingMoved();
|
||||||
|
|||||||
@@ -620,6 +620,92 @@ namespace Game
|
|||||||
GetPlayer().ValidateMovementInfo(packet.Data.Status);
|
GetPlayer().ValidateMovementInfo(packet.Data.Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[WorldPacketHandler(ClientOpcodes.MoveApplyMovementForceAck, Processing = PacketProcessing.ThreadSafe)]
|
||||||
|
void HandleMoveApplyMovementForceAck(MoveApplyMovementForceAck moveApplyMovementForceAck)
|
||||||
|
{
|
||||||
|
Unit mover = _player.m_unitMovedByMe;
|
||||||
|
Cypher.Assert(mover != null);
|
||||||
|
_player.ValidateMovementInfo(moveApplyMovementForceAck.Ack.Status);
|
||||||
|
|
||||||
|
// prevent tampered movement data
|
||||||
|
if (moveApplyMovementForceAck.Ack.Status.Guid != mover.GetGUID())
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Network, $"HandleMoveApplyMovementForceAck: guid error, expected {mover.GetGUID().ToString()}, got {moveApplyMovementForceAck.Ack.Status.Guid.ToString()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveApplyMovementForceAck.Ack.Status.Time += m_clientTimeDelay;
|
||||||
|
|
||||||
|
MoveUpdateApplyMovementForce updateApplyMovementForce = new MoveUpdateApplyMovementForce();
|
||||||
|
updateApplyMovementForce.Status = moveApplyMovementForceAck.Ack.Status;
|
||||||
|
updateApplyMovementForce.Force = moveApplyMovementForceAck.Force;
|
||||||
|
mover.SendMessageToSet(updateApplyMovementForce, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[WorldPacketHandler(ClientOpcodes.MoveRemoveMovementForceAck, Processing = PacketProcessing.ThreadSafe)]
|
||||||
|
void HandleMoveRemoveMovementForceAck(MoveRemoveMovementForceAck moveRemoveMovementForceAck)
|
||||||
|
{
|
||||||
|
Unit mover = _player.m_unitMovedByMe;
|
||||||
|
Cypher.Assert(mover != null);
|
||||||
|
_player.ValidateMovementInfo(moveRemoveMovementForceAck.Ack.Status);
|
||||||
|
|
||||||
|
// prevent tampered movement data
|
||||||
|
if (moveRemoveMovementForceAck.Ack.Status.Guid != mover.GetGUID())
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Network, $"HandleMoveRemoveMovementForceAck: guid error, expected {mover.GetGUID().ToString()}, got {moveRemoveMovementForceAck.Ack.Status.Guid.ToString()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveRemoveMovementForceAck.Ack.Status.Time += m_clientTimeDelay;
|
||||||
|
|
||||||
|
MoveUpdateRemoveMovementForce updateRemoveMovementForce = new MoveUpdateRemoveMovementForce();
|
||||||
|
updateRemoveMovementForce.Status = moveRemoveMovementForceAck.Ack.Status;
|
||||||
|
updateRemoveMovementForce.TriggerGUID = moveRemoveMovementForceAck.ID;
|
||||||
|
mover.SendMessageToSet(updateRemoveMovementForce, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[WorldPacketHandler(ClientOpcodes.MoveSetModMovementForceMagnitudeAck, Processing = PacketProcessing.ThreadSafe)]
|
||||||
|
void HandleMoveSetModMovementForceMagnitudeAck(MovementSpeedAck setModMovementForceMagnitudeAck)
|
||||||
|
{
|
||||||
|
Unit mover = _player.m_unitMovedByMe;
|
||||||
|
Cypher.Assert(mover != null); // there must always be a mover
|
||||||
|
_player.ValidateMovementInfo(setModMovementForceMagnitudeAck.Ack.Status);
|
||||||
|
|
||||||
|
// prevent tampered movement data
|
||||||
|
if (setModMovementForceMagnitudeAck.Ack.Status.Guid != mover.GetGUID())
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Network, "HandleSetModMovementForceMagnitudeAck: guid error, expected {mover.GetGUID().ToString()}, got {setModMovementForceMagnitudeAck.Ack.Status.guid.ToString()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip all except last
|
||||||
|
if (_player.m_movementForceModMagnitudeChanges > 0)
|
||||||
|
{
|
||||||
|
--_player.m_movementForceModMagnitudeChanges;
|
||||||
|
if (_player.m_movementForceModMagnitudeChanges == 0)
|
||||||
|
{
|
||||||
|
float expectedModMagnitude = 1.0f;
|
||||||
|
MovementForces movementForces = mover.GetMovementForces();
|
||||||
|
if (movementForces != null)
|
||||||
|
expectedModMagnitude = movementForces.GetModMagnitude();
|
||||||
|
|
||||||
|
if (Math.Abs(expectedModMagnitude - setModMovementForceMagnitudeAck.Speed) > 0.01f)
|
||||||
|
{
|
||||||
|
Log.outDebug(LogFilter.Misc, $"Player {_player.GetName()} from account id {_player.GetSession().GetAccountId()} kicked for incorrect movement force magnitude (must be {expectedModMagnitude} instead {setModMovementForceMagnitudeAck.Speed})");
|
||||||
|
_player.GetSession().KickPlayer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setModMovementForceMagnitudeAck.Ack.Status.Time += m_clientTimeDelay;
|
||||||
|
|
||||||
|
MoveUpdateSpeed updateModMovementForceMagnitude = new MoveUpdateSpeed(ServerOpcodes.MoveUpdateModMovementForceMagnitude);
|
||||||
|
updateModMovementForceMagnitude.Status = setModMovementForceMagnitudeAck.Ack.Status;
|
||||||
|
updateModMovementForceMagnitude.Speed = setModMovementForceMagnitudeAck.Speed;
|
||||||
|
mover.SendMessageToSet(updateModMovementForceMagnitude, false);
|
||||||
|
}
|
||||||
|
|
||||||
[WorldPacketHandler(ClientOpcodes.MoveTimeSkipped, Processing = PacketProcessing.Inplace)]
|
[WorldPacketHandler(ClientOpcodes.MoveTimeSkipped, Processing = PacketProcessing.Inplace)]
|
||||||
void HandleMoveTimeSkipped(MoveTimeSkipped moveTimeSkipped)
|
void HandleMoveTimeSkipped(MoveTimeSkipped moveTimeSkipped)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -268,6 +268,44 @@ namespace Game.Network.Packets
|
|||||||
foreach (var point in spline.getPoints())
|
foreach (var point in spline.getPoints())
|
||||||
data.WriteVector3(point);
|
data.WriteVector3(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void WriteMovementForceWithDirection(MovementForce movementForce, WorldPacket data, Position objectPosition = null)
|
||||||
|
{
|
||||||
|
data.WritePackedGuid(movementForce.ID);
|
||||||
|
data.WriteVector3(movementForce.Origin);
|
||||||
|
if (movementForce.Type == 1 && objectPosition != null) // gravity
|
||||||
|
{
|
||||||
|
Vector3 direction = Vector3.Zero;
|
||||||
|
if (movementForce.Magnitude != 0.0f)
|
||||||
|
{
|
||||||
|
Position tmp = new Position(movementForce.Origin.X - objectPosition.GetPositionX(),
|
||||||
|
movementForce.Origin.Y - objectPosition.GetPositionY(),
|
||||||
|
movementForce.Origin.Z - objectPosition.GetPositionZ());
|
||||||
|
float lengthSquared = tmp.GetExactDistSq(0.0f, 0.0f, 0.0f);
|
||||||
|
if (lengthSquared > 0.0f)
|
||||||
|
{
|
||||||
|
float mult = 1.0f / (float)Math.Sqrt(lengthSquared) * movementForce.Magnitude;
|
||||||
|
tmp.posX *= mult;
|
||||||
|
tmp.posY *= mult;
|
||||||
|
tmp.posZ *= mult;
|
||||||
|
float minLengthSquared = (tmp.GetPositionX() * tmp.GetPositionX() * 0.04f) +
|
||||||
|
(tmp.GetPositionY() * tmp.GetPositionY() * 0.04f) +
|
||||||
|
(tmp.GetPositionZ() * tmp.GetPositionZ() * 0.04f);
|
||||||
|
if (lengthSquared > minLengthSquared)
|
||||||
|
direction = new Vector3(tmp.posX, tmp.posY, tmp.posZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.WriteVector3(direction);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.WriteVector3(movementForce.Direction);
|
||||||
|
|
||||||
|
data.WriteUInt32(movementForce.TransportID);
|
||||||
|
data.WriteFloat(movementForce.Magnitude);
|
||||||
|
data.WriteBits(movementForce.Type, 2);
|
||||||
|
data.FlushBits();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ClientPlayerMovement : ClientPacket
|
public class ClientPlayerMovement : ClientPacket
|
||||||
@@ -588,7 +626,7 @@ namespace Game.Network.Packets
|
|||||||
{
|
{
|
||||||
MovementExtensions.WriteMovementInfo(_worldPacket, Status);
|
MovementExtensions.WriteMovementInfo(_worldPacket, Status);
|
||||||
|
|
||||||
_worldPacket.WriteInt32(MovementForces.Count);
|
_worldPacket.WriteInt32(MovementForces != null ? MovementForces.Count : 0);
|
||||||
_worldPacket.WriteBit(WalkSpeed.HasValue);
|
_worldPacket.WriteBit(WalkSpeed.HasValue);
|
||||||
_worldPacket.WriteBit(RunSpeed.HasValue);
|
_worldPacket.WriteBit(RunSpeed.HasValue);
|
||||||
_worldPacket.WriteBit(RunBackSpeed.HasValue);
|
_worldPacket.WriteBit(RunBackSpeed.HasValue);
|
||||||
@@ -600,8 +638,9 @@ namespace Game.Network.Packets
|
|||||||
_worldPacket.WriteBit(PitchRate.HasValue);
|
_worldPacket.WriteBit(PitchRate.HasValue);
|
||||||
_worldPacket.FlushBits();
|
_worldPacket.FlushBits();
|
||||||
|
|
||||||
foreach (MovementForce force in MovementForces)
|
if (MovementForces != null)
|
||||||
force.Write(_worldPacket);
|
foreach (MovementForce force in MovementForces)
|
||||||
|
force.Write(_worldPacket);
|
||||||
|
|
||||||
if (WalkSpeed.HasValue)
|
if (WalkSpeed.HasValue)
|
||||||
_worldPacket.WriteFloat(WalkSpeed.Value);
|
_worldPacket.WriteFloat(WalkSpeed.Value);
|
||||||
@@ -632,7 +671,7 @@ namespace Game.Network.Packets
|
|||||||
}
|
}
|
||||||
|
|
||||||
public MovementInfo Status;
|
public MovementInfo Status;
|
||||||
public List<MovementForce> MovementForces = new List<MovementForce>();
|
public List<MovementForce> MovementForces;
|
||||||
public Optional<float> SwimBackSpeed;
|
public Optional<float> SwimBackSpeed;
|
||||||
public Optional<float> FlightSpeed;
|
public Optional<float> FlightSpeed;
|
||||||
public Optional<float> SwimSpeed;
|
public Optional<float> SwimSpeed;
|
||||||
@@ -644,18 +683,78 @@ namespace Game.Network.Packets
|
|||||||
public Optional<float> PitchRate;
|
public Optional<float> PitchRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MoveApplyMovementForce : ServerPacket
|
||||||
|
{
|
||||||
|
public MoveApplyMovementForce() : base(ServerOpcodes.MoveApplyMovementForce, ConnectionType.Instance) { }
|
||||||
|
|
||||||
|
public override void Write()
|
||||||
|
{
|
||||||
|
_worldPacket.WritePackedGuid(MoverGUID);
|
||||||
|
_worldPacket.WriteInt32(SequenceIndex);
|
||||||
|
Force.Write(_worldPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectGuid MoverGUID;
|
||||||
|
public int SequenceIndex;
|
||||||
|
public MovementForce Force;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveApplyMovementForceAck : ClientPacket
|
||||||
|
{
|
||||||
|
public MoveApplyMovementForceAck(WorldPacket packet) : base(packet) { }
|
||||||
|
|
||||||
|
public override void Read()
|
||||||
|
{
|
||||||
|
Ack.Read(_worldPacket);
|
||||||
|
Force.Read(_worldPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MovementAck Ack = new MovementAck();
|
||||||
|
public MovementForce Force = new MovementForce();
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveRemoveMovementForce : ServerPacket
|
||||||
|
{
|
||||||
|
public MoveRemoveMovementForce() : base(ServerOpcodes.MoveRemoveMovementForce, ConnectionType.Instance) { }
|
||||||
|
|
||||||
|
public override void Write()
|
||||||
|
{
|
||||||
|
_worldPacket.WritePackedGuid(MoverGUID);
|
||||||
|
_worldPacket.WriteInt32(SequenceIndex);
|
||||||
|
_worldPacket.WritePackedGuid(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectGuid MoverGUID;
|
||||||
|
public int SequenceIndex;
|
||||||
|
public ObjectGuid ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveRemoveMovementForceAck : ClientPacket
|
||||||
|
{
|
||||||
|
public MoveRemoveMovementForceAck(WorldPacket packet) : base(packet) { }
|
||||||
|
|
||||||
|
public override void Read()
|
||||||
|
{
|
||||||
|
Ack.Read(_worldPacket);
|
||||||
|
ID = _worldPacket.ReadPackedGuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MovementAck Ack = new MovementAck();
|
||||||
|
public ObjectGuid ID;
|
||||||
|
}
|
||||||
|
|
||||||
class MoveUpdateApplyMovementForce : ServerPacket
|
class MoveUpdateApplyMovementForce : ServerPacket
|
||||||
{
|
{
|
||||||
public MoveUpdateApplyMovementForce() : base(ServerOpcodes.MoveUpdateApplyMovementForce) { }
|
public MoveUpdateApplyMovementForce() : base(ServerOpcodes.MoveUpdateApplyMovementForce) { }
|
||||||
|
|
||||||
public override void Write()
|
public override void Write()
|
||||||
{
|
{
|
||||||
MovementExtensions.WriteMovementInfo(_worldPacket, movementInfo);
|
MovementExtensions.WriteMovementInfo(_worldPacket, Status);
|
||||||
Force.Write(_worldPacket);
|
Force.Write(_worldPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
MovementInfo movementInfo = new MovementInfo();
|
public MovementInfo Status = new MovementInfo();
|
||||||
MovementForce Force = new MovementForce();
|
public MovementForce Force = new MovementForce();
|
||||||
}
|
}
|
||||||
|
|
||||||
class MoveUpdateRemoveMovementForce : ServerPacket
|
class MoveUpdateRemoveMovementForce : ServerPacket
|
||||||
@@ -664,12 +763,12 @@ namespace Game.Network.Packets
|
|||||||
|
|
||||||
public override void Write()
|
public override void Write()
|
||||||
{
|
{
|
||||||
MovementExtensions.WriteMovementInfo(_worldPacket, movementInfo);
|
MovementExtensions.WriteMovementInfo(_worldPacket, Status);
|
||||||
_worldPacket.WritePackedGuid(TriggerGUID);
|
_worldPacket.WritePackedGuid(TriggerGUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
MovementInfo movementInfo = new MovementInfo();
|
public MovementInfo Status = new MovementInfo();
|
||||||
ObjectGuid TriggerGUID;
|
public ObjectGuid TriggerGUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MoveTeleportAck : ClientPacket
|
class MoveTeleportAck : ClientPacket
|
||||||
@@ -1060,6 +1159,18 @@ namespace Game.Network.Packets
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Structs
|
//Structs
|
||||||
|
public struct MovementAck
|
||||||
|
{
|
||||||
|
public void Read(WorldPacket data)
|
||||||
|
{
|
||||||
|
Status = MovementExtensions.ReadMovementInfo(data);
|
||||||
|
AckIndex = data.ReadInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MovementInfo Status;
|
||||||
|
public int AckIndex;
|
||||||
|
}
|
||||||
|
|
||||||
public struct MonsterSplineFilterKey
|
public struct MonsterSplineFilterKey
|
||||||
{
|
{
|
||||||
public void Write(WorldPacket data)
|
public void Write(WorldPacket data)
|
||||||
@@ -1232,39 +1343,6 @@ namespace Game.Network.Packets
|
|||||||
public bool VehicleExitTeleport;
|
public bool VehicleExitTeleport;
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MovementForce
|
|
||||||
{
|
|
||||||
public void Write(WorldPacket data)
|
|
||||||
{
|
|
||||||
data.WritePackedGuid(ID);
|
|
||||||
data.WriteVector3(Origin);
|
|
||||||
data.WriteVector3(Direction);
|
|
||||||
data.WriteUInt32(TransportID);
|
|
||||||
data.WriteFloat(Magnitude);
|
|
||||||
data.WriteBits(Type, 2);
|
|
||||||
data.FlushBits();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectGuid ID;
|
|
||||||
public Vector3 Origin;
|
|
||||||
public Vector3 Direction;
|
|
||||||
public uint TransportID;
|
|
||||||
public float Magnitude;
|
|
||||||
public byte Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct MovementAck
|
|
||||||
{
|
|
||||||
public void Read(WorldPacket data)
|
|
||||||
{
|
|
||||||
Status = MovementExtensions.ReadMovementInfo(data);
|
|
||||||
AckIndex = data.ReadInt32();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MovementInfo Status;
|
|
||||||
public int AckIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct MoveKnockBackSpeeds
|
public struct MoveKnockBackSpeeds
|
||||||
{
|
{
|
||||||
public void Write(WorldPacket data)
|
public void Write(WorldPacket data)
|
||||||
|
|||||||
@@ -2330,6 +2330,23 @@ namespace Game.Spells
|
|||||||
target.SetCanTurnWhileFalling(apply);
|
target.SetCanTurnWhileFalling(apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AuraEffectHandler(AuraType.IgnoreMovementForces)]
|
||||||
|
void HandleIgnoreMovementForces(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||||
|
{
|
||||||
|
if (!mode.HasAnyFlag(AuraEffectHandleModes.SendForClientMask))
|
||||||
|
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 ***/
|
/*** THREAT ***/
|
||||||
/****************************/
|
/****************************/
|
||||||
@@ -2722,6 +2739,15 @@ namespace Game.Spells
|
|||||||
target.UpdateSpeed(UnitMoveType.Run);
|
target.UpdateSpeed(UnitMoveType.Run);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AuraEffectHandler(AuraType.ModMovementForceMagnitude)]
|
||||||
|
void HandleModMovementForceMagnitude(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||||
|
{
|
||||||
|
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask))
|
||||||
|
return;
|
||||||
|
|
||||||
|
aurApp.GetTarget().UpdateMovementForcesModMagnitude();
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
/*** IMMUNITY ***/
|
/*** IMMUNITY ***/
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
@@ -6027,7 +6053,7 @@ namespace Game.Spells
|
|||||||
uint summonEntry = (uint)spellEffect.MiscValue;
|
uint summonEntry = (uint)spellEffect.MiscValue;
|
||||||
if (summonEntry != 0)
|
if (summonEntry != 0)
|
||||||
summonedEntries.Add(summonEntry);
|
summonedEntries.Add(summonEntry);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user