using Content.Client.DoAfter; using Content.Client.UserInterface.Controls; using Content.Shared.Power.Generator; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; namespace Content.Client.Power.Generator; [GenerateTypedNameReferences] public sealed partial class GeneratorWindow : FancyWindow { [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly ILocalizationManager _loc = default!; private EntityUid _entity; public float? MaximumPower; public event Action? OnPower; public event Action? OnState; public event Action? OnSwitchOutput; public event Action? OnEjectFuel; public GeneratorWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); TargetPower.IsValid += IsValid; TargetPower.ValueChanged += (args) => { OnPower?.Invoke(args.Value); }; StartButton.OnPressed += _ => OnState?.Invoke(true); StopButton.OnPressed += _ => OnState?.Invoke(false); OutputSwitchButton.OnPressed += _ => OnSwitchOutput?.Invoke(); FuelEject.OnPressed += _ => OnEjectFuel?.Invoke(); } public void SetEntity(EntityUid entity) { _entity = entity; EntityView.SetEntity(entity); } private bool IsValid(int arg) { if (arg < 0) return false; if (arg > (MaximumPower / 1000.0f ?? 0)) return false; return true; } public void Update(PortableGeneratorComponentBuiState state) { MaximumPower = state.MaximumPower; if (!_entityManager.TryGetComponent(_entity, out FuelGeneratorComponent? component)) return; if (!TargetPower.LineEditControl.HasKeyboardFocus()) TargetPower.OverrideValue((int)(state.TargetPower / 1000.0f)); var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, component); Efficiency.Text = efficiency.ToString("P1"); var burnRate = component.OptimalBurnRate / efficiency; var left = state.RemainingFuel / burnRate; Eta.Text = Loc.GetString( "portable-generator-ui-eta", ("minutes", Math.Ceiling(left / 60.0))); FuelFraction.Value = state.RemainingFuel - (int) state.RemainingFuel; FuelLeft.Text = ((int) MathF.Floor(state.RemainingFuel)).ToString(); var progress = 0f; var unanchored = !_entityManager.GetComponent(_entity).Anchored; var starting = !unanchored && TryGetStartProgress(out progress); var on = !unanchored && !starting && state.On; var off = !unanchored && !starting && !state.On; LabelUnanchored.Visible = unanchored; StartProgress.Visible = starting; StopButton.Visible = on; StartButton.Visible = off; if (starting) { StatusLabel.Text = _loc.GetString("portable-generator-ui-status-starting"); StatusLabel.SetOnlyStyleClass("Caution"); StartProgress.Value = progress; } else if (on) { StatusLabel.Text = _loc.GetString("portable-generator-ui-status-running"); StatusLabel.SetOnlyStyleClass("Good"); } else { StatusLabel.Text = _loc.GetString("portable-generator-ui-status-stopped"); StatusLabel.SetOnlyStyleClass("Danger"); } var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable); var switcher = _entityManager.System(); OutputSwitchLabel.Visible = canSwitch; OutputSwitchButton.Visible = canSwitch; if (switchable != null) { var voltage = switcher.VoltageString(switcher.GetVoltage(_entity, switchable)); OutputSwitchLabel.Text = Loc.GetString("portable-generator-ui-current-output", ("voltage", voltage)); var nextVoltage = switcher.VoltageString(switcher.GetNextVoltage(_entity, switchable)); OutputSwitchButton.Text = Loc.GetString("power-switchable-switch-voltage", ("voltage", nextVoltage)); OutputSwitchButton.Disabled = state.On; } CloggedLabel.Visible = state.Clogged; if (state.NetworkStats is { } netStats) { NetworkStats.Text = Loc.GetString( "portable-generator-ui-network-stats-value", ("load", netStats.Load), ("supply", netStats.Supply)); var good = netStats.Load <= netStats.Supply; NetworkStats.SetOnlyStyleClass(good ? "Good" : "Caution"); } else { NetworkStats.Text = Loc.GetString("portable-generator-ui-network-stats-not-connected"); NetworkStats.StyleClasses.Clear(); } } private bool TryGetStartProgress(out float progress) { // Try to check progress of auto-revving first if (_entityManager.TryGetComponent(_entity, out var activeGeneratorRevvingComponent) && _entityManager.TryGetComponent(_entity, out var portableGeneratorComponent)) { var calculatedProgress = activeGeneratorRevvingComponent.CurrentTime / portableGeneratorComponent.StartTime; progress = (float) calculatedProgress; return true; } var doAfterSystem = _entityManager.EntitySysManager.GetEntitySystem(); return doAfterSystem.TryFindActiveDoAfter(_entity, out _, out _, out progress); } }