Resolves AirlockVisualizer is Obsolete (#13884)
This commit is contained in:
@@ -1,5 +1,112 @@
|
|||||||
|
using Content.Client.Wires.Visualizers;
|
||||||
|
using Content.Shared.Doors.Components;
|
||||||
using Content.Shared.Doors.Systems;
|
using Content.Shared.Doors.Systems;
|
||||||
|
using Robust.Client.Animations;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
|
||||||
namespace Content.Client.Doors;
|
namespace Content.Client.Doors;
|
||||||
|
|
||||||
public sealed class AirlockSystem : SharedAirlockSystem { }
|
public sealed class AirlockSystem : SharedAirlockSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<AirlockComponent, ComponentStartup>(OnComponentStartup);
|
||||||
|
SubscribeLocalEvent<AirlockComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnComponentStartup(EntityUid uid, AirlockComponent comp, ComponentStartup args)
|
||||||
|
{
|
||||||
|
// Has to be on component startup because we don't know what order components initialize in and running this before DoorComponent inits _will_ crash.
|
||||||
|
if(!TryComp<DoorComponent>(uid, out var door))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (comp.OpenUnlitVisible) // Otherwise there are flashes of the fallback sprite between clicking on the door and the door closing animation starting.
|
||||||
|
{
|
||||||
|
door.OpenSpriteStates.Add((DoorVisualLayers.BaseUnlit, comp.OpenSpriteState));
|
||||||
|
door.ClosedSpriteStates.Add((DoorVisualLayers.BaseUnlit, comp.ClosedSpriteState));
|
||||||
|
}
|
||||||
|
|
||||||
|
((Animation)door.OpeningAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
|
||||||
|
{
|
||||||
|
LayerKey = DoorVisualLayers.BaseUnlit,
|
||||||
|
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningSpriteState, 0f) },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
((Animation)door.ClosingAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
|
||||||
|
{
|
||||||
|
LayerKey = DoorVisualLayers.BaseUnlit,
|
||||||
|
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingSpriteState, 0f) },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
door.DenyingAnimation = new Animation()
|
||||||
|
{
|
||||||
|
Length = TimeSpan.FromSeconds(comp.DenyAnimationTime),
|
||||||
|
AnimationTracks =
|
||||||
|
{
|
||||||
|
new AnimationTrackSpriteFlick()
|
||||||
|
{
|
||||||
|
LayerKey = DoorVisualLayers.BaseUnlit,
|
||||||
|
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.DenySpriteState, 0f) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!comp.AnimatePanel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
((Animation)door.OpeningAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
|
||||||
|
{
|
||||||
|
LayerKey = WiresVisualLayers.MaintenancePanel,
|
||||||
|
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningPanelSpriteState, 0f)},
|
||||||
|
});
|
||||||
|
|
||||||
|
((Animation)door.ClosingAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick
|
||||||
|
{
|
||||||
|
LayerKey = WiresVisualLayers.MaintenancePanel,
|
||||||
|
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingPanelSpriteState, 0f)},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAppearanceChange(EntityUid uid, AirlockComponent comp, ref AppearanceChangeEvent args)
|
||||||
|
{
|
||||||
|
if (args.Sprite == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var boltedVisible = false;
|
||||||
|
var emergencyLightsVisible = false;
|
||||||
|
var unlitVisible = false;
|
||||||
|
|
||||||
|
if (!_appearanceSystem.TryGetData<DoorState>(uid, DoorVisuals.State, out var state, args.Component))
|
||||||
|
state = DoorState.Closed;
|
||||||
|
|
||||||
|
if (_appearanceSystem.TryGetData<bool>(uid, DoorVisuals.Powered, out var powered, args.Component) && powered)
|
||||||
|
{
|
||||||
|
boltedVisible = _appearanceSystem.TryGetData<bool>(uid, DoorVisuals.BoltLights, out var lights, args.Component) && lights;
|
||||||
|
emergencyLightsVisible = _appearanceSystem.TryGetData<bool>(uid, DoorVisuals.EmergencyLights, out var eaLights, args.Component) && eaLights;
|
||||||
|
unlitVisible =
|
||||||
|
state == DoorState.Closing
|
||||||
|
|| state == DoorState.Opening
|
||||||
|
|| state == DoorState.Denying
|
||||||
|
|| (state == DoorState.Open && comp.OpenUnlitVisible)
|
||||||
|
|| (_appearanceSystem.TryGetData<bool>(uid, DoorVisuals.ClosedLights, out var closedLights, args.Component) && closedLights);
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible);
|
||||||
|
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, boltedVisible);
|
||||||
|
if (comp.EmergencyAccessLayer)
|
||||||
|
{
|
||||||
|
args.Sprite.LayerSetVisible(
|
||||||
|
DoorVisualLayers.BaseEmergencyAccess,
|
||||||
|
emergencyLightsVisible
|
||||||
|
&& state != DoorState.Open
|
||||||
|
&& state != DoorState.Opening
|
||||||
|
&& state != DoorState.Closing
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,256 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Client.Wires.Visualizers;
|
|
||||||
using Content.Shared.Doors.Components;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.Animations;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.ResourceManagement;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
|
||||||
using Robust.Shared.Timing;
|
|
||||||
|
|
||||||
namespace Content.Client.Doors
|
|
||||||
{
|
|
||||||
[UsedImplicitly]
|
|
||||||
public sealed class AirlockVisualizer : AppearanceVisualizer, ISerializationHooks
|
|
||||||
{
|
|
||||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
|
||||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
|
||||||
|
|
||||||
private const string AnimationKey = "airlock_animation";
|
|
||||||
|
|
||||||
[DataField("animationTime")]
|
|
||||||
private float _delay = 0.8f;
|
|
||||||
|
|
||||||
[DataField("denyAnimationTime")]
|
|
||||||
private float _denyDelay = 0.3f;
|
|
||||||
|
|
||||||
|
|
||||||
[DataField("emagAnimationTime")]
|
|
||||||
private float _delayEmag = 1.5f;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the maintenance panel is animated or stays static.
|
|
||||||
/// False for windoors.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("animatedPanel")]
|
|
||||||
private bool _animatedPanel = true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Means the door is simply open / closed / opening / closing. No wires or access.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("simpleVisuals")]
|
|
||||||
private bool _simpleVisuals = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the BaseUnlit layer should still be visible when the airlock
|
|
||||||
/// is opened.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("openUnlitVisible")]
|
|
||||||
private bool _openUnlitVisible = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the door should have an emergency access layer
|
|
||||||
/// </summary>
|
|
||||||
[DataField("emergencyAccessLayer")]
|
|
||||||
private bool _emergencyAccessLayer = true;
|
|
||||||
|
|
||||||
private Animation CloseAnimation = default!;
|
|
||||||
private Animation OpenAnimation = default!;
|
|
||||||
private Animation DenyAnimation = default!;
|
|
||||||
private Animation EmaggingAnimation = default!;
|
|
||||||
|
|
||||||
void ISerializationHooks.AfterDeserialization()
|
|
||||||
{
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
CloseAnimation = new Animation { Length = TimeSpan.FromSeconds(_delay) };
|
|
||||||
{
|
|
||||||
var flick = new AnimationTrackSpriteFlick();
|
|
||||||
CloseAnimation.AnimationTracks.Add(flick);
|
|
||||||
flick.LayerKey = DoorVisualLayers.Base;
|
|
||||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("closing", 0f));
|
|
||||||
|
|
||||||
if (!_simpleVisuals)
|
|
||||||
{
|
|
||||||
var flickUnlit = new AnimationTrackSpriteFlick();
|
|
||||||
CloseAnimation.AnimationTracks.Add(flickUnlit);
|
|
||||||
flickUnlit.LayerKey = DoorVisualLayers.BaseUnlit;
|
|
||||||
flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("closing_unlit", 0f));
|
|
||||||
|
|
||||||
if (_animatedPanel)
|
|
||||||
{
|
|
||||||
var flickMaintenancePanel = new AnimationTrackSpriteFlick();
|
|
||||||
CloseAnimation.AnimationTracks.Add(flickMaintenancePanel);
|
|
||||||
flickMaintenancePanel.LayerKey = WiresVisualLayers.MaintenancePanel;
|
|
||||||
flickMaintenancePanel.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("panel_closing", 0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenAnimation = new Animation { Length = TimeSpan.FromSeconds(_delay) };
|
|
||||||
{
|
|
||||||
var flick = new AnimationTrackSpriteFlick();
|
|
||||||
OpenAnimation.AnimationTracks.Add(flick);
|
|
||||||
flick.LayerKey = DoorVisualLayers.Base;
|
|
||||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("opening", 0f));
|
|
||||||
|
|
||||||
if (!_simpleVisuals)
|
|
||||||
{
|
|
||||||
var flickUnlit = new AnimationTrackSpriteFlick();
|
|
||||||
OpenAnimation.AnimationTracks.Add(flickUnlit);
|
|
||||||
flickUnlit.LayerKey = DoorVisualLayers.BaseUnlit;
|
|
||||||
flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("opening_unlit", 0f));
|
|
||||||
|
|
||||||
if (_animatedPanel)
|
|
||||||
{
|
|
||||||
var flickMaintenancePanel = new AnimationTrackSpriteFlick();
|
|
||||||
OpenAnimation.AnimationTracks.Add(flickMaintenancePanel);
|
|
||||||
flickMaintenancePanel.LayerKey = WiresVisualLayers.MaintenancePanel;
|
|
||||||
flickMaintenancePanel.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("panel_opening", 0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EmaggingAnimation = new Animation { Length = TimeSpan.FromSeconds(_delay) };
|
|
||||||
{
|
|
||||||
var flickUnlit = new AnimationTrackSpriteFlick();
|
|
||||||
EmaggingAnimation.AnimationTracks.Add(flickUnlit);
|
|
||||||
flickUnlit.LayerKey = DoorVisualLayers.BaseUnlit;
|
|
||||||
flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("sparks", 0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_simpleVisuals)
|
|
||||||
{
|
|
||||||
DenyAnimation = new Animation { Length = TimeSpan.FromSeconds(_denyDelay) };
|
|
||||||
{
|
|
||||||
var flick = new AnimationTrackSpriteFlick();
|
|
||||||
DenyAnimation.AnimationTracks.Add(flick);
|
|
||||||
flick.LayerKey = DoorVisualLayers.BaseUnlit;
|
|
||||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("deny_unlit", 0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Obsolete("Subscribe to your component being initialised instead.")]
|
|
||||||
public override void InitializeEntity(EntityUid entity)
|
|
||||||
{
|
|
||||||
if (!_entMan.HasComponent<AnimationPlayerComponent>(entity))
|
|
||||||
{
|
|
||||||
_entMan.AddComponent<AnimationPlayerComponent>(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Obsolete("Subscribe to AppearanceChangeEvent instead.")]
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
// only start playing animations once.
|
|
||||||
if (!_gameTiming.IsFirstTimePredicted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
var sprite = _entMan.GetComponent<SpriteComponent>(component.Owner);
|
|
||||||
var animPlayer = _entMan.GetComponent<AnimationPlayerComponent>(component.Owner);
|
|
||||||
if (!component.TryGetData(DoorVisuals.State, out DoorState state))
|
|
||||||
{
|
|
||||||
state = DoorState.Closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
var door = _entMan.GetComponent<DoorComponent>(component.Owner);
|
|
||||||
|
|
||||||
if (component.TryGetData(DoorVisuals.BaseRSI, out string baseRsi))
|
|
||||||
{
|
|
||||||
if (!_resourceCache.TryGetResource<RSIResource>(SharedSpriteComponent.TextureRoot / baseRsi, out var res))
|
|
||||||
{
|
|
||||||
Logger.Error("Unable to load RSI '{0}'. Trace:\n{1}", baseRsi, Environment.StackTrace);
|
|
||||||
}
|
|
||||||
foreach (ISpriteLayer layer in sprite.AllLayers)
|
|
||||||
{
|
|
||||||
layer.Rsi = res?.RSI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animPlayer.HasRunningAnimation(AnimationKey))
|
|
||||||
{
|
|
||||||
animPlayer.Stop(AnimationKey);
|
|
||||||
}
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case DoorState.Open:
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.Base, "open");
|
|
||||||
if (_openUnlitVisible && !_simpleVisuals)
|
|
||||||
{
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.BaseUnlit, "open_unlit");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DoorState.Closed:
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.Base, "closed");
|
|
||||||
if (!_simpleVisuals)
|
|
||||||
{
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.BaseUnlit, "closed_unlit");
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.BaseBolted, "bolted_unlit");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DoorState.Opening:
|
|
||||||
animPlayer.Play(OpenAnimation, AnimationKey);
|
|
||||||
break;
|
|
||||||
case DoorState.Closing:
|
|
||||||
if (door.CurrentlyCrushing.Count == 0)
|
|
||||||
animPlayer.Play(CloseAnimation, AnimationKey);
|
|
||||||
else
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.Base, "closed");
|
|
||||||
break;
|
|
||||||
case DoorState.Denying:
|
|
||||||
animPlayer.Play(DenyAnimation, AnimationKey);
|
|
||||||
break;
|
|
||||||
case DoorState.Welded:
|
|
||||||
break;
|
|
||||||
case DoorState.Emagging:
|
|
||||||
animPlayer.Play(EmaggingAnimation, AnimationKey);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_simpleVisuals)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var boltedVisible = false;
|
|
||||||
var emergencyLightsVisible = false;
|
|
||||||
var unlitVisible = false;
|
|
||||||
|
|
||||||
if (component.TryGetData(DoorVisuals.Powered, out bool powered) && powered)
|
|
||||||
{
|
|
||||||
boltedVisible = component.TryGetData(DoorVisuals.BoltLights, out bool lights) && lights;
|
|
||||||
emergencyLightsVisible = component.TryGetData(DoorVisuals.EmergencyLights, out bool eaLights) && eaLights;
|
|
||||||
unlitVisible = state == DoorState.Closing
|
|
||||||
|| state == DoorState.Opening
|
|
||||||
|| state == DoorState.Denying
|
|
||||||
|| state == DoorState.Open && _openUnlitVisible
|
|
||||||
|| (component.TryGetData(DoorVisuals.ClosedLights, out bool closedLights) && closedLights);
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible);
|
|
||||||
sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, boltedVisible);
|
|
||||||
if (_emergencyAccessLayer)
|
|
||||||
{
|
|
||||||
sprite.LayerSetVisible(DoorVisualLayers.BaseEmergencyAccess,
|
|
||||||
emergencyLightsVisible
|
|
||||||
&& state != DoorState.Open
|
|
||||||
&& state != DoorState.Opening
|
|
||||||
&& state != DoorState.Closing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum DoorVisualLayers : byte
|
|
||||||
{
|
|
||||||
Base,
|
|
||||||
BaseUnlit,
|
|
||||||
BaseBolted,
|
|
||||||
BaseEmergencyAccess,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +1,135 @@
|
|||||||
using Content.Shared.Doors.Components;
|
using Content.Shared.Doors.Components;
|
||||||
using Content.Shared.Doors.Systems;
|
using Content.Shared.Doors.Systems;
|
||||||
|
using Robust.Client.Animations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Client.Doors;
|
namespace Content.Client.Doors;
|
||||||
|
|
||||||
public sealed class DoorSystem : SharedDoorSystem
|
public sealed class DoorSystem : SharedDoorSystem
|
||||||
{
|
{
|
||||||
// Gotta love it when both the client-side and server-side sprite components both have a draw depth, but for
|
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
|
||||||
// whatever bloody reason the shared component doesn't.
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
protected override void UpdateAppearance(EntityUid uid, DoorComponent? door = null)
|
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref door))
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<DoorComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnComponentInit(EntityUid uid, DoorComponent comp, ComponentInit args)
|
||||||
|
{
|
||||||
|
comp.OpenSpriteStates = new(2);
|
||||||
|
comp.ClosedSpriteStates = new(2);
|
||||||
|
|
||||||
|
comp.OpenSpriteStates.Add((DoorVisualLayers.Base, comp.OpenSpriteState));
|
||||||
|
comp.ClosedSpriteStates.Add((DoorVisualLayers.Base, comp.ClosedSpriteState));
|
||||||
|
|
||||||
|
comp.OpeningAnimation = new Animation()
|
||||||
|
{
|
||||||
|
Length = TimeSpan.FromSeconds(comp.OpeningAnimationTime),
|
||||||
|
AnimationTracks =
|
||||||
|
{
|
||||||
|
new AnimationTrackSpriteFlick()
|
||||||
|
{
|
||||||
|
LayerKey = DoorVisualLayers.Base,
|
||||||
|
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningSpriteState, 0f) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
comp.ClosingAnimation = new Animation()
|
||||||
|
{
|
||||||
|
Length = TimeSpan.FromSeconds(comp.ClosingAnimationTime),
|
||||||
|
AnimationTracks =
|
||||||
|
{
|
||||||
|
new AnimationTrackSpriteFlick()
|
||||||
|
{
|
||||||
|
LayerKey = DoorVisualLayers.Base,
|
||||||
|
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingSpriteState, 0f) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
comp.EmaggingAnimation = new Animation ()
|
||||||
|
{
|
||||||
|
Length = TimeSpan.FromSeconds(comp.EmaggingAnimationTime),
|
||||||
|
AnimationTracks =
|
||||||
|
{
|
||||||
|
new AnimationTrackSpriteFlick()
|
||||||
|
{
|
||||||
|
LayerKey = DoorVisualLayers.BaseUnlit,
|
||||||
|
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.EmaggingSpriteState, 0f) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAppearanceChange(EntityUid uid, DoorComponent comp, ref AppearanceChangeEvent args)
|
||||||
|
{
|
||||||
|
if (args.Sprite == null || !_gameTiming.IsFirstTimePredicted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
base.UpdateAppearance(uid, door);
|
if(!AppearanceSystem.TryGetData<DoorState>(uid, DoorVisuals.State, out var state, args.Component))
|
||||||
|
state = DoorState.Closed;
|
||||||
|
|
||||||
if (TryComp(uid, out SpriteComponent? sprite))
|
if (AppearanceSystem.TryGetData<string>(uid, DoorVisuals.BaseRSI, out var baseRsi, args.Component))
|
||||||
{
|
{
|
||||||
sprite.DrawDepth = (door.State == DoorState.Open)
|
if (!_resourceCache.TryGetResource<RSIResource>(SharedSpriteComponent.TextureRoot / baseRsi, out var res))
|
||||||
? door.OpenDrawDepth
|
{
|
||||||
: door.ClosedDrawDepth;
|
Logger.Error("Unable to load RSI '{0}'. Trace:\n{1}", baseRsi, Environment.StackTrace);
|
||||||
|
}
|
||||||
|
foreach (ISpriteLayer layer in args.Sprite.AllLayers)
|
||||||
|
{
|
||||||
|
layer.Rsi = res?.RSI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TryComp<AnimationPlayerComponent>(uid, out var animPlayer);
|
||||||
|
if (_animationSystem.HasRunningAnimation(uid, animPlayer, DoorComponent.AnimationKey))
|
||||||
|
_animationSystem.Stop(uid, animPlayer, DoorComponent.AnimationKey); // Halt all running anomations.
|
||||||
|
|
||||||
|
args.Sprite.DrawDepth = comp.ClosedDrawDepth;
|
||||||
|
switch(state)
|
||||||
|
{
|
||||||
|
case DoorState.Open:
|
||||||
|
args.Sprite.DrawDepth = comp.OpenDrawDepth;
|
||||||
|
foreach(var (layer, layerState) in comp.OpenSpriteStates)
|
||||||
|
{
|
||||||
|
args.Sprite.LayerSetState(layer, layerState);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DoorState.Closed:
|
||||||
|
foreach(var (layer, layerState) in comp.ClosedSpriteStates)
|
||||||
|
{
|
||||||
|
args.Sprite.LayerSetState(layer, layerState);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DoorState.Opening:
|
||||||
|
if (animPlayer != null && comp.OpeningAnimation != default)
|
||||||
|
_animationSystem.Play(uid, animPlayer, (Animation)comp.OpeningAnimation, DoorComponent.AnimationKey);
|
||||||
|
break;
|
||||||
|
case DoorState.Closing:
|
||||||
|
if (animPlayer != null && comp.ClosingAnimation != default && comp.CurrentlyCrushing.Count == 0)
|
||||||
|
_animationSystem.Play(uid, animPlayer, (Animation)comp.ClosingAnimation, DoorComponent.AnimationKey);
|
||||||
|
break;
|
||||||
|
case DoorState.Denying:
|
||||||
|
if (animPlayer != null && comp.DenyingAnimation != default)
|
||||||
|
_animationSystem.Play(uid, animPlayer, (Animation)comp.DenyingAnimation, DoorComponent.AnimationKey);
|
||||||
|
break;
|
||||||
|
case DoorState.Welded:
|
||||||
|
break;
|
||||||
|
case DoorState.Emagging:
|
||||||
|
if (animPlayer != null && comp.EmaggingAnimation != default)
|
||||||
|
_animationSystem.Play(uid, animPlayer, (Animation)comp.EmaggingAnimation, DoorComponent.AnimationKey);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException($"Invalid door visual state {state}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Threading;
|
|
||||||
using Content.Shared.Doors.Systems;
|
using Content.Shared.Doors.Systems;
|
||||||
using Content.Shared.MachineLinking;
|
using Content.Shared.MachineLinking;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
@@ -56,8 +55,16 @@ public sealed class AirlockComponent : Component
|
|||||||
[DataField("keepOpenIfClicked")]
|
[DataField("keepOpenIfClicked")]
|
||||||
public bool KeepOpenIfClicked = false;
|
public bool KeepOpenIfClicked = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the door bolts are currently deployed.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
public bool BoltsDown;
|
public bool BoltsDown;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the bolt lights are currently enabled.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
public bool BoltLightsEnabled = true;
|
public bool BoltLightsEnabled = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -86,10 +93,80 @@ public sealed class AirlockComponent : Component
|
|||||||
public float AutoCloseDelayModifier = 1.0f;
|
public float AutoCloseDelayModifier = 1.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The receiver port for turning off automatic closing.
|
/// The receiver port for turning off automatic closing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("autoClosePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
[DataField("autoClosePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
public string AutoClosePort = "AutoClose";
|
public string AutoClosePort = "AutoClose";
|
||||||
|
|
||||||
|
#region Graphics
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the door lights should be visible.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("openUnlitVisible")]
|
||||||
|
public bool OpenUnlitVisible = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the door should display emergency access lights.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("emergencyAccessLayer")]
|
||||||
|
public bool EmergencyAccessLayer = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not to animate the panel when the door opens or closes.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("animatePanel")]
|
||||||
|
public bool AnimatePanel = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used to animate the airlock frame when the airlock opens.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("openingSpriteState")]
|
||||||
|
public string OpeningSpriteState = "opening_unlit";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used to animate the airlock panel when the airlock opens.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("openingPanelSpriteState")]
|
||||||
|
public string OpeningPanelSpriteState = "panel_opening";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used to animate the airlock frame when the airlock closes.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("closingSpriteState")]
|
||||||
|
public string ClosingSpriteState = "closing_unlit";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used to animate the airlock panel when the airlock closes.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("closingPanelSpriteState")]
|
||||||
|
public string ClosingPanelSpriteState = "panel_closing";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the open airlock lights.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("openSpriteState")]
|
||||||
|
public string OpenSpriteState = "open_unlit";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the closed airlock lights.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("closedSpriteState")]
|
||||||
|
public string ClosedSpriteState = "closed_unlit";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the 'access denied' lights animation.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("denySpriteState")]
|
||||||
|
public string DenySpriteState = "deny_unlit";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How long the animation played when the airlock denies access is in seconds.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("denyAnimationTime")]
|
||||||
|
public float DenyAnimationTime = 0.3f;
|
||||||
|
|
||||||
|
#endregion Graphics
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.Doors.Systems;
|
||||||
using Content.Shared.Tools;
|
using Content.Shared.Tools;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
@@ -13,16 +15,17 @@ namespace Content.Shared.Doors.Components;
|
|||||||
|
|
||||||
[NetworkedComponent]
|
[NetworkedComponent]
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class DoorComponent : Component, ISerializationHooks
|
public sealed class DoorComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current state of the door -- whether it is open, closed, opening, or closing.
|
/// The current state of the door -- whether it is open, closed, opening, or closing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This should never be set directly.
|
/// This should never be set directly, use <see cref="SharedDoorSystem.SetState(EntityUid, DoorState, DoorComponent?)"/> instead.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField("state")]
|
[DataField("state")]
|
||||||
|
[Access(typeof(SharedDoorSystem))]
|
||||||
public DoorState State = DoorState.Closed;
|
public DoorState State = DoorState.Closed;
|
||||||
|
|
||||||
#region Timing
|
#region Timing
|
||||||
@@ -139,6 +142,97 @@ public sealed class DoorComponent : Component, ISerializationHooks
|
|||||||
public HashSet<EntityUid> CurrentlyCrushing = new();
|
public HashSet<EntityUid> CurrentlyCrushing = new();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Graphics
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The key used when playing door opening/closing/emagging/deny animations.
|
||||||
|
/// </summary>
|
||||||
|
public const string AnimationKey = "door_animation";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the door when it's open.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("openSpriteState")]
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string OpenSpriteState = "open";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite states used for the door while it's open.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadOnly)]
|
||||||
|
public List<(DoorVisualLayers, string)> OpenSpriteStates = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the door when it's closed.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("closedSpriteState")]
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string ClosedSpriteState = "closed";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite states used for the door while it's closed.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadOnly)]
|
||||||
|
public List<(DoorVisualLayers, string)> ClosedSpriteStates = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the door when it's opening.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("openingSpriteState")]
|
||||||
|
public string OpeningSpriteState = "opening";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the door when it's closing.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("closingSpriteState")]
|
||||||
|
public string ClosingSpriteState = "closing";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the door when it's being emagged.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("emaggingSpriteState")]
|
||||||
|
public string EmaggingSpriteState = "emagging";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the door when it's open.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("openingAnimationTime")]
|
||||||
|
public float OpeningAnimationTime = 0.8f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the door when it's open.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("closingAnimationTime")]
|
||||||
|
public float ClosingAnimationTime = 0.8f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state used for the door when it's open.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("emaggingAnimationTime")]
|
||||||
|
public float EmaggingAnimationTime = 1.5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The animation used when the door opens.
|
||||||
|
/// </summary>
|
||||||
|
public object OpeningAnimation = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The animation used when the door closes.
|
||||||
|
/// </summary>
|
||||||
|
public object ClosingAnimation = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The animation used when the door denies access.
|
||||||
|
/// </summary>
|
||||||
|
public object DenyingAnimation = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The animation used when the door is emagged.
|
||||||
|
/// </summary>
|
||||||
|
public object EmaggingAnimation = default!;
|
||||||
|
|
||||||
|
#endregion Graphics
|
||||||
|
|
||||||
#region Serialization
|
#region Serialization
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Time until next state change. Because apparently <see cref="IGameTiming.CurTime"/> might not get saved/restored.
|
/// Time until next state change. Because apparently <see cref="IGameTiming.CurTime"/> might not get saved/restored.
|
||||||
@@ -209,7 +303,7 @@ public sealed class DoorComponent : Component, ISerializationHooks
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public enum DoorState
|
public enum DoorState : byte
|
||||||
{
|
{
|
||||||
Closed,
|
Closed,
|
||||||
Closing,
|
Closing,
|
||||||
@@ -221,7 +315,7 @@ public enum DoorState
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public enum DoorVisuals
|
public enum DoorVisuals : byte
|
||||||
{
|
{
|
||||||
State,
|
State,
|
||||||
Powered,
|
Powered,
|
||||||
@@ -231,6 +325,14 @@ public enum DoorVisuals
|
|||||||
BaseRSI,
|
BaseRSI,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum DoorVisualLayers : byte
|
||||||
|
{
|
||||||
|
Base,
|
||||||
|
BaseUnlit,
|
||||||
|
BaseBolted,
|
||||||
|
BaseEmergencyAccess,
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class DoorComponentState : ComponentState
|
public sealed class DoorComponentState : ComponentState
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
[Dependency] protected readonly TagSystem Tags = default!;
|
[Dependency] protected readonly TagSystem Tags = default!;
|
||||||
[Dependency] protected readonly SharedAudioSystem Audio = default!;
|
[Dependency] protected readonly SharedAudioSystem Audio = default!;
|
||||||
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
|
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] protected readonly SharedAppearanceSystem AppearanceSystem = default!;
|
||||||
[Dependency] private readonly OccluderSystem _occluder = default!;
|
[Dependency] private readonly OccluderSystem _occluder = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -49,7 +49,7 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<DoorComponent, ComponentInit>(OnInit);
|
SubscribeLocalEvent<DoorComponent, ComponentInit>(OnComponentInit);
|
||||||
SubscribeLocalEvent<DoorComponent, ComponentRemove>(OnRemove);
|
SubscribeLocalEvent<DoorComponent, ComponentRemove>(OnRemove);
|
||||||
|
|
||||||
SubscribeLocalEvent<DoorComponent, ComponentGetState>(OnGetState);
|
SubscribeLocalEvent<DoorComponent, ComponentGetState>(OnGetState);
|
||||||
@@ -61,7 +61,7 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<DoorComponent, PreventCollideEvent>(PreventCollision);
|
SubscribeLocalEvent<DoorComponent, PreventCollideEvent>(PreventCollision);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInit(EntityUid uid, DoorComponent door, ComponentInit args)
|
protected virtual void OnComponentInit(EntityUid uid, DoorComponent door, ComponentInit args)
|
||||||
{
|
{
|
||||||
if (door.NextStateChange != null)
|
if (door.NextStateChange != null)
|
||||||
_activeDoors.Add(door);
|
_activeDoors.Add(door);
|
||||||
@@ -88,7 +88,7 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
|| door.State == DoorState.Opening && !door.Partial;
|
|| door.State == DoorState.Opening && !door.Partial;
|
||||||
|
|
||||||
SetCollidable(uid, collidable, door);
|
SetCollidable(uid, collidable, door);
|
||||||
UpdateAppearance(uid, door);
|
AppearanceSystem.SetData(uid, DoorVisuals.State, door.State);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRemove(EntityUid uid, DoorComponent door, ComponentRemove args)
|
private void OnRemove(EntityUid uid, DoorComponent door, ComponentRemove args)
|
||||||
@@ -123,7 +123,7 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
_activeDoors.Add(door);
|
_activeDoors.Add(door);
|
||||||
|
|
||||||
RaiseLocalEvent(uid, new DoorStateChangedEvent(door.State), false);
|
RaiseLocalEvent(uid, new DoorStateChangedEvent(door.State), false);
|
||||||
UpdateAppearance(uid, door);
|
AppearanceSystem.SetData(uid, DoorVisuals.State, door.State);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SetState(EntityUid uid, DoorState state, DoorComponent? door = null)
|
protected void SetState(EntityUid uid, DoorState state, DoorComponent? door = null)
|
||||||
@@ -167,19 +167,9 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
door.State = state;
|
door.State = state;
|
||||||
Dirty(door);
|
Dirty(door);
|
||||||
RaiseLocalEvent(uid, new DoorStateChangedEvent(state), false);
|
RaiseLocalEvent(uid, new DoorStateChangedEvent(state), false);
|
||||||
UpdateAppearance(uid, door);
|
AppearanceSystem.SetData(uid, DoorVisuals.State, door.State);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void UpdateAppearance(EntityUid uid, DoorComponent? door = null)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref door))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!TryComp(uid, out AppearanceComponent? appearance))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_appearance.SetData(uid, DoorVisuals.State, door.State);
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Interactions
|
#region Interactions
|
||||||
@@ -365,7 +355,7 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
door.NextStateChange = GameTiming.CurTime + door.OpenTimeTwo;
|
door.NextStateChange = GameTiming.CurTime + door.OpenTimeTwo;
|
||||||
door.State = DoorState.Opening;
|
door.State = DoorState.Opening;
|
||||||
UpdateAppearance(uid, door);
|
AppearanceSystem.SetData(uid, DoorVisuals.State, DoorState.Opening);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
layers:
|
layers:
|
||||||
- state: closed
|
- state: closed
|
||||||
map: ["enum.DoorVisualLayers.Base"]
|
map: ["enum.DoorVisualLayers.Base"]
|
||||||
|
- type: AnimationPlayer
|
||||||
- type: Fixtures
|
- type: Fixtures
|
||||||
fixtures:
|
fixtures:
|
||||||
- shape:
|
- shape:
|
||||||
@@ -36,9 +37,6 @@
|
|||||||
closeSound:
|
closeSound:
|
||||||
path: /Audio/Effects/curtain_openclose.ogg
|
path: /Audio/Effects/curtain_openclose.ogg
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
simpleVisuals: true
|
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
damageContainer: Inorganic
|
damageContainer: Inorganic
|
||||||
damageModifierSet: Wood
|
damageModifierSet: Wood
|
||||||
|
|||||||
@@ -104,6 +104,7 @@
|
|||||||
enabled: false
|
enabled: false
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Structures/Doors/Airlocks/Glass/glass.rsi
|
sprite: Structures/Doors/Airlocks/Glass/glass.rsi
|
||||||
|
- type: AnimationPlayer
|
||||||
- type: Fixtures
|
- type: Fixtures
|
||||||
fixtures:
|
fixtures:
|
||||||
- shape:
|
- shape:
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
shader: unshaded
|
shader: unshaded
|
||||||
- state: panel_open
|
- state: panel_open
|
||||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||||
|
- type: AnimationPlayer
|
||||||
- type: Physics
|
- type: Physics
|
||||||
- type: Fixtures
|
- type: Fixtures
|
||||||
fixtures:
|
fixtures:
|
||||||
@@ -65,8 +66,6 @@
|
|||||||
time: 3
|
time: 3
|
||||||
- type: Airlock
|
- type: Airlock
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
- type: WiresVisuals
|
- type: WiresVisuals
|
||||||
- type: ApcPowerReceiver
|
- type: ApcPowerReceiver
|
||||||
powerLoad: 20
|
powerLoad: 20
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Structures/Doors/Airlocks/Standard/external.rsi
|
sprite: Structures/Doors/Airlocks/Standard/external.rsi
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
- type: WiresVisuals
|
- type: WiresVisuals
|
||||||
- type: PaintableAirlock
|
- type: PaintableAirlock
|
||||||
group: External
|
group: External
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
shader: unshaded
|
shader: unshaded
|
||||||
- state: panel_open
|
- state: panel_open
|
||||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||||
|
- type: AnimationPlayer
|
||||||
- type: Physics
|
- type: Physics
|
||||||
- type: Fixtures
|
- type: Fixtures
|
||||||
fixtures:
|
fixtures:
|
||||||
@@ -56,8 +57,6 @@
|
|||||||
time: 10
|
time: 10
|
||||||
- type: Airlock
|
- type: Airlock
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
- type: WiresVisuals
|
- type: WiresVisuals
|
||||||
- type: ApcPowerReceiver
|
- type: ApcPowerReceiver
|
||||||
powerLoad: 20
|
powerLoad: 20
|
||||||
|
|||||||
@@ -37,13 +37,16 @@
|
|||||||
- state: closed_unlit
|
- state: closed_unlit
|
||||||
shader: unshaded
|
shader: unshaded
|
||||||
map: ["enum.DoorVisualLayers.BaseUnlit"]
|
map: ["enum.DoorVisualLayers.BaseUnlit"]
|
||||||
|
visible: false
|
||||||
- state: welded
|
- state: welded
|
||||||
map: ["enum.WeldableLayers.BaseWelded"]
|
map: ["enum.WeldableLayers.BaseWelded"]
|
||||||
- state: bolted_unlit
|
- state: bolted_unlit
|
||||||
shader: unshaded
|
shader: unshaded
|
||||||
map: ["enum.DoorVisualLayers.BaseBolted"]
|
map: ["enum.DoorVisualLayers.BaseBolted"]
|
||||||
|
visible: false
|
||||||
- state: panel_open
|
- state: panel_open
|
||||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||||
|
- type: AnimationPlayer
|
||||||
- type: Fixtures
|
- type: Fixtures
|
||||||
fixtures:
|
fixtures:
|
||||||
- shape:
|
- shape:
|
||||||
@@ -72,15 +75,13 @@
|
|||||||
path: /Audio/Machines/airlock_close.ogg
|
path: /Audio/Machines/airlock_close.ogg
|
||||||
denySound:
|
denySound:
|
||||||
path: /Audio/Machines/airlock_deny.ogg
|
path: /Audio/Machines/airlock_deny.ogg
|
||||||
|
openingAnimationTime: 0.6
|
||||||
|
closingAnimationTime: 0.6
|
||||||
- type: Weldable
|
- type: Weldable
|
||||||
fuel: 3
|
fuel: 3
|
||||||
time: 3
|
time: 3
|
||||||
- type: Firelock
|
- type: Firelock
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
animationTime: 0.6
|
|
||||||
emergencyAccessLayer: false
|
|
||||||
- type: WiresVisuals
|
- type: WiresVisuals
|
||||||
- type: Wires
|
- type: Wires
|
||||||
BoardName: "Firelock Control"
|
BoardName: "Firelock Control"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
layers:
|
layers:
|
||||||
- state: closed
|
- state: closed
|
||||||
map: ["enum.DoorVisualLayers.Base"]
|
map: ["enum.DoorVisualLayers.Base"]
|
||||||
|
- type: AnimationPlayer
|
||||||
- type: Physics
|
- type: Physics
|
||||||
- type: Fixtures
|
- type: Fixtures
|
||||||
fixtures:
|
fixtures:
|
||||||
@@ -31,15 +32,13 @@
|
|||||||
closeTimeTwo: 0.6
|
closeTimeTwo: 0.6
|
||||||
openTimeOne: 0.6
|
openTimeOne: 0.6
|
||||||
openTimeTwo: 0.2
|
openTimeTwo: 0.2
|
||||||
|
openingAnimationTime: 1.2
|
||||||
|
closingAnimationTime: 1.2
|
||||||
openSound:
|
openSound:
|
||||||
path: /Audio/Effects/stonedoor_openclose.ogg
|
path: /Audio/Effects/stonedoor_openclose.ogg
|
||||||
closeSound:
|
closeSound:
|
||||||
path: /Audio/Effects/stonedoor_openclose.ogg
|
path: /Audio/Effects/stonedoor_openclose.ogg
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
simpleVisuals: true
|
|
||||||
animationTime: 1.2
|
|
||||||
- type: Airtight
|
- type: Airtight
|
||||||
fixVacuum: true
|
fixVacuum: true
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
|
|||||||
@@ -15,16 +15,14 @@
|
|||||||
closeTimeTwo: 0.4
|
closeTimeTwo: 0.4
|
||||||
openTimeOne: 0.4
|
openTimeOne: 0.4
|
||||||
openTimeTwo: 0.4
|
openTimeTwo: 0.4
|
||||||
|
openingAnimationTime: 1.0
|
||||||
|
closingAnimationTime: 1.0
|
||||||
pryTime: -1
|
pryTime: -1
|
||||||
crushDamage:
|
crushDamage:
|
||||||
types:
|
types:
|
||||||
Blunt: 25 # yowch
|
Blunt: 25 # yowch
|
||||||
- type: Occluder
|
- type: Occluder
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
simpleVisuals: true
|
|
||||||
animationTime: 1.0
|
|
||||||
- type: RadiationBlocker
|
- type: RadiationBlocker
|
||||||
resistance: 8
|
resistance: 8
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
layers:
|
layers:
|
||||||
- state: closed
|
- state: closed
|
||||||
map: ["enum.DoorVisualLayers.Base"]
|
map: ["enum.DoorVisualLayers.Base"]
|
||||||
|
- type: AnimationPlayer
|
||||||
- type: Physics
|
- type: Physics
|
||||||
- type: Fixtures
|
- type: Fixtures
|
||||||
fixtures:
|
fixtures:
|
||||||
@@ -38,6 +39,8 @@
|
|||||||
closeTimeTwo: 1.2
|
closeTimeTwo: 1.2
|
||||||
openTimeOne: 1.2
|
openTimeOne: 1.2
|
||||||
openTimeTwo: 0.2
|
openTimeTwo: 0.2
|
||||||
|
openingAnimationTime: 1.4
|
||||||
|
closingAnimationTime: 1.4
|
||||||
crushDamage:
|
crushDamage:
|
||||||
types:
|
types:
|
||||||
Blunt: 5 # getting shutters closed on you probably doesn't hurt that much
|
Blunt: 5 # getting shutters closed on you probably doesn't hurt that much
|
||||||
@@ -49,10 +52,6 @@
|
|||||||
fuel: 3
|
fuel: 3
|
||||||
time: 3
|
time: 3
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
simpleVisuals: true
|
|
||||||
animationTime: 1.4
|
|
||||||
- type: UserInterface
|
- type: UserInterface
|
||||||
interfaces:
|
interfaces:
|
||||||
- key: enum.WiresUiKey.Key
|
- key: enum.WiresUiKey.Key
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
map: ["enum.DoorVisualLayers.BaseEmergencyAccess"]
|
map: ["enum.DoorVisualLayers.BaseEmergencyAccess"]
|
||||||
- state: panel_open
|
- state: panel_open
|
||||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||||
|
- type: AnimationPlayer
|
||||||
- type: ApcPowerReceiver
|
- type: ApcPowerReceiver
|
||||||
- type: ExtensionCableReceiver
|
- type: ExtensionCableReceiver
|
||||||
- type: DoorSignalControl
|
- type: DoorSignalControl
|
||||||
@@ -78,11 +79,6 @@
|
|||||||
- !type:DoActsBehavior
|
- !type:DoActsBehavior
|
||||||
acts: [ "Destruction" ]
|
acts: [ "Destruction" ]
|
||||||
- type: AccessReader
|
- type: AccessReader
|
||||||
- type: Airlock
|
|
||||||
keepOpenIfClicked: true
|
|
||||||
openPanelVisible: true
|
|
||||||
# needed so that windoors will close regardless of whether there are people in it; it doesn't crush after all
|
|
||||||
safety: false
|
|
||||||
- type: ContainerFill
|
- type: ContainerFill
|
||||||
containers:
|
containers:
|
||||||
board: [ DoorElectronics ]
|
board: [ DoorElectronics ]
|
||||||
@@ -91,12 +87,22 @@
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
- type: Door
|
- type: Door
|
||||||
canCrush: false
|
canCrush: false
|
||||||
|
openingAnimationTime: 0.9
|
||||||
|
closingAnimationTime: 0.9
|
||||||
openSound:
|
openSound:
|
||||||
path: /Audio/Machines/windoor_open.ogg
|
path: /Audio/Machines/windoor_open.ogg
|
||||||
closeSound:
|
closeSound:
|
||||||
path: /Audio/Machines/windoor_open.ogg
|
path: /Audio/Machines/windoor_open.ogg
|
||||||
denySound:
|
denySound:
|
||||||
path: /Audio/Machines/airlock_deny.ogg
|
path: /Audio/Machines/airlock_deny.ogg
|
||||||
|
- type: Airlock
|
||||||
|
keepOpenIfClicked: true
|
||||||
|
openPanelVisible: true
|
||||||
|
denyAnimationTime: 0.4
|
||||||
|
animatePanel: false
|
||||||
|
openUnlitVisible: true
|
||||||
|
# needed so that windoors will close regardless of whether there are people in it; it doesn't crush after all
|
||||||
|
safety: false
|
||||||
- type: Electrified
|
- type: Electrified
|
||||||
enabled: false
|
enabled: false
|
||||||
usesApcPower: true
|
usesApcPower: true
|
||||||
@@ -108,12 +114,6 @@
|
|||||||
- key: enum.WiresUiKey.Key
|
- key: enum.WiresUiKey.Key
|
||||||
type: WiresBoundUserInterface
|
type: WiresBoundUserInterface
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: AirlockVisualizer
|
|
||||||
animationTime: 0.9
|
|
||||||
denyAnimationTime: 0.4
|
|
||||||
animatedPanel: false
|
|
||||||
openUnlitVisible: true
|
|
||||||
- type: WiresVisuals
|
- type: WiresVisuals
|
||||||
- type: Airtight
|
- type: Airtight
|
||||||
fixVacuum: true
|
fixVacuum: true
|
||||||
|
|||||||
Reference in New Issue
Block a user