diff --git a/binaries/data/mods/public/simulation/components/Attack.js b/binaries/data/mods/public/simulation/components/Attack.js index b2ea6ca0d3..e5a386e186 100644 --- a/binaries/data/mods/public/simulation/components/Attack.js +++ b/binaries/data/mods/public/simulation/components/Attack.js @@ -308,6 +308,26 @@ Attack.prototype.GetPreference = function(target) return minPref; }; +/** + * Get the full range of attack using all available attack types. + */ +Attack.prototype.GetFullAttackRange = function() +{ + let ret = {"min": Infinity, "max": 0}; + for (let type of this.GetAttackTypes()) + { + // Ignore the special attack "slaughter" dedicated to domestic animals + if (type == "Slaughter") + continue; + let range = this.GetRange(type); + if (range.min < ret.min) + ret.min = range.min; + if (range.max > ret.max) + ret.max = range.max; + } + return ret; +}; + /** * Return the type of the best attack. * TODO: this should probably depend on range, target, etc, @@ -322,7 +342,15 @@ Attack.prototype.GetBestAttackAgainst = function(target, allowCapture) { var cmpFormation = Engine.QueryInterface(target, IID_Formation); if (cmpFormation) - return this.GetBestAttack(); + { + // TODO: Formation against formation needs review + let best = ["Ranged", "Melee", "Capture"]; + let types = this.GetAttackTypes(); + for (let attack of best) + if (types.indexOf(attack) != -1) + return attack; + return undefined; + } var cmpIdentity = Engine.QueryInterface(target, IID_Identity); if (!cmpIdentity) diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js index de04d9c588..5afe69e2c0 100644 --- a/binaries/data/mods/public/simulation/components/UnitAI.js +++ b/binaries/data/mods/public/simulation/components/UnitAI.js @@ -4476,14 +4476,6 @@ UnitAI.prototype.CheckTargetIsInVisionRange = function(target) return distance < range; }; -UnitAI.prototype.GetBestAttack = function() -{ - var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); - if (!cmpAttack) - return undefined; - return cmpAttack.GetBestAttack(); -}; - UnitAI.prototype.GetBestAttackAgainst = function(target, allowCapture) { var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); @@ -5451,7 +5443,7 @@ UnitAI.prototype.GetQueryRange = function(iid) var cmpRanged = Engine.QueryInterface(this.entity, iid); if (!cmpRanged) return ret; - var range = iid !== IID_Attack ? cmpRanged.GetRange() : cmpRanged.GetRange(cmpRanged.GetBestAttack()); + var range = iid !== IID_Attack ? cmpRanged.GetRange() : cmpRanged.GetFullAttackRange(); ret.min = range.min; ret.max = range.max; } @@ -5468,7 +5460,7 @@ UnitAI.prototype.GetQueryRange = function(iid) var cmpRanged = Engine.QueryInterface(this.entity, iid); if (!cmpRanged) return ret; - var range = iid !== IID_Attack ? cmpRanged.GetRange() : cmpRanged.GetRange(cmpRanged.GetBestAttack()); + var range = iid !== IID_Attack ? cmpRanged.GetRange() : cmpRanged.GetFullAttackRange(); var cmpVision = Engine.QueryInterface(this.entity, IID_Vision); if (!cmpVision) return ret; diff --git a/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js b/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js index 2dad957591..557a7bcd15 100644 --- a/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js +++ b/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js @@ -96,7 +96,7 @@ function TestFormationExiting(mode) AddMock(unit, IID_Attack, { GetRange: function() { return { "max": 10, "min": 0}; }, - GetBestAttack: function() { return "melee"; }, + GetFullAttackRange: function() { return { "max": 40, "min": 0}; }, GetBestAttackAgainst: function(t) { return "melee"; }, GetTimers: function() { return { "prepare": 500, "repeat": 1000 }; }, CanAttack: function(v) { return true; }, @@ -245,7 +245,7 @@ function TestMoveIntoFormationWhileAttacking() AddMock(unit + i, IID_Attack, { GetRange: function() { return {"max":10, "min": 0}; }, - GetBestAttack: function() { return "melee"; }, + GetFullAttackRange: function() { return { "max": 40, "min": 0}; }, GetBestAttackAgainst: function(t) { return "melee"; }, GetTimers: function() { return { "prepare": 500, "repeat": 1000 }; }, CanAttack: function(v) { return true; },