Files
crystall-punk-14/Content.Client/_CP14/DemiplaneTraveling/CP14DemiplaneMapWindow.xaml.cs

267 lines
8.4 KiB
C#

using System.Numerics;
using System.Text;
using Content.Client._CP14.UserInterface.Systems.NodeTree;
using Content.Client.Administration.Managers;
using Content.Shared._CP14.DemiplaneTraveling;
using Content.Shared.Administration;
using Robust.Client.AutoGenerated;
using Robust.Client.Player;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Utility;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Client._CP14.DemiplaneTraveling;
[GenerateTypedNameReferences]
public sealed partial class CP14DemiplaneMapWindow : DefaultWindow
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly ILogManager _log = default!;
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IClientAdminManager _admin = default!;
private CP14DemiplaneMapUiState? _cachedState;
private CP14DemiplaneMapNode? _selectedNode;
public event Action<Vector2i>? OnEject;
public event Action<Vector2i>? OnRevoke;
private ISawmill Sawmill { get; init; }
public CP14DemiplaneMapWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
Sawmill = _log.GetSawmill("cp14_demiplane_map_window");
EjectButton.OnPressed += EjectPressed;
RevokeButton.OnPressed += RevokePressed;
GraphControl.OnOffsetChanged += offset =>
{
ParallaxBackground.Offset = -offset * 0.25f + new Vector2(1000, 1000); //hardcoding is bad
};
GraphControl.OnNodeSelected += SelectNode;
}
private void RevokePressed(BaseButton.ButtonEventArgs obj)
{
if (_selectedNode == null)
return;
if (_cachedState == null)
return;
foreach (var node in _cachedState.Nodes)
{
if (node.Value != _selectedNode)
continue;
OnRevoke?.Invoke(node.Key);
Close();
return;
}
}
private void EjectPressed(BaseButton.ButtonEventArgs obj)
{
if (_selectedNode == null)
return;
if (_cachedState == null)
return;
foreach (var node in _cachedState.Nodes)
{
if (node.Value != _selectedNode)
continue;
OnEject?.Invoke(node.Key);
Close();
return;
}
}
public void UpdateState(CP14DemiplaneMapUiState state)
{
_cachedState = state;
HashSet<CP14NodeTreeElement> nodeTreeElements = new();
foreach (var node in state.Nodes)
{
if (node.Value.Start)
{
var startElement = new CP14NodeTreeElement(
nodeKey: node.Key.ToString(),
gained: true,
active: false,
node.Value.UiPosition * 100,
icon: new SpriteSpecifier.Rsi(new ResPath("_CP14/Interface/NodeTree/demiplane_map.rsi"), "center"));
nodeTreeElements.Add(startElement);
}
else
{
_prototype.TryIndex(node.Value.LocationConfig, out var location);
var treeElement = new CP14NodeTreeElement(
nodeKey: node.Key.ToString(),
gained: node.Value.Completed,
active: node.Value.InFrontierZone || node.Value.Completed,
node.Value.UiPosition * 100,
icon: location?.Icon);
nodeTreeElements.Add(treeElement);
}
}
var edges = new HashSet<(string, string)>();
foreach (var edge in state.Edges)
{
edges.Add((edge.Item1.ToString(), edge.Item2.ToString()));
}
GraphControl.UpdateState(
new CP14NodeTreeUiState(
nodeTreeElements,
edges: edges,
frameIcon: new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/NodeTree/demiplane_map.rsi"),
"frame"),
hoveredIcon: new SpriteSpecifier.Rsi(
new ResPath("/Textures/_CP14/Interface/NodeTree/demiplane_map.rsi"),
"hovered"),
selectedIcon: new SpriteSpecifier.Rsi(
new ResPath("/Textures/_CP14/Interface/NodeTree/demiplane_map.rsi"),
"selected"),
learnedIcon: new SpriteSpecifier.Rsi(
new ResPath("/Textures/_CP14/Interface/NodeTree/demiplane_map.rsi"),
"learned"),
activeLineColor: new Color(172, 102, 190),
lineColor: new Color(83, 40, 121)
)
);
}
private void SelectNode(CP14NodeTreeElement? node)
{
if (node == null)
{
DeselectNode();
return;
}
if (_cachedState == null)
{
Sawmill.Error("Tried to select node without a cached state.");
return;
}
if (node.NodeKey.Trim('(', ')').Split(',') is { Length: 2 } parts
&& int.TryParse(parts[0], out var x)
&& int.TryParse(parts[1], out var y)
&& _cachedState.Nodes.TryGetValue(new Vector2i(x, y), out var mapNode))
{
SelectNode(mapNode);
}
else
{
Sawmill.Error($"Tried to select node {node.NodeKey} that doesn't exist in the map.");
DeselectNode();
}
}
private void SelectNode(CP14DemiplaneMapNode? node)
{
_selectedNode = node;
var isAdmin = _admin.IsAdmin();
if (node == null)
{
DeselectNode();
return;
}
if (_cachedState == null)
{
Sawmill.Error("Tried to select node without a cached state.");
return;
}
if (node.LocationConfig != null && _prototype.TryIndex(node.LocationConfig, out var location))
{
if (location.Name is not null)
Name.Text = Loc.GetString(location.Name);
//Generate description
HashSet<LocId> modifierNames = new();
foreach (var modifier in node.Modifiers)
{
if (!_prototype.TryIndex(modifier, out var indexedModifier))
continue;
if (indexedModifier.Name is null)
continue;
modifierNames.Add(indexedModifier.Name.Value);
}
var sb = new StringBuilder();
foreach (var name in modifierNames)
{
sb.Append("- " + Loc.GetString(name) + "\n");
}
sb.Append("\n");
if (!node.InFrontierZone && !node.Completed)
sb.Append(Loc.GetString("cp14-demiplane-map-status-blocked"));
else if (node.InFrontierZone && !node.InUsing)
sb.Append(Loc.GetString("cp14-demiplane-map-status-allowed"));
else if (node.InUsing)
sb.Append(Loc.GetString("cp14-demiplane-map-status-used"));
else if (node.Completed)
sb.Append(Loc.GetString("cp14-demiplane-map-status-scanned"));
sb.Append("\n \n");
if (node.AdditionalLevel > 0 && !node.Completed)
{
sb.Append(Loc.GetString("cp14-demiplane-map-add-level", ("count", node.AdditionalLevel))+"\n");
sb.Append(Loc.GetString("cp14-demiplane-map-add-level-tooltip")+"\n");
}
Description.Text = sb.ToString();
LocationView.Texture = location.Icon?.Frame0();
}
else
{
Name.Text = string.Empty;
Description.Text = string.Empty;
LocationView.Texture = null;
}
EjectButton.Disabled = !node.InFrontierZone || node.InUsing;
RevokeButton.Disabled = !node.InUsing;
//Admin part
AdminPanel.Visible = isAdmin;
var adminSb = new StringBuilder();
adminSb.Append("Modifiers: \n");
foreach (var modifier in node.Modifiers)
{
adminSb.Append("- " + Loc.GetString(modifier.Id) + "\n");
}
AdminDescription.Text = adminSb.ToString();
}
private void DeselectNode()
{
Name.Text = string.Empty;
Description.Text = string.Empty;
LocationView.Texture = null;
EjectButton.Disabled = true;
RevokeButton.Disabled = true;
}
}