Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 4,710 Lines • ▼ Show 20 Lines | UnitAI.prototype.MoveToTargetAttackRange = function(target, type) | ||||
if (!this.CheckTargetVisible(target)) | if (!this.CheckTargetVisible(target)) | ||||
return false; | return false; | ||||
let range = this.GetRange(IID_Attack, type, target); | let range = this.GetRange(IID_Attack, type, target); | ||||
if (!range) | if (!range) | ||||
return false; | return false; | ||||
let thisCmpPosition = Engine.QueryInterface(this.entity, IID_Position); | // In case the range returns negative, we are probably too high compared to the target. Hope we come close enough. | ||||
if (!thisCmpPosition.IsInWorld()) | const parabolicMaxRange = Math.max(0, Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).GetEffectiveParabolicRange(this.entity, target, range.max, range.elevationBonus)); | ||||
Freagarach: One does need to check whether the target is in world by checking if `parabolicMaxRange` is not… | |||||
Done Inline ActionsunitMotion->moveToTargetRange => unitMotion->ComputeGoal => Obstruction->GetObstructionSquare check there to make it fail. There is also the comment bb: unitMotion->moveToTargetRange => unitMotion->ComputeGoal => Obstruction->GetObstructionSquare… | |||||
Not Done Inline ActionsSorry, I totally missed the Math.max,,, Freagarach: Sorry, I totally missed the `Math.max`,,, | |||||
Not Done Inline ActionsIdem. Freagarach: Idem. | |||||
return false; | |||||
let s = thisCmpPosition.GetPosition(); | |||||
let targetCmpPosition = Engine.QueryInterface(target, IID_Position); | |||||
if (!targetCmpPosition || !targetCmpPosition.IsInWorld()) | |||||
return false; | |||||
// Parabolic range compuation is the same as in BuildingAI's FireArrows. | |||||
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); | |||||
// No negative roots please | |||||
if (h <= -range.max / 2) | |||||
// return false? Or hope you come close enough? | |||||
parabolicMaxRange = 0; | |||||
// The parabole changes while walking so be cautious: | // The parabole changes while walking so be cautious: | ||||
let guessedMaxRange = parabolicMaxRange > range.max ? (range.max + parabolicMaxRange) / 2 : parabolicMaxRange; | let guessedMaxRange = parabolicMaxRange > range.max ? (range.max + parabolicMaxRange) / 2 : parabolicMaxRange; | ||||
return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, range.min, guessedMaxRange); | return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, range.min, guessedMaxRange); | ||||
}; | }; | ||||
UnitAI.prototype.MoveToTargetRangeExplicit = function(target, min, max) | UnitAI.prototype.MoveToTargetRangeExplicit = function(target, min, max) | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | if (this.IsFormationMember()) | ||||
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); | ||||
let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); | let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); | ||||
Not Done Inline ActionsAlso not needed anymore. Freagarach: Also not needed anymore. | |||||
return cmpAttack && cmpAttack.IsTargetInRange(target, type); | return cmpAttack && cmpAttack.IsTargetInRange(target, type); | ||||
}; | }; | ||||
UnitAI.prototype.CheckTargetRangeExplicit = function(target, min, max) | UnitAI.prototype.CheckTargetRangeExplicit = function(target, min, max) | ||||
{ | { | ||||
let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); | ||||
return cmpObstructionManager.IsInTargetRange(this.entity, target, min, max, false); | return cmpObstructionManager.IsInTargetRange(this.entity, target, min, max, false); | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 1,667 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
One does need to check whether the target is in world by checking if parabolicMaxRange is not -1, right? Or does the moveToTargetRange check that?