diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 76ca107aa3..ad7c87e6e3 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -24,26 +24,26 @@ namespace OpenRA public readonly World World; public readonly uint ActorID; - - IOccupySpace OccupiesSpace; + + Lazy occupySpace; IHasLocation HasLocation; Lazy Move; public Cached Bounds; public Cached ExtendedBounds; - public int2 Location - { get { - if (OccupiesSpace == null) - OccupiesSpace = Trait(); - return OccupiesSpace.TopLeft; - }} + public IOccupySpace OccupiesSpace { get { return occupySpace.Value; } } + + public int2 Location { get { return occupySpace.Value.TopLeft; } } public int2 CenterLocation - { get { - if (HasLocation == null) - HasLocation = Trait(); - return HasLocation.PxPosition; - }} + { + get + { + if (HasLocation == null) + HasLocation = Trait(); + return HasLocation.PxPosition; + } + } [Sync] public Player Owner; @@ -60,6 +60,8 @@ namespace OpenRA if( initDict.Contains() ) Owner = init.Get(); + occupySpace = Lazy.New( () => TraitOrDefault() ); + if (name != null) { if (!Rules.Info.ContainsKey(name.ToLowerInvariant())) diff --git a/OpenRA.Game/ActorMap.cs b/OpenRA.Game/ActorMap.cs index a0c3337217..37bac791de 100644 --- a/OpenRA.Game/ActorMap.cs +++ b/OpenRA.Game/ActorMap.cs @@ -44,8 +44,8 @@ namespace OpenRA map = world.Map; influence = new InfluenceNode[world.Map.MapSize.X, world.Map.MapSize.Y]; - world.ActorAdded += a => Add( a, a.TraitOrDefault() ); - world.ActorRemoved += a => Remove( a, a.TraitOrDefault() ); + world.ActorAdded += a => Add( a, a.OccupiesSpace ); + world.ActorRemoved += a => Remove( a, a.OccupiesSpace ); } public IEnumerable GetUnitsAt( int2 a ) @@ -71,8 +71,8 @@ namespace OpenRA if (!AnyUnitsAt(a)) return true; - return new[]{SubCell.TopLeft, SubCell.TopRight, SubCell.Center, - SubCell.BottomLeft, SubCell.BottomRight}.Any(b => !AnyUnitsAt(a,b)); + return new[]{ SubCell.TopLeft, SubCell.TopRight, SubCell.Center, + SubCell.BottomLeft, SubCell.BottomRight }.Any(b => !AnyUnitsAt(a,b)); } public bool AnyUnitsAt(int2 a) diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 21b10feb4d..dccc25259d 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -132,7 +132,7 @@ namespace OpenRA.Traits public static IEnumerable GetVisOrigins(Actor a) { - var ios = a.TraitOrDefault(); + var ios = a.OccupiesSpace; if (ios != null) { var cells = ios.OccupiedCells(); diff --git a/OpenRA.Mods.RA/Activities/CaptureActor.cs b/OpenRA.Mods.RA/Activities/CaptureActor.cs index 7a77488e42..f2c87a69cc 100644 --- a/OpenRA.Mods.RA/Activities/CaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/CaptureActor.cs @@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Activities if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; if (target.Owner == self.Owner) return NextActivity; - if( !target.Trait().OccupiedCells().Any( x => x.First == self.Location ) ) + if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; // todo: clean this up diff --git a/OpenRA.Mods.RA/Activities/Demolish.cs b/OpenRA.Mods.RA/Activities/Demolish.cs index a708aa505c..35148a4bb9 100644 --- a/OpenRA.Mods.RA/Activities/Demolish.cs +++ b/OpenRA.Mods.RA/Activities/Demolish.cs @@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA.Activities if (IsCanceled) return NextActivity; if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - if( !target.Trait().OccupiedCells().Any( x => x.First == self.Location ) ) + if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, () => diff --git a/OpenRA.Mods.RA/Activities/DonateSupplies.cs b/OpenRA.Mods.RA/Activities/DonateSupplies.cs index fd51b76025..98e76b719e 100644 --- a/OpenRA.Mods.RA/Activities/DonateSupplies.cs +++ b/OpenRA.Mods.RA/Activities/DonateSupplies.cs @@ -30,7 +30,7 @@ namespace OpenRA.Mods.RA.Activities { if (IsCanceled) return NextActivity; if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - if (!target.Trait().OccupiedCells().Any(x => x.First == self.Location)) + if (!target.OccupiesSpace.OccupiedCells().Any(x => x.First == self.Location)) return NextActivity; target.Owner.PlayerActor.Trait().GiveCash(payload); diff --git a/OpenRA.Mods.RA/Activities/Enter.cs b/OpenRA.Mods.RA/Activities/Enter.cs index 17849b8246..6dcf9df962 100755 --- a/OpenRA.Mods.RA/Activities/Enter.cs +++ b/OpenRA.Mods.RA/Activities/Enter.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA.Activities return NextActivity; var mobile = self.Trait(); - var nearest = target.Trait().NearestCellTo( mobile.toCell ); + var nearest = target.OccupiesSpace.NearestCellTo( mobile.toCell ); if( ( nearest - mobile.toCell ).LengthSquared > 2 ) return Util.SequenceActivities( new MoveAdjacentTo( target ), this ); diff --git a/OpenRA.Mods.RA/Activities/Infiltrate.cs b/OpenRA.Mods.RA/Activities/Infiltrate.cs index 3f48122279..119013bff3 100644 --- a/OpenRA.Mods.RA/Activities/Infiltrate.cs +++ b/OpenRA.Mods.RA/Activities/Infiltrate.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; if (target.Owner == self.Owner) return NextActivity; - if( !target.Trait().OccupiedCells().Any( x => x.First == self.Location ) ) + if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; foreach (var t in target.TraitsImplementing()) diff --git a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs index 6a75e6e041..a073bc4294 100755 --- a/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs +++ b/OpenRA.Mods.RA/Activities/MoveAdjacentTo.cs @@ -35,12 +35,12 @@ namespace OpenRA.Mods.RA.Activities if( IsCanceled || !target.IsValid) return NextActivity; var mobile = self.Trait(); - Pair[] cells = new Pair[] {}; + var cells = new Pair[] {}; if (target.IsActor) - cells = target.Actor.Trait().OccupiedCells().ToArray(); + cells = target.Actor.OccupiesSpace.OccupiedCells().ToArray(); if (cells.Length == 0) - cells = new OpenRA.FileFormats.Pair[] { + cells = new [] { Pair.New(Util.CellContaining(target.CenterLocation), SubCell.FullCell) }; var ps1 = new PathSearch( self.World, mobile.Info, self.Owner ) diff --git a/OpenRA.Mods.RA/Activities/RepairBuilding.cs b/OpenRA.Mods.RA/Activities/RepairBuilding.cs index 829505bfc1..98dcb9c06d 100644 --- a/OpenRA.Mods.RA/Activities/RepairBuilding.cs +++ b/OpenRA.Mods.RA/Activities/RepairBuilding.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA.Activities { if (IsCanceled) return NextActivity; if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; - if( !target.Trait().OccupiedCells().Any( x => x.First == self.Location ) ) + if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; var health = target.Trait(); diff --git a/OpenRA.Mods.RA/AppearsOnRadar.cs b/OpenRA.Mods.RA/AppearsOnRadar.cs index d5cfc7ee57..c0fd369897 100755 --- a/OpenRA.Mods.RA/AppearsOnRadar.cs +++ b/OpenRA.Mods.RA/AppearsOnRadar.cs @@ -15,29 +15,25 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - public class AppearsOnRadarInfo : TraitInfo + public class AppearsOnRadarInfo : ITraitInfo { public readonly bool UseLocation = false; + + public object Create(ActorInitializer init) { return new AppearsOnRadar(this); } } public class AppearsOnRadar : IRadarSignature { AppearsOnRadarInfo info; - IOccupySpace Space; + + public AppearsOnRadar(AppearsOnRadarInfo info) { this.info = info; } public IEnumerable RadarSignatureCells(Actor self) { - if (info == null) - info = self.Info.Traits.Get(); - if (info.UseLocation) return new int2[] { self.Location }; else - { - if (Space == null) - Space = self.Trait(); - return Space.OccupiedCells().Select(c => c.First); - } + return self.OccupiesSpace.OccupiedCells().Select(c => c.First); } public Color RadarSignatureColor(Actor self)