Add LandOnCondition to the trait Aircraft which triggers a landing and prevents takeoffs while the condition is met

This commit is contained in:
Jean-Rémy Buchs
2017-06-03 00:48:28 +02:00
committed by atlimit8
parent c4d2fdbd83
commit 1d1802a163
13 changed files with 126 additions and 2 deletions

View File

@@ -57,6 +57,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (plane.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (IsCanceled || !target.IsValidFor(self))
return NextActivity;

View File

@@ -36,6 +36,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (!target.IsValidFor(self))
return NextActivity;

View File

@@ -28,6 +28,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (plane.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (IsCanceled)
return NextActivity;

View File

@@ -32,6 +32,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (plane.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (IsCanceled || !target.IsValidFor(self))
return NextActivity;

View File

@@ -25,6 +25,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (plane.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (IsCanceled || !self.World.Map.Contains(self.Location))
return NextActivity;

View File

@@ -29,6 +29,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (plane.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (IsCanceled || remainingTicks-- == 0)
return NextActivity;

View File

@@ -52,6 +52,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (helicopter.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (IsCanceled || !target.IsValidFor(self))
return NextActivity;

View File

@@ -54,6 +54,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (helicopter.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (IsCanceled || !target.IsValidFor(self))
return NextActivity;

View File

@@ -27,6 +27,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (helicopter.ForceLanding)
{
Cancel(self);
return NextActivity;
}
if (IsCanceled)
return NextActivity;

View File

@@ -42,6 +42,11 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
// Special case: Don't kill other deploy hotkey activities.
if (heli.ForceLanding)
return NextActivity;
if (IsCanceled)
return NextActivity;

View File

@@ -110,6 +110,11 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
// Special case: Don't kill other deploy hotkey activities.
if (plane.ForceLanding)
return NextActivity;
if (IsCanceled || self.IsDead)
return NextActivity;

View File

@@ -28,6 +28,13 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding)
{
Cancel(self);
return NextActivity;
}
aircraft.UnReserve();
var host = aircraft.GetActorBelow();

View File

@@ -17,6 +17,7 @@ using OpenRA.Activities;
using OpenRA.Mods.Common.Activities;
using OpenRA.Mods.Common.Orders;
using OpenRA.Primitives;
using OpenRA.Support;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
@@ -39,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly int TurnSpeed = 255;
public readonly int Speed = 1;
[Desc("Minimum altitude where this aircraft is considered airborne")]
[Desc("Minimum altitude where this aircraft is considered airborne.")]
public readonly int MinAirborneAltitude = 1;
public readonly HashSet<string> LandableTerrainTypes = new HashSet<string>();
@@ -100,6 +101,9 @@ namespace OpenRA.Mods.Common.Traits
yield return new FacingInit(PreviewFacing);
}
[Desc("Condition when this aircraft should land as soon as possible and refuse to take off.")]
public readonly BooleanExpression LandOnCondition;
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary<CPos, SubCell>(); }
bool IOccupySpaceInfo.SharesCell { get { return false; } }
@@ -124,7 +128,7 @@ namespace OpenRA.Mods.Common.Traits
}
public class Aircraft : ITick, ISync, IFacing, IPositionable, IMove, IIssueOrder, IResolveOrder, IOrderVoice, IDeathActorInitModifier,
INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing, IActorPreviewInitModifier, IIssueDeployOrder
INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing, IActorPreviewInitModifier, IIssueDeployOrder, IObservesVariables
{
static readonly Pair<CPos, SubCell>[] NoCells = { };
@@ -142,6 +146,7 @@ namespace OpenRA.Mods.Common.Traits
public int TurnSpeed { get { return Info.TurnSpeed; } }
public Actor ReservedActor { get; private set; }
public bool MayYieldReservation { get; private set; }
public bool ForceLanding { get; private set; }
bool airborne;
bool cruising;
@@ -152,6 +157,7 @@ namespace OpenRA.Mods.Common.Traits
bool isMoving;
bool isMovingVertically;
WPos cachedPosition;
bool? landNow;
public Aircraft(ActorInitializer init, AircraftInfo info)
{
@@ -171,6 +177,17 @@ namespace OpenRA.Mods.Common.Traits
IsPlane = !info.CanHover;
}
public virtual IEnumerable<VariableObserver> GetVariableObservers()
{
if (Info.LandOnCondition != null)
yield return new VariableObserver(ForceLandConditionChanged, Info.LandOnCondition.Variables);
}
void ForceLandConditionChanged(Actor self, IReadOnlyDictionary<string, int> variables)
{
landNow = Info.LandOnCondition.Evaluate(variables);
}
public void Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
@@ -208,6 +225,33 @@ namespace OpenRA.Mods.Common.Traits
self.QueueActivity(new TakeOff(self));
}
// Add land activity if LandOnCondidion resolves to true and the actor can land at the current location.
if (landNow.HasValue && landNow.Value && airborne && CanLand(self.Location)
&& !(self.CurrentActivity is HeliLand || self.CurrentActivity is Turn))
{
self.CancelActivity();
if (Info.TurnToLand)
self.QueueActivity(new Turn(self, Info.InitialFacing));
self.QueueActivity(new HeliLand(self, true));
ForceLanding = true;
}
// Add takeoff activity if LandOnCondidion resolves to false and the actor should not land when idle.
if (landNow.HasValue && !landNow.Value && !cruising && !(self.CurrentActivity is TakeOff))
{
ForceLanding = false;
if (!Info.LandWhenIdle)
{
self.CancelActivity();
self.QueueActivity(new TakeOff(self));
}
}
var oldCachedPosition = cachedPosition;
cachedPosition = self.CenterPosition;
isMoving = (oldCachedPosition - cachedPosition).HorizontalLengthSquared != 0;