Wire hacking is now fancy.
1. new UI 2. wires are correctly randomized. 3. wires layouts are shared across machines in the same round.
@@ -1,17 +1,11 @@
|
|||||||
using System;
|
|
||||||
using Robust.Client.GameObjects.Components.UserInterface;
|
using Robust.Client.GameObjects.Components.UserInterface;
|
||||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Wires
|
namespace Content.Client.GameObjects.Components.Wires
|
||||||
{
|
{
|
||||||
public class WiresBoundUserInterface : BoundUserInterface
|
public class WiresBoundUserInterface : BoundUserInterface
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
public WiresBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
public WiresBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -21,7 +15,7 @@ namespace Content.Client.GameObjects.Components.Wires
|
|||||||
protected override void Open()
|
protected override void Open()
|
||||||
{
|
{
|
||||||
base.Open();
|
base.Open();
|
||||||
_menu = new WiresMenu(_localizationManager) {Owner = this};
|
_menu = new WiresMenu(this);
|
||||||
|
|
||||||
_menu.OnClose += Close;
|
_menu.OnClose += Close;
|
||||||
_menu.OpenCentered();
|
_menu.OpenCentered();
|
||||||
@@ -33,9 +27,16 @@ namespace Content.Client.GameObjects.Components.Wires
|
|||||||
_menu.Populate((WiresBoundUserInterfaceState) state);
|
_menu.Populate((WiresBoundUserInterfaceState) state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PerformAction(Guid guid, WiresAction action)
|
public void PerformAction(int id, WiresAction action)
|
||||||
{
|
{
|
||||||
SendMessage(new WiresActionMessage(guid, action));
|
SendMessage(new WiresActionMessage(id, action));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
_menu.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,66 +1,618 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Client.Animations;
|
||||||
|
using Content.Client.GameObjects.EntitySystems;
|
||||||
|
using Content.Client.UserInterface.Stylesheets;
|
||||||
|
using Content.Client.Utility;
|
||||||
|
using Content.Shared.GameObjects.Components;
|
||||||
|
using Robust.Client.Animations;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.Graphics.Drawing;
|
||||||
|
using Robust.Client.Interfaces.ResourceManagement;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Shared.Animations;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Wires
|
namespace Content.Client.GameObjects.Components.Wires
|
||||||
{
|
{
|
||||||
public class WiresMenu : SS14Window
|
public class WiresMenu : BaseWindow
|
||||||
{
|
{
|
||||||
private readonly ILocalizationManager _localizationManager;
|
public WiresBoundUserInterface Owner { get; }
|
||||||
protected override Vector2? CustomSize => (300, 150);
|
|
||||||
public WiresBoundUserInterface Owner { get; set; }
|
|
||||||
|
|
||||||
private readonly VBoxContainer _wiresContainer;
|
private readonly Control _wiresHBox;
|
||||||
|
private readonly Control _topContainer;
|
||||||
|
private readonly Control _statusContainer;
|
||||||
|
|
||||||
public WiresMenu(ILocalizationManager localizationManager)
|
private readonly Label _nameLabel;
|
||||||
|
private readonly Label _serialLabel;
|
||||||
|
|
||||||
|
public TextureButton CloseButton { get; set; }
|
||||||
|
|
||||||
|
public WiresMenu(WiresBoundUserInterface owner)
|
||||||
{
|
{
|
||||||
_localizationManager = localizationManager;
|
var resourceCache = IoCManager.Resolve<IResourceCache>();
|
||||||
Title = _localizationManager.GetString("Wires");
|
|
||||||
_wiresContainer = new VBoxContainer();
|
Owner = owner;
|
||||||
Contents.AddChild(_wiresContainer);
|
var rootContainer = new LayoutContainer {Name = "WireRoot"};
|
||||||
|
AddChild(rootContainer);
|
||||||
|
|
||||||
|
MouseFilter = MouseFilterMode.Stop;
|
||||||
|
|
||||||
|
var panelTex = resourceCache.GetTexture("/Nano/button.svg.96dpi.png");
|
||||||
|
var back = new StyleBoxTexture
|
||||||
|
{
|
||||||
|
Texture = panelTex,
|
||||||
|
Modulate = Color.FromHex("#25252A"),
|
||||||
|
};
|
||||||
|
back.SetPatchMargin(StyleBox.Margin.All, 10);
|
||||||
|
|
||||||
|
var topPanel = new PanelContainer
|
||||||
|
{
|
||||||
|
PanelOverride = back,
|
||||||
|
MouseFilter = MouseFilterMode.Pass
|
||||||
|
};
|
||||||
|
var bottomWrap = new LayoutContainer
|
||||||
|
{
|
||||||
|
Name = "BottomWrap"
|
||||||
|
};
|
||||||
|
var bottomPanel = new PanelContainer
|
||||||
|
{
|
||||||
|
PanelOverride = back,
|
||||||
|
MouseFilter = MouseFilterMode.Pass
|
||||||
|
};
|
||||||
|
|
||||||
|
var shadow = new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new PanelContainer
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (2, 0),
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#525252ff")}
|
||||||
|
},
|
||||||
|
new PanelContainer
|
||||||
|
{
|
||||||
|
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||||
|
MouseFilter = MouseFilterMode.Stop,
|
||||||
|
Name = "Shadow",
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.Black.WithAlpha(0.5f)}
|
||||||
|
},
|
||||||
|
new PanelContainer
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (2, 0),
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#525252ff")}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var wrappingHBox = new HBoxContainer();
|
||||||
|
_wiresHBox = new HBoxContainer {SeparationOverride = 4, SizeFlagsVertical = SizeFlags.ShrinkEnd};
|
||||||
|
|
||||||
|
wrappingHBox.AddChild(new Control {CustomMinimumSize = (20, 0)});
|
||||||
|
wrappingHBox.AddChild(_wiresHBox);
|
||||||
|
wrappingHBox.AddChild(new Control {CustomMinimumSize = (20, 0)});
|
||||||
|
|
||||||
|
bottomWrap.AddChild(bottomPanel);
|
||||||
|
|
||||||
|
LayoutContainer.SetAnchorPreset(bottomPanel, LayoutContainer.LayoutPreset.BottomWide);
|
||||||
|
LayoutContainer.SetMarginTop(bottomPanel, -55);
|
||||||
|
|
||||||
|
bottomWrap.AddChild(shadow);
|
||||||
|
|
||||||
|
LayoutContainer.SetAnchorPreset(shadow, LayoutContainer.LayoutPreset.BottomWide);
|
||||||
|
LayoutContainer.SetMarginBottom(shadow, -55);
|
||||||
|
LayoutContainer.SetMarginTop(shadow, -80);
|
||||||
|
LayoutContainer.SetMarginLeft(shadow, 12);
|
||||||
|
LayoutContainer.SetMarginRight(shadow, -12);
|
||||||
|
|
||||||
|
bottomWrap.AddChild(wrappingHBox);
|
||||||
|
LayoutContainer.SetAnchorPreset(wrappingHBox, LayoutContainer.LayoutPreset.Wide);
|
||||||
|
LayoutContainer.SetMarginBottom(wrappingHBox, -4);
|
||||||
|
|
||||||
|
rootContainer.AddChild(topPanel);
|
||||||
|
rootContainer.AddChild(bottomWrap);
|
||||||
|
|
||||||
|
LayoutContainer.SetAnchorPreset(topPanel, LayoutContainer.LayoutPreset.Wide);
|
||||||
|
LayoutContainer.SetMarginBottom(topPanel, -80);
|
||||||
|
|
||||||
|
LayoutContainer.SetAnchorPreset(bottomWrap, LayoutContainer.LayoutPreset.VerticalCenterWide);
|
||||||
|
LayoutContainer.SetGrowHorizontal(bottomWrap, LayoutContainer.GrowDirection.Both);
|
||||||
|
|
||||||
|
var topContainerWrap = new VBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
(_topContainer = new VBoxContainer()),
|
||||||
|
new Control {CustomMinimumSize = (0, 110)}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rootContainer.AddChild(topContainerWrap);
|
||||||
|
|
||||||
|
LayoutContainer.SetAnchorPreset(topContainerWrap, LayoutContainer.LayoutPreset.Wide);
|
||||||
|
|
||||||
|
var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13);
|
||||||
|
var fontSmall = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 10);
|
||||||
|
|
||||||
|
Button helpButton;
|
||||||
|
var topRow = new MarginContainer
|
||||||
|
{
|
||||||
|
MarginLeftOverride = 4,
|
||||||
|
MarginTopOverride = 2,
|
||||||
|
MarginRightOverride = 12,
|
||||||
|
MarginBottomOverride = 2,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
(_nameLabel = new Label
|
||||||
|
{
|
||||||
|
Text = Loc.GetString("Wires"),
|
||||||
|
FontOverride = font,
|
||||||
|
FontColorOverride = StyleNano.NanoGold,
|
||||||
|
SizeFlagsVertical = SizeFlags.ShrinkCenter
|
||||||
|
}),
|
||||||
|
new Control
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (8, 0),
|
||||||
|
},
|
||||||
|
(_serialLabel = new Label
|
||||||
|
{
|
||||||
|
Text = Loc.GetString("DEAD-BEEF"),
|
||||||
|
FontOverride = fontSmall,
|
||||||
|
FontColorOverride = Color.Gray,
|
||||||
|
SizeFlagsVertical = SizeFlags.ShrinkCenter
|
||||||
|
}),
|
||||||
|
new Control
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (20, 0),
|
||||||
|
SizeFlagsHorizontal = SizeFlags.Expand
|
||||||
|
},
|
||||||
|
(helpButton = new Button {Text = "?"}),
|
||||||
|
new Control
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (2, 0),
|
||||||
|
},
|
||||||
|
(CloseButton = new TextureButton
|
||||||
|
{
|
||||||
|
StyleClasses = {SS14Window.StyleClassWindowCloseButton},
|
||||||
|
SizeFlagsVertical = SizeFlags.ShrinkCenter
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
helpButton.OnPressed += a =>
|
||||||
|
{
|
||||||
|
var popup = new HelpPopup();
|
||||||
|
UserInterfaceManager.ModalRoot.AddChild(popup);
|
||||||
|
|
||||||
|
popup.Open(UIBox2.FromDimensions(a.Event.PointerLocation.Position, (400, 200)));
|
||||||
|
};
|
||||||
|
|
||||||
|
var middle = new PanelContainer
|
||||||
|
{
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#202025")},
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new MarginContainer
|
||||||
|
{
|
||||||
|
MarginLeftOverride = 8,
|
||||||
|
MarginRightOverride = 8,
|
||||||
|
MarginTopOverride = 4,
|
||||||
|
MarginBottomOverride = 4,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
(_statusContainer = new GridContainer
|
||||||
|
{
|
||||||
|
// TODO: automatically change columns count.
|
||||||
|
Columns = 3
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_topContainer.AddChild(topRow);
|
||||||
|
_topContainer.AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (0, 2),
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#525252ff")}
|
||||||
|
});
|
||||||
|
_topContainer.AddChild(middle);
|
||||||
|
_topContainer.AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (0, 2),
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#525252ff")}
|
||||||
|
});
|
||||||
|
CloseButton.OnPressed += _ => Close();
|
||||||
|
LayoutContainer.SetSize(this, (300, 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Populate(WiresBoundUserInterfaceState state)
|
public void Populate(WiresBoundUserInterfaceState state)
|
||||||
{
|
{
|
||||||
_wiresContainer.RemoveAllChildren();
|
_nameLabel.Text = state.BoardName;
|
||||||
|
_serialLabel.Text = state.SerialNumber;
|
||||||
|
|
||||||
|
_wiresHBox.RemoveAllChildren();
|
||||||
|
var random = new Random(state.WireSeed);
|
||||||
foreach (var wire in state.WiresList)
|
foreach (var wire in state.WiresList)
|
||||||
{
|
{
|
||||||
var container = new HBoxContainer();
|
var mirror = random.Next(2) == 0;
|
||||||
var newLabel = new Label()
|
var flip = random.Next(2) == 0;
|
||||||
|
var type = random.Next(2);
|
||||||
|
var control = new WireControl(wire.Color, wire.Letter, wire.IsCut, flip, mirror, type)
|
||||||
{
|
{
|
||||||
Text = $"{_localizationManager.GetString(wire.Color.Name())}: ",
|
SizeFlagsVertical = SizeFlags.ShrinkEnd
|
||||||
FontColorOverride = wire.Color,
|
|
||||||
};
|
};
|
||||||
container.AddChild(newLabel);
|
_wiresHBox.AddChild(control);
|
||||||
|
|
||||||
var newButton = new Button()
|
control.WireClicked += () =>
|
||||||
{
|
{
|
||||||
Text = _localizationManager.GetString("Pulse"),
|
Owner.PerformAction(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut);
|
||||||
};
|
};
|
||||||
newButton.OnPressed += _ => Owner.PerformAction(wire.Guid, WiresAction.Pulse);
|
|
||||||
container.AddChild(newButton);
|
|
||||||
|
|
||||||
newButton = new Button()
|
control.ContactsClicked += () =>
|
||||||
{
|
{
|
||||||
Text = wire.IsCut ? _localizationManager.GetString("Mend") : _localizationManager.GetString("Cut"),
|
Owner.PerformAction(wire.Id, WiresAction.Pulse);
|
||||||
};
|
};
|
||||||
newButton.OnPressed += _ => Owner.PerformAction(wire.Guid, wire.IsCut ? WiresAction.Mend : WiresAction.Cut);
|
|
||||||
container.AddChild(newButton);
|
|
||||||
_wiresContainer.AddChild(container);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_statusContainer.RemoveAllChildren();
|
||||||
foreach (var status in state.Statuses)
|
foreach (var status in state.Statuses)
|
||||||
{
|
{
|
||||||
var container = new HBoxContainer();
|
if (status.Value is StatusLightData statusLightData)
|
||||||
container.AddChild(new Label
|
|
||||||
{
|
{
|
||||||
Text = status
|
_statusContainer.AddChild(new StatusLight(statusLightData));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_statusContainer.AddChild(new Label
|
||||||
|
{
|
||||||
|
Text = status.ToString()
|
||||||
});
|
});
|
||||||
_wiresContainer.AddChild(container);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override DragMode GetDragModeFor(Vector2 relativeMousePos)
|
||||||
|
{
|
||||||
|
return DragMode.Move;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool HasPoint(Vector2 point)
|
||||||
|
{
|
||||||
|
// This makes it so our base window won't count for hit tests,
|
||||||
|
// but we will still receive mouse events coming in from Pass mouse filter mode.
|
||||||
|
// So basically, it perfectly shells out the hit tests to the panels we have!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class WireControl : Control
|
||||||
|
{
|
||||||
|
private const string TextureContact = "/Textures/UserInterface/WireHacking/contact.svg.96dpi.png";
|
||||||
|
|
||||||
|
public event Action WireClicked;
|
||||||
|
public event Action ContactsClicked;
|
||||||
|
|
||||||
|
public WireControl(WireColor color, WireLetter letter, bool isCut, bool flip, bool mirror, int type)
|
||||||
|
{
|
||||||
|
SizeFlagsHorizontal = SizeFlags.ShrinkCenter;
|
||||||
|
MouseFilter = MouseFilterMode.Stop;
|
||||||
|
|
||||||
|
var resourceCache = IoCManager.Resolve<IResourceCache>();
|
||||||
|
|
||||||
|
var layout = new LayoutContainer();
|
||||||
|
AddChild(layout);
|
||||||
|
|
||||||
|
var greek = new Label
|
||||||
|
{
|
||||||
|
Text = letter.Letter().ToString(),
|
||||||
|
SizeFlagsVertical = SizeFlags.ShrinkEnd,
|
||||||
|
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
||||||
|
Align = Label.AlignMode.Center,
|
||||||
|
FontOverride = resourceCache.GetFont("/Fonts/NotoSansDisplay/NotoSansDisplay-Bold.ttf", 12),
|
||||||
|
FontColorOverride = Color.Gray,
|
||||||
|
ToolTip = letter.Name(),
|
||||||
|
MouseFilter = MouseFilterMode.Stop
|
||||||
|
};
|
||||||
|
|
||||||
|
layout.AddChild(greek);
|
||||||
|
LayoutContainer.SetAnchorPreset(greek, LayoutContainer.LayoutPreset.BottomWide);
|
||||||
|
LayoutContainer.SetGrowVertical(greek, LayoutContainer.GrowDirection.Begin);
|
||||||
|
LayoutContainer.SetGrowHorizontal(greek, LayoutContainer.GrowDirection.Both);
|
||||||
|
|
||||||
|
var contactTexture = resourceCache.GetTexture(TextureContact);
|
||||||
|
var contact1 = new TextureRect
|
||||||
|
{
|
||||||
|
Texture = contactTexture,
|
||||||
|
Modulate = Color.FromHex("#E1CA76")
|
||||||
|
};
|
||||||
|
|
||||||
|
layout.AddChild(contact1);
|
||||||
|
LayoutContainer.SetPosition(contact1, (0, 0));
|
||||||
|
|
||||||
|
var contact2 = new TextureRect
|
||||||
|
{
|
||||||
|
Texture = contactTexture,
|
||||||
|
Modulate = Color.FromHex("#E1CA76")
|
||||||
|
};
|
||||||
|
|
||||||
|
layout.AddChild(contact2);
|
||||||
|
LayoutContainer.SetPosition(contact2, (0, 60));
|
||||||
|
|
||||||
|
var wire = new WireRender(color, isCut, flip, mirror, type);
|
||||||
|
|
||||||
|
layout.AddChild(wire);
|
||||||
|
LayoutContainer.SetPosition(wire, (2, 16));
|
||||||
|
|
||||||
|
ToolTip = color.Name();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Vector2 CalculateMinimumSize()
|
||||||
|
{
|
||||||
|
return (20, 102);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
base.KeyBindDown(args);
|
||||||
|
|
||||||
|
if (args.Function != EngineKeyFunctions.UIClick)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.RelativePixelPosition.Y > 20 && args.RelativePixelPosition.Y < 60)
|
||||||
|
{
|
||||||
|
WireClicked?.Invoke();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ContactsClicked?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool HasPoint(Vector2 point)
|
||||||
|
{
|
||||||
|
return base.HasPoint(point) && point.Y <= 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class WireRender : Control
|
||||||
|
{
|
||||||
|
private readonly WireColor _color;
|
||||||
|
private readonly bool _isCut;
|
||||||
|
private readonly bool _flip;
|
||||||
|
private readonly bool _mirror;
|
||||||
|
private readonly int _type;
|
||||||
|
|
||||||
|
private static readonly string[] TextureNormal =
|
||||||
|
{
|
||||||
|
"/Textures/UserInterface/WireHacking/wire_1.svg.96dpi.png",
|
||||||
|
"/Textures/UserInterface/WireHacking/wire_2.svg.96dpi.png"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] TextureCut =
|
||||||
|
{
|
||||||
|
"/Textures/UserInterface/WireHacking/wire_1_cut.svg.96dpi.png",
|
||||||
|
"/Textures/UserInterface/WireHacking/wire_2_cut.svg.96dpi.png",
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] TextureCopper =
|
||||||
|
{
|
||||||
|
"/Textures/UserInterface/WireHacking/wire_1_copper.svg.96dpi.png",
|
||||||
|
"/Textures/UserInterface/WireHacking/wire_2_copper.svg.96dpi.png"
|
||||||
|
};
|
||||||
|
|
||||||
|
public WireRender(WireColor color, bool isCut, bool flip, bool mirror, int type)
|
||||||
|
{
|
||||||
|
_color = color;
|
||||||
|
_isCut = isCut;
|
||||||
|
_flip = flip;
|
||||||
|
_mirror = mirror;
|
||||||
|
_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Vector2 CalculateMinimumSize()
|
||||||
|
{
|
||||||
|
return (16, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
var resC = IoCManager.Resolve<IResourceCache>();
|
||||||
|
|
||||||
|
var colorValue = _color.ColorValue();
|
||||||
|
var tex = resC.GetTexture(_isCut ? TextureCut[_type] : TextureNormal[_type]);
|
||||||
|
|
||||||
|
var l = 0f;
|
||||||
|
var r = tex.Width + l;
|
||||||
|
var t = 0f;
|
||||||
|
var b = tex.Height + t;
|
||||||
|
|
||||||
|
if (_flip)
|
||||||
|
{
|
||||||
|
(t, b) = (b, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mirror)
|
||||||
|
{
|
||||||
|
(l, r) = (r, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
l *= UIScale;
|
||||||
|
r *= UIScale;
|
||||||
|
t *= UIScale;
|
||||||
|
b *= UIScale;
|
||||||
|
|
||||||
|
var rect = new UIBox2(l, t, r, b);
|
||||||
|
if (_isCut)
|
||||||
|
{
|
||||||
|
var copper = Color.Orange;
|
||||||
|
var copperTex = resC.GetTexture(TextureCopper[_type]);
|
||||||
|
handle.DrawTextureRect(copperTex, rect, copper);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle.DrawTextureRect(tex, rect, colorValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class StatusLight : Control
|
||||||
|
{
|
||||||
|
private static readonly Animation _blinkingFast = new Animation
|
||||||
|
{
|
||||||
|
Length = TimeSpan.FromSeconds(0.2),
|
||||||
|
AnimationTracks =
|
||||||
|
{
|
||||||
|
new AnimationTrackControlProperty
|
||||||
|
{
|
||||||
|
Property = nameof(Control.Modulate),
|
||||||
|
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||||
|
KeyFrames =
|
||||||
|
{
|
||||||
|
new AnimationTrackProperty.KeyFrame(Color.White, 0f),
|
||||||
|
new AnimationTrackProperty.KeyFrame(Color.Transparent, 0.1f),
|
||||||
|
new AnimationTrackProperty.KeyFrame(Color.White, 0.1f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Animation _blinkingSlow = new Animation
|
||||||
|
{
|
||||||
|
Length = TimeSpan.FromSeconds(0.8),
|
||||||
|
AnimationTracks =
|
||||||
|
{
|
||||||
|
new AnimationTrackControlProperty
|
||||||
|
{
|
||||||
|
Property = nameof(Control.Modulate),
|
||||||
|
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||||
|
KeyFrames =
|
||||||
|
{
|
||||||
|
new AnimationTrackProperty.KeyFrame(Color.White, 0f),
|
||||||
|
new AnimationTrackProperty.KeyFrame(Color.White, 0.3f),
|
||||||
|
new AnimationTrackProperty.KeyFrame(Color.Transparent, 0.1f),
|
||||||
|
new AnimationTrackProperty.KeyFrame(Color.Transparent, 0.3f),
|
||||||
|
new AnimationTrackProperty.KeyFrame(Color.White, 0.1f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public StatusLight(StatusLightData data)
|
||||||
|
{
|
||||||
|
var resC = IoCManager.Resolve<IResourceCache>();
|
||||||
|
var hsv = Color.ToHsv(data.Color);
|
||||||
|
hsv.Z /= 2;
|
||||||
|
var dimColor = Color.FromHsv(hsv);
|
||||||
|
TextureRect activeLight;
|
||||||
|
|
||||||
|
var lightContainer = new Control
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new TextureRect
|
||||||
|
{
|
||||||
|
Texture = resC.GetTexture(
|
||||||
|
"/Textures/UserInterface/WireHacking/light_off_base.svg.96dpi.png"),
|
||||||
|
Stretch = TextureRect.StretchMode.KeepCentered,
|
||||||
|
ModulateSelfOverride = dimColor
|
||||||
|
},
|
||||||
|
(activeLight = new TextureRect
|
||||||
|
{
|
||||||
|
ModulateSelfOverride = data.Color.WithAlpha(0.4f),
|
||||||
|
Stretch = TextureRect.StretchMode.KeepCentered,
|
||||||
|
Texture =
|
||||||
|
resC.GetTexture("/Textures/UserInterface/WireHacking/light_on_base.svg.96dpi.png"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Animation animation = null;
|
||||||
|
|
||||||
|
switch (data.State)
|
||||||
|
{
|
||||||
|
case StatusLightState.Off:
|
||||||
|
activeLight.Visible = false;
|
||||||
|
break;
|
||||||
|
case StatusLightState.On:
|
||||||
|
break;
|
||||||
|
case StatusLightState.BlinkingFast:
|
||||||
|
animation = _blinkingFast;
|
||||||
|
break;
|
||||||
|
case StatusLightState.BlinkingSlow:
|
||||||
|
animation = _blinkingSlow;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animation != null)
|
||||||
|
{
|
||||||
|
activeLight.PlayAnimation(animation, "blink");
|
||||||
|
|
||||||
|
activeLight.AnimationCompleted += s =>
|
||||||
|
{
|
||||||
|
if (s == "blink")
|
||||||
|
{
|
||||||
|
activeLight.PlayAnimation(animation, s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var font = IoCManager.Resolve<IResourceCache>().GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 12);
|
||||||
|
|
||||||
|
var hBox = new HBoxContainer {SeparationOverride = 4};
|
||||||
|
hBox.AddChild(new Label
|
||||||
|
{
|
||||||
|
Text = data.Text,
|
||||||
|
FontOverride = font,
|
||||||
|
FontColorOverride = Color.FromHex("#A1A6AE"),
|
||||||
|
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
||||||
|
});
|
||||||
|
hBox.AddChild(lightContainer);
|
||||||
|
hBox.AddChild(new Control {CustomMinimumSize = (6, 0)});
|
||||||
|
AddChild(hBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class HelpPopup : Popup
|
||||||
|
{
|
||||||
|
private const string Text = "Click on the gold contacts with a multitool in hand to pulse their wire.\n" +
|
||||||
|
"Click on the wires with a pair of wirecutters in hand to cut/mend them.\n\n" +
|
||||||
|
"The lights at the top show the state of the machine, " +
|
||||||
|
"messing with wires will probably do stuff to them.\n" +
|
||||||
|
"Wire layouts are different each round, " +
|
||||||
|
"but consistent between machines of the same type.";
|
||||||
|
|
||||||
|
public HelpPopup()
|
||||||
|
{
|
||||||
|
var label = new RichTextLabel();
|
||||||
|
label.SetMessage(Text);
|
||||||
|
AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
StyleClasses = {ExamineSystem.StyleClassEntityTooltip},
|
||||||
|
Children = {label}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using Content.Server.GameObjects.Components.Power;
|
|||||||
using Content.Server.GameObjects.Components.VendingMachines;
|
using Content.Server.GameObjects.Components.VendingMachines;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Utility;
|
|
||||||
using Content.Shared.GameObjects.Components.Doors;
|
using Content.Shared.GameObjects.Components.Doors;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -13,6 +12,8 @@ using Robust.Server.Interfaces.GameObjects;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent.WiresAction;
|
using static Content.Shared.GameObjects.Components.SharedWiresComponent.WiresAction;
|
||||||
using Timer = Robust.Shared.Timers.Timer;
|
using Timer = Robust.Shared.Timers.Timer;
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
private CancellationTokenSource _powerWiresPulsedTimerCancel;
|
private CancellationTokenSource _powerWiresPulsedTimerCancel;
|
||||||
|
|
||||||
private bool _powerWiresPulsed;
|
private bool _powerWiresPulsed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// True if either power wire was pulsed in the last <see cref="PowerWiresTimeout"/>.
|
/// True if either power wire was pulsed in the last <see cref="PowerWiresTimeout"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -56,16 +58,30 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
private void UpdateWiresStatus()
|
private void UpdateWiresStatus()
|
||||||
{
|
{
|
||||||
var powerMessage = "A yellow light is on.";
|
var powerLight = new StatusLightData(Color.Yellow, StatusLightState.On, "POWR");
|
||||||
if (PowerWiresPulsed)
|
if (PowerWiresPulsed)
|
||||||
{
|
{
|
||||||
powerMessage = "A yellow light is blinking rapidly.";
|
powerLight = new StatusLightData(Color.Yellow, StatusLightState.BlinkingFast, "POWR");
|
||||||
} else if (_wires.IsWireCut(Wires.MainPower) &&
|
}
|
||||||
|
else if (_wires.IsWireCut(Wires.MainPower) &&
|
||||||
_wires.IsWireCut(Wires.BackupPower))
|
_wires.IsWireCut(Wires.BackupPower))
|
||||||
{
|
{
|
||||||
powerMessage = "A red light is on.";
|
powerLight = new StatusLightData(Color.Red, StatusLightState.On, "POWR");
|
||||||
}
|
}
|
||||||
_wires.SetStatus(WiresStatus.PowerIndicator, _localizationMgr.GetString(powerMessage));
|
|
||||||
|
_wires.SetStatus(AirlockWireStatus.PowerIndicator, powerLight);
|
||||||
|
_wires.SetStatus(1, new StatusLightData(Color.Red, StatusLightState.Off, "BOLT"));
|
||||||
|
_wires.SetStatus(2, new StatusLightData(Color.Lime, StatusLightState.On, "BLTL"));
|
||||||
|
_wires.SetStatus(3, new StatusLightData(Color.Purple, StatusLightState.BlinkingSlow, "AICT"));
|
||||||
|
_wires.SetStatus(4, new StatusLightData(Color.Orange, StatusLightState.Off, "TIME"));
|
||||||
|
_wires.SetStatus(5, new StatusLightData(Color.Red, StatusLightState.Off, "SAFE"));
|
||||||
|
/*
|
||||||
|
_wires.SetStatus(6, powerLight);
|
||||||
|
_wires.SetStatus(7, powerLight);
|
||||||
|
_wires.SetStatus(8, powerLight);
|
||||||
|
_wires.SetStatus(9, powerLight);
|
||||||
|
_wires.SetStatus(10, powerLight);
|
||||||
|
_wires.SetStatus(11, powerLight);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePowerCutStatus()
|
private void UpdatePowerCutStatus()
|
||||||
@@ -125,19 +141,26 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
/// Mending restores power.
|
/// Mending restores power.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MainPower,
|
MainPower,
|
||||||
|
|
||||||
/// <see cref="MainPower"/>
|
/// <see cref="MainPower"/>
|
||||||
BackupPower,
|
BackupPower,
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum WiresStatus
|
|
||||||
{
|
|
||||||
PowerIndicator,
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterWires(WiresComponent.WiresBuilder builder)
|
public void RegisterWires(WiresComponent.WiresBuilder builder)
|
||||||
{
|
{
|
||||||
builder.CreateWire(Wires.MainPower);
|
builder.CreateWire(Wires.MainPower);
|
||||||
builder.CreateWire(Wires.BackupPower);
|
builder.CreateWire(Wires.BackupPower);
|
||||||
|
builder.CreateWire(1);
|
||||||
|
builder.CreateWire(2);
|
||||||
|
builder.CreateWire(3);
|
||||||
|
builder.CreateWire(4);
|
||||||
|
/*builder.CreateWire(5);
|
||||||
|
builder.CreateWire(6);
|
||||||
|
builder.CreateWire(7);
|
||||||
|
builder.CreateWire(8);
|
||||||
|
builder.CreateWire(9);
|
||||||
|
builder.CreateWire(10);
|
||||||
|
builder.CreateWire(11);*/
|
||||||
UpdateWiresStatus();
|
UpdateWiresStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,6 +215,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Deny();
|
base.Deny();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,11 +240,10 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
if (State == DoorState.Closed)
|
if (State == DoorState.Closed)
|
||||||
Open();
|
Open();
|
||||||
else if(State == DoorState.Open)
|
else if (State == DoorState.Open)
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,43 +6,43 @@ using Content.Server.GameObjects.Components.VendingMachines;
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using Content.Server.Utility;
|
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components
|
namespace Content.Server.GameObjects.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class WiresComponent : SharedWiresComponent, IInteractUsing, IExamine
|
public class WiresComponent : SharedWiresComponent, IInteractUsing, IExamine, IMapInit
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IRobustRandom _random;
|
[Dependency] private readonly IRobustRandom _random;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
private AudioSystem _audioSystem;
|
private AudioSystem _audioSystem;
|
||||||
private AppearanceComponent _appearance;
|
private AppearanceComponent _appearance;
|
||||||
private BoundUserInterface _userInterface;
|
private BoundUserInterface _userInterface;
|
||||||
|
|
||||||
private bool _isPanelOpen;
|
private bool _isPanelOpen;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opening the maintenance panel (typically with a screwdriver) changes this.
|
/// Opening the maintenance panel (typically with a screwdriver) changes this.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
public bool IsPanelOpen
|
public bool IsPanelOpen
|
||||||
{
|
{
|
||||||
get => _isPanelOpen;
|
get => _isPanelOpen;
|
||||||
@@ -52,15 +52,18 @@ namespace Content.Server.GameObjects.Components
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_isPanelOpen = value;
|
_isPanelOpen = value;
|
||||||
UpdateAppearance();
|
UpdateAppearance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _isPanelVisible = true;
|
private bool _isPanelVisible = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Components can set this to prevent the maintenance panel overlay from showing even if it's open
|
/// Components can set this to prevent the maintenance panel overlay from showing even if it's open
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
public bool IsPanelVisible
|
public bool IsPanelVisible
|
||||||
{
|
{
|
||||||
get => _isPanelVisible;
|
get => _isPanelVisible;
|
||||||
@@ -70,11 +73,34 @@ namespace Content.Server.GameObjects.Components
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_isPanelVisible = value;
|
_isPanelVisible = value;
|
||||||
UpdateAppearance();
|
UpdateAppearance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string BoardName
|
||||||
|
{
|
||||||
|
get => _boardName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_boardName = value;
|
||||||
|
UpdateUserInterface();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string SerialNumber
|
||||||
|
{
|
||||||
|
get => _serialNumber;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_serialNumber = value;
|
||||||
|
UpdateUserInterface();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateAppearance()
|
private void UpdateAppearance()
|
||||||
{
|
{
|
||||||
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen && IsPanelVisible);
|
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen && IsPanelVisible);
|
||||||
@@ -88,26 +114,27 @@ namespace Content.Server.GameObjects.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status messages are displayed at the bottom of the UI.
|
/// Status messages are displayed at the bottom of the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<object, string> _statuses = new Dictionary<object, string>();
|
private readonly Dictionary<object, object> _statuses = new Dictionary<object, object>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="AssignColor"/> and <see cref="WiresBuilder.CreateWire"/>.
|
/// <see cref="AssignAppearance"/> and <see cref="WiresBuilder.CreateWire"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<Color> _availableColors = new List<Color>()
|
private readonly List<WireColor> _availableColors =
|
||||||
{
|
new List<WireColor>((WireColor[]) Enum.GetValues(typeof(WireColor)));
|
||||||
Color.Red,
|
|
||||||
Color.Blue,
|
private readonly List<WireLetter> _availableLetters =
|
||||||
Color.Green,
|
new List<WireLetter>((WireLetter[]) Enum.GetValues(typeof(WireLetter)));
|
||||||
Color.Orange,
|
|
||||||
Color.Brown,
|
private string _boardName;
|
||||||
Color.Gold,
|
|
||||||
Color.Gray,
|
private string _serialNumber;
|
||||||
Color.Cyan,
|
|
||||||
Color.Navy,
|
// Used to generate wire appearance randomization client side.
|
||||||
Color.Purple,
|
// We honestly don't care what it is or such but do care that it doesn't change between UI re-opens.
|
||||||
Color.Pink,
|
[ViewVariables]
|
||||||
Color.Fuchsia,
|
private int _wireSeed;
|
||||||
};
|
[ViewVariables]
|
||||||
|
private string _layoutId;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -120,16 +147,89 @@ namespace Content.Server.GameObjects.Components
|
|||||||
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GenerateSerialNumber()
|
||||||
|
{
|
||||||
|
var random = IoCManager.Resolve<IRobustRandom>();
|
||||||
|
Span<char> data = stackalloc char[9];
|
||||||
|
data[4] = '-';
|
||||||
|
|
||||||
|
if (random.Prob(0.01f))
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
// Cyrillic Letters
|
||||||
|
data[i] = (char) random.Next(0x0410, 0x0430);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
// Letters
|
||||||
|
data[i] = (char) random.Next(0x41, 0x5B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 5; i < 9; i++)
|
||||||
|
{
|
||||||
|
// Digits
|
||||||
|
data[i] = (char) random.Next(0x30, 0x3A);
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialNumber = new string(data);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Startup()
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
base.Startup();
|
base.Startup();
|
||||||
|
|
||||||
|
|
||||||
|
WireLayout layout = null;
|
||||||
|
var hackingSystem = EntitySystem.Get<WireHackingSystem>();
|
||||||
|
if (_layoutId != null)
|
||||||
|
{
|
||||||
|
hackingSystem.TryGetLayout(_layoutId, out layout);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var wiresProvider in Owner.GetAllComponents<IWires>())
|
foreach (var wiresProvider in Owner.GetAllComponents<IWires>())
|
||||||
{
|
{
|
||||||
var builder = new WiresBuilder(this, wiresProvider);
|
var builder = new WiresBuilder(this, wiresProvider, layout);
|
||||||
wiresProvider.RegisterWires(builder);
|
wiresProvider.RegisterWires(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (layout != null)
|
||||||
|
{
|
||||||
|
WiresList.Sort((a, b) =>
|
||||||
|
{
|
||||||
|
var pA = layout.Specifications[a.Identifier].Position;
|
||||||
|
var pB = layout.Specifications[b.Identifier].Position;
|
||||||
|
|
||||||
|
return pA.CompareTo(pB);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IoCManager.Resolve<IRobustRandom>().Shuffle(WiresList);
|
||||||
|
|
||||||
|
if (_layoutId != null)
|
||||||
|
{
|
||||||
|
var dict = new Dictionary<object, WireLayout.WireData>();
|
||||||
|
for (var i = 0; i < WiresList.Count; i++)
|
||||||
|
{
|
||||||
|
var d = WiresList[i];
|
||||||
|
dict.Add(d.Identifier, new WireLayout.WireData(d.Letter, d.Color, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
hackingSystem.AddLayout(_layoutId, new WireLayout(dict));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = 0;
|
||||||
|
foreach (var wire in WiresList)
|
||||||
|
{
|
||||||
|
wire.Id = ++id;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,39 +240,53 @@ namespace Content.Server.GameObjects.Components
|
|||||||
public bool IsWireCut(object identifier)
|
public bool IsWireCut(object identifier)
|
||||||
{
|
{
|
||||||
var wire = WiresList.Find(x => x.Identifier.Equals(identifier));
|
var wire = WiresList.Find(x => x.Identifier.Equals(identifier));
|
||||||
if(wire == null) throw new ArgumentException();
|
if (wire == null) throw new ArgumentException();
|
||||||
return wire.IsCut;
|
return wire.IsCut;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Wire
|
public class Wire
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Used in client-server communication to identify a wire without telling the client what the wire does.
|
|
||||||
/// </summary>
|
|
||||||
public readonly Guid Guid;
|
|
||||||
/// <summary>
|
|
||||||
/// Registered by components implementing IWires, used to identify which wire the client interacted with.
|
|
||||||
/// </summary>
|
|
||||||
public readonly object Identifier;
|
|
||||||
/// <summary>
|
|
||||||
/// The color of the wire. It needs to have a corresponding entry in <see cref="Robust.Shared.Maths.Color.DefaultColors"/>.
|
|
||||||
/// </summary>
|
|
||||||
public readonly Color Color;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The component that registered the wire.
|
/// The component that registered the wire.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly IWires Owner;
|
public IWires Owner { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the wire is cut.
|
/// Whether the wire is cut.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsCut;
|
public bool IsCut { get; set; }
|
||||||
public Wire(Guid guid, object identifier, Color color, IWires owner, bool isCut)
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used in client-server communication to identify a wire without telling the client what the wire does.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The color of the wire.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public WireColor Color { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The greek letter shown below the wire.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public WireLetter Letter { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registered by components implementing IWires, used to identify which wire the client interacted with.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public object Identifier { get; }
|
||||||
|
|
||||||
|
public Wire(IWires owner, bool isCut, WireColor color, WireLetter letter, object identifier)
|
||||||
{
|
{
|
||||||
Guid = guid;
|
|
||||||
Identifier = identifier;
|
|
||||||
Color = color;
|
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
IsCut = isCut;
|
IsCut = isCut;
|
||||||
|
Color = color;
|
||||||
|
Letter = letter;
|
||||||
|
Identifier = identifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,24 +297,42 @@ namespace Content.Server.GameObjects.Components
|
|||||||
{
|
{
|
||||||
[NotNull] private readonly WiresComponent _wires;
|
[NotNull] private readonly WiresComponent _wires;
|
||||||
[NotNull] private readonly IWires _owner;
|
[NotNull] private readonly IWires _owner;
|
||||||
|
[CanBeNull] private readonly WireLayout _layout;
|
||||||
|
|
||||||
public WiresBuilder(WiresComponent wires, IWires owner)
|
public WiresBuilder(WiresComponent wires, IWires owner, WireLayout layout)
|
||||||
{
|
{
|
||||||
_wires = wires;
|
_wires = wires;
|
||||||
_owner = owner;
|
_owner = owner;
|
||||||
|
_layout = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateWire(object identifier, Color? color = null, bool isCut = false)
|
public void CreateWire(object identifier, (WireColor, WireLetter)? appearance = null, bool isCut = false)
|
||||||
{
|
{
|
||||||
if (!color.HasValue)
|
WireLetter letter;
|
||||||
|
WireColor color;
|
||||||
|
if (!appearance.HasValue)
|
||||||
{
|
{
|
||||||
color = _wires.AssignColor();
|
if (_layout != null && _layout.Specifications.TryGetValue(identifier, out var specification))
|
||||||
|
{
|
||||||
|
color = specification.Color;
|
||||||
|
letter = specification.Letter;
|
||||||
|
_wires._availableColors.Remove(color);
|
||||||
|
_wires._availableLetters.Remove(letter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_wires._availableColors.Remove(color.Value);
|
(color, letter) = _wires.AssignAppearance();
|
||||||
}
|
}
|
||||||
_wires.WiresList.Add(new Wire(Guid.NewGuid(), identifier, color.Value, _owner, isCut));
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(color, letter) = appearance.Value;
|
||||||
|
_wires._availableColors.Remove(color);
|
||||||
|
_wires._availableLetters.Remove(letter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ENSURE NO RANDOM OVERLAP.
|
||||||
|
_wires.WiresList.Add(new Wire(_owner, isCut, color, letter, identifier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,13 +340,12 @@ namespace Content.Server.GameObjects.Components
|
|||||||
/// Picks a color from <see cref="_availableColors"/> and removes it from the list.
|
/// Picks a color from <see cref="_availableColors"/> and removes it from the list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The picked color.</returns>
|
/// <returns>The picked color.</returns>
|
||||||
private Color AssignColor()
|
private (WireColor, WireLetter) AssignAppearance()
|
||||||
{
|
{
|
||||||
if(_availableColors.Count == 0)
|
var color = _availableColors.Count == 0 ? WireColor.Red : _random.PickAndTake(_availableColors);
|
||||||
{
|
var letter = _availableLetters.Count == 0 ? WireLetter.α : _random.PickAndTake(_availableLetters);
|
||||||
return Color.Black;
|
|
||||||
}
|
return (color, letter);
|
||||||
return _random.PickAndTake(_availableColors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -231,30 +362,41 @@ namespace Content.Server.GameObjects.Components
|
|||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case WiresActionMessage msg:
|
case WiresActionMessage msg:
|
||||||
var wire = WiresList.Find(x => x.Guid == msg.Guid);
|
var wire = WiresList.Find(x => x.Id == msg.Id);
|
||||||
|
if (wire == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var player = serverMsg.Session.AttachedEntity;
|
var player = serverMsg.Session.AttachedEntity;
|
||||||
if (!player.TryGetComponent(out IHandsComponent handsComponent))
|
if (!player.TryGetComponent(out IHandsComponent handsComponent))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You have no hands."));
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player,
|
||||||
|
Loc.GetString("You have no hands."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(player.Transform.MapPosition, Owner.Transform.MapPosition, ignoredEnt: Owner))
|
if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(player.Transform.MapPosition, Owner.Transform.MapPosition, ignoredEnt: Owner))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You can't reach there!"));
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player,
|
||||||
|
Loc.GetString("You can't reach there!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var activeHandEntity = handsComponent.GetActiveHand?.Owner;
|
var activeHandEntity = handsComponent.GetActiveHand?.Owner;
|
||||||
activeHandEntity.TryGetComponent<ToolComponent>(out var tool);
|
ToolComponent tool = null;
|
||||||
|
activeHandEntity?.TryGetComponent(out tool);
|
||||||
|
|
||||||
switch (msg.Action)
|
switch (msg.Action)
|
||||||
{
|
{
|
||||||
case WiresAction.Cut:
|
case WiresAction.Cut:
|
||||||
if (tool == null || !tool.HasQuality(ToolQuality.Cutting))
|
if (tool == null || !tool.HasQuality(ToolQuality.Cutting))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You need to hold a wirecutter in your hand!"));
|
_notifyManager.PopupMessageCursor(player,
|
||||||
|
Loc.GetString("You need to hold a wirecutter in your hand!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tool.PlayUseSound();
|
tool.PlayUseSound();
|
||||||
wire.IsCut = true;
|
wire.IsCut = true;
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
@@ -262,9 +404,11 @@ namespace Content.Server.GameObjects.Components
|
|||||||
case WiresAction.Mend:
|
case WiresAction.Mend:
|
||||||
if (tool == null || !tool.HasQuality(ToolQuality.Cutting))
|
if (tool == null || !tool.HasQuality(ToolQuality.Cutting))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You need to hold a wirecutter in your hand!"));
|
_notifyManager.PopupMessageCursor(player,
|
||||||
|
Loc.GetString("You need to hold a wirecutter in your hand!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tool.PlayUseSound();
|
tool.PlayUseSound();
|
||||||
wire.IsCut = false;
|
wire.IsCut = false;
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
@@ -272,17 +416,22 @@ namespace Content.Server.GameObjects.Components
|
|||||||
case WiresAction.Pulse:
|
case WiresAction.Pulse:
|
||||||
if (tool == null || !tool.HasQuality(ToolQuality.Multitool))
|
if (tool == null || !tool.HasQuality(ToolQuality.Multitool))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You need to hold a multitool in your hand!"));
|
_notifyManager.PopupMessageCursor(player,
|
||||||
|
Loc.GetString("You need to hold a multitool in your hand!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wire.IsCut)
|
if (wire.IsCut)
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You can't pulse a wire that's been cut!"));
|
_notifyManager.PopupMessageCursor(player,
|
||||||
|
Loc.GetString("You can't pulse a wire that's been cut!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_audioSystem.Play("/Audio/effects/multitool_pulse.ogg", Owner);
|
_audioSystem.Play("/Audio/effects/multitool_pulse.ogg", Owner);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wire.Owner.WiresUpdate(new WiresUpdateEventArgs(wire.Identifier, msg.Action));
|
wire.Owner.WiresUpdate(new WiresUpdateEventArgs(wire.Identifier, msg.Action));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -293,9 +442,27 @@ namespace Content.Server.GameObjects.Components
|
|||||||
var clientList = new List<ClientWire>();
|
var clientList = new List<ClientWire>();
|
||||||
foreach (var entry in WiresList)
|
foreach (var entry in WiresList)
|
||||||
{
|
{
|
||||||
clientList.Add(new ClientWire(entry.Guid, entry.Color, entry.IsCut));
|
clientList.Add(new ClientWire(entry.Id, entry.IsCut, entry.Color,
|
||||||
|
entry.Letter));
|
||||||
}
|
}
|
||||||
_userInterface.SetState(new WiresBoundUserInterfaceState(clientList, _statuses.Values.ToList()));
|
|
||||||
|
_userInterface.SetState(
|
||||||
|
new WiresBoundUserInterfaceState(
|
||||||
|
clientList.ToArray(),
|
||||||
|
_statuses.Select(p => new StatusEntry(p.Key, p.Value)).ToArray(),
|
||||||
|
BoardName,
|
||||||
|
SerialNumber,
|
||||||
|
_wireSeed));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
|
||||||
|
serializer.DataField(ref _boardName, "BoardName", "Wires");
|
||||||
|
serializer.DataField(ref _serialNumber, "SerialNumber", null);
|
||||||
|
serializer.DataField(ref _wireSeed, "WireSeed", 0);
|
||||||
|
serializer.DataField(ref _layoutId, "LayoutId", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
@@ -307,7 +474,8 @@ namespace Content.Server.GameObjects.Components
|
|||||||
|
|
||||||
IsPanelOpen = !IsPanelOpen;
|
IsPanelOpen = !IsPanelOpen;
|
||||||
EntitySystem.Get<AudioSystem>()
|
EntitySystem.Get<AudioSystem>()
|
||||||
.Play(IsPanelOpen ? "/Audio/machines/screwdriveropen.ogg" : "/Audio/machines/screwdriverclose.ogg", Owner);
|
.Play(IsPanelOpen ? "/Audio/machines/screwdriveropen.ogg" : "/Audio/machines/screwdriverclose.ogg",
|
||||||
|
Owner);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,17 +488,32 @@ namespace Content.Server.GameObjects.Components
|
|||||||
: "The [color=lightgray]maintenance panel[/color] is [color=darkred]closed[/color]."));
|
: "The [color=lightgray]maintenance panel[/color] is [color=darkred]closed[/color]."));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStatus(object statusIdentifier, string newMessage)
|
public void SetStatus(object statusIdentifier, object status)
|
||||||
{
|
{
|
||||||
if (_statuses.TryGetValue(statusIdentifier, out var storedMessage))
|
if (_statuses.TryGetValue(statusIdentifier, out var storedMessage))
|
||||||
{
|
{
|
||||||
if (storedMessage == newMessage)
|
if (storedMessage == status)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_statuses[statusIdentifier] = newMessage;
|
|
||||||
|
_statuses[statusIdentifier] = status;
|
||||||
|
UpdateUserInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IMapInit.MapInit()
|
||||||
|
{
|
||||||
|
if (SerialNumber == null)
|
||||||
|
{
|
||||||
|
GenerateSerialNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_wireSeed == 0)
|
||||||
|
{
|
||||||
|
_wireSeed = IoCManager.Resolve<IRobustRandom>().Next(1, int.MaxValue);
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
|
{
|
||||||
|
public class WireHackingSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[ViewVariables] private readonly Dictionary<string, WireLayout> _layouts =
|
||||||
|
new Dictionary<string, WireLayout>();
|
||||||
|
|
||||||
|
public bool TryGetLayout(string id, out WireLayout layout)
|
||||||
|
{
|
||||||
|
return _layouts.TryGetValue(id, out layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLayout(string id, WireLayout layout)
|
||||||
|
{
|
||||||
|
_layouts.Add(id, layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetLayouts()
|
||||||
|
{
|
||||||
|
_layouts.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class WireLayout
|
||||||
|
{
|
||||||
|
[ViewVariables] public IReadOnlyDictionary<object, WireData> Specifications { get; }
|
||||||
|
|
||||||
|
public WireLayout(IReadOnlyDictionary<object, WireData> specifications)
|
||||||
|
{
|
||||||
|
Specifications = specifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class WireData
|
||||||
|
{
|
||||||
|
public WireLetter Letter { get; }
|
||||||
|
public WireColor Color { get; }
|
||||||
|
public int Position { get; }
|
||||||
|
|
||||||
|
public WireData(WireLetter letter, WireColor color, int position)
|
||||||
|
{
|
||||||
|
Letter = letter;
|
||||||
|
Color = color;
|
||||||
|
Position = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ using Content.Server.GameObjects.Components.Access;
|
|||||||
using Content.Server.GameObjects.Components.Markers;
|
using Content.Server.GameObjects.Components.Markers;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Observer;
|
using Content.Server.GameObjects.Components.Observer;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.GameTicking.GamePresets;
|
using Content.Server.GameTicking.GamePresets;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.Chat;
|
using Content.Server.Interfaces.Chat;
|
||||||
@@ -26,6 +27,7 @@ using Robust.Server.ServerStatus;
|
|||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Enums;
|
using Robust.Shared.Enums;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.Configuration;
|
using Robust.Shared.Interfaces.Configuration;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
@@ -469,6 +471,8 @@ namespace Content.Server.GameTicking
|
|||||||
|
|
||||||
_spawnedPositions.Clear();
|
_spawnedPositions.Clear();
|
||||||
_manifest.Clear();
|
_manifest.Clear();
|
||||||
|
|
||||||
|
EntitySystem.Get<WireHackingSystem>().ResetLayouts();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _preRoundSetup()
|
private void _preRoundSetup()
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.GameObjects.Components.Doors
|
||||||
|
{
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum AirlockWireStatus
|
||||||
|
{
|
||||||
|
PowerIndicator,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects.Components
|
namespace Content.Shared.GameObjects.Components
|
||||||
{
|
{
|
||||||
@@ -31,44 +34,257 @@ namespace Content.Shared.GameObjects.Components
|
|||||||
Pulse,
|
Pulse,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum StatusLightState
|
||||||
|
{
|
||||||
|
Off,
|
||||||
|
On,
|
||||||
|
BlinkingFast,
|
||||||
|
BlinkingSlow
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
[PublicAPI]
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum WireLetter : byte
|
||||||
|
{
|
||||||
|
α,
|
||||||
|
β,
|
||||||
|
γ,
|
||||||
|
δ,
|
||||||
|
ε,
|
||||||
|
ζ,
|
||||||
|
η,
|
||||||
|
θ,
|
||||||
|
ι,
|
||||||
|
κ,
|
||||||
|
λ,
|
||||||
|
μ,
|
||||||
|
ν,
|
||||||
|
ξ,
|
||||||
|
ο,
|
||||||
|
π,
|
||||||
|
ρ,
|
||||||
|
σ,
|
||||||
|
τ,
|
||||||
|
υ,
|
||||||
|
φ,
|
||||||
|
χ,
|
||||||
|
ψ,
|
||||||
|
ω
|
||||||
|
}
|
||||||
|
|
||||||
|
[PublicAPI]
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum WireColor : byte
|
||||||
|
{
|
||||||
|
Red,
|
||||||
|
Blue,
|
||||||
|
Green,
|
||||||
|
Orange,
|
||||||
|
Brown,
|
||||||
|
Gold,
|
||||||
|
Gray,
|
||||||
|
Cyan,
|
||||||
|
Navy,
|
||||||
|
Purple,
|
||||||
|
Pink,
|
||||||
|
Fuchsia
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public struct StatusLightData
|
||||||
|
{
|
||||||
|
public StatusLightData(Color color, StatusLightState state, string text)
|
||||||
|
{
|
||||||
|
Color = color;
|
||||||
|
State = state;
|
||||||
|
Text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color Color { get; }
|
||||||
|
public StatusLightState State { get; }
|
||||||
|
public string Text { get; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Color: {Color}, State: {State}, Text: {Text}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class WiresBoundUserInterfaceState : BoundUserInterfaceState
|
public class WiresBoundUserInterfaceState : BoundUserInterfaceState
|
||||||
{
|
{
|
||||||
public readonly List<ClientWire> WiresList;
|
public string BoardName { get; }
|
||||||
public readonly List<string> Statuses;
|
public string SerialNumber { get; }
|
||||||
|
public ClientWire[] WiresList { get; }
|
||||||
|
public StatusEntry[] Statuses { get; }
|
||||||
|
public int WireSeed { get; }
|
||||||
|
|
||||||
public WiresBoundUserInterfaceState(List<ClientWire> wiresList, List<string> statuses)
|
public WiresBoundUserInterfaceState(ClientWire[] wiresList, StatusEntry[] statuses, string boardName, string serialNumber, int wireSeed)
|
||||||
{
|
{
|
||||||
|
BoardName = boardName;
|
||||||
|
SerialNumber = serialNumber;
|
||||||
|
WireSeed = wireSeed;
|
||||||
WiresList = wiresList;
|
WiresList = wiresList;
|
||||||
Statuses = statuses;
|
Statuses = statuses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public struct StatusEntry
|
||||||
|
{
|
||||||
|
public readonly object Key;
|
||||||
|
public readonly object Value;
|
||||||
|
|
||||||
|
public StatusEntry(object key, object value)
|
||||||
|
{
|
||||||
|
Key = key;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{Key}, {Value}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class ClientWire
|
public class ClientWire
|
||||||
{
|
{
|
||||||
public Guid Guid;
|
public int Id;
|
||||||
public Color Color;
|
|
||||||
public bool IsCut;
|
public bool IsCut;
|
||||||
|
public WireColor Color;
|
||||||
|
public WireLetter Letter;
|
||||||
|
|
||||||
public ClientWire(Guid guid, Color color, bool isCut)
|
public ClientWire(int id, bool isCut, WireColor color, WireLetter letter)
|
||||||
{
|
{
|
||||||
Guid = guid;
|
Id = id;
|
||||||
Color = color;
|
|
||||||
IsCut = isCut;
|
IsCut = isCut;
|
||||||
|
Letter = letter;
|
||||||
|
Color = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class WiresActionMessage : BoundUserInterfaceMessage
|
public class WiresActionMessage : BoundUserInterfaceMessage
|
||||||
{
|
{
|
||||||
public readonly Guid Guid;
|
public readonly int Id;
|
||||||
public readonly WiresAction Action;
|
public readonly WiresAction Action;
|
||||||
public WiresActionMessage(Guid guid, WiresAction action)
|
|
||||||
|
public WiresActionMessage(int id, WiresAction action)
|
||||||
{
|
{
|
||||||
Guid = guid;
|
Id = id;
|
||||||
Action = action;
|
Action = action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class HackingWiresExt
|
||||||
|
{
|
||||||
|
public static string Name(this WireColor color)
|
||||||
|
{
|
||||||
|
return Loc.GetString(color switch
|
||||||
|
{
|
||||||
|
WireColor.Red => "Red",
|
||||||
|
WireColor.Blue => "Blue",
|
||||||
|
WireColor.Green => "Green",
|
||||||
|
WireColor.Orange => "Orange",
|
||||||
|
WireColor.Brown => "Brown",
|
||||||
|
WireColor.Gold => "Gold",
|
||||||
|
WireColor.Gray => "Gray",
|
||||||
|
WireColor.Cyan => "Cyan",
|
||||||
|
WireColor.Navy => "Navy",
|
||||||
|
WireColor.Purple => "Purple",
|
||||||
|
WireColor.Pink => "Pink",
|
||||||
|
WireColor.Fuchsia => "Fuchsia",
|
||||||
|
_ => throw new InvalidOperationException()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color ColorValue(this WireColor color)
|
||||||
|
{
|
||||||
|
return color switch
|
||||||
|
{
|
||||||
|
WireColor.Red => Color.Red,
|
||||||
|
WireColor.Blue => Color.Blue,
|
||||||
|
WireColor.Green => Color.Green,
|
||||||
|
WireColor.Orange => Color.Orange,
|
||||||
|
WireColor.Brown => Color.Brown,
|
||||||
|
WireColor.Gold => Color.Gold,
|
||||||
|
WireColor.Gray => Color.Gray,
|
||||||
|
WireColor.Cyan => Color.Cyan,
|
||||||
|
WireColor.Navy => Color.Navy,
|
||||||
|
WireColor.Purple => Color.Purple,
|
||||||
|
WireColor.Pink => Color.Pink,
|
||||||
|
WireColor.Fuchsia => Color.Fuchsia,
|
||||||
|
_ => throw new InvalidOperationException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Name(this WireLetter letter)
|
||||||
|
{
|
||||||
|
return Loc.GetString(letter switch
|
||||||
|
{
|
||||||
|
WireLetter.α => "Alpha",
|
||||||
|
WireLetter.β => "Beta",
|
||||||
|
WireLetter.γ => "Gamma",
|
||||||
|
WireLetter.δ => "Delta",
|
||||||
|
WireLetter.ε => "Epsilon",
|
||||||
|
WireLetter.ζ => "Zeta",
|
||||||
|
WireLetter.η => "Eta",
|
||||||
|
WireLetter.θ => "Theta",
|
||||||
|
WireLetter.ι => "Iota",
|
||||||
|
WireLetter.κ => "Kappa",
|
||||||
|
WireLetter.λ => "Lambda",
|
||||||
|
WireLetter.μ => "Mu",
|
||||||
|
WireLetter.ν => "Nu",
|
||||||
|
WireLetter.ξ => "Xi",
|
||||||
|
WireLetter.ο => "Omicron",
|
||||||
|
WireLetter.π => "Pi",
|
||||||
|
WireLetter.ρ => "Rho",
|
||||||
|
WireLetter.σ => "Sigma",
|
||||||
|
WireLetter.τ => "Tau",
|
||||||
|
WireLetter.υ => "Upsilon",
|
||||||
|
WireLetter.φ => "Phi",
|
||||||
|
WireLetter.χ => "Chi",
|
||||||
|
WireLetter.ψ => "Psi",
|
||||||
|
WireLetter.ω => "Omega",
|
||||||
|
_ => throw new InvalidOperationException()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static char Letter(this WireLetter letter)
|
||||||
|
{
|
||||||
|
return letter switch
|
||||||
|
{
|
||||||
|
WireLetter.α => 'α',
|
||||||
|
WireLetter.β => 'β',
|
||||||
|
WireLetter.γ => 'γ',
|
||||||
|
WireLetter.δ => 'δ',
|
||||||
|
WireLetter.ε => 'ε',
|
||||||
|
WireLetter.ζ => 'ζ',
|
||||||
|
WireLetter.η => 'η',
|
||||||
|
WireLetter.θ => 'θ',
|
||||||
|
WireLetter.ι => 'ι',
|
||||||
|
WireLetter.κ => 'κ',
|
||||||
|
WireLetter.λ => 'λ',
|
||||||
|
WireLetter.μ => 'μ',
|
||||||
|
WireLetter.ν => 'ν',
|
||||||
|
WireLetter.ξ => 'ξ',
|
||||||
|
WireLetter.ο => 'ο',
|
||||||
|
WireLetter.π => 'π',
|
||||||
|
WireLetter.ρ => 'ρ',
|
||||||
|
WireLetter.σ => 'σ',
|
||||||
|
WireLetter.τ => 'τ',
|
||||||
|
WireLetter.υ => 'υ',
|
||||||
|
WireLetter.φ => 'φ',
|
||||||
|
WireLetter.χ => 'χ',
|
||||||
|
WireLetter.ψ => 'ψ',
|
||||||
|
WireLetter.ω => 'ω',
|
||||||
|
_ => throw new InvalidOperationException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
Content.Tests/Shared/WireHackingTest.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Shared.GameObjects.Components;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Robust.UnitTesting;
|
||||||
|
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||||
|
|
||||||
|
namespace Content.Tests.Shared
|
||||||
|
{
|
||||||
|
// Making sure nobody forgets to set values for these wire colors/letters.
|
||||||
|
// Also a thinly veiled excuse to bloat the test count.
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class WireHackingTest : RobustUnitTest
|
||||||
|
{
|
||||||
|
public static IEnumerable<WireColor> ColorValues = (WireColor[]) Enum.GetValues(typeof(WireColor));
|
||||||
|
public static IEnumerable<WireLetter> LetterValues = (WireLetter[]) Enum.GetValues(typeof(WireLetter));
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestColorNameExists([ValueSource(nameof(ColorValues))] WireColor color)
|
||||||
|
{
|
||||||
|
Assert.DoesNotThrow(() => color.Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestColorValueExists([ValueSource(nameof(ColorValues))] WireColor color)
|
||||||
|
{
|
||||||
|
Assert.DoesNotThrow(() => color.ColorValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLetterNameExists([ValueSource(nameof(LetterValues))] WireLetter letter)
|
||||||
|
{
|
||||||
|
Assert.DoesNotThrow(() => letter.Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLetterLetterExists([ValueSource(nameof(LetterValues))] WireLetter letter)
|
||||||
|
{
|
||||||
|
Assert.DoesNotThrow(() => letter.Letter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Resources/Fonts/Boxfont-round/Boxfont Round.ttf
Normal file
2
Resources/Fonts/Boxfont-round/credits.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
https://fontlibrary.org/en/font/boxfont-round
|
||||||
|
License: CC-0
|
||||||
@@ -42,6 +42,8 @@
|
|||||||
- type: WiresVisualizer2D
|
- type: WiresVisualizer2D
|
||||||
- type: PowerDevice
|
- type: PowerDevice
|
||||||
- type: Wires
|
- type: Wires
|
||||||
|
BoardName: "Airlock Control"
|
||||||
|
LayoutId: Airlock
|
||||||
- type: UserInterface
|
- type: UserInterface
|
||||||
interfaces:
|
interfaces:
|
||||||
- key: enum.WiresUiKey.Key
|
- key: enum.WiresUiKey.Key
|
||||||
|
|||||||
@@ -44,6 +44,8 @@
|
|||||||
- type: PowerDevice
|
- type: PowerDevice
|
||||||
priority: Low
|
priority: Low
|
||||||
- type: Wires
|
- type: Wires
|
||||||
|
BoardName: "Vending Machine"
|
||||||
|
LayoutId: Vending
|
||||||
- type: Anchorable
|
- type: Anchorable
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
71
Resources/Textures/UserInterface/WireHacking/contact.svg
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/contact.svg.96dpi.png"
|
||||||
|
sodipodi:docname="contact.svg"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
id="svg1055"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 5.2916665 5.2916667"
|
||||||
|
height="20"
|
||||||
|
width="20">
|
||||||
|
<defs
|
||||||
|
id="defs1049" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:snap-page="true"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="13.143062"
|
||||||
|
inkscape:cx="7.9388602"
|
||||||
|
inkscape:zoom="16.596042"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata1052">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(-79.848503,-133.93878)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1">
|
||||||
|
<path
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Nano/button.svg.96dpi.png"
|
||||||
|
sodipodi:nodetypes="ccccccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="rect1684"
|
||||||
|
d="m 79.848503,133.93878 v 4.23333 l 1.058333,1.05834 4.233334,0 v -4.23334 l -1.058334,-1.05833 z"
|
||||||
|
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.672306;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 182 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="10"
|
||||||
|
height="10"
|
||||||
|
viewBox="0 0 2.6458333 2.6458334"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1067"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
sodipodi:docname="light_off_base.svg"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/light_off_base.svg.96dpi.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96">
|
||||||
|
<defs
|
||||||
|
id="defs1061" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="48.200006"
|
||||||
|
inkscape:cx="5.9595811"
|
||||||
|
inkscape:cy="6.1399278"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata1064">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<circle
|
||||||
|
r="1.3229166"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke-width:0.822271;stroke-linejoin:round;stop-color:#000000"
|
||||||
|
id="path1630"
|
||||||
|
cx="1.3229166"
|
||||||
|
cy="1.3229166" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 212 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/light_on_base.svg.96dpi.png"
|
||||||
|
sodipodi:docname="light_on_base.svg"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
id="svg1656"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 5.2916665 5.2916668"
|
||||||
|
height="20"
|
||||||
|
width="20">
|
||||||
|
<defs
|
||||||
|
id="defs1650" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
units="px"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="13.844648"
|
||||||
|
inkscape:cx="10.215346"
|
||||||
|
inkscape:zoom="32.858486"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata1653">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1">
|
||||||
|
<circle
|
||||||
|
r="2.6458333"
|
||||||
|
cy="2.6458333"
|
||||||
|
cx="2.6458333"
|
||||||
|
id="path2219"
|
||||||
|
style="fill:#ffffff;stroke-width:4.8121;stroke-linejoin:round;stop-color:#000000" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 345 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
68
Resources/Textures/UserInterface/WireHacking/wire_1.svg
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/wire_1.svg.96dpi.png"
|
||||||
|
sodipodi:docname="wire_1.svg"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
id="svg2245"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 4.2333332 13.229168"
|
||||||
|
height="50"
|
||||||
|
width="16">
|
||||||
|
<defs
|
||||||
|
id="defs2239" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
units="px"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="32.466344"
|
||||||
|
inkscape:cx="0.28200599"
|
||||||
|
inkscape:zoom="16"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2242">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1">
|
||||||
|
<path
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/path2808.png"
|
||||||
|
sodipodi:nodetypes="cssssc"
|
||||||
|
id="path2808"
|
||||||
|
d="m 2.1166667,0 v 0.79613126 c 0,0.78760474 -1.0120136,2.42170104 -0.793751,3.17261784 C 1.4470644,4.3958736 3.8422507,6.0675058 2.554148,7.5607995 0.659652,9.7570832 2.1232809,10.802432 2.1232809,11.958902 v 1.270265"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1.45521169;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 554 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="16"
|
||||||
|
height="50"
|
||||||
|
viewBox="0 0 4.2333332 13.229168"
|
||||||
|
version="1.1"
|
||||||
|
id="svg2245"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
sodipodi:docname="wire_1_copper.svg"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/wire_1_copper.svg.96dpi.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96">
|
||||||
|
<defs
|
||||||
|
id="defs2239" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="16.596042"
|
||||||
|
inkscape:cx="3.6251654"
|
||||||
|
inkscape:cy="20.811313"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2242">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 2.1166667,0.79613126 c 0,0.71990754 -1.0996836,1.90834794 -1.1076036,2.68421504 0,0 1.0503303,1.4967767 1.2175433,1.8433776 m 1.0130953,1.4005037 c 0,0 -0.3977935,1.5923631 -0.4631103,1.6724885 C 1.1487967,10.393567 2.1232809,10.847046 2.1232809,11.958902"
|
||||||
|
id="path2808"
|
||||||
|
sodipodi:nodetypes="csccsc"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/path2808.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 524 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
68
Resources/Textures/UserInterface/WireHacking/wire_1_cut.svg
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/wire_1_cut.svg.96dpi.png"
|
||||||
|
sodipodi:docname="wire_1_cut.svg"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
id="svg2245"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 4.2333332 13.229168"
|
||||||
|
height="50"
|
||||||
|
width="16">
|
||||||
|
<defs
|
||||||
|
id="defs2239" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
units="px"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="32.466344"
|
||||||
|
inkscape:cx="0.28200599"
|
||||||
|
inkscape:zoom="16"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2242">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1">
|
||||||
|
<path
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/path2808.png"
|
||||||
|
sodipodi:nodetypes="cssccssc"
|
||||||
|
id="path2808"
|
||||||
|
d="m 2.1166667,0 v 0.79613126 c 0,0.71990754 -1.0996836,1.90834794 -1.1076036,2.68421504 0,0 0.6326351,0.8654513 0.7998481,1.2120522 m 1.1950287,2.7625683 c 0,0 -0.1620317,0.8616239 -0.2273485,0.9417493 C 1.1487967,10.393567 2.1232809,10.847046 2.1232809,11.958902 v 1.270265"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1.45521;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 498 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
68
Resources/Textures/UserInterface/WireHacking/wire_2.svg
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="16"
|
||||||
|
height="50"
|
||||||
|
viewBox="0 0 4.2333332 13.229168"
|
||||||
|
version="1.1"
|
||||||
|
id="svg2245"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
sodipodi:docname="wire_2.svg"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/wire_2.svg.96dpi.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96">
|
||||||
|
<defs
|
||||||
|
id="defs2239" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="16.596042"
|
||||||
|
inkscape:cx="5.0983612"
|
||||||
|
inkscape:cy="25.635501"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2242">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1.45521;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 2.1166667,0 v 0.79613126 c 0,0.78760474 -0.5971633,2.27740564 -0.3789007,3.02832244 0.1241487,0.4271245 0.7517153,2.4865506 0.3834964,3.7183084 -0.8307376,2.7789659 0.00202,3.2596699 0.00202,4.4161399 v 1.270265"
|
||||||
|
id="path2808"
|
||||||
|
sodipodi:nodetypes="cssssc"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/path2808.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 500 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/wire_copper_2.svg.96dpi.png"
|
||||||
|
sodipodi:docname="wire_2_copper.svg"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
id="svg2245"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 4.2333332 13.229168"
|
||||||
|
height="50"
|
||||||
|
width="16">
|
||||||
|
<defs
|
||||||
|
id="defs2239" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
units="px"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="24.153232"
|
||||||
|
inkscape:cx="6.7373069"
|
||||||
|
inkscape:zoom="17.214288"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2242">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1">
|
||||||
|
<path
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/path2808.png"
|
||||||
|
sodipodi:nodetypes="cssccssc"
|
||||||
|
id="path2808"
|
||||||
|
d="m 2.1166667,0 v 0.79613126 c 0,0.63154634 -0.3962617,2.17791674 -0.4407643,3.15307984 -0.010997,0.240968 0.1844183,1.1549069 0.2276656,1.3036958 m 0.5110368,1.2695316 c -0.020506,0.068595 -0.2186245,0.72274 -0.2372771,0.7890946 -0.7370104,2.6218434 -0.054045,3.5194449 -0.054045,4.6473689 v 1.270265"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 451 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
68
Resources/Textures/UserInterface/WireHacking/wire_2_cut.svg
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="16"
|
||||||
|
height="50"
|
||||||
|
viewBox="0 0 4.2333332 13.229168"
|
||||||
|
version="1.1"
|
||||||
|
id="svg2245"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
sodipodi:docname="wire_2_cut.svg"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/wire_2_cut.svg.96dpi.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96">
|
||||||
|
<defs
|
||||||
|
id="defs2239" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="17.855565"
|
||||||
|
inkscape:cx="5.0983612"
|
||||||
|
inkscape:cy="25.635501"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1043"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2242">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1.45521;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 2.1166667,0 v 0.79613126 c 0,0.78760474 -0.6162946,2.99800944 -0.398032,3.74892624 M 2.3427376,7.5240277 C 1.512,10.302994 2.1232824,10.802432 2.1232824,11.958902 v 1.270265"
|
||||||
|
id="path2808"
|
||||||
|
sodipodi:nodetypes="csccsc"
|
||||||
|
inkscape:export-filename="/ssdhome/pj/Projects/space-station-14-content/Resources/Textures/UserInterface/WireHacking/path2808.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 444 B |
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||