Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/Attack.js
Show First 20 Lines • Show All 489 Lines • ▼ Show 20 Lines | Attack.prototype.GetRange = function(type) | ||||||||||||||
min = ApplyValueModificationsToEntity("Attack/" + type + "/MinRange", min, this.entity); | min = ApplyValueModificationsToEntity("Attack/" + type + "/MinRange", min, this.entity); | ||||||||||||||
let elevationBonus = +(this.template[type].ElevationBonus || 0); | let elevationBonus = +(this.template[type].ElevationBonus || 0); | ||||||||||||||
elevationBonus = ApplyValueModificationsToEntity("Attack/" + type + "/ElevationBonus", elevationBonus, this.entity); | elevationBonus = ApplyValueModificationsToEntity("Attack/" + type + "/ElevationBonus", elevationBonus, this.entity); | ||||||||||||||
return { "max": max, "min": min, "elevationBonus": elevationBonus }; | return { "max": max, "min": min, "elevationBonus": elevationBonus }; | ||||||||||||||
}; | }; | ||||||||||||||
/** | /** | ||||||||||||||
Stan: You should use doxygen style comments. I'm not sure this function even needs a comment as it's… | |||||||||||||||
Done Inline Actionsdoxygen = C++, JSdoc = JS. GetElevationDamageBonus would indeed remove the last bit of ambiguity making the comment unneeded. elexis: doxygen = C++, JSdoc = JS.
GetElevationDamageBonus would indeed remove the last bit of… | |||||||||||||||
* Attack the target entity. This should only be called after a successful range check, | * Attack the target entity. This should only be called after a successful range check, | ||||||||||||||
* and should only be called after GetTimers().repeat msec has passed since the last | * and should only be called after GetTimers().repeat msec has passed since the last | ||||||||||||||
* call to PerformAttack. | * call to PerformAttack. | ||||||||||||||
*/ | */ | ||||||||||||||
Done Inline Actions-> Damage component I guess elexis: -> Damage component I guess | |||||||||||||||
Attack.prototype.PerformAttack = function(type, target) | Attack.prototype.PerformAttack = function(type, target) | ||||||||||||||
{ | { | ||||||||||||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | |||||||||||||||
if (!cmpPosition || !cmpPosition.IsInWorld()) | |||||||||||||||
return; | |||||||||||||||
let selfPosition = cmpPosition.GetPosition(); | |||||||||||||||
let attackerOwner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); | let attackerOwner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); | ||||||||||||||
// If this is a ranged attack, then launch a projectile | // If this is a ranged attack, then launch a projectile | ||||||||||||||
if (type == "Ranged") | if (type == "Ranged") | ||||||||||||||
Done Inline ActionsNot sure we need that temp. variable. Stan: Not sure we need that temp. variable. | |||||||||||||||
Done Inline ActionsIt is needed further up in the code as well :) For the TTT calculation. Freagarach: It is needed further up in the code as well :) For the TTT calculation. | |||||||||||||||
{ | { | ||||||||||||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | ||||||||||||||
let turnLength = cmpTimer.GetLatestTurnLength()/1000; | let turnLength = cmpTimer.GetLatestTurnLength()/1000; | ||||||||||||||
// In the future this could be extended: | // In the future this could be extended: | ||||||||||||||
// * Obstacles like trees could reduce the probability of the target being hit | // * Obstacles like trees could reduce the probability of the target being hit | ||||||||||||||
// * Obstacles like walls should block projectiles entirely | // * Obstacles like walls should block projectiles entirely | ||||||||||||||
let horizSpeed = +this.template[type].Projectile.Speed; | let horizSpeed = +this.template[type].Projectile.Speed; | ||||||||||||||
let gravity = +this.template[type].Projectile.Gravity; | let gravity = +this.template[type].Projectile.Gravity; | ||||||||||||||
// horizSpeed /= 2; gravity /= 2; // slow it down for testing | // horizSpeed /= 2; gravity /= 2; // slow it down for testing | ||||||||||||||
// We will try to estimate the position of the target, where we can hit it. | // We will try to estimate the position of the target, where we can hit it. | ||||||||||||||
// We first estimate the time-till-hit by extrapolating linearly the movement | // We first estimate the time-till-hit by extrapolating linearly the movement | ||||||||||||||
// of the last turn. We compute the time till an arrow will intersect the target. | // of the last turn. We compute the time till an arrow will intersect the target. | ||||||||||||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | |||||||||||||||
if (!cmpPosition || !cmpPosition.IsInWorld()) | |||||||||||||||
return; | |||||||||||||||
let selfPosition = cmpPosition.GetPosition(); | |||||||||||||||
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 targetVelocity = Vector3D.sub(targetPosition, cmpTargetPosition.GetPreviousPosition()).div(turnLength); | let targetVelocity = Vector3D.sub(targetPosition, cmpTargetPosition.GetPreviousPosition()).div(turnLength); | ||||||||||||||
let timeToTarget = PositionHelper.PredictTimeToTarget(selfPosition, horizSpeed, targetPosition, targetVelocity); | let timeToTarget = PositionHelper.PredictTimeToTarget(selfPosition, horizSpeed, targetPosition, targetVelocity); | ||||||||||||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | if (cmpSound) | ||||||||||||||
attackImpactSound = cmpSound.GetSoundGroup("attack_impact_" + type.toLowerCase()); | attackImpactSound = cmpSound.GetSoundGroup("attack_impact_" + type.toLowerCase()); | ||||||||||||||
let data = { | let data = { | ||||||||||||||
"type": type, | "type": type, | ||||||||||||||
"attackData": this.GetAttackEffectsData(type), | "attackData": this.GetAttackEffectsData(type), | ||||||||||||||
"target": target, | "target": target, | ||||||||||||||
"attacker": this.entity, | "attacker": this.entity, | ||||||||||||||
"attackerOwner": attackerOwner, | "attackerOwner": attackerOwner, | ||||||||||||||
"attackerPosition": selfPosition, | |||||||||||||||
"attackHeightOffset": this.GetRange(type).elevationBonus, | |||||||||||||||
"position": realTargetPosition, | "position": realTargetPosition, | ||||||||||||||
"direction": missileDirection, | "direction": missileDirection, | ||||||||||||||
"projectileId": id, | "projectileId": id, | ||||||||||||||
"attackImpactSound": attackImpactSound, | "attackImpactSound": attackImpactSound, | ||||||||||||||
Done Inline Actionswold be better to only pass atomic values rather than doing any kind of computation (logic) here elexis: wold be better to only pass atomic values rather than doing any kind of computation (logic) here | |||||||||||||||
"splash": this.GetSplashData(type), | "splash": this.GetSplashData(type), | ||||||||||||||
"friendlyFire": this.template[type].Projectile.FriendlyFire == "true", | "friendlyFire": this.template[type].Projectile.FriendlyFire == "true", | ||||||||||||||
}; | }; | ||||||||||||||
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, selfPosition, this.GetRange(type).elevationBonus); | ||||||||||||||
wraitiiUnsubmitted Done Inline Actions
(or even go the whole way, and: Attacking.HandleAttackEffects(target, { "type": type, "attackData": this.GetAttackEffectsData(type), "attacker": this.entity, "attackerOwner": attackerOwner, "attackerPosition": selfPosition, "attackHeightOffset": this.GetRange(type).elevationBonus }); ) wraitii: (or even go the whole way, and:
```
Attacking.HandleAttackEffects(target, {
"type": type… | |||||||||||||||
}; | }; | ||||||||||||||
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); | ||||||||||||||
Show All 27 Lines |
Wildfire Games · Phabricator
You should use doxygen style comments. I'm not sure this function even needs a comment as it's self explicit but maybe for parameters.