From 59befcda474439ccf96afdf7186f8ee1537970a2 Mon Sep 17 00:00:00 2001 From: Vigers Ray Date: Wed, 1 Jan 2025 07:46:45 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B5=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81?= =?UTF-8?q?=D0=BA=D0=B0=D1=82=D1=8C=20=D0=94=D0=9E=20=D0=B5=D1=81=D0=BB?= =?UTF-8?q?=D0=B8=20=D0=BD=D0=B0=20=D0=BC=D0=BE=D0=B6=D0=B5=D1=82=20=D0=B1?= =?UTF-8?q?=D1=8B=D1=82=D1=8C=20=D0=BC=D0=B5=D0=BD=D1=8C=D1=88=D0=B5=203?= =?UTF-8?q?=20=D0=B3=D0=BB=D0=B0=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTicking/Rules/GameRuleSystem.cs | 57 +++++++++++++++++++ .../Components/GameRuleComponent.cs | 3 + .../_strings/game-ticking/game-ticker.ftl | 1 + .../_Sunrise/AssaultOps/roundstart.yml | 5 +- 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/Content.Server/GameTicking/Rules/GameRuleSystem.cs b/Content.Server/GameTicking/Rules/GameRuleSystem.cs index cb5b1175495..330338994b8 100644 --- a/Content.Server/GameTicking/Rules/GameRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/GameRuleSystem.cs @@ -1,7 +1,13 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Chat.Managers; +using Content.Server.Jobs; +using Content.Server.Preferences.Managers; +using Content.Server.Revolutionary.Components; using Content.Shared.GameTicking.Components; +using Content.Shared.Preferences; +using Content.Shared.Roles; using Robust.Server.GameObjects; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -13,6 +19,8 @@ public abstract partial class GameRuleSystem : EntitySystem where T : ICompon [Dependency] protected readonly IChatManager ChatManager = default!; [Dependency] protected readonly GameTicker GameTicker = default!; [Dependency] protected readonly IGameTiming Timing = default!; + [Dependency] protected readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IComponentFactory _componentFactory = default!; // Not protected, just to be used in utility methods [Dependency] private readonly AtmosphereSystem _atmosphere = default!; @@ -37,6 +45,55 @@ private void OnStartAttempt(RoundStartAttemptEvent args) var query = QueryAllRules(); while (query.MoveNext(out var uid, out _, out var gameRule)) { + // Sunrise-Start + if (gameRule.MinCommandStaff > 0) + { + var availableHeads = new List(); + + foreach (var playerSession in args.Players) + { + var userId = playerSession.UserId; + var preferencesManager = IoCManager.Resolve(); + var prefs = preferencesManager.GetPreferences(userId); + var profile = prefs.SelectedCharacter as HumanoidCharacterProfile; + if (profile == null) + continue; + foreach (var profileJobPriority in profile.JobPriorities) + { + if (profileJobPriority.Value == JobPriority.Never) + continue; + if (!_prototype.TryIndex(profileJobPriority.Key.Id, out var job)) + continue; + foreach (var special in job.Special) + { + if (special is not AddComponentSpecial componentSpecial) + continue; + + foreach (var componentSpecialComponent in componentSpecial.Components) + { + var copy = _componentFactory.GetComponent(componentSpecialComponent.Value); + if (copy is CommandStaffComponent) + { + if (availableHeads.Contains(profileJobPriority.Key)) + continue; + availableHeads.Add(profileJobPriority.Key); + } + } + } + } + } + + if (gameRule.CancelPresetOnTooFewPlayers && availableHeads.Count < gameRule.MinCommandStaff) + { + ChatManager.SendAdminAnnouncement(Loc.GetString("preset-not-enough-ready-command-staff", + ("readyCommandStaffCount", args.Players.Length), + ("minimumCommandStaff", gameRule.MinCommandStaff), + ("presetName", ToPrettyString(uid)))); + args.Cancel(); + } + } + // Sunrise-Edit + var minPlayers = gameRule.MinPlayers; if (args.Players.Length >= minPlayers) continue; diff --git a/Content.Shared/GameTicking/Components/GameRuleComponent.cs b/Content.Shared/GameTicking/Components/GameRuleComponent.cs index 87a5822d474..85501562dd8 100644 --- a/Content.Shared/GameTicking/Components/GameRuleComponent.cs +++ b/Content.Shared/GameTicking/Components/GameRuleComponent.cs @@ -23,6 +23,9 @@ public sealed partial class GameRuleComponent : Component [DataField] public int MinPlayers; + [DataField] + public int MinCommandStaff; + /// /// If true, this rule not having enough players will cancel the preset selection. /// If false, it will simply not run silently. diff --git a/Resources/Locale/ru-RU/_strings/game-ticking/game-ticker.ftl b/Resources/Locale/ru-RU/_strings/game-ticking/game-ticker.ftl index 9ac7403c324..19346d98db0 100644 --- a/Resources/Locale/ru-RU/_strings/game-ticking/game-ticker.ftl +++ b/Resources/Locale/ru-RU/_strings/game-ticking/game-ticker.ftl @@ -44,6 +44,7 @@ latejoin-arrivals-direction-time = Шаттл, который доставит latejoin-arrivals-dumped-from-shuttle = Таинственная сила не позволяет вам улететь на шаттле прибытия. latejoin-arrivals-teleport-to-spawn = Таинственная сила телепортирует вас с шаттла прибытия. Удачной смены! preset-not-enough-ready-players = Не удалось запустить пресет { $presetName }. Требуется { $minimumPlayers } игроков, но готовы только { $readyPlayersCount }. +preset-not-enough-ready-command-staff = Не удалось запустить пресет { $presetName }. Требуется { $minimumCommandStaff } членов командного состава, но может быть только { $readyCommandStaffCount }. preset-no-one-ready = Не удалось запустить режим { $presetName }. Нет готовых игроков. game-run-level-PreRoundLobby = Лобби до начала раунда game-run-level-InRound = В раунде diff --git a/Resources/Prototypes/_Sunrise/AssaultOps/roundstart.yml b/Resources/Prototypes/_Sunrise/AssaultOps/roundstart.yml index eefe60c150d..57cb4297722 100644 --- a/Resources/Prototypes/_Sunrise/AssaultOps/roundstart.yml +++ b/Resources/Prototypes/_Sunrise/AssaultOps/roundstart.yml @@ -3,7 +3,8 @@ parent: BaseGameRule components: - type: GameRule - minPlayers: 0 # 20 + minPlayers: 20 + minCommandStaff: 3 - type: AssaultOpsRule faction: Syndicate - type: LoadMapRule @@ -46,7 +47,7 @@ fallbackRoles: [ AssaultCommander ] spawnerPrototype: SpawnPointAssaultOpsOperative max: 5 - playerRatio: 1 # 20 + playerRatio: 15 startingGear: AssaultOperativeGear roleLoadout: - RoleSurvivalAssaultOps