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,
|
||||
SuppressTransforms = 483, // NYI
|
||||
Unk484 = 484,
|
||||
Unk485 = 485,
|
||||
ModMovementForceMagnitude = 485,
|
||||
Unk486 = 486,
|
||||
Unk487 = 487,
|
||||
Unk488 = 488,
|
||||
|
||||
@@ -336,21 +336,24 @@ namespace Game.Entities
|
||||
data.WriteFloat(unit.GetSpeed(UnitMoveType.TurnRate));
|
||||
data.WriteFloat(unit.GetSpeed(UnitMoveType.PitchRate));
|
||||
|
||||
data.WriteUInt32(0); // unit.m_movementInfo.forces.size()
|
||||
data.WriteFloat(1.0f); // MovementForcesModMagnitude
|
||||
MovementForces movementForces = unit.GetMovementForces();
|
||||
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.FlushBits();
|
||||
|
||||
//for (public uint i = 0; i < unit.m_movementInfo.forces.Count; ++i)
|
||||
//{
|
||||
// *data << ObjectGuid(ID);
|
||||
// *data << Vector3(Origin);
|
||||
// *data << Vector3(Direction);
|
||||
// *data << uint32(TransportID);
|
||||
// *data.WriteFloat(Magnitude);
|
||||
// *data.WriteBits(Type, 2);
|
||||
//}
|
||||
if (movementForces != null)
|
||||
foreach (MovementForce force in movementForces.GetForces())
|
||||
MovementExtensions.WriteMovementForceWithDirection(force, data, unit);
|
||||
|
||||
// HasMovementSpline - marks that spline data is present in packet
|
||||
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 bool NoBirthAnim;
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace Game.Entities
|
||||
//Movement
|
||||
public PlayerTaxi m_taxi = new PlayerTaxi();
|
||||
public byte[] m_forced_speed_changes = new byte[(int)UnitMoveType.Max];
|
||||
public byte m_movementForceModMagnitudeChanges;
|
||||
uint m_lastFallTime;
|
||||
float m_lastFallZ;
|
||||
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);
|
||||
|
||||
/*! 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);
|
||||
|
||||
//! 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);
|
||||
|
||||
//! 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
|
||||
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
|
||||
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.FallingSlow) && !HasAuraType(AuraType.FeatherFall),
|
||||
RemoveViolatingFlags(mi.HasMovementFlag(MovementFlag.FallingSlow) && !m_unitMovedByMe.HasAuraType(AuraType.FeatherFall),
|
||||
MovementFlag.FallingSlow);
|
||||
|
||||
/*! 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 RemoveAuraVision(PlayerFieldByte2Flags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AuraVision), (byte)flags); }
|
||||
|
||||
|
||||
public bool CanTameExoticPets() { return IsGameMaster() || HasAuraType(AuraType.AllowTamePetType); }
|
||||
|
||||
void SendAttackSwingDeadTarget() { SendPacket(new AttackSwingError(AttackSwingErr.DeadTarget)); }
|
||||
@@ -7528,7 +7527,7 @@ namespace Game.Entities
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
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))
|
||||
m_objectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace Game.Entities
|
||||
public uint m_movementCounter; //< Incrementing counter used in movement packets
|
||||
TimeTrackerSmall movesplineTimer;
|
||||
public Player m_playerMovingMe;
|
||||
MovementForces _movementForces;
|
||||
|
||||
//Combat
|
||||
protected List<Unit> attackerList = new List<Unit>();
|
||||
|
||||
@@ -1415,6 +1415,138 @@ namespace Game.Entities
|
||||
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)
|
||||
{
|
||||
SetPlayHoverAnim data = new SetPlayHoverAnim();
|
||||
@@ -1562,6 +1694,8 @@ namespace Game.Entities
|
||||
|
||||
MoveUpdateTeleport moveUpdateTeleport = new MoveUpdateTeleport();
|
||||
moveUpdateTeleport.Status = m_movementInfo;
|
||||
if (_movementForces != null)
|
||||
moveUpdateTeleport.MovementForces = _movementForces.GetForces();
|
||||
Unit broadcastSource = this;
|
||||
|
||||
Player playerMover = GetPlayerBeingMoved();
|
||||
|
||||
@@ -620,6 +620,92 @@ namespace Game
|
||||
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)]
|
||||
void HandleMoveTimeSkipped(MoveTimeSkipped moveTimeSkipped)
|
||||
{
|
||||
|
||||
@@ -268,6 +268,44 @@ namespace Game.Network.Packets
|
||||
foreach (var point in spline.getPoints())
|
||||
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
|
||||
@@ -588,7 +626,7 @@ namespace Game.Network.Packets
|
||||
{
|
||||
MovementExtensions.WriteMovementInfo(_worldPacket, Status);
|
||||
|
||||
_worldPacket.WriteInt32(MovementForces.Count);
|
||||
_worldPacket.WriteInt32(MovementForces != null ? MovementForces.Count : 0);
|
||||
_worldPacket.WriteBit(WalkSpeed.HasValue);
|
||||
_worldPacket.WriteBit(RunSpeed.HasValue);
|
||||
_worldPacket.WriteBit(RunBackSpeed.HasValue);
|
||||
@@ -600,8 +638,9 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteBit(PitchRate.HasValue);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
foreach (MovementForce force in MovementForces)
|
||||
force.Write(_worldPacket);
|
||||
if (MovementForces != null)
|
||||
foreach (MovementForce force in MovementForces)
|
||||
force.Write(_worldPacket);
|
||||
|
||||
if (WalkSpeed.HasValue)
|
||||
_worldPacket.WriteFloat(WalkSpeed.Value);
|
||||
@@ -632,7 +671,7 @@ namespace Game.Network.Packets
|
||||
}
|
||||
|
||||
public MovementInfo Status;
|
||||
public List<MovementForce> MovementForces = new List<MovementForce>();
|
||||
public List<MovementForce> MovementForces;
|
||||
public Optional<float> SwimBackSpeed;
|
||||
public Optional<float> FlightSpeed;
|
||||
public Optional<float> SwimSpeed;
|
||||
@@ -644,18 +683,78 @@ namespace Game.Network.Packets
|
||||
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
|
||||
{
|
||||
public MoveUpdateApplyMovementForce() : base(ServerOpcodes.MoveUpdateApplyMovementForce) { }
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
MovementExtensions.WriteMovementInfo(_worldPacket, movementInfo);
|
||||
MovementExtensions.WriteMovementInfo(_worldPacket, Status);
|
||||
Force.Write(_worldPacket);
|
||||
}
|
||||
|
||||
MovementInfo movementInfo = new MovementInfo();
|
||||
MovementForce Force = new MovementForce();
|
||||
public MovementInfo Status = new MovementInfo();
|
||||
public MovementForce Force = new MovementForce();
|
||||
}
|
||||
|
||||
class MoveUpdateRemoveMovementForce : ServerPacket
|
||||
@@ -664,12 +763,12 @@ namespace Game.Network.Packets
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
MovementExtensions.WriteMovementInfo(_worldPacket, movementInfo);
|
||||
MovementExtensions.WriteMovementInfo(_worldPacket, Status);
|
||||
_worldPacket.WritePackedGuid(TriggerGUID);
|
||||
}
|
||||
|
||||
MovementInfo movementInfo = new MovementInfo();
|
||||
ObjectGuid TriggerGUID;
|
||||
public MovementInfo Status = new MovementInfo();
|
||||
public ObjectGuid TriggerGUID;
|
||||
}
|
||||
|
||||
class MoveTeleportAck : ClientPacket
|
||||
@@ -1060,6 +1159,18 @@ namespace Game.Network.Packets
|
||||
}
|
||||
|
||||
//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 void Write(WorldPacket data)
|
||||
@@ -1232,39 +1343,6 @@ namespace Game.Network.Packets
|
||||
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 void Write(WorldPacket data)
|
||||
|
||||
@@ -2330,6 +2330,23 @@ namespace Game.Spells
|
||||
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 ***/
|
||||
/****************************/
|
||||
@@ -2722,6 +2739,15 @@ namespace Game.Spells
|
||||
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 ***/
|
||||
/*********************************************************/
|
||||
@@ -6027,7 +6053,7 @@ namespace Game.Spells
|
||||
uint summonEntry = (uint)spellEffect.MiscValue;
|
||||
if (summonEntry != 0)
|
||||
summonedEntries.Add(summonEntry);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user