diff --git a/OpenRA.Mods.Common/Projectiles/AreaBeam.cs b/OpenRA.Mods.Common/Projectiles/AreaBeam.cs index fcf5a13d2f..5f149d0157 100644 --- a/OpenRA.Mods.Common/Projectiles/AreaBeam.cs +++ b/OpenRA.Mods.Common/Projectiles/AreaBeam.cs @@ -21,8 +21,6 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Projectiles { - public enum InaccuracyType { Maximum, PerCellIncrement, Absolute } - public class AreaBeamInfo : IProjectileInfo { [Desc("Projectile speed in WDist / tick, two values indicate a randomly picked velocity per beam.")] @@ -132,23 +130,8 @@ namespace OpenRA.Mods.Common.Projectiles target = args.PassiveTarget; if (info.Inaccuracy.Length > 0) { - var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - - var maxOffset = 0; - switch (info.InaccuracyType) - { - case InaccuracyType.Maximum: - maxOffset = inaccuracy * (target - headPos).Length / args.Weapon.Range.Length; - break; - case InaccuracyType.PerCellIncrement: - maxOffset = inaccuracy * (target - headPos).Length / 1024; - break; - case InaccuracyType.Absolute: - maxOffset = inaccuracy; - break; - } - - target += WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024; + var maxInaccuracyOffset = Util.GetProjectileInaccuracy(info.Inaccuracy.Length, info.InaccuracyType, args); + target += WVec.FromPDF(world.SharedRandom, 2) * maxInaccuracyOffset / 1024; } towardsTargetFacing = (target - headPos).Yaw; diff --git a/OpenRA.Mods.Common/Projectiles/Bullet.cs b/OpenRA.Mods.Common/Projectiles/Bullet.cs index a66766f2c7..9991fb343f 100644 --- a/OpenRA.Mods.Common/Projectiles/Bullet.cs +++ b/OpenRA.Mods.Common/Projectiles/Bullet.cs @@ -149,24 +149,8 @@ namespace OpenRA.Mods.Common.Projectiles target = args.PassiveTarget; if (info.Inaccuracy.Length > 0) { - var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - var range = Util.ApplyPercentageModifiers(args.Weapon.Range.Length, args.RangeModifiers); - - var maxOffset = 0; - switch (info.InaccuracyType) - { - case InaccuracyType.Maximum: - maxOffset = inaccuracy * (target - pos).Length / range; - break; - case InaccuracyType.PerCellIncrement: - maxOffset = inaccuracy * (target - pos).Length / 1024; - break; - case InaccuracyType.Absolute: - maxOffset = inaccuracy; - break; - } - - target += WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024; + var maxInaccuracyOffset = Util.GetProjectileInaccuracy(info.Inaccuracy.Length, info.InaccuracyType, args); + target += WVec.FromPDF(world.SharedRandom, 2) * maxInaccuracyOffset / 1024; } if (info.AirburstAltitude > WDist.Zero) diff --git a/OpenRA.Mods.Common/Projectiles/InstantHit.cs b/OpenRA.Mods.Common/Projectiles/InstantHit.cs index 58fa83b938..fa6a17c452 100644 --- a/OpenRA.Mods.Common/Projectiles/InstantHit.cs +++ b/OpenRA.Mods.Common/Projectiles/InstantHit.cs @@ -55,23 +55,9 @@ namespace OpenRA.Mods.Common.Projectiles target = args.GuidedTarget; else if (info.Inaccuracy.Length > 0) { - var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - - var maxOffset = 0; - switch (info.InaccuracyType) - { - case InaccuracyType.Maximum: - maxOffset = inaccuracy * (args.PassiveTarget - args.Source).Length / args.Weapon.Range.Length; - break; - case InaccuracyType.PerCellIncrement: - maxOffset = inaccuracy * (args.PassiveTarget - args.Source).Length / 1024; - break; - case InaccuracyType.Absolute: - maxOffset = inaccuracy; - break; - } - - target = Target.FromPos(args.PassiveTarget + WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024); + var maxInaccuracyOffset = Util.GetProjectileInaccuracy(info.Inaccuracy.Length, info.InaccuracyType, args); + var inaccuracyOffset = WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxInaccuracyOffset / 1024; + target = Target.FromPos(args.PassiveTarget + inaccuracyOffset); } else target = Target.FromPos(args.PassiveTarget); diff --git a/OpenRA.Mods.Common/Projectiles/LaserZap.cs b/OpenRA.Mods.Common/Projectiles/LaserZap.cs index c0f830cfbe..b896a82ed9 100644 --- a/OpenRA.Mods.Common/Projectiles/LaserZap.cs +++ b/OpenRA.Mods.Common/Projectiles/LaserZap.cs @@ -132,23 +132,8 @@ namespace OpenRA.Mods.Common.Projectiles if (info.Inaccuracy.Length > 0) { - var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - - var maxOffset = 0; - switch (info.InaccuracyType) - { - case InaccuracyType.Maximum: - maxOffset = inaccuracy * (target - source).Length / args.Weapon.Range.Length; - break; - case InaccuracyType.PerCellIncrement: - maxOffset = inaccuracy * (target - source).Length / 1024; - break; - case InaccuracyType.Absolute: - maxOffset = inaccuracy; - break; - } - - target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024; + var maxInaccuracyOffset = Util.GetProjectileInaccuracy(info.Inaccuracy.Length, info.InaccuracyType, args); + target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxInaccuracyOffset / 1024; } if (!string.IsNullOrEmpty(info.HitAnim)) diff --git a/OpenRA.Mods.Common/Projectiles/Missile.cs b/OpenRA.Mods.Common/Projectiles/Missile.cs index 891af33e3f..2399a65721 100644 --- a/OpenRA.Mods.Common/Projectiles/Missile.cs +++ b/OpenRA.Mods.Common/Projectiles/Missile.cs @@ -238,23 +238,8 @@ namespace OpenRA.Mods.Common.Projectiles var inaccuracy = lockOn && info.LockOnInaccuracy.Length > -1 ? info.LockOnInaccuracy.Length : info.Inaccuracy.Length; if (inaccuracy > 0) { - inaccuracy = Util.ApplyPercentageModifiers(inaccuracy, args.InaccuracyModifiers); - - var maxOffset = 0; - switch (info.InaccuracyType) - { - case InaccuracyType.Maximum: - maxOffset = inaccuracy * (targetPosition - pos).Length / args.Weapon.Range.Length; - break; - case InaccuracyType.PerCellIncrement: - maxOffset = inaccuracy * (targetPosition - pos).Length / 1024; - break; - case InaccuracyType.Absolute: - maxOffset = inaccuracy; - break; - } - - offset = WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024; + var maxInaccuracyOffset = Util.GetProjectileInaccuracy(info.Inaccuracy.Length, info.InaccuracyType, args); + offset = WVec.FromPDF(world.SharedRandom, 2) * maxInaccuracyOffset / 1024; } DetermineLaunchSpeedAndAngle(world, out speed, out vFacing); diff --git a/OpenRA.Mods.Common/Projectiles/Railgun.cs b/OpenRA.Mods.Common/Projectiles/Railgun.cs index e0fd17be6a..798ce6721b 100644 --- a/OpenRA.Mods.Common/Projectiles/Railgun.cs +++ b/OpenRA.Mods.Common/Projectiles/Railgun.cs @@ -134,23 +134,8 @@ namespace OpenRA.Mods.Common.Projectiles if (info.Inaccuracy.Length > 0) { - var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - - var maxOffset = 0; - switch (info.InaccuracyType) - { - case InaccuracyType.Maximum: - maxOffset = inaccuracy * (target - source).Length / args.Weapon.Range.Length; - break; - case InaccuracyType.PerCellIncrement: - maxOffset = inaccuracy * (target - source).Length / 1024; - break; - case InaccuracyType.Absolute: - maxOffset = inaccuracy; - break; - } - - target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024; + var maxInaccuracyOffset = Util.GetProjectileInaccuracy(info.Inaccuracy.Length, info.InaccuracyType, args); + target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxInaccuracyOffset / 1024; } if (!string.IsNullOrEmpty(info.HitAnim)) diff --git a/OpenRA.Mods.Common/Util.cs b/OpenRA.Mods.Common/Util.cs index 95c6b471ec..1acb1d2f9f 100644 --- a/OpenRA.Mods.Common/Util.cs +++ b/OpenRA.Mods.Common/Util.cs @@ -11,9 +11,9 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using OpenRA.GameRules; -using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; using OpenRA.Support; @@ -21,6 +21,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common { + public enum InaccuracyType { Maximum, PerCellIncrement, Absolute } + public static class Util { public static int TickFacing(int facing, int desiredFacing, int rot) @@ -251,5 +253,22 @@ namespace OpenRA.Mods.Common return t.Name; } + + public static int GetProjectileInaccuracy(int baseInaccuracy, InaccuracyType inaccuracyType, ProjectileArgs args) + { + var inaccuracy = ApplyPercentageModifiers(baseInaccuracy, args.InaccuracyModifiers); + switch (inaccuracyType) + { + case InaccuracyType.Maximum: + var weaponMaxRange = ApplyPercentageModifiers(args.Weapon.Range.Length, args.RangeModifiers); + return inaccuracy * (args.PassiveTarget - args.Source).Length / weaponMaxRange; + case InaccuracyType.PerCellIncrement: + return inaccuracy * (args.PassiveTarget - args.Source).Length / 1024; + case InaccuracyType.Absolute: + return inaccuracy; + default: + throw new InvalidEnumArgumentException("inaccuracyType", (int)inaccuracyType, typeof(InaccuracyType)); + } + } } }