Intercom buffs and fixes (#29580)
* Intercom buffs and fixes * remove unused bui state * mild sec intercom buff * reinforce sec intercoms
23
Content.Client/Radio/EntitySystems/RadioDeviceSystem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Content.Client.Radio.Ui;
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Radio.EntitySystems;
|
||||
|
||||
public sealed class RadioDeviceSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<IntercomComponent, AfterAutoHandleStateEvent>(OnAfterHandleState);
|
||||
}
|
||||
|
||||
private void OnAfterHandleState(Entity<IntercomComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (_ui.TryGetOpenUi<IntercomBoundUserInterface>(ent.Owner, IntercomUiKey.Key, out var bui))
|
||||
bui.Update(ent);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Radio.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Radio.Ui;
|
||||
|
||||
@@ -19,7 +19,9 @@ public sealed class IntercomBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_menu = new();
|
||||
var comp = EntMan.GetComponent<IntercomComponent>(Owner);
|
||||
|
||||
_menu = new((Owner, comp));
|
||||
|
||||
_menu.OnMicPressed += enabled =>
|
||||
{
|
||||
@@ -46,13 +48,8 @@ public sealed class IntercomBoundUserInterface : BoundUserInterface
|
||||
_menu?.Close();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
public void Update(Entity<IntercomComponent> ent)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not IntercomBoundUIState msg)
|
||||
return;
|
||||
|
||||
_menu?.Update(msg);
|
||||
_menu?.Update(ent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Radio.Ui;
|
||||
|
||||
@@ -17,38 +18,54 @@ public sealed partial class IntercomMenu : FancyWindow
|
||||
|
||||
private readonly List<string> _channels = new();
|
||||
|
||||
public IntercomMenu()
|
||||
public IntercomMenu(Entity<IntercomComponent> entity)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
MicButton.OnPressed += args => OnMicPressed?.Invoke(args.Button.Pressed);
|
||||
SpeakerButton.OnPressed += args => OnSpeakerPressed?.Invoke(args.Button.Pressed);
|
||||
|
||||
Update(entity);
|
||||
}
|
||||
|
||||
public void Update(IntercomBoundUIState state)
|
||||
public void Update(Entity<IntercomComponent> entity)
|
||||
{
|
||||
MicButton.Pressed = state.MicEnabled;
|
||||
SpeakerButton.Pressed = state.SpeakerEnabled;
|
||||
MicButton.Pressed = entity.Comp.MicrophoneEnabled;
|
||||
SpeakerButton.Pressed = entity.Comp.SpeakerEnabled;
|
||||
|
||||
MicButton.Disabled = entity.Comp.SupportedChannels.Count == 0;
|
||||
SpeakerButton.Disabled = entity.Comp.SupportedChannels.Count == 0;
|
||||
ChannelOptions.Disabled = entity.Comp.SupportedChannels.Count == 0;
|
||||
|
||||
ChannelOptions.Clear();
|
||||
_channels.Clear();
|
||||
for (var i = 0; i < state.AvailableChannels.Count; i++)
|
||||
for (var i = 0; i < entity.Comp.SupportedChannels.Count; i++)
|
||||
{
|
||||
var channel = state.AvailableChannels[i];
|
||||
if (!_prototype.TryIndex<RadioChannelPrototype>(channel, out var prototype))
|
||||
var channel = entity.Comp.SupportedChannels[i];
|
||||
if (!_prototype.TryIndex(channel, out var prototype))
|
||||
continue;
|
||||
|
||||
_channels.Add(channel);
|
||||
ChannelOptions.AddItem(Loc.GetString(prototype.Name), i);
|
||||
|
||||
if (channel == state.SelectedChannel)
|
||||
if (channel == entity.Comp.CurrentChannel)
|
||||
ChannelOptions.Select(i);
|
||||
}
|
||||
|
||||
if (entity.Comp.SupportedChannels.Count == 0)
|
||||
{
|
||||
ChannelOptions.AddItem(Loc.GetString("intercom-options-none"), 0);
|
||||
ChannelOptions.Select(0);
|
||||
}
|
||||
|
||||
ChannelOptions.OnItemSelected += args =>
|
||||
{
|
||||
if (!_channels.TryGetValue(args.Id, out var proto))
|
||||
return;
|
||||
|
||||
ChannelOptions.SelectId(args.Id);
|
||||
OnChannelSelected?.Invoke(_channels[args.Id]);
|
||||
OnChannelSelected?.Invoke(proto);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Interaction;
|
||||
using Content.Server.Popups;
|
||||
@@ -6,13 +7,10 @@ using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Radio.Components;
|
||||
using Content.Server.Speech;
|
||||
using Content.Server.Speech.Components;
|
||||
using Content.Shared.UserInterface;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Radio.EntitySystems;
|
||||
@@ -28,7 +26,6 @@ public sealed class RadioDeviceSystem : EntitySystem
|
||||
[Dependency] private readonly RadioSystem _radio = default!;
|
||||
[Dependency] private readonly InteractionSystem _interaction = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
|
||||
// Used to prevent a shitter from using a bunch of radios to spam chat.
|
||||
private HashSet<(string, EntityUid)> _recentlySent = new();
|
||||
@@ -47,7 +44,7 @@ public sealed class RadioDeviceSystem : EntitySystem
|
||||
SubscribeLocalEvent<RadioSpeakerComponent, ActivateInWorldEvent>(OnActivateSpeaker);
|
||||
SubscribeLocalEvent<RadioSpeakerComponent, RadioReceiveEvent>(OnReceiveRadio);
|
||||
|
||||
SubscribeLocalEvent<IntercomComponent, BeforeActivatableUIOpenEvent>(OnBeforeIntercomUiOpen);
|
||||
SubscribeLocalEvent<IntercomComponent, EncryptionChannelsChangedEvent>(OnIntercomEncryptionChannelsChanged);
|
||||
SubscribeLocalEvent<IntercomComponent, ToggleIntercomMicMessage>(OnToggleIntercomMic);
|
||||
SubscribeLocalEvent<IntercomComponent, ToggleIntercomSpeakerMessage>(OnToggleIntercomSpeaker);
|
||||
SubscribeLocalEvent<IntercomComponent, SelectIntercomChannelMessage>(OnSelectIntercomChannel);
|
||||
@@ -150,18 +147,18 @@ public sealed class RadioDeviceSystem : EntitySystem
|
||||
SetSpeakerEnabled(uid, user, !component.Enabled, quiet, component);
|
||||
}
|
||||
|
||||
public void SetSpeakerEnabled(EntityUid uid, EntityUid user, bool enabled, bool quiet = false, RadioSpeakerComponent? component = null)
|
||||
public void SetSpeakerEnabled(EntityUid uid, EntityUid? user, bool enabled, bool quiet = false, RadioSpeakerComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
component.Enabled = enabled;
|
||||
|
||||
if (!quiet)
|
||||
if (!quiet && user != null)
|
||||
{
|
||||
var state = Loc.GetString(component.Enabled ? "handheld-radio-component-on-state" : "handheld-radio-component-off-state");
|
||||
var message = Loc.GetString("handheld-radio-component-on-use", ("radioState", state));
|
||||
_popup.PopupEntity(message, user, user);
|
||||
_popup.PopupEntity(message, user.Value, user.Value);
|
||||
}
|
||||
|
||||
_appearance.SetData(uid, RadioDeviceVisuals.Speaker, component.Enabled);
|
||||
@@ -213,61 +210,74 @@ public sealed class RadioDeviceSystem : EntitySystem
|
||||
var nameEv = new TransformSpeakerNameEvent(args.MessageSource, Name(args.MessageSource));
|
||||
RaiseLocalEvent(args.MessageSource, nameEv);
|
||||
|
||||
var name = Loc.GetString("speech-name-relay", ("speaker", Name(uid)),
|
||||
var name = Loc.GetString("speech-name-relay",
|
||||
("speaker", Name(uid)),
|
||||
("originalName", nameEv.Name));
|
||||
|
||||
// log to chat so people can identity the speaker/source, but avoid clogging ghost chat if there are many radios
|
||||
_chat.TrySendInGameICMessage(uid, args.Message, InGameICChatType.Whisper, ChatTransmitRange.GhostRangeLimit, nameOverride: name, checkRadioPrefix: false);
|
||||
}
|
||||
|
||||
private void OnBeforeIntercomUiOpen(EntityUid uid, IntercomComponent component, BeforeActivatableUIOpenEvent args)
|
||||
private void OnIntercomEncryptionChannelsChanged(Entity<IntercomComponent> ent, ref EncryptionChannelsChangedEvent args)
|
||||
{
|
||||
UpdateIntercomUi(uid, component);
|
||||
ent.Comp.SupportedChannels = args.Component.Channels.Select(p => new ProtoId<RadioChannelPrototype>(p)).ToList();
|
||||
|
||||
var channel = args.Component.DefaultChannel;
|
||||
if (ent.Comp.CurrentChannel != null && ent.Comp.SupportedChannels.Contains(ent.Comp.CurrentChannel.Value))
|
||||
channel = ent.Comp.CurrentChannel;
|
||||
|
||||
SetIntercomChannel(ent, channel);
|
||||
}
|
||||
|
||||
private void OnToggleIntercomMic(EntityUid uid, IntercomComponent component, ToggleIntercomMicMessage args)
|
||||
private void OnToggleIntercomMic(Entity<IntercomComponent> ent, ref ToggleIntercomMicMessage args)
|
||||
{
|
||||
if (component.RequiresPower && !this.IsPowered(uid, EntityManager))
|
||||
if (ent.Comp.RequiresPower && !this.IsPowered(ent, EntityManager))
|
||||
return;
|
||||
|
||||
SetMicrophoneEnabled(uid, args.Actor, args.Enabled, true);
|
||||
UpdateIntercomUi(uid, component);
|
||||
SetMicrophoneEnabled(ent, args.Actor, args.Enabled, true);
|
||||
ent.Comp.MicrophoneEnabled = args.Enabled;
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
private void OnToggleIntercomSpeaker(EntityUid uid, IntercomComponent component, ToggleIntercomSpeakerMessage args)
|
||||
private void OnToggleIntercomSpeaker(Entity<IntercomComponent> ent, ref ToggleIntercomSpeakerMessage args)
|
||||
{
|
||||
if (component.RequiresPower && !this.IsPowered(uid, EntityManager))
|
||||
if (ent.Comp.RequiresPower && !this.IsPowered(ent, EntityManager))
|
||||
return;
|
||||
|
||||
SetSpeakerEnabled(uid, args.Actor, args.Enabled, true);
|
||||
UpdateIntercomUi(uid, component);
|
||||
SetSpeakerEnabled(ent, args.Actor, args.Enabled, true);
|
||||
ent.Comp.SpeakerEnabled = args.Enabled;
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
private void OnSelectIntercomChannel(EntityUid uid, IntercomComponent component, SelectIntercomChannelMessage args)
|
||||
private void OnSelectIntercomChannel(Entity<IntercomComponent> ent, ref SelectIntercomChannelMessage args)
|
||||
{
|
||||
if (component.RequiresPower && !this.IsPowered(uid, EntityManager))
|
||||
if (ent.Comp.RequiresPower && !this.IsPowered(ent, EntityManager))
|
||||
return;
|
||||
|
||||
if (!_protoMan.TryIndex<RadioChannelPrototype>(args.Channel, out _) || !component.SupportedChannels.Contains(args.Channel))
|
||||
if (!_protoMan.HasIndex<RadioChannelPrototype>(args.Channel) || !ent.Comp.SupportedChannels.Contains(args.Channel))
|
||||
return;
|
||||
|
||||
if (TryComp<RadioMicrophoneComponent>(uid, out var mic))
|
||||
mic.BroadcastChannel = args.Channel;
|
||||
if (TryComp<RadioSpeakerComponent>(uid, out var speaker))
|
||||
speaker.Channels = new(){ args.Channel };
|
||||
UpdateIntercomUi(uid, component);
|
||||
SetIntercomChannel(ent, args.Channel);
|
||||
}
|
||||
|
||||
private void UpdateIntercomUi(EntityUid uid, IntercomComponent component)
|
||||
private void SetIntercomChannel(Entity<IntercomComponent> ent, ProtoId<RadioChannelPrototype>? channel)
|
||||
{
|
||||
var micComp = CompOrNull<RadioMicrophoneComponent>(uid);
|
||||
var speakerComp = CompOrNull<RadioSpeakerComponent>(uid);
|
||||
ent.Comp.CurrentChannel = channel;
|
||||
|
||||
var micEnabled = micComp?.Enabled ?? false;
|
||||
var speakerEnabled = speakerComp?.Enabled ?? false;
|
||||
var availableChannels = component.SupportedChannels;
|
||||
var selectedChannel = micComp?.BroadcastChannel ?? SharedChatSystem.CommonChannel;
|
||||
var state = new IntercomBoundUIState(micEnabled, speakerEnabled, availableChannels, selectedChannel);
|
||||
_ui.SetUiState(uid, IntercomUiKey.Key, state);
|
||||
if (channel == null)
|
||||
{
|
||||
SetSpeakerEnabled(ent, null, false);
|
||||
SetMicrophoneEnabled(ent, null, false);
|
||||
ent.Comp.MicrophoneEnabled = false;
|
||||
ent.Comp.SpeakerEnabled = false;
|
||||
Dirty(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryComp<RadioMicrophoneComponent>(ent, out var mic))
|
||||
mic.BroadcastChannel = channel;
|
||||
if (TryComp<RadioSpeakerComponent>(ent, out var speaker))
|
||||
speaker.Channels = new(){ channel };
|
||||
Dirty(ent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,15 @@ public sealed class RadioSystem : EntitySystem
|
||||
// set used to prevent radio feedback loops.
|
||||
private readonly HashSet<string> _messages = new();
|
||||
|
||||
private EntityQuery<TelecomExemptComponent> _exemptQuery;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<IntrinsicRadioReceiverComponent, RadioReceiveEvent>(OnIntrinsicReceive);
|
||||
SubscribeLocalEvent<IntrinsicRadioTransmitterComponent, EntitySpokeEvent>(OnIntrinsicSpeak);
|
||||
|
||||
_exemptQuery = GetEntityQuery<TelecomExemptComponent>();
|
||||
}
|
||||
|
||||
private void OnIntrinsicSpeak(EntityUid uid, IntrinsicRadioTransmitterComponent component, EntitySpokeEvent args)
|
||||
@@ -121,9 +125,8 @@ public sealed class RadioSystem : EntitySystem
|
||||
|
||||
var sourceMapId = Transform(radioSource).MapID;
|
||||
var hasActiveServer = HasActiveServer(sourceMapId, channel.ID);
|
||||
var hasMicro = HasComp<RadioMicrophoneComponent>(radioSource);
|
||||
var sourceServerExempt = _exemptQuery.HasComp(radioSource);
|
||||
|
||||
var speakerQuery = GetEntityQuery<RadioSpeakerComponent>();
|
||||
var radioQuery = EntityQueryEnumerator<ActiveRadioComponent, TransformComponent>();
|
||||
while (canSend && radioQuery.MoveNext(out var receiver, out var radio, out var transform))
|
||||
{
|
||||
@@ -138,7 +141,7 @@ public sealed class RadioSystem : EntitySystem
|
||||
continue;
|
||||
|
||||
// don't need telecom server for long range channels or handheld radios and intercoms
|
||||
var needServer = !channel.LongRange && (!hasMicro || !speakerQuery.HasComponent(receiver));
|
||||
var needServer = !channel.LongRange && !sourceServerExempt;
|
||||
if (needServer && !hasActiveServer)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Radio.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Handles intercom ui and is authoritative on the channels an intercom can access.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
|
||||
public sealed partial class IntercomComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Does this intercom require popwer to function
|
||||
/// Does this intercom require power to function
|
||||
/// </summary>
|
||||
[DataField("requiresPower"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public bool RequiresPower = true;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool SpeakerEnabled;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool MicrophoneEnabled;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public ProtoId<RadioChannelPrototype>? CurrentChannel;
|
||||
|
||||
/// <summary>
|
||||
/// The list of radio channel prototypes this intercom can choose between.
|
||||
/// </summary>
|
||||
[DataField("supportedChannels", customTypeSerializer: typeof(PrototypeIdListSerializer<RadioChannelPrototype>))]
|
||||
public List<string> SupportedChannels = new();
|
||||
[DataField, AutoNetworkedField]
|
||||
public List<ProtoId<RadioChannelPrototype>> SupportedChannels = new();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Radio.Components;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for a radio that doesn't need a telecom server in order to broadcast.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class TelecomExemptComponent : Component;
|
||||
@@ -31,6 +31,7 @@ public sealed partial class EncryptionKeySystem : EntitySystem
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||
[Dependency] private readonly SharedWiresSystem _wires = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -150,7 +151,7 @@ public sealed partial class EncryptionKeySystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
|
||||
if (!_wires.IsPanelOpen(uid))
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString("encryption-keys-panel-locked"), uid, args.User);
|
||||
return;
|
||||
@@ -184,8 +185,15 @@ public sealed partial class EncryptionKeySystem : EntitySystem
|
||||
|
||||
if (component.Channels.Count > 0)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("examine-encryption-channels-prefix"));
|
||||
AddChannelsExamine(component.Channels, component.DefaultChannel, args, _protoManager, "examine-encryption-channel");
|
||||
using (args.PushGroup(nameof(EncryptionKeyComponent)))
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("examine-encryption-channels-prefix"));
|
||||
AddChannelsExamine(component.Channels,
|
||||
component.DefaultChannel,
|
||||
args,
|
||||
_protoManager,
|
||||
"examine-encryption-channel");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Radio;
|
||||
|
||||
@@ -8,23 +9,6 @@ public enum IntercomUiKey
|
||||
Key,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class IntercomBoundUIState : BoundUserInterfaceState
|
||||
{
|
||||
public bool MicEnabled;
|
||||
public bool SpeakerEnabled;
|
||||
public List<string> AvailableChannels;
|
||||
public string SelectedChannel;
|
||||
|
||||
public IntercomBoundUIState(bool micEnabled, bool speakerEnabled, List<string> availableChannels, string selectedChannel)
|
||||
{
|
||||
MicEnabled = micEnabled;
|
||||
SpeakerEnabled = speakerEnabled;
|
||||
AvailableChannels = availableChannels;
|
||||
SelectedChannel = selectedChannel;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ToggleIntercomMicMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@ public abstract class SharedWiresSystem : EntitySystem
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<WiresPanelComponent, ComponentStartup>(OnStartup);
|
||||
SubscribeLocalEvent<WiresPanelComponent, WirePanelDoAfterEvent>(OnPanelDoAfter);
|
||||
SubscribeLocalEvent<WiresPanelComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
SubscribeLocalEvent<WiresPanelComponent, ExaminedEvent>(OnExamine);
|
||||
@@ -28,6 +29,11 @@ public abstract class SharedWiresSystem : EntitySystem
|
||||
SubscribeLocalEvent<ActivatableUIRequiresPanelComponent, PanelChangedEvent>(OnActivatableUIPanelChanged);
|
||||
}
|
||||
|
||||
private void OnStartup(Entity<WiresPanelComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
UpdateAppearance(ent, ent);
|
||||
}
|
||||
|
||||
private void OnPanelDoAfter(EntityUid uid, WiresPanelComponent panel, WirePanelDoAfterEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
intercom-menu-title = Intercom
|
||||
intercom-channel-label = Channel:
|
||||
intercom-button-text-mic = Mic.
|
||||
intercom-button-text-speaker = Speak
|
||||
intercom-button-text-speaker = Spkr.
|
||||
intercom-options-none = No channels
|
||||
intercom-flavor-text-left = Keep lines free of chatter
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
parent: BaseItem
|
||||
id: RadioHandheld
|
||||
components:
|
||||
- type: TelecomExempt
|
||||
- type: RadioMicrophone
|
||||
broadcastChannel: Handheld
|
||||
- type: RadioSpeaker
|
||||
@@ -39,4 +40,4 @@
|
||||
sprite: Objects/Devices/securityhandy.rsi
|
||||
- type: Item
|
||||
sprite: Objects/Devices/securityhandy.rsi
|
||||
heldPrefix: walkietalkie
|
||||
heldPrefix: walkietalkie
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- type: entity
|
||||
id: Intercom
|
||||
id: BaseIntercom
|
||||
name: intercom
|
||||
description: An intercom. For when the station just needs to know something.
|
||||
abstract: true
|
||||
@@ -9,6 +9,10 @@
|
||||
- type: Electrified
|
||||
enabled: false
|
||||
usesApcPower: true
|
||||
- type: TelecomExempt
|
||||
- type: EncryptionKeyHolder
|
||||
keySlots: 3
|
||||
keysExtractionMethod: Prying
|
||||
- type: RadioMicrophone
|
||||
powerRequired: true
|
||||
unobstructedRequired: true
|
||||
@@ -24,12 +28,14 @@
|
||||
- type: InteractionOutline
|
||||
- type: Appearance
|
||||
- type: WiresVisuals
|
||||
- type: WiresPanelSecurity
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board: [ IntercomElectronics ]
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
board: !type:Container
|
||||
key_slots: !type:Container
|
||||
- type: Sprite
|
||||
noRot: false
|
||||
drawdepth: SmallObjects
|
||||
@@ -49,7 +55,6 @@
|
||||
visible: false
|
||||
- state: panel
|
||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- type: Transform
|
||||
noRot: false
|
||||
@@ -61,6 +66,7 @@
|
||||
- type: ActivatableUIRequiresPower
|
||||
- type: ActivatableUI
|
||||
key: enum.IntercomUiKey.Key
|
||||
singleUser: true
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
enum.IntercomUiKey.Key:
|
||||
@@ -116,7 +122,7 @@
|
||||
- Wallmount
|
||||
|
||||
- type: entity
|
||||
id: IntercomAssesmbly
|
||||
id: IntercomAssembly
|
||||
name: intercom assembly
|
||||
description: An intercom. It doesn't seem very helpful right now.
|
||||
components:
|
||||
@@ -126,7 +132,18 @@
|
||||
- type: Sprite
|
||||
drawdepth: SmallObjects
|
||||
sprite: Structures/Wallmounts/intercom.rsi
|
||||
state: build
|
||||
layers:
|
||||
- state: build
|
||||
- state: panel
|
||||
visible: false
|
||||
map: [ "wires" ]
|
||||
- type: Appearance
|
||||
- type: GenericVisualizer
|
||||
visuals:
|
||||
enum.ConstructionVisuals.Layer:
|
||||
wires:
|
||||
0: { visible: false }
|
||||
1: { visible: true }
|
||||
- type: Construction
|
||||
graph: Intercom
|
||||
node: assembly
|
||||
@@ -137,97 +154,176 @@
|
||||
snap:
|
||||
- Wallmount
|
||||
|
||||
# this weird inheritance BS exists for construction shitcode
|
||||
- type: entity
|
||||
id: IntercomConstructed
|
||||
parent: BaseIntercom
|
||||
suffix: Empty, Panel Open
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: base
|
||||
- state: unshaded
|
||||
map: ["enum.PowerDeviceVisualLayers.Powered"]
|
||||
shader: unshaded
|
||||
- state: broadcasting
|
||||
map: ["enum.RadioDeviceVisualLayers.Broadcasting"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: speaker
|
||||
map: ["enum.RadioDeviceVisualLayers.Speaker"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: panel
|
||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||
visible: true
|
||||
- type: WiresPanel
|
||||
open: true
|
||||
|
||||
- type: entity
|
||||
id: Intercom
|
||||
parent: IntercomConstructed
|
||||
suffix: ""
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: base
|
||||
- state: unshaded
|
||||
map: ["enum.PowerDeviceVisualLayers.Powered"]
|
||||
shader: unshaded
|
||||
- state: broadcasting
|
||||
map: ["enum.RadioDeviceVisualLayers.Broadcasting"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: speaker
|
||||
map: ["enum.RadioDeviceVisualLayers.Speaker"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: panel
|
||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||
- type: WiresPanel
|
||||
open: false
|
||||
|
||||
- type: entity
|
||||
id: IntercomCommon
|
||||
parent: Intercom
|
||||
suffix: Common
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
|
||||
- type: entity
|
||||
id: IntercomCommand
|
||||
parent: Intercom
|
||||
suffix: Command
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- Command
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
- EncryptionKeyCommand
|
||||
|
||||
- type: entity
|
||||
id: IntercomEngineering
|
||||
parent: Intercom
|
||||
suffix: Engineering
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- Engineering
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
- EncryptionKeyEngineering
|
||||
|
||||
- type: entity
|
||||
id: IntercomMedical
|
||||
parent: Intercom
|
||||
suffix: Medical
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- Medical
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
- EncryptionKeyMedical
|
||||
|
||||
- type: entity
|
||||
id: IntercomScience
|
||||
parent: Intercom
|
||||
suffix: Science
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- Science
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
- EncryptionKeyScience
|
||||
|
||||
- type: entity
|
||||
id: IntercomSecurity
|
||||
parent: Intercom
|
||||
suffix: Security
|
||||
description: An intercom. It's been reinforced with metal from security helmets, making it a bitch-and-a-half to open.
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- Security
|
||||
- type: WiresPanel
|
||||
openDelay: 5
|
||||
- type: WiresPanelSecurity
|
||||
examine: wires-panel-component-on-examine-security-level2
|
||||
wiresAccessible: false
|
||||
- type: Construction
|
||||
node: intercomReinforced
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
- EncryptionKeySecurity
|
||||
|
||||
- type: entity
|
||||
id: IntercomService
|
||||
parent: Intercom
|
||||
suffix: Service
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- Service
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
- EncryptionKeyService
|
||||
|
||||
- type: entity
|
||||
id: IntercomSupply
|
||||
parent: Intercom
|
||||
suffix: Supply
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- Supply
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
- EncryptionKeyCargo
|
||||
|
||||
- type: entity
|
||||
id: IntercomAll
|
||||
parent: Intercom
|
||||
suffix: All
|
||||
components:
|
||||
- type: Intercom
|
||||
supportedChannels:
|
||||
- Common
|
||||
- Command
|
||||
- Engineering
|
||||
- Medical
|
||||
- Science
|
||||
- Security
|
||||
- Service
|
||||
- Supply
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board:
|
||||
- IntercomElectronics
|
||||
key_slots:
|
||||
- EncryptionKeyCommon
|
||||
- EncryptionKeyStationMaster
|
||||
|
||||
@@ -11,13 +11,17 @@
|
||||
doAfter: 2.0
|
||||
|
||||
- node: assembly
|
||||
entity: IntercomAssesmbly
|
||||
entity: IntercomAssembly
|
||||
edges:
|
||||
- to: wired
|
||||
steps:
|
||||
- material: Cable
|
||||
amount: 2
|
||||
doAfter: 1
|
||||
completed:
|
||||
- !type:VisualizerDataInt
|
||||
key: "enum.ConstructionVisuals.Layer"
|
||||
data: 1
|
||||
- to: start
|
||||
completed:
|
||||
- !type:GivePrototype
|
||||
@@ -29,7 +33,7 @@
|
||||
doAfter: 2
|
||||
|
||||
- node: wired
|
||||
entity: IntercomAssesmbly
|
||||
entity: IntercomAssembly
|
||||
edges:
|
||||
- to: electronics
|
||||
steps:
|
||||
@@ -45,6 +49,9 @@
|
||||
- !type:GivePrototype
|
||||
prototype: CableApcStack1
|
||||
amount: 2
|
||||
- !type:VisualizerDataInt
|
||||
key: "enum.ConstructionVisuals.Layer"
|
||||
data: 0
|
||||
steps:
|
||||
- tool: Cutting
|
||||
doAfter: 1
|
||||
@@ -57,7 +64,11 @@
|
||||
doAfter: 2
|
||||
|
||||
- node: intercom
|
||||
entity: IntercomCommon #TODO: make this work with encryption keys
|
||||
entity: IntercomConstructed
|
||||
doNotReplaceInheritingEntities: true
|
||||
actions:
|
||||
- !type:SetWiresPanelSecurity
|
||||
wiresAccessible: true
|
||||
edges:
|
||||
- to: wired
|
||||
conditions:
|
||||
@@ -72,3 +83,27 @@
|
||||
steps:
|
||||
- tool: Prying
|
||||
doAfter: 1
|
||||
- to: intercomReinforced
|
||||
conditions:
|
||||
- !type:WirePanel
|
||||
steps:
|
||||
- material: Steel
|
||||
amount: 1
|
||||
- tool: Welding
|
||||
doAfter: 1
|
||||
|
||||
- node: intercomReinforced
|
||||
actions:
|
||||
- !type:SetWiresPanelSecurity
|
||||
examine: wires-panel-component-on-examine-security-level2
|
||||
wiresAccessible: false
|
||||
edges:
|
||||
- to: intercom
|
||||
conditions:
|
||||
- !type:WirePanel
|
||||
completed:
|
||||
- !type:GivePrototype
|
||||
prototype: SheetSteel1
|
||||
steps:
|
||||
- tool: Welding
|
||||
doAfter: 5
|
||||
|
||||
@@ -790,7 +790,7 @@
|
||||
# INTERCOM
|
||||
- type: construction
|
||||
name: intercom
|
||||
id: IntercomAssesmbly
|
||||
id: IntercomAssembly
|
||||
graph: Intercom
|
||||
startNode: start
|
||||
targetNode: intercom
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 729 B |
|
Before Width: | Height: | Size: 171 B After Width: | Height: | Size: 137 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 656 B |
|
Before Width: | Height: | Size: 656 B After Width: | Height: | Size: 316 B |
|
Before Width: | Height: | Size: 157 B After Width: | Height: | Size: 134 B |
|
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 217 B |
@@ -358,3 +358,6 @@ FloorTileItemReinforced: PartRodMetal1
|
||||
|
||||
#2024-06-25
|
||||
BookChefGaming: BookHowToCookForFortySpaceman
|
||||
|
||||
#2024-06-29
|
||||
IntercomAssesmbly: IntercomAssembly
|
||||
|
||||