Rewrite Aircraft movement using world coords.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -19,10 +19,10 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
public class AircraftInfo : ITraitInfo, IFacingInfo, IOccupySpaceInfo, UsesInit<AltitudeInit>, UsesInit<LocationInit>, UsesInit<FacingInit>
|
||||
{
|
||||
public readonly int CruiseAltitude = 30;
|
||||
|
||||
[ActorReference]
|
||||
public readonly string[] RepairBuildings = { "fix" };
|
||||
[ActorReference]
|
||||
@@ -32,57 +32,47 @@ namespace OpenRA.Mods.RA.Air
|
||||
public readonly int Speed = 1;
|
||||
public readonly string[] LandableTerrainTypes = { };
|
||||
|
||||
public virtual object Create( ActorInitializer init ) { return new Aircraft( init , this ); }
|
||||
public virtual object Create(ActorInitializer init) { return new Aircraft(init, this); }
|
||||
public int GetInitialFacing() { return InitialFacing; }
|
||||
}
|
||||
|
||||
public class Aircraft : IFacing, IPositionable, ISync, INotifyKilled, IIssueOrder, IOrderVoice
|
||||
{
|
||||
public IDisposable reservation;
|
||||
static readonly Pair<CPos, SubCell>[] NoCells = new Pair<CPos, SubCell>[] { };
|
||||
|
||||
public void UnReserve()
|
||||
{
|
||||
if (reservation != null)
|
||||
{
|
||||
reservation.Dispose();
|
||||
reservation = null;
|
||||
}
|
||||
}
|
||||
readonly AircraftInfo info;
|
||||
readonly Actor self;
|
||||
|
||||
public void Killed(Actor self, AttackInfo e)
|
||||
{
|
||||
UnReserve();
|
||||
}
|
||||
|
||||
protected readonly Actor self;
|
||||
[Sync] public int Facing { get; set; }
|
||||
[Sync] public int Altitude { get; set; }
|
||||
[Sync] public PSubPos SubPxPosition;
|
||||
[Sync] public WPos CenterPosition { get; private set; }
|
||||
public CPos TopLeft { get { return CenterPosition.ToCPos(); } }
|
||||
public IDisposable Reservation;
|
||||
public int ROT { get { return info.ROT; } }
|
||||
|
||||
public WPos CenterPosition { get { return PxPosition.ToWPos(Altitude); } }
|
||||
public PPos PxPosition { get { return SubPxPosition.ToPPos(); } }
|
||||
public CPos TopLeft { get { return PxPosition.ToCPos(); } }
|
||||
|
||||
readonly AircraftInfo Info;
|
||||
|
||||
public Aircraft(ActorInitializer init , AircraftInfo info)
|
||||
public Aircraft(ActorInitializer init, AircraftInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.self = init.self;
|
||||
if( init.Contains<LocationInit>() )
|
||||
this.SubPxPosition = Util.CenterOfCell( init.Get<LocationInit, CPos>() ).ToPSubPos();
|
||||
|
||||
this.Facing = init.Contains<FacingInit>() ? init.Get<FacingInit,int>() : info.InitialFacing;
|
||||
this.Altitude = init.Contains<AltitudeInit>() ? init.Get<AltitudeInit,int>() : 0;
|
||||
Info = info;
|
||||
if (init.Contains<LocationInit>())
|
||||
SetPosition(self, init.Get<LocationInit, CPos>());
|
||||
|
||||
this.Facing = init.Contains<FacingInit>() ? init.Get<FacingInit, int>() : info.InitialFacing;
|
||||
|
||||
if (init.Contains<AltitudeInit>())
|
||||
{
|
||||
var z = init.Get<AltitudeInit, int>() * 1024 / Game.CellSize;
|
||||
SetPosition(self, CenterPosition + new WVec(0, 0, z - CenterPosition.Z));
|
||||
}
|
||||
}
|
||||
|
||||
public Actor GetActorBelow()
|
||||
{
|
||||
if (Altitude != 0)
|
||||
if (self.CenterPosition.Z != 0)
|
||||
return null; // not on the ground.
|
||||
|
||||
return self.World.FindActorsInBox(self.CenterPosition, self.CenterPosition)
|
||||
.FirstOrDefault( a => a.HasTrait<Reservable>() );
|
||||
.FirstOrDefault(a => a.HasTrait<Reservable>());
|
||||
}
|
||||
|
||||
protected void ReserveSpawnBuilding()
|
||||
@@ -94,29 +84,39 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
var res = afld.Trait<Reservable>();
|
||||
if (res != null)
|
||||
reservation = res.Reserve(afld, self, this);
|
||||
Reservation = res.Reserve(afld, self, this);
|
||||
}
|
||||
|
||||
public int ROT { get { return Info.ROT; } }
|
||||
public void UnReserve()
|
||||
{
|
||||
if (Reservation != null)
|
||||
{
|
||||
Reservation.Dispose();
|
||||
Reservation = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Killed(Actor self, AttackInfo e)
|
||||
{
|
||||
UnReserve();
|
||||
}
|
||||
|
||||
public void SetPosition(Actor self, CPos cell)
|
||||
{
|
||||
SubPxPosition = Util.CenterOfCell(cell).ToPSubPos();
|
||||
}
|
||||
|
||||
public void SetPosition(Actor self, WPos pos)
|
||||
{
|
||||
// TODO: Handle altitude
|
||||
SubPxPosition = PPos.FromWPos(pos).ToPSubPos();
|
||||
// Changes position, but not altitude
|
||||
CenterPosition = cell.CenterPosition + new WVec(0, 0, CenterPosition.Z);
|
||||
}
|
||||
|
||||
public void SetPosition(Actor self, WPos pos) { CenterPosition = pos; }
|
||||
public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos); }
|
||||
|
||||
public bool AircraftCanEnter(Actor a)
|
||||
{
|
||||
if (self.AppearsHostileTo(a)) return false;
|
||||
return Info.RearmBuildings.Contains(a.Info.Name)
|
||||
|| Info.RepairBuildings.Contains(a.Info.Name);
|
||||
if (self.AppearsHostileTo(a))
|
||||
return false;
|
||||
|
||||
return info.RearmBuildings.Contains(a.Info.Name)
|
||||
|| info.RepairBuildings.Contains(a.Info.Name);
|
||||
}
|
||||
|
||||
public bool CanEnterCell(CPos location) { return true; }
|
||||
@@ -125,20 +125,20 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
get
|
||||
{
|
||||
decimal ret = Info.Speed;
|
||||
decimal ret = info.Speed;
|
||||
foreach (var t in self.TraitsImplementing<ISpeedModifier>())
|
||||
ret *= t.GetSpeedModifier();
|
||||
return (int)ret;
|
||||
}
|
||||
}
|
||||
|
||||
Pair<CPos, SubCell>[] noCells = new Pair<CPos, SubCell>[] { };
|
||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return noCells; }
|
||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return NoCells; }
|
||||
|
||||
public void TickMove(int speed, int facing)
|
||||
public WVec FlyStep(int facing)
|
||||
{
|
||||
var rawspeed = speed * 7 / (32 * PSubPos.PerPx);
|
||||
SubPxPosition += rawspeed * -Util.SubPxVector[facing];
|
||||
var speed = MovementSpeed * 7 * 1024 / (Game.CellSize * 32);
|
||||
var dir = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(facing));
|
||||
return speed * dir / 1024;
|
||||
}
|
||||
|
||||
public bool CanLand(CPos cell)
|
||||
@@ -150,15 +150,15 @@ namespace OpenRA.Mods.RA.Air
|
||||
return false;
|
||||
|
||||
var type = self.World.GetTerrainType(cell);
|
||||
return Info.LandableTerrainTypes.Contains(type);
|
||||
return info.LandableTerrainTypes.Contains(type);
|
||||
}
|
||||
|
||||
public IEnumerable<Activity> GetResupplyActivities(Actor a)
|
||||
{
|
||||
var name = a.Info.Name;
|
||||
if (Info.RearmBuildings.Contains(name))
|
||||
if (info.RearmBuildings.Contains(name))
|
||||
yield return new Rearm(self);
|
||||
if (Info.RepairBuildings.Contains(name))
|
||||
if (info.RepairBuildings.Contains(name))
|
||||
yield return new Repair(a);
|
||||
}
|
||||
|
||||
@@ -228,6 +228,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
cursor = self.World.Map.IsInMap(location) ? "move" : "move-blocked";
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsQueued { get; protected set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -24,14 +24,13 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove)
|
||||
{
|
||||
return new FlyAttack( newTarget );
|
||||
return new FlyAttack(newTarget);
|
||||
}
|
||||
|
||||
protected override bool CanAttack(Actor self, Target target)
|
||||
{
|
||||
// dont fire while landed
|
||||
return base.CanAttack(self, target)
|
||||
&& self.Trait<Aircraft>().Altitude > 0;
|
||||
return base.CanAttack(self, target) && self.CenterPosition.Z > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -19,6 +19,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
public readonly bool Spins = true;
|
||||
public readonly bool Moves = false;
|
||||
public readonly WRange Velocity = new WRange(43);
|
||||
|
||||
public object Create(ActorInitializer init) { return new FallsToEarth(init.self, this); }
|
||||
}
|
||||
@@ -47,7 +48,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
if (aircraft.Altitude <= 0)
|
||||
if (self.CenterPosition.Z <= 0)
|
||||
{
|
||||
if (info.Explosion != null)
|
||||
Combat.DoExplosion(self, info.Explosion, self.CenterPosition);
|
||||
@@ -62,15 +63,14 @@ namespace OpenRA.Mods.RA.Air
|
||||
aircraft.Facing = (aircraft.Facing + spin) % 256;
|
||||
}
|
||||
|
||||
if (info.Moves)
|
||||
FlyUtil.Fly(self, aircraft.Altitude);
|
||||
|
||||
aircraft.Altitude--;
|
||||
var move = info.Moves ? aircraft.FlyStep(aircraft.Facing) : WVec.Zero;
|
||||
move -= new WVec(WRange.Zero, WRange.Zero, info.Velocity);
|
||||
aircraft.SetPosition(self, aircraft.CenterPosition + move);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Cannot be cancelled
|
||||
public override void Cancel( Actor self ) { }
|
||||
public override void Cancel(Actor self) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -20,6 +20,23 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
Fly(WPos pos) { this.pos = pos; }
|
||||
|
||||
public static void FlyToward(Actor self, Plane plane, int desiredFacing, WRange desiredAltitude)
|
||||
{
|
||||
var move = plane.FlyStep(plane.Facing);
|
||||
var altitude = plane.CenterPosition.Z;
|
||||
|
||||
plane.Facing = Util.TickFacing(plane.Facing, desiredFacing, plane.ROT);
|
||||
|
||||
if (altitude != desiredAltitude.Range)
|
||||
{
|
||||
var delta = move.HorizontalLength * plane.Info.MaximumPitch.Tan() / 1024;
|
||||
var dz = (desiredAltitude.Range - altitude).Clamp(-delta, delta);
|
||||
move += new WVec(0, 0, dz);
|
||||
}
|
||||
|
||||
plane.SetPosition(self, plane.CenterPosition + move);
|
||||
}
|
||||
|
||||
public static Fly ToPos(WPos pos) { return new Fly(pos); }
|
||||
public static Fly ToCell(CPos pos) { return new Fly(pos.CenterPosition); }
|
||||
|
||||
@@ -33,16 +50,16 @@ namespace OpenRA.Mods.RA.Air
|
||||
if (d.HorizontalLengthSquared < 91022)
|
||||
return NextActivity;
|
||||
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
var cruiseAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
var desiredFacing = Util.GetFacing(d, aircraft.Facing);
|
||||
if (aircraft.Altitude == cruiseAltitude)
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
var plane = self.Trait<Plane>();
|
||||
var desiredFacing = Util.GetFacing(d, plane.Facing);
|
||||
var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize);
|
||||
|
||||
if (aircraft.Altitude < cruiseAltitude)
|
||||
++aircraft.Altitude;
|
||||
// Don't turn until we've reached the cruise altitude
|
||||
if (plane.CenterPosition.Z < cruiseAltitude.Range)
|
||||
desiredFacing = plane.Facing;
|
||||
|
||||
FlyToward(self, plane, desiredFacing, cruiseAltitude);
|
||||
|
||||
FlyUtil.Fly(self, cruiseAltitude);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -51,14 +68,4 @@ namespace OpenRA.Mods.RA.Air
|
||||
yield return Target.FromPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FlyUtil
|
||||
{
|
||||
public static void Fly(Actor self, int desiredAltitude)
|
||||
{
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
aircraft.TickMove(PSubPos.PerPx * aircraft.MovementSpeed, aircraft.Facing);
|
||||
aircraft.Altitude += Math.Sign(desiredAltitude - aircraft.Altitude);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -17,20 +17,16 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
var cruiseAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
if (IsCanceled)
|
||||
return NextActivity;
|
||||
|
||||
if (IsCanceled) return NextActivity;
|
||||
var plane = self.Trait<Plane>();
|
||||
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
// We can't possibly turn this fast
|
||||
var desiredFacing = plane.Facing + 64;
|
||||
var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize);
|
||||
Fly.FlyToward(self, plane, desiredFacing, cruiseAltitude);
|
||||
|
||||
var desiredFacing = aircraft.Facing + 64; // we can't possibly turn this fast.
|
||||
if (aircraft.Altitude == cruiseAltitude)
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
|
||||
if (aircraft.Altitude < cruiseAltitude)
|
||||
++aircraft.Altitude;
|
||||
|
||||
FlyUtil.Fly(self, cruiseAltitude);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -20,10 +20,13 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if( IsCanceled ) return NextActivity;
|
||||
var targetAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
if (remainingTicks-- == 0) return NextActivity;
|
||||
FlyUtil.Fly(self, targetAltitude);
|
||||
if (IsCanceled || remainingTicks-- == 0)
|
||||
return NextActivity;
|
||||
|
||||
var plane = self.Trait<Plane>();
|
||||
var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize);
|
||||
Fly.FlyToward(self, plane, plane.Facing, cruiseAltitude);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -32,15 +35,16 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
var targetAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
if (IsCanceled || !self.World.Map.IsInMap(self.Location))
|
||||
return NextActivity;
|
||||
|
||||
FlyUtil.Fly(self, targetAltitude);
|
||||
var plane = self.Trait<Plane>();
|
||||
var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize);
|
||||
Fly.FlyToward(self, plane, plane.Facing, cruiseAltitude);
|
||||
return this;
|
||||
}
|
||||
|
||||
public override void Cancel( Actor self )
|
||||
public override void Cancel(Actor self)
|
||||
{
|
||||
base.Cancel(self);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -17,36 +17,35 @@ namespace OpenRA.Mods.RA.Air
|
||||
public class HeliAttack : Activity
|
||||
{
|
||||
Target target;
|
||||
public HeliAttack( Target target ) { this.target = target; }
|
||||
public HeliAttack(Target target) { this.target = target; }
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if (IsCanceled) return NextActivity;
|
||||
if (!target.IsValid) return NextActivity;
|
||||
if (IsCanceled || !target.IsValid)
|
||||
return NextActivity;
|
||||
|
||||
var limitedAmmo = self.TraitOrDefault<LimitedAmmo>();
|
||||
var reloads = self.TraitOrDefault<Reloads>();
|
||||
if (limitedAmmo != null && !limitedAmmo.HasAmmo() && reloads == null)
|
||||
return Util.SequenceActivities( new HeliReturn(), NextActivity );
|
||||
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
var info = self.Info.Traits.Get<HelicopterInfo>();
|
||||
if (aircraft.Altitude != info.CruiseAltitude)
|
||||
{
|
||||
aircraft.Altitude += Math.Sign(info.CruiseAltitude - aircraft.Altitude);
|
||||
return this;
|
||||
}
|
||||
return Util.SequenceActivities(new HeliReturn(), NextActivity);
|
||||
|
||||
var helicopter = self.Trait<Helicopter>();
|
||||
var attack = self.Trait<AttackHeli>();
|
||||
var dist = target.CenterPosition - self.CenterPosition;
|
||||
|
||||
var desiredFacing = Util.GetFacing(dist, aircraft.Facing);
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
// Can rotate facing while ascending
|
||||
var desiredFacing = Util.GetFacing(dist, helicopter.Facing);
|
||||
helicopter.Facing = Util.TickFacing(helicopter.Facing, desiredFacing, helicopter.ROT);
|
||||
|
||||
var cruiseAltitude = new WRange(helicopter.Info.CruiseAltitude * 1024 / Game.CellSize);
|
||||
if (HeliFly.AdjustAltitude(self, helicopter, cruiseAltitude))
|
||||
return this;
|
||||
|
||||
// Fly towards the target
|
||||
if (!target.IsInRange(self.CenterPosition, attack.GetMaximumRange()))
|
||||
aircraft.TickMove(PSubPos.PerPx * aircraft.MovementSpeed, desiredFacing);
|
||||
helicopter.SetPosition(self, helicopter.CenterPosition + helicopter.FlyStep(desiredFacing));
|
||||
|
||||
attack.DoAttack( self, target );
|
||||
attack.DoAttack(self, target);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -17,35 +17,48 @@ namespace OpenRA.Mods.RA.Air
|
||||
class HeliFly : Activity
|
||||
{
|
||||
readonly WPos pos;
|
||||
|
||||
public HeliFly(WPos pos) { this.pos = pos; }
|
||||
public HeliFly(CPos pos) { this.pos = pos.CenterPosition; }
|
||||
|
||||
public static bool AdjustAltitude(Actor self, Helicopter helicopter, WRange targetAltitude)
|
||||
{
|
||||
var altitude = helicopter.CenterPosition.Z;
|
||||
if (altitude == targetAltitude.Range)
|
||||
return false;
|
||||
|
||||
var delta = helicopter.Info.AltitudeVelocity.Range;
|
||||
var dz = (targetAltitude.Range - altitude).Clamp(-delta, delta);
|
||||
helicopter.SetPosition(self, helicopter.CenterPosition + new WVec(0, 0, dz));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if (IsCanceled)
|
||||
return NextActivity;
|
||||
|
||||
var info = self.Info.Traits.Get<HelicopterInfo>();
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
var helicopter = self.Trait<Helicopter>();
|
||||
|
||||
if (aircraft.Altitude != info.CruiseAltitude)
|
||||
{
|
||||
aircraft.Altitude += Math.Sign(info.CruiseAltitude - aircraft.Altitude);
|
||||
var cruiseAltitude = new WRange(helicopter.Info.CruiseAltitude * 1024 / Game.CellSize);
|
||||
if (HeliFly.AdjustAltitude(self, helicopter, cruiseAltitude))
|
||||
return this;
|
||||
}
|
||||
|
||||
// Rotate towards the target
|
||||
var dist = pos - self.CenterPosition;
|
||||
var desiredFacing = Util.GetFacing(dist, helicopter.Facing);
|
||||
helicopter.Facing = Util.TickFacing(helicopter.Facing, desiredFacing, helicopter.ROT);
|
||||
|
||||
// The next move would overshoot, so just set the final position
|
||||
var dist = pos - self.CenterPosition;
|
||||
var moveDist = aircraft.MovementSpeed * 7 * 1024 / (Game.CellSize * 32);
|
||||
if (dist.HorizontalLengthSquared < moveDist*moveDist)
|
||||
var move = helicopter.FlyStep(desiredFacing);
|
||||
if (dist.HorizontalLengthSquared < move.HorizontalLengthSquared)
|
||||
{
|
||||
aircraft.SetPosition(self, pos);
|
||||
helicopter.SetPosition(self, pos + new WVec(0, 0, cruiseAltitude.Range - pos.Z));
|
||||
return NextActivity;
|
||||
}
|
||||
|
||||
var desiredFacing = Util.GetFacing(dist, aircraft.Facing);
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
aircraft.TickMove(PSubPos.PerPx * aircraft.MovementSpeed, desiredFacing);
|
||||
helicopter.SetPosition(self, helicopter.CenterPosition + move);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -14,27 +14,27 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
class HeliLand : Activity
|
||||
{
|
||||
public HeliLand(bool requireSpace, int minimalAltitude)
|
||||
bool requireSpace;
|
||||
|
||||
public HeliLand(bool requireSpace)
|
||||
{
|
||||
this.requireSpace = requireSpace;
|
||||
this.minimalAltitude = minimalAltitude;
|
||||
}
|
||||
|
||||
bool requireSpace;
|
||||
int minimalAltitude = 0;
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if (IsCanceled) return NextActivity;
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
if (aircraft.Altitude == minimalAltitude)
|
||||
if (IsCanceled)
|
||||
return NextActivity;
|
||||
|
||||
if (requireSpace && !aircraft.CanLand(self.Location))
|
||||
var helicopter = self.Trait<Helicopter>();
|
||||
|
||||
if (requireSpace && !helicopter.CanLand(self.Location))
|
||||
return this;
|
||||
|
||||
--aircraft.Altitude;
|
||||
return this;
|
||||
if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.LandAltitude))
|
||||
return this;
|
||||
|
||||
return NextActivity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -9,8 +9,8 @@
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
@@ -19,16 +19,16 @@ namespace OpenRA.Mods.RA.Air
|
||||
static Actor ChooseHelipad(Actor self)
|
||||
{
|
||||
var rearmBuildings = self.Info.Traits.Get<HelicopterInfo>().RearmBuildings;
|
||||
return self.World.Actors.Where( a => a.Owner == self.Owner ).FirstOrDefault(
|
||||
a => rearmBuildings.Contains(a.Info.Name) &&
|
||||
!Reservable.IsReserved(a));
|
||||
return self.World.Actors.Where(a => a.Owner == self.Owner).FirstOrDefault(
|
||||
a => rearmBuildings.Contains(a.Info.Name) && !Reservable.IsReserved(a));
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if (IsCanceled) return NextActivity;
|
||||
var dest = ChooseHelipad(self);
|
||||
if (IsCanceled)
|
||||
return NextActivity;
|
||||
|
||||
var dest = ChooseHelipad(self);
|
||||
var initialFacing = self.Info.Traits.Get<AircraftInfo>().InitialFacing;
|
||||
|
||||
if (dest == null)
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
.ClosestTo(self);
|
||||
|
||||
if (nearestHpad == null)
|
||||
return Util.SequenceActivities(new Turn(initialFacing), new HeliLand(true, 0), NextActivity);
|
||||
return Util.SequenceActivities(new Turn(initialFacing), new HeliLand(true), NextActivity);
|
||||
else
|
||||
return Util.SequenceActivities(new HeliFly(nearestHpad.CenterPosition));
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
var res = dest.TraitOrDefault<Reservable>();
|
||||
var heli = self.Trait<Helicopter>();
|
||||
if (res != null)
|
||||
heli.reservation = res.Reserve(dest, self, heli);
|
||||
heli.Reservation = res.Reserve(dest, self, heli);
|
||||
|
||||
var exit = dest.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
||||
var offset = (exit != null) ? exit.SpawnOffsetVector : WVec.Zero;
|
||||
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
return Util.SequenceActivities(
|
||||
new HeliFly(dest.CenterPosition + offset),
|
||||
new Turn(initialFacing),
|
||||
new HeliLand(false, 0),
|
||||
new HeliLand(false),
|
||||
new Rearm(self),
|
||||
NextActivity);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -19,28 +19,29 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public readonly WRange IdealSeparation = new WRange(1706);
|
||||
public readonly bool LandWhenIdle = true;
|
||||
public readonly int MinimalLandAltitude = 0;
|
||||
public readonly WRange LandAltitude = WRange.Zero;
|
||||
public readonly WRange AltitudeVelocity = new WRange(43);
|
||||
|
||||
public override object Create(ActorInitializer init) { return new Helicopter(init, this); }
|
||||
}
|
||||
|
||||
class Helicopter : Aircraft, ITick, IResolveOrder
|
||||
{
|
||||
HelicopterInfo info;
|
||||
public HelicopterInfo Info;
|
||||
bool firstTick = true;
|
||||
|
||||
public Helicopter(ActorInitializer init, HelicopterInfo info)
|
||||
: base(init, info)
|
||||
{
|
||||
this.info = info;
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (reservation != null)
|
||||
if (Reservation != null)
|
||||
{
|
||||
reservation.Dispose();
|
||||
reservation = null;
|
||||
Reservation.Dispose();
|
||||
Reservation = null;
|
||||
}
|
||||
|
||||
if (order.OrderString == "Move")
|
||||
@@ -51,10 +52,10 @@ namespace OpenRA.Mods.RA.Air
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new HeliFly(target));
|
||||
|
||||
if (info.LandWhenIdle)
|
||||
if (Info.LandWhenIdle)
|
||||
{
|
||||
self.QueueActivity(new Turn(info.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(true, info.MinimalLandAltitude));
|
||||
self.QueueActivity(new Turn(Info.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
var res = order.TargetActor.TraitOrDefault<Reservable>();
|
||||
if (res != null)
|
||||
reservation = res.Reserve(order.TargetActor, self, this);
|
||||
Reservation = res.Reserve(order.TargetActor, self, this);
|
||||
|
||||
var exit = order.TargetActor.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
||||
var offset = (exit != null) ? exit.SpawnOffsetVector : WVec.Zero;
|
||||
@@ -78,8 +79,8 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new HeliFly(order.TargetActor.CenterPosition + offset));
|
||||
self.QueueActivity(new Turn(info.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(false, info.MinimalLandAltitude));
|
||||
self.QueueActivity(new Turn(Info.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(false));
|
||||
self.QueueActivity(new ResupplyAircraft());
|
||||
}
|
||||
}
|
||||
@@ -94,10 +95,10 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
self.CancelActivity();
|
||||
|
||||
if (info.LandWhenIdle)
|
||||
if (Info.LandWhenIdle)
|
||||
{
|
||||
self.QueueActivity(new Turn(info.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(true, info.MinimalLandAltitude));
|
||||
self.QueueActivity(new Turn(Info.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,10 +113,12 @@ namespace OpenRA.Mods.RA.Air
|
||||
}
|
||||
|
||||
// Repulsion only applies when we're flying!
|
||||
if (Altitude != info.CruiseAltitude)
|
||||
var altitude = CenterPosition.Z;
|
||||
var cruiseAltitude = Info.CruiseAltitude * 1024 / Game.CellSize;
|
||||
if (altitude != cruiseAltitude)
|
||||
return;
|
||||
|
||||
var otherHelis = self.World.FindActorsInCircle(self.CenterPosition, info.IdealSeparation)
|
||||
var otherHelis = self.World.FindActorsInCircle(self.CenterPosition, Info.IdealSeparation)
|
||||
.Where(a => a.HasTrait<Helicopter>());
|
||||
|
||||
var f = otherHelis
|
||||
@@ -124,17 +127,17 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
int repulsionFacing = Util.GetFacing(f, -1);
|
||||
if (repulsionFacing != -1)
|
||||
TickMove(PSubPos.PerPx * MovementSpeed, repulsionFacing);
|
||||
SetPosition(self, CenterPosition + FlyStep(repulsionFacing));
|
||||
}
|
||||
|
||||
public WVec GetRepulseForce(Actor self, Actor other)
|
||||
{
|
||||
if (self == other || other.Trait<Helicopter>().Altitude < Altitude)
|
||||
if (self == other || other.CenterPosition.Z < self.CenterPosition.Z)
|
||||
return WVec.Zero;
|
||||
|
||||
var d = self.CenterPosition - other.CenterPosition;
|
||||
var distSq = d.HorizontalLengthSquared;
|
||||
if (distSq > info.IdealSeparation.Range * info.IdealSeparation.Range)
|
||||
if (distSq > Info.IdealSeparation.Range * Info.IdealSeparation.Range)
|
||||
return WVec.Zero;
|
||||
|
||||
if (distSq < 1)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -16,35 +16,31 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public class Land : Activity
|
||||
{
|
||||
Target Target;
|
||||
Target target;
|
||||
|
||||
public Land(Target t) { Target = t; }
|
||||
public Land(Target t) { target = t; }
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if (!Target.IsValid)
|
||||
if (!target.IsValid)
|
||||
Cancel(self);
|
||||
|
||||
if (IsCanceled)
|
||||
return NextActivity;
|
||||
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
var d = Target.CenterPosition - self.CenterPosition;
|
||||
var plane = self.Trait<Plane>();
|
||||
var d = target.CenterPosition - self.CenterPosition;
|
||||
|
||||
// The next move would overshoot, so just set the final position
|
||||
var moveDist = aircraft.MovementSpeed * 7 * 1024 / (Game.CellSize * 32);
|
||||
if (d.HorizontalLengthSquared < moveDist*moveDist)
|
||||
var move = plane.FlyStep(plane.Facing);
|
||||
if (d.HorizontalLengthSquared < move.HorizontalLengthSquared)
|
||||
{
|
||||
aircraft.SetPosition(self, Target.CenterPosition);
|
||||
plane.SetPosition(self, target.CenterPosition);
|
||||
return NextActivity;
|
||||
}
|
||||
|
||||
if (aircraft.Altitude > 0)
|
||||
--aircraft.Altitude;
|
||||
|
||||
var desiredFacing = Util.GetFacing(d, aircraft.Facing);
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
aircraft.TickMove(PSubPos.PerPx * aircraft.MovementSpeed, aircraft.Facing);
|
||||
var desiredFacing = Util.GetFacing(d, plane.Facing);
|
||||
Fly.FlyToward(self, plane, desiredFacing, WRange.Zero);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -16,15 +16,21 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public class PlaneInfo : AircraftInfo
|
||||
{
|
||||
public override object Create( ActorInitializer init ) { return new Plane( init, this ); }
|
||||
public readonly WAngle MaximumPitch = WAngle.FromDegrees(10);
|
||||
|
||||
public override object Create(ActorInitializer init) { return new Plane(init, this); }
|
||||
}
|
||||
|
||||
public class Plane : Aircraft, IResolveOrder, ITick, ISync
|
||||
{
|
||||
public readonly PlaneInfo Info;
|
||||
[Sync] public WPos RTBPathHash;
|
||||
|
||||
public Plane( ActorInitializer init, PlaneInfo info )
|
||||
: base( init, info ) { }
|
||||
public Plane(ActorInitializer init, PlaneInfo info)
|
||||
: base(init, info)
|
||||
{
|
||||
Info = info;
|
||||
}
|
||||
|
||||
bool firstTick = true;
|
||||
public void Tick(Actor self)
|
||||
@@ -49,7 +55,6 @@ namespace OpenRA.Mods.RA.Air
|
||||
self.QueueActivity(Fly.ToCell(target));
|
||||
self.QueueActivity(new FlyCircle());
|
||||
}
|
||||
|
||||
else if (order.OrderString == "Enter")
|
||||
{
|
||||
if (Reservable.IsReserved(order.TargetActor)) return;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -17,14 +17,13 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
class ReturnOnIdleInfo : TraitInfo<ReturnOnIdle> { }
|
||||
|
||||
// fly home or fly-off-map behavior for idle planes
|
||||
|
||||
class ReturnOnIdle : INotifyIdle
|
||||
{
|
||||
public void TickIdle(Actor self)
|
||||
{
|
||||
var altitude = self.Trait<Aircraft>().Altitude;
|
||||
if (altitude == 0) return; // we're on the ground, let's stay there.
|
||||
// We're on the ground, let's stay there.
|
||||
if (self.CenterPosition.Z == 0)
|
||||
return;
|
||||
|
||||
var airfield = ReturnToBase.ChooseAirfield(self, true);
|
||||
if (airfield != null)
|
||||
@@ -38,13 +37,13 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
// i'd prefer something we own
|
||||
var someBuilding = self.World.ActorsWithTrait<Building>()
|
||||
.Select( a => a.Actor )
|
||||
.Select(a => a.Actor)
|
||||
.FirstOrDefault(a => a.Owner == self.Owner);
|
||||
|
||||
// failing that, something unlikely to shoot at us
|
||||
if (someBuilding == null)
|
||||
someBuilding = self.World.ActorsWithTrait<Building>()
|
||||
.Select( a => a.Actor )
|
||||
.Select(a => a.Actor)
|
||||
.FirstOrDefault(a => self.Owner.Stances[a.Owner] == Stance.Ally);
|
||||
|
||||
if (someBuilding == null)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
@@ -46,22 +46,21 @@ namespace OpenRA.Mods.RA.Air
|
||||
if (res != null)
|
||||
{
|
||||
plane.UnReserve();
|
||||
plane.reservation = res.Reserve(dest, self, plane);
|
||||
plane.Reservation = res.Reserve(dest, self, plane);
|
||||
}
|
||||
|
||||
var landPos = dest.CenterPosition;
|
||||
var speed = plane.MovementSpeed * 1024 / Game.CellSize / 5;
|
||||
|
||||
// Distance required for descent.
|
||||
// TODO: Generalize this for arbitrary flight pitches
|
||||
var landDistance = planeInfo.CruiseAltitude * speed;
|
||||
var landDistance = planeInfo.CruiseAltitude * 1024 * 1024 / (Game.CellSize * plane.Info.MaximumPitch.Tan());
|
||||
var altitude = planeInfo.CruiseAltitude * 1024 / Game.CellSize;
|
||||
|
||||
// Land towards the east
|
||||
var approachStart = landPos + new WVec(-landDistance, 0, altitude);
|
||||
|
||||
// Add 10% to the turning radius to ensure we have enough room
|
||||
var turnRadius = (int)(141 * speed / planeInfo.ROT / (float)(Math.PI));
|
||||
var speed = plane.MovementSpeed * 1024 / (Game.CellSize * 5);
|
||||
var turnRadius = (int)(141 * speed / planeInfo.ROT / (float)Math.PI);
|
||||
|
||||
// Find the center of the turning circles for clockwise and counterclockwise turns
|
||||
var angle = WAngle.FromFacing(plane.Facing);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -9,13 +9,13 @@
|
||||
#endregion
|
||||
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public class TargetableAircraftInfo : TargetableUnitInfo, Requires<AircraftInfo>
|
||||
public class TargetableAircraftInfo : TargetableUnitInfo
|
||||
{
|
||||
public readonly string[] GroundedTargetTypes = { };
|
||||
public override object Create(ActorInitializer init) { return new TargetableAircraft(init.self, this); }
|
||||
@@ -24,19 +24,19 @@ namespace OpenRA.Mods.RA.Air
|
||||
public class TargetableAircraft : TargetableUnit
|
||||
{
|
||||
readonly TargetableAircraftInfo info;
|
||||
readonly Aircraft Aircraft;
|
||||
readonly Actor self;
|
||||
|
||||
public TargetableAircraft(Actor self, TargetableAircraftInfo info)
|
||||
: base(self, info)
|
||||
{
|
||||
this.info = info;
|
||||
Aircraft = self.Trait<Aircraft>();
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public override string[] TargetTypes
|
||||
{
|
||||
get { return (Aircraft.Altitude > 0) ? info.TargetTypes
|
||||
: info.GroundedTargetTypes; }
|
||||
get { return (self.CenterPosition.Z > 0) ? info.TargetTypes
|
||||
: info.GroundedTargetTypes; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -52,7 +52,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
var aircraft = self.TraitOrDefault<Aircraft>();
|
||||
if (aircraft != null)
|
||||
td.Add(new AltitudeInit(aircraft.Altitude));
|
||||
td.Add(new AltitudeInit(aircraft.CenterPosition.Z * Game.CellSize / 1024));
|
||||
|
||||
var facing = self.TraitOrDefault<IFacing>();
|
||||
if (facing != null)
|
||||
|
||||
@@ -215,9 +215,10 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
foreach (var aircraft in SovietAircraft())
|
||||
{
|
||||
var pos = aircraft.CenterPosition;
|
||||
var plane = aircraft.Trait<Plane>();
|
||||
var ammo = aircraft.Trait<LimitedAmmo>();
|
||||
if ((plane.Altitude == 0 && ammo.FullAmmo()) || (plane.Altitude != 0 && ammo.HasAmmo()))
|
||||
if ((pos.Z == 0 && ammo.FullAmmo()) || (pos.Z != 0 && ammo.HasAmmo()))
|
||||
{
|
||||
var enemy = FirstUnshroudedOrDefault(enemies.OrderBy(u => (aircraft.CenterPosition - u.CenterPosition).LengthSquared), world, 10);
|
||||
if (enemy != null)
|
||||
@@ -225,13 +226,13 @@ namespace OpenRA.Mods.RA.Missions
|
||||
if (!aircraft.IsIdle && aircraft.GetCurrentActivity().GetType() != typeof(FlyAttack))
|
||||
aircraft.CancelActivity();
|
||||
|
||||
if (plane.Altitude == 0)
|
||||
if (pos.Z == 0)
|
||||
plane.UnReserve();
|
||||
|
||||
aircraft.QueueActivity(new FlyAttack(Target.FromActor(enemy)));
|
||||
}
|
||||
}
|
||||
else if (plane.Altitude != 0 && !LandIsQueued(aircraft))
|
||||
else if (pos.Z != 0 && !LandIsQueued(aircraft))
|
||||
{
|
||||
aircraft.CancelActivity();
|
||||
aircraft.QueueActivity(new ReturnToBase(aircraft, null));
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
chinook.QueueActivity(new HeliFly(lz.CenterPosition + offset)); // no reservation of hpad but it's not needed
|
||||
chinook.QueueActivity(new Turn(0));
|
||||
chinook.QueueActivity(new HeliLand(false, 0));
|
||||
chinook.QueueActivity(new HeliLand(false));
|
||||
chinook.QueueActivity(new UnloadCargo(true));
|
||||
chinook.QueueActivity(new Wait(150));
|
||||
chinook.QueueActivity(new HeliFly(entry));
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) });
|
||||
chinook.QueueActivity(new HeliFly(lz));
|
||||
chinook.QueueActivity(new Turn(0));
|
||||
chinook.QueueActivity(new HeliLand(true, 0));
|
||||
chinook.QueueActivity(new HeliLand(true));
|
||||
chinook.QueueActivity(new WaitFor(() => chinook.Trait<Cargo>().Passengers.Contains(unit)));
|
||||
chinook.QueueActivity(new Wait(150));
|
||||
chinook.QueueActivity(new HeliFly(exit));
|
||||
@@ -62,7 +62,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
chinook.Trait<Cargo>().Load(chinook, unit);
|
||||
chinook.QueueActivity(new HeliFly(lz));
|
||||
chinook.QueueActivity(new Turn(0));
|
||||
chinook.QueueActivity(new HeliLand(true, 0));
|
||||
chinook.QueueActivity(new HeliLand(true));
|
||||
chinook.QueueActivity(new UnloadCargo(true));
|
||||
chinook.QueueActivity(new CallFunc(() => afterUnload(unit)));
|
||||
chinook.QueueActivity(new Wait(150));
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
LandableTerrainTypes: Sand, Rock, Transition, Spice, Dune
|
||||
RepairBuildings: repair
|
||||
RearmBuildings: starporta,starporto,starporth
|
||||
MinimalLandAltitude: 25
|
||||
LandAltitude: 800
|
||||
RenderUnit:
|
||||
WithCargo:
|
||||
LocalOffset: 0,0,-854
|
||||
|
||||
Reference in New Issue
Block a user