From 4e3d6bde4ff60ad6066f35ca3ac7976cf6ebecd7 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Thu, 6 Aug 2015 18:21:07 +0300 Subject: [PATCH 1/7] Split AircraftMoveOrderTargeter to its own file --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Orders/AircraftMoveOrderTargeter.cs | 48 +++++++++++++++++++ OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 32 ------------- 3 files changed, 49 insertions(+), 32 deletions(-) create mode 100644 OpenRA.Mods.Common/Orders/AircraftMoveOrderTargeter.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 7e29d02214..977388d811 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -201,6 +201,7 @@ + diff --git a/OpenRA.Mods.Common/Orders/AircraftMoveOrderTargeter.cs b/OpenRA.Mods.Common/Orders/AircraftMoveOrderTargeter.cs new file mode 100644 index 0000000000..ee87282d44 --- /dev/null +++ b/OpenRA.Mods.Common/Orders/AircraftMoveOrderTargeter.cs @@ -0,0 +1,48 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 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. For more information, + * see COPYING. + */ +#endregion + +using System.Collections.Generic; +using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Orders +{ + class AircraftMoveOrderTargeter : IOrderTargeter + { + public string OrderID { get { return "Move"; } } + public int OrderPriority { get { return 4; } } + public bool OverrideSelection { get { return false; } } + + readonly AircraftInfo info; + + public AircraftMoveOrderTargeter(AircraftInfo info) { this.info = info; } + + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) + { + if (target.Type != TargetType.Terrain) + return false; + + var location = self.World.Map.CellContaining(target.CenterPosition); + var explored = self.Owner.Shroud.IsExplored(location); + cursor = self.World.Map.Contains(location) ? + (self.World.Map.GetTerrainInfo(location).CustomCursor ?? "move") : + "move-blocked"; + + IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); + + if (!explored && !info.MoveIntoShroud) + cursor = "move-blocked"; + + return true; + } + + public bool IsQueued { get; protected set; } + } +} diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 8c2bb032fa..619a3e545f 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -372,36 +372,4 @@ namespace OpenRA.Mods.Common.Traits } } } - - class AircraftMoveOrderTargeter : IOrderTargeter - { - public string OrderID { get { return "Move"; } } - public int OrderPriority { get { return 4; } } - public bool OverrideSelection { get { return false; } } - - readonly AircraftInfo info; - - public AircraftMoveOrderTargeter(AircraftInfo info) { this.info = info; } - - public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) - { - if (target.Type != TargetType.Terrain) - return false; - - var location = self.World.Map.CellContaining(target.CenterPosition); - var explored = self.Owner.Shroud.IsExplored(location); - cursor = self.World.Map.Contains(location) ? - (self.World.Map.GetTerrainInfo(location).CustomCursor ?? "move") : - "move-blocked"; - - IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - - if (!explored && !info.MoveIntoShroud) - cursor = "move-blocked"; - - return true; - } - - public bool IsQueued { get; protected set; } - } } From 0ee1ad3fa499d44c1fbd726fa62843146afcd289 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Thu, 6 Aug 2015 22:09:17 +0300 Subject: [PATCH 2/7] Add a default value to ReturnToBase's constructor for non-Lua usages --- OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs index fc47f318d9..050b0e0270 100644 --- a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs +++ b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Activities Actor dest; WPos w1, w2, w3; - public ReturnToBase(Actor self, Actor dest) + public ReturnToBase(Actor self, Actor dest = null) { this.dest = dest; plane = self.Trait(); From 8a443666678eacefad2b593a157c265d82599d58 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Thu, 6 Aug 2015 18:33:52 +0300 Subject: [PATCH 3/7] Merge Plane and Helicopter into Aircraft --- .../Traits/Buildings/ProductionAirdrop.cs | 2 +- OpenRA.Mods.Common/Activities/Air/Fly.cs | 6 +- .../Activities/Air/FlyCircle.cs | 5 +- .../Activities/Air/FlyFollow.cs | 4 +- .../Activities/Air/FlyOffMap.cs | 5 +- OpenRA.Mods.Common/Activities/Air/FlyTimed.cs | 5 +- .../Activities/Air/HeliAttack.cs | 5 +- OpenRA.Mods.Common/Activities/Air/HeliFly.cs | 10 +- .../Activities/Air/HeliFlyCircle.cs | 6 +- OpenRA.Mods.Common/Activities/Air/HeliLand.cs | 4 +- .../Activities/Air/HeliReturn.cs | 4 +- OpenRA.Mods.Common/Activities/Air/Land.cs | 4 +- .../Activities/Air/ReturnToBase.cs | 11 +- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 5 +- .../Scripting/Global/ReinforcementsGlobal.cs | 18 +- ...aneProperties.cs => AircraftProperties.cs} | 21 +- .../Properties/HelicopterProperties.cs | 31 -- OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 412 ++++++++++++++---- OpenRA.Mods.Common/Traits/Air/Helicopter.cs | 153 ------- OpenRA.Mods.Common/Traits/Air/Plane.cs | 129 ------ OpenRA.Mods.Common/Traits/Cargo.cs | 8 +- .../Traits/SupportPowers/AirstrikePower.cs | 2 +- OpenRA.Mods.Common/Traits/Transforms.cs | 2 +- .../Traits/World/CrateSpawner.cs | 2 +- OpenRA.Mods.D2k/Activities/DeliverUnit.cs | 6 +- OpenRA.Mods.D2k/Activities/PickupUnit.cs | 6 +- OpenRA.Mods.D2k/Traits/Carryall.cs | 3 +- .../Traits/SupportPowers/ParatroopersPower.cs | 2 +- 28 files changed, 401 insertions(+), 470 deletions(-) rename OpenRA.Mods.Common/Scripting/Properties/{PlaneProperties.cs => AircraftProperties.cs} (60%) delete mode 100644 OpenRA.Mods.Common/Scripting/Properties/HelicopterProperties.cs delete mode 100644 OpenRA.Mods.Common/Traits/Air/Helicopter.cs delete mode 100644 OpenRA.Mods.Common/Traits/Air/Plane.cs diff --git a/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs b/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs index 617640c0bf..1cbd7d5d46 100644 --- a/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs +++ b/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.Cnc.Traits if (!self.IsInWorld || self.IsDead) return; - var altitude = self.World.Map.Rules.Actors[actorType].TraitInfo().CruiseAltitude; + var altitude = self.World.Map.Rules.Actors[actorType].TraitInfo().CruiseAltitude; var actor = w.CreateActor(actorType, new TypeDictionary { new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WDist.Zero, WDist.Zero, altitude)), diff --git a/OpenRA.Mods.Common/Activities/Air/Fly.cs b/OpenRA.Mods.Common/Activities/Air/Fly.cs index 70ada20612..dc955a15e8 100644 --- a/OpenRA.Mods.Common/Activities/Air/Fly.cs +++ b/OpenRA.Mods.Common/Activities/Air/Fly.cs @@ -17,14 +17,14 @@ namespace OpenRA.Mods.Common.Activities { public class Fly : Activity { - readonly Plane plane; + readonly Aircraft plane; readonly Target target; readonly WDist maxRange; readonly WDist minRange; public Fly(Actor self, Target t) { - plane = self.Trait(); + plane = self.Trait(); target = t; } @@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Activities this.minRange = minRange; } - public static void FlyToward(Actor self, Plane plane, int desiredFacing, WDist desiredAltitude) + public static void FlyToward(Actor self, Aircraft plane, int desiredFacing, WDist desiredAltitude) { desiredAltitude = new WDist(plane.CenterPosition.Z) + desiredAltitude - self.World.Map.DistanceAboveTerrain(plane.CenterPosition); diff --git a/OpenRA.Mods.Common/Activities/Air/FlyCircle.cs b/OpenRA.Mods.Common/Activities/Air/FlyCircle.cs index abd86f5bd9..f3af7e605f 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyCircle.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyCircle.cs @@ -10,18 +10,17 @@ using OpenRA.Activities; using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities { public class FlyCircle : Activity { - readonly Plane plane; + readonly Aircraft plane; readonly WDist cruiseAltitude; public FlyCircle(Actor self) { - plane = self.Trait(); + plane = self.Trait(); cruiseAltitude = plane.Info.CruiseAltitude; } diff --git a/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs b/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs index 42a360a0c4..5b717d1af5 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs @@ -17,14 +17,14 @@ namespace OpenRA.Mods.Common.Activities public class FlyFollow : Activity { Target target; - Plane plane; + Aircraft plane; WDist minRange; WDist maxRange; public FlyFollow(Actor self, Target target, WDist minRange, WDist maxRange) { this.target = target; - plane = self.Trait(); + plane = self.Trait(); this.minRange = minRange; this.maxRange = maxRange; } diff --git a/OpenRA.Mods.Common/Activities/Air/FlyOffMap.cs b/OpenRA.Mods.Common/Activities/Air/FlyOffMap.cs index ae14d90ee5..19ea996400 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyOffMap.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyOffMap.cs @@ -10,17 +10,16 @@ using OpenRA.Activities; using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities { public class FlyOffMap : Activity { - readonly Plane plane; + readonly Aircraft plane; public FlyOffMap(Actor self) { - plane = self.Trait(); + plane = self.Trait(); } public override Activity Tick(Actor self) diff --git a/OpenRA.Mods.Common/Activities/Air/FlyTimed.cs b/OpenRA.Mods.Common/Activities/Air/FlyTimed.cs index 0b5dc020be..21de44c4a4 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyTimed.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyTimed.cs @@ -10,20 +10,19 @@ using OpenRA.Activities; using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities { public class FlyTimed : Activity { - readonly Plane plane; + readonly Aircraft plane; readonly WDist cruiseAltitude; int remainingTicks; public FlyTimed(int ticks, Actor self) { remainingTicks = ticks; - plane = self.Trait(); + plane = self.Trait(); cruiseAltitude = plane.Info.CruiseAltitude; } diff --git a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs index 0d501ec01a..e977c6de3f 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs @@ -8,7 +8,6 @@ */ #endregion -using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.Activities; @@ -19,7 +18,7 @@ namespace OpenRA.Mods.Common.Activities { public class HeliAttack : Activity { - readonly Helicopter helicopter; + readonly Aircraft helicopter; readonly AttackHeli attackHeli; readonly AmmoPool[] ammoPools; readonly bool attackOnlyVisibleTargets; @@ -44,7 +43,7 @@ namespace OpenRA.Mods.Common.Activities public HeliAttack(Actor self, Target target, bool attackOnlyVisibleTargets = true) { Target = target; - helicopter = self.Trait(); + helicopter = self.Trait(); attackHeli = self.Trait(); ammoPools = self.TraitsImplementing().ToArray(); this.attackOnlyVisibleTargets = attackOnlyVisibleTargets; diff --git a/OpenRA.Mods.Common/Activities/Air/HeliFly.cs b/OpenRA.Mods.Common/Activities/Air/HeliFly.cs index 1717f87c42..f2578ec13e 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliFly.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliFly.cs @@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Activities { public class HeliFly : Activity { - readonly Helicopter helicopter; + readonly Aircraft helicopter; readonly Target target; readonly WDist maxRange; readonly WDist minRange; @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Activities public HeliFly(Actor self, Target t) { - helicopter = self.Trait(); + helicopter = self.Trait(); target = t; } @@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Activities this.minRange = minRange; } - public static bool AdjustAltitude(Actor self, Helicopter helicopter, WDist targetAltitude) + public static bool AdjustAltitude(Actor self, Aircraft helicopter, WDist targetAltitude) { targetAltitude = new WDist(helicopter.CenterPosition.Z) + targetAltitude - self.World.Map.DistanceAboveTerrain(helicopter.CenterPosition); @@ -105,9 +105,9 @@ namespace OpenRA.Mods.Common.Activities public class HeliFlyAndLandWhenIdle : HeliFly { - private readonly HelicopterInfo info; + private readonly AircraftInfo info; - public HeliFlyAndLandWhenIdle(Actor self, Target t, HelicopterInfo info) + public HeliFlyAndLandWhenIdle(Actor self, Target t, AircraftInfo info) : base(self, t) { this.info = info; diff --git a/OpenRA.Mods.Common/Activities/Air/HeliFlyCircle.cs b/OpenRA.Mods.Common/Activities/Air/HeliFlyCircle.cs index 34b3704103..b414cad8d5 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliFlyCircle.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliFlyCircle.cs @@ -8,8 +8,6 @@ */ #endregion -using System; -using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Traits; @@ -18,11 +16,11 @@ namespace OpenRA.Mods.Common.Activities { public class HeliFlyCircle : Activity { - readonly Helicopter helicopter; + readonly Aircraft helicopter; public HeliFlyCircle(Actor self) { - helicopter = self.Trait(); + helicopter = self.Trait(); } public override Activity Tick(Actor self) diff --git a/OpenRA.Mods.Common/Activities/Air/HeliLand.cs b/OpenRA.Mods.Common/Activities/Air/HeliLand.cs index 4fd677f115..3c9a2310c9 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliLand.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliLand.cs @@ -15,14 +15,14 @@ namespace OpenRA.Mods.Common.Activities { public class HeliLand : Activity { - readonly Helicopter helicopter; + readonly Aircraft helicopter; bool requireSpace; bool playedSound; public HeliLand(Actor self, bool requireSpace) { this.requireSpace = requireSpace; - helicopter = self.Trait(); + helicopter = self.Trait(); } public override Activity Tick(Actor self) diff --git a/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs b/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs index 42cc0da1aa..efc4eb9fef 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs @@ -17,11 +17,11 @@ namespace OpenRA.Mods.Common.Activities { public class HeliReturn : Activity { - readonly Helicopter heli; + readonly Aircraft heli; public HeliReturn(Actor self) { - heli = self.Trait(); + heli = self.Trait(); } public Actor ChooseHelipad(Actor self) diff --git a/OpenRA.Mods.Common/Activities/Air/Land.cs b/OpenRA.Mods.Common/Activities/Air/Land.cs index 762c61a73f..c7ddd74d27 100644 --- a/OpenRA.Mods.Common/Activities/Air/Land.cs +++ b/OpenRA.Mods.Common/Activities/Air/Land.cs @@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities public class Land : Activity { readonly Target target; - readonly Plane plane; + readonly Aircraft plane; public Land(Actor self, Target t) { target = t; - plane = self.Trait(); + plane = self.Trait(); } public override Activity Tick(Actor self) diff --git a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs index 050b0e0270..ff485f4549 100644 --- a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs +++ b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs @@ -18,8 +18,8 @@ namespace OpenRA.Mods.Common.Activities { public class ReturnToBase : Activity { - readonly Plane plane; - readonly PlaneInfo planeInfo; + readonly Aircraft plane; + readonly AircraftInfo planeInfo; bool isCalculated; Actor dest; WPos w1, w2, w3; @@ -27,13 +27,13 @@ namespace OpenRA.Mods.Common.Activities public ReturnToBase(Actor self, Actor dest = null) { this.dest = dest; - plane = self.Trait(); - planeInfo = self.Info.TraitInfo(); + plane = self.Trait(); + planeInfo = self.Info.TraitInfo(); } public static Actor ChooseAirfield(Actor self, bool unreservedOnly) { - var rearmBuildings = self.Info.TraitInfo().RearmBuildings; + var rearmBuildings = self.Info.TraitInfo().RearmBuildings; return self.World.ActorsWithTrait() .Where(a => a.Actor.Owner == self.Owner) .Where(a => rearmBuildings.Contains(a.Actor.Info.Name) @@ -94,7 +94,6 @@ namespace OpenRA.Mods.Common.Activities w1 = posCenter + tangentOffset; w2 = approachCenter + tangentOffset; w3 = approachStart; - plane.RTBPathHash = w1 + (WVec)w2 + (WVec)w3; isCalculated = true; } diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 977388d811..734bfb3fe6 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -205,6 +205,7 @@ + @@ -235,13 +236,11 @@ - - @@ -258,8 +257,6 @@ - - diff --git a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs index 934c2fca76..ec62bf1dd4 100644 --- a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs @@ -137,11 +137,19 @@ namespace OpenRA.Mods.Common.Scripting } else { - var heli = transport.Info.TraitInfoOrDefault(); - if (heli != null) + var aircraftInfo = transport.TraitOrDefault(); + if (aircraftInfo != null) { - transport.QueueActivity(new Turn(transport, heli.InitialFacing)); - transport.QueueActivity(new HeliLand(transport, true)); + if (!aircraftInfo.IsPlane) + { + transport.QueueActivity(new Turn(transport, aircraftInfo.Info.InitialFacing)); + transport.QueueActivity(new HeliLand(transport, true)); + } + else + { + transport.QueueActivity(new Land(transport, Target.FromCell(transport.World, entryPath.Last()))); + } + transport.QueueActivity(new Wait(15)); } @@ -151,7 +159,7 @@ namespace OpenRA.Mods.Common.Scripting transport.QueueActivity(new WaitFor(() => cargo.IsEmpty(transport))); } - transport.QueueActivity(new Wait(heli != null ? 50 : 25)); + transport.QueueActivity(new Wait(aircraftInfo != null ? 50 : 25)); } if (exitFunc != null) diff --git a/OpenRA.Mods.Common/Scripting/Properties/PlaneProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/AircraftProperties.cs similarity index 60% rename from OpenRA.Mods.Common/Scripting/Properties/PlaneProperties.cs rename to OpenRA.Mods.Common/Scripting/Properties/AircraftProperties.cs index a49f21039f..68006b7c5d 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/PlaneProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/AircraftProperties.cs @@ -16,23 +16,34 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Scripting { [ScriptPropertyGroup("Movement")] - public class PlaneProperties : ScriptActorProperties, Requires + public class AircraftProperties : ScriptActorProperties, Requires { - public PlaneProperties(ScriptContext context, Actor self) - : base(context, self) { } + readonly bool isPlane; + + public AircraftProperties(ScriptContext context, Actor self) + : base(context, self) + { + isPlane = self.Trait().IsPlane; + } [ScriptActorPropertyActivity] [Desc("Fly within the cell grid.")] public void Move(CPos cell) { - Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell))); + if (isPlane) + Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell))); + else + Self.QueueActivity(new HeliFly(Self, Target.FromCell(Self.World, cell))); } [ScriptActorPropertyActivity] [Desc("Return to the base, which is either the airfield given, or an auto-selected one otherwise.")] public void ReturnToBase(Actor airfield = null) { - Self.QueueActivity(new ReturnToBase(Self, airfield)); + if (isPlane) + Self.QueueActivity(new ReturnToBase(Self, airfield)); + else + Self.QueueActivity(new HeliReturn(Self)); } } } \ No newline at end of file diff --git a/OpenRA.Mods.Common/Scripting/Properties/HelicopterProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/HelicopterProperties.cs deleted file mode 100644 index eb0e718d63..0000000000 --- a/OpenRA.Mods.Common/Scripting/Properties/HelicopterProperties.cs +++ /dev/null @@ -1,31 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 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. For more information, - * see COPYING. - */ -#endregion - -using OpenRA.Mods.Common.Activities; -using OpenRA.Mods.Common.Traits; -using OpenRA.Scripting; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Scripting -{ - [ScriptPropertyGroup("Movement")] - public class HelicopterProperties : ScriptActorProperties, Requires - { - public HelicopterProperties(ScriptContext context, Actor self) - : base(context, self) { } - - [ScriptActorPropertyActivity] - [Desc("Fly within the cell grid.")] - public void Move(CPos cell) - { - Self.QueueActivity(new HeliFly(Self, Target.FromCell(Self.World, cell))); - } - } -} \ No newline at end of file diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 619a3e545f..59f416f13b 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Common.Activities; @@ -19,7 +20,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - public class AircraftInfo : IPositionableInfo, IFacingInfo, IOccupySpaceInfo, ICruiseAltitudeInfo, UsesInit, UsesInit + public class AircraftInfo : IPositionableInfo, IFacingInfo, IOccupySpaceInfo, IMoveInfo, ICruiseAltitudeInfo, + UsesInit, UsesInit { public readonly WDist CruiseAltitude = new WDist(1280); public readonly WDist IdealSeparation = new WDist(1706); @@ -53,23 +55,51 @@ namespace OpenRA.Mods.Common.Traits [Desc("The upgrades to grant to self while airborne.")] public readonly string[] AirborneUpgrades = { }; + [Desc("Can the actor hover in place mid-air? If not, then the actor will have to remain in motion (circle around).")] + public readonly bool CanHover = false; + + [Desc("Will this actor try to land after it has no more commands?")] + public readonly bool LandWhenIdle = true; + + [Desc("Does this actor need to turn before landing?")] + public readonly bool TurnToLand = false; + + public readonly WDist LandAltitude = WDist.Zero; + + [Desc("How fast this actor ascends or descends when using horizontal take off/landing.")] + public readonly WAngle MaximumPitch = WAngle.FromDegrees(10); + + [Desc("How fast this actor ascends or descends when using vertical take off/landing.")] + public readonly WDist AltitudeVelocity = new WDist(43); + + [Desc("Sound to play when the actor is taking off.")] + public readonly string TakeoffSound = null; + + [Desc("Sound to play when the actor is landing.")] + public readonly string LandingSound = null; + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary(); } bool IOccupySpaceInfo.SharesCell { get { return false; } } } - public class Aircraft : IFacing, IPositionable, ISync, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyCreated, INotifyActorDisposing + public class Aircraft : ITick, ISync, IFacing, IPositionable, IMove, IIssueOrder, IResolveOrder, IOrderVoice, + INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing { static readonly Pair[] NoCells = { }; - readonly AircraftInfo info; + public readonly bool IsPlane; + public readonly AircraftInfo Info; readonly Actor self; + UpgradeManager um; [Sync] public int Facing { get; set; } [Sync] public WPos CenterPosition { get; private set; } public CPos TopLeft { get { return self.World.Map.CellContaining(CenterPosition); } } public IDisposable Reservation; - public int ROT { get { return info.ROT; } } + public int ROT { get { return Info.ROT; } } + + bool airborne; bool IsAirborne { get @@ -85,21 +115,19 @@ namespace OpenRA.Mods.Common.Traits if (um != null) { if (airborne) - foreach (var u in info.AirborneUpgrades) + foreach (var u in Info.AirborneUpgrades) um.GrantUpgrade(self, u, this); else - foreach (var u in info.AirborneUpgrades) + foreach (var u in Info.AirborneUpgrades) um.RevokeUpgrade(self, u, this); } } } - bool airborne = false; - public Aircraft(ActorInitializer init, AircraftInfo info) { - this.info = info; - this.self = init.Self; + Info = info; + self = init.Self; if (init.Contains()) SetPosition(self, init.Get()); @@ -108,10 +136,23 @@ namespace OpenRA.Mods.Common.Traits SetPosition(self, init.Get()); Facing = init.Contains() ? init.Get() : info.InitialFacing; + + // TODO: HACK: This is a hack until we can properly distinquish between airplane and helicopter! + // Or until the activities get unified enough so that it doesn't matter. + IsPlane = !info.CanHover; } public void Created(Actor self) { um = self.TraitOrDefault(); } + public void AddedToWorld(Actor self) + { + self.World.ActorMap.AddInfluence(self, this); + self.World.ActorMap.AddPosition(self, this); + self.World.ScreenMap.Add(self); + if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= Info.MinAirborneAltitude) + IsAirborne = true; + } + bool firstTick = true; public virtual void Tick(Actor self) { @@ -143,24 +184,39 @@ namespace OpenRA.Mods.Common.Traits if (repulsionFacing == -1) return; - var speed = info.RepulsionSpeed != -1 ? info.RepulsionSpeed : MovementSpeed; + var speed = Info.RepulsionSpeed != -1 ? Info.RepulsionSpeed : MovementSpeed; SetPosition(self, CenterPosition + FlyStep(speed, repulsionFacing)); } public virtual WVec GetRepulsionForce() { - if (!info.Repulsable) + if (!Info.Repulsable) return WVec.Zero; // Repulsion only applies when we're flying! var altitude = CenterPosition.Z; - if (altitude != info.CruiseAltitude.Length) + if (altitude != Info.CruiseAltitude.Length) return WVec.Zero; - return self.World.FindActorsInCircle(self.CenterPosition, info.IdealSeparation) - .Where(a => !a.IsDead && a.Info.HasTraitInfo() && a.Info.TraitInfo().CruiseAltitude == info.CruiseAltitude) + var repulsionForce = self.World.FindActorsInCircle(self.CenterPosition, Info.IdealSeparation) + .Where(a => !a.IsDead && a.Info.HasTraitInfo() + && a.Info.TraitInfo().CruiseAltitude == Info.CruiseAltitude) .Select(GetRepulsionForce) .Aggregate(WVec.Zero, (a, b) => a + b); + + if (Info.CanHover) + return repulsionForce; + + // Non-hovering actors mush always keep moving forward, so they need extra calculations. + var currentDir = FlyStep(Facing); + var length = currentDir.HorizontalLength * repulsionForce.HorizontalLength; + if (length == 0) + return WVec.Zero; + + var dot = WVec.Dot(currentDir, repulsionForce) / length; + + // avoid stalling the plane + return dot >= 0 ? repulsionForce : WVec.Zero; } public WVec GetRepulsionForce(Actor other) @@ -170,7 +226,7 @@ namespace OpenRA.Mods.Common.Traits var d = self.CenterPosition - other.CenterPosition; var distSq = d.HorizontalLengthSquared; - if (distSq > info.IdealSeparation.LengthSquared) + if (distSq > Info.IdealSeparation.LengthSquared) return WVec.Zero; if (distSq < 1) @@ -219,78 +275,13 @@ namespace OpenRA.Mods.Common.Traits } } - public void Disposing(Actor self) - { - UnReserve(); - } - - public void SetPosition(Actor self, WPos pos) - { - CenterPosition = pos; - - if (self.IsInWorld) - { - self.World.ScreenMap.Update(self); - self.World.ActorMap.UpdatePosition(self, this); - IsAirborne = self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= info.MinAirborneAltitude; - } - } - - // Changes position, but not altitude - public void SetPosition(Actor self, CPos cell, SubCell subCell = SubCell.Any) - { - SetPosition(self, self.World.Map.CenterOfCell(cell) + new WVec(0, 0, CenterPosition.Z)); - } - - public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos); } - - public void AddedToWorld(Actor self) - { - self.World.ActorMap.AddInfluence(self, this); - self.World.ActorMap.AddPosition(self, this); - self.World.ScreenMap.Add(self); - if (self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= info.MinAirborneAltitude) - IsAirborne = true; - } - - public void RemovedFromWorld(Actor self) - { - UnReserve(); - self.World.ActorMap.RemoveInfluence(self, this); - self.World.ActorMap.RemovePosition(self, this); - self.World.ScreenMap.Remove(self); - IsAirborne = false; - } - public bool AircraftCanEnter(Actor a) { if (self.AppearsHostileTo(a)) return false; - return info.RearmBuildings.Contains(a.Info.Name) - || info.RepairBuildings.Contains(a.Info.Name); - } - - public bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any) { return false; } // TODO: Handle landing - public SubCell GetValidSubCell(SubCell preferred) { return SubCell.Invalid; } - public SubCell GetAvailableSubCell(CPos a, SubCell preferredSubCell = SubCell.Any, Actor ignoreActor = null, bool checkTransientActors = true) - { - // Does not use any subcell - return SubCell.Invalid; - } - - public bool CanEnterCell(CPos cell, Actor ignoreActor = null, bool checkTransientActors = true) { return true; } - - public bool CanEnterTargetNow(Actor self, Target target) - { - if (target.Positions.Any(p => self.World.ActorMap.GetUnitsAt(self.World.Map.CellContaining(p)).Any(a => a != self && a != target.Actor))) - return false; - var res = target.Actor.TraitOrDefault(); - if (res == null) - return true; - UnReserve(); - Reservation = res.Reserve(target.Actor, self, this); - return true; + return Info.RearmBuildings.Contains(a.Info.Name) + || Info.RepairBuildings.Contains(a.Info.Name); } public int MovementSpeed @@ -299,7 +290,7 @@ namespace OpenRA.Mods.Common.Traits { var modifiers = self.TraitsImplementing() .Select(m => m.GetSpeedModifier()); - return Util.ApplyPercentageModifiers(info.Speed, modifiers); + return Util.ApplyPercentageModifiers(Info.Speed, modifiers); } } @@ -325,18 +316,151 @@ namespace OpenRA.Mods.Common.Traits return false; var type = self.World.Map.GetTerrainInfo(cell).Type; - return info.LandableTerrainTypes.Contains(type); + return Info.LandableTerrainTypes.Contains(type); } public virtual IEnumerable GetResupplyActivities(Actor a) { var name = a.Info.Name; - if (info.RearmBuildings.Contains(name)) + if (Info.RearmBuildings.Contains(name)) yield return new Rearm(self); - if (info.RepairBuildings.Contains(name)) + if (Info.RepairBuildings.Contains(name)) yield return new Repair(a); } + #region Implement IPositionable + + public bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any) { return false; } // TODO: Handle landing + public bool CanEnterCell(CPos cell, Actor ignoreActor = null, bool checkTransientActors = true) { return true; } + public SubCell GetValidSubCell(SubCell preferred) { return SubCell.Invalid; } + public SubCell GetAvailableSubCell(CPos a, SubCell preferredSubCell = SubCell.Any, Actor ignoreActor = null, bool checkTransientActors = true) + { + // Does not use any subcell + return SubCell.Invalid; + } + + public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos); } + + // Changes position, but not altitude + public void SetPosition(Actor self, CPos cell, SubCell subCell = SubCell.Any) + { + SetPosition(self, self.World.Map.CenterOfCell(cell) + new WVec(0, 0, CenterPosition.Z)); + } + + public void SetPosition(Actor self, WPos pos) + { + CenterPosition = pos; + + if (!self.IsInWorld) + return; + + self.World.ScreenMap.Update(self); + self.World.ActorMap.UpdatePosition(self, this); + IsAirborne = self.World.Map.DistanceAboveTerrain(CenterPosition).Length >= Info.MinAirborneAltitude; + } + + #endregion + + #region Implement IMove + + public Activity MoveTo(CPos cell, int nearEnough) + { + if (IsPlane) + return new FlyAndContinueWithCirclesWhenIdle(self, Target.FromCell(self.World, cell)); + + return new HeliFly(self, Target.FromCell(self.World, cell)); + } + + public Activity MoveTo(CPos cell, Actor ignoredActor) + { + if (IsPlane) + return new FlyAndContinueWithCirclesWhenIdle(self, Target.FromCell(self.World, cell)); + + return new HeliFly(self, Target.FromCell(self.World, cell)); + } + + public Activity MoveWithinRange(Target target, WDist range) + { + if (IsPlane) + return new FlyAndContinueWithCirclesWhenIdle(self, target, WDist.Zero, range); + + return new HeliFly(self, target, WDist.Zero, range); + } + + public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange) + { + if (IsPlane) + return new FlyAndContinueWithCirclesWhenIdle(self, target, minRange, maxRange); + + return new HeliFly(self, target, minRange, maxRange); + } + + public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange) + { + if (IsPlane) + return new FlyFollow(self, target, minRange, maxRange); + + return new Follow(self, target, minRange, maxRange); + } + + public Activity MoveIntoWorld(Actor self, CPos cell, SubCell subCell = SubCell.Any) + { + if (IsPlane) + return new Fly(self, Target.FromCell(self.World, cell)); + + return new HeliFly(self, Target.FromCell(self.World, cell, subCell)); + } + + public Activity MoveToTarget(Actor self, Target target) + { + if (IsPlane) + return new Fly(self, target, WDist.FromCells(3), WDist.FromCells(5)); + + return Util.SequenceActivities(new HeliFly(self, target), new Turn(self, Info.InitialFacing)); + } + + public Activity MoveIntoTarget(Actor self, Target target) + { + if (IsPlane) + return new Land(self, target); + + return new HeliLand(self, false); + } + + public Activity VisualMove(Actor self, WPos fromPos, WPos toPos) + { + // TODO: Ignore repulsion when moving + if (IsPlane) + return Util.SequenceActivities( + new CallFunc(() => SetVisualPosition(self, fromPos)), + new Fly(self, Target.FromPos(toPos))); + + return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)), + new HeliFly(self, Target.FromPos(toPos))); + } + + public CPos NearestMoveableCell(CPos cell) { return cell; } + + public bool IsMoving { get { return self.CenterPosition.Z > 0; } set { } } + + public bool CanEnterTargetNow(Actor self, Target target) + { + if (target.Positions.Any(p => self.World.ActorMap.GetUnitsAt(self.World.Map.CellContaining(p)).Any(a => a != self && a != target.Actor))) + return false; + + var res = target.Actor.TraitOrDefault(); + if (res == null) + return true; + + UnReserve(); + Reservation = res.Reserve(target.Actor, self, this); + return true; + } + + #endregion + + #region Implement order interfaces + public IEnumerable Orders { get @@ -344,7 +468,7 @@ namespace OpenRA.Mods.Common.Traits yield return new EnterAlliedActorTargeter("Enter", 5, target => AircraftCanEnter(target), target => !Reservable.IsReserved(target)); - yield return new AircraftMoveOrderTargeter(info); + yield return new AircraftMoveOrderTargeter(Info); } } @@ -367,9 +491,119 @@ namespace OpenRA.Mods.Common.Traits case "Enter": case "ReturnToBase": case "Stop": - return info.Voice; + return Info.Voice; default: return null; } } + + public void ResolveOrder(Actor self, Order order) + { + if (order.OrderString == "Move") + { + var cell = self.World.Map.Clamp(order.TargetLocation); + + if (!Info.MoveIntoShroud && !self.Owner.Shroud.IsExplored(cell)) + return; + + if (!order.Queued) + UnReserve(); + + var target = Target.FromCell(self.World, cell); + + self.SetTargetLine(target, Color.Green); + + if (IsPlane) + self.QueueActivity(order.Queued, new FlyAndContinueWithCirclesWhenIdle(self, target)); + else + self.QueueActivity(order.Queued, new HeliFlyAndLandWhenIdle(self, target, Info)); + } + else if (order.OrderString == "Enter") + { + if (!order.Queued) + UnReserve(); + + if (Reservable.IsReserved(order.TargetActor)) + { + if (IsPlane) + self.QueueActivity(new ReturnToBase(self)); + else + self.QueueActivity(new HeliReturn(self)); + } + else + { + self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green); + + if (IsPlane) + { + self.QueueActivity(order.Queued, Util.SequenceActivities( + new ReturnToBase(self, order.TargetActor), + new ResupplyAircraft(self))); + } + else + { + var res = order.TargetActor.TraitOrDefault(); + if (res != null) + Reservation = res.Reserve(order.TargetActor, self, this); + + Action enter = () => + { + var exit = order.TargetActor.Info.TraitInfos().FirstOrDefault(); + var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero; + + self.QueueActivity(new HeliFly(self, Target.FromPos(order.TargetActor.CenterPosition + offset))); + self.QueueActivity(new Turn(self, Info.InitialFacing)); + self.QueueActivity(new HeliLand(self, false)); + self.QueueActivity(new ResupplyAircraft(self)); + self.QueueActivity(new TakeOff(self)); + }; + + self.QueueActivity(order.Queued, new CallFunc(enter)); + } + } + } + else if (order.OrderString == "Stop") + { + UnReserve(); + self.CancelActivity(); + + // TODO: Implement INotifyBecomingIdle instead + if (!IsPlane && Info.LandWhenIdle) + { + if (Info.TurnToLand) + self.QueueActivity(new Turn(self, Info.InitialFacing)); + + self.QueueActivity(new HeliLand(self, true)); + } + } + else if (order.OrderString == "ReturnToBase") + { + UnReserve(); + self.CancelActivity(); + if (IsPlane) + self.QueueActivity(new ReturnToBase(self)); + else + self.QueueActivity(new HeliReturn(self)); + + self.QueueActivity(new ResupplyAircraft(self)); + } + else + UnReserve(); + } + + #endregion + + public void RemovedFromWorld(Actor self) + { + UnReserve(); + self.World.ActorMap.RemoveInfluence(self, this); + self.World.ActorMap.RemovePosition(self, this); + self.World.ScreenMap.Remove(self); + IsAirborne = false; + } + + public void Disposing(Actor self) + { + UnReserve(); + } } } diff --git a/OpenRA.Mods.Common/Traits/Air/Helicopter.cs b/OpenRA.Mods.Common/Traits/Air/Helicopter.cs deleted file mode 100644 index 5402445ade..0000000000 --- a/OpenRA.Mods.Common/Traits/Air/Helicopter.cs +++ /dev/null @@ -1,153 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 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. For more information, - * see COPYING. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using OpenRA.Activities; -using OpenRA.Mods.Common.Activities; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - public class HelicopterInfo : AircraftInfo, IMoveInfo - { - [Desc("Allow the helicopter land after it has no more commands.")] - public readonly bool LandWhenIdle = true; - - [Desc("Allow the helicopter turn before landing.")] - public readonly bool TurnToLand = false; - public readonly WDist LandAltitude = WDist.Zero; - - [Desc("How fast the helicopter ascends or descends.")] - public readonly WDist AltitudeVelocity = new WDist(43); - - public readonly string TakeoffSound = null; - public readonly string LandingSound = null; - - public override object Create(ActorInitializer init) { return new Helicopter(init, this); } - } - - public class Helicopter : Aircraft, ITick, IResolveOrder, IMove - { - public readonly HelicopterInfo Info; - Actor self; - public bool IsMoving { get { return self.CenterPosition.Z > 0; } set { } } - - public Helicopter(ActorInitializer init, HelicopterInfo info) - : base(init, info) - { - self = init.Self; - Info = info; - } - - public void ResolveOrder(Actor self, Order order) - { - if (order.OrderString == "Move") - { - var cell = self.World.Map.Clamp(order.TargetLocation); - var explored = self.Owner.Shroud.IsExplored(cell); - - if (!explored && !Info.MoveIntoShroud) - return; - - var target = Target.FromCell(self.World, cell); - self.SetTargetLine(target, Color.Green); - - if (!order.Queued) - UnReserve(); - - self.QueueActivity(order.Queued, new HeliFlyAndLandWhenIdle(self, target, Info)); - } - else if (order.OrderString == "Enter") - { - Action enter = () => - { - if (Reservable.IsReserved(order.TargetActor)) - self.QueueActivity(order.Queued, new HeliReturn(self)); - else - { - var res = order.TargetActor.TraitOrDefault(); - if (res != null) - Reservation = res.Reserve(order.TargetActor, self, this); - - var exit = order.TargetActor.Info.TraitInfos().FirstOrDefault(); - var offset = (exit != null) ? exit.SpawnOffset : WVec.Zero; - - self.SetTargetLine(Target.FromActor(order.TargetActor), Color.Green); - - self.QueueActivity(new HeliFly(self, Target.FromPos(order.TargetActor.CenterPosition + offset))); - self.QueueActivity(new Turn(self, Info.InitialFacing)); - self.QueueActivity(new HeliLand(self, false)); - self.QueueActivity(new ResupplyAircraft(self)); - self.QueueActivity(new TakeOff(self)); - } - }; - - self.QueueActivity(order.Queued, new CallFunc(enter)); - - if (!order.Queued) - UnReserve(); - } - else - UnReserve(); - - if (order.OrderString == "ReturnToBase") - { - self.CancelActivity(); - self.QueueActivity(new HeliReturn(self)); - } - - if (order.OrderString == "Stop") - { - self.CancelActivity(); - - if (Info.LandWhenIdle) - { - if (Info.TurnToLand) - self.QueueActivity(new Turn(self, Info.InitialFacing)); - - self.QueueActivity(new HeliLand(self, true)); - } - } - } - - public Activity MoveTo(CPos cell, int nearEnough) { return new HeliFly(self, Target.FromCell(self.World, cell)); } - public Activity MoveTo(CPos cell, Actor ignoredActor) { return new HeliFly(self, Target.FromCell(self.World, cell)); } - public Activity MoveWithinRange(Target target, WDist range) { return new HeliFly(self, target, WDist.Zero, range); } - public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange) { return new HeliFly(self, target, minRange, maxRange); } - public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange) { return new Follow(self, target, minRange, maxRange); } - public CPos NearestMoveableCell(CPos cell) { return cell; } - - public Activity MoveIntoWorld(Actor self, CPos cell, SubCell subCell = SubCell.Any) - { - return new HeliFly(self, Target.FromCell(self.World, cell, subCell)); - } - - public Activity MoveIntoTarget(Actor self, Target target) { return new HeliLand(self, false); } - public Activity MoveToTarget(Actor self, Target target) - { - return Util.SequenceActivities(new HeliFly(self, target), new Turn(self, Info.InitialFacing)); - } - - public Activity VisualMove(Actor self, WPos fromPos, WPos toPos) - { - // TODO: Ignore repulsion when moving - return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)), new HeliFly(self, Target.FromPos(toPos))); - } - - public override IEnumerable GetResupplyActivities(Actor a) - { - foreach (var b in base.GetResupplyActivities(a)) - yield return b; - } - } -} diff --git a/OpenRA.Mods.Common/Traits/Air/Plane.cs b/OpenRA.Mods.Common/Traits/Air/Plane.cs deleted file mode 100644 index 2b6a712cd9..0000000000 --- a/OpenRA.Mods.Common/Traits/Air/Plane.cs +++ /dev/null @@ -1,129 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 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. For more information, - * see COPYING. - */ -#endregion - -using System; -using System.Drawing; -using OpenRA.Activities; -using OpenRA.Mods.Common.Activities; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - public class PlaneInfo : AircraftInfo, IMoveInfo - { - public readonly WAngle MaximumPitch = WAngle.FromDegrees(10); - - public override object Create(ActorInitializer init) { return new Plane(init, this); } - } - - public class Plane : Aircraft, IResolveOrder, IMove, ITick, ISync - { - public readonly PlaneInfo Info; - [Sync] public WPos RTBPathHash; - Actor self; - public bool IsMoving { get { return self.CenterPosition.Z > 0; } set { } } - - public Plane(ActorInitializer init, PlaneInfo info) - : base(init, info) - { - self = init.Self; - Info = info; - } - - public override WVec GetRepulsionForce() - { - var repulsionForce = base.GetRepulsionForce(); - if (repulsionForce == WVec.Zero) - return WVec.Zero; - - var currentDir = FlyStep(Facing); - var length = currentDir.HorizontalLength * repulsionForce.HorizontalLength; - if (length == 0) - return WVec.Zero; - - var dot = WVec.Dot(currentDir, repulsionForce) / length; - - // avoid stalling the plane - return dot >= 0 ? repulsionForce : WVec.Zero; - } - - public void ResolveOrder(Actor self, Order order) - { - if (order.OrderString == "Move") - { - var cell = self.World.Map.Clamp(order.TargetLocation); - var explored = self.Owner.Shroud.IsExplored(cell); - - if (!explored && !Info.MoveIntoShroud) - return; - - if (!order.Queued) - UnReserve(); - - var target = Target.FromCell(self.World, cell); - self.SetTargetLine(target, Color.Green); - self.QueueActivity(order.Queued, new FlyAndContinueWithCirclesWhenIdle(self, target)); - } - else if (order.OrderString == "Enter") - { - if (Reservable.IsReserved(order.TargetActor)) - return; - - if (!order.Queued) - UnReserve(); - - self.SetTargetLine(Target.FromOrder(self.World, order), Color.Green); - self.QueueActivity(order.Queued, Util.SequenceActivities(new ReturnToBase(self, order.TargetActor), new ResupplyAircraft(self))); - } - else if (order.OrderString == "Stop") - { - UnReserve(); - self.CancelActivity(); - } - else if (order.OrderString == "ReturnToBase") - { - var airfield = ReturnToBase.ChooseAirfield(self, true); - if (airfield == null) - return; - - UnReserve(); - self.CancelActivity(); - self.SetTargetLine(Target.FromActor(airfield), Color.Green); - self.QueueActivity(new ReturnToBase(self, airfield)); - self.QueueActivity(new ResupplyAircraft(self)); - } - else - { - // Game.Debug("Unreserve due to unhandled order: {0}".F(order.OrderString)); - UnReserve(); - } - } - - public Activity MoveTo(CPos cell, int nearEnough) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell)), new FlyCircle(self)); } - public Activity MoveTo(CPos cell, Actor ignoredActor) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell)), new FlyCircle(self)); } - public Activity MoveWithinRange(Target target, WDist range) { return Util.SequenceActivities(new Fly(self, target, WDist.Zero, range), new FlyCircle(self)); } - public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange) - { - return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle(self)); - } - - public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange) { return new FlyFollow(self, target, minRange, maxRange); } - public CPos NearestMoveableCell(CPos cell) { return cell; } - - public Activity MoveIntoWorld(Actor self, CPos cell, SubCell subCell = SubCell.Any) { return new Fly(self, Target.FromCell(self.World, cell)); } - public Activity VisualMove(Actor self, WPos fromPos, WPos toPos) - { - return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)), new Fly(self, Target.FromPos(toPos))); - } - - public Activity MoveToTarget(Actor self, Target target) { return new Fly(self, target, WDist.FromCells(3), WDist.FromCells(5)); } - public Activity MoveIntoTarget(Actor self, Target target) { return new Land(self, target); } - } -} diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index 437a844fd2..07bb3b5cef 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits int totalWeight = 0; int reservedWeight = 0; - Helicopter helicopter; + Aircraft aircraft; CPos currentCell; public IEnumerable CurrentAdjacentCells { get; private set; } @@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Traits public void Created(Actor self) { - helicopter = self.TraitOrDefault(); + aircraft = self.TraitOrDefault(); } static int GetWeight(Actor a) { return a.Info.TraitInfo().Weight; } @@ -144,7 +144,7 @@ namespace OpenRA.Mods.Common.Traits Unloading = true; self.CancelActivity(); - if (helicopter != null) + if (aircraft != null) self.QueueActivity(new HeliLand(self, true)); self.QueueActivity(new UnloadCargo(self, true)); } @@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.Traits return false; } - return !IsEmpty(self) && (helicopter == null || helicopter.CanLand(self.Location)) + return !IsEmpty(self) && (aircraft == null || aircraft.CanLand(self.Location)) && CurrentAdjacentCells != null && CurrentAdjacentCells.Any(c => Passengers.Any(p => p.Trait().CanEnterCell(c))); } diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs index de7575b4d1..460628c582 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs @@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Traits if (randomize) attackFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings); - var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo().CruiseAltitude.Length; + var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo().CruiseAltitude.Length; var attackRotation = WRot.FromFacing(attackFacing); var delta = new WVec(0, -1024, 0).Rotate(attackRotation); target = target + new WVec(0, 0, altitude); diff --git a/OpenRA.Mods.Common/Traits/Transforms.cs b/OpenRA.Mods.Common/Traits/Transforms.cs index 10f934fd95..3c480ec50e 100644 --- a/OpenRA.Mods.Common/Traits/Transforms.cs +++ b/OpenRA.Mods.Common/Traits/Transforms.cs @@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Traits if (self.Info.HasTraitInfo()) self.QueueActivity(new Turn(self, info.Facing)); - if (self.Info.HasTraitInfo()) + if (self.Info.HasTraitInfo()) self.QueueActivity(new HeliLand(self, true)); foreach (var nt in self.TraitsImplementing()) diff --git a/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs b/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs index 9ead8be8f8..5335b13ad4 100644 --- a/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs +++ b/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs @@ -111,7 +111,7 @@ namespace OpenRA.Mods.Common.Traits var dropFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings); var delta = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(dropFacing)); - var altitude = self.World.Map.Rules.Actors[info.DeliveryAircraft].TraitInfo().CruiseAltitude.Length; + var altitude = self.World.Map.Rules.Actors[info.DeliveryAircraft].TraitInfo().CruiseAltitude.Length; var target = self.World.Map.CenterOfCell(p) + new WVec(0, 0, altitude); var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024; var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Length * delta / 1024; diff --git a/OpenRA.Mods.D2k/Activities/DeliverUnit.cs b/OpenRA.Mods.D2k/Activities/DeliverUnit.cs index b707a59dda..75f058452c 100644 --- a/OpenRA.Mods.D2k/Activities/DeliverUnit.cs +++ b/OpenRA.Mods.D2k/Activities/DeliverUnit.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.D2k.Activities readonly IMove movement; readonly Carryable carryable; readonly Carryall carryall; - readonly Helicopter helicopter; + readonly Aircraft aircraft; readonly IPositionable positionable; readonly IFacing cargoFacing; readonly IFacing selfFacing; @@ -39,7 +39,7 @@ namespace OpenRA.Mods.D2k.Activities cargo = carryall.Carrying; movement = self.Trait(); carryable = cargo.Trait(); - helicopter = self.Trait(); + aircraft = self.Trait(); positionable = cargo.Trait(); cargoFacing = cargo.Trait(); selfFacing = self.Trait(); @@ -95,7 +95,7 @@ namespace OpenRA.Mods.D2k.Activities return this; } - if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.LandAltitude)) + if (HeliFly.AdjustAltitude(self, aircraft, aircraft.Info.LandAltitude)) return this; state = State.Release; return Util.SequenceActivities(new Wait(15), this); diff --git a/OpenRA.Mods.D2k/Activities/PickupUnit.cs b/OpenRA.Mods.D2k/Activities/PickupUnit.cs index 65ad493b9d..52131bcb77 100644 --- a/OpenRA.Mods.D2k/Activities/PickupUnit.cs +++ b/OpenRA.Mods.D2k/Activities/PickupUnit.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.D2k.Activities readonly IMove movement; readonly Carryable carryable; readonly Carryall carryall; - readonly Helicopter helicopter; + readonly Aircraft aircraft; readonly IFacing cargoFacing; readonly IFacing selfFacing; @@ -37,7 +37,7 @@ namespace OpenRA.Mods.D2k.Activities cargoFacing = cargo.Trait(); movement = self.Trait(); carryall = self.Trait(); - helicopter = self.Trait(); + aircraft = self.Trait(); selfFacing = self.Trait(); state = State.Intercept; } @@ -90,7 +90,7 @@ namespace OpenRA.Mods.D2k.Activities state = State.TakeOff; return this; case State.TakeOff: - if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.CruiseAltitude)) + if (HeliFly.AdjustAltitude(self, aircraft, aircraft.Info.CruiseAltitude)) return this; return NextActivity; } diff --git a/OpenRA.Mods.D2k/Traits/Carryall.cs b/OpenRA.Mods.D2k/Traits/Carryall.cs index adc02c0113..382576de31 100644 --- a/OpenRA.Mods.D2k/Traits/Carryall.cs +++ b/OpenRA.Mods.D2k/Traits/Carryall.cs @@ -50,7 +50,8 @@ namespace OpenRA.Mods.D2k.Traits IsBusy = false; IsCarrying = false; - var helicopter = self.Info.TraitInfoOrDefault(); + + var helicopter = self.Info.TraitInfoOrDefault(); carryHeight = helicopter != null ? helicopter.LandAltitude : WDist.Zero; } diff --git a/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs b/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs index dc6e2b06e8..b4e1933790 100644 --- a/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs +++ b/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs @@ -72,7 +72,7 @@ namespace OpenRA.Mods.RA.Traits if (randomize) dropFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings); - var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo().CruiseAltitude.Length; + var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo().CruiseAltitude.Length; var dropRotation = WRot.FromFacing(dropFacing); var delta = new WVec(0, -1024, 0).Rotate(dropRotation); target = target + new WVec(0, 0, altitude); From d55541c5f8162cf2183623f4dd348bd91c478df0 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Wed, 12 Aug 2015 17:42:09 +0300 Subject: [PATCH 4/7] Add an upgrade rule for Plane removal --- .../UtilityCommands/UpgradeRules.cs | 18 +++++++++++++----- mods/cnc/rules/aircraft.yaml | 4 ++-- mods/d2k/rules/aircraft.yaml | 6 +++--- mods/ra/maps/fort-lonestar/map.yaml | 2 +- mods/ra/rules/aircraft.yaml | 10 +++++----- mods/ra/rules/husks.yaml | 8 ++++---- mods/ts/rules/aircraft.yaml | 4 ++-- mods/ts/rules/defaults.yaml | 2 +- 8 files changed, 31 insertions(+), 23 deletions(-) diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 0eb364fba4..067bcc6f92 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -1832,9 +1832,9 @@ namespace OpenRA.Mods.Common.UtilityCommands if (inftraits != null) { node.Value.Nodes.Add(new MiniYamlNode("QuantizeFacingsFromSequence", null, new List - { - new MiniYamlNode("Sequence", "stand"), - })); + { + new MiniYamlNode("Sequence", "stand"), + })); } var other = node.Value.Nodes.FirstOrDefault(x => @@ -2030,7 +2030,8 @@ namespace OpenRA.Mods.Common.UtilityCommands } else cloakedTargetTypes = new MiniYamlNode("TargetTypes", ""); - node.Value.Nodes.Add(new MiniYamlNode("Targetable@UNDERWATER", "", new List { + node.Value.Nodes.Add(new MiniYamlNode("Targetable@UNDERWATER", "", new List + { cloakedTargetTypes, new MiniYamlNode("UpgradeTypes", "underwater"), new MiniYamlNode("UpgradeMinEnabledLevel", "1") @@ -2067,7 +2068,8 @@ namespace OpenRA.Mods.Common.UtilityCommands } else groundTargetTypes = new MiniYamlNode("TargetTypes", ""); - node.Value.Nodes.Add(new MiniYamlNode("Targetable@GROUND", "", new List { + node.Value.Nodes.Add(new MiniYamlNode("Targetable@GROUND", "", new List + { groundTargetTypes, new MiniYamlNode("UpgradeTypes", "airborne"), new MiniYamlNode("UpgradeMaxEnabledLevel", "0") @@ -2175,6 +2177,12 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + if (engineVersion < 20150927) + { + if (depth == 1 && node.Key == "Plane") + node.Key = "Aircraft"; + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/mods/cnc/rules/aircraft.yaml b/mods/cnc/rules/aircraft.yaml index f9f1be6a11..552ba9566e 100644 --- a/mods/cnc/rules/aircraft.yaml +++ b/mods/cnc/rules/aircraft.yaml @@ -151,7 +151,7 @@ C17: Description: Drops vehicle reinforcements on Airstrips Valued: Cost: 2000 - Plane: + Aircraft: ROT: 5 Speed: 326 Repulsable: False @@ -188,7 +188,7 @@ A10: Description: Used to deliver air strikes. Valued: Cost: 2000 - Plane: + Aircraft: ROT: 4 Speed: 373 Repulsable: False diff --git a/mods/d2k/rules/aircraft.yaml b/mods/d2k/rules/aircraft.yaml index 2893928317..0ff58461a3 100644 --- a/mods/d2k/rules/aircraft.yaml +++ b/mods/d2k/rules/aircraft.yaml @@ -51,7 +51,7 @@ frigate: Tooltip: Name: Frigate Description: Supply spacecraft - Plane: + Aircraft: ROT: 1 Speed: 126 RepairBuildings: repair_pad @@ -75,7 +75,7 @@ ornithopter: HP: 900 Armor: Type: light - Plane: + Aircraft: ROT: 2 Speed: 189 RepairBuildings: @@ -93,7 +93,7 @@ ornithopter.husk: Inherits: ^AircraftHusk Tooltip: Name: Ornithopter - Plane: + Aircraft: ROT: 5 Speed: 189 RepairBuildings: diff --git a/mods/ra/maps/fort-lonestar/map.yaml b/mods/ra/maps/fort-lonestar/map.yaml index 5220ceee8c..c1966d92ac 100644 --- a/mods/ra/maps/fort-lonestar/map.yaml +++ b/mods/ra/maps/fort-lonestar/map.yaml @@ -719,7 +719,7 @@ Rules: HP: 60 Armor: Type: Light - Plane: + Aircraft: ROT: 5 Speed: 280 AmmoPool: diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index a75cd3b636..9f1b6179ad 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -6,7 +6,7 @@ BADR: HP: 300 Armor: Type: Light - Plane: + Aircraft: CruiseAltitude: 2560 ROT: 5 Speed: 149 @@ -44,7 +44,7 @@ BADR.Bomber: HP: 300 Armor: Type: Light - Plane: + Aircraft: CruiseAltitude: 2560 ROT: 5 Speed: 149 @@ -100,7 +100,7 @@ MIG: LocalYaw: -40, 24 AttackPlane: FacingTolerance: 20 - Plane: + Aircraft: CruiseAltitude: 2560 InitialFacing: 192 ROT: 4 @@ -162,7 +162,7 @@ YAK: MuzzleSequence: muzzle AttackPlane: FacingTolerance: 20 - Plane: + Aircraft: CruiseAltitude: 2560 RearmBuildings: afld InitialFacing: 192 @@ -342,7 +342,7 @@ U2: HP: 2000 Armor: Type: Heavy - Plane: + Aircraft: CruiseAltitude: 2560 ROT: 7 Speed: 373 diff --git a/mods/ra/rules/husks.yaml b/mods/ra/rules/husks.yaml index 7053e6a84e..91f6041088 100644 --- a/mods/ra/rules/husks.yaml +++ b/mods/ra/rules/husks.yaml @@ -117,7 +117,7 @@ BADR.Husk: Inherits: ^PlaneHusk Tooltip: Name: Badger - Plane: + Aircraft: ROT: 5 Speed: 149 AirborneUpgrades: airborne @@ -140,7 +140,7 @@ MIG.Husk: Offset: -598,-683,0 Contrail@2: Offset: -598,683,0 - Plane: + Aircraft: ROT: 5 Speed: 186 AirborneUpgrades: airborne @@ -160,7 +160,7 @@ YAK.Husk: Name: Yak Attack Plane Contrail: Offset: -853,0,0 - Plane: + Aircraft: ROT: 5 Speed: 149 AirborneUpgrades: airborne @@ -213,7 +213,7 @@ HIND.Husk: U2.Husk: Inherits: ^PlaneHusk - Plane: + Aircraft: ROT: 7 Speed: 373 AirborneUpgrades: airborne diff --git a/mods/ts/rules/aircraft.yaml b/mods/ts/rules/aircraft.yaml index 6cdcc566d2..97091249cc 100644 --- a/mods/ts/rules/aircraft.yaml +++ b/mods/ts/rules/aircraft.yaml @@ -115,7 +115,7 @@ ORCAB: Prerequisites: ~gahpad, gatech Selectable: Bounds: 30,24 - Plane: + Aircraft: CruiseAltitude: 3072 MaximumPitch: 120 ROT: 3 @@ -226,7 +226,7 @@ SCRIN: Bounds: 30,24 Voiced: VoiceSet: Scrin - Plane: + Aircraft: MaximumPitch: 90 ROT: 3 Speed: 168 diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index e19d4f97aa..eef8b32259 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -492,7 +492,7 @@ ^Plane: Inherits: ^Aircraft - Plane: + Aircraft: RepairBuildings: gadept RearmBuildings: gahpad, nahpad LandWhenIdle: no From 1ab2a781f133c7e974f61a3c05304419d4557177 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Wed, 12 Aug 2015 18:32:30 +0300 Subject: [PATCH 5/7] Add an upgrade rule for Helicopter removal --- .../UtilityCommands/UpgradeRules.cs | 6 ++++++ mods/cnc/rules/aircraft.yaml | 18 ++++++------------ mods/cnc/rules/defaults.yaml | 6 +++++- mods/d2k/rules/aircraft.yaml | 8 +++++--- mods/d2k/rules/misc.yaml | 2 +- mods/ra/rules/aircraft.yaml | 9 ++++++--- mods/ra/rules/husks.yaml | 9 ++++++--- mods/ts/rules/aircraft.yaml | 18 ++++++------------ mods/ts/rules/defaults.yaml | 3 ++- 9 files changed, 43 insertions(+), 36 deletions(-) diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 067bcc6f92..6a861cf6ce 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -2181,6 +2181,12 @@ namespace OpenRA.Mods.Common.UtilityCommands { if (depth == 1 && node.Key == "Plane") node.Key = "Aircraft"; + + if (depth == 1 && node.Key == "Helicopter") + { + node.Key = "Aircraft"; + node.Value.Nodes.Add(new MiniYamlNode("CanHover", "True")); + } } UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); diff --git a/mods/cnc/rules/aircraft.yaml b/mods/cnc/rules/aircraft.yaml index 552ba9566e..d4f868b4eb 100644 --- a/mods/cnc/rules/aircraft.yaml +++ b/mods/cnc/rules/aircraft.yaml @@ -9,14 +9,13 @@ TRAN: BuildPaletteOrder: 10 Prerequisites: hpad Queue: Aircraft.GDI, Aircraft.Nod - Helicopter: + Aircraft: LandWhenIdle: true ROT: 5 Speed: 140 InitialFacing: 0 LandableTerrainTypes: Clear,Rough,Road,Ore,Beach,Tiberium,BlueTiberium AltitudeVelocity: 0c100 - AirborneUpgrades: airborne Health: HP: 90 Armor: @@ -53,11 +52,10 @@ HELI: BuildPaletteOrder: 20 Prerequisites: hpad, anyhq, ~techlevel.medium Queue: Aircraft.Nod - Helicopter: + Aircraft: RearmBuildings: hpad ROT: 4 Speed: 186 - AirborneUpgrades: airborne Health: HP: 125 Armor: @@ -105,11 +103,10 @@ ORCA: BuildPaletteOrder: 20 Prerequisites: hpad, anyhq, ~techlevel.medium Queue: Aircraft.GDI - Helicopter: + Aircraft: RearmBuildings: hpad ROT: 4 Speed: 186 - AirborneUpgrades: airborne Health: HP: 90 Armor: @@ -221,10 +218,9 @@ TRAN.Husk: Inherits: ^HelicopterHusk Tooltip: Name: Chinook Transport - Helicopter: + Aircraft: ROT: 5 Speed: 140 - AirborneUpgrades: airborne RevealsShroud: Range: 8c0 Type: CenterPosition @@ -239,10 +235,9 @@ HELI.Husk: Inherits: ^HelicopterHusk Tooltip: Name: Apache Longbow - Helicopter: + Aircraft: ROT: 4 Speed: 186 - AirborneUpgrades: airborne RevealsShroud: Range: 10c0 Type: CenterPosition @@ -255,10 +250,9 @@ ORCA.Husk: Inherits: ^HelicopterHusk Tooltip: Name: Orca - Helicopter: + Aircraft: ROT: 4 Speed: 186 - AirborneUpgrades: airborne RevealsShroud: Range: 10c0 Type: CenterPosition diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 314542ad34..55ef7abde5 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -131,11 +131,12 @@ SelectionDecorations: Selectable: Bounds: 24,24 - Helicopter: + Aircraft: RepairBuildings: hpad RearmBuildings: LandWhenIdle: false AirborneUpgrades: airborne + CanHover: True HiddenUnderFog: Type: CenterPosition ActorLostNotification: @@ -664,6 +665,9 @@ ^HelicopterHusk: Inherits: ^CommonHuskDefaults WithShadow: + Aircraft: + AirborneUpgrades: airborne + CanHover: True FallsToEarth: Spins: True Moves: False diff --git a/mods/d2k/rules/aircraft.yaml b/mods/d2k/rules/aircraft.yaml index 0ff58461a3..228295b9ae 100644 --- a/mods/d2k/rules/aircraft.yaml +++ b/mods/d2k/rules/aircraft.yaml @@ -9,7 +9,7 @@ carryall.reinforce: HP: 4800 Armor: Type: light - Helicopter: + Aircraft: CruiseAltitude: 2100 InitialFacing: 0 ROT: 4 @@ -21,6 +21,7 @@ carryall.reinforce: LandAltitude: 100 LandWhenIdle: False AirborneUpgrades: airborne + CanHover: True Targetable@GROUND: TargetTypes: Ground, Vehicle UpgradeTypes: airborne @@ -66,7 +67,6 @@ frigate: ornithopter: Inherits: ^Plane - Targetable: TargetTypes: Air AttackBomber: Armament: @@ -81,6 +81,7 @@ ornithopter: RepairBuildings: RearmBuildings: Repulsable: False + CanHover: True AmmoPool: Ammo: 5 Tooltip: @@ -105,11 +106,12 @@ carryall.husk: Inherits: ^AircraftHusk Tooltip: Name: Carryall - Helicopter: + Aircraft: ROT: 4 Speed: 112 RepairBuildings: RearmBuildings: + CanHover: True RenderSprites: Image: carryall diff --git a/mods/d2k/rules/misc.yaml b/mods/d2k/rules/misc.yaml index bd0481364e..aca636b6d1 100644 --- a/mods/d2k/rules/misc.yaml +++ b/mods/d2k/rules/misc.yaml @@ -131,7 +131,7 @@ waypoint: ^carryall.colorpicker: Inherits: carryall - Helicopter: + Aircraft: InitialFacing: 104 RenderSprites: Image: carryall diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index 9f1b6179ad..0711c1a1af 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -212,7 +212,7 @@ TRAN: RevealsShroud: Range: 12c0 Type: CenterPosition - Helicopter: + Aircraft: RearmBuildings: hpad InitialFacing: 0 ROT: 5 @@ -220,6 +220,7 @@ TRAN: LandableTerrainTypes: Clear,Rough,Road,Ore,Beach AltitudeVelocity: 0c100 AirborneUpgrades: airborne + CanHover: True WithRotor@PRIMARY: Offset: -597,0,341 Sequence: rotor2 @@ -260,13 +261,14 @@ HELI: LocalOffset: 0,213,-85 AttackHeli: FacingTolerance: 20 - Helicopter: + Aircraft: RearmBuildings: hpad LandWhenIdle: false InitialFacing: 20 ROT: 4 Speed: 149 AirborneUpgrades: airborne + CanHover: True AutoTarget: InitialStance: HoldFire WithRotor: @@ -312,13 +314,14 @@ HIND: MuzzleSequence: muzzle AttackHeli: FacingTolerance: 20 - Helicopter: + Aircraft: RearmBuildings: hpad LandWhenIdle: false InitialFacing: 20 ROT: 4 Speed: 112 AirborneUpgrades: airborne + CanHover: True AutoTarget: InitialStance: HoldFire WithRotor: diff --git a/mods/ra/rules/husks.yaml b/mods/ra/rules/husks.yaml index 91f6041088..9a52b37dc1 100644 --- a/mods/ra/rules/husks.yaml +++ b/mods/ra/rules/husks.yaml @@ -85,10 +85,11 @@ TRAN.Husk: Inherits: ^HelicopterHusk Tooltip: Name: Transport Helicopter - Helicopter: + Aircraft: ROT: 4 Speed: 149 AirborneUpgrades: airborne + CanHover: True WithRotor@PRIMARY: Offset: -597,0,341 WithRotor@SECONDARY: @@ -178,10 +179,11 @@ HELI.Husk: Inherits: ^HelicopterHusk Tooltip: Name: Longbow - Helicopter: + Aircraft: ROT: 4 Speed: 149 AirborneUpgrades: airborne + CanHover: True WithRotor: Offset: 0,0,85 SmokeTrailWhenDamaged: @@ -197,10 +199,11 @@ HIND.Husk: Inherits: ^HelicopterHusk Tooltip: Name: Hind - Helicopter: + Aircraft: ROT: 4 Speed: 112 AirborneUpgrades: airborne + CanHover: True WithRotor: SmokeTrailWhenDamaged: Offset: -427,0,0 diff --git a/mods/ts/rules/aircraft.yaml b/mods/ts/rules/aircraft.yaml index 97091249cc..9310cec3aa 100644 --- a/mods/ts/rules/aircraft.yaml +++ b/mods/ts/rules/aircraft.yaml @@ -4,13 +4,12 @@ DPOD: Cost: 10 Tooltip: Name: Drop Pod - Helicopter: + Aircraft: LandWhenIdle: yes ROT: 5 Speed: 149 InitialFacing: 0 LandableTerrainTypes: Clear - AirborneUpgrades: airborne Health: HP: 60 Armor: @@ -40,7 +39,7 @@ DSHP: Cost: 1000 Tooltip: Name: Dropship - Helicopter: + Aircraft: LandWhenIdle: yes ROT: 5 Speed: 168 @@ -48,7 +47,6 @@ DSHP: LandableTerrainTypes: Clear TakeoffSound: dropup1.aud LandingSound: dropdwn1.aud - AirborneUpgrades: airborne Health: HP: 200 Armor: @@ -76,11 +74,10 @@ ORCA: Prerequisites: ~gahpad Selectable: Bounds: 30,24 - Helicopter: + Aircraft: RearmBuildings: gahpad, nahpad ROT: 5 Speed: 186 - AirborneUpgrades: airborne Health: HP: 200 Armor: @@ -155,7 +152,7 @@ ORCATRAN: BuildPaletteOrder: 10 Prerequisites: ~disabled RenderSprites: - Helicopter: + Aircraft: LandWhenIdle: yes ROT: 5 Speed: 84 @@ -163,7 +160,6 @@ ORCATRAN: LandableTerrainTypes: Clear TakeoffSound: dropup1.aud LandingSound: dropdwn1.aud - AirborneUpgrades: airborne Health: HP: 200 Armor: @@ -189,7 +185,7 @@ TRNSPORT: Queue: Air BuildPaletteOrder: 10 Prerequisites: ~gahpad, gadept - Helicopter: + Aircraft: LandWhenIdle: yes ROT: 5 Speed: 149 @@ -198,7 +194,6 @@ TRNSPORT: TakeoffSound: dropup1.aud LandingSound: dropdwn1.aud AltitudeVelocity: 64 - AirborneUpgrades: airborne Health: HP: 175 Armor: @@ -265,11 +260,10 @@ APACHE: Prerequisites: ~nahpad Selectable: Bounds: 30,24 - Helicopter: + Aircraft: RearmBuildings: gahpad, nahpad ROT: 5 Speed: 130 - AirborneUpgrades: airborne Health: HP: 225 Armor: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index eef8b32259..f7c71144d3 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -482,13 +482,14 @@ ^Helicopter: Inherits: ^Aircraft - Helicopter: + Aircraft: RepairBuildings: gadept RearmBuildings: LandWhenIdle: no CruiseAltitude: 2048 Voice: Move AirborneUpgrades: airborne + CanHover: True ^Plane: Inherits: ^Aircraft From 15a5bde7e7e05cfee950d9ded0283ab5427320ba Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Thu, 13 Aug 2015 01:41:48 +0300 Subject: [PATCH 6/7] Don't stop rearming if ordered to "Stop" while rearming This one actually fixes a bug. --- OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 59f416f13b..8ab5610403 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -563,8 +563,14 @@ namespace OpenRA.Mods.Common.Traits } else if (order.OrderString == "Stop") { - UnReserve(); self.CancelActivity(); + if (GetActorBelow() != null) + { + self.QueueActivity(new ResupplyAircraft(self)); + return; + } + + UnReserve(); // TODO: Implement INotifyBecomingIdle instead if (!IsPlane && Info.LandWhenIdle) From 0ee38de4bb684a8d06f63ac055085a54b4803d19 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Sat, 5 Sep 2015 18:01:35 +0300 Subject: [PATCH 7/7] Rename HeliReturn Rename HeliReturn to HeliReturnToBase to keep somewhat with the convention established for Plane- against Heli- oriented traits. --- OpenRA.Mods.Common/Activities/Air/HeliAttack.cs | 2 +- .../Activities/Air/{HeliReturn.cs => HeliReturnToBase.cs} | 4 ++-- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 2 +- OpenRA.Mods.Common/Scripting/Properties/AircraftProperties.cs | 2 +- OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) rename OpenRA.Mods.Common/Activities/Air/{HeliReturn.cs => HeliReturnToBase.cs} (96%) diff --git a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs index e977c6de3f..a3964930dd 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs @@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Activities // If all ammo pools are depleted and none reload automatically, return to helipad to reload and then move to next activity // 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 Util.SequenceActivities(new HeliReturn(self), NextActivity); + return Util.SequenceActivities(new HeliReturnToBase(self), NextActivity); var dist = target.CenterPosition - self.CenterPosition; diff --git a/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs b/OpenRA.Mods.Common/Activities/Air/HeliReturnToBase.cs similarity index 96% rename from OpenRA.Mods.Common/Activities/Air/HeliReturn.cs rename to OpenRA.Mods.Common/Activities/Air/HeliReturnToBase.cs index efc4eb9fef..7c9ee1a58a 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliReturnToBase.cs @@ -15,11 +15,11 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities { - public class HeliReturn : Activity + public class HeliReturnToBase : Activity { readonly Aircraft heli; - public HeliReturn(Actor self) + public HeliReturnToBase(Actor self) { heli = self.Trait(); } diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 734bfb3fe6..a049b6dc9f 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -101,7 +101,7 @@ - + diff --git a/OpenRA.Mods.Common/Scripting/Properties/AircraftProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/AircraftProperties.cs index 68006b7c5d..747f19d2ab 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/AircraftProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/AircraftProperties.cs @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Scripting if (isPlane) Self.QueueActivity(new ReturnToBase(Self, airfield)); else - Self.QueueActivity(new HeliReturn(Self)); + Self.QueueActivity(new HeliReturnToBase(Self)); } } } \ No newline at end of file diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 8ab5610403..620d732280 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -527,7 +527,7 @@ namespace OpenRA.Mods.Common.Traits if (IsPlane) self.QueueActivity(new ReturnToBase(self)); else - self.QueueActivity(new HeliReturn(self)); + self.QueueActivity(new HeliReturnToBase(self)); } else { @@ -588,7 +588,7 @@ namespace OpenRA.Mods.Common.Traits if (IsPlane) self.QueueActivity(new ReturnToBase(self)); else - self.QueueActivity(new HeliReturn(self)); + self.QueueActivity(new HeliReturnToBase(self)); self.QueueActivity(new ResupplyAircraft(self)); }