Disable job buttons when they aren't available or late join is disallowed (#2251)

* Disable job buttons when they aren't available

In real time too, the technology is overwhelming

* Jobs are all unavailable when late join is disallowed.

* Better ToggleDisallowLateJoin command parsing

* Add togglelatejoin to groups.

Co-authored-by: Víctor Aguilera Puerto <zddm@outlook.es>
This commit is contained in:
DrSmugleaf
2020-10-16 11:22:58 +02:00
committed by GitHub
parent be096f7ebf
commit 435fb2630e
8 changed files with 118 additions and 2 deletions

View File

@@ -22,6 +22,7 @@ namespace Content.Client.GameTicking
[Dependency] private readonly IStateManager _stateManager = default!; [Dependency] private readonly IStateManager _stateManager = default!;
[ViewVariables] private bool _initialized; [ViewVariables] private bool _initialized;
private readonly List<string> _jobsAvailable = new List<string>();
[ViewVariables] public bool AreWeReady { get; private set; } [ViewVariables] public bool AreWeReady { get; private set; }
[ViewVariables] public bool IsGameStarted { get; private set; } [ViewVariables] public bool IsGameStarted { get; private set; }
@@ -30,11 +31,13 @@ namespace Content.Client.GameTicking
[ViewVariables] public DateTime StartTime { get; private set; } [ViewVariables] public DateTime StartTime { get; private set; }
[ViewVariables] public bool Paused { get; private set; } [ViewVariables] public bool Paused { get; private set; }
[ViewVariables] public Dictionary<NetUserId, PlayerStatus> Status { get; private set; } [ViewVariables] public Dictionary<NetUserId, PlayerStatus> Status { get; private set; }
[ViewVariables] public IReadOnlyList<string> JobsAvailable => _jobsAvailable;
public event Action InfoBlobUpdated; public event Action InfoBlobUpdated;
public event Action LobbyStatusUpdated; public event Action LobbyStatusUpdated;
public event Action LobbyReadyUpdated; public event Action LobbyReadyUpdated;
public event Action LobbyLateJoinStatusUpdated; public event Action LobbyLateJoinStatusUpdated;
public event Action<IReadOnlyList<string>> LobbyJobsAvailableUpdated;
public void Initialize() public void Initialize()
{ {
@@ -52,6 +55,7 @@ namespace Content.Client.GameTicking
IoCManager.Resolve<IClyde>().RequestWindowAttention(); IoCManager.Resolve<IClyde>().RequestWindowAttention();
}); });
_netManager.RegisterNetMessage<MsgTickerLateJoinStatus>(nameof(MsgTickerLateJoinStatus), LateJoinStatus); _netManager.RegisterNetMessage<MsgTickerLateJoinStatus>(nameof(MsgTickerLateJoinStatus), LateJoinStatus);
_netManager.RegisterNetMessage<MsgTickerJobsAvailable>(nameof(MsgTickerJobsAvailable), UpdateJobsAvailable);
Status = new Dictionary<NetUserId, PlayerStatus>(); Status = new Dictionary<NetUserId, PlayerStatus>();
_initialized = true; _initialized = true;
@@ -63,6 +67,12 @@ namespace Content.Client.GameTicking
LobbyLateJoinStatusUpdated?.Invoke(); LobbyLateJoinStatusUpdated?.Invoke();
} }
private void UpdateJobsAvailable(MsgTickerJobsAvailable message)
{
_jobsAvailable.Clear();
_jobsAvailable.AddRange(message.JobsAvailable);
LobbyJobsAvailableUpdated?.Invoke(JobsAvailable);
}
private void JoinLobby(MsgTickerJoinLobby message) private void JoinLobby(MsgTickerJoinLobby message)
{ {

View File

@@ -14,11 +14,13 @@ namespace Content.Client.Interfaces
DateTime StartTime { get; } DateTime StartTime { get; }
bool Paused { get; } bool Paused { get; }
Dictionary<NetUserId, PlayerStatus> Status { get; } Dictionary<NetUserId, PlayerStatus> Status { get; }
IReadOnlyList<string> JobsAvailable { get; }
void Initialize(); void Initialize();
event Action InfoBlobUpdated; event Action InfoBlobUpdated;
event Action LobbyStatusUpdated; event Action LobbyStatusUpdated;
event Action LobbyReadyUpdated; event Action LobbyReadyUpdated;
event Action LobbyLateJoinStatusUpdated; event Action LobbyLateJoinStatusUpdated;
event Action<IReadOnlyList<string>> LobbyJobsAvailableUpdated;
} }
} }

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.Client.Interfaces;
using Content.Shared.Roles; using Content.Shared.Roles;
using Robust.Client.Console; using Robust.Client.Console;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
@@ -18,11 +20,14 @@ namespace Content.Client.UserInterface
{ {
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IClientConsole _console = default!; [Dependency] private readonly IClientConsole _console = default!;
[Dependency] private readonly IClientGameTicker _gameTicker = default!;
protected override Vector2? CustomSize => (360, 560); protected override Vector2? CustomSize => (360, 560);
public event Action<string> SelectedId; public event Action<string> SelectedId;
private Dictionary<string, JobButton> JobButtons = new Dictionary<string, JobButton>();
public LateJoinGui() public LateJoinGui()
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
@@ -84,6 +89,13 @@ namespace Content.Client.UserInterface
{ {
SelectedId?.Invoke(jobButton.JobId); SelectedId?.Invoke(jobButton.JobId);
}; };
if (!_gameTicker.JobsAvailable.Contains(job.ID))
{
jobButton.Disabled = true;
}
JobButtons[job.ID] = jobButton;
} }
SelectedId += jobId => SelectedId += jobId =>
@@ -93,7 +105,7 @@ namespace Content.Client.UserInterface
Close(); Close();
}; };
_gameTicker.LobbyJobsAvailableUpdated += JobsAvailableUpdated;
} }
public string ReturnId() public string ReturnId()
@@ -101,7 +113,26 @@ namespace Content.Client.UserInterface
return SelectedId.ToString(); return SelectedId.ToString();
} }
private void JobsAvailableUpdated(IReadOnlyList<string> jobs)
{
foreach (var (id, button) in JobButtons)
{
button.Disabled = !jobs.Contains(id);
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_gameTicker.LobbyJobsAvailableUpdated -= JobsAvailableUpdated;
JobButtons.Clear();
}
}
} }
class JobButton : ContainerButton class JobButton : ContainerButton
{ {
public string JobId { get; set; } public string JobId { get; set; }

View File

@@ -196,5 +196,11 @@ namespace Content.Server.GameTicking
{ {
_spawnedPositions[jobId] = _spawnedPositions.GetValueOrDefault(jobId, 0) + 1; _spawnedPositions[jobId] = _spawnedPositions.GetValueOrDefault(jobId, 0) + 1;
} }
private void UpdateJobsAvailable()
{
var lobbyPlayers = _playersInLobby.Keys.Select(p => p.ConnectedClient).ToList();
_netManager.ServerSendToMany(GetJobsAvailable(), lobbyPlayers);
}
} }
} }

View File

@@ -143,6 +143,7 @@ namespace Content.Server.GameTicking
_netManager.RegisterNetMessage<MsgRoundEndMessage>(nameof(MsgRoundEndMessage)); _netManager.RegisterNetMessage<MsgRoundEndMessage>(nameof(MsgRoundEndMessage));
_netManager.RegisterNetMessage<MsgRequestWindowAttention>(nameof(MsgRequestWindowAttention)); _netManager.RegisterNetMessage<MsgRequestWindowAttention>(nameof(MsgRequestWindowAttention));
_netManager.RegisterNetMessage<MsgTickerLateJoinStatus>(nameof(MsgTickerLateJoinStatus)); _netManager.RegisterNetMessage<MsgTickerLateJoinStatus>(nameof(MsgTickerLateJoinStatus));
_netManager.RegisterNetMessage<MsgTickerJobsAvailable>(nameof(MsgTickerJobsAvailable));
SetStartPreset(_configurationManager.GetCVar(CCVars.GameLobbyDefaultPreset)); SetStartPreset(_configurationManager.GetCVar(CCVars.GameLobbyDefaultPreset));
@@ -307,6 +308,7 @@ namespace Content.Server.GameTicking
_sendStatusToAll(); _sendStatusToAll();
ReqWindowAttentionAll(); ReqWindowAttentionAll();
UpdateLateJoinStatus(); UpdateLateJoinStatus();
UpdateJobsAvailable();
} }
private void UpdateLateJoinStatus() private void UpdateLateJoinStatus()
@@ -420,6 +422,7 @@ namespace Content.Server.GameTicking
{ {
DisallowLateJoin = disallowLateJoin; DisallowLateJoin = disallowLateJoin;
UpdateLateJoinStatus(); UpdateLateJoinStatus();
UpdateJobsAvailable();
} }
public T AddGameRule<T>() where T : GameRule, new() public T AddGameRule<T>() where T : GameRule, new()
@@ -817,6 +820,7 @@ namespace Content.Server.GameTicking
var character = GetPlayerProfile(session); var character = GetPlayerProfile(session);
SpawnPlayer(session, character, jobId, lateJoin); SpawnPlayer(session, character, jobId, lateJoin);
UpdateJobsAvailable();
} }
private void SpawnPlayer(IPlayerSession session, private void SpawnPlayer(IPlayerSession session,
@@ -915,6 +919,7 @@ namespace Content.Server.GameTicking
_netManager.ServerSendMessage(_getStatusMsg(session), session.ConnectedClient); _netManager.ServerSendMessage(_getStatusMsg(session), session.ConnectedClient);
_netManager.ServerSendMessage(GetInfoMsg(), session.ConnectedClient); _netManager.ServerSendMessage(GetInfoMsg(), session.ConnectedClient);
_netManager.ServerSendMessage(GetPlayerStatus(), session.ConnectedClient); _netManager.ServerSendMessage(GetPlayerStatus(), session.ConnectedClient);
_netManager.ServerSendMessage(GetJobsAvailable(), session.ConnectedClient);
} }
private void _playerJoinGame(IPlayerSession session) private void _playerJoinGame(IPlayerSession session)
@@ -938,6 +943,22 @@ namespace Content.Server.GameTicking
return msg; return msg;
} }
private MsgTickerJobsAvailable GetJobsAvailable()
{
var message = _netManager.CreateNetMessage<MsgTickerJobsAvailable>();
// If late join is disallowed, return no available jobs.
if (DisallowLateJoin)
return message;
message.JobsAvailable = GetAvailablePositions()
.Where(e => e.Value > 0)
.Select(e => e.Key)
.ToArray();
return message;
}
private MsgTickerLobbyReady GetStatusSingle(IPlayerSession player, PlayerStatus status) private MsgTickerLobbyReady GetStatusSingle(IPlayerSession player, PlayerStatus status)
{ {
var msg = _netManager.CreateNetMessage<MsgTickerLobbyReady>(); var msg = _netManager.CreateNetMessage<MsgTickerLobbyReady>();

View File

@@ -262,7 +262,15 @@ namespace Content.Server.GameTicking
var ticker = IoCManager.Resolve<IGameTicker>(); var ticker = IoCManager.Resolve<IGameTicker>();
ticker.ToggleDisallowLateJoin(bool.Parse(args[0])); if (bool.TryParse(args[0], out var result))
{
ticker.ToggleDisallowLateJoin(bool.Parse(args[0]));
shell.SendText(player, result ? "Late joining has been disabled." : "Late joining has been enabled.");
}
else
{
shell.SendText(player, "Invalid argument.");
}
} }
} }

View File

@@ -231,6 +231,42 @@ namespace Content.Shared.GameTicking
} }
} }
protected class MsgTickerJobsAvailable : NetMessage
{
#region REQUIRED
public const MsgGroups GROUP = MsgGroups.Command;
public const string NAME = nameof(MsgTickerJobsAvailable);
public MsgTickerJobsAvailable(INetChannel channel) : base(NAME, GROUP) { }
#endregion
/// <summary>
/// The Status of the Player in the lobby (ready, observer, ...)
/// </summary>
public string[] JobsAvailable { get; set; } = Array.Empty<string>();
public override void ReadFromBuffer(NetIncomingMessage buffer)
{
var amount = buffer.ReadInt32();
JobsAvailable = new string[amount];
for (var i = 0; i < amount; i++)
{
JobsAvailable[i] = buffer.ReadString();
}
}
public override void WriteToBuffer(NetOutgoingMessage buffer)
{
buffer.Write(JobsAvailable.Length);
foreach (var job in JobsAvailable)
{
buffer.Write(job);
}
}
}
public struct RoundEndPlayerInfo public struct RoundEndPlayerInfo
{ {

View File

@@ -108,6 +108,7 @@
- godmode - godmode
- deleteewi - deleteewi
- hurt - hurt
- toggledisallowlatejoin
CanViewVar: true CanViewVar: true
CanAdminPlace: true CanAdminPlace: true
CanAdminMenu: true CanAdminMenu: true
@@ -209,6 +210,7 @@
- godmode - godmode
- deleteewi - deleteewi
- hurt - hurt
- toggledisallowlatejoin
CanViewVar: true CanViewVar: true
CanAdminPlace: true CanAdminPlace: true
CanScript: true CanScript: true