diff --git a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleMenu.xaml.cs b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleMenu.xaml.cs index 5031a3d99c..90732f814f 100644 --- a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleMenu.xaml.cs +++ b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleMenu.xaml.cs @@ -23,6 +23,9 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow // For rendering the progress bar, updated from BUI state private TimeSpan? _startTime; private TimeSpan? _totalTime; + private TimeSpan? _accumulatedRunTime; + + private bool _paused; public AnalysisConsoleMenu() { @@ -39,10 +42,15 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow { base.FrameUpdate(args); - if (_startTime is not { } start || _totalTime is not { } total) + if (_startTime is not { } start || _totalTime is not { } total || _accumulatedRunTime is not { } accumulated) return; - var remaining = start + total - _timing.CurTime; + var remaining = total - accumulated; + if (!_paused) + { + // If the analyzer is running, its remaining time is further discounted by the time it's been running for. + remaining += start - _timing.CurTime; + } var secsText = Math.Max((int) remaining.TotalSeconds, 0); ProgressLabel.Text = Loc.GetString("analysis-console-progress-text", @@ -89,7 +97,14 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow if (state.Scanning) { - message.AddMarkup(Loc.GetString("analysis-console-info-scanner")); + if (state.Paused) + { + message.AddMarkup(Loc.GetString("analysis-console-info-scanner-paused")); + } + else + { + message.AddMarkup(Loc.GetString("analysis-console-info-scanner")); + } Information.SetMessage(message); UpdateArtifactIcon(null); //set it to blank return; @@ -121,6 +136,8 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow _startTime = state.StartTime; _totalTime = state.TotalTime; + _accumulatedRunTime = state.AccumulatedRunTime; + _paused = state.Paused; } } diff --git a/Content.Server/Xenoarchaeology/Equipment/Components/ActiveArtifactAnalyzerComponent.cs b/Content.Server/Xenoarchaeology/Equipment/Components/ActiveArtifactAnalyzerComponent.cs index 7d3fe6a2f0..7c1fe288fc 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Components/ActiveArtifactAnalyzerComponent.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Components/ActiveArtifactAnalyzerComponent.cs @@ -10,11 +10,24 @@ namespace Content.Server.Xenoarchaeology.Equipment.Components; public sealed partial class ActiveArtifactAnalyzerComponent : Component { /// - /// When did the scanning start? + /// When did the scanning start or last resume? /// [DataField("startTime", customTypeSerializer: typeof(TimespanSerializer))] public TimeSpan StartTime; + /// + /// When pausing, this will store the duration the scan has already been running for. + /// + [ViewVariables(VVAccess.ReadWrite)] + public TimeSpan AccumulatedRunTime; + + /// + /// Is analysis paused? + /// It could be when the Artifact Analyzer has no power, for example. + /// + [ViewVariables(VVAccess.ReadWrite)] + public bool AnalysisPaused = false; + /// /// What is being scanned? /// diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs index 500546c033..abb14fbc8d 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs @@ -79,7 +79,10 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var active, out var scan)) { - if (_timing.CurTime - active.StartTime < scan.AnalysisDuration * scan.AnalysisDurationMulitplier) + if (active.AnalysisPaused) + continue; + + if (_timing.CurTime - active.StartTime < scan.AnalysisDuration * scan.AnalysisDurationMulitplier - active.AccumulatedRunTime) continue; FinishScan(uid, scan, active); @@ -209,9 +212,11 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem var serverConnected = TryComp(uid, out var client) && client.ConnectedToServer; var scanning = TryComp(component.AnalyzerEntity, out var active); + var paused = active != null ? active.AnalysisPaused : false; + var state = new AnalysisConsoleScanUpdateState(GetNetEntity(artifact), analyzerConnected, serverConnected, - canScan, canPrint, msg, scanning, active?.StartTime, totalTime, points); + canScan, canPrint, msg, scanning, paused, active?.StartTime, active?.AccumulatedRunTime, totalTime, points); var bui = _ui.GetUi(uid, ArtifactAnalzyerUiKey.Key); _ui.SetUiState(bui, state); @@ -248,8 +253,12 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem var activeComp = EnsureComp(component.AnalyzerEntity.Value); activeComp.StartTime = _timing.CurTime; + activeComp.AccumulatedRunTime = TimeSpan.Zero; activeComp.Artifact = ent.Value; + if (TryComp(component.AnalyzerEntity.Value, out var powa)) + activeComp.AnalysisPaused = !powa.Powered; + var activeArtifact = EnsureComp(ent.Value); activeArtifact.Scanner = component.AnalyzerEntity.Value; UpdateUserInterface(uid, component); @@ -415,6 +424,33 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem UpdateUserInterface(component.Console.Value); } + [PublicAPI] + public void PauseScan(EntityUid uid, ArtifactAnalyzerComponent? component = null, ActiveArtifactAnalyzerComponent? active = null) + { + if (!Resolve(uid, ref component, ref active) || active.AnalysisPaused) + return; + + active.AnalysisPaused = true; + // As we pause, we store what was already completed. + active.AccumulatedRunTime = (_timing.CurTime - active.StartTime) + active.AccumulatedRunTime; + + if (Exists(component.Console)) + UpdateUserInterface(component.Console.Value); + } + + [PublicAPI] + public void ResumeScan(EntityUid uid, ArtifactAnalyzerComponent? component = null, ActiveArtifactAnalyzerComponent? active = null) + { + if (!Resolve(uid, ref component, ref active) || !active.AnalysisPaused) + return; + + active.StartTime = _timing.CurTime; + active.AnalysisPaused = false; + + if (Exists(component.Console)) + UpdateUserInterface(component.Console.Value); + } + private void OnRefreshParts(EntityUid uid, ArtifactAnalyzerComponent component, RefreshPartsEvent args) { var analysisRating = args.PartRatings[component.MachinePartAnalysisDuration]; @@ -462,10 +498,16 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem _ambientSound.SetAmbience(uid, false); } - private void OnPowerChanged(EntityUid uid, ActiveArtifactAnalyzerComponent component, ref PowerChangedEvent args) + private void OnPowerChanged(EntityUid uid, ActiveArtifactAnalyzerComponent active, ref PowerChangedEvent args) { if (!args.Powered) - CancelScan(component.Artifact); + { + PauseScan(uid, null, active); + } + else + { + ResumeScan(uid, null, active); + } } } diff --git a/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactAnalyzer.cs b/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactAnalyzer.cs index a36effaf5e..cecacceda9 100644 --- a/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactAnalyzer.cs +++ b/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactAnalyzer.cs @@ -46,14 +46,18 @@ public sealed class AnalysisConsoleScanUpdateState : BoundUserInterfaceState public bool Scanning; + public bool Paused; + public TimeSpan? StartTime; + public TimeSpan? AccumulatedRunTime; + public TimeSpan? TotalTime; public int PointAmount; public AnalysisConsoleScanUpdateState(NetEntity? artifact, bool analyzerConnected, bool serverConnected, bool canScan, bool canPrint, - FormattedMessage? scanReport, bool scanning, TimeSpan? startTime, TimeSpan? totalTime, int pointAmount) + FormattedMessage? scanReport, bool scanning, bool paused, TimeSpan? startTime, TimeSpan? accumulatedRunTime, TimeSpan? totalTime, int pointAmount) { Artifact = artifact; AnalyzerConnected = analyzerConnected; @@ -64,7 +68,10 @@ public sealed class AnalysisConsoleScanUpdateState : BoundUserInterfaceState ScanReport = scanReport; Scanning = scanning; + Paused = paused; + StartTime = startTime; + AccumulatedRunTime = accumulatedRunTime; TotalTime = totalTime; PointAmount = pointAmount; diff --git a/Resources/Locale/en-US/xenoarchaeology/artifact-analyzer.ftl b/Resources/Locale/en-US/xenoarchaeology/artifact-analyzer.ftl index 6968005db0..599f36ec91 100644 --- a/Resources/Locale/en-US/xenoarchaeology/artifact-analyzer.ftl +++ b/Resources/Locale/en-US/xenoarchaeology/artifact-analyzer.ftl @@ -21,6 +21,7 @@ analysis-console-info-edges = EDGES: {$edges} analysis-console-info-value = UNEXTRACTED_VALUE: {$value} analysis-console-info-scanner = Scanning... +analysis-console-info-scanner-paused = Paused. analysis-console-progress-text = {$seconds -> [one] T-{$seconds} second *[other] T-{$seconds} seconds