diff --git a/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs b/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs
index 29511ceb4d..80fc60360c 100644
--- a/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs
+++ b/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Content.Shared.GameObjects.Components.Instruments;
+using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Client.Audio.Midi;
using Robust.Shared.Audio.Midi;
@@ -28,6 +29,7 @@ namespace Content.Client.GameObjects.Components.Instruments
[Dependency] private readonly IGameTiming _timing;
#pragma warning restore 649
+ [CanBeNull]
private IMidiRenderer _renderer;
private int _instrumentProgram = 1;
@@ -42,8 +44,14 @@ namespace Content.Client.GameObjects.Components.Instruments
[ViewVariables(VVAccess.ReadWrite)]
public bool LoopMidi
{
- get => _renderer.LoopMidi;
- set => _renderer.LoopMidi = value;
+ get => _renderer?.LoopMidi ?? false;
+ set
+ {
+ if (_renderer != null)
+ {
+ _renderer.LoopMidi = value;
+ }
+ }
}
///
@@ -53,9 +61,13 @@ namespace Content.Client.GameObjects.Components.Instruments
public int InstrumentProgram
{
get => _instrumentProgram;
- set {
+ set
+ {
_instrumentProgram = value;
- _renderer.MidiProgram = _instrumentProgram;
+ if (_renderer != null)
+ {
+ _renderer.MidiProgram = _instrumentProgram;
+ }
}
}
@@ -63,22 +75,26 @@ namespace Content.Client.GameObjects.Components.Instruments
/// Whether there's a midi song being played or not.
///
[ViewVariables]
- public bool IsMidiOpen => _renderer.Status == MidiRendererStatus.File;
+ public bool IsMidiOpen => _renderer?.Status == MidiRendererStatus.File;
///
/// Whether the midi renderer is listening for midi input or not.
///
[ViewVariables]
- public bool IsInputOpen => _renderer.Status == MidiRendererStatus.Input;
+ public bool IsInputOpen => _renderer?.Status == MidiRendererStatus.Input;
public override void Initialize()
{
base.Initialize();
IoCManager.InjectDependencies(this);
_renderer = _midiManager.GetNewRenderer();
- _renderer.MidiProgram = _instrumentProgram;
- _renderer.TrackingEntity = Owner;
- _renderer.OnMidiPlayerFinished += () => { OnMidiPlaybackEnded?.Invoke(); };
+
+ if (_renderer != null)
+ {
+ _renderer.MidiProgram = _instrumentProgram;
+ _renderer.TrackingEntity = Owner;
+ _renderer.OnMidiPlayerFinished += () => { OnMidiPlaybackEnded?.Invoke(); };
+ }
}
protected override void Shutdown()
@@ -93,9 +109,16 @@ namespace Content.Client.GameObjects.Components.Instruments
serializer.DataField(ref _instrumentProgram, "program", 1);
}
- public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
+ public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
+ IComponent component = null)
{
base.HandleMessage(message, netChannel, component);
+
+ if (_renderer == null)
+ {
+ return;
+ }
+
switch (message)
{
case InstrumentMidiEventMessage midiEventMessage:
@@ -107,8 +130,8 @@ namespace Content.Client.GameObjects.Components.Instruments
case InstrumentStopMidiMessage _:
_renderer.StopAllNotes();
- if(IsInputOpen) CloseInput();
- if(IsMidiOpen) CloseMidi();
+ if (IsInputOpen) CloseInput();
+ if (IsMidiOpen) CloseMidi();
break;
}
}
@@ -116,7 +139,7 @@ namespace Content.Client.GameObjects.Components.Instruments
///
public bool OpenInput()
{
- if (_renderer.OpenInput())
+ if (_renderer != null && _renderer.OpenInput())
{
_renderer.OnMidiEvent += RendererOnMidiEvent;
return true;
@@ -128,28 +151,37 @@ namespace Content.Client.GameObjects.Components.Instruments
///
public bool CloseInput()
{
- if (!_renderer.CloseInput()) return false;
+ if (_renderer == null || !_renderer.CloseInput())
+ {
+ return false;
+ }
+
_renderer.OnMidiEvent -= RendererOnMidiEvent;
return true;
-
}
///
public bool OpenMidi(string filename)
{
- if (!_renderer.OpenMidi(filename)) return false;
+ if (_renderer == null || !_renderer.OpenMidi(filename))
+ {
+ return false;
+ }
+
_renderer.OnMidiEvent += RendererOnMidiEvent;
return true;
-
}
///
public bool CloseMidi()
{
- if (!_renderer.CloseMidi()) return false;
+ if (_renderer == null || !_renderer.CloseMidi())
+ {
+ return false;
+ }
+
_renderer.OnMidiEvent -= RendererOnMidiEvent;
return true;
-
}
///
diff --git a/Content.Client/Instruments/InstrumentMenu.cs b/Content.Client/Instruments/InstrumentMenu.cs
index b0880fbb48..0fb39bde2e 100644
--- a/Content.Client/Instruments/InstrumentMenu.cs
+++ b/Content.Client/Instruments/InstrumentMenu.cs
@@ -1,10 +1,13 @@
using Content.Client.GameObjects.Components.Instruments;
+using Content.Client.UserInterface;
using Robust.Client.Audio.Midi;
+using Robust.Client.Graphics.Drawing;
using Robust.Client.Interfaces.UserInterface;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.IoC;
+using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Maths;
@@ -27,7 +30,7 @@ namespace Content.Client.Instruments
public InstrumentMenu(InstrumentBoundUserInterface owner)
{
IoCManager.InjectDependencies(this);
- Title = "Instrument";
+ Title = Loc.GetString("Instrument");
_owner = owner;
@@ -55,7 +58,7 @@ namespace Content.Client.Instruments
midiInputButton = new Button()
{
- Text = "MIDI Input",
+ Text = Loc.GetString("MIDI Input"),
TextAlign = Label.AlignMode.Center,
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 1,
@@ -73,7 +76,7 @@ namespace Content.Client.Instruments
var midiFileButton = new Button()
{
- Text = "Open File",
+ Text = Loc.GetString("Play MIDI File"),
TextAlign = Label.AlignMode.Center,
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 1,
@@ -91,7 +94,7 @@ namespace Content.Client.Instruments
midiLoopButton = new Button()
{
- Text = "Loop",
+ Text = Loc.GetString("Loop"),
TextAlign = Label.AlignMode.Center,
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 1,
@@ -110,7 +113,7 @@ namespace Content.Client.Instruments
midiStopButton = new Button()
{
- Text = "Stop",
+ Text = Loc.GetString("Stop"),
TextAlign = Label.AlignMode.Center,
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 1,
@@ -132,6 +135,26 @@ namespace Content.Client.Instruments
margin.AddChild(vBox);
+ if (!_midiManager.IsAvailable)
+ {
+ margin.AddChild(new PanelContainer
+ {
+ MouseFilter = MouseFilterMode.Stop,
+ PanelOverride = new StyleBoxFlat {BackgroundColor = Color.Black.WithAlpha(0.90f)},
+ Children =
+ {
+ new Label
+ {
+ Align = Label.AlignMode.Center,
+ SizeFlagsVertical = SizeFlags.ShrinkCenter,
+ SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
+ StyleClasses = {NanoStyle.StyleClassLabelBig},
+ Text = Loc.GetString("MIDI support is currently\nnot available on your platform.")
+ }
+ }
+ });
+ }
+
Contents.AddChild(margin);
}
@@ -148,7 +171,8 @@ namespace Content.Client.Instruments
private async void MidiFileButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
{
- var filename = await _fileDialogManager.OpenFile();
+ var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi"));
+ var filename = await _fileDialogManager.OpenFile(filters);
if (filename == null) return;
@@ -160,7 +184,7 @@ namespace Content.Client.Instruments
if (!_owner.Instrument.OpenMidi(filename)) return;
MidiPlaybackSetButtonsDisabled(false);
- if(midiInputButton.Pressed)
+ if (midiInputButton.Pressed)
midiInputButton.Pressed = false;
}
diff --git a/Resources/Prototypes/Entities/buildings/instruments.yml b/Resources/Prototypes/Entities/buildings/instruments.yml
index ce8cc881b9..2c6edf0355 100644
--- a/Resources/Prototypes/Entities/buildings/instruments.yml
+++ b/Resources/Prototypes/Entities/buildings/instruments.yml
@@ -1,70 +1,70 @@
-# - type: entity
-# name: BaseInstrument
-# id: BaseInstrument
-# abstract: true
-# components:
-# - type: Instrument
-# handheld: false
-#
-# - type: Clickable
-# - type: InteractionOutline
-#
-# - type: Collidable
-# shapes:
-# - !type:PhysShapeAabb
-# layer: 31
-#
-# - type: SnapGrid
-# offset: Center
-#
-# - type: Damageable
-# - type: Destructible
-# thresholdvalue: 50
-#
-# - type: UserInterface
-# interfaces:
-# - key: enum.InstrumentUiKey.Key
-# type: InstrumentBoundUserInterface
-#
-# - type: entity
-# name: Piano
-# parent: BaseInstrument
-# id: PianoInstrument
-# description: Play Needles Piano Now.
-# components:
-# - type: Instrument
-# program: 1
-# - type: Sprite
-# sprite: Objects/Instruments/musician.rsi
-# state: piano
-# - type: Icon
-# sprite: Objects/Instruments/musician.rsi
-# state: piano
-#
-# - type: entity
-# name: Minimoog
-# parent: BaseInstrument
-# id: MinimoogInstrument
-# components:
-# - type: Instrument
-# program: 7
-# - type: Sprite
-# sprite: Objects/Instruments/musician.rsi
-# state: minimoog
-# - type: Icon
-# sprite: Objects/Instruments/musician.rsi
-# state: minimoog
-#
-# - type: entity
-# name: Xylophone
-# parent: BaseInstrument
-# id: XylophoneInstrument
-# components:
-# - type: Instrument
-# program: 13
-# - type: Sprite
-# sprite: Objects/Instruments/musician.rsi
-# state: xylophone
-# - type: Icon
-# sprite: Objects/Instruments/musician.rsi
-# state: xylophone
+ - type: entity
+ name: BaseInstrument
+ id: BaseInstrument
+ abstract: true
+ components:
+ - type: Instrument
+ handheld: false
+
+ - type: Clickable
+ - type: InteractionOutline
+
+ - type: Collidable
+ shapes:
+ - !type:PhysShapeAabb
+ layer: 31
+
+ - type: SnapGrid
+ offset: Center
+
+ - type: Damageable
+ - type: Destructible
+ thresholdvalue: 50
+
+ - type: UserInterface
+ interfaces:
+ - key: enum.InstrumentUiKey.Key
+ type: InstrumentBoundUserInterface
+
+ - type: entity
+ name: Piano
+ parent: BaseInstrument
+ id: PianoInstrument
+ description: Play Needles Piano Now.
+ components:
+ - type: Instrument
+ program: 1
+ - type: Sprite
+ sprite: Objects/Instruments/musician.rsi
+ state: piano
+ - type: Icon
+ sprite: Objects/Instruments/musician.rsi
+ state: piano
+
+ - type: entity
+ name: Minimoog
+ parent: BaseInstrument
+ id: MinimoogInstrument
+ components:
+ - type: Instrument
+ program: 7
+ - type: Sprite
+ sprite: Objects/Instruments/musician.rsi
+ state: minimoog
+ - type: Icon
+ sprite: Objects/Instruments/musician.rsi
+ state: minimoog
+
+ - type: entity
+ name: Xylophone
+ parent: BaseInstrument
+ id: XylophoneInstrument
+ components:
+ - type: Instrument
+ program: 13
+ - type: Sprite
+ sprite: Objects/Instruments/musician.rsi
+ state: xylophone
+ - type: Icon
+ sprite: Objects/Instruments/musician.rsi
+ state: xylophone