Add a ProjectedCellLayer and use it in Shroud.cs

This commit is contained in:
abcdefg30
2020-05-22 18:42:21 +02:00
committed by reaperrr
parent 385e70552e
commit 67fd71ab92
2 changed files with 94 additions and 56 deletions

View File

@@ -0,0 +1,50 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using OpenRA.Primitives;
namespace OpenRA
{
public sealed class ProjectedCellLayer<T> : CellLayerBase<T>
{
public ProjectedCellLayer(Map map)
: base(map) { }
public ProjectedCellLayer(MapGridType gridType, Size size)
: base(gridType, size) { }
// Resolve an array index from map coordinates.
int Index(PPos uv)
{
return uv.V * Size.Width + uv.U;
}
/// <summary>Gets or sets the layer contents using projected map coordinates.</summary>
public T this[PPos uv]
{
get
{
return entries[Index(uv)];
}
set
{
entries[Index(uv)] = value;
}
}
public bool Contains(PPos uv)
{
return bounds.Contains(uv.U, uv.V);
}
}
}

View File

@@ -94,14 +94,14 @@ namespace OpenRA.Traits
readonly Dictionary<object, ShroudSource> sources = new Dictionary<object, ShroudSource>(); readonly Dictionary<object, ShroudSource> sources = new Dictionary<object, ShroudSource>();
// Per-cell count of each source type, used to resolve the final cell type // Per-cell count of each source type, used to resolve the final cell type
readonly CellLayer<short> passiveVisibleCount; readonly ProjectedCellLayer<short> passiveVisibleCount;
readonly CellLayer<short> visibleCount; readonly ProjectedCellLayer<short> visibleCount;
readonly CellLayer<short> generatedShroudCount; readonly ProjectedCellLayer<short> generatedShroudCount;
readonly CellLayer<bool> explored; readonly ProjectedCellLayer<bool> explored;
readonly CellLayer<bool> touched; readonly ProjectedCellLayer<bool> touched;
// Per-cell cache of the resolved cell type (shroud/fog/visible) // Per-cell cache of the resolved cell type (shroud/fog/visible)
readonly CellLayer<ShroudCellType> resolvedType; readonly ProjectedCellLayer<ShroudCellType> resolvedType;
[Sync] [Sync]
bool disabled; bool disabled;
@@ -137,14 +137,14 @@ namespace OpenRA.Traits
this.info = info; this.info = info;
map = self.World.Map; map = self.World.Map;
passiveVisibleCount = new CellLayer<short>(map); passiveVisibleCount = new ProjectedCellLayer<short>(map);
visibleCount = new CellLayer<short>(map); visibleCount = new ProjectedCellLayer<short>(map);
generatedShroudCount = new CellLayer<short>(map); generatedShroudCount = new ProjectedCellLayer<short>(map);
explored = new CellLayer<bool>(map); explored = new ProjectedCellLayer<bool>(map);
touched = new CellLayer<bool>(map); touched = new ProjectedCellLayer<bool>(map);
// Defaults to 0 = Shroud // Defaults to 0 = Shroud
resolvedType = new CellLayer<ShroudCellType>(map); resolvedType = new ProjectedCellLayer<ShroudCellType>(map);
} }
void INotifyCreated.Created(Actor self) void INotifyCreated.Created(Actor self)
@@ -164,27 +164,26 @@ namespace OpenRA.Traits
foreach (var puv in map.ProjectedCellBounds) foreach (var puv in map.ProjectedCellBounds)
{ {
var uv = (MPos)puv; if (!touched[puv])
if (!touched[uv])
continue; continue;
touched[uv] = false; touched[puv] = false;
var type = ShroudCellType.Shroud; var type = ShroudCellType.Shroud;
if (explored[uv] && (!shroudGenerationEnabled || generatedShroudCount[uv] == 0 || visibleCount[uv] > 0)) if (explored[puv] && (!shroudGenerationEnabled || generatedShroudCount[puv] == 0 || visibleCount[puv] > 0))
{ {
var count = visibleCount[uv]; var count = visibleCount[puv];
if (passiveVisibilityEnabled) if (passiveVisibilityEnabled)
count += passiveVisibleCount[uv]; count += passiveVisibleCount[puv];
type = count > 0 ? ShroudCellType.Visible : ShroudCellType.Fog; type = count > 0 ? ShroudCellType.Visible : ShroudCellType.Fog;
} }
var oldResolvedType = resolvedType[uv]; var oldResolvedType = resolvedType[puv];
resolvedType[uv] = type; resolvedType[puv] = type;
if (type != oldResolvedType) if (type != oldResolvedType)
OnShroudChanged((PPos)uv); OnShroudChanged(puv);
} }
Hash = Sync.HashPlayer(self.Owner) + self.World.WorldTick; Hash = Sync.HashPlayer(self.Owner) + self.World.WorldTick;
@@ -232,22 +231,21 @@ namespace OpenRA.Traits
if (!map.Contains(puv)) if (!map.Contains(puv))
continue; continue;
var uv = (MPos)puv; touched[puv] = true;
touched[uv] = true;
switch (type) switch (type)
{ {
case SourceType.PassiveVisibility: case SourceType.PassiveVisibility:
passiveVisibilityEnabled = true; passiveVisibilityEnabled = true;
passiveVisibleCount[uv]++; passiveVisibleCount[puv]++;
explored[uv] = true; explored[puv] = true;
break; break;
case SourceType.Visibility: case SourceType.Visibility:
visibleCount[uv]++; visibleCount[puv]++;
explored[uv] = true; explored[puv] = true;
break; break;
case SourceType.Shroud: case SourceType.Shroud:
shroudGenerationEnabled = true; shroudGenerationEnabled = true;
generatedShroudCount[uv]++; generatedShroudCount[puv]++;
break; break;
} }
} }
@@ -264,18 +262,17 @@ namespace OpenRA.Traits
// Cells outside the visible bounds don't increment visibleCount // Cells outside the visible bounds don't increment visibleCount
if (map.Contains(puv)) if (map.Contains(puv))
{ {
var uv = (MPos)puv; touched[puv] = true;
touched[uv] = true;
switch (state.Type) switch (state.Type)
{ {
case SourceType.PassiveVisibility: case SourceType.PassiveVisibility:
passiveVisibleCount[uv]--; passiveVisibleCount[puv]--;
break; break;
case SourceType.Visibility: case SourceType.Visibility:
visibleCount[uv]--; visibleCount[puv]--;
break; break;
case SourceType.Shroud: case SourceType.Shroud:
generatedShroudCount[uv]--; generatedShroudCount[puv]--;
break; break;
} }
} }
@@ -288,11 +285,10 @@ namespace OpenRA.Traits
{ {
foreach (var puv in cells) foreach (var puv in cells)
{ {
var uv = (MPos)puv; if (map.Contains(puv) && !explored[puv])
if (map.Contains(puv) && !explored[uv])
{ {
touched[uv] = true; touched[puv] = true;
explored[uv] = true; explored[puv] = true;
} }
} }
} }
@@ -304,11 +300,10 @@ namespace OpenRA.Traits
foreach (var puv in map.ProjectedCellBounds) foreach (var puv in map.ProjectedCellBounds)
{ {
var uv = (MPos)puv; if (!explored[puv] && s.explored[puv])
if (!explored[uv] && s.explored[uv])
{ {
touched[uv] = true; touched[puv] = true;
explored[uv] = true; explored[puv] = true;
} }
} }
} }
@@ -317,11 +312,10 @@ namespace OpenRA.Traits
{ {
foreach (var puv in map.ProjectedCellBounds) foreach (var puv in map.ProjectedCellBounds)
{ {
var uv = (MPos)puv; if (!explored[puv])
if (!explored[uv])
{ {
touched[uv] = true; touched[puv] = true;
explored[uv] = true; explored[puv] = true;
} }
} }
} }
@@ -330,9 +324,8 @@ namespace OpenRA.Traits
{ {
foreach (var puv in map.ProjectedCellBounds) foreach (var puv in map.ProjectedCellBounds)
{ {
var uv = (MPos)puv; touched[puv] = true;
touched[uv] = true; explored[puv] = (visibleCount[puv] + passiveVisibleCount[puv]) > 0;
explored[uv] = (visibleCount[uv] + passiveVisibleCount[uv]) > 0;
} }
} }
@@ -363,8 +356,7 @@ namespace OpenRA.Traits
if (Disabled) if (Disabled)
return map.Contains(puv); return map.Contains(puv);
var uv = (MPos)puv; return resolvedType.Contains(puv) && resolvedType[puv] > ShroudCellType.Shroud;
return resolvedType.Contains(uv) && resolvedType[uv] > ShroudCellType.Shroud;
} }
public bool IsVisible(WPos pos) public bool IsVisible(WPos pos)
@@ -379,9 +371,6 @@ namespace OpenRA.Traits
public bool IsVisible(MPos uv) public bool IsVisible(MPos uv)
{ {
if (!resolvedType.Contains(uv))
return false;
foreach (var puv in map.ProjectedCellsCovering(uv)) foreach (var puv in map.ProjectedCellsCovering(uv))
if (IsVisible(puv)) if (IsVisible(puv))
return true; return true;
@@ -395,15 +384,14 @@ namespace OpenRA.Traits
if (!FogEnabled) if (!FogEnabled)
return map.Contains(puv); return map.Contains(puv);
var uv = (MPos)puv; return resolvedType.Contains(puv) && resolvedType[puv] == ShroudCellType.Visible;
return resolvedType.Contains(uv) && resolvedType[uv] == ShroudCellType.Visible;
} }
public bool Contains(PPos uv) public bool Contains(PPos uv)
{ {
// Check that uv is inside the map area. There is nothing special // Check that uv is inside the map area. There is nothing special
// about explored here: any of the CellLayers would have been suitable. // about explored here: any of the CellLayers would have been suitable.
return explored.Contains((MPos)uv); return explored.Contains(uv);
} }
} }
} }