Index: ps/trunk/binaries/data/mods/public/maps/random/polar_sea_triggers.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/polar_sea_triggers.js +++ ps/trunk/binaries/data/mods/public/maps/random/polar_sea_triggers.js @@ -39,7 +39,8 @@ continue; // The returned entities are sorted by RangeManager already - let targets = Attacking.EntitiesNearPoint(attackerPos, 200, players).filter(ent => { + // Only consider units implementing Health since wolves deal damage. + let targets = Attacking.EntitiesNearPoint(attackerPos, 200, players, IID_Health).filter(ent => { let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); return cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses); }); Index: ps/trunk/binaries/data/mods/public/simulation/components/DelayedDamage.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/DelayedDamage.js +++ ps/trunk/binaries/data/mods/public/simulation/components/DelayedDamage.js @@ -8,6 +8,13 @@ }; /** + * When missiles miss their target, other units in MISSILE_HIT_RADIUS range are considered. + * Large missiles should probably implement splash damage anyways, + * so keep this value low for performance. + */ +DelayedDamage.prototype.MISSILE_HIT_RADIUS = 2; + +/** * Handles hit logic after the projectile travel time has passed. * @param {Object} data - The data sent by the caller. * @param {string} data.type - The type of damage. @@ -69,8 +76,7 @@ return; // If we didn't hit the main target look for nearby units. - let ents = Attacking.EntitiesNearPoint(Vector2D.from3D(data.position), - targetPosition.horizDistanceTo(data.position) * 2, + let ents = Attacking.EntitiesNearPoint(Vector2D.from3D(data.position), this.MISSILE_HIT_RADIUS, Attacking.GetPlayersToDamage(data.attackerOwner, data.friendlyFire)); for (let ent of ents) Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js @@ -614,7 +614,7 @@ cmpDelayedDamage.MissileHit(data, 0); TS_ASSERT(hitEnts.has(61)); - TS_ASSERT_EQUALS(dealtDamage, 100 + 2 * 200); + TS_ASSERT_EQUALS(dealtDamage, 100 + 200); dealtDamage = 0; TS_ASSERT(hitEnts.has(62)); hitEnts.clear(); Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Attacking.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/Attacking.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/Attacking.js @@ -298,28 +298,17 @@ * @param {Vector2D} origin - The point to check around. * @param {number} radius - The radius around the point to check. * @param {number[]} players - The players of which we need to check entities. + * @param {number} itf - Interface IID that returned entities must implement. Defaults to none. * @return {number[]} The id's of the entities in range of the given point. */ -Attacking.prototype.EntitiesNearPoint = function(origin, radius, players) +Attacking.prototype.EntitiesNearPoint = function(origin, radius, players, itf = 0) { // If there is insufficient data return an empty array. if (!origin || !radius || !players || !players.length) return []; let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); - - // Return all entities, except for Gaia: IID_Health is required to avoid returning trees and such. - let gaiaEntities = []; - let gaiaIndex = players.indexOf(0); - if (gaiaIndex !== -1) - { - // splice() modifies players in-place and returns [0] - gaiaEntities = gaiaEntities.concat(cmpRangeManager.ExecuteQueryAroundPos(origin, 0, radius, players.splice(gaiaIndex, 1), IID_Health)); - if (!players.length) - return gaiaEntities; - } - - return cmpRangeManager.ExecuteQueryAroundPos(origin, 0, radius, players, 0).concat(gaiaEntities); + return cmpRangeManager.ExecuteQueryAroundPos(origin, 0, radius, players, itf); }; /**