diff --git a/Content.Server/Actions/Actions/PAIMidi.cs b/Content.Server/Actions/Actions/PAIMidi.cs
new file mode 100644
index 0000000000..717c8a3f42
--- /dev/null
+++ b/Content.Server/Actions/Actions/PAIMidi.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Linq;
+using Content.Server.Ghost;
+using Content.Shared.Actions.Behaviors;
+using Content.Shared.Actions.Components;
+using Content.Shared.Cooldown;
+using JetBrains.Annotations;
+using Robust.Shared.GameObjects;
+using Robust.Shared.IoC;
+using Robust.Shared.Serialization.Manager.Attributes;
+using Robust.Server.GameObjects;
+using Content.Shared.Instruments;
+
+namespace Content.Server.Actions.Actions
+{
+ ///
+ /// Pull up MIDI instrument interface for PAIs to "play themselves"
+ ///
+ [UsedImplicitly]
+ [DataDefinition]
+ public class PAIMidi : IInstantAction
+ {
+
+ public void DoInstantAction(InstantActionEventArgs args)
+ {
+ if (!args.Performer.TryGetComponent(out var serverUi)) return;
+ if (!args.Performer.TryGetComponent(out var actor)) return;
+ if (!serverUi.TryGetBoundUserInterface(InstrumentUiKey.Key,out var bui)) return;
+
+ bui.Toggle(actor.PlayerSession);
+
+ }
+ }
+}
diff --git a/Content.Server/PAI/PAISystem.cs b/Content.Server/PAI/PAISystem.cs
index 190c3c7910..b7429ba162 100644
--- a/Content.Server/PAI/PAISystem.cs
+++ b/Content.Server/PAI/PAISystem.cs
@@ -2,9 +2,12 @@ using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.PAI;
using Content.Shared.Verbs;
+using Content.Shared.Instruments;
using Content.Server.Popups;
+using Content.Server.Instruments;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Mind.Components;
+using Robust.Server.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.GameObjects;
@@ -16,6 +19,7 @@ namespace Content.Server.PAI
public class PAISystem : SharedPAISystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
+ [Dependency] private readonly InstrumentSystem _instrumentSystem = default!;
public override void Initialize()
{
@@ -97,6 +101,15 @@ namespace Content.Server.PAI
private void PAITurningOff(EntityUid uid)
{
UpdatePAIAppearance(uid, PAIStatus.Off);
+ // Close the instrument interface if it was open
+ // before closing
+ if (EntityManager.TryGetComponent(uid, out var serverUi))
+ if (EntityManager.TryGetComponent(uid, out var actor))
+ if (serverUi.TryGetBoundUserInterface(InstrumentUiKey.Key,out var bui))
+ bui.Close(actor.PlayerSession);
+
+ // Stop instrument
+ if (EntityManager.TryGetComponent(uid, out var instrument)) _instrumentSystem.Clean(uid, instrument);
if (EntityManager.TryGetComponent(uid, out var metadata))
{
var proto = metadata.EntityPrototype;
diff --git a/Content.Shared/Actions/ActionType.cs b/Content.Shared/Actions/ActionType.cs
index 109a5c73f1..0cb60f42f0 100644
--- a/Content.Shared/Actions/ActionType.cs
+++ b/Content.Shared/Actions/ActionType.cs
@@ -17,7 +17,8 @@ namespace Content.Shared.Actions
DebugTargetPointRepeat,
DebugTargetEntity,
DebugTargetEntityRepeat,
- SpellPie
+ SpellPie,
+ PAIMidi
}
///
diff --git a/Resources/Audio/MidiCustom/space-station-14.sf2 b/Resources/Audio/MidiCustom/space-station-14.sf2
index a4411188e3..cdcfab1aab 100644
Binary files a/Resources/Audio/MidiCustom/space-station-14.sf2 and b/Resources/Audio/MidiCustom/space-station-14.sf2 differ
diff --git a/Resources/Prototypes/Actions/actions.yml b/Resources/Prototypes/Actions/actions.yml
index 420e81982d..12374551c9 100644
--- a/Resources/Prototypes/Actions/actions.yml
+++ b/Resources/Prototypes/Actions/actions.yml
@@ -66,6 +66,17 @@
cooldown: 120
maxTargets: 3
+- type: action
+ actionType: PAIMidi
+ icon: Interface/Actions/midi.png
+ name: "Play MIDI"
+ description: "Open your portable MIDI interface to soothe your owner."
+ filters:
+ - pai
+ - music
+ behaviorType: Instant
+ behavior: !type:PAIMidi
+
- type: action
actionType: DebugInstant
icon: Interface/Alerts/human_health.rsi/health1.png
@@ -133,3 +144,4 @@
repeat: true
behavior: !type:DebugTargetEntity { }
+
diff --git a/Resources/Prototypes/Entities/Objects/Fun/pai.yml b/Resources/Prototypes/Entities/Objects/Fun/pai.yml
index f1a7d9ff85..195ab7fec6 100644
--- a/Resources/Prototypes/Entities/Objects/Fun/pai.yml
+++ b/Resources/Prototypes/Entities/Objects/Fun/pai.yml
@@ -6,6 +6,15 @@
name: personal ai device
description: Your electronic pal who's fun to be with!
components:
+ - type: Instrument
+ allowPercussion: false
+ handheld: false
+ bank: 1
+ program: 2
+ - type: UserInterface
+ interfaces:
+ - key: enum.InstrumentUiKey.Key
+ type: InstrumentBoundUserInterface
- type: Sprite
netsync: false
sprite: Objects/Devices/pda.rsi
@@ -20,6 +29,8 @@
- type: GhostRadio
- type: DoAfter
- type: Actions
+ innateActions:
+ - PAIMidi
# This has to be installed because otherwise they're not "alive",
# so they can ghost and come back.
# Note that the personal AI never "dies".
diff --git a/Resources/Textures/Interface/Actions/midi.png b/Resources/Textures/Interface/Actions/midi.png
new file mode 100644
index 0000000000..38d89b609e
Binary files /dev/null and b/Resources/Textures/Interface/Actions/midi.png differ