144 lines
3.9 KiB
C#
144 lines
3.9 KiB
C#
using System;
|
|
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.Network;
|
|
using SS14.Shared.Maths;
|
|
using SS14.Shared.Timers;
|
|
|
|
namespace Content.Server.GameObjects
|
|
{
|
|
public class ServerDoorComponent : Component, IAttackHand
|
|
{
|
|
public override string Name => "Door";
|
|
|
|
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();
|
|
|
|
collidableComponent = Owner.GetComponent<CollidableComponent>();
|
|
_appearance = Owner.GetComponent<AppearanceComponent>();
|
|
}
|
|
|
|
public override void OnRemove()
|
|
{
|
|
collidableComponent = null;
|
|
_appearance = null;
|
|
|
|
base.OnRemove();
|
|
}
|
|
|
|
public bool Attackhand(IEntity user)
|
|
{
|
|
if (_state == DoorState.Open)
|
|
{
|
|
Close();
|
|
}
|
|
else if (_state == DoorState.Closed)
|
|
{
|
|
Open();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
|
{
|
|
base.HandleMessage(message, netChannel, component);
|
|
|
|
switch (message)
|
|
{
|
|
case BumpedEntMsg msg:
|
|
if (_state != DoorState.Closed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Open();
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void 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()
|
|
{
|
|
if (collidableComponent.TryCollision(Vector2.Zero))
|
|
{
|
|
// Do nothing, somebody's in the door.
|
|
return false;
|
|
}
|
|
|
|
_state = DoorState.Closing;
|
|
collidableComponent.IsHardCollidable = true;
|
|
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 (_state != DoorState.Open)
|
|
{
|
|
return;
|
|
}
|
|
|
|
OpenTimeCounter += frameTime;
|
|
if (OpenTimeCounter > AUTO_CLOSE_DELAY)
|
|
{
|
|
if (!Close())
|
|
{
|
|
// Try again in 2 seconds if it's jammed or something.
|
|
OpenTimeCounter -= 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
private enum DoorState
|
|
{
|
|
Closed,
|
|
Open,
|
|
Closing,
|
|
Opening,
|
|
}
|
|
}
|
|
}
|