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())