/// <summary> /// Uses an empty hand on an entity /// Finds components with the InteractHand interface and calls their function /// NOTE: Does not have an InRangeUnobstructed check /// </summary> public void InteractHand(EntityUid user, EntityUid target) { if (!_actionBlockerSystem.CanInteract(user)) { return; } // all interactions should only happen when in range / unobstructed, so no range check is needed var message = new InteractHandEvent(user, target); RaiseLocalEvent(target, message); _adminLogSystem.Add(LogType.InteractHand, LogImpact.Low, $"{user} interacted with {target}"); if (message.Handled) { return; } var interactHandEventArgs = new InteractHandEventArgs(user, target); var interactHandComps = EntityManager.GetComponents <IInteractHand>(target).ToList(); foreach (var interactHandComp in interactHandComps) { // If an InteractHand returns a status completion we finish our interaction #pragma warning disable 618 if (interactHandComp.InteractHand(interactHandEventArgs)) #pragma warning restore 618 { return; } } // Else we run Activate. InteractionActivate(user, target); }
private void OnInteracted(EntityUid uid, SignalSwitchComponent component, InteractHandEvent args) { component.State = !component.State; RaiseLocalEvent(uid, new InvokePortEvent("state", component.State), false); RaiseLocalEvent(uid, new InvokePortEvent("stateChange"), false); args.Handled = true; }
private void OnInteractHand(EntityUid uid, ToiletComponent component, InteractHandEvent args) { if (args.Handled) { return; } // trying get something from stash? if (component.LidOpen) { var gotItem = _secretStash.TryGetItem(uid, args.User); if (gotItem) { args.Handled = true; return; } } // just want to up/down seat? // check that nobody seats on seat right now if (EntityManager.TryGetComponent(uid, out StrapComponent? strap)) { if (strap.BuckledEntities.Count != 0) { return; } } ToggleToiletSeat(uid, component); args.Handled = true; }
/// <summary> /// Uses an empty hand on an entity /// Finds components with the InteractHand interface and calls their function /// NOTE: Does not have any range or can-interact checks. These should all have been done before this function is called. /// </summary> public override void InteractHand(EntityUid user, EntityUid target) { // TODO PREDICTION move server-side interaction logic into the shared system for interaction prediction. // all interactions should only happen when in range / unobstructed, so no range check is needed var message = new InteractHandEvent(user, target); RaiseLocalEvent(target, message); _adminLogSystem.Add(LogType.InteractHand, LogImpact.Low, $"{ToPrettyString(user):user} interacted with {ToPrettyString(target):target}"); if (message.Handled) { return; } var interactHandEventArgs = new InteractHandEventArgs(user, target); var interactHandComps = AllComps <IInteractHand>(target).ToList(); foreach (var interactHandComp in interactHandComps) { // If an InteractHand returns a status completion we finish our interaction #pragma warning disable 618 if (interactHandComp.InteractHand(interactHandEventArgs)) #pragma warning restore 618 { return; } } // Else we run Activate. InteractionActivate(user, target, checkCanInteract: false, checkUseDelay: true, checkAccess: false); }
/// <summary> /// If the cabinet is opened and has an entity, try and take it. Otherwise toggle the cabinet open/closed; /// </summary> private void OnInteractHand(EntityUid uid, ItemCabinetComponent comp, InteractHandEvent args) { if (args.Handled) { return; } if (!EntityManager.TryGetComponent(uid, out SharedItemSlotsComponent itemSlots)) { return; } if (!itemSlots.Slots.TryGetValue(comp.CabinetSlot, out var slot)) { return; } if (comp.Opened && slot.HasEntity) { _itemSlotsSystem.TryEjectContent(uid, comp.CabinetSlot, args.User); } else { ToggleItemCabinet(uid, comp); } args.Handled = true; }
private void OnInteractHand(EntityUid uid, EmitterComponent component, InteractHandEvent args) { args.Handled = true; if (EntityManager.TryGetComponent(uid, out LockComponent? lockComp) && lockComp.Locked) { component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-access-locked", ("target", component.Owner))); return; } if (EntityManager.TryGetComponent(component.Owner, out PhysicsComponent? phys) && phys.BodyType == BodyType.Static) { if (!component.IsOn) { SwitchOn(component); component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-turned-on", ("target", component.Owner))); } else { SwitchOff(component); component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-turned-off", ("target", component.Owner))); } _adminLog.Add(LogType.Emitter, component.IsOn ? LogImpact.Medium : LogImpact.High, $"{ToPrettyString(args.User):player} toggled {ToPrettyString(uid):emitter}"); } else { component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-not-anchored", ("target", component.Owner))); } }
/// <summary> /// Uses an empty hand on an entity /// Finds components with the InteractHand interface and calls their function /// NOTE: Does not have an InRangeUnobstructed check /// </summary> public void InteractHand(IEntity user, IEntity target) { if (!Get <ActionBlockerSystem>().CanInteract(user)) { return; } // all interactions should only happen when in range / unobstructed, so no range check is needed var message = new InteractHandEvent(user, target); RaiseLocalEvent(target.Uid, message); if (message.Handled) { return; } var interactHandEventArgs = new InteractHandEventArgs(user, target); var interactHandComps = target.GetAllComponents <IInteractHand>().ToList(); foreach (var interactHandComp in interactHandComps) { // If an InteractHand returns a status completion we finish our interaction if (interactHandComp.InteractHand(interactHandEventArgs)) { return; } } // Else we run Activate. InteractionActivate(user, target); }
private void OnInteract(EntityUid uid, AirAlarmComponent component, InteractHandEvent args) { if (!_interactionSystem.InRangeUnobstructed(args.User, args.Target)) { return; } if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor)) { return; } if (EntityManager.TryGetComponent(uid, out WiresComponent wire) && wire.IsPanelOpen) { args.Handled = false; return; } if (EntityManager.TryGetComponent(uid, out ApcPowerReceiverComponent recv) && !recv.Powered) { return; } _uiSystem.GetUiOrNull(component.Owner, SharedAirAlarmInterfaceKey.Key)?.Open(actor.PlayerSession); component.ActivePlayers.Add(actor.PlayerSession.UserId); AddActiveInterface(uid); SendAddress(uid); SendAlarmMode(uid); SendThresholds(uid); SyncAllDevices(uid); SendAirData(uid); }
private void OnInteractHand(EntityUid uid, EmitterComponent component, InteractHandEvent args) { args.Handled = true; if (EntityManager.TryGetComponent(uid, out LockComponent? lockComp) && lockComp.Locked) { component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-access-locked", ("target", component.Owner))); return; } if (EntityManager.TryGetComponent(component.Owner, out PhysicsComponent? phys) && phys.BodyType == BodyType.Static) { if (!component.IsOn) { SwitchOn(component); component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-turned-on", ("target", component.Owner))); } else { SwitchOff(component); component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-turned-off", ("target", component.Owner))); } } else { component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-not-anchored", ("target", component.Owner))); } }
private void OnHandInteract(EntityUid uid, SharedItemComponent component, InteractHandEvent args) { if (args.Handled || !component.CanPickup) { return; } args.Handled = _handsSystem.TryPickup(args.User, uid, animateUser: false); }
private void OnInteractHand(EntityUid uid, StrapComponent component, InteractHandEvent args) { if (!TryComp <BuckleComponent>(args.User, out var buckle)) { return; } buckle.ToggleBuckle(args.User, uid); }
private void OnAmmoBoxInteractHand(EntityUid uid, AmmoBoxComponent component, InteractHandEvent args) { if (args.Handled) { return; } TryUse(args.User, component); }
private void OnInteractHand(EntityUid uid, KitchenSpikeComponent component, InteractHandEvent args) { if (args.Handled) { return; } if (component.MeatParts > 0) { _popupSystem.PopupEntity(Loc.GetString("comp-kitchen-spike-knife-needed"), uid, Filter.Entities(args.User)); args.Handled = true; } }
private void OnInteractHand(EntityUid uid, PoweredLightComponent light, InteractHandEvent args) { if (args.Handled) { return; } // check if light has bulb to eject var bulbUid = GetBulb(uid, light); if (bulbUid == null) { return; } // check if it's possible to apply burn damage to user var userUid = args.User; if (EntityManager.TryGetComponent(userUid, out HeatResistanceComponent? heatResist) && EntityManager.TryGetComponent(bulbUid.Value, out LightBulbComponent? lightBulb)) { // get users heat resistance var res = heatResist.GetHeatResistance(); // check heat resistance against user var burnedHand = light.CurrentLit && res < lightBulb.BurningTemperature; if (burnedHand) { // apply damage to users hands and show message with sound var burnMsg = Loc.GetString("powered-light-component-burn-hand"); _popupSystem.PopupEntity(burnMsg, uid, Filter.Entities(userUid)); var damage = _damageableSystem.TryChangeDamage(userUid, light.Damage); if (damage != null) { _logSystem.Add(LogType.Damaged, $"{ToPrettyString(args.User):user} burned their hand on {ToPrettyString(args.Target):target} and received {damage.Total:damage} damage"); } SoundSystem.Play(Filter.Pvs(uid), light.BurnHandSound.GetSound(), uid); args.Handled = true; return; } } // all checks passed // just try to eject bulb args.Handled = EjectBulb(uid, userUid, light) != null; }
private void OnInteractHand(EntityUid uid, ItemCabinetComponent comp, InteractHandEvent args) { args.Handled = true; if (comp.Opened) { if (comp.ItemContainer.ContainedEntity == null) { RaiseLocalEvent(uid, new ToggleItemCabinetEvent(), false); return; } RaiseLocalEvent(uid, new TryEjectItemCabinetEvent(args.User), false); } else { RaiseLocalEvent(uid, new ToggleItemCabinetEvent(), false); } }
private void OnInteractHand(EntityUid uid, KnockedDownComponent knocked, InteractHandEvent args) { if (args.Handled || knocked.HelpTimer > 0f) { return; } // Set it to half the help interval so helping is actually useful... knocked.HelpTimer = knocked.HelpInterval / 2f; _statusEffectSystem.TryRemoveTime(uid, "KnockedDown", TimeSpan.FromSeconds(knocked.HelpInterval)); SoundSystem.Play(Filter.Pvs(uid), knocked.StunAttemptSound.GetSound(), uid, AudioHelpers.WithVariation(0.05f)); knocked.Dirty(); args.Handled = true; }
private void OnHandInteract(EntityUid uid, SharedItemComponent component, InteractHandEvent args) { if (args.Handled) { return; } if (!TryComp(args.User, out SharedHandsComponent? hands)) { return; } if (hands.ActiveHand == null) { return; } args.Handled = hands.TryPickupEntity(hands.ActiveHand, uid, false, animateUser: false); }
/// <summary> /// Attempt to take an item from a slot, if any are set to EjectOnInteract. /// </summary> private void OnInteractHand(EntityUid uid, ItemSlotsComponent itemSlots, InteractHandEvent args) { if (args.Handled) { return; } foreach (var slot in itemSlots.Slots.Values) { if (slot.Locked || !slot.EjectOnInteract || slot.Item == null) { continue; } args.Handled = true; TryEjectToHands(uid, slot, args.User); break; } }
/// <summary> /// Toggles the state of the switch and sents a <see cref="DeviceNetworkConstants.CmdSetState"/> command with the /// <see cref="DeviceNetworkConstants.StateEnabled"/> value set to state. /// </summary> private void OnInteracted(EntityUid uid, ApcNetSwitchComponent component, InteractHandEvent args) { if (!EntityManager.TryGetComponent(uid, out DeviceNetworkComponent? networkComponent)) { return; } component.State = !component.State; var payload = new NetworkPayload { [DeviceNetworkConstants.Command] = DeviceNetworkConstants.CmdSetState, [DeviceNetworkConstants.StateEnabled] = component.State, }; _deviceNetworkSystem.QueuePacket(uid, DeviceNetworkConstants.NullAddress, networkComponent.Frequency, payload, true); args.Handled = true; }
private void OnPumpInteractHand(EntityUid uid, GasVolumePumpComponent pump, InteractHandEvent args) { if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor)) { return; } if (EntityManager.GetComponent <TransformComponent>(pump.Owner).Anchored) { _userInterfaceSystem.TryOpen(uid, GasVolumePumpUiKey.Key, actor.PlayerSession); DirtyUI(uid, pump); } else { args.User.PopupMessageCursor(Loc.GetString("comp-gas-pump-ui-needs-anchor")); } args.Handled = true; }
private void OnInteractHand(EntityUid uid, FireAlarmComponent component, InteractHandEvent args) { if (!_interactionSystem.InRangeUnobstructed(args.User, args.Target)) { return; } if (EntityManager.TryGetComponent(args.User, out ActorComponent? actor) && EntityManager.TryGetComponent(uid, out AtmosMonitorComponent? monitor) && this.IsPowered(uid, EntityManager)) { if (monitor.HighestAlarmInNetwork == AtmosMonitorAlarmType.Normal) { _monitorSystem.Alert(uid, AtmosMonitorAlarmType.Danger); } else { _monitorSystem.ResetAll(uid); } } }
private void OnInteractHand(EntityUid uid, TwoWayLeverComponent component, InteractHandEvent args) { component.State = component.State switch { TwoWayLeverSignal.Middle => component.NextSignalLeft ? TwoWayLeverSignal.Left : TwoWayLeverSignal.Right, TwoWayLeverSignal.Right => TwoWayLeverSignal.Middle, TwoWayLeverSignal.Left => TwoWayLeverSignal.Middle, _ => throw new ArgumentOutOfRangeException() }; if (component.State == TwoWayLeverSignal.Middle) { component.NextSignalLeft = !component.NextSignalLeft; } if (EntityManager.TryGetComponent <AppearanceComponent>(uid, out var appearanceComponent)) { appearanceComponent.SetData(TwoWayLeverVisuals.State, component.State); } RaiseLocalEvent(uid, new InvokePortEvent("state", component.State)); args.Handled = true; } }
private void OnInteractHand(EntityUid uid, SignalButtonComponent component, InteractHandEvent args) { RaiseLocalEvent(uid, new InvokePortEvent("pressed"), false); args.Handled = true; }
private void HandleInteractHand(EntityUid uid, BuckleComponent component, InteractHandEvent args) { args.Handled = component.TryUnbuckle(args.User); }
private void OnInteractHand(EntityUid uid, PoweredLightComponent light, InteractHandEvent args) { if (args.Handled) { return; } if (light.CancelToken != null) { return; } // check if light has bulb to eject var bulbUid = GetBulb(uid, light); if (bulbUid == null) { return; } // check if it's possible to apply burn damage to user var userUid = args.User; if (EntityManager.TryGetComponent(userUid, out HeatResistanceComponent? heatResist) && EntityManager.TryGetComponent(bulbUid.Value, out LightBulbComponent? lightBulb)) { // get users heat resistance var res = heatResist.GetHeatResistance(); // check heat resistance against user var burnedHand = light.CurrentLit && res < lightBulb.BurningTemperature; if (burnedHand) { // apply damage to users hands and show message with sound var burnMsg = Loc.GetString("powered-light-component-burn-hand"); _popupSystem.PopupEntity(burnMsg, uid, Filter.Entities(userUid)); var damage = _damageableSystem.TryChangeDamage(userUid, light.Damage); if (damage != null) { _adminLogger.Add(LogType.Damaged, $"{ToPrettyString(args.User):user} burned their hand on {ToPrettyString(args.Target):target} and received {damage.Total:damage} damage"); } SoundSystem.Play(light.BurnHandSound.GetSound(), Filter.Pvs(uid), uid); args.Handled = true; return; } } //removing a broken/burned bulb, so allow instant removal if (TryComp <LightBulbComponent>(bulbUid.Value, out var bulb) && bulb.State != LightBulbState.Normal) { args.Handled = EjectBulb(uid, userUid, light) != null; return; } // removing a working bulb, so require a delay light.CancelToken = new CancellationTokenSource(); _doAfterSystem.DoAfter(new DoAfterEventArgs((EntityUid)userUid, light.EjectBulbDelay, light.CancelToken.Token, uid) { BreakOnUserMove = true, BreakOnDamage = true, BreakOnStun = true, TargetFinishedEvent = new EjectBulbCompleteEvent() { Component = light, User = userUid, Target = uid, }, TargetCancelledEvent = new EjectBulbCancelledEvent() { Component = light, } }); args.Handled = true; }
private void OnCanisterInteractHand(EntityUid uid, GasCanisterComponent component, InteractHandEvent args) { if (!args.User.TryGetComponent(out ActorComponent? actor)) { return; } component.Owner.GetUIOrNull(GasCanisterUiKey.Key)?.Open(actor.PlayerSession); args.Handled = true; }
private void OnInteractHand(EntityUid uid, InteractionPopupComponent component, InteractHandEvent args) { if (args.Handled) { return; } var curTime = _gameTiming.CurTime; if (curTime < component.LastInteractTime + component.InteractDelay) { return; } if (TryComp <MobStateComponent>(uid, out var state) && // if it has a MobStateComponent, !state.IsAlive()) // AND if that state is not Alive (e.g. dead/incapacitated/critical) { return; } string msg = ""; // Stores the text to be shown in the popup message string?sfx = null; // Stores the filepath of the sound to be played if (_random.Prob(component.SuccessChance)) { if (component.InteractSuccessString != null) { msg = Loc.GetString(component.InteractSuccessString, ("target", uid)); // Success message (localized). } if (component.InteractSuccessSound != null) { sfx = component.InteractSuccessSound.GetSound(); } } else { if (component.InteractFailureString != null) { msg = Loc.GetString(component.InteractFailureString, ("target", uid)); // Failure message (localized). } if (component.InteractFailureSound != null) { sfx = component.InteractFailureSound.GetSound(); } } if (component.PopupPerceivedByOthers) { _popupSystem.PopupEntity(msg, uid, Filter.Pvs(uid)); //play for everyone in range } else { _popupSystem.PopupEntity(msg, uid, Filter.Entities(args.User)); //play only for the initiating entity. } if (sfx is not null) //not all cases will have sound. { if (component.SoundPerceivedByOthers) { SoundSystem.Play(Filter.Pvs(args.Target), sfx, args.Target); //play for everyone in range } else { SoundSystem.Play(Filter.Entities(args.User, args.Target), sfx, args.Target); //play only for the initiating entity and its target. } } component.LastInteractTime = curTime; args.Handled = true; }
private void OnInteract(EntityUid uid, ArtifactInteractionTriggerComponent component, InteractHandEvent args) { if (args.Handled) { return; } if (!component.EmptyHandActivation) { return; } args.Handled = _artifactSystem.TryActivateArtifact(uid, args.User); }
private void OnInteract(EntityUid uid, ContainmentFieldGeneratorComponent component, InteractHandEvent args) { if (args.Handled) { return; } if (TryComp(component.Owner, out TransformComponent? transformComp) && transformComp.Anchored) { if (!component.Enabled) { TurnOn(component); } else if (component.Enabled && component.IsConnected) { _popupSystem.PopupEntity(Loc.GetString("comp-containment-anchor-warning"), args.User, Filter.Entities(args.User)); return; } else { TurnOff(component); } } args.Handled = true; }
private void OnElectrifiedHandInteract(EntityUid uid, ElectrifiedComponent electrified, InteractHandEvent args) { if (!electrified.OnHandInteract) { return; } TryDoElectrifiedAct(uid, args.User, 1, electrified); }