return;
}
- _popup.PopupClient(Loc.GetString("base-computer-ui-component-not-powered", ("machine", ent.Owner)), args.User, args.User);
+ if (!args.Silent)
+ _popup.PopupClient(Loc.GetString("base-computer-ui-component-not-powered", ("machine", ent.Owner)), args.User, args.User);
+
args.Cancel();
}
}
private void OnAfterUIOpen(EntityUid uid, BlockGameArcadeComponent component, AfterActivatableUIOpenEvent args)
{
if (component.Player == null)
- component.Player = args.Actor;
+ component.Player = args.User;
else
- component.Spectators.Add(args.Actor);
+ component.Spectators.Add(args.User);
- UpdatePlayerStatus(uid, args.Actor, component);
- component.Game?.UpdateNewPlayerUI(args.Actor);
+ UpdatePlayerStatus(uid, args.User, component);
+ component.Game?.UpdateNewPlayerUI(args.User);
}
private void OnAfterUiClose(EntityUid uid, BlockGameArcadeComponent component, BoundUIClosedEvent args)
private void OnUIActivationAttempt(EntityUid uid, SpaceHeaterComponent spaceHeater, ActivatableUIOpenAttemptEvent args)
{
- if (!Comp<TransformComponent>(uid).Anchored)
- {
+ if (Comp<TransformComponent>(uid).Anchored)
+ return;
+
+ if (!args.Silent)
_popup.PopupEntity(Loc.GetString("comp-space-heater-unanchored", ("device", Loc.GetString("comp-space-heater-device-name"))), uid, args.User);
- args.Cancel();
- }
+
+ args.Cancel();
}
private void OnDeviceUpdated(EntityUid uid, SpaceHeaterComponent spaceHeater, ref AtmosDeviceUpdateEvent args)
UpdateListUiState(conf, conf.Comp);
}
-
- private void OnUiOpenAttempt(EntityUid uid, NetworkConfiguratorComponent configurator, ActivatableUIOpenAttemptEvent args)
- {
- if (configurator.LinkModeActive)
- args.Cancel();
- }
#endregion
}
{
if (!_accessReaderSystem.IsAllowed(args.User, ent))
{
- var msg = Loc.GetString("war-declarator-not-working");
- _popupSystem.PopupEntity(msg, ent);
+ if (!args.Silent)
+ {
+ var msg = Loc.GetString("war-declarator-not-working");
+ _popupSystem.PopupEntity(msg, ent);
+ }
args.Cancel();
return;
}
if (component.AccountOwner == mind)
return;
- _popup.PopupEntity(Loc.GetString("store-not-account-owner", ("store", uid)), uid, args.User);
+ if (!args.Silent)
+ _popup.PopupEntity(Loc.GetString("store-not-account-owner", ("store", uid)), uid, args.User);
+
args.Cancel();
}
if (!_access.IsAllowed(args.User, activatableUI))
{
args.Cancel();
- if (activatableUI.Comp.PopupMessage != null)
+ if (activatableUI.Comp.PopupMessage != null && !args.Silent)
_popup.PopupClient(Loc.GetString(activatableUI.Comp.PopupMessage), activatableUI, args.User);
}
}
if (TryComp<BlindableComponent>(args.User, out var blindable) && blindable.IsBlind)
{
- _popupSystem.PopupClient(Loc.GetString("blindness-fail-attempt"), args.User, Shared.Popups.PopupType.MediumCaution);
+ if (!args.Silent)
+ _popupSystem.PopupClient(Loc.GetString("blindness-fail-attempt"), args.User, Shared.Popups.PopupType.MediumCaution);
args.Cancel();
}
}
return;
args.Cancel();
+
+ if (args.Silent)
+ return;
+
if (lockComp.Locked && component.Popup != null)
{
_sharedPopupSystem.PopupClient(Loc.GetString(component.Popup), uid, args.User);
return;
args.Cancel();
- Popup.PopupClient(Loc.GetString("emergency-shuttle-console-no-early-launches"), ent, args.User);
+
+ if (!args.Silent)
+ Popup.PopupClient(Loc.GetString("emergency-shuttle-console-no-early-launches"), ent, args.User);
}
}
namespace Content.Shared.UserInterface;
/// <summary>
+/// Raised on the entity with an activatable UI when attempting to open it.
/// This is raised BEFORE opening a UI! Do not listen and then open / do something use
/// <see cref="AfterActivatableUIOpenEvent"/> for that.
/// </summary>
-public sealed class ActivatableUIOpenAttemptEvent : CancellableEntityEventArgs
+public sealed class ActivatableUIOpenAttemptEvent(EntityUid user, bool silent) : CancellableEntityEventArgs
{
- public EntityUid User { get; }
- public ActivatableUIOpenAttemptEvent(EntityUid who)
- {
- User = who;
- }
+ /// <summary>
+ /// The player trying to open the UI.
+ /// </summary>
+ public readonly EntityUid User = user;
+
+ /// <summary>
+ /// Whether subscriptions are allowed to play a sound or show popups.
+ /// This is used to prevent just looking at the verb without even clicking on it showing a popup or playing sounds.
+ /// </summary>
+ public bool Silent = silent;
}
-public sealed class UserOpenActivatableUIAttemptEvent : CancellableEntityEventArgs //have to one-up the already stroke-inducing name
+/// <summary>
+/// Raised on the player when they are attempting to open an activatable UI.
+/// This is raised BEFORE opening a UI! Do not listen and then open / do something use
+/// <see cref="AfterActivatableUIOpenEvent"/> for that.
+/// </summary>
+public sealed class UserOpenActivatableUIAttemptEvent(EntityUid user, EntityUid target, bool silent) : CancellableEntityEventArgs //have to one-up the already stroke-inducing name
{
- public EntityUid User { get; }
- public EntityUid Target { get; }
- public UserOpenActivatableUIAttemptEvent(EntityUid who, EntityUid target)
- {
- User = who;
- Target = target;
- }
+ /// <summary>
+ /// The player trying to open the UI.
+ /// </summary>
+ public readonly EntityUid User = user;
+
+ /// <summary>
+ /// The target entity with the UI.
+ /// </summary>
+ public readonly EntityUid Target = target;
+
+ /// <summary>
+ /// Whether subscriptions are allowed to play a sound or show popups.
+ /// This is used to prevent just looking at the verb without even clicking on it to show a popup or play sounds if the attempt is cancelled.
+ /// </summary>
+ public bool Silent = silent;
}
-public sealed class AfterActivatableUIOpenEvent : EntityEventArgs
+/// <summary>
+/// Raised on the entity with an activatable UI after the UI has been opened.
+/// </summary>
+public sealed class AfterActivatableUIOpenEvent(EntityUid user) : EntityEventArgs
{
- public EntityUid User { get; }
- public readonly EntityUid Actor;
-
- public AfterActivatableUIOpenEvent(EntityUid who, EntityUid actor)
- {
- User = who;
- Actor = actor;
- }
+ /// <summary>
+ /// The player that opened the UI.
+ /// </summary>
+ public readonly EntityUid User = user;
}
/// <summary>
-/// This is after it's decided the user can open the UI,
+/// Raised on the entity with an activatable UI after it's decided the user can open the UI,
/// but before the UI actually opens.
-/// Use this if you need to prepare the UI itself
+/// Use this if you need to prepare the UI itself.
/// </summary>
-public sealed class BeforeActivatableUIOpenEvent : EntityEventArgs
+public sealed class BeforeActivatableUIOpenEvent(EntityUid user) : EntityEventArgs
{
- public EntityUid User { get; }
- public BeforeActivatableUIOpenEvent(EntityUid who)
- {
- User = who;
- }
+ /// <summary>
+ /// The player that is opening the UI.
+ /// </summary>
+ public readonly EntityUid User = user;
}
public sealed class ActivatableUIPlayerChangedEvent : EntityEventArgs
if (args.Cancelled)
return;
- if (!Transform(ent.Owner).Anchored)
- {
- if (ent.Comp.Popup != null)
- {
- _popup.PopupClient(Loc.GetString(ent.Comp.Popup), args.User);
- }
+ if (Transform(ent.Owner).Anchored)
+ return;
- args.Cancel();
+ if (ent.Comp.Popup != null && !args.Silent)
+ {
+ _popup.PopupClient(Loc.GetString(ent.Comp.Popup), args.User);
}
+
+ args.Cancel();
}
}
return;
// Check if we have the appropriate drawrate / userate to even open it.
- if (!_cell.HasActivatableCharge(uid, user: args.User, predicted: true) ||
- !_cell.HasDrawCharge(uid, user: args.User, predicted: true))
+ // Don't pass in the user for the popup if silent.
+ if (!_cell.HasActivatableCharge(uid, user: args.Silent ? null : args.User, predicted: true) ||
+ !_cell.HasDrawCharge(uid, user: args.Silent ? null : args.User, predicted: true))
{
args.Cancel();
}
if (component.InHandsOnly)
{
- if (!_hands.IsHolding((args.User, args.Hands), uid, out var hand ))
+ if (!_hands.IsHolding((args.User, args.Hands), uid, out var hand))
return false;
if (component.RequireActiveHand && args.Hands.ActiveHandId != hand)
}
}
- return (args.CanInteract || HasComp<GhostComponent>(args.User) && !component.BlockSpectators) && !RaiseCanOpenEventChecks(args.User, uid);
+ return ((args.CanInteract
+ || HasComp<GhostComponent>(args.User)
+ && !component.BlockSpectators))
+ && RaiseCanOpenEventChecks(args.User, uid, silent: true); // silent to prevent popups or sounds when only looking at the verb
}
private void OnUseInHand(EntityUid uid, ActivatableUIComponent component, UseInHandEvent args)
// If we've gotten this far, fire a cancellable event that indicates someone is about to activate this.
// This is so that stuff can require further conditions (like power).
- if (RaiseCanOpenEventChecks(user, uiEntity))
+ if (!RaiseCanOpenEventChecks(user, uiEntity))
return false;
// Give the UI an opportunity to prepare itself if it needs to do anything
_uiSystem.OpenUi(uiEntity, aui.Key, user);
//Let the component know a user opened it so it can do whatever it needs to do
- var aae = new AfterActivatableUIOpenEvent(user, user);
+ var aae = new AfterActivatableUIOpenEvent(user);
RaiseLocalEvent(uiEntity, aae);
return true;
CloseAll(ent, ent);
}
- private bool RaiseCanOpenEventChecks(EntityUid user, EntityUid uiEntity)
+ private bool RaiseCanOpenEventChecks(EntityUid user, EntityUid uiEntity, bool silent = false)
{
- // If we've gotten this far, fire a cancellable event that indicates someone is about to activate this.
+ // If we've gotten this far, fire a cancellable event that indicates someone is attempting to activate this UI.
// This is so that stuff can require further conditions (like power).
- var oae = new ActivatableUIOpenAttemptEvent(user);
- var uae = new UserOpenActivatableUIAttemptEvent(user, uiEntity);
+ var uae = new UserOpenActivatableUIAttemptEvent(user, uiEntity, silent);
RaiseLocalEvent(user, uae);
+
+ if (uae.Cancelled)
+ return false;
+
+ var oae = new ActivatableUIOpenAttemptEvent(user, silent);
RaiseLocalEvent(uiEntity, oae);
- return oae.Cancelled || uae.Cancelled;
+
+ if (oae.Cancelled)
+ return false;
+
+ return true;
}
}