using ACE.Entity; using ACE.Entity.Enum; using ACE.Server.Network.Structure; using ACE.Server.WorldObjects; using log4net; namespace ACE.Server.Entity { /// /// Convenience wrapper for transitioning the most common uses of Motion /// public class Motion { private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); // previously in MotionState base abstract class, only 1 reference // IsAutonomous TRUE would indicate a client-initiated movement public bool IsAutonomous; /// /// 5 different modes of operation: Invalid (General), MoveToObject, MoveToPosition, TurnToObject, TurnToHeading /// public MovementType MovementType; public MotionFlags MotionFlags; // stick to object / standing long jump public MotionStance Stance; // CurrentStyle // modes of operation: // General - InterpretedMotionState / StickyObject public InterpretedMotionState MotionState = new InterpretedMotionState(); public ObjectGuid TargetGuid; // this is dual-purposed for both Target and StickyObject (fixme) // MoveToObject - targetguid, position, movetoparams, runrate public Position Position; // used for: MoveTo's public MoveToParameters MoveToParameters = new MoveToParameters(); // used for MoveTo and TurnTo public float RunRate; // used for: MoveTo's // MoveToPosition - position, movetoparams, runrate // TurnToObject - target, desiredheading, turnto params public float DesiredHeading; // overrides MovementParams version // TurnToHeading - turnto params /// /// Constructs a new Motion from a MotionStance /// This is used to switch combat stances /// public Motion(MotionStance stance) { Stance = stance; } /// /// Constructs a new MoveToObject / TurnToObject motion /// public Motion(WorldObject wo, WorldObject target, MovementType type) { if (wo.CurrentMotionState != null) Stance = wo.CurrentMotionState.Stance; else { Stance = new Motion(MotionStance.NonCombat).Stance; log.Warn($"{wo.Name} (0x{wo.Guid}) has a null CurrentMotionState, subbing in new Motion(MotionStance.NonCombat) for it."); } MovementType = type; Position = new Position(target.Location); TargetGuid = target.Guid; } /// /// Constructs a new MoveToPosition motion /// public Motion(WorldObject wo, Position position) { if (wo.CurrentMotionState != null) Stance = wo.CurrentMotionState.Stance; else { Stance = new Motion(MotionStance.NonCombat).Stance; log.Warn($"{wo.Name} (0x{wo.Guid}) has a null CurrentMotionState, subbing in new Motion(MotionStance.NonCombat) for it."); } MovementType = MovementType.MoveToPosition; Position = new Position(position); } /// /// Constructs a new TurnToHeading motion /// public Motion(WorldObject wo, Position position, float heading) { if (wo.CurrentMotionState != null) Stance = wo.CurrentMotionState.Stance; else { Stance = new Motion(MotionStance.NonCombat).Stance; log.Warn($"{wo.Name} (0x{wo.Guid}) has a null CurrentMotionState, subbing in new Motion(MotionStance.NonCombat) for it."); } MovementType = MovementType.TurnToHeading; Position = new Position(position); DesiredHeading = heading; } public Motion(MotionStance stance, MotionCommand motion, float speed = 1.0f) { Stance = stance; SetForwardCommand(motion, speed); } public Motion(WorldObject wo, MotionCommand motion, float speed = 1.0f) { if (wo.CurrentMotionState != null) Stance = wo.CurrentMotionState.Stance; else { Stance = new Motion(MotionStance.NonCombat).Stance; log.Warn($"{wo.Name} (0x{wo.Guid}) has a null CurrentMotionState, subbing in new Motion(MotionStance.NonCombat) for it."); } SetForwardCommand(motion, speed); } public Motion(Motion motion) { // copy constructor IsAutonomous = motion.IsAutonomous; MovementType = motion.MovementType; MotionFlags = motion.MotionFlags; Stance = motion.Stance; if (motion.MotionState != null) MotionState = new InterpretedMotionState(motion.MotionState); TargetGuid = motion.TargetGuid; if (motion.Position != null) Position = new Position(motion.Position); if (motion.MoveToParameters != null) MoveToParameters = new MoveToParameters(motion.MoveToParameters); RunRate = motion.RunRate; DesiredHeading = motion.DesiredHeading; } public void SetForwardCommand(MotionCommand motion, float speed = 1.0f) { MotionState.ForwardCommand = motion; MotionState.ForwardSpeed = speed; } public void SetSidestepCommand(MotionCommand motion, float speed = 1.0f) { MotionState.SidestepCommand = motion; MotionState.SidestepSpeed = speed; } public void SetTurnCommand(MotionCommand motion, float speed = 1.0f) { MotionState.TurnCommand = motion; MotionState.TurnSpeed = speed; } public void Persist(Motion motion) { SetSidestepCommand(motion.MotionState.SidestepCommand, motion.MotionState.SidestepSpeed); SetTurnCommand(motion.MotionState.TurnCommand, motion.MotionState.TurnSpeed); } } }