mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-09-21 20:06:40 +00:00
UnitAI: Simplify GetQueryRange and fix issues
38b33b0484 partly rewrote GetQueryRange but ended up with two
bugs/regressions:
- in standGround, melee units used an effective max-range of 0 instead
of their melee attack max range
- units that have a min-range did not see units within their min-range
(even though they can move).
This fixes these issues and rewrite the function in a simpler fashion
for readability.
This commit is contained in:
committed by
wraitii
parent
3cbcb69e7f
commit
cb6f46db71
@@ -6655,59 +6655,49 @@ UnitAI.prototype.FindWalkAndFightTargets = function()
|
||||
* The query range depends on stance because it represents the distance at which
|
||||
* the unit should "notice" an enemy and potentially start moving toward it.
|
||||
*
|
||||
* @param {number} iid - IID_Vision, IID_Heal, or IID_Attack
|
||||
* @returns {{min: number, max: number, base: number, parabolic: boolean}}
|
||||
* 'parabolic' indicates that the caller
|
||||
* should use a parabolic range query (accounting for elevation) instead of a
|
||||
* flat 2D one. Generally used for projectile attacks.
|
||||
* 'base' is a non-parabolic 2D detection range that always counts as in-range.
|
||||
* @param {number} iid - IID_Vision, IID_Heal, or IID_Attack.
|
||||
* @returns {{min: number, max: number, base: number, parabolic: boolean}} -
|
||||
* 'parabolic' asks the caller for a parabolic query, where 'max' is the
|
||||
* elevation-aware parabola and 'base' a flat circle around it. A flat query
|
||||
* uses 'max' alone.
|
||||
*/
|
||||
UnitAI.prototype.GetQueryRange = function(iid)
|
||||
{
|
||||
const ret = { "min": 0, "max": 0, "base": 0, "parabolic": false };
|
||||
|
||||
const cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
|
||||
if (!cmpVision)
|
||||
return ret;
|
||||
return { "min": 0, "max": 0, "base": 0, "parabolic": false };
|
||||
|
||||
const visionRange = cmpVision.GetRange();
|
||||
|
||||
if (iid === IID_Vision)
|
||||
{
|
||||
ret.max = visionRange;
|
||||
return ret;
|
||||
}
|
||||
return { "min": 0, "max": visionRange, "base": 0, "parabolic": false };
|
||||
|
||||
const range = this.GetRange(iid);
|
||||
if (!range)
|
||||
return ret;
|
||||
return { "min": 0, "max": 0, "base": 0, "parabolic": false };
|
||||
|
||||
// The query range depends on stance because it represents the distance at which
|
||||
// the unit should "notice" an enemy and potentially start moving toward it.
|
||||
// On StandGround, we care only about what we can immediately attack.
|
||||
if (this.GetStance().respondStandGround)
|
||||
return { "min": range.min, "max": range.max, "base": 0, "parabolic": !!range.parabolic };
|
||||
|
||||
// In all stances, always spot targets within effective attack/heal range.
|
||||
Object.assign(ret, range);
|
||||
|
||||
let nonParabolicMax = 0;
|
||||
let walkRange = 0;
|
||||
if (this.GetStance().respondChase)
|
||||
// Chase: Always spot targets within vision range, so we can chase them.
|
||||
nonParabolicMax = visionRange;
|
||||
walkRange = visionRange;
|
||||
else if (this.GetStance().respondHoldGround)
|
||||
// HoldGround: willing to move a bit, so spot targets within attack range + half vision.
|
||||
nonParabolicMax = Math.min(range.max + visionRange / 2, visionRange);
|
||||
|
||||
// StandGround: nonParabolicMax stays 0, using only parabolic range.
|
||||
|
||||
// We probably have stance 'passive' and we wouldn't have a range,
|
||||
// but as it is the default for healers we need to set it to something sane.
|
||||
// HoldGround: willing to move a bit, but not to leave the area.
|
||||
walkRange = Math.min(range.max + visionRange / 2, visionRange);
|
||||
else if (iid === IID_Heal)
|
||||
nonParabolicMax = visionRange;
|
||||
// We probably have stance 'passive' and we wouldn't have a range,
|
||||
// but as it is the default for healers we need to set it to something sane.
|
||||
walkRange = visionRange;
|
||||
|
||||
if (ret.parabolic)
|
||||
ret.base = nonParabolicMax;
|
||||
else
|
||||
ret.max = nonParabolicMax;
|
||||
// Other stances can move away, so keep the minimum range at 0.
|
||||
if (range.parabolic)
|
||||
return { "min": 0, "max": range.max, "base": walkRange, "parabolic": true };
|
||||
|
||||
return ret;
|
||||
// One radius has to cover both what we can hit and what we would walk to.
|
||||
return { "min": 0, "max": Math.max(range.max, walkRange), "base": 0, "parabolic": false };
|
||||
};
|
||||
|
||||
UnitAI.prototype.GetStance = function()
|
||||
|
||||
Reference in New Issue
Block a user