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.Shared.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Wires
|
||||
{
|
||||
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)
|
||||
{
|
||||
}
|
||||
@@ -21,7 +15,7 @@ namespace Content.Client.GameObjects.Components.Wires
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
_menu = new WiresMenu(_localizationManager) {Owner = this};
|
||||
_menu = new WiresMenu(this);
|
||||
|
||||
_menu.OnClose += Close;
|
||||
_menu.OpenCentered();
|
||||
@@ -33,9 +27,16 @@ namespace Content.Client.GameObjects.Components.Wires
|
||||
_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.CustomControls;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Wires
|
||||
{
|
||||
public class WiresMenu : SS14Window
|
||||
public class WiresMenu : BaseWindow
|
||||
{
|
||||
private readonly ILocalizationManager _localizationManager;
|
||||
protected override Vector2? CustomSize => (300, 150);
|
||||
public WiresBoundUserInterface Owner { get; set; }
|
||||
public WiresBoundUserInterface Owner { get; }
|
||||
|
||||
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;
|
||||
Title = _localizationManager.GetString("Wires");
|
||||
_wiresContainer = new VBoxContainer();
|
||||
Contents.AddChild(_wiresContainer);
|
||||
var resourceCache = IoCManager.Resolve<IResourceCache>();
|
||||
|
||||
Owner = owner;
|
||||
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)
|
||||
{
|
||||
_wiresContainer.RemoveAllChildren();
|
||||
_nameLabel.Text = state.BoardName;
|
||||
_serialLabel.Text = state.SerialNumber;
|
||||
|
||||
_wiresHBox.RemoveAllChildren();
|
||||
var random = new Random(state.WireSeed);
|
||||
foreach (var wire in state.WiresList)
|
||||
{
|
||||
var container = new HBoxContainer();
|
||||
var newLabel = new Label()
|
||||
var mirror = random.Next(2) == 0;
|
||||
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())}: ",
|
||||
FontColorOverride = wire.Color,
|
||||
SizeFlagsVertical = SizeFlags.ShrinkEnd
|
||||
};
|
||||
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)
|
||||
{
|
||||
var container = new HBoxContainer();
|
||||
container.AddChild(new Label
|
||||
if (status.Value is StatusLightData statusLightData)
|
||||
{
|
||||
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.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components.Doors;
|
||||
using Content.Shared.GameObjects.Components.Interactable;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -13,6 +12,8 @@ using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent.WiresAction;
|
||||
using Timer = Robust.Shared.Timers.Timer;
|
||||
|
||||
@@ -40,6 +41,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
private CancellationTokenSource _powerWiresPulsedTimerCancel;
|
||||
|
||||
private bool _powerWiresPulsed;
|
||||
|
||||
/// <summary>
|
||||
/// True if either power wire was pulsed in the last <see cref="PowerWiresTimeout"/>.
|
||||
/// </summary>
|
||||
@@ -56,16 +58,30 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
|
||||
private void UpdateWiresStatus()
|
||||
{
|
||||
var powerMessage = "A yellow light is on.";
|
||||
var powerLight = new StatusLightData(Color.Yellow, StatusLightState.On, "POWR");
|
||||
if (PowerWiresPulsed)
|
||||
{
|
||||
powerMessage = "A yellow light is blinking rapidly.";
|
||||
} else if (_wires.IsWireCut(Wires.MainPower) &&
|
||||
powerLight = new StatusLightData(Color.Yellow, StatusLightState.BlinkingFast, "POWR");
|
||||
}
|
||||
else if (_wires.IsWireCut(Wires.MainPower) &&
|
||||
_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()
|
||||
@@ -125,19 +141,26 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
/// Mending restores power.
|
||||
/// </summary>
|
||||
MainPower,
|
||||
|
||||
/// <see cref="MainPower"/>
|
||||
BackupPower,
|
||||
}
|
||||
|
||||
private enum WiresStatus
|
||||
{
|
||||
PowerIndicator,
|
||||
}
|
||||
|
||||
public void RegisterWires(WiresComponent.WiresBuilder builder)
|
||||
{
|
||||
builder.CreateWire(Wires.MainPower);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -192,6 +215,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base.Deny();
|
||||
}
|
||||
|
||||
@@ -216,11 +240,10 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
|
||||
if (State == DoorState.Closed)
|
||||
Open();
|
||||
else if(State == DoorState.Open)
|
||||
else if (State == DoorState.Open)
|
||||
Close();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,43 +6,43 @@ using Content.Server.GameObjects.Components.VendingMachines;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.GameObjects.Components.Interactable;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class WiresComponent : SharedWiresComponent, IInteractUsing, IExamine
|
||||
public class WiresComponent : SharedWiresComponent, IInteractUsing, IExamine, IMapInit
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IRobustRandom _random;
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||
#pragma warning restore 649
|
||||
private AudioSystem _audioSystem;
|
||||
private AppearanceComponent _appearance;
|
||||
private BoundUserInterface _userInterface;
|
||||
|
||||
private bool _isPanelOpen;
|
||||
|
||||
/// <summary>
|
||||
/// Opening the maintenance panel (typically with a screwdriver) changes this.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public bool IsPanelOpen
|
||||
{
|
||||
get => _isPanelOpen;
|
||||
@@ -52,15 +52,18 @@ namespace Content.Server.GameObjects.Components
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isPanelOpen = value;
|
||||
UpdateAppearance();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isPanelVisible = true;
|
||||
|
||||
/// <summary>
|
||||
/// Components can set this to prevent the maintenance panel overlay from showing even if it's open
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public bool IsPanelVisible
|
||||
{
|
||||
get => _isPanelVisible;
|
||||
@@ -70,11 +73,34 @@ namespace Content.Server.GameObjects.Components
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isPanelVisible = value;
|
||||
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()
|
||||
{
|
||||
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen && IsPanelVisible);
|
||||
@@ -88,26 +114,27 @@ namespace Content.Server.GameObjects.Components
|
||||
/// <summary>
|
||||
/// Status messages are displayed at the bottom of the UI.
|
||||
/// </summary>
|
||||
private readonly Dictionary<object, string> _statuses = new Dictionary<object, string>();
|
||||
private readonly Dictionary<object, object> _statuses = new Dictionary<object, object>();
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="AssignColor"/> and <see cref="WiresBuilder.CreateWire"/>.
|
||||
/// <see cref="AssignAppearance"/> and <see cref="WiresBuilder.CreateWire"/>.
|
||||
/// </summary>
|
||||
private readonly List<Color> _availableColors = new List<Color>()
|
||||
{
|
||||
Color.Red,
|
||||
Color.Blue,
|
||||
Color.Green,
|
||||
Color.Orange,
|
||||
Color.Brown,
|
||||
Color.Gold,
|
||||
Color.Gray,
|
||||
Color.Cyan,
|
||||
Color.Navy,
|
||||
Color.Purple,
|
||||
Color.Pink,
|
||||
Color.Fuchsia,
|
||||
};
|
||||
private readonly List<WireColor> _availableColors =
|
||||
new List<WireColor>((WireColor[]) Enum.GetValues(typeof(WireColor)));
|
||||
|
||||
private readonly List<WireLetter> _availableLetters =
|
||||
new List<WireLetter>((WireLetter[]) Enum.GetValues(typeof(WireLetter)));
|
||||
|
||||
private string _boardName;
|
||||
|
||||
private string _serialNumber;
|
||||
|
||||
// Used to generate wire appearance randomization client side.
|
||||
// We honestly don't care what it is or such but do care that it doesn't change between UI re-opens.
|
||||
[ViewVariables]
|
||||
private int _wireSeed;
|
||||
[ViewVariables]
|
||||
private string _layoutId;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -120,16 +147,89 @@ namespace Content.Server.GameObjects.Components
|
||||
_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()
|
||||
{
|
||||
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>())
|
||||
{
|
||||
var builder = new WiresBuilder(this, wiresProvider);
|
||||
var builder = new WiresBuilder(this, wiresProvider, layout);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -140,39 +240,53 @@ namespace Content.Server.GameObjects.Components
|
||||
public bool IsWireCut(object 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;
|
||||
}
|
||||
|
||||
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>
|
||||
/// The component that registered the wire.
|
||||
/// </summary>
|
||||
public readonly IWires Owner;
|
||||
public IWires Owner { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the wire is cut.
|
||||
/// </summary>
|
||||
public bool IsCut;
|
||||
public Wire(Guid guid, object identifier, Color color, IWires owner, bool isCut)
|
||||
public bool IsCut { get; set; }
|
||||
|
||||
/// <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;
|
||||
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 IWires _owner;
|
||||
[CanBeNull] private readonly WireLayout _layout;
|
||||
|
||||
public WiresBuilder(WiresComponent wires, IWires owner)
|
||||
public WiresBuilder(WiresComponent wires, IWires owner, WireLayout layout)
|
||||
{
|
||||
_wires = wires;
|
||||
_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
|
||||
{
|
||||
_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.
|
||||
/// </summary>
|
||||
/// <returns>The picked color.</returns>
|
||||
private Color AssignColor()
|
||||
private (WireColor, WireLetter) AssignAppearance()
|
||||
{
|
||||
if(_availableColors.Count == 0)
|
||||
{
|
||||
return Color.Black;
|
||||
}
|
||||
return _random.PickAndTake(_availableColors);
|
||||
var color = _availableColors.Count == 0 ? WireColor.Red : _random.PickAndTake(_availableColors);
|
||||
var letter = _availableLetters.Count == 0 ? WireLetter.α : _random.PickAndTake(_availableLetters);
|
||||
|
||||
return (color, letter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -231,30 +362,41 @@ namespace Content.Server.GameObjects.Components
|
||||
switch (message)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
var activeHandEntity = handsComponent.GetActiveHand?.Owner;
|
||||
activeHandEntity.TryGetComponent<ToolComponent>(out var tool);
|
||||
ToolComponent tool = null;
|
||||
activeHandEntity?.TryGetComponent(out tool);
|
||||
|
||||
switch (msg.Action)
|
||||
{
|
||||
case WiresAction.Cut:
|
||||
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;
|
||||
}
|
||||
|
||||
tool.PlayUseSound();
|
||||
wire.IsCut = true;
|
||||
UpdateUserInterface();
|
||||
@@ -262,9 +404,11 @@ namespace Content.Server.GameObjects.Components
|
||||
case WiresAction.Mend:
|
||||
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;
|
||||
}
|
||||
|
||||
tool.PlayUseSound();
|
||||
wire.IsCut = false;
|
||||
UpdateUserInterface();
|
||||
@@ -272,17 +416,22 @@ namespace Content.Server.GameObjects.Components
|
||||
case WiresAction.Pulse:
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
_audioSystem.Play("/Audio/effects/multitool_pulse.ogg", Owner);
|
||||
break;
|
||||
}
|
||||
|
||||
wire.Owner.WiresUpdate(new WiresUpdateEventArgs(wire.Identifier, msg.Action));
|
||||
break;
|
||||
}
|
||||
@@ -293,9 +442,27 @@ namespace Content.Server.GameObjects.Components
|
||||
var clientList = new List<ClientWire>();
|
||||
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)
|
||||
@@ -307,7 +474,8 @@ namespace Content.Server.GameObjects.Components
|
||||
|
||||
IsPanelOpen = !IsPanelOpen;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -320,17 +488,32 @@ namespace Content.Server.GameObjects.Components
|
||||
: "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 (storedMessage == newMessage)
|
||||
if (storedMessage == status)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.Mobs;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.GameTicking.GamePresets;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
@@ -26,6 +27,7 @@ using Robust.Server.ServerStatus;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
@@ -469,6 +471,8 @@ namespace Content.Server.GameTicking
|
||||
|
||||
_spawnedPositions.Clear();
|
||||
_manifest.Clear();
|
||||
|
||||
EntitySystem.Get<WireHackingSystem>().ResetLayouts();
|
||||
}
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components
|
||||
{
|
||||
@@ -31,44 +34,257 @@ namespace Content.Shared.GameObjects.Components
|
||||
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]
|
||||
public class WiresBoundUserInterfaceState : BoundUserInterfaceState
|
||||
{
|
||||
public readonly List<ClientWire> WiresList;
|
||||
public readonly List<string> Statuses;
|
||||
public string BoardName { get; }
|
||||
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;
|
||||
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]
|
||||
public class ClientWire
|
||||
{
|
||||
public Guid Guid;
|
||||
public Color Color;
|
||||
public int Id;
|
||||
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;
|
||||
Color = color;
|
||||
Id = id;
|
||||
IsCut = isCut;
|
||||
Letter = letter;
|
||||
Color = color;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class WiresActionMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly Guid Guid;
|
||||
public readonly int Id;
|
||||
public readonly WiresAction Action;
|
||||
public WiresActionMessage(Guid guid, WiresAction action)
|
||||
|
||||
public WiresActionMessage(int id, WiresAction action)
|
||||
{
|
||||
Guid = guid;
|
||||
Id = id;
|
||||
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: PowerDevice
|
||||
- type: Wires
|
||||
BoardName: "Airlock Control"
|
||||
LayoutId: Airlock
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
- key: enum.WiresUiKey.Key
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
- type: PowerDevice
|
||||
priority: Low
|
||||
- type: Wires
|
||||
BoardName: "Vending Machine"
|
||||
LayoutId: Vending
|
||||
- type: Anchorable
|
||||
|
||||
- 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
|
||||