Merge branch 'master' into ed-04-08-2025-upstream-sync
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
|
||||
namespace Content.Client._CP14.DemiplaneTraveling;
|
||||
|
||||
public sealed partial class CP14ClientStationDemiplaneMapSystem : CP14SharedStationDemiplaneMapSystem
|
||||
{
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._CP14.DemiplaneTraveling;
|
||||
|
||||
public sealed class CP14DemiplaneMapBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private CP14DemiplaneMapWindow? _window;
|
||||
|
||||
public CP14DemiplaneMapBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<CP14DemiplaneMapWindow>();
|
||||
|
||||
_window.OnEject += pos => SendMessage(new CP14DemiplaneMapEjectMessage(pos));
|
||||
//_window.OnRevoke += pos => SendMessage(new CP14DemiplaneMapRevokeMessage(pos));
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (_window == null || state is not CP14DemiplaneMapUiState mapState)
|
||||
return;
|
||||
|
||||
_window?.UpdateState(mapState);
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
<demiplaneTraveling:CP14DemiplaneMapWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:parallax="clr-namespace:Content.Client.Parallax"
|
||||
xmlns:nodeTree="clr-namespace:Content.Client._CP14.UserInterface.Systems.NodeTree"
|
||||
xmlns:demiplaneTraveling="clr-namespace:Content.Client._CP14.DemiplaneTraveling"
|
||||
Title="{Loc 'cp14-demiplane-map-title'}"
|
||||
MinSize="1000 650"
|
||||
SetSize="1800 950">
|
||||
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True">
|
||||
<!-- Selected Location -->
|
||||
<BoxContainer Margin="10 10 10 10" MaxWidth="240" SetWidth="240" Orientation="Vertical"
|
||||
HorizontalExpand="False" VerticalExpand="True">
|
||||
<!-- Location View -->
|
||||
<PanelContainer Name="BackPanel" HorizontalAlignment="Center">
|
||||
<PanelContainer.PanelOverride>
|
||||
<graphics:StyleBoxTexture Modulate="#1B1B1E" PatchMarginBottom="10" PatchMarginLeft="10"
|
||||
PatchMarginRight="10" PatchMarginTop="10" />
|
||||
</PanelContainer.PanelOverride>
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True">
|
||||
<TextureRect Stretch="Scale" Name="LocationView" SetSize="64 64" HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" MinSize="64 64"
|
||||
HorizontalExpand="True" VerticalExpand="True" Access="Public" />
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
<customControls:HSeparator StyleClasses="HighDivider" Margin="0 15 0 10" />
|
||||
<!-- Location Data -->
|
||||
<BoxContainer Name="NodeViewContainer" Orientation="Vertical" VerticalExpand="True">
|
||||
<ScrollContainer HScrollEnabled="False" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="False" VerticalExpand="True">
|
||||
<BoxContainer Name="InfoContainer" Orientation="Vertical" HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Name="Name" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center"
|
||||
HorizontalExpand="True" HorizontalAlignment="Center" />
|
||||
</BoxContainer>
|
||||
<!-- Description -->
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<RichTextLabel Name="Description" HorizontalExpand="True" Access="Public" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
<Control MinHeight="5" />
|
||||
<!-- Buttons -->
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Button Name="EjectButton" Text="{Loc 'cp14-demiplane-map-eject'}"
|
||||
ToolTip="{Loc 'cp14-demiplane-map-eject-tooltip'}" StyleClasses="OpenRight"
|
||||
HorizontalExpand="True" MinHeight="35" Access="Public" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Button Name="RevokeButton" Text="{Loc 'cp14-demiplane-map-revoke'}"
|
||||
ToolTip="{Loc 'cp14-demiplane-map-revoke-tooltip'}" StyleClasses="OpenRight"
|
||||
HorizontalExpand="True" MinHeight="35" Access="Public" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<customControls:VSeparator StyleClasses="LowDivider" />
|
||||
|
||||
<!-- Demiplane map Tree -->
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Name="TreeName" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center"
|
||||
HorizontalExpand="True" HorizontalAlignment="Center" />
|
||||
</BoxContainer>
|
||||
<PanelContainer Margin="10 10 10 10" HorizontalExpand="True" VerticalExpand="True" RectClipContent="True">
|
||||
<parallax:ParallaxControl Name="ParallaxBackground" ScaleX="4" ScaleY="4"
|
||||
ParallaxPrototype="KettleStation" Access="Public" SpeedX="10" SpeedY="5" />
|
||||
<BoxContainer Margin="10 10 10 10" Orientation="Horizontal" HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<nodeTree:CP14NodeTreeGraphControl Name="GraphControl" HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" Access="Public" />
|
||||
</BoxContainer>
|
||||
<!-- Admin Description -->
|
||||
<BoxContainer Name="AdminPanel" Visible="False" HorizontalExpand="True" HorizontalAlignment="Right" VerticalAlignment="Top">
|
||||
<RichTextLabel Name="AdminDescription" HorizontalExpand="True" Access="Public" />
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</demiplaneTraveling:CP14DemiplaneMapWindow>
|
||||
@@ -1,266 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
using Content.Client._CP14.DemiplaneTraveling;
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
<customControls:VSeparator StyleClasses="LowDivider" />
|
||||
|
||||
<!-- Demiplane map Tree -->
|
||||
<!-- Trading positions map Tree -->
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Name="TreeName" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center"
|
||||
|
||||
Reference in New Issue
Block a user