diff --git a/OpenRA.Mods.Common/Activities/Air/HeliFly.cs b/OpenRA.Mods.Common/Activities/Air/HeliFly.cs index 7e0d484846..1af53306f2 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliFly.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliFly.cs @@ -164,7 +164,7 @@ namespace OpenRA.Mods.Common.Activities { if (info.TurnToLand) self.QueueActivity(new Turn(self, info.InitialFacing)); - self.QueueActivity(new HeliLand(self, true)); + self.QueueActivity(new Land(self, true)); activity = NextActivity; } diff --git a/OpenRA.Mods.Common/Activities/Air/HeliLand.cs b/OpenRA.Mods.Common/Activities/Air/HeliLand.cs deleted file mode 100644 index 163a37fc17..0000000000 --- a/OpenRA.Mods.Common/Activities/Air/HeliLand.cs +++ /dev/null @@ -1,81 +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.Activities; -using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Activities -{ - public class HeliLand : Activity - { - readonly Aircraft aircraft; - readonly WDist landAltitude; - readonly bool requireSpace; - readonly Actor ignoreActor; - - bool soundPlayed; - bool landingInitiated; - - public HeliLand(Actor self, bool requireSpace, Actor ignoreActor = null) - : this(self, requireSpace, self.Trait().LandAltitude, ignoreActor) { } - - public HeliLand(Actor self, bool requireSpace, WDist landAltitude, Actor ignoreActor = null) - { - this.requireSpace = requireSpace; - this.landAltitude = landAltitude; - this.ignoreActor = ignoreActor; - aircraft = self.Trait(); - } - - public override Activity Tick(Actor self) - { - if (ChildActivity != null) - { - ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); - if (ChildActivity != null) - return this; - } - - if (IsCanceling) - { - aircraft.RemoveInfluence(); - return NextActivity; - } - - if (requireSpace && !landingInitiated) - { - var landingCell = self.Location; - if (!aircraft.CanLand(landingCell, ignoreActor)) - { - QueueChild(self, new Wait(25), true); - self.NotifyBlocker(landingCell); - return this; - } - - aircraft.AddInfluence(landingCell); - aircraft.EnteringCell(self); - landingInitiated = true; - } - - if (!soundPlayed && aircraft.Info.LandingSounds.Length > 0 && !self.IsAtGroundLevel()) - { - Game.Sound.Play(SoundType.World, aircraft.Info.LandingSounds, self.World, aircraft.CenterPosition); - soundPlayed = true; - } - - if (HeliFly.AdjustAltitude(self, aircraft, landAltitude)) - return this; - - return NextActivity; - } - } -} diff --git a/OpenRA.Mods.Common/Activities/Air/Land.cs b/OpenRA.Mods.Common/Activities/Air/Land.cs index 21634666a4..1ac4a7ee9b 100644 --- a/OpenRA.Mods.Common/Activities/Air/Land.cs +++ b/OpenRA.Mods.Common/Activities/Air/Land.cs @@ -21,18 +21,33 @@ namespace OpenRA.Mods.Common.Activities readonly Aircraft aircraft; readonly bool requireSpace; readonly Actor ignoreActor; + readonly WDist landAltitude; + readonly bool ignoreTarget; bool landingInitiated; bool soundPlayed; - public Land(Actor self, Target t, bool requireSpace, Actor ignoreActor = null) + public Land(Actor self, Target t, bool requireSpace, WDist landAltitude, Actor ignoreActor = null) { target = t; aircraft = self.Trait(); this.requireSpace = requireSpace; this.ignoreActor = ignoreActor; + this.landAltitude = landAltitude != WDist.Zero ? landAltitude : aircraft.Info.LandAltitude; } + public Land(Actor self, Target t, bool requireSpace, Actor ignoreActor = null) + : this(self, t, requireSpace, WDist.Zero, ignoreActor) { } + + public Land(Actor self, bool requireSpace, WDist landAltitude, Actor ignoreActor = null) + : this(self, Target.FromPos(self.CenterPosition), requireSpace, landAltitude, ignoreActor) + { + ignoreTarget = true; + } + + public Land(Actor self, bool requireSpace, Actor ignoreActor = null) + : this(self, requireSpace, WDist.Zero, ignoreActor) { } + public override Activity Tick(Actor self) { if (ChildActivity != null) @@ -42,8 +57,11 @@ namespace OpenRA.Mods.Common.Activities return this; } - if (!target.IsValidFor(self)) + if (!ignoreTarget && !target.IsValidFor(self)) + { + Cancel(self); return NextActivity; + } if (IsCanceling) { @@ -53,11 +71,13 @@ namespace OpenRA.Mods.Common.Activities if (requireSpace && !landingInitiated) { - var landingCell = self.World.Map.CellContaining(target.CenterPosition); + var landingCell = !aircraft.Info.VTOL ? self.World.Map.CellContaining(target.CenterPosition) : self.Location; if (!aircraft.CanLand(landingCell, ignoreActor)) { // Maintain holding pattern. - QueueChild(self, new FlyCircle(self, 25), true); + if (!aircraft.Info.CanHover) + QueueChild(self, new FlyCircle(self, 25), true); + self.NotifyBlocker(landingCell); return this; } @@ -67,12 +87,22 @@ namespace OpenRA.Mods.Common.Activities landingInitiated = true; } - if (!soundPlayed && aircraft.Info.LandingSounds.Length > 0 && !self.IsAtGroundLevel()) + var altitude = self.World.Map.DistanceAboveTerrain(self.CenterPosition); + if (aircraft.Info.VTOL) { - Game.Sound.Play(SoundType.World, aircraft.Info.LandingSounds, self.World, aircraft.CenterPosition); - soundPlayed = true; + var landAlt = !ignoreTarget ? self.World.Map.DistanceAboveTerrain(target.CenterPosition) : landAltitude; + if (!soundPlayed && aircraft.Info.LandingSounds.Length > 0 && altitude != landAlt) + PlayLandingSound(self); + + if (HeliFly.AdjustAltitude(self, aircraft, landAlt)) + return this; + + return NextActivity; } + if (!soundPlayed && aircraft.Info.LandingSounds.Length > 0 && altitude != landAltitude) + PlayLandingSound(self); + var d = target.CenterPosition - self.CenterPosition; // The next move would overshoot, so just set the final position @@ -88,5 +118,11 @@ namespace OpenRA.Mods.Common.Activities return this; } + + void PlayLandingSound(Actor self) + { + Game.Sound.Play(SoundType.World, aircraft.Info.LandingSounds, self.World, aircraft.CenterPosition); + soundPlayed = true; + } } } diff --git a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs index 820c1431ff..d79e88860f 100644 --- a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs +++ b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs @@ -192,7 +192,7 @@ namespace OpenRA.Mods.Common.Activities if (aircraft.Info.TurnToLand) Queue(self, new Turn(self, aircraft.Info.InitialFacing)); - Queue(self, new HeliLand(self, true)); + Queue(self, new Land(self, true)); return NextActivity; } else @@ -230,7 +230,7 @@ namespace OpenRA.Mods.Common.Activities if (aircraft.Info.TurnToDock) QueueChild(self, new Turn(self, aircraft.Info.InitialFacing), true); - QueueChild(self, new HeliLand(self, true, dest), true); + QueueChild(self, new Land(self, true, dest), true); } else QueueChild(self, new Land(self, Target.FromPos(dest.CenterPosition + offset), true, dest), true); diff --git a/OpenRA.Mods.Common/Activities/DeliverUnit.cs b/OpenRA.Mods.Common/Activities/DeliverUnit.cs index 6426fa054d..f86a358fd3 100644 --- a/OpenRA.Mods.Common/Activities/DeliverUnit.cs +++ b/OpenRA.Mods.Common/Activities/DeliverUnit.cs @@ -109,7 +109,7 @@ namespace OpenRA.Mods.Common.Activities // Make sure that the carried actor is on the ground before releasing it if (self.World.Map.DistanceAboveTerrain(carryablePosition) != WDist.Zero) - QueueChild(self, new HeliLand(self, true), true); + QueueChild(self, new Land(self, true), true); // Pause briefly before releasing for visual effect if (carryall.Info.UnloadingDelay > 0) diff --git a/OpenRA.Mods.Common/Activities/PickupUnit.cs b/OpenRA.Mods.Common/Activities/PickupUnit.cs index 3d6c8942a5..8a4fb5ee36 100644 --- a/OpenRA.Mods.Common/Activities/PickupUnit.cs +++ b/OpenRA.Mods.Common/Activities/PickupUnit.cs @@ -126,7 +126,7 @@ namespace OpenRA.Mods.Common.Activities if (targetPosition.Z != self.CenterPosition.Z) { - QueueChild(self, new HeliLand(self, false, self.World.Map.DistanceAboveTerrain(targetPosition)), true); + QueueChild(self, new Land(self, false, self.World.Map.DistanceAboveTerrain(targetPosition)), true); return this; } diff --git a/OpenRA.Mods.Common/Activities/Transform.cs b/OpenRA.Mods.Common/Activities/Transform.cs index 11c79d862f..33ad62235d 100644 --- a/OpenRA.Mods.Common/Activities/Transform.cs +++ b/OpenRA.Mods.Common/Activities/Transform.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Activities QueueChild(self, new Turn(self, Facing)); if (self.Info.HasTraitInfo()) - QueueChild(self, new HeliLand(self, true)); + QueueChild(self, new Land(self, true)); } public override Activity Tick(Actor self) diff --git a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs index e4d6d33e27..f896287798 100644 --- a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs @@ -183,7 +183,7 @@ namespace OpenRA.Mods.Common.Scripting Move(transport, destination); transport.QueueActivity(new Turn(transport, aircraft.Info.InitialFacing)); - transport.QueueActivity(new HeliLand(transport, true)); + transport.QueueActivity(new Land(transport, true)); } else { diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 231d0b94c3..e42b18537f 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -314,14 +314,14 @@ namespace OpenRA.Mods.Common.Traits // Add land activity if LandOnCondidion resolves to true and the actor can land at the current location. if (!ForceLanding && landNow.HasValue && landNow.Value && airborne && CanLand(self.Location) - && !(self.CurrentActivity is HeliLand || self.CurrentActivity is Turn)) + && !((self.CurrentActivity is Land && Info.VTOL) || self.CurrentActivity is Turn)) { self.CancelActivity(); if (Info.TurnToLand) self.QueueActivity(new Turn(self, Info.InitialFacing)); - self.QueueActivity(new HeliLand(self, true)); + self.QueueActivity(new Land(self, true)); ForceLanding = true; } @@ -625,7 +625,7 @@ namespace OpenRA.Mods.Common.Traits if (Info.TurnToLand) self.QueueActivity(new Turn(self, Info.InitialFacing)); - self.QueueActivity(new HeliLand(self, true)); + self.QueueActivity(new Land(self, true)); } else if (!Info.CanHover && !atLandAltitude) self.QueueActivity(new FlyCircle(self, -1, Info.IdleTurnSpeed > -1 ? Info.IdleTurnSpeed : TurnSpeed)); @@ -815,7 +815,7 @@ namespace OpenRA.Mods.Common.Traits if (!Info.VTOL) return new Land(self, target, false); - return new HeliLand(self, false); + return new Land(self, false); } public Activity VisualMove(Actor self, WPos fromPos, WPos toPos) diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index ffe477f135..cfbabc2c69 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -193,7 +193,7 @@ namespace OpenRA.Mods.Common.Traits Unloading = true; if (aircraft != null) - self.QueueActivity(new HeliLand(self, true)); + self.QueueActivity(new Land(self, true)); self.QueueActivity(new UnloadCargo(self, true)); } }