Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/Attack.js
Show First 20 Lines • Show All 479 Lines • ▼ Show 20 Lines | if (type == "Ranged") | ||||
let cmpTargetPosition = Engine.QueryInterface(target, IID_Position); | let cmpTargetPosition = Engine.QueryInterface(target, IID_Position); | ||||
if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) | if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) | ||||
return; | return; | ||||
let targetPosition = cmpTargetPosition.GetPosition(); | let targetPosition = cmpTargetPosition.GetPosition(); | ||||
let previousTargetPosition = Engine.QueryInterface(target, IID_Position).GetPreviousPosition(); | let previousTargetPosition = Engine.QueryInterface(target, IID_Position).GetPreviousPosition(); | ||||
let targetVelocity = Vector3D.sub(targetPosition, previousTargetPosition).div(turnLength); | let targetVelocity = Vector3D.sub(targetPosition, previousTargetPosition).div(turnLength); | ||||
let timeToTarget = this.PredictTimeToTarget(selfPosition, horizSpeed, targetPosition, targetVelocity); | let timeToTarget = PositionHelper.PredictTimeToTarget(selfPosition, horizSpeed, targetPosition, targetVelocity); | ||||
let predictedPosition = (timeToTarget !== false) ? Vector3D.mult(targetVelocity, timeToTarget).add(targetPosition) : targetPosition; | let predictedPosition = (timeToTarget !== false) ? Vector3D.mult(targetVelocity, timeToTarget).add(targetPosition) : targetPosition; | ||||
// Add inaccuracy based on spread. | // Add inaccuracy based on spread. | ||||
let distanceModifiedSpread = ApplyValueModificationsToEntity("Attack/Ranged/Spread", +this.template[type].Projectile.Spread, this.entity) * | let distanceModifiedSpread = ApplyValueModificationsToEntity("Attack/Ranged/Spread", +this.template[type].Projectile.Spread, this.entity) * | ||||
predictedPosition.horizDistanceTo(selfPosition) / 100; | predictedPosition.horizDistanceTo(selfPosition) / 100; | ||||
let randNorm = randomNormal2D(); | let randNorm = randomNormal2D(); | ||||
let offsetX = randNorm[0] * distanceModifiedSpread; | let offsetX = randNorm[0] * distanceModifiedSpread; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if (type == "Ranged") | ||||
}; | }; | ||||
cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_DelayedDamage, "MissileHit", +this.template[type].Delay + timeToTarget * 1000, data); | cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_DelayedDamage, "MissileHit", +this.template[type].Delay + timeToTarget * 1000, data); | ||||
} | } | ||||
else | else | ||||
Attacking.HandleAttackEffects(target, type, this.GetAttackEffectsData(type), this.entity, attackerOwner); | Attacking.HandleAttackEffects(target, type, this.GetAttackEffectsData(type), this.entity, attackerOwner); | ||||
}; | }; | ||||
/** | |||||
* Get the predicted time of collision between a projectile (or a chaser) | |||||
* and its target, assuming they both move in straight line at a constant speed. | |||||
* Vertical component of movement is ignored. | |||||
* @param {Vector3D} selfPosition - the 3D position of the projectile (or chaser). | |||||
* @param {number} horizSpeed - the horizontal speed of the projectile (or chaser). | |||||
* @param {Vector3D} targetPosition - the 3D position of the target. | |||||
* @param {Vector3D} targetVelocity - the 3D velocity vector of the target. | |||||
* @return {Vector3D|boolean} - the 3D predicted position or false if the collision will not happen. | |||||
*/ | |||||
Attack.prototype.PredictTimeToTarget = function(selfPosition, horizSpeed, targetPosition, targetVelocity) | |||||
{ | |||||
let relativePosition = new Vector3D.sub(targetPosition, selfPosition); | |||||
let a = targetVelocity.x * targetVelocity.x + targetVelocity.z * targetVelocity.z - horizSpeed * horizSpeed; | |||||
let b = relativePosition.x * targetVelocity.x + relativePosition.z * targetVelocity.z; | |||||
let c = relativePosition.x * relativePosition.x + relativePosition.z * relativePosition.z; | |||||
// The predicted time to reach the target is the smallest non negative solution | |||||
// (when it exists) of the equation a t^2 + 2 b t + c = 0. | |||||
// Using c>=0, we can straightly compute the right solution. | |||||
if (c == 0) | |||||
return 0; | |||||
let disc = b * b - a * c; | |||||
if (a < 0 || b < 0 && disc >= 0) | |||||
return c / (Math.sqrt(disc) - b); | |||||
return false; | |||||
}; | |||||
Attack.prototype.OnValueModification = function(msg) | Attack.prototype.OnValueModification = function(msg) | ||||
{ | { | ||||
if (msg.component != "Attack") | if (msg.component != "Attack") | ||||
return; | return; | ||||
let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); | let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); | ||||
if (!cmpUnitAI) | if (!cmpUnitAI) | ||||
return; | return; | ||||
Show All 25 Lines |
Wildfire Games · Phabricator