示例#1
0
        private bool IsAroundCollider(ITransformComponent transform, IMoverComponent mover,
                                      CollidableComponent collider)
        {
            foreach (var entity in _entityManager.GetEntitiesInRange(transform.Owner, mover.GrabRange, true))
            {
                if (entity == transform.Owner)
                {
                    continue; // Don't try to push off of yourself!
                }

                if (!entity.TryGetComponent <CollidableComponent>(out var otherCollider))
                {
                    continue;
                }

                // TODO: Item check.
                var touching = ((collider.CollisionMask & otherCollider.CollisionLayer) != 0x0 ||
                                (otherCollider.CollisionMask & collider.CollisionLayer) != 0x0) && // Ensure collision
                               true;    // !entity.HasComponent<ItemComponent>(); // This can't be an item

                if (touching)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#2
0
        public override void Initialize()
        {
            base.Initialize();

            collidableComponent         = Owner.GetComponent <CollidableComponent>();
            collidableComponent.OnBump += OnBump;
        }
        public void TerminateEntity()
        {
            // Arrange.
            int entityID = 76;

            CollidableComponent      collidable = new CollidableComponent(entityID);
            PositionComponent        position   = new PositionComponent(entityID, 43f, 0f);
            Texture2DRenderComponent texture    = new Texture2DRenderComponent(entityID, 7, null);

            componentManager
            .RegisterType <CollidableComponent, CollidableComponentCR>()
            .RegisterType <PositionComponent, PositionCR>()
            .RegisterType <Texture2DRenderComponent, Texture2DRenderCR>()
            .SetComponent(collidable)
            .SetComponent(position)
            .SetComponent(texture);

            // Act.
            ((IComponentTerminator)componentManager).TerminateEntity(entityID);

            // Assert.
            Assert.IsTrue(!componentManager.ContainsComponent <CollidableComponent>(entityID) &&
                          !componentManager.ContainsComponent <PositionComponent>(entityID) &&
                          !componentManager.ContainsComponent <Texture2DRenderComponent>(entityID));
        }
示例#4
0
        public override void Initialize()
        {
            base.Initialize();

            collidableComponent = Owner.GetComponent <CollidableComponent>();
            spriteComponent     = Owner.GetComponent <SpriteComponent>();
        }
示例#5
0
        public override void OnRemove()
        {
            collidableComponent = null;
            spriteComponent     = null;

            base.OnRemove();
        }
示例#6
0
        public override void Initialize()
        {
            base.Initialize();

            collidableComponent = Owner.GetComponent <CollidableComponent>();
            _appearance         = Owner.GetComponent <AppearanceComponent>();
        }
示例#7
0
        public override void OnRemove()
        {
            collidableComponent = null;
            _appearance         = null;

            base.OnRemove();
        }
示例#8
0
        public void InitComponent(int entityID)
        {
            // Arrange.
            CollidableComponent component;

            // Act.
            component = new CollidableComponent(entityID);

            // Assert.
            Assert.AreEqual(entityID, component.EntityID);
        }
示例#9
0
        public void Equals_ShouldBeEqual(int entityID)
        {
            // Arrange.
            CollidableComponent component1;
            CollidableComponent component2;

            // Act.
            component1 = new CollidableComponent(entityID);
            component2 = new CollidableComponent(entityID);

            // Assert.
            Assert.IsTrue(component1 == component2);
        }
示例#10
0
        public void Equals_ShouldNotBeEqual(int entity1, int entity2)
        {
            // Arrange.
            CollidableComponent component1;
            CollidableComponent component2;

            // Act.
            component1 = new CollidableComponent(entity1);
            component2 = new CollidableComponent(entity2);

            // Assert.
            Assert.IsFalse(component1 == component2);
        }
示例#11
0
        /// <summary>
        /// Send an event, if the object is entering a collision.
        /// </summary>
        /// <param name="collider">
        /// The <see cref="Collider"/> collider of the trigger object, reported by Unity.
        /// </param>
        public void OnTriggerEnter(Collider collider)
        {
            CollidableComponent collidee = collider.GetComponent <CollidableComponent>();

            if (collidee == null)
            {
                return;
            }

            int entityId            = this.GetComponent <EntityComponent>().EntityId;
            CollisionEventData data = new CollisionEventData(entityId, collidee.EntityId, collider);

            this.Game.EventManager.FireEvent(
                new HelGamesEvent(
                    CollisionEvents.TriggerEntered,
                    data));
        }
示例#12
0
        /// <summary>
        /// Send an event, if the object is entering a collision.
        /// </summary>
        /// <param name="collisionInfo">
        /// The <see cref="Collision"/> collision information, reported by Unity.
        /// </param>
        public void OnCollisionExit(Collision collisionInfo)
        {
            CollidableComponent collidee = collisionInfo.collider.GetComponent <CollidableComponent>();

            if (collidee == null)
            {
                return;
            }

            int entityId            = this.GetComponent <EntityComponent>().EntityId;
            CollisionEventData data = new CollisionEventData(entityId, collidee.EntityId, collisionInfo);

            this.Game.EventManager.FireEvent(
                new HelGamesEvent(
                    CollisionEvents.CollisionLeft,
                    data));
        }
示例#13
0
        public Monsters(string name, Vector2 pos) : base(pos)
        {
            Sprite   = GFX.SpriteBank.Create(name);
            Collider = new Hitbox(Sprite.Width, Sprite.Height);
            Add(Sprite);
            Tag = GAccess.HittableTag;
            AddTag(GAccess.MonsterTag);
            StateMachine       = new StateMachine(2);
            StateMachine.State = StIdle;

            // detect area
            DetectAreaCollider = new CollidableComponent(true, false, true);
            float detectAreaColliderWidth  = Sprite.Width * 3;
            float detectAreaColliderHeight = Sprite.Width * 3;

            DetectAreaCollider.Collider = new Hitbox(detectAreaColliderWidth, detectAreaColliderHeight,
                                                     -detectAreaColliderWidth / 2 + Sprite.Width / 2,
                                                     -detectAreaColliderHeight / 2 + Sprite.Height / 2);
            Add(DetectAreaCollider);

            Depth = 1;
        }
示例#14
0
 private IEnumerable <Manifold> FindCollisionsFor(CollidableComponent a,
                                                  List <(EntityUid, EntityUid)> combinations,
示例#15
0
 public override void OnRemove()
 {
     collidableComponent.OnBump -= OnBump;
     collidableComponent         = null;
     spriteComponent             = null;
 }
示例#16
0
        private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent collider = null)
        {
            if (physics.Controller == null)
            {
                // Set up controller
                physics.SetController <MoverController>();
            }

            var weightless = !transform.Owner.HasComponent <MovementIgnoreGravityComponent>() &&
                             _physicsManager.IsWeightless(transform.GridPosition);

            if (weightless && collider != null)
            {
                // No gravity: is our entity touching anything?
                var touching = IsAroundCollider(transform, mover, collider);

                if (!touching)
                {
                    return;
                }
            }

            if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless)
            {
                (physics.Controller as MoverController)?.StopMoving();
            }
            else
            {
                if (weightless)
                {
                    (physics.Controller as MoverController)?.Push(mover.VelocityDir, mover.CurrentPushSpeed);
                    transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle();
                    return;
                }
                (physics.Controller as MoverController)?.Move(mover.VelocityDir,
                                                              mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed);
                transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle();

                // Handle footsteps.
                if (_mapManager.GridExists(mover.LastPosition.GridID))
                {
                    // Can happen when teleporting between grids.
                    var distance = transform.GridPosition.Distance(_mapManager, mover.LastPosition);
                    mover.StepSoundDistance += distance;
                }

                mover.LastPosition = transform.GridPosition;
                float distanceNeeded;
                if (mover.Sprinting)
                {
                    distanceNeeded = StepSoundMoveDistanceRunning;
                }
                else
                {
                    distanceNeeded = StepSoundMoveDistanceWalking;
                }
                if (mover.StepSoundDistance > distanceNeeded)
                {
                    mover.StepSoundDistance = 0;

                    if (!mover.Owner.HasComponent <FootstepSoundComponent>())
                    {
                        return;
                    }

                    if (mover.Owner.TryGetComponent <InventoryComponent>(out var inventory) &&
                        inventory.TryGetSlotItem <ItemComponent>(EquipmentSlotDefines.Slots.SHOES, out var item) &&
                        item.Owner.TryGetComponent <FootstepModifierComponent>(out var modifier))
                    {
                        modifier.PlayFootstep();
                    }
                    else
                    {
                        PlayFootstepSound(transform.GridPosition);
                    }
                }
            }
        public override void Update(GameTime gameTime)
        {
            // Var to store collision event data.
            IList <CollisionEvent> collisionEvents = new List <CollisionEvent>();

            // Get running worlds.
            IReadOnlyList <IWorld> worlds = worldManager.GetWorldsInState(WorldState.Running);

            // Run through running worlds and check for collisions.
            foreach (IWorld world in worlds)
            {
                // Store component manager.
                IComponentManager componentManager = world.ComponentManager;

                // Check if the world has the required component registries.
                if (!componentManager.ContainsRegistry <CollidableComponent>() ||
                    !componentManager.ContainsRegistry <HitboxCollisionComponent>() ||
                    !componentManager.ContainsRegistry <PositionComponent>() ||
                    !componentManager.ContainsRegistry <TransformComponent>())
                {
                    continue;
                }

                // Get component registries.
                IComponentRegistry <CollidableComponent> collidableComponents =
                    (IComponentRegistry <CollidableComponent>)componentManager.GetRegistry <CollidableComponent>();
                IComponentRegistry <HitboxCollisionComponent> hitboxCollisionComponents =
                    (IComponentRegistry <HitboxCollisionComponent>)componentManager.GetRegistry <HitboxCollisionComponent>();
                IComponentRegistry <PositionComponent> positionComponents =
                    (IComponentRegistry <PositionComponent>)componentManager.GetRegistry <PositionComponent>();
                IComponentRegistry <TransformComponent> transformComponents =
                    (IComponentRegistry <TransformComponent>)componentManager.GetRegistry <TransformComponent>();

                // Iterate hitbox collision components.
                for (int i = 0; i < hitboxCollisionComponents.Count; i++)
                {
                    // Get components.
                    HitboxCollisionComponent hitbox    = hitboxCollisionComponents[i];
                    PositionComponent        position  = positionComponents.Get(hitbox.EntityID);
                    TransformComponent       transform = transformComponents.Get(hitbox.EntityID);

                    // Iterate collidable components and calculate collision.
                    for (int j = 0; j < collidableComponents.Count; j++)
                    {
                        // Get components for collidable entity.
                        CollidableComponent collidable          = collidableComponents[j];
                        PositionComponent   collidablePosition  = positionComponents.Get(collidable.EntityID);
                        TransformComponent  collidableTransform = transformComponents.Get(collidable.EntityID);

                        // Create hitboxes.
                        Rectangle entityA = new Rectangle((int)position.X, (int)position.Y, transform.Width, transform.Height);
                        Rectangle entityB = new Rectangle((int)collidablePosition.X, (int)collidablePosition.Y,
                                                          collidableTransform.Width, collidableTransform.Height);

                        // Perform collision detection.
                        if (entityA.Intersects(entityB))
                        {
                            // Entities collided.
                            collisionEvents.Add(new CollisionEvent(hitbox.EntityID, collidable.EntityID, world.ID));
                        }
                    }
                }
            }

            // An entity can be both a collider and a collidable, so filter out any events where this is true.
            // We could check this before performing the collision detection but we want to avoid
            // branch predictions in the hot path as much as possible.
            collisionEvents = collisionEvents.Where(x => x.Collidable != x.Collider).ToList();

            // Emit events.
            foreach (CollisionEvent collisionEvent in collisionEvents)
            {
                eventManager.Emit(collisionEvent);
            }
        }
示例#18
0
        public override void Run()
        {
            // If there is no state, setup world.
            if (State == WorldState.None)
            {
                // Create ball.
                int ballID = EntityManager.CreateEntity();

                // Load texture.
                Texture2D ballTexture = ContentManager.Load <Texture2D>("square");

                // Create components.
                HitboxCollisionComponent ballHitbox   = new HitboxCollisionComponent(ballID);
                PhysicsComponent         ballPhysics  = new PhysicsComponent(ballID, 0, 0, 0, 0, 1, 150, 150);
                PositionComponent        ballPosition = new PositionComponent(ballID,
                                                                              (engine.ScreenWidth / 2) - (ballTexture.Width / 2), (engine.ScreenHeight / 2) - (ballTexture.Height / 2));
                Texture2DRenderComponent ballRender    = new Texture2DRenderComponent(ballID, 1, ballTexture);
                TransformComponent       ballTransform = new TransformComponent(ballID, ballTexture.Height, 0, 1, ballTexture.Width);

                // Add components.
                ComponentManager
                .SetComponent(ballHitbox)
                .SetComponent(ballPhysics)
                .SetComponent(ballPosition)
                .SetComponent(ballRender)
                .SetComponent(ballTransform);

                // Emit ball create event.
                EventManager.Emit(new BallCreateEvent(ballID));


                // Create player one paddle.
                int paddleAID = EntityManager.CreateEntity();

                // Load texture.
                Texture2D paddleATexture = ContentManager.Load <Texture2D>("paddle");

                // Create components.
                CollidableComponent      paddleACollidable = new CollidableComponent(paddleAID);
                PhysicsComponent         paddleAPhysics    = new PhysicsComponent(paddleAID, 0, 0, 0, 0, 1, 0, 0);
                PositionComponent        paddleAPosition   = new PositionComponent(paddleAID, 0, (engine.ScreenHeight / 2) - (paddleATexture.Height / 2));
                Texture2DRenderComponent paddleARender     = new Texture2DRenderComponent(paddleAID, 2, paddleATexture);
                TransformComponent       paddleATransform  = new TransformComponent(paddleAID, paddleATexture.Height, 0, 1, paddleATexture.Width);

                // Add components.
                ComponentManager
                .SetComponent(paddleACollidable)
                .SetComponent(paddleAPhysics)
                .SetComponent(paddleAPosition)
                .SetComponent(paddleARender)
                .SetComponent(paddleATransform);

                // Emit paddle create event.
                EventManager.Emit(new PaddleCreateEvent(paddleAID, 1));


                // Create player two paddle.
                int paddleBID = EntityManager.CreateEntity();

                // Load texture.
                Texture2D paddleBTexture = ContentManager.Load <Texture2D>("paddle");

                // Create components.
                CollidableComponent paddleBCollidable = new CollidableComponent(paddleBID);
                PhysicsComponent    paddleBPhysics    = new PhysicsComponent(paddleBID, 0, 0, 0, 0, 1, 0, 0);
                PositionComponent   paddleBPosition   = new PositionComponent(paddleBID, (engine.ScreenWidth - paddleBTexture.Width),
                                                                              (engine.ScreenHeight / 2) - (paddleBTexture.Height / 2));
                Texture2DRenderComponent paddleBRender    = new Texture2DRenderComponent(paddleBID, 2, paddleBTexture);
                TransformComponent       paddleBTransform = new TransformComponent(paddleBID, paddleBTexture.Height, 0, 1, paddleBTexture.Width);

                // Add components.
                ComponentManager
                .SetComponent(paddleBCollidable)
                .SetComponent(paddleBPhysics)
                .SetComponent(paddleBPosition)
                .SetComponent(paddleBRender)
                .SetComponent(paddleBTransform);

                // Emit paddle create event.
                EventManager.Emit(new PaddleCreateEvent(paddleBID, 2));
            }

            base.Run();
        }
示例#19
0
 private void FindCollisionsFor(CollidableComponent a, PhysicsComponent aPhysics,
                                HashSet <(EntityUid, EntityUid)> combinations)
        public override void Run()
        {
            // If there is no state, setup world.
            if (State == WorldState.None)
            {
                // Initialise random number generator.
                Random random = new Random();

                // Var to hold IDs of created balls.
                int[] ballIDs = new int[Pong.BallCount];

                // Create balls.
                for (int i = 0; i < ballIDs.Length; i++)
                {
                    // Create ball.
                    int ballID = EntityManager.CreateEntity();

                    // Load texture.
                    Texture2D ballTexture = ContentManager.Load <Texture2D>("square");

                    // Create components.
                    HitboxCollisionComponent ballHitbox   = new HitboxCollisionComponent(ballID);
                    PhysicsComponent         ballPhysics  = new PhysicsComponent(ballID, 0, 0, 0, 0, 1, 150, 150);
                    PositionComponent        ballPosition = new PositionComponent(ballID,
                                                                                  random.Next(200, engine.ScreenWidth - 201) - (ballTexture.Width / 2),
                                                                                  random.Next(150, engine.ScreenHeight - 151) - (ballTexture.Height / 2));
                    Texture2DRenderComponent ballRender    = new Texture2DRenderComponent(ballID, 1, ballTexture);
                    TransformComponent       ballTransform = new TransformComponent(ballID, ballTexture.Height, 0, 0.35f, ballTexture.Width);

                    // Add components.
                    ComponentManager
                    .SetComponent(ballHitbox)
                    .SetComponent(ballPhysics)
                    .SetComponent(ballPosition)
                    .SetComponent(ballRender)
                    .SetComponent(ballTransform);

                    // Add ID to array.
                    ballIDs[i] = ballID;
                }

                // Emit ball create event.
                EventManager.Emit(new BallCreateEvent(ballIDs));


                // Create player one paddle.
                int paddleAID = EntityManager.CreateEntity();

                // Load texture.
                Texture2D paddleATexture = ContentManager.Load <Texture2D>("paddle");

                // Create components.
                CollidableComponent      paddleACollidable = new CollidableComponent(paddleAID);
                PhysicsComponent         paddleAPhysics    = new PhysicsComponent(paddleAID, 0, 0, 0, 0, 1, 0, 0);
                PositionComponent        paddleAPosition   = new PositionComponent(paddleAID, 0, (engine.ScreenHeight / 2) - (paddleATexture.Height / 2));
                Texture2DRenderComponent paddleARender     = new Texture2DRenderComponent(paddleAID, 2, paddleATexture);
                TransformComponent       paddleATransform  = new TransformComponent(paddleAID, paddleATexture.Height, 0, 1, paddleATexture.Width);

                // Add components.
                ComponentManager
                .SetComponent(paddleACollidable)
                .SetComponent(paddleAPhysics)
                .SetComponent(paddleAPosition)
                .SetComponent(paddleARender)
                .SetComponent(paddleATransform);

                // Emit paddle create event.
                EventManager.Emit(new PaddleCreateEvent(paddleAID, 1));


                // Create player two paddle.
                int paddleBID = EntityManager.CreateEntity();

                // Load texture.
                Texture2D paddleBTexture = ContentManager.Load <Texture2D>("paddle");

                // Create components.
                CollidableComponent paddleBCollidable = new CollidableComponent(paddleBID);
                PhysicsComponent    paddleBPhysics    = new PhysicsComponent(paddleBID, 0, 0, 0, 0, 1, 0, 0);
                PositionComponent   paddleBPosition   = new PositionComponent(paddleBID, (engine.ScreenWidth - paddleBTexture.Width),
                                                                              (engine.ScreenHeight / 2) - (paddleBTexture.Height / 2));
                Texture2DRenderComponent paddleBRender    = new Texture2DRenderComponent(paddleBID, 2, paddleBTexture);
                TransformComponent       paddleBTransform = new TransformComponent(paddleBID, paddleBTexture.Height, 0, 1, paddleBTexture.Width);

                // Add components.
                ComponentManager
                .SetComponent(paddleBCollidable)
                .SetComponent(paddleBPhysics)
                .SetComponent(paddleBPosition)
                .SetComponent(paddleBRender)
                .SetComponent(paddleBTransform);

                // Emit paddle create event.
                EventManager.Emit(new PaddleCreateEvent(paddleBID, 2));
            }

            base.Run();
        }
示例#21
0
        public override void Update(GameTime gameTime)
        {
            // Var to store collision event data.
            IList <CollisionEvent> collisionEvents = new List <CollisionEvent>();

            // Get running worlds.
            IReadOnlyList <IWorld> worlds = worldManager.GetWorldsInState(WorldState.Running);

            // Run through running worlds and check for collisions.
            foreach (IWorld world in worlds)
            {
                // Store component manager.
                IComponentManager componentManager = world.ComponentManager;

                // Check if the world has the required component registries.
                if (!componentManager.ContainsRegistry <CircleCollisionComponent>() ||
                    !componentManager.ContainsRegistry <CollidableComponent>() ||
                    !componentManager.ContainsRegistry <PositionComponent>() ||
                    !componentManager.ContainsRegistry <TransformComponent>())
                {
                    continue;
                }

                // Get component registries.
                IComponentRegistry <CircleCollisionComponent> circleCollisionComponents =
                    (IComponentRegistry <CircleCollisionComponent>)componentManager.GetRegistry <CircleCollisionComponent>();
                IComponentRegistry <CollidableComponent> collidableComponents =
                    (IComponentRegistry <CollidableComponent>)componentManager.GetRegistry <CollidableComponent>();
                IComponentRegistry <PositionComponent> positionComponents =
                    (IComponentRegistry <PositionComponent>)componentManager.GetRegistry <PositionComponent>();
                IComponentRegistry <TransformComponent> transformComponents =
                    (IComponentRegistry <TransformComponent>)componentManager.GetRegistry <TransformComponent>();

                // Iterate circle collision components.
                for (int i = 0; i < circleCollisionComponents.Count; i++)
                {
                    // Get components.
                    CircleCollisionComponent circle    = circleCollisionComponents[i];
                    PositionComponent        position  = positionComponents.Get(circle.EntityID);
                    TransformComponent       transform = transformComponents.Get(circle.EntityID);

                    // Iterate collidable components and calculate collision.
                    for (int j = 0; j < collidableComponents.Count; j++)
                    {
                        // Get components for collidable entity.
                        CollidableComponent collidable          = collidableComponents[j];
                        PositionComponent   collidablePosition  = positionComponents.Get(collidable.EntityID);
                        TransformComponent  collidableTransform = transformComponents.Get(collidable.EntityID);

                        // Calculate the radius of the entities.
                        float rA = (transform.Scale * transform.Width) / 2;
                        float rB = (collidableTransform.Scale * collidableTransform.Width) / 2;

                        // Check if the distance between the two entities is less than the radii.
                        if (Vector2.Distance(new Vector2(position.X, position.Y),
                                             new Vector2(collidablePosition.X, collidablePosition.Y)) < (rA + rB))
                        {
                            // Entities collided.
                            collisionEvents.Add(new CollisionEvent(circle.EntityID, collidable.EntityID, world.ID));
                        }
                    }
                }
            }

            // An entity can be both a collider and a collidable, so filter out any events where this is true.
            // We could check this before performing the collision detection but we want to avoid
            // branch predictions in the hot path as much as possible.
            collisionEvents = collisionEvents.Where(x => x.Collidable != x.Collider).ToList();

            // Emit events.
            foreach (CollisionEvent collisionEvent in collisionEvents)
            {
                eventManager.Emit(collisionEvent);
            }
        }
示例#22
0
 public PhysShapeList(CollidableComponent owner)
 {
     _owner = owner;
 }
示例#23
0
        private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent collider = null)
        {
            bool weightless = false;

            var tile = _mapManager.GetGrid(transform.GridID).GetTileRef(transform.GridPosition).Tile;

            if ((!_mapManager.GetGrid(transform.GridID).HasGravity || tile.IsEmpty) && collider != null)
            {
                weightless = true;
                // No gravity: is our entity touching anything?
                var touching = false;
                foreach (var entity in _entityManager.GetEntitiesInRange(transform.Owner, mover.GrabRange, true))
                {
                    if (entity.TryGetComponent <CollidableComponent>(out var otherCollider))
                    {
                        if (otherCollider.Owner == transform.Owner)
                        {
                            continue;                                         // Don't try to push off of yourself!
                        }
                        touching |= ((collider.CollisionMask & otherCollider.CollisionLayer) != 0x0 ||
                                     (otherCollider.CollisionMask & collider.CollisionLayer) != 0x0) && // Ensure collision
                                    !entity.HasComponent <ItemComponent>();   // This can't be an item
                    }
                }
                if (!touching)
                {
                    return;
                }
            }
            if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner))
            {
                if (physics.LinearVelocity != Vector2.Zero)
                {
                    physics.LinearVelocity = Vector2.Zero;
                }
            }
            else
            {
                if (weightless)
                {
                    physics.LinearVelocity  = mover.VelocityDir * mover.CurrentPushSpeed;
                    transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle();
                    return;
                }

                physics.LinearVelocity  = mover.VelocityDir * (mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed);
                transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle();

                // Handle footsteps.
                if (_mapManager.GridExists(mover.LastPosition.GridID))
                {
                    // Can happen when teleporting between grids.
                    var distance = transform.GridPosition.Distance(_mapManager, mover.LastPosition);
                    mover.StepSoundDistance += distance;
                }

                mover.LastPosition = transform.GridPosition;
                float distanceNeeded;
                if (mover.Sprinting)
                {
                    distanceNeeded = StepSoundMoveDistanceRunning;
                }
                else
                {
                    distanceNeeded = StepSoundMoveDistanceWalking;
                }
                if (mover.StepSoundDistance > distanceNeeded)
                {
                    mover.StepSoundDistance = 0;

                    if (!mover.Owner.HasComponent <FootstepSoundComponent>())
                    {
                        return;
                    }

                    if (mover.Owner.TryGetComponent <InventoryComponent>(out var inventory) &&
                        inventory.TryGetSlotItem <ItemComponent>(EquipmentSlotDefines.Slots.SHOES, out var item) &&
                        item.Owner.TryGetComponent <FootstepModifierComponent>(out var modifier))
                    {
                        modifier.PlayFootstep();
                    }
                    else
                    {
                        PlayFootstepSound(transform.GridPosition);
                    }
                }
            }