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/AirstrikePower.cs b/OpenRA.Mods.RA/SupportPowers/AirstrikePower.cs index eadeeba275..6c88987efd 100644 --- a/OpenRA.Mods.RA/SupportPowers/AirstrikePower.cs +++ b/OpenRA.Mods.RA/SupportPowers/AirstrikePower.cs @@ -29,13 +29,6 @@ namespace OpenRA.Mods.RA public readonly int QuantizedFacings = 32; public readonly WRange Cordon = new WRange(5120); - [ActorReference] - [Desc("Actor to spawn when the aircraft first enter the map")] - public readonly string FlareActor = null; - - [Desc("Amount of time to keep the flare alive after the aircraft have finished attacking")] - public readonly int FlareRemoveDelay = 25; - [ActorReference] [Desc("Actor to spawn when the aircraft start attacking")] public readonly string CameraActor = null; @@ -68,7 +61,6 @@ namespace OpenRA.Mods.RA var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Range * delta / 1024; var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Range * delta / 1024; - Actor flare = null; Actor camera = null; Beacon beacon = null; var aircraftInRange = new Dictionary(); @@ -104,7 +96,7 @@ namespace OpenRA.Mods.RA { aircraftInRange[a] = false; - // Remove the camera and flare when the final plane leaves the target area + // Remove the camera when the final plane leaves the target area if (!aircraftInRange.Any(kv => kv.Value)) { if (camera != null) @@ -113,27 +105,12 @@ namespace OpenRA.Mods.RA camera.QueueActivity(new RemoveSelf()); } - if (flare != null) - { - flare.QueueActivity(new Wait(info.FlareRemoveDelay)); - flare.QueueActivity(new RemoveSelf()); - } - - camera = flare = null; + camera = null; } }; self.World.AddFrameEndTask(w => { - if (info.FlareActor != null) - { - flare = w.CreateActor(info.FlareActor, new TypeDictionary - { - new LocationInit(order.TargetLocation), - new OwnerInit(self.Owner), - }); - } - var notification = self.Owner.IsAlliedWith(self.World.RenderPlayer) ? Info.LaunchSound : Info.IncomingSound; Sound.Play(notification); 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/cnc/maps/gdi03/map.yaml b/mods/cnc/maps/gdi03/map.yaml index a440d23c35..1380b2abc8 100644 --- a/mods/cnc/maps/gdi03/map.yaml +++ b/mods/cnc/maps/gdi03/map.yaml @@ -991,7 +991,6 @@ Rules: IncomingSound: enemya.aud UnitType: a10 DisplayBeacon: True - BeaconDuration: -1 BeaconPoster: airstrike DisplayRadarPing: True CameraActor: camera diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index 251cf083e9..62a41172c7 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -435,7 +435,6 @@ HQ: IncomingSound: enemya.aud UnitType: a10 DisplayBeacon: True - BeaconDuration: -1 BeaconPoster: airstrike DisplayRadarPing: True CameraActor: camera @@ -550,7 +549,6 @@ TMPL: IncomingSound: nuke1.aud MissileWeapon: atomic DisplayBeacon: True - BeaconDuration: -1 BeaconPoster: atomic DisplayRadarPing: True CameraActor: camera diff --git a/mods/d2k/rules/atreides.yaml b/mods/d2k/rules/atreides.yaml index b99146f77c..520999e40b 100644 --- a/mods/d2k/rules/atreides.yaml +++ b/mods/d2k/rules/atreides.yaml @@ -60,7 +60,6 @@ PALACEA: UnitType: orni.bomber SelectTargetSound: DisplayBeacon: True - BeaconDuration: -1 CameraActor: camera CanPowerDown: DisabledOverlay: diff --git a/mods/d2k/rules/harkonnen.yaml b/mods/d2k/rules/harkonnen.yaml index 2fc05e8d94..0ccdcf70dd 100644 --- a/mods/d2k/rules/harkonnen.yaml +++ b/mods/d2k/rules/harkonnen.yaml @@ -98,7 +98,6 @@ PALACEH: SpawnOffset: -512,1c171,0 DisplayBeacon: True DisplayRadarPing: True - BeaconDuration: -1 CameraActor: camera CanPowerDown: DisabledOverlay: diff --git a/mods/d2k/rules/ordos.yaml b/mods/d2k/rules/ordos.yaml index 434a772e14..241b40a6a8 100644 --- a/mods/d2k/rules/ordos.yaml +++ b/mods/d2k/rules/ordos.yaml @@ -89,7 +89,6 @@ PALACEO: UnitType: orni.bomber SelectTargetSound: DisplayBeacon: True - BeaconDuration: -1 CameraActor: camera CanPowerDown: DisabledOverlay: diff --git a/mods/ra/bits/lores-camicon.shp b/mods/ra/bits/lores-camicon.shp new file mode 100644 index 0000000000..671b7f6b10 Binary files /dev/null and b/mods/ra/bits/lores-camicon.shp differ diff --git a/mods/ra/bits/lores-pbmbicon.shp b/mods/ra/bits/lores-pbmbicon.shp new file mode 100644 index 0000000000..e37c64dae8 Binary files /dev/null and b/mods/ra/bits/lores-pbmbicon.shp differ 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/misc.yaml b/mods/ra/rules/misc.yaml index 93051c793f..b6bc7b3d11 100644 --- a/mods/ra/rules/misc.yaml +++ b/mods/ra/rules/misc.yaml @@ -251,7 +251,10 @@ powerproxy.parabombs: AllowMultiple: yes UnitType: badr.bomber SelectTargetSound: slcttgt1.aud - FlareActor: flare + QuantizedFacings: 8 + DisplayBeacon: True + BeaconPoster: pbmbicon + CameraActor: camera powerproxy.sonarpulse: SonarPulsePower: diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 82ad7a130a..a672f2b043 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -37,7 +37,6 @@ MSLO: SpawnOffset: 0,427,0 DisplayTimer: True DisplayBeacon: True - BeaconDuration: -1 DisplayRadarPing: True BeaconPoster: atomicon CameraActor: camera @@ -891,13 +890,19 @@ 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 + QuantizedFacings: 8 + DisplayBeacon: True + BeaconPoster: camicon ParatroopersPower: Icon: paratroopers ChargeTime: 360 diff --git a/mods/ra/sequences/misc.yaml b/mods/ra/sequences/misc.yaml index b0408434aa..09c34989e3 100644 --- a/mods/ra/sequences/misc.yaml +++ b/mods/ra/sequences/misc.yaml @@ -129,6 +129,14 @@ beacon: Start: 0 Length: * Offset: 0,-42 + pbmbicon: lores-pbmbicon + Start: 0 + Length: * + Offset: 0,-42 + camicon: lores-camicon + Start: 0 + Length: * + Offset: 0,-42 clock: beaconclock Start: 0 Length: *