Intercom buffs and fixes (#29580)

* Intercom buffs and fixes

* remove unused bui state

* mild sec intercom buff

* reinforce sec intercoms
This commit is contained in:
Nemanja
2024-07-07 10:19:10 -04:00
committed by GitHub
parent 063c5de985
commit 0e9ed36b85
22 changed files with 338 additions and 136 deletions

View 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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
};
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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;
@@ -183,9 +184,16 @@ public sealed partial class EncryptionKeySystem : EntitySystem
}
if (component.Channels.Count > 0)
{
using (args.PushGroup(nameof(EncryptionKeyComponent)))
{
args.PushMarkup(Loc.GetString("examine-encryption-channels-prefix"));
AddChannelsExamine(component.Channels, component.DefaultChannel, args, _protoManager, "examine-encryption-channel");
AddChannelsExamine(component.Channels,
component.DefaultChannel,
args,
_protoManager,
"examine-encryption-channel");
}
}
}

View File

@@ -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
{

View File

@@ -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)

View File

@@ -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

View File

@@ -4,6 +4,7 @@
parent: BaseItem
id: RadioHandheld
components:
- type: TelecomExempt
- type: RadioMicrophone
broadcastChannel: Handheld
- type: RadioSpeaker

View File

@@ -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

View File

@@ -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

View File

@@ -790,7 +790,7 @@
# INTERCOM
- type: construction
name: intercom
id: IntercomAssesmbly
id: IntercomAssembly
graph: Intercom
startNode: start
targetNode: intercom

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 656 B

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 B

After

Width:  |  Height:  |  Size: 217 B

View File

@@ -358,3 +358,6 @@ FloorTileItemReinforced: PartRodMetal1
#2024-06-25
BookChefGaming: BookHowToCookForFortySpaceman
#2024-06-29
IntercomAssesmbly: IntercomAssembly