diff --git a/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs b/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs index 9397d17ef5..caf4036f9a 100644 --- a/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs +++ b/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs @@ -66,7 +66,8 @@ namespace OpenRA.Mods.Cnc.Traits new FacingInit(64) }); - actor.QueueActivity(new Fly(actor, Target.FromCell(w, self.Location + new CVec(9, 0)))); + var plane = actor.Trait(); + actor.QueueActivity(new Fly(actor, Target.FromCell(w, self.Location + new CVec(9, 0)), plane)); actor.QueueActivity(new Land(actor, Target.FromActor(self))); actor.QueueActivity(new CallFunc(() => { @@ -80,7 +81,7 @@ namespace OpenRA.Mods.Cnc.Traits Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Country.Race); })); - actor.QueueActivity(new Fly(actor, Target.FromCell(w, endPos))); + actor.QueueActivity(new Fly(actor, Target.FromCell(w, endPos), plane)); actor.QueueActivity(new RemoveSelf()); }); diff --git a/OpenRA.Mods.Common/Activities/Air/Fly.cs b/OpenRA.Mods.Common/Activities/Air/Fly.cs index a8460e1c08..2d1edd0266 100644 --- a/OpenRA.Mods.Common/Activities/Air/Fly.cs +++ b/OpenRA.Mods.Common/Activities/Air/Fly.cs @@ -22,14 +22,14 @@ namespace OpenRA.Mods.Common.Activities readonly WRange maxRange; readonly WRange minRange; - public Fly(Actor self, Target t) + public Fly(Actor self, Target t, Plane plane) { - plane = self.Trait(); target = t; + this.plane = plane; } - public Fly(Actor self, Target t, WRange minRange, WRange maxRange) - : this(self, t) + public Fly(Actor self, Target t, Plane plane, WRange minRange, WRange maxRange) + : this(self, t, plane) { this.maxRange = maxRange; this.minRange = minRange; diff --git a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs index ade6867341..1332aa25c7 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs @@ -21,13 +21,16 @@ namespace OpenRA.Mods.Common.Activities { readonly Target target; readonly AttackPlane attackPlane; + readonly Plane plane; readonly IEnumerable ammoPools; Activity inner; - int ticksUntilTurn = 50; + int ticksUntilTurn; - public FlyAttack(Actor self, Target target) + public FlyAttack(Actor self, Target target, Plane plane) { this.target = target; + this.plane = plane; + ticksUntilTurn = plane.Info.AttackTurnDelay; attackPlane = self.TraitOrDefault(); ammoPools = self.TraitsImplementing(); } @@ -52,9 +55,9 @@ namespace OpenRA.Mods.Common.Activities // TODO: This should fire each weapon at its maximum range if (target.IsInRange(self.CenterPosition, attackPlane.Armaments.Select(a => a.Weapon.MinRange).Min())) - inner = Util.SequenceActivities(new FlyTimed(ticksUntilTurn, self), new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); + inner = Util.SequenceActivities(new FlyTimed(ticksUntilTurn, self), new Fly(self, target, plane), new FlyTimed(ticksUntilTurn, self)); else - inner = Util.SequenceActivities(new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); + inner = Util.SequenceActivities(new Fly(self, target, plane), new FlyTimed(ticksUntilTurn, self)); } inner = Util.RunActivity(self, inner); diff --git a/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs b/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs index 7da1c5c1dc..f760cb55ed 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs @@ -21,10 +21,10 @@ namespace OpenRA.Mods.Common.Activities WRange minRange; WRange maxRange; - public FlyFollow(Actor self, Target target, WRange minRange, WRange maxRange) + public FlyFollow(Actor self, Target target, Plane plane, WRange minRange, WRange maxRange) { this.target = target; - plane = self.Trait(); + this.plane = plane; this.minRange = minRange; this.maxRange = maxRange; } @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Activities return this; } - return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), this); + return Util.SequenceActivities(new Fly(self, target, plane, minRange, maxRange), this); } } } diff --git a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs index d342661e34..a6e69998a1 100644 --- a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs +++ b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs @@ -24,11 +24,11 @@ namespace OpenRA.Mods.Common.Activities Actor dest; WPos w1, w2, w3; - public ReturnToBase(Actor self, Actor dest) + public ReturnToBase(Actor self, Actor dest, Plane plane) { this.dest = dest; - plane = self.Trait(); - planeInfo = self.Info.Traits.Get(); + this.plane = plane; + planeInfo = plane.Info; } public static Actor ChooseAirfield(Actor self, bool unreservedOnly) @@ -113,15 +113,15 @@ namespace OpenRA.Mods.Common.Activities self.CancelActivity(); if (nearestAfld != null) - return Util.SequenceActivities(new Fly(self, Target.FromActor(nearestAfld)), new FlyCircle(self)); + return Util.SequenceActivities(new Fly(self, Target.FromActor(nearestAfld), plane), new FlyCircle(self)); else return new FlyCircle(self); } return Util.SequenceActivities( - new Fly(self, Target.FromPos(w1)), - new Fly(self, Target.FromPos(w2)), - new Fly(self, Target.FromPos(w3)), + new Fly(self, Target.FromPos(w1), plane), + new Fly(self, Target.FromPos(w2), plane), + new Fly(self, Target.FromPos(w3), plane), new Land(self, Target.FromActor(dest)), NextActivity); } diff --git a/OpenRA.Mods.Common/Scripting/Properties/PlaneProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/PlaneProperties.cs index 919c5149f9..713f9ea0e4 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/PlaneProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/PlaneProperties.cs @@ -25,14 +25,14 @@ namespace OpenRA.Mods.Common.Scripting [Desc("Fly within the cell grid.")] public void Move(CPos cell) { - Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell))); + Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell), Self.Trait())); } [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)); + Self.QueueActivity(new ReturnToBase(Self, airfield, Self.Trait())); } } @@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Scripting [Desc("Fly an attack against the target actor.")] public void Attack(Actor target) { - Self.QueueActivity(new FlyAttack(Self, Target.FromActor(target))); + Self.QueueActivity(new FlyAttack(Self, Target.FromActor(target), Self.Trait())); } } } \ No newline at end of file diff --git a/OpenRA.Mods.Common/Traits/Air/AttackPlane.cs b/OpenRA.Mods.Common/Traits/Air/AttackPlane.cs index 26f89f4df6..a9b7cde7fd 100644 --- a/OpenRA.Mods.Common/Traits/Air/AttackPlane.cs +++ b/OpenRA.Mods.Common/Traits/Air/AttackPlane.cs @@ -14,19 +14,24 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - public class AttackPlaneInfo : AttackFrontalInfo + public class AttackPlaneInfo : AttackFrontalInfo, Requires { public override object Create(ActorInitializer init) { return new AttackPlane(init.Self, this); } } public class AttackPlane : AttackFrontal { + readonly Plane plane; + public AttackPlane(Actor self, AttackPlaneInfo info) - : base(self, info) { } + : base(self, info) + { + plane = self.Trait(); + } public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) { - return new FlyAttack(self, newTarget); + return new FlyAttack(self, newTarget, plane); } protected override bool CanAttack(Actor self, Target target) diff --git a/OpenRA.Mods.Common/Traits/Air/Plane.cs b/OpenRA.Mods.Common/Traits/Air/Plane.cs index 8e18c49e9d..3a69284681 100644 --- a/OpenRA.Mods.Common/Traits/Air/Plane.cs +++ b/OpenRA.Mods.Common/Traits/Air/Plane.cs @@ -20,6 +20,9 @@ namespace OpenRA.Mods.Common.Traits { public readonly WAngle MaximumPitch = WAngle.FromDegrees(10); + [Desc("Delay, in game ticks, before turning to attack.")] + public readonly int AttackTurnDelay = 50; + public override object Create(ActorInitializer init) { return new Plane(init, this); } } @@ -88,7 +91,7 @@ namespace OpenRA.Mods.Common.Traits var target = Target.FromCell(self.World, cell); self.SetTargetLine(target, Color.Green); self.CancelActivity(); - self.QueueActivity(new Fly(self, target)); + self.QueueActivity(new Fly(self, target, this)); self.QueueActivity(new FlyCircle(self)); } else if (order.OrderString == "Enter") @@ -100,7 +103,7 @@ namespace OpenRA.Mods.Common.Traits self.SetTargetLine(Target.FromOrder(self.World, order), Color.Green); self.CancelActivity(); - self.QueueActivity(new ReturnToBase(self, order.TargetActor)); + self.QueueActivity(new ReturnToBase(self, order.TargetActor, this)); self.QueueActivity(new ResupplyAircraft(self)); } else if (order.OrderString == "Stop") @@ -116,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits UnReserve(); self.CancelActivity(); self.SetTargetLine(Target.FromActor(airfield), Color.Green); - self.QueueActivity(new ReturnToBase(self, airfield)); + self.QueueActivity(new ReturnToBase(self, airfield, this)); self.QueueActivity(new ResupplyAircraft(self)); } else @@ -126,24 +129,24 @@ namespace OpenRA.Mods.Common.Traits } } - 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, WRange range) { return Util.SequenceActivities(new Fly(self, target, WRange.Zero, range), new FlyCircle(self)); } + public Activity MoveTo(CPos cell, int nearEnough) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell), this), new FlyCircle(self)); } + public Activity MoveTo(CPos cell, Actor ignoredActor) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell), this), new FlyCircle(self)); } + public Activity MoveWithinRange(Target target, WRange range) { return Util.SequenceActivities(new Fly(self, target, this, WRange.Zero, range), new FlyCircle(self)); } public Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange) { - return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle(self)); + return Util.SequenceActivities(new Fly(self, target, this, minRange, maxRange), new FlyCircle(self)); } - public Activity MoveFollow(Actor self, Target target, WRange minRange, WRange maxRange) { return new FlyFollow(self, target, minRange, maxRange); } + public Activity MoveFollow(Actor self, Target target, WRange minRange, WRange maxRange) { return new FlyFollow(self, target, this, 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 MoveIntoWorld(Actor self, CPos cell, SubCell subCell = SubCell.Any) { return new Fly(self, Target.FromCell(self.World, cell), this); } public Activity VisualMove(Actor self, WPos fromPos, WPos toPos) { - return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)), new Fly(self, Target.FromPos(toPos))); + return Util.SequenceActivities(new CallFunc(() => SetVisualPosition(self, fromPos)), new Fly(self, Target.FromPos(toPos), this)); } - public Activity MoveToTarget(Actor self, Target target) { return new Fly(self, target, WRange.FromCells(3), WRange.FromCells(5)); } + public Activity MoveToTarget(Actor self, Target target) { return new Fly(self, target, this, WRange.FromCells(3), WRange.FromCells(5)); } public Activity MoveIntoTarget(Actor self, Target target) { return new Land(self, target); } } } diff --git a/OpenRA.Mods.Common/Traits/Air/ReturnOnIdle.cs b/OpenRA.Mods.Common/Traits/Air/ReturnOnIdle.cs index 64c8de885b..6a402f84ec 100644 --- a/OpenRA.Mods.Common/Traits/Air/ReturnOnIdle.cs +++ b/OpenRA.Mods.Common/Traits/Air/ReturnOnIdle.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits var airfield = ReturnToBase.ChooseAirfield(self, true); if (airfield != null) { - self.QueueActivity(new ReturnToBase(self, airfield)); + self.QueueActivity(new ReturnToBase(self, airfield, self.Trait())); self.QueueActivity(new ResupplyAircraft(self)); } else @@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.Traits return; } - self.QueueActivity(new Fly(self, Target.FromActor(someBuilding))); + self.QueueActivity(new Fly(self, Target.FromActor(someBuilding), self.Trait())); self.QueueActivity(new FlyCircle(self)); } } diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs index f75d831fa3..9eb267ba9d 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs @@ -155,8 +155,10 @@ namespace OpenRA.Mods.Common.Traits attack.OnExitedAttackRange += onExitRange; attack.OnRemovedFromWorld += onExitRange; - a.QueueActivity(new Fly(a, Target.FromPos(target + spawnOffset))); - a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset))); + var plane = a.Trait(); + a.QueueActivity(new Fly(a, Target.FromPos(target + spawnOffset), plane)); + a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset), plane)); + a.QueueActivity(new RemoveSelf()); aircraftInRange.Add(a, false); distanceTestActor = a; diff --git a/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs b/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs index bb8fae99cf..de6adf7779 100644 --- a/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs +++ b/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs @@ -123,7 +123,7 @@ namespace OpenRA.Mods.Common.Traits plane.Trait().Load(plane, crate); plane.CancelActivity(); - plane.QueueActivity(new Fly(plane, Target.FromPos(finishEdge))); + plane.QueueActivity(new Fly(plane, Target.FromPos(finishEdge), plane.Trait())); plane.QueueActivity(new RemoveSelf()); } else diff --git a/OpenRA.Mods.RA/Scripting/Properties/ParadropProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/ParadropProperties.cs index dfc5d77b77..f6abe62a2e 100644 --- a/OpenRA.Mods.RA/Scripting/Properties/ParadropProperties.cs +++ b/OpenRA.Mods.RA/Scripting/Properties/ParadropProperties.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Scripting public void Paradrop(CPos cell) { paradrop.SetLZ(cell, true); - Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell))); + Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell), Self.Trait())); Self.QueueActivity(new FlyOffMap(Self)); Self.QueueActivity(new RemoveSelf()); } diff --git a/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs b/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs index 580c6e1d43..e40becfe7e 100644 --- a/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs +++ b/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs @@ -185,8 +185,9 @@ namespace OpenRA.Mods.RA.Traits foreach (var p in passengers) cargo.Load(a, p); - a.QueueActivity(new Fly(a, Target.FromPos(target + spawnOffset))); - a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset))); + var plane = a.Trait(); + a.QueueActivity(new Fly(a, Target.FromPos(target + spawnOffset), plane)); + a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset), plane)); a.QueueActivity(new RemoveSelf()); aircraftInRange.Add(a, false); distanceTestActor = a;