diff --git a/OpenRA.Game/Map/ProjectedCellLayer.cs b/OpenRA.Game/Map/ProjectedCellLayer.cs
index 1cf01cdc62..c95bd1c74e 100644
--- a/OpenRA.Game/Map/ProjectedCellLayer.cs
+++ b/OpenRA.Game/Map/ProjectedCellLayer.cs
@@ -22,11 +22,24 @@ namespace OpenRA
: base(gridType, size) { }
// Resolve an array index from map coordinates.
- int Index(PPos uv)
+ public int Index(PPos uv)
{
return uv.V * Size.Width + uv.U;
}
+ public T this[int index]
+ {
+ get
+ {
+ return entries[index];
+ }
+
+ set
+ {
+ entries[index] = value;
+ }
+ }
+
/// Gets or sets the layer contents using projected map coordinates.
public T this[PPos uv]
{
diff --git a/OpenRA.Game/Traits/Player/Shroud.cs b/OpenRA.Game/Traits/Player/Shroud.cs
index 731624062e..229e06330d 100644
--- a/OpenRA.Game/Traits/Player/Shroud.cs
+++ b/OpenRA.Game/Traits/Player/Shroud.cs
@@ -99,6 +99,7 @@ namespace OpenRA.Traits
readonly ProjectedCellLayer generatedShroudCount;
readonly ProjectedCellLayer explored;
readonly ProjectedCellLayer touched;
+ bool anyCellTouched;
// Per-cell cache of the resolved cell type (shroud/fog/visible)
readonly ProjectedCellLayer resolvedType;
@@ -142,6 +143,7 @@ namespace OpenRA.Traits
generatedShroudCount = new ProjectedCellLayer(map);
explored = new ProjectedCellLayer(map);
touched = new ProjectedCellLayer(map);
+ anyCellTouched = true;
// Defaults to 0 = Shroud
resolvedType = new ProjectedCellLayer(map);
@@ -159,31 +161,42 @@ namespace OpenRA.Traits
void ITick.Tick(Actor self)
{
+ if (!anyCellTouched)
+ return;
+
+ anyCellTouched = false;
+
if (OnShroudChanged == null)
return;
foreach (var puv in map.ProjectedCells)
{
- if (!touched[puv])
+ var index = touched.Index(puv);
+ if (!touched[index])
continue;
- touched[puv] = false;
+ touched[index] = false;
var type = ShroudCellType.Shroud;
- if (explored[puv] && (!shroudGenerationEnabled || generatedShroudCount[puv] == 0 || visibleCount[puv] > 0))
+ if (explored[index])
{
- var count = visibleCount[puv];
- if (passiveVisibilityEnabled)
- count += passiveVisibleCount[puv];
+ var count = visibleCount[index];
+ if (!shroudGenerationEnabled || count > 0 || generatedShroudCount[index] == 0)
+ {
+ if (passiveVisibilityEnabled)
+ count += passiveVisibleCount[index];
- type = count > 0 ? ShroudCellType.Visible : ShroudCellType.Fog;
+ type = count > 0 ? ShroudCellType.Visible : ShroudCellType.Fog;
+ }
}
- var oldResolvedType = resolvedType[puv];
- resolvedType[puv] = type;
+ var oldResolvedType = resolvedType[index];
if (type != oldResolvedType)
+ {
+ resolvedType[index] = type;
OnShroudChanged(puv);
+ }
}
Hash = Sync.HashPlayer(self.Owner) + self.World.WorldTick;
@@ -231,21 +244,23 @@ namespace OpenRA.Traits
if (!map.Contains(puv))
continue;
- touched[puv] = true;
+ var index = touched.Index(puv);
+ touched[index] = true;
+ anyCellTouched = true;
switch (type)
{
case SourceType.PassiveVisibility:
passiveVisibilityEnabled = true;
- passiveVisibleCount[puv]++;
- explored[puv] = true;
+ passiveVisibleCount[index]++;
+ explored[index] = true;
break;
case SourceType.Visibility:
- visibleCount[puv]++;
- explored[puv] = true;
+ visibleCount[index]++;
+ explored[index] = true;
break;
case SourceType.Shroud:
shroudGenerationEnabled = true;
- generatedShroudCount[puv]++;
+ generatedShroudCount[index]++;
break;
}
}
@@ -261,17 +276,19 @@ namespace OpenRA.Traits
// Cells outside the visible bounds don't increment visibleCount
if (map.Contains(puv))
{
- touched[puv] = true;
+ var index = touched.Index(puv);
+ touched[index] = true;
+ anyCellTouched = true;
switch (state.Type)
{
case SourceType.PassiveVisibility:
- passiveVisibleCount[puv]--;
+ passiveVisibleCount[index]--;
break;
case SourceType.Visibility:
- visibleCount[puv]--;
+ visibleCount[index]--;
break;
case SourceType.Shroud:
- generatedShroudCount[puv]--;
+ generatedShroudCount[index]--;
break;
}
}
@@ -284,10 +301,15 @@ namespace OpenRA.Traits
{
foreach (var puv in cells)
{
- if (map.Contains(puv) && !explored[puv])
+ if (map.Contains(puv))
{
- touched[puv] = true;
- explored[puv] = true;
+ var index = touched.Index(puv);
+ if (!explored[index])
+ {
+ touched[index] = true;
+ anyCellTouched = true;
+ explored[index] = true;
+ }
}
}
}
@@ -299,10 +321,12 @@ namespace OpenRA.Traits
foreach (var puv in map.ProjectedCells)
{
- if (!explored[puv] && s.explored[puv])
+ var index = touched.Index(puv);
+ if (!explored[index] && s.explored[index])
{
- touched[puv] = true;
- explored[puv] = true;
+ touched[index] = true;
+ anyCellTouched = true;
+ explored[index] = true;
}
}
}
@@ -311,10 +335,12 @@ namespace OpenRA.Traits
{
foreach (var puv in map.ProjectedCells)
{
- if (!explored[puv])
+ var index = touched.Index(puv);
+ if (!explored[index])
{
- touched[puv] = true;
- explored[puv] = true;
+ touched[index] = true;
+ anyCellTouched = true;
+ explored[index] = true;
}
}
}
@@ -323,9 +349,12 @@ namespace OpenRA.Traits
{
foreach (var puv in map.ProjectedCells)
{
- touched[puv] = true;
- explored[puv] = (visibleCount[puv] + passiveVisibleCount[puv]) > 0;
+ var index = touched.Index(puv);
+ touched[index] = true;
+ explored[index] = (visibleCount[index] + passiveVisibleCount[index]) > 0;
}
+
+ anyCellTouched = true;
}
public bool IsExplored(WPos pos)