Fix looking at verbs causing sounds or popups (#41609)

* fix verb popups

* spelling
This commit is contained in:
slarticodefast
2025-11-28 22:41:44 +01:00
committed by GitHub
parent 73c8ad0183
commit ed7c004de2
14 changed files with 115 additions and 76 deletions

View File

@@ -18,7 +18,9 @@ public sealed class ActivatableUIRequiresPowerSystem : SharedActivatableUIRequir
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();
}
}

View File

@@ -52,12 +52,12 @@ public sealed class BlockGameArcadeSystem : EntitySystem
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)

View File

@@ -54,11 +54,13 @@ public sealed class SpaceHeaterSystem : EntitySystem
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)

View File

@@ -839,11 +839,5 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
UpdateListUiState(conf, conf.Comp);
}
private void OnUiOpenAttempt(EntityUid uid, NetworkConfiguratorComponent configurator, ActivatableUIOpenAttemptEvent args)
{
if (configurator.LinkModeActive)
args.Cancel();
}
#endregion
}

View File

@@ -44,8 +44,11 @@ public sealed class WarDeclaratorSystem : EntitySystem
{
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;
}

View File

@@ -81,7 +81,9 @@ public sealed partial class StoreSystem : EntitySystem
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();
}

View File

@@ -23,7 +23,7 @@ public sealed class ActivatableUIRequiresAccessSystem : EntitySystem
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);
}
}

View File

@@ -24,7 +24,8 @@ public sealed class ActivatableUIRequiresVisionSystem : EntitySystem
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();
}
}

View File

@@ -477,6 +477,10 @@ public sealed class LockSystem : EntitySystem
return;
args.Cancel();
if (args.Silent)
return;
if (lockComp.Locked && component.Popup != null)
{
_sharedPopupSystem.PopupClient(Loc.GetString(component.Popup), uid, args.User);

View File

@@ -29,6 +29,8 @@ public abstract class SharedEmergencyShuttleSystem : EntitySystem
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);
}
}

View File

@@ -1,53 +1,70 @@
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;
public sealed class UserOpenActivatableUIAttemptEvent : 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;
}
}
public sealed class AfterActivatableUIOpenEvent : EntityEventArgs
{
public EntityUid User { get; }
public readonly EntityUid Actor;
public AfterActivatableUIOpenEvent(EntityUid who, EntityUid actor)
{
User = who;
Actor = actor;
}
/// <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;
}
/// <summary>
/// This is 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
/// 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 BeforeActivatableUIOpenEvent : EntityEventArgs
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 BeforeActivatableUIOpenEvent(EntityUid who)
{
User = who;
}
/// <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;
}
/// <summary>
/// Raised on the entity with an activatable UI after the UI has been opened.
/// </summary>
public sealed class AfterActivatableUIOpenEvent(EntityUid user) : EntityEventArgs
{
/// <summary>
/// The player that opened the UI.
/// </summary>
public readonly EntityUid User = user;
}
/// <summary>
/// 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.
/// </summary>
public sealed class BeforeActivatableUIOpenEvent(EntityUid user) : EntityEventArgs
{
/// <summary>
/// The player that is opening the UI.
/// </summary>
public readonly EntityUid User = user;
}
public sealed class ActivatableUIPlayerChangedEvent : EntityEventArgs

View File

@@ -32,14 +32,14 @@ public sealed class ActivatableUIRequiresAnchorSystem : EntitySystem
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();
}
}

View File

@@ -74,8 +74,9 @@ public sealed partial class ActivatableUISystem
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();
}

View File

@@ -108,7 +108,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
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)
@@ -116,7 +116,10 @@ public sealed partial class ActivatableUISystem : EntitySystem
}
}
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)
@@ -225,7 +228,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
// 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
@@ -237,7 +240,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
_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;
@@ -283,14 +286,22 @@ public sealed partial class ActivatableUISystem : EntitySystem
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;
}
}