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);
}
public WDist DistanceAboveTerrain(WPos pos)
{
var cell = CellContaining(pos);
var delta = pos - CenterOfCell(cell);
return new WDist(delta.Z);
}
public CPos CellContaining(WPos pos)
{
if (TileShape == TileShape.Rectangle)

View File

@@ -18,6 +18,25 @@ namespace OpenRA.Mods.Common
{
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)
{
var stance = toActor.Owner.Stances[self.Owner];

View File

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

View File

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

View File

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

View File

@@ -65,7 +65,8 @@ namespace OpenRA.Mods.Common.Traits
return;
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;
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 (cp.Z > 0)
if (inAir)
{
self.World.AddFrameEndTask(w =>
{

View File

@@ -565,7 +565,7 @@ namespace OpenRA.Mods.Common.Traits
public void FinishedMoving(Actor self)
{
// Only make actor crush if it is on the ground
if (self.CenterPosition.Z != 0)
if (!self.IsAtGroundLevel())
return;
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)
{
var isAir = pos.Z > 0;
var isWater = pos.Z <= 0 && world.Map.GetTerrainInfo(cell).IsWater;
var dat = world.Map.DistanceAboveTerrain(pos);
var isAir = dat.Length > 0;
var isWater = dat.Length <= 0 && world.Map.GetTerrainInfo(cell).IsWater;
var isDirectHit = GetDirectHit(world, cell, pos);
if (isAir && !isDirectHit)