コード例 #1
0
    private Vector3 PickAPointInFront(IMoverComponent mover, float distanceAhead, float radius, float angle)
    {
        var centerPoint = mover.CurrentPosition + (mover.LastDirectionFacing.normalized * distanceAhead);
        var destination = GetPointWithinACircle(centerPoint, radius, angle);

        return(destination);
    }
コード例 #2
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);
        }
コード例 #3
0
        protected void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, IPhysicsComponent physics,
                                        ICollidableComponent?collider = null)
        {
            physics.EnsureController <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;
                }
            }

            // TODO: movement check.
            var(walkDir, sprintDir) = mover.VelocityDir;
            var combined = walkDir + sprintDir;

            if (combined.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless)
            {
                if (physics.TryGetController(out MoverController controller))
                {
                    controller.StopMoving();
                }
            }
            else
            {
                //Console.WriteLine($"{IoCManager.Resolve<IGameTiming>().TickStamp}: {combined}");

                if (weightless)
                {
                    if (physics.TryGetController(out MoverController controller))
                    {
                        controller.Push(combined, mover.CurrentPushSpeed);
                    }

                    transform.LocalRotation = walkDir.GetDir().ToAngle();
                    return;
                }

                var total = walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed;
                //Console.WriteLine($"{walkDir} ({mover.CurrentWalkSpeed}) + {sprintDir} ({mover.CurrentSprintSpeed}): {total}");

                { if (physics.TryGetController(out MoverController controller))
                  {
                      controller.Move(total, 1);
                  }
                }

                transform.LocalRotation = total.GetDir().ToAngle();

                HandleFootsteps(mover);
            }
        }
コード例 #4
0
    public static Vector3 Flee(Vector3 targetPosition, Vector3 currentVelocity, IMoverComponent mover)
    {
        var desired = (targetPosition - mover.CurrentPosition) * -1;

        //var desired = mover.CurrentPosition - targetPosition;
        desired = desired.normalized * mover.MaxSpeed;

        return(Steer(desired, currentVelocity, mover.MaxSteering));
    }
コード例 #5
0
        protected void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, IPhysicsComponent physics)
        {
            physics.EnsureController <MoverController>();

            var weightless = transform.Owner.IsWeightless();

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

                if (!touching)
                {
                    transform.LocalRotation = physics.LinearVelocity.GetDir().ToAngle();
                    return;
                }
            }

            // TODO: movement check.
            var(walkDir, sprintDir) = mover.VelocityDir;
            var combined = walkDir + sprintDir;

            if (combined.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless)
            {
                if (physics.TryGetController(out MoverController controller))
                {
                    controller.StopMoving();
                }
            }
            else
            {
                if (weightless)
                {
                    if (physics.TryGetController(out MoverController controller))
                    {
                        controller.Push(combined, mover.CurrentPushSpeed);
                    }

                    transform.LocalRotation = physics.LinearVelocity.GetDir().ToAngle();
                    return;
                }

                var total = walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed;

                {
                    if (physics.TryGetController(out MoverController controller))
                    {
                        controller.Move(total, 1);
                    }
                }

                transform.LocalRotation = total.GetDir().ToAngle();

                HandleFootsteps(mover);
            }
        }
コード例 #6
0
    public static Vector3 Seek(Vector3 targetPosition, Vector3 currentVelocity, IMoverComponent mover)
    {
        var desired = targetPosition - mover.CurrentPosition;

        //var desired = targetPosition - currentVelocity;
        desired = desired.normalized * mover.MaxSpeed;

        return(Steer(desired, mover.CurrentVelocity, mover.MaxSteering));
        //return Steer(desired, currentVelocity, mover.MaxSteering);
    }
コード例 #7
0
        /// <summary>
        ///     Movement while considering actionblockers, weightlessness, etc.
        /// </summary>
        /// <param name="mover"></param>
        /// <param name="physicsComponent"></param>
        /// <param name="mobMover"></param>
        protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent,
                                         IMobMoverComponent mobMover)
        {
            // TODO: Look at https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html?highlight=controller as it has some adviceo n kinematic controllersx
            if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _mapManager))
            {
                return;
            }

            var transform = mover.Owner.Transform;

            var(walkDir, sprintDir) = mover.VelocityDir;

            var weightless = transform.Owner.IsWeightless(physicsComponent, mapManager: _mapManager);

            // Handle wall-pushes.
            if (weightless)
            {
                // No gravity: is our entity touching anything?
                var touching = IsAroundCollider(_broadPhaseSystem, transform, mobMover, physicsComponent);

                if (!touching)
                {
                    transform.WorldRotation = physicsComponent.LinearVelocity.GetDir().ToAngle();
                    return;
                }
            }

            // Regular movement.
            // Target velocity.
            // This is relative to the map / grid we're on.
            var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed);

            var worldTotal = _relativeMovement ?
                             new Angle(transform.Parent !.WorldRotation.Theta).RotateVec(total) :
                             total;

            DebugTools.Assert(MathHelper.CloseTo(total.Length, worldTotal.Length));

            if (weightless)
            {
                worldTotal *= mobMover.WeightlessStrength;
            }

            if (worldTotal != Vector2.Zero)
            {
                // This should have its event run during island solver soooo
                transform.DeferUpdates  = true;
                transform.WorldRotation = worldTotal.GetDir().ToAngle();
                transform.DeferUpdates  = false;
                HandleFootsteps(mover, mobMover);
            }

            physicsComponent.LinearVelocity = worldTotal;
        }
コード例 #8
0
        private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics)
        {
            if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner))
            {
                if (physics.LinearVelocity != Vector2.Zero)
                {
                    physics.LinearVelocity = Vector2.Zero;
                }
            }
            else
            {
                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);
                    }
                }
            }
コード例 #9
0
        protected override void HandleFootsteps(IMoverComponent mover)
        {
            var transform = mover.Owner.Transform;

            // Handle footsteps.
            if (_mapManager.GridExists(mover.LastPosition.GetGridId(EntityManager)))
            {
                // Can happen when teleporting between grids.
                if (!transform.Coordinates.TryDistance(_entityManager, mover.LastPosition, out var distance))
                {
                    mover.LastPosition = transform.Coordinates;
                    return;
                }

                mover.StepSoundDistance += distance;
            }

            mover.LastPosition = transform.Coordinates;
            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.Coordinates);
                }
            }
コード例 #10
0
        /// <summary>
        ///     A generic kinematic mover for entities.
        /// </summary>
        protected void HandleKinematicMovement(IMoverComponent mover, PhysicsComponent physicsComponent)
        {
            var(walkDir, sprintDir) = mover.VelocityDir;

            // Regular movement.
            // Target velocity.
            var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed);

            if (total != Vector2.Zero)
            {
                mover.Owner.Transform.LocalRotation = total.GetDir().ToAngle();
            }

            physicsComponent.LinearVelocity = total;
        }
コード例 #11
0
        protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent, IMobMoverComponent mobMover)
        {
            // TODO: Look at https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html?highlight=controller as it has some adviceo n kinematic controllersx
            if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _physicsManager))
            {
                return;
            }

            var transform = mover.Owner.Transform;

            var(walkDir, sprintDir) = mover.VelocityDir;

            var weightless = transform.Owner.IsWeightless(_physicsManager);

            // Handle wall-pushes.
            if (weightless)
            {
                // No gravity: is our entity touching anything?
                var touching = IsAroundCollider(_broadPhaseSystem, transform, mobMover, physicsComponent);

                if (!touching)
                {
                    transform.LocalRotation = physicsComponent.LinearVelocity.GetDir().ToAngle();
                    return;
                }
            }

            // Regular movement.
            // Target velocity.
            var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed);

            if (weightless)
            {
                total *= mobMover.WeightlessStrength;
            }

            if (total != Vector2.Zero)
            {
                // This should have its event run during island solver soooo
                transform.DeferUpdates  = true;
                transform.LocalRotation = total.GetDir().ToAngle();
                transform.DeferUpdates  = false;
                HandleFootsteps(mover, mobMover);
            }

            physicsComponent.LinearVelocity = total;
        }
コード例 #12
0
        /// <summary>
        ///     A generic kinematic mover for entities.
        /// </summary>
        protected void HandleKinematicMovement(IMoverComponent mover, PhysicsComponent physicsComponent)
        {
            var(walkDir, sprintDir) = mover.VelocityDir;

            // Regular movement.
            // Target velocity.
            var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed);

            var worldTotal = _relativeMovement ? new Angle(mover.Owner.Transform.Parent !.WorldRotation.Theta).RotateVec(total) : total;

            if (worldTotal != Vector2.Zero)
            {
                mover.Owner.Transform.WorldRotation = worldTotal.GetDir().ToAngle();
            }

            physicsComponent.LinearVelocity = worldTotal;
        }
コード例 #13
0
    public static Vector3 Arriving(IMoverComponent mover, Vector3 direction, Vector3 target, float distanceFromTarget = 0, float threshold = 0)
    {
        if (threshold < 0 || distanceFromTarget < 0)
        {
            throw new ArgumentOutOfRangeException("Threshold or distanceFromTarget must have a value of >= 0");
        }

        float arrivingDistanceToTarget = Vector3.Distance(mover.CurrentPosition, target);

        var distance = Vector3.Distance(target, mover.CurrentPosition) - distanceFromTarget;

        if (distance < threshold)
        {
            distance = 0;
        }
        float multiplier = (distance < arrivingDistanceToTarget) ? distance / arrivingDistanceToTarget : 1;

        return(Vector3.ClampMagnitude(direction, mover.MaxSpeed * multiplier));
    }
コード例 #14
0
        private bool IsAroundCollider(ITransformComponent transform, IMoverComponent mover,
            IPhysicsComponent 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<IPhysicsComponent>(out var otherCollider) ||
                    !otherCollider.CanCollide ||
                    (collider.CollisionMask & otherCollider.CollisionLayer) == 0)
                {
                    continue;
                }

                // Don't count pulled entities
                if (otherCollider.HasController<PullController>())
                {
                    continue;
                }

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

                if (touching)
                {
                    return true;
                }
            }

            return false;
        }
コード例 #15
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);
                    }
                }
            }
コード例 #16
0
 protected virtual void HandleFootsteps(IMoverComponent mover)
 {
 }
コード例 #17
0
 private void OnMoverStartup(EntityUid uid, IMoverComponent component, ComponentStartup args)
 {
     UpdateCanMove(uid, component);
 }
 private void Awake()
 {
     _mover = GetComponent <IMoverComponent>();
 }
コード例 #19
0
ファイル: MoverSystem.cs プロジェクト: zamp/space-station-14
        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);
                    }
                }
            }