Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/Attack.js
Show First 20 Lines • Show All 439 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* 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. | ||||
*/ | */ | ||||
Attack.prototype.PerformAttack = function(type, target) | Attack.prototype.PerformAttack = function(type, target) | ||||
{ | { | ||||
let attackerOwner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); | let attackerData = { | ||||
"owner": Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(), | |||||
"entity": this.entity, | |||||
}; | |||||
// 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") | ||||
{ | { | ||||
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 | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | if (type == "Ranged") | ||||
let cmpSound = Engine.QueryInterface(this.entity, IID_Sound); | let cmpSound = Engine.QueryInterface(this.entity, IID_Sound); | ||||
if (cmpSound) | 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, | "attackerData": attackerData, | ||||
"attackerOwner": attackerOwner, | |||||
"position": realTargetPosition, | "position": realTargetPosition, | ||||
"direction": missileDirection, | "direction": missileDirection, | ||||
"projectileId": id, | "projectileId": id, | ||||
"attackImpactSound": attackImpactSound | "attackImpactSound": attackImpactSound | ||||
}; | }; | ||||
if (this.template[type].Splash) | if (this.template[type].Splash) | ||||
data.splash = { | data.splash = { | ||||
"friendlyFire": this.template[type].Splash.FriendlyFire != "false", | "friendlyFire": this.template[type].Splash.FriendlyFire != "false", | ||||
"radius": +this.template[type].Splash.Range, | "radius": +this.template[type].Splash.Range, | ||||
"shape": this.template[type].Splash.Shape, | "shape": this.template[type].Splash.Shape, | ||||
"attackData": this.GetAttackEffectsData(type, true), | "attackData": this.GetAttackEffectsData(type, 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(type, this.GetAttackEffectsData(type), target, this.entity, attackerOwner); | Attacking.HandleAttackEffects(type, this.GetAttackEffectsData(type), target, attackerData); | ||||
wraitii: Mostly my point here is that attackerData is basically the same as "data" above, you might want… | |||||
Done Inline ActionsattackerData is also used in data. Freagarach: `attackerData` is also used in `data`. | |||||
Done Inline ActionsYes my point is that you might ultimately want to send friendlyFire to HandleAttackEffects, and at that point you'll have to send { "attackerData": attackerData, "friendlyFire": true } and you will have gained very little from adding a new object. So I'd keep it flat. wraitii: Yes my point is that you might ultimately want to send friendlyFire to HandleAttackEffects, and… | |||||
}; | }; | ||||
/** | /** | ||||
* Get the predicted time of collision between a projectile (or a chaser) | * 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. | * and its target, assuming they both move in straight line at a constant speed. | ||||
* Vertical component of movement is ignored. | * Vertical component of movement is ignored. | ||||
* @param {Vector3D} selfPosition - the 3D position of the projectile (or chaser). | * @param {Vector3D} selfPosition - the 3D position of the projectile (or chaser). | ||||
* @param {number} horizSpeed - the horizontal speed of the projectile (or chaser). | * @param {number} horizSpeed - the horizontal speed of the projectile (or chaser). | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
Mostly my point here is that attackerData is basically the same as "data" above, you might want to pass Friendly fire in the future, you might want to pass sounds, you might want to pass a direction. I don't think there's a particular reason to not send the whole thing, thus I don't think there's a particular reason to split attackerData off.