Add a ProjectedCellLayer and use it in Shroud.cs
This commit is contained in:
50
OpenRA.Game/Map/ProjectedCellLayer.cs
Normal file
50
OpenRA.Game/Map/ProjectedCellLayer.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user