Core/Movement: Implemented movement forces

Port From (https://github.com/TrinityCore/TrinityCore/commit/8e98ceb2936842ea0032cbfdc04a510d6b1e5de0)
This commit is contained in:
hondacrx
2019-09-08 12:48:10 -04:00
parent 981e1e04c1
commit 5b67e2f539
9 changed files with 458 additions and 62 deletions
@@ -506,7 +506,7 @@ namespace Framework.Constants
Unk482 = 482,
SuppressTransforms = 483, // NYI
Unk484 = 484,
Unk485 = 485,
ModMovementForceMagnitude = 485,
Unk486 = 486,
Unk487 = 487,
Unk488 = 488,
+82 -11
View File
@@ -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;
+5 -6
View File
@@ -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);
+1
View File
@@ -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>();
+134
View File
@@ -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();
+86
View File
@@ -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)
{
+121 -43
View File
@@ -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)
+27 -1
View File
@@ -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);
}
}