diff --git a/Content.Server/GameTicking/Presets/GamePresetPrototype.cs b/Content.Server/GameTicking/Presets/GamePresetPrototype.cs
index 4731364ace2..f82f0c25c70 100644
--- a/Content.Server/GameTicking/Presets/GamePresetPrototype.cs
+++ b/Content.Server/GameTicking/Presets/GamePresetPrototype.cs
@@ -33,6 +33,15 @@ public sealed partial class GamePresetPrototype : IPrototype
[DataField("maxPlayers")]
public int? MaxPlayers;
+ // Begin Imp
+ ///
+ /// Ensures that this gamemode does not get selected for a number of rounds
+ /// by something like Secret. This is not considered when the preset is forced.
+ ///
+ [DataField]
+ public int Cooldown = 0;
+ // End Imp
+
[DataField("rules", customTypeSerializer: typeof(PrototypeIdListSerializer))]
public IReadOnlyList Rules { get; private set; } = Array.Empty();
diff --git a/Content.Server/GameTicking/Rules/SecretRuleSystem.cs b/Content.Server/GameTicking/Rules/SecretRuleSystem.cs
index e82cecde368..d38b798bc58 100644
--- a/Content.Server/GameTicking/Rules/SecretRuleSystem.cs
+++ b/Content.Server/GameTicking/Rules/SecretRuleSystem.cs
@@ -4,6 +4,7 @@
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Presets;
using Content.Server.GameTicking.Rules.Components;
+using Content.Shared._DV.CCVars; // DeltaV
using Content.Shared.GameTicking.Components;
using Content.Shared.Random;
using Content.Shared.CCVar;
@@ -22,6 +23,11 @@ public sealed class SecretRuleSystem : GameRuleSystem
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IComponentFactory _compFact = default!;
+ [Dependency] private readonly GameTicker _ticker = default!; // begin Imp
+
+ // Dictionary that contains the minimum round number for certain preset
+ // prototypes to be allowed to roll again
+ private static Dictionary, int> _nextRoundAllowed = new(); // end Imp
private string _ruleCompName = default!;
@@ -46,6 +52,15 @@ protected override void Added(EntityUid uid, SecretRuleComponent component, Game
Log.Info($"Selected {preset.ID} as the secret preset.");
_adminLogger.Add(LogType.EventStarted, $"Selected {preset.ID} as the secret preset.");
+ if (_configurationManager.GetCVar(DCCVars.EnableBacktoBack) == true) // DeltaV
+ {
+ if (preset.Cooldown > 0) // Begin Imp
+ {
+ _nextRoundAllowed[preset.ID] = _ticker.RoundId + preset.Cooldown + 1;
+ Log.Info($"{preset.ID} is now on cooldown until {_nextRoundAllowed[preset.ID]}");
+ } // End Imp
+ } // DeltaV
+
foreach (var rule in preset.Rules)
{
EntityUid ruleEnt;
@@ -167,6 +182,15 @@ private bool CanPick([NotNullWhen(true)] GamePresetPrototype? selected, int play
return false;
}
+ if (_configurationManager.GetCVar(DCCVars.EnableBacktoBack) == true) // DeltaV
+ {
+ if (_nextRoundAllowed.ContainsKey(selected.ID) && _nextRoundAllowed[selected.ID] > _ticker.RoundId) // Begin Imp
+ {
+ Log.Info($"Skipping preset {selected.ID} (Not available until round {_nextRoundAllowed[selected.ID]}");
+ return false;
+ } // End Imp
+ } // DeltaV
+
return true;
}
}
diff --git a/Content.Shared/_DV/CCVars/DCCVars.cs b/Content.Shared/_DV/CCVars/DCCVars.cs
index d28faf854d2..059f16732da 100644
--- a/Content.Shared/_DV/CCVars/DCCVars.cs
+++ b/Content.Shared/_DV/CCVars/DCCVars.cs
@@ -155,4 +155,10 @@ public sealed class DCCVars
///
public static readonly CVarDef DiscordReplyColor =
CVarDef.Create("admin.discord_reply_color", string.Empty, CVar.SERVERONLY);
+
+ ///
+ /// Whether or not to disable the preset selecting test rule from running. Should be disabled in production. DeltaV specific, attached to Impstation Secret concurrent feature.
+ ///
+ public static readonly CVarDef EnableBacktoBack =
+ CVarDef.Create("game.disable_preset_test", false, CVar.SERVERONLY);
}
diff --git a/Resources/Prototypes/game_presets.yml b/Resources/Prototypes/game_presets.yml
index 5eaafddfaf9..39ffa1d4b26 100644
--- a/Resources/Prototypes/game_presets.yml
+++ b/Resources/Prototypes/game_presets.yml
@@ -5,6 +5,7 @@
name: survival-title
showInVote: true # secret # DeltaV - Me when the survival. Used for periapsis.
description: survival-description
+ cooldown: 2 # Imp - Can't occur thrice
rules:
- MeteorSwarmScheduler
- RampingStationEventScheduler
@@ -155,6 +156,7 @@
- tator
name: traitor-title
description: traitor-description
+ cooldown: 2 # Imp - Can't occur thrice
showInVote: false
rules:
- Traitor
@@ -185,6 +187,7 @@
name: nukeops-title
description: nukeops-description
showInVote: false
+ cooldown: 2 # Imp - Can't occur thrice
rules:
- Nukeops
- SubGamemodesRule
@@ -222,6 +225,7 @@
- zomber
name: zombie-title
description: zombie-description
+ cooldown: 2 # Imp - Can't occur thrice
showInVote: false
rules:
- Zombie