From 701b1524e5f865f48ac26e873adf2f524195e81e Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sat, 6 Jul 2019 15:37:36 +0200 Subject: [PATCH] Fix InstantHit crashing if blockable and target is dead If the weapon has TargetActorCenter, the projectile is Blockable and the target dies the same tick the projectile is fired but before the 'blocked' check is performed, the target.CenterPosition lookup would crash since the target has become invalid. Work around this by ignoring TargetActorCenter and using args.PassiveTarget position instead if the target is already dead. --- OpenRA.Mods.Common/Projectiles/InstantHit.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/OpenRA.Mods.Common/Projectiles/InstantHit.cs b/OpenRA.Mods.Common/Projectiles/InstantHit.cs index f26ffa4777..a8e4861dd5 100644 --- a/OpenRA.Mods.Common/Projectiles/InstantHit.cs +++ b/OpenRA.Mods.Common/Projectiles/InstantHit.cs @@ -65,10 +65,17 @@ namespace OpenRA.Mods.Common.Projectiles { // Check for blocking actors WPos blockedPos; - if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, args.Source, target.CenterPosition, - info.Width, out blockedPos)) + if (info.Blockable) { - target = Target.FromPos(blockedPos); + // If GuidedTarget has become invalid due to getting killed the same tick, + // we need to set target to args.PassiveTarget to prevent target.CenterPosition below from crashing. + // The warheads have target validity checks themselves so they don't need this, but AnyBlockingActorsBetween does. + if (target.Type == TargetType.Invalid) + target = Target.FromPos(args.PassiveTarget); + + if (BlocksProjectiles.AnyBlockingActorsBetween(world, args.Source, target.CenterPosition, + info.Width, out blockedPos)) + target = Target.FromPos(blockedPos); } args.Weapon.Impact(target, args.SourceActor, args.DamageModifiers);