Restart vote improvements, voting localization.
Restart votes now need 80% majority to succeed. Restart votes now have a 3 minute cooldown on the caller. Voting stuff has been localized.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Robust.Server.Player;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Server.Player;
|
||||
|
||||
namespace Content.Server.Voting
|
||||
{
|
||||
@@ -10,6 +11,8 @@ namespace Content.Server.Voting
|
||||
bool Finished { get; }
|
||||
bool Cancelled { get; }
|
||||
|
||||
IReadOnlyDictionary<object, int> VotesPerOption { get; }
|
||||
|
||||
event VoteFinishedEventHandler OnFinished;
|
||||
bool IsValidOption(int optionId);
|
||||
void CastVote(IPlayerSession session, int? optionId);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
@@ -15,15 +16,16 @@ namespace Content.Server.Voting
|
||||
var alone = _playerManager.PlayerCount == 1 && initiator != null;
|
||||
var options = new VoteOptions
|
||||
{
|
||||
Title = Loc.GetString("Restart round"),
|
||||
Title = Loc.GetString("ui-vote-restart-title"),
|
||||
Options =
|
||||
{
|
||||
(Loc.GetString("Yes"), true),
|
||||
(Loc.GetString("No"), false)
|
||||
(Loc.GetString("ui-vote-restart-yes"), true),
|
||||
(Loc.GetString("ui-vote-restart-no"), false)
|
||||
},
|
||||
Duration = alone
|
||||
? TimeSpan.FromSeconds(10)
|
||||
: TimeSpan.FromSeconds(30)
|
||||
: TimeSpan.FromSeconds(30),
|
||||
InitiatorTimeout = TimeSpan.FromMinutes(3)
|
||||
};
|
||||
|
||||
if (alone)
|
||||
@@ -33,23 +35,22 @@ namespace Content.Server.Voting
|
||||
|
||||
var vote = CreateVote(options);
|
||||
|
||||
vote.OnFinished += (_, args) =>
|
||||
vote.OnFinished += (_, _) =>
|
||||
{
|
||||
if (args.Winner == null)
|
||||
{
|
||||
_chatManager.DispatchServerAnnouncement(Loc.GetString("Restart vote failed due to tie."));
|
||||
return;
|
||||
}
|
||||
var votesYes = vote.VotesPerOption[true];
|
||||
var votesNo = vote.VotesPerOption[false];
|
||||
var total = votesYes + votesNo;
|
||||
|
||||
var win = (bool) args.Winner;
|
||||
if (win)
|
||||
var ratioRequired = _cfg.GetCVar(CCVars.VoteRestartRequiredRatio);
|
||||
if (votesYes / (float) total >= ratioRequired)
|
||||
{
|
||||
_chatManager.DispatchServerAnnouncement(Loc.GetString("Restart vote succeeded."));
|
||||
_chatManager.DispatchServerAnnouncement(Loc.GetString("ui-vote-restart-succeeded"));
|
||||
_ticker.RestartRound();
|
||||
}
|
||||
else
|
||||
{
|
||||
_chatManager.DispatchServerAnnouncement(Loc.GetString("Restart vote failed."));
|
||||
_chatManager.DispatchServerAnnouncement(
|
||||
Loc.GetString("ui-vote-restart-failed", ("ratio", ratioRequired)));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -64,16 +65,16 @@ namespace Content.Server.Voting
|
||||
{
|
||||
var presets = new Dictionary<string, string>
|
||||
{
|
||||
["traitor"] = "Traitor",
|
||||
["extended"] = "Extended",
|
||||
["sandbox"] = "Sandbox",
|
||||
["suspicion"] = "Suspicion"
|
||||
["traitor"] = "mode-traitor",
|
||||
["extended"] = "mode-extended",
|
||||
["sandbox"] = "mode-sandbox",
|
||||
["suspicion"] = "mode-suspicion",
|
||||
};
|
||||
|
||||
var alone = _playerManager.PlayerCount == 1 && initiator != null;
|
||||
var options = new VoteOptions
|
||||
{
|
||||
Title = Loc.GetString("Next gamemode"),
|
||||
Title = Loc.GetString("ui-vote-gamemode-title"),
|
||||
Duration = alone
|
||||
? TimeSpan.FromSeconds(10)
|
||||
: TimeSpan.FromSeconds(30)
|
||||
@@ -98,13 +99,13 @@ namespace Content.Server.Voting
|
||||
{
|
||||
picked = (string) IoCManager.Resolve<IRobustRandom>().Pick(args.Winners);
|
||||
_chatManager.DispatchServerAnnouncement(
|
||||
Loc.GetString("Tie for gamemode vote! Picking... {0}", Loc.GetString(presets[picked])));
|
||||
Loc.GetString("ui-vote-gamemode-tie", ("picked", Loc.GetString(presets[picked]))));
|
||||
}
|
||||
else
|
||||
{
|
||||
picked = (string) args.Winner;
|
||||
_chatManager.DispatchServerAnnouncement(
|
||||
Loc.GetString("{0} won the gamemode vote!", Loc.GetString(presets[picked])));
|
||||
Loc.GetString("ui-vote-gamemode-win", ("winner", Loc.GetString(presets[picked]))));
|
||||
}
|
||||
|
||||
_ticker.SetStartPreset(picked);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
@@ -10,11 +11,13 @@ using Content.Shared.Administration;
|
||||
using Content.Shared.Network.NetMessages;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
#nullable enable
|
||||
|
||||
@@ -23,6 +26,7 @@ namespace Content.Server.Voting
|
||||
public sealed partial class VoteManager : IVoteManager
|
||||
{
|
||||
[Dependency] private readonly IServerNetManager _netManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
@@ -320,7 +324,7 @@ namespace Content.Server.Voting
|
||||
}
|
||||
else
|
||||
{
|
||||
options.InitiatorText = Loc.GetString("The server");
|
||||
options.InitiatorText = Loc.GetString("ui-vote-initiator-server");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,6 +393,8 @@ namespace Content.Server.Voting
|
||||
public bool Finished => _reg.Finished;
|
||||
public bool Cancelled => _reg.Cancelled;
|
||||
|
||||
public IReadOnlyDictionary<object, int> VotesPerOption { get; }
|
||||
|
||||
public event VoteFinishedEventHandler? OnFinished
|
||||
{
|
||||
add => _reg.OnFinished += value;
|
||||
@@ -405,6 +411,8 @@ namespace Content.Server.Voting
|
||||
{
|
||||
_mgr = mgr;
|
||||
_reg = reg;
|
||||
|
||||
VotesPerOption = new VoteDict(reg);
|
||||
}
|
||||
|
||||
public bool IsValidOption(int optionId)
|
||||
@@ -421,6 +429,62 @@ namespace Content.Server.Voting
|
||||
{
|
||||
_mgr.CancelVote(_reg);
|
||||
}
|
||||
|
||||
private sealed class VoteDict : IReadOnlyDictionary<object, int>
|
||||
{
|
||||
private readonly VoteReg _reg;
|
||||
|
||||
public VoteDict(VoteReg reg)
|
||||
{
|
||||
_reg = reg;
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<object, int>> GetEnumerator()
|
||||
{
|
||||
return _reg.Entries.Select(e => KeyValuePair.Create(e.Data, e.Votes)).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public int Count => _reg.Entries.Length;
|
||||
|
||||
public bool ContainsKey(object key)
|
||||
{
|
||||
return TryGetValue(key, out _);
|
||||
}
|
||||
|
||||
public bool TryGetValue(object key, out int value)
|
||||
{
|
||||
var entry = _reg.Entries.FirstOrNull(a => a.Data.Equals(key));
|
||||
if (entry != null)
|
||||
{
|
||||
value = entry.Value.Votes;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public int this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!TryGetValue(key, out var votes))
|
||||
{
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
|
||||
return votes;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<object> Keys => _reg.Entries.Select(c => c.Data);
|
||||
public IEnumerable<int> Values => _reg.Entries.Select(c => c.Votes);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Reference in New Issue
Block a user