From 1553a8a5cb153d4f57b1788d24f5508f3d3f6ba9 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sat, 24 Nov 2018 22:35:16 +0100 Subject: [PATCH] Fix empty activity tick when becoming idle Activities usually don't do much more than cleanup on their last, 'null' tick. That, combined with queued activities normally only starting to tick on the next tick, would lead to visible 1-tick 'gaps' between movement activities. Non-movement activities would suffer from the same problem, only with different (presumably less noticable) symptoms. Now we start ticking any activity that was queued from OnBecomingIdle immediately, to avoid that issue. --- OpenRA.Game/Actor.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index b44d1bd23e..d92398e34c 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -77,6 +77,7 @@ namespace OpenRA readonly IMouseBounds[] mouseBounds; readonly IVisibilityModifier[] visibilityModifiers; readonly IDefaultVisibility defaultVisibility; + readonly INotifyBecomingIdle[] becomingIdles; readonly INotifyIdle[] tickIdles; readonly ITargetablePositions[] targetablePositions; WPos[] staticTargetablePositions; @@ -120,6 +121,7 @@ namespace OpenRA mouseBounds = TraitsImplementing().ToArray(); visibilityModifiers = TraitsImplementing().ToArray(); defaultVisibility = Trait(); + becomingIdles = TraitsImplementing().ToArray(); tickIdles = TraitsImplementing().ToArray(); Targetables = TraitsImplementing().ToArray(); targetablePositions = TraitsImplementing().ToArray(); @@ -141,8 +143,15 @@ namespace OpenRA CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity); if (!wasIdle && IsIdle) - foreach (var n in TraitsImplementing()) + { + foreach (var n in becomingIdles) n.OnBecomingIdle(this); + + // If IsIdle is true, it means the last CurrentActivity.Tick returned null. + // If a next activity has been queued via OnBecomingIdle, we need to start running it now, + // to avoid an 'empty' null tick where the actor will (visibly, if moving) do nothing. + CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity); + } else if (wasIdle) foreach (var tickIdle in tickIdles) tickIdle.TickIdle(this);