Convert helicopter activities to world coords.
This commit is contained in:
@@ -16,15 +16,14 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
{
|
{
|
||||||
class HeliFly : Activity
|
class HeliFly : Activity
|
||||||
{
|
{
|
||||||
public readonly PPos Dest;
|
readonly WPos pos;
|
||||||
public HeliFly(PPos dest)
|
public HeliFly(WPos pos) { this.pos = pos; }
|
||||||
{
|
public HeliFly(CPos pos) { this.pos = pos.CenterPosition; }
|
||||||
Dest = dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (IsCanceled) return NextActivity;
|
if (IsCanceled)
|
||||||
|
return NextActivity;
|
||||||
|
|
||||||
var info = self.Info.Traits.Get<HelicopterInfo>();
|
var info = self.Info.Traits.Get<HelicopterInfo>();
|
||||||
var aircraft = self.Trait<Aircraft>();
|
var aircraft = self.Trait<Aircraft>();
|
||||||
@@ -35,10 +34,12 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dist = Dest - aircraft.PxPosition;
|
// The next move would overshoot, so just set the final position
|
||||||
if (Math.Abs(dist.X) < 2 && Math.Abs(dist.Y) < 2)
|
var dist = pos - self.CenterPosition;
|
||||||
|
var moveDist = aircraft.MovementSpeed * 7 * 1024 / (Game.CellSize * 32);
|
||||||
|
if (dist.HorizontalLengthSquared < moveDist*moveDist)
|
||||||
{
|
{
|
||||||
aircraft.SubPxPosition = Dest.ToPSubPos();
|
aircraft.SubPxPosition = PPos.FromWPos(pos).ToPSubPos();
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
|
|
||||||
public override IEnumerable<Target> GetTargets(Actor self)
|
public override IEnumerable<Target> GetTargets(Actor self)
|
||||||
{
|
{
|
||||||
yield return Target.FromPos(Dest);
|
yield return Target.FromPos(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
if (nearestHpad == null)
|
if (nearestHpad == null)
|
||||||
return Util.SequenceActivities(new Turn(initialFacing), new HeliLand(true, 0), NextActivity);
|
return Util.SequenceActivities(new Turn(initialFacing), new HeliLand(true, 0), NextActivity);
|
||||||
else
|
else
|
||||||
return Util.SequenceActivities(new HeliFly(Util.CenterOfCell(nearestHpad.Location)));
|
return Util.SequenceActivities(new HeliFly(nearestHpad.CenterPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
var res = dest.TraitOrDefault<Reservable>();
|
var res = dest.TraitOrDefault<Reservable>();
|
||||||
@@ -51,10 +51,11 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
heli.reservation = res.Reserve(dest, self, heli);
|
heli.reservation = res.Reserve(dest, self, heli);
|
||||||
|
|
||||||
var exit = dest.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
var exit = dest.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
||||||
var offset = exit != null ? exit.SpawnOffsetVector : PVecInt.Zero;
|
var offset = (exit == null) ? WVec.Zero :
|
||||||
|
new WVec(exit.SpawnOffsetVector.X, exit.SpawnOffsetVector.Y, 0) * 1024 / Game.CellSize;
|
||||||
|
|
||||||
return Util.SequenceActivities(
|
return Util.SequenceActivities(
|
||||||
new HeliFly(dest.Trait<IHasLocation>().PxPosition + offset),
|
new HeliFly(dest.CenterPosition + offset),
|
||||||
new Turn(initialFacing),
|
new Turn(initialFacing),
|
||||||
new HeliLand(false, 0),
|
new HeliLand(false, 0),
|
||||||
new Rearm(self),
|
new Rearm(self),
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
{
|
{
|
||||||
class HelicopterInfo : AircraftInfo
|
class HelicopterInfo : AircraftInfo
|
||||||
{
|
{
|
||||||
public readonly int IdealSeparation = 40;
|
public readonly WRange IdealSeparation = new WRange(1706);
|
||||||
public readonly bool LandWhenIdle = true;
|
public readonly bool LandWhenIdle = true;
|
||||||
public readonly int MinimalLandAltitude = 0;
|
public readonly int MinimalLandAltitude = 0;
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
|
|
||||||
self.SetTargetLine(Target.FromCell(target), Color.Green);
|
self.SetTargetLine(Target.FromCell(target), Color.Green);
|
||||||
self.CancelActivity();
|
self.CancelActivity();
|
||||||
self.QueueActivity(new HeliFly(Util.CenterOfCell(target)));
|
self.QueueActivity(new HeliFly(target));
|
||||||
|
|
||||||
if (Info.LandWhenIdle)
|
if (Info.LandWhenIdle)
|
||||||
{
|
{
|
||||||
@@ -71,12 +71,13 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
reservation = res.Reserve(order.TargetActor, self, this);
|
reservation = res.Reserve(order.TargetActor, self, this);
|
||||||
|
|
||||||
var exit = order.TargetActor.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
var exit = order.TargetActor.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
||||||
var offset = exit != null ? exit.SpawnOffsetVector : PVecInt.Zero;
|
var offset = (exit == null) ? WVec.Zero :
|
||||||
|
new WVec(exit.SpawnOffsetVector.X, exit.SpawnOffsetVector.Y, 0) * 1024 / Game.CellSize;
|
||||||
|
|
||||||
self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green);
|
self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green);
|
||||||
|
|
||||||
self.CancelActivity();
|
self.CancelActivity();
|
||||||
self.QueueActivity(new HeliFly(order.TargetActor.Trait<IHasLocation>().PxPosition + offset));
|
self.QueueActivity(new HeliFly(order.TargetActor.CenterPosition + offset));
|
||||||
self.QueueActivity(new Turn(Info.InitialFacing));
|
self.QueueActivity(new Turn(Info.InitialFacing));
|
||||||
self.QueueActivity(new HeliLand(false, Info.MinimalLandAltitude));
|
self.QueueActivity(new HeliLand(false, Info.MinimalLandAltitude));
|
||||||
self.QueueActivity(new ResupplyAircraft());
|
self.QueueActivity(new ResupplyAircraft());
|
||||||
@@ -110,38 +111,40 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
ReserveSpawnBuilding();
|
ReserveSpawnBuilding();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* repulsion only applies when we're flying */
|
// Repulsion only applies when we're flying!
|
||||||
if (Altitude <= 0) return;
|
if (Altitude != Info.CruiseAltitude)
|
||||||
|
return;
|
||||||
|
|
||||||
var separation = new WRange(Info.IdealSeparation * 1024 / Game.CellSize);
|
var otherHelis = self.World.FindActorsInCircle(self.CenterPosition, Info.IdealSeparation)
|
||||||
var otherHelis = self.World.FindActorsInCircle(self.CenterPosition, separation)
|
|
||||||
.Where(a => a.HasTrait<Helicopter>());
|
.Where(a => a.HasTrait<Helicopter>());
|
||||||
|
|
||||||
var f = otherHelis
|
var f = otherHelis
|
||||||
.Select(h => GetRepulseForce(self, h))
|
.Select(h => GetRepulseForce(self, h))
|
||||||
.Aggregate(PSubVec.Zero, (a, b) => a + b);
|
.Aggregate(WVec.Zero, (a, b) => a + b);
|
||||||
|
|
||||||
// FIXME(jsd): not sure which units GetFacing accepts; code is unclear to me.
|
int repulsionFacing = Util.GetFacing(f, -1);
|
||||||
int repulsionFacing = Util.GetFacing( f.ToInt2(), -1 );
|
|
||||||
if (repulsionFacing != -1)
|
if (repulsionFacing != -1)
|
||||||
TickMove(PSubPos.PerPx * MovementSpeed, repulsionFacing);
|
TickMove(PSubPos.PerPx * MovementSpeed, repulsionFacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a vector in subPx units
|
public WVec GetRepulseForce(Actor self, Actor other)
|
||||||
public PSubVec GetRepulseForce(Actor self, Actor h)
|
|
||||||
{
|
{
|
||||||
if (self == h)
|
if (self == other || other.Trait<Helicopter>().Altitude < Altitude)
|
||||||
return PSubVec.Zero;
|
return WVec.Zero;
|
||||||
if( h.Trait<Helicopter>().Altitude < Altitude )
|
|
||||||
return PSubVec.Zero;
|
|
||||||
var d = self.CenterLocation - h.CenterLocation;
|
|
||||||
|
|
||||||
if (d.Length > Info.IdealSeparation)
|
var d = self.CenterPosition - other.CenterPosition;
|
||||||
return PSubVec.Zero;
|
var dlSq = d.HorizontalLengthSquared;
|
||||||
|
if (dlSq > Info.IdealSeparation.Range*Info.IdealSeparation.Range)
|
||||||
|
return WVec.Zero;
|
||||||
|
|
||||||
if (d.LengthSquared < 1)
|
if (dlSq < 1)
|
||||||
return Util.SubPxVector[self.World.SharedRandom.Next(255)];
|
{
|
||||||
return (5 * d.ToPSubVec()) / d.LengthSquared;
|
var yaw = self.World.SharedRandom.Next(0, 1023);
|
||||||
|
var rot = new WRot(WAngle.Zero, WAngle.Zero, new WAngle(yaw));
|
||||||
|
return new WVec(1024, 0, 0).Rotate(rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (d * 1024 * 8) / (int)dlSq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,14 +217,15 @@ namespace OpenRA.Mods.RA.Missions
|
|||||||
cargo.Load(chinook, world.CreateActor(false, ChinookCargo.Random(world.SharedRandom), allies, null, null));
|
cargo.Load(chinook, world.CreateActor(false, ChinookCargo.Random(world.SharedRandom), allies, null, null));
|
||||||
|
|
||||||
var exit = lz.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
var exit = lz.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
|
||||||
var offset = exit != null ? exit.SpawnOffsetVector : PVecInt.Zero;
|
var offset = (exit == null) ? WVec.Zero :
|
||||||
|
new WVec(exit.SpawnOffsetVector.X, exit.SpawnOffsetVector.Y, 0) * 1024 / Game.CellSize;
|
||||||
|
|
||||||
chinook.QueueActivity(new HeliFly(lz.CenterLocation + offset)); // no reservation of hpad but it's not needed
|
chinook.QueueActivity(new HeliFly(lz.CenterPosition + offset)); // no reservation of hpad but it's not needed
|
||||||
chinook.QueueActivity(new Turn(0));
|
chinook.QueueActivity(new Turn(0));
|
||||||
chinook.QueueActivity(new HeliLand(false, 0));
|
chinook.QueueActivity(new HeliLand(false, 0));
|
||||||
chinook.QueueActivity(new UnloadCargo(true));
|
chinook.QueueActivity(new UnloadCargo(true));
|
||||||
chinook.QueueActivity(new Wait(150));
|
chinook.QueueActivity(new Wait(150));
|
||||||
chinook.QueueActivity(new HeliFly(Util.CenterOfCell(entry)));
|
chinook.QueueActivity(new HeliFly(entry));
|
||||||
chinook.QueueActivity(new RemoveSelf());
|
chinook.QueueActivity(new RemoveSelf());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,12 @@ namespace OpenRA.Mods.RA.Missions
|
|||||||
public static Actor ExtractUnitWithChinook(World world, Player owner, Actor unit, CPos entry, CPos lz, CPos exit)
|
public static Actor ExtractUnitWithChinook(World world, Player owner, Actor unit, CPos entry, CPos lz, CPos exit)
|
||||||
{
|
{
|
||||||
var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) });
|
var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) });
|
||||||
chinook.QueueActivity(new HeliFly(Util.CenterOfCell(lz)));
|
chinook.QueueActivity(new HeliFly(lz));
|
||||||
chinook.QueueActivity(new Turn(0));
|
chinook.QueueActivity(new Turn(0));
|
||||||
chinook.QueueActivity(new HeliLand(true, 0));
|
chinook.QueueActivity(new HeliLand(true, 0));
|
||||||
chinook.QueueActivity(new WaitFor(() => chinook.Trait<Cargo>().Passengers.Contains(unit)));
|
chinook.QueueActivity(new WaitFor(() => chinook.Trait<Cargo>().Passengers.Contains(unit)));
|
||||||
chinook.QueueActivity(new Wait(150));
|
chinook.QueueActivity(new Wait(150));
|
||||||
chinook.QueueActivity(new HeliFly(Util.CenterOfCell(exit)));
|
chinook.QueueActivity(new HeliFly(exit));
|
||||||
chinook.QueueActivity(new RemoveSelf());
|
chinook.QueueActivity(new RemoveSelf());
|
||||||
return chinook;
|
return chinook;
|
||||||
}
|
}
|
||||||
@@ -60,13 +60,13 @@ namespace OpenRA.Mods.RA.Missions
|
|||||||
var unit = world.CreateActor(false, unitName, new TypeDictionary { new OwnerInit(owner) });
|
var unit = world.CreateActor(false, unitName, new TypeDictionary { new OwnerInit(owner) });
|
||||||
var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) });
|
var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) });
|
||||||
chinook.Trait<Cargo>().Load(chinook, unit);
|
chinook.Trait<Cargo>().Load(chinook, unit);
|
||||||
chinook.QueueActivity(new HeliFly(Util.CenterOfCell(lz)));
|
chinook.QueueActivity(new HeliFly(lz));
|
||||||
chinook.QueueActivity(new Turn(0));
|
chinook.QueueActivity(new Turn(0));
|
||||||
chinook.QueueActivity(new HeliLand(true, 0));
|
chinook.QueueActivity(new HeliLand(true, 0));
|
||||||
chinook.QueueActivity(new UnloadCargo(true));
|
chinook.QueueActivity(new UnloadCargo(true));
|
||||||
chinook.QueueActivity(new CallFunc(() => afterUnload(unit)));
|
chinook.QueueActivity(new CallFunc(() => afterUnload(unit)));
|
||||||
chinook.QueueActivity(new Wait(150));
|
chinook.QueueActivity(new Wait(150));
|
||||||
chinook.QueueActivity(new HeliFly(Util.CenterOfCell(exit)));
|
chinook.QueueActivity(new HeliFly(exit));
|
||||||
chinook.QueueActivity(new RemoveSelf());
|
chinook.QueueActivity(new RemoveSelf());
|
||||||
return Pair.New(chinook, unit);
|
return Pair.New(chinook, unit);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ namespace OpenRA.Mods.RA
|
|||||||
var helicopter = newUnit.TraitOrDefault<Helicopter>();
|
var helicopter = newUnit.TraitOrDefault<Helicopter>();
|
||||||
if (helicopter != null)
|
if (helicopter != null)
|
||||||
{
|
{
|
||||||
newUnit.QueueActivity(new HeliFly(Util.CenterOfCell(rp.rallyPoint)));
|
newUnit.QueueActivity(new HeliFly(rp.rallyPoint));
|
||||||
return rp.rallyPoint;
|
return rp.rallyPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user