diff --git a/Content.Client/Instruments/InstrumentComponent.cs b/Content.Client/Instruments/InstrumentComponent.cs index 74218f802f..068dc26ac5 100644 --- a/Content.Client/Instruments/InstrumentComponent.cs +++ b/Content.Client/Instruments/InstrumentComponent.cs @@ -4,7 +4,7 @@ using Robust.Shared.Audio.Midi; namespace Content.Client.Instruments; -[RegisterComponent, ComponentReference(typeof(SharedInstrumentComponent))] +[RegisterComponent] public sealed partial class InstrumentComponent : SharedInstrumentComponent { public event Action? OnMidiPlaybackEnded; diff --git a/Content.Client/Instruments/InstrumentSystem.cs b/Content.Client/Instruments/InstrumentSystem.cs index 0b969b6efd..e89df99fd6 100644 --- a/Content.Client/Instruments/InstrumentSystem.cs +++ b/Content.Client/Instruments/InstrumentSystem.cs @@ -6,12 +6,12 @@ using JetBrains.Annotations; using Robust.Client.Audio.Midi; using Robust.Shared.Audio.Midi; using Robust.Shared.Configuration; +using Robust.Shared.GameStates; using Robust.Shared.Network; using Robust.Shared.Timing; namespace Content.Client.Instruments; -[UsedImplicitly] public sealed class InstrumentSystem : SharedInstrumentSystem { [Dependency] private readonly IClientNetManager _netManager = default!; @@ -37,6 +37,27 @@ public sealed class InstrumentSystem : SharedInstrumentSystem SubscribeNetworkEvent(OnMidiStop); SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnHandleState); + } + + private void OnHandleState(EntityUid uid, SharedInstrumentComponent component, ref ComponentHandleState args) + { + if (args.Current is not InstrumentComponentState state) + return; + + component.Playing = state.Playing; + component.InstrumentProgram = state.InstrumentProgram; + component.InstrumentBank = state.InstrumentBank; + component.AllowPercussion = state.AllowPercussion; + component.AllowProgramChange = state.AllowProgramChange; + component.RespectMidiLimits = state.RespectMidiLimits; + component.Master = EnsureEntity(state.Master, uid); + component.FilteredChannels = state.FilteredChannels; + + if (component.Playing) + SetupRenderer(uid, true, component); + else + EndRenderer(uid, true, component); } public override void Shutdown() @@ -71,9 +92,19 @@ public sealed class InstrumentSystem : SharedInstrumentSystem RaiseNetworkEvent(new InstrumentSetFilteredChannelEvent(GetNetEntity(uid), channel, value)); } + public override bool ResolveInstrument(EntityUid uid, ref SharedInstrumentComponent? component) + { + if (component is not null) + return true; + + TryComp(uid, out var localComp); + component = localComp; + return component != null; + } + public override void SetupRenderer(EntityUid uid, bool fromStateChange, SharedInstrumentComponent? component = null) { - if (!Resolve(uid, ref component)) + if (!ResolveInstrument(uid, ref component)) return; if (component is not InstrumentComponent instrument) @@ -156,7 +187,7 @@ public sealed class InstrumentSystem : SharedInstrumentSystem public override void EndRenderer(EntityUid uid, bool fromStateChange, SharedInstrumentComponent? component = null) { - if (!Resolve(uid, ref component, false)) + if (!ResolveInstrument(uid, ref component)) return; if (component is not InstrumentComponent instrument) diff --git a/Content.Server/Instruments/InstrumentComponent.cs b/Content.Server/Instruments/InstrumentComponent.cs index 51de0ed35b..5a6b5828da 100644 --- a/Content.Server/Instruments/InstrumentComponent.cs +++ b/Content.Server/Instruments/InstrumentComponent.cs @@ -5,7 +5,7 @@ using Robust.Server.Player; namespace Content.Server.Instruments; -[RegisterComponent, ComponentReference(typeof(SharedInstrumentComponent))] +[RegisterComponent] public sealed partial class InstrumentComponent : SharedInstrumentComponent { [Dependency] private readonly IEntityManager _entMan = default!; diff --git a/Content.Server/Instruments/InstrumentSystem.cs b/Content.Server/Instruments/InstrumentSystem.cs index 7094706950..4e002eb677 100644 --- a/Content.Server/Instruments/InstrumentSystem.cs +++ b/Content.Server/Instruments/InstrumentSystem.cs @@ -15,6 +15,7 @@ using Robust.Shared.Audio.Midi; using Robust.Shared.Collections; using Robust.Shared.Configuration; using Robust.Shared.Console; +using Robust.Shared.GameStates; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -55,9 +56,26 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem SubscribeLocalEvent(OnBoundUIOpened); SubscribeLocalEvent(OnBoundUIRequestBands); + SubscribeLocalEvent(OnStrumentGetState); + _conHost.RegisterCommand("addtoband", AddToBandCommand); } + private void OnStrumentGetState(EntityUid uid, InstrumentComponent component, ref ComponentGetState args) + { + args.State = new InstrumentComponentState() + { + Playing = component.Playing, + InstrumentProgram = component.InstrumentProgram, + InstrumentBank = component.InstrumentBank, + AllowPercussion = component.AllowPercussion, + AllowProgramChange = component.AllowProgramChange, + RespectMidiLimits = component.RespectMidiLimits, + Master = GetNetEntity(component.Master), + FilteredChannels = component.FilteredChannels + }; + } + [AdminCommand(AdminFlags.Fun)] private void AddToBandCommand(IConsoleShell shell, string _, string[] args) { @@ -441,4 +459,14 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem if (_bui.TryGetUi(uid, InstrumentUiKey.Key, out var bui)) _bui.ToggleUi(bui, session); } + + public override bool ResolveInstrument(EntityUid uid, ref SharedInstrumentComponent? component) + { + if (component is not null) + return true; + + TryComp(uid, out var localComp); + component = localComp; + return component != null; + } } diff --git a/Content.Server/Instruments/SwappableInstrumentSystem.cs b/Content.Server/Instruments/SwappableInstrumentSystem.cs index 465cdb7fdf..3f3cfb9e6d 100644 --- a/Content.Server/Instruments/SwappableInstrumentSystem.cs +++ b/Content.Server/Instruments/SwappableInstrumentSystem.cs @@ -22,7 +22,7 @@ public sealed class SwappableInstrumentSystem : EntitySystem if (!args.CanInteract || !args.CanAccess || component.InstrumentList.Count <= 1) return; - if (!TryComp(uid, out var instrument)) + if (!TryComp(uid, out var instrument)) return; var priority = 0; diff --git a/Content.Shared/Instruments/SharedInstrumentComponent.cs b/Content.Shared/Instruments/SharedInstrumentComponent.cs index cdd85b90ac..73500f3869 100644 --- a/Content.Shared/Instruments/SharedInstrumentComponent.cs +++ b/Content.Shared/Instruments/SharedInstrumentComponent.cs @@ -6,35 +6,54 @@ using Robust.Shared.Serialization; namespace Content.Shared.Instruments; [NetworkedComponent] -[AutoGenerateComponentState(true)] [Access(typeof(SharedInstrumentSystem))] public abstract partial class SharedInstrumentComponent : Component { - [ViewVariables, AutoNetworkedField] + [ViewVariables] public bool Playing { get; set; } - [DataField("program"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField("program"), ViewVariables(VVAccess.ReadWrite)] public byte InstrumentProgram { get; set; } - [DataField("bank"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField("bank"), ViewVariables(VVAccess.ReadWrite)] public byte InstrumentBank { get; set; } - [DataField("allowPercussion"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField("allowPercussion"), ViewVariables(VVAccess.ReadWrite)] public bool AllowPercussion { get; set; } - [DataField("allowProgramChange"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField("allowProgramChange"), ViewVariables(VVAccess.ReadWrite)] public bool AllowProgramChange { get ; set; } - [DataField("respectMidiLimits"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField("respectMidiLimits"), ViewVariables(VVAccess.ReadWrite)] public bool RespectMidiLimits { get; set; } = true; - [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] public EntityUid? Master { get; set; } = null; - [ViewVariables, AutoNetworkedField] + [ViewVariables] public BitArray FilteredChannels { get; set; } = new(RobustMidiEvent.MaxChannels, true); } +[Serializable, NetSerializable] +public sealed class InstrumentComponentState : ComponentState +{ + public bool Playing; + + public byte InstrumentProgram; + + public byte InstrumentBank; + + public bool AllowPercussion; + + public bool AllowProgramChange; + + public bool RespectMidiLimits; + + public NetEntity? Master; + + public BitArray FilteredChannels = default!; +} + /// /// This message is sent to the client to completely stop midi input and midi playback. diff --git a/Content.Shared/Instruments/SharedInstrumentSystem.cs b/Content.Shared/Instruments/SharedInstrumentSystem.cs index a2a7425a5b..87e3a69489 100644 --- a/Content.Shared/Instruments/SharedInstrumentSystem.cs +++ b/Content.Shared/Instruments/SharedInstrumentSystem.cs @@ -2,10 +2,7 @@ namespace Content.Shared.Instruments; public abstract class SharedInstrumentSystem : EntitySystem { - public override void Initialize() - { - SubscribeLocalEvent(AfterHandleInstrumentState); - } + public abstract bool ResolveInstrument(EntityUid uid, ref SharedInstrumentComponent? component); public virtual void SetupRenderer(EntityUid uid, bool fromStateChange, SharedInstrumentComponent? instrument = null) { @@ -21,12 +18,4 @@ public abstract class SharedInstrumentSystem : EntitySystem component.InstrumentProgram = program; Dirty(component); } - - private void AfterHandleInstrumentState(EntityUid uid, SharedInstrumentComponent instrument, ref AfterAutoHandleStateEvent args) - { - if(instrument.Playing) - SetupRenderer(uid, true, instrument); - else - EndRenderer(uid, true, instrument); - } }