nuke me harder

This commit is contained in:
Janet Blackquill 2026-06-16 13:53:00 -04:00
parent 3cfbc26090
commit 450ee88dc0
3 changed files with 108 additions and 2 deletions

View File

@ -1,4 +1,40 @@
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server._DV.Uprising;
[RegisterComponent, Access(typeof(UprisingRuleSystem))]
public sealed partial class UprisingRuleComponent : Component;
[RegisterComponent, Access(typeof(UprisingRuleSystem)), AutoGenerateComponentPause]
public sealed partial class UprisingRuleComponent : Component
{
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan? NukeAnnouncementAt;
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan? NukeTimeAt;
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan? FirstWarningAt;
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan? ImpendingWarningAt;
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan? FinalWarningAt;
[DataField]
public TimeSpan NukeAnnouncementDelay = TimeSpan.FromMinutes(30);
[DataField]
public TimeSpan NukeTimeDelay = TimeSpan.FromMinutes(90);
[DataField]
public TimeSpan FirstWarning = TimeSpan.FromMinutes(30);
[DataField]
public TimeSpan ImpendingWarning = TimeSpan.FromMinutes(15);
[DataField]
public TimeSpan FinalWarning = TimeSpan.FromMinutes(5);
[DataField]
public float NukeDuration = 60f;
}

View File

@ -1,11 +1,19 @@
using Content.Server.GameTicking.Rules;
using Content.Server.Nuke;
using Content.Server.Roles;
using Content.Shared._DV.Roles;
using Content.Shared.Chat;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.GameTicking.Components;
namespace Content.Server._DV.Uprising;
public sealed class UprisingRuleSystem : GameRuleSystem<UprisingRuleComponent>
{
[Dependency] private readonly SharedChatSystem _chat = default!;
[Dependency] private readonly NukeSystem _nuke = default!;
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
public override void Initialize()
{
base.Initialize();
@ -14,6 +22,64 @@ public sealed class UprisingRuleSystem : GameRuleSystem<UprisingRuleComponent>
SubscribeLocalEvent<InsurgentRoleComponent, GetBriefingEvent>(OnGetInsurgentBriefing);
}
protected override void Started(EntityUid uid, UprisingRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);
component.NukeAnnouncementAt = Timing.CurTime + component.NukeAnnouncementDelay;
component.NukeTimeAt = Timing.CurTime + component.NukeTimeDelay;
component.FirstWarningAt = Timing.CurTime + component.FirstWarning;
component.ImpendingWarningAt = Timing.CurTime + component.ImpendingWarning;
component.FinalWarningAt = Timing.CurTime + component.FinalWarning;
}
protected override void ActiveTick(EntityUid uid, UprisingRuleComponent component, GameRuleComponent gameRule, float frameTime)
{
base.ActiveTick(uid, component, gameRule, frameTime);
if (component.NukeAnnouncementAt is { } nukeAnnouncement && nukeAnnouncement <= Timing.CurTime)
{
var time = component.NukeTimeAt.HasValue ? component.NukeTimeAt.Value - Timing.CurTime : component.NukeTimeDelay;
_chat.DispatchGlobalAnnouncement(Loc.GetString("uprising-announcement-nuke-announcement", ("time", (int)Math.Round(time.TotalMinutes))));
component.NukeAnnouncementAt = null;
}
if (component.FirstWarningAt is { } firstWarning && firstWarning <= Timing.CurTime)
{
var time = component.NukeTimeAt.HasValue ? component.NukeTimeAt.Value - Timing.CurTime : component.FirstWarning;
_chat.DispatchGlobalAnnouncement(Loc.GetString("uprising-announcement-first-warning", ("time", (int)Math.Round(time.TotalMinutes))));
component.FirstWarningAt = null;
}
if (component.ImpendingWarningAt is { } impendingWarning && impendingWarning <= Timing.CurTime)
{
var time = component.NukeTimeAt.HasValue ? component.NukeTimeAt.Value - Timing.CurTime : component.ImpendingWarning;
_chat.DispatchGlobalAnnouncement(Loc.GetString("uprising-announcement-impending-warning", ("time", (int)Math.Round(time.TotalMinutes))));
component.ImpendingWarningAt = null;
}
if (component.FinalWarningAt is { } finalWarning && finalWarning <= Timing.CurTime)
{
var time = component.NukeTimeAt.HasValue ? component.NukeTimeAt.Value - Timing.CurTime : component.FinalWarning;
_chat.DispatchGlobalAnnouncement(Loc.GetString("uprising-announcement-impending-warning", ("time", (int)Math.Round(time.TotalMinutes))));
component.FinalWarningAt = null;
}
if (component.NukeTimeAt is { } nukeTime && nukeTime <= Timing.CurTime)
{
component.NukeTimeAt = null;
var query = EntityQueryEnumerator<NukeComponent>();
while (query.MoveNext(out var bombUid, out var bomb))
{
_nuke.SetRemainingTime(bombUid, component.NukeDuration, bomb);
_itemSlots.SetLock(bombUid, bomb.DiskSlot, false);
_itemSlots.TryEject(bombUid, bomb.DiskSlot, null, out _, true);
_itemSlots.SetLock(bombUid, bomb.DiskSlot, true);
_nuke.ArmBomb(bombUid, bomb);
}
}
}
private void OnGetLoyalistBriefing(Entity<LoyalistRoleComponent> ent, ref GetBriefingEvent args)
{
args.Append(Loc.GetString("antag-Loyalist.briefing"));

View File

@ -0,0 +1,4 @@
uprising-announcement-nuke-announcement = Automated risk management systems have flagged your station as posing a threat to NanoTrasen. Contracts will be terminated in {$time} minutes unless the situation resolves.
uprising-announcement-first-warning = Automated risk management systems still continue to flag your station as posing a threat to NanoTrasen. Please intervene within {$time} minutes.
uprising-announcement-impending-warning = Automated risk management systems have initiated a task in the contract termination subsystem for your station. The decision will be rendered final in {$time} minutes.
uprising-announcement-final-warning = Contract termination will begin in {$time} minutes.