Merge pull request #12102 from pchote/more-resupply-tweaks

Tweak aircraft resupply behaviour.
This commit is contained in:
Oliver Brakmann
2016-09-26 19:03:46 +02:00
committed by GitHub
7 changed files with 70 additions and 24 deletions

View File

@@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Activities
// 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 ActivityUtils.SequenceActivities(new ReturnToBase(self), this); return ActivityUtils.SequenceActivities(new ReturnToBase(self, aircraft.Info.AbortOnResupply), this);
if (attackPlane != null) if (attackPlane != null)
attackPlane.DoAttack(self, target); attackPlane.DoAttack(self, target);

View File

@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Activities
// If any AmmoPool is depleted and no weapon is valid against target, return to helipad to reload and then resume the activity // If any AmmoPool is depleted and no weapon is valid against target, return to helipad to reload and then resume the activity
if (ammoPools.Any(x => !x.Info.SelfReloads && !x.HasAmmo()) && !attackHeli.HasAnyValidWeapons(target)) if (ammoPools.Any(x => !x.Info.SelfReloads && !x.HasAmmo()) && !attackHeli.HasAnyValidWeapons(target))
return ActivityUtils.SequenceActivities(new HeliReturnToBase(self), this); return ActivityUtils.SequenceActivities(new HeliReturnToBase(self, helicopter.Info.AbortOnResupply), this);
var dist = target.CenterPosition - self.CenterPosition; var dist = target.CenterPosition - self.CenterPosition;

View File

@@ -19,10 +19,14 @@ namespace OpenRA.Mods.Common.Activities
public class HeliReturnToBase : Activity public class HeliReturnToBase : Activity
{ {
readonly Aircraft heli; readonly Aircraft heli;
readonly bool alwaysLand;
readonly bool abortOnResupply;
public HeliReturnToBase(Actor self) public HeliReturnToBase(Actor self, bool abortOnResupply, bool alwaysLand = true)
{ {
heli = self.Trait<Aircraft>(); heli = self.Trait<Aircraft>();
this.alwaysLand = alwaysLand;
this.abortOnResupply = abortOnResupply;
} }
public Actor ChooseHelipad(Actor self) public Actor ChooseHelipad(Actor self)
@@ -68,17 +72,36 @@ namespace OpenRA.Mods.Common.Activities
} }
} }
heli.MakeReservation(dest);
var exit = dest.Info.TraitInfos<ExitInfo>().FirstOrDefault(); var exit = dest.Info.TraitInfos<ExitInfo>().FirstOrDefault();
var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero; var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero;
if (ShouldLandAtBuilding(self, dest))
{
heli.MakeReservation(dest);
return ActivityUtils.SequenceActivities(
new HeliFly(self, Target.FromPos(dest.CenterPosition + offset)),
new Turn(self, initialFacing),
new HeliLand(self, false),
new ResupplyAircraft(self),
!abortOnResupply ? NextActivity : null);
}
return ActivityUtils.SequenceActivities( return ActivityUtils.SequenceActivities(
new HeliFly(self, Target.FromPos(dest.CenterPosition + offset)), new HeliFly(self, Target.FromPos(dest.CenterPosition + offset)),
new Turn(self, initialFacing),
new HeliLand(self, false),
new ResupplyAircraft(self),
NextActivity); NextActivity);
} }
bool ShouldLandAtBuilding(Actor self, Actor dest)
{
if (alwaysLand)
return true;
if (heli.Info.RepairBuildings.Contains(dest.Info.Name) && self.GetDamageState() != DamageState.Undamaged)
return true;
return heli.Info.RearmBuildings.Contains(dest.Info.Name) && self.TraitsImplementing<AmmoPool>()
.Any(p => !p.Info.SelfReloads && !p.FullAmmo());
}
} }
} }

View File

@@ -22,13 +22,17 @@ namespace OpenRA.Mods.Common.Activities
{ {
readonly Aircraft plane; readonly Aircraft plane;
readonly AircraftInfo planeInfo; readonly AircraftInfo planeInfo;
readonly bool alwaysLand;
readonly bool abortOnResupply;
bool isCalculated; bool isCalculated;
Actor dest; Actor dest;
WPos w1, w2, w3; WPos w1, w2, w3;
public ReturnToBase(Actor self, Actor dest = null) public ReturnToBase(Actor self, bool abortOnResupply, Actor dest = null, bool alwaysLand = true)
{ {
this.dest = dest; this.dest = dest;
this.alwaysLand = alwaysLand;
this.abortOnResupply = abortOnResupply;
plane = self.Trait<Aircraft>(); plane = self.Trait<Aircraft>();
planeInfo = self.Info.TraitInfo<AircraftInfo>(); planeInfo = self.Info.TraitInfo<AircraftInfo>();
} }
@@ -51,8 +55,6 @@ namespace OpenRA.Mods.Common.Activities
if (dest == null) if (dest == null)
return; return;
plane.MakeReservation(dest);
var landPos = dest.CenterPosition; var landPos = dest.CenterPosition;
var altitude = planeInfo.CruiseAltitude.Length; var altitude = planeInfo.CruiseAltitude.Length;
@@ -94,6 +96,18 @@ namespace OpenRA.Mods.Common.Activities
isCalculated = true; isCalculated = true;
} }
bool ShouldLandAtBuilding(Actor self, Actor dest)
{
if (alwaysLand)
return true;
if (planeInfo.RepairBuildings.Contains(dest.Info.Name) && self.GetDamageState() != DamageState.Undamaged)
return true;
return planeInfo.RearmBuildings.Contains(dest.Info.Name) && self.TraitsImplementing<AmmoPool>()
.Any(p => !p.Info.SelfReloads && !p.FullAmmo());
}
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled || self.IsDead) if (IsCanceled || self.IsDead)
@@ -128,9 +142,17 @@ 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 ResupplyAircraft(self)); if (ShouldLandAtBuilding(self, dest))
landingProcedures.Add(NextActivity); {
plane.MakeReservation(dest);
landingProcedures.Add(new Land(self, Target.FromActor(dest)));
landingProcedures.Add(new ResupplyAircraft(self));
}
if (!abortOnResupply)
landingProcedures.Add(NextActivity);
return ActivityUtils.SequenceActivities(landingProcedures.ToArray()); return ActivityUtils.SequenceActivities(landingProcedures.ToArray());
} }

View File

@@ -42,9 +42,9 @@ namespace OpenRA.Mods.Common.Scripting
public void ReturnToBase(Actor airfield = null) public void ReturnToBase(Actor airfield = null)
{ {
if (isPlane) if (isPlane)
Self.QueueActivity(new ReturnToBase(Self, airfield)); Self.QueueActivity(new ReturnToBase(Self, false, airfield));
else else
Self.QueueActivity(new HeliReturnToBase(Self)); Self.QueueActivity(new HeliReturnToBase(Self, false));
} }
[ScriptActorPropertyActivity] [ScriptActorPropertyActivity]

View File

@@ -69,6 +69,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Does this actor need to turn before landing?")] [Desc("Does this actor need to turn before landing?")]
public readonly bool TurnToLand = false; public readonly bool TurnToLand = false;
[Desc("Does this actor cancel its previous activity after resupplying?")]
public readonly bool AbortOnResupply = true;
public readonly WDist LandAltitude = WDist.Zero; public readonly WDist LandAltitude = WDist.Zero;
[Desc("How fast this actor ascends or descends when using horizontal take off/landing.")] [Desc("How fast this actor ascends or descends when using horizontal take off/landing.")]
@@ -559,9 +562,9 @@ namespace OpenRA.Mods.Common.Traits
if (Reservable.IsReserved(order.TargetActor)) if (Reservable.IsReserved(order.TargetActor))
{ {
if (IsPlane) if (IsPlane)
self.QueueActivity(new ReturnToBase(self)); self.QueueActivity(new ReturnToBase(self, Info.AbortOnResupply));
else else
self.QueueActivity(new HeliReturnToBase(self)); self.QueueActivity(new HeliReturnToBase(self, Info.AbortOnResupply));
} }
else else
{ {
@@ -570,7 +573,7 @@ namespace OpenRA.Mods.Common.Traits
if (IsPlane) if (IsPlane)
{ {
self.QueueActivity(order.Queued, ActivityUtils.SequenceActivities( self.QueueActivity(order.Queued, ActivityUtils.SequenceActivities(
new ReturnToBase(self, order.TargetActor), new ReturnToBase(self, Info.AbortOnResupply, order.TargetActor),
new ResupplyAircraft(self))); new ResupplyAircraft(self)));
} }
else else
@@ -618,11 +621,9 @@ namespace OpenRA.Mods.Common.Traits
UnReserve(); UnReserve();
self.CancelActivity(); self.CancelActivity();
if (IsPlane) if (IsPlane)
self.QueueActivity(new ReturnToBase(self)); self.QueueActivity(new ReturnToBase(self, Info.AbortOnResupply, null, false));
else else
self.QueueActivity(new HeliReturnToBase(self)); self.QueueActivity(new HeliReturnToBase(self, Info.AbortOnResupply, false));
self.QueueActivity(new ResupplyAircraft(self));
} }
} }

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
var airfield = ReturnToBase.ChooseAirfield(self, true); var airfield = ReturnToBase.ChooseAirfield(self, true);
if (airfield != null) if (airfield != null)
{ {
self.QueueActivity(new ReturnToBase(self, airfield)); self.QueueActivity(new ReturnToBase(self, aircraftInfo.AbortOnResupply, airfield));
self.QueueActivity(new ResupplyAircraft(self)); self.QueueActivity(new ResupplyAircraft(self));
} }
else else