diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index f2be7be225..a31f23573a 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -28,6 +28,7 @@ namespace Content.Client.Actions [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IResourceManager _resources = default!; [Dependency] private readonly ISerializationManager _serialization = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; @@ -50,6 +51,15 @@ namespace Content.Client.Actions SubscribeLocalEvent(HandleComponentState); } + public override void Dirty(ActionType action) + { + if (_playerManager.LocalPlayer?.ControlledEntity != action.AttachedEntity) + return; + + base.Dirty(action); + ActionsUpdated?.Invoke(); + } + private void HandleComponentState(EntityUid uid, ActionsComponent component, ref ComponentHandleState args) { if (args.Current is not ActionsComponentState state) @@ -119,31 +129,36 @@ namespace Content.Client.Actions public override void AddAction(EntityUid uid, ActionType action, EntityUid? provider, ActionsComponent? comp = null, bool dirty = true) { + if (uid != _playerManager.LocalPlayer?.ControlledEntity) + return; + + if (GameTiming.ApplyingState && !action.ClientExclusive) + return; + if (!Resolve(uid, ref comp, false)) return; + dirty &= !action.ClientExclusive; base.AddAction(uid, action, provider, comp, dirty); - - if (uid == _playerManager.LocalPlayer?.ControlledEntity) - ActionAdded?.Invoke(action); + ActionAdded?.Invoke(action); } - public override void RemoveActions(EntityUid uid, IEnumerable actions, ActionsComponent? comp = null, bool dirty = true) + public override void RemoveAction(EntityUid uid, ActionType action, ActionsComponent? comp = null, bool dirty = true) { if (uid != _playerManager.LocalPlayer?.ControlledEntity) return; + if (GameTiming.ApplyingState && !action.ClientExclusive) + return; + if (!Resolve(uid, ref comp, false)) return; - var actionList = actions.ToList(); - base.RemoveActions(uid, actionList, comp, dirty); + dirty &= !action.ClientExclusive; + base.RemoveAction(uid, action, comp, dirty); - foreach (var act in actionList) - { - if (act.AutoRemove) - ActionRemoved?.Invoke(act); - } + if (action.AutoRemove) + ActionRemoved?.Invoke(action); } /// @@ -175,9 +190,7 @@ namespace Content.Client.Actions _popupSystem.PopupEntity(msg, user); } - if (action.Sound != null) - SoundSystem.Play(action.Sound.GetSound(), Filter.Local(), user, action.AudioParams); - + _audio.Play(action.Sound, Filter.Local(), user, false); return performedAction; } diff --git a/Content.Shared/Actions/ActionTypes/ActionType.cs b/Content.Shared/Actions/ActionTypes/ActionType.cs index 5681be17aa..566c02d12f 100644 --- a/Content.Shared/Actions/ActionTypes/ActionType.cs +++ b/Content.Shared/Actions/ActionTypes/ActionType.cs @@ -148,6 +148,8 @@ public abstract class ActionType : IEquatable, IComparable, ICloneab /// [DataField("temporary")] public bool Temporary; + // TODO re-add support for this + // UI refactor seems to have just broken it. /// /// Determines the appearance of the entity-icon for actions that are enabled via some entity. @@ -168,9 +170,6 @@ public abstract class ActionType : IEquatable, IComparable, ICloneab [DataField("sound")] public SoundSpecifier? Sound; - [DataField("audioParams")] - public AudioParams? AudioParams; - /// /// A pop-up to show the user when performing this action. Gets passed through localization. /// @@ -260,7 +259,6 @@ public abstract class ActionType : IEquatable, IComparable, ICloneab Speech = toClone.Speech; UseDelay = toClone.UseDelay; Sound = toClone.Sound; - AudioParams = toClone.AudioParams; UserPopup = toClone.UserPopup; Popup = toClone.Popup; PopupToggleSuffix = toClone.PopupToggleSuffix; diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index c94d914b97..558b878536 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -323,7 +323,7 @@ public abstract class SharedActionsSystem : EntitySystem var filter = predicted ? Filter.PvsExcept(performer) : Filter.Pvs(performer); - _audio.Play(action.Sound, filter, performer, true, action.AudioParams); + _audio.Play(action.Sound, filter, performer, true); if (string.IsNullOrWhiteSpace(action.Popup)) return true; @@ -356,12 +356,10 @@ public abstract class SharedActionsSystem : EntitySystem comp ??= EnsureComp(uid); action.Provider = provider; - action.AttachedEntity = comp.Owner; + action.AttachedEntity = uid; AddActionInternal(comp, action); - // for client-exclusive actions, the client shouldn't mark the comp as dirty. Otherwise that just leads to - // unnecessary prediction resetting and state handling. - if (dirty && !action.ClientExclusive) + if (dirty) Dirty(comp); } @@ -400,29 +398,26 @@ public abstract class SharedActionsSystem : EntitySystem if (!Resolve(uid, ref comp, false)) return; - var provided = comp.Actions.Where(act => act.Provider == provider).ToList(); - - if (provided.Count > 0) - RemoveActions(uid, provided, comp); + foreach (var act in comp.Actions.ToArray()) + { + if (act.Provider == provider) + RemoveAction(uid, act, comp, dirty: false); + } + Dirty(comp); } - public virtual void RemoveActions(EntityUid uid, IEnumerable actions, ActionsComponent? comp = null, bool dirty = true) + public virtual void RemoveAction(EntityUid uid, ActionType action, ActionsComponent? comp = null, bool dirty = true) { if (!Resolve(uid, ref comp, false)) return; - foreach (var action in actions) - { - comp.Actions.Remove(action); - action.AttachedEntity = null; - } + comp.Actions.Remove(action); + action.AttachedEntity = null; if (dirty) Dirty(comp); } - public void RemoveAction(EntityUid uid, ActionType action, ActionsComponent? comp = null) - => RemoveActions(uid, new[] { action }, comp); #endregion #region EquipHandlers