Alerts now use SpriteSpecifier

This commit is contained in:
Pieter-Jan Briers
2020-12-23 23:42:48 +01:00
parent 9b53793ca5
commit 44e3cc9395
5 changed files with 43 additions and 39 deletions

View File

@@ -25,7 +25,6 @@ namespace Content.Client.GameObjects.Components.Mobs
public sealed class ClientAlertsComponent : SharedAlertsComponent public sealed class ClientAlertsComponent : SharedAlertsComponent
{ {
[Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
private AlertsUI _ui; private AlertsUI _ui;
private AlertOrderPrototype _alertOrder; private AlertOrderPrototype _alertOrder;
@@ -202,7 +201,7 @@ namespace Content.Client.GameObjects.Components.Mobs
private AlertControl CreateAlertControl(AlertPrototype alert, AlertState alertState) private AlertControl CreateAlertControl(AlertPrototype alert, AlertState alertState)
{ {
var alertControl = new AlertControl(alert, alertState.Severity, _resourceCache) var alertControl = new AlertControl(alert, alertState.Severity)
{ {
Cooldown = alertState.Cooldown Cooldown = alertState.Cooldown
}; };

View File

@@ -1,10 +1,9 @@
#nullable enable #nullable enable
using System; using System;
using Content.Client.Utility;
using Content.Shared.Alert; using Content.Shared.Alert;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Client.Utility;
using Robust.Shared.Interfaces.Timing; using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Maths; using Robust.Shared.Maths;
@@ -41,23 +40,20 @@ namespace Content.Client.UserInterface.Controls
private readonly IGameTiming _gameTiming; private readonly IGameTiming _gameTiming;
private readonly TextureRect _icon; private readonly TextureRect _icon;
private readonly CooldownGraphic _cooldownGraphic; private readonly CooldownGraphic _cooldownGraphic;
private readonly IResourceCache _resourceCache;
/// <summary> /// <summary>
/// Creates an alert control reflecting the indicated alert + state /// Creates an alert control reflecting the indicated alert + state
/// </summary> /// </summary>
/// <param name="alert">alert to display</param> /// <param name="alert">alert to display</param>
/// <param name="severity">severity of alert, null if alert doesn't have severity levels</param> /// <param name="severity">severity of alert, null if alert doesn't have severity levels</param>
/// <param name="resourceCache">resourceCache to use to load alert icon textures</param> public AlertControl(AlertPrototype alert, short? severity)
public AlertControl(AlertPrototype alert, short? severity, IResourceCache resourceCache)
{ {
_gameTiming = IoCManager.Resolve<IGameTiming>(); _gameTiming = IoCManager.Resolve<IGameTiming>();
TooltipDelay = CustomTooltipDelay; TooltipDelay = CustomTooltipDelay;
TooltipSupplier = SupplyTooltip; TooltipSupplier = SupplyTooltip;
_resourceCache = resourceCache;
Alert = alert; Alert = alert;
_severity = severity; _severity = severity;
var texture = _resourceCache.GetTexture(alert.GetIconPath(_severity)); var texture = alert.GetIcon(_severity).Frame0();
_icon = new TextureRect _icon = new TextureRect
{ {
TextureScale = (2, 2), TextureScale = (2, 2),
@@ -83,7 +79,7 @@ namespace Content.Client.UserInterface.Controls
if (_severity != severity) if (_severity != severity)
{ {
_severity = severity; _severity = severity;
_icon.Texture = _resourceCache.GetTexture(Alert.GetIconPath(_severity)); _icon.Texture = Alert.GetIcon(_severity).Frame0();
} }
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Globalization;
using Content.Shared.Interfaces; using Content.Shared.Interfaces;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Log; using Robust.Shared.Log;
@@ -28,7 +29,7 @@ namespace Content.Shared.Alert
/// to get the correct icon path for a particular severity level. /// to get the correct icon path for a particular severity level.
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
public string IconPath { get; private set; } public SpriteSpecifier Icon { get; private set; }
/// <summary> /// <summary>
/// Name to show in tooltip window. Accepts formatting. /// Name to show in tooltip window. Accepts formatting.
@@ -59,6 +60,7 @@ namespace Content.Shared.Alert
/// -1 (no effect) unless MaxSeverity is specified. Defaults to 1. Minimum severity level supported by this state. /// -1 (no effect) unless MaxSeverity is specified. Defaults to 1. Minimum severity level supported by this state.
/// </summary> /// </summary>
public short MinSeverity => MaxSeverity == -1 ? (short) -1 : _minSeverity; public short MinSeverity => MaxSeverity == -1 ? (short) -1 : _minSeverity;
private short _minSeverity; private short _minSeverity;
/// <summary> /// <summary>
@@ -87,7 +89,7 @@ namespace Content.Shared.Alert
{ {
var serializer = YamlObjectSerializer.NewReader(mapping); var serializer = YamlObjectSerializer.NewReader(mapping);
serializer.DataField(this, x => x.IconPath, "icon", string.Empty); serializer.DataField(this, x => x.Icon, "icon", SpriteSpecifier.Invalid);
serializer.DataField(this, x => x.MaxSeverity, "maxSeverity", (short) -1); serializer.DataField(this, x => x.MaxSeverity, "maxSeverity", (short) -1);
serializer.DataField(ref _minSeverity, "minSeverity", (short) 1); serializer.DataField(ref _minSeverity, "minSeverity", (short) 1);
@@ -106,6 +108,7 @@ namespace Content.Shared.Alert
{ {
Category = alertCategory; Category = alertCategory;
} }
AlertKey = new AlertKey(AlertType, Category); AlertKey = new AlertKey(AlertType, Category);
HasOnClick = serializer.TryReadDataField("onClick", out string _); HasOnClick = serializer.TryReadDataField("onClick", out string _);
@@ -116,40 +119,45 @@ namespace Content.Shared.Alert
/// <param name="severity">severity level, if supported by this alert</param> /// <param name="severity">severity level, if supported by this alert</param>
/// <returns>the icon path to the texture for the provided severity level</returns> /// <returns>the icon path to the texture for the provided severity level</returns>
public string GetIconPath(short? severity = null) public SpriteSpecifier GetIcon(short? severity = null)
{ {
if (!SupportsSeverity && severity != null) if (!SupportsSeverity && severity != null)
{ {
Logger.WarningS("alert", "attempted to get icon path for severity level for alert {0}, but" + throw new InvalidOperationException("This alert does not support severity");
" this alert does not support severity levels", AlertType);
} }
if (!SupportsSeverity) return IconPath;
if (!SupportsSeverity)
return Icon;
if (severity == null) if (severity == null)
{ {
Logger.WarningS("alert", "attempted to get icon path without severity level for alert {0}," + throw new ArgumentException("No severity specified but this alert has severity.", nameof(severity));
" but this alert requires a severity level. Using lowest" +
" valid severity level instead...", AlertType);
severity = MinSeverity;
} }
if (severity < MinSeverity) if (severity < MinSeverity)
{ {
Logger.WarningS("alert", "attempted to get icon path with severity level {0} for alert {1}," + throw new ArgumentOutOfRangeException(nameof(severity), "Severity below minimum severity.");
" but the minimum severity level for this alert is {2}. Using" +
" lowest valid severity level instead...", severity, AlertType, MinSeverity);
severity = MinSeverity;
}
if (severity > MaxSeverity)
{
Logger.WarningS("alert", "attempted to get icon path with severity level {0} for alert {1}," +
" but the max severity level for this alert is {2}. Using" +
" highest valid severity level instead...", severity, AlertType, MaxSeverity);
severity = MaxSeverity;
} }
// split and add the severity number to the path if (severity > MaxSeverity)
var ext = IconPath.LastIndexOf('.'); {
return IconPath.Substring(0, ext) + severity + IconPath.Substring(ext, IconPath.Length - ext); throw new ArgumentOutOfRangeException(nameof(severity), "Severity above maximum severity.");
}
var severityText = severity.Value.ToString(CultureInfo.InvariantCulture);
switch (Icon)
{
case SpriteSpecifier.EntityPrototype entityPrototype:
throw new InvalidOperationException("Severity not supported for EntityPrototype icon");
case SpriteSpecifier.Rsi rsi:
return new SpriteSpecifier.Rsi(rsi.RsiPath, rsi.RsiState + severityText);
case SpriteSpecifier.Texture texture:
var newName = texture.TexturePath.FilenameWithoutExtension + severityText;
return new SpriteSpecifier.Texture(
texture.TexturePath.WithName(newName + "." + texture.TexturePath.Extension));
default:
throw new ArgumentOutOfRangeException(nameof(Icon));
}
} }
} }
@@ -180,6 +188,7 @@ namespace Content.Shared.Alert
{ {
return other.AlertCategory == AlertCategory; return other.AlertCategory == AlertCategory;
} }
return AlertType == other.AlertType && AlertCategory == other.AlertCategory; return AlertType == other.AlertType && AlertCategory == other.AlertCategory;
} }

View File

@@ -33,14 +33,14 @@ namespace Content.Tests.Shared.Alert
alertManager.Initialize(); alertManager.Initialize();
Assert.That(alertManager.TryGet(AlertType.LowPressure, out var lowPressure)); Assert.That(alertManager.TryGet(AlertType.LowPressure, out var lowPressure));
Assert.That(lowPressure.IconPath, Is.EqualTo("/Textures/Interface/Alerts/Pressure/lowpressure.png")); Assert.That(lowPressure.Icon, Is.EqualTo(new SpriteSpecifier.Texture(new ResourcePath("/Textures/Interface/Alerts/Pressure/lowpressure.png"))));
Assert.That(alertManager.TryGet(AlertType.HighPressure, out var highPressure)); Assert.That(alertManager.TryGet(AlertType.HighPressure, out var highPressure));
Assert.That(highPressure.IconPath, Is.EqualTo("/Textures/Interface/Alerts/Pressure/highpressure.png")); Assert.That(highPressure.Icon, Is.EqualTo(new SpriteSpecifier.Texture(new ResourcePath("/Textures/Interface/Alerts/Pressure/highpressure.png"))));
Assert.That(alertManager.TryGet(AlertType.LowPressure, out lowPressure)); Assert.That(alertManager.TryGet(AlertType.LowPressure, out lowPressure));
Assert.That(lowPressure.IconPath, Is.EqualTo("/Textures/Interface/Alerts/Pressure/lowpressure.png")); Assert.That(lowPressure.Icon, Is.EqualTo(new SpriteSpecifier.Texture(new ResourcePath("/Textures/Interface/Alerts/Pressure/lowpressure.png"))));
Assert.That(alertManager.TryGet(AlertType.HighPressure, out highPressure)); Assert.That(alertManager.TryGet(AlertType.HighPressure, out highPressure));
Assert.That(highPressure.IconPath, Is.EqualTo("/Textures/Interface/Alerts/Pressure/highpressure.png")); Assert.That(highPressure.Icon, Is.EqualTo(new SpriteSpecifier.Texture(new ResourcePath("/Textures/Interface/Alerts/Pressure/highpressure.png"))));
} }
} }
} }

View File

@@ -44,7 +44,7 @@ namespace Content.Tests.Shared.Alert
{ {
var alert = GetTestPrototype(); var alert = GetTestPrototype();
Assert.That(alert.GetIconPath(severity), Is.EqualTo(expected)); Assert.That(alert.GetIcon(severity), Is.EqualTo(new SpriteSpecifier.Texture(new ResourcePath(expected))));
} }
private AlertPrototype GetTestPrototype() private AlertPrototype GetTestPrototype()