From fe7b5171dd26873e9e51c9f9633c92a442c43019 Mon Sep 17 00:00:00 2001 From: mszabo Date: Sun, 27 Oct 2024 21:19:36 +0100 Subject: [PATCH] Fix high-shields not intercepting indirect fire shells https://github.com/CombatExtended-Continued/CombatExtended/pull/2869 adjusted the collision check used by shields to normalize away the 3D component of positions by default, which in turn caused high-shields to no longer intercept indirect fire shells. Switch these to use spherical collision checking to bring back the old behavior. --- .../Projectiles/ProjectileCE.cs | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 2f0566e40f..4f46de9c68 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -652,7 +652,17 @@ protected bool CheckIntercept(Thing interceptorThing, CompProjectileInterceptor { return false; } - if (CE_Utility.IntersectionPoint(LastPos, newExactPos, shieldPosition, radius, out Vector3[] sect)) + if (CE_Utility.IntersectionPoint( + LastPos, + newExactPos, + shieldPosition, + radius, + out Vector3[] sect, + // Don't normalize away the 3D component of the projectile position when checking for collisions + // between indirect fire projectiles and shields that protect against them + // (e.g. mortar shells targeting a high-shield). + spherical: interceptorComp.Props.interceptAirProjectiles && def.projectile.flyOverhead + )) { ExactPosition = newExactPos = sect.OrderBy(x => (OriginIV3.ToVector3() - x).sqrMagnitude).First(); landed = true; @@ -720,12 +730,23 @@ protected bool CheckForCollisionBetween() List list = base.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor); for (int i = 0; i < list.Count; i++) { - if (CheckIntercept(list[i], list[i].TryGetComp())) + if (!CheckIntercept(list[i], list[i].TryGetComp())) { - landed = true; - this.Impact(null); + continue; + } + + // Have high-shields absorb intercepted indirect fire projectiles without detonating them. + // Since CE simulates a 3D trajectory for such shells but explosions occur on ground level, + // detonating the shell would cause damage to objects under the high-shield. + if (def.projectile.flyOverhead) + { + this.Destroy(); return true; } + + landed = true; + this.Impact(null); + return true; } if (BlockerRegistry.CheckForCollisionBetweenCallback(this, LastPos, ExactPosition)) {