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;
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)