Add Map.DistanceAboveTerrain(WPos) and Actor.IsAtGroundLevel() extension method
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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 =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user