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); } }
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); } }
/// <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(); }
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); }
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); } }
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; }
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); }
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; } }
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); }
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; } }
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); } }
private void OnPumpInteractUsing(EntityUid uid, PumpBarrelComponent component, InteractUsingEvent args) { if (args.Handled) { return; } if (TryInsertBullet(component, args)) { args.Handled = true; } }
private void OnInteractUsing(EntityUid uid, KitchenSpikeComponent component, InteractUsingEvent args) { if (args.Handled) { return; } if (TryGetPiece(uid, args.User, args.Used)) { args.Handled = true; } }
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; }
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; }
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); }
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; }
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; } }
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; }
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); }