using Content.Client.Message;
using Content.Client.Stylesheets;
+using Content.Client.UserInterface.Controls;
using Content.Shared.Implants.Components;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
_parent = parent;
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
_label.MaxWidth = 350;
- AddChild(_label);
+ AddChild(new ClipControl { Children = { _label } });
Update();
}
_ => Loc.GetString("injector-invalid-injector-toggle-mode")
};
- var (implantName, implantDescription) = _parent.ImplanterSlot.HasItem switch
- {
- false => (Loc.GetString("implanter-empty-text"), ""),
- true => (_parent.ImplantData.Item1, _parent.ImplantData.Item2),
- };
-
+ var implantName = _parent.ImplanterSlot.HasItem
+ ? _parent.ImplantData.Item1
+ : Loc.GetString("implanter-empty-text");
_label.SetMarkup(Loc.GetString("implanter-label",
("implantName", implantName),
- ("implantDescription", implantDescription),
- ("modeString", modeStringLocalized),
- ("lineBreak", "\n")));
+ ("modeString", modeStringLocalized)));
}
}
public const string StyleClassPowerStateGood = "PowerStateGood";
public const string StyleClassItemStatus = "ItemStatus";
+ public const string StyleClassItemStatusNotHeld = "ItemStatusNotHeld";
+ public static readonly Color ItemStatusNotHeldColor = Color.Gray;
//Background
public const string StyleClassBackgroundBaseDark = "PanelBackgroundBaseDark";
new StyleProperty("font", notoSans10),
}),
+ Element()
+ .Class(StyleClassItemStatusNotHeld)
+ .Prop("font", notoSansItalic10)
+ .Prop("font-color", ItemStatusNotHeldColor),
+
Element<RichTextLabel>()
.Class(StyleClassItemStatus)
.Prop(nameof(RichTextLabel.LineHeightScale), 0.7f)
--- /dev/null
+using System.Numerics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+
+namespace Content.Client.UserInterface.Controls;
+
+/// <summary>
+/// Pretends to child controls that there's infinite space.
+/// This can be used to make something like a <see cref="RichTextLabel"/> clip instead of wrapping.
+/// </summary>
+public sealed class ClipControl : Control
+{
+ private bool _clipHorizontal = true;
+ private bool _clipVertical = true;
+
+ public bool ClipHorizontal
+ {
+ get => _clipHorizontal;
+ set
+ {
+ _clipHorizontal = value;
+ InvalidateMeasure();
+ }
+ }
+
+ public bool ClipVertical
+ {
+ get => _clipVertical;
+ set
+ {
+ _clipVertical = value;
+ InvalidateMeasure();
+ }
+ }
+
+ protected override Vector2 MeasureOverride(Vector2 availableSize)
+ {
+ if (ClipHorizontal)
+ availableSize = availableSize with { X = float.PositiveInfinity };
+ if (ClipVertical)
+ availableSize = availableSize with { Y = float.PositiveInfinity };
+
+ return base.MeasureOverride(availableSize);
+ }
+
+ protected override Vector2 ArrangeOverride(Vector2 finalSize)
+ {
+ foreach (var child in Children)
+ {
+ child.Arrange(UIBox2.FromDimensions(Vector2.Zero, child.DesiredSize));
+ }
+
+ return finalSize;
+ }
+}
public sealed class HandButton : SlotControl
{
+ public HandLocation HandLocation { get; }
+
public HandButton(string handName, HandLocation handLocation)
{
+ HandLocation = handLocation;
Name = "hand_" + handName;
SlotName = handName;
SetBackground(handLocation);
_player.LocalSession?.AttachedEntity is { } playerEntity &&
_handsSystem.TryGetHand(playerEntity, handName, out var hand, _playerHandsComponent))
{
- if (hand.Location == HandLocation.Left)
+ var foldedLocation = hand.Location.GetUILocation();
+ if (foldedLocation == HandUILocation.Left)
{
_statusHandLeft = handControl;
HandsGui.UpdatePanelEntityLeft(hand.HeldEntity);
HandsGui.UpdatePanelEntityRight(hand.HeldEntity);
}
- HandsGui.SetHighlightHand(hand.Location);
+ HandsGui.SetHighlightHand(foldedLocation);
}
}
// If we don't have a status for this hand type yet, set it.
// This means we have status filled by default in most scenarios,
// otherwise the user'd need to switch hands to "activate" the hands the first time.
- if (location == HandLocation.Left)
+ if (location.GetUILocation() == HandUILocation.Left)
_statusHandLeft ??= button;
else
_statusHandRight ??= button;
+ UpdateVisibleStatusPanels();
+
return button;
}
_handLookup.Remove(handName);
handButton.Dispose();
+ UpdateVisibleStatusPanels();
return true;
}
+ private void UpdateVisibleStatusPanels()
+ {
+ var leftVisible = false;
+ var rightVisible = false;
+
+ foreach (var hand in _handLookup.Values)
+ {
+ if (hand.HandLocation.GetUILocation() == HandUILocation.Left)
+ {
+ leftVisible = true;
+ }
+ else
+ {
+ rightVisible = true;
+ }
+ }
+
+ HandsGui?.UpdateStatusVisibility(leftVisible, rightVisible);
+ }
+
public string RegisterHandContainer(HandsContainer handContainer)
{
var name = "HandContainer_" + _backupSuffix;
Name="StatusPanelRight"
HorizontalAlignment="Center" Margin="0 0 -2 2"
SetWidth="125"
- MaxHeight="60"/>
+ SetHeight="60"/>
<hands:HandsContainer
Name="HandContainer"
Access="Public"
Name="StatusPanelLeft"
HorizontalAlignment="Center" Margin="-2 0 0 2"
SetWidth="125"
- MaxHeight="60"/>
+ SetHeight="60"/>
<inventory:ItemSlotButtonContainer
Name="MainHotbar"
SlotGroup="MainHotbar"
public HotbarGui()
{
RobustXamlLoader.Load(this);
- StatusPanelRight.SetSide(HandLocation.Right);
- StatusPanelLeft.SetSide(HandLocation.Left);
+ StatusPanelRight.SetSide(HandUILocation.Right);
+ StatusPanelLeft.SetSide(HandUILocation.Left);
var hotbarController = UserInterfaceManager.GetUIController<HotbarUIController>();
hotbarController.Setup(HandContainer, StoragePanel);
StatusPanelRight.Update(entity);
}
- public void SetHighlightHand(HandLocation? hand)
+ public void SetHighlightHand(HandUILocation? hand)
{
- StatusPanelLeft.UpdateHighlight(hand is HandLocation.Left);
- StatusPanelRight.UpdateHighlight(hand is HandLocation.Middle or HandLocation.Right);
+ StatusPanelLeft.UpdateHighlight(hand is HandUILocation.Left);
+ StatusPanelRight.UpdateHighlight(hand is HandUILocation.Right);
+ }
+
+ public void UpdateStatusVisibility(bool left, bool right)
+ {
+ StatusPanelLeft.Visible = left;
+ StatusPanelRight.Visible = right;
}
}
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
VerticalAlignment="Bottom"
HorizontalAlignment="Center">
- <Control Name="VisWrapper" Visible="False">
- <PanelContainer Name="Panel">
- <PanelContainer.PanelOverride>
- <graphics:StyleBoxTexture
- PatchMarginBottom="4"
- PatchMarginTop="6"
- TextureScale="2 2"
- Mode="Tile"/>
- </PanelContainer.PanelOverride>
- </PanelContainer>
- <PanelContainer Name="HighlightPanel">
- <PanelContainer.PanelOverride>
- <graphics:StyleBoxTexture PatchMarginBottom="4" PatchMarginTop="6" TextureScale="2 2">
- </graphics:StyleBoxTexture>
- </PanelContainer.PanelOverride>
- </PanelContainer>
- <BoxContainer Name="Contents" Orientation="Vertical" Margin="0 6 0 4">
- <BoxContainer Name="StatusContents" Orientation="Vertical" />
- <Label Name="ItemNameLabel" ClipText="True" StyleClasses="ItemStatus" Align="Left" />
- </BoxContainer>
- </Control>
+ <PanelContainer Name="Panel">
+ <PanelContainer.PanelOverride>
+ <graphics:StyleBoxTexture
+ PatchMarginBottom="4"
+ PatchMarginTop="6"
+ TextureScale="2 2"
+ Mode="Tile"/>
+ </PanelContainer.PanelOverride>
+ </PanelContainer>
+ <PanelContainer Name="HighlightPanel">
+ <PanelContainer.PanelOverride>
+ <graphics:StyleBoxTexture PatchMarginBottom="4" PatchMarginTop="6" TextureScale="2 2">
+ </graphics:StyleBoxTexture>
+ </PanelContainer.PanelOverride>
+ </PanelContainer>
+ <BoxContainer Name="Contents" Orientation="Vertical" Margin="0 6 0 4" RectClipContent="True">
+ <BoxContainer Name="StatusContents" Orientation="Vertical" VerticalExpand="True" VerticalAlignment="Bottom" />
+ <Control>
+ <Label Name="NoItemLabel" ClipText="True" StyleClasses="ItemStatusNotHeld" Align="Left" Text="{Loc 'item-status-not-held'}" />
+ <Label Name="ItemNameLabel" ClipText="True" StyleClasses="ItemStatus" Align="Left" Visible="False" />
+ </Control>
+ </BoxContainer>
</controls:ItemStatusPanel>
-using System.Numerics;
using Content.Client.Items;
-using Content.Client.Resources;
using Content.Shared.Hands.Components;
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;
using Robust.Shared.Utility;
-using static Content.Client.IoC.StaticIoC;
namespace Content.Client.UserInterface.Systems.Inventory.Controls;
[ViewVariables] private EntityUid? _entity;
// Tracked so we can re-run SetSide() if the theme changes.
- private HandLocation _side;
+ private HandUILocation _side;
public ItemStatusPanel()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
-
- SetSide(HandLocation.Middle);
}
- public void SetSide(HandLocation location)
+ public void SetSide(HandUILocation location)
{
// AN IMPORTANT REMINDER ABOUT THIS CODE:
// In the UI, the RIGHT hand is on the LEFT on the screen.
switch (location)
{
- case HandLocation.Right:
+ case HandUILocation.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:
- case HandLocation.Left:
+ case HandUILocation.Left:
texture = Theme.ResolveTexture("item_status_left");
textureHighlight = Theme.ResolveTexture("item_status_left_highlight");
cutOut = StyleBox.Margin.Right;
public void Update(EntityUid? entity)
{
+ ItemNameLabel.Visible = entity != null;
+ NoItemLabel.Visible = entity == null;
+
if (entity == null)
{
+ ItemNameLabel.Text = "";
ClearOldStatus();
_entity = null;
- VisWrapper.Visible = false;
return;
}
UpdateItemName();
}
-
- VisWrapper.Visible = true;
}
public void UpdateHighlight(bool highlight)
namespace Content.Client.Weapons.Ranged.ItemStatus;
-/// <summary>
-/// Renders one or more rows of bullets for item status.
-/// </summary>
-/// <remarks>
-/// This is a custom control to allow complex responsive layout logic.
-/// </remarks>
-public sealed class BulletRender : Control
+public abstract class BaseBulletRenderer : 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");
-
- /// <summary>
- /// Try to ensure there's at least this many bullets on one row.
- /// </summary>
- /// <remarks>
- /// 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.
- /// </remarks>
- 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;
+ private LayoutParameters _params;
public int Rows { get; set; } = 2;
public int Count { get; set; }
get => _capacity;
set
{
+ if (_capacity == value)
+ return;
+
_capacity = value;
InvalidateMeasure();
}
}
- public BulletType Type
+ protected LayoutParameters Parameters
{
- get => _type;
+ get => _params;
set
{
- _type = value;
+ _params = value;
InvalidateMeasure();
}
}
- public BulletRender()
- {
- var resC = IoCManager.Resolve<IResourceCache>();
- _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 height = _params.ItemHeight * rows + (_params.VerticalSeparation * rows - 1);
var width = RowWidth(countPerRow);
return new Vector2(width, height);
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 altColor = false;
var thisRowCount = Math.Min(countPerRow, Capacity - bulletsDone);
if (thisRowCount <= 0)
// 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).
+ // 4. There's enough bullets that at least one will end up on the next row.
var nextRowCount = Capacity - bulletsDone - thisRowCount;
- if (nextRowCount < MinCountPerRow && row != Rows - 1 && MinCountPerRow < countPerRow)
- thisRowCount -= MinCountPerRow - nextRowCount;
+ if (nextRowCount < _params.MinCountPerRow && row != Rows - 1 && _params.MinCountPerRow < countPerRow && nextRowCount > 0)
+ thisRowCount -= _params.MinCountPerRow - nextRowCount;
// Account for row width to right-align.
var rowWidth = RowWidth(thisRowCount);
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;
+ renderPos.Y = Size.Y - renderPos.Y - _params.ItemHeight;
+
+ DrawItem(handle, renderPos, absIdx < spent, altColor);
+
+ pos.X += _params.ItemSeparation;
altColor ^= true;
}
bulletsDone += thisRowCount;
pos.X = 0;
- pos.Y += BulletHeight + VerticalSeparation;
+ pos.Y += _params.ItemHeight + _params.VerticalSeparation;
}
}
+ protected abstract void DrawItem(DrawingHandleScreen handle, Vector2 renderPos, bool spent, bool altColor);
+
private int CountPerRow(float width)
{
- var (separation, bulletWidth) = BulletParams();
- return (int) ((width - bulletWidth + separation) / separation);
+ return (int) ((width - _params.ItemWidth + _params.ItemSeparation) / _params.ItemSeparation);
+ }
+
+ private int RowWidth(int count)
+ {
+ return (count - 1) * _params.ItemSeparation + _params.ItemWidth;
}
- private (int separation, int width) BulletParams()
+ protected struct LayoutParameters
{
- return Type switch
+ public int ItemHeight;
+ public int ItemSeparation;
+ public int ItemWidth;
+ public int VerticalSeparation;
+
+ /// <summary>
+ /// Try to ensure there's at least this many bullets on one row.
+ /// </summary>
+ /// <remarks>
+ /// 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.
+ /// </remarks>
+ public int MinCountPerRow;
+ }
+}
+
+/// <summary>
+/// Renders one or more rows of bullets for item status.
+/// </summary>
+/// <remarks>
+/// This is a custom control to allow complex responsive layout logic.
+/// </remarks>
+public sealed class BulletRender : BaseBulletRenderer
+{
+ public const int MinCountPerRow = 7;
+
+ public const int BulletHeight = 12;
+ public const int VerticalSeparation = 2;
+
+ private static readonly LayoutParameters LayoutNormal = new LayoutParameters
+ {
+ ItemHeight = BulletHeight,
+ ItemSeparation = 3,
+ ItemWidth = 5,
+ VerticalSeparation = VerticalSeparation,
+ MinCountPerRow = MinCountPerRow
+ };
+
+ private static readonly LayoutParameters LayoutTiny = new LayoutParameters
+ {
+ ItemHeight = BulletHeight,
+ ItemSeparation = 2,
+ ItemWidth = 2,
+ VerticalSeparation = VerticalSeparation,
+ MinCountPerRow = MinCountPerRow
+ };
+
+ 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");
+
+ private readonly Texture _bulletTiny;
+ private readonly Texture _bulletNormal;
+
+ private BulletType _type = BulletType.Normal;
+
+ public BulletType Type
+ {
+ get => _type;
+ set
{
- BulletType.Normal => (BulletSeparationNormal, BulletWidthNormal),
- BulletType.Tiny => (BulletSeparationTiny, BulletWidthTiny),
- _ => throw new ArgumentOutOfRangeException()
- };
+ if (_type == value)
+ return;
+
+ Parameters = _type switch
+ {
+ BulletType.Normal => LayoutNormal,
+ BulletType.Tiny => LayoutTiny,
+ _ => throw new ArgumentOutOfRangeException()
+ };
+
+ _type = value;
+ }
}
- private int RowWidth(int count)
+ public BulletRender()
{
- var (separation, bulletWidth) = BulletParams();
+ var resC = IoCManager.Resolve<IResourceCache>();
+ _bulletTiny = resC.GetTexture("/Textures/Interface/ItemStatus/Bullets/tiny.png");
+ _bulletNormal = resC.GetTexture("/Textures/Interface/ItemStatus/Bullets/normal.png");
+ Parameters = LayoutNormal;
+ }
- return (count - 1) * separation + bulletWidth;
+ protected override void DrawItem(DrawingHandleScreen handle, Vector2 renderPos, bool spent, bool altColor)
+ {
+ Color color;
+ if (spent)
+ color = altColor ? ColorGoneA : ColorGoneB;
+ else
+ color = altColor ? ColorA : ColorB;
+
+ var texture = _type == BulletType.Tiny ? _bulletTiny : _bulletNormal;
+ handle.DrawTexture(texture, renderPos, color);
}
public enum BulletType
Tiny
}
}
+
+public sealed class BatteryBulletRenderer : BaseBulletRenderer
+{
+ private static readonly Color ItemColor = Color.FromHex("#E00000");
+ private static readonly Color ItemColorGone = Color.Black;
+
+ private const int SizeH = 10;
+ private const int SizeV = 10;
+ private const int Separation = 4;
+
+ public BatteryBulletRenderer()
+ {
+ Parameters = new LayoutParameters
+ {
+ ItemWidth = SizeH,
+ ItemHeight = SizeV,
+ ItemSeparation = SizeH + Separation,
+ MinCountPerRow = 3,
+ VerticalSeparation = Separation
+ };
+ }
+
+ protected override void DrawItem(DrawingHandleScreen handle, Vector2 renderPos, bool spent, bool altColor)
+ {
+ var color = spent ? ItemColorGone : ItemColor;
+ handle.DrawRect(UIBox2.FromDimensions(renderPos, new Vector2(SizeH, SizeV)), color);
+ }
+}
public sealed class BoxesStatusControl : Control
{
- private readonly BoxContainer _bulletsList;
+ private readonly BatteryBulletRenderer _bullets;
private readonly Label _ammoCount;
public BoxesStatusControl()
AddChild(new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
- HorizontalExpand = true,
Children =
{
- new Control
+ (_bullets = new BatteryBulletRenderer
{
- HorizontalExpand = true,
- Children =
- {
- (_bulletsList = new BoxContainer
- {
- Orientation = BoxContainer.LayoutOrientation.Horizontal,
- VerticalAlignment = VAlignment.Center,
- SeparationOverride = 4
- }),
- }
- },
- new Control() { MinSize = new Vector2(5, 0) },
+ Margin = new Thickness(0, 0, 5, 0),
+ HorizontalExpand = true
+ }),
(_ammoCount = new Label
{
StyleClasses = { StyleNano.StyleClassItemStatus },
HorizontalAlignment = HAlignment.Right,
+ VerticalAlignment = VAlignment.Bottom
}),
}
});
public void Update(int count, int max)
{
- _bulletsList.RemoveAllChildren();
-
_ammoCount.Visible = true;
_ammoCount.Text = $"x{count:00}";
- max = Math.Min(max, 8);
- FillBulletRow(_bulletsList, count, max);
- }
- private static void FillBulletRow(Control container, int count, int capacity)
- {
- var colorGone = Color.FromHex("#000000");
- var color = Color.FromHex("#E00000");
-
- // Draw the empty ones
- for (var i = count; i < capacity; i++)
- {
- container.AddChild(new PanelContainer
- {
- PanelOverride = new StyleBoxFlat()
- {
- BackgroundColor = colorGone,
- },
- MinSize = new Vector2(10, 15),
- });
- }
-
- // 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 PanelContainer
- {
- PanelOverride = new StyleBoxFlat()
- {
- BackgroundColor = color,
- },
- MinSize = new Vector2(10, 15),
- });
- }
+ _bullets.Capacity = max;
+ _bullets.Count = count;
}
}
/// <summary>
/// What side of the body this hand is on.
/// </summary>
+/// <seealso cref="HandUILocation"/>
+/// <seealso cref="HandLocationExt"/>
public enum HandLocation : byte
{
Left,
Middle,
Right
}
+
+/// <summary>
+/// What side of the UI a hand is on.
+/// </summary>
+/// <seealso cref="HandLocationExt"/>
+/// <seealso cref="HandLocation"/>
+public enum HandUILocation : byte
+{
+ Left,
+ Right
+}
+
+/// <summary>
+/// Helper functions for working with <see cref="HandLocation"/>.
+/// </summary>
+public static class HandLocationExt
+{
+ /// <summary>
+ /// Convert a <see cref="HandLocation"/> into the appropriate <see cref="HandUILocation"/>.
+ /// This maps "middle" hands to <see cref="HandUILocation.Right"/>.
+ /// </summary>
+ public static HandUILocation GetUILocation(this HandLocation location)
+ {
+ return location switch
+ {
+ HandLocation.Left => HandUILocation.Left,
+ HandLocation.Middle => HandUILocation.Right,
+ HandLocation.Right => HandUILocation.Right,
+ _ => throw new ArgumentOutOfRangeException(nameof(location), location, null)
+ };
+ }
+}
network-configurator-examine-switch-modes = Press {$key} to switch modes
# item status
-network-configurator-item-status-label = Current mode: {$mode}
-{$keybinding} to switch mode
+network-configurator-item-status-label = Mode: {$mode}
+ Switch: {$keybinding}
implanter-draw-text = Draw
implanter-inject-text = Inject
-implanter-empty-text = None
+implanter-empty-text = Empty
-implanter-label = Implant: [color=green]{$implantName}[/color] | [color=white]{$modeString}[/color]{$lineBreak}{$implantDescription}
+implanter-label = [color=green]{$implantName}[/color]
+ Mode: [color=white]{$modeString}[/color]
implanter-contained-implant-text = [color=green]{$desc}[/color]
--- /dev/null
+item-status-not-held = No held item
-geiger-item-control-status = Radiation: [color={$color}]{$rads} rads[/color]
+geiger-item-control-status = [color={$color}]{$rads} rads[/color]
geiger-item-control-disabled = Disabled
geiger-component-examine = Current radiation: [color={$color}]{$rads} rads[/color]