diff --git a/Content.Server/Construction/Completions/ChangeWiresPanelSecurityLevel.cs b/Content.Server/Construction/Completions/ChangeWiresPanelSecurityLevel.cs deleted file mode 100644 index e4848492aef1..000000000000 --- a/Content.Server/Construction/Completions/ChangeWiresPanelSecurityLevel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Content.Server.Wires; -using Content.Shared.Construction; -using Content.Shared.Wires; -using JetBrains.Annotations; - -namespace Content.Server.Construction.Completions; - -[UsedImplicitly] -[DataDefinition] -public sealed partial class ChangeWiresPanelSecurityLevel : IGraphAction -{ - [DataField("level")] - [ValidatePrototypeId] - public string WiresPanelSecurityLevelID = "Level0"; - - public void PerformAction(EntityUid uid, EntityUid? userUid, IEntityManager entityManager) - { - if (WiresPanelSecurityLevelID == null) - return; - - if (entityManager.TryGetComponent(uid, out WiresPanelComponent? wiresPanel) - && entityManager.TrySystem(out WiresSystem? wiresSystem)) - { - wiresSystem.SetWiresPanelSecurityData(uid, wiresPanel, WiresPanelSecurityLevelID); - } - } -} diff --git a/Content.Server/Construction/Completions/SetWiresPanelSecurity.cs b/Content.Server/Construction/Completions/SetWiresPanelSecurity.cs new file mode 100644 index 000000000000..fc718249c26b --- /dev/null +++ b/Content.Server/Construction/Completions/SetWiresPanelSecurity.cs @@ -0,0 +1,35 @@ +using Content.Shared.Construction; +using Content.Shared.Wires; +using JetBrains.Annotations; + +namespace Content.Server.Construction.Completions; + +/// +/// This graph action is used to set values on entities with the +/// + +[UsedImplicitly] +[DataDefinition] +public sealed partial class SetWiresPanelSecurity : IGraphAction +{ + /// + /// Sets the Examine field on the entity's + /// + [DataField("examine")] + public string Examine = string.Empty; + + /// + /// Sets the WiresAccessible field on the entity's + /// + [DataField("wiresAccessible")] + public bool WiresAccessible = true; + + public void PerformAction(EntityUid uid, EntityUid? userUid, IEntityManager entityManager) + { + if (entityManager.TryGetComponent(uid, out WiresPanelSecurityComponent? _)) + { + var ev = new WiresPanelSecurityEvent(Examine, WiresAccessible); + entityManager.EventBus.RaiseLocalEvent(uid, ev); + } + } +} diff --git a/Content.Server/Construction/Conditions/HasTag.cs b/Content.Server/Construction/Conditions/HasTag.cs new file mode 100644 index 000000000000..b89dbbfd4905 --- /dev/null +++ b/Content.Server/Construction/Conditions/HasTag.cs @@ -0,0 +1,43 @@ +using Content.Shared.Construction; +using JetBrains.Annotations; +using Content.Shared.Doors.Components; +using Content.Shared.Examine; +using YamlDotNet.Core.Tokens; +using Content.Shared.Tag; + +namespace Content.Server.Construction.Conditions +{ + /// + /// This condition checks whether if an entity with the possesses a specific tag + /// + [UsedImplicitly] + [DataDefinition] + public sealed partial class HasTag : IGraphCondition + { + /// + /// The tag the entity is being checked for + /// + [DataField("tag")] + public string Tag { get; private set; } + + public bool Condition(EntityUid uid, IEntityManager entityManager) + { + if (!entityManager.TrySystem(out var tagSystem)) + return false; + + return tagSystem.HasTag(uid, Tag); + } + + public bool DoExamine(ExaminedEvent args) + { + return false; + } + + public IEnumerable GenerateGuideEntry() + { + yield return new ConstructionGuideEntry() + { + }; + } + } +} diff --git a/Content.Server/Construction/ConstructionSystem.Graph.cs b/Content.Server/Construction/ConstructionSystem.Graph.cs index 5d4bcde4cecb..be8b0e688dd5 100644 --- a/Content.Server/Construction/ConstructionSystem.Graph.cs +++ b/Content.Server/Construction/ConstructionSystem.Graph.cs @@ -8,6 +8,7 @@ using Robust.Server.Containers; using Robust.Shared.Containers; using Robust.Shared.Prototypes; +using System.Linq; namespace Content.Server.Construction { @@ -298,9 +299,23 @@ public bool ChangeNode(EntityUid uid, EntityUid? userUid, string id, bool perfor throw new Exception("Missing construction components"); } + // Exit if the new entity's prototype is the same as the original, or the prototype is invalid if (newEntity == metaData.EntityPrototype?.ID || !_prototypeManager.HasIndex(newEntity)) return null; + // [Optional] Exit if the new entity's prototype is a parent of the original + // E.g., if an entity with the 'AirlockCommand' prototype was to be replaced with a new entity that + // had the 'Airlock' prototype, and DoNotReplaceInheritingEntities was true, the code block would + // exit here because 'AirlockCommand' is derived from 'Airlock' + if (GetCurrentNode(uid, construction)?.DoNotReplaceInheritingEntities == true && + metaData.EntityPrototype?.ID != null) + { + var parents = _prototypeManager.EnumerateParents(metaData.EntityPrototype.ID)?.ToList(); + + if (parents != null && parents.Any(x => x.ID == newEntity)) + return null; + } + // Optional resolves. Resolve(uid, ref containerManager, false); diff --git a/Content.Server/Construction/ConstructionSystem.Interactions.cs b/Content.Server/Construction/ConstructionSystem.Interactions.cs index e2e99ad74eaa..21daabdb5da6 100644 --- a/Content.Server/Construction/ConstructionSystem.Interactions.cs +++ b/Content.Server/Construction/ConstructionSystem.Interactions.cs @@ -12,6 +12,7 @@ using Content.Shared.Prying.Systems; using Content.Shared.Radio.EntitySystems; using Content.Shared.Tools.Components; +using Content.Shared.Tools.Systems; using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Utility; @@ -38,7 +39,7 @@ private void InitializeInteractions() // Event handling. Add your subscriptions here! Just make sure they're all handled by EnqueueEvent. SubscribeLocalEvent(EnqueueEvent, - new []{typeof(AnchorableSystem), typeof(PryingSystem) }, + new []{typeof(AnchorableSystem), typeof(PryingSystem), typeof(WeldableSystem)}, new []{typeof(EncryptionKeySystem)}); SubscribeLocalEvent(EnqueueEvent); SubscribeLocalEvent(EnqueueEvent); diff --git a/Content.Server/Doors/Systems/AirlockSystem.cs b/Content.Server/Doors/Systems/AirlockSystem.cs index 67f732f28e41..06fdac45d8f7 100644 --- a/Content.Server/Doors/Systems/AirlockSystem.cs +++ b/Content.Server/Doors/Systems/AirlockSystem.cs @@ -18,7 +18,6 @@ public sealed class AirlockSystem : SharedAirlockSystem [Dependency] private readonly WiresSystem _wiresSystem = default!; [Dependency] private readonly PowerReceiverSystem _power = default!; [Dependency] private readonly DoorBoltSystem _bolts = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; public override void Initialize() { @@ -153,8 +152,8 @@ private void OnActivate(EntityUid uid, AirlockComponent component, ActivateInWor { if (TryComp(uid, out var panel) && panel.Open && - _prototypeManager.TryIndex(panel.CurrentSecurityLevelID, out var securityLevelPrototype) && - securityLevelPrototype.WiresAccessible && + TryComp(uid, out var wiresPanelSecurity) && + wiresPanelSecurity.WiresAccessible && TryComp(args.User, out var actor)) { _wiresSystem.OpenUserInterface(uid, actor.PlayerSession); diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs index e9522485ca1b..37b6282bb646 100644 --- a/Content.Server/Wires/WiresSystem.cs +++ b/Content.Server/Wires/WiresSystem.cs @@ -2,6 +2,8 @@ using System.Linq; using System.Threading; using Content.Server.Administration.Logs; +using Content.Server.Construction; +using Content.Server.Construction.Components; using Content.Server.Power.Components; using Content.Server.UserInterface; using Content.Shared.Database; @@ -33,6 +35,7 @@ public sealed class WiresSystem : SharedWiresSystem [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly ConstructionSystem _construction = default!; // This is where all the wire layouts are stored. [ViewVariables] private readonly Dictionary _layouts = new(); @@ -58,6 +61,7 @@ public override void Initialize() SubscribeLocalEvent(OnDoAfter); SubscribeLocalEvent(OnAttemptOpenActivatableUI); SubscribeLocalEvent(OnActivatableUIPanelChanged); + SubscribeLocalEvent(SetWiresPanelSecurity); } private void SetOrCreateWireLayout(EntityUid uid, WiresComponent? wires = null) { @@ -459,8 +463,8 @@ private void OnInteractUsing(EntityUid uid, WiresComponent component, InteractUs return; if (panel.Open && - _protoMan.TryIndex(panel.CurrentSecurityLevelID, out var securityLevelPrototype) && - securityLevelPrototype.WiresAccessible && + TryComp(uid, out var wiresPanelSecurity) && + wiresPanelSecurity.WiresAccessible && (_toolSystem.HasQuality(args.Used, "Cutting", tool) || _toolSystem.HasQuality(args.Used, "Pulsing", tool))) { @@ -526,6 +530,14 @@ private void OnMapInit(EntityUid uid, WiresComponent component, MapInitEvent arg if (component.WireSeed == 0) component.WireSeed = _random.Next(1, int.MaxValue); + // Update the construction graph to make sure that it starts on the node specified by WiresPanelSecurityComponent + if (TryComp(uid, out var wiresPanelSecurity) && + !string.IsNullOrEmpty(wiresPanelSecurity.SecurityLevel) && + TryComp(uid, out var construction)) + { + _construction.ChangeNode(uid, null, wiresPanelSecurity.SecurityLevel, true, construction); + } + UpdateUserInterface(uid); } #endregion @@ -656,13 +668,14 @@ public void TogglePanel(EntityUid uid, WiresPanelComponent component, bool open) RaiseLocalEvent(uid, ref ev); } - public void SetWiresPanelSecurityData(EntityUid uid, WiresPanelComponent component, string wiresPanelSecurityLevelID) + public void SetWiresPanelSecurity(EntityUid uid, WiresPanelSecurityComponent component, WiresPanelSecurityEvent args) { - component.CurrentSecurityLevelID = wiresPanelSecurityLevelID; + component.Examine = args.Examine; + component.WiresAccessible = args.WiresAccessible; + Dirty(uid, component); - if (_protoMan.TryIndex(component.CurrentSecurityLevelID, out var securityLevelPrototype) && - securityLevelPrototype.WiresAccessible) + if (!args.WiresAccessible) { _uiSystem.TryCloseAll(uid, WiresUiKey.Key); } diff --git a/Content.Shared/Construction/ConstructionGraphEdge.cs b/Content.Shared/Construction/ConstructionGraphEdge.cs index 6ac757174301..5166da94207d 100644 --- a/Content.Shared/Construction/ConstructionGraphEdge.cs +++ b/Content.Shared/Construction/ConstructionGraphEdge.cs @@ -1,4 +1,4 @@ -using Content.Shared.Construction.Steps; +using Content.Shared.Construction.Steps; namespace Content.Shared.Construction { diff --git a/Content.Shared/Construction/ConstructionGraphNode.cs b/Content.Shared/Construction/ConstructionGraphNode.cs index 265463c2431e..fd70569e9daa 100644 --- a/Content.Shared/Construction/ConstructionGraphNode.cs +++ b/Content.Shared/Construction/ConstructionGraphNode.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using Content.Shared.Construction.NodeEntities; using Content.Shared.Construction.Serialization; using Robust.Shared.Prototypes; @@ -31,6 +31,20 @@ public sealed partial class ConstructionGraphNode [DataField("entity", customTypeSerializer: typeof(GraphNodeEntitySerializer), serverOnly:true)] public IGraphNodeEntity Entity { get; private set; } = new NullNodeEntity(); + /// + /// Ignore requests to change the entity if the entity's current prototype inherits from specified replacement + /// + /// + /// When this bool is true and a construction node specifies that the current entity should be replaced with a new entity, if the + /// current entity has an entity prototype which inherits from the replacement entity prototype, entity replacement will not occur. + /// E.g., if an entity with the 'AirlockCommand' prototype was to be replaced with a new entity that had the 'Airlock' prototype, + /// and 'DoNotReplaceInheritingEntities' was true, the entity would not be replaced because 'AirlockCommand' is derived from 'Airlock' + /// This will largely be used for construction graphs which have removeable upgrades, such as hacking protections for airlocks, + /// so that the upgrades can be removed and you can return to the last primary construction step without replacing the entity + /// + [DataField("doNotReplaceInheritingEntities")] + public bool DoNotReplaceInheritingEntities = false; + public ConstructionGraphEdge? GetEdge(string target) { foreach (var edge in _edges) diff --git a/Content.Shared/Wires/SharedWiresSystem.cs b/Content.Shared/Wires/SharedWiresSystem.cs index 055827e8b1dd..50465537e8cc 100644 --- a/Content.Shared/Wires/SharedWiresSystem.cs +++ b/Content.Shared/Wires/SharedWiresSystem.cs @@ -6,14 +6,11 @@ namespace Content.Shared.Wires; public abstract class SharedWiresSystem : EntitySystem { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnExamine); - SubscribeLocalEvent(OnWeldableAttempt); } private void OnExamine(EntityUid uid, WiresPanelComponent component, ExaminedEvent args) @@ -26,21 +23,11 @@ private void OnExamine(EntityUid uid, WiresPanelComponent component, ExaminedEve { args.PushMarkup(Loc.GetString("wires-panel-component-on-examine-open")); - if (_prototypeManager.TryIndex(component.CurrentSecurityLevelID, out var securityLevelPrototype) && - securityLevelPrototype.Examine != null) + if (TryComp(uid, out var wiresPanelSecurity) && + wiresPanelSecurity.Examine != null) { - args.PushMarkup(Loc.GetString(securityLevelPrototype.Examine)); + args.PushMarkup(Loc.GetString(wiresPanelSecurity.Examine)); } } } - - private void OnWeldableAttempt(EntityUid uid, WiresPanelComponent component, WeldableAttemptEvent args) - { - if (component.Open && - _prototypeManager.TryIndex(component.CurrentSecurityLevelID, out var securityLevelPrototype) && - !securityLevelPrototype.WeldingAllowed) - { - args.Cancel(); - } - } } diff --git a/Content.Shared/Wires/WiresPanelComponent.cs b/Content.Shared/Wires/WiresPanelComponent.cs index adc9d9a5f097..1162d0503386 100644 --- a/Content.Shared/Wires/WiresPanelComponent.cs +++ b/Content.Shared/Wires/WiresPanelComponent.cs @@ -27,14 +27,6 @@ public sealed partial class WiresPanelComponent : Component [DataField("screwdriverCloseSound")] public SoundSpecifier ScrewdriverCloseSound = new SoundPathSpecifier("/Audio/Machines/screwdriverclose.ogg"); - - /// - /// This prototype describes the current security features of the wire panel - /// - [DataField("securityLevel")] - [ValidatePrototypeId] - [AutoNetworkedField] - public string CurrentSecurityLevelID = "Level0"; } /// diff --git a/Content.Shared/Wires/WiresPanelSecurityComponent.cs b/Content.Shared/Wires/WiresPanelSecurityComponent.cs new file mode 100644 index 000000000000..e894f1f0c9e5 --- /dev/null +++ b/Content.Shared/Wires/WiresPanelSecurityComponent.cs @@ -0,0 +1,50 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Wires; + +/// +/// Allows hacking protections to a be added to an entity. +/// These safeguards are determined via a construction graph, +/// so the entity requires for this to function +/// +[NetworkedComponent, RegisterComponent] +[Access(typeof(SharedWiresSystem))] +[AutoGenerateComponentState] +public sealed partial class WiresPanelSecurityComponent : Component +{ + /// + /// A verbal description of the wire panel's current security level + /// + [DataField("examine")] + [AutoNetworkedField] + public string? Examine = default!; + + /// + /// Determines whether the wiring is accessible to hackers or not + /// + [DataField("wiresAccessible")] + [AutoNetworkedField] + public bool WiresAccessible = true; + + /// + /// Name of the construction graph node that the entity will start on + /// + [DataField("securityLevel")] + [AutoNetworkedField] + public string SecurityLevel = string.Empty; +} + +/// +/// This event gets raised when security settings on a wires panel change +/// +public sealed class WiresPanelSecurityEvent : EntityEventArgs +{ + public readonly string? Examine; + public readonly bool WiresAccessible; + + public WiresPanelSecurityEvent(string? examine, bool wiresAccessible) + { + Examine = examine; + WiresAccessible = wiresAccessible; + } +} diff --git a/Content.Shared/Wires/WiresPanelSecurityLevelPrototype.cs b/Content.Shared/Wires/WiresPanelSecurityLevelPrototype.cs deleted file mode 100644 index 8ddc8eeab819..000000000000 --- a/Content.Shared/Wires/WiresPanelSecurityLevelPrototype.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Robust.Shared.Prototypes; - -namespace Content.Shared.Wires; - -[Prototype("WiresPanelSecurityLevel")] -public sealed class WiresPanelSecurityLevelPrototype : IPrototype -{ - [IdDataField] - public string ID { get; private set; } = default!; - - /// - /// A verbal description of the wire panel's current security level - /// - [DataField("examine")] - public string? Examine = default!; - - /// - /// Determines whether the wiring is accessible to hackers or not - /// - [DataField("wiresAccessible")] - public bool WiresAccessible = true; - - /// - /// Determines whether the device can be welded shut or not - /// - /// - /// Should be set false when you need to weld/unweld something to/from the wire panel - /// - [DataField("weldingAllowed")] - public bool WeldingAllowed = true; -} diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml index f445163257d4..940e2e8b36cb 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml @@ -69,10 +69,8 @@ components: - type: Sprite sprite: Structures/Doors/Airlocks/Standard/command.rsi - - type: WiresPanel - securityLevel: Level2 - - type: Construction - node: airlockMedSecurity + - type: WiresPanelSecurity + securityLevel: medSecurity - type: entity parent: Airlock @@ -138,7 +136,10 @@ group: Glass - type: RadiationBlocker resistance: 2 - + - type: Tag + tags: + - GlassAirlock + # This tag is used to nagivate the Airlock construction graph. It's needed because the construction graph is shared between Airlock, AirlockGlass, and HighSecDoor - type: entity parent: AirlockGlass id: AirlockEngineeringGlass @@ -218,10 +219,8 @@ sprite: Structures/Doors/Airlocks/Glass/command.rsi - type: PaintableAirlock group: Glass - - type: WiresPanel - securityLevel: Level2 - - type: Construction - node: glassAirlockMedSecurity + - type: WiresPanelSecurity + securityLevel: medSecurity - type: entity parent: AirlockGlass diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml index f40ef4ea8474..51d3cfdda098 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml @@ -74,6 +74,7 @@ enabled: false usesApcPower: true - type: WiresPanel + - type: WiresPanelSecurity - type: Wires BoardName: wires-board-name-airlock LayoutId: Airlock @@ -131,5 +132,10 @@ - type: AccessReader - type: StaticPrice price: 150 + - type: Tag + tags: + - Airlock + # This tag is used to nagivate the Airlock construction graph. It's needed because the construction graph is shared between Airlock, AirlockGlass, and HighSecDoor placement: mode: SnapgridCenter + diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml index 80194a48cdfc..c653d2d0100f 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml @@ -67,7 +67,8 @@ enabled: false usesApcPower: true - type: WiresPanel - securityLevel: Level5 + - type: WiresPanelSecurity + securityLevel: maxSecurity - type: Wires BoardName: wires-board-name-highsec LayoutId: HighSec @@ -94,5 +95,9 @@ key: walls mode: NoSprite - type: Construction - graph: HighSecDoor - node: maxSecurity + graph: Airlock + node: highSecDoor + - type: Tag + tags: + - HighSecDoor + # This tag is used to nagivate the Airlock construction graph. It's needed because this construction graph is shared between Airlock, AirlockGlass, and HighSecDoor \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Doors/wires_panel_security.yml b/Resources/Prototypes/Entities/Structures/Doors/wires_panel_security.yml deleted file mode 100644 index 4a42ed36ad8f..000000000000 --- a/Resources/Prototypes/Entities/Structures/Doors/wires_panel_security.yml +++ /dev/null @@ -1,45 +0,0 @@ -- type: WiresPanelSecurityLevel - id: Level0 - wiresAccessible: true - -- type: WiresPanelSecurityLevel - id: Level1 - examine: wires-panel-component-on-examine-security-level1 - wiresAccessible: false - weldingAllowed: false - -- type: WiresPanelSecurityLevel - id: Level2 - examine: wires-panel-component-on-examine-security-level2 - wiresAccessible: false - weldingAllowed: false - -- type: WiresPanelSecurityLevel - id: Level3 - examine: wires-panel-component-on-examine-security-level3 - wiresAccessible: false - weldingAllowed: false - -- type: WiresPanelSecurityLevel - id: Level4 - examine: wires-panel-component-on-examine-security-level4 - wiresAccessible: false - weldingAllowed: false - -- type: WiresPanelSecurityLevel - id: Level5 - examine: wires-panel-component-on-examine-security-level5 - wiresAccessible: false - -- type: WiresPanelSecurityLevel - id: Level6 - examine: wires-panel-component-on-examine-security-level6 - wiresAccessible: false - weldingAllowed: false - -- type: WiresPanelSecurityLevel - id: Level7 - examine: wires-panel-component-on-examine-security-level7 - wiresAccessible: false - weldingAllowed: false - \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml index 3d7e45873185..4ddeb3851960 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml @@ -110,11 +110,14 @@ - tool: Prying doAfter: 5 +## Glass airlock - node: glassAirlock entity: AirlockGlass + doNotReplaceInheritingEntities: true actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level0 + - !type:SetWiresPanelSecurity + wiresAccessible: true + weldingAllowed: true edges: - to: glassElectronics conditions: @@ -132,7 +135,7 @@ - tool: Prying doAfter: 2 - - to: glassAirlockMedSecurityBreached + - to: medSecurityUnfinished conditions: - !type:WirePanel {} steps: @@ -140,21 +143,24 @@ amount: 2 doAfter: 2 - - to: glassAirlockHighSecurityBreached + - to: highSecurityUnfinished conditions: - !type:WirePanel {} steps: - material: Plasteel amount: 2 doAfter: 2 - -## Return node so that removing all internal plating doesn't reset the door - - node: glassAirlockUnsecured + +## Standard airlock + - node: airlock + entity: Airlock + doNotReplaceInheritingEntities: true actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level0 + - !type:SetWiresPanelSecurity + wiresAccessible: true + weldingAllowed: true edges: - - to: glassElectronics + - to: wired conditions: - !type:EntityAnchored {} - !type:DoorWelded {} @@ -163,22 +169,20 @@ - !type:WirePanel {} - !type:AllWiresCut completed: - - !type:SpawnPrototype - prototype: SheetRGlass1 - amount: 1 + - !type:EmptyAllContainers {} steps: - tool: Prying - doAfter: 2 + doAfter: 5 - - to: glassAirlockMedSecurityBreached + - to: medSecurityUnfinished conditions: - !type:WirePanel {} steps: - material: Steel amount: 2 doAfter: 2 - - - to: glassAirlockHighSecurityBreached + + - to: highSecurityUnfinished conditions: - !type:WirePanel {} steps: @@ -186,293 +190,166 @@ amount: 2 doAfter: 2 -## Medium security level airlock: a layer of steel plating protects the internal wiring - - node: glassAirlockMedSecurityBreached +## High security door + - node: highSecDoor actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level1 - edges: - - to: glassAirlockUnsecured - completed: - - !type:GivePrototype - prototype: SheetSteel1 - amount: 2 + - !type:SetWiresPanelSecurity + wiresAccessible: true + weldingAllowed: true + edges: + - to: medSecurityUnfinished conditions: - !type:WirePanel {} steps: - - tool: Prying - doAfter: 4 + - material: Steel + amount: 2 + doAfter: 2 - - to: glassAirlockMedSecurity - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 3 - - - node: glassAirlockMedSecurity - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level2 - edges: - - to: glassAirlockMedSecurityBreached + - to: highSecurityUnfinished conditions: - !type:WirePanel {} steps: - - tool: Welding - doAfter: 10 + - material: Plasteel + amount: 2 + doAfter: 2 -## High security level airlock: a layer of plasteel plating protects the internal wiring - - node: glassAirlockHighSecurityBreached +## Medium security level door: a layer of steel plating protects the internal wiring + - node: medSecurityUnfinished actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level3 + - !type:SetWiresPanelSecurity + examine: wires-panel-component-on-examine-security-level1 + wiresAccessible: false + weldingAllowed: false edges: - - to: glassAirlockUnsecured + - to: glassAirlock completed: - !type:GivePrototype - prototype: SheetPlasteel1 + prototype: SheetSteel1 amount: 2 conditions: - !type:WirePanel {} + - !type:HasTag + tag: GlassAirlock steps: - tool: Prying doAfter: 4 - - - to: glassAirlockHighSecurity - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 5 - - - node: glassAirlockHighSecurity - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level4 - edges: - - to: glassAirlockHighSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 15 - - - to: glassAirlockMaxSecurity - conditions: - - !type:WirePanel {} - steps: - - material: MetalRod - amount: 2 - doAfter: 1 - -## Max security level airlock: an electric grill is added - - node: glassAirlockMaxSecurity - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level5 - edges: - - to: glassAirlockHighSecurity + + - to: airlock completed: - - !type:AttemptElectrocute - !type:GivePrototype - prototype: PartRodMetal1 + prototype: SheetSteel1 amount: 2 - conditions: - - !type:WirePanel {} - steps: - - tool: Cutting - doAfter: 0.5 - - - to: glassAirlockSuperMaxSecurityBreached conditions: - !type:WirePanel {} - steps: - - material: Plasteel - amount: 2 - doAfter: 2 - -## Super max security level airlock: an additional layer of plasteel is added - - node: glassAirlockSuperMaxSecurityBreached - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level6 - edges: - - to: glassAirlockMaxSecurity + - !type:HasTag + tag: Airlock + steps: + - tool: Prying + doAfter: 4 + + - to: highSecDoor completed: - !type:GivePrototype - prototype: SheetPlasteel1 + prototype: SheetSteel1 amount: 2 conditions: - !type:WirePanel {} + - !type:HasTag + tag: HighSecDoor steps: - tool: Prying doAfter: 4 - - to: glassAirlockSuperMaxSecurity + - to: medSecurity conditions: - !type:WirePanel {} steps: - tool: Welding - doAfter: 5 + doAfter: 3 - - node: glassAirlockSuperMaxSecurity + - node: medSecurity actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level7 + - !type:SetWiresPanelSecurity + examine: wires-panel-component-on-examine-security-level2 + wiresAccessible: false + weldingAllowed: false edges: - - to: glassAirlockSuperMaxSecurityBreached + - to: medSecurityUnfinished conditions: - !type:WirePanel {} steps: - tool: Welding - doAfter: 15 + doAfter: 10 - - node: airlock - entity: Airlock +## High security level door: a layer of plasteel plating protects the internal wiring + - node: highSecurityUnfinished actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level0 + - !type:SetWiresPanelSecurity + examine: wires-panel-component-on-examine-security-level3 + wiresAccessible: false + weldingAllowed: false edges: - - to: wired #TODO DOOR ELECTRONICS. If door electronics ever govern access permissions, this step should probably be further down? It makes it too easy to swap permissions around. See also windoor. - conditions: - - !type:EntityAnchored {} - - !type:DoorWelded {} - - !type:DoorBolted - value: false - - !type:WirePanel {} - - !type:AllWiresCut + - to: glassAirlock completed: - - !type:EmptyAllContainers {} - steps: - - tool: Prying - doAfter: 5 - - - to: airlockMedSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - material: Steel - amount: 2 - doAfter: 2 - - - to: airlockHighSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - material: Plasteel + - !type:GivePrototype + prototype: SheetPlasteel1 amount: 2 - doAfter: 2 - -## Return node so that removing all internal plating doesn't reset the door - - node: airlockUnsecured - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level0 - edges: - - to: wired conditions: - - !type:EntityAnchored {} - - !type:DoorWelded {} - - !type:DoorBolted - value: false - !type:WirePanel {} - - !type:AllWiresCut - completed: - - !type:EmptyAllContainers {} + - !type:HasTag + tag: GlassAirlock steps: - tool: Prying - doAfter: 5 - - - to: airlockMedSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - material: Steel - amount: 2 - doAfter: 2 + doAfter: 4 - - to: airlockHighSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - material: Plasteel - amount: 2 - doAfter: 2 - -## Medium security level airlock: a layer of steel plating protects the internal wiring - - node: airlockMedSecurityBreached - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level1 - edges: - - to: airlockUnsecured + - to: airlock completed: - !type:GivePrototype - prototype: SheetSteel1 + prototype: SheetPlasteel1 amount: 2 conditions: - !type:WirePanel {} + - !type:HasTag + tag: Airlock steps: - tool: Prying doAfter: 4 - - - to: airlockMedSecurity - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 3 - - - node: airlockMedSecurity - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level2 - edges: - - to: airlockMedSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 10 - -## High security level airlock: a layer of plasteel plating protects the internal wiring - - node: airlockHighSecurityBreached - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level3 - edges: - - to: airlockUnsecured + + - to: highSecDoor completed: - !type:GivePrototype prototype: SheetPlasteel1 amount: 2 conditions: - !type:WirePanel {} + - !type:HasTag + tag: HighSecDoor steps: - tool: Prying doAfter: 4 - - to: airlockHighSecurity + - to: highSecurity conditions: - !type:WirePanel {} steps: - tool: Welding doAfter: 5 - - node: airlockHighSecurity + - node: highSecurity actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level4 + - !type:SetWiresPanelSecurity + examine: wires-panel-component-on-examine-security-level4 + wiresAccessible: false + weldingAllowed: false edges: - - to: airlockHighSecurityBreached + - to: highSecurityUnfinished conditions: - !type:WirePanel {} steps: - tool: Welding doAfter: 15 - - to: airlockMaxSecurity + - to: maxSecurity conditions: - !type:WirePanel {} steps: @@ -480,13 +357,15 @@ amount: 2 doAfter: 1 -## Max security level airlock: an electric grill is added - - node: airlockMaxSecurity +## Max security level door: an electric grill is added + - node: maxSecurity actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level5 + - !type:SetWiresPanelSecurity + examine: wires-panel-component-on-examine-security-level5 + wiresAccessible: false + weldingAllowed: true edges: - - to: airlockHighSecurity + - to: highSecurity completed: - !type:AttemptElectrocute - !type:GivePrototype @@ -498,7 +377,7 @@ - tool: Cutting doAfter: 0.5 - - to: airlockSuperMaxSecurityBreached + - to: superMaxSecurityUnfinished conditions: - !type:WirePanel {} steps: @@ -506,13 +385,15 @@ amount: 2 doAfter: 2 -## Super max security level airlock: an additional layer of plasteel is added - - node: airlockSuperMaxSecurityBreached +## Super max security level door: an additional layer of plasteel is added + - node: superMaxSecurityUnfinished actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level6 + - !type:SetWiresPanelSecurity + examine: wires-panel-component-on-examine-security-level6 + wiresAccessible: false + weldingAllowed: false edges: - - to: airlockMaxSecurity + - to: maxSecurity completed: - !type:GivePrototype prototype: SheetPlasteel1 @@ -523,21 +404,24 @@ - tool: Prying doAfter: 4 - - to: airlockSuperMaxSecurity + - to: superMaxSecurity conditions: - !type:WirePanel {} steps: - tool: Welding doAfter: 5 - - node: airlockSuperMaxSecurity + - node: superMaxSecurity actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level7 + - !type:SetWiresPanelSecurity + examine: wires-panel-component-on-examine-security-level7 + wiresAccessible: false + weldingAllowed: false edges: - - to: airlockSuperMaxSecurityBreached + - to: superMaxSecurityUnfinished conditions: - !type:WirePanel {} steps: - tool: Welding - doAfter: 15 + doAfter: 15 + diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/highsec.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/highsec.yml deleted file mode 100644 index bf210ad463cb..000000000000 --- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/highsec.yml +++ /dev/null @@ -1,166 +0,0 @@ -- type: constructionGraph - id: HighSecDoor - start: start - graph: - - node: start - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level0 - edges: - - to: medSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - material: Steel - amount: 2 - doAfter: 2 - - - to: highSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - material: Plasteel - amount: 2 - doAfter: 2 - -## Medium security level door: a layer of steel plating protects the internal wiring - - node: medSecurityBreached - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level1 - edges: - - to: start - completed: - - !type:GivePrototype - prototype: SheetSteel1 - amount: 2 - conditions: - - !type:WirePanel {} - steps: - - tool: Prying - doAfter: 4 - - - to: medSecurity - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 3 - - - node: medSecurity - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level2 - edges: - - to: medSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 10 - -## High security level door: a layer of plasteel plating protects the internal wiring - - node: highSecurityBreached - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level3 - edges: - - to: start - completed: - - !type:GivePrototype - prototype: SheetPlasteel1 - amount: 2 - conditions: - - !type:WirePanel {} - steps: - - tool: Prying - doAfter: 4 - - - to: highSecurity - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 5 - - - node: highSecurity - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level4 - edges: - - to: highSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 15 - - - to: maxSecurity - conditions: - - !type:WirePanel {} - steps: - - material: MetalRod - amount: 2 - doAfter: 1 - -## Max security level door: an electric grill is added - - node: maxSecurity - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level5 - edges: - - to: highSecurity - completed: - - !type:AttemptElectrocute - - !type:GivePrototype - prototype: PartRodMetal1 - amount: 2 - conditions: - - !type:WirePanel {} - steps: - - tool: Cutting - doAfter: 0.5 - - - to: superMaxSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - material: Plasteel - amount: 2 - doAfter: 2 - -## Super max security level door: an additional layer of plasteel is added - - node: superMaxSecurityBreached - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level6 - edges: - - to: maxSecurity - completed: - - !type:GivePrototype - prototype: SheetPlasteel1 - amount: 2 - conditions: - - !type:WirePanel {} - steps: - - tool: Prying - doAfter: 4 - - - to: superMaxSecurity - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 5 - - - node: superMaxSecurity - actions: - - !type:ChangeWiresPanelSecurityLevel - level: Level7 - edges: - - to: superMaxSecurityBreached - conditions: - - !type:WirePanel {} - steps: - - tool: Welding - doAfter: 15 diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index d01f8c1ddfb8..bbf91fcc5adb 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -3,6 +3,9 @@ - type: Tag id: AirAlarmElectronics + +- type: Tag + id: Airlock - type: Tag id: AirSensor @@ -487,6 +490,9 @@ - type: Tag id: GeigerCounter + +- type: Tag + id: GlassAirlock - type: Tag id: GlassBeaker @@ -503,7 +509,6 @@ - type: Tag id: GuideEmbeded - - type: Tag id: Hamster @@ -554,6 +559,9 @@ - type: Tag id: HighRiskItem + +- type: Tag + id: HighSecDoor - type: Tag id: Hoe