Add IdleBehavior enum to Aircraft

This commit is contained in:
reaperrr
2019-06-10 06:05:16 +02:00
committed by abcdefg30
parent d185f6e9f1
commit bfcdb3a8a2
13 changed files with 130 additions and 129 deletions

View File

@@ -21,9 +21,21 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public enum IdleBehaviorType
{
None,
Land,
ReturnToBase,
LeaveMap,
}
public class AircraftInfo : ITraitInfo, IPositionableInfo, IFacingInfo, IMoveInfo, ICruiseAltitudeInfo,
IActorPreviewInitInfo, IEditorActorOptions, IObservesVariablesInfo
{
[Desc("Behavior when aircraft becomes idle. Options are Land, ReturnToBase, LeaveMap, and None.",
"'Land' will behave like 'None' (hover or circle) if a suitable landing site is not available.")]
public readonly IdleBehaviorType IdleBehavior = IdleBehaviorType.None;
public readonly WDist CruiseAltitude = new WDist(1280);
[Desc("Whether the aircraft can be repulsed.")]
@@ -78,9 +90,6 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Does the actor land and take off vertically?")]
public readonly bool VTOL = false;
[Desc("Will this actor try to land after it has no more commands?")]
public readonly bool LandWhenIdle = true;
[Desc("Does this VTOL actor need to turn before landing (on terrain)?")]
public readonly bool TurnToLand = false;
@@ -365,10 +374,9 @@ namespace OpenRA.Mods.Common.Traits
{
ForceLanding = false;
if (!Info.LandWhenIdle)
if (Info.IdleBehavior != IdleBehaviorType.Land)
{
self.CancelActivity();
self.QueueActivity(new TakeOff(self));
}
}
@@ -684,15 +692,31 @@ namespace OpenRA.Mods.Common.Traits
}
}
var isCircler = !Info.CanHover;
if (!atLandAltitude && Info.LandWhenIdle && Info.LandableTerrainTypes.Count > 0)
self.QueueActivity(new Land(self));
else if (isCircler && !atLandAltitude)
self.QueueActivity(new FlyCircle(self, -1, Info.IdleTurnSpeed > -1 ? Info.IdleTurnSpeed : TurnSpeed));
else if (atLandAltitude && !CanLand(self.Location) && ReservedActor == null)
self.QueueActivity(new TakeOff(self));
else if (!atLandAltitude && altitude != Info.CruiseAltitude && !Info.LandWhenIdle)
self.QueueActivity(new TakeOff(self));
if (Info.IdleBehavior == IdleBehaviorType.LeaveMap)
{
self.QueueActivity(new FlyOffMap(self));
self.QueueActivity(new RemoveSelf());
}
else if (Info.IdleBehavior == IdleBehaviorType.ReturnToBase && GetActorBelow() == null)
self.QueueActivity(new ReturnToBase(self, null, !Info.TakeOffOnResupply));
else
{
if (atLandAltitude)
{
if (!CanLand(self.Location) && ReservedActor == null)
self.QueueActivity(new TakeOff(self));
// All remaining idle behaviors rely on not being atLandAltitude, so unconditionally return
return;
}
if (Info.IdleBehavior != IdleBehaviorType.Land && altitude != Info.CruiseAltitude)
self.QueueActivity(new TakeOff(self));
else if (Info.IdleBehavior == IdleBehaviorType.Land && Info.LandableTerrainTypes.Count > 0)
self.QueueActivity(new Land(self));
else if (!Info.CanHover)
self.QueueActivity(new FlyCircle(self, -1, Info.IdleTurnSpeed > -1 ? Info.IdleTurnSpeed : TurnSpeed));
}
}
#region Implement IPositionable

View File

@@ -1,28 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2019 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.Mods.Common.Activities;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Leave the map when idle.")]
class FlyAwayOnIdleInfo : TraitInfo<FlyAwayOnIdle> { }
class FlyAwayOnIdle : INotifyIdle
{
void INotifyIdle.TickIdle(Actor self)
{
self.QueueActivity(new FlyOffMap(self));
self.QueueActivity(new RemoveSelf());
}
}
}

View File

@@ -1,68 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2019 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 System.Linq;
using OpenRA.Mods.Common.Activities;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Return to a player owned RearmActor. If none available, head back to base and circle over it.")]
public class ReturnOnIdleInfo : ITraitInfo, Requires<AircraftInfo>
{
public object Create(ActorInitializer init) { return new ReturnOnIdle(init.Self, this); }
}
public class ReturnOnIdle : INotifyIdle
{
readonly AircraftInfo aircraftInfo;
public ReturnOnIdle(Actor self, ReturnOnIdleInfo info)
{
aircraftInfo = self.Info.TraitInfo<AircraftInfo>();
}
void INotifyIdle.TickIdle(Actor self)
{
// We're on the ground, let's stay there.
if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length < aircraftInfo.MinAirborneAltitude)
return;
var resupplier = ReturnToBase.ChooseResupplier(self, true);
if (resupplier != null)
self.QueueActivity(new ReturnToBase(self, resupplier));
else
{
// nowhere to land, pick something friendly and circle over it.
// I'd prefer something we own
var someBuilding = self.World.ActorsHavingTrait<Building>()
.FirstOrDefault(a => a.Owner == self.Owner);
// failing that, something unlikely to shoot at us
if (someBuilding == null)
someBuilding = self.World.ActorsHavingTrait<Building>()
.FirstOrDefault(a => self.Owner.Stances[a.Owner] == Stance.Ally);
if (someBuilding == null)
{
// ... going down the garden to eat worms ...
self.QueueActivity(new FlyOffMap(self));
self.QueueActivity(new RemoveSelf());
return;
}
self.QueueActivity(new Fly(self, Target.FromActor(someBuilding)));
self.QueueActivity(new FlyCircle(self));
}
}
}
}