Files
tbd-station-14/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs
2021-12-21 21:23:29 +01:00

214 lines
7.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Presets;
using Content.Server.Maps;
using Content.Server.RoundEnd;
using Content.Shared.CCVar;
using Content.Shared.Voting;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Voting.Managers
{
public sealed partial class VoteManager
{
private static readonly Dictionary<StandardVoteType, CVarDef<bool>> _voteTypesToEnableCVars = new()
{
{StandardVoteType.Restart, CCVars.VoteRestartEnabled},
{StandardVoteType.Preset, CCVars.VotePresetEnabled},
{StandardVoteType.Map, CCVars.VoteMapEnabled},
};
public void CreateStandardVote(IPlayerSession? initiator, StandardVoteType voteType)
{
switch (voteType)
{
case StandardVoteType.Restart:
CreateRestartVote(initiator);
break;
case StandardVoteType.Preset:
CreatePresetVote(initiator);
break;
case StandardVoteType.Map:
CreateMapVote(initiator);
break;
default:
throw new ArgumentOutOfRangeException(nameof(voteType), voteType, null);
}
TimeoutStandardVote(voteType);
}
private void CreateRestartVote(IPlayerSession? 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"), true),
(Loc.GetString("ui-vote-restart-no"), false)
},
Duration = alone
? TimeSpan.FromSeconds(10)
: TimeSpan.FromSeconds(30),
InitiatorTimeout = TimeSpan.FromMinutes(3)
};
if (alone)
options.InitiatorTimeout = TimeSpan.FromSeconds(10);
WirePresetVoteInitiator(options, initiator);
var vote = CreateVote(options);
vote.OnFinished += (_, _) =>
{
var votesYes = vote.VotesPerOption[true];
var votesNo = vote.VotesPerOption[false];
var total = votesYes + votesNo;
var ratioRequired = _cfg.GetCVar(CCVars.VoteRestartRequiredRatio);
if (votesYes / (float) total >= ratioRequired)
{
_chatManager.DispatchServerAnnouncement(Loc.GetString("ui-vote-restart-succeeded"));
EntitySystem.Get<RoundEndSystem>().EndRound();
}
else
{
_chatManager.DispatchServerAnnouncement(
Loc.GetString("ui-vote-restart-failed", ("ratio", ratioRequired)));
}
};
if (initiator != null)
{
// Cast yes vote if created the vote yourself.
vote.CastVote(initiator, 0);
}
foreach (var player in _playerManager.ServerSessions)
{
if (player != initiator && !_afkManager.IsAfk(player))
{
// Everybody else defaults to a no vote.
vote.CastVote(player, 1);
}
}
}
private void CreatePresetVote(IPlayerSession? initiator)
{
var presets = new Dictionary<string, string>();
foreach (var preset in _prototypeManager.EnumeratePrototypes<GamePresetPrototype>())
{
if(!preset.ShowInVote)
continue;
presets[preset.ID] = preset.ModeTitle;
}
var alone = _playerManager.PlayerCount == 1 && initiator != null;
var options = new VoteOptions
{
Title = Loc.GetString("ui-vote-gamemode-title"),
Duration = alone
? TimeSpan.FromSeconds(10)
: TimeSpan.FromSeconds(30)
};
if (alone)
options.InitiatorTimeout = TimeSpan.FromSeconds(10);
foreach (var (k, v) in presets)
{
options.Options.Add((Loc.GetString(v), k));
}
WirePresetVoteInitiator(options, initiator);
var vote = CreateVote(options);
vote.OnFinished += (_, args) =>
{
string picked;
if (args.Winner == null)
{
picked = (string) _random.Pick(args.Winners);
_chatManager.DispatchServerAnnouncement(
Loc.GetString("ui-vote-gamemode-tie", ("picked", Loc.GetString(presets[picked]))));
}
else
{
picked = (string) args.Winner;
_chatManager.DispatchServerAnnouncement(
Loc.GetString("ui-vote-gamemode-win", ("winner", Loc.GetString(presets[picked]))));
}
EntitySystem.Get<GameTicker>().SetGamePreset(picked);
};
}
private void CreateMapVote(IPlayerSession? initiator)
{
var maps = _gameMapManager.CurrentlyEligibleMaps().ToDictionary(map => map, map => map.MapName);
var alone = _playerManager.PlayerCount == 1 && initiator != null;
var options = new VoteOptions
{
Title = Loc.GetString("ui-vote-map-title"),
Duration = alone
? TimeSpan.FromSeconds(10)
: TimeSpan.FromSeconds(180)
};
if (alone)
options.InitiatorTimeout = TimeSpan.FromSeconds(10);
foreach (var (k, v) in maps)
{
options.Options.Add((v, k));
}
WirePresetVoteInitiator(options, initiator);
var vote = CreateVote(options);
vote.OnFinished += (_, args) =>
{
GameMapPrototype picked;
if (args.Winner == null)
{
picked = (GameMapPrototype) _random.Pick(args.Winners);
_chatManager.DispatchServerAnnouncement(
Loc.GetString("ui-vote-map-tie", ("picked", maps[picked])));
}
else
{
picked = (GameMapPrototype) args.Winner;
_chatManager.DispatchServerAnnouncement(
Loc.GetString("ui-vote-map-win", ("winner", maps[picked])));
}
_gameMapManager.TrySelectMap(picked.ID);
};
}
private void TimeoutStandardVote(StandardVoteType type)
{
var timeout = TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.VoteSameTypeTimeout));
_standardVoteTimeout[type] = _timing.RealTime + timeout;
DirtyCanCallVoteAll();
}
}
}