From 5bc47f483473d3574434460ddb91ee34767bc69c Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Thu, 13 Jun 2013 09:38:07 +1200 Subject: [PATCH 1/3] Add generation counting to Actor and Target This allows us to invalidate targets based on arbitrary conditions, just by bumping the actor's generation number. The next patches will use this. --- OpenRA.Game/Actor.cs | 1 + OpenRA.Game/Traits/Target.cs | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 08fbaf0a17..00105153eb 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -72,6 +72,7 @@ namespace OpenRA Activity currentActivity; public Group Group; + public int Generation; internal Actor(World world, string name, TypeDictionary initDict ) { diff --git a/OpenRA.Game/Traits/Target.cs b/OpenRA.Game/Traits/Target.cs index 068e859e3c..4af8de64bb 100644 --- a/OpenRA.Game/Traits/Target.cs +++ b/OpenRA.Game/Traits/Target.cs @@ -18,6 +18,7 @@ namespace OpenRA.Traits Player owner; PPos pos; bool valid; + int generation; public static Target FromActor(Actor a) { @@ -25,7 +26,8 @@ namespace OpenRA.Traits { actor = a, valid = (a != null), - owner = (a != null) ? a.Owner : null + owner = (a != null) ? a.Owner : null, + generation = a.Generation, }; } public static Target FromPos(PPos p) { return new Target { pos = p, valid = true }; } @@ -39,7 +41,7 @@ namespace OpenRA.Traits public static readonly Target None = new Target(); - public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && !actor.IsDead() && actor.Owner == owner)); } } + public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && !actor.IsDead() && actor.Owner == owner && actor.Generation == generation)); } } public PPos PxPosition { get { return IsActor ? actor.Trait().PxPosition : pos; } } public PPos CenterLocation { get { return PxPosition; } } From ae809ce39fa1b13a080fa7b2a0e09c80a1564081 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Thu, 13 Jun 2013 09:44:50 +1200 Subject: [PATCH 2/3] Use actor/target generations to invalidate targets on ownership change --- OpenRA.Game/Actor.cs | 1 + OpenRA.Game/Traits/Target.cs | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 00105153eb..47bfa08aca 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -273,6 +273,7 @@ namespace OpenRA // momentarily remove from world so the ownership queries don't get confused w.Remove(this); Owner = newOwner; + Generation++; w.Add(this); foreach (var t in this.TraitsImplementing()) diff --git a/OpenRA.Game/Traits/Target.cs b/OpenRA.Game/Traits/Target.cs index 4af8de64bb..33456afd5c 100644 --- a/OpenRA.Game/Traits/Target.cs +++ b/OpenRA.Game/Traits/Target.cs @@ -15,7 +15,6 @@ namespace OpenRA.Traits public static Target[] NoTargets = {}; Actor actor; - Player owner; PPos pos; bool valid; int generation; @@ -26,7 +25,6 @@ namespace OpenRA.Traits { actor = a, valid = (a != null), - owner = (a != null) ? a.Owner : null, generation = a.Generation, }; } @@ -41,7 +39,7 @@ namespace OpenRA.Traits public static readonly Target None = new Target(); - public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && !actor.IsDead() && actor.Owner == owner && actor.Generation == generation)); } } + public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && !actor.IsDead() && actor.Generation == generation)); } } public PPos PxPosition { get { return IsActor ? actor.Trait().PxPosition : pos; } } public PPos CenterLocation { get { return PxPosition; } } From 59d10cfc5d3a24350b7a2015b8f6ca73d74c8ebe Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Thu, 13 Jun 2013 09:47:42 +1200 Subject: [PATCH 3/3] Invalidate targets when chronoshifted This replaces OpenRA/OpenRA#2807, without the massive cost. --- OpenRA.Mods.RA/Activities/Teleport.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenRA.Mods.RA/Activities/Teleport.cs b/OpenRA.Mods.RA/Activities/Teleport.cs index ede8cbed78..f9809d9f83 100755 --- a/OpenRA.Mods.RA/Activities/Teleport.cs +++ b/OpenRA.Mods.RA/Activities/Teleport.cs @@ -33,6 +33,7 @@ namespace OpenRA.Mods.RA.Activities Sound.Play("chrono2.aud", destination.ToPPos()); self.Trait().SetPosition(self, destination); + self.Generation++; if (killCargo && self.HasTrait()) { @@ -66,6 +67,7 @@ namespace OpenRA.Mods.RA.Activities public override Activity Tick(Actor self) { self.Trait().SetPosition(self, destination); + self.Generation++; return NextActivity; } }