diff --git a/Content.Client/Chemistry/Components/SolutionItemStatusComponent.cs b/Content.Client/Chemistry/Components/SolutionItemStatusComponent.cs new file mode 100644 index 0000000000..58c5a05894 --- /dev/null +++ b/Content.Client/Chemistry/Components/SolutionItemStatusComponent.cs @@ -0,0 +1,22 @@ +using Content.Client.Chemistry.EntitySystems; +using Content.Client.Chemistry.UI; + +namespace Content.Client.Chemistry.Components; + +/// +/// Exposes a solution container's contents via a basic item status control. +/// +/// +/// Shows the solution volume, max volume, and transfer amount. +/// +/// +/// +[RegisterComponent] +public sealed partial class SolutionItemStatusComponent : Component +{ + /// + /// The ID of the solution that will be shown on the item status control. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public string Solution = "default"; +} diff --git a/Content.Client/Chemistry/EntitySystems/SolutionItemStatusSystem.cs b/Content.Client/Chemistry/EntitySystems/SolutionItemStatusSystem.cs new file mode 100644 index 0000000000..76aab516a7 --- /dev/null +++ b/Content.Client/Chemistry/EntitySystems/SolutionItemStatusSystem.cs @@ -0,0 +1,22 @@ +using Content.Client.Chemistry.Components; +using Content.Client.Chemistry.UI; +using Content.Client.Items; +using Content.Shared.Chemistry.EntitySystems; + +namespace Content.Client.Chemistry.EntitySystems; + +/// +/// Wires up item status logic for . +/// +/// +public sealed class SolutionItemStatusSystem : EntitySystem +{ + [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; + + public override void Initialize() + { + base.Initialize(); + Subs.ItemStatus( + entity => new SolutionStatusControl(entity, EntityManager, _solutionContainerSystem)); + } +} diff --git a/Content.Client/Chemistry/UI/SolutionStatusControl.cs b/Content.Client/Chemistry/UI/SolutionStatusControl.cs new file mode 100644 index 0000000000..1a33ffb0e1 --- /dev/null +++ b/Content.Client/Chemistry/UI/SolutionStatusControl.cs @@ -0,0 +1,59 @@ +using Content.Client.Chemistry.Components; +using Content.Client.Chemistry.EntitySystems; +using Content.Client.Items.UI; +using Content.Client.Message; +using Content.Client.Stylesheets; +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.FixedPoint; +using Robust.Client.UserInterface.Controls; + +namespace Content.Client.Chemistry.UI; + +/// +/// Displays basic solution information for . +/// +/// +public sealed class SolutionStatusControl : PollingItemStatusControl +{ + private readonly Entity _parent; + private readonly IEntityManager _entityManager; + private readonly SharedSolutionContainerSystem _solutionContainers; + private readonly RichTextLabel _label; + + public SolutionStatusControl( + Entity parent, + IEntityManager entityManager, + SharedSolutionContainerSystem solutionContainers) + { + _parent = parent; + _entityManager = entityManager; + _solutionContainers = solutionContainers; + _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } }; + AddChild(_label); + } + + protected override Data PollData() + { + if (!_solutionContainers.TryGetSolution(_parent.Owner, _parent.Comp.Solution, out _, out var solution)) + return default; + + FixedPoint2? transferAmount = null; + if (_entityManager.TryGetComponent(_parent.Owner, out SolutionTransferComponent? transfer)) + transferAmount = transfer.TransferAmount; + + return new Data(solution.Volume, solution.MaxVolume, transferAmount); + } + + protected override void Update(in Data data) + { + var markup = Loc.GetString("solution-status-volume", + ("currentVolume", data.Volume), + ("maxVolume", data.MaxVolume)); + if (data.TransferVolume is { } transferVolume) + markup += "\n" + Loc.GetString("solution-status-transfer", ("volume", transferVolume)); + _label.SetMarkup(markup); + } + + public readonly record struct Data(FixedPoint2 Volume, FixedPoint2 MaxVolume, FixedPoint2? TransferVolume); +} diff --git a/Content.Client/Items/UI/PollingItemStatusControl.cs b/Content.Client/Items/UI/PollingItemStatusControl.cs new file mode 100644 index 0000000000..39cffb06f6 --- /dev/null +++ b/Content.Client/Items/UI/PollingItemStatusControl.cs @@ -0,0 +1,28 @@ +using Robust.Client.UserInterface; +using Robust.Shared.Timing; + +namespace Content.Client.Items.UI; + +/// +/// A base for item status controls that poll data every frame. Avoids UI updates if data didn't change. +/// +/// The full status control data that is polled every frame. +public abstract class PollingItemStatusControl : Control where TData : struct, IEquatable +{ + private TData _lastData; + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + + var newData = PollData(); + if (newData.Equals(_lastData)) + return; + + _lastData = newData; + Update(newData); + } + + protected abstract TData PollData(); + protected abstract void Update(in TData data); +} diff --git a/Content.Client/Stylesheets/StyleNano.cs b/Content.Client/Stylesheets/StyleNano.cs index a589abb83a..5fc17447c3 100644 --- a/Content.Client/Stylesheets/StyleNano.cs +++ b/Content.Client/Stylesheets/StyleNano.cs @@ -1234,6 +1234,11 @@ namespace Content.Client.Stylesheets new StyleProperty("font", notoSans10), }), + Element() + .Class(StyleClassItemStatus) + .Prop(nameof(RichTextLabel.LineHeightScale), 0.7f) + .Prop(nameof(Control.Margin), new Thickness(0, 0, 0, -6)), + // Slider new StyleRule(SelectorElement.Type(typeof(Slider)), new [] { diff --git a/Content.Client/Tools/ToolSystem.cs b/Content.Client/Tools/ToolSystem.cs index 3eb2cc45cb..2207242918 100644 --- a/Content.Client/Tools/ToolSystem.cs +++ b/Content.Client/Tools/ToolSystem.cs @@ -13,7 +13,7 @@ namespace Content.Client.Tools { base.Initialize(); - Subs.ItemStatus(ent => new WelderStatusControl(ent)); + Subs.ItemStatus(ent => new WelderStatusControl(ent, EntityManager, this)); Subs.ItemStatus(ent => new MultipleToolStatusControl(ent)); } diff --git a/Content.Client/Tools/UI/WelderStatusControl.cs b/Content.Client/Tools/UI/WelderStatusControl.cs index dae742efc3..3d44d6fa84 100644 --- a/Content.Client/Tools/UI/WelderStatusControl.cs +++ b/Content.Client/Tools/UI/WelderStatusControl.cs @@ -1,55 +1,45 @@ +using Content.Client.Items.UI; using Content.Client.Message; using Content.Client.Stylesheets; +using Content.Shared.FixedPoint; using Content.Shared.Tools.Components; -using Robust.Client.UserInterface; +using Content.Shared.Tools.Systems; using Robust.Client.UserInterface.Controls; -using Robust.Shared.Timing; namespace Content.Client.Tools.UI; -public sealed class WelderStatusControl : Control +public sealed class WelderStatusControl : PollingItemStatusControl { - [Dependency] private readonly IGameTiming _gameTiming = default!; - - private readonly ToolSystem _tool; - private readonly Entity _parent; + private readonly IEntityManager _entityManager; + private readonly SharedToolSystem _toolSystem; private readonly RichTextLabel _label; - public WelderStatusControl(Entity parent) + public WelderStatusControl(Entity parent, IEntityManager entityManager, SharedToolSystem toolSystem) { - IoCManager.InjectDependencies(this); - _parent = parent; - var entMan = IoCManager.Resolve(); - _tool = entMan.System(); - + _entityManager = entityManager; + _toolSystem = toolSystem; _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } }; AddChild(_label); UpdateDraw(); } - /// - protected override void FrameUpdate(FrameEventArgs args) + protected override Data PollData() { - base.FrameUpdate(args); - - Update(); + var (fuel, capacity) = _toolSystem.GetWelderFuelAndCapacity(_parent, _parent.Comp); + return new Data(fuel, capacity, _parent.Comp.Enabled); } - public void Update() + protected override void Update(in Data data) { - if (!_gameTiming.IsFirstTimePredicted) - return; - - var (fuel, fuelCap) = _tool.GetWelderFuelAndCapacity(_parent, _parent); - var lit = _parent.Comp.Enabled; - _label.SetMarkup(Loc.GetString("welder-component-on-examine-detailed-message", - ("colorName", fuel < fuelCap / 4f ? "darkorange" : "orange"), - ("fuelLeft", Math.Round(fuel.Float(), 1)), - ("fuelCapacity", fuelCap), - ("status", Loc.GetString(lit ? "welder-component-on-examine-welder-lit-message" : "welder-component-on-examine-welder-not-lit-message")))); + ("colorName", data.Fuel < data.FuelCapacity / 4f ? "darkorange" : "orange"), + ("fuelLeft", data.Fuel), + ("fuelCapacity", data.FuelCapacity), + ("status", Loc.GetString(data.Lit ? "welder-component-on-examine-welder-lit-message" : "welder-component-on-examine-welder-not-lit-message")))); } + + public record struct Data(FixedPoint2 Fuel, FixedPoint2 FuelCapacity, bool Lit); } diff --git a/Content.Client/UserInterface/Systems/Hands/HandsUIController.cs b/Content.Client/UserInterface/Systems/Hands/HandsUIController.cs index bb550b0433..e57c15462e 100644 --- a/Content.Client/UserInterface/Systems/Hands/HandsUIController.cs +++ b/Content.Client/UserInterface/Systems/Hands/HandsUIController.cs @@ -28,6 +28,15 @@ public sealed class HandsUIController : UIController, IOnStateEntered _handLookup = new(); private HandsComponent? _playerHandsComponent; private HandButton? _activeHand = null; + + // We only have two item status controls (left and right hand), + // but we may have more than two hands. + // We handle this by having the item status be the *last active* hand of that side. + // These variables store which that is. + // ("middle" hands are hardcoded as right, whatever) + private HandButton? _statusHandLeft; + private HandButton? _statusHandRight; + private int _backupSuffix = 0; //this is used when autogenerating container names if they don't have names private HotbarGui? HandsGui => UIManager.GetActiveUIWidgetOrNull(); @@ -180,8 +189,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered(); _hands = UIManager.GetUIController(); diff --git a/Content.Client/UserInterface/Systems/Hotbar/Widgets/HotbarGui.xaml b/Content.Client/UserInterface/Systems/Hotbar/Widgets/HotbarGui.xaml index 0e9f0c77f9..3afe11ba33 100644 --- a/Content.Client/UserInterface/Systems/Hotbar/Widgets/HotbarGui.xaml +++ b/Content.Client/UserInterface/Systems/Hotbar/Widgets/HotbarGui.xaml @@ -10,21 +10,14 @@ Orientation="Vertical" HorizontalAlignment="Center"> - - - - - - + + + + + ColumnLimit="6"/> + (); - hotbarController.Setup(HandContainer, StatusPanel, StoragePanel); + hotbarController.Setup(HandContainer, StoragePanel); LayoutContainer.SetGrowVertical(this, LayoutContainer.GrowDirection.Begin); } - public void UpdatePanelEntity(EntityUid? entity) + public void UpdatePanelEntityLeft(EntityUid? entity) { - StatusPanel.Update(entity); - if (entity == null) - { - StatusPanel.Visible = false; - return; - } + StatusPanelLeft.Update(entity); + } - StatusPanel.Visible = true; + public void UpdatePanelEntityRight(EntityUid? entity) + { + StatusPanelRight.Update(entity); + } + + public void SetHighlightHand(HandLocation? hand) + { + StatusPanelLeft.UpdateHighlight(hand is HandLocation.Left); + StatusPanelRight.UpdateHighlight(hand is HandLocation.Middle or HandLocation.Right); } } diff --git a/Content.Client/UserInterface/Systems/Inventory/Controls/ItemStatusPanel.xaml b/Content.Client/UserInterface/Systems/Inventory/Controls/ItemStatusPanel.xaml index d469e6ced0..81142d64d2 100644 --- a/Content.Client/UserInterface/Systems/Inventory/Controls/ItemStatusPanel.xaml +++ b/Content.Client/UserInterface/Systems/Inventory/Controls/ItemStatusPanel.xaml @@ -3,22 +3,26 @@ xmlns:controls="clr-namespace:Content.Client.UserInterface.Systems.Inventory.Controls" xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client" VerticalAlignment="Bottom" - HorizontalAlignment="Center" - MinSize="150 0"> - - - - - - - + diff --git a/Content.Client/UserInterface/Systems/Inventory/Controls/ItemStatusPanel.xaml.cs b/Content.Client/UserInterface/Systems/Inventory/Controls/ItemStatusPanel.xaml.cs index 90ae571711..e1fe6ab246 100644 --- a/Content.Client/UserInterface/Systems/Inventory/Controls/ItemStatusPanel.xaml.cs +++ b/Content.Client/UserInterface/Systems/Inventory/Controls/ItemStatusPanel.xaml.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Client.Items; using Content.Client.Resources; using Content.Shared.Hands.Components; @@ -5,6 +6,7 @@ using Content.Shared.IdentityManagement; using Content.Shared.Inventory.VirtualItem; using Robust.Client.AutoGenerated; using Robust.Client.Graphics; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; using Robust.Shared.Timing; @@ -14,12 +16,15 @@ using static Content.Client.IoC.StaticIoC; namespace Content.Client.UserInterface.Systems.Inventory.Controls; [GenerateTypedNameReferences] -public sealed partial class ItemStatusPanel : BoxContainer +public sealed partial class ItemStatusPanel : Control { [Dependency] private readonly IEntityManager _entityManager = default!; [ViewVariables] private EntityUid? _entity; + // Tracked so we can re-run SetSide() if the theme changes. + private HandLocation _side; + public ItemStatusPanel() { RobustXamlLoader.Load(this); @@ -30,41 +35,65 @@ public sealed partial class ItemStatusPanel : BoxContainer public void SetSide(HandLocation location) { - string texture; + // AN IMPORTANT REMINDER ABOUT THIS CODE: + // In the UI, the RIGHT hand is on the LEFT on the screen. + // So that a character facing DOWN matches the hand positions. + + Texture? texture; + Texture? textureHighlight; StyleBox.Margin cutOut; StyleBox.Margin flat; - Label.AlignMode textAlign; + Thickness contentMargin; switch (location) { - case HandLocation.Left: - texture = "/Textures/Interface/Nano/item_status_right.svg.96dpi.png"; - cutOut = StyleBox.Margin.Left | StyleBox.Margin.Top; - flat = StyleBox.Margin.Right | StyleBox.Margin.Bottom; - textAlign = Label.AlignMode.Right; + case HandLocation.Right: + texture = Theme.ResolveTexture("item_status_right"); + textureHighlight = Theme.ResolveTexture("item_status_right_highlight"); + cutOut = StyleBox.Margin.Left; + flat = StyleBox.Margin.Right; + contentMargin = MarginFromThemeColor("_itemstatus_content_margin_right"); break; case HandLocation.Middle: - texture = "/Textures/Interface/Nano/item_status_middle.svg.96dpi.png"; - cutOut = StyleBox.Margin.Right | StyleBox.Margin.Top; - flat = StyleBox.Margin.Left | StyleBox.Margin.Bottom; - textAlign = Label.AlignMode.Left; - break; - case HandLocation.Right: - texture = "/Textures/Interface/Nano/item_status_left.svg.96dpi.png"; - cutOut = StyleBox.Margin.Right | StyleBox.Margin.Top; - flat = StyleBox.Margin.Left | StyleBox.Margin.Bottom; - textAlign = Label.AlignMode.Left; + case HandLocation.Left: + texture = Theme.ResolveTexture("item_status_left"); + textureHighlight = Theme.ResolveTexture("item_status_left_highlight"); + cutOut = StyleBox.Margin.Right; + flat = StyleBox.Margin.Left; + contentMargin = MarginFromThemeColor("_itemstatus_content_margin_left"); break; default: throw new ArgumentOutOfRangeException(nameof(location), location, null); } - var panel = (StyleBoxTexture) Panel.PanelOverride!; - panel.Texture = ResC.GetTexture(texture); - panel.SetPatchMargin(flat, 2); - panel.SetPatchMargin(cutOut, 13); + Contents.Margin = contentMargin; - ItemNameLabel.Align = textAlign; + var panel = (StyleBoxTexture) Panel.PanelOverride!; + panel.Texture = texture; + panel.SetPatchMargin(flat, 4); + panel.SetPatchMargin(cutOut, 7); + + var panelHighlight = (StyleBoxTexture) HighlightPanel.PanelOverride!; + panelHighlight.Texture = textureHighlight; + panelHighlight.SetPatchMargin(flat, 4); + panelHighlight.SetPatchMargin(cutOut, 7); + + _side = location; + } + + private Thickness MarginFromThemeColor(string itemName) + { + // This is the worst thing I've ever programmed + // (can you tell I'm a graphics programmer?) + // (the margin needs to change depending on the UI theme, so we use a fake color entry to store the value) + + var color = Theme.ResolveColorOrSpecified(itemName); + return new Thickness(color.RByte, color.GByte, color.BByte, color.AByte); + } + + protected override void OnThemeUpdated() + { + SetSide(_side); } protected override void FrameUpdate(FrameEventArgs args) @@ -79,7 +108,7 @@ public sealed partial class ItemStatusPanel : BoxContainer { ClearOldStatus(); _entity = null; - Panel.Visible = false; + VisWrapper.Visible = false; return; } @@ -91,7 +120,12 @@ public sealed partial class ItemStatusPanel : BoxContainer UpdateItemName(); } - Panel.Visible = true; + VisWrapper.Visible = true; + } + + public void UpdateHighlight(bool highlight) + { + HighlightPanel.Visible = highlight; } private void UpdateItemName() diff --git a/Content.Client/Weapons/Ranged/ItemStatus/BulletRender.cs b/Content.Client/Weapons/Ranged/ItemStatus/BulletRender.cs new file mode 100644 index 0000000000..492fad3872 --- /dev/null +++ b/Content.Client/Weapons/Ranged/ItemStatus/BulletRender.cs @@ -0,0 +1,178 @@ +using System.Numerics; +using Content.Client.Resources; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Client.UserInterface; + +namespace Content.Client.Weapons.Ranged.ItemStatus; + +/// +/// Renders one or more rows of bullets for item status. +/// +/// +/// This is a custom control to allow complex responsive layout logic. +/// +public sealed class BulletRender : Control +{ + private static readonly Color ColorA = Color.FromHex("#b68f0e"); + private static readonly Color ColorB = Color.FromHex("#d7df60"); + private static readonly Color ColorGoneA = Color.FromHex("#000000"); + private static readonly Color ColorGoneB = Color.FromHex("#222222"); + + /// + /// Try to ensure there's at least this many bullets on one row. + /// + /// + /// For example, if there are two rows and the second row has only two bullets, + /// we "steal" some bullets from the row below it to make it look nicer. + /// + public const int MinCountPerRow = 7; + + public const int BulletHeight = 12; + public const int BulletSeparationNormal = 3; + public const int BulletSeparationTiny = 2; + public const int BulletWidthNormal = 5; + public const int BulletWidthTiny = 2; + public const int VerticalSeparation = 2; + + private readonly Texture _bulletTiny; + private readonly Texture _bulletNormal; + + private int _capacity; + private BulletType _type = BulletType.Normal; + + public int Rows { get; set; } = 2; + public int Count { get; set; } + + public int Capacity + { + get => _capacity; + set + { + _capacity = value; + InvalidateMeasure(); + } + } + + public BulletType Type + { + get => _type; + set + { + _type = value; + InvalidateMeasure(); + } + } + + public BulletRender() + { + var resC = IoCManager.Resolve(); + _bulletTiny = resC.GetTexture("/Textures/Interface/ItemStatus/Bullets/tiny.png"); + _bulletNormal = resC.GetTexture("/Textures/Interface/ItemStatus/Bullets/normal.png"); + } + + protected override Vector2 MeasureOverride(Vector2 availableSize) + { + var countPerRow = Math.Min(Capacity, CountPerRow(availableSize.X)); + + var rows = Math.Min((int) MathF.Ceiling(Capacity / (float) countPerRow), Rows); + + var height = BulletHeight * rows + (BulletSeparationNormal * rows - 1); + var width = RowWidth(countPerRow); + + return new Vector2(width, height); + } + + protected override void Draw(DrawingHandleScreen handle) + { + // Scale rendering in this control by UIScale. + var currentTransform = handle.GetTransform(); + handle.SetTransform(Matrix3.CreateScale(new Vector2(UIScale)) * currentTransform); + + var countPerRow = CountPerRow(Size.X); + + var (separation, _) = BulletParams(); + var texture = Type == BulletType.Normal ? _bulletNormal : _bulletTiny; + + var pos = new Vector2(); + + var altColor = false; + + var spent = Capacity - Count; + + var bulletsDone = 0; + + // Draw by rows, bottom to top. + for (var row = 0; row < Rows; row++) + { + altColor = false; + + var thisRowCount = Math.Min(countPerRow, Capacity - bulletsDone); + if (thisRowCount <= 0) + break; + + // Handle MinCountPerRow + // We only do this if: + // 1. The next row would have less than MinCountPerRow bullets. + // 2. The next row is actually visible (we aren't the last row). + // 3. MinCountPerRow is actually smaller than the count per row (avoid degenerate cases). + var nextRowCount = Capacity - bulletsDone - thisRowCount; + if (nextRowCount < MinCountPerRow && row != Rows - 1 && MinCountPerRow < countPerRow) + thisRowCount -= MinCountPerRow - nextRowCount; + + // Account for row width to right-align. + var rowWidth = RowWidth(thisRowCount); + pos.X += Size.X - rowWidth; + + // Draw row left to right (so overlapping works) + for (var bullet = 0; bullet < thisRowCount; bullet++) + { + var absIdx = Capacity - bulletsDone - thisRowCount + bullet; + Color color; + if (absIdx >= spent) + color = altColor ? ColorA : ColorB; + else + color = altColor ? ColorGoneA : ColorGoneB; + + var renderPos = pos; + renderPos.Y = Size.Y - renderPos.Y - BulletHeight; + handle.DrawTexture(texture, renderPos, color); + pos.X += separation; + altColor ^= true; + } + + bulletsDone += thisRowCount; + pos.X = 0; + pos.Y += BulletHeight + VerticalSeparation; + } + } + + private int CountPerRow(float width) + { + var (separation, bulletWidth) = BulletParams(); + return (int) ((width - bulletWidth + separation) / separation); + } + + private (int separation, int width) BulletParams() + { + return Type switch + { + BulletType.Normal => (BulletSeparationNormal, BulletWidthNormal), + BulletType.Tiny => (BulletSeparationTiny, BulletWidthTiny), + _ => throw new ArgumentOutOfRangeException() + }; + } + + private int RowWidth(int count) + { + var (separation, bulletWidth) = BulletParams(); + + return (count - 1) * separation + bulletWidth; + } + + public enum BulletType + { + Normal, + Tiny + } +} diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.AmmoCounter.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.AmmoCounter.cs index 32343af56f..cc7405b047 100644 --- a/Content.Client/Weapons/Ranged/Systems/GunSystem.AmmoCounter.cs +++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.AmmoCounter.cs @@ -4,11 +4,11 @@ using Content.Client.Items; using Content.Client.Resources; using Content.Client.Stylesheets; using Content.Client.Weapons.Ranged.Components; +using Content.Client.Weapons.Ranged.ItemStatus; using Robust.Client.Animations; using Robust.Client.Graphics; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; -using Robust.Shared.Graphics; namespace Content.Client.Weapons.Ranged.Systems; @@ -91,116 +91,26 @@ public sealed partial class GunSystem private sealed class DefaultStatusControl : Control { - private readonly BoxContainer _bulletsListTop; - private readonly BoxContainer _bulletsListBottom; + private readonly BulletRender _bulletRender; public DefaultStatusControl() { MinHeight = 15; HorizontalExpand = true; - VerticalAlignment = Control.VAlignment.Center; - AddChild(new BoxContainer + VerticalAlignment = VAlignment.Center; + AddChild(_bulletRender = new BulletRender { - Orientation = BoxContainer.LayoutOrientation.Vertical, - HorizontalExpand = true, - VerticalAlignment = VAlignment.Center, - SeparationOverride = 0, - Children = - { - (_bulletsListTop = new BoxContainer - { - Orientation = BoxContainer.LayoutOrientation.Horizontal, - SeparationOverride = 0 - }), - new BoxContainer - { - Orientation = BoxContainer.LayoutOrientation.Horizontal, - HorizontalExpand = true, - Children = - { - new Control - { - HorizontalExpand = true, - Children = - { - (_bulletsListBottom = new BoxContainer - { - Orientation = BoxContainer.LayoutOrientation.Horizontal, - VerticalAlignment = VAlignment.Center, - SeparationOverride = 0 - }), - } - }, - } - } - } + HorizontalAlignment = HAlignment.Right, + VerticalAlignment = VAlignment.Bottom }); } public void Update(int count, int capacity) { - _bulletsListTop.RemoveAllChildren(); - _bulletsListBottom.RemoveAllChildren(); + _bulletRender.Count = count; + _bulletRender.Capacity = capacity; - string texturePath; - if (capacity <= 20) - { - texturePath = "/Textures/Interface/ItemStatus/Bullets/normal.png"; - } - else if (capacity <= 30) - { - texturePath = "/Textures/Interface/ItemStatus/Bullets/small.png"; - } - else - { - texturePath = "/Textures/Interface/ItemStatus/Bullets/tiny.png"; - } - - var texture = StaticIoC.ResC.GetTexture(texturePath); - - const int tinyMaxRow = 60; - - if (capacity > tinyMaxRow) - { - FillBulletRow(_bulletsListBottom, Math.Min(tinyMaxRow, count), tinyMaxRow, texture); - FillBulletRow(_bulletsListTop, Math.Max(0, count - tinyMaxRow), capacity - tinyMaxRow, texture); - } - else - { - FillBulletRow(_bulletsListBottom, count, capacity, texture); - } - } - - private static void FillBulletRow(Control container, int count, int capacity, Texture texture) - { - var colorA = Color.FromHex("#b68f0e"); - var colorB = Color.FromHex("#d7df60"); - var colorGoneA = Color.FromHex("#000000"); - var colorGoneB = Color.FromHex("#222222"); - - var altColor = false; - - for (var i = count; i < capacity; i++) - { - container.AddChild(new TextureRect - { - Texture = texture, - ModulateSelfOverride = altColor ? colorGoneA : colorGoneB - }); - - altColor ^= true; - } - - for (var i = 0; i < count; i++) - { - container.AddChild(new TextureRect - { - Texture = texture, - ModulateSelfOverride = altColor ? colorA : colorB - }); - - altColor ^= true; - } + _bulletRender.Type = capacity > 50 ? BulletRender.BulletType.Tiny : BulletRender.BulletType.Normal; } } @@ -291,7 +201,7 @@ public sealed partial class GunSystem private sealed class ChamberMagazineStatusControl : Control { - private readonly BoxContainer _bulletsList; + private readonly BulletRender _bulletRender; private readonly TextureRect _chamberedBullet; private readonly Label _noMagazineLabel; private readonly Label _ammoCount; @@ -308,23 +218,16 @@ public sealed partial class GunSystem HorizontalExpand = true, Children = { - (_chamberedBullet = new TextureRect - { - Texture = StaticIoC.ResC.GetTexture("/Textures/Interface/ItemStatus/Bullets/chambered_rotated.png"), - VerticalAlignment = VAlignment.Center, - HorizontalAlignment = HAlignment.Right, - }), - new Control() { MinSize = new Vector2(5,0) }, new Control { HorizontalExpand = true, + Margin = new Thickness(0, 0, 5, 0), Children = { - (_bulletsList = new BoxContainer + (_bulletRender = new BulletRender { - Orientation = BoxContainer.LayoutOrientation.Horizontal, - VerticalAlignment = VAlignment.Center, - SeparationOverride = 0 + HorizontalAlignment = HAlignment.Right, + VerticalAlignment = VAlignment.Bottom }), (_noMagazineLabel = new Label { @@ -333,12 +236,25 @@ public sealed partial class GunSystem }) } }, - new Control() { MinSize = new Vector2(5,0) }, - (_ammoCount = new Label + new BoxContainer { - StyleClasses = {StyleNano.StyleClassItemStatus}, - HorizontalAlignment = HAlignment.Right, - }), + Orientation = BoxContainer.LayoutOrientation.Vertical, + VerticalAlignment = VAlignment.Bottom, + Margin = new Thickness(0, 0, 0, 2), + Children = + { + (_ammoCount = new Label + { + StyleClasses = {StyleNano.StyleClassItemStatus}, + HorizontalAlignment = HAlignment.Right, + }), + (_chamberedBullet = new TextureRect + { + Texture = StaticIoC.ResC.GetTexture("/Textures/Interface/ItemStatus/Bullets/chambered.png"), + HorizontalAlignment = HAlignment.Left, + }), + } + } } }); } @@ -348,61 +264,24 @@ public sealed partial class GunSystem _chamberedBullet.ModulateSelfOverride = chambered ? Color.FromHex("#d7df60") : Color.Black; - _bulletsList.RemoveAllChildren(); - if (!magazine) { + _bulletRender.Visible = false; _noMagazineLabel.Visible = true; _ammoCount.Visible = false; return; } + _bulletRender.Visible = true; _noMagazineLabel.Visible = false; _ammoCount.Visible = true; - var texturePath = "/Textures/Interface/ItemStatus/Bullets/normal.png"; - var texture = StaticIoC.ResC.GetTexture(texturePath); + _bulletRender.Count = count; + _bulletRender.Capacity = capacity; + + _bulletRender.Type = capacity > 50 ? BulletRender.BulletType.Tiny : BulletRender.BulletType.Normal; _ammoCount.Text = $"x{count:00}"; - capacity = Math.Min(capacity, 20); - FillBulletRow(_bulletsList, count, capacity, texture); - } - - private static void FillBulletRow(Control container, int count, int capacity, Texture texture) - { - var colorA = Color.FromHex("#b68f0e"); - var colorB = Color.FromHex("#d7df60"); - var colorGoneA = Color.FromHex("#000000"); - var colorGoneB = Color.FromHex("#222222"); - - var altColor = false; - - // Draw the empty ones - for (var i = count; i < capacity; i++) - { - container.AddChild(new TextureRect - { - Texture = texture, - ModulateSelfOverride = altColor ? colorGoneA : colorGoneB, - Stretch = TextureRect.StretchMode.KeepCentered - }); - - altColor ^= true; - } - - // Draw the full ones, but limit the count to the capacity - count = Math.Min(count, capacity); - for (var i = 0; i < count; i++) - { - container.AddChild(new TextureRect - { - Texture = texture, - ModulateSelfOverride = altColor ? colorA : colorB, - Stretch = TextureRect.StretchMode.KeepCentered - }); - - altColor ^= true; - } } public void PlayAlarmAnimation(Animation animation) diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj index 8782454eac..70e404fdef 100644 --- a/Content.Server/Content.Server.csproj +++ b/Content.Server/Content.Server.csproj @@ -28,7 +28,6 @@ - diff --git a/Content.Server/Entry/IgnoredComponents.cs b/Content.Server/Entry/IgnoredComponents.cs index fe073da7a4..d9b81c8e5a 100644 --- a/Content.Server/Entry/IgnoredComponents.cs +++ b/Content.Server/Entry/IgnoredComponents.cs @@ -14,12 +14,13 @@ namespace Content.Server.Entry "Icon", "HandheldGPS", "CableVisualizer", + "SolutionItemStatus", "UIFragment", "PdaBorderColor", "InventorySlots", "LightFade", "HolidayRsiSwap", - "OptionsVisualizer", + "OptionsVisualizer" }; } } diff --git a/Content.Server/Tools/ToolSystem.cs b/Content.Server/Tools/ToolSystem.cs index 7b2de57efc..7738a6398f 100644 --- a/Content.Server/Tools/ToolSystem.cs +++ b/Content.Server/Tools/ToolSystem.cs @@ -45,10 +45,10 @@ public sealed class ToolSystem : SharedToolSystem if (welder.WelderTimer < welder.WelderUpdateTimer) continue; - if (!SolutionContainerSystem.ResolveSolution((uid, solutionContainer), welder.FuelSolutionName, ref welder.FuelSolution, out var solution)) + if (!SolutionContainerSystem.TryGetSolution((uid, solutionContainer), welder.FuelSolutionName, out var solutionComp, out var solution)) continue; - SolutionContainerSystem.RemoveReagent(welder.FuelSolution.Value, welder.FuelReagent, welder.FuelConsumption * welder.WelderTimer); + SolutionContainerSystem.RemoveReagent(solutionComp.Value, welder.FuelReagent, welder.FuelConsumption * welder.WelderTimer); if (solution.GetTotalPrototypeQuantity(welder.FuelReagent) <= FixedPoint2.Zero) { diff --git a/Content.Shared/Tools/Components/WelderComponent.cs b/Content.Shared/Tools/Components/WelderComponent.cs index f133be675d..3c78a03fde 100644 --- a/Content.Shared/Tools/Components/WelderComponent.cs +++ b/Content.Shared/Tools/Components/WelderComponent.cs @@ -23,12 +23,6 @@ public sealed partial class WelderComponent : Component [DataField] public string FuelSolutionName = "Welder"; - /// - /// Solution on the entity that contains the fuel. - /// - [ViewVariables(VVAccess.ReadWrite)] - public Entity? FuelSolution; - /// /// Reagent that will be used as fuel for welding. /// diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs b/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs index 6bab296db5..e790b59cd1 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs @@ -24,10 +24,10 @@ public abstract partial class SharedToolSystem public virtual void TurnOn(Entity entity, EntityUid? user) { - if (!SolutionContainerSystem.ResolveSolution(entity.Owner, entity.Comp.FuelSolutionName, ref entity.Comp.FuelSolution)) + if (!SolutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.FuelSolutionName, out var solutionComp, out _)) return; - SolutionContainerSystem.RemoveReagent(entity.Comp.FuelSolution.Value, entity.Comp.FuelReagent, entity.Comp.FuelLitCost); + SolutionContainerSystem.RemoveReagent(solutionComp.Value, entity.Comp.FuelReagent, entity.Comp.FuelLitCost); AdminLogger.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} toggled {ToPrettyString(entity.Owner):welder} on"); @@ -45,9 +45,17 @@ public abstract partial class SharedToolSystem public (FixedPoint2 fuel, FixedPoint2 capacity) GetWelderFuelAndCapacity(EntityUid uid, WelderComponent? welder = null, SolutionContainerManagerComponent? solutionContainer = null) { - if (!Resolve(uid, ref welder, ref solutionContainer) - || !SolutionContainerSystem.ResolveSolution((uid, solutionContainer), welder.FuelSolutionName, ref welder.FuelSolution, out var fuelSolution)) - return (FixedPoint2.Zero, FixedPoint2.Zero); + if (!Resolve(uid, ref welder, ref solutionContainer)) + return default; + + if (!SolutionContainer.TryGetSolution( + (uid, solutionContainer), + welder.FuelSolutionName, + out _, + out var fuelSolution)) + { + return default; + } return (fuelSolution.GetTotalPrototypeQuantity(welder.FuelReagent), fuelSolution.MaxVolume); } @@ -89,13 +97,13 @@ public abstract partial class SharedToolSystem if (TryComp(target, out ReagentTankComponent? tank) && tank.TankType == ReagentTankType.Fuel && SolutionContainerSystem.TryGetDrainableSolution(target, out var targetSoln, out var targetSolution) - && SolutionContainerSystem.ResolveSolution(entity.Owner, entity.Comp.FuelSolutionName, ref entity.Comp.FuelSolution, out var welderSolution)) + && SolutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.FuelSolutionName, out var solutionComp, out var welderSolution)) { var trans = FixedPoint2.Min(welderSolution.AvailableVolume, targetSolution.Volume); if (trans > 0) { var drained = SolutionContainerSystem.Drain(target, targetSoln.Value, trans); - SolutionContainerSystem.TryAddSolution(entity.Comp.FuelSolution.Value, drained); + SolutionContainerSystem.TryAddSolution(solutionComp.Value, drained); _audioSystem.PlayPredicted(entity.Comp.WelderRefill, entity, user: args.User); _popup.PopupClient(Loc.GetString("welder-component-after-interact-refueled-message"), entity, args.User); } @@ -153,7 +161,7 @@ public abstract partial class SharedToolSystem private void OnActivateAttempt(Entity entity, ref ItemToggleActivateAttemptEvent args) { - if (!SolutionContainerSystem.ResolveSolution(entity.Owner, entity.Comp.FuelSolutionName, ref entity.Comp.FuelSolution, out var solution)) + if (!SolutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.FuelSolutionName, out _, out var solution)) { args.Cancelled = true; args.Popup = Loc.GetString("welder-component-no-fuel-message"); diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.cs b/Content.Shared/Tools/Systems/SharedToolSystem.cs index 362f4f7683..9edae9b78f 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.cs @@ -31,6 +31,7 @@ public abstract partial class SharedToolSystem : EntitySystem [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly TileSystem _tiles = default!; [Dependency] private readonly TurfSystem _turfs = default!; + [Dependency] protected readonly SharedSolutionContainerSystem SolutionContainer = default!; public override void Initialize() { diff --git a/Resources/Locale/en-US/chemistry/components/solution-status.ftl b/Resources/Locale/en-US/chemistry/components/solution-status.ftl new file mode 100644 index 0000000000..0ec5f932e0 --- /dev/null +++ b/Resources/Locale/en-US/chemistry/components/solution-status.ftl @@ -0,0 +1,2 @@ +solution-status-volume = Volume: [color=white]{$currentVolume}/{$maxVolume}u[/color] +solution-status-transfer = Transfer: [color=white]{$volume}u[/color] diff --git a/Resources/Locale/en-US/tools/components/welder-component.ftl b/Resources/Locale/en-US/tools/components/welder-component.ftl index 681975deb8..6307068521 100644 --- a/Resources/Locale/en-US/tools/components/welder-component.ftl +++ b/Resources/Locale/en-US/tools/components/welder-component.ftl @@ -4,7 +4,8 @@ welder-component-no-fuel-message = The welder has no fuel left! welder-component-no-fuel-in-tank = The {$owner} is empty. welder-component-on-examine-welder-lit-message = [color=orange]Lit[/color] welder-component-on-examine-welder-not-lit-message = Not lit -welder-component-on-examine-detailed-message = Fuel: [color={$colorName}]{$fuelLeft}/{$fuelCapacity}[/color]. {$status} +welder-component-on-examine-detailed-message = Fuel: [color={$colorName}]{$fuelLeft}/{$fuelCapacity}[/color] + {$status} welder-component-suicide-lit-others-message = {$victim} welds their every orifice closed! It looks like they are trying to commit suicide! welder-component-suicide-lit-message = You weld your every orifice closed! welder-component-suicide-unlit-others-message = {$victim} bashes themselves with the unlit welding torch! diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml index 0e19c03dee..64b3568adf 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml @@ -24,6 +24,8 @@ solution: spray - type: SolutionTransfer canChangeTransferAmount: true + - type: SolutionItemStatus + solution: spray - type: UseDelay - type: Spray transferAmount: 10 diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml index 01efcfa950..8034844a82 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml @@ -32,6 +32,8 @@ solution: beaker - type: SolutionTransfer canChangeTransferAmount: true + - type: SolutionItemStatus + solution: beaker - type: UserInterface interfaces: - key: enum.TransferAmountUiKey.Key diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml index 9ac699db5a..fdf58dc484 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml @@ -41,6 +41,8 @@ solution: beaker - type: SolutionTransfer canChangeTransferAmount: true + - type: SolutionItemStatus + solution: beaker - type: UserInterface interfaces: - key: enum.TransferAmountUiKey.Key diff --git a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml index d0a3bb3702..77803a13ec 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml @@ -51,6 +51,8 @@ solution: bucket - type: DrainableSolution solution: bucket + - type: SolutionItemStatus + solution: bucket - type: Appearance - type: SolutionContainerVisuals maxFillLevels: 3 diff --git a/Resources/Prototypes/themes.yml b/Resources/Prototypes/themes.yml index edd2681a62..3952687255 100644 --- a/Resources/Prototypes/themes.yml +++ b/Resources/Prototypes/themes.yml @@ -12,6 +12,8 @@ concerningOrangeFore: "#A5762F" dangerousRedFore: "#BB3232" disabledFore: "#5A5A5A" + _itemstatus_content_margin_right: "#06060404" + _itemstatus_content_margin_left: "#04060604" - type: uiTheme id: SS14PlasmafireTheme path: /Textures/Interface/Plasmafire/ @@ -26,6 +28,8 @@ concerningOrangeFore: "#FFF5EE" dangerousRedFore: "#FFF5EE" disabledFore: "#FFF5EE" + _itemstatus_content_margin_right: "#06060404" + _itemstatus_content_margin_left: "#04060604" - type: uiTheme id: SS14SlimecoreTheme path: /Textures/Interface/Slimecore/ @@ -40,6 +44,8 @@ concerningOrangeFore: "#FFF5EE" dangerousRedFore: "#FFF5EE" disabledFore: "#FFF5EE" + _itemstatus_content_margin_right: "#06060404" + _itemstatus_content_margin_left: "#04060604" - type: uiTheme id: SS14ClockworkTheme path: /Textures/Interface/Clockwork/ @@ -54,6 +60,8 @@ concerningOrangeFore: "#FFF5EE" dangerousRedFore: "#FFF5EE" disabledFore: "#FFF5EE" + _itemstatus_content_margin_right: "#06060404" + _itemstatus_content_margin_left: "#04060604" - type: uiTheme id: SS14RetroTheme path: /Textures/Interface/Retro/ @@ -68,6 +76,8 @@ concerningOrangeFore: "#FFF5EE" dangerousRedFore: "#FFF5EE" disabledFore: "#FFF5EE" + _itemstatus_content_margin_right: "#06060404" + _itemstatus_content_margin_left: "#04060604" - type: uiTheme id: SS14MinimalistTheme path: /Textures/Interface/Minimalist/ @@ -82,6 +92,8 @@ concerningOrangeFore: "#A5762F" dangerousRedFore: "#BB3232" disabledFore: "#5A5A5A" + _itemstatus_content_margin_right: "#06060604" + _itemstatus_content_margin_left: "#06060604" - type: uiTheme id: SS14AshenTheme path: /Textures/Interface/Ashen/ @@ -96,3 +108,5 @@ concerningOrangeFore: "#FFF5EE" dangerousRedFore: "#FFF5EE" disabledFore: "#FFF5EE" + _itemstatus_content_margin_right: "#06060604" + _itemstatus_content_margin_left: "#06060604" diff --git a/Resources/Textures/Interface/Ashen/item_status_left.png b/Resources/Textures/Interface/Ashen/item_status_left.png new file mode 100644 index 0000000000..fb2bf2b9b4 Binary files /dev/null and b/Resources/Textures/Interface/Ashen/item_status_left.png differ diff --git a/Resources/Textures/Interface/Ashen/item_status_left_highlight.png b/Resources/Textures/Interface/Ashen/item_status_left_highlight.png new file mode 100644 index 0000000000..91cd15dd4c Binary files /dev/null and b/Resources/Textures/Interface/Ashen/item_status_left_highlight.png differ diff --git a/Resources/Textures/Interface/Ashen/item_status_right.png b/Resources/Textures/Interface/Ashen/item_status_right.png new file mode 100644 index 0000000000..53f4f362d0 Binary files /dev/null and b/Resources/Textures/Interface/Ashen/item_status_right.png differ diff --git a/Resources/Textures/Interface/Ashen/item_status_right_highlight.png b/Resources/Textures/Interface/Ashen/item_status_right_highlight.png new file mode 100644 index 0000000000..ad16bab6d1 Binary files /dev/null and b/Resources/Textures/Interface/Ashen/item_status_right_highlight.png differ diff --git a/Resources/Textures/Interface/Clockwork/item_status_left.png b/Resources/Textures/Interface/Clockwork/item_status_left.png new file mode 100644 index 0000000000..1ce950362d Binary files /dev/null and b/Resources/Textures/Interface/Clockwork/item_status_left.png differ diff --git a/Resources/Textures/Interface/Clockwork/item_status_left_highlight.png b/Resources/Textures/Interface/Clockwork/item_status_left_highlight.png new file mode 100644 index 0000000000..f715e06276 Binary files /dev/null and b/Resources/Textures/Interface/Clockwork/item_status_left_highlight.png differ diff --git a/Resources/Textures/Interface/Clockwork/item_status_right.png b/Resources/Textures/Interface/Clockwork/item_status_right.png new file mode 100644 index 0000000000..5ea5ffcffa Binary files /dev/null and b/Resources/Textures/Interface/Clockwork/item_status_right.png differ diff --git a/Resources/Textures/Interface/Clockwork/item_status_right_highlight.png b/Resources/Textures/Interface/Clockwork/item_status_right_highlight.png new file mode 100644 index 0000000000..315d595c92 Binary files /dev/null and b/Resources/Textures/Interface/Clockwork/item_status_right_highlight.png differ diff --git a/Resources/Textures/Interface/Default/item_status_left.png b/Resources/Textures/Interface/Default/item_status_left.png new file mode 100644 index 0000000000..6c980f226e Binary files /dev/null and b/Resources/Textures/Interface/Default/item_status_left.png differ diff --git a/Resources/Textures/Interface/Default/item_status_left_highlight.png b/Resources/Textures/Interface/Default/item_status_left_highlight.png new file mode 100644 index 0000000000..87dea5cf10 Binary files /dev/null and b/Resources/Textures/Interface/Default/item_status_left_highlight.png differ diff --git a/Resources/Textures/Interface/Default/item_status_right.png b/Resources/Textures/Interface/Default/item_status_right.png new file mode 100644 index 0000000000..82ad44b48c Binary files /dev/null and b/Resources/Textures/Interface/Default/item_status_right.png differ diff --git a/Resources/Textures/Interface/Default/item_status_right_highlight.png b/Resources/Textures/Interface/Default/item_status_right_highlight.png new file mode 100644 index 0000000000..0c1c344848 Binary files /dev/null and b/Resources/Textures/Interface/Default/item_status_right_highlight.png differ diff --git a/Resources/Textures/Interface/Minimalist/item_status_left.png b/Resources/Textures/Interface/Minimalist/item_status_left.png new file mode 100644 index 0000000000..d70eca2fe9 Binary files /dev/null and b/Resources/Textures/Interface/Minimalist/item_status_left.png differ diff --git a/Resources/Textures/Interface/Minimalist/item_status_left_highlight.png b/Resources/Textures/Interface/Minimalist/item_status_left_highlight.png new file mode 100644 index 0000000000..b69872cd89 Binary files /dev/null and b/Resources/Textures/Interface/Minimalist/item_status_left_highlight.png differ diff --git a/Resources/Textures/Interface/Minimalist/item_status_right.png b/Resources/Textures/Interface/Minimalist/item_status_right.png new file mode 100644 index 0000000000..89171b9b47 Binary files /dev/null and b/Resources/Textures/Interface/Minimalist/item_status_right.png differ diff --git a/Resources/Textures/Interface/Minimalist/item_status_right_highlight.png b/Resources/Textures/Interface/Minimalist/item_status_right_highlight.png new file mode 100644 index 0000000000..d1474cee12 Binary files /dev/null and b/Resources/Textures/Interface/Minimalist/item_status_right_highlight.png differ diff --git a/Resources/Textures/Interface/Nano/item_status_left.svg b/Resources/Textures/Interface/Nano/item_status_left.svg deleted file mode 100644 index c97f8de016..0000000000 --- a/Resources/Textures/Interface/Nano/item_status_left.svg +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/Resources/Textures/Interface/Nano/item_status_left.svg.96dpi.png b/Resources/Textures/Interface/Nano/item_status_left.svg.96dpi.png deleted file mode 100644 index 5169343ea4..0000000000 Binary files a/Resources/Textures/Interface/Nano/item_status_left.svg.96dpi.png and /dev/null differ diff --git a/Resources/Textures/Interface/Nano/item_status_middle.svg b/Resources/Textures/Interface/Nano/item_status_middle.svg deleted file mode 100644 index a913981db1..0000000000 --- a/Resources/Textures/Interface/Nano/item_status_middle.svg +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/Resources/Textures/Interface/Nano/item_status_middle.svg.96dpi.png b/Resources/Textures/Interface/Nano/item_status_middle.svg.96dpi.png deleted file mode 100644 index dc1f84cea8..0000000000 Binary files a/Resources/Textures/Interface/Nano/item_status_middle.svg.96dpi.png and /dev/null differ diff --git a/Resources/Textures/Interface/Nano/item_status_right.svg b/Resources/Textures/Interface/Nano/item_status_right.svg deleted file mode 100644 index d898bb2ce0..0000000000 --- a/Resources/Textures/Interface/Nano/item_status_right.svg +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/Resources/Textures/Interface/Nano/item_status_right.svg.96dpi.png b/Resources/Textures/Interface/Nano/item_status_right.svg.96dpi.png deleted file mode 100644 index 72f7e6de6b..0000000000 Binary files a/Resources/Textures/Interface/Nano/item_status_right.svg.96dpi.png and /dev/null differ diff --git a/Resources/Textures/Interface/Plasmafire/item_status_left.png b/Resources/Textures/Interface/Plasmafire/item_status_left.png new file mode 100644 index 0000000000..d5d25c9809 Binary files /dev/null and b/Resources/Textures/Interface/Plasmafire/item_status_left.png differ diff --git a/Resources/Textures/Interface/Plasmafire/item_status_left_highlight.png b/Resources/Textures/Interface/Plasmafire/item_status_left_highlight.png new file mode 100644 index 0000000000..afe37513fd Binary files /dev/null and b/Resources/Textures/Interface/Plasmafire/item_status_left_highlight.png differ diff --git a/Resources/Textures/Interface/Plasmafire/item_status_right.png b/Resources/Textures/Interface/Plasmafire/item_status_right.png new file mode 100644 index 0000000000..ca97f81c8f Binary files /dev/null and b/Resources/Textures/Interface/Plasmafire/item_status_right.png differ diff --git a/Resources/Textures/Interface/Plasmafire/item_status_right_highlight.png b/Resources/Textures/Interface/Plasmafire/item_status_right_highlight.png new file mode 100644 index 0000000000..b95822b737 Binary files /dev/null and b/Resources/Textures/Interface/Plasmafire/item_status_right_highlight.png differ diff --git a/Resources/Textures/Interface/Retro/item_status_left.png b/Resources/Textures/Interface/Retro/item_status_left.png new file mode 100644 index 0000000000..21b107b84d Binary files /dev/null and b/Resources/Textures/Interface/Retro/item_status_left.png differ diff --git a/Resources/Textures/Interface/Retro/item_status_left_highlight.png b/Resources/Textures/Interface/Retro/item_status_left_highlight.png new file mode 100644 index 0000000000..fdd5a4fe7d Binary files /dev/null and b/Resources/Textures/Interface/Retro/item_status_left_highlight.png differ diff --git a/Resources/Textures/Interface/Retro/item_status_right.png b/Resources/Textures/Interface/Retro/item_status_right.png new file mode 100644 index 0000000000..5e7d54618d Binary files /dev/null and b/Resources/Textures/Interface/Retro/item_status_right.png differ diff --git a/Resources/Textures/Interface/Retro/item_status_right_highlight.png b/Resources/Textures/Interface/Retro/item_status_right_highlight.png new file mode 100644 index 0000000000..c6e12c41e6 Binary files /dev/null and b/Resources/Textures/Interface/Retro/item_status_right_highlight.png differ diff --git a/Resources/Textures/Interface/Slimecore/item_status_left.png b/Resources/Textures/Interface/Slimecore/item_status_left.png new file mode 100644 index 0000000000..a7d940f401 Binary files /dev/null and b/Resources/Textures/Interface/Slimecore/item_status_left.png differ diff --git a/Resources/Textures/Interface/Slimecore/item_status_left_highlight.png b/Resources/Textures/Interface/Slimecore/item_status_left_highlight.png new file mode 100644 index 0000000000..322355b135 Binary files /dev/null and b/Resources/Textures/Interface/Slimecore/item_status_left_highlight.png differ diff --git a/Resources/Textures/Interface/Slimecore/item_status_right.png b/Resources/Textures/Interface/Slimecore/item_status_right.png new file mode 100644 index 0000000000..77b53340a6 Binary files /dev/null and b/Resources/Textures/Interface/Slimecore/item_status_right.png differ diff --git a/Resources/Textures/Interface/Slimecore/item_status_right_highlight.png b/Resources/Textures/Interface/Slimecore/item_status_right_highlight.png new file mode 100644 index 0000000000..1e1a631db4 Binary files /dev/null and b/Resources/Textures/Interface/Slimecore/item_status_right_highlight.png differ