From 4b6853b433a29d0af4705e5785c532dc19144fb1 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 5 Dec 2018 21:01:00 +0000 Subject: [PATCH] Prevent multiple Transforms from triggering in the same tick. This leads to actor duplication. --- OpenRA.Game/Actor.cs | 4 ++++ OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs | 3 +++ OpenRA.Mods.Common/Activities/Transform.cs | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index d92398e34c..f64d091aea 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -42,6 +42,7 @@ namespace OpenRA public Player Owner { get; internal set; } public bool IsInWorld { get; internal set; } + public bool WillDispose { get; private set; } public bool Disposed { get; private set; } public Activity CurrentActivity { get; private set; } @@ -284,6 +285,9 @@ namespace OpenRA if (CurrentActivity != null) CurrentActivity.RootActivity.OnActorDisposeOuter(this); + // Allow traits/activities to prevent a race condition when they depend on disposing the actor (e.g. Transforms) + WillDispose = true; + World.AddFrameEndTask(w => { if (Disposed) diff --git a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs index c3992824c5..ef60f07eac 100644 --- a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs +++ b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs @@ -204,6 +204,9 @@ namespace OpenRA.Mods.Cnc.Traits void ITick.Tick(Actor self) { + if (self.WillDispose) + return; + if (triggered) health.InflictDamage(self, chronosphere, new Damage(info.Damage, info.DamageTypes), true); diff --git a/OpenRA.Mods.Common/Activities/Transform.cs b/OpenRA.Mods.Common/Activities/Transform.cs index dca91d34c4..3c8bc77187 100644 --- a/OpenRA.Mods.Common/Activities/Transform.cs +++ b/OpenRA.Mods.Common/Activities/Transform.cs @@ -89,7 +89,7 @@ namespace OpenRA.Mods.Common.Activities { self.World.AddFrameEndTask(w => { - if (self.IsDead) + if (self.IsDead || self.WillDispose) return; foreach (var nt in self.TraitsImplementing())