Fix air unit resupply #5966
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -105,6 +105,7 @@ Also thanks to:
|
||||
* Paolo Chiodi (paolochiodi)
|
||||
* Paul Dovydaitis (pdovy)
|
||||
* Pavlos Touboulidis (pav)
|
||||
* Pedro Ferreira Ramos (bateramos)
|
||||
* Pizzaoverhead
|
||||
* Piët Delport (pjdelport)
|
||||
* Psydev
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -774,6 +774,7 @@
|
||||
<Compile Include="Traits\Buildings\FreeActorWithDelivery.cs" />
|
||||
<Compile Include="Traits\ExitsDebugOverlay.cs" />
|
||||
<Compile Include="Traits\World\ExitsDebugOverlayManager.cs" />
|
||||
<Compile Include="Activities\Air\FlyCircleTimed.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -83,6 +83,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Sound to play when the actor is landing.")]
|
||||
public readonly string LandingSound = null;
|
||||
|
||||
[Desc("The distance of the resupply base that the aircraft will wait for its turn.")]
|
||||
public readonly WDist WaitDistanceFromResupplyBase = new WDist(3072);
|
||||
|
||||
[Desc("The number of ticks that a airplane will wait to make a new search for an available airport.")]
|
||||
public readonly int NumberOfTicksToVerifyAvailableAirport = 150;
|
||||
|
||||
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary<CPos, SubCell>(); }
|
||||
bool IOccupySpaceInfo.SharesCell { get { return false; } }
|
||||
}
|
||||
@@ -98,6 +104,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
UpgradeManager um;
|
||||
IDisposable reservation;
|
||||
Actor reservedActor;
|
||||
IEnumerable<int> speedModifiers;
|
||||
|
||||
[Sync] public int Facing { get; set; }
|
||||
@@ -181,6 +188,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!Info.Repulsable)
|
||||
return WVec.Zero;
|
||||
|
||||
if (reservation != null)
|
||||
{
|
||||
var distanceFromReservationActor = (reservedActor.CenterPosition - self.CenterPosition).HorizontalLength;
|
||||
if (distanceFromReservationActor < Info.WaitDistanceFromResupplyBase.Length)
|
||||
return WVec.Zero;
|
||||
}
|
||||
|
||||
// Repulsion only applies when we're flying!
|
||||
var altitude = self.World.Map.DistanceAboveTerrain(CenterPosition).Length;
|
||||
if (altitude != Info.CruiseAltitude.Length)
|
||||
@@ -261,7 +275,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
UnReserve();
|
||||
var reservable = target.TraitOrDefault<Reservable>();
|
||||
if (reservable != null)
|
||||
{
|
||||
reservation = reservable.Reserve(target, self, this);
|
||||
reservedActor = target;
|
||||
}
|
||||
}
|
||||
|
||||
public void UnReserve()
|
||||
@@ -271,6 +288,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
reservation.Dispose();
|
||||
reservation = null;
|
||||
reservedActor = null;
|
||||
|
||||
if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length <= Info.LandAltitude.Length)
|
||||
self.QueueActivity(new TakeOff(self));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user