Files
wwdpublic/Content.Server/Nuke/NukeCodePaperSystem.cs
DEATHB4DEFEAT e3bc8d4c0e Random Announcer System (#415)
# Description

Replaces every instance of station announcements with an announcer
system meant to handle audio and messages for various announcers defined
in prototypes instead of each server replacing the scattered files
inconsistently with whatever singular thing they want to hear announce
messages.

# TODO

- [x] Systems
- [x] CVars
- [x] Sounds
- [x] Client volume slider
- [x] Collections
- [x] Prototypes
- [x] Events
- [x] Commands
- [x] PR media
- [x] Deglobalize
- [x] Passthrough localization parameters to overrides
- [x] Make every announcer follow the template
- [x] Move sounds into subdirectories
- [x] Make announcement IDs camelCased
- [x] Test announcement localizations
- [x] Weighted announcer lists

---

<details><summary><h1>Media</h1></summary>
<p>


https://github.com/Simple-Station/Parkstation-Friendly-Chainsaw/assets/77995199/caf5805d-acb0-4140-b344-875a8f79e5ee

</p>
</details>

---

# Changelog

🆑
- add: Added 4 new announcers that will randomly be selected every shift
2024-07-12 16:13:50 -04:00

134 lines
4.8 KiB
C#

using System.Diagnostics.CodeAnalysis;
using Content.Server.Chat.Systems;
using Content.Server.Fax;
using Content.Server.Paper;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared.Paper;
using Robust.Shared.Random;
using Robust.Shared.Utility;
using Content.Server.Announcements.Systems;
using Robust.Shared.Player;
namespace Content.Server.Nuke
{
public sealed class NukeCodePaperSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly PaperSystem _paper = default!;
[Dependency] private readonly FaxSystem _faxSystem = default!;
[Dependency] private readonly AnnouncerSystem _announcer = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<NukeCodePaperComponent, MapInitEvent>(OnMapInit,
after: new []{ typeof(NukeLabelSystem) });
}
private void OnMapInit(EntityUid uid, NukeCodePaperComponent component, MapInitEvent args)
{
SetupPaper(uid, component);
}
private void SetupPaper(EntityUid uid, NukeCodePaperComponent? component = null, EntityUid? station = null)
{
if (!Resolve(uid, ref component))
return;
if (TryGetRelativeNukeCode(uid, out var paperContent, station, onlyCurrentStation: component.AllNukesAvailable))
{
_paper.SetContent(uid, paperContent);
}
}
/// <summary>
/// Send a nuclear code to all faxes on that station which are authorized to receive nuke codes.
/// </summary>
/// <returns>True if at least one fax received codes</returns>
public bool SendNukeCodes(EntityUid station)
{
if (!HasComp<StationDataComponent>(station))
{
return false;
}
var faxes = EntityQueryEnumerator<FaxMachineComponent>();
var wasSent = false;
while (faxes.MoveNext(out var faxEnt, out var fax))
{
if (!fax.ReceiveNukeCodes || !TryGetRelativeNukeCode(faxEnt, out var paperContent, station))
continue;
var printout = new FaxPrintout(
paperContent,
Loc.GetString("nuke-codes-fax-paper-name"),
null,
"paper_stamp-centcom",
new List<StampDisplayInfo>
{
new StampDisplayInfo { StampedName = Loc.GetString("stamp-component-stamped-name-centcom"), StampedColor = Color.FromHex("#BB3232") },
}
);
_faxSystem.Receive(faxEnt, printout, null, fax);
wasSent = true;
}
if (wasSent)
_announcer.SendAnnouncement(_announcer.GetAnnouncementId("NukeCodes"), Filter.Broadcast(),
"nuke-component-announcement-send-codes", colorOverride: Color.Red);
return wasSent;
}
private bool TryGetRelativeNukeCode(
EntityUid uid,
[NotNullWhen(true)] out string? nukeCode,
EntityUid? station = null,
TransformComponent? transform = null,
bool onlyCurrentStation = false)
{
nukeCode = null;
if (!Resolve(uid, ref transform))
{
return false;
}
var owningStation = station ?? _station.GetOwningStation(uid);
var codesMessage = new FormattedMessage();
// Find the first nuke that matches the passed location.
var nukes = new List<Entity<NukeComponent>>();
var query = EntityQueryEnumerator<NukeComponent>();
while (query.MoveNext(out var nukeUid, out var nuke))
{
nukes.Add((nukeUid, nuke));
}
_random.Shuffle(nukes);
foreach (var (nukeUid, nuke) in nukes)
{
if (!onlyCurrentStation &&
(owningStation == null &&
nuke.OriginMapGrid != (transform.MapID, transform.GridUid) ||
nuke.OriginStation != owningStation))
{
continue;
}
codesMessage.PushNewline();
codesMessage.AddMarkup(Loc.GetString("nuke-codes-list", ("name", MetaData(nukeUid).EntityName), ("code", nuke.Code)));
break;
}
if (!codesMessage.IsEmpty)
nukeCode = Loc.GetString("nuke-codes-message")+codesMessage;
return !codesMessage.IsEmpty;
}
}
}