Refactor IDoorCheck into entity events (#4366)
* IDoorCheck refactored to events # Conflicts: # Content.Server/Atmos/TileAtmosphere.cs # Content.Server/Doors/Components/AirlockComponent.cs # Content.Server/Doors/Components/FirelockComponent.cs # Content.Server/Doors/Components/ServerDoorComponent.cs # Content.Server/Doors/IDoorCheck.cs * namespaces * Fix mapinit bug with refreshautoclose * ok i guess these just didnt feel like staging today
This commit is contained in:
@@ -17,15 +17,6 @@ namespace Content.Client.Doors
|
|||||||
{
|
{
|
||||||
private const string AnimationKey = "airlock_animation";
|
private const string AnimationKey = "airlock_animation";
|
||||||
|
|
||||||
[DataField("open_sound", required: true)]
|
|
||||||
private string _openSound = default!;
|
|
||||||
|
|
||||||
[DataField("close_sound", required: true)]
|
|
||||||
private string _closeSound = default!;
|
|
||||||
|
|
||||||
[DataField("deny_sound", required: true)]
|
|
||||||
private string _denySound = default!;
|
|
||||||
|
|
||||||
[DataField("animation_time")]
|
[DataField("animation_time")]
|
||||||
private float _delay = 0.8f;
|
private float _delay = 0.8f;
|
||||||
|
|
||||||
@@ -51,14 +42,6 @@ namespace Content.Client.Doors
|
|||||||
CloseAnimation.AnimationTracks.Add(flickMaintenancePanel);
|
CloseAnimation.AnimationTracks.Add(flickMaintenancePanel);
|
||||||
flickMaintenancePanel.LayerKey = WiresVisualizer.WiresVisualLayers.MaintenancePanel;
|
flickMaintenancePanel.LayerKey = WiresVisualizer.WiresVisualLayers.MaintenancePanel;
|
||||||
flickMaintenancePanel.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("panel_closing", 0f));
|
flickMaintenancePanel.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("panel_closing", 0f));
|
||||||
|
|
||||||
var sound = new AnimationTrackPlaySound();
|
|
||||||
CloseAnimation.AnimationTracks.Add(sound);
|
|
||||||
|
|
||||||
if (_closeSound != null)
|
|
||||||
{
|
|
||||||
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_closeSound, 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(_delay)};
|
OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(_delay)};
|
||||||
@@ -80,11 +63,6 @@ namespace Content.Client.Doors
|
|||||||
|
|
||||||
var sound = new AnimationTrackPlaySound();
|
var sound = new AnimationTrackPlaySound();
|
||||||
OpenAnimation.AnimationTracks.Add(sound);
|
OpenAnimation.AnimationTracks.Add(sound);
|
||||||
|
|
||||||
if (_openSound != null)
|
|
||||||
{
|
|
||||||
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_openSound, 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DenyAnimation = new Animation {Length = TimeSpan.FromSeconds(0.3f)};
|
DenyAnimation = new Animation {Length = TimeSpan.FromSeconds(0.3f)};
|
||||||
@@ -96,11 +74,6 @@ namespace Content.Client.Doors
|
|||||||
|
|
||||||
var sound = new AnimationTrackPlaySound();
|
var sound = new AnimationTrackPlaySound();
|
||||||
DenyAnimation.AnimationTracks.Add(sound);
|
DenyAnimation.AnimationTracks.Add(sound);
|
||||||
|
|
||||||
if (_denySound != null)
|
|
||||||
{
|
|
||||||
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_denySound, 0, () => AudioHelpers.WithVariation(0.05f)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Buffers;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.Atmos.Components;
|
using Content.Server.Atmos.Components;
|
||||||
using Content.Server.Coordinates.Helpers;
|
using Content.Server.Coordinates.Helpers;
|
||||||
|
using Content.Server.Doors.Components;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
|||||||
@@ -7,12 +7,14 @@ using Content.Shared.Doors;
|
|||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Notification;
|
using Content.Shared.Notification;
|
||||||
using Content.Shared.Notification.Managers;
|
using Content.Shared.Notification.Managers;
|
||||||
|
using Content.Shared.Sound;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using static Content.Shared.Wires.SharedWiresComponent;
|
using static Content.Shared.Wires.SharedWiresComponent;
|
||||||
using static Content.Shared.Wires.SharedWiresComponent.WiresAction;
|
using static Content.Shared.Wires.SharedWiresComponent.WiresAction;
|
||||||
@@ -23,30 +25,41 @@ namespace Content.Server.Doors.Components
|
|||||||
/// Companion component to ServerDoorComponent that handles airlock-specific behavior -- wires, requiring power to operate, bolts, and allowing automatic closing.
|
/// Companion component to ServerDoorComponent that handles airlock-specific behavior -- wires, requiring power to operate, bolts, and allowing automatic closing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[ComponentReference(typeof(IDoorCheck))]
|
public class AirlockComponent : Component, IWires
|
||||||
public class AirlockComponent : Component, IWires, IDoorCheck
|
|
||||||
{
|
{
|
||||||
public override string Name => "Airlock";
|
public override string Name => "Airlock";
|
||||||
|
|
||||||
[ComponentDependency]
|
[ComponentDependency]
|
||||||
private readonly ServerDoorComponent? _doorComponent = null;
|
public readonly ServerDoorComponent? DoorComponent = null;
|
||||||
|
|
||||||
[ComponentDependency]
|
[ComponentDependency]
|
||||||
private readonly SharedAppearanceComponent? _appearanceComponent = null;
|
public readonly SharedAppearanceComponent? AppearanceComponent = null;
|
||||||
|
|
||||||
[ComponentDependency]
|
[ComponentDependency]
|
||||||
private readonly ApcPowerReceiverComponent? _receiverComponent = null;
|
public readonly ApcPowerReceiverComponent? ReceiverComponent = null;
|
||||||
|
|
||||||
[ComponentDependency]
|
[ComponentDependency]
|
||||||
private readonly WiresComponent? _wiresComponent = null;
|
public readonly WiresComponent? WiresComponent = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sound to play when the bolts on the airlock go up.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("boltUpSound")]
|
||||||
|
public SoundSpecifier BoltUpSound = new SoundPathSpecifier("/Audio/Machines/boltsup.ogg");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sound to play when the bolts on the airlock go down.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("boltDownSound")]
|
||||||
|
public SoundSpecifier BoltDownSound = new SoundPathSpecifier("/Audio/Machines/boltsdown.ogg");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Duration for which power will be disabled after pulsing either power wire.
|
/// Duration for which power will be disabled after pulsing either power wire.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly TimeSpan PowerWiresTimeout = TimeSpan.FromSeconds(5.0);
|
[DataField("powerWiresTimeout")]
|
||||||
|
public float PowerWiresTimeout = 5.0f;
|
||||||
|
|
||||||
private CancellationTokenSource _powerWiresPulsedTimerCancel = new();
|
private CancellationTokenSource _powerWiresPulsedTimerCancel = new();
|
||||||
|
|
||||||
private bool _powerWiresPulsed;
|
private bool _powerWiresPulsed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -83,7 +96,7 @@ namespace Content.Server.Doors.Components
|
|||||||
private bool BoltLightsVisible
|
private bool BoltLightsVisible
|
||||||
{
|
{
|
||||||
get => _boltLightsWirePulsed && BoltsDown && IsPowered()
|
get => _boltLightsWirePulsed && BoltsDown && IsPowered()
|
||||||
&& _doorComponent != null && _doorComponent.State == SharedDoorComponent.DoorState.Closed;
|
&& DoorComponent != null && DoorComponent.State == SharedDoorComponent.DoorState.Closed;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_boltLightsWirePulsed = value;
|
_boltLightsWirePulsed = value;
|
||||||
@@ -91,120 +104,53 @@ namespace Content.Server.Doors.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly TimeSpan AutoCloseDelayFast = TimeSpan.FromSeconds(1);
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("autoClose")]
|
||||||
|
public bool AutoClose = true;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
private bool _autoClose = true;
|
[DataField("autoCloseDelayModifier")]
|
||||||
|
public float AutoCloseDelayModifier = 1.0f;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
private bool _normalCloseSpeed = true;
|
public bool Safety = true;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
private bool _safety = true;
|
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
if (_receiverComponent != null && _appearanceComponent != null)
|
if (ReceiverComponent != null && AppearanceComponent != null)
|
||||||
{
|
{
|
||||||
_appearanceComponent.SetData(DoorVisuals.Powered, _receiverComponent.Powered);
|
AppearanceComponent.SetData(DoorVisuals.Powered, ReceiverComponent.Powered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, IComponent? component)
|
public bool CanChangeState()
|
||||||
{
|
|
||||||
base.HandleMessage(message, component);
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case PowerChangedMessage powerChanged:
|
|
||||||
PowerDeviceOnOnPowerStateChanged(powerChanged);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IDoorCheck.OnStateChange(SharedDoorComponent.DoorState doorState)
|
|
||||||
{
|
|
||||||
// Only show the maintenance panel if the airlock is closed
|
|
||||||
if (_wiresComponent != null)
|
|
||||||
{
|
|
||||||
_wiresComponent.IsPanelVisible = doorState != SharedDoorComponent.DoorState.Open;
|
|
||||||
}
|
|
||||||
// If the door is closed, we should look if the bolt was locked while closing
|
|
||||||
UpdateBoltLightStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IDoorCheck.OpenCheck() => CanChangeState();
|
|
||||||
|
|
||||||
bool IDoorCheck.CloseCheck() => CanChangeState();
|
|
||||||
|
|
||||||
bool IDoorCheck.DenyCheck() => CanChangeState();
|
|
||||||
|
|
||||||
bool IDoorCheck.SafetyCheck() => _safety;
|
|
||||||
|
|
||||||
bool IDoorCheck.AutoCloseCheck() => _autoClose;
|
|
||||||
|
|
||||||
TimeSpan? IDoorCheck.GetCloseSpeed()
|
|
||||||
{
|
|
||||||
if (_normalCloseSpeed)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return AutoCloseDelayFast;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IDoorCheck.BlockActivate(ActivateEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (_wiresComponent != null && _wiresComponent.IsPanelOpen &&
|
|
||||||
eventArgs.User.TryGetComponent(out ActorComponent? actor))
|
|
||||||
{
|
|
||||||
_wiresComponent.OpenInterface(actor.PlayerSession);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IDoorCheck.CanPryCheck(InteractUsingEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (IsBolted())
|
|
||||||
{
|
|
||||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("airlock-component-cannot-pry-is-bolted-message "));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (IsPowered())
|
|
||||||
{
|
|
||||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("airlock-component-cannot-pry-is-powered-message"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CanChangeState()
|
|
||||||
{
|
{
|
||||||
return IsPowered() && !IsBolted();
|
return IsPowered() && !IsBolted();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsBolted()
|
public bool IsBolted()
|
||||||
{
|
{
|
||||||
return _boltsDown;
|
return _boltsDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsPowered()
|
public bool IsPowered()
|
||||||
{
|
{
|
||||||
return _receiverComponent == null || _receiverComponent.Powered;
|
return ReceiverComponent == null || ReceiverComponent.Powered;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateBoltLightStatus()
|
public void UpdateBoltLightStatus()
|
||||||
{
|
{
|
||||||
if (_appearanceComponent != null)
|
if (AppearanceComponent != null)
|
||||||
{
|
{
|
||||||
_appearanceComponent.SetData(DoorVisuals.BoltLights, BoltLightsVisible);
|
AppearanceComponent.SetData(DoorVisuals.BoltLights, BoltLightsVisible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateWiresStatus()
|
public void UpdateWiresStatus()
|
||||||
{
|
{
|
||||||
if (_doorComponent == null)
|
if (DoorComponent == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -214,9 +160,9 @@ namespace Content.Server.Doors.Components
|
|||||||
{
|
{
|
||||||
powerLight = new StatusLightData(Color.Yellow, StatusLightState.BlinkingFast, "POWR");
|
powerLight = new StatusLightData(Color.Yellow, StatusLightState.BlinkingFast, "POWR");
|
||||||
}
|
}
|
||||||
else if (_wiresComponent != null &&
|
else if (WiresComponent != null &&
|
||||||
_wiresComponent.IsWireCut(Wires.MainPower) &&
|
WiresComponent.IsWireCut(Wires.MainPower) &&
|
||||||
_wiresComponent.IsWireCut(Wires.BackupPower))
|
WiresComponent.IsWireCut(Wires.BackupPower))
|
||||||
{
|
{
|
||||||
powerLight = new StatusLightData(Color.Red, StatusLightState.On, "POWR");
|
powerLight = new StatusLightData(Color.Red, StatusLightState.On, "POWR");
|
||||||
}
|
}
|
||||||
@@ -226,63 +172,59 @@ namespace Content.Server.Doors.Components
|
|||||||
var boltLightsStatus = new StatusLightData(Color.Lime,
|
var boltLightsStatus = new StatusLightData(Color.Lime,
|
||||||
_boltLightsWirePulsed ? StatusLightState.On : StatusLightState.Off, "BLTL");
|
_boltLightsWirePulsed ? StatusLightState.On : StatusLightState.Off, "BLTL");
|
||||||
|
|
||||||
|
var ev = new DoorGetCloseTimeModifierEvent();
|
||||||
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, ev, false);
|
||||||
|
|
||||||
var timingStatus =
|
var timingStatus =
|
||||||
new StatusLightData(Color.Orange, !_autoClose ? StatusLightState.Off :
|
new StatusLightData(Color.Orange, !AutoClose ? StatusLightState.Off :
|
||||||
!_normalCloseSpeed ? StatusLightState.BlinkingSlow :
|
!MathHelper.CloseTo(ev.CloseTimeModifier, 1.0f) ? StatusLightState.BlinkingSlow :
|
||||||
StatusLightState.On,
|
StatusLightState.On,
|
||||||
"TIME");
|
"TIME");
|
||||||
|
|
||||||
var safetyStatus =
|
var safetyStatus =
|
||||||
new StatusLightData(Color.Red, _safety ? StatusLightState.On : StatusLightState.Off, "SAFE");
|
new StatusLightData(Color.Red, Safety ? StatusLightState.On : StatusLightState.Off, "SAFE");
|
||||||
|
|
||||||
if (_wiresComponent == null)
|
if (WiresComponent == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_wiresComponent.SetStatus(AirlockWireStatus.PowerIndicator, powerLight);
|
WiresComponent.SetStatus(AirlockWireStatus.PowerIndicator, powerLight);
|
||||||
_wiresComponent.SetStatus(AirlockWireStatus.BoltIndicator, boltStatus);
|
WiresComponent.SetStatus(AirlockWireStatus.BoltIndicator, boltStatus);
|
||||||
_wiresComponent.SetStatus(AirlockWireStatus.BoltLightIndicator, boltLightsStatus);
|
WiresComponent.SetStatus(AirlockWireStatus.BoltLightIndicator, boltLightsStatus);
|
||||||
_wiresComponent.SetStatus(AirlockWireStatus.AIControlIndicator, new StatusLightData(Color.Purple, StatusLightState.BlinkingSlow, "AICT"));
|
WiresComponent.SetStatus(AirlockWireStatus.AIControlIndicator, new StatusLightData(Color.Purple, StatusLightState.BlinkingSlow, "AICT"));
|
||||||
_wiresComponent.SetStatus(AirlockWireStatus.TimingIndicator, timingStatus);
|
WiresComponent.SetStatus(AirlockWireStatus.TimingIndicator, timingStatus);
|
||||||
_wiresComponent.SetStatus(AirlockWireStatus.SafetyIndicator, safetyStatus);
|
WiresComponent.SetStatus(AirlockWireStatus.SafetyIndicator, safetyStatus);
|
||||||
/*
|
|
||||||
_wires.SetStatus(6, powerLight);
|
|
||||||
_wires.SetStatus(7, powerLight);
|
|
||||||
_wires.SetStatus(8, powerLight);
|
|
||||||
_wires.SetStatus(9, powerLight);
|
|
||||||
_wires.SetStatus(10, powerLight);
|
|
||||||
_wires.SetStatus(11, powerLight);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePowerCutStatus()
|
private void UpdatePowerCutStatus()
|
||||||
{
|
{
|
||||||
if (_receiverComponent == null)
|
if (ReceiverComponent == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PowerWiresPulsed)
|
if (PowerWiresPulsed)
|
||||||
{
|
{
|
||||||
_receiverComponent.PowerDisabled = true;
|
ReceiverComponent.PowerDisabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_wiresComponent == null)
|
if (WiresComponent == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_receiverComponent.PowerDisabled =
|
ReceiverComponent.PowerDisabled =
|
||||||
_wiresComponent.IsWireCut(Wires.MainPower) ||
|
WiresComponent.IsWireCut(Wires.MainPower) ||
|
||||||
_wiresComponent.IsWireCut(Wires.BackupPower);
|
WiresComponent.IsWireCut(Wires.BackupPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PowerDeviceOnOnPowerStateChanged(PowerChangedMessage e)
|
private void PowerDeviceOnOnPowerStateChanged(PowerChangedMessage e)
|
||||||
{
|
{
|
||||||
if (_appearanceComponent != null)
|
if (AppearanceComponent != null)
|
||||||
{
|
{
|
||||||
_appearanceComponent.SetData(DoorVisuals.Powered, e.Powered);
|
AppearanceComponent.SetData(DoorVisuals.Powered, e.Powered);
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoltLights also got out
|
// BoltLights also got out
|
||||||
@@ -341,19 +283,13 @@ namespace Content.Server.Doors.Components
|
|||||||
builder.CreateWire(Wires.BoltLight);
|
builder.CreateWire(Wires.BoltLight);
|
||||||
builder.CreateWire(Wires.Timing);
|
builder.CreateWire(Wires.Timing);
|
||||||
builder.CreateWire(Wires.Safety);
|
builder.CreateWire(Wires.Safety);
|
||||||
/*
|
|
||||||
builder.CreateWire(6);
|
|
||||||
builder.CreateWire(7);
|
|
||||||
builder.CreateWire(8);
|
|
||||||
builder.CreateWire(9);
|
|
||||||
builder.CreateWire(10);
|
|
||||||
builder.CreateWire(11);*/
|
|
||||||
UpdateWiresStatus();
|
UpdateWiresStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WiresUpdate(WiresUpdateEventArgs args)
|
public void WiresUpdate(WiresUpdateEventArgs args)
|
||||||
{
|
{
|
||||||
if(_doorComponent == null)
|
if(DoorComponent == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -367,7 +303,7 @@ namespace Content.Server.Doors.Components
|
|||||||
PowerWiresPulsed = true;
|
PowerWiresPulsed = true;
|
||||||
_powerWiresPulsedTimerCancel.Cancel();
|
_powerWiresPulsedTimerCancel.Cancel();
|
||||||
_powerWiresPulsedTimerCancel = new CancellationTokenSource();
|
_powerWiresPulsedTimerCancel = new CancellationTokenSource();
|
||||||
Owner.SpawnTimer(PowerWiresTimeout,
|
Owner.SpawnTimer(TimeSpan.FromSeconds(PowerWiresTimeout),
|
||||||
() => PowerWiresPulsed = false,
|
() => PowerWiresPulsed = false,
|
||||||
_powerWiresPulsedTimerCancel.Token);
|
_powerWiresPulsedTimerCancel.Token);
|
||||||
break;
|
break;
|
||||||
@@ -390,11 +326,11 @@ namespace Content.Server.Doors.Components
|
|||||||
BoltLightsVisible = !_boltLightsWirePulsed;
|
BoltLightsVisible = !_boltLightsWirePulsed;
|
||||||
break;
|
break;
|
||||||
case Wires.Timing:
|
case Wires.Timing:
|
||||||
_normalCloseSpeed = !_normalCloseSpeed;
|
AutoCloseDelayModifier = 0.5f;
|
||||||
_doorComponent.RefreshAutoClose();
|
DoorComponent.RefreshAutoClose();
|
||||||
break;
|
break;
|
||||||
case Wires.Safety:
|
case Wires.Safety:
|
||||||
_safety = !_safety;
|
Safety = !Safety;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,11 +349,11 @@ namespace Content.Server.Doors.Components
|
|||||||
BoltLightsVisible = true;
|
BoltLightsVisible = true;
|
||||||
break;
|
break;
|
||||||
case Wires.Timing:
|
case Wires.Timing:
|
||||||
_autoClose = true;
|
AutoClose = true;
|
||||||
_doorComponent.RefreshAutoClose();
|
DoorComponent.RefreshAutoClose();
|
||||||
break;
|
break;
|
||||||
case Wires.Safety:
|
case Wires.Safety:
|
||||||
_safety = true;
|
Safety = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,11 +369,11 @@ namespace Content.Server.Doors.Components
|
|||||||
BoltLightsVisible = false;
|
BoltLightsVisible = false;
|
||||||
break;
|
break;
|
||||||
case Wires.Timing:
|
case Wires.Timing:
|
||||||
_autoClose = false;
|
AutoClose = false;
|
||||||
_doorComponent.RefreshAutoClose();
|
DoorComponent.RefreshAutoClose();
|
||||||
break;
|
break;
|
||||||
case Wires.Safety:
|
case Wires.Safety:
|
||||||
_safety = false;
|
Safety = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,7 +391,7 @@ namespace Content.Server.Doors.Components
|
|||||||
|
|
||||||
BoltsDown = newBolts;
|
BoltsDown = newBolts;
|
||||||
|
|
||||||
SoundSystem.Play(Filter.Broadcast(), newBolts ? "/Audio/Machines/boltsdown.ogg" : "/Audio/Machines/boltsup.ogg", Owner);
|
SoundSystem.Play(Filter.Broadcast(), newBolts ? BoltDownSound.GetSound() : BoltUpSound.GetSound(), Owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server.Atmos.Components;
|
||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
using Content.Server.Doors;
|
using Content.Server.Doors;
|
||||||
using Content.Server.Doors.Components;
|
using Content.Server.Doors.Components;
|
||||||
@@ -6,26 +7,34 @@ using Content.Shared.Interaction;
|
|||||||
using Content.Shared.Notification.Managers;
|
using Content.Shared.Notification.Managers;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.Components
|
namespace Content.Server.Doors.Components
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Companion component to ServerDoorComponent that handles firelock-specific behavior -- primarily prying, and not being openable on open-hand click.
|
/// Companion component to ServerDoorComponent that handles firelock-specific behavior -- primarily prying,
|
||||||
|
/// and not being openable on open-hand click.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[ComponentReference(typeof(IDoorCheck))]
|
public class FirelockComponent : Component
|
||||||
public class FirelockComponent : Component, IDoorCheck
|
|
||||||
{
|
{
|
||||||
public override string Name => "Firelock";
|
public override string Name => "Firelock";
|
||||||
|
|
||||||
[ComponentDependency]
|
[ComponentDependency]
|
||||||
private readonly ServerDoorComponent? _doorComponent = null;
|
public readonly ServerDoorComponent? DoorComponent = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pry time modifier to be used when the firelock is currently closed due to fire or pressure.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[DataField("lockedPryTimeModifier")]
|
||||||
|
public float LockedPryTimeModifier = 1.5f;
|
||||||
|
|
||||||
public bool EmergencyPressureStop()
|
public bool EmergencyPressureStop()
|
||||||
{
|
{
|
||||||
if (_doorComponent != null && _doorComponent.State == SharedDoorComponent.DoorState.Open && _doorComponent.CanCloseGeneric())
|
if (DoorComponent != null && DoorComponent.State == SharedDoorComponent.DoorState.Open && DoorComponent.CanCloseGeneric())
|
||||||
{
|
{
|
||||||
_doorComponent.Close();
|
DoorComponent.Close();
|
||||||
if (Owner.TryGetComponent(out AirtightComponent? airtight))
|
if (Owner.TryGetComponent(out AirtightComponent? airtight))
|
||||||
{
|
{
|
||||||
EntitySystem.Get<AirtightSystem>().SetAirblocked(airtight, true);
|
EntitySystem.Get<AirtightSystem>().SetAirblocked(airtight, true);
|
||||||
@@ -35,41 +44,6 @@ namespace Content.Server.Atmos.Components
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IDoorCheck.OpenCheck()
|
|
||||||
{
|
|
||||||
return !IsHoldingFire() && !IsHoldingPressure();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IDoorCheck.DenyCheck() => false;
|
|
||||||
|
|
||||||
float? IDoorCheck.GetPryTime()
|
|
||||||
{
|
|
||||||
if (IsHoldingFire() || IsHoldingPressure())
|
|
||||||
{
|
|
||||||
return 1.5f;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IDoorCheck.BlockActivate(ActivateEventArgs eventArgs) => true;
|
|
||||||
|
|
||||||
void IDoorCheck.OnStartPry(InteractUsingEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (_doorComponent == null || _doorComponent.State != SharedDoorComponent.DoorState.Closed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsHoldingPressure())
|
|
||||||
{
|
|
||||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("firelock-component-is-holding-pressure-message"));
|
|
||||||
}
|
|
||||||
else if (IsHoldingFire())
|
|
||||||
{
|
|
||||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("firelock-component-is-holding-fire-message"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsHoldingPressure(float threshold = 20)
|
public bool IsHoldingPressure(float threshold = 20)
|
||||||
{
|
{
|
||||||
var atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
|
var atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
|
||||||
@@ -14,6 +14,7 @@ using Content.Shared.Damage;
|
|||||||
using Content.Shared.Damage.Components;
|
using Content.Shared.Damage.Components;
|
||||||
using Content.Shared.Doors;
|
using Content.Shared.Doors;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Sound;
|
||||||
using Content.Shared.Tool;
|
using Content.Shared.Tool;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
@@ -37,9 +38,6 @@ namespace Content.Server.Doors.Components
|
|||||||
[ComponentReference(typeof(SharedDoorComponent))]
|
[ComponentReference(typeof(SharedDoorComponent))]
|
||||||
public class ServerDoorComponent : SharedDoorComponent, IActivate, IInteractUsing, IMapInit
|
public class ServerDoorComponent : SharedDoorComponent, IActivate, IInteractUsing, IMapInit
|
||||||
{
|
{
|
||||||
[ComponentDependency]
|
|
||||||
private readonly IDoorCheck? _doorCheck = null;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
[DataField("board")]
|
[DataField("board")]
|
||||||
private string? _boardPrototype;
|
private string? _boardPrototype;
|
||||||
@@ -63,11 +61,8 @@ namespace Content.Server.Doors.Components
|
|||||||
_ => throw new ArgumentOutOfRangeException(),
|
_ => throw new ArgumentOutOfRangeException(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_doorCheck != null)
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, new DoorStateChangedEvent(State), false);
|
||||||
{
|
_autoCloseCancelTokenSource?.Cancel();
|
||||||
_doorCheck.OnStateChange(State);
|
|
||||||
RefreshAutoClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Dirty();
|
Dirty();
|
||||||
}
|
}
|
||||||
@@ -105,7 +100,7 @@ namespace Content.Server.Doors.Components
|
|||||||
/// Handled in Startup().
|
/// Handled in Startup().
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)] [DataField("startOpen")]
|
[ViewVariables(VVAccess.ReadWrite)] [DataField("startOpen")]
|
||||||
private bool _startOpen;
|
private bool _startOpen = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the airlock is welded shut. Can be set by the prototype, although this will fail if the door isn't weldable.
|
/// Whether the airlock is welded shut. Can be set by the prototype, although this will fail if the door isn't weldable.
|
||||||
@@ -139,6 +134,41 @@ namespace Content.Server.Doors.Components
|
|||||||
[DataField("weldable")]
|
[DataField("weldable")]
|
||||||
private bool _weldable = true;
|
private bool _weldable = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sound to play when the door opens.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("openSound")]
|
||||||
|
public SoundSpecifier? OpenSound;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sound to play when the door closes.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("closeSound")]
|
||||||
|
public SoundSpecifier? CloseSound;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sound to play if the door is denied.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("denySound")]
|
||||||
|
public SoundSpecifier? DenySound;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default time that the door should take to pry open.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("pryTime")]
|
||||||
|
public float PryTime = 0.5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Minimum interval allowed between deny sounds in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("denySoundMinimumInterval")]
|
||||||
|
public float DenySoundMinimumInterval = 250.0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to stop people from spamming the deny sound.
|
||||||
|
/// </summary>
|
||||||
|
private TimeSpan LastDenySoundTime = TimeSpan.Zero;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the door can currently be welded.
|
/// Whether the door can currently be welded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -149,6 +179,7 @@ namespace Content.Server.Doors.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private bool _beingWelded;
|
private bool _beingWelded;
|
||||||
|
|
||||||
|
|
||||||
//[ViewVariables(VVAccess.ReadWrite)]
|
//[ViewVariables(VVAccess.ReadWrite)]
|
||||||
//[DataField("canCrush")]
|
//[DataField("canCrush")]
|
||||||
//private bool _canCrush = true; // TODO implement door crushing
|
//private bool _canCrush = true; // TODO implement door crushing
|
||||||
@@ -187,7 +218,7 @@ namespace Content.Server.Doors.Components
|
|||||||
Logger.Warning("{0} prototype loaded with incompatible flags: 'welded' and 'startOpen' are both true.", Owner.Name);
|
Logger.Warning("{0} prototype loaded with incompatible flags: 'welded' and 'startOpen' are both true.", Owner.Name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QuickOpen();
|
QuickOpen(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateDoorElectronicsBoard();
|
CreateDoorElectronicsBoard();
|
||||||
@@ -195,10 +226,10 @@ namespace Content.Server.Doors.Components
|
|||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (_doorCheck != null && _doorCheck.BlockActivate(eventArgs))
|
DoorClickShouldActivateEvent ev = new DoorClickShouldActivateEvent(eventArgs);
|
||||||
{
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, ev, false);
|
||||||
|
if (ev.Handled)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (State == DoorState.Open)
|
if (State == DoorState.Open)
|
||||||
{
|
{
|
||||||
@@ -279,12 +310,10 @@ namespace Content.Server.Doors.Components
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(_doorCheck != null)
|
|
||||||
{
|
|
||||||
return _doorCheck.OpenCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
var ev = new BeforeDoorOpenedEvent();
|
||||||
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, ev, false);
|
||||||
|
return !ev.Cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -301,12 +330,19 @@ namespace Content.Server.Doors.Components
|
|||||||
_stateChangeCancelTokenSource?.Cancel();
|
_stateChangeCancelTokenSource?.Cancel();
|
||||||
_stateChangeCancelTokenSource = new();
|
_stateChangeCancelTokenSource = new();
|
||||||
|
|
||||||
|
if (OpenSound != null)
|
||||||
|
{
|
||||||
|
SoundSystem.Play(Filter.Pvs(Owner), OpenSound.GetSound(),
|
||||||
|
AudioParams.Default.WithVolume(-5));
|
||||||
|
}
|
||||||
|
|
||||||
Owner.SpawnTimer(OpenTimeOne, async () =>
|
Owner.SpawnTimer(OpenTimeOne, async () =>
|
||||||
{
|
{
|
||||||
OnPartialOpen();
|
OnPartialOpen();
|
||||||
await Timer.Delay(OpenTimeTwo, _stateChangeCancelTokenSource.Token);
|
await Timer.Delay(OpenTimeTwo, _stateChangeCancelTokenSource.Token);
|
||||||
|
|
||||||
State = DoorState.Open;
|
State = DoorState.Open;
|
||||||
|
RefreshAutoClose();
|
||||||
}, _stateChangeCancelTokenSource.Token);
|
}, _stateChangeCancelTokenSource.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,7 +356,7 @@ namespace Content.Server.Doors.Components
|
|||||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new AccessReaderChangeMessage(Owner, false));
|
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new AccessReaderChangeMessage(Owner, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void QuickOpen()
|
private void QuickOpen(bool refresh)
|
||||||
{
|
{
|
||||||
if (Occludes && Owner.TryGetComponent(out OccluderComponent? occluder))
|
if (Occludes && Owner.TryGetComponent(out OccluderComponent? occluder))
|
||||||
{
|
{
|
||||||
@@ -328,6 +364,8 @@ namespace Content.Server.Doors.Components
|
|||||||
}
|
}
|
||||||
OnPartialOpen();
|
OnPartialOpen();
|
||||||
State = DoorState.Open;
|
State = DoorState.Open;
|
||||||
|
if(refresh)
|
||||||
|
RefreshAutoClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -366,17 +404,19 @@ namespace Content.Server.Doors.Components
|
|||||||
/// <returns>Boolean describing whether this door can close.</returns>
|
/// <returns>Boolean describing whether this door can close.</returns>
|
||||||
public bool CanCloseGeneric()
|
public bool CanCloseGeneric()
|
||||||
{
|
{
|
||||||
if (_doorCheck != null && !_doorCheck.CloseCheck())
|
var ev = new BeforeDoorClosedEvent();
|
||||||
{
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, ev, false);
|
||||||
|
if (ev.Cancelled)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return !IsSafetyColliding();
|
return !IsSafetyColliding();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SafetyCheck()
|
private bool SafetyCheck()
|
||||||
{
|
{
|
||||||
return (_doorCheck != null && _doorCheck.SafetyCheck()) || _inhibitCrush;
|
var ev = new DoorSafetyEnabledEvent();
|
||||||
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, ev, false);
|
||||||
|
return ev.Safety || _inhibitCrush;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -412,6 +452,13 @@ namespace Content.Server.Doors.Components
|
|||||||
|
|
||||||
_stateChangeCancelTokenSource?.Cancel();
|
_stateChangeCancelTokenSource?.Cancel();
|
||||||
_stateChangeCancelTokenSource = new();
|
_stateChangeCancelTokenSource = new();
|
||||||
|
|
||||||
|
if (CloseSound != null)
|
||||||
|
{
|
||||||
|
SoundSystem.Play(Filter.Pvs(Owner), CloseSound.GetSound(),
|
||||||
|
AudioParams.Default.WithVolume(-10));
|
||||||
|
}
|
||||||
|
|
||||||
Owner.SpawnTimer(CloseTimeOne, async () =>
|
Owner.SpawnTimer(CloseTimeOne, async () =>
|
||||||
{
|
{
|
||||||
// if somebody walked into the door as it was closing, and we don't crush things
|
// if somebody walked into the door as it was closing, and we don't crush things
|
||||||
@@ -504,10 +551,10 @@ namespace Content.Server.Doors.Components
|
|||||||
|
|
||||||
public void Deny()
|
public void Deny()
|
||||||
{
|
{
|
||||||
if (_doorCheck != null && !_doorCheck.DenyCheck())
|
var ev = new BeforeDoorDeniedEvent();
|
||||||
{
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, ev, false);
|
||||||
|
if (ev.Cancelled)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (State == DoorState.Open || IsWeldedShut)
|
if (State == DoorState.Open || IsWeldedShut)
|
||||||
return;
|
return;
|
||||||
@@ -515,6 +562,25 @@ namespace Content.Server.Doors.Components
|
|||||||
_stateChangeCancelTokenSource?.Cancel();
|
_stateChangeCancelTokenSource?.Cancel();
|
||||||
_stateChangeCancelTokenSource = new();
|
_stateChangeCancelTokenSource = new();
|
||||||
SetAppearance(DoorVisualState.Deny);
|
SetAppearance(DoorVisualState.Deny);
|
||||||
|
|
||||||
|
if (DenySound != null)
|
||||||
|
{
|
||||||
|
if (LastDenySoundTime == TimeSpan.Zero)
|
||||||
|
{
|
||||||
|
LastDenySoundTime = _gameTiming.CurTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var difference = _gameTiming.CurTime - LastDenySoundTime;
|
||||||
|
if (difference < TimeSpan.FromMilliseconds(DenySoundMinimumInterval))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastDenySoundTime = _gameTiming.CurTime;
|
||||||
|
SoundSystem.Play(Filter.Pvs(Owner), DenySound.GetSound(),
|
||||||
|
AudioParams.Default.WithVolume(-3));
|
||||||
|
}
|
||||||
|
|
||||||
Owner.SpawnTimer(DenyTime, () =>
|
Owner.SpawnTimer(DenyTime, () =>
|
||||||
{
|
{
|
||||||
SetAppearance(DoorVisualState.Closed);
|
SetAppearance(DoorVisualState.Closed);
|
||||||
@@ -522,19 +588,24 @@ namespace Content.Server.Doors.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stops the current auto-close timer if there is one. Starts a new one if this is appropriate (i.e. entity has an IDoorCheck component that allows auto-closing).
|
/// Starts a new auto close timer if this is appropriate
|
||||||
|
/// (i.e. event raised is not cancelled).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RefreshAutoClose()
|
public void RefreshAutoClose()
|
||||||
{
|
{
|
||||||
_autoCloseCancelTokenSource?.Cancel();
|
if (State != DoorState.Open)
|
||||||
|
|
||||||
if (State != DoorState.Open || _doorCheck == null || !_doorCheck.AutoCloseCheck())
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
var autoev = new BeforeDoorAutoCloseEvent();
|
||||||
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, autoev, false);
|
||||||
|
if (autoev.Cancelled)
|
||||||
|
return;
|
||||||
|
|
||||||
_autoCloseCancelTokenSource = new();
|
_autoCloseCancelTokenSource = new();
|
||||||
|
|
||||||
var realCloseTime = _doorCheck.GetCloseSpeed() ?? AutoCloseDelay;
|
var ev = new DoorGetCloseTimeModifierEvent();
|
||||||
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, ev, false);
|
||||||
|
var realCloseTime = AutoCloseDelay * ev.CloseTimeModifier;
|
||||||
|
|
||||||
Owner.SpawnRepeatingTimer(realCloseTime, async () =>
|
Owner.SpawnRepeatingTimer(realCloseTime, async () =>
|
||||||
{
|
{
|
||||||
@@ -556,21 +627,18 @@ namespace Content.Server.Doors.Components
|
|||||||
// for prying doors
|
// for prying doors
|
||||||
if (tool.HasQuality(ToolQuality.Prying) && !IsWeldedShut)
|
if (tool.HasQuality(ToolQuality.Prying) && !IsWeldedShut)
|
||||||
{
|
{
|
||||||
var successfulPry = false;
|
var ev = new DoorGetPryTimeModifierEvent();
|
||||||
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, ev, false);
|
||||||
|
|
||||||
if (_doorCheck != null)
|
var canEv = new BeforeDoorPryEvent(eventArgs);
|
||||||
{
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, canEv, false);
|
||||||
_doorCheck.OnStartPry(eventArgs);
|
|
||||||
successfulPry = await tool.UseTool(eventArgs.User, Owner,
|
var successfulPry = await tool.UseTool(eventArgs.User, Owner,
|
||||||
_doorCheck.GetPryTime() ?? 0.5f, ToolQuality.Prying, () => _doorCheck.CanPryCheck(eventArgs));
|
ev.PryTimeModifier * PryTime, ToolQuality.Prying, () => !canEv.Cancelled);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
successfulPry = await tool.UseTool(eventArgs.User, Owner, 0.5f, ToolQuality.Prying);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (successfulPry && !IsWeldedShut)
|
if (successfulPry && !IsWeldedShut)
|
||||||
{
|
{
|
||||||
|
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, new OnDoorPryEvent(eventArgs), false);
|
||||||
if (State == DoorState.Closed)
|
if (State == DoorState.Closed)
|
||||||
{
|
{
|
||||||
Open();
|
Open();
|
||||||
|
|||||||
141
Content.Server/Doors/DoorEvents.cs
Normal file
141
Content.Server/Doors/DoorEvents.cs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using Content.Shared.Doors;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Doors
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the door's State variable is changed to a new variable that it was not equal to before.
|
||||||
|
/// </summary>
|
||||||
|
public class DoorStateChangedEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public SharedDoorComponent.DoorState State;
|
||||||
|
|
||||||
|
public DoorStateChangedEvent(SharedDoorComponent.DoorState state)
|
||||||
|
{
|
||||||
|
State = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the door is determining whether it is able to open.
|
||||||
|
/// Cancel to stop the door from being opened.
|
||||||
|
/// </summary>
|
||||||
|
public class BeforeDoorOpenedEvent : CancellableEntityEventArgs
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the door is successfully opened.
|
||||||
|
/// </summary>
|
||||||
|
public class OnDoorOpenedEvent : HandledEntityEventArgs
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the door is determining whether it is able to close.
|
||||||
|
/// Cancel to stop the door from being closed.
|
||||||
|
/// </summary>
|
||||||
|
public class BeforeDoorClosedEvent : CancellableEntityEventArgs
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the door is successfully closed.
|
||||||
|
/// </summary>
|
||||||
|
public class OnDoorClosedEvent : HandledEntityEventArgs
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the door is determining whether it is able to deny.
|
||||||
|
/// Cancel to stop the door from being able to deny.
|
||||||
|
/// </summary>
|
||||||
|
public class BeforeDoorDeniedEvent : CancellableEntityEventArgs
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when access to the door is denied.
|
||||||
|
/// </summary>
|
||||||
|
public class OnDoorDeniedEvent : HandledEntityEventArgs
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised to determine whether the door's safety is on.
|
||||||
|
/// Modify Safety to set the door's safety.
|
||||||
|
/// </summary>
|
||||||
|
public class DoorSafetyEnabledEvent : HandledEntityEventArgs
|
||||||
|
{
|
||||||
|
public bool Safety = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised to determine whether the door should automatically close.
|
||||||
|
/// Cancel to stop it from automatically closing.
|
||||||
|
/// </summary>
|
||||||
|
public class BeforeDoorAutoCloseEvent : CancellableEntityEventArgs
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised to determine how long the door's pry time should be modified by.
|
||||||
|
/// Multiply PryTimeModifier by the desired amount.
|
||||||
|
/// </summary>
|
||||||
|
public class DoorGetPryTimeModifierEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public float PryTimeModifier = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised to determine how long the door's close time should be modified by.
|
||||||
|
/// Multiply CloseTimeModifier by the desired amount.
|
||||||
|
/// </summary>
|
||||||
|
public class DoorGetCloseTimeModifierEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public float CloseTimeModifier = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised to determine whether clicking the door should open/close it.
|
||||||
|
/// </summary>
|
||||||
|
public class DoorClickShouldActivateEvent : HandledEntityEventArgs
|
||||||
|
{
|
||||||
|
public ActivateEventArgs Args;
|
||||||
|
|
||||||
|
public DoorClickShouldActivateEvent(ActivateEventArgs args)
|
||||||
|
{
|
||||||
|
Args = args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when an attempt to pry open the door is made.
|
||||||
|
/// Cancel to stop the door from being pried open.
|
||||||
|
/// </summary>
|
||||||
|
public class BeforeDoorPryEvent : CancellableEntityEventArgs
|
||||||
|
{
|
||||||
|
public InteractUsingEventArgs Args;
|
||||||
|
|
||||||
|
public BeforeDoorPryEvent(InteractUsingEventArgs args)
|
||||||
|
{
|
||||||
|
Args = args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when a door is successfully pried open.
|
||||||
|
/// </summary>
|
||||||
|
public class OnDoorPryEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public InteractUsingEventArgs Args;
|
||||||
|
|
||||||
|
public OnDoorPryEvent(InteractUsingEventArgs args)
|
||||||
|
{
|
||||||
|
Args = args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.Doors;
|
|
||||||
using Content.Shared.Interaction;
|
|
||||||
|
|
||||||
namespace Content.Server.Doors
|
|
||||||
{
|
|
||||||
public interface IDoorCheck
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Called when the door's State variable is changed to a new variable that it was not equal to before.
|
|
||||||
/// </summary>
|
|
||||||
void OnStateChange(SharedDoorComponent.DoorState doorState) { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when the door is determining whether it is able to open.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the door should open, false if it should not.</returns>
|
|
||||||
bool OpenCheck() => true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when the door is determining whether it is able to close.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the door should close, false if it should not.</returns>
|
|
||||||
bool CloseCheck() => true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when the door is determining whether it is able to deny.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the door should deny, false if it should not.</returns>
|
|
||||||
bool DenyCheck() => true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the door's safety is on.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if safety is on, false if it is not.</returns>
|
|
||||||
bool SafetyCheck() => false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the door should close automatically.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the door should close automatically, false if it should not.</returns>
|
|
||||||
bool AutoCloseCheck() => false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets an override for the amount of time to pry open the door, or null if there is no override.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Float if there is an override, null otherwise.</returns>
|
|
||||||
float? GetPryTime() => null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets an override for the amount of time before the door automatically closes, or null if there is no override.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>TimeSpan if there is an override, null otherwise.</returns>
|
|
||||||
TimeSpan? GetCloseSpeed() => null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A check to determine whether or not a click on the door should interact with it with the intent to open/close.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the door's IActivate should not run, false otherwise.</returns>
|
|
||||||
bool BlockActivate(ActivateEventArgs eventArgs) => false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when somebody begins to pry open the door.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="eventArgs">The eventArgs of the InteractUsing method that called this function.</param>
|
|
||||||
void OnStartPry(InteractUsingEventArgs eventArgs) { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check representing whether or not the door can be pried open.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="eventArgs">The eventArgs of the InteractUsing method that called this function.</param>
|
|
||||||
/// <returns>True if the door can be pried open, false if it cannot.</returns>
|
|
||||||
bool CanPryCheck(InteractUsingEventArgs eventArgs) => true;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
109
Content.Server/Doors/Systems/AirlockSystem.cs
Normal file
109
Content.Server/Doors/Systems/AirlockSystem.cs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
using Content.Server.Doors.Components;
|
||||||
|
using Content.Server.Power.Components;
|
||||||
|
using Content.Shared.Doors;
|
||||||
|
using Content.Shared.Notification.Managers;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
|
||||||
|
namespace Content.Server.Doors.Systems
|
||||||
|
{
|
||||||
|
public class AirlockSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<AirlockComponent, PowerChangedEvent>(OnPowerChanged);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, DoorStateChangedEvent>(OnStateChanged);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, BeforeDoorOpenedEvent>(OnBeforeDoorOpened);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, BeforeDoorClosedEvent>(OnBeforeDoorClosed);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, BeforeDoorDeniedEvent>(OnBeforeDoorDenied);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, DoorSafetyEnabledEvent>(OnDoorSafetyCheck);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, BeforeDoorAutoCloseEvent>(OnDoorAutoCloseCheck);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, DoorGetCloseTimeModifierEvent>(OnDoorCloseTimeModifier);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, DoorClickShouldActivateEvent>(OnDoorClickShouldActivate);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, BeforeDoorPryEvent>(OnDoorPry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPowerChanged(EntityUid uid, AirlockComponent component, PowerChangedEvent args)
|
||||||
|
{
|
||||||
|
if (component.AppearanceComponent != null)
|
||||||
|
{
|
||||||
|
component.AppearanceComponent.SetData(DoorVisuals.Powered, args.Powered);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoltLights also got out
|
||||||
|
component.UpdateBoltLightStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStateChanged(EntityUid uid, AirlockComponent component, DoorStateChangedEvent args)
|
||||||
|
{
|
||||||
|
// Only show the maintenance panel if the airlock is closed
|
||||||
|
if (component.WiresComponent != null)
|
||||||
|
{
|
||||||
|
component.WiresComponent.IsPanelVisible = args.State != SharedDoorComponent.DoorState.Open;
|
||||||
|
}
|
||||||
|
// If the door is closed, we should look if the bolt was locked while closing
|
||||||
|
component.UpdateBoltLightStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBeforeDoorOpened(EntityUid uid, AirlockComponent component, BeforeDoorOpenedEvent args)
|
||||||
|
{
|
||||||
|
if (!component.CanChangeState())
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBeforeDoorClosed(EntityUid uid, AirlockComponent component, BeforeDoorClosedEvent args)
|
||||||
|
{
|
||||||
|
if (!component.CanChangeState())
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBeforeDoorDenied(EntityUid uid, AirlockComponent component, BeforeDoorDeniedEvent args)
|
||||||
|
{
|
||||||
|
if (!component.CanChangeState())
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoorSafetyCheck(EntityUid uid, AirlockComponent component, DoorSafetyEnabledEvent args)
|
||||||
|
{
|
||||||
|
args.Safety = component.Safety;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoorAutoCloseCheck(EntityUid uid, AirlockComponent component, BeforeDoorAutoCloseEvent args)
|
||||||
|
{
|
||||||
|
if (!component.AutoClose)
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoorCloseTimeModifier(EntityUid uid, AirlockComponent component, DoorGetCloseTimeModifierEvent args)
|
||||||
|
{
|
||||||
|
args.CloseTimeModifier *= component.AutoCloseDelayModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoorClickShouldActivate(EntityUid uid, AirlockComponent component, DoorClickShouldActivateEvent args)
|
||||||
|
{
|
||||||
|
if (component.WiresComponent != null && component.WiresComponent.IsPanelOpen &&
|
||||||
|
args.Args.User.TryGetComponent(out ActorComponent? actor))
|
||||||
|
{
|
||||||
|
component.WiresComponent.OpenInterface(actor.PlayerSession);
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoorPry(EntityUid uid, AirlockComponent component, BeforeDoorPryEvent args)
|
||||||
|
{
|
||||||
|
if (component.IsBolted())
|
||||||
|
{
|
||||||
|
component.Owner.PopupMessage(args.Args.User, Loc.GetString("airlock-component-cannot-pry-is-bolted-message"));
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
if (component.IsPowered())
|
||||||
|
{
|
||||||
|
component.Owner.PopupMessage(args.Args.User, Loc.GetString("airlock-component-cannot-pry-is-powered-message"));
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
Content.Server/Doors/Systems/FirelockSystem.cs
Normal file
69
Content.Server/Doors/Systems/FirelockSystem.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using Content.Server.Doors.Components;
|
||||||
|
using Content.Shared.Doors;
|
||||||
|
using Content.Shared.Notification.Managers;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
|
||||||
|
namespace Content.Server.Doors.Systems
|
||||||
|
{
|
||||||
|
public class FirelockSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<FirelockComponent, BeforeDoorOpenedEvent>(OnBeforeDoorOpened);
|
||||||
|
SubscribeLocalEvent<FirelockComponent, BeforeDoorDeniedEvent>(OnBeforeDoorDenied);
|
||||||
|
SubscribeLocalEvent<FirelockComponent, DoorGetPryTimeModifierEvent>(OnDoorGetPryTimeModifier);
|
||||||
|
SubscribeLocalEvent<FirelockComponent, DoorClickShouldActivateEvent>(OnDoorClickShouldActivate);
|
||||||
|
SubscribeLocalEvent<FirelockComponent, BeforeDoorPryEvent>(OnBeforeDoorPry);
|
||||||
|
SubscribeLocalEvent<FirelockComponent, BeforeDoorAutoCloseEvent>(OnBeforeDoorAutoclose);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBeforeDoorOpened(EntityUid uid, FirelockComponent component, BeforeDoorOpenedEvent args)
|
||||||
|
{
|
||||||
|
if (component.IsHoldingFire() || component.IsHoldingPressure())
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBeforeDoorDenied(EntityUid uid, FirelockComponent component, BeforeDoorDeniedEvent args)
|
||||||
|
{
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoorGetPryTimeModifier(EntityUid uid, FirelockComponent component, DoorGetPryTimeModifierEvent args)
|
||||||
|
{
|
||||||
|
if (component.IsHoldingFire() || component.IsHoldingPressure())
|
||||||
|
args.PryTimeModifier *= component.LockedPryTimeModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoorClickShouldActivate(EntityUid uid, FirelockComponent component, DoorClickShouldActivateEvent args)
|
||||||
|
{
|
||||||
|
// We're a firelock, you can't click to open it
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBeforeDoorPry(EntityUid uid, FirelockComponent component, BeforeDoorPryEvent args)
|
||||||
|
{
|
||||||
|
if (component.DoorComponent == null || component.DoorComponent.State != SharedDoorComponent.DoorState.Closed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.IsHoldingPressure())
|
||||||
|
{
|
||||||
|
component.Owner.PopupMessage(args.Args.User, Loc.GetString("firelock-component-is-holding-pressure-message"));
|
||||||
|
}
|
||||||
|
else if (component.IsHoldingFire())
|
||||||
|
{
|
||||||
|
component.Owner.PopupMessage(args.Args.User, Loc.GetString("firelock-component-is-holding-fire-message"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBeforeDoorAutoclose(EntityUid uid, FirelockComponent component, BeforeDoorAutoCloseEvent args)
|
||||||
|
{
|
||||||
|
// Firelocks can't autoclose, they must be manually closed
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,9 @@ namespace Content.Shared.Doors
|
|||||||
[ComponentDependency]
|
[ComponentDependency]
|
||||||
protected readonly IPhysBody? PhysicsComponent = null;
|
protected readonly IPhysBody? PhysicsComponent = null;
|
||||||
|
|
||||||
|
[Dependency]
|
||||||
|
protected readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private DoorState _state = DoorState.Closed;
|
private DoorState _state = DoorState.Closed;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -38,13 +38,16 @@
|
|||||||
- SmallImpassable
|
- SmallImpassable
|
||||||
- type: Door
|
- type: Door
|
||||||
board: DoorElectronics
|
board: DoorElectronics
|
||||||
|
openSound:
|
||||||
|
path: /Audio/Machines/airlock_open.ogg
|
||||||
|
closeSound:
|
||||||
|
path: /Audio/Machines/airlock_close.ogg
|
||||||
|
denySound:
|
||||||
|
path: /Audio/Machines/airlock_deny.ogg
|
||||||
- type: Airlock
|
- type: Airlock
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
visuals:
|
||||||
- type: AirlockVisualizer
|
- type: AirlockVisualizer
|
||||||
open_sound: /Audio/Machines/airlock_open.ogg
|
|
||||||
close_sound: /Audio/Machines/airlock_close.ogg
|
|
||||||
deny_sound: /Audio/Machines/airlock_deny.ogg
|
|
||||||
- type: WiresVisualizer
|
- type: WiresVisualizer
|
||||||
- type: ApcPowerReceiver
|
- type: ApcPowerReceiver
|
||||||
- type: Wires
|
- type: Wires
|
||||||
|
|||||||
@@ -6,12 +6,15 @@
|
|||||||
components:
|
components:
|
||||||
- type: Door
|
- type: Door
|
||||||
bumpOpen: false
|
bumpOpen: false
|
||||||
|
openSound:
|
||||||
|
path: /Audio/Machines/airlock_ext_open.ogg
|
||||||
|
closeSound:
|
||||||
|
path: /Audio/Machines/airlock_ext_close.ogg
|
||||||
|
denySound:
|
||||||
|
path: /Audio/Machines/airlock_deny.ogg
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Structures/Doors/Airlocks/Standard/external.rsi
|
sprite: Structures/Doors/Airlocks/Standard/external.rsi
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
visuals:
|
||||||
- type: AirlockVisualizer
|
- type: AirlockVisualizer
|
||||||
open_sound: /Audio/Machines/airlock_ext_open.ogg
|
|
||||||
close_sound: /Audio/Machines/airlock_ext_close.ogg
|
|
||||||
deny_sound: /Audio/Machines/airlock_deny.ogg
|
|
||||||
- type: WiresVisualizer
|
- type: WiresVisualizer
|
||||||
|
|||||||
@@ -54,13 +54,16 @@
|
|||||||
startOpen: true
|
startOpen: true
|
||||||
bumpOpen: false
|
bumpOpen: false
|
||||||
inhibitCrush: false
|
inhibitCrush: false
|
||||||
|
openSound:
|
||||||
|
path: /Audio/Machines/airlock_open.ogg
|
||||||
|
closeSound:
|
||||||
|
path: /Audio/Machines/airlock_close.ogg
|
||||||
|
denySound:
|
||||||
|
path: /Audio/Machines/airlock_deny.ogg
|
||||||
- type: Firelock
|
- type: Firelock
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
visuals:
|
||||||
- type: AirlockVisualizer
|
- type: AirlockVisualizer
|
||||||
open_sound: /Audio/Machines/airlock_open.ogg
|
|
||||||
close_sound: /Audio/Machines/airlock_close.ogg
|
|
||||||
deny_sound: /Audio/Machines/airlock_deny.ogg
|
|
||||||
animation_time: 0.6
|
animation_time: 0.6
|
||||||
- type: WiresVisualizer
|
- type: WiresVisualizer
|
||||||
- type: Wires
|
- type: Wires
|
||||||
|
|||||||
Reference in New Issue
Block a user