Re-organize all projects (#4166)
This commit is contained in:
@@ -1,63 +0,0 @@
|
||||
using Content.Shared.GameObjects.Components.Chemistry.ReagentDispenser;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using static Content.Shared.GameObjects.Components.Power.AME.SharedAMEControllerComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power.AME
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class AMEControllerBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private AMEWindow? _window;
|
||||
|
||||
public AMEControllerBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new AMEWindow();
|
||||
_window.OnClose += Close;
|
||||
_window.OpenCentered();
|
||||
|
||||
_window.EjectButton.OnPressed += _ => ButtonPressed(UiButton.Eject);
|
||||
_window.ToggleInjection.OnPressed += _ => ButtonPressed(UiButton.ToggleInjection);
|
||||
_window.IncreaseFuelButton.OnPressed += _ => ButtonPressed(UiButton.IncreaseFuel);
|
||||
_window.DecreaseFuelButton.OnPressed += _ => ButtonPressed(UiButton.DecreaseFuel);
|
||||
_window.RefreshPartsButton.OnPressed += _ => ButtonPressed(UiButton.RefreshParts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the ui each time new state data is sent from the server.
|
||||
/// </summary>
|
||||
/// <param name="state">
|
||||
/// Data of the <see cref="SharedReagentDispenserComponent"/> that this ui represents.
|
||||
/// Sent from the server.
|
||||
/// </param>
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
var castState = (AMEControllerBoundUserInterfaceState) state;
|
||||
_window?.UpdateState(castState); //Update window state
|
||||
}
|
||||
|
||||
private void ButtonPressed(UiButton button, int dispenseIndex = -1)
|
||||
{
|
||||
SendMessage(new UiButtonPressedMessage(button));
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using static Content.Shared.GameObjects.Components.Power.AME.SharedAMEControllerComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power.AME
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class AMEControllerVisualizer : AppearanceVisualizer
|
||||
{
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
base.InitializeEntity(entity);
|
||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||
|
||||
sprite.LayerMapSet(Layers.Display, sprite.AddLayerState("control_on"));
|
||||
sprite.LayerSetVisible(Layers.Display, false);
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
if (component.TryGetData<string>(AMEControllerVisuals.DisplayState, out var state))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case "on":
|
||||
sprite.LayerSetState(Layers.Display, "control_on");
|
||||
sprite.LayerSetVisible(Layers.Display, true);
|
||||
break;
|
||||
case "critical":
|
||||
sprite.LayerSetState(Layers.Display, "control_critical");
|
||||
sprite.LayerSetVisible(Layers.Display, true);
|
||||
break;
|
||||
case "fuck":
|
||||
sprite.LayerSetState(Layers.Display, "control_fuck");
|
||||
sprite.LayerSetVisible(Layers.Display, true);
|
||||
break;
|
||||
case "off":
|
||||
sprite.LayerSetVisible(Layers.Display, false);
|
||||
break;
|
||||
default:
|
||||
sprite.LayerSetVisible(Layers.Display, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Layers : byte
|
||||
{
|
||||
Display,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using static Content.Shared.GameObjects.Components.Power.AME.SharedAMEShieldComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power.AME
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class AMEVisualizer : AppearanceVisualizer
|
||||
{
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
base.InitializeEntity(entity);
|
||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||
sprite.LayerMapSet(Layers.Core, sprite.AddLayerState("core"));
|
||||
sprite.LayerSetVisible(Layers.Core, false);
|
||||
sprite.LayerMapSet(Layers.CoreState, sprite.AddLayerState("core_weak"));
|
||||
sprite.LayerSetVisible(Layers.CoreState, false);
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
if (component.TryGetData<string>(AMEShieldVisuals.Core, out var core))
|
||||
{
|
||||
if (core == "isCore")
|
||||
{
|
||||
sprite.LayerSetState(Layers.Core, "core");
|
||||
sprite.LayerSetVisible(Layers.Core, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetVisible(Layers.Core, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (component.TryGetData<string>(AMEShieldVisuals.CoreState, out var coreState))
|
||||
switch (coreState)
|
||||
{
|
||||
case "weak":
|
||||
sprite.LayerSetState(Layers.CoreState, "core_weak");
|
||||
sprite.LayerSetVisible(Layers.CoreState, true);
|
||||
break;
|
||||
case "strong":
|
||||
sprite.LayerSetState(Layers.CoreState, "core_strong");
|
||||
sprite.LayerSetVisible(Layers.CoreState, true);
|
||||
break;
|
||||
case "off":
|
||||
sprite.LayerSetVisible(Layers.CoreState, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Layers : byte
|
||||
{
|
||||
Core,
|
||||
CoreState,
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using static Content.Shared.GameObjects.Components.Power.AME.SharedAMEControllerComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power.AME
|
||||
{
|
||||
public class AMEWindow : SS14Window
|
||||
{
|
||||
public Label InjectionStatus { get; set; }
|
||||
public Button EjectButton { get; set; }
|
||||
public Button ToggleInjection { get; set; }
|
||||
public Button IncreaseFuelButton { get; set; }
|
||||
public Button DecreaseFuelButton { get; set; }
|
||||
public Button RefreshPartsButton { get; set; }
|
||||
public ProgressBar? FuelMeter { get; set; }
|
||||
public Label FuelAmount { get; set; }
|
||||
public Label InjectionAmount { get; set; }
|
||||
public Label CoreCount { get; set; }
|
||||
|
||||
|
||||
public AMEWindow()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
Title = "Antimatter Control Unit";
|
||||
|
||||
MinSize = SetSize = (250, 250);
|
||||
|
||||
Contents.AddChild(new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("Engine Status") + ": "},
|
||||
(InjectionStatus = new Label {Text = "Not Injecting"})
|
||||
}
|
||||
},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(ToggleInjection = new Button {Text = "Toggle Injection", StyleClasses = {StyleBase.ButtonOpenBoth}, Disabled = true}),
|
||||
}
|
||||
},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("Fuel Status") + ": "},
|
||||
(FuelAmount = new Label {Text = "No fuel inserted"})
|
||||
}
|
||||
},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(EjectButton = new Button {Text = "Eject", StyleClasses = {StyleBase.ButtonOpenBoth}, Disabled = true}),
|
||||
}
|
||||
},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("Injection amount") + ": "},
|
||||
(InjectionAmount = new Label {Text = "0"})
|
||||
}
|
||||
},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(IncreaseFuelButton = new Button {Text = "Increase", StyleClasses = {StyleBase.ButtonOpenRight}}),
|
||||
(DecreaseFuelButton = new Button {Text = "Decrease", StyleClasses = {StyleBase.ButtonOpenLeft}}),
|
||||
}
|
||||
},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(RefreshPartsButton = new Button {Text = "Refresh Parts", StyleClasses = {StyleBase.ButtonOpenBoth }, Disabled = true }),
|
||||
new Label { Text = Loc.GetString("Core count") + ": "},
|
||||
(CoreCount = new Label { Text = "0"}),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This searches recursively through all the children of "parent"
|
||||
/// and sets the Disabled value of any buttons found to "val"
|
||||
/// </summary>
|
||||
/// <param name="parent">The control which childrens get searched</param>
|
||||
/// <param name="val">The value to which disabled gets set</param>
|
||||
private void SetButtonDisabledRecursive(Control parent, bool val)
|
||||
{
|
||||
foreach (var child in parent.Children)
|
||||
{
|
||||
if (child is Button but)
|
||||
{
|
||||
but.Disabled = val;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.Children != null)
|
||||
{
|
||||
SetButtonDisabledRecursive(child, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the UI state when new state data is received from the server.
|
||||
/// </summary>
|
||||
/// <param name="state">State data sent by the server.</param>
|
||||
public void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
var castState = (AMEControllerBoundUserInterfaceState) state;
|
||||
|
||||
// Disable all buttons if not powered
|
||||
if (Contents.Children != null)
|
||||
{
|
||||
SetButtonDisabledRecursive(Contents, !castState.HasPower);
|
||||
EjectButton.Disabled = false;
|
||||
}
|
||||
|
||||
if(!castState.HasFuelJar)
|
||||
{
|
||||
EjectButton.Disabled = true;
|
||||
ToggleInjection.Disabled = true;
|
||||
FuelAmount.Text = Loc.GetString("No fuel inserted");
|
||||
}
|
||||
else
|
||||
{
|
||||
EjectButton.Disabled = false;
|
||||
ToggleInjection.Disabled = false;
|
||||
FuelAmount.Text = $"{castState.FuelAmount}";
|
||||
}
|
||||
|
||||
if(!castState.IsMaster)
|
||||
{
|
||||
ToggleInjection.Disabled = true;
|
||||
}
|
||||
|
||||
if (!castState.Injecting)
|
||||
{
|
||||
InjectionStatus.Text = Loc.GetString("Not Injecting");
|
||||
}
|
||||
else
|
||||
{
|
||||
InjectionStatus.Text = Loc.GetString("Injecting...");
|
||||
}
|
||||
|
||||
RefreshPartsButton.Disabled = castState.Injecting;
|
||||
|
||||
CoreCount.Text = $"{castState.CoreCount}";
|
||||
InjectionAmount.Text = $"{castState.InjectionAmount}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
using System;
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class ApcBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private ApcWindow? _window;
|
||||
private BaseButton? _breakerButton;
|
||||
private Label? _externalPowerStateLabel;
|
||||
private ProgressBar? _chargeBar;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new ApcWindow();
|
||||
_window.OnClose += Close;
|
||||
_window.OpenCentered();
|
||||
|
||||
_breakerButton = _window.BreakerButton;
|
||||
_breakerButton.OnPressed += _ => SendMessage(new ApcToggleMainBreakerMessage());
|
||||
|
||||
_externalPowerStateLabel = _window.ExternalPowerStateLabel;
|
||||
_chargeBar = _window.ChargeBar;
|
||||
}
|
||||
|
||||
public ApcBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
var castState = (ApcBoundInterfaceState) state;
|
||||
|
||||
if (_breakerButton != null)
|
||||
{
|
||||
_breakerButton.Pressed = castState.MainBreaker;
|
||||
}
|
||||
|
||||
if (_externalPowerStateLabel != null)
|
||||
{
|
||||
switch (castState.ApcExternalPower)
|
||||
{
|
||||
case ApcExternalPowerState.None:
|
||||
_externalPowerStateLabel.Text = "None";
|
||||
_externalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateNone);
|
||||
break;
|
||||
case ApcExternalPowerState.Low:
|
||||
_externalPowerStateLabel.Text = "Low";
|
||||
_externalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateLow);
|
||||
break;
|
||||
case ApcExternalPowerState.Good:
|
||||
_externalPowerStateLabel.Text = "Good";
|
||||
_externalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateGood);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
if (_chargeBar != null)
|
||||
{
|
||||
_chargeBar.Value = castState.Charge;
|
||||
UpdateChargeBarColor(castState.Charge);
|
||||
|
||||
if (_window != null)
|
||||
{
|
||||
var chargePercentage = (castState.Charge / _chargeBar.MaxValue) * 100.0f;
|
||||
_window.ChargePercentage.Text = " " + chargePercentage.ToString("0.00") + "%";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateChargeBarColor(float charge)
|
||||
{
|
||||
if (_chargeBar == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var normalizedCharge = charge / _chargeBar.MaxValue;
|
||||
|
||||
const float leftHue = 0.0f; // Red
|
||||
const float middleHue = 0.066f; // Orange
|
||||
const float rightHue = 0.33f; // Green
|
||||
const float saturation = 1.0f; // Uniform saturation
|
||||
const float value = 0.8f; // Uniform value / brightness
|
||||
const float alpha = 1.0f; // Uniform alpha
|
||||
|
||||
// These should add up to 1.0 or your transition won't be smooth
|
||||
const float leftSideSize = 0.5f; // Fraction of _chargeBar lerped from leftHue to middleHue
|
||||
const float rightSideSize = 0.5f; // Fraction of _chargeBar lerped from middleHue to rightHue
|
||||
|
||||
float finalHue;
|
||||
if (normalizedCharge <= leftSideSize)
|
||||
{
|
||||
normalizedCharge /= leftSideSize; // Adjust range to 0.0 to 1.0
|
||||
finalHue = MathHelper.Lerp(leftHue, middleHue, normalizedCharge);
|
||||
}
|
||||
else
|
||||
{
|
||||
normalizedCharge = (normalizedCharge - leftSideSize) / rightSideSize; // Adjust range to 0.0 to 1.0.
|
||||
finalHue = MathHelper.Lerp(middleHue, rightHue, normalizedCharge);
|
||||
}
|
||||
|
||||
// Check if null first to avoid repeatedly creating this.
|
||||
_chargeBar.ForegroundStyleBoxOverride ??= new StyleBoxFlat();
|
||||
|
||||
var foregroundStyleBoxOverride = (StyleBoxFlat) _chargeBar.ForegroundStyleBoxOverride;
|
||||
foregroundStyleBoxOverride.BackgroundColor =
|
||||
Color.FromHsv(new Vector4(finalHue, saturation, value, alpha));
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private class ApcWindow : SS14Window
|
||||
{
|
||||
public Button BreakerButton { get; set; }
|
||||
public Label ExternalPowerStateLabel { get; set; }
|
||||
public ProgressBar ChargeBar { get; set; }
|
||||
public Label ChargePercentage { get; set; }
|
||||
|
||||
public ApcWindow()
|
||||
{
|
||||
Title = "APC";
|
||||
var rows = new VBoxContainer();
|
||||
|
||||
var statusHeader = new Label {Text = "Power Status: "};
|
||||
rows.AddChild(statusHeader);
|
||||
|
||||
var breaker = new HBoxContainer();
|
||||
var breakerLabel = new Label {Text = "Main Breaker: "};
|
||||
BreakerButton = new CheckButton {Text = "Toggle"};
|
||||
breaker.AddChild(breakerLabel);
|
||||
breaker.AddChild(BreakerButton);
|
||||
rows.AddChild(breaker);
|
||||
|
||||
var externalStatus = new HBoxContainer();
|
||||
var externalStatusLabel = new Label {Text = "External Power: "};
|
||||
ExternalPowerStateLabel = new Label {Text = "Good"};
|
||||
ExternalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateGood);
|
||||
externalStatus.AddChild(externalStatusLabel);
|
||||
externalStatus.AddChild(ExternalPowerStateLabel);
|
||||
rows.AddChild(externalStatus);
|
||||
|
||||
var charge = new HBoxContainer();
|
||||
var chargeLabel = new Label {Text = "Charge:"};
|
||||
ChargeBar = new ProgressBar
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
MinValue = 0.0f,
|
||||
MaxValue = 1.0f,
|
||||
Page = 0.0f,
|
||||
Value = 0.5f
|
||||
};
|
||||
ChargePercentage = new Label();
|
||||
charge.AddChild(chargeLabel);
|
||||
charge.AddChild(ChargeBar);
|
||||
charge.AddChild(ChargePercentage);
|
||||
rows.AddChild(charge);
|
||||
|
||||
Contents.AddChild(rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Content.Shared.GameObjects.Components.Power.ApcNetComponents.PowerReceiverUsers;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power.ApcNetComponents.PowerReceiverUsers
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class PoweredLightVisualizer : AppearanceVisualizer
|
||||
{
|
||||
[DataField("minBlinkingTime")] private float _minBlinkingTime = 0.5f;
|
||||
[DataField("maxBlinkingTime")] private float _maxBlinkingTime = 2;
|
||||
[DataField("blinkingSound")] private string? _blinkingSound;
|
||||
|
||||
private bool _wasBlinking;
|
||||
|
||||
private Action<string>? _blinkingCallback;
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
if (!component.Owner.TryGetComponent(out ISpriteComponent? sprite)) return;
|
||||
if (!component.Owner.TryGetComponent(out PointLightComponent? light)) return;
|
||||
if (!component.TryGetData(PoweredLightVisuals.BulbState, out PoweredLightState state)) return;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PoweredLightState.Empty:
|
||||
sprite.LayerSetState(PoweredLightLayers.Base, "empty");
|
||||
ToggleBlinkingAnimation(component, false);
|
||||
light.Enabled = false;
|
||||
break;
|
||||
case PoweredLightState.Off:
|
||||
sprite.LayerSetState(PoweredLightLayers.Base, "off");
|
||||
ToggleBlinkingAnimation(component, false);
|
||||
light.Enabled = false;
|
||||
break;
|
||||
case PoweredLightState.On:
|
||||
if (component.TryGetData(PoweredLightVisuals.BulbColor, out Color color))
|
||||
light.Color = color;
|
||||
if (component.TryGetData(PoweredLightVisuals.Blinking, out bool isBlinking))
|
||||
ToggleBlinkingAnimation(component, isBlinking);
|
||||
if (!isBlinking)
|
||||
{
|
||||
sprite.LayerSetState(PoweredLightLayers.Base, "on");
|
||||
light.Enabled = true;
|
||||
}
|
||||
break;
|
||||
case PoweredLightState.Broken:
|
||||
sprite.LayerSetState(PoweredLightLayers.Base, "broken");
|
||||
ToggleBlinkingAnimation(component, false);
|
||||
light.Enabled = false;
|
||||
break;
|
||||
case PoweredLightState.Burned:
|
||||
sprite.LayerSetState(PoweredLightLayers.Base, "burn");
|
||||
ToggleBlinkingAnimation(component, false);
|
||||
light.Enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ToggleBlinkingAnimation(AppearanceComponent component, bool isBlinking)
|
||||
{
|
||||
if (isBlinking == _wasBlinking)
|
||||
return;
|
||||
_wasBlinking = isBlinking;
|
||||
|
||||
component.Owner.EnsureComponent(out AnimationPlayerComponent animationPlayer);
|
||||
|
||||
if (isBlinking)
|
||||
{
|
||||
_blinkingCallback = (animName) => animationPlayer.Play(BlinkingAnimation(), "blinking");
|
||||
animationPlayer.AnimationCompleted += _blinkingCallback;
|
||||
animationPlayer.Play(BlinkingAnimation(), "blinking");
|
||||
}
|
||||
else if (animationPlayer.HasRunningAnimation("blinking"))
|
||||
{
|
||||
if (_blinkingCallback != null)
|
||||
animationPlayer.AnimationCompleted -= _blinkingCallback;
|
||||
animationPlayer.Stop("blinking");
|
||||
}
|
||||
}
|
||||
|
||||
private Animation BlinkingAnimation()
|
||||
{
|
||||
var random = IoCManager.Resolve<IRobustRandom>();
|
||||
var randomTime = random.NextFloat() *
|
||||
(_maxBlinkingTime - _minBlinkingTime) + _minBlinkingTime;
|
||||
|
||||
var blinkingAnim = new Animation()
|
||||
{
|
||||
Length = TimeSpan.FromSeconds(randomTime),
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackComponentProperty
|
||||
{
|
||||
ComponentType = typeof(PointLightComponent),
|
||||
InterpolationMode = AnimationInterpolationMode.Nearest,
|
||||
Property = nameof(PointLightComponent.Enabled),
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(false, 0),
|
||||
new AnimationTrackProperty.KeyFrame(true, 1)
|
||||
}
|
||||
},
|
||||
new AnimationTrackSpriteFlick()
|
||||
{
|
||||
LayerKey = PoweredLightLayers.Base,
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackSpriteFlick.KeyFrame("off", 0),
|
||||
new AnimationTrackSpriteFlick.KeyFrame("on", 0.5f)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (_blinkingSound != null)
|
||||
{
|
||||
blinkingAnim.AnimationTracks.Add(new AnimationTrackPlaySound()
|
||||
{
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackPlaySound.KeyFrame(_blinkingSound, 0.5f)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return blinkingAnim;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
public class ApcVisualizer : AppearanceVisualizer
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
base.InitializeEntity(entity);
|
||||
|
||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||
|
||||
sprite.LayerMapSet(Layers.ChargeState, sprite.AddLayerState("apco3-0"));
|
||||
sprite.LayerSetShader(Layers.ChargeState, "unshaded");
|
||||
|
||||
sprite.LayerMapSet(Layers.Lock, sprite.AddLayerState("apcox-0"));
|
||||
sprite.LayerSetShader(Layers.Lock, "unshaded");
|
||||
|
||||
sprite.LayerMapSet(Layers.Equipment, sprite.AddLayerState("apco0-3"));
|
||||
sprite.LayerSetShader(Layers.Equipment, "unshaded");
|
||||
|
||||
sprite.LayerMapSet(Layers.Lighting, sprite.AddLayerState("apco1-3"));
|
||||
sprite.LayerSetShader(Layers.Lighting, "unshaded");
|
||||
|
||||
sprite.LayerMapSet(Layers.Environment, sprite.AddLayerState("apco2-3"));
|
||||
sprite.LayerSetShader(Layers.Environment, "unshaded");
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
if (component.TryGetData<ApcChargeState>(ApcVisuals.ChargeState, out var state))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case ApcChargeState.Lack:
|
||||
sprite.LayerSetState(Layers.ChargeState, "apco3-0");
|
||||
break;
|
||||
case ApcChargeState.Charging:
|
||||
sprite.LayerSetState(Layers.ChargeState, "apco3-1");
|
||||
break;
|
||||
case ApcChargeState.Full:
|
||||
sprite.LayerSetState(Layers.ChargeState, "apco3-2");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(Layers.ChargeState, "apco3-0");
|
||||
}
|
||||
}
|
||||
|
||||
enum Layers : byte
|
||||
{
|
||||
ChargeState,
|
||||
Lock,
|
||||
Equipment,
|
||||
Lighting,
|
||||
Environment,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
using System;
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class AutolatheVisualizer : AppearanceVisualizer
|
||||
{
|
||||
private const string AnimationKey = "inserting_animation";
|
||||
|
||||
private Animation _buildingAnimation;
|
||||
private Animation _insertingMetalAnimation;
|
||||
private Animation _insertingGlassAnimation;
|
||||
private Animation _insertingGoldAnimation;
|
||||
private Animation _insertingPlasmaAnimation;
|
||||
private Animation _insertingPlasticAnimation;
|
||||
|
||||
public AutolatheVisualizer()
|
||||
{
|
||||
_buildingAnimation = PopulateAnimation("building", "building_unlit", 0.5f);
|
||||
_insertingMetalAnimation = PopulateAnimation("inserting_metal", "inserting_unlit", 0.5f);
|
||||
_insertingGlassAnimation = PopulateAnimation("inserting_glass", "inserting_unlit", 0.5f);
|
||||
_insertingGoldAnimation = PopulateAnimation("inserting_gold", "inserting_unlit", 0.5f);
|
||||
_insertingPlasmaAnimation = PopulateAnimation("inserting_plasma", "inserting_unlit", 0.5f);
|
||||
_insertingPlasticAnimation = PopulateAnimation("inserting_plastic", "inserting_unlit", 0.5f);
|
||||
}
|
||||
|
||||
private Animation PopulateAnimation(string sprite, string spriteUnlit, float length)
|
||||
{
|
||||
var animation = new Animation {Length = TimeSpan.FromSeconds(length)};
|
||||
|
||||
var flick = new AnimationTrackSpriteFlick();
|
||||
animation.AnimationTracks.Add(flick);
|
||||
flick.LayerKey = AutolatheVisualLayers.Base;
|
||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(sprite, 0f));
|
||||
|
||||
var flickUnlit = new AnimationTrackSpriteFlick();
|
||||
animation.AnimationTracks.Add(flickUnlit);
|
||||
flickUnlit.LayerKey = AutolatheVisualLayers.BaseUnlit;
|
||||
flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(spriteUnlit, 0f));
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
if (!entity.HasComponent<AnimationPlayerComponent>())
|
||||
{
|
||||
entity.AddComponent<AnimationPlayerComponent>();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
var animPlayer = component.Owner.GetComponent<AnimationPlayerComponent>();
|
||||
if (!component.TryGetData(PowerDeviceVisuals.VisualState, out LatheVisualState state))
|
||||
{
|
||||
state = LatheVisualState.Idle;
|
||||
}
|
||||
sprite.LayerSetVisible(AutolatheVisualLayers.AnimationLayer, true);
|
||||
switch (state)
|
||||
{
|
||||
case LatheVisualState.Idle:
|
||||
if (animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Stop(AnimationKey);
|
||||
}
|
||||
|
||||
sprite.LayerSetState(AutolatheVisualLayers.Base, "icon");
|
||||
sprite.LayerSetState(AutolatheVisualLayers.BaseUnlit, "unlit");
|
||||
sprite.LayerSetVisible(AutolatheVisualLayers.AnimationLayer, false);
|
||||
break;
|
||||
case LatheVisualState.Producing:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_buildingAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingMetal:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingMetalAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingGlass:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingGlassAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingGold:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingGoldAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingPlasma:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingPlasmaAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingPlastic:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingPlasticAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
var glowingPartsVisible = !(component.TryGetData(PowerDeviceVisuals.Powered, out bool powered) && !powered);
|
||||
sprite.LayerSetVisible(AutolatheVisualLayers.BaseUnlit, glowingPartsVisible);
|
||||
}
|
||||
|
||||
public enum AutolatheVisualLayers : byte
|
||||
{
|
||||
Base,
|
||||
BaseUnlit,
|
||||
AnimationLayer
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class PowerCellVisualizer : AppearanceVisualizer
|
||||
{
|
||||
[DataField("prefix")]
|
||||
private string? _prefix;
|
||||
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
base.InitializeEntity(entity);
|
||||
|
||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||
|
||||
if (_prefix != null)
|
||||
{
|
||||
sprite.LayerMapSet(Layers.Charge, sprite.AddLayerState($"{_prefix}_100"));
|
||||
sprite.LayerSetShader(Layers.Charge, "unshaded");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
if (component.TryGetData(PowerCellVisuals.ChargeLevel, out byte level))
|
||||
{
|
||||
var adjustedLevel = level * 25;
|
||||
sprite.LayerSetState(Layers.Charge, $"{_prefix}_{adjustedLevel}");
|
||||
}
|
||||
}
|
||||
|
||||
private enum Layers : byte
|
||||
{
|
||||
Charge
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class PowerChargerVisualizer : AppearanceVisualizer
|
||||
{
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
base.InitializeEntity(entity);
|
||||
|
||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||
|
||||
// Base item
|
||||
sprite.LayerMapSet(Layers.Base, sprite.AddLayerState("empty"));
|
||||
|
||||
// Light
|
||||
sprite.LayerMapSet(Layers.Light, sprite.AddLayerState("light-off"));
|
||||
sprite.LayerSetShader(Layers.Light, "unshaded");
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
|
||||
// Update base item
|
||||
if (component.TryGetData(CellVisual.Occupied, out bool occupied))
|
||||
{
|
||||
// TODO: don't throw if it doesn't have a full state
|
||||
sprite.LayerSetState(Layers.Base, occupied ? "full" : "empty");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(Layers.Base, "empty");
|
||||
}
|
||||
|
||||
// Update lighting
|
||||
if (component.TryGetData(CellVisual.Light, out CellChargerStatus status))
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case CellChargerStatus.Off:
|
||||
sprite.LayerSetState(Layers.Light, "light-off");
|
||||
break;
|
||||
case CellChargerStatus.Empty:
|
||||
sprite.LayerSetState(Layers.Light, "light-empty");
|
||||
break;
|
||||
case CellChargerStatus.Charging:
|
||||
sprite.LayerSetState(Layers.Light, "light-charging");
|
||||
break;
|
||||
case CellChargerStatus.Charged:
|
||||
sprite.LayerSetState(Layers.Light, "light-charged");
|
||||
break;
|
||||
default:
|
||||
sprite.LayerSetState(Layers.Light, "light-off");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(Layers.Light, "light-off");
|
||||
}
|
||||
}
|
||||
|
||||
enum Layers : byte
|
||||
{
|
||||
Base,
|
||||
Light,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class PowerDeviceVisualizer : AppearanceVisualizer
|
||||
{
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
var powered = component.TryGetData(PowerDeviceVisuals.Powered, out bool poweredVar) && poweredVar;
|
||||
sprite.LayerSetVisible(PowerDeviceVisualLayers.Powered, powered);
|
||||
}
|
||||
}
|
||||
|
||||
public enum PowerDeviceVisualLayers : byte
|
||||
{
|
||||
Powered
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
using System;
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class ProtolatheVisualizer : AppearanceVisualizer
|
||||
{
|
||||
private const string AnimationKey = "inserting_animation";
|
||||
|
||||
private Animation _buildingAnimation;
|
||||
private Animation _insertingMetalAnimation;
|
||||
private Animation _insertingGlassAnimation;
|
||||
private Animation _insertingGoldAnimation;
|
||||
private Animation _insertingPlasmaAnimation;
|
||||
private Animation _insertingPlasticAnimation;
|
||||
|
||||
public ProtolatheVisualizer()
|
||||
{
|
||||
_buildingAnimation = PopulateAnimation("building", "building_unlit", 0.8f);
|
||||
_insertingMetalAnimation = PopulateAnimation("inserting_metal", "inserting_unlit", 0.8f);
|
||||
_insertingGlassAnimation = PopulateAnimation("inserting_glass", "inserting_unlit", 0.8f);
|
||||
_insertingGoldAnimation = PopulateAnimation("inserting_gold", "inserting_unlit", 0.8f);
|
||||
_insertingPlasmaAnimation = PopulateAnimation("inserting_plasma", "inserting_unlit", 0.8f);
|
||||
_insertingPlasticAnimation = PopulateAnimation("inserting_plastic", "inserting_unlit", 0.8f);
|
||||
}
|
||||
|
||||
private Animation PopulateAnimation(string sprite, string spriteUnlit, float length)
|
||||
{
|
||||
var animation = new Animation { Length = TimeSpan.FromSeconds(length) };
|
||||
|
||||
var flick = new AnimationTrackSpriteFlick();
|
||||
animation.AnimationTracks.Add(flick);
|
||||
flick.LayerKey = ProtolatheVisualLayers.Base;
|
||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(sprite, 0f));
|
||||
|
||||
var flickUnlit = new AnimationTrackSpriteFlick();
|
||||
animation.AnimationTracks.Add(flickUnlit);
|
||||
flickUnlit.LayerKey = ProtolatheVisualLayers.BaseUnlit;
|
||||
flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(spriteUnlit, 0f));
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
if (!entity.HasComponent<AnimationPlayerComponent>())
|
||||
{
|
||||
entity.AddComponent<AnimationPlayerComponent>();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
var animPlayer = component.Owner.GetComponent<AnimationPlayerComponent>();
|
||||
if (!component.TryGetData(PowerDeviceVisuals.VisualState, out LatheVisualState state))
|
||||
{
|
||||
state = LatheVisualState.Idle;
|
||||
}
|
||||
sprite.LayerSetVisible(ProtolatheVisualLayers.AnimationLayer, true);
|
||||
switch (state)
|
||||
{
|
||||
case LatheVisualState.Idle:
|
||||
if (animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Stop(AnimationKey);
|
||||
}
|
||||
|
||||
sprite.LayerSetState(ProtolatheVisualLayers.Base, "icon");
|
||||
sprite.LayerSetState(ProtolatheVisualLayers.BaseUnlit, "unlit");
|
||||
sprite.LayerSetVisible(ProtolatheVisualLayers.AnimationLayer, false);
|
||||
break;
|
||||
case LatheVisualState.Producing:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_buildingAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingMetal:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingMetalAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingGlass:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingGlassAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingGold:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingGoldAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingPlasma:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingPlasmaAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
case LatheVisualState.InsertingPlastic:
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_insertingPlasticAnimation, AnimationKey);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
var glowingPartsVisible = !(component.TryGetData(PowerDeviceVisuals.Powered, out bool powered) && !powered);
|
||||
sprite.LayerSetVisible(ProtolatheVisualLayers.BaseUnlit, glowingPartsVisible);
|
||||
}
|
||||
|
||||
public enum ProtolatheVisualLayers : byte
|
||||
{
|
||||
Base,
|
||||
BaseUnlit,
|
||||
AnimationLayer
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class SmesVisualizer : AppearanceVisualizer
|
||||
{
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
base.InitializeEntity(entity);
|
||||
|
||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
||||
|
||||
sprite.LayerMapSet(Layers.Input, sprite.AddLayerState("smes-oc0"));
|
||||
sprite.LayerSetShader(Layers.Input, "unshaded");
|
||||
sprite.LayerMapSet(Layers.Charge, sprite.AddLayerState("smes-og1"));
|
||||
sprite.LayerSetShader(Layers.Charge, "unshaded");
|
||||
sprite.LayerSetVisible(Layers.Charge, false);
|
||||
sprite.LayerMapSet(Layers.Output, sprite.AddLayerState("smes-op0"));
|
||||
sprite.LayerSetShader(Layers.Output, "unshaded");
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
if (!component.TryGetData<int>(SmesVisuals.LastChargeLevel, out var level) || level == 0)
|
||||
{
|
||||
sprite.LayerSetVisible(Layers.Charge, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetVisible(Layers.Charge, true);
|
||||
sprite.LayerSetState(Layers.Charge, $"smes-og{level}");
|
||||
}
|
||||
|
||||
if (component.TryGetData<ChargeState>(SmesVisuals.LastChargeState, out var state))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case ChargeState.Still:
|
||||
sprite.LayerSetState(Layers.Input, "smes-oc0");
|
||||
sprite.LayerSetState(Layers.Output, "smes-op1");
|
||||
break;
|
||||
case ChargeState.Charging:
|
||||
sprite.LayerSetState(Layers.Input, "smes-oc1");
|
||||
sprite.LayerSetState(Layers.Output, "smes-op1");
|
||||
break;
|
||||
case ChargeState.Discharging:
|
||||
sprite.LayerSetState(Layers.Input, "smes-oc0");
|
||||
sprite.LayerSetState(Layers.Output, "smes-op2");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(Layers.Input, "smes-oc0");
|
||||
sprite.LayerSetState(Layers.Output, "smes-op1");
|
||||
}
|
||||
}
|
||||
|
||||
enum Layers : byte
|
||||
{
|
||||
Input,
|
||||
Charge,
|
||||
Output,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
using System;
|
||||
using Content.Shared.GameObjects.Components.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class SolarControlConsoleBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
private SolarControlWindow? _window;
|
||||
private SolarControlConsoleBoundInterfaceState _lastState = new(0, 0, 0, 0);
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new SolarControlWindow(_gameTiming);
|
||||
_window.OnClose += Close;
|
||||
_window.PanelRotation.OnTextEntered += (text) => {
|
||||
double value;
|
||||
if (double.TryParse(text.Text, out value))
|
||||
{
|
||||
SolarControlConsoleAdjustMessage msg = new SolarControlConsoleAdjustMessage();
|
||||
msg.Rotation = Angle.FromDegrees(value);
|
||||
msg.AngularVelocity = _lastState.AngularVelocity;
|
||||
SendMessage(msg);
|
||||
}
|
||||
};
|
||||
_window.PanelVelocity.OnTextEntered += (text) => {
|
||||
double value;
|
||||
if (double.TryParse(text.Text, out value))
|
||||
{
|
||||
SolarControlConsoleAdjustMessage msg = new SolarControlConsoleAdjustMessage();
|
||||
msg.Rotation = _lastState.Rotation;
|
||||
msg.AngularVelocity = Angle.FromDegrees(value / 60);
|
||||
SendMessage(msg);
|
||||
}
|
||||
};
|
||||
_window.OpenCentered();
|
||||
}
|
||||
|
||||
public SolarControlConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private string FormatAngle(Angle d)
|
||||
{
|
||||
return d.Degrees.ToString("F1");
|
||||
}
|
||||
|
||||
// The idea behind this is to prevent every update from the server
|
||||
// breaking the textfield.
|
||||
private void UpdateField(LineEdit field, string newValue)
|
||||
{
|
||||
if (!field.HasKeyboardFocus())
|
||||
{
|
||||
field.Text = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (_window == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SolarControlConsoleBoundInterfaceState scc = (SolarControlConsoleBoundInterfaceState) state;
|
||||
_lastState = scc;
|
||||
_window.NotARadar.UpdateState(scc);
|
||||
_window.OutputPower.Text = ((int) MathF.Floor(scc.OutputPower)).ToString();
|
||||
_window.SunAngle.Text = FormatAngle(scc.TowardsSun);
|
||||
UpdateField(_window.PanelRotation, FormatAngle(scc.Rotation));
|
||||
UpdateField(_window.PanelVelocity, FormatAngle(scc.AngularVelocity * 60));
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class SolarControlWindow : SS14Window
|
||||
{
|
||||
public readonly Label OutputPower;
|
||||
public readonly Label SunAngle;
|
||||
|
||||
public readonly SolarControlNotARadar NotARadar;
|
||||
|
||||
public readonly LineEdit PanelRotation;
|
||||
public readonly LineEdit PanelVelocity;
|
||||
|
||||
public SolarControlWindow(IGameTiming igt)
|
||||
{
|
||||
Title = "Solar Control Window";
|
||||
|
||||
var rows = new GridContainer();
|
||||
rows.Columns = 2;
|
||||
|
||||
// little secret: the reason I put the values
|
||||
// in the first column is because otherwise the UI
|
||||
// layouter autoresizes the window to be too small
|
||||
rows.AddChild(new Label {Text = "Output Power:"});
|
||||
rows.AddChild(new Label {Text = ""});
|
||||
|
||||
rows.AddChild(OutputPower = new Label {Text = "?"});
|
||||
rows.AddChild(new Label {Text = "W"});
|
||||
|
||||
rows.AddChild(new Label {Text = "Sun Angle:"});
|
||||
rows.AddChild(new Label {Text = ""});
|
||||
|
||||
rows.AddChild(SunAngle = new Label {Text = "?"});
|
||||
rows.AddChild(new Label {Text = "°"});
|
||||
|
||||
rows.AddChild(new Label {Text = "Panel Angle:"});
|
||||
rows.AddChild(new Label {Text = ""});
|
||||
|
||||
rows.AddChild(PanelRotation = new LineEdit());
|
||||
rows.AddChild(new Label {Text = "°"});
|
||||
|
||||
rows.AddChild(new Label {Text = "Panel Angular Velocity:"});
|
||||
rows.AddChild(new Label {Text = ""});
|
||||
|
||||
rows.AddChild(PanelVelocity = new LineEdit());
|
||||
rows.AddChild(new Label {Text = "°/min."});
|
||||
|
||||
rows.AddChild(new Label {Text = "Press Enter to confirm."});
|
||||
rows.AddChild(new Label {Text = ""});
|
||||
|
||||
PanelRotation.HorizontalExpand = true;
|
||||
PanelVelocity.HorizontalExpand = true;
|
||||
|
||||
NotARadar = new SolarControlNotARadar(igt);
|
||||
|
||||
var outerColumns = new HBoxContainer();
|
||||
outerColumns.AddChild(rows);
|
||||
outerColumns.AddChild(NotARadar);
|
||||
Contents.AddChild(outerColumns);
|
||||
Resizable = false;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class SolarControlNotARadar : Control
|
||||
{
|
||||
// IoC doesn't apply here, so it's propagated from the parent class.
|
||||
// This is used for client-side prediction of the panel rotation.
|
||||
// This makes the display feel a lot smoother.
|
||||
private IGameTiming _gameTiming;
|
||||
|
||||
private SolarControlConsoleBoundInterfaceState _lastState = new(0, 0, 0, 0);
|
||||
|
||||
private TimeSpan _lastStateTime = TimeSpan.Zero;
|
||||
|
||||
public const int SizeFull = 290;
|
||||
public const int RadiusCircle = 140;
|
||||
|
||||
public SolarControlNotARadar(IGameTiming igt)
|
||||
{
|
||||
_gameTiming = igt;
|
||||
MinSize = (SizeFull, SizeFull);
|
||||
}
|
||||
|
||||
public void UpdateState(SolarControlConsoleBoundInterfaceState ls)
|
||||
{
|
||||
_lastState = ls;
|
||||
_lastStateTime = _gameTiming.CurTime;
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
var point = SizeFull / 2;
|
||||
var fakeAA = new Color(0.08f, 0.08f, 0.08f);
|
||||
var gridLines = new Color(0.08f, 0.08f, 0.08f);
|
||||
var panelExtentCutback = 4;
|
||||
var gridLinesRadial = 8;
|
||||
var gridLinesEquatorial = 8;
|
||||
|
||||
// Draw base
|
||||
handle.DrawCircle((point, point), RadiusCircle + 1, fakeAA);
|
||||
handle.DrawCircle((point, point), RadiusCircle, Color.Black);
|
||||
|
||||
// Draw grid lines
|
||||
for (var i = 0; i < gridLinesEquatorial; i++)
|
||||
{
|
||||
handle.DrawCircle((point, point), (RadiusCircle / gridLinesEquatorial) * i, gridLines, false);
|
||||
}
|
||||
|
||||
for (var i = 0; i < gridLinesRadial; i++)
|
||||
{
|
||||
Angle angle = (Math.PI / gridLinesRadial) * i;
|
||||
var aExtent = angle.ToVec() * RadiusCircle;
|
||||
handle.DrawLine((point, point) - aExtent, (point, point) + aExtent, gridLines);
|
||||
}
|
||||
|
||||
// The rotations need to be adjusted because Y is inverted in Robust (like BYOND)
|
||||
Vector2 rotMul = (1, -1);
|
||||
|
||||
Angle predictedPanelRotation = _lastState.Rotation + (_lastState.AngularVelocity * ((_gameTiming.CurTime - _lastStateTime).TotalSeconds));
|
||||
|
||||
var extent = predictedPanelRotation.ToVec() * rotMul * RadiusCircle;
|
||||
Vector2 extentOrtho = (extent.Y, -extent.X);
|
||||
handle.DrawLine((point, point) - extentOrtho, (point, point) + extentOrtho, Color.White);
|
||||
handle.DrawLine((point, point) + (extent / panelExtentCutback), (point, point) + extent - (extent / panelExtentCutback), Color.DarkGray);
|
||||
|
||||
var sunExtent = _lastState.TowardsSun.ToVec() * rotMul * RadiusCircle;
|
||||
handle.DrawLine((point, point) + sunExtent, (point, point), Color.Yellow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user