Merge pull request #12158 from reaperrr/areabeam-tracking

Add AreaBeam target tracking
This commit is contained in:
Oliver Brakmann
2016-12-23 14:44:11 +01:00
committed by GitHub
4 changed files with 55 additions and 7 deletions

View File

@@ -54,6 +54,9 @@ namespace OpenRA.Mods.Common.Projectiles
[Desc("Can this projectile be blocked when hitting actors with an IBlocksProjectiles trait.")] [Desc("Can this projectile be blocked when hitting actors with an IBlocksProjectiles trait.")]
public readonly bool Blockable = false; public readonly bool Blockable = false;
[Desc("Does the beam follow the target.")]
public readonly bool TrackTarget = false;
[Desc("Extra search radius beyond beam width. Required to ensure affecting actors with large health radius.")] [Desc("Extra search radius beyond beam width. Required to ensure affecting actors with large health radius.")]
public readonly WDist TargetExtraSearchRadius = new WDist(1536); public readonly WDist TargetExtraSearchRadius = new WDist(1536);
@@ -93,6 +96,7 @@ namespace OpenRA.Mods.Common.Projectiles
int tailTicks; int tailTicks;
bool isHeadTravelling = true; bool isHeadTravelling = true;
bool isTailTravelling; bool isTailTravelling;
bool continueTracking = true;
bool IsBeamComplete { get { return !isHeadTravelling && headTicks >= length && bool IsBeamComplete { get { return !isHeadTravelling && headTicks >= length &&
!isTailTravelling && tailTicks >= length; } } !isTailTravelling && tailTicks >= length; } }
@@ -132,8 +136,44 @@ namespace OpenRA.Mods.Common.Projectiles
length = Math.Max((target - headPos).Length / speed.Length, 1); length = Math.Max((target - headPos).Length / speed.Length, 1);
} }
void TrackTarget()
{
if (!continueTracking)
return;
if (args.GuidedTarget.IsValidFor(args.SourceActor))
{
var guidedTargetPos = args.GuidedTarget.CenterPosition;
var targetDistance = new WDist((guidedTargetPos - args.Source).Length);
// Only continue tracking target if it's within weapon range +
// BeyondTargetRange to avoid edge case stuttering (start firing and immediately stop again).
if (targetDistance > args.Weapon.Range + info.BeyondTargetRange)
StopTargeting();
else
{
target = guidedTargetPos;
towardsTargetFacing = (target - args.Source).Yaw.Facing;
// Update the target position with the range we shoot beyond the target by
// I.e. we can deliberately overshoot, so aim for that position
var dir = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(towardsTargetFacing));
target += dir * info.BeyondTargetRange.Length / 1024;
}
}
}
void StopTargeting()
{
continueTracking = false;
isTailTravelling = true;
}
public void Tick(World world) public void Tick(World world)
{ {
if (info.TrackTarget)
TrackTarget();
if (++headTicks >= length) if (++headTicks >= length)
{ {
headPos = target; headPos = target;
@@ -148,14 +188,14 @@ namespace OpenRA.Mods.Common.Projectiles
tailPos = args.Source; tailPos = args.Source;
} }
// Allow for 1 cell (1024) leniency to avoid edge case stuttering (start firing and immediately stop again). // Allow for leniency to avoid edge case stuttering (start firing and immediately stop again).
var outOfWeaponRange = args.Weapon.Range.Length + 1024 < (args.PassiveTarget - args.Source).Length; var outOfWeaponRange = args.Weapon.Range + info.BeyondTargetRange < new WDist((args.PassiveTarget - args.Source).Length);
// While the head is travelling, the tail must start to follow Duration ticks later. // While the head is travelling, the tail must start to follow Duration ticks later.
// Alternatively, also stop emitting the beam if source actor dies or is ordered to stop. // Alternatively, also stop emitting the beam if source actor dies or is ordered to stop.
if ((headTicks >= info.Duration && !isTailTravelling) || args.SourceActor.IsDead || if ((headTicks >= info.Duration && !isTailTravelling) || args.SourceActor.IsDead ||
!actorAttackBase.IsAttacking || outOfWeaponRange) !actorAttackBase.IsAttacking || outOfWeaponRange)
isTailTravelling = true; StopTargeting();
if (isTailTravelling) if (isTailTravelling)
{ {

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Projectiles
public readonly Color Color = Color.Red; public readonly Color Color = Color.Red;
[Desc("Beam follows the target.")] [Desc("Beam follows the target.")]
public readonly bool TracksTarget = true; public readonly bool TrackTarget = true;
[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;
@@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.Projectiles
public void Tick(World world) public void Tick(World world)
{ {
// Beam tracks target // Beam tracks target
if (info.TracksTarget && args.GuidedTarget.IsValidFor(args.SourceActor)) if (info.TrackTarget && args.GuidedTarget.IsValidFor(args.SourceActor))
target = args.GuidedTarget.CenterPosition; target = args.GuidedTarget.CenterPosition;
// Check for blocking actors // Check for blocking actors

View File

@@ -751,14 +751,14 @@ namespace OpenRA.Mods.Common.UtilityCommands
} }
// Rename LaserZap BeamDuration to just Duration // Rename LaserZap BeamDuration to just Duration
if (engineVersion < 20161009) if (engineVersion < 20161020)
{ {
if (node.Key == "BeamDuration") if (node.Key == "BeamDuration")
node.Key = "Duration"; node.Key = "Duration";
} }
// Rename Bullet Angle to LaunchAngle // Rename Bullet Angle to LaunchAngle
if (engineVersion < 20161016) if (engineVersion < 20161020)
{ {
if (node.Key == "Angle") if (node.Key == "Angle")
node.Key = "LaunchAngle"; node.Key = "LaunchAngle";
@@ -774,6 +774,13 @@ namespace OpenRA.Mods.Common.UtilityCommands
} }
} }
// Rename LaserZap TracksTarget to TrackTarget
if (engineVersion < 20161217)
{
if (node.Key == "TracksTarget")
node.Key = "TrackTarget";
}
UpgradeWeaponRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); UpgradeWeaponRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1);
} }
} }

View File

@@ -77,6 +77,7 @@ SonicZap:
ZOffset: 2047 ZOffset: 2047
BeyondTargetRange: 0c256 BeyondTargetRange: 0c256
Blockable: true Blockable: true
TrackTarget: true
Color: 50F5FF45 Color: 50F5FF45
Warhead@1Dam: SpreadDamage Warhead@1Dam: SpreadDamage
Range: 0, 32 Range: 0, 32