using System; using ACE.Entity.Enum; using ACE.Server.Network.Structure; namespace ACE.Server.Physics.Animation { public class MovementParameters { public MovementParamFlags Flags { get => MovementParamFlagsHelper.Get(this); set => MovementParamFlagsHelper.Set(this, value); } public bool CanWalk; public bool CanRun; public bool CanSidestep; public bool CanWalkBackwards; public bool CanCharge; public bool FailWalk; public bool UseFinalHeading; public bool Sticky; public bool MoveAway; public bool MoveTowards; public bool UseSpheres; public bool SetHoldKey; public bool Autonomous; public bool ModifyRawState; public bool ModifyInterpretedState; public bool CancelMoveTo; public bool StopCompletely; public bool DisableJumpDuringLink; public float DistanceToObject; public float MinDistance; public float DesiredHeading; public float Speed; public float FailDistance; public float WalkRunThreshold; public int ContextID; public HoldKey HoldKeyToApply; public int ActionStamp; public const float Default_DistanceToObject = 0.6f; public const float Default_FailDistance = float.MaxValue; public const float Default_MinDistance = 0.0f; public const float Default_Speed = 1.0f; //public const float Default_WalkRunThreshold = 15.0f; public const float Default_WalkRunThreshold = 1.0f; public MovementParameters() { CanWalk = true; CanRun = true; CanSidestep = true; CanWalkBackwards = true; CanCharge = true; //FailWalk = false; //UseFinalHeading = false; //Sticky = false; //MoveAway = false; MoveTowards = true; UseSpheres = true; SetHoldKey = true; //Autonomous = false; ModifyRawState = true; ModifyInterpretedState = true; CancelMoveTo = true; StopCompletely = true; //DisableJumpDuringLink = false; DistanceToObject = Default_DistanceToObject; FailDistance = Default_FailDistance; //DesiredHeading = 0; MinDistance = Default_MinDistance; Speed = Default_Speed; WalkRunThreshold = Default_WalkRunThreshold; //ContextID = 0; HoldKeyToApply = HoldKey.Invalid; //ActionStamp = 0; //Flags = (MovementParamFlags)0x1EE0F; } /// /// Copy construtor /// public MovementParameters(MovementParameters mvp, bool onlyBits = false) { Flags = mvp.Flags; if (!onlyBits) CopyNonFlag(mvp); } /// /// Only copies some fields from input movement params /// public void CopySome(MovementParameters mvp) { // TODO: should this really be only copying some fields?? review CanWalk = mvp.CanWalk; CanRun = mvp.CanRun; CanSidestep = mvp.CanSidestep; CanWalkBackwards = mvp.CanWalkBackwards; CanCharge = mvp.CanCharge; // - failwalk // - use final heading // - sticky // - moveaway MoveTowards = mvp.MoveTowards; UseSpheres = mvp.UseSpheres; SetHoldKey = mvp.SetHoldKey; // - autonomous ModifyRawState = mvp.ModifyRawState; ModifyInterpretedState = mvp.ModifyInterpretedState; CancelMoveTo = mvp.CancelMoveTo; StopCompletely = mvp.StopCompletely; // - disable jump during link DistanceToObject = mvp.DistanceToObject; FailDistance = mvp.FailDistance; // - desired heading MinDistance = mvp.MinDistance; Speed = mvp.Speed; WalkRunThreshold = mvp.WalkRunThreshold; // - context id HoldKeyToApply = mvp.HoldKeyToApply; // - action stamp } public void CopyNonFlag(MovementParameters mvp) { // TODO: review again, take bitflags into consideration DistanceToObject = mvp.DistanceToObject; FailDistance = mvp.FailDistance; DesiredHeading = mvp.DesiredHeading; MinDistance = mvp.MinDistance; Speed = mvp.Speed; WalkRunThreshold = mvp.WalkRunThreshold; ContextID = mvp.ContextID; HoldKeyToApply = mvp.HoldKeyToApply; ActionStamp = mvp.ActionStamp; } public void get_command(float dist, float heading, ref uint motion, ref HoldKey holdKey, ref bool movingAway) { if (MoveTowards || !MoveAway) { if (MoveAway) towards_and_away(dist, heading, ref motion, ref movingAway); else { if (dist > DistanceToObject) { motion = (uint)MotionCommand.WalkForward; movingAway = false; } else motion = 0; } } else if (MoveAway) { if (dist < MinDistance) { motion = (uint)MotionCommand.WalkForward; movingAway = true; } else motion = 0; } if (CanRun && (!CanWalk || dist - DistanceToObject > WalkRunThreshold)) holdKey = HoldKey.Run; else holdKey = HoldKey.None; } public float get_desired_heading(uint motion, bool movingAway) { switch (motion) { case (uint)MotionCommand.RunForward: case (uint)MotionCommand.WalkForward: return movingAway ? 180.0f : 0.0f; case (uint)MotionCommand.WalkBackwards: return movingAway ? 0.0f : 180.0f; default: return 0.0f; } } public void towards_and_away(float dist, float heading, ref uint command, ref bool movingAway) { if (dist > DistanceToObject) { command = (uint)MotionCommand.WalkForward; movingAway = false; } else if (dist - MinDistance < PhysicsGlobals.EPSILON) { command = (uint)MotionCommand.WalkBackwards; movingAway = true; } else command = 0; } public MovementParameters(MoveToParameters mvp) { Flags = (MovementParamFlags)mvp.MovementParameters; DistanceToObject = mvp.DistanceToObject; MinDistance = mvp.MinDistance; DesiredHeading = mvp.DesiredHeading; Speed = mvp.Speed; FailDistance = mvp.FailDistance; WalkRunThreshold = mvp.WalkRunThreshold; } } }