forked from 0ad/0ad
136 lines
3.5 KiB
JavaScript
136 lines
3.5 KiB
JavaScript
var PETRA = function(m)
|
|
{
|
|
|
|
// Specialization of Armies used by the defense manager.
|
|
m.DefenseArmy = function(gameState, defManager, ownEntities, foeEntities)
|
|
{
|
|
if (!m.Army.call(this, gameState, defManager, ownEntities, foeEntities))
|
|
return false;
|
|
|
|
return true;
|
|
};
|
|
|
|
m.DefenseArmy.prototype = Object.create(m.Army.prototype);
|
|
|
|
m.DefenseArmy.prototype.assignUnit = function (gameState, entID)
|
|
{
|
|
// we'll assume this defender is ours already.
|
|
// we'll also override any previous assignment
|
|
|
|
var ent = gameState.getEntityById(entID);
|
|
if (!ent || !ent.position())
|
|
return false;
|
|
|
|
var idMin = undefined;
|
|
var distMin = undefined;
|
|
var idMinAll = undefined;
|
|
var distMinAll = undefined;
|
|
for (var id of this.foeEntities)
|
|
{
|
|
var eEnt = gameState.getEntityById(id);
|
|
if (!eEnt || !eEnt.position()) // probably can't happen.
|
|
continue;
|
|
|
|
if (eEnt.unitAIOrderData().length && eEnt.unitAIOrderData()[0]["target"] &&
|
|
eEnt.unitAIOrderData()[0]["target"] === entID)
|
|
{ // being attacked >>> target the unit
|
|
idMin = id;
|
|
break;
|
|
}
|
|
|
|
var dist = API3.SquareVectorDistance(ent.position(), eEnt.position());
|
|
if (idMinAll === undefined || dist < distMinAll)
|
|
{
|
|
idMinAll = id;
|
|
distMinAll = dist;
|
|
}
|
|
if (this.assignedAgainst[id].length > 2) // already enough units against it
|
|
continue;
|
|
if (idMin === undefined || dist < distMin)
|
|
{
|
|
idMin = id;
|
|
distMin = dist;
|
|
}
|
|
}
|
|
|
|
if (idMin !== undefined)
|
|
var idFoe = idMin;
|
|
else if (idMinAll !== undefined)
|
|
var idFoe = idMinAll
|
|
else
|
|
return false;
|
|
|
|
var ownIndex = gameState.ai.accessibility.getAccessValue(ent.position());
|
|
var foePosition = gameState.getEntityById(idFoe).position();
|
|
var foeIndex = gameState.ai.accessibility.getAccessValue(foePosition);
|
|
if (ownIndex === foeIndex || ent.hasClass("Ship"))
|
|
{
|
|
this.assignedTo[entID] = idFoe;
|
|
this.assignedAgainst[idFoe].push(entID);
|
|
ent.attack(idFoe);
|
|
}
|
|
else
|
|
gameState.ai.HQ.navalManager.requireTransport(gameState, ent, ownIndex, foeIndex, foePosition);
|
|
return true;
|
|
};
|
|
|
|
// TODO: this should return cleverer results ("needs anti-elephant"…)
|
|
m.DefenseArmy.prototype.needsDefenders = function (gameState, events)
|
|
{
|
|
// some preliminary checks because we don't update for tech
|
|
if (this.foeStrength < 0 || this.ownStrength < 0)
|
|
this.recalculateStrengths(gameState);
|
|
|
|
if (this.foeStrength * this.defenseRatio <= this.ownStrength)
|
|
return false;
|
|
return this.foeStrength * this.defenseRatio - this.ownStrength;
|
|
};
|
|
|
|
m.DefenseArmy.prototype.getState = function (gameState)
|
|
{
|
|
if (this.foeEntities.length === 0)
|
|
return 0;
|
|
return 1;
|
|
};
|
|
|
|
m.DefenseArmy.prototype.update = function (gameState)
|
|
{
|
|
for (var entId of this.ownEntities)
|
|
{
|
|
var ent = gameState.getEntityById(entId);
|
|
if (!ent)
|
|
continue;
|
|
var orders = ent.unitAIOrderData();
|
|
if (orders.length === 0 && !ent.getMetadata(PlayerID, "transport"))
|
|
this.assignUnit(gameState, entId);
|
|
}
|
|
|
|
var breakaways = this.onUpdate(gameState);
|
|
|
|
return breakaways;
|
|
};
|
|
|
|
m.DefenseArmy.prototype.debug = function (gameState)
|
|
{
|
|
m.debug(" ");
|
|
m.debug ("Army " + this.ID)
|
|
// m.debug ("Entities " + this.foeEntities.length);
|
|
// m.debug ("Strength " + this.foeStrength);
|
|
// debug (gameState.getEntityById(ent)._templateName + ", ID " + ent);
|
|
//debug ("Defenders " + this.ownEntities.length);
|
|
for (var ent of this.foeEntities)
|
|
{
|
|
if (gameState.getEntityById(ent) !== undefined)
|
|
{
|
|
warn(gameState.getEntityById(ent)._templateName + ", ID " + ent);
|
|
Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent], "rgb": [0.5,0,0]});
|
|
}
|
|
else
|
|
warn("ent " + ent);
|
|
}
|
|
m.debug ("");
|
|
};
|
|
|
|
return m;
|
|
}(PETRA);
|