Pipe painter (now with airlock painter) (#19031)
* Add a pipe painting function to the airlock painter Signed-off-by: c4llv07e <kseandi@gmail.com> * Rename engineer painter to omnipainter Signed-off-by: c4llv07e <kseandi@gmail.com> * review changes Signed-off-by: c4llv07e <kseandi@gmail.com> * fix migration duplicate Signed-off-by: c4llv07e <kseandi@gmail.com> --------- Signed-off-by: c4llv07e <kseandi@gmail.com>
This commit is contained in:
53
Content.Client/SprayPainter/SprayPainterSystem.cs
Normal file
53
Content.Client/SprayPainter/SprayPainterSystem.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Content.Shared.SprayPainter;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Client.SprayPainter;
|
||||
|
||||
public sealed class SprayPainterSystem : SharedSprayPainterSystem
|
||||
{
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
|
||||
public List<SprayPainterEntry> Entries { get; private set; } = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
foreach (string style in Styles)
|
||||
{
|
||||
string? iconPath = Groups
|
||||
.FindAll(x => x.StylePaths.ContainsKey(style))?
|
||||
.MaxBy(x => x.IconPriority)?.StylePaths[style];
|
||||
if (iconPath == null)
|
||||
{
|
||||
Entries.Add(new SprayPainterEntry(style, null));
|
||||
continue;
|
||||
}
|
||||
|
||||
RSIResource doorRsi = _resourceCache.GetResource<RSIResource>(SpriteSpecifierSerializer.TextureRoot / new ResPath(iconPath));
|
||||
if (!doorRsi.RSI.TryGetState("closed", out var icon))
|
||||
{
|
||||
Entries.Add(new SprayPainterEntry(style, null));
|
||||
continue;
|
||||
}
|
||||
|
||||
Entries.Add(new SprayPainterEntry(style, icon.Frame0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SprayPainterEntry
|
||||
{
|
||||
public string Name;
|
||||
public Texture? Icon;
|
||||
|
||||
public SprayPainterEntry(string name, Texture? icon)
|
||||
{
|
||||
Name = name;
|
||||
Icon = icon;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Content.Shared.SprayPainter;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.SprayPainter.UI;
|
||||
|
||||
public sealed class SprayPainterBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[ViewVariables]
|
||||
private SprayPainterWindow? _window;
|
||||
|
||||
[ViewVariables]
|
||||
private SprayPainterSystem? _painter;
|
||||
|
||||
public SprayPainterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new SprayPainterWindow();
|
||||
|
||||
_painter = EntMan.System<SprayPainterSystem>();
|
||||
|
||||
_window.OpenCentered();
|
||||
_window.OnClose += Close;
|
||||
_window.OnSpritePicked = OnSpritePicked;
|
||||
_window.OnColorPicked = OnColorPicked;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
_window?.Dispose();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
if (_painter == null)
|
||||
return;
|
||||
|
||||
if (state is not SprayPainterBoundUserInterfaceState stateCast)
|
||||
return;
|
||||
|
||||
_window.Populate(_painter.Entries,
|
||||
stateCast.SelectedStyle,
|
||||
stateCast.SelectedColorKey,
|
||||
stateCast.Palette);
|
||||
}
|
||||
|
||||
private void OnSpritePicked(ItemList.ItemListSelectedEventArgs args)
|
||||
{
|
||||
SendMessage(new SprayPainterSpritePickedMessage(args.ItemIndex));
|
||||
}
|
||||
|
||||
private void OnColorPicked(ItemList.ItemListSelectedEventArgs args)
|
||||
{
|
||||
var key = _window?.IndexToColorKey(args.ItemIndex);
|
||||
SendMessage(new SprayPainterColorPickedMessage(key));
|
||||
}
|
||||
}
|
||||
34
Content.Client/SprayPainter/UI/SprayPainterWindow.xaml
Normal file
34
Content.Client/SprayPainter/UI/SprayPainterWindow.xaml
Normal file
@@ -0,0 +1,34 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
MinSize="500 300"
|
||||
SetSize="500 500"
|
||||
Title="{Loc 'spray-painter-window-title'}">
|
||||
<BoxContainer Orientation="Horizontal"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
SeparationOverride="4"
|
||||
MinWidth="450">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
SeparationOverride="4"
|
||||
MinWidth="200">
|
||||
<Label Name="SelectedSpriteLabel"
|
||||
Text="{Loc 'spray-painter-selected-style'}">
|
||||
</Label>
|
||||
<ItemList Name="SpriteList"
|
||||
SizeFlagsStretchRatio="8"
|
||||
VerticalExpand="True"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Vertical"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
SeparationOverride="4"
|
||||
MinWidth="200">
|
||||
<Label Name="SelectedColorLabel"
|
||||
Text="{Loc 'spray-painter-selected-color'}"/>
|
||||
<ItemList Name="ColorList"
|
||||
SizeFlagsStretchRatio="8"
|
||||
VerticalExpand="True"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
96
Content.Client/SprayPainter/UI/SprayPainterWindow.xaml.cs
Normal file
96
Content.Client/SprayPainter/UI/SprayPainterWindow.xaml.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.SprayPainter.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class SprayPainterWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
|
||||
private readonly SpriteSystem _spriteSystem;
|
||||
|
||||
public Action<ItemList.ItemListSelectedEventArgs>? OnSpritePicked;
|
||||
public Action<ItemList.ItemListSelectedEventArgs>? OnColorPicked;
|
||||
public Dictionary<string, int> ItemColorIndex = new();
|
||||
|
||||
private Dictionary<string, Color> currentPalette = new();
|
||||
private const string colorLocKeyPrefix = "pipe-painter-color-";
|
||||
private List<SprayPainterEntry> CurrentEntries = new List<SprayPainterEntry>();
|
||||
|
||||
private readonly SpriteSpecifier _colorEntryIconTexture = new SpriteSpecifier.Rsi(
|
||||
new ResPath("Structures/Piping/Atmospherics/pipe.rsi"),
|
||||
"pipeStraight");
|
||||
|
||||
public SprayPainterWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
_spriteSystem = _sysMan.GetEntitySystem<SpriteSystem>();
|
||||
}
|
||||
|
||||
private static string GetColorLocString(string? colorKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(colorKey))
|
||||
return Loc.GetString("pipe-painter-no-color-selected");
|
||||
var locKey = colorLocKeyPrefix + colorKey;
|
||||
|
||||
if (!Loc.TryGetString(locKey, out var locString))
|
||||
locString = colorKey;
|
||||
|
||||
return locString;
|
||||
}
|
||||
|
||||
public string? IndexToColorKey(int index)
|
||||
{
|
||||
return (string?) ColorList[index].Metadata;
|
||||
}
|
||||
|
||||
public void Populate(List<SprayPainterEntry> entries, int selectedStyle, string? selectedColorKey, Dictionary<string, Color> palette)
|
||||
{
|
||||
// Only clear if the entries change. Otherwise the list would "jump" after selecting an item
|
||||
if (!CurrentEntries.Equals(entries))
|
||||
{
|
||||
CurrentEntries = entries;
|
||||
SpriteList.Clear();
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
SpriteList.AddItem(entry.Name, entry.Icon);
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentPalette.Equals(palette))
|
||||
{
|
||||
currentPalette = palette;
|
||||
ItemColorIndex.Clear();
|
||||
ColorList.Clear();
|
||||
|
||||
foreach (var color in palette)
|
||||
{
|
||||
var locString = GetColorLocString(color.Key);
|
||||
var item = ColorList.AddItem(locString, _spriteSystem.Frame0(_colorEntryIconTexture));
|
||||
item.IconModulate = color.Value;
|
||||
item.Metadata = color.Key;
|
||||
|
||||
ItemColorIndex.Add(color.Key, ColorList.IndexOf(item));
|
||||
}
|
||||
}
|
||||
|
||||
// Disable event so we don't send a new event for pre-selectedStyle entry and end up in a loop
|
||||
|
||||
if (selectedColorKey != null)
|
||||
{
|
||||
var index = ItemColorIndex[selectedColorKey];
|
||||
ColorList.OnItemSelected -= OnColorPicked;
|
||||
ColorList[index].Selected = true;
|
||||
ColorList.OnItemSelected += OnColorPicked;
|
||||
}
|
||||
|
||||
SpriteList.OnItemSelected -= OnSpritePicked;
|
||||
SpriteList[selectedStyle].Selected = true;
|
||||
SpriteList.OnItemSelected += OnSpritePicked;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user