private void SetMoveInput(InputMoverComponent component, MoveButtons buttons)
 {
     if (component.HeldMoveButtons == buttons)
     {
         return;
     }
     component.HeldMoveButtons = buttons;
     Dirty(component);
 }
 private void OnInputHandleState(EntityUid uid, InputMoverComponent component, ref ComponentHandleState args)
 {
     if (args.Current is not InputMoverComponentState state)
     {
         return;
     }
     component.HeldMoveButtons  = state.Buttons;
     component.LastInputTick    = GameTick.Zero;
     component.LastInputSubTick = 0;
     component.CanMove          = state.CanMove;
 }
        private void OnInputInit(EntityUid uid, InputMoverComponent component, ComponentInit args)
        {
            var xform = Transform(uid);

            if (!xform.ParentUid.IsValid())
            {
                return;
            }

            component.LastGridAngle = Transform(xform.ParentUid).WorldRotation;
        }
        private void SetMoveInput(InputMoverComponent component, ushort subTick, bool enabled, MoveButtons bit)
        {
            // Modifies held state of a movement button at a certain sub tick and updates current tick movement vectors.
            ResetSubtick(component);

            if (subTick >= component.LastInputSubTick)
            {
                var fraction = (subTick - component.LastInputSubTick) / (float)ushort.MaxValue;

                ref var lastMoveAmount = ref component.Sprinting ? ref component.CurTickSprintMovement : ref component.CurTickWalkMovement;

                lastMoveAmount += DirVecForButtons(component.HeldMoveButtons) * fraction;

                component.LastInputSubTick = subTick;
            }
        /// <summary>
        ///     Toggles one of the four cardinal directions. Each of the four directions are
        ///     composed into a single direction vector, <see cref="VelocityDir"/>. Enabling
        ///     opposite directions will cancel each other out, resulting in no direction.
        /// </summary>
        public void SetVelocityDirection(InputMoverComponent component, Direction direction, ushort subTick, bool enabled)
        {
            // Logger.Info($"[{_gameTiming.CurTick}/{subTick}] {direction}: {enabled}");

            var bit = direction switch
            {
                Direction.East => MoveButtons.Right,
                Direction.North => MoveButtons.Up,
                Direction.West => MoveButtons.Left,
                Direction.South => MoveButtons.Down,
                _ => throw new ArgumentException(nameof(direction))
            };

            SetMoveInput(component, subTick, enabled, bit);
        }
        public (Vector2 Walking, Vector2 Sprinting) GetVelocityInput(InputMoverComponent mover)
        {
            if (!Timing.InSimulation)
            {
                // Outside of simulation we'll be running client predicted movement per-frame.
                // So return a full-length vector as if it's a full tick.
                // Physics system will have the correct time step anyways.
                var immediateDir = DirVecForButtons(mover.HeldMoveButtons);
                return(mover.Sprinting ? (Vector2.Zero, immediateDir) : (immediateDir, Vector2.Zero));
            }

            Vector2 walk;
            Vector2 sprint;
            float   remainingFraction;

            if (Timing.CurTick > mover.LastInputTick)
            {
                walk              = Vector2.Zero;
                sprint            = Vector2.Zero;
                remainingFraction = 1;
            }
            else
            {
                walk              = mover.CurTickWalkMovement;
                sprint            = mover.CurTickSprintMovement;
                remainingFraction = (ushort.MaxValue - mover.LastInputSubTick) / (float)ushort.MaxValue;
            }

            var curDir = DirVecForButtons(mover.HeldMoveButtons) * remainingFraction;

            if (mover.Sprinting)
            {
                sprint += curDir;
            }
            else
            {
                walk += curDir;
            }

            // Logger.Info($"{curDir}{walk}{sprint}");
            return(walk, sprint);
        }
 private void OnInputGetState(EntityUid uid, InputMoverComponent component, ref ComponentGetState args)
 {
     args.State = new InputMoverComponentState(component.HeldMoveButtons, component.CanMove);
 }
 private void OnMoverStartup(EntityUid uid, InputMoverComponent component, ComponentStartup args)
 {
     UpdateCanMove(uid, component);
 }