diff --git a/OpenRA.Mods.Common/Projectiles/AreaBeam.cs b/OpenRA.Mods.Common/Projectiles/AreaBeam.cs index 8ab2b88d62..681365c298 100644 --- a/OpenRA.Mods.Common/Projectiles/AreaBeam.cs +++ b/OpenRA.Mods.Common/Projectiles/AreaBeam.cs @@ -21,6 +21,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Projectiles { + public enum InaccuracyType { Maximum, PerCellIncrement } + public class AreaBeamInfo : IProjectileInfo { [Desc("Projectile speed in WDist / tick, two values indicate a randomly picked velocity per beam.")] @@ -47,9 +49,11 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Ranges at which each Falloff step is defined.")] public readonly WDist[] Range = { WDist.Zero, new WDist(int.MaxValue) }; - [Desc("Maximum offset at the maximum range.")] public readonly WDist Inaccuracy = WDist.Zero; + [Desc("Controls the way inaccuracy is calculated. Possible values are 'Maximum' and 'PerCellIncrement'.")] + public readonly InaccuracyType InaccuracyType = InaccuracyType.Maximum; + [Desc("Can this projectile be blocked when hitting actors with an IBlocksProjectiles trait.")] public readonly bool Blockable = false; @@ -129,7 +133,13 @@ namespace OpenRA.Mods.Common.Projectiles if (info.Inaccuracy.Length > 0) { var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - var maxOffset = inaccuracy * (target - headPos).Length / args.Weapon.Range.Length; + + int maxOffset; + if (info.InaccuracyType == InaccuracyType.Maximum) + maxOffset = inaccuracy * (target - headPos).Length / args.Weapon.Range.Length; + else + maxOffset = inaccuracy * (target - headPos).Length / 1024; + target += WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024; } diff --git a/OpenRA.Mods.Common/Projectiles/Bullet.cs b/OpenRA.Mods.Common/Projectiles/Bullet.cs index 1d8fd6923f..9c8924abba 100644 --- a/OpenRA.Mods.Common/Projectiles/Bullet.cs +++ b/OpenRA.Mods.Common/Projectiles/Bullet.cs @@ -27,9 +27,11 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Projectile speed in WDist / tick, two values indicate variable velocity.")] public readonly WDist[] Speed = { new WDist(17) }; - [Desc("Maximum offset at the maximum range.")] public readonly WDist Inaccuracy = WDist.Zero; + [Desc("Controls the way inaccuracy is calculated. Possible values are 'Maximum' and 'PerCellIncrement'.")] + public readonly InaccuracyType InaccuracyType = InaccuracyType.Maximum; + [Desc("Image to display.")] public readonly string Image = null; @@ -149,7 +151,13 @@ namespace OpenRA.Mods.Common.Projectiles { var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); var range = Util.ApplyPercentageModifiers(args.Weapon.Range.Length, args.RangeModifiers); - var maxOffset = inaccuracy * (target - pos).Length / range; + + int maxOffset; + if (info.InaccuracyType == InaccuracyType.Maximum) + maxOffset = inaccuracy * (target - pos).Length / range; + else + maxOffset = inaccuracy * (target - pos).Length / 1024; + target += WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024; } diff --git a/OpenRA.Mods.Common/Projectiles/InstantHit.cs b/OpenRA.Mods.Common/Projectiles/InstantHit.cs index fdf58afd63..488d156f82 100644 --- a/OpenRA.Mods.Common/Projectiles/InstantHit.cs +++ b/OpenRA.Mods.Common/Projectiles/InstantHit.cs @@ -21,9 +21,11 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Simple, invisible, usually direct-on-target projectile.")] public class InstantHitInfo : IProjectileInfo { - [Desc("Maximum offset at the maximum range.")] public readonly WDist Inaccuracy = WDist.Zero; + [Desc("Controls the way inaccuracy is calculated. Possible values are 'Maximum' and 'PerCellIncrement'.")] + public readonly InaccuracyType InaccuracyType = InaccuracyType.Maximum; + [Desc("Projectile can be blocked.")] public readonly bool Blockable = false; @@ -54,7 +56,13 @@ namespace OpenRA.Mods.Common.Projectiles else if (info.Inaccuracy.Length > 0) { var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - var maxOffset = inaccuracy * (args.PassiveTarget - args.Source).Length / args.Weapon.Range.Length; + + int maxOffset; + if (info.InaccuracyType == InaccuracyType.Maximum) + maxOffset = inaccuracy * (args.PassiveTarget - args.Source).Length / args.Weapon.Range.Length; + else + maxOffset = inaccuracy * (args.PassiveTarget - args.Source).Length / 1024; + target = Target.FromPos(args.PassiveTarget + WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024); } else diff --git a/OpenRA.Mods.Common/Projectiles/LaserZap.cs b/OpenRA.Mods.Common/Projectiles/LaserZap.cs index 2855e6ec62..665df898e7 100644 --- a/OpenRA.Mods.Common/Projectiles/LaserZap.cs +++ b/OpenRA.Mods.Common/Projectiles/LaserZap.cs @@ -50,9 +50,11 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Beam follows the target.")] public readonly bool TrackTarget = true; - [Desc("Maximum offset at the maximum range.")] public readonly WDist Inaccuracy = WDist.Zero; + [Desc("Controls the way inaccuracy is calculated. Possible values are 'Maximum' and 'PerCellIncrement'.")] + public readonly InaccuracyType InaccuracyType = InaccuracyType.Maximum; + [Desc("Beam can be blocked.")] public readonly bool Blockable = false; @@ -130,8 +132,14 @@ namespace OpenRA.Mods.Common.Projectiles if (info.Inaccuracy.Length > 0) { - var inaccuracy = OpenRA.Mods.Common.Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - var maxOffset = inaccuracy * (target - source).Length / args.Weapon.Range.Length; + var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); + + int maxOffset; + if (info.InaccuracyType == InaccuracyType.Maximum) + maxOffset = inaccuracy * (target - source).Length / args.Weapon.Range.Length; + else + maxOffset = inaccuracy * (target - source).Length / 1024; + target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024; } diff --git a/OpenRA.Mods.Common/Projectiles/Missile.cs b/OpenRA.Mods.Common/Projectiles/Missile.cs index 10d120da02..1a2e2472e4 100644 --- a/OpenRA.Mods.Common/Projectiles/Missile.cs +++ b/OpenRA.Mods.Common/Projectiles/Missile.cs @@ -71,9 +71,11 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Width of projectile (used for finding blocking actors).")] public readonly WDist Width = new WDist(1); - [Desc("Maximum inaccuracy offset at the maximum range")] public readonly WDist Inaccuracy = WDist.Zero; + [Desc("Controls the way inaccuracy is calculated. Possible values are 'Maximum' and 'PerCellIncrement'.")] + public readonly InaccuracyType InaccuracyType = InaccuracyType.Maximum; + [Desc("Inaccuracy override when sucessfully locked onto target. Defaults to Inaccuracy if negative.")] public readonly WDist LockOnInaccuracy = new WDist(-1); @@ -237,7 +239,12 @@ namespace OpenRA.Mods.Common.Projectiles if (inaccuracy > 0) { inaccuracy = Util.ApplyPercentageModifiers(inaccuracy, args.InaccuracyModifiers); - offset = WVec.FromPDF(world.SharedRandom, 2) * inaccuracy / 1024; + + var maxOffset = inaccuracy; + if (info.InaccuracyType == InaccuracyType.PerCellIncrement) + maxOffset = inaccuracy * (targetPosition - pos).Length / 1024; + + offset = WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024; } DetermineLaunchSpeedAndAngle(world, out speed, out vFacing); diff --git a/OpenRA.Mods.Common/Projectiles/Railgun.cs b/OpenRA.Mods.Common/Projectiles/Railgun.cs index dda4284bd5..7e2d4718a2 100644 --- a/OpenRA.Mods.Common/Projectiles/Railgun.cs +++ b/OpenRA.Mods.Common/Projectiles/Railgun.cs @@ -25,9 +25,11 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Damage all units hit by the beam instead of just the target?")] public readonly bool DamageActorsInLine = false; - [Desc("Maximum offset at the maximum range.")] public readonly WDist Inaccuracy = WDist.Zero; + [Desc("Controls the way inaccuracy is calculated. Possible values are 'Maximum' and 'PerCellIncrement'.")] + public readonly InaccuracyType InaccuracyType = InaccuracyType.Maximum; + [Desc("Can this projectile be blocked when hitting actors with an IBlocksProjectiles trait.")] public readonly bool Blockable = false; @@ -130,6 +132,19 @@ namespace OpenRA.Mods.Common.Projectiles BeamColor = beamColor; HelixColor = helixColor; + if (info.Inaccuracy.Length > 0) + { + var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); + + int maxOffset; + if (info.InaccuracyType == InaccuracyType.Maximum) + maxOffset = inaccuracy * (target - source).Length / args.Weapon.Range.Length; + else + maxOffset = inaccuracy * (target - source).Length / 1024; + + target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024; + } + if (!string.IsNullOrEmpty(info.HitAnim)) hitanim = new Animation(args.SourceActor.World, info.HitAnim);