Update neighbours when walls are destroyed or sold. Fixes #2351.

This commit is contained in:
Paul Chote
2014-04-05 16:27:39 +13:00
parent 1ac4c6d1e1
commit 52b4ac0aed

View File

@@ -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<RenderBuildingWall>().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<RenderBuildingWall>();
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<RenderBuildingWall>())
.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);
}
}
}