Make projectiles use most sensible blocker scan radius
By default, but allow custom overrides.
This commit is contained in:
@@ -22,7 +22,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Projectiles
|
namespace OpenRA.Mods.Common.Projectiles
|
||||||
{
|
{
|
||||||
public class AreaBeamInfo : IProjectileInfo
|
public class AreaBeamInfo : IProjectileInfo, IRulesetLoaded<WeaponInfo>
|
||||||
{
|
{
|
||||||
[Desc("Projectile speed in WDist / tick, two values indicate a randomly picked velocity per beam.")]
|
[Desc("Projectile speed in WDist / tick, two values indicate a randomly picked velocity per beam.")]
|
||||||
public readonly WDist[] Speed = { new WDist(128) };
|
public readonly WDist[] Speed = { new WDist(128) };
|
||||||
@@ -57,9 +57,6 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
[Desc("Does the beam follow the target.")]
|
[Desc("Does the beam follow the target.")]
|
||||||
public readonly bool TrackTarget = false;
|
public readonly bool TrackTarget = false;
|
||||||
|
|
||||||
[Desc("Extra search radius beyond beam width. Required to ensure affecting actors with large health radius.")]
|
|
||||||
public readonly WDist TargetExtraSearchRadius = new WDist(1536);
|
|
||||||
|
|
||||||
[Desc("Should the beam be visually rendered? False = Beam is invisible.")]
|
[Desc("Should the beam be visually rendered? False = Beam is invisible.")]
|
||||||
public readonly bool RenderBeam = true;
|
public readonly bool RenderBeam = true;
|
||||||
|
|
||||||
@@ -72,11 +69,28 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
[Desc("Beam color is the player's color.")]
|
[Desc("Beam color is the player's color.")]
|
||||||
public readonly bool UsePlayerColor = false;
|
public readonly bool UsePlayerColor = false;
|
||||||
|
|
||||||
|
[Desc("Scan radius for actors with projectile-blocking trait. If set to zero (default), it will automatically scale",
|
||||||
|
"to the blocker with the largest health shape. Only set custom values if you know what you're doing.")]
|
||||||
|
public WDist BlockerScanRadius = WDist.Zero;
|
||||||
|
|
||||||
|
[Desc("Scan radius for actors damaged by beam. If set to zero (default), it will automatically scale to the largest health shape.",
|
||||||
|
"Only set custom values if you know what you're doing.")]
|
||||||
|
public WDist AreaVictimScanRadius = WDist.Zero;
|
||||||
|
|
||||||
public IProjectile Create(ProjectileArgs args)
|
public IProjectile Create(ProjectileArgs args)
|
||||||
{
|
{
|
||||||
var c = UsePlayerColor ? args.SourceActor.Owner.Color.RGB : Color;
|
var c = UsePlayerColor ? args.SourceActor.Owner.Color.RGB : Color;
|
||||||
return new AreaBeam(this, args, c);
|
return new AreaBeam(this, args, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RulesetLoaded(Ruleset rules, WeaponInfo wi)
|
||||||
|
{
|
||||||
|
if (BlockerScanRadius == WDist.Zero)
|
||||||
|
BlockerScanRadius = Util.MinimumRequiredBlockerScanRadius(rules);
|
||||||
|
|
||||||
|
if (AreaVictimScanRadius == WDist.Zero)
|
||||||
|
AreaVictimScanRadius = Util.MinimumRequiredVictimScanRadius(rules);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AreaBeam : IProjectile, ISync
|
public class AreaBeam : IProjectile, ISync
|
||||||
@@ -211,7 +225,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
// Check for blocking actors
|
// Check for blocking actors
|
||||||
WPos blockedPos;
|
WPos blockedPos;
|
||||||
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, tailPos, headPos,
|
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, tailPos, headPos,
|
||||||
info.Width, info.TargetExtraSearchRadius, out blockedPos))
|
info.Width, info.BlockerScanRadius, out blockedPos))
|
||||||
{
|
{
|
||||||
headPos = blockedPos;
|
headPos = blockedPos;
|
||||||
target = headPos;
|
target = headPos;
|
||||||
@@ -221,7 +235,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
// Damage is applied to intersected actors every DamageInterval ticks
|
// Damage is applied to intersected actors every DamageInterval ticks
|
||||||
if (headTicks % info.DamageInterval == 0)
|
if (headTicks % info.DamageInterval == 0)
|
||||||
{
|
{
|
||||||
var actors = world.FindActorsOnLine(tailPos, headPos, info.Width, info.TargetExtraSearchRadius);
|
var actors = world.FindActorsOnLine(tailPos, headPos, info.Width, info.AreaVictimScanRadius);
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
{
|
{
|
||||||
var adjustedModifiers = args.DamageModifiers.Append(GetFalloff((args.Source - a.CenterPosition).Length));
|
var adjustedModifiers = args.DamageModifiers.Append(GetFalloff((args.Source - a.CenterPosition).Length));
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Projectiles
|
namespace OpenRA.Mods.Common.Projectiles
|
||||||
{
|
{
|
||||||
public class BulletInfo : IProjectileInfo
|
public class BulletInfo : IProjectileInfo, IRulesetLoaded<WeaponInfo>
|
||||||
{
|
{
|
||||||
[Desc("Projectile speed in WDist / tick, two values indicate variable velocity.")]
|
[Desc("Projectile speed in WDist / tick, two values indicate variable velocity.")]
|
||||||
public readonly WDist[] Speed = { new WDist(17) };
|
public readonly WDist[] Speed = { new WDist(17) };
|
||||||
@@ -57,9 +57,6 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
[Desc("Width of projectile (used for finding blocking actors).")]
|
[Desc("Width of projectile (used for finding blocking actors).")]
|
||||||
public readonly WDist Width = new WDist(1);
|
public readonly WDist Width = new WDist(1);
|
||||||
|
|
||||||
[Desc("Extra search radius beyond path for blocking actors.")]
|
|
||||||
public readonly WDist TargetExtraSearchRadius = new WDist(1536);
|
|
||||||
|
|
||||||
[Desc("Arc in WAngles, two values indicate variable arc.")]
|
[Desc("Arc in WAngles, two values indicate variable arc.")]
|
||||||
public readonly WAngle[] LaunchAngle = { WAngle.Zero };
|
public readonly WAngle[] LaunchAngle = { WAngle.Zero };
|
||||||
|
|
||||||
@@ -95,7 +92,24 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
public readonly int ContrailDelay = 1;
|
public readonly int ContrailDelay = 1;
|
||||||
public readonly WDist ContrailWidth = new WDist(64);
|
public readonly WDist ContrailWidth = new WDist(64);
|
||||||
|
|
||||||
|
[Desc("Scan radius for actors with projectile-blocking trait. If set to zero (default), it will automatically scale",
|
||||||
|
"to the blocker with the largest health shape. Only set custom values if you know what you're doing.")]
|
||||||
|
public WDist BlockerScanRadius = WDist.Zero;
|
||||||
|
|
||||||
|
[Desc("Extra search radius beyond path for actors with ValidBounceBlockerStances. If set to zero (default), ",
|
||||||
|
"it will automatically scale to the largest health shape. Only set custom values if you know what you're doing.")]
|
||||||
|
public WDist BounceBlockerScanRadius = WDist.Zero;
|
||||||
|
|
||||||
public IProjectile Create(ProjectileArgs args) { return new Bullet(this, args); }
|
public IProjectile Create(ProjectileArgs args) { return new Bullet(this, args); }
|
||||||
|
|
||||||
|
public void RulesetLoaded(Ruleset rules, WeaponInfo wi)
|
||||||
|
{
|
||||||
|
if (BlockerScanRadius == WDist.Zero)
|
||||||
|
BlockerScanRadius = Util.MinimumRequiredBlockerScanRadius(rules);
|
||||||
|
|
||||||
|
if (BounceBlockerScanRadius == WDist.Zero)
|
||||||
|
BounceBlockerScanRadius = Util.MinimumRequiredVictimScanRadius(rules);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Bullet : IProjectile, ISync
|
public class Bullet : IProjectile, ISync
|
||||||
@@ -196,7 +210,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
var shouldExplode = false;
|
var shouldExplode = false;
|
||||||
WPos blockedPos;
|
WPos blockedPos;
|
||||||
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, lastPos, pos, info.Width,
|
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, lastPos, pos, info.Width,
|
||||||
info.TargetExtraSearchRadius, out blockedPos))
|
info.BlockerScanRadius, out blockedPos))
|
||||||
{
|
{
|
||||||
pos = blockedPos;
|
pos = blockedPos;
|
||||||
shouldExplode = true;
|
shouldExplode = true;
|
||||||
@@ -219,7 +233,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
|
|
||||||
if (flightLengthReached && shouldBounce)
|
if (flightLengthReached && shouldBounce)
|
||||||
{
|
{
|
||||||
shouldExplode |= AnyValidTargetsInRadius(world, pos, info.Width + info.TargetExtraSearchRadius, args.SourceActor, true);
|
shouldExplode |= AnyValidTargetsInRadius(world, pos, info.Width + info.BounceBlockerScanRadius, args.SourceActor, true);
|
||||||
target += (pos - source) * info.BounceRangeModifier / 100;
|
target += (pos - source) * info.BounceRangeModifier / 100;
|
||||||
var dat = world.Map.DistanceAboveTerrain(target);
|
var dat = world.Map.DistanceAboveTerrain(target);
|
||||||
target += new WVec(0, 0, -dat.Length);
|
target += new WVec(0, 0, -dat.Length);
|
||||||
@@ -237,7 +251,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
|
|
||||||
// After first bounce, check for targets each tick
|
// After first bounce, check for targets each tick
|
||||||
if (remainingBounces < info.BounceCount)
|
if (remainingBounces < info.BounceCount)
|
||||||
shouldExplode |= AnyValidTargetsInRadius(world, pos, info.Width + info.TargetExtraSearchRadius, args.SourceActor, true);
|
shouldExplode |= AnyValidTargetsInRadius(world, pos, info.Width + info.BounceBlockerScanRadius, args.SourceActor, true);
|
||||||
|
|
||||||
if (shouldExplode)
|
if (shouldExplode)
|
||||||
Explode(world);
|
Explode(world);
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Projectiles
|
namespace OpenRA.Mods.Common.Projectiles
|
||||||
{
|
{
|
||||||
[Desc("Simple invisible direct on target projectile.")]
|
[Desc("Simple, invisible, usually direct-on-target projectile.")]
|
||||||
public class InstantHitInfo : IProjectileInfo
|
public class InstantHitInfo : IProjectileInfo, IRulesetLoaded<WeaponInfo>
|
||||||
{
|
{
|
||||||
[Desc("Maximum offset at the maximum range.")]
|
[Desc("Maximum offset at the maximum range.")]
|
||||||
public readonly WDist Inaccuracy = WDist.Zero;
|
public readonly WDist Inaccuracy = WDist.Zero;
|
||||||
@@ -30,10 +30,17 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
[Desc("The width of the projectile.")]
|
[Desc("The width of the projectile.")]
|
||||||
public readonly WDist Width = new WDist(1);
|
public readonly WDist Width = new WDist(1);
|
||||||
|
|
||||||
[Desc("Extra search radius beyond projectile width. Required to ensure affecting actors with large health radius.")]
|
[Desc("Scan radius for actors with projectile-blocking trait. If set to zero (default), it will automatically scale",
|
||||||
public readonly WDist TargetExtraSearchRadius = new WDist(1536);
|
"to the blocker with the largest health shape. Only set custom values if you know what you're doing.")]
|
||||||
|
public WDist BlockerScanRadius = WDist.Zero;
|
||||||
|
|
||||||
public IProjectile Create(ProjectileArgs args) { return new InstantHit(this, args); }
|
public IProjectile Create(ProjectileArgs args) { return new InstantHit(this, args); }
|
||||||
|
|
||||||
|
public void RulesetLoaded(Ruleset rules, WeaponInfo wi)
|
||||||
|
{
|
||||||
|
if (BlockerScanRadius == WDist.Zero)
|
||||||
|
BlockerScanRadius = Util.MinimumRequiredBlockerScanRadius(rules);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InstantHit : IProjectile
|
public class InstantHit : IProjectile
|
||||||
@@ -65,7 +72,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
// Check for blocking actors
|
// Check for blocking actors
|
||||||
WPos blockedPos;
|
WPos blockedPos;
|
||||||
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, source, target.CenterPosition,
|
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, source, target.CenterPosition,
|
||||||
info.Width, info.TargetExtraSearchRadius, out blockedPos))
|
info.Width, info.BlockerScanRadius, out blockedPos))
|
||||||
{
|
{
|
||||||
target = Target.FromPos(blockedPos);
|
target = Target.FromPos(blockedPos);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ using OpenRA.Traits;
|
|||||||
namespace OpenRA.Mods.Common.Projectiles
|
namespace OpenRA.Mods.Common.Projectiles
|
||||||
{
|
{
|
||||||
[Desc("Not a sprite, but an engine effect.")]
|
[Desc("Not a sprite, but an engine effect.")]
|
||||||
public class LaserZapInfo : IProjectileInfo
|
public class LaserZapInfo : IProjectileInfo, IRulesetLoaded<WeaponInfo>
|
||||||
{
|
{
|
||||||
[Desc("The width of the zap.")]
|
[Desc("The width of the zap.")]
|
||||||
public readonly WDist Width = new WDist(86);
|
public readonly WDist Width = new WDist(86);
|
||||||
@@ -46,9 +46,6 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
[Desc("Maximum offset at the maximum range.")]
|
[Desc("Maximum offset at the maximum range.")]
|
||||||
public readonly WDist Inaccuracy = WDist.Zero;
|
public readonly WDist Inaccuracy = WDist.Zero;
|
||||||
|
|
||||||
[Desc("Extra search radius beyond beam width. Required to ensure affecting actors with large health radius.")]
|
|
||||||
public readonly WDist TargetExtraSearchRadius = new WDist(1536);
|
|
||||||
|
|
||||||
[Desc("Beam can be blocked.")]
|
[Desc("Beam can be blocked.")]
|
||||||
public readonly bool Blockable = false;
|
public readonly bool Blockable = false;
|
||||||
|
|
||||||
@@ -77,11 +74,21 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
|
|
||||||
[PaletteReference] public readonly string HitAnimPalette = "effect";
|
[PaletteReference] public readonly string HitAnimPalette = "effect";
|
||||||
|
|
||||||
|
[Desc("Scan radius for actors with projectile-blocking trait. If set to zero (default), it will automatically scale",
|
||||||
|
"to the blocker with the largest health shape. Only set custom values if you know what you're doing.")]
|
||||||
|
public WDist BlockerScanRadius = WDist.Zero;
|
||||||
|
|
||||||
public IProjectile Create(ProjectileArgs args)
|
public IProjectile Create(ProjectileArgs args)
|
||||||
{
|
{
|
||||||
var c = UsePlayerColor ? args.SourceActor.Owner.Color.RGB : Color;
|
var c = UsePlayerColor ? args.SourceActor.Owner.Color.RGB : Color;
|
||||||
return new LaserZap(this, args, c);
|
return new LaserZap(this, args, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RulesetLoaded(Ruleset rules, WeaponInfo wi)
|
||||||
|
{
|
||||||
|
if (BlockerScanRadius == WDist.Zero)
|
||||||
|
BlockerScanRadius = Util.MinimumRequiredBlockerScanRadius(rules);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LaserZap : IProjectile, ISync
|
public class LaserZap : IProjectile, ISync
|
||||||
@@ -126,7 +133,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
// Check for blocking actors
|
// Check for blocking actors
|
||||||
WPos blockedPos;
|
WPos blockedPos;
|
||||||
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, source, target,
|
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, source, target,
|
||||||
info.Width, info.TargetExtraSearchRadius, out blockedPos))
|
info.Width, info.BlockerScanRadius, out blockedPos))
|
||||||
{
|
{
|
||||||
target = blockedPos;
|
target = blockedPos;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Projectiles
|
namespace OpenRA.Mods.Common.Projectiles
|
||||||
{
|
{
|
||||||
public class MissileInfo : IProjectileInfo
|
public class MissileInfo : IProjectileInfo, IRulesetLoaded<WeaponInfo>
|
||||||
{
|
{
|
||||||
[Desc("Name of the image containing the projectile sequence.")]
|
[Desc("Name of the image containing the projectile sequence.")]
|
||||||
public readonly string Image = null;
|
public readonly string Image = null;
|
||||||
@@ -64,9 +64,6 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
[Desc("Width of projectile (used for finding blocking actors).")]
|
[Desc("Width of projectile (used for finding blocking actors).")]
|
||||||
public readonly WDist Width = new WDist(1);
|
public readonly WDist Width = new WDist(1);
|
||||||
|
|
||||||
[Desc("Extra search radius beyond path for blocking actors.")]
|
|
||||||
public readonly WDist TargetExtraSearchRadius = new WDist(1536);
|
|
||||||
|
|
||||||
[Desc("Maximum offset at the maximum range")]
|
[Desc("Maximum offset at the maximum range")]
|
||||||
public readonly WDist Inaccuracy = WDist.Zero;
|
public readonly WDist Inaccuracy = WDist.Zero;
|
||||||
|
|
||||||
@@ -145,7 +142,17 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
"not trigger fast enough, causing the missile to fly past the target.")]
|
"not trigger fast enough, causing the missile to fly past the target.")]
|
||||||
public readonly WDist CloseEnough = new WDist(298);
|
public readonly WDist CloseEnough = new WDist(298);
|
||||||
|
|
||||||
|
[Desc("Scan radius for actors with projectile-blocking trait. If set to zero (default), it will automatically scale",
|
||||||
|
"to the blocker with the largest health shape. Only set custom values if you know what you're doing.")]
|
||||||
|
public WDist BlockerScanRadius = WDist.Zero;
|
||||||
|
|
||||||
public IProjectile Create(ProjectileArgs args) { return new Missile(this, args); }
|
public IProjectile Create(ProjectileArgs args) { return new Missile(this, args); }
|
||||||
|
|
||||||
|
public void RulesetLoaded(Ruleset rules, WeaponInfo wi)
|
||||||
|
{
|
||||||
|
if (BlockerScanRadius == WDist.Zero)
|
||||||
|
BlockerScanRadius = Util.MinimumRequiredBlockerScanRadius(rules);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: double check square roots!!!
|
// TODO: double check square roots!!!
|
||||||
@@ -826,7 +833,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
var shouldExplode = false;
|
var shouldExplode = false;
|
||||||
WPos blockedPos;
|
WPos blockedPos;
|
||||||
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, lastPos, pos, info.Width,
|
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, lastPos, pos, info.Width,
|
||||||
info.TargetExtraSearchRadius, out blockedPos))
|
info.BlockerScanRadius, out blockedPos))
|
||||||
{
|
{
|
||||||
pos = blockedPos;
|
pos = blockedPos;
|
||||||
shouldExplode = true;
|
shouldExplode = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user