Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/Attack.js
Show First 20 Lines • Show All 498 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 attackerOwner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); | ||||
let data = { | |||||
"type": type, | |||||
"attackData": this.GetAttackEffectsData(type), | |||||
"target": target, | |||||
"attacker": this.entity, | |||||
"attackerOwner": attackerOwner, | |||||
}; | |||||
// 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 | ||||
// * Obstacles like walls should block projectiles entirely | // * Obstacles like walls should block projectiles entirely | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | if (type == "Ranged") | ||||
let id = cmpProjectileManager.LaunchProjectileAtPoint(launchPoint, realTargetPosition, horizSpeed, gravity, actorName, impactActorName, impactAnimationLifetime); | let id = cmpProjectileManager.LaunchProjectileAtPoint(launchPoint, realTargetPosition, horizSpeed, gravity, actorName, impactActorName, impactAnimationLifetime); | ||||
let attackImpactSound = ""; | let attackImpactSound = ""; | ||||
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 = { | data.position = realTargetPosition; | ||||
"type": type, | data.direction = missileDirection; | ||||
"attackData": this.GetAttackEffectsData(type), | data.projectileId = id; | ||||
"target": target, | data.attackImpactSound = attackImpactSound; | ||||
"attacker": this.entity, | data.splash = this.GetSplashData(type); | ||||
"attackerOwner": attackerOwner, | data.friendlyFire = this.template[type].Projectile.FriendlyFire == "true"; | ||||
"position": realTargetPosition, | |||||
"direction": missileDirection, | |||||
"projectileId": id, | |||||
"attackImpactSound": attackImpactSound, | |||||
"splash": this.GetSplashData(type), | |||||
"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, data); | ||||
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… | |||||
}; | }; | ||||
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
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.