Merge pull request #8866 from Phrohdoh/feat#terrain-height-at

Implement DistanceAboveTerrain
This commit is contained in:
Paul Chote
2015-08-01 17:54:31 +01:00
9 changed files with 39 additions and 15 deletions

View File

@@ -775,6 +775,13 @@ namespace OpenRA
return CenterOfCell(cell); return CenterOfCell(cell);
} }
public WDist DistanceAboveTerrain(WPos pos)
{
var cell = CellContaining(pos);
var delta = pos - CenterOfCell(cell);
return new WDist(delta.Z);
}
public CPos CellContaining(WPos pos) public CPos CellContaining(WPos pos)
{ {
if (TileShape == TileShape.Rectangle) if (TileShape == TileShape.Rectangle)

View File

@@ -18,6 +18,25 @@ namespace OpenRA.Mods.Common
{ {
public static class ActorExts public static class ActorExts
{ {
public static bool IsAtGroundLevel(this Actor self)
{
if (self.IsDead)
return false;
if (!self.HasTrait<IPositionable>())
return false;
if (!self.IsInWorld)
return false;
var map = self.World.Map;
if (!map.Contains(self.Location))
return false;
return map.DistanceAboveTerrain(self.CenterPosition).Length == 0;
}
public static bool AppearsFriendlyTo(this Actor self, Actor toActor) public static bool AppearsFriendlyTo(this Actor self, Actor toActor)
{ {
var stance = toActor.Owner.Stances[self.Owner]; var stance = toActor.Owner.Stances[self.Owner];

View File

@@ -104,8 +104,7 @@ namespace OpenRA.Mods.Common.Graphics
public void Render(WorldRenderer wr) public void Render(WorldRenderer wr)
{ {
// TODO: This is a temporary workaround until we have a proper ramp-aware height calculation var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length);
var groundPos = wr.World.Map.CenterOfCell(wr.World.Map.CellContaining(voxel.pos));
var ts = Game.ModData.Manifest.TileSize; var ts = Game.ModData.Manifest.TileSize;
var groundZ = ts.Height * (groundPos.Z - voxel.pos.Z) / 1024f; var groundZ = ts.Height * (groundPos.Z - voxel.pos.Z) / 1024f;

View File

@@ -171,7 +171,7 @@ namespace OpenRA.Mods.Common.Traits
public bool CanLoad(Actor self, Actor a) public bool CanLoad(Actor self, Actor a)
{ {
return (reserves.Contains(a) || HasSpace(GetWeight(a))) && self.CenterPosition.Z == 0; return (reserves.Contains(a) || HasSpace(GetWeight(a))) && self.IsAtGroundLevel();
} }
internal bool ReserveSpace(Actor a) internal bool ReserveSpace(Actor a)

View File

@@ -189,11 +189,8 @@ namespace OpenRA.Mods.Common.Traits
public bool CrushableBy(string[] crushClasses, Player owner) public bool CrushableBy(string[] crushClasses, Player owner)
{ {
// Crate can only be crushed if it is not in the air or underground // Crate can only be crushed if it is not in the air.
if (CenterPosition.Z != 0) return self.IsAtGroundLevel() && crushClasses.Contains(info.CrushClass);
return false;
return crushClasses.Contains(info.CrushClass);
} }
public void AddedToWorld(Actor self) public void AddedToWorld(Actor self)

View File

@@ -65,8 +65,8 @@ namespace OpenRA.Mods.Common.Traits
public bool CrushableBy(string[] crushClasses, Player crushOwner) public bool CrushableBy(string[] crushClasses, Player crushOwner)
{ {
// Only make actor crushable if it is on the ground // Only make actor crushable if it is on the ground.
if (self.CenterPosition.Z != 0) if (!self.IsAtGroundLevel())
return false; return false;
if (!info.CrushedByFriendlies && crushOwner.IsAlliedWith(self.Owner)) if (!info.CrushedByFriendlies && crushOwner.IsAlliedWith(self.Owner))

View File

@@ -65,7 +65,8 @@ namespace OpenRA.Mods.Common.Traits
return; return;
var cp = self.CenterPosition; var cp = self.CenterPosition;
if ((cp.Z > 0 && !info.EjectInAir) || (cp.Z == 0 && !info.EjectOnGround)) var inAir = !self.IsAtGroundLevel();
if ((inAir && !info.EjectInAir) || (!inAir && !info.EjectOnGround))
return; return;
var pilot = self.World.CreateActor(false, info.PilotActor.ToLowerInvariant(), var pilot = self.World.CreateActor(false, info.PilotActor.ToLowerInvariant(),
@@ -73,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits
if (info.AllowUnsuitableCell || IsSuitableCell(self, pilot)) if (info.AllowUnsuitableCell || IsSuitableCell(self, pilot))
{ {
if (cp.Z > 0) if (inAir)
{ {
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {

View File

@@ -565,7 +565,7 @@ namespace OpenRA.Mods.Common.Traits
public void FinishedMoving(Actor self) public void FinishedMoving(Actor self)
{ {
// Only make actor crush if it is on the ground // Only make actor crush if it is on the ground
if (self.CenterPosition.Z != 0) if (!self.IsAtGroundLevel())
return; return;
var crushables = self.World.ActorMap.GetUnitsAt(ToCell).Where(a => a != self) var crushables = self.World.ActorMap.GetUnitsAt(ToCell).Where(a => a != self)

View File

@@ -39,8 +39,9 @@ namespace OpenRA.Mods.Common.Warheads
public static ImpactType GetImpactType(World world, CPos cell, WPos pos) public static ImpactType GetImpactType(World world, CPos cell, WPos pos)
{ {
var isAir = pos.Z > 0; var dat = world.Map.DistanceAboveTerrain(pos);
var isWater = pos.Z <= 0 && world.Map.GetTerrainInfo(cell).IsWater; var isAir = dat.Length > 0;
var isWater = dat.Length <= 0 && world.Map.GetTerrainInfo(cell).IsWater;
var isDirectHit = GetDirectHit(world, cell, pos); var isDirectHit = GetDirectHit(world, cell, pos);
if (isAir && !isDirectHit) if (isAir && !isDirectHit)