diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index ee96b6545c..954ff97abe 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -695,6 +695,7 @@
+
diff --git a/OpenRA.Mods.Common/Traits/AffectsShroud.cs b/OpenRA.Mods.Common/Traits/AffectsShroud.cs
new file mode 100644
index 0000000000..4f0a84884b
--- /dev/null
+++ b/OpenRA.Mods.Common/Traits/AffectsShroud.cs
@@ -0,0 +1,101 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2015 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,
+ * see COPYING.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.Common.Traits
+{
+ public abstract class AffectsShroudInfo : ITraitInfo
+ {
+ public readonly WDist Range = WDist.Zero;
+
+ [Desc("Possible values are CenterPosition (measure range from the center) and ",
+ "Footprint (measure range from the footprint)")]
+ public readonly VisibilityType Type = VisibilityType.Footprint;
+
+ public abstract object Create(ActorInitializer init);
+ }
+
+ public abstract class AffectsShroud : ITick, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld
+ {
+ static readonly PPos[] NoCells = { };
+
+ readonly AffectsShroudInfo info;
+ [Sync] CPos cachedLocation;
+ [Sync] bool cachedDisabled;
+
+ protected abstract void AddCellsToPlayerShroud(Actor self, Player player, PPos[] uv);
+ protected abstract void RemoveCellsFromPlayerShroud(Actor self, Player player);
+ protected virtual bool IsDisabled(Actor self) { return false; }
+
+ public AffectsShroud(Actor self, AffectsShroudInfo info) { this.info = info; }
+
+ PPos[] ProjectedCells(Actor self)
+ {
+ var map = self.World.Map;
+ var range = Range;
+ if (range == WDist.Zero)
+ return NoCells;
+
+ if (info.Type == VisibilityType.Footprint)
+ return self.OccupiesSpace.OccupiedCells()
+ .SelectMany(kv => Shroud.ProjectedCellsInRange(map, kv.First, range))
+ .Distinct().ToArray();
+
+ return Shroud.ProjectedCellsInRange(map, self.CenterPosition, range)
+ .ToArray();
+ }
+
+ public void Tick(Actor self)
+ {
+ if (!self.IsInWorld)
+ return;
+
+ var centerPosition = self.CenterPosition;
+ var projectedPos = centerPosition - new WVec(0, centerPosition.Z, centerPosition.Z);
+ var projectedLocation = self.World.Map.CellContaining(projectedPos);
+ var disabled = IsDisabled(self);
+
+ if (cachedLocation == projectedLocation && cachedDisabled == disabled)
+ return;
+
+ cachedLocation = projectedLocation;
+ cachedDisabled = disabled;
+
+ var cells = ProjectedCells(self);
+ foreach (var p in self.World.Players)
+ {
+ RemoveCellsFromPlayerShroud(self, p);
+ AddCellsToPlayerShroud(self, p, cells);
+ }
+ }
+
+ public void AddedToWorld(Actor self)
+ {
+ var centerPosition = self.CenterPosition;
+ var projectedPos = centerPosition - new WVec(0, centerPosition.Z, centerPosition.Z);
+ cachedLocation = self.World.Map.CellContaining(projectedPos);
+ cachedDisabled = IsDisabled(self);
+ var cells = ProjectedCells(self);
+ foreach (var p in self.World.Players)
+ AddCellsToPlayerShroud(self, p, cells);
+ }
+
+ public void RemovedFromWorld(Actor self)
+ {
+ foreach (var p in self.World.Players)
+ RemoveCellsFromPlayerShroud(self, p);
+ }
+
+ public WDist Range { get { return cachedDisabled ? WDist.Zero : info.Range; } }
+ }
+}
diff --git a/OpenRA.Mods.Common/Traits/CreatesShroud.cs b/OpenRA.Mods.Common/Traits/CreatesShroud.cs
index f00d0143b3..a64802b144 100644
--- a/OpenRA.Mods.Common/Traits/CreatesShroud.cs
+++ b/OpenRA.Mods.Common/Traits/CreatesShroud.cs
@@ -10,19 +10,17 @@
namespace OpenRA.Mods.Common.Traits
{
- public class CreatesShroudInfo : RevealsShroudInfo
+ public class CreatesShroudInfo : AffectsShroudInfo
{
public override object Create(ActorInitializer init) { return new CreatesShroud(init.Self, this); }
}
- public class CreatesShroud : RevealsShroud
+ public class CreatesShroud : AffectsShroud
{
public CreatesShroud(Actor self, CreatesShroudInfo info)
- : base(self, info)
- {
- addCellsToPlayerShroud = (p, uv) => p.Shroud.AddProjectedShroudGeneration(self, uv);
- removeCellsFromPlayerShroud = p => p.Shroud.RemoveShroudGeneration(self);
- isDisabled = () => self.IsDisabled();
- }
+ : base(self, info) { }
+ protected override void AddCellsToPlayerShroud(Actor self, Player p, PPos[] uv) { p.Shroud.AddProjectedShroudGeneration(self, uv); }
+ protected override void RemoveCellsFromPlayerShroud(Actor self, Player p) { p.Shroud.RemoveShroudGeneration(self); }
+ protected override bool IsDisabled(Actor self) { return self.IsDisabled(); }
}
}
\ No newline at end of file
diff --git a/OpenRA.Mods.Common/Traits/RevealsShroud.cs b/OpenRA.Mods.Common/Traits/RevealsShroud.cs
index c7aba8b796..9a643b57fe 100644
--- a/OpenRA.Mods.Common/Traits/RevealsShroud.cs
+++ b/OpenRA.Mods.Common/Traits/RevealsShroud.cs
@@ -8,101 +8,18 @@
*/
#endregion
-using System;
-using System.Linq;
-using OpenRA.Traits;
-
namespace OpenRA.Mods.Common.Traits
{
- public class RevealsShroudInfo : ITraitInfo
+ public class RevealsShroudInfo : AffectsShroudInfo
{
- public readonly WDist Range = WDist.Zero;
-
- [Desc("Possible values are CenterPosition (measure range from the center) and ",
- "Footprint (measure range from the footprint)")]
- public readonly VisibilityType Type = VisibilityType.Footprint;
-
- public virtual object Create(ActorInitializer init) { return new RevealsShroud(init.Self, this); }
+ public override object Create(ActorInitializer init) { return new RevealsShroud(init.Self, this); }
}
- public class RevealsShroud : ITick, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld
+ public class RevealsShroud : AffectsShroud
{
- static readonly PPos[] NoCells = { };
-
- readonly RevealsShroudInfo info;
- [Sync] CPos cachedLocation;
- [Sync] bool cachedDisabled;
-
- protected Action addCellsToPlayerShroud;
- protected Action removeCellsFromPlayerShroud;
- protected Func isDisabled;
-
public RevealsShroud(Actor self, RevealsShroudInfo info)
- {
- this.info = info;
-
- addCellsToPlayerShroud = (p, uv) => p.Shroud.AddProjectedVisibility(self, uv);
- removeCellsFromPlayerShroud = p => p.Shroud.RemoveVisibility(self);
- isDisabled = () => false;
- }
-
- PPos[] ProjectedCells(Actor self)
- {
- var map = self.World.Map;
- var range = Range;
- if (range == WDist.Zero)
- return NoCells;
-
- if (info.Type == VisibilityType.Footprint)
- return self.OccupiesSpace.OccupiedCells()
- .SelectMany(kv => Shroud.ProjectedCellsInRange(map, kv.First, range))
- .Distinct().ToArray();
-
- return Shroud.ProjectedCellsInRange(map, self.CenterPosition, range)
- .ToArray();
- }
-
- public void Tick(Actor self)
- {
- if (!self.IsInWorld)
- return;
-
- var centerPosition = self.CenterPosition;
- var projectedPos = centerPosition - new WVec(0, centerPosition.Z, centerPosition.Z);
- var projectedLocation = self.World.Map.CellContaining(projectedPos);
- var disabled = isDisabled();
-
- if (cachedLocation == projectedLocation && cachedDisabled == disabled)
- return;
-
- cachedLocation = projectedLocation;
- cachedDisabled = disabled;
-
- var cells = ProjectedCells(self);
- foreach (var p in self.World.Players)
- {
- removeCellsFromPlayerShroud(p);
- addCellsToPlayerShroud(p, cells);
- }
- }
-
- public void AddedToWorld(Actor self)
- {
- var centerPosition = self.CenterPosition;
- var projectedPos = centerPosition - new WVec(0, centerPosition.Z, centerPosition.Z);
- cachedLocation = self.World.Map.CellContaining(projectedPos);
- cachedDisabled = isDisabled();
- var cells = ProjectedCells(self);
- foreach (var p in self.World.Players)
- addCellsToPlayerShroud(p, cells);
- }
-
- public void RemovedFromWorld(Actor self)
- {
- foreach (var p in self.World.Players)
- removeCellsFromPlayerShroud(p);
- }
-
- public WDist Range { get { return cachedDisabled ? WDist.Zero : info.Range; } }
+ : base(self, info) { }
+ protected override void AddCellsToPlayerShroud(Actor self, Player p, PPos[] uv) { p.Shroud.AddProjectedVisibility(self, uv); }
+ protected override void RemoveCellsFromPlayerShroud(Actor self, Player p) { p.Shroud.RemoveVisibility(self); }
}
}