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); } }
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); } }
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))); }
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); } }
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); }
public override float GetScore(Blackboard context) { var self = context.GetState <SelfState>().GetValue(); if (!ActionBlockerSystem.CanMove(self)) { return(0.0f); } return(1.0f); }
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; }
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); }
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(); } }
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); }); }