diff --git a/Content.Client/Content.Client.csproj b/Content.Client/Content.Client.csproj
index 0ee6c4f572..d73805adbb 100644
--- a/Content.Client/Content.Client.csproj
+++ b/Content.Client/Content.Client.csproj
@@ -63,6 +63,7 @@
+
@@ -98,4 +99,4 @@
-
\ No newline at end of file
+
diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs
index 2514b1deb6..a05012f210 100644
--- a/Content.Client/EntryPoint.cs
+++ b/Content.Client/EntryPoint.cs
@@ -21,6 +21,8 @@ namespace Content.Client
factory.Register();
factory.RegisterReference();
+
+ factory.Register();
}
}
}
diff --git a/Content.Client/GameObjects/Components/Doors/ClientDoorComponent.cs b/Content.Client/GameObjects/Components/Doors/ClientDoorComponent.cs
new file mode 100644
index 0000000000..00f4f9315c
--- /dev/null
+++ b/Content.Client/GameObjects/Components/Doors/ClientDoorComponent.cs
@@ -0,0 +1,71 @@
+using Content.Shared.GameObjects;
+using Lidgren.Network;
+using SS14.Client.GameObjects;
+using SS14.Shared.GameObjects;
+using SS14.Shared.Utility;
+using YamlDotNet.RepresentationModel;
+
+namespace Content.Client.GameObjects
+{
+ public class ClientDoorComponent : SharedDoorComponent
+ {
+ public bool Opened { get; private set; }
+ private SpriteComponent spriteComponent;
+
+ private string OpenSprite = "door_ewo";
+ private string CloseSprite = "door_ew";
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ spriteComponent = Owner.GetComponent();
+ }
+
+ private void Open()
+ {
+ Opened = true;
+ spriteComponent.SetSpriteByKey(OpenSprite);
+ }
+
+ private void Close()
+ {
+ Opened = false;
+ spriteComponent.SetSpriteByKey(CloseSprite);
+ }
+
+ public override void HandleComponentState(ComponentState state)
+ {
+ var castState = (DoorComponentState)state;
+ if (castState.Opened == Opened)
+ {
+ return;
+ }
+
+ if (castState.Opened)
+ {
+ Open();
+ }
+ else
+ {
+ Close();
+ }
+ }
+
+ public override void LoadParameters(YamlMappingNode mapping)
+ {
+ base.LoadParameters(mapping);
+
+ YamlNode node;
+ if (mapping.TryGetNode("openstate", out node))
+ {
+ OpenSprite = node.AsString();
+ }
+
+ if (mapping.TryGetNode("closestate", out node))
+ {
+ CloseSprite = node.AsString();
+ }
+ }
+ }
+}
diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj
index e6e25054f4..8d58127e11 100644
--- a/Content.Server/Content.Server.csproj
+++ b/Content.Server/Content.Server.csproj
@@ -56,6 +56,7 @@
+
diff --git a/Content.Server/EntryPoint.cs b/Content.Server/EntryPoint.cs
index 1075573c64..dae7cb70d9 100644
--- a/Content.Server/EntryPoint.cs
+++ b/Content.Server/EntryPoint.cs
@@ -27,6 +27,7 @@ namespace Content.Server
factory.Register();
factory.Register();
factory.Register();
+ factory.Register();
}
}
}
diff --git a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs
new file mode 100644
index 0000000000..50d279c681
--- /dev/null
+++ b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs
@@ -0,0 +1,104 @@
+using Content.Server.Interfaces.GameObjects;
+using Content.Shared.GameObjects;
+using SS14.Server.GameObjects;
+using SS14.Shared.GameObjects;
+using SS14.Shared.Interfaces.GameObjects.Components;
+using SS14.Shared.Log;
+using SS14.Shared.Maths;
+
+namespace Content.Server.GameObjects
+{
+ public class ServerDoorComponent : SharedDoorComponent
+ {
+ public bool Opened { get; private set; }
+
+ private float OpenTimeCounter;
+
+ private IInteractableComponent interactableComponent;
+ private CollidableComponent collidableComponent;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ interactableComponent = Owner.GetComponent();
+ interactableComponent.OnAttackHand += OnAttackHand;
+ collidableComponent = Owner.GetComponent();
+ collidableComponent.OnBump += OnBump;
+ }
+
+ public override void OnRemove()
+ {
+ interactableComponent.OnAttackHand -= OnAttackHand;
+ interactableComponent = null;
+ collidableComponent.OnBump -= OnBump;
+ collidableComponent = null;
+ }
+
+ private void OnAttackHand(object sender, AttackHandEventArgs args)
+ {
+ if (Opened)
+ {
+ Close();
+ }
+ else
+ {
+ Open();
+ }
+ }
+
+ private void OnBump(object sender, BumpEventArgs args)
+ {
+ Logger.Info("Bump!");
+ if (Opened)
+ {
+ return;
+ }
+
+ Open();
+ }
+
+ public void Open()
+ {
+ Opened = true;
+ collidableComponent.IsHardCollidable = false;
+ }
+
+ public bool Close()
+ {
+ if (collidableComponent.TryCollision(Vector2.Zero))
+ {
+ // Do nothing, somebody's in the door.
+ return false;
+ }
+ Opened = false;
+ OpenTimeCounter = 0;
+ collidableComponent.IsHardCollidable = true;
+ return true;
+ }
+
+ public override ComponentState GetComponentState()
+ {
+ return new DoorComponentState(Opened);
+ }
+
+ private const float AUTO_CLOSE_DELAY = 5;
+ public override void Update(float frameTime)
+ {
+ if (!Opened)
+ {
+ return;
+ }
+
+ OpenTimeCounter += frameTime;
+ if (OpenTimeCounter > AUTO_CLOSE_DELAY)
+ {
+ if (!Close())
+ {
+ // Try again in 2 seconds if it's jammed or something.
+ OpenTimeCounter -= 2;
+ }
+ }
+ }
+ }
+}
diff --git a/Content.Shared/Content.Shared.csproj b/Content.Shared/Content.Shared.csproj
index bd366e7ba7..20f38254d5 100644
--- a/Content.Shared/Content.Shared.csproj
+++ b/Content.Shared/Content.Shared.csproj
@@ -55,6 +55,7 @@
+
diff --git a/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs b/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs
new file mode 100644
index 0000000000..4a939daad1
--- /dev/null
+++ b/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs
@@ -0,0 +1,23 @@
+using System;
+using SS14.Shared.GameObjects;
+
+namespace Content.Shared.GameObjects
+{
+ public abstract class SharedDoorComponent : Component
+ {
+ public override string Name => "Door";
+ public override uint? NetID => ContentNetIDs.DOOR;
+ public override Type StateType => typeof(DoorComponentState);
+ }
+
+ [Serializable]
+ public class DoorComponentState : ComponentState
+ {
+ public readonly bool Opened;
+
+ public DoorComponentState(bool opened) : base(ContentNetIDs.DOOR)
+ {
+ Opened = opened;
+ }
+ }
+}
diff --git a/Content.Shared/GameObjects/ContentNetIDs.cs b/Content.Shared/GameObjects/ContentNetIDs.cs
index 9d67fe9038..905c08c640 100644
--- a/Content.Shared/GameObjects/ContentNetIDs.cs
+++ b/Content.Shared/GameObjects/ContentNetIDs.cs
@@ -7,5 +7,6 @@
public const uint DESTRUCTIBLE = 1001;
public const uint TEMPERATURE = 1002;
public const uint HANDS = 1003;
+ public const uint DOOR = 1004;
}
}
diff --git a/Resources/Prototypes/Entities/Clothing.yml b/Resources/Prototypes/Entities/Clothing.yml
index d6958811ec..5f4ec1b3ae 100644
--- a/Resources/Prototypes/Entities/Clothing.yml
+++ b/Resources/Prototypes/Entities/Clothing.yml
@@ -7,6 +7,9 @@
sprite: player_shoes
notWornSprite: shoes
+ - type: Icon
+ icon: shoes
+
- type: entity
parent: BaseItem
id: JanitorUniformItem
@@ -15,3 +18,6 @@
- type: WearableAnimatedSprite
sprite: player_jumpsuit_gray
notWornSprite: janitorsuit
+
+ - type: Icon
+ icon: janitorsuit
diff --git a/Resources/Prototypes/Entities/Door.yml b/Resources/Prototypes/Entities/Door.yml
new file mode 100644
index 0000000000..fea4e841d6
--- /dev/null
+++ b/Resources/Prototypes/Entities/Door.yml
@@ -0,0 +1,25 @@
+- type: entity
+ id: DoorContent
+ name: Actual door
+ components:
+ - type: Transform
+ - type: Clickable
+ - type: Interactable
+ - type: Sprite
+ drawdepth: FloorPlaceable
+ sprites:
+ - door_ew
+ - door_ewo
+
+ - type: Icon
+ icon: door_ew
+
+ - type: BoundingBox
+ sizeX: 1.9
+ offsetY: 1.5
+ - type: Collidable
+ - type: Door
+
+ placement:
+ snap:
+ - Wall