using System.Numerics; using System.Text; using Content.Client._CP14.UserInterface.Systems.NodeTree; using Content.Client.Administration.Managers; using Content.Shared._CP14.Demiplane; using Robust.Client.AutoGenerated; using Robust.Client.Player; 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.Demiplane; [GenerateTypedNameReferences] public sealed partial class CP14DemiplaneMapWindow : DefaultWindow { [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly ILogManager _log = default!; [Dependency] private readonly IClientAdminManager _admin = default!; private CP14DemiplaneMapUiState? _cachedState; private ISawmill Sawmill { get; init; } public CP14DemiplaneMapWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); Sawmill = _log.GetSawmill("cp14_demiplane_map_window"); GraphControl.OnOffsetChanged += offset => { ParallaxBackground.Offset = -offset * 0.25f + new Vector2(1000, 1000); //hardcoding is bad }; GraphControl.OnNodeSelected += SelectNode; } public void UpdateState(CP14DemiplaneMapUiState state) { _cachedState = state; HashSet 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.Opened, active: node.Value.Opened, 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) { 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 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"); } Description.Text = sb.ToString(); LocationView.Texture = location.Icon?.Frame0(); } else { Name.Text = string.Empty; Description.Text = string.Empty; LocationView.Texture = null; } //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; } }