From 5cdf0e6a67679e6fc18a95ac9f96c7928853627b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sun, 22 Jun 2014 18:02:23 +0200 Subject: [PATCH 1/4] generalize MoveFlash as parametrized SpriteEffect --- .../Effects/{MoveFlash.cs => SpriteEffect.cs} | 14 ++++++++------ OpenRA.Game/OpenRA.Game.csproj | 2 +- .../Widgets/WorldInteractionControllerWidget.cs | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) rename OpenRA.Game/Effects/{MoveFlash.cs => SpriteEffect.cs} (60%) diff --git a/OpenRA.Game/Effects/MoveFlash.cs b/OpenRA.Game/Effects/SpriteEffect.cs similarity index 60% rename from OpenRA.Game/Effects/MoveFlash.cs rename to OpenRA.Game/Effects/SpriteEffect.cs index 63c70814b5..db8c00bfcd 100644 --- a/OpenRA.Game/Effects/MoveFlash.cs +++ b/OpenRA.Game/Effects/SpriteEffect.cs @@ -1,6 +1,6 @@ -#region Copyright & License Information +#region Copyright & License Information /* - * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * 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, @@ -13,15 +13,17 @@ using OpenRA.Graphics; namespace OpenRA.Effects { - public class MoveFlash : IEffect + public class SpriteEffect : IEffect { + string palette; Animation anim; WPos pos; - public MoveFlash(WPos pos, World world) + public SpriteEffect(WPos pos, World world, string sprite, string palette) { this.pos = pos; - anim = new Animation(world, "moveflsh"); + this.palette = palette; + anim = new Animation(world, sprite); anim.PlayThen("idle", () => world.AddFrameEndTask(w => w.Remove(this))); } @@ -32,7 +34,7 @@ namespace OpenRA.Effects public IEnumerable Render(WorldRenderer wr) { - return anim.Render(pos, WVec.Zero, 0, wr.Palette("moveflash"), 1f / wr.Viewport.Zoom); + return anim.Render(pos, WVec.Zero, 0, wr.Palette(palette), 1f / wr.Viewport.Zoom); } } } \ No newline at end of file diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 7a159f5ca3..467a2ffe1b 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -212,7 +212,6 @@ - @@ -243,6 +242,7 @@ + diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index 7dc0ac36ae..fe2ba2bc7b 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -160,7 +160,7 @@ namespace OpenRA.Widgets } else if (o.TargetLocation != CPos.Zero) { - world.AddFrameEndTask(w => w.Add(new MoveFlash(worldRenderer.Position(worldRenderer.Viewport.ViewToWorldPx(mi.Location)), world))); + world.AddFrameEndTask(w => w.Add(new SpriteEffect(worldRenderer.Position(worldRenderer.Viewport.ViewToWorldPx(mi.Location)), world, "moveflsh", "moveflash"))); flashed = true; } } From 43bca0e73df7e2d4c2d91b00324be2bd38a71ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 21 Jun 2014 22:23:54 +0200 Subject: [PATCH 2/4] add the sonar pulse closes #4729 --- .../SupportPowers/SonarPulsePower.cs | 32 ++++++++++++++++--- mods/ra/rules/misc.yaml | 21 +++++++++--- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs b/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs index 621ff46278..f484a69261 100755 --- a/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs +++ b/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * 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, @@ -8,10 +8,22 @@ */ #endregion +using OpenRA.Mods.RA.Activities; +using OpenRA.Mods.RA.Effects; +using OpenRA.Primitives; + namespace OpenRA.Mods.RA { public class SonarPulsePowerInfo : SupportPowerInfo { + [Desc("Actor to spawn to reveal the submarines")] + public readonly string SonarActor = "sonar"; + + [Desc("Amount of time to keep the actor alive")] + public readonly int SonarDuration = 250; + + public readonly string SonarPing = "sonpulse.aud"; + public override object Create(ActorInitializer init) { return new SonarPulsePower(init.self, this); } } @@ -22,10 +34,22 @@ namespace OpenRA.Mods.RA { base.Activate(self, order, manager); - // TODO: Reveal submarines + var info = Info as SonarPulsePowerInfo; - // Should this play for all players? - Sound.Play("sonpulse.aud"); + if (info.SonarActor != null) + { + self.World.AddFrameEndTask(w => + { + var sonar = w.CreateActor(info.SonarActor, new TypeDictionary + { + new LocationInit(order.TargetLocation), + new OwnerInit(self.Owner), + }); + Sound.Play(info.SonarPing, sonar.CenterPosition); + sonar.QueueActivity(new Wait(info.SonarDuration)); + sonar.QueueActivity(new RemoveSelf()); + }); + } } } } diff --git a/mods/ra/rules/misc.yaml b/mods/ra/rules/misc.yaml index 82abbb1ebe..4018d03757 100644 --- a/mods/ra/rules/misc.yaml +++ b/mods/ra/rules/misc.yaml @@ -151,6 +151,20 @@ camera.paradrop: Types: Camera BodyOrientation: +SONAR: + Immobile: + OccupiesSpace: false + Health: + HP: 1000 + RevealsShroud: + Range: 10c0 + ProximityCaptor: + Types: Sonar + BodyOrientation: + DetectCloaked: + Range: 10 + CloakTypes: Underwater + FLARE: Immobile: OccupiesSpace: false @@ -270,10 +284,9 @@ powerproxy.parabombs: powerproxy.sonarpulse: SonarPulsePower: Icon: sonar - Description: Sonar Pulse (Single Use) - LongDesc: Reveals all submarines on the map for a \nshort time. - AllowMultiple: yes - OneShot: yes + Description: Sonar Pulse + LongDesc: Reveals all submarines in the vicinity for a \nshort time. + ChargeTime: 30 EndChargeSound: pulse1.aud SelectTargetSound: slcttgt1.aud From f60fefd5f52dc1b05d10fd1a9908f449085fc19f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Thu, 3 Jul 2014 19:15:04 +0200 Subject: [PATCH 3/4] add a ripple animation based on the move flash --- OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs b/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs index f484a69261..01293151ce 100755 --- a/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs +++ b/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs @@ -8,6 +8,7 @@ */ #endregion +using OpenRA.Effects; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Effects; using OpenRA.Primitives; @@ -24,6 +25,9 @@ namespace OpenRA.Mods.RA public readonly string SonarPing = "sonpulse.aud"; + public readonly string RippleSequence = "moveflsh"; + public readonly string RipplePalette = "moveflash"; + public override object Create(ActorInitializer init) { return new SonarPulsePower(init.self, this); } } @@ -45,7 +49,12 @@ namespace OpenRA.Mods.RA new LocationInit(order.TargetLocation), new OwnerInit(self.Owner), }); + Sound.Play(info.SonarPing, sonar.CenterPosition); + + if (!string.IsNullOrEmpty(info.RippleSequence) && !string.IsNullOrEmpty(info.RipplePalette)) + w.Add(new SpriteEffect(sonar.CenterPosition, w, info.RippleSequence, info.RipplePalette)); + sonar.QueueActivity(new Wait(info.SonarDuration)); sonar.QueueActivity(new RemoveSelf()); }); From 91a076728d952be1849b377bd45f374a257868f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 5 Jul 2014 11:22:30 +0200 Subject: [PATCH 4/4] generalize into SpawnActorPower closes #5724 --- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 2 +- .../SupportPowers/SonarPulsePower.cs | 64 ------------------ .../SupportPowers/SpawnActorPower.cs | 67 +++++++++++++++++++ OpenRA.Utility/UpgradeRules.cs | 7 ++ mods/ra/rules/misc.yaml | 7 +- 5 files changed, 81 insertions(+), 66 deletions(-) delete mode 100755 OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs create mode 100755 OpenRA.Mods.RA/SupportPowers/SpawnActorPower.cs diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index b6170b9d72..6b357803dc 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -351,7 +351,6 @@ - @@ -520,6 +519,7 @@ + diff --git a/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs b/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs deleted file mode 100755 index 01293151ce..0000000000 --- a/OpenRA.Mods.RA/SupportPowers/SonarPulsePower.cs +++ /dev/null @@ -1,64 +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.Effects; -using OpenRA.Mods.RA.Activities; -using OpenRA.Mods.RA.Effects; -using OpenRA.Primitives; - -namespace OpenRA.Mods.RA -{ - public class SonarPulsePowerInfo : SupportPowerInfo - { - [Desc("Actor to spawn to reveal the submarines")] - public readonly string SonarActor = "sonar"; - - [Desc("Amount of time to keep the actor alive")] - public readonly int SonarDuration = 250; - - public readonly string SonarPing = "sonpulse.aud"; - - public readonly string RippleSequence = "moveflsh"; - public readonly string RipplePalette = "moveflash"; - - public override object Create(ActorInitializer init) { return new SonarPulsePower(init.self, this); } - } - - public class SonarPulsePower : SupportPower - { - public SonarPulsePower(Actor self, SonarPulsePowerInfo info) : base(self, info) { } - public override void Activate(Actor self, Order order, SupportPowerManager manager) - { - base.Activate(self, order, manager); - - var info = Info as SonarPulsePowerInfo; - - if (info.SonarActor != null) - { - self.World.AddFrameEndTask(w => - { - var sonar = w.CreateActor(info.SonarActor, new TypeDictionary - { - new LocationInit(order.TargetLocation), - new OwnerInit(self.Owner), - }); - - Sound.Play(info.SonarPing, sonar.CenterPosition); - - if (!string.IsNullOrEmpty(info.RippleSequence) && !string.IsNullOrEmpty(info.RipplePalette)) - w.Add(new SpriteEffect(sonar.CenterPosition, w, info.RippleSequence, info.RipplePalette)); - - sonar.QueueActivity(new Wait(info.SonarDuration)); - sonar.QueueActivity(new RemoveSelf()); - }); - } - } - } -} diff --git a/OpenRA.Mods.RA/SupportPowers/SpawnActorPower.cs b/OpenRA.Mods.RA/SupportPowers/SpawnActorPower.cs new file mode 100755 index 0000000000..a3927557e4 --- /dev/null +++ b/OpenRA.Mods.RA/SupportPowers/SpawnActorPower.cs @@ -0,0 +1,67 @@ +#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.Effects; +using OpenRA.Mods.RA.Activities; +using OpenRA.Mods.RA.Effects; +using OpenRA.Primitives; + +namespace OpenRA.Mods.RA +{ + [Desc("Spawns an actor that stays for a limited amount of time.")] + public class SpawnActorPowerInfo : SupportPowerInfo + { + [Desc("Actor to spawn.")] + public readonly string Actor = null; + + [Desc("Amount of time to keep the actor alive in ticks.")] + public readonly int LifeTime = 250; + + public readonly string DeploySound = null; + + public readonly string EffectSequence = null; + public readonly string EffectPalette = null; + + public override object Create(ActorInitializer init) { return new SpawnActorPower(init.self, this); } + } + + public class SpawnActorPower : SupportPower + { + public SpawnActorPower(Actor self, SpawnActorPowerInfo info) : base(self, info) { } + public override void Activate(Actor self, Order order, SupportPowerManager manager) + { + base.Activate(self, order, manager); + + var info = Info as SpawnActorPowerInfo; + + if (info.Actor != null) + { + self.World.AddFrameEndTask(w => + { + var location = self.World.Map.CenterOfCell(order.TargetLocation); + + Sound.Play(info.DeploySound, location); + + if (!string.IsNullOrEmpty(info.EffectSequence) && !string.IsNullOrEmpty(info.EffectPalette)) + w.Add(new SpriteEffect(location, w, info.EffectSequence, info.EffectPalette)); + + var actor = w.CreateActor(info.Actor, new TypeDictionary + { + new LocationInit(order.TargetLocation), + new OwnerInit(self.Owner), + }); + + actor.QueueActivity(new Wait(info.LifeTime)); + actor.QueueActivity(new RemoveSelf()); + }); + } + } + } +} diff --git a/OpenRA.Utility/UpgradeRules.cs b/OpenRA.Utility/UpgradeRules.cs index e6ad3bd9ca..f1da09e260 100644 --- a/OpenRA.Utility/UpgradeRules.cs +++ b/OpenRA.Utility/UpgradeRules.cs @@ -282,6 +282,13 @@ namespace OpenRA.Utility node.Key = "ParachuteSequence"; } + // SonarPulsePower was implemented as a generic SpawnActorPower + if (engineVersion < 20140703) + { + if (depth == 1 && node.Key == "SonarPulsePower") + node.Key = "SpawnActorPower"; + } + if (engineVersion < 20140707) { // SpyPlanePower was removed (use AirstrikePower instead) diff --git a/mods/ra/rules/misc.yaml b/mods/ra/rules/misc.yaml index 4018d03757..6316d7d81c 100644 --- a/mods/ra/rules/misc.yaml +++ b/mods/ra/rules/misc.yaml @@ -282,13 +282,18 @@ powerproxy.parabombs: CameraActor: camera powerproxy.sonarpulse: - SonarPulsePower: + SpawnActorPower: Icon: sonar Description: Sonar Pulse LongDesc: Reveals all submarines in the vicinity for a \nshort time. ChargeTime: 30 EndChargeSound: pulse1.aud SelectTargetSound: slcttgt1.aud + Actor: sonar + LifeTime: 250 + DeploySound: sonpulse.aud + EffectSequence: moveflsh + EffectPalette: moveflash mpspawn: Immobile: