Index: binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- binaries/data/mods/public/simulation/components/UnitAI.js +++ binaries/data/mods/public/simulation/components/UnitAI.js @@ -4386,10 +4386,7 @@ }; /** - * Check if the target is inside the attack range - * For melee attacks, this goes straigt to the regular range calculation - * For ranged attacks, the parabolic formula is used to accout for bigger ranges - * when the target is lower, and smaller ranges when the target is higher + * Check if the target is inside the attack range. */ UnitAI.prototype.CheckTargetAttackRange = function(target, type) { @@ -4406,9 +4403,6 @@ if (cmpFormation) target = cmpFormation.GetClosestMember(this.entity); - if (type != "Ranged") - return this.CheckTargetRange(target, IID_Attack, type); - let targetCmpPosition = Engine.QueryInterface(target, IID_Position); if (!targetCmpPosition || !targetCmpPosition.IsInWorld()) return false; @@ -4421,11 +4415,19 @@ return false; let s = thisCmpPosition.GetPosition(); - let t = targetCmpPosition.GetPosition(); - let h = s.y - t.y + range.elevationBonus; - let maxRange = Math.sqrt(Math.square(range.max) + 2 * range.max * h); + + let maxRange; + // Use a parabolic function for projectile attacks... + // When the target is lower larger range, + // and smaller ranges when the target is higher. + if (type == "Ranged") + maxRange = Math.sqrt(Math.square(range.max) + 2 * range.max * h); + // and genuine Pythagoras for non-projectile attacks. + // Which means smaller ranges when the target is not on the same level. + else + maxRange = Math.sqrt(Math.square(range.max) - Math.square(h)); if (maxRange < 0) return false;