Make ghost component ECS (#4159)
* Make ghost component ECS * Remove players and locations properties from ghost component * Address reviews * One more doc * Fix client ghost component state method error
This commit is contained in:
@@ -1,143 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Client.Chat.Managers;
|
||||
using Content.Client.HUD;
|
||||
using Content.Shared.Ghost;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Client.Ghost
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class GhostComponent : SharedGhostComponent
|
||||
{
|
||||
[Dependency] private readonly IGameHud _gameHud = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IComponentManager _componentManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
|
||||
public List<string> WarpNames = new();
|
||||
public Dictionary<EntityUid,string> PlayerNames = new();
|
||||
|
||||
private GhostGui? _gui ;
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)] public bool CanReturnToBody { get; private set; } = true;
|
||||
|
||||
private bool _isAttached;
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
|
||||
_gui?.Dispose();
|
||||
|
||||
// PlayerDetachedMsg might not fire due to deletion order so...
|
||||
if (_isAttached)
|
||||
{
|
||||
SetGhostVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetGhostVisibility(bool visibility)
|
||||
{
|
||||
foreach (var ghost in _componentManager.GetAllComponents(typeof(GhostComponent), true))
|
||||
{
|
||||
if (ghost.Owner.TryGetComponent(out SpriteComponent? component))
|
||||
{
|
||||
component.Visible = visibility;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
if (Owner.TryGetComponent(out SpriteComponent? component))
|
||||
{
|
||||
component.Visible =
|
||||
_playerManager.LocalPlayer?.ControlledEntity?.HasComponent<GhostComponent>() ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, IComponent? component)
|
||||
{
|
||||
base.HandleMessage(message, component);
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case PlayerAttachedMsg _:
|
||||
if (_gui == null)
|
||||
{
|
||||
_gui = new GhostGui(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gui.Orphan();
|
||||
}
|
||||
|
||||
_gameHud.HandsContainer.AddChild(_gui);
|
||||
SetGhostVisibility(true);
|
||||
_isAttached = true;
|
||||
|
||||
break;
|
||||
|
||||
case PlayerDetachedMsg _:
|
||||
_gui!.Parent?.RemoveChild(_gui);
|
||||
SetGhostVisibility(false);
|
||||
_isAttached = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SendReturnToBodyMessage() => SendNetworkMessage(new ReturnToBodyComponentMessage());
|
||||
|
||||
public void SendGhostWarpRequestMessage(string warpName) => SendNetworkMessage(new GhostWarpToLocationRequestMessage(warpName));
|
||||
|
||||
public void SendGhostWarpRequestMessage(EntityUid target) => SendNetworkMessage(new GhostWarpToTargetRequestMessage(target));
|
||||
|
||||
public void GhostRequestWarpPoint() => SendNetworkMessage(new GhostRequestWarpPointData());
|
||||
|
||||
public void GhostRequestPlayerNames() => SendNetworkMessage(new GhostRequestPlayerNameData());
|
||||
public GhostGui? Gui { get; set; }
|
||||
public bool IsAttached { get; set; }
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
{
|
||||
base.HandleComponentState(curState, nextState);
|
||||
|
||||
if (curState is not GhostComponentState state) return;
|
||||
|
||||
CanReturnToBody = state.CanReturnToBody;
|
||||
|
||||
if (Owner == _playerManager.LocalPlayer!.ControlledEntity)
|
||||
if (curState is not GhostComponentState)
|
||||
{
|
||||
_gui?.Update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession? session = null)
|
||||
{
|
||||
base.HandleNetworkMessage(message, netChannel, session);
|
||||
|
||||
switch (message)
|
||||
if (Owner == _playerManager.LocalPlayer?.ControlledEntity)
|
||||
{
|
||||
case GhostReplyWarpPointData data:
|
||||
WarpNames = new List<string>();
|
||||
foreach (var names in data.WarpName)
|
||||
{
|
||||
WarpNames.Add(names);
|
||||
}
|
||||
break;
|
||||
case GhostReplyPlayerNameData data:
|
||||
PlayerNames = new Dictionary<EntityUid, string>();
|
||||
foreach (var (key, value) in data.PlayerNames)
|
||||
{
|
||||
PlayerNames.Add(key,value);
|
||||
}
|
||||
break;
|
||||
Gui?.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Ghost;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
|
||||
@@ -17,19 +21,29 @@ namespace Content.Client.Ghost
|
||||
|
||||
public GhostTargetWindow? TargetWindow { get; }
|
||||
|
||||
public GhostGui(GhostComponent owner)
|
||||
public GhostGui(GhostComponent owner, IEntityNetworkManager eventBus)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_owner = owner;
|
||||
|
||||
TargetWindow = new GhostTargetWindow(owner);
|
||||
TargetWindow = new GhostTargetWindow(owner, eventBus);
|
||||
|
||||
MouseFilter = MouseFilterMode.Ignore;
|
||||
|
||||
_ghostWarp.OnPressed += _ => TargetWindow.Populate();
|
||||
_returnToBody.OnPressed += _ => owner.SendReturnToBodyMessage();
|
||||
_ghostRoles.OnPressed += _ => IoCManager.Resolve<IClientConsoleHost>().RemoteExecuteCommand(null, "ghostroles");
|
||||
_ghostWarp.OnPressed += _ =>
|
||||
{
|
||||
eventBus.SendSystemNetworkMessage(new GhostWarpsRequestEvent());
|
||||
TargetWindow.Populate();
|
||||
TargetWindow.OpenCentered();
|
||||
};
|
||||
_returnToBody.OnPressed += _ =>
|
||||
{
|
||||
var msg = new GhostReturnToBodyRequest();
|
||||
eventBus.SendSystemNetworkMessage(msg);
|
||||
};
|
||||
_ghostRoles.OnPressed += _ => IoCManager.Resolve<IClientConsoleHost>()
|
||||
.RemoteExecuteCommand(null, "ghostroles");
|
||||
|
||||
AddChild(new HBoxContainer
|
||||
{
|
||||
@@ -40,28 +54,42 @@ namespace Content.Client.Ghost
|
||||
_ghostRoles,
|
||||
}
|
||||
});
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
_returnToBody.Disabled = !_owner.CanReturnToBody;
|
||||
TargetWindow?.Populate();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
TargetWindow?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GhostTargetWindow : SS14Window
|
||||
{
|
||||
private readonly GhostComponent _owner;
|
||||
private readonly IEntityNetworkManager _netManager;
|
||||
|
||||
private readonly VBoxContainer _buttonContainer;
|
||||
|
||||
public GhostTargetWindow(GhostComponent owner)
|
||||
public List<string> Locations { get; set; } = new();
|
||||
|
||||
public Dictionary<EntityUid, string> Players { get; set; } = new();
|
||||
|
||||
public GhostTargetWindow(GhostComponent owner, IEntityNetworkManager netManager)
|
||||
{
|
||||
MinSize = SetSize = (300, 450);
|
||||
Title = "Ghost Warp";
|
||||
_owner = owner;
|
||||
_owner.GhostRequestWarpPoint();
|
||||
_owner.GhostRequestPlayerNames();
|
||||
_netManager = netManager;
|
||||
|
||||
_buttonContainer = new VBoxContainer()
|
||||
{
|
||||
@@ -86,12 +114,11 @@ namespace Content.Client.Ghost
|
||||
_buttonContainer.DisposeAllChildren();
|
||||
AddButtonPlayers();
|
||||
AddButtonLocations();
|
||||
OpenCentered();
|
||||
}
|
||||
|
||||
private void AddButtonPlayers()
|
||||
{
|
||||
foreach (var (key, value) in _owner.PlayerNames)
|
||||
foreach (var (key, value) in Players)
|
||||
{
|
||||
var currentButtonRef = new Button
|
||||
{
|
||||
@@ -106,7 +133,8 @@ namespace Content.Client.Ghost
|
||||
|
||||
currentButtonRef.OnPressed += (_) =>
|
||||
{
|
||||
_owner.SendGhostWarpRequestMessage(key);
|
||||
var msg = new GhostWarpToTargetRequestEvent(key);
|
||||
_netManager.SendSystemNetworkMessage(msg);
|
||||
};
|
||||
|
||||
_buttonContainer.AddChild(currentButtonRef);
|
||||
@@ -115,7 +143,7 @@ namespace Content.Client.Ghost
|
||||
|
||||
private void AddButtonLocations()
|
||||
{
|
||||
foreach (var name in _owner.WarpNames)
|
||||
foreach (var name in Locations)
|
||||
{
|
||||
var currentButtonRef = new Button
|
||||
{
|
||||
@@ -130,7 +158,8 @@ namespace Content.Client.Ghost
|
||||
|
||||
currentButtonRef.OnPressed += (_) =>
|
||||
{
|
||||
_owner.SendGhostWarpRequestMessage(name);
|
||||
var msg = new GhostWarpToLocationRequestEvent(name);
|
||||
_netManager.SendSystemNetworkMessage(msg);
|
||||
};
|
||||
|
||||
_buttonContainer.AddChild(currentButtonRef);
|
||||
|
||||
117
Content.Client/Ghost/GhostSystem.cs
Normal file
117
Content.Client/Ghost/GhostSystem.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using Content.Client.HUD;
|
||||
using Content.Shared.Ghost;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Client.Ghost
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class GhostSystem : SharedGhostSystem
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IGameHud _gameHud = default!;
|
||||
|
||||
private bool _ghostVisibility;
|
||||
|
||||
private bool GhostVisibility
|
||||
{
|
||||
get => _ghostVisibility;
|
||||
set
|
||||
{
|
||||
if (_ghostVisibility == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ghostVisibility = value;
|
||||
|
||||
foreach (var ghost in ComponentManager.GetAllComponents(typeof(GhostComponent), true))
|
||||
{
|
||||
if (ghost.Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||
{
|
||||
sprite.Visible = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<GhostComponent, ComponentInit>(OnGhostInit);
|
||||
SubscribeLocalEvent<GhostComponent, ComponentRemove>(OnGhostRemove);
|
||||
|
||||
SubscribeLocalEvent<GhostComponent, PlayerAttachedEvent>(OnGhostPlayerAttach);
|
||||
SubscribeLocalEvent<GhostComponent, PlayerDetachedEvent>(OnGhostPlayerDetach);
|
||||
|
||||
SubscribeNetworkEvent<GhostWarpsResponseEvent>(OnGhostWarpsResponse);
|
||||
}
|
||||
|
||||
private void OnGhostInit(EntityUid uid, GhostComponent component, ComponentInit args)
|
||||
{
|
||||
if (component.Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||
{
|
||||
sprite.Visible = GhostVisibility;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGhostRemove(EntityUid uid, GhostComponent component, ComponentRemove args)
|
||||
{
|
||||
component.Gui?.Dispose();
|
||||
|
||||
// PlayerDetachedMsg might not fire due to deletion order so...
|
||||
if (component.IsAttached)
|
||||
{
|
||||
GhostVisibility = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, PlayerAttachedEvent playerAttachedEvent)
|
||||
{
|
||||
if (component.Gui == null)
|
||||
{
|
||||
component.Gui = new GhostGui(component, EntityManager.EntityNetManager!);
|
||||
component.Gui.Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
component.Gui.Orphan();
|
||||
}
|
||||
|
||||
_gameHud.HandsContainer.AddChild(component.Gui);
|
||||
GhostVisibility = true;
|
||||
component.IsAttached = true;
|
||||
}
|
||||
|
||||
private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, PlayerDetachedEvent args)
|
||||
{
|
||||
component.Gui?.Parent?.RemoveChild(component.Gui);
|
||||
GhostVisibility = false;
|
||||
component.IsAttached = false;
|
||||
}
|
||||
|
||||
private void OnGhostWarpsResponse(GhostWarpsResponseEvent msg)
|
||||
{
|
||||
var entity = _playerManager.LocalPlayer?.ControlledEntity;
|
||||
|
||||
if (entity == null ||
|
||||
!entity.TryGetComponent(out GhostComponent? ghost))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var window = ghost.Gui?.TargetWindow;
|
||||
|
||||
if (window != null)
|
||||
{
|
||||
window.Locations = msg.Locations;
|
||||
window.Players = msg.Players;
|
||||
window.Populate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user