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