Experimental nukie changes (#9428)
This commit is contained in:
@@ -4,6 +4,7 @@ using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Coordinates.Helpers;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Explosion.EntitySystems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Station.Systems;
|
||||
@@ -30,6 +31,17 @@ namespace Content.Server.Nuke
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
[Dependency] private readonly ServerGlobalSoundSystem _soundSystem = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Used to calculate when the nuke song should start playing for maximum kino with the nuke sfx
|
||||
/// </summary>
|
||||
private const float NukeSongLength = 60f + 51.6f;
|
||||
|
||||
/// <summary>
|
||||
/// Time to leave between the nuke song and the nuke alarm playing.
|
||||
/// </summary>
|
||||
private const float NukeSongBuffer = 1.5f;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -51,6 +63,10 @@ namespace Content.Server.Nuke
|
||||
SubscribeLocalEvent<NukeComponent, NukeKeypadMessage>(OnKeypadButtonPressed);
|
||||
SubscribeLocalEvent<NukeComponent, NukeKeypadClearMessage>(OnClearButtonPressed);
|
||||
SubscribeLocalEvent<NukeComponent, NukeKeypadEnterMessage>(OnEnterButtonPressed);
|
||||
|
||||
// Doafter events
|
||||
SubscribeLocalEvent<NukeComponent, NukeDisarmSuccessEvent>(OnDisarmSuccess);
|
||||
SubscribeLocalEvent<NukeComponent, NukeDisarmCancelledEvent>(OnDisarmCancelled);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, NukeComponent component, ComponentInit args)
|
||||
@@ -98,6 +114,7 @@ namespace Content.Server.Nuke
|
||||
}
|
||||
|
||||
#region Anchor
|
||||
|
||||
private void OnAnchorAttempt(EntityUid uid, NukeComponent component, AnchorAttemptEvent args)
|
||||
{
|
||||
CheckAnchorAttempt(uid, component, args);
|
||||
@@ -124,9 +141,11 @@ namespace Content.Server.Nuke
|
||||
{
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Events
|
||||
|
||||
private async void OnAnchorButtonPressed(EntityUid uid, NukeComponent component, NukeAnchorMessage args)
|
||||
{
|
||||
if (!component.DiskSlot.HasItem)
|
||||
@@ -188,9 +207,28 @@ namespace Content.Server.Nuke
|
||||
}
|
||||
else
|
||||
{
|
||||
DisarmBomb(uid, component);
|
||||
if (args.Session.AttachedEntity is not { } user)
|
||||
return;
|
||||
|
||||
DisarmBombDoafter(uid, user, component);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Doafter Events
|
||||
|
||||
private void OnDisarmSuccess(EntityUid uid, NukeComponent component, NukeDisarmSuccessEvent args)
|
||||
{
|
||||
component.DisarmCancelToken = null;
|
||||
DisarmBomb(uid, component);
|
||||
}
|
||||
|
||||
private void OnDisarmCancelled(EntityUid uid, NukeComponent component, NukeDisarmCancelledEvent args)
|
||||
{
|
||||
component.DisarmCancelToken = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void TickCooldown(EntityUid uid, float frameTime, NukeComponent? nuke = null)
|
||||
@@ -217,6 +255,14 @@ namespace Content.Server.Nuke
|
||||
|
||||
nuke.RemainingTime -= frameTime;
|
||||
|
||||
// Start playing the nuke event song so that it ends a couple seconds before the alert sound
|
||||
// should play
|
||||
if (nuke.RemainingTime <= NukeSongLength + nuke.AlertSoundTime + NukeSongBuffer && !nuke.PlayedNukeSong)
|
||||
{
|
||||
_soundSystem.DispatchStationEventMusic(uid, nuke.ArmMusic, StationEventMusicType.Nuke);
|
||||
nuke.PlayedNukeSong = true;
|
||||
}
|
||||
|
||||
// play alert sound if time is running out
|
||||
if (nuke.RemainingTime <= nuke.AlertSoundTime && !nuke.PlayedAlertSound)
|
||||
{
|
||||
@@ -248,28 +294,29 @@ namespace Content.Server.Nuke
|
||||
component.Status = NukeStatus.AWAIT_CODE;
|
||||
break;
|
||||
case NukeStatus.AWAIT_CODE:
|
||||
{
|
||||
if (!component.DiskSlot.HasItem)
|
||||
{
|
||||
if (!component.DiskSlot.HasItem)
|
||||
{
|
||||
component.Status = NukeStatus.AWAIT_DISK;
|
||||
component.EnteredCode = "";
|
||||
break;
|
||||
}
|
||||
|
||||
var isValid = _codes.IsCodeValid(component.EnteredCode);
|
||||
if (isValid)
|
||||
{
|
||||
component.Status = NukeStatus.AWAIT_ARM;
|
||||
component.RemainingTime = component.Timer;
|
||||
PlaySound(uid, component.AccessGrantedSound, 0, component);
|
||||
}
|
||||
else
|
||||
{
|
||||
component.EnteredCode = "";
|
||||
PlaySound(uid, component.AccessDeniedSound, 0, component);
|
||||
}
|
||||
component.Status = NukeStatus.AWAIT_DISK;
|
||||
component.EnteredCode = "";
|
||||
break;
|
||||
}
|
||||
|
||||
var isValid = _codes.IsCodeValid(component.EnteredCode);
|
||||
if (isValid)
|
||||
{
|
||||
component.Status = NukeStatus.AWAIT_ARM;
|
||||
component.RemainingTime = component.Timer;
|
||||
PlaySound(uid, component.AccessGrantedSound, 0, component);
|
||||
}
|
||||
else
|
||||
{
|
||||
component.EnteredCode = "";
|
||||
PlaySound(uid, component.AccessDeniedSound, 0, component);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case NukeStatus.AWAIT_ARM:
|
||||
// do nothing, wait for arm button to be pressed
|
||||
break;
|
||||
@@ -322,6 +369,7 @@ namespace Content.Server.Nuke
|
||||
}
|
||||
|
||||
#region Public API
|
||||
|
||||
/// <summary>
|
||||
/// Force a nuclear bomb to start a countdown timer
|
||||
/// </summary>
|
||||
@@ -350,6 +398,7 @@ namespace Content.Server.Nuke
|
||||
|
||||
NukeArmedAudio(component);
|
||||
|
||||
_itemSlots.SetLock(uid, component.DiskSlot, true);
|
||||
component.Status = NukeStatus.ARMED;
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
@@ -376,6 +425,7 @@ namespace Content.Server.Nuke
|
||||
var sender = Loc.GetString("nuke-component-announcement-sender");
|
||||
_chatSystem.DispatchStationAnnouncement(uid, announcement, sender, false);
|
||||
|
||||
component.PlayedNukeSong = false;
|
||||
NukeDisarmedAudio(component);
|
||||
|
||||
// disable sound and reset it
|
||||
@@ -383,6 +433,7 @@ namespace Content.Server.Nuke
|
||||
component.AlertAudioStream?.Stop();
|
||||
|
||||
// start bomb cooldown
|
||||
_itemSlots.SetLock(uid, component.DiskSlot, false);
|
||||
component.Status = NukeStatus.COOLDOWN;
|
||||
component.CooldownTime = component.Cooldown;
|
||||
|
||||
@@ -440,12 +491,30 @@ namespace Content.Server.Nuke
|
||||
component.RemainingTime = timer;
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void DisarmBombDoafter(EntityUid uid, EntityUid user, NukeComponent nuke)
|
||||
{
|
||||
nuke.DisarmCancelToken = new();
|
||||
var doafter = new DoAfterEventArgs(user, nuke.DisarmDoafterLength, nuke.DisarmCancelToken.Value, uid)
|
||||
{
|
||||
TargetCancelledEvent = new NukeDisarmCancelledEvent(),
|
||||
TargetFinishedEvent = new NukeDisarmSuccessEvent(),
|
||||
BreakOnDamage = true,
|
||||
BreakOnStun = true,
|
||||
BreakOnTargetMove = true,
|
||||
BreakOnUserMove = true,
|
||||
NeedHand = true,
|
||||
};
|
||||
|
||||
_doAfterSystem.DoAfter(doafter);
|
||||
_popups.PopupEntity(Loc.GetString("nuke-component-doafter-warning"), user, Filter.Entities(user));
|
||||
}
|
||||
|
||||
private void NukeArmedAudio(NukeComponent component)
|
||||
{
|
||||
_soundSystem.PlayGlobalOnStation(component.Owner, component.ArmSound.GetSound());
|
||||
_soundSystem.DispatchStationEventMusic(component.Owner, component.ArmMusic, StationEventMusicType.Nuke);
|
||||
}
|
||||
|
||||
private void NukeDisarmedAudio(NukeComponent component)
|
||||
@@ -456,4 +525,15 @@ namespace Content.Server.Nuke
|
||||
}
|
||||
|
||||
public sealed class NukeExplodedEvent : EntityEventArgs {}
|
||||
|
||||
/// <summary>
|
||||
/// Raised directed on the nuke when its disarm doafter is successful.
|
||||
/// </summary>
|
||||
public sealed class NukeDisarmSuccessEvent : EntityEventArgs {}
|
||||
|
||||
/// <summary>
|
||||
/// Raised directed on the nuke when its disarm doafter is cancelled.
|
||||
/// </summary>
|
||||
public sealed class NukeDisarmCancelledEvent : EntityEventArgs {}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user