diff --git a/OpenRA.Mods.RA/AttackBomber.cs b/OpenRA.Mods.RA/AttackBomber.cs index c731394cc1..dd943e5fb9 100644 --- a/OpenRA.Mods.RA/AttackBomber.cs +++ b/OpenRA.Mods.RA/AttackBomber.cs @@ -31,6 +31,7 @@ namespace OpenRA.Mods.RA AttackBomberInfo info; [Sync] Target target; [Sync] bool inAttackRange; + [Sync] bool facingTarget = true; public event Action OnRemovedFromWorld = self => { }; public event Action OnEnteredAttackRange = self => { }; @@ -47,8 +48,14 @@ namespace OpenRA.Mods.RA var cp = self.CenterPosition; var bombTarget = Target.FromPos(cp - new WVec(0, 0, cp.Z)); var wasInAttackRange = inAttackRange; + var wasFacingTarget = facingTarget; + inAttackRange = false; + var f = facing.Value.Facing; + var facingToTarget = Util.GetFacing(target.CenterPosition - self.CenterPosition, f); + facingTarget = Math.Abs(facingToTarget - f) % 256 <= info.FacingTolerance; + // Bombs drop anywhere in range foreach (var a in Armaments.Where(a => a.Info.Name == info.Bombs)) { @@ -60,9 +67,7 @@ namespace OpenRA.Mods.RA } // Guns only fire when approaching the target - var f = facing.Value.Facing; - var facingToTarget = Util.GetFacing(target.CenterPosition - self.CenterPosition, f); - if (Math.Abs(facingToTarget - f) % 256 <= info.FacingTolerance) + if (facingTarget) { foreach (var a in Armaments.Where(a => a.Info.Name == info.Guns)) { @@ -75,6 +80,10 @@ namespace OpenRA.Mods.RA } } + // Actors without armaments may want to trigger an action when it passes the target + if (!Armaments.Any()) + inAttackRange = !wasInAttackRange && !facingTarget && wasFacingTarget; + if (inAttackRange && !wasInAttackRange) OnEnteredAttackRange(self); diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 72c741aea3..b6170b9d72 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -352,7 +352,6 @@ - diff --git a/OpenRA.Mods.RA/SupportPowers/SpyPlanePower.cs b/OpenRA.Mods.RA/SupportPowers/SpyPlanePower.cs deleted file mode 100644 index a858b73279..0000000000 --- a/OpenRA.Mods.RA/SupportPowers/SpyPlanePower.cs +++ /dev/null @@ -1,59 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2014 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.RA.Activities; -using OpenRA.Mods.RA.Air; -using OpenRA.Primitives; -using OpenRA.Traits; - -namespace OpenRA.Mods.RA -{ - class SpyPlanePowerInfo : SupportPowerInfo - { - public readonly int RevealTime = 6; // seconds - public override object Create(ActorInitializer init) { return new SpyPlanePower(init.self,this); } - } - - class SpyPlanePower : SupportPower - { - public SpyPlanePower(Actor self, SpyPlanePowerInfo info) : base(self, info) { } - - public override void Activate(Actor self, Order order, SupportPowerManager manager) - { - base.Activate(self, order, manager); - - var enterCell = self.World.Map.ChooseRandomEdgeCell(self.World.SharedRandom); - var altitude = self.World.Map.Rules.Actors["u2"].Traits.Get().CruiseAltitude; - - var plane = self.World.CreateActor("u2", new TypeDictionary - { - new CenterPositionInit(self.World.Map.CenterOfCell(enterCell) + new WVec(WRange.Zero, WRange.Zero, altitude)), - new OwnerInit(self.Owner), - new FacingInit(self.World.Map.FacingBetween(enterCell, order.TargetLocation, 0)) - }); - - plane.CancelActivity(); - plane.QueueActivity(new Fly(plane, Target.FromCell(self.World, order.TargetLocation))); - plane.QueueActivity(new CallFunc(() => plane.World.AddFrameEndTask( w => - { - var camera = w.CreateActor("camera", new TypeDictionary - { - new LocationInit( order.TargetLocation ), - new OwnerInit( self.Owner ), - }); - - camera.QueueActivity(new Wait(25 * ((SpyPlanePowerInfo)Info).RevealTime)); - camera.QueueActivity(new RemoveSelf()); - }))); - plane.QueueActivity(new FlyOffMap()); - plane.QueueActivity(new RemoveSelf()); - } - } -} diff --git a/OpenRA.Utility/UpgradeRules.cs b/OpenRA.Utility/UpgradeRules.cs index e6c7964477..db85cd44a8 100644 --- a/OpenRA.Utility/UpgradeRules.cs +++ b/OpenRA.Utility/UpgradeRules.cs @@ -282,6 +282,27 @@ namespace OpenRA.Utility node.Key = "ParachuteSequence"; } + // SpyPlanePower was removed (use AirstrikePower instead) + if (engineVersion < 20140707) + { + if (depth == 1 && node.Key == "SpyPlanePower") + { + node.Key = "AirstrikePower"; + + var revealTime = 6 * 25; + var revealNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "RevealTime"); + if (revealNode != null) + { + revealTime = int.Parse(revealNode.Value.Value) * 25; + node.Value.Nodes.Remove(revealNode); + } + + node.Value.Nodes.Add(new MiniYamlNode("CameraActor", new MiniYaml("camera"))); + node.Value.Nodes.Add(new MiniYamlNode("CameraRemoveDelay", new MiniYaml(revealTime.ToString()))); + node.Value.Nodes.Add(new MiniYamlNode("UnitType", new MiniYaml("u2"))); + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index adc028ab8a..ca6ea973ac 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -341,6 +341,7 @@ U2: RenderUnit: WithShadow: IronCurtainable: + AttackBomber: -Selectable: -GainsExperience: Contrail@1: diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index f043794e95..da984520d0 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -890,13 +890,16 @@ AFLD: Produces: Plane Reservable: IronCurtainable: - SpyPlanePower: + AirstrikePower: Icon: spyplane ChargeTime: 180 Description: Spy Plane LongDesc: Reveals an area of the map\nand cloaked enemy units. SelectTargetSound: slcttgt1.aud EndChargeSound: spypln1.aud + CameraActor: camera + CameraRemoveDelay: 150 + UnitType: u2 ParatroopersPower: Icon: paratroopers ChargeTime: 360