Atmos pipe rework (#3833)
* Initial * Cleanup a bunch of things * some changes dunno * RequireAnchored * a * stuff * more work * Lots of progress * delete pipe visualizer * a * b * pipenet and pipenode cleanup * Fixes * Adds GasValve * Adds GasMiner * Fix stuff, maybe? * More fixes * Ignored components on the client * Adds thermomachine behavior, change a bunch of stuff * Remove Anchored * some work, but it's shitcode * significantly more ECS * ECS AtmosDevices * Cleanup * fix appearance * when the pipe direction is sus * Gas tanks and canisters * pipe anchoring and stuff * coding is my passion * Unsafe pipes take longer to unanchor * turns out we're no longer using eris canisters * Gas canister inserted tank appearance, improvements * Work on a bunch of appearances * Scrubber appearance * Reorganize AtmosphereSystem.Piping into a bunch of different systems * Appearance for vent/scrubber/pump turns off when leaving atmosphere * ThermoMachine appearance * Cleanup gas tanks * Remove passive gate unused imports * remove old canister UI functionality * PipeNode environment air, make everything use AssumeAir instead of merging manually * a * Reorganize atmos to follow new structure * ????? * Canister UI, restructure client * Restructure shared * Fix build tho * listen, at least the canister UI works entirely... * fix build : ) * Atmos device prototypes have names and descriptions * gas canister ui slider doesn't jitter * trinary prototypes * sprite for miners * ignore components * fix YAML * Fix port system doing useless thing * Fix build * fix thinking moment * fix build again because * canister direction * pipenode is a word * GasTank Air will throw on invalid states * fix build.... * Unhardcode volume pump thresholds * Volume pump and filter take time into account * Rename Join/Leave atmosphere events to AtmosDeviceEnabled/Disabled Event * Gas tank node volume is set by initial mixtuer * I love node container
This commit is contained in:
committed by
GitHub
parent
cfc3f2e7fc
commit
a2b737d945
164
Content.Client/Power/SolarControlWindow.xaml.cs
Normal file
164
Content.Client/Power/SolarControlWindow.xaml.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Content.Shared.Solar;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Power
|
||||
{
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class SolarControlWindow : SS14Window, IComputerWindow<SolarControlConsoleBoundInterfaceState>
|
||||
{
|
||||
private SolarControlConsoleBoundInterfaceState _lastState = new(0, 0, 0, 0);
|
||||
|
||||
public SolarControlWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public void SetupComputerWindow(ComputerBoundUserInterfaceBase cb)
|
||||
{
|
||||
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;
|
||||
cb.SendMessage(msg);
|
||||
// Predict this...
|
||||
_lastState.Rotation = msg.Rotation;
|
||||
NotARadar.UpdateState(_lastState);
|
||||
}
|
||||
};
|
||||
PanelVelocity.OnTextEntered += (text) => {
|
||||
double value;
|
||||
if (double.TryParse(text.Text, out value))
|
||||
{
|
||||
SolarControlConsoleAdjustMessage msg = new SolarControlConsoleAdjustMessage();
|
||||
msg.Rotation = NotARadar.PredictedPanelRotation;
|
||||
msg.AngularVelocity = Angle.FromDegrees(value / 60);
|
||||
cb.SendMessage(msg);
|
||||
// Predict this...
|
||||
_lastState.Rotation = NotARadar.PredictedPanelRotation;
|
||||
_lastState.AngularVelocity = msg.AngularVelocity;
|
||||
NotARadar.UpdateState(_lastState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateState(SolarControlConsoleBoundInterfaceState scc)
|
||||
{
|
||||
_lastState = scc;
|
||||
NotARadar.UpdateState(scc);
|
||||
OutputPower.Text = ((int) MathF.Floor(scc.OutputPower)).ToString();
|
||||
SunAngle.Text = FormatAngle(scc.TowardsSun);
|
||||
UpdateField(PanelRotation, FormatAngle(scc.Rotation));
|
||||
UpdateField(PanelVelocity, FormatAngle(scc.AngularVelocity * 60));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public sealed class SolarControlNotARadar : Control
|
||||
{
|
||||
// This is used for client-side prediction of the panel rotation.
|
||||
// This makes the display feel a lot smoother.
|
||||
private IGameTiming _gameTiming = IoCManager.Resolve<IGameTiming>();
|
||||
|
||||
private SolarControlConsoleBoundInterfaceState _lastState = new(0, 0, 0, 0);
|
||||
|
||||
private TimeSpan _lastStateTime = TimeSpan.Zero;
|
||||
|
||||
public const int StandardSizeFull = 290;
|
||||
public const int StandardRadiusCircle = 140;
|
||||
public int SizeFull => (int) (StandardSizeFull * UIScale);
|
||||
public int RadiusCircle => (int) (StandardRadiusCircle * UIScale);
|
||||
|
||||
public SolarControlNotARadar()
|
||||
{
|
||||
MinSize = (SizeFull, SizeFull);
|
||||
}
|
||||
|
||||
public void UpdateState(SolarControlConsoleBoundInterfaceState ls)
|
||||
{
|
||||
_lastState = ls;
|
||||
_lastStateTime = _gameTiming.CurTime;
|
||||
}
|
||||
|
||||
public Angle PredictedPanelRotation => _lastState.Rotation + (_lastState.AngularVelocity * ((_gameTiming.CurTime - _lastStateTime).TotalSeconds));
|
||||
|
||||
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);
|
||||
// Hotfix corrections I don't understand
|
||||
Angle rotOfs = new Angle(Math.PI * -0.5);
|
||||
|
||||
Angle predictedPanelRotation = PredictedPanelRotation;
|
||||
|
||||
var extent = (predictedPanelRotation + rotOfs).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 + rotOfs).ToVec() * rotMul * RadiusCircle;
|
||||
handle.DrawLine((point, point) + sunExtent, (point, point), Color.Yellow);
|
||||
}
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public class SolarControlConsoleBoundUserInterface : ComputerBoundUserInterface<SolarControlWindow, SolarControlConsoleBoundInterfaceState>
|
||||
{
|
||||
public SolarControlConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user