Petra: garrison siege units when useful

This was SVN commit r16252.
This commit is contained in:
mimo 2015-01-30 18:41:33 +00:00
parent ad4e995bd4
commit e1e5979d73
2 changed files with 45 additions and 4 deletions

View File

@ -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)
{

View File

@ -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;