diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs
index 2a33d01bd09e..b0806c3d6e4f 100644
--- a/Content.Server/GameTicking/GameTicker.GameRule.cs
+++ b/Content.Server/GameTicking/GameTicker.GameRule.cs
@@ -9,6 +9,7 @@
using Robust.Shared.Console;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
namespace Content.Server.GameTicking;
@@ -150,6 +151,16 @@ public bool StartGameRule(EntityUid ruleEntity, GameRuleComponent? ruleData = nu
_allPreviousGameRules.Add((currentTime, id));
}
+ if (ruleData.FalseActivationProb != 0f)
+ {
+ if (_robustRandom.Prob(ruleData.FalseActivationProb))
+ {
+ _adminLogger.Add(LogType.EventStarted, LogImpact.High, $"Event fake started: {ToPrettyString(ruleEntity)}");
+ EndGameRule(ruleEntity, ruleData);
+ return false;
+ }
+ }
+
_sawmill.Info($"Started game rule {ToPrettyString(ruleEntity)}");
_adminLogger.Add(LogType.EventStarted, $"Started game rule {ToPrettyString(ruleEntity)}");
diff --git a/Content.Server/StationEvents/Components/AlertLevelInterceptionRuleComponent.cs b/Content.Server/StationEvents/Components/AlertLevelInterceptionRuleComponent.cs
deleted file mode 100644
index 6907aa617608..000000000000
--- a/Content.Server/StationEvents/Components/AlertLevelInterceptionRuleComponent.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Content.Server.StationEvents.Events;
-using Content.Server.AlertLevel;
-using Robust.Shared.Prototypes;
-
-namespace Content.Server.StationEvents.Components;
-
-[RegisterComponent, Access(typeof(AlertLevelInterceptionRule))]
-public sealed partial class AlertLevelInterceptionRuleComponent : Component
-{
- ///
- /// Alert level to set the station to when the event starts.
- ///
- [DataField]
- public string AlertLevel = "blue";
-}
diff --git a/Content.Server/StationEvents/Components/StartStationEventRuleComponent.cs b/Content.Server/StationEvents/Components/StartStationEventRuleComponent.cs
new file mode 100644
index 000000000000..5fe6838c7266
--- /dev/null
+++ b/Content.Server/StationEvents/Components/StartStationEventRuleComponent.cs
@@ -0,0 +1,9 @@
+using Content.Server.StationEvents.Events;
+
+namespace Content.Server.StationEvents.Components;
+
+[RegisterComponent, Access(typeof(StartStationEventRule))]
+public sealed partial class StartStationEventRuleComponent : Component
+{
+
+}
\ No newline at end of file
diff --git a/Content.Server/StationEvents/Components/StationEventComponent.cs b/Content.Server/StationEvents/Components/StationEventComponent.cs
index fdd1d3962e74..ee3036bcf60a 100644
--- a/Content.Server/StationEvents/Components/StationEventComponent.cs
+++ b/Content.Server/StationEvents/Components/StationEventComponent.cs
@@ -1,5 +1,7 @@
using Robust.Shared.Audio;
+using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+using Content.Server.AlertLevel;
namespace Content.Server.StationEvents.Components;
@@ -48,6 +50,19 @@ public sealed partial class StationEventComponent : Component
[DataField]
public int ReoccurrenceDelay = 30;
+
+ ///
+ /// Alert level to set the station to when the event starts.
+ ///
+ [DataField]
+ public ProtoId? AlertLevel;
+
+ ///
+ /// Alarm level that will NOT be ignored when the event starts
+ ///
+ [DataField]
+ public ProtoId? NotIgnoredAlarmLevel = "green";
+
///
/// How long the event lasts.
///
diff --git a/Content.Server/StationEvents/Events/AlertLevelInterceptionRule.cs b/Content.Server/StationEvents/Events/AlertLevelInterceptionRule.cs
deleted file mode 100644
index 916d7d16883f..000000000000
--- a/Content.Server/StationEvents/Events/AlertLevelInterceptionRule.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using Content.Server.StationEvents.Components;
-using Content.Server.AlertLevel;
-using Content.Shared.GameTicking.Components;
-
-namespace Content.Server.StationEvents.Events;
-
-public sealed class AlertLevelInterceptionRule : StationEventSystem
-{
- [Dependency] private readonly AlertLevelSystem _alertLevelSystem = default!;
-
- protected override void Started(EntityUid uid, AlertLevelInterceptionRuleComponent component, GameRuleComponent gameRule,
- GameRuleStartedEvent args)
- {
- base.Started(uid, component, gameRule, args);
-
- if (!TryGetRandomStation(out var chosenStation))
- return;
- if (_alertLevelSystem.GetLevel(chosenStation.Value) != "green")
- return;
-
- _alertLevelSystem.SetLevel(chosenStation.Value, component.AlertLevel, true, true, true);
- }
-}
diff --git a/Content.Server/StationEvents/Events/StartStationEventRule.cs b/Content.Server/StationEvents/Events/StartStationEventRule.cs
new file mode 100644
index 000000000000..b3dced9972df
--- /dev/null
+++ b/Content.Server/StationEvents/Events/StartStationEventRule.cs
@@ -0,0 +1,15 @@
+using Content.Server.StationEvents.Components;
+using Content.Shared.GameTicking.Components;
+
+namespace Content.Server.StationEvents.Events;
+
+//TO DO: delete and forget about this as the worst joke ever.
+public sealed class StartStationEventRule : StationEventSystem
+{
+ protected override void Started(EntityUid uid, StartStationEventRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
+ {
+ if (!TryComp(uid, out var stationEvent))
+ return;
+ base.Started(uid, component, gameRule, args);
+ }
+}
\ No newline at end of file
diff --git a/Content.Server/StationEvents/Events/StationEventSystem.cs b/Content.Server/StationEvents/Events/StationEventSystem.cs
index c4c51afd2a1f..50f69af82d57 100644
--- a/Content.Server/StationEvents/Events/StationEventSystem.cs
+++ b/Content.Server/StationEvents/Events/StationEventSystem.cs
@@ -1,6 +1,8 @@
using Content.Server.Administration.Logs;
using Content.Server.Chat.Systems;
using Content.Server.GameTicking.Rules;
+using Content.Server.GameTicking.Rules.Components;
+using Content.Server.AlertLevel;
using Content.Server.Station.Systems;
using Content.Server.StationEvents.Components;
using Content.Shared.Database;
@@ -21,6 +23,7 @@ public abstract class StationEventSystem : GameRuleSystem where T : ICompo
[Dependency] protected readonly ChatSystem ChatSystem = default!;
[Dependency] protected readonly SharedAudioSystem Audio = default!;
[Dependency] protected readonly StationSystem StationSystem = default!;
+ [Dependency] protected readonly AlertLevelSystem _alertLevelSystem = default!;
protected ISawmill Sawmill = default!;
@@ -44,6 +47,16 @@ protected override void Added(EntityUid uid, T component, GameRuleComponent game
if (stationEvent.StartAnnouncement != null)
ChatSystem.DispatchGlobalAnnouncement(Loc.GetString(stationEvent.StartAnnouncement), playSound: false, colorOverride: stationEvent.StartAnnouncementColor);
+ if (stationEvent.AlertLevel != null)
+ {
+ if (!TryGetRandomStation(out var chosenStation))
+ return;
+ if (_alertLevelSystem.GetLevel(chosenStation.Value) != stationEvent.NotIgnoredAlarmLevel)
+ return;
+
+ _alertLevelSystem.SetLevel(chosenStation.Value, stationEvent.AlertLevel, true, true, true);
+ }
+
Audio.PlayGlobal(stationEvent.StartAudio, Filter.Broadcast(), true);
}
diff --git a/Content.Shared/GameTicking/Components/GameRuleComponent.cs b/Content.Shared/GameTicking/Components/GameRuleComponent.cs
index 87a5822d4747..c039d84535a3 100644
--- a/Content.Shared/GameTicking/Components/GameRuleComponent.cs
+++ b/Content.Shared/GameTicking/Components/GameRuleComponent.cs
@@ -16,6 +16,12 @@ public sealed partial class GameRuleComponent : Component
///
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan ActivatedAt;
+
+ ///
+ /// A floating indicator of how often an event can be falsely triggered
+ ///
+ [DataField]
+ public float FalseActivationProb = 0f;
///
/// The minimum amount of players needed for this game rule.
diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml
index bfd9dd6230e5..924f37073726 100644
--- a/Resources/Prototypes/GameRules/events.yml
+++ b/Resources/Prototypes/GameRules/events.yml
@@ -447,16 +447,19 @@
parent: BaseTraitorRule
id: SleeperAgents
components:
+ - type: GameRule
+ falseActivationProb: 0.5
- type: StationEvent
earliestStart: 30
weight: 8
minimumPlayers: 15
+ alertLevel: blue
maxOccurrences: 1 # can only happen once per round
startAnnouncement: station-event-communication-interception
startAudio:
path: /Audio/Announcements/intercept.ogg
duration: null # the rule has to last the whole round not 1 second
- - type: AlertLevelInterceptionRule
+ - type: StartStationEventRule
- type: AntagSelection
definitions:
- prefRoles: [ TraitorSleeper ]