Merge pull request #12370 from pchote/heightmap-shroud-reveal

Implement heightmap-visibility blocking
This commit is contained in:
reaperrr
2016-11-18 14:23:53 +01:00
committed by GitHub
12 changed files with 118 additions and 8 deletions

View File

@@ -241,6 +241,7 @@ namespace OpenRA
bool initializedCellProjection;
CellLayer<PPos[]> cellProjection;
CellLayer<List<MPos>> inverseCellProjection;
CellLayer<byte> projectedHeight;
public static string ComputeUID(IReadOnlyPackage package)
{
@@ -420,6 +421,7 @@ namespace OpenRA
cellProjection = new CellLayer<PPos[]>(this);
inverseCellProjection = new CellLayer<List<MPos>>(this);
projectedHeight = new CellLayer<byte>(this);
// Initialize collections
foreach (var cell in AllCells)
@@ -455,13 +457,54 @@ namespace OpenRA
// Remove old reverse projection
foreach (var puv in cellProjection[uv])
inverseCellProjection[(MPos)puv].Remove(uv);
{
var temp = (MPos)puv;
inverseCellProjection[temp].Remove(uv);
projectedHeight[temp] = ProjectedCellHeightInner(puv);
}
var projected = ProjectCellInner(uv);
cellProjection[uv] = projected;
foreach (var puv in projected)
inverseCellProjection[(MPos)puv].Add(uv);
{
var temp = (MPos)puv;
inverseCellProjection[temp].Add(uv);
var height = ProjectedCellHeightInner(puv);
projectedHeight[temp] = height;
// Propagate height up cliff faces
while (true)
{
temp = new MPos(temp.U, temp.V - 1);
if (!inverseCellProjection.Contains(temp) || inverseCellProjection[temp].Any())
break;
projectedHeight[temp] = height;
}
}
}
byte ProjectedCellHeightInner(PPos puv)
{
while (inverseCellProjection.Contains((MPos)puv))
{
var inverse = inverseCellProjection[(MPos)puv];
if (inverse.Any())
{
// The original games treat the top of cliffs the same way as the bottom
// This information isn't stored in the map data, so query the offset from the tileset
var temp = inverse.MaxBy(uv => uv.V);
var terrain = Tiles[temp];
return (byte)(Height[temp] - Rules.TileSet.Templates[terrain.Type][terrain.Index].Height);
}
// Try the next cell down if this is a cliff face
puv = new PPos(puv.U, puv.V + 1);
}
return 0;
}
PPos[] ProjectCellInner(MPos uv)
@@ -786,6 +829,11 @@ namespace OpenRA
return inverseCellProjection[uv];
}
public byte ProjectedHeight(PPos puv)
{
return projectedHeight[(MPos)puv];
}
public int FacingBetween(CPos cell, CPos towards, int fallbackfacing)
{
var delta = CenterOfCell(towards) - CenterOfCell(cell);

View File

@@ -115,7 +115,7 @@ namespace OpenRA.Traits
Hash += 1;
}
public static IEnumerable<PPos> ProjectedCellsInRange(Map map, WPos pos, WDist range)
public static IEnumerable<PPos> ProjectedCellsInRange(Map map, WPos pos, WDist range, int maxHeightDelta = -1)
{
// Account for potential extra half-cell from odd-height terrain
var r = (range.Length + 1023 + 512) / 1024;
@@ -124,15 +124,22 @@ namespace OpenRA.Traits
// Project actor position into the shroud plane
var projectedPos = pos - new WVec(0, pos.Z, pos.Z);
var projectedCell = map.CellContaining(projectedPos);
var projectedHeight = pos.Z / 512;
foreach (var c in map.FindTilesInCircle(projectedCell, r, true))
{
if ((map.CenterOfCell(c) - projectedPos).HorizontalLengthSquared <= limit)
yield return (PPos)c.ToMPos(map);
{
var puv = (PPos)c.ToMPos(map);
if (maxHeightDelta < 0 || map.ProjectedHeight(puv) < projectedHeight + maxHeightDelta)
yield return puv;
}
}
}
public static IEnumerable<PPos> ProjectedCellsInRange(Map map, CPos cell, WDist range)
public static IEnumerable<PPos> ProjectedCellsInRange(Map map, CPos cell, WDist range, int maxHeightDelta = -1)
{
return ProjectedCellsInRange(map, map.CenterOfCell(cell), range);
return ProjectedCellsInRange(map, map.CenterOfCell(cell), range, maxHeightDelta);
}
public void AddProjectedVisibility(object key, PPos[] visible)

View File

@@ -18,6 +18,9 @@ namespace OpenRA.Mods.Common.Traits
{
public readonly WDist Range = WDist.Zero;
[Desc("If >= 0, prevent cells that are this much higher than the actor from being revealed.")]
public readonly int MaxHeightDelta = -1;
[Desc("Possible values are CenterPosition (measure range from the center) and ",
"Footprint (measure range from the footprint)")]
public readonly VisibilityType Type = VisibilityType.Footprint;
@@ -47,10 +50,10 @@ namespace OpenRA.Mods.Common.Traits
if (Info.Type == VisibilityType.Footprint)
return self.OccupiesSpace.OccupiedCells()
.SelectMany(kv => Shroud.ProjectedCellsInRange(map, kv.First, range))
.SelectMany(kv => Shroud.ProjectedCellsInRange(map, kv.First, range, Info.MaxHeightDelta))
.Distinct().ToArray();
return Shroud.ProjectedCellsInRange(map, self.CenterPosition, range)
return Shroud.ProjectedCellsInRange(map, self.CenterPosition, range, Info.MaxHeightDelta)
.ToArray();
}

View File

@@ -1240,6 +1240,7 @@ GASPOT:
HP: 400
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
WithIdleOverlay@LIGHTS:
Sequence: idle-lights
SelectionDecorations:
@@ -1261,6 +1262,7 @@ GALITE:
Type: Wood
RevealsShroud:
Range: 2c0
MaxHeightDelta: 3
Power:
Amount: 0
# TODO: should use terrain lighting instead, depends on https://github.com/OpenRA/OpenRA/issues/3605
@@ -1298,6 +1300,7 @@ GAICBM:
Type: Wood
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Transforms:
IntoActor: icbm
Offset: 1,1

View File

@@ -14,6 +14,7 @@
Type: Heavy
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
Turreted:
TurnSpeed: 3
Armament@PRIMARY:
@@ -48,6 +49,7 @@
Speed: 56
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
TRUCKA:
Inherits: ^TRUCK
@@ -70,6 +72,7 @@ ICBM:
TurnSpeed: 5
RevealsShroud:
Range: 7c0
MaxHeightDelta: 3
Transforms:
IntoActor: gaicbm
Offset: -1,-1
@@ -93,6 +96,7 @@ BUS:
Type: Light
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Cargo:
Types: Infantry
MaxWeight: 20
@@ -116,6 +120,7 @@ PICK:
Type: Light
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Cargo:
Types: Infantry
MaxWeight: 2
@@ -139,6 +144,7 @@ CAR:
Type: Light
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Cargo:
Types: Infantry
MaxWeight: 4
@@ -162,6 +168,7 @@ WINI:
Type: Light
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Cargo:
Types: Infantry
MaxWeight: 5

View File

@@ -157,6 +157,7 @@
Type: Wood
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
Tooltip:
RenderSprites:
Palette: terraindecoration
@@ -254,6 +255,7 @@
Cost: 10
RevealsShroud:
Range: 2c0
MaxHeightDelta: 3
Mobile:
Voice: Move
Speed: 71
@@ -794,6 +796,7 @@
Type: Light
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Selectable:
Bounds: 40,24
WithTextControlGroupDecoration:

View File

@@ -20,6 +20,7 @@ GAPOWR:
Type: Wood
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
WithIdleOverlay@LIGHTS:
Sequence: idle-lights
WithIdleOverlay@PLUG:
@@ -87,6 +88,7 @@ GAPILE:
Type: Wood
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
RallyPoint:
Offset: 2,3
Palette: mouse
@@ -141,6 +143,7 @@ GAWEAP:
HP: 1000
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
Armor:
Type: Heavy
RallyPoint:
@@ -199,6 +202,7 @@ GAHPAD:
HP: 600
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Exit@1:
SpawnOffset: 0,-256,0
ExitsDebugOverlay:
@@ -255,6 +259,7 @@ GADEPT:
HP: 1100
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Reservable:
RepairsUnits:
PlayerExperience: 15
@@ -319,6 +324,7 @@ GARADR:
RenderDetectionCircle:
RevealsShroud:
Range: 10c0
MaxHeightDelta: 3
WithIdleOverlay@DISH:
Sequence: idle-dish
PauseOnLowPower: yes
@@ -354,6 +360,7 @@ GATECH:
Type: Wood
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
WithIdleOverlay@LIGHTS:
Sequence: idle-lights
Power:
@@ -396,6 +403,7 @@ GAPLUG:
Type: Wood
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
IonCannonPower:
Cursor: ioncannon
UpgradeTypes: plug.ioncannon

View File

@@ -20,6 +20,7 @@ APC:
Type: Heavy
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Turreted:
TurnSpeed: 10
Cargo:
@@ -76,6 +77,7 @@ HVR:
Type: Wood
RevealsShroud:
Range: 7c0
MaxHeightDelta: 3
Armament:
Weapon: HoverMissile
LocalOffset: 0,171,384, 0,-171,384
@@ -118,6 +120,7 @@ SMECH:
Type: Light
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
AttackFrontal:
Voice: Attack
AutoTarget:
@@ -160,6 +163,7 @@ MMCH:
Type: Heavy
RevealsShroud:
Range: 8c0
MaxHeightDelta: 3
BodyOrientation:
QuantizedFacings: 32
UseClassicPerspectiveFudge: False
@@ -209,6 +213,7 @@ HMEC:
Type: Heavy
RevealsShroud:
Range: 8c0
MaxHeightDelta: 3
AttackFrontal:
Voice: Attack
AutoTarget:
@@ -249,6 +254,7 @@ SONIC:
Type: Heavy
RevealsShroud:
Range: 7c0
MaxHeightDelta: 3
Armament:
Weapon: SonicZap
LocalOffset: -50,0,410

View File

@@ -22,6 +22,7 @@ NAPOWR:
Type: Wood
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
WithIdleOverlay@LIGHTS:
Sequence: idle-lights
Power:
@@ -60,6 +61,7 @@ NAAPWR:
Type: Wood
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
WithIdleOverlay@LIGHTS:
Sequence: idle-lights
Power:
@@ -98,6 +100,7 @@ NAHAND:
Type: Wood
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Exit@1:
SpawnOffset: 384,768,0
ExitCell: 3,2
@@ -152,6 +155,7 @@ NAWEAP:
Type: Heavy
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
RallyPoint:
Offset: 4,1
Palette: mouse
@@ -204,6 +208,7 @@ NAHPAD:
HP: 600
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Exit@1:
SpawnOffset: 0,-256,0
ExitsDebugOverlay:
@@ -274,6 +279,7 @@ NARADR:
RenderDetectionCircle:
RevealsShroud:
Range: 10c0
MaxHeightDelta: 3
WithIdleOverlay@DISH:
Sequence: idle-dish
PauseOnLowPower: true
@@ -309,6 +315,7 @@ NATECH:
Type: Wood
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
WithIdleOverlay@LIGHTS:
Sequence: idle-lights
Power:
@@ -341,6 +348,7 @@ NATMPL:
Type: Wood
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
Power:
Amount: -200
WithIdleOverlay@LIGHTS:
@@ -377,6 +385,7 @@ NASTLH:
Type: Wood
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
WithIdleOverlay@pulse:
Sequence: pulse
PauseOnLowPower: true
@@ -422,6 +431,7 @@ NAWAST:
HP: 400
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
TiberianSunRefinery:
DockAngle: 160
DockOffset: 2,1

View File

@@ -18,6 +18,7 @@ BGGY:
Type: Light
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
Armament:
Weapon: RaiderCannon
LocalOffset: 0,-43,384, 0,43,384
@@ -51,6 +52,7 @@ BIKE:
Type: Wood
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Armament@PRIMARY:
Weapon: BikeMissile
UpgradeTypes: eliteweapon
@@ -109,6 +111,7 @@ TTNK:
WithMuzzleOverlay:
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
RenderSprites:
Image: ttnk
DeployToUpgrade:
@@ -192,6 +195,7 @@ ART2:
TurnSpeed: 2
RevealsShroud:
Range: 9c0
MaxHeightDelta: 3
RenderVoxels:
LightAmbientColor: 0.4, 0.4, 0.4
Transforms:
@@ -219,6 +223,7 @@ REPAIR:
TurnSpeed: 5
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Armament:
Weapon: Repair
Cursor: repair
@@ -262,6 +267,7 @@ WEED:
Type: Heavy
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
-WithVoxelBody:
WithVoxelUnloadBody:
-GainsExperience:
@@ -289,6 +295,7 @@ SAPC:
Type: Heavy
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Cargo:
Types: Infantry
MaxWeight: 5
@@ -318,6 +325,7 @@ SUBTANK:
Type: Light
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Armament:
Weapon: FireballLauncher
AttackFrontal:
@@ -345,6 +353,7 @@ STNK:
Type: Light
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Cloak:
InitialDelay: 90
CloakDelay: 90

View File

@@ -15,6 +15,7 @@ GACNST:
Type: Wood
RevealsShroud:
Range: 5c0
MaxHeightDelta: 3
Production:
Produces: Building,Defense
Valued:
@@ -73,6 +74,7 @@ PROC:
HP: 900
RevealsShroud:
Range: 6c0
MaxHeightDelta: 3
TiberianSunRefinery:
DockAngle: 160
DockOffset: 2,1
@@ -129,6 +131,7 @@ GASILO:
Type: Wood
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
RenderSprites:
Image: gasilo.gdi
FactionImages:

View File

@@ -19,6 +19,7 @@ MCV:
Speed: 85
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
MustBeDestroyed:
RequiredForShortGame: true
BaseBuilding:
@@ -82,6 +83,7 @@ HARV:
Type: Heavy
RevealsShroud:
Range: 4c0
MaxHeightDelta: 3
-GainsExperience:
-WithVoxelBody:
WithVoxelUnloadBody:
@@ -129,6 +131,7 @@ LPST:
TurnSpeed: 5
RevealsShroud:
Range: 7c0
MaxHeightDelta: 3
RenderSprites:
Image: lpst.gdi
FactionImages: