Merge pull request #12158 from reaperrr/areabeam-tracking
Add AreaBeam target tracking
This commit is contained in:
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user