Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/helpers/Attack.js
Show First 20 Lines • Show All 225 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* Damages units around a given origin. | * Damages units around a given origin. | ||||
* @param {Object} data - The data sent by the caller. | * @param {Object} data - The data sent by the caller. | ||||
* @param {string} data.type - The type of damage. | * @param {string} data.type - The type of damage. | ||||
* @param {Object} data.attackData - The attack data. | * @param {Object} data.attackData - The attack data. | ||||
* @param {number} data.attacker - The entity id of the attacker. | * @param {number} data.attacker - The entity id of the attacker. | ||||
* @param {number} data.attackerOwner - The player id of the attacker. | * @param {number} data.attackerOwner - The player id of the attacker. | ||||
* @param {Vector2D} data.origin - The origin of the projectile hit. | * @param {Vector2D} data.origin - The origin of the projectile hit. | ||||
* @param {number} data.radius - The radius of the splash damage. | * @param {number} data.minRange - The minimal radius of the area damage. | ||||
* @param {number} data.maxRange - The maximum radius of the area damage. | |||||
* @param {string} data.shape - The shape of the radius. | * @param {string} data.shape - The shape of the radius. | ||||
* @param {Vector3D} [data.direction] - The unit vector defining the direction. Needed for linear splash damage. | * @param {Vector3D} [data.direction] - The unit vector defining the direction. Needed for linear splash damage. | ||||
* @param {boolean} data.friendlyFire - A flag indicating if allied entities also ought to be damaged. | * @param {boolean} data.friendlyFire - A flag indicating if allied entities also ought to be damaged. | ||||
*/ | */ | ||||
AttackHelper.prototype.CauseDamageOverArea = function(data) | AttackHelper.prototype.CauseDamageOverArea = function(data) | ||||
{ | { | ||||
let nearEnts = PositionHelper.EntitiesNearPoint(data.origin, data.radius, | const nearEnts = PositionHelper.EntitiesNearPoint(data.origin, data.minRange, data.maxRange, | ||||
this.GetPlayersToDamage(data.attackerOwner, data.friendlyFire)); | this.GetPlayersToDamage(data.attackerOwner, data.friendlyFire)); | ||||
let damageMultiplier = 1; | let damageMultiplier = 1; | ||||
let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | const cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | ||||
// Cycle through all the nearby entities and damage it appropriately based on its distance from the origin. | // Cycle through all the nearby entities and damage it appropriately based on its distance from the origin. | ||||
for (let ent of nearEnts) | for (let ent of nearEnts) | ||||
{ | { | ||||
// Correct somewhat for the entity's obstruction radius. | // Correct somewhat for the entity's obstruction radius. | ||||
// TODO: linear falloff should arguably use something cleverer. | // TODO: linear falloff should arguably use something cleverer. | ||||
let distance = cmpObstructionManager.DistanceToPoint(ent, data.origin.x, data.origin.y); | let distance = cmpObstructionManager.DistanceToPoint(ent, data.origin.x, data.origin.y); | ||||
if (data.shape == 'Circular') // circular effect with quadratic falloff in every direction | if (data.shape == 'Circular') // circular effect with quadratic falloff in every direction | ||||
damageMultiplier = 1 - distance * distance / (data.radius * data.radius); | damageMultiplier = Math.max(0, 1 - Math.max(0, Math.square((distance - data.minRange) / (data.maxRange - data.minRange)))); | ||||
else if (data.shape == 'Linear') // linear effect with quadratic falloff in two directions (only used for certain missiles) | else if (data.shape == 'Linear') // linear effect with quadratic falloff in two directions (only used for certain missiles) | ||||
{ | { | ||||
// The entity has a position here since it was returned by the range manager. | // The entity has a position here since it was returned by the range manager. | ||||
let entityPosition = Engine.QueryInterface(ent, IID_Position).GetPosition2D(); | let entityPosition = Engine.QueryInterface(ent, IID_Position).GetPosition2D(); | ||||
let relativePos = entityPosition.sub(data.origin).normalize().mult(distance); | let relativePos = entityPosition.sub(data.origin).normalize().mult(distance); | ||||
// Get the position relative to the missile direction. | // Get the position relative to the missile direction. | ||||
let direction = Vector2D.from3D(data.direction); | let direction = Vector2D.from3D(data.direction); | ||||
let parallelPos = relativePos.dot(direction); | let parallelPos = relativePos.dot(direction); | ||||
let perpPos = relativePos.cross(direction); | let perpPos = relativePos.cross(direction); | ||||
// The width of linear splash is one fifth of the normal splash radius. | // The width of linear splash is one fifth of the normal splash radius. | ||||
let width = data.radius / 5; | const width = (data.maxRange - data.minRange) / 5; | ||||
// Check that the unit is within the distance splash width of the line starting at the missile's | // Check that the unit is within the distance splash width of the line starting at the missile's | ||||
// landing point which extends in the direction of the missile for length splash radius. | // landing point which extends in the direction of the missile for length splash radius. | ||||
if (parallelPos >= 0 && Math.abs(perpPos) < width) // If in radius, quadratic falloff in both directions | if (parallelPos >= 0 && Math.abs(perpPos) < width) // If in radius, quadratic falloff in both directions | ||||
damageMultiplier = (1 - parallelPos * parallelPos / (data.radius * data.radius)) * | damageMultiplier = Math.max(0, | ||||
(1 - perpPos * perpPos / (width * width)); | (1 - Math.max(0, Math.square((parallelPos - data.minRange) / width))) * (1 - Math.square(perpPos / width)) | ||||
); | |||||
else | else | ||||
damageMultiplier = 0; | damageMultiplier = 0; | ||||
} | } | ||||
else // In case someone calls this function with an invalid shape. | else // In case someone calls this function with an invalid shape. | ||||
{ | { | ||||
warn("The " + data.shape + " splash damage shape is not implemented!"); | warn("The " + data.shape + " splash damage shape is not implemented!"); | ||||
} | } | ||||
// The RangeManager can return units that are too far away (due to approximations there) | // The RangeManager can return units that are too far away (due to approximations there) | ||||
▲ Show 20 Lines • Show All 99 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator