Core/Movement: Implemented movement forces
Port From (https://github.com/TrinityCore/TrinityCore/commit/8e98ceb2936842ea0032cbfdc04a510d6b1e5de0)
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user