Merge pull request #6471 from reaperrr/missile-lockon

Added functionality and descriptions to Missile projectile
This commit is contained in:
Chris Forbes
2014-09-18 09:12:21 +12:00
3 changed files with 31 additions and 19 deletions

View File

@@ -70,8 +70,8 @@ namespace OpenRA.Mods.RA.Effects
if (info.Angle.Length > 1 && info.Speed.Length > 1)
{
angle = new WAngle(args.SourceActor.World.SharedRandom.Next(info.Angle[0].Angle, info.Angle[1].Angle));
speed = new WRange(args.SourceActor.World.SharedRandom.Next(info.Speed[0].Range, info.Speed[1].Range));
angle = new WAngle(world.SharedRandom.Next(info.Angle[0].Angle, info.Angle[1].Angle));
speed = new WRange(world.SharedRandom.Next(info.Speed[0].Range, info.Speed[1].Range));
}
else
{
@@ -86,7 +86,7 @@ namespace OpenRA.Mods.RA.Effects
.Select(m => m.GetInaccuracyModifier());
var inaccuracy = Traits.Util.ApplyPercentageModifiers(info.Inaccuracy.Range, modifiers);
var maxOffset = inaccuracy * (target - pos).Length / args.Weapon.Range.Range;
target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024;
target += WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024;
}
facing = Traits.Util.GetFacing(target - pos, 0);
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.RA.Effects
if (info.ContrailLength > 0)
{
var color = info.ContrailUsePlayerColor ? ContrailRenderable.ChooseColor(args.SourceActor) : info.ContrailColor;
trail = new ContrailRenderable(args.SourceActor.World, color, info.ContrailLength, info.ContrailDelay, 0);
trail = new ContrailRenderable(world, color, info.ContrailLength, info.ContrailDelay, 0);
}
smokeTicks = info.TrailDelay;

View File

@@ -23,7 +23,9 @@ namespace OpenRA.Mods.RA.Effects
{
[Desc("Projectile speed in WRange / tick")]
public readonly WRange Speed = new WRange(8);
[Desc("Maximum vertical pitch when changing altitude.")]
public readonly WAngle MaximumPitch = WAngle.FromDegrees(30);
[Desc("How many ticks before this missile is armed and can explode.")]
public readonly int Arm = 0;
[Desc("Check for whether an actor with BlocksBullets: trait blocks fire")]
public readonly bool High = false;
@@ -31,11 +33,14 @@ namespace OpenRA.Mods.RA.Effects
public readonly string Trail = null;
[Desc("Maximum offset at the maximum range")]
public readonly WRange Inaccuracy = WRange.Zero;
[Desc("Probability of locking onto and following target.")]
public readonly int LockOnProbability = 100;
public readonly string Image = null;
[Desc("Rate of Turning")]
public readonly int ROT = 5;
[Desc("Explode when following the target longer than this.")]
public readonly int RangeLimit = 0;
[Desc("If fired at aircraft, increase speed by 50%.")]
public readonly bool TurboBoost = false;
public readonly int TrailInterval = 2;
public readonly int ContrailLength = 0;
@@ -45,18 +50,16 @@ namespace OpenRA.Mods.RA.Effects
public readonly bool Jammable = true;
[Desc("Explodes when leaving the following terrain type, e.g., Water for torpedoes.")]
public readonly string BoundToTerrainType = "";
[Desc("Explodes when inside this proximity radius to target.",
"Note: If this value is lower than the missile speed, this check might",
"not trigger fast enough, causing the missile to fly past the target.")]
public readonly WRange CloseEnough = new WRange(298);
public IEffect Create(ProjectileArgs args) { return new Missile(this, args); }
}
class Missile : IEffect, ISync
{
// HACK: the missile movement code isn't smart enough to explode
// when the projectile passes the actor. This defines an arbitrary
// proximity radius that they will explode within, which makes
// missiles difficult to consistently balance.
static readonly WRange MissileCloseEnough = new WRange(298);
readonly MissileInfo info;
readonly ProjectileArgs args;
readonly Animation anim;
@@ -71,6 +74,8 @@ namespace OpenRA.Mods.RA.Effects
[Sync] WVec offset;
[Sync] int ticks;
[Sync] bool lockOn = false;
[Sync] public Actor SourceActor { get { return args.SourceActor; } }
[Sync] public Target GuidedTarget { get { return args.GuidedTarget; } }
@@ -84,24 +89,29 @@ namespace OpenRA.Mods.RA.Effects
targetPosition = args.PassiveTarget;
var world = args.SourceActor.World;
if (world.SharedRandom.Next(100) <= info.LockOnProbability)
lockOn = true;
if (info.Inaccuracy.Range > 0)
{
var modifiers = args.SourceActor.TraitsImplementing<IInaccuracyModifier>()
.Select(m => m.GetInaccuracyModifier());
var inaccuracy = Traits.Util.ApplyPercentageModifiers(info.Inaccuracy.Range, modifiers);
offset = WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * inaccuracy / 1024;
offset = WVec.FromPDF(world.SharedRandom, 2) * inaccuracy / 1024;
}
if (info.Image != null)
{
anim = new Animation(args.SourceActor.World, info.Image, () => facing);
anim = new Animation(world, info.Image, () => facing);
anim.PlayRepeating("idle");
}
if (info.ContrailLength > 0)
{
var color = info.ContrailUsePlayerColor ? ContrailRenderable.ChooseColor(args.SourceActor) : info.ContrailColor;
trail = new ContrailRenderable(args.SourceActor.World, color, info.ContrailLength, info.ContrailDelay, 0);
trail = new ContrailRenderable(world, color, info.ContrailLength, info.ContrailDelay, 0);
}
}
@@ -122,7 +132,7 @@ namespace OpenRA.Mods.RA.Effects
anim.Tick();
// Missile tracks target
if (args.GuidedTarget.IsValidFor(args.SourceActor))
if (args.GuidedTarget.IsValidFor(args.SourceActor) && lockOn)
targetPosition = args.GuidedTarget.CenterPosition;
var dist = targetPosition + offset - pos;
@@ -164,7 +174,7 @@ namespace OpenRA.Mods.RA.Effects
var cell = world.Map.CellContaining(pos);
var shouldExplode = (pos.Z < 0) // Hit the ground
|| (dist.LengthSquared < MissileCloseEnough.Range * MissileCloseEnough.Range) // Within range
|| (dist.LengthSquared < info.CloseEnough.Range * info.CloseEnough.Range) // Within range
|| (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|| (!info.High && world.ActorMap.GetUnitsAt(cell).Any(a => a.HasTrait<IBlocksBullets>())) // Hit a wall
|| !world.Map.Contains(cell) // This also avoids an IndexOutOfRangeException in GetTerrainInfo below.

View File

@@ -88,16 +88,18 @@ Bazooka:
Palette: ra
Projectile: Missile
Speed: 213
Arm: 2
High: yes
Arm: 3
High: true
Shadow: true
Inaccuracy: 128
Image: DRAGON
ROT: 8
RangeLimit: 35
RangeLimit: 50
CloseEnough: 256
LockOnProbability: 80
Warhead@1Dam: SpreadDamage
Spread: 128
Damage: 25
Damage: 35
DeathType: 2
ValidTargets: Ground, Air
Versus: