diff --git a/Content.Server/StationEvents/Components/ClericalErrorRuleComponent.cs b/Content.Server/StationEvents/Components/ClericalErrorRuleComponent.cs new file mode 100644 index 0000000000..afbb992475 --- /dev/null +++ b/Content.Server/StationEvents/Components/ClericalErrorRuleComponent.cs @@ -0,0 +1,23 @@ +using Content.Server.StationEvents.Events; + +namespace Content.Server.StationEvents.Components; + +/// +/// This is a station event that randomly removes some records from the station record database. +/// +[RegisterComponent] +[Access(typeof(ClericalErrorRule))] +public sealed partial class ClericalErrorRuleComponent : Component +{ + /// + /// The minimum percentage number of records to remove from the station. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float MinToRemove = 0.0025f; + + /// + /// The maximum percentage number of records to remove from the station. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float MaxToRemove = 0.1f; +} diff --git a/Content.Server/StationEvents/Events/ClericalErrorRule.cs b/Content.Server/StationEvents/Events/ClericalErrorRule.cs new file mode 100644 index 0000000000..c1b4cd9334 --- /dev/null +++ b/Content.Server/StationEvents/Events/ClericalErrorRule.cs @@ -0,0 +1,43 @@ +using Content.Server.GameTicking.Rules.Components; +using Content.Server.StationEvents.Components; +using Content.Server.StationRecords; +using Content.Server.StationRecords.Systems; +using Content.Shared.StationRecords; +using Robust.Shared.Random; + +namespace Content.Server.StationEvents.Events; + +public sealed class ClericalErrorRule : StationEventSystem +{ + [Dependency] private readonly StationRecordsSystem _stationRecords = default!; + + protected override void Started(EntityUid uid, ClericalErrorRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) + { + base.Started(uid, component, gameRule, args); + + if (!TryGetRandomStation(out var chosenStation)) + return; + + if (!TryComp(chosenStation, out var stationRecords)) + return; + + var recordCount = stationRecords.Records.Keys.Count; + + if (recordCount == 0) + return; + + var min = (int) Math.Max(1, Math.Round(component.MinToRemove * recordCount)); + var max = (int) Math.Max(min, Math.Round(component.MaxToRemove * recordCount)); + var toRemove = RobustRandom.Next(min, max); + var keys = new List(); + for (var i = 0; i < toRemove; i++) + { + keys.Add(RobustRandom.Pick(stationRecords.Records.Keys)); + } + + foreach (var key in keys) + { + _stationRecords.RemoveRecord(chosenStation.Value, key, stationRecords); + } + } +} diff --git a/Resources/Locale/en-US/station-events/events/bureaucratic-error.ftl b/Resources/Locale/en-US/station-events/events/bureaucratic-error.ftl index 8042ac871e..9323c4cb8c 100644 --- a/Resources/Locale/en-US/station-events/events/bureaucratic-error.ftl +++ b/Resources/Locale/en-US/station-events/events/bureaucratic-error.ftl @@ -1 +1,2 @@ station-event-bureaucratic-error-announcement = A recent bureaucratic error in the Organic Resources Department may result in personnel shortages in some departments and redundant staffing in others. +station-event-clerical-error-announcement = A minor clerical error in the Organic Resources Department has resulted in the permanent destruction of some of the station records. diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 6534a686ea..b197b643f3 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -55,6 +55,18 @@ duration: 1 - type: BureaucraticErrorRule +- type: entity + id: ClericalError + parent: BaseGameRule + noSpawn: true + components: + - type: StationEvent + startAnnouncement: station-event-clerical-error-announcement + minimumPlayers: 15 + weight: 5 + duration: 1 + - type: ClericalErrorRule + - type: entity parent: BaseGameRule id: ClosetSkeleton