Beispiel #1
0
        private void AddAlternativeVerbs(EntityUid uid, MedicalScannerComponent component, GetAlternativeVerbsEvent args)
        {
            if (!args.CanAccess || !args.CanInteract)
            {
                return;
            }

            // Eject verb
            if (component.IsOccupied)
            {
                Verb verb = new();
                verb.Act      = () => component.EjectBody();
                verb.Category = VerbCategory.Eject;
                verb.Text     = Loc.GetString("medical-scanner-verb-noun-occupant");
                args.Verbs.Add(verb);
            }

            // Self-insert verb
            if (!component.IsOccupied &&
                component.CanInsert(args.User) &&
                _actionBlockerSystem.CanMove(args.User))
            {
                Verb verb = new();
                verb.Act  = () => component.InsertBody(args.User);
                verb.Text = Loc.GetString("medical-scanner-verb-enter");
                // TODO VERN ICON
                // TODO VERB CATEGORY
                // create a verb category for "enter"?
                // See also, disposal unit.  Also maybe add verbs for entering lockers/body bags?
                args.Verbs.Add(verb);
            }
        }
        private void AddAlternativeVerbs(EntityUid uid, MedicalScannerComponent component, GetVerbsEvent <AlternativeVerb> args)
        {
            if (!args.CanAccess || !args.CanInteract)
            {
                return;
            }

            // Eject verb
            if (IsOccupied(component))
            {
                AlternativeVerb verb = new();
                verb.Act      = () => EjectBody(uid, component);
                verb.Category = VerbCategory.Eject;
                verb.Text     = Loc.GetString("medical-scanner-verb-noun-occupant");
                args.Verbs.Add(verb);
            }

            // Self-insert verb
            if (!IsOccupied(component) &&
                component.CanInsert(args.User) &&
                _blocker.CanMove(args.User))
            {
                AlternativeVerb verb = new();
                verb.Act  = () => InsertBody(component.Owner, args.User, component);
                verb.Text = Loc.GetString("medical-scanner-verb-enter");
                args.Verbs.Add(verb);
            }
        }
Beispiel #3
0
        public override void UpdateAfterProcessing()
        {
            if (ControlledComponent == null)
            {
                return;
            }

            if (ControlledComponent.Owner.IsWeightless())
            {
                if (ActionBlockerSystem.CanMove(ControlledComponent.Owner) &&
                    ControlledComponent.IsColliding(Vector2.Zero, false))
                {
                    Stop();
                }

                return;
            }

            LinearVelocity *= Decay;

            if (LinearVelocity.Length < 0.001)
            {
                Stop();
            }
        }
        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);
            }
        }
Beispiel #5
0
 public static bool UseMobMovement(SharedBroadPhaseSystem broadPhaseSystem, PhysicsComponent body, IPhysicsManager?physicsManager = null)
 {
     return((body.BodyStatus == BodyStatus.OnGround) &
            body.Owner.HasComponent <IMobStateComponent>() &&
            ActionBlockerSystem.CanMove(body.Owner) &&
            (!body.Owner.IsWeightless(physicsManager) ||
             body.Owner.TryGetComponent(out SharedPlayerMobMoverComponent? mover) &&
             IsAroundCollider(broadPhaseSystem, body.Owner.Transform, mover, body)));
 }
Beispiel #6
0
        public override Outcome Execute(float frameTime)
        {
            if (RouteJob != null && RouteJob.Status == JobStatus.Finished)
            {
                ReceivedRoute();
            }

            return(!ActionBlockerSystem.CanMove(Owner) ? Outcome.Failed : Outcome.Continuing);
        }
        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);
            }
        }
Beispiel #8
0
        private void OnRelayMoveInput(EntityUid uid, SharedPullableComponent component, RelayMoveInputEvent args)
        {
            var entity = args.Session.AttachedEntity;

            if (entity == null || !_blocker.CanMove(entity.Value))
            {
                return;
            }
            _pullSystem.TryStopPull(component);
        }
Beispiel #9
0
        public override float GetScore(Blackboard context)
        {
            var self = context.GetState <SelfState>().GetValue();

            if (!ActionBlockerSystem.CanMove(self))
            {
                return(0.0f);
            }

            return(1.0f);
        }
Beispiel #10
0
        private void OnRelayMoveInput(EntityUid uid, SharedPullableComponent component, ref MoveInputEvent args)
        {
            var entity = args.Entity;

            if (_mobState.IsIncapacitated(entity) || !_blocker.CanMove(entity))
            {
                return;
            }

            _pullSystem.TryStopPull(component);
        }
        private void IdleState()
        {
            if (!ActionBlockerSystem.CanMove(SelfEntity))
            {
                DisabledPositiveEdge();
                return;
            }

            if (_timeMan.CurTime < _startStateTime + IdleTimeSpan)
            {
                return;
            }

            var entWorldPos = SelfEntity.Transform.WorldPosition;

            if (SelfEntity.TryGetComponent <CollidableComponent>(out var bounds))
            {
                entWorldPos = ((IPhysBody)bounds).WorldAABB.Center;
            }

            var rngState = GenSeed();

            for (var i = 0; i < 3; i++) // you get 3 chances to find a place to walk
            {
                var dir        = new Vector2(Random01(ref rngState) * 2 - 1, Random01(ref rngState) * 2 - 1).Normalized;
                var ray        = new CollisionRay(entWorldPos, dir, (int)CollisionGroup.Impassable);
                var rayResults = _physMan.IntersectRay(SelfEntity.Transform.MapID, ray, MaxWalkDistance, SelfEntity).ToList();

                if (rayResults.Count == 1)
                {
                    var rayResult = rayResults[0];
                    if (rayResult.Distance > 1) // hit an impassable object
                    {
                        // set the new position back from the wall a bit
                        _walkTargetPos = entWorldPos + dir * (rayResult.Distance - 0.5f);
                        WalkingPositiveEdge();
                        return;
                    }
                }
                else // hit nothing (path clear)
                {
                    _walkTargetPos = dir * MaxWalkDistance;
                    WalkingPositiveEdge();
                    return;
                }
            }

            // can't find clear spot, do nothing, sleep longer
            _startStateTime = _timeMan.CurTime;
        }
Beispiel #12
0
        private void OnRelayMoveInput(EntityUid uid, SharedPullableComponent component, RelayMoveInputEvent args)
        {
            var entity = args.Session.AttachedEntity;

            if (entity == null || !_blocker.CanMove(entity.Value))
            {
                return;
            }
            if (TryComp <MobStateComponent>(component.Owner, out var mobState) && mobState.IsIncapacitated())
            {
                return;
            }
            _pullSystem.TryStopPull(component);
        }
Beispiel #13
0
        bool IDragDropOn.CanDragDropOn(DragDropEventArgs eventArgs)
        {
            if (!eventArgs.Dragged.TryGetComponent <IMobStateComponent>(out var state))
            {
                return(false);
            }

            // TODO: Wouldn't we just need the CanMove check?
            if (state.IsDead() || state.IsCritical() || state.IsIncapacitated() || !ActionBlockerSystem.CanMove(eventArgs.Dragged))
            {
                return(true);
            }

            return(false);
        }
        private void DisabledState()
        {
            if (_timeMan.CurTime < _startStateTime + DisabledTimeout)
            {
                return;
            }

            if (ActionBlockerSystem.CanMove(SelfEntity))
            {
                var rngState = GenSeed();
                IdlePositiveEdge(ref rngState);
            }
            else
            {
                DisabledPositiveEdge();
            }
        }
Beispiel #15
0
        public async Task BuckleUnbuckleCooldownRangeTest()
        {
            var server = StartServerDummyTicker();

            IEntity         human  = null;
            IEntity         chair  = null;
            BuckleComponent buckle = null;
            StrapComponent  strap  = null;

            await server.WaitAssertion(() =>
            {
                var mapManager = IoCManager.Resolve <IMapManager>();

                mapManager.CreateNewMapEntity(MapId.Nullspace);

                var entityManager = IoCManager.Resolve <IEntityManager>();

                human = entityManager.SpawnEntity("HumanMob_Content", MapCoordinates.Nullspace);
                chair = entityManager.SpawnEntity("ChairWood", MapCoordinates.Nullspace);

                // Default state, unbuckled
                Assert.True(human.TryGetComponent(out buckle));
                Assert.NotNull(buckle);
                Assert.Null(buckle.BuckledTo);
                Assert.False(buckle.Buckled);
                Assert.True(ActionBlockerSystem.CanMove(human));
                Assert.True(ActionBlockerSystem.CanChangeDirection(human));
                Assert.True(EffectBlockerSystem.CanFall(human));

                // Default state, no buckled entities, strap
                Assert.True(chair.TryGetComponent(out strap));
                Assert.NotNull(strap);
                Assert.IsEmpty(strap.BuckledEntities);
                Assert.Zero(strap.OccupiedSize);

                // Side effects of buckling
                Assert.True(buckle.TryBuckle(human, chair));
                Assert.NotNull(buckle.BuckledTo);
                Assert.True(buckle.Buckled);
                Assert.True(((BuckleComponentState)buckle.GetComponentState()).Buckled);
                Assert.False(ActionBlockerSystem.CanMove(human));
                Assert.False(ActionBlockerSystem.CanChangeDirection(human));
                Assert.False(EffectBlockerSystem.CanFall(human));
                Assert.That(human.Transform.WorldPosition, Is.EqualTo(chair.Transform.WorldPosition));

                // Side effects of buckling for the strap
                Assert.That(strap.BuckledEntities, Does.Contain(human));
                Assert.That(strap.OccupiedSize, Is.EqualTo(buckle.Size));
                Assert.Positive(strap.OccupiedSize);

                // Trying to buckle while already buckled fails
                Assert.False(buckle.TryBuckle(human, chair));

                // Trying to unbuckle too quickly fails
                Assert.False(buckle.TryUnbuckle(human));
                Assert.False(buckle.ToggleBuckle(human, chair));
                Assert.True(buckle.Buckled);
            });

            // Wait enough ticks for the unbuckling cooldown to run out
            await server.WaitRunTicks(60);

            await server.WaitAssertion(() =>
            {
                // Still buckled
                Assert.True(buckle.Buckled);

                // Unbuckle
                Assert.True(buckle.TryUnbuckle(human));
                Assert.Null(buckle.BuckledTo);
                Assert.False(buckle.Buckled);
                Assert.True(ActionBlockerSystem.CanMove(human));
                Assert.True(ActionBlockerSystem.CanChangeDirection(human));
                Assert.True(EffectBlockerSystem.CanFall(human));

                // Unbuckle, strap
                Assert.IsEmpty(strap.BuckledEntities);
                Assert.Zero(strap.OccupiedSize);

                // Re-buckling has no cooldown
                Assert.True(buckle.TryBuckle(human, chair));
                Assert.True(buckle.Buckled);

                // On cooldown
                Assert.False(buckle.TryUnbuckle(human));
                Assert.True(buckle.Buckled);
                Assert.False(buckle.ToggleBuckle(human, chair));
                Assert.True(buckle.Buckled);
                Assert.False(buckle.ToggleBuckle(human, chair));
                Assert.True(buckle.Buckled);
            });

            // Wait enough ticks for the unbuckling cooldown to run out
            await server.WaitRunTicks(60);

            await server.WaitAssertion(() =>
            {
                // Still buckled
                Assert.True(buckle.Buckled);

                // Unbuckle
                Assert.True(buckle.TryUnbuckle(human));
                Assert.False(buckle.Buckled);

                // Move away from the chair
                human.Transform.WorldPosition += (1000, 1000);

                // Out of range
                Assert.False(buckle.TryBuckle(human, chair));
                Assert.False(buckle.TryUnbuckle(human));
                Assert.False(buckle.ToggleBuckle(human, chair));

                // Move near the chair
                human.Transform.WorldPosition = chair.Transform.WorldPosition + (0.5f, 0);

                // In range
                Assert.True(buckle.TryBuckle(human, chair));
                Assert.True(buckle.Buckled);
                Assert.False(buckle.TryUnbuckle(human));
                Assert.True(buckle.Buckled);
                Assert.False(buckle.ToggleBuckle(human, chair));
                Assert.True(buckle.Buckled);

                // Force unbuckle
                Assert.True(buckle.TryUnbuckle(human, true));
                Assert.False(buckle.Buckled);
                Assert.True(ActionBlockerSystem.CanMove(human));
                Assert.True(ActionBlockerSystem.CanChangeDirection(human));
                Assert.True(EffectBlockerSystem.CanFall(human));

                // Re-buckle
                Assert.True(buckle.TryBuckle(human, chair));

                // Move away from the chair
                human.Transform.WorldPosition += (1, 0);
            });

            await server.WaitRunTicks(1);

            await server.WaitAssertion(() =>
            {
                // No longer buckled
                Assert.False(buckle.Buckled);
                Assert.Null(buckle.BuckledTo);
                Assert.IsEmpty(strap.BuckledEntities);
            });
        }
        public async Task BuckleUnbuckleCooldownRangeTest()
        {
            var cOptions = new ClientIntegrationOptions {
                ExtraPrototypes = Prototypes
            };
            var sOptions = new ServerIntegrationOptions {
                ExtraPrototypes = Prototypes
            };

            var(client, server) = await StartConnectedServerClientPair(cOptions, sOptions);

            IEntity         human  = null;
            IEntity         chair  = null;
            BuckleComponent buckle = null;
            StrapComponent  strap  = null;

            await server.WaitAssertion(() =>
            {
                var mapManager    = IoCManager.Resolve <IMapManager>();
                var entityManager = IoCManager.Resolve <IEntityManager>();

                var gridId      = new GridId(1);
                var grid        = mapManager.GetGrid(gridId);
                var coordinates = grid.GridEntityId.ToCoordinates();

                human = entityManager.SpawnEntity(BuckleDummyId, coordinates);
                chair = entityManager.SpawnEntity(StrapDummyId, coordinates);

                // Default state, unbuckled
                Assert.True(human.TryGetComponent(out buckle));
                Assert.NotNull(buckle);
                Assert.Null(buckle.BuckledTo);
                Assert.False(buckle.Buckled);
                Assert.True(ActionBlockerSystem.CanMove(human));
                Assert.True(ActionBlockerSystem.CanChangeDirection(human));
                Assert.True(EffectBlockerSystem.CanFall(human));

                // Default state, no buckled entities, strap
                Assert.True(chair.TryGetComponent(out strap));
                Assert.NotNull(strap);
                Assert.IsEmpty(strap.BuckledEntities);
                Assert.Zero(strap.OccupiedSize);

                // Side effects of buckling
                Assert.True(buckle.TryBuckle(human, chair));
                Assert.NotNull(buckle.BuckledTo);
                Assert.True(buckle.Buckled);

                var player = IoCManager.Resolve <IPlayerManager>().GetAllPlayers().Single();
                Assert.True(((BuckleComponentState)buckle.GetComponentState(player)).Buckled);
                Assert.False(ActionBlockerSystem.CanMove(human));
                Assert.False(ActionBlockerSystem.CanChangeDirection(human));
                Assert.False(EffectBlockerSystem.CanFall(human));
                Assert.That(human.Transform.WorldPosition, Is.EqualTo(chair.Transform.WorldPosition));

                // Side effects of buckling for the strap
                Assert.That(strap.BuckledEntities, Does.Contain(human));
                Assert.That(strap.OccupiedSize, Is.EqualTo(buckle.Size));
                Assert.Positive(strap.OccupiedSize);

                // Trying to buckle while already buckled fails
                Assert.False(buckle.TryBuckle(human, chair));

                // Trying to unbuckle too quickly fails
                Assert.False(buckle.TryUnbuckle(human));
                Assert.False(buckle.ToggleBuckle(human, chair));
                Assert.True(buckle.Buckled);
            });

            // Wait enough ticks for the unbuckling cooldown to run out
            await server.WaitRunTicks(60);

            await server.WaitAssertion(() =>
            {
                // Still buckled
                Assert.True(buckle.Buckled);

                // Unbuckle
                Assert.True(buckle.TryUnbuckle(human));
                Assert.Null(buckle.BuckledTo);
                Assert.False(buckle.Buckled);
                Assert.True(ActionBlockerSystem.CanMove(human));
                Assert.True(ActionBlockerSystem.CanChangeDirection(human));
                Assert.True(EffectBlockerSystem.CanFall(human));

                // Unbuckle, strap
                Assert.IsEmpty(strap.BuckledEntities);
                Assert.Zero(strap.OccupiedSize);

                // Re-buckling has no cooldown
                Assert.True(buckle.TryBuckle(human, chair));
                Assert.True(buckle.Buckled);

                // On cooldown
                Assert.False(buckle.TryUnbuckle(human));
                Assert.True(buckle.Buckled);
                Assert.False(buckle.ToggleBuckle(human, chair));
                Assert.True(buckle.Buckled);
                Assert.False(buckle.ToggleBuckle(human, chair));
                Assert.True(buckle.Buckled);
            });

            // Wait enough ticks for the unbuckling cooldown to run out
            await server.WaitRunTicks(60);

            await server.WaitAssertion(() =>
            {
                // Still buckled
                Assert.True(buckle.Buckled);

                // Unbuckle
                Assert.True(buckle.TryUnbuckle(human));
                Assert.False(buckle.Buckled);

                // Move away from the chair
                human.Transform.WorldPosition += (1000, 1000);

                // Out of range
                Assert.False(buckle.TryBuckle(human, chair));
                Assert.False(buckle.TryUnbuckle(human));
                Assert.False(buckle.ToggleBuckle(human, chair));

                // Move near the chair
                human.Transform.WorldPosition = chair.Transform.WorldPosition + (0.5f, 0);

                // In range
                Assert.True(buckle.TryBuckle(human, chair));
                Assert.True(buckle.Buckled);
                Assert.False(buckle.TryUnbuckle(human));
                Assert.True(buckle.Buckled);
                Assert.False(buckle.ToggleBuckle(human, chair));
                Assert.True(buckle.Buckled);

                // Force unbuckle
                Assert.True(buckle.TryUnbuckle(human, true));
                Assert.False(buckle.Buckled);
                Assert.True(ActionBlockerSystem.CanMove(human));
                Assert.True(ActionBlockerSystem.CanChangeDirection(human));
                Assert.True(EffectBlockerSystem.CanFall(human));

                // Re-buckle
                Assert.True(buckle.TryBuckle(human, chair));

                // Move away from the chair
                human.Transform.WorldPosition += (1, 0);
            });

            await server.WaitRunTicks(1);

            await server.WaitAssertion(() =>
            {
                // No longer buckled
                Assert.False(buckle.Buckled);
                Assert.Null(buckle.BuckledTo);
                Assert.IsEmpty(strap.BuckledEntities);
            });
        }