diff --git a/Content.Server/Instruments/SwappableInstrumentComponent.cs b/Content.Server/Instruments/SwappableInstrumentComponent.cs new file mode 100644 index 0000000000..bfe8b5c3a6 --- /dev/null +++ b/Content.Server/Instruments/SwappableInstrumentComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Server.Instruments; + +[RegisterComponent] +public sealed class SwappableInstrumentComponent : Component +{ + /// + /// Used to store the different instruments that can be swapped between. + /// string = display name of the instrument + /// byte 1 = instrument midi program + /// byte 2 = instrument midi bank + /// + [DataField("instrumentList", required: true)] + public Dictionary InstrumentList = new(); +} diff --git a/Content.Server/Instruments/SwappableInstrumentSystem.cs b/Content.Server/Instruments/SwappableInstrumentSystem.cs new file mode 100644 index 0000000000..1f64a0c7c7 --- /dev/null +++ b/Content.Server/Instruments/SwappableInstrumentSystem.cs @@ -0,0 +1,51 @@ +using Content.Shared.Instruments; +using Content.Shared.Popups; +using Content.Shared.Verbs; +using Robust.Shared.Player; + +namespace Content.Server.Instruments; + +public sealed class SwappableInstrumentSystem : EntitySystem +{ + [Dependency] private readonly SharedInstrumentSystem _sharedInstrument = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(AddStyleVerb); + } + + private void AddStyleVerb(EntityUid uid, SwappableInstrumentComponent component, GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess || component.InstrumentList.Count <= 1) + return; + + if (!TryComp(uid, out var instrument)) + return; + + if (instrument.Playing) //no changing while playing + return; + + var priority = 0; + foreach (var entry in component.InstrumentList) + { + AlternativeVerb selection = new() + { + Text = entry.Key, + Category = VerbCategory.InstrumentStyle, + Priority = priority, + Act = () => + { + _sharedInstrument.SetInstrumentProgram(instrument, entry.Value.Item1, entry.Value.Item2); + _popup.PopupEntity(Loc.GetString("swappable-instrument-component-style-set", ("style", entry.Key)), + args.User, Filter.Entities(args.User)); + } + }; + + priority--; + args.Verbs.Add(selection); + } + } +} diff --git a/Content.Shared/Instruments/SharedInstrumentSystem.cs b/Content.Shared/Instruments/SharedInstrumentSystem.cs index f356b722b4..767738f175 100644 --- a/Content.Shared/Instruments/SharedInstrumentSystem.cs +++ b/Content.Shared/Instruments/SharedInstrumentSystem.cs @@ -18,6 +18,12 @@ public abstract class SharedInstrumentSystem : EntitySystem public virtual void EndRenderer(EntityUid uid, bool fromStateChange, SharedInstrumentComponent? instrument = null) { } + public void SetInstrumentProgram(SharedInstrumentComponent component, byte program, byte bank) + { + component.InstrumentProgram = program; + component.InstrumentBank = bank; + } + private void OnGetState(EntityUid uid, SharedInstrumentComponent instrument, ref ComponentGetState args) { args.State = diff --git a/Content.Shared/Verbs/VerbCategory.cs b/Content.Shared/Verbs/VerbCategory.cs index 66b0e39055..53a05cacc5 100644 --- a/Content.Shared/Verbs/VerbCategory.cs +++ b/Content.Shared/Verbs/VerbCategory.cs @@ -68,6 +68,9 @@ namespace Content.Shared.Verbs public static readonly VerbCategory Split = new("verb-categories-split", null); + public static readonly VerbCategory InstrumentStyle = + new("verb-categories-instrument-style", null); + public static readonly VerbCategory SetSensor = new("verb-categories-set-sensor", null); } } diff --git a/Resources/Locale/en-US/instruments/instruments-component.ftl b/Resources/Locale/en-US/instruments/instruments-component.ftl index db412a9342..cbbe835140 100644 --- a/Resources/Locale/en-US/instruments/instruments-component.ftl +++ b/Resources/Locale/en-US/instruments/instruments-component.ftl @@ -8,3 +8,6 @@ instruments-component-menu-no-midi-support = MIDI support is currently not FluidSynth or a development package for FluidSynth. +# SwappableInstrumentComponent +swappable-instrument-component-style-set = Style set to "{$style}" + diff --git a/Resources/Locale/en-US/verbs/verb-system.ftl b/Resources/Locale/en-US/verbs/verb-system.ftl index c4fdaed060..27d4da4985 100644 --- a/Resources/Locale/en-US/verbs/verb-system.ftl +++ b/Resources/Locale/en-US/verbs/verb-system.ftl @@ -20,6 +20,7 @@ verb-categories-rotate = Rotate verb-categories-smite = Smite verb-categories-transfer = Set Transfer Amount verb-categories-split = Split +verb-categories-instrument-style = Instrument Style verb-categories-set-sensor = Sensor verb-categories-timer = Set Delay diff --git a/Resources/Prototypes/Entities/Objects/Fun/instruments.yml b/Resources/Prototypes/Entities/Objects/Fun/instruments.yml index 957ea64dba..7dd8b43082 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/instruments.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/instruments.yml @@ -26,6 +26,10 @@ components: - type: Instrument program: 62 + - type: SwappableInstrument + instrumentList: + "Electro": {62: 0} #i needed generic sounding synth presets, sue me + "Bubbles": {63: 0} - type: Sprite sprite: Objects/Fun/Instruments/h_synthesizer.rsi state: icon @@ -43,7 +47,11 @@ description: Anyway, here's Wonderwall. components: - type: Instrument - program: 25 + program: 24 + - type: SwappableInstrument + instrumentList: + "Nylon": {24: 0} + "Steel": {25: 0} - type: Sprite sprite: Objects/Fun/Instruments/guitar.rsi state: icon @@ -82,6 +90,10 @@ components: - type: Instrument program: 56 + - type: SwappableInstrument + instrumentList: + "Standard": {56: 0} + "Muted": {59: 0} - type: Sprite sprite: Objects/Fun/Instruments/trumpet.rsi state: icon @@ -117,6 +129,11 @@ components: - type: Instrument program: 27 + - type: SwappableInstrument + instrumentList: + "Clean": {27: 0} + "Jazz": {25: 0} + "Muted": {28: 0} - type: Sprite sprite: Objects/Fun/Instruments/eguitar.rsi state: icon @@ -134,6 +151,10 @@ components: - type: Instrument program: 21 + - type: SwappableInstrument + instrumentList: + "Standard": {21: 0} + "Tango": {23: 0} - type: Sprite sprite: Objects/Fun/Instruments/accordion.rsi state: icon @@ -240,7 +261,13 @@ description: An instrument. You could probably grind this into raw jazz. components: - type: Instrument - program: 67 + program: 66 + - type: SwappableInstrument + instrumentList: + "Soprano": {64: 0} + "Alto": {65: 0} + "Tenor": {66: 0} + "Baritone": {67: 0} - type: Sprite sprite: Objects/Fun/Instruments/saxophone.rsi state: icon