Improve paper stamping experience (#17135)
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using Content.Client.Eui;
|
using Content.Client.Eui;
|
||||||
using Content.Shared.Eui;
|
using Content.Shared.Eui;
|
||||||
using Content.Shared.Fax;
|
using Content.Shared.Fax;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -15,7 +15,8 @@ public sealed class AdminFaxEui : BaseEui
|
|||||||
_window = new AdminFaxWindow();
|
_window = new AdminFaxWindow();
|
||||||
_window.OnClose += () => SendMessage(new AdminFaxEuiMsg.Close());
|
_window.OnClose += () => SendMessage(new AdminFaxEuiMsg.Close());
|
||||||
_window.OnFollowFax += uid => SendMessage(new AdminFaxEuiMsg.Follow(uid));
|
_window.OnFollowFax += uid => SendMessage(new AdminFaxEuiMsg.Follow(uid));
|
||||||
_window.OnMessageSend += args => SendMessage(new AdminFaxEuiMsg.Send(args.uid, args.title, args.from, args.message, args.stamp));
|
_window.OnMessageSend += args => SendMessage(new AdminFaxEuiMsg.Send(args.uid, args.title,
|
||||||
|
args.stampedBy, args.message, args.stampSprite, args.stampColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Opened()
|
public override void Opened()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<DefaultWindow xmlns="https://spacestation14.io"
|
<DefaultWindow xmlns="https://spacestation14.io"
|
||||||
Title="{Loc admin-fax-title}"
|
Title="{Loc admin-fax-title}"
|
||||||
MinWidth="400">
|
MinWidth="400">
|
||||||
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
<Control MinWidth="5" />
|
<Control MinWidth="5" />
|
||||||
<OptionButton Name="StampSelector" HorizontalExpand="True" />
|
<OptionButton Name="StampSelector" HorizontalExpand="True" />
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
|
<Label Text="{Loc admin-fax-stamp-color}" />
|
||||||
|
<ColorSelectorSliders Margin="12 0 0 0" Name="StampColorSelector" Color="#BB3232"/>
|
||||||
<Control MinHeight="10" />
|
<Control MinHeight="10" />
|
||||||
<Button Name="SendButton" Text="{Loc admin-fax-send}"></Button>
|
<Button Name="SendButton" Text="{Loc admin-fax-send}"></Button>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Content.Shared.Fax;
|
using Content.Shared.Fax;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.ResourceManagement;
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
@@ -13,7 +13,7 @@ public sealed partial class AdminFaxWindow : DefaultWindow
|
|||||||
{
|
{
|
||||||
private const string StampsRsiPath = "/Textures/Objects/Misc/bureaucracy.rsi";
|
private const string StampsRsiPath = "/Textures/Objects/Misc/bureaucracy.rsi";
|
||||||
|
|
||||||
public Action<(EntityUid uid, string title, string from, string message, string stamp)>? OnMessageSend;
|
public Action<(EntityUid uid, string title, string stampedBy, string message, string stampSprite, Color stampColor)>? OnMessageSend;
|
||||||
public Action<EntityUid>? OnFollowFax;
|
public Action<EntityUid>? OnFollowFax;
|
||||||
|
|
||||||
public AdminFaxWindow()
|
public AdminFaxWindow()
|
||||||
@@ -28,6 +28,9 @@ public sealed partial class AdminFaxWindow : DefaultWindow
|
|||||||
FollowButton.OnPressed += FollowFax;
|
FollowButton.OnPressed += FollowFax;
|
||||||
SendButton.OnPressed += SendMessage;
|
SendButton.OnPressed += SendMessage;
|
||||||
|
|
||||||
|
// Don't use this, but ColorSelectorSliders requires it:
|
||||||
|
StampColorSelector.OnColorChanged += (Color) => {};
|
||||||
|
|
||||||
var loc = IoCManager.Resolve<ILocalizationManager>();
|
var loc = IoCManager.Resolve<ILocalizationManager>();
|
||||||
MessageEdit.Placeholder = new Rope.Leaf(loc.GetString("admin-fax-message-placeholder")); // TextEdit work only with Nodes
|
MessageEdit.Placeholder = new Rope.Leaf(loc.GetString("admin-fax-message-placeholder")); // TextEdit work only with Nodes
|
||||||
}
|
}
|
||||||
@@ -90,6 +93,7 @@ public sealed partial class AdminFaxWindow : DefaultWindow
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var from = FromEdit.Text;
|
var from = FromEdit.Text;
|
||||||
OnMessageSend?.Invoke((faxUid.Value, title, from, message, stamp));
|
var stampColor = StampColorSelector.Color;
|
||||||
|
OnMessageSend?.Invoke((faxUid.Value, title, from, message, stamp, stampColor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,67 +5,66 @@ using Robust.Shared.Input;
|
|||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using static Content.Shared.Paper.SharedPaperComponent;
|
using static Content.Shared.Paper.SharedPaperComponent;
|
||||||
|
|
||||||
namespace Content.Client.Paper.UI
|
namespace Content.Client.Paper.UI;
|
||||||
|
|
||||||
|
[UsedImplicitly]
|
||||||
|
public sealed class PaperBoundUserInterface : BoundUserInterface
|
||||||
{
|
{
|
||||||
[UsedImplicitly]
|
[ViewVariables]
|
||||||
public sealed class PaperBoundUserInterface : BoundUserInterface
|
private PaperWindow? _window;
|
||||||
|
|
||||||
|
public PaperBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
}
|
||||||
private PaperWindow? _window;
|
|
||||||
|
|
||||||
public PaperBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
protected override void Open()
|
||||||
|
{
|
||||||
|
base.Open();
|
||||||
|
|
||||||
|
_window = new PaperWindow();
|
||||||
|
_window.OnClose += Close;
|
||||||
|
_window.Input.OnKeyBindDown += args => // Solution while TextEdit don't have events
|
||||||
{
|
{
|
||||||
}
|
if (args.Function == EngineKeyFunctions.TextSubmit)
|
||||||
|
|
||||||
protected override void Open()
|
|
||||||
{
|
|
||||||
base.Open();
|
|
||||||
|
|
||||||
_window = new PaperWindow();
|
|
||||||
_window.OnClose += Close;
|
|
||||||
_window.Input.OnKeyBindDown += args => // Solution while TextEdit don't have events
|
|
||||||
{
|
{
|
||||||
if (args.Function == EngineKeyFunctions.TextSubmit)
|
var text = Rope.Collapse(_window.Input.TextRope);
|
||||||
{
|
Input_OnTextEntered(text);
|
||||||
var text = Rope.Collapse(_window.Input.TextRope);
|
args.Handle();
|
||||||
Input_OnTextEntered(text);
|
|
||||||
args.Handle();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (EntMan.TryGetComponent<PaperVisualsComponent>(Owner, out var visuals))
|
|
||||||
{
|
|
||||||
_window.InitVisuals(visuals);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
_window.OpenCentered();
|
if (EntMan.TryGetComponent<PaperVisualsComponent>(Owner, out var visuals))
|
||||||
|
{
|
||||||
|
_window.InitVisuals(Owner, visuals);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateState(BoundUserInterfaceState state)
|
_window.OpenCentered();
|
||||||
{
|
}
|
||||||
base.UpdateState(state);
|
|
||||||
_window?.Populate((PaperBoundUserInterfaceState) state);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Input_OnTextEntered(string text)
|
protected override void UpdateState(BoundUserInterfaceState state)
|
||||||
|
{
|
||||||
|
base.UpdateState(state);
|
||||||
|
_window?.Populate((PaperBoundUserInterfaceState) state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Input_OnTextEntered(string text)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(text))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(text))
|
SendMessage(new PaperInputTextMessage(text));
|
||||||
|
|
||||||
|
if (_window != null)
|
||||||
{
|
{
|
||||||
SendMessage(new PaperInputTextMessage(text));
|
_window.Input.TextRope = Rope.Leaf.Empty;
|
||||||
|
_window.Input.CursorPosition = new TextEdit.CursorPos(0, TextEdit.LineBreakBias.Top);
|
||||||
if (_window != null)
|
|
||||||
{
|
|
||||||
_window.Input.TextRope = Rope.Leaf.Empty;
|
|
||||||
_window.Input.CursorPosition = new TextEdit.CursorPos(0, TextEdit.LineBreakBias.Top);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
protected override void Dispose(bool disposing)
|
||||||
base.Dispose(disposing);
|
{
|
||||||
if (!disposing) return;
|
base.Dispose(disposing);
|
||||||
_window?.Dispose();
|
if (!disposing) return;
|
||||||
}
|
_window?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
<TextEdit Name="Input" StyleClasses="PaperLineEdit" Access="Public" />
|
<TextEdit Name="Input" StyleClasses="PaperLineEdit" Access="Public" />
|
||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
<BoxContainer Name="StampDisplay" Orientation="Vertical" VerticalAlignment="Bottom" Margin="6"/>
|
<paper:StampCollection Name="StampDisplay" VerticalAlignment="Bottom" Margin="6"/>
|
||||||
|
|
||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
|
|||||||
@@ -44,8 +44,11 @@ namespace Content.Client.Paper.UI
|
|||||||
/// Initialize this UI according to <code>visuals</code> Initializes
|
/// Initialize this UI according to <code>visuals</code> Initializes
|
||||||
/// textures, recalculates sizes, and applies some layout rules.
|
/// textures, recalculates sizes, and applies some layout rules.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void InitVisuals(PaperVisualsComponent visuals)
|
public void InitVisuals(EntityUid entity, PaperVisualsComponent visuals)
|
||||||
{
|
{
|
||||||
|
// Randomize the placement of any stamps based on the entity UID
|
||||||
|
// so that there's some variety in different papers.
|
||||||
|
StampDisplay.PlacementSeed = (int)entity;
|
||||||
var resCache = IoCManager.Resolve<IResourceCache>();
|
var resCache = IoCManager.Resolve<IResourceCache>();
|
||||||
|
|
||||||
// Initialize the background:
|
// Initialize the background:
|
||||||
@@ -206,9 +209,10 @@ namespace Content.Client.Paper.UI
|
|||||||
BlankPaperIndicator.Visible = !isEditing && state.Text.Length == 0;
|
BlankPaperIndicator.Visible = !isEditing && state.Text.Length == 0;
|
||||||
|
|
||||||
StampDisplay.RemoveAllChildren();
|
StampDisplay.RemoveAllChildren();
|
||||||
|
StampDisplay.RemoveStamps();
|
||||||
foreach(var stamper in state.StampedBy)
|
foreach(var stamper in state.StampedBy)
|
||||||
{
|
{
|
||||||
StampDisplay.AddChild(new StampWidget{ Stamper = stamper });
|
StampDisplay.AddStamp(new StampWidget{ StampInfo = stamper });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +224,7 @@ namespace Content.Client.Paper.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected override DragMode GetDragModeFor(Vector2 relativeMousePos)
|
protected override DragMode GetDragModeFor(Vector2 relativeMousePos)
|
||||||
{
|
{
|
||||||
var mode = DragMode.Move;
|
var mode = DragMode.None;
|
||||||
|
|
||||||
// Be quite generous with resize margins:
|
// Be quite generous with resize margins:
|
||||||
if (relativeMousePos.Y < DRAG_MARGIN_SIZE)
|
if (relativeMousePos.Y < DRAG_MARGIN_SIZE)
|
||||||
@@ -241,6 +245,10 @@ namespace Content.Client.Paper.UI
|
|||||||
mode |= DragMode.Right;
|
mode |= DragMode.Right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((mode & _allowedResizeModes) == DragMode.None)
|
||||||
|
{
|
||||||
|
return DragMode.Move;
|
||||||
|
}
|
||||||
return mode & _allowedResizeModes;
|
return mode & _allowedResizeModes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
Content.Client/Paper/UI/StampCollection.xaml
Normal file
5
Content.Client/Paper/UI/StampCollection.xaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<paper:StampCollection xmlns="https://spacestation14.io"
|
||||||
|
xmlns:paper="clr-namespace:Content.Client.Paper.UI"
|
||||||
|
MinSize="150 150">
|
||||||
|
|
||||||
|
</paper:StampCollection>
|
||||||
98
Content.Client/Paper/UI/StampCollection.xaml.cs
Normal file
98
Content.Client/Paper/UI/StampCollection.xaml.cs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Client.Paper.UI;
|
||||||
|
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public sealed partial class StampCollection : Container
|
||||||
|
{
|
||||||
|
private List<StampWidget> _stamps = new();
|
||||||
|
|
||||||
|
/// Seed for random number generator to place stamps deterministically
|
||||||
|
public int PlacementSeed;
|
||||||
|
|
||||||
|
public StampCollection()
|
||||||
|
{
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove any stamps from the page
|
||||||
|
/// </summary>
|
||||||
|
public void RemoveStamps()
|
||||||
|
{
|
||||||
|
_stamps.Clear();
|
||||||
|
InvalidateArrange();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a stamp to the display; will perform
|
||||||
|
/// automatic layout.
|
||||||
|
/// </summary>
|
||||||
|
public void AddStamp(StampWidget s)
|
||||||
|
{
|
||||||
|
_stamps.Add(s);
|
||||||
|
AddChild(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Vector2 ArrangeOverride(Vector2 finalSize)
|
||||||
|
{
|
||||||
|
var random = new Random(PlacementSeed);
|
||||||
|
var r = (finalSize * 0.5f).Length();
|
||||||
|
var dtheta = -MathHelper.DegreesToRadians(90);
|
||||||
|
var theta0 = random.Next(0, 3) * dtheta;
|
||||||
|
var thisCenter = PixelSizeBox.TopLeft + finalSize * UIScale * 0.5f;
|
||||||
|
|
||||||
|
// Here's where we lay out the stamps. The first stamp goes in the
|
||||||
|
// center of this container; subsequent stamps will chose an angle
|
||||||
|
// (theta) to place the center of the stamp. The stamp is moved out
|
||||||
|
// as far as it can in that direction, taking the size and
|
||||||
|
// orientation of the stamp into account.
|
||||||
|
for (var i = 0; i < _stamps.Count; i++)
|
||||||
|
{
|
||||||
|
var stampOrientation = MathHelper.DegreesToRadians((random.NextFloat() - 0.5f) * 10.0f) ;
|
||||||
|
_stamps[i].Orientation = stampOrientation;
|
||||||
|
|
||||||
|
var theta = theta0 + dtheta * 0.5f + dtheta * i + (i > 4 ? MathF.Log(1 + i / 4) * dtheta : 0); // There is probably a better way to lay these out, to minimize overlaps
|
||||||
|
var childCenterOnCircle = thisCenter;
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
// First stamp can go in the center. Subsequent stamps have to find space.
|
||||||
|
childCenterOnCircle += new Vector2(MathF.Cos(theta), MathF.Sin(theta)) * r * UIScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
var childHeLocal = _stamps[i].DesiredPixelSize * 0.5f;
|
||||||
|
var c = childHeLocal * MathF.Abs(MathF.Cos(stampOrientation));
|
||||||
|
var s = childHeLocal * MathF.Abs(MathF.Sin(stampOrientation));
|
||||||
|
var childHePage = new Vector2(c.X + s.Y, s.X + c.Y);
|
||||||
|
var controlBox = new UIBox2(PixelSizeBox.TopLeft, PixelSizeBox.TopLeft + finalSize * UIScale);
|
||||||
|
var clampedCenter = Clamp(Shrink(controlBox, childHePage), childCenterOnCircle);
|
||||||
|
var finalPosition = clampedCenter - childHePage;
|
||||||
|
var finalPositionAsInt = new Vector2i((int)finalPosition.X, (int)finalPosition.Y);
|
||||||
|
_stamps[i].ArrangePixel(new UIBox2i(finalPositionAsInt, finalPositionAsInt + _stamps[i].DesiredPixelSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shrink a UIBox2 by a half extents, moving both the top-left and
|
||||||
|
/// bottom-right closer together.
|
||||||
|
/// </summary>
|
||||||
|
private UIBox2 Shrink(UIBox2 box, Vector2 shrinkHe)
|
||||||
|
{
|
||||||
|
return new UIBox2(box.TopLeft + shrinkHe, box.BottomRight - shrinkHe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the input vector clamped to be within the UIBox
|
||||||
|
/// </summary>
|
||||||
|
private Vector2 Clamp(UIBox2 box, Vector2 point)
|
||||||
|
{
|
||||||
|
return Vector2.Min(box.BottomRight, Vector2.Max(box.TopLeft, point));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
2
Content.Client/Paper/UI/StampLabel.xaml
Normal file
2
Content.Client/Paper/UI/StampLabel.xaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<paper:StampLabel xmlns="https://spacestation14.io"
|
||||||
|
xmlns:paper="clr-namespace:Content.Client.Paper.UI" />
|
||||||
56
Content.Client/Paper/UI/StampLabel.xaml.cs
Normal file
56
Content.Client/Paper/UI/StampLabel.xaml.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Client.Paper.UI;
|
||||||
|
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public sealed partial class StampLabel : Label
|
||||||
|
{
|
||||||
|
/// A scale that's applied to the text to ensure it
|
||||||
|
/// fits in the allowed space.
|
||||||
|
private Vector2 _textScaling = Vector2.One;
|
||||||
|
|
||||||
|
/// Shader used to draw the stamps
|
||||||
|
private ShaderInstance? _stampShader;
|
||||||
|
|
||||||
|
/// Allows an additional orientation to be applied to
|
||||||
|
/// this control.
|
||||||
|
public float Orientation = 0.0f;
|
||||||
|
|
||||||
|
public StampLabel()
|
||||||
|
{
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
|
||||||
|
var prototypes = IoCManager.Resolve<IPrototypeManager>();
|
||||||
|
_stampShader = prototypes.Index<ShaderPrototype>("PaperStamp").InstanceUnique();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Vector2 MeasureOverride(Vector2 availableSize)
|
||||||
|
{
|
||||||
|
var desiredTextSize = base.MeasureOverride(availableSize);
|
||||||
|
var clampedScale = Vector2.Min(availableSize / desiredTextSize, Vector2.One);
|
||||||
|
var keepAspectRatio = MathF.Min(clampedScale.X, clampedScale.Y);
|
||||||
|
const float shimmerReduction = 0.1f;
|
||||||
|
_textScaling = Vector2.One * MathF.Round(keepAspectRatio / shimmerReduction) * shimmerReduction;
|
||||||
|
return desiredTextSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
var offset = new Vector2(PixelPosition.X * MathF.Cos(Orientation) - PixelPosition.Y * MathF.Sin(Orientation),
|
||||||
|
PixelPosition.Y * MathF.Cos(Orientation) + PixelPosition.X * MathF.Sin(Orientation));
|
||||||
|
|
||||||
|
_stampShader?.SetParameter("objCoord", GlobalPosition * UIScale * new Vector2(1, -1));
|
||||||
|
handle.UseShader(_stampShader);
|
||||||
|
handle.SetTransform(GlobalPixelPosition - PixelPosition + offset, Orientation, _textScaling);
|
||||||
|
base.Draw(handle);
|
||||||
|
|
||||||
|
// Restore a sane transform+shader
|
||||||
|
handle.SetTransform(Matrix3.Identity);
|
||||||
|
handle.UseShader(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,22 +4,7 @@
|
|||||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||||
xmlns:paper="clr-namespace:Content.Client.Paper.UI" HorizontalAlignment="Center" Margin="6">
|
xmlns:paper="clr-namespace:Content.Client.Paper.UI" HorizontalAlignment="Center" Margin="6">
|
||||||
|
|
||||||
<BoxContainer Orientation="Vertical">
|
<paper:StampLabel Name="StampedByLabel" StyleClasses="LabelHeadingBigger"
|
||||||
<PanelContainer>
|
FontColorOverride="{x:Static style:StyleNano.DangerousRedFore}"
|
||||||
<PanelContainer.PanelOverride>
|
Margin="12 6 12 6"/>
|
||||||
<gfx:StyleBoxFlat BackgroundColor="{x:Static style:StyleNano.DangerousRedFore}" />
|
|
||||||
</PanelContainer.PanelOverride>
|
|
||||||
<Control MinSize="3 3" />
|
|
||||||
</PanelContainer>
|
|
||||||
|
|
||||||
<Label Name="StampedByLabel" StyleClasses="LabelHeadingBigger" FontColorOverride="{x:Static style:StyleNano.DangerousRedFore}" Margin="12 6 12 6"/>
|
|
||||||
|
|
||||||
<PanelContainer>
|
|
||||||
<PanelContainer.PanelOverride>
|
|
||||||
<gfx:StyleBoxFlat BackgroundColor="{x:Static style:StyleNano.DangerousRedFore}" />
|
|
||||||
</PanelContainer.PanelOverride>
|
|
||||||
<Control MinSize="3 3" />
|
|
||||||
</PanelContainer>
|
|
||||||
|
|
||||||
</BoxContainer>
|
|
||||||
</paper:StampWidget>
|
</paper:StampWidget>
|
||||||
|
|||||||
@@ -1,23 +1,59 @@
|
|||||||
|
using System.Numerics;
|
||||||
using Content.Shared.Paper;
|
using Content.Shared.Paper;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Client.Paper.UI
|
namespace Content.Client.Paper.UI;
|
||||||
|
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public sealed partial class StampWidget : PanelContainer
|
||||||
{
|
{
|
||||||
[GenerateTypedNameReferences]
|
private StyleBoxTexture _borderTexture;
|
||||||
public sealed partial class StampWidget : Container
|
private ShaderInstance? _stampShader;
|
||||||
{
|
|
||||||
public string? Stamper {
|
|
||||||
get => StampedByLabel.Text;
|
|
||||||
set => StampedByLabel.Text = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StampWidget()
|
public float Orientation
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
get => StampedByLabel.Orientation;
|
||||||
|
set => StampedByLabel.Orientation = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StampDisplayInfo StampInfo {
|
||||||
|
set {
|
||||||
|
StampedByLabel.Text = Loc.GetString(value.StampedName);
|
||||||
|
StampedByLabel.FontColorOverride = value.StampedColor;
|
||||||
|
ModulateSelfOverride = value.StampedColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StampWidget()
|
||||||
|
{
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
var resCache = IoCManager.Resolve<IResourceCache>();
|
||||||
|
var borderImage = resCache.GetResource<TextureResource>(
|
||||||
|
"/Textures/Interface/Paper/paper_stamp_border.svg.96dpi.png");
|
||||||
|
_borderTexture = new StyleBoxTexture {
|
||||||
|
Texture = borderImage,
|
||||||
|
};
|
||||||
|
_borderTexture.SetPatchMargin(StyleBoxTexture.Margin.All, 7.0f);
|
||||||
|
PanelOverride = _borderTexture;
|
||||||
|
|
||||||
|
var prototypes = IoCManager.Resolve<IPrototypeManager>();
|
||||||
|
_stampShader = prototypes.Index<ShaderPrototype>("PaperStamp").InstanceUnique();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
_stampShader?.SetParameter("objCoord", GlobalPosition * UIScale * new Vector2(1, -1));
|
||||||
|
handle.UseShader(_stampShader);
|
||||||
|
handle.SetTransform(GlobalPosition * UIScale, Orientation, Vector2.One);
|
||||||
|
base.Draw(handle);
|
||||||
|
|
||||||
|
// Restore a sane transform+shader
|
||||||
|
handle.SetTransform(Matrix3.Identity);
|
||||||
|
handle.UseShader(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
using Content.Server.DeviceNetwork.Components;
|
using Content.Server.DeviceNetwork.Components;
|
||||||
using Content.Server.EUI;
|
using Content.Server.EUI;
|
||||||
using Content.Server.Ghost.Components;
|
using Content.Server.Ghost.Components;
|
||||||
using Content.Shared.Eui;
|
using Content.Shared.Eui;
|
||||||
using Content.Shared.Fax;
|
using Content.Shared.Fax;
|
||||||
using Content.Shared.Follower;
|
using Content.Shared.Follower;
|
||||||
|
using Content.Shared.Paper;
|
||||||
|
|
||||||
namespace Content.Server.Fax.AdminUI;
|
namespace Content.Server.Fax.AdminUI;
|
||||||
|
|
||||||
@@ -53,7 +54,8 @@ public sealed class AdminFaxEui : BaseEui
|
|||||||
}
|
}
|
||||||
case AdminFaxEuiMsg.Send sendData:
|
case AdminFaxEuiMsg.Send sendData:
|
||||||
{
|
{
|
||||||
var printout = new FaxPrintout(sendData.Content, sendData.Title, null, sendData.StampState, new() { sendData.From });
|
var printout = new FaxPrintout(sendData.Content, sendData.Title, null, sendData.StampState,
|
||||||
|
new() { new StampDisplayInfo { StampedName = sendData.From, StampedColor = sendData.StampColor } });
|
||||||
_faxSystem.Receive(sendData.Target, printout);
|
_faxSystem.Receive(sendData.Target, printout);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Shared.Containers.ItemSlots;
|
using Content.Shared.Containers.ItemSlots;
|
||||||
|
using Content.Shared.Paper;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
@@ -136,18 +137,18 @@ public sealed class FaxPrintout
|
|||||||
public string? StampState { get; }
|
public string? StampState { get; }
|
||||||
|
|
||||||
[DataField("stampedBy")]
|
[DataField("stampedBy")]
|
||||||
public List<string> StampedBy { get; } = new();
|
public List<StampDisplayInfo> StampedBy { get; } = new();
|
||||||
|
|
||||||
private FaxPrintout()
|
private FaxPrintout()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public FaxPrintout(string content, string name, string? prototypeId = null, string? stampState = null, List<string>? stampedBy = null)
|
public FaxPrintout(string content, string name, string? prototypeId = null, string? stampState = null, List<StampDisplayInfo>? stampedBy = null)
|
||||||
{
|
{
|
||||||
Content = content;
|
Content = content;
|
||||||
Name = name;
|
Name = name;
|
||||||
PrototypeId = prototypeId ?? "";
|
PrototypeId = prototypeId ?? "";
|
||||||
StampState = stampState;
|
StampState = stampState;
|
||||||
StampedBy = stampedBy ?? new List<string>();
|
StampedBy = stampedBy ?? new List<StampDisplayInfo>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using Content.Shared.Emag.Components;
|
|||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Fax;
|
using Content.Shared.Fax;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Paper;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
@@ -272,7 +273,7 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
args.Data.TryGetValue(FaxConstants.FaxPaperStampStateData, out string? stampState);
|
args.Data.TryGetValue(FaxConstants.FaxPaperStampStateData, out string? stampState);
|
||||||
args.Data.TryGetValue(FaxConstants.FaxPaperStampedByData, out List<string>? stampedBy);
|
args.Data.TryGetValue(FaxConstants.FaxPaperStampedByData, out List<StampDisplayInfo>? stampedBy);
|
||||||
args.Data.TryGetValue(FaxConstants.FaxPaperPrototypeData, out string? prototypeId);
|
args.Data.TryGetValue(FaxConstants.FaxPaperPrototypeData, out string? prototypeId);
|
||||||
|
|
||||||
var printout = new FaxPrintout(content, name, prototypeId, stampState, stampedBy);
|
var printout = new FaxPrintout(content, name, prototypeId, stampState, stampedBy);
|
||||||
@@ -461,9 +462,9 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
// Apply stamps
|
// Apply stamps
|
||||||
if (printout.StampState != null)
|
if (printout.StampState != null)
|
||||||
{
|
{
|
||||||
foreach (var stampedBy in printout.StampedBy)
|
foreach (var stamp in printout.StampedBy)
|
||||||
{
|
{
|
||||||
_paperSystem.TryStamp(printed, stampedBy, printout.StampState);
|
_paperSystem.TryStamp(printed, stamp, printout.StampState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Server.Fax;
|
|||||||
using Content.Server.Paper;
|
using Content.Server.Paper;
|
||||||
using Content.Server.Station.Components;
|
using Content.Server.Station.Components;
|
||||||
using Content.Server.Station.Systems;
|
using Content.Server.Station.Systems;
|
||||||
|
using Content.Shared.Paper;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
@@ -66,7 +67,11 @@ namespace Content.Server.Nuke
|
|||||||
Loc.GetString("nuke-codes-fax-paper-name"),
|
Loc.GetString("nuke-codes-fax-paper-name"),
|
||||||
null,
|
null,
|
||||||
"paper_stamp-centcom",
|
"paper_stamp-centcom",
|
||||||
new() { Loc.GetString("stamp-component-stamped-name-centcom") });
|
new List<StampDisplayInfo>
|
||||||
|
{
|
||||||
|
new StampDisplayInfo { StampedName = Loc.GetString("stamp-component-stamped-name-centcom"), StampedColor = Color.FromHex("#BB3232") },
|
||||||
|
}
|
||||||
|
);
|
||||||
_faxSystem.Receive(faxEnt, printout, null, fax);
|
_faxSystem.Receive(faxEnt, printout, null, fax);
|
||||||
|
|
||||||
wasSent = true;
|
wasSent = true;
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
using Content.Shared.Paper;
|
using Content.Shared.Paper;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
namespace Content.Server.Paper
|
namespace Content.Server.Paper;
|
||||||
|
|
||||||
|
[NetworkedComponent, RegisterComponent]
|
||||||
|
public sealed class PaperComponent : SharedPaperComponent
|
||||||
{
|
{
|
||||||
[NetworkedComponent, RegisterComponent]
|
public PaperAction Mode;
|
||||||
public sealed class PaperComponent : SharedPaperComponent
|
[DataField("content")]
|
||||||
{
|
public string Content { get; set; } = "";
|
||||||
public PaperAction Mode;
|
|
||||||
[DataField("content")]
|
|
||||||
public string Content { get; set; } = "";
|
|
||||||
|
|
||||||
[DataField("contentSize")]
|
[DataField("contentSize")]
|
||||||
public int ContentSize { get; set; } = 6000;
|
public int ContentSize { get; set; } = 6000;
|
||||||
|
|
||||||
[DataField("stampedBy")]
|
[DataField("stampedBy")]
|
||||||
public List<string> StampedBy { get; set; } = new();
|
public List<StampDisplayInfo> StampedBy { get; set; } = new();
|
||||||
/// <summary>
|
|
||||||
/// Stamp to be displayed on the paper, state from beauracracy.rsi
|
/// <summary>
|
||||||
/// </summary>
|
/// Stamp to be displayed on the paper, state from beauracracy.rsi
|
||||||
[DataField("stampState")]
|
/// </summary>
|
||||||
public string? StampState { get; set; }
|
[DataField("stampState")]
|
||||||
}
|
public string? StampState { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Linq;
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Server.UserInterface;
|
using Content.Server.UserInterface;
|
||||||
@@ -90,7 +91,7 @@ namespace Content.Server.Paper
|
|||||||
|
|
||||||
if (paperComp.StampedBy.Count > 0)
|
if (paperComp.StampedBy.Count > 0)
|
||||||
{
|
{
|
||||||
var commaSeparated = string.Join(", ", paperComp.StampedBy);
|
var commaSeparated = string.Join(", ", paperComp.StampedBy.Select(s => Loc.GetString(s.StampedName)));
|
||||||
args.PushMarkup(
|
args.PushMarkup(
|
||||||
Loc.GetString(
|
Loc.GetString(
|
||||||
"paper-component-examine-detail-stamped-by", ("paper", uid), ("stamps", commaSeparated))
|
"paper-component-examine-detail-stamped-by", ("paper", uid), ("stamps", commaSeparated))
|
||||||
@@ -114,13 +115,15 @@ namespace Content.Server.Paper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a stamp, attempt to stamp paper
|
// If a stamp, attempt to stamp paper
|
||||||
if (TryComp<StampComponent>(args.Used, out var stampComp) && TryStamp(uid, stampComp.StampedName, stampComp.StampState, paperComp))
|
if (TryComp<StampComponent>(args.Used, out var stampComp) && TryStamp(uid, GetStampInfo(stampComp), stampComp.StampState, paperComp))
|
||||||
{
|
{
|
||||||
// successfully stamped, play popup
|
// successfully stamped, play popup
|
||||||
var stampPaperOtherMessage = Loc.GetString("paper-component-action-stamp-paper-other", ("user", Identity.Entity(args.User, EntityManager)), ("target", Identity.Entity(args.Target, EntityManager)), ("stamp", args.Used));
|
var stampPaperOtherMessage = Loc.GetString("paper-component-action-stamp-paper-other",
|
||||||
_popupSystem.PopupEntity(stampPaperOtherMessage, args.User, Filter.PvsExcept(args.User, entityManager: EntityManager), true);
|
("user", args.User), ("target", args.Target), ("stamp", args.Used));
|
||||||
|
|
||||||
var stampPaperSelfMessage = Loc.GetString("paper-component-action-stamp-paper-self", ("target", Identity.Entity(args.Target, EntityManager)), ("stamp", args.Used));
|
_popupSystem.PopupEntity(stampPaperOtherMessage, args.User, Filter.PvsExcept(args.User, entityManager: EntityManager), true);
|
||||||
|
var stampPaperSelfMessage = Loc.GetString("paper-component-action-stamp-paper-self",
|
||||||
|
("target", args.Target), ("stamp", args.Used));
|
||||||
_popupSystem.PopupEntity(stampPaperSelfMessage, args.User, args.User);
|
_popupSystem.PopupEntity(stampPaperSelfMessage, args.User, args.User);
|
||||||
|
|
||||||
_audio.PlayPvs(stampComp.Sound, uid);
|
_audio.PlayPvs(stampComp.Sound, uid);
|
||||||
@@ -129,6 +132,14 @@ namespace Content.Server.Paper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StampDisplayInfo GetStampInfo(StampComponent stamp)
|
||||||
|
{
|
||||||
|
return new StampDisplayInfo {
|
||||||
|
StampedName = stamp.StampedName,
|
||||||
|
StampedColor = stamp.StampedColor
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void OnInputTextMessage(EntityUid uid, PaperComponent paperComp, PaperInputTextMessage args)
|
private void OnInputTextMessage(EntityUid uid, PaperComponent paperComp, PaperInputTextMessage args)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(args.Text))
|
if (string.IsNullOrEmpty(args.Text))
|
||||||
@@ -161,17 +172,19 @@ namespace Content.Server.Paper
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Accepts the name and state to be stamped onto the paper, returns true if successful.
|
/// Accepts the name and state to be stamped onto the paper, returns true if successful.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool TryStamp(EntityUid uid, string stampName, string stampState, PaperComponent? paperComp = null)
|
public bool TryStamp(EntityUid uid, StampDisplayInfo stampInfo, string spriteStampState, PaperComponent? paperComp = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref paperComp))
|
if (!Resolve(uid, ref paperComp))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!paperComp.StampedBy.Contains(Loc.GetString(stampName)))
|
if (!paperComp.StampedBy.Contains(stampInfo))
|
||||||
{
|
{
|
||||||
paperComp.StampedBy.Add(Loc.GetString(stampName));
|
paperComp.StampedBy.Add(stampInfo);
|
||||||
if (paperComp.StampState == null && TryComp<AppearanceComponent>(uid, out var appearance))
|
if (paperComp.StampState == null && TryComp<AppearanceComponent>(uid, out var appearance))
|
||||||
{
|
{
|
||||||
paperComp.StampState = stampState;
|
paperComp.StampState = spriteStampState;
|
||||||
|
// Would be nice to be able to display multiple sprites on the paper
|
||||||
|
// but most of the existing images overlap
|
||||||
_appearance.SetData(uid, PaperVisuals.Stamp, paperComp.StampState, appearance);
|
_appearance.SetData(uid, PaperVisuals.Stamp, paperComp.StampState, appearance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Content.Shared.Eui;
|
using Content.Shared.Eui;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Fax;
|
namespace Content.Shared.Fax;
|
||||||
@@ -55,14 +55,16 @@ public static class AdminFaxEuiMsg
|
|||||||
public string From { get; }
|
public string From { get; }
|
||||||
public string Content { get; }
|
public string Content { get; }
|
||||||
public string StampState { get; }
|
public string StampState { get; }
|
||||||
|
public Color StampColor { get; }
|
||||||
|
|
||||||
public Send(EntityUid target, string title, string from, string content, string stamp)
|
public Send(EntityUid target, string title, string from, string content, string stamp, Color stampColor)
|
||||||
{
|
{
|
||||||
Target = target;
|
Target = target;
|
||||||
Title = title;
|
Title = title;
|
||||||
From = from;
|
From = from;
|
||||||
Content = content;
|
Content = content;
|
||||||
StampState = stamp;
|
StampState = stamp;
|
||||||
|
StampColor = stampColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,60 +1,59 @@
|
|||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Paper
|
namespace Content.Shared.Paper;
|
||||||
|
|
||||||
|
public abstract class SharedPaperComponent : Component
|
||||||
{
|
{
|
||||||
public abstract class SharedPaperComponent : Component
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class PaperBoundUserInterfaceState : BoundUserInterfaceState
|
||||||
{
|
{
|
||||||
[Serializable, NetSerializable]
|
public readonly string Text;
|
||||||
public sealed class PaperBoundUserInterfaceState : BoundUserInterfaceState
|
public readonly List<StampDisplayInfo> StampedBy;
|
||||||
|
public readonly PaperAction Mode;
|
||||||
|
|
||||||
|
public PaperBoundUserInterfaceState(string text, List<StampDisplayInfo> stampedBy, PaperAction mode = PaperAction.Read)
|
||||||
{
|
{
|
||||||
public readonly string Text;
|
Text = text;
|
||||||
public readonly List<string> StampedBy;
|
StampedBy = stampedBy;
|
||||||
public readonly PaperAction Mode;
|
Mode = mode;
|
||||||
|
|
||||||
public PaperBoundUserInterfaceState(string text, List<string> stampedBy, PaperAction mode = PaperAction.Read)
|
|
||||||
{
|
|
||||||
Text = text;
|
|
||||||
StampedBy = stampedBy;
|
|
||||||
Mode = mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed class PaperInputTextMessage : BoundUserInterfaceMessage
|
|
||||||
{
|
|
||||||
public readonly string Text;
|
|
||||||
|
|
||||||
public PaperInputTextMessage(string text)
|
|
||||||
{
|
|
||||||
Text = text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public enum PaperUiKey
|
|
||||||
{
|
|
||||||
Key
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public enum PaperAction
|
|
||||||
{
|
|
||||||
Read,
|
|
||||||
Write,
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public enum PaperVisuals : byte
|
|
||||||
{
|
|
||||||
Status,
|
|
||||||
Stamp
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public enum PaperStatus : byte
|
|
||||||
{
|
|
||||||
Blank,
|
|
||||||
Written
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class PaperInputTextMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public readonly string Text;
|
||||||
|
|
||||||
|
public PaperInputTextMessage(string text)
|
||||||
|
{
|
||||||
|
Text = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum PaperUiKey
|
||||||
|
{
|
||||||
|
Key
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum PaperAction
|
||||||
|
{
|
||||||
|
Read,
|
||||||
|
Write,
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum PaperVisuals : byte
|
||||||
|
{
|
||||||
|
Status,
|
||||||
|
Stamp
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum PaperStatus : byte
|
||||||
|
{
|
||||||
|
Blank,
|
||||||
|
Written
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,52 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
|
||||||
namespace Content.Shared.Paper
|
namespace Content.Shared.Paper;
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed class StampComponent : Component
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The loc string name that will be stamped to the piece of paper on examine.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("stampedName")]
|
|
||||||
public string StampedName { get; set; } = "stamp-component-stamped-name-default";
|
|
||||||
/// <summary>
|
|
||||||
/// Tne sprite state of the stamp to display on the paper from bureacracy.rsi.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("stampState")]
|
|
||||||
public string StampState { get; set; } = "paper_stamp-generic";
|
|
||||||
|
|
||||||
[DataField("sound")]
|
/// <summary>
|
||||||
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Items/Stamp/thick_stamp_sub.ogg")
|
/// Set of required information to draw a stamp in UIs, where
|
||||||
{
|
/// representing the state of the stamp at the point in time
|
||||||
Params = AudioParams.Default.WithVolume(-2f).WithMaxDistance(5f)
|
/// when it was applied to a paper. These fields mirror the
|
||||||
};
|
/// equivalent in the component.
|
||||||
|
/// </summary>
|
||||||
|
[DataDefinition, Serializable, NetSerializable]
|
||||||
|
public struct StampDisplayInfo
|
||||||
|
{
|
||||||
|
StampDisplayInfo(string s)
|
||||||
|
{
|
||||||
|
StampedName = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DataField("stampedName")]
|
||||||
|
public string StampedName;
|
||||||
|
|
||||||
|
[DataField("stampedColor")]
|
||||||
|
public Color StampedColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class StampComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The loc string name that will be stamped to the piece of paper on examine.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("stampedName")]
|
||||||
|
public string StampedName { get; set; } = "stamp-component-stamped-name-default";
|
||||||
|
/// <summary>
|
||||||
|
/// Tne sprite state of the stamp to display on the paper from bureacracy.rsi.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("stampState")]
|
||||||
|
public string StampState { get; set; } = "paper_stamp-generic";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The color of the ink used by the stamp in UIs
|
||||||
|
/// </summary>
|
||||||
|
[DataField("stampedColor")]
|
||||||
|
public Color StampedColor = Color.FromHex("#BB3232"); // StyleNano.DangerousRedFore
|
||||||
|
|
||||||
|
[DataField("sound")]
|
||||||
|
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Items/Stamp/thick_stamp_sub.ogg")
|
||||||
|
{
|
||||||
|
Params = AudioParams.Default.WithVolume(-2f).WithMaxDistance(5f)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Command
|
# Command
|
||||||
cmd-faxui-desc = Open admin window for sending faxes
|
cmd-faxui-desc = Open admin window for sending faxes
|
||||||
cmd-faxui-help = Usage: faxui
|
cmd-faxui-help = Usage: faxui
|
||||||
|
|
||||||
@@ -7,7 +7,8 @@ admin-fax-title = Admin Fax Manager
|
|||||||
admin-fax-fax = Fax:
|
admin-fax-fax = Fax:
|
||||||
admin-fax-follow = Follow
|
admin-fax-follow = Follow
|
||||||
admin-fax-title-placeholder = Paper name...
|
admin-fax-title-placeholder = Paper name...
|
||||||
admin-fax-from-placeholder = From who...
|
admin-fax-from-placeholder = Stamped by...
|
||||||
admin-fax-message-placeholder = Your message here...
|
admin-fax-message-placeholder = Your message here...
|
||||||
admin-fax-stamp = Stamp:
|
admin-fax-stamp = Stamp icon:
|
||||||
|
admin-fax-stamp-color = Stamp color:
|
||||||
admin-fax-send = Send
|
admin-fax-send = Send
|
||||||
|
|||||||
@@ -91310,7 +91310,8 @@ entities:
|
|||||||
type: Transform
|
type: Transform
|
||||||
- stampState: paper_stamp-syndicate
|
- stampState: paper_stamp-syndicate
|
||||||
stampedBy:
|
stampedBy:
|
||||||
- Syndicate
|
- stampedName: stamp-component-stamped-name-syndicate
|
||||||
|
stampedColor: '#850000'
|
||||||
content: >-
|
content: >-
|
||||||
Operative, i have succeeded in the mission and this is the remainder of the evidence. I am hiding it behind this wall and escaping ASAP.
|
Operative, i have succeeded in the mission and this is the remainder of the evidence. I am hiding it behind this wall and escaping ASAP.
|
||||||
|
|
||||||
|
|||||||
@@ -421,6 +421,7 @@
|
|||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-default
|
stampedName: stamp-component-stamped-name-default
|
||||||
stampState: "paper_stamp-generic"
|
stampState: "paper_stamp-generic"
|
||||||
|
stampedColor: "#a23e3e"
|
||||||
sound:
|
sound:
|
||||||
path: /Audio/Items/Stamp/thick_stamp_sub.ogg
|
path: /Audio/Items/Stamp/thick_stamp_sub.ogg
|
||||||
params:
|
params:
|
||||||
@@ -454,6 +455,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-captain
|
stampedName: stamp-component-stamped-name-captain
|
||||||
|
stampedColor: "#3681bb"
|
||||||
stampState: "paper_stamp-cap"
|
stampState: "paper_stamp-cap"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -466,6 +468,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-centcom
|
stampedName: stamp-component-stamped-name-centcom
|
||||||
|
stampedColor: "#006600"
|
||||||
stampState: "paper_stamp-centcom"
|
stampState: "paper_stamp-centcom"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -478,6 +481,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-chaplain
|
stampedName: stamp-component-stamped-name-chaplain
|
||||||
|
stampedColor: "#d70601"
|
||||||
stampState: "paper_stamp-chaplain"
|
stampState: "paper_stamp-chaplain"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -490,6 +494,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-clown
|
stampedName: stamp-component-stamped-name-clown
|
||||||
|
stampedColor: "#ff33cc"
|
||||||
stampState: "paper_stamp-clown"
|
stampState: "paper_stamp-clown"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -505,6 +510,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-ce
|
stampedName: stamp-component-stamped-name-ce
|
||||||
|
stampedColor: "#c69b17"
|
||||||
stampState: "paper_stamp-ce"
|
stampState: "paper_stamp-ce"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -517,6 +523,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-cmo
|
stampedName: stamp-component-stamped-name-cmo
|
||||||
|
stampedColor: "#33ccff"
|
||||||
stampState: "paper_stamp-cmo"
|
stampState: "paper_stamp-cmo"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -529,6 +536,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-hop
|
stampedName: stamp-component-stamped-name-hop
|
||||||
|
stampedColor: "#6ec0ea"
|
||||||
stampState: "paper_stamp-hop"
|
stampState: "paper_stamp-hop"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -541,6 +549,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-hos
|
stampedName: stamp-component-stamped-name-hos
|
||||||
|
stampedColor: "#cc0000"
|
||||||
stampState: "paper_stamp-hos"
|
stampState: "paper_stamp-hos"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -553,6 +562,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-mime
|
stampedName: stamp-component-stamped-name-mime
|
||||||
|
stampedColor: "#777777"
|
||||||
stampState: "paper_stamp-mime"
|
stampState: "paper_stamp-mime"
|
||||||
# TODO remove sound from mime's rubber stamp
|
# TODO remove sound from mime's rubber stamp
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
@@ -566,6 +576,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-qm
|
stampedName: stamp-component-stamped-name-qm
|
||||||
|
stampedColor: "#a23e3e"
|
||||||
stampState: "paper_stamp-qm"
|
stampState: "paper_stamp-qm"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -578,6 +589,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-rd
|
stampedName: stamp-component-stamped-name-rd
|
||||||
|
stampedColor: "#1f66a0"
|
||||||
stampState: "paper_stamp-rd"
|
stampState: "paper_stamp-rd"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -590,6 +602,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-trader
|
stampedName: stamp-component-stamped-name-trader
|
||||||
|
stampedColor: "#000000"
|
||||||
stampState: "paper_stamp-trader"
|
stampState: "paper_stamp-trader"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -602,6 +615,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-syndicate
|
stampedName: stamp-component-stamped-name-syndicate
|
||||||
|
stampedColor: "#850000"
|
||||||
stampState: "paper_stamp-syndicate"
|
stampState: "paper_stamp-syndicate"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -614,6 +628,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-warden
|
stampedName: stamp-component-stamped-name-warden
|
||||||
|
stampedColor: "#5b0000"
|
||||||
stampState: "paper_stamp-warden"
|
stampState: "paper_stamp-warden"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -626,6 +641,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-approved
|
stampedName: stamp-component-stamped-name-approved
|
||||||
|
stampedColor: "#00be00"
|
||||||
stampState: "paper_stamp-ok"
|
stampState: "paper_stamp-ok"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
@@ -638,6 +654,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: Stamp
|
- type: Stamp
|
||||||
stampedName: stamp-component-stamped-name-denied
|
stampedName: stamp-component-stamped-name-denied
|
||||||
|
stampedColor: "#a23e3e"
|
||||||
stampState: "paper_stamp-deny"
|
stampState: "paper_stamp-deny"
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/bureaucracy.rsi
|
sprite: Objects/Misc/bureaucracy.rsi
|
||||||
|
|||||||
@@ -71,3 +71,8 @@
|
|||||||
id: Stealth
|
id: Stealth
|
||||||
kind: source
|
kind: source
|
||||||
path: "/Textures/Shaders/stealth.swsl"
|
path: "/Textures/Shaders/stealth.swsl"
|
||||||
|
|
||||||
|
- type: shader
|
||||||
|
id: PaperStamp
|
||||||
|
kind: source
|
||||||
|
path: "/Textures/Shaders/paperstamp.swsl"
|
||||||
|
|||||||
103
Resources/Textures/Interface/Paper/paper_stamp_border.svg
Normal file
103
Resources/Textures/Interface/Paper/paper_stamp_border.svg
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="35.0625"
|
||||||
|
height="34"
|
||||||
|
viewBox="0 0 35.0625 34"
|
||||||
|
fill="none"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="paper_stamp_border.svg"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||||
|
inkscape:export-filename="paper_stamp_border.svg.96dpi.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<metadata
|
||||||
|
id="metadata10">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs8">
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="powerclip"
|
||||||
|
id="path-effect302"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
inverse="true"
|
||||||
|
flatten="false"
|
||||||
|
hide_clip="false"
|
||||||
|
message="Use fill-rule evenodd on <b>fill and stroke</b> dialog if no flatten result after convert clip to paths." />
|
||||||
|
<clipPath
|
||||||
|
clipPathUnits="userSpaceOnUse"
|
||||||
|
id="clipPath298">
|
||||||
|
<rect
|
||||||
|
x="2.6084003"
|
||||||
|
y="2.5943766"
|
||||||
|
width="26.783199"
|
||||||
|
height="26.811247"
|
||||||
|
rx="4.1848745"
|
||||||
|
fill="#ffffff"
|
||||||
|
id="rect300"
|
||||||
|
style="display:none;stroke-width:0.837413"
|
||||||
|
d="M 6.7932749,2.5943766 H 25.206725 c 2.318421,0 4.184875,1.866454 4.184875,4.1848745 V 25.220749 c 0,2.31842 -1.866454,4.184874 -4.184875,4.184874 H 6.7932749 c -2.3184205,0 -4.1848746,-1.866454 -4.1848746,-4.184874 V 6.7792511 c 0,-2.3184205 1.8664541,-4.1848745 4.1848746,-4.1848745 z" />
|
||||||
|
<path
|
||||||
|
id="lpe_path-effect302"
|
||||||
|
style="stroke-width:0.837413"
|
||||||
|
class="powerclip"
|
||||||
|
d="M -5,-5 H 37 V 37 H -5 Z M 6.7932749,2.5943766 c -2.3184205,0 -4.1848746,1.866454 -4.1848746,4.1848745 V 25.220749 c 0,2.31842 1.8664541,4.184874 4.1848746,4.184874 H 25.206725 c 2.318421,0 4.184875,-1.866454 4.184875,-4.184874 V 6.7792511 c 0,-2.3184205 -1.866454,-4.1848745 -4.184875,-4.1848745 z" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1916"
|
||||||
|
inkscape:window-height="1034"
|
||||||
|
id="namedview6"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:zoom="15.527471"
|
||||||
|
inkscape:cx="6.7300077"
|
||||||
|
inkscape:cy="17.16313"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="44"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg4"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:deskcolor="#d1d1d1" />
|
||||||
|
<path
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
rx="5"
|
||||||
|
fill="#ffffff"
|
||||||
|
id="rect2"
|
||||||
|
clip-path="url(#clipPath298)"
|
||||||
|
inkscape:path-effect="#path-effect302"
|
||||||
|
d="m 5,0 h 22 c 2.77,0 5,2.23 5,5 v 22 c 0,2.77 -2.23,5 -5,5 H 5 C 2.23,32 0,29.77 0,27 V 5 C 0,2.23 2.23,0 5,0 Z"
|
||||||
|
sodipodi:type="rect"
|
||||||
|
transform="translate(1,1)" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 445 B |
53
Resources/Textures/Shaders/paperstamp.swsl
Normal file
53
Resources/Textures/Shaders/paperstamp.swsl
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// Object position in screen space. Allows the noise to
|
||||||
|
// have a constant screen-space size, without being
|
||||||
|
// affected by the widget layout/position.
|
||||||
|
uniform highp vec2 objCoord;
|
||||||
|
|
||||||
|
// Magic, well-known 2d random function; makes perlin-like noise
|
||||||
|
highp vec2 random(highp vec2 uv){
|
||||||
|
uv = vec2( dot(uv, vec2(127.1,311.7) ),
|
||||||
|
dot(uv, vec2(269.5,183.3) ) );
|
||||||
|
return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
|
||||||
|
}
|
||||||
|
|
||||||
|
highp float noise(highp vec2 uv) {
|
||||||
|
highp vec2 uv_i = floor(uv);
|
||||||
|
highp vec2 uv_f = fract(uv);
|
||||||
|
|
||||||
|
highp vec2 t = smoothstep(0.0, 1.0, uv_f);
|
||||||
|
|
||||||
|
// Sample the random function and run a bilinear filter to smooth it out
|
||||||
|
highp float tl = dot( random(uv_i + vec2(0.0,0.0) ), uv_f - vec2(0.0,0.0) );
|
||||||
|
highp float tr = dot( random(uv_i + vec2(1.0,0.0) ), uv_f - vec2(1.0,0.0) );
|
||||||
|
highp float bl = dot( random(uv_i + vec2(0.0,1.0) ), uv_f - vec2(0.0,1.0) );
|
||||||
|
highp float br = dot( random(uv_i + vec2(1.0,1.0) ), uv_f - vec2(1.0,1.0) );
|
||||||
|
|
||||||
|
highp float tA = mix( tl, tr, t.x );
|
||||||
|
highp float tB = mix( bl, br, t.x );
|
||||||
|
return mix( tA, tB, t.y ) + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
// Stamps have orientation, and the texture sampling is nearest
|
||||||
|
// pixel, so run a bilinear filter to smooth out the edges.
|
||||||
|
{
|
||||||
|
highp vec4 tl = texture2D(TEXTURE, UV);
|
||||||
|
highp vec4 tr = texture2D(TEXTURE, UV + vec2(TEXTURE_PIXEL_SIZE.x, 0.0));
|
||||||
|
highp vec4 bl = texture2D(TEXTURE, UV + vec2(0.0, TEXTURE_PIXEL_SIZE.y));
|
||||||
|
highp vec4 br = texture2D(TEXTURE, UV + TEXTURE_PIXEL_SIZE);
|
||||||
|
|
||||||
|
highp vec2 textureSize = 1.0 / TEXTURE_PIXEL_SIZE;
|
||||||
|
highp vec2 f = fract( UV * textureSize );
|
||||||
|
highp vec4 tA = mix( tl, tr, f.x );
|
||||||
|
highp vec4 tB = mix( bl, br, f.x );
|
||||||
|
COLOR = mix( tA, tB, f.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a bit of noise to mimic imperfect contact with the paper
|
||||||
|
{
|
||||||
|
float stampNoise = noise((FRAGCOORD.xy - objCoord) * vec2(0.03, 0.03)) *
|
||||||
|
noise((FRAGCOORD.xy - objCoord) * vec2(0.08, 0.08));
|
||||||
|
COLOR.a *= min(0.9, 0.4 + smoothstep(0.05, 0.3, stampNoise));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user