diff --git a/Content.Client/Doors/AirlockVisualizer.cs b/Content.Client/Doors/AirlockVisualizer.cs index a428a5bc2e..51ff752e13 100644 --- a/Content.Client/Doors/AirlockVisualizer.cs +++ b/Content.Client/Doors/AirlockVisualizer.cs @@ -17,9 +17,26 @@ namespace Content.Client.Doors { private const string AnimationKey = "airlock_animation"; - [DataField("animation_time")] + [DataField("animationTime")] private float _delay = 0.8f; + [DataField("denyAnimationTime")] + private float _denyDelay = 0.3f; + + /// + /// Whether the maintenance panel is animated or stays static. + /// False for windoors. + /// + [DataField("animatedPanel")] + private bool _animatedPanel = true; + + /// + /// Whether the BaseUnlit layer should still be visible when the airlock + /// is opened. + /// + [DataField("openUnlitVisible")] + private bool _openUnlitVisible = false; + private Animation CloseAnimation = default!; private Animation OpenAnimation = default!; private Animation DenyAnimation = default!; @@ -38,10 +55,13 @@ namespace Content.Client.Doors flickUnlit.LayerKey = DoorVisualLayers.BaseUnlit; flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("closing_unlit", 0f)); - var flickMaintenancePanel = new AnimationTrackSpriteFlick(); - CloseAnimation.AnimationTracks.Add(flickMaintenancePanel); - flickMaintenancePanel.LayerKey = WiresVisualizer.WiresVisualLayers.MaintenancePanel; - flickMaintenancePanel.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("panel_closing", 0f)); + if (_animatedPanel) + { + var flickMaintenancePanel = new AnimationTrackSpriteFlick(); + CloseAnimation.AnimationTracks.Add(flickMaintenancePanel); + flickMaintenancePanel.LayerKey = WiresVisualizer.WiresVisualLayers.MaintenancePanel; + flickMaintenancePanel.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("panel_closing", 0f)); + } } OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(_delay)}; @@ -56,24 +76,21 @@ namespace Content.Client.Doors flickUnlit.LayerKey = DoorVisualLayers.BaseUnlit; flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("opening_unlit", 0f)); - var flickMaintenancePanel = new AnimationTrackSpriteFlick(); - OpenAnimation.AnimationTracks.Add(flickMaintenancePanel); - flickMaintenancePanel.LayerKey = WiresVisualizer.WiresVisualLayers.MaintenancePanel; - flickMaintenancePanel.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("panel_opening", 0f)); - - var sound = new AnimationTrackPlaySound(); - OpenAnimation.AnimationTracks.Add(sound); + if (_animatedPanel) + { + var flickMaintenancePanel = new AnimationTrackSpriteFlick(); + OpenAnimation.AnimationTracks.Add(flickMaintenancePanel); + flickMaintenancePanel.LayerKey = WiresVisualizer.WiresVisualLayers.MaintenancePanel; + flickMaintenancePanel.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("panel_opening", 0f)); + } } - DenyAnimation = new Animation {Length = TimeSpan.FromSeconds(0.3f)}; + DenyAnimation = new Animation {Length = TimeSpan.FromSeconds(_denyDelay)}; { var flick = new AnimationTrackSpriteFlick(); DenyAnimation.AnimationTracks.Add(flick); flick.LayerKey = DoorVisualLayers.BaseUnlit; flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("deny_unlit", 0f)); - - var sound = new AnimationTrackPlaySound(); - DenyAnimation.AnimationTracks.Add(sound); } } @@ -108,13 +125,16 @@ namespace Content.Client.Doors { case DoorVisualState.Open: sprite.LayerSetState(DoorVisualLayers.Base, "open"); - unlitVisible = false; + unlitVisible = _openUnlitVisible; + if (_openUnlitVisible) + { + sprite.LayerSetState(DoorVisualLayers.BaseUnlit, "open_unlit"); + } break; case DoorVisualState.Closed: sprite.LayerSetState(DoorVisualLayers.Base, "closed"); sprite.LayerSetState(DoorVisualLayers.BaseUnlit, "closed_unlit"); sprite.LayerSetState(DoorVisualLayers.BaseBolted, "bolted_unlit"); - sprite.LayerSetState(WiresVisualizer.WiresVisualLayers.MaintenancePanel, "panel_open"); break; case DoorVisualState.Opening: animPlayer.Play(OpenAnimation, AnimationKey); diff --git a/Content.Server/Doors/Components/AirlockComponent.cs b/Content.Server/Doors/Components/AirlockComponent.cs index dda64b4cda..83a1745daf 100644 --- a/Content.Server/Doors/Components/AirlockComponent.cs +++ b/Content.Server/Doors/Components/AirlockComponent.cs @@ -59,6 +59,12 @@ namespace Content.Server.Doors.Components [DataField("powerWiresTimeout")] public float PowerWiresTimeout = 5.0f; + /// + /// Whether the maintenance panel should be visible even if the airlock is opened. + /// + [DataField("openPanelVisible")] + public bool OpenPanelVisible = false; + private CancellationTokenSource _powerWiresPulsedTimerCancel = new(); private bool _powerWiresPulsed; diff --git a/Content.Server/Doors/Systems/AirlockSystem.cs b/Content.Server/Doors/Systems/AirlockSystem.cs index 73d6508272..4645319b53 100644 --- a/Content.Server/Doors/Systems/AirlockSystem.cs +++ b/Content.Server/Doors/Systems/AirlockSystem.cs @@ -42,7 +42,9 @@ namespace Content.Server.Doors.Systems // Only show the maintenance panel if the airlock is closed if (component.WiresComponent != null) { - component.WiresComponent.IsPanelVisible = args.State != SharedDoorComponent.DoorState.Open; + component.WiresComponent.IsPanelVisible = + component.OpenPanelVisible + || args.State != SharedDoorComponent.DoorState.Open; } // If the door is closed, we should look if the bolt was locked while closing component.UpdateBoltLightStatus(); diff --git a/Resources/Audio/Machines/windoor_open.ogg b/Resources/Audio/Machines/windoor_open.ogg new file mode 100644 index 0000000000..26f094b597 Binary files /dev/null and b/Resources/Audio/Machines/windoor_open.ogg differ diff --git a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml index 74cc60c768..bba134dd1b 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml @@ -64,7 +64,7 @@ - type: Appearance visuals: - type: AirlockVisualizer - animation_time: 0.6 + animationTime: 0.6 - type: WiresVisualizer - type: Wires BoardName: "Firelock Control" @@ -113,7 +113,7 @@ fixtures: - shape: !type:PhysShapeRect - bounds: "0.49,-0.49,-0.49,-0.2" # don't want this colliding with walls or they won't close + bounds: "-0.2,-0.49,-0.49,0.49" # don't want this colliding with walls or they won't close mask: - MobImpassable layer: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml new file mode 100644 index 0000000000..be3701c135 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml @@ -0,0 +1,76 @@ +- type: entity + id: WindoorAssembly + name: windoor assembly + description: It opens, it closes, and you can see through it! + parent: BaseStructure + components: + - type: InteractionOutline + - type: Sprite + netsync: false + drawdepth: FloorObjects + sprite: Structures/Doors/Windoors/windoor.rsi + layers: + - state: assembly + - type: Physics + fixtures: + - shape: + !type:PhysShapeAabb + bounds: "-0.2,-0.49,-0.49,0.49" + mass: 30 + mask: + - Impassable + - VaultImpassable + - type: Anchorable + - type: Pullable + - type: Rotatable + - type: Damageable + resistances: metallicResistances + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 300 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 3 + - type: Construction + graph: windoor + node: assembly + placement: + mode: SnapgridCenter + +- type: entity + id: WindoorAssemblySecure + name: secure windoor assembly + description: It opens, it closes, and you can see through it! This one looks tough. + parent: WindoorAssembly + components: + - type: Sprite + netsync: false + drawdepth: Mobs + sprite: Structures/Doors/Windoors/windoor.rsi + layers: + - state: secure_underlay + - state: assembly + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 600 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + SheetPlasteel1: + min: 1 + max: 2 + - type: Construction + graph: windoor + node: assemblySecure + diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base.yml new file mode 100644 index 0000000000..cc078a321b --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base.yml @@ -0,0 +1,135 @@ +- type: entity + id: BaseWindoor + parent: BaseStructure + abstract: true + placement: + mode: SnapgridCenter + components: + - type: InteractionOutline + - type: Physics + fixtures: + - shape: + !type:PhysShapeAabb + bounds: "-0.2,-0.49,-0.49,0.49" + mass: 50 + layer: + - Impassable + - MobImpassable + - VaultImpassable + - SmallImpassable + mask: + - VaultImpassable + - type: Sprite + netsync: false + drawdepth: FloorObjects + sprite: Structures/Doors/Windoors/windoor.rsi + layers: + - state: closed + map: ["enum.DoorVisualLayers.Base"] + - state: closed_unlit + shader: unshaded + map: ["enum.DoorVisualLayers.BaseUnlit"] + - state: welded + map: ["enum.DoorVisualLayers.BaseWelded"] + - state: bolted_unlit + shader: unshaded + map: ["enum.DoorVisualLayers.BaseBolted"] + - state: panel_open + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: ApcPowerReceiver + - type: Damageable + resistances: glassResistances + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 + SheetSteel1: + min: 2 + max: 4 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: AccessReader + - type: Airlock + openPanelVisible: true + - type: Door + weldable: false + openSound: + path: /Audio/Machines/windoor_open.ogg + closeSound: + path: /Audio/Machines/windoor_open.ogg + denySound: + path: /Audio/Machines/airlock_deny.ogg + - type: Wires + BoardName: "Windoor Control" + LayoutId: Airlock + - type: UserInterface + interfaces: + - key: enum.WiresUiKey.Key + type: WiresBoundUserInterface + - type: Appearance + visuals: + - type: AirlockVisualizer + animationTime: 0.9 + denyAnimationTime: 0.4 + animatedPanel: false + openUnlitVisible: true + - type: WiresVisualizer + - type: Construction + graph: windoor + node: windoor + +- type: entity + id: BaseSecureWindoor + parent: BaseWindoor + abstract: true + components: + - type: Airtight + fixVacuum: true + noAirWhenFullyAirBlocked: false + airBlockedDirection: + - South + - type: Sprite + netsync: false + drawdepth: FloorObjects + sprite: Structures/Doors/Windoors/windoor.rsi + layers: + - state: secure_underlay + - state: closed + map: [ "enum.DoorVisualLayers.Base" ] + - state: closed_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseUnlit" ] + - state: welded + map: [ "enum.DoorVisualLayers.BaseWelded" ] + - state: bolted_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseBolted" ] + - state: panel_open + map: [ "enum.WiresVisualLayers.MaintenancePanel" ] + visible: false + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 400 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 + SheetPlasteel1: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Construction + graph: windoor + node: windoorSecure diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/windoor.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/windoor.yml new file mode 100644 index 0000000000..31debff337 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/windoor.yml @@ -0,0 +1,48 @@ +- type: entity + id: Windoor + parent: BaseWindoor + name: windoor + description: It's a window and a sliding door. Wow! + +- type: entity + id: WindoorSecure + parent: BaseSecureWindoor + name: secure windoor + description: It's a sturdy window and a sliding door. Wow! + +# TODO remove these with parameterized prototypes/whatever we end up doing +# Bar windoor +- type: entity + parent: Windoor + id: WindoorBarLocked + suffix: Bar, Locked + components: + - type: AccessReader + access: [["Bar"]] + +# Chemistry windoor +- type: entity + parent: WindoorSecure + id: WindoorMedicalLocked + suffix: Medical, Locked + components: + - type: AccessReader + access: [["Medical"]] + +# HOP's office windoor +- type: entity + parent: WindoorSecure + id: WindoorCommandLocked + suffix: Command, Locked + components: + - type: AccessReader + access: [["Command"]] + +# Cargo windoor +- type: entity + parent: Windoor + id: WindoorCargoLocked + suffix: Cargo, Locked + components: + - type: AccessReader + access: [["Cargo"]] diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/windoor.yml b/Resources/Prototypes/Recipes/Construction/Graphs/windoor.yml new file mode 100644 index 0000000000..f947fdd414 --- /dev/null +++ b/Resources/Prototypes/Recipes/Construction/Graphs/windoor.yml @@ -0,0 +1,221 @@ +- type: constructionGraph + id: windoor + start: start + graph: + - node: start + edges: + - to: assembly + completed: + - !type:SetAnchor + value: false + steps: + - material: Steel + amount: 4 + doAfter: 2 + - to: assemblySecure + completed: + - !type:SetAnchor + value: false + steps: + - material: Plasteel + amount: 4 + doAfter: 2 + + - node: assembly + entity: WindoorAssembly + actions: + - !type:SnapToGrid {} + - !type:SetAnchor {} + edges: + - to: glass + conditions: + - !type:EntityAnchored {} + steps: + - material: Glass + amount: 5 + doAfter: 1 + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 4 + - !type:DeleteEntity {} + steps: + - tool: Welding + doAfter: 2 + + - node: glass + entity: WindoorAssembly + edges: + - to: wired + conditions: + - !type:EntityAnchored { } + steps: + - material: Cable + amount: 5 + doAfter: 1 + - to: assembly + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetGlass1 + amount: 5 + - !type:DeleteEntity { } + steps: + - tool: Screwing + doAfter: 2 + + - node: wired + entity: WindoorAssembly + edges: + - to: electronics + conditions: + - !type:EntityAnchored {} + steps: + - tag: DoorElectronics + store: board + name: "door electronics circuit board" + icon: + sprite: "Objects/Misc/module.rsi" + state: "door_electronics" + doAfter: 1 + - to: glass + completed: + - !type:SpawnPrototype + prototype: CableApcStack1 + amount: 5 + steps: + - tool: Cutting + doAfter: 1 + + - node: electronics + entity: WindoorAssembly + edges: + - to: windoor + conditions: + - !type:EntityAnchored {} + steps: + - tool: Screwing + doAfter: 2 + + - node: windoor + entity: Windoor + edges: + - to: wired + conditions: + - !type:EntityAnchored {} + - !type:AirlockBolted + value: false + - !type:WirePanel {} + - !type:ContainerNotEmpty # TODO ShadowCommander: Remove when map gets updated + container: board + completed: + - !type:EmptyAllContainers {} + steps: + - tool: Prying + doAfter: 1 + + - node: assemblySecure + entity: WindoorAssemblySecure + actions: + - !type:SnapToGrid { } + - !type:SetAnchor { } + edges: + - to: glassSecure + conditions: + - !type:EntityAnchored { } + steps: + - material: ReinforcedGlass + amount: 5 + doAfter: 1 + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetPlasteel1 + amount: 4 + - !type:DeleteEntity { } + steps: + - tool: Welding + doAfter: 10 + + - node: glassSecure + entity: WindoorAssemblySecure + edges: + - to: wiredSecure + conditions: + - !type:EntityAnchored { } + steps: + - material: Cable + amount: 5 + doAfter: 1 + - to: assemblySecure + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetRGlass1 + amount: 5 + - !type:DeleteEntity { } + steps: + - tool: Screwing + doAfter: 4 + + + - node: wiredSecure + entity: WindoorAssemblySecure + edges: + - to: electronicsSecure + conditions: + - !type:EntityAnchored { } + steps: + - tag: DoorElectronics + store: board + name: "door electronics circuit board" + icon: + sprite: "Objects/Misc/module.rsi" + state: "door_electronics" + doAfter: 1 + - to: glassSecure + completed: + - !type:SpawnPrototype + prototype: CableApcStack1 + amount: 5 + steps: + - tool: Cutting + doAfter: 3 + + - node: electronicsSecure + entity: WindoorAssemblySecure + edges: + - to: windoorSecure + conditions: + - !type:EntityAnchored { } + steps: + - tool: Screwing + doAfter: 4 + + - node: windoorSecure + entity: WindoorSecure + edges: + - to: wired + conditions: + - !type:EntityAnchored {} + - !type:AirlockBolted + value: false + - !type:WirePanel {} + - !type:ContainerNotEmpty # TODO ShadowCommander: Remove when map gets updated + container: board + completed: + - !type:EmptyAllContainers {} + steps: + - tool: Prying + doAfter: 4 diff --git a/Resources/Prototypes/Recipes/Construction/structures.yml b/Resources/Prototypes/Recipes/Construction/structures.yml index 2e52a35875..a9424d1aea 100644 --- a/Resources/Prototypes/Recipes/Construction/structures.yml +++ b/Resources/Prototypes/Recipes/Construction/structures.yml @@ -125,7 +125,7 @@ canRotate: false - type: construction - name: Firelock + name: firelock id: Firelock graph: Firelock startNode: start @@ -142,7 +142,7 @@ - !type:TileNotBlocked {} - type: construction - name: Catwalk + name: catwalk id: Catwalk graph: Catwalk startNode: start @@ -164,7 +164,7 @@ canBuildInImpassable: false - type: construction - name: Wooden Barricade + name: wooden barricade id: Barricade graph: barricade startNode: start @@ -181,7 +181,7 @@ - !type:TileNotBlocked {} - type: construction - name: Airlock + name: airlock id: airlock graph: airlock startNode: start @@ -196,3 +196,37 @@ canBuildInImpassable: false conditions: - !type:TileNotBlocked {} + +- type: construction + name: windoor + id: windoor + graph: windoor + startNode: start + targetNode: windoor + category: Structures + description: It opens, it closes, and you can see through it! + icon: + sprite: Structures/Doors/Windoors/windoor.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked {} + +- type: construction + name: secure windoor + id: secureWindoor + graph: windoor + startNode: start + targetNode: windoorSecure + category: Structures + description: It opens, it closes, and you can see through it! This one looks tough. + icon: + sprite: Structures/Doors/Windoors/windoor.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked {} diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/assembly.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/assembly.png new file mode 100644 index 0000000000..668997d837 Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/assembly.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/bolted_unlit.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/bolted_unlit.png new file mode 100644 index 0000000000..2ca98a410d Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/bolted_unlit.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closed.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closed.png new file mode 100644 index 0000000000..fe1f75ba13 Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closed.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closed_unlit.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closed_unlit.png new file mode 100644 index 0000000000..435a5cb044 Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closed_unlit.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closing.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closing.png new file mode 100644 index 0000000000..e7085665d7 Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closing.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closing_unlit.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closing_unlit.png new file mode 100644 index 0000000000..a7265ce6ec Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/closing_unlit.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/deny_unlit.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/deny_unlit.png new file mode 100644 index 0000000000..aface6a2f6 Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/deny_unlit.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/meta.json b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/meta.json new file mode 100644 index 0000000000..9a8f157fc8 --- /dev/null +++ b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/meta.json @@ -0,0 +1,168 @@ +{ + "version":1, + "license":"CC-BY-SA-3.0", + "copyright":"Taken from tgstation at https://github.com/tgstation/tgstation/blob/3681006d7102045e334e8eddb23a8685fcdb258a/icons/obj/doors/windoor.dmi", + "size": { + "x":32, + "y":32 + }, + "states":[ + { + "name":"assembly", + "directions":4, + "delays":[ + [ + 0.3,0.3 + ], + [ + 0.3,0.3 + ], + [ + 0.3,0.3 + ], + [ + 0.3,0.3 + ] + ] + }, + { + "name":"closed", + "directions":4 + }, + { + "name":"closed_unlit", + "directions":4 + }, + { + "name":"closing", + "directions":4, + "delays":[ + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ] + ] + }, + { + "name":"closing_unlit", + "directions":4, + "delays":[ + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1] + ] + }, + { + "name":"open", + "directions":4 + }, + { + "name":"open_unlit", + "directions":4 + }, + { + "name":"opening", + "directions":4, + "delays":[ + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ] + ] + }, + { + "name":"opening_unlit", + "directions":4, + "delays":[ + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1,0.1 + ] + ] + }, + { + "name":"deny_unlit", + "directions":4, + "delays":[ + [ + 0.1,0.2,0.1 + ], + [ + 0.1,0.2,0.1 + ], + [ + 0.1,0.2,0.1 + ], + [ + 0.1,0.2,0.1 + ] + ] + }, + { + "name":"spark", + "directions":4, + "delays":[ + [ + 0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1 + ], + [ + 0.1,0.1,0.1,0.1,0.1,0.1 + ] + ] + }, + { + "name":"panel_open", + "directions":4 + }, + { + "name":"bolted_unlit", + "directions":4 + }, + { + "name":"welded", + "directions":4 + }, + { + "name":"secure_underlay", + "directions":4 + } + ] +} diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/open.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/open.png new file mode 100644 index 0000000000..2089729a6a Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/open.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/open_unlit.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/open_unlit.png new file mode 100644 index 0000000000..ddcc55de0a Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/open_unlit.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/opening.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/opening.png new file mode 100644 index 0000000000..5b68943ff6 Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/opening.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/opening_unlit.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/opening_unlit.png new file mode 100644 index 0000000000..9a3072db8a Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/opening_unlit.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/panel_open.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/panel_open.png new file mode 100644 index 0000000000..21bbb4dedf Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/panel_open.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/secure_underlay.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/secure_underlay.png new file mode 100644 index 0000000000..e574e9a12c Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/secure_underlay.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/spark.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/spark.png new file mode 100644 index 0000000000..a139b5d3c3 Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/spark.png differ diff --git a/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/welded.png b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/welded.png new file mode 100644 index 0000000000..2975c479be Binary files /dev/null and b/Resources/Textures/Structures/Doors/Windoors/windoor.rsi/welded.png differ