Merge remote-tracking branch 'upstream/master' into 20-10-30-admins
This commit is contained in:
@@ -13,6 +13,7 @@ using Content.Client.UserInterface.AdminMenu;
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Content.Client.Utility;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Client
|
||||
@@ -37,6 +38,7 @@ namespace Content.Client
|
||||
IoCManager.Register<IClickMapManager, ClickMapManager>();
|
||||
IoCManager.Register<IStationEventManager, StationEventManager>();
|
||||
IoCManager.Register<IAdminMenuManager, AdminMenuManager>();
|
||||
IoCManager.Register<AlertManager, AlertManager>();
|
||||
IoCManager.Register<IClientAdminManager, ClientAdminManager>();
|
||||
IoCManager.Register<EuiManager, EuiManager>();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared;
|
||||
using Robust.Client.Interfaces.Console;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -14,10 +15,13 @@ namespace Content.Client.Commands
|
||||
|
||||
public bool Execute(IDebugConsole console, params string[] args)
|
||||
{
|
||||
var _configurationManager = IoCManager.Resolve<IConfigurationManager>();
|
||||
var old = _configurationManager.GetCVar<bool>("outline.enabled");
|
||||
_configurationManager.SetCVar("outline.enabled", !old);
|
||||
console.AddLine($"Draw outlines set to: {_configurationManager.GetCVar<bool>("outline.enabled")}");
|
||||
var configurationManager = IoCManager.Resolve<IConfigurationManager>();
|
||||
var cvar = CCVars.OutlineEnabled;
|
||||
var old = configurationManager.GetCVar(cvar);
|
||||
|
||||
configurationManager.SetCVar(cvar, !old);
|
||||
console.AddLine($"Draw outlines set to: {configurationManager.GetCVar(cvar)}");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ using Content.Shared.GameObjects.Components.Power.AME;
|
||||
using Content.Shared.GameObjects.Components.Research;
|
||||
using Content.Shared.GameObjects.Components.VendingMachines;
|
||||
using Content.Shared.Kitchen;
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Client;
|
||||
using Robust.Client.Interfaces;
|
||||
using Robust.Client.Interfaces.Graphics.Overlays;
|
||||
@@ -104,8 +105,6 @@ namespace Content.Client
|
||||
{
|
||||
IoCManager.Resolve<IMapManager>().CreateNewMapEntity(MapId.Nullspace);
|
||||
};
|
||||
|
||||
_configurationManager.RegisterCVar("outline.enabled", true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -156,6 +155,7 @@ namespace Content.Client
|
||||
IoCManager.Resolve<IStationEventManager>().Initialize();
|
||||
IoCManager.Resolve<IAdminMenuManager>().Initialize();
|
||||
IoCManager.Resolve<EuiManager>().Initialize();
|
||||
IoCManager.Resolve<AlertManager>().Initialize();
|
||||
|
||||
_baseClient.RunLevelChanged += (sender, args) =>
|
||||
{
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
using Content.Shared.GameObjects.Components.Body.Behavior;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Body.Mechanism
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedHeartBehaviorComponent))]
|
||||
public class HeartBehaviorComponent : SharedHeartBehaviorComponent
|
||||
{
|
||||
public override void Update(float frameTime) { }
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ namespace Content.Client.GameObjects.Components.Wires
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
_menu.OnClose -= Close;
|
||||
_menu.Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Namotion.Reflection;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
@@ -142,7 +141,7 @@ namespace Content.Client.GameObjects.Components.Wires
|
||||
|
||||
private void OnConfirm(ButtonEventArgs args)
|
||||
{
|
||||
var config = GenerateDictionary<string, LineEdit>(_inputs, "Text");
|
||||
var config = GenerateDictionary(_inputs, "Text");
|
||||
|
||||
Owner.SendConfiguration(config);
|
||||
Close();
|
||||
@@ -153,13 +152,13 @@ namespace Content.Client.GameObjects.Components.Wires
|
||||
return Owner.Validation == null || Owner.Validation.IsMatch(value);
|
||||
}
|
||||
|
||||
private Dictionary<string, TConfig> GenerateDictionary<TConfig, TInput>(List<(string name, TInput input)> inputs, string propertyName) where TInput : Control
|
||||
private Dictionary<string, string> GenerateDictionary(IEnumerable<(string name, LineEdit input)> inputs, string propertyName)
|
||||
{
|
||||
var dictionary = new Dictionary<string, TConfig>();
|
||||
var dictionary = new Dictionary<string, string>();
|
||||
|
||||
foreach (var input in inputs)
|
||||
{
|
||||
var value = input.input.TryGetPropertyValue<TConfig>(propertyName);
|
||||
dictionary.Add(input.name, value);
|
||||
dictionary.Add(input.name, input.input.Text);
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
|
||||
93
Content.Client/GameObjects/Components/Mobs/AlertControl.cs
Normal file
93
Content.Client/GameObjects/Components/Mobs/AlertControl.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Content.Client.UserInterface;
|
||||
using Content.Client.Utility;
|
||||
using Content.Shared.Alert;
|
||||
using OpenToolkit.Mathematics;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Mobs
|
||||
{
|
||||
public class AlertControl : BaseButton
|
||||
{
|
||||
public AlertPrototype Alert { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Total duration of the cooldown in seconds. Null if no duration / cooldown.
|
||||
/// </summary>
|
||||
public int? TotalDuration { get; set; }
|
||||
|
||||
private short? _severity;
|
||||
private readonly TextureRect _icon;
|
||||
private CooldownGraphic _cooldownGraphic;
|
||||
|
||||
private readonly IResourceCache _resourceCache;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates an alert control reflecting the indicated alert + state
|
||||
/// </summary>
|
||||
/// <param name="alert">alert to display</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, IResourceCache resourceCache)
|
||||
{
|
||||
_resourceCache = resourceCache;
|
||||
Alert = alert;
|
||||
_severity = severity;
|
||||
var texture = _resourceCache.GetTexture(alert.GetIconPath(_severity));
|
||||
_icon = new TextureRect
|
||||
{
|
||||
TextureScale = (2, 2),
|
||||
Texture = texture
|
||||
};
|
||||
|
||||
Children.Add(_icon);
|
||||
_cooldownGraphic = new CooldownGraphic();
|
||||
Children.Add(_cooldownGraphic);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change the alert severity, changing the displayed icon
|
||||
/// </summary>
|
||||
public void SetSeverity(short? severity)
|
||||
{
|
||||
if (_severity != severity)
|
||||
{
|
||||
_severity = severity;
|
||||
_icon.Texture = _resourceCache.GetTexture(Alert.GetIconPath(_severity));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the displayed cooldown amount, doing nothing if alertCooldown is null
|
||||
/// </summary>
|
||||
/// <param name="alertCooldown">cooldown start and end</param>
|
||||
/// <param name="curTime">current game time</param>
|
||||
public void UpdateCooldown((TimeSpan Start, TimeSpan End)? alertCooldown, in TimeSpan curTime)
|
||||
{
|
||||
if (!alertCooldown.HasValue)
|
||||
{
|
||||
_cooldownGraphic.Progress = 0;
|
||||
_cooldownGraphic.Visible = false;
|
||||
TotalDuration = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var start = alertCooldown.Value.Start;
|
||||
var end = alertCooldown.Value.End;
|
||||
|
||||
var length = (end - start).TotalSeconds;
|
||||
var progress = (curTime - start).TotalSeconds / length;
|
||||
var ratio = (progress <= 1 ? (1 - progress) : (curTime - end).TotalSeconds * -5);
|
||||
|
||||
TotalDuration = (int?) Math.Round(length);
|
||||
_cooldownGraphic.Progress = MathHelper.Clamp((float)ratio, -1, 1);
|
||||
_cooldownGraphic.Visible = ratio > -1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Client.UserInterface;
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Content.Client.Utility;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.Graphics;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Client.Interfaces.UserInterface;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Serilog;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Mobs
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedAlertsComponent))]
|
||||
public sealed class ClientAlertsComponent : SharedAlertsComponent
|
||||
{
|
||||
private static readonly float TooltipTextMaxWidth = 265;
|
||||
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
private AlertsUI _ui;
|
||||
private PanelContainer _tooltip;
|
||||
private RichTextLabel _stateName;
|
||||
private RichTextLabel _stateDescription;
|
||||
private RichTextLabel _stateCooldown;
|
||||
private AlertOrderPrototype _alertOrder;
|
||||
private bool _tooltipReady;
|
||||
|
||||
[ViewVariables]
|
||||
private Dictionary<AlertKey, AlertControl> _alertControls
|
||||
= new Dictionary<AlertKey, AlertControl>();
|
||||
|
||||
/// <summary>
|
||||
/// Allows calculating if we need to act due to this component being controlled by the current mob
|
||||
/// TODO: should be revisited after space-wizards/RobustToolbox#1255
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private bool CurrentlyControlled => _playerManager.LocalPlayer != null && _playerManager.LocalPlayer.ControlledEntity == Owner;
|
||||
|
||||
protected override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
PlayerDetached();
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, IComponent component)
|
||||
{
|
||||
base.HandleMessage(message, component);
|
||||
switch (message)
|
||||
{
|
||||
case PlayerAttachedMsg _:
|
||||
PlayerAttached();
|
||||
break;
|
||||
case PlayerDetachedMsg _:
|
||||
PlayerDetached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
||||
{
|
||||
base.HandleComponentState(curState, nextState);
|
||||
|
||||
if (!(curState is AlertsComponentState state))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// update the dict of states based on the array we got in the message
|
||||
SetAlerts(state.Alerts);
|
||||
|
||||
UpdateAlertsControls();
|
||||
}
|
||||
|
||||
private void PlayerAttached()
|
||||
{
|
||||
if (!CurrentlyControlled || _ui != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_alertOrder = IoCManager.Resolve<IPrototypeManager>().EnumeratePrototypes<AlertOrderPrototype>().FirstOrDefault();
|
||||
if (_alertOrder == null)
|
||||
{
|
||||
Logger.ErrorS("alert", "no alertOrder prototype found, alerts will be in random order");
|
||||
}
|
||||
|
||||
_ui = new AlertsUI(IoCManager.Resolve<IClyde>());
|
||||
var uiManager = IoCManager.Resolve<IUserInterfaceManager>();
|
||||
uiManager.StateRoot.AddChild(_ui);
|
||||
|
||||
_tooltip = new PanelContainer
|
||||
{
|
||||
Visible = false,
|
||||
StyleClasses = { StyleNano.StyleClassTooltipPanel }
|
||||
};
|
||||
var tooltipVBox = new VBoxContainer
|
||||
{
|
||||
RectClipContent = true
|
||||
};
|
||||
_tooltip.AddChild(tooltipVBox);
|
||||
_stateName = new RichTextLabel
|
||||
{
|
||||
MaxWidth = TooltipTextMaxWidth,
|
||||
StyleClasses = { StyleNano.StyleClassTooltipAlertTitle }
|
||||
};
|
||||
tooltipVBox.AddChild(_stateName);
|
||||
_stateDescription = new RichTextLabel
|
||||
{
|
||||
MaxWidth = TooltipTextMaxWidth,
|
||||
StyleClasses = { StyleNano.StyleClassTooltipAlertDescription }
|
||||
};
|
||||
tooltipVBox.AddChild(_stateDescription);
|
||||
_stateCooldown = new RichTextLabel
|
||||
{
|
||||
MaxWidth = TooltipTextMaxWidth,
|
||||
StyleClasses = { StyleNano.StyleClassTooltipAlertCooldown }
|
||||
};
|
||||
tooltipVBox.AddChild(_stateCooldown);
|
||||
|
||||
uiManager.PopupRoot.AddChild(_tooltip);
|
||||
|
||||
UpdateAlertsControls();
|
||||
}
|
||||
|
||||
private void PlayerDetached()
|
||||
{
|
||||
_ui?.Dispose();
|
||||
_ui = null;
|
||||
_alertControls.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the displayed alerts based on current state of Alerts, performing
|
||||
/// a diff to ensure we only change what's changed (this avoids active tooltips disappearing any
|
||||
/// time state changes)
|
||||
/// </summary>
|
||||
private void UpdateAlertsControls()
|
||||
{
|
||||
if (!CurrentlyControlled || _ui == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// remove any controls with keys no longer present
|
||||
var toRemove = new List<AlertKey>();
|
||||
foreach (var existingKey in _alertControls.Keys)
|
||||
{
|
||||
if (!IsShowingAlert(existingKey))
|
||||
{
|
||||
toRemove.Add(existingKey);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var alertKeyToRemove in toRemove)
|
||||
{
|
||||
// remove and dispose the control
|
||||
_alertControls.Remove(alertKeyToRemove, out var control);
|
||||
control?.Dispose();
|
||||
}
|
||||
|
||||
// now we know that alertControls contains alerts that should still exist but
|
||||
// may need to updated,
|
||||
// also there may be some new alerts we need to show.
|
||||
// further, we need to ensure they are ordered w.r.t their configured order
|
||||
foreach (var alertStatus in EnumerateAlertStates())
|
||||
{
|
||||
if (!AlertManager.TryDecode(alertStatus.AlertEncoded, out var newAlert))
|
||||
{
|
||||
Logger.ErrorS("alert", "Unable to decode alert {0}", alertStatus.AlertEncoded);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_alertControls.TryGetValue(newAlert.AlertKey, out var existingAlertControl) &&
|
||||
existingAlertControl.Alert.AlertType == newAlert.AlertType)
|
||||
{
|
||||
// id is the same, simply update the existing control severity
|
||||
existingAlertControl.SetSeverity(alertStatus.Severity);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingAlertControl?.Dispose();
|
||||
|
||||
// this is a new alert + alert key or just a different alert with the same
|
||||
// key, create the control and add it in the appropriate order
|
||||
var newAlertControl = CreateAlertControl(newAlert, alertStatus);
|
||||
if (_alertOrder != null)
|
||||
{
|
||||
var added = false;
|
||||
foreach (var alertControl in _ui.Grid.Children)
|
||||
{
|
||||
if (_alertOrder.Compare(newAlert, ((AlertControl) alertControl).Alert) < 0)
|
||||
{
|
||||
var idx = alertControl.GetPositionInParent();
|
||||
_ui.Grid.Children.Add(newAlertControl);
|
||||
newAlertControl.SetPositionInParent(idx);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!added)
|
||||
{
|
||||
_ui.Grid.Children.Add(newAlertControl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ui.Grid.Children.Add(newAlertControl);
|
||||
}
|
||||
|
||||
_alertControls[newAlert.AlertKey] = newAlertControl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AlertControl CreateAlertControl(AlertPrototype alert, AlertState alertState)
|
||||
{
|
||||
|
||||
var alertControl = new AlertControl(alert, alertState.Severity, _resourceCache);
|
||||
// show custom tooltip for the status control
|
||||
alertControl.OnShowTooltip += AlertOnOnShowTooltip;
|
||||
alertControl.OnHideTooltip += AlertOnOnHideTooltip;
|
||||
|
||||
alertControl.OnPressed += AlertControlOnPressed;
|
||||
|
||||
return alertControl;
|
||||
}
|
||||
|
||||
private void AlertControlOnPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
AlertPressed(args, args.Button as AlertControl);
|
||||
}
|
||||
|
||||
private void AlertOnOnHideTooltip(object sender, EventArgs e)
|
||||
{
|
||||
_tooltipReady = false;
|
||||
_tooltip.Visible = false;
|
||||
}
|
||||
|
||||
private void AlertOnOnShowTooltip(object sender, EventArgs e)
|
||||
{
|
||||
var alertControl = (AlertControl) sender;
|
||||
_stateName.SetMessage(alertControl.Alert.Name);
|
||||
_stateDescription.SetMessage(alertControl.Alert.Description);
|
||||
// check for a cooldown
|
||||
if (alertControl.TotalDuration != null && alertControl.TotalDuration > 0)
|
||||
{
|
||||
_stateCooldown.SetMessage(FormattedMessage.FromMarkup("[color=#776a6a]" +
|
||||
alertControl.TotalDuration +
|
||||
" sec cooldown[/color]"));
|
||||
_stateCooldown.Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_stateCooldown.Visible = false;
|
||||
}
|
||||
// TODO: Text display of cooldown
|
||||
Tooltips.PositionTooltip(_tooltip);
|
||||
// if we set it visible here the size of the previous tooltip will flicker for a frame,
|
||||
// so instead we wait until FrameUpdate to make it visible
|
||||
_tooltipReady = true;
|
||||
}
|
||||
|
||||
private void AlertPressed(BaseButton.ButtonEventArgs args, AlertControl alert)
|
||||
{
|
||||
if (args.Event.Function != EngineKeyFunctions.UIClick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (AlertManager.TryEncode(alert.Alert, out var encoded))
|
||||
{
|
||||
SendNetworkMessage(new ClickAlertMessage(encoded));
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.ErrorS("alert", "unable to encode alert {0}", alert.Alert.AlertType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void FrameUpdate(float frameTime)
|
||||
{
|
||||
if (_tooltipReady)
|
||||
{
|
||||
_tooltipReady = false;
|
||||
_tooltip.Visible = true;
|
||||
}
|
||||
foreach (var (alertKey, alertControl) in _alertControls)
|
||||
{
|
||||
// reconcile all alert controls with their current cooldowns
|
||||
if (TryGetAlertState(alertKey, out var alertState))
|
||||
{
|
||||
alertControl.UpdateCooldown(alertState.Cooldown, _gameTiming.CurTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WarningS("alert", "coding error - no alert state for alert {0} " +
|
||||
"even though we had an AlertControl for it, this" +
|
||||
" should never happen", alertControl.Alert.AlertType);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected override void AfterClearAlert()
|
||||
{
|
||||
UpdateAlertsControls();
|
||||
}
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
|
||||
foreach (var alertControl in _alertControls.Values)
|
||||
{
|
||||
alertControl.OnShowTooltip -= AlertOnOnShowTooltip;
|
||||
alertControl.OnHideTooltip -= AlertOnOnHideTooltip;
|
||||
alertControl.OnPressed -= AlertControlOnPressed;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Client.UserInterface;
|
||||
using Content.Client.Utility;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Client.Interfaces.UserInterface;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Mobs
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedStatusEffectsComponent))]
|
||||
public sealed class ClientStatusEffectsComponent : SharedStatusEffectsComponent
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
private StatusEffectsUI _ui;
|
||||
[ViewVariables]
|
||||
private Dictionary<StatusEffect, StatusEffectStatus> _status = new Dictionary<StatusEffect, StatusEffectStatus>();
|
||||
[ViewVariables]
|
||||
private Dictionary<StatusEffect, CooldownGraphic> _cooldown = new Dictionary<StatusEffect, CooldownGraphic>();
|
||||
|
||||
public override IReadOnlyDictionary<StatusEffect, StatusEffectStatus> Statuses => _status;
|
||||
|
||||
/// <summary>
|
||||
/// Allows calculating if we need to act due to this component being controlled by the current mob
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private bool CurrentlyControlled => _playerManager.LocalPlayer != null && _playerManager.LocalPlayer.ControlledEntity == Owner;
|
||||
|
||||
protected override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
PlayerDetached();
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, IComponent component)
|
||||
{
|
||||
base.HandleMessage(message, component);
|
||||
switch (message)
|
||||
{
|
||||
case PlayerAttachedMsg _:
|
||||
PlayerAttached();
|
||||
break;
|
||||
case PlayerDetachedMsg _:
|
||||
PlayerDetached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
||||
{
|
||||
base.HandleComponentState(curState, nextState);
|
||||
|
||||
if (!(curState is StatusEffectComponentState state) || _status == state.StatusEffects)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_status = state.StatusEffects;
|
||||
UpdateStatusEffects();
|
||||
}
|
||||
|
||||
private void PlayerAttached()
|
||||
{
|
||||
if (!CurrentlyControlled || _ui != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_ui = new StatusEffectsUI();
|
||||
_userInterfaceManager.StateRoot.AddChild(_ui);
|
||||
UpdateStatusEffects();
|
||||
}
|
||||
|
||||
private void PlayerDetached()
|
||||
{
|
||||
_ui?.Dispose();
|
||||
_ui = null;
|
||||
_cooldown.Clear();
|
||||
}
|
||||
|
||||
public override void ChangeStatusEffectIcon(StatusEffect effect, string icon)
|
||||
{
|
||||
if (_status.TryGetValue(effect, out var value) &&
|
||||
value.Icon == icon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_status[effect] = new StatusEffectStatus
|
||||
{
|
||||
Icon = icon,
|
||||
Cooldown = value.Cooldown
|
||||
};
|
||||
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public void UpdateStatusEffects()
|
||||
{
|
||||
if (!CurrentlyControlled || _ui == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_cooldown.Clear();
|
||||
_ui.VBox.DisposeAllChildren();
|
||||
|
||||
foreach (var (key, effect) in _status.OrderBy(x => (int) x.Key))
|
||||
{
|
||||
var texture = _resourceCache.GetTexture(effect.Icon);
|
||||
var status = new StatusControl(key, texture)
|
||||
{
|
||||
ToolTip = key.ToString()
|
||||
};
|
||||
|
||||
if (effect.Cooldown.HasValue)
|
||||
{
|
||||
var cooldown = new CooldownGraphic();
|
||||
status.Children.Add(cooldown);
|
||||
_cooldown[key] = cooldown;
|
||||
}
|
||||
|
||||
status.OnPressed += args => StatusPressed(args, status);
|
||||
|
||||
_ui.VBox.AddChild(status);
|
||||
}
|
||||
}
|
||||
|
||||
private void StatusPressed(BaseButton.ButtonEventArgs args, StatusControl status)
|
||||
{
|
||||
if (args.Event.Function != EngineKeyFunctions.UIClick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendNetworkMessage(new ClickStatusMessage(status.Effect));
|
||||
}
|
||||
|
||||
public override void RemoveStatusEffect(StatusEffect effect)
|
||||
{
|
||||
if (!_status.Remove(effect))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateStatusEffects();
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public void FrameUpdate(float frameTime)
|
||||
{
|
||||
foreach (var (effect, cooldownGraphic) in _cooldown)
|
||||
{
|
||||
var status = _status[effect];
|
||||
if (!status.Cooldown.HasValue)
|
||||
{
|
||||
cooldownGraphic.Progress = 0;
|
||||
cooldownGraphic.Visible = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
var start = status.Cooldown.Value.Item1;
|
||||
var end = status.Cooldown.Value.Item2;
|
||||
|
||||
var length = (end - start).TotalSeconds;
|
||||
var progress = (_gameTiming.CurTime - start).TotalSeconds / length;
|
||||
var ratio = (progress <= 1 ? (1 - progress) : (_gameTiming.CurTime - end).TotalSeconds * -5);
|
||||
|
||||
cooldownGraphic.Progress = MathHelper.Clamp((float)ratio, -1, 1);
|
||||
cooldownGraphic.Visible = ratio > -1f;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ChangeStatusEffect(StatusEffect effect, string icon, (TimeSpan, TimeSpan)? cooldown)
|
||||
{
|
||||
_status[effect] = new StatusEffectStatus()
|
||||
{
|
||||
Icon = icon,
|
||||
Cooldown = cooldown
|
||||
};
|
||||
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
@@ -39,15 +39,6 @@ namespace Content.Client.GameObjects.Components.Mobs
|
||||
offset *= (ResetTime - _time) / ResetTime;
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out CameraRecoilComponent recoilComponent))
|
||||
{
|
||||
recoilComponent.BaseOffset = offset;
|
||||
}
|
||||
else if (Owner.TryGetComponent(out EyeComponent eyeComponent))
|
||||
{
|
||||
eyeComponent.Offset = offset;
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out ISpriteComponent spriteComponent))
|
||||
{
|
||||
// We have to account for rotation so the offset still checks out.
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#nullable enable
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Mobs
|
||||
{
|
||||
public class StatusControl : BaseButton
|
||||
{
|
||||
public readonly StatusEffect Effect;
|
||||
|
||||
public StatusControl(StatusEffect effect, Texture? texture)
|
||||
{
|
||||
Effect = effect;
|
||||
|
||||
var item = new TextureRect
|
||||
{
|
||||
TextureScale = (2, 2),
|
||||
Texture = texture
|
||||
};
|
||||
|
||||
Children.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,12 +44,14 @@ namespace Content.Client.GameObjects.Components.Storage
|
||||
|
||||
if (!component.Owner.TryGetComponent(out ISpriteComponent? sprite)) return;
|
||||
|
||||
sprite.LayerSetState(
|
||||
CrematoriumVisualLayers.Base,
|
||||
component.GetData<bool>(MorgueVisuals.Open)
|
||||
? _stateOpen
|
||||
: _stateClosed
|
||||
);
|
||||
if (component.TryGetData(MorgueVisuals.Open, out bool open))
|
||||
{
|
||||
sprite.LayerSetState(CrematoriumVisualLayers.Base, open ? _stateOpen : _stateClosed);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(CrematoriumVisualLayers.Base, _stateClosed);
|
||||
}
|
||||
|
||||
var lightState = "";
|
||||
if (component.TryGetData(MorgueVisuals.HasContents, out bool hasContents) && hasContents) lightState = _lightContents;
|
||||
|
||||
@@ -49,12 +49,14 @@ namespace Content.Client.GameObjects.Components.Storage
|
||||
|
||||
if (!component.Owner.TryGetComponent(out ISpriteComponent? sprite)) return;
|
||||
|
||||
sprite.LayerSetState(
|
||||
MorgueVisualLayers.Base,
|
||||
component.GetData<bool>(MorgueVisuals.Open)
|
||||
? _stateOpen
|
||||
: _stateClosed
|
||||
);
|
||||
if (component.TryGetData(MorgueVisuals.Open, out bool open))
|
||||
{
|
||||
sprite.LayerSetState(MorgueVisualLayers.Base, open ? _stateOpen : _stateClosed);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(MorgueVisualLayers.Base, _stateClosed);
|
||||
}
|
||||
|
||||
var lightState = "";
|
||||
if (component.TryGetData(MorgueVisuals.HasContents, out bool hasContents) && hasContents) lightState = _lightContents;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Content.Client.GameObjects.Components.PDA
|
||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
||||
|
||||
private PDAMenu _menu;
|
||||
private PDAMenuPopup failPopup;
|
||||
private PDAMenuPopup _failPopup;
|
||||
|
||||
public PDABoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
@@ -47,6 +47,11 @@ namespace Content.Client.GameObjects.Components.PDA
|
||||
SendMessage(new PDAEjectIDMessage());
|
||||
};
|
||||
|
||||
_menu.EjectPenButton.OnPressed += args =>
|
||||
{
|
||||
SendMessage(new PDAEjectPenMessage());
|
||||
};
|
||||
|
||||
_menu.MasterTabContainer.OnTabChanged += i =>
|
||||
{
|
||||
var tab = _menu.MasterTabContainer.GetChild(i);
|
||||
@@ -60,12 +65,12 @@ namespace Content.Client.GameObjects.Components.PDA
|
||||
{
|
||||
if (_menu.CurrentLoggedInAccount.DataBalance < listing.Price)
|
||||
{
|
||||
failPopup = new PDAMenuPopup(Loc.GetString("Insufficient funds!"));
|
||||
_userInterfaceManager.ModalRoot.AddChild(failPopup);
|
||||
failPopup.Open(UIBox2.FromDimensions(_menu.Position.X + 150, _menu.Position.Y + 60, 156, 24));
|
||||
_failPopup = new PDAMenuPopup(Loc.GetString("Insufficient funds!"));
|
||||
_userInterfaceManager.ModalRoot.AddChild(_failPopup);
|
||||
_failPopup.Open(UIBox2.FromDimensions(_menu.Position.X + 150, _menu.Position.Y + 60, 156, 24));
|
||||
_menu.OnClose += () =>
|
||||
{
|
||||
failPopup.Dispose();
|
||||
_failPopup.Dispose();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -106,6 +111,7 @@ namespace Content.Client.GameObjects.Components.PDA
|
||||
}
|
||||
|
||||
_menu.EjectIDButton.Visible = msg.PDAOwnerInfo.IdOwner != null;
|
||||
_menu.EjectPenButton.Visible = msg.HasPen;
|
||||
if (msg.Account != null)
|
||||
{
|
||||
_menu.CurrentLoggedInAccount = msg.Account;
|
||||
@@ -220,6 +226,7 @@ namespace Content.Client.GameObjects.Components.PDA
|
||||
|
||||
public Button FlashLightToggleButton { get; }
|
||||
public Button EjectIDButton { get; }
|
||||
public Button EjectPenButton { get; }
|
||||
|
||||
public TabContainer MasterTabContainer;
|
||||
|
||||
@@ -288,13 +295,20 @@ namespace Content.Client.GameObjects.Components.PDA
|
||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
||||
SizeFlagsVertical = SizeFlags.ShrinkCenter
|
||||
};
|
||||
EjectPenButton = new Button
|
||||
{
|
||||
Text = Loc.GetString("Eject Pen"),
|
||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
||||
SizeFlagsVertical = SizeFlags.ShrinkCenter
|
||||
};
|
||||
|
||||
var innerHBoxContainer = new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
IDInfoLabel,
|
||||
EjectIDButton
|
||||
EjectIDButton,
|
||||
EjectPenButton
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Content.Shared.AI;
|
||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
||||
using Robust.Client.Interfaces.UserInterface;
|
||||
@@ -178,7 +179,7 @@ namespace Content.Client.GameObjects.EntitySystems.AI
|
||||
|
||||
var panel = new PanelContainer
|
||||
{
|
||||
StyleClasses = {"tooltipBox"},
|
||||
StyleClasses = { StyleNano.StyleClassTooltipPanel },
|
||||
Children = {vBox},
|
||||
MouseFilter = Control.MouseFilterMode.Ignore,
|
||||
ModulateSelfOverride = Color.White.WithAlpha(0.75f),
|
||||
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Client.GameObjects.EntitySystems
|
||||
{
|
||||
public class StatusEffectsSystem : EntitySystem
|
||||
public class AlertsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
@@ -16,9 +16,9 @@ namespace Content.Client.GameObjects.EntitySystems
|
||||
if (!_gameTiming.IsFirstTimePredicted)
|
||||
return;
|
||||
|
||||
foreach (var clientStatusEffectsComponent in EntityManager.ComponentManager.EntityQuery<ClientStatusEffectsComponent>())
|
||||
foreach (var clientAlertsComponent in EntityManager.ComponentManager.EntityQuery<ClientAlertsComponent>())
|
||||
{
|
||||
clientStatusEffectsComponent.FrameUpdate(frameTime);
|
||||
clientAlertsComponent.FrameUpdate(frameTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,23 +56,20 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
|
||||
/// Is the cancellation bar red?
|
||||
/// </summary>
|
||||
private bool _flash = true;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Last time we swapped the flash.
|
||||
/// </summary>
|
||||
private TimeSpan _lastFlash;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// How long each cancellation bar flash lasts in seconds.
|
||||
/// </summary>
|
||||
private const float FlashTime = 0.125f;
|
||||
|
||||
|
||||
private const int XPixelDiff = 20 * DoAfterBarScale;
|
||||
|
||||
public const byte DoAfterBarScale = 2;
|
||||
private static readonly Color StartColor = new Color(0.8f, 0.0f, 0.2f); // red
|
||||
private static readonly Color EndColor = new Color(0.92f, 0.77f, 0.34f); // yellow
|
||||
private static readonly Color CompletedColor = new Color(0.0f, 0.8f, 0.27f); // green
|
||||
|
||||
public DoAfterBar()
|
||||
{
|
||||
@@ -108,28 +105,25 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
|
||||
}
|
||||
|
||||
color = new Color(1.0f, 0.0f, 0.0f, _flash ? 1.0f : 0.0f);
|
||||
}
|
||||
}
|
||||
else if (Ratio >= 1.0f)
|
||||
{
|
||||
color = CompletedColor;
|
||||
color = new Color(0f, 1f, 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// lerp
|
||||
color = new Color(
|
||||
StartColor.R + (EndColor.R - StartColor.R) * Ratio,
|
||||
StartColor.G + (EndColor.G - StartColor.G) * Ratio,
|
||||
StartColor.B + (EndColor.B - StartColor.B) * Ratio,
|
||||
StartColor.A);
|
||||
var hue = (5f / 18f) * Ratio;
|
||||
color = Color.FromHsv((hue, 1f, 0.75f, 1f));
|
||||
}
|
||||
|
||||
|
||||
handle.UseShader(_shader);
|
||||
// If you want to make this less hard-coded be my guest
|
||||
var leftOffset = 2 * DoAfterBarScale;
|
||||
var box = new UIBox2i(
|
||||
leftOffset,
|
||||
leftOffset,
|
||||
-2 + 2 * DoAfterBarScale,
|
||||
leftOffset + (int) (XPixelDiff * Ratio),
|
||||
leftOffset + (int) (XPixelDiff * Ratio),
|
||||
-2);
|
||||
handle.DrawRect(box, color);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
"Drink",
|
||||
"Food",
|
||||
"FoodContainer",
|
||||
"Stomach",
|
||||
"Rotatable",
|
||||
"MagicMirror",
|
||||
"FloorTile",
|
||||
@@ -180,10 +179,8 @@
|
||||
"BreakableConstruction",
|
||||
"GasCanister",
|
||||
"GasCanisterPort",
|
||||
"Lung",
|
||||
"Cleanable",
|
||||
"Configuration",
|
||||
"Brain",
|
||||
"PlantHolder",
|
||||
"SeedExtractor",
|
||||
"Produce",
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Client.Interfaces.Parallax;
|
||||
using Content.Shared;
|
||||
using Nett;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
@@ -34,12 +35,12 @@ namespace Content.Client.Parallax
|
||||
|
||||
public async void LoadParallax()
|
||||
{
|
||||
if (!_configurationManager.GetCVar<bool>("parallax.enabled"))
|
||||
if (!_configurationManager.GetCVar(CCVars.ParallaxEnabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var debugParallax = _configurationManager.GetCVar<bool>("parallax.debug");
|
||||
var debugParallax = _configurationManager.GetCVar(CCVars.ParallaxDebug);
|
||||
string contents;
|
||||
TomlTable table;
|
||||
// Load normal config into memory
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Content.Client.Sandbox
|
||||
public Button ToggleSubfloorButton;
|
||||
public Button ShowMarkersButton; //Shows spawn points
|
||||
public Button ShowBbButton; //Shows bounding boxes
|
||||
public Button MachineLinkingButton; // Enables/disables machine linking mode.
|
||||
|
||||
public SandboxWindow()
|
||||
{
|
||||
@@ -77,6 +78,9 @@ namespace Content.Client.Sandbox
|
||||
|
||||
ShowBbButton = new Button { Text = Loc.GetString("Show Bb"), ToggleMode = true };
|
||||
vBox.AddChild(ShowBbButton);
|
||||
|
||||
MachineLinkingButton = new Button { Text = Loc.GetString("Link machines"), ToggleMode = true };
|
||||
vBox.AddChild(MachineLinkingButton);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +190,7 @@ namespace Content.Client.Sandbox
|
||||
_window.ToggleSubfloorButton.OnPressed += OnToggleSubfloorButtonClicked;
|
||||
_window.ShowMarkersButton.OnPressed += OnShowMarkersButtonClicked;
|
||||
_window.ShowBbButton.OnPressed += OnShowBbButtonClicked;
|
||||
_window.MachineLinkingButton.OnPressed += OnMachineLinkingButtonClicked;
|
||||
|
||||
_window.OpenCentered();
|
||||
}
|
||||
@@ -241,6 +246,10 @@ namespace Content.Client.Sandbox
|
||||
{
|
||||
ShowBb();
|
||||
}
|
||||
private void OnMachineLinkingButtonClicked(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
LinkMachines();
|
||||
}
|
||||
|
||||
private void OnGiveAdminAccessButtonClicked(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
@@ -318,5 +327,10 @@ namespace Content.Client.Sandbox
|
||||
{
|
||||
_console.ProcessCommand("showbb");
|
||||
}
|
||||
|
||||
private void LinkMachines()
|
||||
{
|
||||
_console.ProcessCommand("signallink");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Content.Client.GameObjects.Components;
|
||||
using Content.Client.Utility;
|
||||
using Content.Shared;
|
||||
using Robust.Client.GameObjects.EntitySystems;
|
||||
using Robust.Client.Interfaces.GameObjects;
|
||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
||||
@@ -71,7 +72,7 @@ namespace Content.Client.State
|
||||
}
|
||||
|
||||
InteractionOutlineComponent outline;
|
||||
if(!ConfigurationManager.GetCVar<bool>("outline.enabled"))
|
||||
if(!ConfigurationManager.GetCVar(CCVars.OutlineEnabled))
|
||||
{
|
||||
if(entityToClick != null && entityToClick.TryGetComponent(out outline))
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ using Robust.Client.Interfaces.UserInterface;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -111,10 +112,10 @@ namespace Content.Client.State
|
||||
return;
|
||||
}
|
||||
|
||||
var configName = _configurationManager.GetCVar<string>("player.name");
|
||||
var configName = _configurationManager.GetCVar(CVars.PlayerName);
|
||||
if (_mainMenuControl.UserNameBox.Text != configName)
|
||||
{
|
||||
_configurationManager.SetCVar("player.name", inputName);
|
||||
_configurationManager.SetCVar(CVars.PlayerName, inputName);
|
||||
_configurationManager.SaveToFile();
|
||||
}
|
||||
|
||||
@@ -248,7 +249,7 @@ namespace Content.Client.State
|
||||
vBox.AddChild(userNameHBox);
|
||||
userNameHBox.AddChild(new Label {Text = "Username:"});
|
||||
|
||||
var currentUserName = _configurationManager.GetCVar<string>("player.name");
|
||||
var currentUserName = _configurationManager.GetCVar(CVars.PlayerName);
|
||||
UserNameBox = new LineEdit
|
||||
{
|
||||
Text = currentUserName, PlaceHolder = "Username",
|
||||
|
||||
73
Content.Client/UserInterface/AlertsUI.cs
Normal file
73
Content.Client/UserInterface/AlertsUI.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Robust.Client.Graphics.Drawing;
|
||||
using Robust.Client.Interfaces.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Content.Client.UserInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// The status effects display on the right side of the screen.
|
||||
/// </summary>
|
||||
public sealed class AlertsUI : Control
|
||||
{
|
||||
public GridContainer Grid { get; }
|
||||
|
||||
private readonly IClyde _clyde;
|
||||
|
||||
public AlertsUI(IClyde clyde)
|
||||
{
|
||||
_clyde = clyde;
|
||||
var panelContainer = new PanelContainer
|
||||
{
|
||||
StyleClasses = {StyleNano.StyleClassTransparentBorderedWindowPanel},
|
||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||
};
|
||||
AddChild(panelContainer);
|
||||
|
||||
Grid = new GridContainer
|
||||
{
|
||||
MaxHeight = CalcMaxHeight(clyde.ScreenSize),
|
||||
ExpandBackwards = true
|
||||
};
|
||||
panelContainer.AddChild(Grid);
|
||||
clyde.OnWindowResized += ClydeOnOnWindowResized;
|
||||
|
||||
LayoutContainer.SetGrowHorizontal(this, LayoutContainer.GrowDirection.Begin);
|
||||
LayoutContainer.SetAnchorAndMarginPreset(this, LayoutContainer.LayoutPreset.TopRight, margin: 10);
|
||||
LayoutContainer.SetMarginTop(this, 250);
|
||||
}
|
||||
|
||||
protected override void UIScaleChanged()
|
||||
{
|
||||
Grid.MaxHeight = CalcMaxHeight(_clyde.ScreenSize);
|
||||
base.UIScaleChanged();
|
||||
}
|
||||
|
||||
private void ClydeOnOnWindowResized(WindowResizedEventArgs obj)
|
||||
{
|
||||
// TODO: Can rework this once https://github.com/space-wizards/RobustToolbox/issues/1392 is done,
|
||||
// this is here because there isn't currently a good way to allow the grid to adjust its height based
|
||||
// on constraints, otherwise we would use anchors to lay it out
|
||||
Grid.MaxHeight = CalcMaxHeight(obj.NewSize);;
|
||||
}
|
||||
|
||||
private float CalcMaxHeight(Vector2i screenSize)
|
||||
{
|
||||
return Math.Max(((screenSize.Y) / UIScale) - 420, 1);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_clyde.OnWindowResized -= ClydeOnOnWindowResized;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ namespace Content.Client.UserInterface
|
||||
PanelOverride = new StyleBoxFlat {BackgroundColor = StyleNano.NanoGold},
|
||||
CustomMinimumSize = (2, 0)
|
||||
});
|
||||
_humanoidProfileEditor = new HumanoidProfileEditor(preferencesManager, prototypeManager);
|
||||
_humanoidProfileEditor = new HumanoidProfileEditor(preferencesManager, prototypeManager, entityManager);
|
||||
_humanoidProfileEditor.OnProfileChanged += newProfile => { UpdateUI(); };
|
||||
hBox.AddChild(_humanoidProfileEditor);
|
||||
|
||||
@@ -158,6 +158,15 @@ namespace Content.Client.UserInterface
|
||||
preferencesManager.OnServerDataLoaded += UpdateUI;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
_preferencesManager.OnServerDataLoaded -= UpdateUI;
|
||||
}
|
||||
|
||||
public void Save() => _humanoidProfileEditor.Save();
|
||||
|
||||
private void UpdateUI()
|
||||
@@ -283,7 +292,9 @@ namespace Content.Client.UserInterface
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (!disposing) return;
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
_previewDummy.Delete();
|
||||
_previewDummy = null;
|
||||
}
|
||||
|
||||
@@ -27,29 +27,23 @@ namespace Content.Client.UserInterface
|
||||
/// Possible values range from 1 to -1, where 1 to 0 is a depleting circle animation and 0 to -1 is a blink animation.
|
||||
/// </summary>
|
||||
public float Progress { get; set; }
|
||||
private static readonly Color StartColor = new Color(0.8f, 0.0f, 0.2f); // red
|
||||
private static readonly Color EndColor = new Color(0.92f, 0.77f, 0.34f); // yellow
|
||||
private static readonly Color CompletedColor = new Color(0.0f, 0.8f, 0.27f); // green
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
Span<float> x = stackalloc float[10];
|
||||
Span<float> x = new float[10];
|
||||
Color color;
|
||||
|
||||
var lerp = 1f - MathF.Abs(Progress); // for future bikeshedding purposes
|
||||
|
||||
if (Progress >= 0f)
|
||||
{
|
||||
color = new Color(
|
||||
EndColor.R + (StartColor.R - EndColor.R) * Progress,
|
||||
EndColor.G + (StartColor.G - EndColor.G) * Progress,
|
||||
EndColor.B + (StartColor.B - EndColor.B) * Progress,
|
||||
EndColor.A);
|
||||
var hue = (5f / 18f) * lerp;
|
||||
color = Color.FromHsv((hue, 0.75f, 0.75f, 0.50f));
|
||||
}
|
||||
else
|
||||
{
|
||||
var alpha = MathHelper.Clamp(0.5f * lerp, 0f, 0.5f);
|
||||
color = CompletedColor.WithAlpha(alpha);
|
||||
color = new Color(1f, 1f, 1f, alpha);
|
||||
}
|
||||
|
||||
_shader.SetParameter("progress", Progress);
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Client.GameObjects.Components;
|
||||
using Content.Client.GameObjects.Components;
|
||||
using Content.Client.GameObjects.Components.Mobs;
|
||||
using Content.Client.Interfaces;
|
||||
using Content.Shared;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics.Drawing;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Client.UserInterface
|
||||
{
|
||||
@@ -43,17 +46,25 @@ namespace Content.Client.UserInterface
|
||||
private readonly OptionButton _preferenceUnavailableButton;
|
||||
private readonly List<AntagPreferenceSelector> _antagPreferences;
|
||||
|
||||
private readonly IEntity _previewDummy;
|
||||
private readonly SpriteView _previewSprite;
|
||||
private readonly SpriteView _previewSpriteSide;
|
||||
|
||||
private bool _isDirty;
|
||||
public int CharacterSlot;
|
||||
public HumanoidCharacterProfile Profile;
|
||||
public event Action<HumanoidCharacterProfile> OnProfileChanged;
|
||||
|
||||
public HumanoidProfileEditor(IClientPreferencesManager preferencesManager, IPrototypeManager prototypeManager)
|
||||
public HumanoidProfileEditor(IClientPreferencesManager preferencesManager, IPrototypeManager prototypeManager, IEntityManager entityManager)
|
||||
{
|
||||
_random = IoCManager.Resolve<IRobustRandom>();
|
||||
|
||||
_preferencesManager = preferencesManager;
|
||||
|
||||
var hbox = new HBoxContainer();
|
||||
AddChild(hbox);
|
||||
|
||||
#region Left
|
||||
var margin = new MarginContainer
|
||||
{
|
||||
MarginTopOverride = 10,
|
||||
@@ -61,7 +72,7 @@ namespace Content.Client.UserInterface
|
||||
MarginLeftOverride = 10,
|
||||
MarginRightOverride = 10
|
||||
};
|
||||
AddChild(margin);
|
||||
hbox.AddChild(margin);
|
||||
|
||||
var vBox = new VBoxContainer();
|
||||
margin.AddChild(vBox);
|
||||
@@ -98,7 +109,7 @@ namespace Content.Client.UserInterface
|
||||
{
|
||||
SizeFlagsVertical = SizeFlags.FillExpand
|
||||
};
|
||||
var nameLabel = new Label {Text = Loc.GetString("Name:")};
|
||||
var nameLabel = new Label { Text = Loc.GetString("Name:") };
|
||||
_nameEdit = new LineEdit
|
||||
{
|
||||
CustomMinimumSize = (270, 0),
|
||||
@@ -119,7 +130,7 @@ namespace Content.Client.UserInterface
|
||||
|
||||
#endregion Name
|
||||
|
||||
var tabContainer = new TabContainer {SizeFlagsVertical = SizeFlags.FillExpand};
|
||||
var tabContainer = new TabContainer { SizeFlagsVertical = SizeFlags.FillExpand };
|
||||
vBox.AddChild(tabContainer);
|
||||
|
||||
#region Appearance
|
||||
@@ -141,7 +152,7 @@ namespace Content.Client.UserInterface
|
||||
{
|
||||
var panel = HighlightedContainer();
|
||||
var hBox = new HBoxContainer();
|
||||
var sexLabel = new Label {Text = Loc.GetString("Sex:")};
|
||||
var sexLabel = new Label { Text = Loc.GetString("Sex:") };
|
||||
|
||||
var sexButtonGroup = new ButtonGroup();
|
||||
|
||||
@@ -171,8 +182,8 @@ namespace Content.Client.UserInterface
|
||||
{
|
||||
var panel = HighlightedContainer();
|
||||
var hBox = new HBoxContainer();
|
||||
var ageLabel = new Label {Text = Loc.GetString("Age:")};
|
||||
_ageEdit = new LineEdit {CustomMinimumSize = (40, 0)};
|
||||
var ageLabel = new Label { Text = Loc.GetString("Age:") };
|
||||
_ageEdit = new LineEdit { CustomMinimumSize = (40, 0) };
|
||||
_ageEdit.OnTextChanged += args =>
|
||||
{
|
||||
if (!int.TryParse(args.Text, out var newAge))
|
||||
@@ -348,7 +359,7 @@ namespace Content.Client.UserInterface
|
||||
|
||||
foreach (var antag in prototypeManager.EnumeratePrototypes<AntagPrototype>().OrderBy(a => a.Name))
|
||||
{
|
||||
if(!antag.SetPreference)
|
||||
if (!antag.SetPreference)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -410,6 +421,71 @@ namespace Content.Client.UserInterface
|
||||
|
||||
#endregion Save
|
||||
|
||||
#endregion
|
||||
|
||||
#region Right
|
||||
|
||||
margin = new MarginContainer
|
||||
{
|
||||
MarginTopOverride = 10,
|
||||
MarginBottomOverride = 10,
|
||||
MarginLeftOverride = 10,
|
||||
MarginRightOverride = 10
|
||||
};
|
||||
hbox.AddChild(margin);
|
||||
|
||||
vBox = new VBoxContainer()
|
||||
{
|
||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||
};
|
||||
hbox.AddChild(vBox);
|
||||
|
||||
#region Preview
|
||||
|
||||
_previewDummy = entityManager.SpawnEntity("HumanMob_Dummy", MapCoordinates.Nullspace);
|
||||
var sprite = _previewDummy.GetComponent<SpriteComponent>();
|
||||
|
||||
// Front
|
||||
var box = new Control()
|
||||
{
|
||||
SizeFlagsHorizontal = SizeFlags.Fill,
|
||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||
SizeFlagsStretchRatio = 1f,
|
||||
};
|
||||
vBox.AddChild(box);
|
||||
_previewSprite = new SpriteView
|
||||
{
|
||||
Sprite = sprite,
|
||||
Scale = (6, 6),
|
||||
OverrideDirection = Direction.South,
|
||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
||||
SizeFlagsStretchRatio = 1
|
||||
};
|
||||
box.AddChild(_previewSprite);
|
||||
|
||||
// Side
|
||||
box = new Control()
|
||||
{
|
||||
SizeFlagsHorizontal = SizeFlags.Fill,
|
||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||
SizeFlagsStretchRatio = 1f,
|
||||
};
|
||||
vBox.AddChild(box);
|
||||
_previewSpriteSide = new SpriteView
|
||||
{
|
||||
Sprite = sprite,
|
||||
Scale = (6, 6),
|
||||
OverrideDirection = Direction.East,
|
||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
||||
SizeFlagsStretchRatio = 1
|
||||
};
|
||||
box.AddChild(_previewSpriteSide);
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
if (preferencesManager.ServerDataLoaded)
|
||||
{
|
||||
LoadServerData();
|
||||
@@ -420,6 +496,16 @@ namespace Content.Client.UserInterface
|
||||
IsDirty = false;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
_previewDummy.Delete();
|
||||
_preferencesManager.OnServerDataLoaded -= LoadServerData;
|
||||
}
|
||||
|
||||
private void LoadServerData()
|
||||
{
|
||||
Profile = (HumanoidCharacterProfile) _preferencesManager.Preferences.SelectedCharacter;
|
||||
@@ -458,6 +544,7 @@ namespace Content.Client.UserInterface
|
||||
set
|
||||
{
|
||||
_isDirty = value;
|
||||
UpdatePreview();
|
||||
UpdateSaveButton();
|
||||
}
|
||||
}
|
||||
@@ -503,6 +590,15 @@ namespace Content.Client.UserInterface
|
||||
_saveButton.Disabled = Profile is null || !IsDirty;
|
||||
}
|
||||
|
||||
private void UpdatePreview()
|
||||
{
|
||||
if (Profile is null)
|
||||
return;
|
||||
|
||||
_previewDummy.GetComponent<HumanoidAppearanceComponent>().UpdateFromProfile(Profile);
|
||||
LobbyCharacterPreviewPanel.GiveDummyJobClothes(_previewDummy, Profile);
|
||||
}
|
||||
|
||||
public void UpdateControls()
|
||||
{
|
||||
if (Profile is null) return;
|
||||
@@ -514,6 +610,8 @@ namespace Content.Client.UserInterface
|
||||
UpdateJobPriorities();
|
||||
UpdateAntagPreferences();
|
||||
|
||||
UpdatePreview();
|
||||
|
||||
_preferenceUnavailableButton.SelectId((int) Profile.PreferenceUnavailable);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Content.Shared;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
@@ -121,7 +123,7 @@ namespace Content.Client.UserInterface
|
||||
});
|
||||
ApplyButton.OnPressed += OnApplyButtonPressed;
|
||||
|
||||
VSyncCheckBox.Pressed = _cfg.GetCVar<bool>("display.vsync");
|
||||
VSyncCheckBox.Pressed = _cfg.GetCVar(CVars.DisplayVSync);
|
||||
FullscreenCheckBox.Pressed = ConfigIsFullscreen;
|
||||
LightingPresetOption.SelectId(GetConfigLightingQuality());
|
||||
_uiScaleOption.SelectId(GetConfigUIScalePreset(ConfigUIScale));
|
||||
@@ -137,11 +139,11 @@ namespace Content.Client.UserInterface
|
||||
|
||||
private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
_cfg.SetCVar("display.vsync", VSyncCheckBox.Pressed);
|
||||
_cfg.SetCVar(CVars.DisplayVSync, VSyncCheckBox.Pressed);
|
||||
SetConfigLightingQuality(LightingPresetOption.SelectedId);
|
||||
_cfg.SetCVar("display.windowmode",
|
||||
_cfg.SetCVar(CVars.DisplayWindowMode,
|
||||
(int) (FullscreenCheckBox.Pressed ? WindowMode.Fullscreen : WindowMode.Windowed));
|
||||
_cfg.SetCVar("display.uiScale", UIScaleOptions[_uiScaleOption.SelectedId]);
|
||||
_cfg.SetCVar(CVars.DisplayUIScale, UIScaleOptions[_uiScaleOption.SelectedId]);
|
||||
_cfg.SaveToFile();
|
||||
UpdateApplyButton();
|
||||
}
|
||||
@@ -159,7 +161,7 @@ namespace Content.Client.UserInterface
|
||||
|
||||
private void UpdateApplyButton()
|
||||
{
|
||||
var isVSyncSame = VSyncCheckBox.Pressed == _cfg.GetCVar<bool>("display.vsync");
|
||||
var isVSyncSame = VSyncCheckBox.Pressed == _cfg.GetCVar(CVars.DisplayVSync);
|
||||
var isFullscreenSame = FullscreenCheckBox.Pressed == ConfigIsFullscreen;
|
||||
var isLightingQualitySame = LightingPresetOption.SelectedId == GetConfigLightingQuality();
|
||||
var isUIScaleSame = MathHelper.CloseTo(UIScaleOptions[_uiScaleOption.SelectedId], ConfigUIScale);
|
||||
@@ -167,14 +169,14 @@ namespace Content.Client.UserInterface
|
||||
}
|
||||
|
||||
private bool ConfigIsFullscreen =>
|
||||
_cfg.GetCVar<int>("display.windowmode") == (int) WindowMode.Fullscreen;
|
||||
_cfg.GetCVar(CVars.DisplayWindowMode) == (int) WindowMode.Fullscreen;
|
||||
|
||||
private float ConfigUIScale => _cfg.GetCVar<float>("display.uiScale");
|
||||
private float ConfigUIScale => _cfg.GetCVar(CVars.DisplayUIScale);
|
||||
|
||||
private int GetConfigLightingQuality()
|
||||
{
|
||||
var val = _cfg.GetCVar<int>("display.lightmapdivider");
|
||||
var soft = _cfg.GetCVar<bool>("display.softshadows");
|
||||
var val = _cfg.GetCVar(CVars.DisplayLightMapDivider);
|
||||
var soft = _cfg.GetCVar(CVars.DisplaySoftShadows);
|
||||
if (val >= 8)
|
||||
{
|
||||
return 0;
|
||||
@@ -198,20 +200,20 @@ namespace Content.Client.UserInterface
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
_cfg.SetCVar("display.lightmapdivider", 8);
|
||||
_cfg.SetCVar("display.softshadows", false);
|
||||
_cfg.SetCVar(CVars.DisplayLightMapDivider, 8);
|
||||
_cfg.SetCVar(CVars.DisplaySoftShadows, false);
|
||||
break;
|
||||
case 1:
|
||||
_cfg.SetCVar("display.lightmapdivider", 2);
|
||||
_cfg.SetCVar("display.softshadows", false);
|
||||
_cfg.SetCVar(CVars.DisplayLightMapDivider, 2);
|
||||
_cfg.SetCVar(CVars.DisplaySoftShadows, false);
|
||||
break;
|
||||
case 2:
|
||||
_cfg.SetCVar("display.lightmapdivider", 2);
|
||||
_cfg.SetCVar("display.softshadows", true);
|
||||
_cfg.SetCVar(CVars.DisplayLightMapDivider, 2);
|
||||
_cfg.SetCVar(CVars.DisplaySoftShadows, true);
|
||||
break;
|
||||
case 3:
|
||||
_cfg.SetCVar("display.lightmapdivider", 1);
|
||||
_cfg.SetCVar("display.softshadows", true);
|
||||
_cfg.SetCVar(CVars.DisplayLightMapDivider, 1);
|
||||
_cfg.SetCVar(CVars.DisplaySoftShadows, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.UserInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// The status effects display on the right side of the screen.
|
||||
/// </summary>
|
||||
public sealed class StatusEffectsUI : Control
|
||||
{
|
||||
public VBoxContainer VBox { get; }
|
||||
|
||||
public StatusEffectsUI()
|
||||
{
|
||||
VBox = new VBoxContainer();
|
||||
AddChild(VBox);
|
||||
|
||||
LayoutContainer.SetGrowHorizontal(this, LayoutContainer.GrowDirection.Begin);
|
||||
LayoutContainer.SetAnchorAndMarginPreset(this, LayoutContainer.LayoutPreset.TopRight, margin: 10);
|
||||
LayoutContainer.SetMarginTop(this, 250);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,13 @@ namespace Content.Client.UserInterface.Stylesheets
|
||||
{
|
||||
public sealed class StyleNano : StyleBase
|
||||
{
|
||||
public const string StyleClassBorderedWindowPanel = "BorderedWindowPanel";
|
||||
public const string StyleClassTransparentBorderedWindowPanel = "TransparentBorderedWindowPanel";
|
||||
public const string StyleClassTooltipPanel = "tooltipBox";
|
||||
public const string StyleClassTooltipAlertTitle = "tooltipAlertTitle";
|
||||
public const string StyleClassTooltipAlertDescription = "tooltipAlertDesc";
|
||||
public const string StyleClassTooltipAlertCooldown = "tooltipAlertCooldown";
|
||||
|
||||
public const string StyleClassSliderRed = "Red";
|
||||
public const string StyleClassSliderGreen = "Green";
|
||||
public const string StyleClassSliderBlue = "Blue";
|
||||
@@ -55,6 +62,7 @@ namespace Content.Client.UserInterface.Stylesheets
|
||||
var notoSansDisplayBold14 = resCache.GetFont("/Fonts/NotoSansDisplay/NotoSansDisplay-Bold.ttf", 14);
|
||||
var notoSans16 = resCache.GetFont("/Fonts/NotoSans/NotoSans-Regular.ttf", 16);
|
||||
var notoSansBold16 = resCache.GetFont("/Fonts/NotoSans/NotoSans-Bold.ttf", 16);
|
||||
var notoSansBold18 = resCache.GetFont("/Fonts/NotoSans/NotoSans-Bold.ttf", 18);
|
||||
var notoSansBold20 = resCache.GetFont("/Fonts/NotoSans/NotoSans-Bold.ttf", 20);
|
||||
var textureCloseButton = resCache.GetTexture("/Textures/Interface/Nano/cross.svg.png");
|
||||
var windowHeaderTex = resCache.GetTexture("/Textures/Interface/Nano/window_header.png");
|
||||
@@ -73,6 +81,20 @@ namespace Content.Client.UserInterface.Stylesheets
|
||||
windowBackground.SetPatchMargin(StyleBox.Margin.Horizontal | StyleBox.Margin.Bottom, 2);
|
||||
windowBackground.SetExpandMargin(StyleBox.Margin.Horizontal | StyleBox.Margin.Bottom, 2);
|
||||
|
||||
var borderedWindowBackgroundTex = resCache.GetTexture("/Textures/Interface/Nano/window_background_bordered.png");
|
||||
var borderedWindowBackground = new StyleBoxTexture
|
||||
{
|
||||
Texture = borderedWindowBackgroundTex,
|
||||
};
|
||||
borderedWindowBackground.SetPatchMargin(StyleBox.Margin.All, 2);
|
||||
|
||||
var borderedTransparentWindowBackgroundTex = resCache.GetTexture("/Textures/Interface/Nano/transparent_window_background_bordered.png");
|
||||
var borderedTransparentWindowBackground = new StyleBoxTexture
|
||||
{
|
||||
Texture = borderedTransparentWindowBackgroundTex,
|
||||
};
|
||||
borderedTransparentWindowBackground.SetPatchMargin(StyleBox.Margin.All, 2);
|
||||
|
||||
var textureInvertedTriangle = resCache.GetTexture("/Textures/Interface/Nano/inverted_triangle.svg.png");
|
||||
|
||||
var lineEditTex = resCache.GetTexture("/Textures/Interface/Nano/lineedit.png");
|
||||
@@ -147,7 +169,7 @@ namespace Content.Client.UserInterface.Stylesheets
|
||||
Texture = tooltipTexture,
|
||||
};
|
||||
tooltipBox.SetPatchMargin(StyleBox.Margin.All, 2);
|
||||
tooltipBox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5);
|
||||
tooltipBox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 7);
|
||||
|
||||
// Placeholder
|
||||
var placeholderTexture = resCache.GetTexture("/Textures/Interface/Nano/placeholder.png");
|
||||
@@ -245,6 +267,19 @@ namespace Content.Client.UserInterface.Stylesheets
|
||||
{
|
||||
new StyleProperty(PanelContainer.StylePropertyPanel, windowBackground),
|
||||
}),
|
||||
// bordered window background
|
||||
new StyleRule(
|
||||
new SelectorElement(null, new[] {StyleClassBorderedWindowPanel}, null, null),
|
||||
new[]
|
||||
{
|
||||
new StyleProperty(PanelContainer.StylePropertyPanel, borderedWindowBackground),
|
||||
}),
|
||||
new StyleRule(
|
||||
new SelectorElement(null, new[] {StyleClassTransparentBorderedWindowPanel}, null, null),
|
||||
new[]
|
||||
{
|
||||
new StyleProperty(PanelContainer.StylePropertyPanel, borderedTransparentWindowBackground),
|
||||
}),
|
||||
// Window header.
|
||||
new StyleRule(
|
||||
new SelectorElement(typeof(PanelContainer), new[] {SS14Window.StyleClassWindowHeader}, null, null),
|
||||
@@ -464,7 +499,7 @@ namespace Content.Client.UserInterface.Stylesheets
|
||||
new StyleProperty(PanelContainer.StylePropertyPanel, tooltipBox)
|
||||
}),
|
||||
|
||||
new StyleRule(new SelectorElement(typeof(PanelContainer), new[] {"tooltipBox"}, null, null), new[]
|
||||
new StyleRule(new SelectorElement(typeof(PanelContainer), new [] { StyleClassTooltipPanel }, null, null), new[]
|
||||
{
|
||||
new StyleProperty(PanelContainer.StylePropertyPanel, tooltipBox)
|
||||
}),
|
||||
@@ -482,6 +517,20 @@ namespace Content.Client.UserInterface.Stylesheets
|
||||
new StyleProperty("font", notoSansItalic12),
|
||||
}),
|
||||
|
||||
// alert tooltip
|
||||
new StyleRule(new SelectorElement(typeof(RichTextLabel), new[] {StyleClassTooltipAlertTitle}, null, null), new[]
|
||||
{
|
||||
new StyleProperty("font", notoSansBold18)
|
||||
}),
|
||||
new StyleRule(new SelectorElement(typeof(RichTextLabel), new[] {StyleClassTooltipAlertDescription}, null, null), new[]
|
||||
{
|
||||
new StyleProperty("font", notoSans16)
|
||||
}),
|
||||
new StyleRule(new SelectorElement(typeof(RichTextLabel), new[] {StyleClassTooltipAlertCooldown}, null, null), new[]
|
||||
{
|
||||
new StyleProperty("font", notoSans16)
|
||||
}),
|
||||
|
||||
// Entity tooltip
|
||||
new StyleRule(
|
||||
new SelectorElement(typeof(PanelContainer), new[] {ExamineSystem.StyleClassEntityTooltip}, null,
|
||||
|
||||
Reference in New Issue
Block a user