Airlock hacking (#329)
* Airlock hacking * Added status text * Whoops don't need this * Update Content.Server/GameObjects/Components/Doors/AirlockComponent.cs Co-Authored-By: Pieter-Jan Briers <pieterjan.briers@gmail.com> * ComponentReference ServerDoorComponent * Suggested name
This commit is contained in:
committed by
Pieter-Jan Briers
parent
34f4731c9b
commit
36078382e4
191
Content.Server/GameObjects/Components/Doors/AirlockComponent.cs
Normal file
191
Content.Server/GameObjects/Components/Doors/AirlockComponent.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Content.Server.GameObjects.Components.Interactable.Tools;
|
||||
using Content.Server.GameObjects.Components.Power;
|
||||
using Content.Server.GameObjects.Components.VendingMachines;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent.WiresAction;
|
||||
using Timer = Robust.Shared.Timers.Timer;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Doors
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IActivate))]
|
||||
[ComponentReference(typeof(ServerDoorComponent))]
|
||||
public class AirlockComponent : ServerDoorComponent, IWires, IAttackBy
|
||||
{
|
||||
public override string Name => "Airlock";
|
||||
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly ILocalizationManager _localizationMgr;
|
||||
#pragma warning restore 649
|
||||
|
||||
/// <summary>
|
||||
/// Duration for which power will be disabled after pulsing either power wire.
|
||||
/// </summary>
|
||||
private static readonly TimeSpan PowerWiresTimeout = TimeSpan.FromSeconds(5.0);
|
||||
|
||||
private PowerDeviceComponent _powerDevice;
|
||||
private WiresComponent _wires;
|
||||
|
||||
private CancellationTokenSource _powerWiresPulsedTimerCancel;
|
||||
|
||||
private bool _powerWiresPulsed;
|
||||
/// <summary>
|
||||
/// True if either power wire was pulsed in the last <see cref="PowerWiresTimeout"/>.
|
||||
/// </summary>
|
||||
private bool PowerWiresPulsed
|
||||
{
|
||||
get => _powerWiresPulsed;
|
||||
set
|
||||
{
|
||||
_powerWiresPulsed = value;
|
||||
UpdateWiresStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateWiresStatus()
|
||||
{
|
||||
var powerMessage = "A yellow light is on.";
|
||||
if (_powerWiresPulsed)
|
||||
{
|
||||
powerMessage = "A yellow light is blinking rapidly.";
|
||||
} else if (_wires.IsWireCut(Wires.MainPower) &&
|
||||
_wires.IsWireCut(Wires.BackupPower))
|
||||
{
|
||||
powerMessage = "A red light is on.";
|
||||
}
|
||||
_wires.SetStatus(WiresStatus.PowerIndicator, _localizationMgr.GetString(powerMessage));
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_powerDevice = Owner.GetComponent<PowerDeviceComponent>();
|
||||
_wires = Owner.GetComponent<WiresComponent>();
|
||||
}
|
||||
|
||||
protected override void ActivateImpl(ActivateEventArgs args)
|
||||
{
|
||||
if (_wires.IsOpen)
|
||||
{
|
||||
if (args.User.TryGetComponent(out IActorComponent actor))
|
||||
{
|
||||
_wires.OpenInterface(actor.playerSession);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base.ActivateImpl(args);
|
||||
}
|
||||
}
|
||||
|
||||
private enum Wires
|
||||
{
|
||||
/// <summary>
|
||||
/// Pulsing turns off power for <see cref="AirlockComponent.PowerWiresTimeout"/>.
|
||||
/// Cutting turns off power permanently if <see cref="BackupPower"/> is also cut.
|
||||
/// Mending restores power.
|
||||
/// </summary>
|
||||
MainPower,
|
||||
/// <see cref="MainPower"/>
|
||||
BackupPower,
|
||||
}
|
||||
|
||||
private enum WiresStatus
|
||||
{
|
||||
PowerIndicator,
|
||||
}
|
||||
|
||||
public void RegisterWires(WiresComponent.WiresBuilder builder)
|
||||
{
|
||||
builder.CreateWire(Wires.MainPower);
|
||||
builder.CreateWire(Wires.BackupPower);
|
||||
UpdateWiresStatus();
|
||||
}
|
||||
|
||||
public void WiresUpdate(WiresUpdateEventArgs args)
|
||||
{
|
||||
if (args.Action == Pulse)
|
||||
{
|
||||
switch (args.Identifier)
|
||||
{
|
||||
case Wires.MainPower:
|
||||
case Wires.BackupPower:
|
||||
PowerWiresPulsed = true;
|
||||
_powerWiresPulsedTimerCancel?.Cancel();
|
||||
_powerWiresPulsedTimerCancel = new CancellationTokenSource();
|
||||
Timer.Spawn(PowerWiresTimeout,
|
||||
() => PowerWiresPulsed = false,
|
||||
_powerWiresPulsedTimerCancel.Token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.Action == Mend)
|
||||
{
|
||||
switch (args.Identifier)
|
||||
{
|
||||
case Wires.MainPower:
|
||||
case Wires.BackupPower:
|
||||
// mending power wires instantly restores power
|
||||
_powerWiresPulsedTimerCancel?.Cancel();
|
||||
PowerWiresPulsed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateWiresStatus();
|
||||
}
|
||||
|
||||
public override bool CanOpen()
|
||||
{
|
||||
return IsPowered();
|
||||
}
|
||||
|
||||
public override void Deny()
|
||||
{
|
||||
if (!IsPowered())
|
||||
{
|
||||
return;
|
||||
}
|
||||
base.Deny();
|
||||
}
|
||||
|
||||
private bool IsPowered()
|
||||
{
|
||||
if (PowerWiresPulsed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (_wires.IsWireCut(Wires.MainPower) &&
|
||||
_wires.IsWireCut(Wires.BackupPower))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return _powerDevice.Powered;
|
||||
}
|
||||
|
||||
public bool AttackBy(AttackByEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.AttackWith.HasComponent<CrowbarComponent>() && !IsPowered())
|
||||
{
|
||||
if (_state == DoorState.Closed)
|
||||
{
|
||||
Open();
|
||||
}
|
||||
else if(_state == DoorState.Open)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace Content.Server.GameObjects
|
||||
{
|
||||
public override string Name => "Door";
|
||||
|
||||
private DoorState _state = DoorState.Closed;
|
||||
protected DoorState _state = DoorState.Closed;
|
||||
|
||||
private float OpenTimeCounter;
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Content.Server.GameObjects
|
||||
base.OnRemove();
|
||||
}
|
||||
|
||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||
protected virtual void ActivateImpl(ActivateEventArgs eventArgs)
|
||||
{
|
||||
if (_state == DoorState.Open)
|
||||
{
|
||||
@@ -57,6 +57,11 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||
{
|
||||
ActivateImpl(eventArgs);
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||
{
|
||||
base.HandleMessage(message, netChannel, component);
|
||||
@@ -80,15 +85,27 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanOpen()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanOpen(IEntity user)
|
||||
{
|
||||
if (!CanOpen()) return false;
|
||||
if (!Owner.TryGetComponent(out AccessReader accessReader))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return accessReader.IsAllowed(user);
|
||||
}
|
||||
|
||||
public void TryOpen(IEntity user)
|
||||
{
|
||||
if (Owner.TryGetComponent(out AccessReader accessReader))
|
||||
if (!CanOpen(user))
|
||||
{
|
||||
if (!accessReader.IsAllowed(user))
|
||||
{
|
||||
Deny();
|
||||
return;
|
||||
}
|
||||
Deny();
|
||||
return;
|
||||
}
|
||||
Open();
|
||||
}
|
||||
@@ -135,7 +152,7 @@ namespace Content.Server.GameObjects
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Deny()
|
||||
public virtual void Deny()
|
||||
{
|
||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Deny);
|
||||
Timer.Spawn(DenyTime, () =>
|
||||
@@ -145,7 +162,7 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
|
||||
private const float AUTO_CLOSE_DELAY = 5;
|
||||
public void OnUpdate(float frameTime)
|
||||
public virtual void OnUpdate(float frameTime)
|
||||
{
|
||||
if (_state != DoorState.Open)
|
||||
{
|
||||
@@ -163,7 +180,7 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
private enum DoorState
|
||||
protected enum DoorState
|
||||
{
|
||||
Closed,
|
||||
Open,
|
||||
|
||||
Reference in New Issue
Block a user