From f779755c118354dd4984dbb27d128fd2655db513 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sun, 17 Mar 2019 13:24:26 +0100 Subject: [PATCH] Doors are now automated. --- .../Components/Doors/AirlockVisualizer2D.cs | 47 +++++++++++- .../Components/Doors/ServerDoorComponent.cs | 71 +++++++++++++------ 2 files changed, 93 insertions(+), 25 deletions(-) diff --git a/Content.Client/GameObjects/Components/Doors/AirlockVisualizer2D.cs b/Content.Client/GameObjects/Components/Doors/AirlockVisualizer2D.cs index 8496bdf640..933dfe468c 100644 --- a/Content.Client/GameObjects/Components/Doors/AirlockVisualizer2D.cs +++ b/Content.Client/GameObjects/Components/Doors/AirlockVisualizer2D.cs @@ -1,29 +1,48 @@ using System; using Content.Shared.GameObjects.Components.Doors; +using SS14.Client.Animations; using SS14.Client.GameObjects; +using SS14.Client.GameObjects.Components.Animations; using SS14.Client.Interfaces.GameObjects.Components; +using SS14.Shared.Interfaces.GameObjects; namespace Content.Client.GameObjects.Components.Doors { public class AirlockVisualizer2D : AppearanceVisualizer { + private const string AnimationKey = "airlock_animation"; + + public override void InitializeEntity(IEntity entity) + { + if (!entity.HasComponent()) + { + entity.AddComponent(); + } + } + public override void OnChangeData(AppearanceComponent component) { - base.OnChangeData(component); - var sprite = component.Owner.GetComponent(); + var animPlayer = component.Owner.GetComponent(); if (!component.TryGetData(DoorVisuals.VisualState, out DoorVisualState state)) { state = DoorVisualState.Closed; } + // TODO: need some sorta state to prevent resetting the animation if it's already playing. + // Because right now that could happen. + animPlayer.Stop(AnimationKey); switch (state) { case DoorVisualState.Closed: - case DoorVisualState.Closing: sprite.LayerSetState(DoorVisualLayers.Base, "closed"); break; + case DoorVisualState.Closing: + animPlayer.Play(CloseAnimation, AnimationKey); + break; case DoorVisualState.Opening: + animPlayer.Play(OpenAnimation, AnimationKey); + break; case DoorVisualState.Open: sprite.LayerSetState(DoorVisualLayers.Base, "open"); break; @@ -31,6 +50,28 @@ namespace Content.Client.GameObjects.Components.Doors throw new ArgumentOutOfRangeException(); } } + + private static readonly Animation CloseAnimation; + private static readonly Animation OpenAnimation; + + static AirlockVisualizer2D() + { + CloseAnimation = new Animation {Length = TimeSpan.FromSeconds(1.2f)}; + { + var flick = new AnimationTrackSpriteFlick(); + CloseAnimation.AnimationTracks.Add(flick); + flick.LayerKey = DoorVisualLayers.Base; + flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("closing", 0f)); + } + + OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(1.2f)}; + { + var flick = new AnimationTrackSpriteFlick(); + OpenAnimation.AnimationTracks.Add(flick); + flick.LayerKey = DoorVisualLayers.Base; + flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("opening", 0f)); + } + } } public enum DoorVisualLayers diff --git a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs index 3687dd8f30..e3f72fb3db 100644 --- a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs @@ -1,32 +1,30 @@ using System; -using Content.Server.Interfaces.GameObjects; -using Content.Shared.GameObjects; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects.Components.Doors; using SS14.Server.GameObjects; using SS14.Shared.GameObjects; using SS14.Shared.Interfaces.GameObjects; -using SS14.Shared.Interfaces.GameObjects.Components; -using SS14.Shared.Log; -using SS14.Shared.Maths; -using SS14.Shared.IoC; -using Content.Server.GameObjects.EntitySystems; -using Content.Shared.GameObjects.Components.Doors; -using SS14.Shared.Serialization; using SS14.Shared.Interfaces.Network; -using SS14.Shared.ViewVariables; +using SS14.Shared.Maths; +using SS14.Shared.Timers; namespace Content.Server.GameObjects { public class ServerDoorComponent : Component, IAttackHand { public override string Name => "Door"; - [ViewVariables] - public bool Opened { get; private set; } + + private DoorState _state = DoorState.Closed; private float OpenTimeCounter; private CollidableComponent collidableComponent; private AppearanceComponent _appearance; + private static readonly TimeSpan CloseTime = TimeSpan.FromSeconds(1.2f); + private static readonly TimeSpan OpenTimeOne = TimeSpan.FromSeconds(0.3f); + private static readonly TimeSpan OpenTimeTwo = TimeSpan.FromSeconds(0.9f); + public override void Initialize() { base.Initialize(); @@ -45,11 +43,11 @@ namespace Content.Server.GameObjects public bool Attackhand(IEntity user) { - if (Opened) + if (_state == DoorState.Open) { Close(); } - else + else if (_state == DoorState.Closed) { Open(); } @@ -63,7 +61,7 @@ namespace Content.Server.GameObjects switch (message) { case BumpedEntMsg msg: - if (Opened) + if (_state != DoorState.Closed) { return; } @@ -75,9 +73,23 @@ namespace Content.Server.GameObjects public void Open() { - Opened = true; - collidableComponent.IsHardCollidable = false; - _appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Open); + if (_state != DoorState.Closed) + { + return; + } + + _state = DoorState.Opening; + _appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Opening); + + Timer.Spawn(OpenTimeOne, async () => + { + collidableComponent.IsHardCollidable = false; + + await Timer.Delay(OpenTimeTwo); + + _state = DoorState.Open; + _appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Open); + }); } public bool Close() @@ -87,17 +99,24 @@ namespace Content.Server.GameObjects // Do nothing, somebody's in the door. return false; } - Opened = false; - OpenTimeCounter = 0; + + _state = DoorState.Closing; collidableComponent.IsHardCollidable = true; - _appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closed); + OpenTimeCounter = 0; + _appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closing); + + Timer.Spawn(CloseTime, () => + { + _state = DoorState.Closed; + _appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closed); + }); return true; } private const float AUTO_CLOSE_DELAY = 5; public void OnUpdate(float frameTime) { - if (!Opened) + if (_state != DoorState.Open) { return; } @@ -112,5 +131,13 @@ namespace Content.Server.GameObjects } } } + + private enum DoorState + { + Closed, + Open, + Closing, + Opening, + } } }