Convert non-aircraft positioning to world coords.

This removes the incomplete and unused hover code
on Mobile, which would be more trouble that it is
currently worth to carry over.
This commit is contained in:
Paul Chote
2013-07-21 13:42:25 +12:00
parent 29009fe3a4
commit c3f04cc32e
20 changed files with 67 additions and 96 deletions

View File

@@ -39,6 +39,7 @@ namespace OpenRA
public long LengthSquared { get { return (long)X * X + (long)Y * Y + (long)Z * Z; } }
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
public long HorizontalLengthSquared { get { return (long)X * X + (long)Y * Y; } }
public int HorizontalLength { get { return (int)Math.Sqrt(HorizontalLengthSquared); } }
public WVec Rotate(WRot rot)
{

View File

@@ -135,10 +135,11 @@ namespace OpenRA
var ios = occupySpace.Value;
if (ios != null)
{
loc -= new PVecInt(0, ios.Altitude);
var altitude = ios.CenterPosition.Z * Game.CellSize / 1024;
loc -= new PVecInt(0, altitude);
if (useAltitude)
size = new PVecInt(size.X, size.Y + ios.Altitude);
size = new PVecInt(size.X, size.Y + altitude);
}
return new Rectangle(loc.X, loc.Y, size.X, size.Y);

View File

@@ -97,15 +97,12 @@ namespace OpenRA.Traits
public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); }
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
public interface IOccupySpaceInfo { }
public interface IOccupySpace
{
WPos CenterPosition { get; }
CPos TopLeft { get; }
IEnumerable<Pair<CPos, SubCell>> OccupiedCells();
// TODO: We shouldn't expose the setter here
// This will be going away soon, so isn't a big deal
int Altitude { get; set; }
}
public static class IOccupySpaceExts

View File

@@ -13,7 +13,7 @@ using OpenRA.FileFormats;
namespace OpenRA.Traits
{
class WaypointInfo : ITraitInfo
class WaypointInfo : ITraitInfo, IOccupySpaceInfo
{
public object Create( ActorInitializer init ) { return new Waypoint( init ); }
}
@@ -28,10 +28,7 @@ namespace OpenRA.Traits
}
public CPos TopLeft { get { return location; } }
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield break; }
public WPos CenterPosition { get { return location.CenterPosition; } }
public PPos PxPosition { get { return Util.CenterOfCell(location); } }
public int Altitude { get { return 0; } set { } }
}
}

View File

@@ -55,7 +55,7 @@ namespace OpenRA.Mods.RA.Activities
if (ticks == 0 && IsCanceled)
return NextActivity;
mobile.AdjustPxPosition(self, PPos.FromWPosHackZ(WPos.LerpQuadratic(from, to, angle, ++ticks, length)));
mobile.SetVisualPosition(self, WPos.LerpQuadratic(from, to, angle, ++ticks, length));
if (ticks >= length)
{
mobile.SetLocation(mobile.toCell, mobile.toSubCell, mobile.toCell, mobile.toSubCell);

View File

@@ -20,7 +20,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Air
{
public class AircraftInfo : ITraitInfo, IFacingInfo, UsesInit<AltitudeInit>, UsesInit<LocationInit>, UsesInit<FacingInit>
public class AircraftInfo : ITraitInfo, IFacingInfo, IOccupySpaceInfo, UsesInit<AltitudeInit>, UsesInit<LocationInit>, UsesInit<FacingInit>
{
public readonly int CruiseAltitude = 30;
[ActorReference]
@@ -78,7 +78,7 @@ namespace OpenRA.Mods.RA.Air
public Actor GetActorBelow()
{
if (self.Trait<IOccupySpace>().Altitude != 0)
if (Altitude != 0)
return null; // not on the ground.
return self.World.FindActorsInBox(self.CenterPosition, self.CenterPosition)

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Mods.RA
public readonly string PilotActor = "E1";
public readonly int SuccessRate = 50;
public readonly string ChuteSound = "chute1.aud";
public readonly WRange MinimumEjectHeight = new WRange(427);
}
public class EjectOnDeath : INotifyKilled
@@ -29,14 +30,15 @@ namespace OpenRA.Mods.RA
var info = self.Info.Traits.Get<EjectOnDeathInfo>();
var pilot = self.World.CreateActor(false, info.PilotActor.ToLowerInvariant(),
new TypeDictionary { new OwnerInit(self.Owner) });
var r = self.World.SharedRandom.Next(1, 100);
var aircraft = self.Trait<IPositionable>();
if (IsSuitableCell(pilot, self.Location) && r > 100 - info.SuccessRate && aircraft.Altitude > 10
var r = self.World.SharedRandom.Next(1, 100);
var cp = self.CenterPosition;
if (IsSuitableCell(pilot, self.Location) && r > 100 - info.SuccessRate && cp.Z > info.MinimumEjectHeight.Range
&& self.Owner.WinState != WinState.Lost)
{
self.World.AddFrameEndTask(w => w.Add(new Parachute(pilot, self.CenterPosition)));
Sound.Play(info.ChuteSound, self.CenterPosition);
self.World.AddFrameEndTask(w => w.Add(new Parachute(pilot, cp)));
Sound.Play(info.ChuteSound, cp);
}
else
pilot.Destroy();

View File

@@ -120,8 +120,6 @@ namespace OpenRA.Mods.RA
return;
var barrel = Barrels[Burst % Barrels.Length];
var destios = target.IsActor ? target.Actor.TraitOrDefault<IOccupySpace>() : null;
var muzzlePosition = self.CenterPosition + MuzzleOffset(self, barrel);
var legacyMuzzlePosition = PPos.FromWPos(muzzlePosition);
var legacyMuzzleAltitude = Game.CellSize*muzzlePosition.Z/1024;
@@ -135,8 +133,8 @@ namespace OpenRA.Mods.RA
src = legacyMuzzlePosition,
srcAltitude = legacyMuzzleAltitude,
dest = target.CenterLocation,
destAltitude = destios != null ? destios.Altitude : 0,
dest = PPos.FromWPos(target.CenterPosition),
destAltitude = target.CenterPosition.Z * Game.CellSize / 1024,
facing = legacyFacing,

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Buildings
public class GivesBuildableAreaInfo : TraitInfo<GivesBuildableArea> {}
public class GivesBuildableArea {}
public class BuildingInfo : ITraitInfo, UsesInit<LocationInit>
public class BuildingInfo : ITraitInfo, IOccupySpaceInfo, UsesInit<LocationInit>
{
[Desc("If negative, it will drain power, if positive, it will provide power.")]
public readonly int Power = 0;
@@ -96,7 +96,6 @@ namespace OpenRA.Mods.RA.Buildings
[Sync] readonly CPos topLeft;
PowerManager PlayerPower;
PPos pxPosition;
[Sync] public bool Locked; /* shared activity lock: undeploy, sell, capture, etc */
@@ -110,9 +109,7 @@ namespace OpenRA.Mods.RA.Buildings
public void Unlock() { Locked = false; }
public CPos TopLeft { get { return topLeft; } }
public WPos CenterPosition { get { return PxPosition.ToWPos(0); } }
public PPos PxPosition { get { return pxPosition; } }
public int Altitude { get { return 0; } set { } }
public WPos CenterPosition { get; private set; }
public IEnumerable<string> ProvidesPrerequisites { get { yield return self.Info.Name; } }
@@ -126,8 +123,7 @@ namespace OpenRA.Mods.RA.Buildings
occupiedCells = FootprintUtils.UnpathableTiles( self.Info.Name, Info, TopLeft )
.Select(c => Pair.New(c, SubCell.FullCell)).ToArray();
var position = topLeft.CenterPosition + FootprintUtils.CenterOffset(Info);
pxPosition = PPos.FromWPosHackZ(position);
CenterPosition = topLeft.CenterPosition + FootprintUtils.CenterOffset(Info);
}
public int GetPowerUsage()

View File

@@ -17,14 +17,14 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
public class CargoInfo : ITraitInfo
public class CargoInfo : ITraitInfo, Requires<IOccupySpaceInfo>
{
public readonly int MaxWeight = 0;
public readonly int PipCount = 0;
public readonly string[] Types = { };
public readonly int UnloadFacing = 0;
public readonly string[] InitialUnits = { };
public readonly int minimalUnloadAltitude = 0;
public readonly WRange MaximumUnloadAltitude = WRange.Zero;
public object Create( ActorInitializer init ) { return new Cargo( init, this ); }
}
@@ -93,7 +93,7 @@ namespace OpenRA.Mods.RA
// Cannot unload mid-air
var ios = self.TraitOrDefault<IOccupySpace>();
if (ios != null && ios.Altitude > info.minimalUnloadAltitude)
if (ios != null && ios.CenterPosition.Z > info.MaximumUnloadAltitude.Range)
return false;
// TODO: Check if there is a free tile to unload to
@@ -106,8 +106,7 @@ namespace OpenRA.Mods.RA
return false;
// Cannot load mid-air
var ios = self.TraitOrDefault<IOccupySpace>();
return ios == null || ios.Altitude == info.minimalUnloadAltitude;
return self.CenterPosition.Z < info.MaximumUnloadAltitude.Range;
}
public string CursorForOrder(Actor self, Order order)

View File

@@ -56,12 +56,14 @@ namespace OpenRA.Mods.RA
var weapon = Rules.Weapons[info.Weapon.ToLowerInvariant()];
dropDelay = weapon.ROF;
var centerLocation = PPos.FromWPos(self.CenterPosition);
var altitude = self.CenterPosition.Z * Game.CellSize / 1024;
var args = new ProjectileArgs
{
srcAltitude = self.Trait<IOccupySpace>().Altitude,
srcAltitude = altitude,
destAltitude = 0,
src = self.CenterLocation,
dest = self.CenterLocation,
src = centerLocation,
dest = centerLocation,
facing = self.Trait<IFacing>().Facing,
firedBy = self,
weapon = weapon

View File

@@ -11,12 +11,12 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Traits;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class CrateInfo : ITraitInfo, Requires<RenderSpritesInfo>
class CrateInfo : ITraitInfo, IOccupySpaceInfo, Requires<RenderSpritesInfo>
{
public readonly int Lifetime = 5; // Seconds
public readonly string[] TerrainTypes = { };
@@ -27,23 +27,22 @@ namespace OpenRA.Mods.RA
class Crate : ITick, IPositionable, ICrushable, ISync, INotifyParachuteLanded
{
readonly Actor self;
readonly CrateInfo info;
bool collected;
[Sync] int ticks;
[Sync] public CPos Location;
CrateInfo Info;
bool collected;
public Crate(ActorInitializer init, CrateInfo info)
{
this.self = init.self;
this.info = info;
if (init.Contains<LocationInit>())
{
this.Location = init.Get<LocationInit, CPos>();
PxPosition = Util.CenterOfCell(Location);
}
this.Info = info;
SetPosition(self, init.Get<LocationInit, CPos>());
}
public void WarnCrush(Actor crusher) {}
public void WarnCrush(Actor crusher) { }
public void OnCrush(Actor crusher)
{
@@ -78,17 +77,14 @@ namespace OpenRA.Mods.RA
public void Tick(Actor self)
{
if( ++ticks >= Info.Lifetime * 25 )
if (++ticks >= info.Lifetime * 25)
self.Destroy();
}
public CPos TopLeft { get { return Location; } }
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield return Pair.New( Location, SubCell.FullCell); }
public WPos CenterPosition { get { return PxPosition.ToWPos(Altitude); } }
public PPos PxPosition { get; private set; }
public int Altitude { get { return 0; } set { } }
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield return Pair.New(Location, SubCell.FullCell); }
public WPos CenterPosition { get; private set; }
public void SetPosition(Actor self, WPos pos) { SetPosition(self, pos.ToCPos()); }
public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos.ToCPos()); }
@@ -96,7 +92,7 @@ namespace OpenRA.Mods.RA
{
if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false;
var type = self.World.GetTerrainType(cell);
if (!Info.TerrainTypes.Contains(type))
if (!info.TerrainTypes.Contains(type))
return false;
if (self.World.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(cell) != null) return false;
@@ -107,18 +103,18 @@ namespace OpenRA.Mods.RA
public void SetPosition(Actor self, CPos cell)
{
if( self.IsInWorld )
if (self.IsInWorld)
self.World.ActorMap.Remove(self, this);
Location = cell;
PxPosition = Util.CenterOfCell(cell);
CenterPosition = cell.CenterPosition;
var seq = self.World.GetTerrainInfo(cell).IsWater ? "water" : "land";
var rs = self.Trait<RenderSprites>();
if (seq != rs.anim.CurrentSequence.Name)
rs.anim.PlayRepeating(seq);
if( self.IsInWorld )
if (self.IsInWorld)
self.World.ActorMap.Add(self, this);
}

View File

@@ -97,9 +97,9 @@ namespace OpenRA.Mods.RA.Effects
// In pixels
var dist = Args.target.CenterLocation + offset - PxPosition;
var targetAltitude = 0;
if (Args.target.IsValid && Args.target.IsActor && Args.target.Actor.HasTrait<IOccupySpace>())
targetAltitude = Args.target.Actor.Trait<IOccupySpace>().Altitude;
var targetAltitude = 0;
if (Args.target.IsValid)
targetAltitude = Args.target.CenterPosition.Z * Game.CellSize / 1024;
var jammed = Info.Jammable && world.ActorsWithTrait<JamsMissiles>().Any(tp =>
(tp.Actor.CenterLocation - PxPosition).ToCVec().Length <= tp.Trait.Range

View File

@@ -16,7 +16,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class HuskInfo : ITraitInfo, IFacingInfo
class HuskInfo : ITraitInfo, IOccupySpaceInfo, IFacingInfo
{
public readonly string[] AllowedTerrain = { };
@@ -35,7 +35,6 @@ namespace OpenRA.Mods.RA
[Sync] public int Facing { get; set; }
public int ROT { get { return 0; } }
public int Altitude { get { return 0; } set { } }
public Husk(ActorInitializer init, HuskInfo info)
{

View File

@@ -17,7 +17,7 @@ using OpenRA.FileFormats;
namespace OpenRA.Mods.RA
{
class MineInfo : ITraitInfo
class MineInfo : ITraitInfo, IOccupySpaceInfo
{
public readonly string[] CrushClasses = { };
public readonly bool AvoidFriendly = true;
@@ -61,9 +61,7 @@ namespace OpenRA.Mods.RA
public CPos TopLeft { get { return location; } }
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); }
public WPos CenterPosition { get { return PxPosition.ToWPos(0); } }
public PPos PxPosition { get { return Util.CenterOfCell( location ); } }
public int Altitude { get { return 0; } set { } }
public WPos CenterPosition { get { return location.CenterPosition; } }
}
/* tag trait for stuff that shouldnt trigger mines */

View File

@@ -19,7 +19,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Move
{
[Desc("Unit is able to move.")]
public class MobileInfo : ITraitInfo, IFacingInfo, UsesInit<FacingInit>, UsesInit<LocationInit>, UsesInit<SubCellInit>
public class MobileInfo : ITraitInfo, IOccupySpaceInfo, IFacingInfo, UsesInit<FacingInit>, UsesInit<LocationInit>, UsesInit<SubCellInit>
{
[FieldLoader.LoadUsing("LoadSpeeds")]
[Desc("Set Water: 0 for ground units and lower the value on rough terrain.")]
@@ -35,7 +35,6 @@ namespace OpenRA.Mods.RA.Move
public readonly bool OnRails = false;
[Desc("Allow multiple (infantry) units in one cell.")]
public readonly bool SharesCell = false;
public readonly int Altitude;
public virtual object Create(ActorInitializer init) { return new Mobile(init, this); }
@@ -163,12 +162,9 @@ namespace OpenRA.Mods.RA.Move
set { __facing = value; }
}
[Sync] public int Altitude { get; set; }
public int ROT { get { return Info.ROT; } }
public WPos CenterPosition { get { return PxPosition.ToWPos(Altitude); } }
[Sync] public PPos PxPosition { get; private set; }
[Sync] public WPos CenterPosition { get; private set; }
[Sync] public CPos fromCell { get { return __fromCell; } }
[Sync] public CPos toCell { get { return __toCell; } }
@@ -209,7 +205,12 @@ namespace OpenRA.Mods.RA.Move
}
this.Facing = init.Contains<FacingInit>() ? init.Get<FacingInit, int>() : info.InitialFacing;
this.Altitude = init.Contains<AltitudeInit>() ? init.Get<AltitudeInit, int>() : 0;
if (init.Contains<AltitudeInit>())
{
var z = init.Get<AltitudeInit, int>() * 1024 / Game.CellSize;
SetVisualPosition(self, CenterPosition + new WVec(0, 0, z - CenterPosition.Z));
}
}
public void SetPosition(Actor self, CPos cell)
@@ -219,24 +220,17 @@ namespace OpenRA.Mods.RA.Move
FinishedMoving(self);
}
public void AdjustPxPosition(Actor self, PPos px) /* visual hack only */
{
PxPosition = px;
}
public void SetPosition(Actor self, WPos pos)
{
// TODO: Handle altitude
var cell = pos.ToCPos();
SetLocation(cell,fromSubCell, cell,fromSubCell);
PxPosition = PPos.FromWPos(pos);
SetVisualPosition(self, pos);
FinishedMoving(self);
}
public void SetVisualPosition(Actor self, WPos pos)
{
// TODO: Handle altitude
AdjustPxPosition(self, PPos.FromWPos(pos));
CenterPosition = pos;
}
public IEnumerable<IOrderTargeter> Orders { get { yield return new MoveOrderTargeter(Info); } }

View File

@@ -111,15 +111,6 @@ namespace OpenRA.Mods.RA.Move
public override Activity Tick(Actor self)
{
var mobile = self.Trait<Mobile>();
var info = self.Info.Traits.Get<MobileInfo>();
if (mobile.Altitude != info.Altitude)
{
if (mobile.Altitude < info.Altitude)
++mobile.Altitude;
return this;
}
if (destination == mobile.toCell)
return NextActivity;

View File

@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Render
public void Tick(Actor self)
{
var isFlying = self.Trait<IOccupySpace>().Altitude > 0 && !self.IsDead();
var isFlying = self.CenterPosition.Z > 0 && !self.IsDead();
if (isFlying ^ (rotorAnim.CurrentSequence.Name != "rotor"))
return;

View File

@@ -14,7 +14,6 @@ using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Mods.RA.Air;
using OpenRA.Mods.RA.Move;
namespace OpenRA.Mods.RA.Render
{
@@ -27,13 +26,14 @@ namespace OpenRA.Mods.RA.Render
var ios = self.Trait<IOccupySpace>();
/* rude hack */
var visualOffset = ((ios is Helicopter || ios is Mobile) && ios.Altitude > 0)
var flying = ios.CenterPosition.Z > 0;
var visualOffset = (ios is Helicopter && flying)
? (int)Math.Abs((self.ActorID + Game.LocalTick) / 5 % 4 - 1) - 1 : 0;
var shadowSprites = r.Select(a => a.WithPalette(wr.Palette("shadow"))
.WithPos(a.Pos - new WVec(0, 0, a.Pos.Z)).WithZOffset(a.ZOffset + a.Pos.Z));
var flyingSprites = (ios.Altitude <= 0) ? r :
var flyingSprites = !flying ? r :
r.Select(a => a.WithPos(a.Pos - new WVec(0,0,43*visualOffset)));
return shadowSprites.Concat(flyingSprites);

View File

@@ -28,7 +28,7 @@
Types: Vehicle
MaxWeight: 1
PipCount: 1
minimalUnloadAltitude: 25
MaximumUnloadAltitude: 800
LeavesHusk:
HuskActor: CARRYALL.Husk