Fix air unit resupply #5966
This commit is contained in:
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
// Move to the next activity only if all ammo pools are depleted and none reload automatically
|
||||
// TODO: This should check whether there is ammo left that is actually suitable for the target
|
||||
if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
|
||||
return NextActivity;
|
||||
return ActivityUtils.SequenceActivities(new ReturnToBase(self), NextActivity);
|
||||
|
||||
if (attackPlane != null)
|
||||
attackPlane.DoAttack(self, target);
|
||||
|
||||
36
OpenRA.Mods.Common/Activities/Air/FlyCircleTimed.cs
Normal file
36
OpenRA.Mods.Common/Activities/Air/FlyCircleTimed.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2016 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
public class FlyCircleTimed : FlyCircle
|
||||
{
|
||||
int remainingTicks;
|
||||
|
||||
public FlyCircleTimed(int ticks, Actor self) : base(self)
|
||||
{
|
||||
remainingTicks = ticks;
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if (IsCanceled || remainingTicks-- == 0)
|
||||
return NextActivity;
|
||||
|
||||
base.Tick(self);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,13 +44,28 @@ namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
var rearmBuildings = heli.Info.RearmBuildings;
|
||||
var nearestHpad = self.World.ActorsHavingTrait<Reservable>()
|
||||
.Where(a => a.Owner == self.Owner && rearmBuildings.Contains(a.Info.Name))
|
||||
.ClosestTo(self);
|
||||
.Where(a => a.Owner == self.Owner && rearmBuildings.Contains(a.Info.Name))
|
||||
.ClosestTo(self);
|
||||
|
||||
if (nearestHpad == null)
|
||||
return ActivityUtils.SequenceActivities(new Turn(self, initialFacing), new HeliLand(self, true), NextActivity);
|
||||
else
|
||||
return ActivityUtils.SequenceActivities(new HeliFly(self, Target.FromActor(nearestHpad)));
|
||||
{
|
||||
var distanceFromHelipad = (nearestHpad.CenterPosition - self.CenterPosition).HorizontalLength;
|
||||
var distanceLength = heli.Info.WaitDistanceFromResupplyBase.Length;
|
||||
|
||||
// If no pad is available, move near one and wait
|
||||
if (distanceFromHelipad > distanceLength)
|
||||
{
|
||||
var randomPosition = WVec.FromPDF(self.World.SharedRandom, 2) * distanceLength / 1024;
|
||||
|
||||
var target = Target.FromPos(nearestHpad.CenterPosition + randomPosition);
|
||||
|
||||
return ActivityUtils.SequenceActivities(new HeliFly(self, target, WDist.Zero, heli.Info.WaitDistanceFromResupplyBase), this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
heli.MakeReservation(dest);
|
||||
@@ -62,7 +77,8 @@ namespace OpenRA.Mods.Common.Activities
|
||||
new HeliFly(self, Target.FromPos(dest.CenterPosition + offset)),
|
||||
new Turn(self, initialFacing),
|
||||
new HeliLand(self, false),
|
||||
new ResupplyAircraft(self));
|
||||
new ResupplyAircraft(self),
|
||||
NextActivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,17 @@ namespace OpenRA.Mods.Common.Activities
|
||||
if (host == null)
|
||||
return NextActivity;
|
||||
|
||||
if (aircraft.IsPlane)
|
||||
return ActivityUtils.SequenceActivities(
|
||||
aircraft.GetResupplyActivities(host)
|
||||
.Append(new CallFunc(() => aircraft.UnReserve()))
|
||||
.Append(new WaitFor(() => NextActivity != null || Reservable.IsReserved(host)))
|
||||
.Append(new TakeOff(self))
|
||||
.Append(NextActivity).ToArray());
|
||||
|
||||
// If is helicopter move away as soon as the resupply ends
|
||||
return ActivityUtils.SequenceActivities(
|
||||
aircraft.GetResupplyActivities(host).Append(NextActivity).ToArray());
|
||||
aircraft.GetResupplyActivities(host).Append(new TakeOff(self)).Append(NextActivity).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,11 +106,13 @@ namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
var nearestAfld = ChooseAirfield(self, false);
|
||||
|
||||
self.CancelActivity();
|
||||
if (nearestAfld != null)
|
||||
return ActivityUtils.SequenceActivities(new Fly(self, Target.FromActor(nearestAfld)), new FlyCircle(self));
|
||||
return ActivityUtils.SequenceActivities(
|
||||
new Fly(self, Target.FromActor(nearestAfld), WDist.Zero, plane.Info.WaitDistanceFromResupplyBase),
|
||||
new FlyCircleTimed(plane.Info.NumberOfTicksToVerifyAvailableAirport, self),
|
||||
this);
|
||||
else
|
||||
return new FlyCircle(self);
|
||||
return NextActivity;
|
||||
}
|
||||
|
||||
List<Activity> landingProcedures = new List<Activity>();
|
||||
@@ -123,6 +125,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
// Fix a problem when the airplane is send to resupply near the airport
|
||||
landingProcedures.Add(new Fly(self, Target.FromPos(w3), WDist.Zero, new WDist(turnRadius / 2)));
|
||||
landingProcedures.Add(new Land(self, Target.FromActor(dest)));
|
||||
landingProcedures.Add(new ResupplyAircraft(self));
|
||||
landingProcedures.Add(NextActivity);
|
||||
|
||||
return ActivityUtils.SequenceActivities(landingProcedures.ToArray());
|
||||
|
||||
Reference in New Issue
Block a user