From 9e91232ca74626e17d9e5591c48cae9f06488115 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Fri, 29 Mar 2019 17:02:10 +0100 Subject: [PATCH] Add DetonationAltitude to NukePower And RemoveMissileOnDetonation boolean. Allows airburst, and optionally missile continuing until it hits the ground (without a second explosion). --- OpenRA.Mods.Common/Projectiles/NukeLaunch.cs | 29 ++++++++++++++----- .../Traits/SupportPowers/NukePower.cs | 9 +++++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/OpenRA.Mods.Common/Projectiles/NukeLaunch.cs b/OpenRA.Mods.Common/Projectiles/NukeLaunch.cs index f8d9211abf..231ed3b9d7 100644 --- a/OpenRA.Mods.Common/Projectiles/NukeLaunch.cs +++ b/OpenRA.Mods.Common/Projectiles/NukeLaunch.cs @@ -33,6 +33,8 @@ namespace OpenRA.Mods.Common.Effects readonly WPos ascendTarget; readonly WPos descendSource; readonly WPos descendTarget; + readonly WDist detonationAltitude; + readonly bool removeOnDetonation; readonly int impactDelay; readonly int turn; readonly string trailImage; @@ -45,9 +47,11 @@ namespace OpenRA.Mods.Common.Effects int ticks, trailTicks; int launchDelay; bool isLaunched; + bool detonated; public NukeLaunch(Player firedBy, string name, WeaponInfo weapon, string weaponPalette, string upSequence, string downSequence, - WPos launchPos, WPos targetPos, WDist velocity, int launchDelay, int impactDelay, bool skipAscent, string flashType, + WPos launchPos, WPos targetPos, WDist detonationAltitude, bool removeOnDetonation, WDist velocity, int launchDelay, int impactDelay, + bool skipAscent, string flashType, string trailImage, string[] trailSequences, string trailPalette, bool trailUsePlayerPalette, int trailDelay, int trailInterval) { this.firedBy = firedBy; @@ -74,6 +78,8 @@ namespace OpenRA.Mods.Common.Effects ascendTarget = launchPos + offset; descendSource = targetPos + offset; descendTarget = targetPos; + this.detonationAltitude = detonationAltitude; + this.removeOnDetonation = removeOnDetonation; anim = new Animation(firedBy.World, name); @@ -100,14 +106,15 @@ namespace OpenRA.Mods.Common.Effects if (ticks == turn) anim.PlayRepeating(downSequence); - if (ticks < turn) + var isDescending = ticks >= turn; + if (!isDescending) pos = WPos.LerpQuadratic(ascendSource, ascendTarget, WAngle.Zero, ticks, turn); else pos = WPos.LerpQuadratic(descendSource, descendTarget, WAngle.Zero, ticks - turn, impactDelay - turn); if (!string.IsNullOrEmpty(trailImage) && --trailTicks < 0) { - var trailPos = ticks < turn ? WPos.LerpQuadratic(ascendSource, ascendTarget, WAngle.Zero, ticks - trailDelay, turn) + var trailPos = !isDescending ? WPos.LerpQuadratic(ascendSource, ascendTarget, WAngle.Zero, ticks - trailDelay, turn) : WPos.LerpQuadratic(descendSource, descendTarget, WAngle.Zero, ticks - turn - trailDelay, impactDelay - turn); world.AddFrameEndTask(w => w.Add(new SpriteEffect(trailPos, w, trailImage, trailSequences.Random(world.SharedRandom), @@ -116,23 +123,31 @@ namespace OpenRA.Mods.Common.Effects trailTicks = trailInterval; } - if (ticks == impactDelay) - Explode(world); + var dat = world.Map.DistanceAboveTerrain(pos); + if (ticks == impactDelay || (isDescending && dat <= detonationAltitude)) + Explode(world, ticks == impactDelay || removeOnDetonation); world.ScreenMap.Update(this, pos, anim.Image); ticks++; } - void Explode(World world) + void Explode(World world, bool removeProjectile) { - world.AddFrameEndTask(w => { w.Remove(this); w.ScreenMap.Remove(this); }); + if (removeProjectile) + world.AddFrameEndTask(w => { w.Remove(this); w.ScreenMap.Remove(this); }); + + if (detonated) + return; + weapon.Impact(Target.FromPos(pos), firedBy.PlayerActor, Enumerable.Empty()); world.WorldActor.Trait().AddEffect(20, pos, 5); foreach (var flash in world.WorldActor.TraitsImplementing()) if (flash.Info.Type == flashType) flash.Enable(-1); + + detonated = true; } public IEnumerable Render(WorldRenderer wr) diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs index 0860f30810..7189d9373a 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs @@ -35,6 +35,13 @@ namespace OpenRA.Mods.Common.Traits [Desc("Offset from the actor the missile spawns on.")] public readonly WVec SpawnOffset = WVec.Zero; + [Desc("Altitude offset from the target position at which the warhead should detonate.")] + public readonly WDist DetonationAltitude = WDist.Zero; + + [Desc("Should nuke missile projectile be removed on detonation above ground.", + "'False' will make the missile continue until it hits the ground and disappears (without triggering another explosion).")] + public readonly bool RemoveMissileOnDetonation = true; + [Desc("Palette to use for the missile weapon image.")] [PaletteReference("IsPlayerPalette")] public readonly string MissilePalette = "effect"; @@ -133,7 +140,7 @@ namespace OpenRA.Mods.Common.Traits var palette = info.IsPlayerPalette ? info.MissilePalette + self.Owner.InternalName : info.MissilePalette; var missile = new NukeLaunch(self.Owner, info.MissileWeapon, info.WeaponInfo, palette, info.MissileUp, info.MissileDown, self.CenterPosition + body.LocalToWorld(info.SpawnOffset), - targetPosition, + targetPosition, info.DetonationAltitude, info.RemoveMissileOnDetonation, info.FlightVelocity, info.MissileDelay, info.FlightDelay, info.SkipAscent, info.FlashType, info.TrailImage, info.TrailSequences, info.TrailPalette, info.TrailUsePlayerPalette, info.TrailDelay, info.TrailInterval);