Fix air unit resupply #5966
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -105,6 +105,7 @@ Also thanks to:
|
|||||||
* Paolo Chiodi (paolochiodi)
|
* Paolo Chiodi (paolochiodi)
|
||||||
* Paul Dovydaitis (pdovy)
|
* Paul Dovydaitis (pdovy)
|
||||||
* Pavlos Touboulidis (pav)
|
* Pavlos Touboulidis (pav)
|
||||||
|
* Pedro Ferreira Ramos (bateramos)
|
||||||
* Pizzaoverhead
|
* Pizzaoverhead
|
||||||
* Piët Delport (pjdelport)
|
* Piët Delport (pjdelport)
|
||||||
* Psydev
|
* 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
|
// 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
|
// 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()))
|
if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
|
||||||
return NextActivity;
|
return ActivityUtils.SequenceActivities(new ReturnToBase(self), NextActivity);
|
||||||
|
|
||||||
if (attackPlane != null)
|
if (attackPlane != null)
|
||||||
attackPlane.DoAttack(self, target);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,7 +50,22 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
if (nearestHpad == null)
|
if (nearestHpad == null)
|
||||||
return ActivityUtils.SequenceActivities(new Turn(self, initialFacing), new HeliLand(self, true), NextActivity);
|
return ActivityUtils.SequenceActivities(new Turn(self, initialFacing), new HeliLand(self, true), NextActivity);
|
||||||
else
|
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);
|
heli.MakeReservation(dest);
|
||||||
@@ -62,7 +77,8 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
new HeliFly(self, Target.FromPos(dest.CenterPosition + offset)),
|
new HeliFly(self, Target.FromPos(dest.CenterPosition + offset)),
|
||||||
new Turn(self, initialFacing),
|
new Turn(self, initialFacing),
|
||||||
new HeliLand(self, false),
|
new HeliLand(self, false),
|
||||||
new ResupplyAircraft(self));
|
new ResupplyAircraft(self),
|
||||||
|
NextActivity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,17 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
if (host == null)
|
if (host == null)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
|
if (aircraft.IsPlane)
|
||||||
return ActivityUtils.SequenceActivities(
|
return ActivityUtils.SequenceActivities(
|
||||||
aircraft.GetResupplyActivities(host).Append(NextActivity).ToArray());
|
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(new TakeOff(self)).Append(NextActivity).ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,11 +106,13 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
var nearestAfld = ChooseAirfield(self, false);
|
var nearestAfld = ChooseAirfield(self, false);
|
||||||
|
|
||||||
self.CancelActivity();
|
|
||||||
if (nearestAfld != null)
|
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
|
else
|
||||||
return new FlyCircle(self);
|
return NextActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Activity> landingProcedures = new List<Activity>();
|
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
|
// 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 Fly(self, Target.FromPos(w3), WDist.Zero, new WDist(turnRadius / 2)));
|
||||||
landingProcedures.Add(new Land(self, Target.FromActor(dest)));
|
landingProcedures.Add(new Land(self, Target.FromActor(dest)));
|
||||||
|
landingProcedures.Add(new ResupplyAircraft(self));
|
||||||
landingProcedures.Add(NextActivity);
|
landingProcedures.Add(NextActivity);
|
||||||
|
|
||||||
return ActivityUtils.SequenceActivities(landingProcedures.ToArray());
|
return ActivityUtils.SequenceActivities(landingProcedures.ToArray());
|
||||||
|
|||||||
@@ -774,6 +774,7 @@
|
|||||||
<Compile Include="Traits\Buildings\FreeActorWithDelivery.cs" />
|
<Compile Include="Traits\Buildings\FreeActorWithDelivery.cs" />
|
||||||
<Compile Include="Traits\ExitsDebugOverlay.cs" />
|
<Compile Include="Traits\ExitsDebugOverlay.cs" />
|
||||||
<Compile Include="Traits\World\ExitsDebugOverlayManager.cs" />
|
<Compile Include="Traits\World\ExitsDebugOverlayManager.cs" />
|
||||||
|
<Compile Include="Activities\Air\FlyCircleTimed.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -83,6 +83,12 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
[Desc("Sound to play when the actor is landing.")]
|
[Desc("Sound to play when the actor is landing.")]
|
||||||
public readonly string LandingSound = null;
|
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>(); }
|
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary<CPos, SubCell>(); }
|
||||||
bool IOccupySpaceInfo.SharesCell { get { return false; } }
|
bool IOccupySpaceInfo.SharesCell { get { return false; } }
|
||||||
}
|
}
|
||||||
@@ -98,6 +104,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
UpgradeManager um;
|
UpgradeManager um;
|
||||||
IDisposable reservation;
|
IDisposable reservation;
|
||||||
|
Actor reservedActor;
|
||||||
IEnumerable<int> speedModifiers;
|
IEnumerable<int> speedModifiers;
|
||||||
|
|
||||||
[Sync] public int Facing { get; set; }
|
[Sync] public int Facing { get; set; }
|
||||||
@@ -181,6 +188,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (!Info.Repulsable)
|
if (!Info.Repulsable)
|
||||||
return WVec.Zero;
|
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!
|
// Repulsion only applies when we're flying!
|
||||||
var altitude = self.World.Map.DistanceAboveTerrain(CenterPosition).Length;
|
var altitude = self.World.Map.DistanceAboveTerrain(CenterPosition).Length;
|
||||||
if (altitude != Info.CruiseAltitude.Length)
|
if (altitude != Info.CruiseAltitude.Length)
|
||||||
@@ -261,7 +275,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
UnReserve();
|
UnReserve();
|
||||||
var reservable = target.TraitOrDefault<Reservable>();
|
var reservable = target.TraitOrDefault<Reservable>();
|
||||||
if (reservable != null)
|
if (reservable != null)
|
||||||
|
{
|
||||||
reservation = reservable.Reserve(target, self, this);
|
reservation = reservable.Reserve(target, self, this);
|
||||||
|
reservedActor = target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UnReserve()
|
public void UnReserve()
|
||||||
@@ -271,6 +288,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
reservation.Dispose();
|
reservation.Dispose();
|
||||||
reservation = null;
|
reservation = null;
|
||||||
|
reservedActor = null;
|
||||||
|
|
||||||
if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length <= Info.LandAltitude.Length)
|
if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length <= Info.LandAltitude.Length)
|
||||||
self.QueueActivity(new TakeOff(self));
|
self.QueueActivity(new TakeOff(self));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user