/// <summary>
        ///     Checks that the user and target of a
        ///     <see cref="AfterInteractEventArgs"/> are within a  certain distance
        ///     without any entity that matches the collision mask obstructing them.
        ///     If the <paramref name="range"/> is zero or negative,
        ///     this method will only check if nothing obstructs the entity and component.
        /// </summary>
        /// <param name="args">The event args to use.</param>
        /// <param name="range">
        ///     Maximum distance between the two entity and set of map coordinates.
        /// </param>
        /// <param name="collisionMask">The mask to check for collisions.</param>
        /// <param name="predicate">
        ///     A predicate to check whether to ignore an entity or not.
        ///     If it returns true, it will be ignored.
        /// </param>
        /// <param name="ignoreInsideBlocker">
        ///     If true and both the user and target are inside
        ///     the obstruction, ignores the obstruction and considers the interaction
        ///     unobstructed.
        ///     Therefore, setting this to true makes this check more permissive,
        ///     such as allowing an interaction to occur inside something impassable
        ///     (like a wall). The default, false, makes the check more restrictive.
        /// </param>
        /// <param name="popup">
        ///     Whether or not to popup a feedback message on the user entity for
        ///     it to see.
        /// </param>
        /// <returns>
        ///     True if the two points are within a given range without being obstructed.
        /// </returns>
        public bool InRangeUnobstructed(
            AfterInteractEventArgs args,
            float range = InteractionRange,
            CollisionGroup collisionMask = CollisionGroup.Impassable,
            Ignored?predicate            = null,
            bool ignoreInsideBlocker     = false,
            bool popup = false)
        {
            var user   = args.User;
            var target = args.Target;

            predicate ??= e => e == user;

            MapCoordinates otherPosition;

            if (target == null)
            {
                otherPosition = args.ClickLocation.ToMap(EntityManager);
            }
            else
            {
                otherPosition = target.Transform.MapPosition;
                predicate    += e => e == target;
            }

            return(InRangeUnobstructed(user, otherPosition, range, collisionMask, predicate, ignoreInsideBlocker, popup));
        }
        public void AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null)
            {
                return;
            }

            if (!eventArgs.Target.TryGetComponent(out ISharedBodyManagerComponent body))
            {
                return;
            }

            if (!ActionBlockerSystem.CanInteract(eventArgs.User))
            {
                return;
            }

            if (eventArgs.User != eventArgs.Target &&
                !eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true))
            {
                return;
            }

            if (Owner.TryGetComponent(out StackComponent stack) &&
                !stack.Use(1))
            {
                return;
            }

            foreach (var(type, amount) in Heal)
            {
                body.ChangeDamage(type, -amount, true);
            }
        }
Exemple #3
0
        private void SendBodyPartListToUser(AfterInteractEventArgs eventArgs, IBody body)
        {
            // Create dictionary to send to client (text to be shown : data sent back if selected)
            var toSend = new Dictionary <string, int>();

            foreach (var(key, value) in body.Parts)
            {
                // For each limb in the target, add it to our cache if it is a valid option.
                if (value.CanAddMechanism(this))
                {
                    OptionsCache.Add(IdHash, value);
                    toSend.Add(key + ": " + value.Name, IdHash++);
                }
            }

            if (OptionsCache.Count > 0 &&
                eventArgs.User.TryGetComponent(out IActorComponent? actor))
            {
                OpenSurgeryUI(actor.playerSession);
                UpdateSurgeryUIBodyPartRequest(actor.playerSession, toSend);
                PerformerCache = eventArgs.User;
                BodyCache      = body;
            }
            else // If surgery cannot be performed, show message saying so.
            {
                eventArgs.Target.PopupMessage(eventArgs.User,
                                              Loc.GetString("You see no way to install the {0}.", Owner.Name));
            }
        }
        void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!InteractionChecks.InRangeUnobstructed(eventArgs))
            {
                return;
            }

            if (eventArgs.Target == null)
            {
                return;
            }

            if (!eventArgs.Target.TryGetComponent(out DamageableComponent damagecomponent))
            {
                return;
            }
            if (Owner.TryGetComponent(out StackComponent stackComponent))
            {
                if (!stackComponent.Use(1))
                {
                    Owner.Delete();
                    return;
                }

                damagecomponent.TakeHealing(Damage, Heal);
                return;
            }
            damagecomponent.TakeHealing(Damage, Heal);
            Owner.Delete();
        }
        public static bool InRangeUnOccluded(AfterInteractEventArgs args, float range, Ignored?predicate, bool ignoreInsideBlocker = true)
        {
            var originPos = args.User.Transform.MapPosition;
            var otherPos  = args.Target.Transform.MapPosition;

            return(InRangeUnOccluded(originPos, otherPos, range, predicate, ignoreInsideBlocker));
        }
Exemple #6
0
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: false, popup: true,
                                               collisionMask: Shared.Physics.CollisionGroup.MobImpassable))
            {
                return(true);
            }

            if (Charges <= 0)
            {
                eventArgs.User.PopupMessage(Loc.GetString("crayon-interact-not-enough-left-text"));
                return(true);
            }

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

            var entity = entityManager.SpawnEntity("CrayonDecal", eventArgs.ClickLocation);

            if (entity.TryGetComponent(out AppearanceComponent? appearance))
            {
                appearance.SetData(CrayonVisuals.State, SelectedState);
                appearance.SetData(CrayonVisuals.Color, _color);
                appearance.SetData(CrayonVisuals.Rotation, eventArgs.User.Transform.LocalRotation);
            }

            if (!string.IsNullOrEmpty(_useSound))
            {
                SoundSystem.Play(Filter.Pvs(Owner), _useSound, Owner, AudioHelpers.WithVariation(0.125f));
            }

            // Decrease "Ammo"
            Charges--;
            Dirty();
            return(true);
        }
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true))
            {
                return(true);
            }

            if (!Owner.TryGetComponent(out StackComponent? stack))
            {
                return(true);
            }

            var mapManager = IoCManager.Resolve <IMapManager>();

            var location    = eventArgs.ClickLocation.AlignWithClosestGridTile();
            var locationMap = location.ToMap(Owner.EntityManager);

            if (locationMap.MapId == MapId.Nullspace)
            {
                return(true);
            }
            mapManager.TryGetGrid(location.GetGridId(Owner.EntityManager), out var mapGrid);

            if (_outputTiles == null)
            {
                return(true);
            }

            foreach (var currentTile in _outputTiles)
            {
                var currentTileDefinition = (ContentTileDefinition)_tileDefinitionManager[currentTile];

                if (mapGrid != null)
                {
                    var tile     = mapGrid.GetTileRef(location);
                    var baseTurf = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];

                    if (HasBaseTurf(currentTileDefinition, baseTurf.Name))
                    {
                        if (!EntitySystem.Get <StackSystem>().Use(Owner.Uid, stack, 1))
                        {
                            continue;
                        }

                        PlaceAt(mapGrid, location, currentTileDefinition.TileId);
                        break;
                    }
                }
                else if (HasBaseTurf(currentTileDefinition, "space"))
                {
                    mapGrid = mapManager.CreateGrid(locationMap.MapId);
                    mapGrid.WorldPosition = locationMap.Position;
                    location = new EntityCoordinates(mapGrid.GridEntityId, Vector2.Zero);
                    PlaceAt(mapGrid, location, _tileDefinitionManager[_outputTiles[0]].TileId, mapGrid.TileSize / 2f);
                    break;
                }
            }

            return(true);
        }
Exemple #8
0
        /// <inheritdoc />
        public void AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!InteractionChecks.InRangeUnobstructed(eventArgs))
            {
                return;
            }
            if (!_mapManager.TryGetGrid(eventArgs.ClickLocation.GridID, out var grid))
            {
                return;
            }
            var snapPos  = grid.SnapGridCellFor(eventArgs.ClickLocation, SnapGridOffset.Center);
            var snapCell = grid.GetSnapGridCell(snapPos, SnapGridOffset.Center);

            if (grid.GetTileRef(snapPos).Tile.IsEmpty)
            {
                return;
            }
            foreach (var snapComp in snapCell)
            {
                if (snapComp.Owner.TryGetComponent <WireComponent>(out var wire) && wire.WireType == _blockingWireType)
                {
                    return;
                }
            }
            if (Owner.TryGetComponent(out StackComponent stack) && !stack.Use(1))
            {
                return;
            }
            _entityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos));
        }
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null)
            {
                return(false);
            }

            CloseAllSurgeryUIs();
            OptionsCache.Clear();
            PerformerCache = null;
            BodyCache      = null;

            if (_entities.TryGetComponent(eventArgs.Target.Value, out SharedBodyComponent? body))
            {
                SendBodyPartListToUser(eventArgs, body);
            }
            else if (_entities.TryGetComponent <SharedBodyPartComponent?>(eventArgs.Target.Value, out var part))
            {
                DebugTools.AssertNotNull(part);

                if (!part.TryAddMechanism(this))
                {
                    eventArgs.Target.Value.PopupMessage(eventArgs.User, Loc.GetString("mechanism-component-cannot-fit-message"));
                }
            }

            return(true);
        }
        private void SendBodyPartListToUser(AfterInteractEventArgs eventArgs, SharedBodyComponent body)
        {
            // Create dictionary to send to client (text to be shown : data sent back if selected)
            var toSend = new Dictionary <string, int>();

            foreach (var(part, slot) in body.Parts)
            {
                // For each limb in the target, add it to our cache if it is a valid option.
                if (part.CanAddMechanism(this))
                {
                    OptionsCache.Add(IdHash, slot);
                    toSend.Add(part + ": " + part.Name, IdHash++);
                }
            }

            if (OptionsCache.Count > 0 &&
                _entities.TryGetComponent(eventArgs.User, out ActorComponent? actor))
            {
                OpenSurgeryUI(actor.PlayerSession);
                UpdateSurgeryUIBodyPartRequest(actor.PlayerSession, toSend);
                PerformerCache = eventArgs.User;
                BodyCache      = body;
            }
            else // If surgery cannot be performed, show message saying so.
            {
                eventArgs.Target?.PopupMessage(eventArgs.User,
                                               Loc.GetString("mechanism-component-no-way-to-install-message", ("partName", Name: _entities.GetComponent <MetaDataComponent>(Owner).EntityName)));
            }
        }
        void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!InteractionChecks.InRangeUnobstructed(eventArgs))
            {
                return;
            }

            if (eventArgs.Target == null)
            {
                return;
            }
            if (eventArgs.Target.TryGetComponent <BodySystem.BodyManagerComponent>(out BodySystem.BodyManagerComponent bodyManager))
            {
                _surgeryOptionsCache.Clear();
                var toSend = new Dictionary <string, string>();
                foreach (var(key, value) in bodyManager.PartDictionary)
                {
                    if (value.SurgeryCheck(_surgeryToolClass))
                    {
                        _surgeryOptionsCache.Add(key, value);
                        toSend.Add(key, value.Name);
                    }
                }
                if (_surgeryOptionsCache.Count > 0)
                {
                    OpenSurgeryUI(eventArgs.User);
                    UpdateSurgeryUI(eventArgs.User, toSend);
                    _performerCache = eventArgs.User;
                    _targetCache    = bodyManager;
                }
            }
        }
        void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true))
            {
                return;
            }

            //Make sure we have the attacking entity
            if (eventArgs.Target == null || !Owner.TryGetComponent(out SolutionComponent? solution) || !solution.Injector)
            {
                return;
            }

            var targetEntity = eventArgs.Target;

            //Handle injecting/drawing for solutions
            if (targetEntity.TryGetComponent <SolutionComponent>(out var targetSolution) && targetSolution.Injectable)
            {
                if (_toggleState == InjectorToggleMode.Inject)
                {
                    TryInject(targetSolution, eventArgs.User);
                }
                else if (_toggleState == InjectorToggleMode.Draw)
                {
                    TryDraw(targetSolution, eventArgs.User);
                }
            }
        public async Task <bool> AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (_wirePrototypeID == null)
            {
                return(true);
            }
            if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true))
            {
                return(true);
            }
            if (!_mapManager.TryGetGrid(eventArgs.ClickLocation.GetGridId(Owner.EntityManager), out var grid))
            {
                return(true);
            }
            var snapPos  = grid.SnapGridCellFor(eventArgs.ClickLocation, SnapGridOffset.Center);
            var snapCell = grid.GetSnapGridCell(snapPos, SnapGridOffset.Center);

            if (grid.GetTileRef(snapPos).Tile.IsEmpty)
            {
                return(true);
            }
            foreach (var snapComp in snapCell)
            {
                if (snapComp.Owner.TryGetComponent <WireComponent>(out var wire) && wire.WireType == _blockingWireType)
                {
                    return(true);
                }
            }
            if (Owner.TryGetComponent <StackComponent>(out var stack) && !stack.Use(1))
            {
                return(true);
            }
            Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos));
            return(true);
        }
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            var solutionContainerSystem = EntitySystem.Get <SolutionContainerSystem>();

            if (eventArgs.Target == null || !eventArgs.CanReach)
            {
                return(false);
            }

            var targetEntity = eventArgs.Target;

            if (eventArgs.Target.HasComponent <ReagentTankComponent>() &&
                solutionContainerSystem.TryGetDrainableSolution(targetEntity.Uid, out var targetSolution) &&
                solutionContainerSystem.TryGetDrainableSolution(Owner.Uid, out var container))
            {
                var transfer = ReagentUnit.Min(container.AvailableVolume, targetSolution.DrainAvailable);
                if (transfer > 0)
                {
                    var drained = solutionContainerSystem.Drain(targetEntity.Uid, targetSolution, transfer);
                    solutionContainerSystem.TryAddSolution(Owner.Uid, container, drained);

                    SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner);
                    eventArgs.Target.PopupMessage(eventArgs.User,
                                                  Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", Owner)));
                }

                return(true);
            }

            return(false);
        }
Exemple #15
0
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null)
            {
                return(false);
            }

            // This area is dirty but not sure of an easier way to do it besides add an interface or somethin
            bool changed = false;

            if (eventArgs.Target.TryGetComponent(out RevolverBarrelComponent revolverBarrel))
            {
                for (var i = 0; i < Capacity; i++)
                {
                    var ammo = TakeAmmo();
                    if (ammo == null)
                    {
                        break;
                    }

                    if (revolverBarrel.TryInsertBullet(eventArgs.User, ammo))
                    {
                        changed = true;
                        continue;
                    }

                    // Take the ammo back
                    TryInsertAmmo(eventArgs.User, ammo);
                    break;
                }
            }
            else if (eventArgs.Target.TryGetComponent(out BoltActionBarrelComponent boltActionBarrel))
            {
                for (var i = 0; i < Capacity; i++)
                {
                    var ammo = TakeAmmo();
                    if (ammo == null)
                    {
                        break;
                    }

                    if (boltActionBarrel.TryInsertBullet(eventArgs.User, ammo))
                    {
                        changed = true;
                        continue;
                    }

                    // Take the ammo back
                    TryInsertAmmo(eventArgs.User, ammo);
                    break;
                }
            }

            if (changed)
            {
                UpdateAppearance();
            }

            return(true);
        }
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null)
            {
                return(false);
            }

            if (!eventArgs.Target.HasComponent <DamageableComponent>())
            {
                return(true);
            }

            if (!EntitySystem.Get <ActionBlockerSystem>().CanInteract(eventArgs.User))
            {
                return(true);
            }

            if (eventArgs.User != eventArgs.Target &&
                !eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true))
            {
                return(true);
            }

            if (Owner.TryGetComponent <SharedStackComponent>(out var stack) && !EntitySystem.Get <StackSystem>().Use(Owner.Uid, 1, stack))
            {
                return(true);
            }

            EntitySystem.Get <DamageableSystem>().TryChangeDamage(eventArgs.Target.Uid, Damage, true);

            return(true);
        }
        public void AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true))
            {
                return;
            }
            if (!Owner.TryGetComponent(out StackComponent stack))
            {
                return;
            }

            var location    = eventArgs.ClickLocation.AlignWithClosestGridTile();
            var locationMap = location.ToMap(Owner.EntityManager);

            var desiredTile = (ContentTileDefinition)_tileDefinitionManager[_outputTile];

            if (_mapManager.TryGetGrid(location.GetGridId(Owner.EntityManager), out var mapGrid))
            {
                var tile     = mapGrid.GetTileRef(location);
                var baseTurf = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];

                if (HasBaseTurf(desiredTile, baseTurf.Name) && eventArgs.Target == null && stack.Use(1))
                {
                    PlaceAt(mapGrid, location, desiredTile.TileId);
                }
            }
            else if (HasBaseTurf(desiredTile, "space"))
            {
                mapGrid = _mapManager.CreateGrid(locationMap.MapId);
                mapGrid.WorldPosition = locationMap.Position;
                location = new EntityCoordinates(mapGrid.GridEntityId, Vector2.Zero);
                PlaceAt(mapGrid, location, desiredTile.TileId, mapGrid.TileSize / 2f);
            }
        }
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null || !eventArgs.CanReach)
            {
                return(false);
            }

            if (eventArgs.Target.TryGetComponent(out ReagentTankComponent? tank) &&
                eventArgs.Target.TryGetComponent(out ISolutionInteractionsComponent? targetSolution) &&
                targetSolution.CanDrain &&
                Owner.TryGetComponent(out SolutionContainerComponent? container))
            {
                var trans = ReagentUnit.Min(container.EmptyVolume, targetSolution.DrainAvailable);
                if (trans > 0)
                {
                    var drained = targetSolution.Drain(trans);
                    container.TryAddSolution(drained);

                    SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner);
                    eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", Owner)));
                }

                return(true);
            }

            return(false);
        }
Exemple #19
0
        void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null)
            {
                return;
            }

            CloseAllSurgeryUIs();
            OptionsCache.Clear();
            PerformerCache = null;
            BodyCache      = null;

            if (eventArgs.Target.TryGetComponent(out IBody? body))
            {
                SendBodyPartListToUser(eventArgs, body);
            }
            else if (eventArgs.Target.TryGetComponent <IBodyPart>(out var part))
            {
                DebugTools.AssertNotNull(part);

                if (!part.TryAddMechanism(this))
                {
                    eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("You can't fit it in!"));
                }
            }
        }
Exemple #20
0
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (_wirePrototypeID == null)
            {
                return(true);
            }
            if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true))
            {
                return(true);
            }
            if (!_mapManager.TryGetGrid(eventArgs.ClickLocation.GetGridId(Owner.EntityManager), out var grid))
            {
                return(true);
            }
            var snapPos = grid.TileIndicesFor(eventArgs.ClickLocation);

            if (grid.GetTileRef(snapPos).Tile.IsEmpty)
            {
                return(true);
            }
            foreach (var anchored in grid.GetAnchoredEntities(snapPos))
            {
                if (Owner.EntityManager.ComponentManager.TryGetComponent <WireComponent>(anchored, out var wire) && wire.WireType == _blockingWireType)
                {
                    return(true);
                }
            }
            if (Owner.TryGetComponent <StackComponent>(out var stack) && !stack.Use(1))
            {
                return(true);
            }
            Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos));
            return(true);
        }
        /// <summary>
        /// Called when clicking on entities while holding in active hand
        /// </summary>
        /// <param name="eventArgs"></param>
        void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!InteractionChecks.InRangeUnobstructed(eventArgs))
            {
                return;
            }

            //Make sure we have the attacking entity
            if (eventArgs.Target == null || !_internalContents.Injector)
            {
                return;
            }

            var targetEntity = eventArgs.Target;

            //Handle injecting/drawing for solutions
            if (targetEntity.TryGetComponent <SolutionComponent>(out var targetSolution) && targetSolution.Injectable)
            {
                if (_toggleState == InjectorToggleMode.Inject)
                {
                    TryInject(targetSolution, eventArgs.User);
                }
                else if (_toggleState == InjectorToggleMode.Draw)
                {
                    TryDraw(targetSolution, eventArgs.User);
                }
            }
Exemple #22
0
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null || !eventArgs.CanReach)
            {
                return(false);
            }

            if (eventArgs.Target.TryGetComponent(out ReagentTankComponent? tank) &&
                eventArgs.Target.TryGetComponent(out ISolutionInteractionsComponent? targetSolution) &&
                targetSolution.CanDrain &&
                Owner.TryGetComponent(out SolutionContainerComponent? container))
            {
                var trans = ReagentUnit.Min(container.EmptyVolume, targetSolution.DrainAvailable);
                if (trans > 0)
                {
                    var drained = targetSolution.Drain(trans);
                    container.TryAddSolution(drained);

                    EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Effects/refill.ogg", Owner);
                    eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("{0:TheName} is now refilled", Owner));
                }

                return(true);
            }

            return(false);
        }
Exemple #23
0
        private void SendBodyPartListToUser(AfterInteractEventArgs eventArgs, BodyManagerComponent bodyManager)
        {
            // Create dictionary to send to client (text to be shown : data sent back if selected)
            var toSend = new Dictionary <string, int>();

            foreach (var(key, value) in bodyManager.Parts)
            {
                // For each limb in the target, add it to our cache if it is a valid option.
                if (value.CanInstallMechanism(ContainedMechanism))
                {
                    _optionsCache.Add(_idHash, value);
                    toSend.Add(key + ": " + value.Name, _idHash++);
                }
            }

            if (_optionsCache.Count > 0)
            {
                OpenSurgeryUI(eventArgs.User.GetComponent <BasicActorComponent>().playerSession);
                UpdateSurgeryUIBodyPartRequest(eventArgs.User.GetComponent <BasicActorComponent>().playerSession,
                                               toSend);
                _performerCache            = eventArgs.User;
                _bodyManagerComponentCache = bodyManager;
            }
            else // If surgery cannot be performed, show message saying so.
            {
                eventArgs.Target.PopupMessage(eventArgs.User,
                                              Loc.GetString("You see no way to install the {0}.", Owner.Name));
            }
        }
Exemple #24
0
        void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null)
            {
                return;
            }

            CloseAllSurgeryUIs();
            _optionsCache.Clear();
            _performerCache            = null;
            _bodyManagerComponentCache = null;

            if (eventArgs.Target.TryGetComponent <BodyManagerComponent>(out var bodyManager))
            {
                SendBodyPartListToUser(eventArgs, bodyManager);
            }
            else if (eventArgs.Target.TryGetComponent <DroppedBodyPartComponent>(out var droppedBodyPart))
            {
                DebugTools.AssertNotNull(droppedBodyPart.ContainedBodyPart);

                if (!droppedBodyPart.ContainedBodyPart.TryInstallDroppedMechanism(this))
                {
                    eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("You can't fit it in!"));
                }
            }
        }
Exemple #25
0
        /// <summary>
        /// Default interaction check for after attack interaction types.
        /// Same as <see cref="SharedInteractionSystem.InRangeUnobstructed"/>, but defaults to allow inside blockers.
        /// Validates that attacker is in range of the attacked entity, if there is such an entity.
        /// If there is no attacked entity, validates that they are in range of the clicked position.
        /// Additionally shows a popup if validation fails.
        /// </summary>
        public static bool InRangeUnobstructed(AfterInteractEventArgs eventArgs, bool insideBlockerValid = true)
        {
            if (eventArgs.Target != null)
            {
                if (!EntitySystem.Get <SharedInteractionSystem>().InRangeUnobstructed(eventArgs.User.Transform.MapPosition,
                                                                                      eventArgs.Target.Transform.WorldPosition, ignoredEnt: eventArgs.Target, insideBlockerValid: insideBlockerValid))
                {
                    var localizationManager = IoCManager.Resolve <ILocalizationManager>();
                    eventArgs.Target.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!"));
                    return(false);
                }
            }
            else
            {
                var mapManager = IoCManager.Resolve <IMapManager>();
                if (!EntitySystem.Get <SharedInteractionSystem>().InRangeUnobstructed(eventArgs.User.Transform.MapPosition,
                                                                                      eventArgs.ClickLocation.ToMapPos(mapManager), ignoredEnt: eventArgs.User, insideBlockerValid: insideBlockerValid))
                {
                    var localizationManager = IoCManager.Resolve <ILocalizationManager>();
                    eventArgs.User.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!"));
                    return(false);
                }
            }


            return(true);
        }
        void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null)
            {
                return;
            }

            CloseAllSurgeryUIs();
            _optionsCache.Clear();
            _performerCache            = null;
            _bodyManagerComponentCache = null;

            if (eventArgs.Target.TryGetComponent <BodyManagerComponent>(out BodyManagerComponent bodyManager))
            {
                SendBodyPartListToUser(eventArgs, bodyManager);
            }
            else if (eventArgs.Target.TryGetComponent <DroppedBodyPartComponent>(out DroppedBodyPartComponent droppedBodyPart))
            {
                if (droppedBodyPart.ContainedBodyPart == null)
                {
                    Logger.Debug("Installing a mechanism was attempted on an IEntity with a DroppedBodyPartComponent that doesn't have a BodyPart in it!");
                    throw new InvalidOperationException("A DroppedBodyPartComponent exists without a BodyPart in it!");
                }
                if (!droppedBodyPart.ContainedBodyPart.TryInstallDroppedMechanism(this))
                {
                    _sharedNotifyManager.PopupMessage(eventArgs.Target, eventArgs.User, Loc.GetString("You can't fit it in!"));
                }
            }
        }
        public void AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!Owner.TryGetComponent(out SolutionComponent tank))
            {
                return;
            }

            if (tank.Solution.GetReagentQuantity(_fuelType) == 0)
            {
                Owner.PopupMessage(eventArgs.User,
                                   Loc.GetString("{0:theName} is out of {1}!", Owner, _fuelName));
            }
            else
            {
                tank.TryRemoveReagent(_fuelType, ReagentUnit.New(_fuelCost));

                var playerPos = eventArgs.User.Transform.Coordinates;
                var direction = (eventArgs.ClickLocation.Position - playerPos.Position).Normalized;
                playerPos.Offset(direction / 2);

                var spray = _serverEntityManager.SpawnEntity(_sprayType, playerPos);
                spray.GetComponent <AppearanceComponent>()
                .SetData(ExtinguisherVisuals.Rotation, direction.ToAngle().Degrees);
                spray.GetComponent <GasVaporComponent>().StartMove(direction, 5);

                EntitySystem.Get <AudioSystem>().PlayFromEntity(_spraySound, Owner);
            }
        }
Exemple #28
0
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            var solutionsSys = EntitySystem.Get <SolutionContainerSystem>();

            if (!eventArgs.InRangeUnobstructed() || eventArgs.Target == null)
            {
                return(false);
            }

            if (!_entities.HasComponent <SolutionContainerManagerComponent>(Owner))
            {
                return(false);
            }

            var target = eventArgs.Target !.Value;

            if (!_entities.HasComponent <SolutionContainerManagerComponent>(target))
            {
                return(false);
            }


            if (CanReceive && _entities.TryGetComponent(target, out ReagentTankComponent? tank) &&
                solutionsSys.TryGetRefillableSolution(Owner, out var ownerRefill) &&
                solutionsSys.TryGetDrainableSolution(target, out var targetDrain))
            {
                var transferred = DoTransfer(eventArgs.User, target, targetDrain, Owner, ownerRefill, tank.TransferAmount);
                if (transferred > 0)
                {
                    var toTheBrim = ownerRefill.AvailableVolume == 0;
                    var msg       = toTheBrim
                        ? "comp-solution-transfer-fill-fully"
                        : "comp-solution-transfer-fill-normal";

                    target.PopupMessage(eventArgs.User,
                                        Loc.GetString(msg, ("owner", eventArgs.Target), ("amount", transferred), ("target", Owner)));
                    return(true);
                }
            }

            if (CanSend && solutionsSys.TryGetRefillableSolution(target, out var targetRefill) &&
                solutionsSys.TryGetDrainableSolution(Owner, out var ownerDrain))
            {
                var transferred = DoTransfer(eventArgs.User, Owner, ownerDrain, target, targetRefill, TransferAmount);

                if (transferred > 0)
                {
                    Owner.PopupMessage(eventArgs.User,
                                       Loc.GetString("comp-solution-transfer-transfer-solution",
                                                     ("amount", transferred),
                                                     ("target", target)));

                    return(true);
                }
            }

            return(true);
        }
        // Feeding someone else
        void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null)
            {
                return;
            }

            TryUseFood(eventArgs.User, eventArgs.Target);
        }
Exemple #30
0
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (!eventArgs.CanReach)
            {
                return(false);
            }

            return(TryDoInject(eventArgs.Target, eventArgs.User));
        }