Add indicator showing amount of ghost roles available (#5150)

* Add indicator showing amount of ghost roles available

* Make the indicator turn red if ghost roles are available
This commit is contained in:
20kdc
2021-11-03 23:48:12 +00:00
committed by GitHub
parent 3ab4a30a0f
commit 9eb6e5a109
5 changed files with 77 additions and 4 deletions

View File

@@ -16,6 +16,10 @@ namespace Content.Client.Ghost
[Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IGameHud _gameHud = default!; [Dependency] private readonly IGameHud _gameHud = default!;
// Changes to this value are manually propagated.
// No good way to get an event into the UI.
public int AvailableGhostRoleCount { get; private set; } = 0;
private bool _ghostVisibility; private bool _ghostVisibility;
private bool GhostVisibility private bool GhostVisibility
@@ -51,6 +55,7 @@ namespace Content.Client.Ghost
SubscribeLocalEvent<GhostComponent, PlayerDetachedEvent>(OnGhostPlayerDetach); SubscribeLocalEvent<GhostComponent, PlayerDetachedEvent>(OnGhostPlayerDetach);
SubscribeNetworkEvent<GhostWarpsResponseEvent>(OnGhostWarpsResponse); SubscribeNetworkEvent<GhostWarpsResponseEvent>(OnGhostWarpsResponse);
SubscribeNetworkEvent<GhostUpdateGhostRoleCountEvent>(OnUpdateGhostRoleCount);
} }
private void OnGhostInit(EntityUid uid, GhostComponent component, ComponentInit args) private void OnGhostInit(EntityUid uid, GhostComponent component, ComponentInit args)
@@ -78,7 +83,7 @@ namespace Content.Client.Ghost
// I hate UI I hate UI I Hate UI // I hate UI I hate UI I Hate UI
if (component.Gui == null) if (component.Gui == null)
{ {
component.Gui = new GhostGui(component, EntityManager.EntityNetManager!); component.Gui = new GhostGui(component, this, EntityManager.EntityNetManager!);
component.Gui.Update(); component.Gui.Update();
} }
@@ -113,5 +118,12 @@ namespace Content.Client.Ghost
window.Populate(); window.Populate();
} }
} }
private void OnUpdateGhostRoleCount(GhostUpdateGhostRoleCountEvent msg)
{
AvailableGhostRoleCount = msg.AvailableGhostRoles;
foreach (var ghost in EntityManager.EntityQuery<GhostComponent>(true))
ghost.Gui?.Update();
}
} }
} }

View File

@@ -1,3 +1,4 @@
using Content.Client.Stylesheets;
using Content.Shared.Ghost; using Content.Shared.Ghost;
using Robust.Client.Console; using Robust.Client.Console;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
@@ -13,16 +14,18 @@ namespace Content.Client.Ghost.UI
{ {
private readonly Button _returnToBody = new() {Text = Loc.GetString("ghost-gui-return-to-body-button") }; private readonly Button _returnToBody = new() {Text = Loc.GetString("ghost-gui-return-to-body-button") };
private readonly Button _ghostWarp = new() {Text = Loc.GetString("ghost-gui-ghost-warp-button") }; private readonly Button _ghostWarp = new() {Text = Loc.GetString("ghost-gui-ghost-warp-button") };
private readonly Button _ghostRoles = new() {Text = Loc.GetString("ghost-gui-ghost-roles-button") }; private readonly Button _ghostRoles = new();
private readonly GhostComponent _owner; private readonly GhostComponent _owner;
private readonly GhostSystem _system;
public GhostTargetWindow? TargetWindow { get; } public GhostTargetWindow? TargetWindow { get; }
public GhostGui(GhostComponent owner, IEntityNetworkManager eventBus) public GhostGui(GhostComponent owner, GhostSystem system, IEntityNetworkManager eventBus)
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
_owner = owner; _owner = owner;
_system = system;
TargetWindow = new GhostTargetWindow(eventBus); TargetWindow = new GhostTargetWindow(eventBus);
@@ -57,6 +60,15 @@ namespace Content.Client.Ghost.UI
public void Update() public void Update()
{ {
_returnToBody.Disabled = !_owner.CanReturnToBody; _returnToBody.Disabled = !_owner.CanReturnToBody;
_ghostRoles.Text = Loc.GetString("ghost-gui-ghost-roles-button", ("count", _system.AvailableGhostRoleCount));
if (_system.AvailableGhostRoleCount != 0)
{
_ghostRoles.StyleClasses.Add(StyleBase.ButtonCaution);
}
else
{
_ghostRoles.StyleClasses.Remove(StyleBase.ButtonCaution);
}
TargetWindow?.Populate(); TargetWindow?.Populate();
} }

View File

@@ -6,6 +6,7 @@ using Content.Server.Ghost.Roles.Components;
using Content.Server.Ghost.Roles.UI; using Content.Server.Ghost.Roles.UI;
using Content.Shared.GameTicking; using Content.Shared.GameTicking;
using Content.Shared.Ghost.Roles; using Content.Shared.Ghost.Roles;
using Content.Shared.Ghost;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Server.Player; using Robust.Server.Player;
@@ -13,6 +14,7 @@ using Robust.Shared.Console;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
using Robust.Shared.Enums;
namespace Content.Server.Ghost.Roles namespace Content.Server.Ghost.Roles
{ {
@@ -20,8 +22,10 @@ namespace Content.Server.Ghost.Roles
public class GhostRoleSystem : EntitySystem public class GhostRoleSystem : EntitySystem
{ {
[Dependency] private readonly EuiManager _euiManager = default!; [Dependency] private readonly EuiManager _euiManager = default!;
[Dependency] private IPlayerManager _playerManager = default!;
private uint _nextRoleIdentifier = 0; private uint _nextRoleIdentifier = 0;
private bool _needsUpdateGhostRoleCount = true;
private readonly Dictionary<uint, GhostRoleComponent> _ghostRoles = new(); private readonly Dictionary<uint, GhostRoleComponent> _ghostRoles = new();
private readonly Dictionary<IPlayerSession, GhostRolesEui> _openUis = new(); private readonly Dictionary<IPlayerSession, GhostRolesEui> _openUis = new();
private readonly Dictionary<IPlayerSession, MakeGhostRoleEui> _openMakeGhostRoleUis = new(); private readonly Dictionary<IPlayerSession, MakeGhostRoleEui> _openMakeGhostRoleUis = new();
@@ -35,6 +39,15 @@ namespace Content.Server.Ghost.Roles
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset); SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttached); SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttached);
_playerManager.PlayerStatusChanged += PlayerStatusChanged;
}
public override void Shutdown()
{
base.Shutdown();
_playerManager.PlayerStatusChanged -= PlayerStatusChanged;
} }
private uint GetNextRoleIdentifier() private uint GetNextRoleIdentifier()
@@ -91,6 +104,31 @@ namespace Content.Server.Ghost.Roles
{ {
eui.StateDirty(); eui.StateDirty();
} }
// Note that this, like the EUIs, is deferred.
// This is for roughly the same reasons, too:
// Someone might spawn a ton of ghost roles at once.
_needsUpdateGhostRoleCount = true;
}
public override void Update(float frameTime)
{
base.Update(frameTime);
if (_needsUpdateGhostRoleCount)
{
_needsUpdateGhostRoleCount = false;
var response = new GhostUpdateGhostRoleCountEvent(_ghostRoles.Count);
foreach (var player in _playerManager.GetAllPlayers())
RaiseNetworkEvent(response, player.ConnectedClient);
}
}
private void PlayerStatusChanged(object? blah, SessionStatusEventArgs args)
{
if (args.NewStatus == SessionStatus.InGame)
{
var response = new GhostUpdateGhostRoleCountEvent(_ghostRoles.Count);
RaiseNetworkEvent(response, args.Session.ConnectedClient);
}
} }
public void RegisterGhostRole(GhostRoleComponent role) public void RegisterGhostRole(GhostRoleComponent role)

View File

@@ -113,4 +113,15 @@ namespace Content.Shared.Ghost
public class GhostReturnToBodyRequest : EntityEventArgs public class GhostReturnToBodyRequest : EntityEventArgs
{ {
} }
[Serializable, NetSerializable]
public class GhostUpdateGhostRoleCountEvent : EntityEventArgs
{
public int AvailableGhostRoles { get; }
public GhostUpdateGhostRoleCountEvent(int v)
{
AvailableGhostRoles = v;
}
}
} }

View File

@@ -1,6 +1,6 @@
ghost-gui-return-to-body-button = Return to body ghost-gui-return-to-body-button = Return to body
ghost-gui-ghost-warp-button = Ghost Warp ghost-gui-ghost-warp-button = Ghost Warp
ghost-gui-ghost-roles-button = Ghost Roles ghost-gui-ghost-roles-button = Ghost Roles ({$count})
ghost-target-window-title = Ghost Warp ghost-target-window-title = Ghost Warp
ghost-target-window-current-button = Warp: {$name} ghost-target-window-current-button = Warp: {$name}