Various item status fixes/tweaks (#27267)
* Always display item status panel fully Initial feedback from the UI changes seems to be that a lot of people go "why is there empty space" so let's fix that. * Fix item status middle hand being on the wrong side I think I switched this around when fixing the left/right being inverted in the UI code. * Minor status panel UI tweaks Bottom-align contents now that the panel itself doesn't dynamically expand, prevent weird gaps. Clip contents for panel * Fix clipping on implanters and network configurators. Made them take less space. For implanters the name has to be cut off, which I did by adding a new ClipControl to achieve that in rich text. * Update visibility of item status panels based on whether you have hands at all. This avoids UI for borgs looking silly. Added a new "HandUILocation" enum that doesn't have middle hands to avoid confusion in UI code. * Use BulletRender for laser guns too. Provides all the benefits like fixing layout overflow and allowing multi-line stuff. Looks great now. This involved generalizing BulletRender a bit so it can be used for not-just-bullets. * Fix geiger word wrapping if you're really fucked
This commit is contained in:
committed by
GitHub
parent
38f490e5eb
commit
7b90c08a2c
@@ -1,5 +1,6 @@
|
|||||||
using Content.Client.Message;
|
using Content.Client.Message;
|
||||||
using Content.Client.Stylesheets;
|
using Content.Client.Stylesheets;
|
||||||
|
using Content.Client.UserInterface.Controls;
|
||||||
using Content.Shared.Implants.Components;
|
using Content.Shared.Implants.Components;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
@@ -17,7 +18,7 @@ public sealed class ImplanterStatusControl : Control
|
|||||||
_parent = parent;
|
_parent = parent;
|
||||||
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
|
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
|
||||||
_label.MaxWidth = 350;
|
_label.MaxWidth = 350;
|
||||||
AddChild(_label);
|
AddChild(new ClipControl { Children = { _label } });
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
@@ -42,17 +43,12 @@ public sealed class ImplanterStatusControl : Control
|
|||||||
_ => Loc.GetString("injector-invalid-injector-toggle-mode")
|
_ => Loc.GetString("injector-invalid-injector-toggle-mode")
|
||||||
};
|
};
|
||||||
|
|
||||||
var (implantName, implantDescription) = _parent.ImplanterSlot.HasItem switch
|
var implantName = _parent.ImplanterSlot.HasItem
|
||||||
{
|
? _parent.ImplantData.Item1
|
||||||
false => (Loc.GetString("implanter-empty-text"), ""),
|
: Loc.GetString("implanter-empty-text");
|
||||||
true => (_parent.ImplantData.Item1, _parent.ImplantData.Item2),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
_label.SetMarkup(Loc.GetString("implanter-label",
|
_label.SetMarkup(Loc.GetString("implanter-label",
|
||||||
("implantName", implantName),
|
("implantName", implantName),
|
||||||
("implantDescription", implantDescription),
|
("modeString", modeStringLocalized)));
|
||||||
("modeString", modeStringLocalized),
|
|
||||||
("lineBreak", "\n")));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ namespace Content.Client.Stylesheets
|
|||||||
public const string StyleClassPowerStateGood = "PowerStateGood";
|
public const string StyleClassPowerStateGood = "PowerStateGood";
|
||||||
|
|
||||||
public const string StyleClassItemStatus = "ItemStatus";
|
public const string StyleClassItemStatus = "ItemStatus";
|
||||||
|
public const string StyleClassItemStatusNotHeld = "ItemStatusNotHeld";
|
||||||
|
public static readonly Color ItemStatusNotHeldColor = Color.Gray;
|
||||||
|
|
||||||
//Background
|
//Background
|
||||||
public const string StyleClassBackgroundBaseDark = "PanelBackgroundBaseDark";
|
public const string StyleClassBackgroundBaseDark = "PanelBackgroundBaseDark";
|
||||||
@@ -1234,6 +1236,11 @@ namespace Content.Client.Stylesheets
|
|||||||
new StyleProperty("font", notoSans10),
|
new StyleProperty("font", notoSans10),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
Element()
|
||||||
|
.Class(StyleClassItemStatusNotHeld)
|
||||||
|
.Prop("font", notoSansItalic10)
|
||||||
|
.Prop("font-color", ItemStatusNotHeldColor),
|
||||||
|
|
||||||
Element<RichTextLabel>()
|
Element<RichTextLabel>()
|
||||||
.Class(StyleClassItemStatus)
|
.Class(StyleClassItemStatus)
|
||||||
.Prop(nameof(RichTextLabel.LineHeightScale), 0.7f)
|
.Prop(nameof(RichTextLabel.LineHeightScale), 0.7f)
|
||||||
|
|||||||
55
Content.Client/UserInterface/Controls/ClipControl.cs
Normal file
55
Content.Client/UserInterface/Controls/ClipControl.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,8 +5,11 @@ namespace Content.Client.UserInterface.Systems.Hands.Controls;
|
|||||||
|
|
||||||
public sealed class HandButton : SlotControl
|
public sealed class HandButton : SlotControl
|
||||||
{
|
{
|
||||||
|
public HandLocation HandLocation { get; }
|
||||||
|
|
||||||
public HandButton(string handName, HandLocation handLocation)
|
public HandButton(string handName, HandLocation handLocation)
|
||||||
{
|
{
|
||||||
|
HandLocation = handLocation;
|
||||||
Name = "hand_" + handName;
|
Name = "hand_" + handName;
|
||||||
SlotName = handName;
|
SlotName = handName;
|
||||||
SetBackground(handLocation);
|
SetBackground(handLocation);
|
||||||
|
|||||||
@@ -256,7 +256,8 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
|||||||
_player.LocalSession?.AttachedEntity is { } playerEntity &&
|
_player.LocalSession?.AttachedEntity is { } playerEntity &&
|
||||||
_handsSystem.TryGetHand(playerEntity, handName, out var hand, _playerHandsComponent))
|
_handsSystem.TryGetHand(playerEntity, handName, out var hand, _playerHandsComponent))
|
||||||
{
|
{
|
||||||
if (hand.Location == HandLocation.Left)
|
var foldedLocation = hand.Location.GetUILocation();
|
||||||
|
if (foldedLocation == HandUILocation.Left)
|
||||||
{
|
{
|
||||||
_statusHandLeft = handControl;
|
_statusHandLeft = handControl;
|
||||||
HandsGui.UpdatePanelEntityLeft(hand.HeldEntity);
|
HandsGui.UpdatePanelEntityLeft(hand.HeldEntity);
|
||||||
@@ -268,7 +269,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
|||||||
HandsGui.UpdatePanelEntityRight(hand.HeldEntity);
|
HandsGui.UpdatePanelEntityRight(hand.HeldEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandsGui.SetHighlightHand(hand.Location);
|
HandsGui.SetHighlightHand(foldedLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,11 +300,13 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
|||||||
// If we don't have a status for this hand type yet, set it.
|
// 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,
|
// 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.
|
// 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;
|
_statusHandLeft ??= button;
|
||||||
else
|
else
|
||||||
_statusHandRight ??= button;
|
_statusHandRight ??= button;
|
||||||
|
|
||||||
|
UpdateVisibleStatusPanels();
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,9 +372,30 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
|||||||
|
|
||||||
_handLookup.Remove(handName);
|
_handLookup.Remove(handName);
|
||||||
handButton.Dispose();
|
handButton.Dispose();
|
||||||
|
UpdateVisibleStatusPanels();
|
||||||
return true;
|
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)
|
public string RegisterHandContainer(HandsContainer handContainer)
|
||||||
{
|
{
|
||||||
var name = "HandContainer_" + _backupSuffix;
|
var name = "HandContainer_" + _backupSuffix;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
Name="StatusPanelRight"
|
Name="StatusPanelRight"
|
||||||
HorizontalAlignment="Center" Margin="0 0 -2 2"
|
HorizontalAlignment="Center" Margin="0 0 -2 2"
|
||||||
SetWidth="125"
|
SetWidth="125"
|
||||||
MaxHeight="60"/>
|
SetHeight="60"/>
|
||||||
<hands:HandsContainer
|
<hands:HandsContainer
|
||||||
Name="HandContainer"
|
Name="HandContainer"
|
||||||
Access="Public"
|
Access="Public"
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
Name="StatusPanelLeft"
|
Name="StatusPanelLeft"
|
||||||
HorizontalAlignment="Center" Margin="-2 0 0 2"
|
HorizontalAlignment="Center" Margin="-2 0 0 2"
|
||||||
SetWidth="125"
|
SetWidth="125"
|
||||||
MaxHeight="60"/>
|
SetHeight="60"/>
|
||||||
<inventory:ItemSlotButtonContainer
|
<inventory:ItemSlotButtonContainer
|
||||||
Name="MainHotbar"
|
Name="MainHotbar"
|
||||||
SlotGroup="MainHotbar"
|
SlotGroup="MainHotbar"
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ public sealed partial class HotbarGui : UIWidget
|
|||||||
public HotbarGui()
|
public HotbarGui()
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
StatusPanelRight.SetSide(HandLocation.Right);
|
StatusPanelRight.SetSide(HandUILocation.Right);
|
||||||
StatusPanelLeft.SetSide(HandLocation.Left);
|
StatusPanelLeft.SetSide(HandUILocation.Left);
|
||||||
var hotbarController = UserInterfaceManager.GetUIController<HotbarUIController>();
|
var hotbarController = UserInterfaceManager.GetUIController<HotbarUIController>();
|
||||||
|
|
||||||
hotbarController.Setup(HandContainer, StoragePanel);
|
hotbarController.Setup(HandContainer, StoragePanel);
|
||||||
@@ -29,9 +29,15 @@ public sealed partial class HotbarGui : UIWidget
|
|||||||
StatusPanelRight.Update(entity);
|
StatusPanelRight.Update(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetHighlightHand(HandLocation? hand)
|
public void SetHighlightHand(HandUILocation? hand)
|
||||||
{
|
{
|
||||||
StatusPanelLeft.UpdateHighlight(hand is HandLocation.Left);
|
StatusPanelLeft.UpdateHighlight(hand is HandUILocation.Left);
|
||||||
StatusPanelRight.UpdateHighlight(hand is HandLocation.Middle or HandLocation.Right);
|
StatusPanelRight.UpdateHighlight(hand is HandUILocation.Right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateStatusVisibility(bool left, bool right)
|
||||||
|
{
|
||||||
|
StatusPanelLeft.Visible = left;
|
||||||
|
StatusPanelRight.Visible = right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,25 +4,26 @@
|
|||||||
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
HorizontalAlignment="Center">
|
HorizontalAlignment="Center">
|
||||||
<Control Name="VisWrapper" Visible="False">
|
<PanelContainer Name="Panel">
|
||||||
<PanelContainer Name="Panel">
|
<PanelContainer.PanelOverride>
|
||||||
<PanelContainer.PanelOverride>
|
<graphics:StyleBoxTexture
|
||||||
<graphics:StyleBoxTexture
|
PatchMarginBottom="4"
|
||||||
PatchMarginBottom="4"
|
PatchMarginTop="6"
|
||||||
PatchMarginTop="6"
|
TextureScale="2 2"
|
||||||
TextureScale="2 2"
|
Mode="Tile"/>
|
||||||
Mode="Tile"/>
|
</PanelContainer.PanelOverride>
|
||||||
</PanelContainer.PanelOverride>
|
</PanelContainer>
|
||||||
</PanelContainer>
|
<PanelContainer Name="HighlightPanel">
|
||||||
<PanelContainer Name="HighlightPanel">
|
<PanelContainer.PanelOverride>
|
||||||
<PanelContainer.PanelOverride>
|
<graphics:StyleBoxTexture PatchMarginBottom="4" PatchMarginTop="6" TextureScale="2 2">
|
||||||
<graphics:StyleBoxTexture PatchMarginBottom="4" PatchMarginTop="6" TextureScale="2 2">
|
</graphics:StyleBoxTexture>
|
||||||
</graphics:StyleBoxTexture>
|
</PanelContainer.PanelOverride>
|
||||||
</PanelContainer.PanelOverride>
|
</PanelContainer>
|
||||||
</PanelContainer>
|
<BoxContainer Name="Contents" Orientation="Vertical" Margin="0 6 0 4" RectClipContent="True">
|
||||||
<BoxContainer Name="Contents" Orientation="Vertical" Margin="0 6 0 4">
|
<BoxContainer Name="StatusContents" Orientation="Vertical" VerticalExpand="True" VerticalAlignment="Bottom" />
|
||||||
<BoxContainer Name="StatusContents" Orientation="Vertical" />
|
<Control>
|
||||||
<Label Name="ItemNameLabel" ClipText="True" StyleClasses="ItemStatus" Align="Left" />
|
<Label Name="NoItemLabel" ClipText="True" StyleClasses="ItemStatusNotHeld" Align="Left" Text="{Loc 'item-status-not-held'}" />
|
||||||
</BoxContainer>
|
<Label Name="ItemNameLabel" ClipText="True" StyleClasses="ItemStatus" Align="Left" Visible="False" />
|
||||||
</Control>
|
</Control>
|
||||||
|
</BoxContainer>
|
||||||
</controls:ItemStatusPanel>
|
</controls:ItemStatusPanel>
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
using System.Numerics;
|
|
||||||
using Content.Client.Items;
|
using Content.Client.Items;
|
||||||
using Content.Client.Resources;
|
|
||||||
using Content.Shared.Hands.Components;
|
using Content.Shared.Hands.Components;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Inventory.VirtualItem;
|
using Content.Shared.Inventory.VirtualItem;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using static Content.Client.IoC.StaticIoC;
|
|
||||||
|
|
||||||
namespace Content.Client.UserInterface.Systems.Inventory.Controls;
|
namespace Content.Client.UserInterface.Systems.Inventory.Controls;
|
||||||
|
|
||||||
@@ -23,17 +19,15 @@ public sealed partial class ItemStatusPanel : Control
|
|||||||
[ViewVariables] private EntityUid? _entity;
|
[ViewVariables] private EntityUid? _entity;
|
||||||
|
|
||||||
// Tracked so we can re-run SetSide() if the theme changes.
|
// Tracked so we can re-run SetSide() if the theme changes.
|
||||||
private HandLocation _side;
|
private HandUILocation _side;
|
||||||
|
|
||||||
public ItemStatusPanel()
|
public ItemStatusPanel()
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
SetSide(HandLocation.Middle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSide(HandLocation location)
|
public void SetSide(HandUILocation location)
|
||||||
{
|
{
|
||||||
// AN IMPORTANT REMINDER ABOUT THIS CODE:
|
// AN IMPORTANT REMINDER ABOUT THIS CODE:
|
||||||
// In the UI, the RIGHT hand is on the LEFT on the screen.
|
// In the UI, the RIGHT hand is on the LEFT on the screen.
|
||||||
@@ -47,15 +41,14 @@ public sealed partial class ItemStatusPanel : Control
|
|||||||
|
|
||||||
switch (location)
|
switch (location)
|
||||||
{
|
{
|
||||||
case HandLocation.Right:
|
case HandUILocation.Right:
|
||||||
texture = Theme.ResolveTexture("item_status_right");
|
texture = Theme.ResolveTexture("item_status_right");
|
||||||
textureHighlight = Theme.ResolveTexture("item_status_right_highlight");
|
textureHighlight = Theme.ResolveTexture("item_status_right_highlight");
|
||||||
cutOut = StyleBox.Margin.Left;
|
cutOut = StyleBox.Margin.Left;
|
||||||
flat = StyleBox.Margin.Right;
|
flat = StyleBox.Margin.Right;
|
||||||
contentMargin = MarginFromThemeColor("_itemstatus_content_margin_right");
|
contentMargin = MarginFromThemeColor("_itemstatus_content_margin_right");
|
||||||
break;
|
break;
|
||||||
case HandLocation.Middle:
|
case HandUILocation.Left:
|
||||||
case HandLocation.Left:
|
|
||||||
texture = Theme.ResolveTexture("item_status_left");
|
texture = Theme.ResolveTexture("item_status_left");
|
||||||
textureHighlight = Theme.ResolveTexture("item_status_left_highlight");
|
textureHighlight = Theme.ResolveTexture("item_status_left_highlight");
|
||||||
cutOut = StyleBox.Margin.Right;
|
cutOut = StyleBox.Margin.Right;
|
||||||
@@ -104,11 +97,14 @@ public sealed partial class ItemStatusPanel : Control
|
|||||||
|
|
||||||
public void Update(EntityUid? entity)
|
public void Update(EntityUid? entity)
|
||||||
{
|
{
|
||||||
|
ItemNameLabel.Visible = entity != null;
|
||||||
|
NoItemLabel.Visible = entity == null;
|
||||||
|
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
{
|
{
|
||||||
|
ItemNameLabel.Text = "";
|
||||||
ClearOldStatus();
|
ClearOldStatus();
|
||||||
_entity = null;
|
_entity = null;
|
||||||
VisWrapper.Visible = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,8 +115,6 @@ public sealed partial class ItemStatusPanel : Control
|
|||||||
|
|
||||||
UpdateItemName();
|
UpdateItemName();
|
||||||
}
|
}
|
||||||
|
|
||||||
VisWrapper.Visible = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateHighlight(bool highlight)
|
public void UpdateHighlight(bool highlight)
|
||||||
|
|||||||
@@ -6,40 +6,10 @@ using Robust.Client.UserInterface;
|
|||||||
|
|
||||||
namespace Content.Client.Weapons.Ranged.ItemStatus;
|
namespace Content.Client.Weapons.Ranged.ItemStatus;
|
||||||
|
|
||||||
/// <summary>
|
public abstract class BaseBulletRenderer : Control
|
||||||
/// 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
|
|
||||||
{
|
{
|
||||||
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 int _capacity;
|
||||||
private BulletType _type = BulletType.Normal;
|
private LayoutParameters _params;
|
||||||
|
|
||||||
public int Rows { get; set; } = 2;
|
public int Rows { get; set; } = 2;
|
||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
@@ -49,35 +19,31 @@ public sealed class BulletRender : Control
|
|||||||
get => _capacity;
|
get => _capacity;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
if (_capacity == value)
|
||||||
|
return;
|
||||||
|
|
||||||
_capacity = value;
|
_capacity = value;
|
||||||
InvalidateMeasure();
|
InvalidateMeasure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BulletType Type
|
protected LayoutParameters Parameters
|
||||||
{
|
{
|
||||||
get => _type;
|
get => _params;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_type = value;
|
_params = value;
|
||||||
InvalidateMeasure();
|
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)
|
protected override Vector2 MeasureOverride(Vector2 availableSize)
|
||||||
{
|
{
|
||||||
var countPerRow = Math.Min(Capacity, CountPerRow(availableSize.X));
|
var countPerRow = Math.Min(Capacity, CountPerRow(availableSize.X));
|
||||||
|
|
||||||
var rows = Math.Min((int) MathF.Ceiling(Capacity / (float) countPerRow), Rows);
|
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);
|
var width = RowWidth(countPerRow);
|
||||||
|
|
||||||
return new Vector2(width, height);
|
return new Vector2(width, height);
|
||||||
@@ -91,13 +57,8 @@ public sealed class BulletRender : Control
|
|||||||
|
|
||||||
var countPerRow = CountPerRow(Size.X);
|
var countPerRow = CountPerRow(Size.X);
|
||||||
|
|
||||||
var (separation, _) = BulletParams();
|
|
||||||
var texture = Type == BulletType.Normal ? _bulletNormal : _bulletTiny;
|
|
||||||
|
|
||||||
var pos = new Vector2();
|
var pos = new Vector2();
|
||||||
|
|
||||||
var altColor = false;
|
|
||||||
|
|
||||||
var spent = Capacity - Count;
|
var spent = Capacity - Count;
|
||||||
|
|
||||||
var bulletsDone = 0;
|
var bulletsDone = 0;
|
||||||
@@ -105,7 +66,7 @@ public sealed class BulletRender : Control
|
|||||||
// Draw by rows, bottom to top.
|
// Draw by rows, bottom to top.
|
||||||
for (var row = 0; row < Rows; row++)
|
for (var row = 0; row < Rows; row++)
|
||||||
{
|
{
|
||||||
altColor = false;
|
var altColor = false;
|
||||||
|
|
||||||
var thisRowCount = Math.Min(countPerRow, Capacity - bulletsDone);
|
var thisRowCount = Math.Min(countPerRow, Capacity - bulletsDone);
|
||||||
if (thisRowCount <= 0)
|
if (thisRowCount <= 0)
|
||||||
@@ -116,9 +77,10 @@ public sealed class BulletRender : Control
|
|||||||
// 1. The next row would have less than MinCountPerRow bullets.
|
// 1. The next row would have less than MinCountPerRow bullets.
|
||||||
// 2. The next row is actually visible (we aren't the last row).
|
// 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).
|
// 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;
|
var nextRowCount = Capacity - bulletsDone - thisRowCount;
|
||||||
if (nextRowCount < MinCountPerRow && row != Rows - 1 && MinCountPerRow < countPerRow)
|
if (nextRowCount < _params.MinCountPerRow && row != Rows - 1 && _params.MinCountPerRow < countPerRow && nextRowCount > 0)
|
||||||
thisRowCount -= MinCountPerRow - nextRowCount;
|
thisRowCount -= _params.MinCountPerRow - nextRowCount;
|
||||||
|
|
||||||
// Account for row width to right-align.
|
// Account for row width to right-align.
|
||||||
var rowWidth = RowWidth(thisRowCount);
|
var rowWidth = RowWidth(thisRowCount);
|
||||||
@@ -128,46 +90,130 @@ public sealed class BulletRender : Control
|
|||||||
for (var bullet = 0; bullet < thisRowCount; bullet++)
|
for (var bullet = 0; bullet < thisRowCount; bullet++)
|
||||||
{
|
{
|
||||||
var absIdx = Capacity - bulletsDone - 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;
|
var renderPos = pos;
|
||||||
renderPos.Y = Size.Y - renderPos.Y - BulletHeight;
|
renderPos.Y = Size.Y - renderPos.Y - _params.ItemHeight;
|
||||||
handle.DrawTexture(texture, renderPos, color);
|
|
||||||
pos.X += separation;
|
DrawItem(handle, renderPos, absIdx < spent, altColor);
|
||||||
|
|
||||||
|
pos.X += _params.ItemSeparation;
|
||||||
altColor ^= true;
|
altColor ^= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bulletsDone += thisRowCount;
|
bulletsDone += thisRowCount;
|
||||||
pos.X = 0;
|
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)
|
private int CountPerRow(float width)
|
||||||
{
|
{
|
||||||
var (separation, bulletWidth) = BulletParams();
|
return (int) ((width - _params.ItemWidth + _params.ItemSeparation) / _params.ItemSeparation);
|
||||||
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)
|
private int RowWidth(int count)
|
||||||
{
|
{
|
||||||
var (separation, bulletWidth) = BulletParams();
|
return (count - 1) * _params.ItemSeparation + _params.ItemWidth;
|
||||||
|
}
|
||||||
|
|
||||||
return (count - 1) * separation + bulletWidth;
|
protected struct LayoutParameters
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
if (_type == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Parameters = _type switch
|
||||||
|
{
|
||||||
|
BulletType.Normal => LayoutNormal,
|
||||||
|
BulletType.Tiny => LayoutTiny,
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
};
|
||||||
|
|
||||||
|
_type = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
Parameters = LayoutNormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
public enum BulletType
|
||||||
@@ -176,3 +222,31 @@ public sealed class BulletRender : Control
|
|||||||
Tiny
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public sealed partial class GunSystem
|
|||||||
|
|
||||||
public sealed class BoxesStatusControl : Control
|
public sealed class BoxesStatusControl : Control
|
||||||
{
|
{
|
||||||
private readonly BoxContainer _bulletsList;
|
private readonly BatteryBulletRenderer _bullets;
|
||||||
private readonly Label _ammoCount;
|
private readonly Label _ammoCount;
|
||||||
|
|
||||||
public BoxesStatusControl()
|
public BoxesStatusControl()
|
||||||
@@ -128,27 +128,18 @@ public sealed partial class GunSystem
|
|||||||
AddChild(new BoxContainer
|
AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Control
|
(_bullets = new BatteryBulletRenderer
|
||||||
{
|
{
|
||||||
HorizontalExpand = true,
|
Margin = new Thickness(0, 0, 5, 0),
|
||||||
Children =
|
HorizontalExpand = true
|
||||||
{
|
}),
|
||||||
(_bulletsList = new BoxContainer
|
|
||||||
{
|
|
||||||
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
|
||||||
VerticalAlignment = VAlignment.Center,
|
|
||||||
SeparationOverride = 4
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Control() { MinSize = new Vector2(5, 0) },
|
|
||||||
(_ammoCount = new Label
|
(_ammoCount = new Label
|
||||||
{
|
{
|
||||||
StyleClasses = { StyleNano.StyleClassItemStatus },
|
StyleClasses = { StyleNano.StyleClassItemStatus },
|
||||||
HorizontalAlignment = HAlignment.Right,
|
HorizontalAlignment = HAlignment.Right,
|
||||||
|
VerticalAlignment = VAlignment.Bottom
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -156,46 +147,12 @@ public sealed partial class GunSystem
|
|||||||
|
|
||||||
public void Update(int count, int max)
|
public void Update(int count, int max)
|
||||||
{
|
{
|
||||||
_bulletsList.RemoveAllChildren();
|
|
||||||
|
|
||||||
_ammoCount.Visible = true;
|
_ammoCount.Visible = true;
|
||||||
|
|
||||||
_ammoCount.Text = $"x{count:00}";
|
_ammoCount.Text = $"x{count:00}";
|
||||||
max = Math.Min(max, 8);
|
|
||||||
FillBulletRow(_bulletsList, count, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void FillBulletRow(Control container, int count, int capacity)
|
_bullets.Capacity = max;
|
||||||
{
|
_bullets.Count = count;
|
||||||
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),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,9 +126,43 @@ public sealed class HandsComponentState : ComponentState
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// What side of the body this hand is on.
|
/// What side of the body this hand is on.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <seealso cref="HandUILocation"/>
|
||||||
|
/// <seealso cref="HandLocationExt"/>
|
||||||
public enum HandLocation : byte
|
public enum HandLocation : byte
|
||||||
{
|
{
|
||||||
Left,
|
Left,
|
||||||
Middle,
|
Middle,
|
||||||
Right
|
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)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,5 +41,5 @@ network-configurator-examine-current-mode = Current mode: {$mode}
|
|||||||
network-configurator-examine-switch-modes = Press {$key} to switch modes
|
network-configurator-examine-switch-modes = Press {$key} to switch modes
|
||||||
|
|
||||||
# item status
|
# item status
|
||||||
network-configurator-item-status-label = Current mode: {$mode}
|
network-configurator-item-status-label = Mode: {$mode}
|
||||||
{$keybinding} to switch mode
|
Switch: {$keybinding}
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ implanter-component-implant-already = {$target} already has the {$implant}!
|
|||||||
implanter-draw-text = Draw
|
implanter-draw-text = Draw
|
||||||
implanter-inject-text = Inject
|
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]
|
implanter-contained-implant-text = [color=green]{$desc}[/color]
|
||||||
|
|
||||||
|
|||||||
1
Resources/Locale/en-US/inventory/item-status.ftl
Normal file
1
Resources/Locale/en-US/inventory/item-status.ftl
Normal file
@@ -0,0 +1 @@
|
|||||||
|
item-status-not-held = No held item
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
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-item-control-disabled = Disabled
|
||||||
geiger-component-examine = Current radiation: [color={$color}]{$rads} rads[/color]
|
geiger-component-examine = Current radiation: [color={$color}]{$rads} rads[/color]
|
||||||
|
|||||||
Reference in New Issue
Block a user