Пример #1
0
        private void OnInteractUsing(EntityUid uid, ToiletComponent component, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            // are player trying place or lift of cistern lid?
            if (EntityManager.TryGetComponent(args.Used, out ToolComponent? tool) &&
                tool.Qualities.Contains(component.PryingQuality))
            {
                // check if someone is already prying this toilet
                if (component.IsPrying)
                {
                    return;
                }
                component.IsPrying = true;

                // try to pry toilet cistern
                if (!_toolSystem.UseTool(args.Used, args.User, uid, 0f,
                                         component.PryLidTime, component.PryingQuality,
                                         new ToiletPryFinished(uid), new ToiletPryInterrupted(uid)))
                {
                    component.IsPrying = false;
                    return;
                }

                args.Handled = true;
            }
            // maybe player trying to hide something inside cistern?
            else if (component.LidOpen)
            {
                args.Handled = _secretStash.TryHideItem(uid, args.User, args.Used);
            }
        }
Пример #2
0
        private void OnInteractUsing(EntityUid uid, EmitterComponent component, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (component.AccessReader == null || !args.Used.TryGetComponent(out IAccess? access))
            {
                return;
            }

            if (component.AccessReader.IsAllowed(access))
            {
                component.IsLocked ^= true;

                if (component.IsLocked)
                {
                    component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-lock", ("target", component.Owner)));
                }
                else
                {
                    component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-unlock", ("target", component.Owner)));
                }

                UpdateAppearance(component);
            }
            else
            {
                component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-access-denied"));
            }

            args.Handled = true;
        }
    private void OnInteractUsing(EntityUid uid, SeedExtractorComponent component, InteractUsingEvent args)
    {
        if (!this.IsPowered(uid, EntityManager))
        {
            return;
        }

        if (!TryComp(args.Used, out ProduceComponent? produce))
        {
            return;
        }
        if (!_botanySystem.TryGetSeed(produce, out var seed))
        {
            return;
        }

        _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message", ("name", args.Used)),
                                 Filter.Entities(args.User), PopupType.Medium);

        QueueDel(args.Used);

        var random = _random.Next(component.MinSeeds, component.MaxSeeds);
        var coords = Transform(uid).Coordinates;

        if (random > 1)
        {
            seed.Unique = false;
        }

        for (var i = 0; i < random; i++)
        {
            _botanySystem.SpawnSeedPacket(seed, coords);
        }
    }
Пример #4
0
        /// <summary>
        ///     Tries to insert a held item in any fitting item slot. If a valid slot already contains an item, it will
        ///     swap it out and place the old one in the user's hand.
        /// </summary>
        /// <remarks>
        ///     This only handles the event if the user has an applicable entity that can be inserted. This allows for
        ///     other interactions to still happen (e.g., open UI, or toggle-open), despite the user holding an item.
        ///     Maybe this is undesirable.
        /// </remarks>
        private void OnInteractUsing(EntityUid uid, ItemSlotsComponent itemSlots, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (!EntityManager.TryGetComponent(args.User, out SharedHandsComponent hands))
            {
                return;
            }

            foreach (var slot in itemSlots.Slots.Values)
            {
                if (!CanInsert(uid, args.Used, slot, swap: slot.Swap, popup: args.User))
                {
                    continue;
                }

                // Drop the held item onto the floor. Return if the user cannot drop.
                if (!_handsSystem.TryDrop(args.User, args.Used, handsComp: hands))
                {
                    return;
                }

                if (slot.Item != null)
                {
                    _handsSystem.TryPickupAnyHand(args.User, slot.Item.Value, handsComp: hands);
                }

                Insert(uid, slot, args.Used, args.User, excludeUserAudio: args.Predicted);
                args.Handled = true;
                return;
            }
        }
    private void OnInteractUsing(EntityUid uid, GatherableComponent component, InteractUsingEvent args)
    {
        if (!TryComp <GatheringToolComponent>(args.Used, out var tool) ||
            component.ToolWhitelist?.IsValid(args.Used) == false ||
            tool.GatheringEntities.TryGetValue(uid, out var cancelToken))
        {
            return;
        }

        // Can't gather too many entities at once.
        if (tool.MaxGatheringEntities < tool.GatheringEntities.Count + 1)
        {
            return;
        }

        cancelToken = new CancellationTokenSource();
        tool.GatheringEntities[uid] = cancelToken;

        var doAfter = new DoAfterEventArgs(args.User, tool.GatheringTime, cancelToken.Token, uid)
        {
            BreakOnDamage           = true,
            BreakOnStun             = true,
            BreakOnTargetMove       = true,
            BreakOnUserMove         = true,
            MovementThreshold       = 0.25f,
            BroadcastCancelledEvent = new GatheringDoafterCancel {
                Tool = args.Used, Resource = uid
            },
            TargetFinishedEvent = new GatheringDoafterSuccess {
                Tool = args.Used, Resource = uid, Player = args.User
            }
        };

        _doAfterSystem.DoAfter(doAfter);
    }
        private void OnInteractUsing(EntityUid uid, MicrowaveComponent component, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }
            if (!component.Powered)
            {
                _popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-no-power"), uid, Filter.Entities(args.User));
                return;
            }

            if (component.Broken)
            {
                _popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-broken"), uid, Filter.Entities(args.User));
                return;
            }

            if (!HasComp <SharedItemComponent>(args.Used))
            {
                _popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-transfer-fail"), uid, Filter.Entities(args.User));
                return;
            }

            args.Handled = true;

            component.Storage.Insert(args.Used);
            component.DirtyUi();
        }
Пример #7
0
        private void OnInteractUsing(EntityUid uid, PaperComponent paperComp, InteractUsingEvent args)
        {
            if (_tagSystem.HasTag(args.Used, "Write"))
            {
                if (!TryComp <ActorComponent>(args.User, out var actor))
                {
                    return;
                }

                paperComp.Mode = PaperAction.Write;
                UpdateUserInterface(uid, paperComp);
                _uiSystem.GetUiOrNull(uid, PaperUiKey.Key)?.Open(actor.PlayerSession);
                return;
            }

            // If a stamp, attempt to stamp paper
            if (TryComp <StampComponent>(args.Used, out var stampComp) && TryStamp(uid, stampComp.StampedName, stampComp.StampState, paperComp))
            {
                // successfully stamped, play popup
                var stampPaperOtherMessage = Loc.GetString("paper-component-action-stamp-paper-other", ("user", args.User), ("target", args.Target), ("stamp", args.Used));
                _popupSystem.PopupEntity(stampPaperOtherMessage, args.User, Filter.Pvs(args.User, entityManager: EntityManager).RemoveWhereAttachedEntity(puid => puid == args.User));
                var stampPaperSelfMessage = Loc.GetString("paper-component-action-stamp-paper-self", ("target", args.Target), ("stamp", args.Used));
                _popupSystem.PopupEntity(stampPaperSelfMessage, args.User, Filter.Entities(args.User));
            }
        }
        private void OnPartInteractUsing(EntityUid uid, AMEPartComponent component, InteractUsingEvent args)
        {
            if (!HasComp <HandsComponent>(args.User))
            {
                _popupSystem.PopupEntity(Loc.GetString("ame-part-component-interact-using-no-hands"), uid, Filter.Entities(args.User));
                return;
            }

            if (!_toolSystem.HasQuality(args.Used, component.QualityNeeded))
            {
                return;
            }

            if (!_mapManager.TryGetGrid(args.ClickLocation.GetGridUid(EntityManager), out var mapGrid))
            {
                return; // No AME in space.
            }
            var snapPos = mapGrid.TileIndicesFor(args.ClickLocation);

            if (mapGrid.GetAnchoredEntities(snapPos).Any(sc => HasComp <AMEShieldComponent>(sc)))
            {
                _popupSystem.PopupEntity(Loc.GetString("ame-part-component-shielding-already-present"), uid, Filter.Entities(args.User));
                return;
            }

            var ent = EntityManager.SpawnEntity("AMEShielding", mapGrid.GridTileToLocal(snapPos));

            SoundSystem.Play(component.UnwrapSound.GetSound(), Filter.Pvs(uid), uid);

            EntityManager.QueueDeleteEntity(uid);
        }
Пример #9
0
        private void OnInteractUsing(EntityUid uid, EnergySwordComponent comp, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (!TryComp(args.Used, out ToolComponent? tool) || !tool.Qualities.ContainsAny("Pulsing"))
            {
                return;
            }

            args.Handled = true;
            comp.Hacked  = !comp.Hacked;

            if (comp.Hacked)
            {
                var rgb = EnsureComp <RgbLightControllerComponent>(uid);
                _rgbSystem.SetCycleRate(uid, comp.CycleRate, rgb);
            }
            else
            {
                RemComp <RgbLightControllerComponent>(uid);
            }
        }
Пример #10
0
        public async void Repair(EntityUid uid, RepairableComponent component, InteractUsingEvent args)
        {
            // Only try repair the target if it is damaged
            if (!EntityManager.TryGetComponent(component.Owner, out DamageableComponent? damageable) || damageable.TotalDamage == 0)
            {
                return;
            }

            // Can the tool actually repair this, does it have enough fuel?
            if (!await _toolSystem.UseTool(args.Used, args.User, uid, component.FuelCost, component.DoAfterDelay, component.QualityNeeded))
            {
                return;
            }

            if (component.Damage != null)
            {
                var damageChanged = _damageableSystem.TryChangeDamage(uid, component.Damage, true, false);
                _logSystem.Add(LogType.Healed, $"{ToPrettyString(args.User):user} repaired {ToPrettyString(uid):target} by {damageChanged?.Total}");
            }
            else
            {
                // Repair all damage
                _damageableSystem.SetAllDamage(damageable, 0);
                _logSystem.Add(LogType.Healed, $"{ToPrettyString(args.User):user} repaired {ToPrettyString(uid):target} back to full health");
            }


            component.Owner.PopupMessage(args.User,
                                         Loc.GetString("comp-repairable-repair",
                                                       ("target", component.Owner),
                                                       ("tool", args.Used)));

            args.Handled = true;
        }
Пример #11
0
    public bool TryInsertBullet(PumpBarrelComponent component, InteractUsingEvent args)
    {
        if (!TryComp(args.Used, out AmmoComponent? ammoComponent))
        {
            return(false);
        }

        if (ammoComponent.Caliber != component.Caliber)
        {
            _popup.PopupEntity(Loc.GetString("pump-barrel-component-try-insert-bullet-wrong-caliber"), component.Owner, Filter.Entities(args.User));
            return(false);
        }

        if (component.AmmoContainer.ContainedEntities.Count < component.Capacity - 1)
        {
            component.AmmoContainer.Insert(args.Used);
            component.SpawnedAmmo.Push(args.Used);
            component.Dirty(EntityManager);
            UpdatePumpAppearance(component);
            SoundSystem.Play(Filter.Pvs(component.Owner), component.SoundInsert.GetSound(), component.Owner, AudioParams.Default.WithVolume(-2));
            return(true);
        }

        _popup.PopupEntity(Loc.GetString("pump-barrel-component-try-insert-bullet-no-room"), component.Owner, Filter.Entities(args.User));

        return(false);
    }
        /// <summary>
        /// Uses a item/object on an entity
        /// Finds components with the InteractUsing interface and calls their function
        /// NOTE: Does not have an InRangeUnobstructed check
        /// </summary>
        public async Task InteractUsing(IEntity user, IEntity used, IEntity target, EntityCoordinates clickLocation)
        {
            if (!Get <ActionBlockerSystem>().CanInteract(user))
            {
                return;
            }

            // all interactions should only happen when in range / unobstructed, so no range check is needed
            var interactUsingEvent = new InteractUsingEvent(user, used, target, clickLocation);

            RaiseLocalEvent(target.Uid, interactUsingEvent);
            if (interactUsingEvent.Handled)
            {
                return;
            }

            var interactUsingEventArgs = new InteractUsingEventArgs(user, clickLocation, used, target);

            var interactUsings = target.GetAllComponents <IInteractUsing>().OrderByDescending(x => x.Priority);

            foreach (var interactUsing in interactUsings)
            {
                // If an InteractUsing returns a status completion we finish our interaction
                if (await interactUsing.InteractUsing(interactUsingEventArgs))
                {
                    return;
                }
            }

            // If we aren't directly interacting with the nearby object, lets see if our item has an after interact we can do
            await InteractDoAfter(user, used, target, clickLocation, true);
        }
Пример #13
0
    private void OnInteractUsing(EntityUid uid, SeedExtractorComponent component, InteractUsingEvent args)
    {
        if (!TryComp <ApcPowerReceiverComponent>(uid, out var powerReceiverComponent) || !powerReceiverComponent.Powered)
        {
            return;
        }

        if (TryComp(args.Used, out ProduceComponent? produce))
        {
            if (!_prototypeManager.TryIndex <SeedPrototype>(produce.SeedName, out var seed))
            {
                return;
            }

            _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message", ("name", args.Used)),
                                     Filter.Entities(args.User));

            QueueDel(args.Used);

            var random = _random.Next(component.MinSeeds, component.MaxSeeds);
            var coords = Transform(uid).Coordinates;

            for (var i = 0; i < random; i++)
            {
                _botanySystem.SpawnSeedPacket(seed, coords);
            }
        }
    }
        private void HandleInteract(EntityUid uid, LightReplacerComponent component, InteractUsingEvent eventArgs)
        {
            if (eventArgs.Handled)
            {
                return;
            }

            // standard interaction checks
            if (!_blocker.CanInteract(eventArgs.User))
            {
                return;
            }

            var usedUid = eventArgs.Used;

            // want to insert a new light bulb?
            if (EntityManager.TryGetComponent(usedUid, out LightBulbComponent? bulb))
            {
                eventArgs.Handled = TryInsertBulb(uid, usedUid, eventArgs.User, true, component, bulb);
            }
            // add bulbs from storage?
            else if (EntityManager.TryGetComponent(usedUid, out ServerStorageComponent? storage))
            {
                eventArgs.Handled = TryInsertBulbsFromStorage(uid, usedUid, eventArgs.User, component, storage);
            }
        }
        /// <summary>
        ///     Tries to insert a held item in any fitting item slot. If a valid slot already contains an item, it will
        ///     swap it out and place the old one in the user's hand.
        /// </summary>
        /// <remarks>
        ///     This only handles the event if the user has an applicable entity that can be inserted. This allows for
        ///     other interactions to still happen (e.g., open UI, or toggle-open), despite the user holding an item.
        ///     Maybe this is undesirable.
        /// </remarks>
        private void OnInteractUsing(EntityUid uid, ItemSlotsComponent itemSlots, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (!EntityManager.TryGetComponent(args.User, out SharedHandsComponent hands))
            {
                return;
            }

            foreach (var slot in itemSlots.Slots.Values)
            {
                if (!CanInsert(uid, args.Used, slot, swap: slot.Swap, popup: args.User))
                {
                    continue;
                }

                // Drop the held item onto the floor. Return if the user cannot drop.
                if (!hands.Drop(args.Used))
                {
                    return;
                }

                if (slot.Item != null)
                {
                    hands.TryPutInAnyHand(slot.Item.Value);
                }

                Insert(uid, slot, args.Used, args.User);
                args.Handled = true;
                return;
            }
        }
Пример #16
0
        private void OnInteractUsing(EntityUid uid, PoweredLightComponent component, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            args.Handled = InsertBulb(uid, args.Used, component);
        }
    private void OnInteractUsing(EntityUid uid, WeldableComponent component, InteractUsingEvent args)
    {
        if (args.Handled)
        {
            return;
        }

        args.Handled = TryWeld(uid, args.Used, args.User, component);
    }
Пример #18
0
 private void OnInteractUsing(EntityUid uid, MatchboxComponent component, InteractUsingEvent args)
 {
     if (!args.Handled &&
         args.Used.TryGetComponent <MatchstickComponent>(out var matchstick) &&
         matchstick.CurrentState == SharedBurningStates.Unlit)
     {
         Get <MatchstickSystem>().Ignite(matchstick, args.User);
         args.Handled = true;
     }
 }
 private void OnInteractUsing(EntityUid uid, MatchboxComponent component, InteractUsingEvent args)
 {
     if (!args.Handled &&
         EntityManager.TryGetComponent <MatchstickComponent?>(args.Used, out var matchstick) &&
         matchstick.CurrentState == SmokableState.Unlit)
     {
         Get <MatchstickSystem>().Ignite(matchstick, args.User);
         args.Handled = true;
     }
 }
Пример #20
0
 private void OnInteractUsing(EntityUid uid, StunbatonComponent comp, InteractUsingEvent args)
 {
     if (!ActionBlockerSystem.CanInteract(args.User))
     {
         return;
     }
     if (ComponentManager.TryGetComponent <PowerCellSlotComponent>(uid, out var cellslot))
     {
         cellslot.InsertCell(args.Used);
     }
 }
Пример #21
0
    private void OnPumpInteractUsing(EntityUid uid, PumpBarrelComponent component, InteractUsingEvent args)
    {
        if (args.Handled)
        {
            return;
        }

        if (TryInsertBullet(component, args))
        {
            args.Handled = true;
        }
    }
Пример #22
0
        private void OnInteractUsing(EntityUid uid, KitchenSpikeComponent component, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (TryGetPiece(uid, args.User, args.Used))
            {
                args.Handled = true;
            }
        }
Пример #23
0
    private void OnInteractUsing(EntityUid uid, CableComponent cable, InteractUsingEvent args)
    {
        if (args.Handled)
        {
            return;
        }

        var ev = new CuttingFinishedEvent(args.User);

        _toolSystem.UseTool(args.Used, args.User, uid, 0, cable.CuttingDelay, new[] { cable.CuttingQuality }, doAfterCompleteEvent: ev, doAfterEventTarget: uid);
        args.Handled = true;
    }
Пример #24
0
        private void OnStackInteractUsing(EntityUid uid, StackComponent stack, InteractUsingEvent args)
        {
            if (!args.Used.TryGetComponent <StackComponent>(out var otherStack))
            {
                return;
            }

            if (!otherStack.StackTypeId.Equals(stack.StackTypeId))
            {
                return;
            }

            var toTransfer = Math.Min(stack.Count, otherStack.AvailableSpace);

            SetCount(uid, stack, stack.Count - toTransfer);
            SetCount(args.Used.Uid, otherStack, otherStack.Count + toTransfer);

            var popupPos = args.ClickLocation;

            if (!popupPos.IsValid(EntityManager))
            {
                popupPos = args.User.Transform.Coordinates;
            }

            switch (toTransfer)
            {
            case > 0:
                popupPos.PopupMessage(args.User, $"+{toTransfer}");

                if (otherStack.AvailableSpace == 0)
                {
                    args.Used.SpawnTimer(
                        300,
                        () => popupPos.PopupMessage(
                            args.User,
                            Loc.GetString("comp-stack-becomes-full")
                            )
                        );
                }

                break;

            case 0 when otherStack.AvailableSpace == 0:
                popupPos.PopupMessage(
                    args.User,
                    Loc.GetString("comp-stack-already-full")
                    );
                break;
            }

            args.Handled = true;
        }
Пример #25
0
    private void OnInteractUsing(EntityUid uid, LogComponent component, InteractUsingEvent args)
    {
        if (HasComp <SharpComponent>(args.Used))
        {
            for (var i = 0; i < component.SpawnCount; i++)
            {
                var plank = Spawn(component.SpawnedPrototype, Transform(uid).Coordinates);
                plank.RandomOffset(0.25f);
            }

            QueueDel(uid);
        }
    }
    private void OnUsing(EntityUid uid, ArtifactHeatTriggerComponent component, InteractUsingEvent args)
    {
        if (args.Handled)
        {
            return;
        }

        if (!component.ActivateHotItems || !CheckHot(args.Used))
        {
            return;
        }
        args.Handled = _artifactSystem.TryActivateArtifact(uid, args.User);
    }
Пример #27
0
        private void OnStackInteractUsing(EntityUid uid, StackComponent stack, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (!TryComp <StackComponent>(args.Used, out var otherStack))
            {
                return;
            }

            if (!otherStack.StackTypeId.Equals(stack.StackTypeId))
            {
                return;
            }

            var toTransfer = Math.Min(stack.Count, otherStack.AvailableSpace);

            SetCount(uid, stack.Count - toTransfer, stack);
            SetCount(args.Used, otherStack.Count + toTransfer, otherStack);

            var popupPos = args.ClickLocation;

            if (!popupPos.IsValid(EntityManager))
            {
                popupPos = Transform(args.User).Coordinates;
            }

            var filter = Filter.Entities(args.User);

            switch (toTransfer)
            {
            case > 0:
                _popupSystem.PopupCoordinates($"+{toTransfer}", popupPos, filter);

                if (otherStack.AvailableSpace == 0)
                {
                    _popupSystem.PopupCoordinates(Loc.GetString("comp-stack-becomes-full"),
                                                  popupPos.Offset(new Vector2(0, -0.5f)), filter);
                }

                break;

            case 0 when otherStack.AvailableSpace == 0:
                _popupSystem.PopupCoordinates(Loc.GetString("comp-stack-already-full"), popupPos, filter);
                break;
            }

            args.Handled = true;
        }
Пример #28
0
        private void OnStackInteractUsing(EntityUid uid, SharedStackComponent stack, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (!TryComp(args.Used, out SharedStackComponent? recipientStack))
            {
                return;
            }

            if (!TryMergeStacks(uid, args.Used, out var transfered, stack, recipientStack))
            {
                return;
            }

            args.Handled = true;

            // interaction is done, the rest is just generating a pop-up

            if (!_gameTiming.IsFirstTimePredicted)
            {
                return;
            }

            var popupPos = args.ClickLocation;

            if (!popupPos.IsValid(EntityManager))
            {
                popupPos = Transform(args.User).Coordinates;
            }

            switch (transfered)
            {
            case > 0:
                PopupSystem.PopupCoordinates($"+{transfered}", popupPos, Filter.Local());

                if (recipientStack.AvailableSpace == 0)
                {
                    PopupSystem.PopupCoordinates(Loc.GetString("comp-stack-becomes-full"),
                                                 popupPos.Offset(new Vector2(0, -0.5f)), Filter.Local());
                }

                break;

            case 0 when recipientStack.AvailableSpace == 0:
                PopupSystem.PopupCoordinates(Loc.GetString("comp-stack-already-full"), popupPos, Filter.Local());
                break;
            }
        }
Пример #29
0
        private void OnInteractUsing(EntityUid uid, ItemCabinetComponent comp, InteractUsingEvent args)
        {
            args.Handled = true;
            if (!comp.Opened)
            {
                RaiseLocalEvent(uid, new ToggleItemCabinetEvent(), false);
            }
            else
            {
                RaiseLocalEvent(uid, new TryInsertItemCabinetEvent(args.User, args.Used), false);
            }

            args.Handled = true;
        }
Пример #30
0
    private void OnInteractUsing(EntityUid uid, AnchorableComponent anchorable, InteractUsingEvent args)
    {
        if (args.Handled)
        {
            return;
        }

        // If the used entity doesn't have a tool, return early.
        if (!TryComp(args.Used, out ToolComponent? usedTool) || !usedTool.Qualities.Contains(anchorable.Tool))
        {
            return;
        }

        args.Handled = true;
        TryToggleAnchor(uid, args.User, args.Used, anchorable, usingTool: usedTool);
    }