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