From bf47affd2e690e7fdf7cc371bfcda85fb043068a Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 12 Jan 2017 13:53:55 +0100 Subject: [PATCH 1/3] Add bounce logic to Bullet Allows Bullet projectiles to bounce off ground. --- OpenRA.Mods.Common/Projectiles/Bullet.cs | 35 +++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/OpenRA.Mods.Common/Projectiles/Bullet.cs b/OpenRA.Mods.Common/Projectiles/Bullet.cs index fce58cc640..9f2ad0802d 100644 --- a/OpenRA.Mods.Common/Projectiles/Bullet.cs +++ b/OpenRA.Mods.Common/Projectiles/Bullet.cs @@ -63,6 +63,13 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Arc in WAngles, two values indicate variable arc.")] public readonly WAngle[] LaunchAngle = { WAngle.Zero }; + [Desc("Up to how many times does this bullet bounce when touching ground without hitting a target.", + "0 implies exploding on contact with the originally targeted position.")] + public readonly int BounceCount = 0; + + [Desc("Modify distance of each bounce by this percentage of previous distance.")] + public readonly int BounceRangeModifier = 60; + [Desc("Interval in ticks between each spawned Trail animation.")] public readonly int TrailInterval = 2; @@ -96,10 +103,11 @@ namespace OpenRA.Mods.Common.Projectiles ContrailRenderable contrail; string trailPalette; - [Sync] WPos pos, target; + [Sync] WPos pos, target, source; int length; [Sync] int facing; int ticks, smokeTicks; + int remainingBounces; public Actor SourceActor { get { return args.SourceActor; } } @@ -108,6 +116,7 @@ namespace OpenRA.Mods.Common.Projectiles this.info = info; this.args = args; pos = args.Source; + source = args.Source; var world = args.SourceActor.World; @@ -150,6 +159,7 @@ namespace OpenRA.Mods.Common.Projectiles trailPalette += args.SourceActor.Owner.InternalName; smokeTicks = info.TrailDelay; + remainingBounces = info.BounceCount; } int GetEffectiveFacing() @@ -171,7 +181,7 @@ namespace OpenRA.Mods.Common.Projectiles anim.Tick(); var lastPos = pos; - pos = WPos.LerpQuadratic(args.Source, target, angle, ticks, length); + pos = WPos.LerpQuadratic(source, target, angle, ticks, length); // Check for walls or other blocking obstacles var shouldExplode = false; @@ -185,7 +195,7 @@ namespace OpenRA.Mods.Common.Projectiles if (!string.IsNullOrEmpty(info.TrailImage) && --smokeTicks < 0) { - var delayedPos = WPos.LerpQuadratic(args.Source, target, angle, ticks - info.TrailDelay, length); + var delayedPos = WPos.LerpQuadratic(source, target, angle, ticks - info.TrailDelay, length); world.AddFrameEndTask(w => w.Add(new SpriteEffect(delayedPos, w, info.TrailImage, info.TrailSequences.Random(world.SharedRandom), trailPalette, false, false, GetEffectiveFacing()))); @@ -195,8 +205,25 @@ namespace OpenRA.Mods.Common.Projectiles if (info.ContrailLength > 0) contrail.Update(pos); + var flightLengthReached = ticks++ >= length; + var shouldBounce = remainingBounces > 0; + + if (flightLengthReached && shouldBounce) + { + target += (pos - source) * info.BounceRangeModifier / 100; + var dat = world.Map.DistanceAboveTerrain(target); + target += new WVec(0, 0, -dat.Length); + length = Math.Max((target - pos).Length / speed.Length, 1); + ticks = 0; + source = pos; + remainingBounces--; + } + // Flight length reached / exceeded - shouldExplode |= ticks++ >= length; + shouldExplode |= flightLengthReached && !shouldBounce; + + // Driving into cell with higher height level + shouldExplode |= world.Map.DistanceAboveTerrain(pos).Length < 0; if (shouldExplode) Explode(world); From 2f0b1a16d065bf6f40728d78607bc08cfb35f9a4 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 12 Jan 2017 16:16:35 +0100 Subject: [PATCH 2/3] Upgrade Bullet bounce logic with target checking --- OpenRA.Mods.Common/Projectiles/Bullet.cs | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/OpenRA.Mods.Common/Projectiles/Bullet.cs b/OpenRA.Mods.Common/Projectiles/Bullet.cs index 9f2ad0802d..461454e983 100644 --- a/OpenRA.Mods.Common/Projectiles/Bullet.cs +++ b/OpenRA.Mods.Common/Projectiles/Bullet.cs @@ -70,6 +70,9 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Modify distance of each bounce by this percentage of previous distance.")] public readonly int BounceRangeModifier = 60; + [Desc("If projectile touches an actor with one of these stances during or after the first bounce, trigger explosion.")] + public readonly Stance ValidBounceBlockerStances = Stance.Enemy | Stance.Neutral; + [Desc("Interval in ticks between each spawned Trail animation.")] public readonly int TrailInterval = 2; @@ -210,6 +213,7 @@ namespace OpenRA.Mods.Common.Projectiles if (flightLengthReached && shouldBounce) { + shouldExplode |= AnyValidTargetsInRadius(world, pos, info.Width + info.TargetExtraSearchRadius, args.SourceActor, true); target += (pos - source) * info.BounceRangeModifier / 100; var dat = world.Map.DistanceAboveTerrain(target); target += new WVec(0, 0, -dat.Length); @@ -225,6 +229,10 @@ namespace OpenRA.Mods.Common.Projectiles // Driving into cell with higher height level shouldExplode |= world.Map.DistanceAboveTerrain(pos).Length < 0; + // After first bounce, check for targets each tick + if (remainingBounces < info.BounceCount) + shouldExplode |= AnyValidTargetsInRadius(world, pos, info.Width + info.TargetExtraSearchRadius, args.SourceActor, true); + if (shouldExplode) Explode(world); } @@ -263,5 +271,27 @@ namespace OpenRA.Mods.Common.Projectiles args.Weapon.Impact(Target.FromPos(pos), args.SourceActor, args.DamageModifiers); } + + bool AnyValidTargetsInRadius(World world, WPos pos, WDist radius, Actor firedBy, bool checkTargetType) + { + foreach (var victim in world.FindActorsInCircle(pos, radius)) + { + if (checkTargetType && !Target.FromActor(victim).IsValidFor(firedBy)) + continue; + + if (!info.ValidBounceBlockerStances.HasStance(victim.Owner.Stances[firedBy.Owner])) + continue; + + var healthInfo = victim.Info.TraitInfoOrDefault(); + if (healthInfo == null) + continue; + + // If the impact position is within any actor's HitShape, we have a direct hit + if (healthInfo.Shape.DistanceFromEdge(pos, victim).Length <= 0) + return true; + } + + return false; + } } } From 42a8c83aada1427ba350c9dea1713c113a44b296 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 12 Jan 2017 16:21:05 +0100 Subject: [PATCH 3/3] Make disc Grenade work like in original TS --- mods/ts/weapons/bombsandgrenades.yaml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/mods/ts/weapons/bombsandgrenades.yaml b/mods/ts/weapons/bombsandgrenades.yaml index b320fd6abe..af18d215de 100644 --- a/mods/ts/weapons/bombsandgrenades.yaml +++ b/mods/ts/weapons/bombsandgrenades.yaml @@ -1,15 +1,16 @@ Grenade: ReloadDelay: 60 Range: 4c512 - Projectile: Bullet # TODO: Add bounce effect - Speed: 85 - Blockable: false + Projectile: Bullet + Speed: 160 + Blockable: true Shadow: true - LaunchAngle: 45 - Inaccuracy: 384 + LaunchAngle: 60 + Inaccuracy: 0 Image: DISCUS + BounceCount: 2 Warhead@1Dam: SpreadDamage - Spread: 171 + Spread: 192 Damage: 40 Versus: None: 100