]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Restart votes check player count and ghost levels (#23453)
authorRepo <47093363+Titian3@users.noreply.github.com>
Fri, 19 Jan 2024 07:10:05 +0000 (20:10 +1300)
committerGitHub <noreply@github.com>
Fri, 19 Jan 2024 07:10:05 +0000 (18:10 +1100)
* Restarts have max player count

* Now counts ingame ghosts to determine if restart can be called

* consistant cvar name

* Added a player count with state conditional

Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs
Content.Shared/CCVar/CCVars.cs
Resources/Locale/en-US/voting/managers/vote-manager.ftl

index 3800d7f02c421891c79ae80915a78e5d40aecc87..c479f7498953c0c8c0d4c33664107e8b7b37721b 100644 (file)
@@ -5,8 +5,10 @@ using Content.Server.Maps;
 using Content.Server.RoundEnd;
 using Content.Shared.CCVar;
 using Content.Shared.Database;
+using Content.Shared.Ghost;
 using Content.Shared.Voting;
 using Robust.Shared.Configuration;
+using Robust.Shared.Enums;
 using Robust.Shared.Player;
 using Robust.Shared.Random;
 
@@ -49,73 +51,117 @@ namespace Content.Server.Voting.Managers
 
         private void CreateRestartVote(ICommonSession? initiator)
         {
-            var alone = _playerManager.PlayerCount == 1 && initiator != null;
-            var options = new VoteOptions
+
+            var playerVoteMaximum = _cfg.GetCVar(CCVars.VoteRestartMaxPlayers);
+            var totalPlayers = _playerManager.Sessions.Count(session => session.Status != SessionStatus.Disconnected);
+
+            var ghostVotePercentageRequirement = _cfg.GetCVar(CCVars.VoteRestartGhostPercentage);
+            var ghostCount = 0;
+            
+            foreach (var player in _playerManager.Sessions)
             {
-                Title = Loc.GetString("ui-vote-restart-title"),
-                Options =
+                _playerManager.UpdateState(player);
+                if (player.Status != SessionStatus.Disconnected && _entityManager.HasComponent<GhostComponent>(player.AttachedEntity))
                 {
-                    (Loc.GetString("ui-vote-restart-yes"), "yes"),
-                    (Loc.GetString("ui-vote-restart-no"), "no"),
-                    (Loc.GetString("ui-vote-restart-abstain"), "abstain")
-                },
-                Duration = alone
-                    ? TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.VoteTimerAlone))
-                    : TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.VoteTimerRestart)),
-                InitiatorTimeout = TimeSpan.FromMinutes(5)
-            };
-
-            if (alone)
-                options.InitiatorTimeout = TimeSpan.FromSeconds(10);
+                    ghostCount++;
+                }
+            }
 
-            WirePresetVoteInitiator(options, initiator);
+            var ghostPercentage = 0.0;
+            if (totalPlayers > 0)
+            {
+                ghostPercentage = ((double)ghostCount / totalPlayers) * 100;
+            }
 
-            var vote = CreateVote(options);
+            var roundedGhostPercentage = (int)Math.Round(ghostPercentage);
 
-            vote.OnFinished += (_, _) =>
+            if (totalPlayers <= playerVoteMaximum || roundedGhostPercentage >= ghostVotePercentageRequirement)
+            {
+                StartVote(initiator);
+            }
+            else
             {
-                var votesYes = vote.VotesPerOption["yes"];
-                var votesNo = vote.VotesPerOption["no"];
-                var total = votesYes + votesNo;
+                NotifyNotEnoughGhostPlayers(ghostVotePercentageRequirement, roundedGhostPercentage);
+            }
+        }
+
+        private void StartVote(ICommonSession? initiator)
+        {
+            var alone = _playerManager.PlayerCount == 1 && initiator != null;
+                var options = new VoteOptions
+                {
+                    Title = Loc.GetString("ui-vote-restart-title"),
+                    Options =
+                    {
+                        (Loc.GetString("ui-vote-restart-yes"), "yes"),
+                        (Loc.GetString("ui-vote-restart-no"), "no"),
+                        (Loc.GetString("ui-vote-restart-abstain"), "abstain")
+                    },
+                    Duration = alone
+                        ? TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.VoteTimerAlone))
+                        : TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.VoteTimerRestart)),
+                    InitiatorTimeout = TimeSpan.FromMinutes(5)
+                };
+
+                if (alone)
+                    options.InitiatorTimeout = TimeSpan.FromSeconds(10);
+
+                WirePresetVoteInitiator(options, initiator);
 
-                var ratioRequired = _cfg.GetCVar(CCVars.VoteRestartRequiredRatio);
-                if (total > 0 && votesYes / (float) total >= ratioRequired)
+                var vote = CreateVote(options);
+
+                vote.OnFinished += (_, _) =>
                 {
-                    // Check if an admin is online, and ignore the passed vote if the cvar is enabled
-                    if (_cfg.GetCVar(CCVars.VoteRestartNotAllowedWhenAdminOnline) && _adminMgr.ActiveAdmins.Count() != 0)
+                    var votesYes = vote.VotesPerOption["yes"];
+                    var votesNo = vote.VotesPerOption["no"];
+                    var total = votesYes + votesNo;
+
+                    var ratioRequired = _cfg.GetCVar(CCVars.VoteRestartRequiredRatio);
+                    if (total > 0 && votesYes / (float) total >= ratioRequired)
                     {
-                        _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"Restart vote attempted to pass, but an admin was online. {votesYes}/{votesNo}");
-                    } 
-                    else // If the cvar is disabled or there's no admins on, proceed as normal
+                        // Check if an admin is online, and ignore the passed vote if the cvar is enabled
+                        if (_cfg.GetCVar(CCVars.VoteRestartNotAllowedWhenAdminOnline) && _adminMgr.ActiveAdmins.Count() != 0)
+                        {
+                            _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"Restart vote attempted to pass, but an admin was online. {votesYes}/{votesNo}");
+                        }
+                        else // If the cvar is disabled or there's no admins on, proceed as normal
+                        {
+                            _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"Restart vote succeeded: {votesYes}/{votesNo}");
+                            _chatManager.DispatchServerAnnouncement(Loc.GetString("ui-vote-restart-succeeded"));
+                            var roundEnd = _entityManager.EntitySysManager.GetEntitySystem<RoundEndSystem>();
+                            roundEnd.EndRound();
+                        }
+                    }
+                    else
                     {
-                        _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"Restart vote succeeded: {votesYes}/{votesNo}");
-                        _chatManager.DispatchServerAnnouncement(Loc.GetString("ui-vote-restart-succeeded"));
-                        var roundEnd = _entityManager.EntitySysManager.GetEntitySystem<RoundEndSystem>();
-                        roundEnd.EndRound();
+                        _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"Restart vote failed: {votesYes}/{votesNo}");
+                        _chatManager.DispatchServerAnnouncement(
+                            Loc.GetString("ui-vote-restart-failed", ("ratio", ratioRequired)));
                     }
-                }
-                else
+                };
+
+                if (initiator != null)
                 {
-                    _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"Restart vote failed: {votesYes}/{votesNo}");
-                    _chatManager.DispatchServerAnnouncement(
-                        Loc.GetString("ui-vote-restart-failed", ("ratio", ratioRequired)));
+                    // Cast yes vote if created the vote yourself.
+                    vote.CastVote(initiator, 0);
                 }
-            };
 
-            if (initiator != null)
-            {
-                // Cast yes vote if created the vote yourself.
-                vote.CastVote(initiator, 0);
-            }
-
-            foreach (var player in _playerManager.Sessions)
-            {
-                if (player != initiator)
+                foreach (var player in _playerManager.Sessions)
                 {
-                    // Everybody else defaults to an abstain vote to say they don't mind.
-                    vote.CastVote(player, 2);
+                    if (player != initiator)
+                    {
+                        // Everybody else defaults to an abstain vote to say they don't mind.
+                        vote.CastVote(player, 2);
+                    }
                 }
-            }
+        }
+
+        private void NotifyNotEnoughGhostPlayers(int ghostPercentageRequirement, int roundedGhostPercentage)
+        {
+            // Logic to notify that there are not enough ghost players to start a vote
+            _adminLogger.Add(LogType.Vote, LogImpact.Medium, $"Restart vote failed: Current Ghost player percentage:{roundedGhostPercentage.ToString()}% does not meet {ghostPercentageRequirement.ToString()}%");
+            _chatManager.DispatchServerAnnouncement(
+                Loc.GetString("ui-vote-restart-fail-not-enough-ghost-players", ("ghostPlayerRequirement", ghostPercentageRequirement)));
         }
 
         private void CreatePresetVote(ICommonSession? initiator)
index 1bfca81e2a25a8f1b45ac40f6acb7b22519f1a06..a3b875feef0d5f83e3316298f9fcda7020efa957 100644 (file)
@@ -1256,6 +1256,18 @@ namespace Content.Shared.CCVar
         public static readonly CVarDef<bool> VoteRestartEnabled =
             CVarDef.Create("vote.restart_enabled", true, CVar.SERVERONLY);
 
+        /// <summary>
+        ///     Config for when the restart vote should be allowed to be called regardless with less than this amount of players.
+        /// </summary>
+        public static readonly CVarDef<int> VoteRestartMaxPlayers =
+            CVarDef.Create("vote.restart_max_players", 20, CVar.SERVERONLY);
+
+        /// <summary>
+        ///     Config for when the restart vote should be allowed to be called based on percentage of ghosts.
+        ///
+        public static readonly CVarDef<int> VoteRestartGhostPercentage =
+            CVarDef.Create("vote.restart_ghost_percentage", 75, CVar.SERVERONLY);
+
         /// <summary>
         ///     See vote.enabled, but specific to preset votes
         /// </summary>
index 06de3e77c196c4fca5af4a520a5d2a5f855ef39d..1825fc5ea9452d99620a58602a602f0d01cc9c0f 100644 (file)
@@ -6,6 +6,7 @@ ui-vote-initiator-server = The server
 ui-vote-restart-title = Restart round
 ui-vote-restart-succeeded = Restart vote succeeded.
 ui-vote-restart-failed = Restart vote failed (need { TOSTRING($ratio, "P0") }).
+ui-vote-restart-fail-not-enough-ghost-players = Restart vote failed: A minimum of { $ghostPlayerRequirement }% ghost players is required to initiate a restart vote. Currently, there are not enough ghost players.
 ui-vote-restart-yes = Yes
 ui-vote-restart-no = No
 ui-vote-restart-abstain = Abstain