Merge pull request #6471 from reaperrr/missile-lockon
Added functionality and descriptions to Missile projectile
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user