diff --git a/Content.Client/GameObjects/Components/DoAfterComponent.cs b/Content.Client/GameObjects/Components/DoAfterComponent.cs
index a658ca78de..23e54c217a 100644
--- a/Content.Client/GameObjects/Components/DoAfterComponent.cs
+++ b/Content.Client/GameObjects/Components/DoAfterComponent.cs
@@ -51,7 +51,7 @@ namespace Content.Client.GameObjects.Components
///
public void Enable()
{
- if (Gui != null && !Gui.Disposed)
+ if (Gui?.Disposed == false)
return;
Gui = new DoAfterGui {AttachedEntity = Owner, FirstDraw = true};
@@ -70,6 +70,7 @@ namespace Content.Client.GameObjects.Components
public void Disable()
{
Gui?.Dispose();
+ Gui = null;
}
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
@@ -128,8 +129,7 @@ namespace Content.Client.GameObjects.Components
///
public void Remove(ClientDoAfter clientDoAfter)
{
- if (_doAfters.ContainsKey(clientDoAfter.ID))
- _doAfters.Remove(clientDoAfter.ID);
+ _doAfters.Remove(clientDoAfter.ID);
var found = false;
diff --git a/Content.Client/GameObjects/EntitySystems/DoAfter/DoAfterGui.cs b/Content.Client/GameObjects/EntitySystems/DoAfter/DoAfterGui.cs
index ce588b13b1..ca3beb8a55 100644
--- a/Content.Client/GameObjects/EntitySystems/DoAfter/DoAfterGui.cs
+++ b/Content.Client/GameObjects/EntitySystems/DoAfter/DoAfterGui.cs
@@ -12,11 +12,13 @@ using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
+using Robust.Shared.Utility;
namespace Content.Client.GameObjects.EntitySystems.DoAfter
{
public sealed class DoAfterGui : VBoxContainer
{
+ [Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
@@ -106,12 +108,11 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
var control = _doAfterControls[id];
RemoveChild(control);
+ control.DisposeAllChildren();
_doAfterControls.Remove(id);
_doAfterBars.Remove(id);
- if (_cancelledDoAfters.ContainsKey(id))
- _cancelledDoAfters.Remove(id);
-
+ _cancelledDoAfters.Remove(id);
}
///
@@ -124,11 +125,21 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
if (_cancelledDoAfters.ContainsKey(id))
return;
- if (!_doAfterBars.TryGetValue(id, out var doAfterBar))
+ DoAfterBar doAfterBar;
+
+ if (!_doAfterControls.TryGetValue(id, out var doAfterControl))
{
+ doAfterControl = new PanelContainer();
+ AddChild(doAfterControl);
+ DebugTools.Assert(!_doAfterBars.ContainsKey(id));
doAfterBar = new DoAfterBar();
+ doAfterControl.AddChild(doAfterBar);
_doAfterBars[id] = doAfterBar;
}
+ else
+ {
+ doAfterBar = _doAfterBars[id];
+ }
doAfterBar.Cancelled = true;
_cancelledDoAfters.Add(id, _gameTiming.CurTime);
@@ -148,7 +159,8 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
if (doAfters.Count == 0)
return;
- if (_eyeManager.CurrentMap != AttachedEntity.Transform.MapID)
+ if (_eyeManager.CurrentMap != AttachedEntity.Transform.MapID ||
+ !AttachedEntity.Transform.Coordinates.IsValid(_entityManager))
{
Visible = false;
return;
@@ -172,20 +184,22 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
Visible = true;
var currentTime = _gameTiming.CurTime;
- var toCancel = new List();
+ var toRemove = new List();
// Cleanup cancelled DoAfters
foreach (var (id, cancelTime) in _cancelledDoAfters)
{
if ((currentTime - cancelTime).TotalSeconds > DoAfterSystem.ExcessTime)
- toCancel.Add(id);
+ toRemove.Add(id);
}
- foreach (var id in toCancel)
+ foreach (var id in toRemove)
{
RemoveDoAfter(id);
}
+ toRemove.Clear();
+
// Update 0 -> 1.0f of the things
foreach (var (id, message) in doAfters)
{
@@ -193,8 +207,20 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
continue;
var doAfterBar = _doAfterBars[id];
+ var ratio = (currentTime - message.StartTime).TotalSeconds;
doAfterBar.Ratio = MathF.Min(1.0f,
- (float) (currentTime - message.StartTime).TotalSeconds / message.Delay);
+ (float) ratio / message.Delay);
+
+ // Just in case it doesn't get cleaned up by the system for whatever reason.
+ if (ratio > message.Delay + DoAfterSystem.ExcessTime)
+ {
+ toRemove.Add(id);
+ }
+ }
+
+ foreach (var id in toRemove)
+ {
+ RemoveDoAfter(id);
}
}
}