diff --git a/OpenRA.Mods.RA/Render/RenderBuildingWall.cs b/OpenRA.Mods.RA/Render/RenderBuildingWall.cs index ee1bdddc20..7a25fe890e 100644 --- a/OpenRA.Mods.RA/Render/RenderBuildingWall.cs +++ b/OpenRA.Mods.RA/Render/RenderBuildingWall.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -15,56 +15,86 @@ namespace OpenRA.Mods.RA.Render { class RenderBuildingWallInfo : RenderBuildingInfo { - public override object Create(ActorInitializer init) { return new RenderBuildingWall( init, this ); } + public readonly string Sequence = "idle"; + + public override object Create(ActorInitializer init) { return new RenderBuildingWall(init, this); } } - class RenderBuildingWall : RenderBuilding, INotifyBuildComplete + class RenderBuildingWall : RenderBuilding, INotifyBuildComplete, INotifyAddedToWorld, INotifyRemovedFromWorld { - string seqName; - int adjacentWalls = 0; + readonly RenderBuildingWallInfo info; + int adjacent = 0; + bool dirty = true; - public RenderBuildingWall( ActorInitializer init, RenderBuildingInfo info ) + public RenderBuildingWall(ActorInitializer init, RenderBuildingWallInfo info) : base(init, info) { - seqName = "idle"; + this.info = info; } - public void BuildingComplete( Actor self ) + public void BuildingComplete(Actor self) { - anim.PlayFetchIndex(seqName, () => adjacentWalls); + anim.PlayFetchIndex(info.Sequence, () => adjacent); } public override void DamageStateChanged(Actor self, AttackInfo e) { - anim.PlayFetchIndex(NormalizeSequence(anim, e.DamageState, "idle"), () => adjacentWalls); + anim.PlayFetchIndex(NormalizeSequence(anim, e.DamageState, info.Sequence), () => adjacent); } - bool hasTicked = false; public override void Tick(Actor self) { base.Tick(self); - if (!hasTicked) - { - var vec = new CVec(1, 1); - var adjWalls = self.World.FindActorsInBox(self.Location - vec, self.Location + vec) - .Where(a => a.Info == self.Info && a != self); + if (!dirty) + return; - foreach (var w in adjWalls) - { - w.Trait().AddAdjacentWall(w.Location, self.Location); - AddAdjacentWall(self.Location, w.Location); - } - hasTicked = true; + // Update connection to neighbours + var vec = new CVec(1, 1); + var adjacentActors = self.World.FindActorsInBox(self.Location - vec, self.Location + vec); + + adjacent = 0; + foreach (var a in adjacentActors) + { + var rb = a.TraitOrDefault(); + if (rb == null) + continue; + + var location = self.Location; + var otherLocation = a.Location; + + if (otherLocation == location + new CVec(0, -1)) + adjacent |= 1; + else if (otherLocation == location + new CVec(+1, 0)) + adjacent |= 2; + else if (otherLocation == location + new CVec(0, +1)) + adjacent |= 4; + else if (otherLocation == location + new CVec(-1, 0)) + adjacent |= 8; } + + dirty = false; } - void AddAdjacentWall(CPos location, CPos otherLocation) + void UpdateNeighbours(Actor self) { - if (otherLocation == location + new CVec(0, -1)) adjacentWalls |= 1; - if (otherLocation == location + new CVec(+1, 0)) adjacentWalls |= 2; - if (otherLocation == location + new CVec(0, +1)) adjacentWalls |= 4; - if (otherLocation == location + new CVec(-1, 0)) adjacentWalls |= 8; + var vec = new CVec(1, 1); + var neighbours = self.World.FindActorsInBox(self.Location - vec, self.Location + vec) + .Select(a => a.TraitOrDefault()) + .Where(a => a != null); + + foreach (var rb in neighbours) + rb.dirty = true; + } + + public void AddedToWorld(Actor self) + { + UpdateNeighbours(self); + } + + public void RemovedFromWorld(Actor self) + { + UpdateNeighbours(self); } } }