* PaintableAirlockComponent and AirlockGroupPrototype have been replaced * Slightly redesigned SprayPainterSystem for greater versatility * Added handling of changes to the appearance of doors and storages * PaintableGroup prototypes have been created * Generating tabs with styles in the UI * Fix error with undiscovered layer * Slight improvement * Removed unnecessary property * The category for `PaintableGroup` was allocated to a separate prototype so that the engine itself would check if the category existed * Added canisters, but repainting doesn't work * Added localization to styles * Fix sprite changing * Added the ability to paint canisters * slight ui improvement * Fix yamllinter errors * Fix test * The UI now remembers which tab was open * Fix build (?) * Rename * Charges have been added to the spray painter * Added a charge texture for the spray painter * Now spray painter can paint decals * Increased number of charges * Spawning dummy objects has been replaced by PrototypeManager * added a signature about the painting of the object * fix * Code commenting * Fix upstream * Update Content.Shared/SprayPainter/Components/SprayPainterAmmo.cs Co-authored-by: pathetic meowmeow <uhhadd@gmail.com> * review * Now decals can only be painted if the corresponding tab in the menu is open. * Fixed a bug with pipe and decal tabs not being remembered * Update EntityStorageVisualizerSystem.cs * record * loc * Cleanup * Revert electrified visuals * more cleanup, fix charges, del ammo4 * no empty file, remove meta component * closet exceptions, storage visualizer fixes * enable/disable decal through alt-verb * Fix missed merge conflicts * fix snap offset, button event handlers * simpler order, fix snap loc string * Remove PaintableViz.BaseRSI, no decal item, A-Z * State-respecting UI, BUI updates, FTL fixes * revert DecalPlacerWindow changes * revert unwanted changes, cleanup function order * Limit SprayPainterAmmo write access to AmmoSystem * Remove PaintedSystem * spray paint ammo lathe recipe, youtool listing * category as a list, groups as subtabs * Restore inhand copyright in meta.json * empty spray painter, recipe produces an empty one * allow alpha on spray painter decals * add comments * paintable wall lockers * Restrict painting more objects * Suggested event changes, event cleanup * component comments, fix ammo inhands * uncleanable decals, dirty styles on mapinit * organize paintables, separate emergency/closet grp * fix categories newline at EOF * airlock group whitespace cleanup * realphabetize * Clean up EntityStorageViz merge conflict markers * Apply requested changes * Apply suggestions from sowelipililimute's review Co-authored-by: pathetic meowmeow <uhhadd@gmail.com> * betrayal most foul * Remove members from EntityPaintedEvent * No emerg. group, steelsec to secure, locker/closet * Enable repainting the medical wall locker * comments, no flags on PaintableVisuals * Remove locked variants from closets/wall closets * removable decals * off value consistency * can't paint away those bones * fix precedence * Remove AirlockDepartment, AirlockGroup protos Both unused. * whitelist consistency re: ammo component * add standing emergency closet styles * alphabetize the spray painter listings --------- Co-authored-by: Ertanic <black.ikra.14@gmail.com> Co-authored-by: Эдуард <36124833+Ertanic@users.noreply.github.com> Co-authored-by: pathetic meowmeow <uhhadd@gmail.com>
175 lines
4.9 KiB
C#
175 lines
4.9 KiB
C#
using System.Numerics;
|
|
using Content.Client.Stylesheets;
|
|
using Content.Shared.Decals;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.UserInterface;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Client.SprayPainter.UI;
|
|
|
|
/// <summary>
|
|
/// Used to control decal painting parameters for the spray painter.
|
|
/// </summary>
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class SprayPainterDecals : Control
|
|
{
|
|
public Action<ProtoId<DecalPrototype>>? OnDecalSelected;
|
|
public Action<Color?>? OnColorChanged;
|
|
public Action<int>? OnAngleChanged;
|
|
public Action<bool>? OnSnapChanged;
|
|
|
|
private SpriteSystem? _sprite;
|
|
private string _selectedDecal = string.Empty;
|
|
private List<SprayPainterDecalEntry> _decals = [];
|
|
|
|
public SprayPainterDecals()
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
|
|
AddAngleButton.OnButtonUp += _ => AngleSpinBox.Value += 90;
|
|
SubAngleButton.OnButtonUp += _ => AngleSpinBox.Value -= 90;
|
|
SetZeroAngleButton.OnButtonUp += _ => AngleSpinBox.Value = 0;
|
|
AngleSpinBox.ValueChanged += args => OnAngleChanged?.Invoke(args.Value);
|
|
|
|
UseCustomColorCheckBox.OnPressed += UseCustomColorCheckBoxOnOnPressed;
|
|
SnapToTileCheckBox.OnPressed += SnapToTileCheckBoxOnOnPressed;
|
|
ColorSelector.OnColorChanged += OnColorSelected;
|
|
}
|
|
|
|
private void UseCustomColorCheckBoxOnOnPressed(BaseButton.ButtonEventArgs _)
|
|
{
|
|
OnColorChanged?.Invoke(UseCustomColorCheckBox.Pressed ? ColorSelector.Color : null);
|
|
UpdateColorButtons(UseCustomColorCheckBox.Pressed);
|
|
}
|
|
|
|
private void SnapToTileCheckBoxOnOnPressed(BaseButton.ButtonEventArgs _)
|
|
{
|
|
OnSnapChanged?.Invoke(SnapToTileCheckBox.Pressed);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the decal list.
|
|
/// </summary>
|
|
public void PopulateDecals(List<SprayPainterDecalEntry> decals, SpriteSystem sprite)
|
|
{
|
|
_sprite ??= sprite;
|
|
|
|
_decals = decals;
|
|
DecalsGrid.Children.Clear();
|
|
|
|
foreach (var decal in decals)
|
|
{
|
|
var button = new TextureButton()
|
|
{
|
|
TextureNormal = sprite.Frame0(decal.Sprite),
|
|
Name = decal.Name,
|
|
ToolTip = decal.Name,
|
|
Scale = new Vector2(2, 2),
|
|
};
|
|
button.OnPressed += DecalButtonOnPressed;
|
|
|
|
if (UseCustomColorCheckBox.Pressed)
|
|
{
|
|
button.Modulate = ColorSelector.Color;
|
|
}
|
|
|
|
if (_selectedDecal == decal.Name)
|
|
{
|
|
var panelContainer = new PanelContainer()
|
|
{
|
|
PanelOverride = new StyleBoxFlat()
|
|
{
|
|
BackgroundColor = StyleNano.ButtonColorDefault,
|
|
},
|
|
Children =
|
|
{
|
|
button,
|
|
},
|
|
};
|
|
DecalsGrid.AddChild(panelContainer);
|
|
}
|
|
else
|
|
{
|
|
DecalsGrid.AddChild(button);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnColorSelected(Color color)
|
|
{
|
|
if (!UseCustomColorCheckBox.Pressed)
|
|
return;
|
|
|
|
OnColorChanged?.Invoke(color);
|
|
|
|
UpdateColorButtons(UseCustomColorCheckBox.Pressed);
|
|
}
|
|
|
|
private void UpdateColorButtons(bool apply)
|
|
{
|
|
Color modulateColor = apply ? ColorSelector.Color : Color.White;
|
|
foreach (var button in DecalsGrid.Children)
|
|
{
|
|
switch (button)
|
|
{
|
|
case TextureButton:
|
|
button.Modulate = modulateColor;
|
|
break;
|
|
case PanelContainer panelContainer:
|
|
{
|
|
foreach (TextureButton textureButton in panelContainer.Children)
|
|
textureButton.Modulate = modulateColor;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DecalButtonOnPressed(BaseButton.ButtonEventArgs obj)
|
|
{
|
|
if (obj.Button.Name is not { } name)
|
|
return;
|
|
|
|
_selectedDecal = name;
|
|
OnDecalSelected?.Invoke(_selectedDecal);
|
|
|
|
if (_sprite is null)
|
|
return;
|
|
|
|
PopulateDecals(_decals, _sprite);
|
|
}
|
|
|
|
public void SetSelectedDecal(string name)
|
|
{
|
|
_selectedDecal = name;
|
|
|
|
if (_sprite is null)
|
|
return;
|
|
|
|
PopulateDecals(_decals, _sprite);
|
|
}
|
|
|
|
public void SetAngle(int degrees)
|
|
{
|
|
AngleSpinBox.OverrideValue(degrees);
|
|
}
|
|
|
|
public void SetColor(Color? color)
|
|
{
|
|
UseCustomColorCheckBox.Pressed = color != null;
|
|
if (color != null)
|
|
ColorSelector.Color = color.Value;
|
|
UpdateColorButtons(UseCustomColorCheckBox.Pressed);
|
|
}
|
|
|
|
public void SetSnap(bool snap)
|
|
{
|
|
SnapToTileCheckBox.Pressed = snap;
|
|
}
|
|
}
|