diff --git a/binaries/data/mods/public/simulation/ai/petra/defenseManager.js b/binaries/data/mods/public/simulation/ai/petra/defenseManager.js index b2cd2ffea2..a4ec585ad2 100644 --- a/binaries/data/mods/public/simulation/ai/petra/defenseManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/defenseManager.js @@ -150,8 +150,6 @@ m.DefenseManager.prototype.checkEnemyUnits = function(gameState) m.DefenseManager.prototype.checkEnemyArmies = function(gameState, events) { - var self = this; - for (var o = 0; o < this.armies.length; ++o) { var army = this.armies[o]; @@ -319,9 +317,9 @@ m.DefenseManager.prototype.assignDefenders = function(gameState) // If our defense structures are attacked, garrison soldiers inside when possible // and if a support unit is attacked and has less than 45% health, garrison it inside the nearest cc +// and if a ranged siege unit (not used for defense) is attacked, garrison it in the nearest fortress m.DefenseManager.prototype.checkEvents = function(gameState, events) { - var self = this; var attackedEvents = events["Attacked"]; for (var evt of attackedEvents) { @@ -338,6 +336,19 @@ m.DefenseManager.prototype.checkEvents = function(gameState, events) continue; } + if (target.hasClass("Siege") && !target.hasClass("Melee") && !target.getMetadata(PlayerID, "transport") + && target.getMetadata(PlayerID, "plan") !== -2 && target.getMetadata(PlayerID, "plan") !== -3) + { + if (target.getMetadata(PlayerID, "plan") !== undefined && target.getMetadata(PlayerID, "plan") !== -1) + { + var subrole = target.getMetadata(PlayerID, "subrole"); + if (subrole && (subrole === "completing" || subrole === "walking" || subrole === "attacking")) + continue; + } + this.garrisonSiegeUnit(gameState, target); + continue; + } + var attacker = gameState.getEntityById(evt.attacker); if (!attacker || !attacker.position()) continue; @@ -384,6 +395,36 @@ m.DefenseManager.prototype.garrisonRangedUnitsInside = function(gameState, targe } }; +// garrison a attacked siege ranged unit inside the nearest fortress +m.DefenseManager.prototype.garrisonSiegeUnit = function(gameState, unit) +{ + let distmin = Math.min(); + let nearest = undefined; + let unitAccess = gameState.ai.accessibility.getAccessValue(unit.position()); + let garrisonManager = gameState.ai.HQ.garrisonManager; + gameState.getAllyStructures().forEach(function(ent) { + if (!MatchesClassList(ent.garrisonableClasses(), unit.classes())) + return; + if (garrisonManager.numberOfGarrisonedUnits(ent) >= ent.garrisonMax()) + return; + var entAccess = ent.getMetadata(PlayerID, "access"); + if (!entAccess) + { + entAccess = gameState.ai.accessibility.getAccessValue(ent.position()); + ent.setMetadata(PlayerID, "access", entAccess); + } + if (entAccess !== unitAccess) + return; + var dist = API3.SquareVectorDistance(ent.position(), unit.position()); + if (dist > distmin) + return; + distmin = dist; + nearest = ent; + }); + if (nearest) + garrisonManager.garrison(gameState, unit, nearest, "protection"); +}; + // garrison a hurt unit inside the nearest healing structure m.DefenseManager.prototype.garrisonUnitForHealing = function(gameState, unit) { diff --git a/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js b/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js index bb026957a3..813e2fea29 100644 --- a/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js @@ -183,7 +183,7 @@ m.GarrisonManager.prototype.keepGarrisoned = function(ent, holder, enemiesAround case 'trade': // trader garrisoned in ship return true; case 'protection': // hurt unit for healing or infantry for defense - if (ent.isHurt() && holder.buffHeal()) + if (ent.needsHeal() && holder.buffHeal()) return true; if (enemiesAround && (ent.hasClass("Support") || MatchesClassList(holder.getGarrisonArrowClasses(), ent.classes()))) return true;