forked from mirrors/0ad
Petra: fix a case where the AI loose control of its units (they become only driven by UnitAI)
Reviewed By: Sandarac Differential Revision: https://code.wildfiregames.com/D545 This was SVN commit r19655.
This commit is contained in:
@@ -280,8 +280,69 @@ m.Army.prototype.clear = function (gameState)
|
||||
{
|
||||
while (this.foeEntities.length > 0)
|
||||
this.removeFoe(gameState,this.foeEntities[0]);
|
||||
|
||||
// Go back to our territory, using the nearest (defensive if any) structure.
|
||||
let armyPos = [0, 0];
|
||||
let npos = 0;
|
||||
for (let entId of this.ownEntities)
|
||||
{
|
||||
let ent = gameState.getEntityById(entId);
|
||||
if (!ent)
|
||||
continue;
|
||||
let pos = ent.position();
|
||||
if (!pos || gameState.ai.HQ.territoryMap.getOwner(pos) === PlayerID)
|
||||
continue;
|
||||
armyPos[0] += pos[0];
|
||||
armyPos[1] += pos[1];
|
||||
++npos;
|
||||
}
|
||||
let nearestStructurePos;
|
||||
let defensiveFound;
|
||||
let distmin;
|
||||
let radius;
|
||||
if (npos > 0)
|
||||
{
|
||||
armyPos[0] /= npos;
|
||||
armyPos[1] /= npos;
|
||||
let armyAccess = gameState.ai.accessibility.getAccessValue(armyPos);
|
||||
for (let struct of gameState.getOwnStructures().values())
|
||||
{
|
||||
let pos = struct.position();
|
||||
if (!pos || gameState.ai.HQ.territoryMap.getOwner(pos) !== PlayerID)
|
||||
continue;
|
||||
if (m.getLandAccess(gameState, struct) !== armyAccess)
|
||||
continue;
|
||||
let defensiveStruct = struct.hasDefensiveFire();
|
||||
if (defensiveFound && !defensiveStruct)
|
||||
continue;
|
||||
let dist = API3.SquareVectorDistance(armyPos, pos);
|
||||
if (distmin && dist > distmin && (defensiveFound || !defensiveStruct))
|
||||
continue;
|
||||
if (defensiveStruct)
|
||||
defensiveFound = true;
|
||||
distmin = dist;
|
||||
nearestStructurePos = pos;
|
||||
radius = struct.obstructionRadius();
|
||||
}
|
||||
}
|
||||
while (this.ownEntities.length > 0)
|
||||
this.removeOwn(gameState,this.ownEntities[0]);
|
||||
{
|
||||
let entId = this.ownEntities[0];
|
||||
this.removeOwn(gameState, entId);
|
||||
let ent = gameState.getEntityById(entId);
|
||||
if (ent)
|
||||
{
|
||||
if (!ent.position() ||
|
||||
ent.healthLevel() < this.Config.garrisonHealthLevel.low &&
|
||||
gameState.ai.HQ.defenseManager.garrisonAttackedUnit(gameState, ent))
|
||||
continue;
|
||||
|
||||
if (nearestStructurePos && gameState.ai.HQ.territoryMap.getOwner(ent.position()) !== PlayerID)
|
||||
ent.moveToRange(nearestStructurePos[0], nearestStructurePos[1], radius, radius+5);
|
||||
else
|
||||
ent.stopMoving();
|
||||
}
|
||||
}
|
||||
|
||||
this.assignedAgainst = {};
|
||||
this.assignedTo = {};
|
||||
|
||||
@@ -566,18 +566,18 @@ m.DefenseManager.prototype.garrisonUnitsInside = function(gameState, target, dat
|
||||
let minGarrison = data.min ? data.min : target.garrisonMax();
|
||||
let typeGarrison = data.type ? data.type : "protection";
|
||||
if (gameState.ai.HQ.garrisonManager.numberOfGarrisonedUnits(target) >= minGarrison)
|
||||
return;
|
||||
return false;
|
||||
if (target.hitpoints() < target.garrisonEjectHealth() * target.maxHitpoints())
|
||||
return;
|
||||
return false;
|
||||
if (data.attacker)
|
||||
{
|
||||
let attackTypes = target.attackTypes();
|
||||
if (!attackTypes || attackTypes.indexOf("Ranged") === -1)
|
||||
return;
|
||||
return false;
|
||||
let dist = API3.SquareVectorDistance(data.attacker.position(), target.position());
|
||||
let range = target.attackRange("Ranged").max;
|
||||
if (dist >= range*range)
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
let index = gameState.ai.accessibility.getAccessValue(target.position());
|
||||
let garrisonManager = gameState.ai.HQ.garrisonManager;
|
||||
@@ -592,6 +592,7 @@ m.DefenseManager.prototype.garrisonUnitsInside = function(gameState, target, dat
|
||||
else
|
||||
allowMelee = true;
|
||||
}
|
||||
let ret = false;
|
||||
for (let ent of units.values())
|
||||
{
|
||||
if (garrisonManager.numberOfGarrisonedUnits(target) >= minGarrison)
|
||||
@@ -623,7 +624,9 @@ m.DefenseManager.prototype.garrisonUnitsInside = function(gameState, target, dat
|
||||
if (army)
|
||||
army.removeOwn(gameState, ent.id());
|
||||
garrisonManager.garrison(gameState, ent, target, typeGarrison);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/** garrison a attacked siege ranged unit inside the nearest fortress */
|
||||
@@ -650,6 +653,7 @@ m.DefenseManager.prototype.garrisonSiegeUnit = function(gameState, unit)
|
||||
});
|
||||
if (nearest)
|
||||
garrisonManager.garrison(gameState, unit, nearest, "protection");
|
||||
return nearest !== undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -683,17 +687,18 @@ m.DefenseManager.prototype.garrisonAttackedUnit = function(gameState, unit, emer
|
||||
nearest = ent;
|
||||
}
|
||||
if (!nearest)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (!emergency)
|
||||
{
|
||||
garrisonManager.garrison(gameState, unit, nearest, "protection");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (garrisonManager.numberOfGarrisonedUnits(nearest) >= nearest.garrisonMax()) // make room for this ent
|
||||
nearest.unload(nearest.garrisoned()[0]);
|
||||
|
||||
garrisonManager.garrison(gameState, unit, nearest, nearest.buffHeal() ? "protection" : "emergency");
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user