Merge branch 'master' into ed-04-08-2025-upstream-sync

This commit is contained in:
Red
2025-08-04 13:38:49 +03:00
committed by GitHub
144 changed files with 17364 additions and 370055 deletions

View File

@@ -1,7 +0,0 @@
using Content.Shared._CP14.DemiplaneTraveling;
namespace Content.Client._CP14.DemiplaneTraveling;
public sealed partial class CP14ClientStationDemiplaneMapSystem : CP14SharedStationDemiplaneMapSystem
{
}

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -1,5 +1,3 @@
using Content.Client._CP14.DemiplaneTraveling;
using Content.Shared._CP14.DemiplaneTraveling;
using Content.Shared._CP14.Religion.Systems;
using Robust.Client.UserInterface;

View File

@@ -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"