Differential D2759 Diff 14070 ps/trunk/binaries/data/mods/public/simulation/components/BuildingAI.js
Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/simulation/components/BuildingAI.js
Show First 20 Lines • Show All 333 Lines • ▼ Show 20 Lines | BuildingAI.prototype.FireArrows = function() | ||||
}; | }; | ||||
// Add the UnitAI target separately, as the UnitMotion and RangeManager implementations differ | // Add the UnitAI target separately, as the UnitMotion and RangeManager implementations differ | ||||
if (this.unitAITarget && this.targetUnits.indexOf(this.unitAITarget) == -1) | if (this.unitAITarget && this.targetUnits.indexOf(this.unitAITarget) == -1) | ||||
addTarget(this.unitAITarget); | addTarget(this.unitAITarget); | ||||
for (let target of this.targetUnits) | for (let target of this.targetUnits) | ||||
addTarget(target); | addTarget(target); | ||||
// The obstruction manager performs approximate range checks | |||||
// so we need to verify them here. | |||||
// TODO: perhaps an optional 'precise' mode to range queries would be more performant. | |||||
let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | |||||
let range = cmpAttack.GetRange(attackType); | |||||
let thisCmpPosition = Engine.QueryInterface(this.entity, IID_Position); | |||||
if (!thisCmpPosition.IsInWorld()) | |||||
return; | |||||
let s = thisCmpPosition.GetPosition(); | |||||
for (let i = 0; i < arrowsToFire; ++i) | for (let i = 0; i < arrowsToFire; ++i) | ||||
{ | { | ||||
let selectedIndex = targets.randomIndex(); | let selectedIndex = targets.randomIndex(); | ||||
let selectedTarget = targets.itemAt(selectedIndex); | let selectedTarget = targets.itemAt(selectedIndex); | ||||
if (selectedTarget && this.CheckTargetVisible(selectedTarget)) | // Copied from UnitAI's MoveToTargetAttackRange. | ||||
let targetCmpPosition = Engine.QueryInterface(selectedTarget, IID_Position); | |||||
if (!targetCmpPosition.IsInWorld()) | |||||
continue; | |||||
let t = targetCmpPosition.GetPosition(); | |||||
// h is positive when I'm higher than the target | |||||
let h = s.y - t.y + range.elevationBonus; | |||||
let parabolicMaxRange = Math.sqrt(Math.square(range.max) + 2 * range.max * h); | |||||
if (selectedTarget && this.CheckTargetVisible(selectedTarget) && | |||||
h > -range.max / 2 && cmpObstructionManager.IsInTargetRange( | |||||
this.entity, selectedTarget, range.min, parabolicMaxRange, false)) | |||||
{ | { | ||||
cmpAttack.PerformAttack(attackType, selectedTarget); | cmpAttack.PerformAttack(attackType, selectedTarget); | ||||
PlaySound("attack_" + attackType.toLowerCase(), this.entity); | PlaySound("attack_" + attackType.toLowerCase(), this.entity); | ||||
continue; | continue; | ||||
} | } | ||||
// Could not attack target, retry | // Could not attack target, retry | ||||
targets.removeAt(selectedIndex); | targets.removeAt(selectedIndex); | ||||
Show All 33 Lines |
Wildfire Games · Phabricator