]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Station event component and system tweaks (#28331)
authorMilenVolf <63782763+MilenVolf@users.noreply.github.com>
Sat, 1 Jun 2024 20:34:58 +0000 (23:34 +0300)
committerGitHub <noreply@github.com>
Sat, 1 Jun 2024 20:34:58 +0000 (16:34 -0400)
* Make anomaly, artifact and gifts events announcement sound optional

* Requested changes + Added new "GameRuleAfterAddedEvent" for StationEventSystem

We need to call "Add" in "StationEventSystem" after others GameRule's in case if we need to change StationEventComponent variables.

* Fix margins

* Makes use of GameRuleComponent.Delay and remove station system handling of delays plus small cleanup

* Fix merge

---------

Co-authored-by: AJCM <AJCM@tutanota.com>
13 files changed:
Content.Server/Chat/Systems/ChatSystem.cs
Content.Server/StationEvents/Components/StationEventComponent.cs
Content.Server/StationEvents/Events/AnomalySpawnRule.cs
Content.Server/StationEvents/Events/BluespaceArtifactRule.cs
Content.Server/StationEvents/Events/BreakerFlipRule.cs
Content.Server/StationEvents/Events/CargoGiftsRule.cs
Content.Server/StationEvents/Events/FalseAlarmRule.cs
Content.Server/StationEvents/Events/GasLeakRule.cs
Content.Server/StationEvents/Events/StationEventSystem.cs
Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMicrophoneSystem.cs
Resources/Locale/en-US/station-events/events/anomaly-spawn.ftl
Resources/Prototypes/GameRules/cargo_gifts.yml
Resources/Prototypes/GameRules/events.yml

index 531c4259efea38004db35af94d9d66a65f5e03ee..b79e16a8df9762b51b6a71c3323e322f156f9b0d 100644 (file)
@@ -823,7 +823,7 @@ public sealed partial class ChatSystem : SharedChatSystem
                 recipients.Add(player, new ICChatRecipientData(-1, true));
         }
 
-        RaiseLocalEvent(new ExpandICChatRecipientstEvent(source, voiceGetRange, recipients));
+        RaiseLocalEvent(new ExpandICChatRecipientsEvent(source, voiceGetRange, recipients));
         return recipients;
     }
 
@@ -868,7 +868,7 @@ public sealed partial class ChatSystem : SharedChatSystem
 ///     This event is raised before chat messages are sent out to clients. This enables some systems to send the chat
 ///     messages to otherwise out-of view entities (e.g. for multiple viewports from cameras).
 /// </summary>
-public record ExpandICChatRecipientstEvent(EntityUid Source, float VoiceRange, Dictionary<ICommonSession, ChatSystem.ICChatRecipientData> Recipients)
+public record ExpandICChatRecipientsEvent(EntityUid Source, float VoiceRange, Dictionary<ICommonSession, ChatSystem.ICChatRecipientData> Recipients)
 {
 }
 
index cc17007d90e5f2a34f7015f47c06ce6e3fa17bed..fdd1d3962e74487c2ce7ebc8d064b40ca35125ab 100644 (file)
@@ -24,6 +24,12 @@ public sealed partial class StationEventComponent : Component
     [DataField]
     public string? EndAnnouncement;
 
+    [DataField]
+    public Color StartAnnouncementColor = Color.Gold;
+
+    [DataField]
+    public Color EndAnnouncementColor = Color.Gold;
+
     [DataField]
     public SoundSpecifier? StartAudio;
 
@@ -42,12 +48,6 @@ public sealed partial class StationEventComponent : Component
     [DataField]
     public int ReoccurrenceDelay = 30;
 
-    /// <summary>
-    ///     How long after being added does the event start
-    /// </summary>
-    [DataField]
-    public TimeSpan StartDelay = TimeSpan.Zero;
-
     /// <summary>
     ///     How long the event lasts.
     /// </summary>
@@ -75,13 +75,6 @@ public sealed partial class StationEventComponent : Component
     [DataField]
     public int? MaxOccurrences;
 
-    /// <summary>
-    /// When the station event starts.
-    /// </summary>
-    [DataField("startTime", customTypeSerializer: typeof(TimeOffsetSerializer))]
-    [AutoPausedField]
-    public TimeSpan StartTime;
-
     /// <summary>
     /// When the station event ends.
     /// </summary>
index 96633834ee10789ee5f8ece87bdc82e3891f5a22..cf66a7c052e482195f265b9ca05dab58158e67e6 100644 (file)
@@ -1,6 +1,5 @@
 using Content.Server.Anomaly;
 using Content.Server.GameTicking.Components;
-using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Station.Components;
 using Content.Server.StationEvents.Components;
 
@@ -12,11 +11,14 @@ public sealed class AnomalySpawnRule : StationEventSystem<AnomalySpawnRuleCompon
 
     protected override void Added(EntityUid uid, AnomalySpawnRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
     {
-        base.Added(uid, component, gameRule, args);
+        if (!TryComp<StationEventComponent>(uid, out var stationEvent))
+            return;
 
         var str = Loc.GetString("anomaly-spawn-event-announcement",
             ("sighting", Loc.GetString($"anomaly-spawn-sighting-{RobustRandom.Next(1, 6)}")));
-        ChatSystem.DispatchGlobalAnnouncement(str, colorOverride: Color.FromHex("#18abf5"));
+        stationEvent.StartAnnouncement = str;
+
+        base.Added(uid, component, gameRule, args);
     }
 
     protected override void Started(EntityUid uid, AnomalySpawnRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
index b3ed10999ed34f175120adc01d581328df6b5bb5..aaa0f0cffc325bbdc1464cdf0e658117617f1ff6 100644 (file)
@@ -1,5 +1,4 @@
 using Content.Server.GameTicking.Components;
-using Content.Server.GameTicking.Rules.Components;
 using Content.Server.StationEvents.Components;
 using Robust.Shared.Random;
 
@@ -9,11 +8,14 @@ public sealed class BluespaceArtifactRule : StationEventSystem<BluespaceArtifact
 {
     protected override void Added(EntityUid uid, BluespaceArtifactRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
     {
-        base.Added(uid, component, gameRule, args);
+        if (!TryComp<StationEventComponent>(uid, out var stationEvent))
+            return;
 
         var str = Loc.GetString("bluespace-artifact-event-announcement",
             ("sighting", Loc.GetString(RobustRandom.Pick(component.PossibleSighting))));
-        ChatSystem.DispatchGlobalAnnouncement(str, colorOverride: Color.FromHex("#18abf5"));
+        stationEvent.StartAnnouncement = str;
+
+        base.Added(uid, component, gameRule, args);
     }
 
     protected override void Started(EntityUid uid, BluespaceArtifactRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
index 16d3fd8c95dfe37b95a0e490b855f44fa42eb436..ef282593897434cc140775f0378849383df412cf 100644 (file)
@@ -1,5 +1,4 @@
 using Content.Server.GameTicking.Components;
-using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Power.Components;
 using Content.Server.Power.EntitySystems;
 using Content.Server.Station.Components;
@@ -15,10 +14,14 @@ public sealed class BreakerFlipRule : StationEventSystem<BreakerFlipRuleComponen
 
     protected override void Added(EntityUid uid, BreakerFlipRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
     {
-        base.Added(uid, component, gameRule, args);
+        if (!TryComp<StationEventComponent>(uid, out var stationEvent))
+            return;
 
         var str = Loc.GetString("station-event-breaker-flip-announcement", ("data", Loc.GetString(Loc.GetString($"random-sentience-event-data-{RobustRandom.Next(1, 6)}"))));
-        ChatSystem.DispatchGlobalAnnouncement(str, playSound: false, colorOverride: Color.Gold);
+        stationEvent.StartAnnouncement = str;
+
+        base.Added(uid, component, gameRule, args);
+
     }
 
     protected override void Started(EntityUid uid, BreakerFlipRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
index c27cd302784aef6e9069b4dc2ed25b412bcd10b0..4cddf4674b303a852146d36358e26458fe1632c8 100644 (file)
@@ -3,7 +3,6 @@ using Content.Server.Cargo.Components;
 using Content.Server.Cargo.Systems;
 using Content.Server.GameTicking;
 using Content.Server.GameTicking.Components;
-using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Station.Components;
 using Content.Server.StationEvents.Components;
 using Robust.Shared.Prototypes;
@@ -18,11 +17,14 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
 
     protected override void Added(EntityUid uid, CargoGiftsRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
     {
-        base.Added(uid, component, gameRule, args);
+        if (!TryComp<StationEventComponent>(uid, out var stationEvent))
+            return;
 
         var str = Loc.GetString(component.Announce,
             ("sender", Loc.GetString(component.Sender)), ("description", Loc.GetString(component.Description)), ("dest", Loc.GetString(component.Dest)));
-        ChatSystem.DispatchGlobalAnnouncement(str, colorOverride: Color.FromHex("#18abf5"));
+        stationEvent.StartAnnouncement = str;
+
+        base.Added(uid, component, gameRule, args);
     }
 
     /// <summary>
index e5317a5449f15ab9c15c409e95e06573f502b8cf..115b6d905eaebc36d1037eae0fe6b988ae69f765 100644 (file)
@@ -1,9 +1,7 @@
 using System.Linq;
 using Content.Server.GameTicking.Components;
-using Content.Server.GameTicking.Rules.Components;
 using Content.Server.StationEvents.Components;
 using JetBrains.Annotations;
-using Robust.Shared.Player;
 using Robust.Shared.Random;
 
 namespace Content.Server.StationEvents.Events;
@@ -15,15 +13,16 @@ public sealed class FalseAlarmRule : StationEventSystem<FalseAlarmRuleComponent>
 
     protected override void Started(EntityUid uid, FalseAlarmRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
     {
-        base.Started(uid, component, gameRule, args);
+        if (!TryComp<StationEventComponent>(uid, out var stationEvent))
+            return;
 
         var allEv = _event.AllEvents().Select(p => p.Value).ToList();
         var picked = RobustRandom.Pick(allEv);
 
-        if (picked.StartAnnouncement != null)
-        {
-            ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(picked.StartAnnouncement), playSound: false, colorOverride: Color.Gold);
-        }
-        Audio.PlayGlobal(picked.StartAudio, Filter.Broadcast(), true);
+        stationEvent.StartAnnouncement = picked.StartAnnouncement;
+        stationEvent.StartAudio = picked.StartAudio;
+        stationEvent.StartAnnouncementColor = picked.StartAnnouncementColor;
+
+        base.Started(uid, component, gameRule, args);
     }
 }
index 1221612171d9e1c175d4011f5b8bee59d2862933..c17f17a8279dd63abd320643eb0a6aa121ff29e1 100644 (file)
@@ -29,10 +29,10 @@ namespace Content.Server.StationEvents.Events
                 component.LeakGas = RobustRandom.Pick(component.LeakableGases);
                 // Was 50-50 on using normal distribution.
                 var totalGas = RobustRandom.Next(component.MinimumGas, component.MaximumGas);
-                var startAfter = stationEvent.StartDelay;
                 component.MolesPerSecond = RobustRandom.Next(component.MinimumMolesPerSecond, component.MaximumMolesPerSecond);
 
-                stationEvent.EndTime = _timing.CurTime + TimeSpan.FromSeconds(totalGas / component.MolesPerSecond + startAfter.TotalSeconds);
+                if (gameRule.Delay is {} startAfter)
+                    stationEvent.EndTime = _timing.CurTime + TimeSpan.FromSeconds(totalGas / component.MolesPerSecond + startAfter.Next(RobustRandom));
             }
 
             // Look technically if you wanted to guarantee a leak you'd do this in announcement but having the announcement
index bd377ec16c83c52a014d915b192a427f85b8052d..38390cedb1a9d5e68439ba9bdb668405640d1eca 100644 (file)
@@ -1,14 +1,11 @@
-using System.Linq;
 using Content.Server.Administration.Logs;
 using Content.Server.Chat.Systems;
 using Content.Server.GameTicking.Components;
 using Content.Server.GameTicking.Rules;
-using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Station.Systems;
 using Content.Server.StationEvents.Components;
 using Content.Shared.Database;
 using Robust.Shared.Audio.Systems;
-using Robust.Shared.Map;
 using Robust.Shared.Player;
 using Robust.Shared.Prototypes;
 
@@ -20,7 +17,6 @@ namespace Content.Server.StationEvents.Events;
 public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : IComponent
 {
     [Dependency] protected readonly IAdminLogManager AdminLogManager = default!;
-    [Dependency] protected readonly IMapManager MapManager = default!;
     [Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
     [Dependency] protected readonly ChatSystem ChatSystem = default!;
     [Dependency] protected readonly SharedAudioSystem Audio = default!;
@@ -43,16 +39,12 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : ICompo
         if (!TryComp<StationEventComponent>(uid, out var stationEvent))
             return;
 
-
         AdminLogManager.Add(LogType.EventAnnounced, $"Event added / announced: {ToPrettyString(uid)}");
 
         if (stationEvent.StartAnnouncement != null)
-        {
-            ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.StartAnnouncement), playSound: false, colorOverride: Color.Gold);
-        }
+            ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.StartAnnouncement), playSound: false, colorOverride: stationEvent.StartAnnouncementColor);
 
         Audio.PlayGlobal(stationEvent.StartAudio, Filter.Broadcast(), true);
-        stationEvent.StartTime = Timing.CurTime + stationEvent.StartDelay;
     }
 
     /// <inheritdoc/>
@@ -86,9 +78,7 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : ICompo
         AdminLogManager.Add(LogType.EventStopped, $"Event ended: {ToPrettyString(uid)}");
 
         if (stationEvent.EndAnnouncement != null)
-        {
-            ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.EndAnnouncement), playSound: false, colorOverride: Color.Gold);
-        }
+            ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.EndAnnouncement), playSound: false, colorOverride: stationEvent.EndAnnouncementColor);
 
         Audio.PlayGlobal(stationEvent.EndAudio, Filter.Broadcast(), true);
     }
@@ -108,11 +98,7 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : ICompo
             if (!GameTicker.IsGameRuleAdded(uid, ruleData))
                 continue;
 
-            if (!GameTicker.IsGameRuleActive(uid, ruleData) && Timing.CurTime >= stationEvent.StartTime)
-            {
-                GameTicker.StartGameRule(uid, ruleData);
-            }
-            else if (stationEvent.EndTime != null && Timing.CurTime >= stationEvent.EndTime && GameTicker.IsGameRuleActive(uid, ruleData))
+            if (stationEvent.EndTime != null && Timing.CurTime >= stationEvent.EndTime && GameTicker.IsGameRuleActive(uid, ruleData))
             {
                 GameTicker.EndGameRule(uid, ruleData);
             }
index f411001bd3a3dda79540ab3ce49aa3ae69b7bc2e..1adab9930d91a247c3999b7ce0735d69f4e61f6a 100644 (file)
@@ -16,10 +16,10 @@ public sealed class SurveillanceCameraMicrophoneSystem : EntitySystem
         SubscribeLocalEvent<SurveillanceCameraMicrophoneComponent, ComponentInit>(OnInit);
         SubscribeLocalEvent<SurveillanceCameraMicrophoneComponent, ListenEvent>(RelayEntityMessage);
         SubscribeLocalEvent<SurveillanceCameraMicrophoneComponent, ListenAttemptEvent>(CanListen);
-        SubscribeLocalEvent<ExpandICChatRecipientstEvent>(OnExpandRecipients);
+        SubscribeLocalEvent<ExpandICChatRecipientsEvent>(OnExpandRecipients);
     }
 
-    private void OnExpandRecipients(ExpandICChatRecipientstEvent ev)
+    private void OnExpandRecipients(ExpandICChatRecipientsEvent ev)
     {
         var xformQuery = GetEntityQuery<TransformComponent>();
         var sourceXform = Transform(ev.Source);
index 0e4b5f6e39c2f3b8c4417acb1400381f0c156db8..907c14ce56218f43c717f5b2afdc4b7026510d5d 100644 (file)
@@ -1,4 +1,4 @@
-anomaly-spawn-event-announcement = Our readings have detected a dangerous interspacial anomaly. Please inform the research team of { $sighting }.
+anomaly-spawn-event-announcement = Our readings have detected a dangerous interspacial anomaly. Please inform the research team about { $sighting }.
 
 anomaly-spawn-sighting-1 = low pulsating sounds heard throughout the station
 anomaly-spawn-sighting-2 = strange sources of light
index 62ec96d6a6df4578982958a62e1408f70e72c40b..c5a525129707211dfbf9579ff74ff2ea3b7685d4 100644 (file)
@@ -1,16 +1,30 @@
 - type: entity
-  id: GiftsPizzaPartySmall
+  id: CargoGiftsBase
   parent: BaseGameRule
+  abstract: true
+  components:
+  - type: GameRule
+    delay:
+      min: 10
+      max: 10
+  - type: StationEvent
+    startColor: "#18abf5"
+    startAudio:
+      path: /Audio/Announcements/announce.ogg
+  - type: CargoGiftsRule
+    sender: cargo-gift-default-sender
+
+- type: entity
+  id: GiftsPizzaPartySmall
+  parent: CargoGiftsBase
   noSpawn: true
   components:
   - type: StationEvent
     weight: 5
-    startDelay: 10
     duration: 120
     earliestStart: 20
   - type: CargoGiftsRule
     description: cargo-gift-pizza-small
-    sender: cargo-gift-default-sender
     dest: cargo-gift-dest-bar
     gifts:
       FoodPizza: 1              # 4 pizzas
 
 - type: entity
   id: GiftsPizzaPartyLarge
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 2
-      startDelay: 10
-      duration: 240
-      earliestStart: 20
-      minimumPlayers: 40
-    - type: CargoGiftsRule
-      description: cargo-gift-pizza-large
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-bar
-      gifts:
-        FoodPizzaLarge: 1              # 16 pizzas
-        FoodBarSupply: 1
-        FoodSoftdrinksLarge: 1
+  - type: StationEvent
+    weight: 2
+    duration: 240
+    earliestStart: 20
+    minimumPlayers: 40
+  - type: CargoGiftsRule
+    description: cargo-gift-pizza-large
+    dest: cargo-gift-dest-bar
+    gifts:
+      FoodPizzaLarge: 1              # 16 pizzas
+      FoodBarSupply: 1
+      FoodSoftdrinksLarge: 1
 
 - type: entity
   id: GiftsEngineering
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 5
-      startDelay: 10
-      duration: 240
-      earliestStart: 30
-      minimumPlayers: 10
-    - type: CargoGiftsRule
-      description: cargo-gift-eng
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-eng
-      gifts:
-        EngineeringCableBulk: 1
-        AirlockKit: 1
-        MaterialSteel: 1
-        MaterialPlasteel: 1
-        MaterialGlass: 1
-        CrateVendingMachineRestockEngineering: 1
+  - type: StationEvent
+    weight: 5
+    duration: 240
+    earliestStart: 30
+    minimumPlayers: 10
+  - type: CargoGiftsRule
+    description: cargo-gift-eng
+    dest: cargo-gift-dest-eng
+    gifts:
+      EngineeringCableBulk: 1
+      AirlockKit: 1
+      MaterialSteel: 1
+      MaterialPlasteel: 1
+      MaterialGlass: 1
+      CrateVendingMachineRestockEngineering: 1
 
 - type: entity
   id: GiftsVendingRestock
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 4
-      startDelay: 10
-      duration: 120
-      minimumPlayers: 40
-      earliestStart: 30
-    - type: CargoGiftsRule
-      description: cargo-gift-vending
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-supp
-      gifts:
-        CrateVendingMachineRestockHotDrinks: 3
-        CrateVendingMachineRestockBooze: 1
-        CrateVendingMachineRestockNutriMax: 1
-        CrateVendingMachineRestockRobustSoftdrinks: 2
-        CrateVendingMachineRestockVendomat: 1
-        CrateVendingMachineRestockGetmoreChocolateCorp: 1
+  - type: StationEvent
+    weight: 4
+    duration: 120
+    minimumPlayers: 40
+    earliestStart: 30
+  - type: CargoGiftsRule
+    description: cargo-gift-vending
+    dest: cargo-gift-dest-supp
+    gifts:
+      CrateVendingMachineRestockHotDrinks: 3
+      CrateVendingMachineRestockBooze: 1
+      CrateVendingMachineRestockNutriMax: 1
+      CrateVendingMachineRestockRobustSoftdrinks: 2
+      CrateVendingMachineRestockVendomat: 1
+      CrateVendingMachineRestockGetmoreChocolateCorp: 1
 
 - type: entity
   id: GiftsJanitor
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 6
-      startDelay: 10
-      duration: 120
-      minimumPlayers: 30
-      earliestStart: 20
-    - type: CargoGiftsRule
-      description: cargo-gift-cleaning
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-janitor
-      gifts:
-        ServiceJanitorial: 2
-        ServiceLightsReplacement: 2
-        ServiceJanitorBiosuit: 1
+  - type: StationEvent
+    weight: 6
+    duration: 120
+    minimumPlayers: 30
+    earliestStart: 20
+  - type: CargoGiftsRule
+    description: cargo-gift-cleaning
+    dest: cargo-gift-dest-janitor
+    gifts:
+      ServiceJanitorial: 2
+      ServiceLightsReplacement: 2
+      ServiceJanitorBiosuit: 1
 
 - type: entity
   id: GiftsMedical
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 8
-      startDelay: 10
-      duration: 120
-      earliestStart: 20
-      minimumPlayers: 30
-    - type: CargoGiftsRule
-      description: cargo-gift-medical-supply
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-med
-      gifts:
-        MedicalSupplies: 1
-        MedicalChemistrySupplies: 1
-        EmergencyBruteKit: 1
-        EmergencyAdvancedKit: 1
-        MedicalBiosuit: 1
+  - type: StationEvent
+    weight: 8
+    duration: 120
+    earliestStart: 20
+    minimumPlayers: 30
+  - type: CargoGiftsRule
+    description: cargo-gift-medical-supply
+    dest: cargo-gift-dest-med
+    gifts:
+      MedicalSupplies: 1
+      MedicalChemistrySupplies: 1
+      EmergencyBruteKit: 1
+      EmergencyAdvancedKit: 1
+      MedicalBiosuit: 1
 
 - type: entity
   id: GiftsSpacingSupplies
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 4
-      startDelay: 10
-      duration: 120
-      earliestStart: 10
-      minimumPlayers: 40
-    - type: CargoGiftsRule
-      description: cargo-gift-space-protection
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-supp
-      gifts:
-        EmergencyInternalsLarge: 2
-        EmergencyInflatablewall: 1
-        EmergencyAdvancedKit: 1
-        MedicalBiosuit: 1
-        EmergencyO2Kit: 1
+  - type: StationEvent
+    weight: 4
+    duration: 120
+    earliestStart: 10
+    minimumPlayers: 40
+  - type: CargoGiftsRule
+    description: cargo-gift-space-protection
+    dest: cargo-gift-dest-supp
+    gifts:
+      EmergencyInternalsLarge: 2
+      EmergencyInflatablewall: 1
+      EmergencyAdvancedKit: 1
+      MedicalBiosuit: 1
+      EmergencyO2Kit: 1
 
 - type: entity
   id: GiftsFireProtection
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 4
-      startDelay: 10
-      duration: 120
-      earliestStart: 20
-      minimumPlayers: 40
-    - type: CargoGiftsRule
-      description: cargo-gift-fire-protection
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-supp
-      gifts:
-        EmergencyFire: 2
-        EmergencyBurnKit: 1
-        EmergencyBruteKit: 1
+  - type: StationEvent
+    weight: 4
+    duration: 120
+    earliestStart: 20
+    minimumPlayers: 40
+  - type: CargoGiftsRule
+    description: cargo-gift-fire-protection
+    dest: cargo-gift-dest-supp
+    gifts:
+      EmergencyFire: 2
+      EmergencyBurnKit: 1
+      EmergencyBruteKit: 1
 
 - type: entity
   id: GiftsSecurityGuns
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 3
-      startDelay: 10
-      duration: 120
-      earliestStart: 20
-      minimumPlayers: 50
-    - type: CargoGiftsRule
-      description: cargo-gift-security-guns
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-sec
-      gifts:
-        SecurityArmor: 3
-        ArmorySmg: 1
-        ArmoryShotgun: 1
-        ArmoryLaser: 1
+  - type: StationEvent
+    weight: 3
+    duration: 120
+    earliestStart: 20
+    minimumPlayers: 50
+  - type: CargoGiftsRule
+    description: cargo-gift-security-guns
+    dest: cargo-gift-dest-sec
+    gifts:
+      SecurityArmor: 3
+      ArmorySmg: 1
+      ArmoryShotgun: 1
+      ArmoryLaser: 1
 
 - type: entity
   id: GiftsSecurityRiot
-  parent: BaseGameRule
+  parent: CargoGiftsBase
   noSpawn: true
   components:
-    - type: StationEvent
-      weight: 4
-      startDelay: 10
-      duration: 120
-      earliestStart: 20
-      minimumPlayers: 50
-    - type: CargoGiftsRule
-      description: cargo-gift-security-riot
-      sender: cargo-gift-default-sender
-      dest: cargo-gift-dest-sec
-      gifts:
-        SecurityRiot: 2
-        SecurityRestraints: 2
-        SecurityNonLethal: 2
+  - type: StationEvent
+    weight: 4
+    duration: 120
+    earliestStart: 20
+    minimumPlayers: 50
+  - type: CargoGiftsRule
+    description: cargo-gift-security-riot
+    dest: cargo-gift-dest-sec
+    gifts:
+      SecurityRiot: 2
+      SecurityRestraints: 2
+      SecurityNonLethal: 2
index 9dabc14a344e70fcad604f2448dd1fce7d5c3aa8..9f6e6a812574585b5731a0a4bf5f736352c8debb 100644 (file)
@@ -1,22 +1,63 @@
 - type: entity
-  id: AnomalySpawn
+  id: BaseStationEvent
+  parent: BaseGameRule
+  abstract: true
+  noSpawn: true
+  components:
+    - type: GameRule
+      delay:
+        min:  10
+        max:  20
+
+- type: entity
+  id: BaseStationEventShortDelay
   parent: BaseGameRule
+  abstract: true
+  noSpawn: true
+  components:
+    - type: GameRule
+      delay:
+        min:  10
+        max:  20
+
+- type: entity
+  id: BaseStationEventLongDelay
+  parent: BaseGameRule
+  abstract: true
+  noSpawn: true
+  components:
+    - type: GameRule
+      delay:
+        min:  40
+        max:  60
+
+- type: entity
+  id: AnomalySpawn
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
   - type: StationEvent
+    startAnnouncementColor: "#18abf5"
+    startAudio:
+      path: /Audio/Announcements/announce.ogg
     weight: 8
-    startDelay: 30
     duration: 35
   - type: AnomalySpawnRule
 
 - type: entity
   id: BluespaceArtifact
-  parent: BaseGameRule
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
+  - type: GameRule
+    delay:
+      min:  30
+      max:  30
   - type: StationEvent
+    startAnnouncementColor: "#18abf5"
+    startAudio:
+      path: /Audio/Announcements/announce.ogg
     weight: 8
-    startDelay: 30
     duration: 35
   - type: BluespaceArtifactRule
 
 
 - type: entity
   id: GasLeak
-  parent: BaseGameRule
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
   - type: StationEvent
       path: /Audio/Announcements/attention.ogg
     endAnnouncement: station-event-gas-leak-end-announcement
     weight: 8
-    startDelay: 20
   - type: GasLeakRule
 
 - type: entity
   id: KudzuGrowth
-  parent: BaseGameRule
+  parent: BaseStationEventLongDelay
   noSpawn: true
   components:
   - type: StationEvent
     earliestStart: 15
     minimumPlayers: 15
     weight: 7
-    startDelay: 50
     duration: 240
   - type: KudzuGrowthRule
 
 - type: entity
   id: MeteorSwarm
-  parent: BaseGameRule
+  parent: BaseStationEventLongDelay
   noSpawn: true
   components:
   - type: StationEvent
       params:
         volume: -4
     duration: null #ending is handled by MeteorSwarmRule
-    startDelay: 30
   - type: MeteorSwarmRule
 
 - type: entity
   id: MouseMigration
-  parent: BaseGameRule
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
   - type: StationEvent
     startAnnouncement: station-event-vent-creatures-start-announcement
     startAudio:
       path: /Audio/Announcements/attention.ogg
-    startDelay: 10
     earliestStart: 15
     weight: 6
     duration: 50
 
 - type: entity
   id: CockroachMigration
-  parent: BaseGameRule
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
   - type: StationEvent
     startAnnouncement: station-event-vent-creatures-start-announcement
     startAudio:
       path: /Audio/Announcements/attention.ogg
-    startDelay: 10
     weight: 6
     duration: 50
   - type: VentCrittersRule
 
 - type: entity
   id: PowerGridCheck
-  parent: BaseGameRule
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
   - type: StationEvent
       path: /Audio/Announcements/power_off.ogg
       params:
        volume: -4
-    startDelay: 24
     duration: 60
     maxDuration: 120
   - type: PowerGridCheckRule
 
 - type: entity
   id: VentClog
-  parent: BaseGameRule
+  parent: BaseStationEventLongDelay
   noSpawn: true
   components:
   - type: StationEvent
     earliestStart: 15
     minimumPlayers: 15
     weight: 5
-    startDelay: 50
     duration: 60
   - type: VentClogRule
 
 - type: entity
   id: SlimesSpawn
-  parent: BaseGameRule
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
   - type: StationEvent
     startAnnouncement: station-event-vent-creatures-start-announcement
     startAudio:
       path: /Audio/Announcements/attention.ogg
-    startDelay: 10
     earliestStart: 20
     minimumPlayers: 15
     weight: 5
 
 - type: entity
   id: SpiderSpawn
-  parent: BaseGameRule
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
   - type: StationEvent
     startAnnouncement: station-event-vent-creatures-start-announcement
     startAudio:
       path: /Audio/Announcements/attention.ogg
-    startDelay: 10
     earliestStart: 20
     minimumPlayers: 15
     weight: 5
 
 - type: entity
   id: SpiderClownSpawn
-  parent: BaseGameRule
+  parent: BaseStationEventShortDelay
   noSpawn: true
   components:
   - type: StationEvent
     startAnnouncement: station-event-vent-creatures-start-announcement
     startAudio:
       path: /Audio/Announcements/attention.ogg
-    startDelay: 10
     earliestStart: 20
     minimumPlayers: 20
     weight: 1.5