Device link visualizer (#11054)
* shuffles devicelist to shared, adds an overlay for devicelist * adds space property to overlay * moves networkconfigurator to shared, makes devicelistsystem clientside check activedevicelist * dirties components upon change, adds networkedcomponent to sharednetworkconfigurator * state handlers for networked components * whoops * lots of shuffling, renaming, and access changes * randomizes color for every new entity added to the overlay * adds a client-side action to clear all network overlays if they're active * clones action (oops) * localization, adds a command for clearing network link overlays (in case the action disappears) * moves the entity manager up into the bui fields * makes that a dependency * attempts to just directly get the color from the dict when drawing, now * fixes up a few comments * adds dirty on init to devicelistcomponent * hacky solution related to mapping with a networkconfigurator * more stricter bound on that hacky solution * just checks if the life stage is initialized instead of if the entity was initialized * moves getalldevices to shared * readds linq import * tries to ensure that the show button is toggled on if the device we're trying to configure is currently being tracked by the overlay * some reorganization
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
namespace Content.Client.NetworkConfigurator;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for...
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed class NetworkConfiguratorActiveLinkOverlayComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The entities linked to this network configurator.
|
||||
/// This could just... couldn't this just be grabbed
|
||||
/// if DeviceList was shared?
|
||||
/// </summary>
|
||||
public HashSet<EntityUid> Devices = new();
|
||||
}
|
||||
@@ -1,16 +1,24 @@
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.NetworkConfigurator;
|
||||
|
||||
public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
private NetworkConfiguratorListMenu? _listMenu;
|
||||
private NetworkConfiguratorConfigurationMenu? _configurationMenu;
|
||||
|
||||
private NetworkConfiguratorSystem _netConfig;
|
||||
private DeviceListSystem _deviceList;
|
||||
|
||||
public NetworkConfiguratorBoundUserInterface(ClientUserInterfaceComponent owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_netConfig = _entityManager.System<NetworkConfiguratorSystem>();
|
||||
_deviceList = _entityManager.System<DeviceListSystem>();
|
||||
}
|
||||
|
||||
public void OnRemoveButtonPressed(string address)
|
||||
@@ -38,12 +46,31 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
|
||||
//_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit);
|
||||
_configurationMenu.Clear.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Clear);
|
||||
_configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy);
|
||||
_configurationMenu.Show.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Show);
|
||||
_configurationMenu.Show.OnPressed += OnShowPressed;
|
||||
_configurationMenu.Show.Pressed = _netConfig.ConfiguredListIsTracked(Owner.Owner);
|
||||
_configurationMenu.OpenCentered();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShowPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
if (!args.Button.Pressed)
|
||||
{
|
||||
_netConfig.ToggleVisualization(Owner.Owner, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_entityManager.GetComponent<MetaDataComponent>(Owner.Owner).EntityLifeStage == EntityLifeStage.Initialized)
|
||||
{
|
||||
// We're in mapping mode. Do something hacky.
|
||||
SendMessage(new ManualDeviceListSyncMessage(null, null));
|
||||
return;
|
||||
}
|
||||
|
||||
_netConfig.ToggleVisualization(Owner.Owner, true);
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
@@ -52,6 +79,25 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
|
||||
_listMenu?.UpdateState(castState);
|
||||
}
|
||||
|
||||
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
|
||||
{
|
||||
base.ReceiveMessage(message);
|
||||
|
||||
if (_configurationMenu == null
|
||||
|| _entityManager.GetComponent<MetaDataComponent>(Owner.Owner).EntityLifeStage > EntityLifeStage.Initialized
|
||||
|| message is not ManualDeviceListSyncMessage cast
|
||||
|| cast.Device == null
|
||||
|| cast.Devices == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_netConfig.SetActiveDeviceList(Owner.Owner, cast.Device.Value);
|
||||
_deviceList.UpdateDeviceList(cast.Device.Value, cast.Devices);
|
||||
_netConfig.ToggleVisualization(Owner.Owner, true);
|
||||
_configurationMenu.Show.Pressed = true;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="8 0 8 8">
|
||||
<Button Name="Copy" Text="Copy" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-copy'}" HorizontalExpand="True" StyleClasses="OpenRight"/>
|
||||
<Button Name="Show" Text="Show" Access="Public" Disabled="True" ToolTip="{Loc 'network-configurator-tooltip-show'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||
<Button Name="Show" Text="Show" Access="Public" ToggleMode="True" ToolTip="{Loc 'network-configurator-tooltip-show'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</ui:FancyWindow>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.NetworkConfigurator;
|
||||
|
||||
public sealed class NetworkConfiguratorLinkOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
private readonly DeviceListSystem _deviceListSystem;
|
||||
|
||||
private Dictionary<EntityUid, Color> _colors = new();
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
|
||||
public NetworkConfiguratorLinkOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_deviceListSystem = _entityManager.System<DeviceListSystem>();
|
||||
}
|
||||
|
||||
public void ClearEntity(EntityUid uid)
|
||||
{
|
||||
_colors.Remove(uid);
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
foreach (var tracker in _entityManager.EntityQuery<NetworkConfiguratorActiveLinkOverlayComponent>())
|
||||
{
|
||||
if (_entityManager.Deleted(tracker.Owner) || !_entityManager.TryGetComponent(tracker.Owner, out DeviceListComponent? deviceList))
|
||||
{
|
||||
_entityManager.RemoveComponentDeferred<NetworkConfiguratorActiveLinkOverlayComponent>(tracker.Owner);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_colors.TryGetValue(tracker.Owner, out var color))
|
||||
{
|
||||
color = new Color(
|
||||
_random.Next(0, 255),
|
||||
_random.Next(0, 255),
|
||||
_random.Next(0, 255));
|
||||
_colors.Add(tracker.Owner, color);
|
||||
}
|
||||
|
||||
var sourceTransform = _entityManager.GetComponent<TransformComponent>(tracker.Owner);
|
||||
|
||||
foreach (var device in _deviceListSystem.GetAllDevices(tracker.Owner, deviceList))
|
||||
{
|
||||
if (_entityManager.Deleted(device))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var linkTransform = _entityManager.GetComponent<TransformComponent>(device);
|
||||
|
||||
args.WorldHandle.DrawLine(sourceTransform.WorldPosition, linkTransform.WorldPosition, _colors[tracker.Owner]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Robust.Client.Graphics;
|
||||
|
||||
namespace Content.Client.NetworkConfigurator;
|
||||
|
||||
public sealed class DeviceListSystem : SharedDeviceListSystem
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
using System.Linq;
|
||||
using Content.Client.Actions;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.ActionTypes;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.NetworkConfigurator;
|
||||
|
||||
public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlay = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||
|
||||
private const string Action = "ClearNetworkLinkOverlays";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ClearAllOverlaysEvent>(_ => ClearAllOverlays());
|
||||
}
|
||||
|
||||
public bool ConfiguredListIsTracked(EntityUid uid, NetworkConfiguratorComponent? component = null)
|
||||
{
|
||||
return Resolve(uid, ref component)
|
||||
&& component.ActiveDeviceList != null
|
||||
&& HasComp<NetworkConfiguratorActiveLinkOverlayComponent>(component.ActiveDeviceList.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggles a device list's (tied to this network configurator) connection visualisation on and off.
|
||||
/// </summary>
|
||||
public void ToggleVisualization(EntityUid uid, bool toggle, NetworkConfiguratorComponent? component = null)
|
||||
{
|
||||
if (_playerManager.LocalPlayer == null
|
||||
|| _playerManager.LocalPlayer.ControlledEntity == null
|
||||
|| !Resolve(uid, ref component)
|
||||
|| component.ActiveDeviceList == null)
|
||||
return;
|
||||
|
||||
if (!toggle)
|
||||
{
|
||||
if (_overlay.HasOverlay<NetworkConfiguratorLinkOverlay>())
|
||||
{
|
||||
_overlay.GetOverlay<NetworkConfiguratorLinkOverlay>().ClearEntity(component.ActiveDeviceList.Value);
|
||||
}
|
||||
|
||||
RemComp<NetworkConfiguratorActiveLinkOverlayComponent>(component.ActiveDeviceList.Value);
|
||||
if (!EntityQuery<NetworkConfiguratorActiveLinkOverlayComponent>().Any())
|
||||
{
|
||||
_overlay.RemoveOverlay<NetworkConfiguratorLinkOverlay>();
|
||||
_actions.RemoveAction(_playerManager.LocalPlayer.ControlledEntity.Value, _prototypeManager.Index<InstantActionPrototype>(Action));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_overlay.HasOverlay<NetworkConfiguratorLinkOverlay>())
|
||||
{
|
||||
_overlay.AddOverlay(new NetworkConfiguratorLinkOverlay());
|
||||
_actions.AddAction(_playerManager.LocalPlayer.ControlledEntity.Value, new InstantAction(_prototypeManager.Index<InstantActionPrototype>(Action)), null);
|
||||
}
|
||||
|
||||
EnsureComp<NetworkConfiguratorActiveLinkOverlayComponent>(component.ActiveDeviceList.Value);
|
||||
}
|
||||
|
||||
public void ClearAllOverlays()
|
||||
{
|
||||
if (!_overlay.HasOverlay<NetworkConfiguratorLinkOverlay>())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var tracker in EntityQuery<NetworkConfiguratorActiveLinkOverlayComponent>())
|
||||
{
|
||||
RemCompDeferred<NetworkConfiguratorActiveLinkOverlayComponent>(tracker.Owner);
|
||||
}
|
||||
|
||||
_overlay.RemoveOverlay<NetworkConfiguratorLinkOverlay>();
|
||||
|
||||
if (_playerManager.LocalPlayer?.ControlledEntity != null)
|
||||
{
|
||||
_actions.RemoveAction(_playerManager.LocalPlayer.ControlledEntity.Value, _prototypeManager.Index<InstantActionPrototype>(Action));
|
||||
}
|
||||
}
|
||||
|
||||
// hacky solution related to mapping
|
||||
public void SetActiveDeviceList(EntityUid tool, EntityUid list, NetworkConfiguratorComponent? component = null)
|
||||
{
|
||||
if (!Resolve(tool, ref component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
component.ActiveDeviceList = list;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ClearAllNetworkLinkOverlays : IConsoleCommand
|
||||
{
|
||||
public string Command => "clearnetworklinkoverlays";
|
||||
public string Description => "Clear all network link overlays.";
|
||||
public string Help => Command;
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
IoCManager.Resolve<IEntityManager>().System<NetworkConfiguratorSystem>().ClearAllOverlays();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user