do_after fixes (#3299)

* Try fixing DoAfterBar coordinates issue

Also I have a somewhat shitcode way to ensure it doesn't get stuck but I'll wait to see if it still happens on live.

* Brute force fix the stuck issue

Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
This commit is contained in:
metalgearsloth
2021-02-25 11:32:41 +11:00
committed by GitHub
parent adbcfbb951
commit 94bdf01ab7
2 changed files with 38 additions and 12 deletions

View File

@@ -51,7 +51,7 @@ namespace Content.Client.GameObjects.Components
/// </summary>
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,7 +129,6 @@ namespace Content.Client.GameObjects.Components
/// <param name="clientDoAfter"></param>
public void Remove(ClientDoAfter clientDoAfter)
{
if (_doAfters.ContainsKey(clientDoAfter.ID))
_doAfters.Remove(clientDoAfter.ID);
var found = false;

View File

@@ -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);
}
/// <summary>
@@ -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<byte>();
var toRemove = new List<byte>();
// 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);
}
}
}