private void AddLabelTo(EntityUid uid, HandLabelerComponent?handLabeler, EntityUid target, out string?result)
        {
            if (!Resolve(uid, ref handLabeler))
            {
                result = null;
                return;
            }

            LabelComponent label = target.EnsureComponent <LabelComponent>();

            if (label.OriginalName != null)
            {
                EntityManager.GetComponent <MetaDataComponent>(target).EntityName = label.OriginalName;
            }
            label.OriginalName = null;

            if (handLabeler.AssignedLabel == string.Empty)
            {
                label.CurrentLabel = null;
                result             = Loc.GetString("hand-labeler-successfully-removed");
                return;
            }

            label.OriginalName = EntityManager.GetComponent <MetaDataComponent>(target).EntityName;
            string val = EntityManager.GetComponent <MetaDataComponent>(target).EntityName + $" ({handLabeler.AssignedLabel})";

            EntityManager.GetComponent <MetaDataComponent>(target).EntityName = val;
            label.CurrentLabel = handLabeler.AssignedLabel;
            result             = Loc.GetString("hand-labeler-successfully-applied");
        }
        public static T EnsureContainer <T>(this EntityUid entity, string containerId, out bool alreadyExisted)
            where T : IContainer
        {
            var containerManager = entity.EnsureComponent <ContainerManagerComponent>();

            if (!containerManager.TryGetContainer(containerId, out var existing))
            {
                alreadyExisted = false;
                return(containerManager.MakeContainer <T>(containerId));
            }

            if (!(existing is T container))
            {
                throw new InvalidOperationException(
                          $"The container exists but is of a different type: {existing.GetType()}");
            }

            alreadyExisted = true;
            return(container);
        }
Example #3
0
        protected override void OpenStorage()
        {
            Appearance?.SetData(MorgueVisuals.Open, true);
            Appearance?.SetData(MorgueVisuals.HasContents, false);
            Appearance?.SetData(MorgueVisuals.HasMob, false);
            Appearance?.SetData(MorgueVisuals.HasSoul, false);

            if (_tray == null)
            {
                _tray = _entMan.SpawnEntity(_trayPrototypeId, _entMan.GetComponent <TransformComponent>(Owner).Coordinates);
                var trayComp = _tray.EnsureComponent <MorgueTrayComponent>();
                trayComp.Morgue = Owner;
            }
            else
            {
                TrayContainer?.Remove(_tray);
            }

            _entMan.GetComponent <TransformComponent>(_tray).Coordinates = new EntityCoordinates(Owner, 0, -1);

            base.OpenStorage();
        }
        public async Task InteractionTest()
        {
            var server = StartServer(new ServerContentIntegrationOption
            {
                ContentBeforeIoC = () =>
                {
                    IoCManager.Resolve <IEntitySystemManager>().LoadExtraSystemType <TestInteractionSystem>();
                }
            });

            await server.WaitIdleAsync();

            var sEntities  = server.ResolveDependency <IEntityManager>();
            var mapManager = server.ResolveDependency <IMapManager>();

            var mapId  = MapId.Nullspace;
            var coords = MapCoordinates.Nullspace;

            server.Assert(() =>
            {
                mapId  = mapManager.CreateMap();
                coords = new MapCoordinates(Vector2.Zero, mapId);
            });

            await server.WaitIdleAsync();

            EntityUid user   = default;
            EntityUid target = default;
            EntityUid item   = default;

            server.Assert(() =>
            {
                user = sEntities.SpawnEntity(null, coords);
                user.EnsureComponent <HandsComponent>().AddHand("hand", HandLocation.Left);
                target = sEntities.SpawnEntity(null, coords);
                item   = sEntities.SpawnEntity(null, coords);
                item.EnsureComponent <ItemComponent>();
            });

            await server.WaitRunTicks(1);

            var entitySystemManager = server.ResolveDependency <IEntitySystemManager>();

            Assert.That(entitySystemManager.TryGetEntitySystem <InteractionSystem>(out var interactionSystem));
            Assert.That(entitySystemManager.TryGetEntitySystem <TestInteractionSystem>(out var testInteractionSystem));

            var attack        = false;
            var interactUsing = false;
            var interactHand  = false;

            server.Assert(() =>
            {
                testInteractionSystem.AttackEvent        = (_, _, ev) => { Assert.That(ev.Target, Is.EqualTo(target)); attack = true; };
                testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactUsing = true; };
                testInteractionSystem.InteractHandEvent  = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };

                interactionSystem.DoAttack(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, false, target);
                interactionSystem.UserInteraction(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, target);
                Assert.That(attack);
                Assert.That(interactUsing, Is.False);
                Assert.That(interactHand);

                Assert.That(sEntities.TryGetComponent <HandsComponent>(user, out var hands));
                Assert.That(hands.PutInHand(sEntities.GetComponent <SharedItemComponent>(item)));

                interactionSystem.UserInteraction(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, target);
                Assert.That(interactUsing);
            });

            await server.WaitIdleAsync();
        }
        /// <summary>
        ///     Tries to throw the entity if it has a physics component, otherwise does nothing.
        /// </summary>
        /// <param name="entity">The entity being thrown.</param>
        /// <param name="direction">A vector pointing from the entity to its destination.</param>
        /// <param name="strength">How much the direction vector should be multiplied for velocity.</param>
        /// <param name="user"></param>
        /// <param name="pushbackRatio">The ratio of impulse applied to the thrower - defaults to 10 because otherwise it's not enough to properly recover from getting spaced</param>
        internal static void TryThrow(this EntityUid entity, Vector2 direction, float strength = 1.0f, EntityUid?user = null, float pushbackRatio = 10.0f)
        {
            var entities = IoCManager.Resolve <IEntityManager>();

            if (entities.GetComponent <MetaDataComponent>(entity).EntityDeleted ||
                strength <= 0f ||
                !entities.TryGetComponent(entity, out PhysicsComponent? physicsComponent))
            {
                return;
            }

            if (physicsComponent.BodyType == BodyType.Static)
            {
                Logger.Warning("Tried to throw entity {entity} but can't throw static bodies!");
                return;
            }

            if (entities.HasComponent <MobStateComponent>(entity))
            {
                Logger.Warning("Throwing not supported for mobs!");
                return;
            }

            var comp = entity.EnsureComponent <ThrownItemComponent>();

            if (entities.HasComponent <SharedItemComponent>(entity))
            {
                comp.Thrower = user;
                // Give it a l'il spin.
                if (!entity.HasTag("NoSpinOnThrow"))
                {
                    physicsComponent.ApplyAngularImpulse(ThrowAngularImpulse);
                }
                else if (direction != Vector2.Zero)
                {
                    entities.GetComponent <TransformComponent>(entity).LocalRotation = direction.ToWorldAngle() - Math.PI;
                }

                if (user != null)
                {
                    EntitySystem.Get <InteractionSystem>().ThrownInteraction(user.Value, entity);
                }
            }

            var impulseVector = direction.Normalized * strength * physicsComponent.Mass;

            physicsComponent.ApplyLinearImpulse(impulseVector);

            // Estimate time to arrival so we can apply OnGround status and slow it much faster.
            var time = (direction / strength).Length;

            if (time < FlyTime)
            {
                physicsComponent.BodyStatus = BodyStatus.OnGround;
                EntitySystem.Get <ThrownItemSystem>().LandComponent(comp);
            }
            else
            {
                physicsComponent.BodyStatus = BodyStatus.InAir;

                Timer.Spawn(TimeSpan.FromSeconds(time - FlyTime), () =>
                {
                    if (physicsComponent.Deleted)
                    {
                        return;
                    }
                    physicsComponent.BodyStatus = BodyStatus.OnGround;
                    EntitySystem.Get <ThrownItemSystem>().LandComponent(comp);
                });
            }

            // Give thrower an impulse in the other direction
            if (user != null && pushbackRatio > 0.0f && entities.TryGetComponent(user.Value, out IPhysBody? body))
            {
                var msg = new ThrowPushbackAttemptEvent();
                entities.EventBus.RaiseLocalEvent(body.Owner, msg);

                if (!msg.Cancelled)
                {
                    body.ApplyLinearImpulse(-impulseVector * pushbackRatio);
                }
            }
        }
        public async Task InteractionTest()
        {
            await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = Prototypes });

            var server = pairTracker.Pair.Server;

            var sEntities  = server.ResolveDependency <IEntityManager>();
            var mapManager = server.ResolveDependency <IMapManager>();
            var sysMan     = server.ResolveDependency <IEntitySystemManager>();
            var handSys    = sysMan.GetEntitySystem <SharedHandsSystem>();

            var mapId  = MapId.Nullspace;
            var coords = MapCoordinates.Nullspace;
            await server.WaitAssertion(() =>
            {
                mapId  = mapManager.CreateMap();
                coords = new MapCoordinates(Vector2.Zero, mapId);
            });

            await server.WaitIdleAsync();

            EntityUid user   = default;
            EntityUid target = default;
            EntityUid item   = default;

            await server.WaitAssertion(() =>
            {
                user = sEntities.SpawnEntity(null, coords);
                user.EnsureComponent <HandsComponent>();
                handSys.AddHand(user, "hand", HandLocation.Left);
                target = sEntities.SpawnEntity(null, coords);
                item   = sEntities.SpawnEntity(null, coords);
                item.EnsureComponent <ItemComponent>();
            });

            await server.WaitRunTicks(1);

            var entitySystemManager = server.ResolveDependency <IEntitySystemManager>();

            Assert.That(entitySystemManager.TryGetEntitySystem <InteractionSystem>(out var interactionSystem));
            Assert.That(entitySystemManager.TryGetEntitySystem <TestInteractionSystem>(out var testInteractionSystem));

            var attack        = false;
            var interactUsing = false;
            var interactHand  = false;
            await server.WaitAssertion(() =>
            {
                testInteractionSystem.AttackEvent        = (_, _, ev) => { Assert.That(ev.Target, Is.EqualTo(target)); attack = true; };
                testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactUsing = true; };
                testInteractionSystem.InteractHandEvent  = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };

                interactionSystem.DoAttack(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, false, target);
                interactionSystem.UserInteraction(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, target);
                Assert.That(attack);
                Assert.That(interactUsing, Is.False);
                Assert.That(interactHand);

                Assert.That(handSys.TryPickup(user, item));

                interactionSystem.UserInteraction(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, target);
                Assert.That(interactUsing);
            });

            await pairTracker.CleanReturnAsync();
        }
        public async Task InsideContainerInteractionBlockTest()
        {
            var server = StartServer(new ServerContentIntegrationOption
            {
                ContentBeforeIoC = () =>
                {
                    IoCManager.Resolve <IEntitySystemManager>().LoadExtraSystemType <TestInteractionSystem>();
                },
                FailureLogLevel = Robust.Shared.Log.LogLevel.Error
            });

            await server.WaitIdleAsync();

            var sEntities  = server.ResolveDependency <IEntityManager>();
            var mapManager = server.ResolveDependency <IMapManager>();
            var sysMan     = server.ResolveDependency <IEntitySystemManager>();
            var handSys    = sysMan.GetEntitySystem <SharedHandsSystem>();

            var mapId  = MapId.Nullspace;
            var coords = MapCoordinates.Nullspace;

            server.Assert(() =>
            {
                mapId  = mapManager.CreateMap();
                coords = new MapCoordinates(Vector2.Zero, mapId);
            });

            await server.WaitIdleAsync();

            EntityUid  user            = default;
            EntityUid  target          = default;
            EntityUid  item            = default;
            EntityUid  containerEntity = default;
            IContainer container       = null;

            server.Assert(() =>
            {
                user = sEntities.SpawnEntity(null, coords);
                user.EnsureComponent <HandsComponent>();
                handSys.AddHand(user, "hand", HandLocation.Left);
                target = sEntities.SpawnEntity(null, coords);
                item   = sEntities.SpawnEntity(null, coords);
                item.EnsureComponent <ItemComponent>();
                containerEntity = sEntities.SpawnEntity(null, coords);
                container       = containerEntity.EnsureContainer <Container>("InteractionTestContainer");
            });

            await server.WaitRunTicks(1);

            var entitySystemManager = server.ResolveDependency <IEntitySystemManager>();

            Assert.That(entitySystemManager.TryGetEntitySystem <InteractionSystem>(out var interactionSystem));
            Assert.That(entitySystemManager.TryGetEntitySystem <TestInteractionSystem>(out var testInteractionSystem));

            await server.WaitIdleAsync();

            var attack        = false;
            var interactUsing = false;
            var interactHand  = false;

            server.Assert(() =>
            {
                Assert.That(container.Insert(user));
                Assert.That(sEntities.GetComponent <TransformComponent>(user).Parent.Owner, Is.EqualTo(containerEntity));

                testInteractionSystem.AttackEvent        = (_, _, ev) => { Assert.That(ev.Target, Is.EqualTo(containerEntity)); attack = true; };
                testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(containerEntity)); interactUsing = true; };
                testInteractionSystem.InteractHandEvent  = (ev) => { Assert.That(ev.Target, Is.EqualTo(containerEntity)); interactHand = true; };

                interactionSystem.DoAttack(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, false, target);
                interactionSystem.UserInteraction(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, target);
                Assert.That(attack, Is.False);
                Assert.That(interactUsing, Is.False);
                Assert.That(interactHand, Is.False);

                interactionSystem.DoAttack(user, sEntities.GetComponent <TransformComponent>(containerEntity).Coordinates, false, containerEntity);
                interactionSystem.UserInteraction(user, sEntities.GetComponent <TransformComponent>(containerEntity).Coordinates, containerEntity);
                Assert.That(attack);
                Assert.That(interactUsing, Is.False);
                Assert.That(interactHand);

                Assert.That(handSys.TryPickup(user, item));

                interactionSystem.UserInteraction(user, sEntities.GetComponent <TransformComponent>(target).Coordinates, target);
                Assert.That(interactUsing, Is.False);

                interactionSystem.UserInteraction(user, sEntities.GetComponent <TransformComponent>(containerEntity).Coordinates, containerEntity);
                Assert.That(interactUsing, Is.True);
            });

            await server.WaitIdleAsync();
        }