Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 4,434 Lines • ▼ Show 20 Lines | if (!cmpRanged) | ||||
return false; | return false; | ||||
var range = cmpRanged.GetRange(type); | var range = cmpRanged.GetRange(type); | ||||
let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | ||||
return cmpObstructionManager.IsInTargetRange(this.entity, target, range.min, range.max, false); | return cmpObstructionManager.IsInTargetRange(this.entity, target, range.min, range.max, false); | ||||
}; | }; | ||||
/** | /** | ||||
* Check if the target is inside the attack range | * Check if the target is inside the attack range. | ||||
* For melee attacks, this goes straigt to the regular range calculation | |||||
* For ranged attacks, the parabolic formula is used to accout for bigger ranges | |||||
* when the target is lower, and smaller ranges when the target is higher | |||||
*/ | */ | ||||
UnitAI.prototype.CheckTargetAttackRange = function(target, type) | UnitAI.prototype.CheckTargetAttackRange = function(target, type) | ||||
{ | { | ||||
// for formation members, the formation will take care of the range check | // for formation members, the formation will take care of the range check | ||||
if (this.IsFormationMember()) | if (this.IsFormationMember()) | ||||
{ | { | ||||
let cmpFormationUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI); | let cmpFormationUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI); | ||||
if (cmpFormationUnitAI && cmpFormationUnitAI.IsAttackingAsFormation() && | if (cmpFormationUnitAI && cmpFormationUnitAI.IsAttackingAsFormation() && | ||||
cmpFormationUnitAI.order.data.target == target) | cmpFormationUnitAI.order.data.target == target) | ||||
return true; | return true; | ||||
} | } | ||||
let cmpFormation = Engine.QueryInterface(target, IID_Formation); | let cmpFormation = Engine.QueryInterface(target, IID_Formation); | ||||
if (cmpFormation) | if (cmpFormation) | ||||
target = cmpFormation.GetClosestMember(this.entity); | target = cmpFormation.GetClosestMember(this.entity); | ||||
if (type != "Ranged") | |||||
return this.CheckTargetRange(target, IID_Attack, type); | |||||
let targetCmpPosition = Engine.QueryInterface(target, IID_Position); | let targetCmpPosition = Engine.QueryInterface(target, IID_Position); | ||||
if (!targetCmpPosition || !targetCmpPosition.IsInWorld()) | if (!targetCmpPosition || !targetCmpPosition.IsInWorld()) | ||||
return false; | return false; | ||||
let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); | let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); | ||||
let range = cmpAttack.GetRange(type); | let range = cmpAttack.GetRange(type); | ||||
let thisCmpPosition = Engine.QueryInterface(this.entity, IID_Position); | let thisCmpPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||
if (!thisCmpPosition.IsInWorld()) | if (!thisCmpPosition.IsInWorld()) | ||||
return false; | return false; | ||||
let s = thisCmpPosition.GetPosition(); | let s = thisCmpPosition.GetPosition(); | ||||
let t = targetCmpPosition.GetPosition(); | let t = targetCmpPosition.GetPosition(); | ||||
let h = s.y - t.y + range.elevationBonus; | let h = s.y - t.y + range.elevationBonus; | ||||
let maxRange = Math.sqrt(Math.square(range.max) + 2 * range.max * h); | |||||
let maxRange; | |||||
// Use a parabolic function for projectile attacks... | |||||
// When the target is lower larger range, | |||||
// and smaller ranges when the target is higher. | |||||
if (type == "Ranged") | |||||
maxRange = Math.sqrt(Math.square(range.max) + 2 * range.max * h); | |||||
// ...and genuine Pythagoras for non-projectile attacks. | |||||
// Which means smaller ranges when the target is not on the same level. | |||||
else | |||||
maxRange = Math.sqrt(Math.square(range.max) - Math.square(h)); | |||||
if (maxRange < 0) | if (maxRange < 0) | ||||
return false; | return false; | ||||
let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | ||||
return cmpObstructionManager.IsInTargetRange(this.entity, target, range.min, maxRange, false); | return cmpObstructionManager.IsInTargetRange(this.entity, target, range.min, maxRange, false); | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 1,615 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator