Re-organize all projects (#4166)

This commit is contained in:
DrSmugleaf
2021-06-09 22:19:39 +02:00
committed by GitHub
parent 9f50e4061b
commit ff1a2d97ea
1773 changed files with 5258 additions and 5508 deletions

View File

@@ -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();
}
}
}
}

View File

@@ -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,
}
}
}

View File

@@ -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,
}
}

View File

@@ -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}";
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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,
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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,
}
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}
}

View File

@@ -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,
}
}
}

View File

@@ -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);
}
}
}
}