Add door emag visuals and sound (#6971)
Co-authored-by: fishfish458 <fishfish458>
This commit is contained in:
@@ -26,6 +26,10 @@ namespace Content.Client.Doors
|
|||||||
[DataField("denyAnimationTime")]
|
[DataField("denyAnimationTime")]
|
||||||
private float _denyDelay = 0.3f;
|
private float _denyDelay = 0.3f;
|
||||||
|
|
||||||
|
|
||||||
|
[DataField("emagAnimationTime")]
|
||||||
|
private float _delayEmag = 1.5f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the maintenance panel is animated or stays static.
|
/// Whether the maintenance panel is animated or stays static.
|
||||||
/// False for windoors.
|
/// False for windoors.
|
||||||
@@ -55,6 +59,7 @@ namespace Content.Client.Doors
|
|||||||
private Animation CloseAnimation = default!;
|
private Animation CloseAnimation = default!;
|
||||||
private Animation OpenAnimation = default!;
|
private Animation OpenAnimation = default!;
|
||||||
private Animation DenyAnimation = default!;
|
private Animation DenyAnimation = default!;
|
||||||
|
private Animation EmaggingAnimation = default!;
|
||||||
|
|
||||||
void ISerializationHooks.AfterDeserialization()
|
void ISerializationHooks.AfterDeserialization()
|
||||||
{
|
{
|
||||||
@@ -107,6 +112,13 @@ namespace Content.Client.Doors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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)
|
if (!_simpleVisuals)
|
||||||
{
|
{
|
||||||
@@ -186,6 +198,9 @@ namespace Content.Client.Doors
|
|||||||
case DoorState.Welded:
|
case DoorState.Welded:
|
||||||
weldedVisible = true;
|
weldedVisible = true;
|
||||||
break;
|
break;
|
||||||
|
case DoorState.Emagging:
|
||||||
|
animPlayer.Play(EmaggingAnimation, AnimationKey);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using Robust.Shared.Audio;
|
|||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Physics.Dynamics;
|
using Robust.Shared.Physics.Dynamics;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Content.Shared.Hands.Components;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Content.Server.Doors.Systems;
|
namespace Content.Server.Doors.Systems;
|
||||||
@@ -288,18 +289,35 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||||||
if(!container.Insert(board))
|
if(!container.Insert(board))
|
||||||
Logger.Warning($"Couldn't insert board {ToPrettyString(board)} into door {ToPrettyString(uid)}!");
|
Logger.Warning($"Couldn't insert board {ToPrettyString(board)} into door {ToPrettyString(uid)}!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEmagged(EntityUid uid, DoorComponent door, GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, DoorComponent door, GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
if(TryComp<AirlockComponent>(uid, out var airlockComponent))
|
if(TryComp<AirlockComponent>(uid, out var airlockComponent))
|
||||||
{
|
{
|
||||||
if (door.State == DoorState.Closed)
|
if (door.State == DoorState.Closed)
|
||||||
{
|
{
|
||||||
StartOpening(uid);
|
SetState(uid, DoorState.Emagging, door);
|
||||||
airlockComponent?.SetBoltsWithAudio(!airlockComponent.IsBolted());
|
PlaySound(uid, door.SparkSound.GetSound(), AudioParams.Default.WithVolume(8), args.UserUid, false);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void StartOpening(EntityUid uid, DoorComponent? door = null, EntityUid? user = null, bool predicted = false)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref door))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DoorState lastState = door.State;
|
||||||
|
|
||||||
|
SetState(uid, DoorState.Opening, door);
|
||||||
|
|
||||||
|
if (door.OpenSound != null)
|
||||||
|
PlaySound(uid, door.OpenSound.GetSound(), AudioParams.Default.WithVolume(-5), user, predicted);
|
||||||
|
|
||||||
|
if(lastState == DoorState.Emagging && TryComp<AirlockComponent>(door.Owner, out var airlockComponent))
|
||||||
|
airlockComponent?.SetBoltsWithAudio(!airlockComponent.IsBolted());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class PryFinishedEvent : EntityEventArgs { }
|
public sealed class PryFinishedEvent : EntityEventArgs { }
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ public sealed class DoorComponent : Component, ISerializationHooks
|
|||||||
[DataField("denyDuration")]
|
[DataField("denyDuration")]
|
||||||
public readonly TimeSpan DenyDuration = TimeSpan.FromSeconds(0.45f);
|
public readonly TimeSpan DenyDuration = TimeSpan.FromSeconds(0.45f);
|
||||||
|
|
||||||
|
[DataField("emagDuration")]
|
||||||
|
public readonly TimeSpan EmagDuration = TimeSpan.FromSeconds(0.8f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When the door is active, this is the time when the state will next update.
|
/// When the door is active, this is the time when the state will next update.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -116,6 +119,12 @@ public sealed class DoorComponent : Component, ISerializationHooks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("tryOpenDoorSound")]
|
[DataField("tryOpenDoorSound")]
|
||||||
public SoundSpecifier TryOpenDoorSound = new SoundPathSpecifier("/Audio/Effects/bang.ogg");
|
public SoundSpecifier TryOpenDoorSound = new SoundPathSpecifier("/Audio/Effects/bang.ogg");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sound to play when door has been emagged or possibly electrically tampered
|
||||||
|
/// </summary>
|
||||||
|
[DataField("sparkSound")]
|
||||||
|
public SoundSpecifier SparkSound = new SoundCollectionSpecifier("sparks");
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Crushing
|
#region Crushing
|
||||||
@@ -164,7 +173,7 @@ public sealed class DoorComponent : Component, ISerializationHooks
|
|||||||
_secondsUntilStateChange = null;
|
_secondsUntilStateChange = null;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
var curTime = IoCManager.Resolve<IGameTiming>().CurTime;
|
var curTime = IoCManager.Resolve<IGameTiming>().CurTime;
|
||||||
_secondsUntilStateChange = (float) (NextStateChange.Value - curTime).TotalSeconds;
|
_secondsUntilStateChange = (float) (NextStateChange.Value - curTime).TotalSeconds;
|
||||||
}
|
}
|
||||||
@@ -230,6 +239,7 @@ public enum DoorState
|
|||||||
Opening,
|
Opening,
|
||||||
Welded,
|
Welded,
|
||||||
Denying,
|
Denying,
|
||||||
|
Emagging
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
|
|||||||
@@ -135,6 +135,11 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
door.NextStateChange = GameTiming.CurTime + door.DenyDuration;
|
door.NextStateChange = GameTiming.CurTime + door.DenyDuration;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DoorState.Emagging:
|
||||||
|
_activeDoors.Add(door);
|
||||||
|
door.NextStateChange = GameTiming.CurTime + door.EmagDuration;
|
||||||
|
break;
|
||||||
|
|
||||||
case DoorState.Open:
|
case DoorState.Open:
|
||||||
case DoorState.Closed:
|
case DoorState.Closed:
|
||||||
door.Partial = false;
|
door.Partial = false;
|
||||||
@@ -352,7 +357,7 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
SetCollidable(uid, true, door, physics);
|
SetCollidable(uid, true, door, physics);
|
||||||
door.NextStateChange = GameTiming.CurTime + door.CloseTimeTwo;
|
door.NextStateChange = GameTiming.CurTime + door.CloseTimeTwo;
|
||||||
_activeDoors.Add(door);
|
_activeDoors.Add(door);
|
||||||
|
|
||||||
// Crush any entities. Note that we don't check airlock safety here. This should have been checked before
|
// Crush any entities. Note that we don't check airlock safety here. This should have been checked before
|
||||||
// the door closed.
|
// the door closed.
|
||||||
Crush(uid, door, physics);
|
Crush(uid, door, physics);
|
||||||
@@ -579,6 +584,10 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
SetState(door.Owner, DoorState.Closed, door);
|
SetState(door.Owner, DoorState.Closed, door);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DoorState.Emagging:
|
||||||
|
StartOpening(door.Owner, door);
|
||||||
|
break;
|
||||||
|
|
||||||
case DoorState.Open:
|
case DoorState.Open:
|
||||||
// This door is open, and queued for an auto-close.
|
// This door is open, and queued for an auto-close.
|
||||||
if (!TryClose(door.Owner, door, predicted: true))
|
if (!TryClose(door.Owner, door, predicted: true))
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name":"spark",
|
"name":"sparks",
|
||||||
"directions":4,
|
"directions":4,
|
||||||
"delays":[
|
"delays":[
|
||||||
[
|
[
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 518 B After Width: | Height: | Size: 518 B |
Reference in New Issue
Block a user