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