Turns GameTicker into an EntitySystem. (#4197)

* GameTicker turned into an EntitySystem

* Turns ClientGameTicker into an EntitySystem, turn NetMessages into events

* Change event names to be more consistent with the rest.

* YAML linter uses the dummy gameticker CVar override.

* Fix game ticker initialization order

* Dummy ticker won't spawn players.

* Fix character creation test
This commit is contained in:
Vera Aguilera Puerto
2021-06-20 10:09:24 +02:00
committed by GitHub
parent 15fb554c28
commit d3a611164b
81 changed files with 1711 additions and 1990 deletions

View File

@@ -26,7 +26,6 @@ namespace Content.Client.Audio
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;
[Dependency] private readonly IBaseClient _client = default!;
[Dependency] private readonly IClientGameTicker _clientGameTicker = default!;
private SoundCollectionPrototype _ambientCollection = default!;
@@ -50,7 +49,7 @@ namespace Content.Client.Audio
_client.PlayerJoinedServer += OnJoin;
_client.PlayerLeaveServer += OnLeave;
_clientGameTicker.LobbyStatusUpdated += LobbySongReceived;
Get<ClientGameTicker>().LobbyStatusUpdated += LobbySongReceived;
}
public override void Shutdown()
@@ -62,7 +61,7 @@ namespace Content.Client.Audio
_client.PlayerJoinedServer -= OnJoin;
_client.PlayerLeaveServer -= OnLeave;
_clientGameTicker.LobbyStatusUpdated -= LobbySongReceived;
Get<ClientGameTicker>().LobbyStatusUpdated -= LobbySongReceived;
EndAmbience();
EndLobbyMusic();
@@ -167,7 +166,7 @@ namespace Content.Client.Audio
private void StartLobbyMusic()
{
EndLobbyMusic();
var file = _clientGameTicker.LobbySong;
var file = Get<ClientGameTicker>().LobbySong;
if (file == null) // We have not received the lobby song yet.
{
return;

View File

@@ -167,7 +167,6 @@ namespace Content.Client.Entry
IoCManager.Resolve<IGameHud>().Initialize();
IoCManager.Resolve<IClientNotifyManager>().Initialize();
IoCManager.Resolve<IClientGameTicker>().Initialize();
var overlayMgr = IoCManager.Resolve<IOverlayManager>();
overlayMgr.AddOverlay(new ParallaxOverlay());

View File

@@ -5,6 +5,7 @@ using Content.Client.RoundEnd;
using Content.Client.Viewport;
using Content.Shared.GameTicking;
using Content.Shared.GameWindow;
using JetBrains.Annotations;
using Robust.Client.Graphics;
using Robust.Client.State;
using Robust.Shared.IoC;
@@ -14,10 +15,11 @@ using Robust.Shared.ViewVariables;
namespace Content.Client.GameTicking.Managers
{
public class ClientGameTicker : SharedGameTicker, IClientGameTicker
[UsedImplicitly]
public class ClientGameTicker : SharedGameTicker
{
[Dependency] private readonly IClientNetManager _netManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;
[Dependency] private readonly IClientNetManager _netManager = default!;
[ViewVariables] private bool _initialized;
private readonly List<string> _jobsAvailable = new();
@@ -29,7 +31,7 @@ namespace Content.Client.GameTicking.Managers
[ViewVariables] public string? ServerInfoBlob { get; private set; }
[ViewVariables] public TimeSpan StartTime { get; private set; }
[ViewVariables] public bool Paused { get; private set; }
[ViewVariables] public Dictionary<NetUserId, PlayerStatus> Status { get; private set; } = new();
[ViewVariables] public Dictionary<NetUserId, LobbyPlayerStatus> Status { get; private set; } = new();
[ViewVariables] public IReadOnlyList<string> JobsAvailable => _jobsAvailable;
public event Action? InfoBlobUpdated;
@@ -38,47 +40,47 @@ namespace Content.Client.GameTicking.Managers
public event Action? LobbyLateJoinStatusUpdated;
public event Action<IReadOnlyList<string>>? LobbyJobsAvailableUpdated;
public void Initialize()
public override void Initialize()
{
DebugTools.Assert(!_initialized);
_netManager.RegisterNetMessage<MsgTickerJoinLobby>(nameof(MsgTickerJoinLobby), JoinLobby);
_netManager.RegisterNetMessage<MsgTickerJoinGame>(nameof(MsgTickerJoinGame), JoinGame);
_netManager.RegisterNetMessage<MsgTickerLobbyStatus>(nameof(MsgTickerLobbyStatus), LobbyStatus);
_netManager.RegisterNetMessage<MsgTickerLobbyInfo>(nameof(MsgTickerLobbyInfo), LobbyInfo);
_netManager.RegisterNetMessage<MsgTickerLobbyCountdown>(nameof(MsgTickerLobbyCountdown), LobbyCountdown);
_netManager.RegisterNetMessage<MsgTickerLobbyReady>(nameof(MsgTickerLobbyReady), LobbyReady);
_netManager.RegisterNetMessage<MsgRoundEndMessage>(nameof(MsgRoundEndMessage), RoundEnd);
_netManager.RegisterNetMessage<MsgRequestWindowAttention>(nameof(MsgRequestWindowAttention), msg =>
SubscribeNetworkEvent<TickerJoinLobbyEvent>(JoinLobby);
SubscribeNetworkEvent<TickerJoinGameEvent>(JoinGame);
SubscribeNetworkEvent<TickerLobbyStatusEvent>(LobbyStatus);
SubscribeNetworkEvent<TickerLobbyInfoEvent>(LobbyInfo);
SubscribeNetworkEvent<TickerLobbyCountdownEvent>(LobbyCountdown);
SubscribeNetworkEvent<TickerLobbyReadyEvent>(LobbyReady);
SubscribeNetworkEvent<RoundEndMessageEvent>(RoundEnd);
SubscribeNetworkEvent<RequestWindowAttentionEvent>(msg =>
{
IoCManager.Resolve<IClyde>().RequestWindowAttention();
});
_netManager.RegisterNetMessage<MsgTickerLateJoinStatus>(nameof(MsgTickerLateJoinStatus), LateJoinStatus);
_netManager.RegisterNetMessage<MsgTickerJobsAvailable>(nameof(MsgTickerJobsAvailable), UpdateJobsAvailable);
SubscribeNetworkEvent<TickerLateJoinStatusEvent>(LateJoinStatus);
SubscribeNetworkEvent<TickerJobsAvailableEvent>(UpdateJobsAvailable);
Status = new Dictionary<NetUserId, PlayerStatus>();
Status = new Dictionary<NetUserId, LobbyPlayerStatus>();
_initialized = true;
}
private void LateJoinStatus(MsgTickerLateJoinStatus message)
private void LateJoinStatus(TickerLateJoinStatusEvent message)
{
DisallowedLateJoin = message.Disallowed;
LobbyLateJoinStatusUpdated?.Invoke();
}
private void UpdateJobsAvailable(MsgTickerJobsAvailable message)
private void UpdateJobsAvailable(TickerJobsAvailableEvent message)
{
_jobsAvailable.Clear();
_jobsAvailable.AddRange(message.JobsAvailable);
LobbyJobsAvailableUpdated?.Invoke(JobsAvailable);
}
private void JoinLobby(MsgTickerJoinLobby message)
private void JoinLobby(TickerJoinLobbyEvent message)
{
_stateManager.RequestStateChange<LobbyState>();
}
private void LobbyStatus(MsgTickerLobbyStatus message)
private void LobbyStatus(TickerLobbyStatusEvent message)
{
StartTime = message.StartTime;
IsGameStarted = message.IsRoundStarted;
@@ -91,35 +93,35 @@ namespace Content.Client.GameTicking.Managers
LobbyStatusUpdated?.Invoke();
}
private void LobbyInfo(MsgTickerLobbyInfo message)
private void LobbyInfo(TickerLobbyInfoEvent message)
{
ServerInfoBlob = message.TextBlob;
InfoBlobUpdated?.Invoke();
}
private void JoinGame(MsgTickerJoinGame message)
private void JoinGame(TickerJoinGameEvent message)
{
_stateManager.RequestStateChange<GameScreen>();
}
private void LobbyCountdown(MsgTickerLobbyCountdown message)
private void LobbyCountdown(TickerLobbyCountdownEvent message)
{
StartTime = message.StartTime;
Paused = message.Paused;
}
private void LobbyReady(MsgTickerLobbyReady message)
private void LobbyReady(TickerLobbyReadyEvent message)
{
// Merge the Dictionaries
foreach (var p in message.PlayerStatus)
foreach (var p in message.Status)
{
Status[p.Key] = p.Value;
}
LobbyReadyUpdated?.Invoke();
}
private void RoundEnd(MsgRoundEndMessage message)
private void RoundEnd(RoundEndMessageEvent message)
{
//This is not ideal at all, but I don't see an immediately better fit anywhere else.
var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.RoundEndText, message.RoundDuration, message.AllPlayersEndInfo);

View File

@@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using Robust.Shared.Network;
using static Content.Shared.GameTicking.SharedGameTicker;
namespace Content.Client.GameTicking.Managers
{
public interface IClientGameTicker
{
bool IsGameStarted { get; }
string? ServerInfoBlob { get; }
bool AreWeReady { get; }
string? LobbySong { get; }
bool DisallowedLateJoin { get; }
TimeSpan StartTime { get; }
bool Paused { get; }
Dictionary<NetUserId, PlayerStatus> Status { get; }
IReadOnlyList<string> JobsAvailable { get; }
void Initialize();
event Action InfoBlobUpdated;
event Action LobbyStatusUpdated;
event Action LobbyReadyUpdated;
event Action LobbyLateJoinStatusUpdated;
event Action<IReadOnlyList<string>> LobbyJobsAvailableUpdated;
}
}

View File

@@ -33,7 +33,6 @@ namespace Content.Client.IoC
IoCManager.Register<IGameHud, GameHud>();
IoCManager.Register<IClientNotifyManager, ClientNotifyManager>();
IoCManager.Register<ISharedNotifyManager, ClientNotifyManager>();
IoCManager.Register<IClientGameTicker, ClientGameTicker>();
IoCManager.Register<IParallaxManager, ParallaxManager>();
IoCManager.Register<IChatManager, ChatManager>();
IoCManager.Register<IEscapeMenuOwner, EscapeMenuOwner>();

View File

@@ -9,6 +9,7 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.Utility;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Log;
@@ -22,7 +23,6 @@ namespace Content.Client.LateJoin
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
[Dependency] private readonly IClientGameTicker _gameTicker = default!;
public event Action<string>? SelectedId;
@@ -34,6 +34,8 @@ namespace Content.Client.LateJoin
MinSize = SetSize = (360, 560);
IoCManager.InjectDependencies(this);
var gameTicker = EntitySystem.Get<ClientGameTicker>();
Title = Loc.GetString("Late Join");
var jobList = new VBoxContainer();
@@ -131,7 +133,7 @@ namespace Content.Client.LateJoin
SelectedId?.Invoke(jobButton.JobId);
};
if (!_gameTicker.JobsAvailable.Contains(job.ID))
if (!gameTicker.JobsAvailable.Contains(job.ID))
{
jobButton.Disabled = true;
}
@@ -147,7 +149,7 @@ namespace Content.Client.LateJoin
Close();
};
_gameTicker.LobbyJobsAvailableUpdated += JobsAvailableUpdated;
gameTicker.LobbyJobsAvailableUpdated += JobsAvailableUpdated;
}
private void JobsAvailableUpdated(IReadOnlyList<string> jobs)
@@ -164,7 +166,7 @@ namespace Content.Client.LateJoin
if (disposing)
{
_gameTicker.LobbyJobsAvailableUpdated -= JobsAvailableUpdated;
EntitySystem.Get<ClientGameTicker>().LobbyJobsAvailableUpdated -= JobsAvailableUpdated;
_jobButtons.Clear();
_jobCategories.Clear();
}

View File

@@ -10,6 +10,8 @@ using Content.Client.Preferences.UI;
using Content.Client.Viewport;
using Content.Client.Voting;
using Content.Shared.Chat;
using Content.Shared.GameObjects.Components;
using Content.Shared.GameTicking;
using Content.Shared.Input;
using Robust.Client;
using Robust.Client.Console;
@@ -38,7 +40,6 @@ namespace Content.Client.Lobby
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
[Dependency] private readonly IClientGameTicker _clientGameTicker = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
[Dependency] private readonly IClientPreferencesManager _preferencesManager = default!;
@@ -50,6 +51,7 @@ namespace Content.Client.Lobby
public override void Startup()
{
var gameTicker = EntitySystem.Get<ClientGameTicker>();
_characterSetup = new CharacterSetupGui(_entityManager, _resourceCache, _preferencesManager,
_prototypeManager);
LayoutContainer.SetAnchorPreset(_characterSetup, LayoutContainer.LayoutPreset.Wide);
@@ -105,7 +107,7 @@ namespace Content.Client.Lobby
_lobby.ObserveButton.OnPressed += _ => _consoleHost.ExecuteCommand("observe");
_lobby.ReadyButton.OnPressed += _ =>
{
if (!_clientGameTicker.IsGameStarted)
if (!gameTicker.IsGameStarted)
{
return;
}
@@ -124,29 +126,23 @@ namespace Content.Client.Lobby
UpdatePlayerList();
_playerManager.PlayerListUpdated += PlayerManagerOnPlayerListUpdated;
_clientGameTicker.InfoBlobUpdated += UpdateLobbyUi;
_clientGameTicker.LobbyStatusUpdated += LobbyStatusUpdated;
_clientGameTicker.LobbyReadyUpdated += LobbyReadyUpdated;
_clientGameTicker.LobbyLateJoinStatusUpdated += LobbyLateJoinStatusUpdated;
gameTicker.InfoBlobUpdated += UpdateLobbyUi;
gameTicker.LobbyStatusUpdated += LobbyStatusUpdated;
gameTicker.LobbyReadyUpdated += LobbyReadyUpdated;
gameTicker.LobbyLateJoinStatusUpdated += LobbyLateJoinStatusUpdated;
}
public override void Shutdown()
{
_playerManager.PlayerListUpdated -= PlayerManagerOnPlayerListUpdated;
_clientGameTicker.InfoBlobUpdated -= UpdateLobbyUi;
_clientGameTicker.LobbyStatusUpdated -= LobbyStatusUpdated;
_clientGameTicker.LobbyReadyUpdated -= LobbyReadyUpdated;
_clientGameTicker.LobbyLateJoinStatusUpdated -= LobbyLateJoinStatusUpdated;
_clientGameTicker.Status.Clear();
_lobby.Dispose();
_characterSetup.Dispose();
}
public override void FrameUpdate(FrameEventArgs e)
{
if (_clientGameTicker.IsGameStarted)
var gameTicker = EntitySystem.Get<ClientGameTicker>();
if (gameTicker.IsGameStarted)
{
_lobby.StartTime.Text = "";
return;
@@ -154,13 +150,13 @@ namespace Content.Client.Lobby
string text;
if (_clientGameTicker.Paused)
if (gameTicker.Paused)
{
text = Loc.GetString("Paused");
}
else
{
var difference = _clientGameTicker.StartTime - _gameTiming.CurTime;
var difference = gameTicker.StartTime - _gameTiming.CurTime;
var seconds = difference.TotalSeconds;
if (seconds < 0)
{
@@ -177,15 +173,16 @@ namespace Content.Client.Lobby
private void PlayerManagerOnPlayerListUpdated(object? sender, EventArgs e)
{
var gameTicker = EntitySystem.Get<ClientGameTicker>();
// Remove disconnected sessions from the Ready Dict
foreach (var p in _clientGameTicker.Status)
foreach (var p in gameTicker.Status)
{
if (!_playerManager.SessionsDict.TryGetValue(p.Key, out _))
{
// This is a shitty fix. Observers can rejoin because they are already in the game.
// So we don't delete them, but keep them if they decide to rejoin
if (p.Value != PlayerStatus.Observer)
_clientGameTicker.Status.Remove(p.Key);
if (p.Value != LobbyPlayerStatus.Observer)
gameTicker.Status.Remove(p.Key);
}
}
@@ -202,7 +199,7 @@ namespace Content.Client.Lobby
private void LobbyLateJoinStatusUpdated()
{
_lobby.ReadyButton.Disabled = _clientGameTicker.DisallowedLateJoin;
_lobby.ReadyButton.Disabled = EntitySystem.Get<ClientGameTicker>().DisallowedLateJoin;
}
private void UpdateLobbyUi()
@@ -212,7 +209,9 @@ namespace Content.Client.Lobby
return;
}
if (_clientGameTicker.IsGameStarted)
var gameTicker = EntitySystem.Get<ClientGameTicker>();
if (gameTicker.IsGameStarted)
{
_lobby.ReadyButton.Text = Loc.GetString("Join");
_lobby.ReadyButton.ToggleMode = false;
@@ -224,36 +223,37 @@ namespace Content.Client.Lobby
_lobby.ReadyButton.Text = Loc.GetString("Ready Up");
_lobby.ReadyButton.ToggleMode = true;
_lobby.ReadyButton.Disabled = false;
_lobby.ReadyButton.Pressed = _clientGameTicker.AreWeReady;
_lobby.ReadyButton.Pressed = gameTicker.AreWeReady;
}
if (_clientGameTicker.ServerInfoBlob != null)
if (gameTicker.ServerInfoBlob != null)
{
_lobby.ServerInfo.SetInfoBlob(_clientGameTicker.ServerInfoBlob);
_lobby.ServerInfo.SetInfoBlob(gameTicker.ServerInfoBlob);
}
}
private void UpdatePlayerList()
{
_lobby.OnlinePlayerList.Clear();
var gameTicker = EntitySystem.Get<ClientGameTicker>();
foreach (var session in _playerManager.Sessions.OrderBy(s => s.Name))
{
var readyState = "";
// Don't show ready state if we're ingame
if (!_clientGameTicker.IsGameStarted)
if (!gameTicker.IsGameStarted)
{
PlayerStatus status;
LobbyPlayerStatus status;
if (session.UserId == _playerManager.LocalPlayer?.UserId)
status = _clientGameTicker.AreWeReady ? PlayerStatus.Ready : PlayerStatus.NotReady;
status = gameTicker.AreWeReady ? LobbyPlayerStatus.Ready : LobbyPlayerStatus.NotReady;
else
_clientGameTicker.Status.TryGetValue(session.UserId, out status);
gameTicker.Status.TryGetValue(session.UserId, out status);
readyState = status switch
{
PlayerStatus.NotReady => Loc.GetString("Not Ready"),
PlayerStatus.Ready => Loc.GetString("Ready"),
PlayerStatus.Observer => Loc.GetString("Observer"),
LobbyPlayerStatus.NotReady => Loc.GetString("Not Ready"),
LobbyPlayerStatus.Ready => Loc.GetString("Ready"),
LobbyPlayerStatus.Observer => Loc.GetString("Observer"),
_ => "",
};
}
@@ -264,7 +264,7 @@ namespace Content.Client.Lobby
private void SetReady(bool newReady)
{
if (_clientGameTicker.IsGameStarted)
if (EntitySystem.Get<ClientGameTicker>().IsGameStarted)
{
return;
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Content.Client.Message;
using Content.Shared.GameTicking;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Localization;
@@ -15,7 +16,7 @@ namespace Content.Client.RoundEnd
private VBoxContainer PlayerManifestoTab { get; }
private TabContainer RoundEndWindowTabs { get; }
public RoundEndSummaryWindow(string gm, string roundEnd, TimeSpan roundTimeSpan, List<RoundEndPlayerInfo> info)
public RoundEndSummaryWindow(string gm, string roundEnd, TimeSpan roundTimeSpan, RoundEndMessageEvent.RoundEndPlayerInfo[] info)
{
MinSize = SetSize = (520, 580);