0ad/binaries/data/mods/public/simulation/ai/petra/queueplan-training.js

170 lines
4.8 KiB
JavaScript
Raw Normal View History

var PETRA = function(m)
{
m.TrainingPlan = function(gameState, type, metadata, number, maxMerge)
{
if (!m.QueuePlan.call(this, gameState, type, metadata))
{
warn(" Plan training " + type + " canceled");
return false;
}
this.category = "unit";
this.cost = new API3.Resources(this.template.cost(), +this.template._template.Cost.Population);
this.number = number !== undefined ? number : 1;
this.maxMerge = maxMerge !== undefined ? maxMerge : 5;
return true;
};
m.TrainingPlan.prototype = Object.create(m.QueuePlan.prototype);
m.TrainingPlan.prototype.canStart = function(gameState)
{
if (this.invalidTemplate)
return false;
// TODO: we should probably check pop caps
if (this.metadata && this.metadata.sea)
var trainers = gameState.findTrainers(this.type).filter(API3.Filters.byMetadata(PlayerID, "sea", this.metadata.sea));
else
var trainers = gameState.findTrainers(this.type);
return (trainers.length != 0);
};
m.TrainingPlan.prototype.start = function(gameState)
{
if (this.metadata && this.metadata.trainer)
{
var metadata = {};
for (var key in this.metadata)
if (key !== "trainer")
metadata[key] = this.metadata[key];
var trainer = gameState.getEntityById(this.metadata.trainer);
if (trainer)
2014-07-22 23:23:25 +02:00
trainer.train(this.type, this.number, metadata, this.promotedTypes(gameState));
this.onStart(gameState);
return;
}
if (this.metadata && this.metadata.sea)
var trainers = gameState.findTrainers(this.type).filter(API3.Filters.byMetadata(PlayerID, "sea", this.metadata.sea)).toEntityArray();
else if (this.metadata && this.metadata.base)
var trainers = gameState.findTrainers(this.type).filter(API3.Filters.byMetadata(PlayerID, "base", this.metadata.base)).toEntityArray();
else
var trainers = gameState.findTrainers(this.type).toEntityArray();
// Prefer training buildings with short queues
// (TODO: this should also account for units added to the queue by
// plans that have already been executed this turn)
if (trainers.length > 0)
{
var wantedIndex = undefined;
if (this.metadata && this.metadata.index)
wantedIndex = this.metadata.index;
var workerUnit = (this.metadata && this.metadata.role && this.metadata.role == "worker");
var supportUnit = this.template.hasClass("Support");
trainers.sort(function(a, b) {
let aa = a.trainingQueueTime();
let bb = b.trainingQueueTime();
if (a.hasClass("Civic") && !supportUnit)
aa += 10;
if (b.hasClass("Civic") && !supportUnit)
bb += 10;
if (supportUnit)
{
if (gameState.ai.HQ.isDangerousLocation(a.position()))
aa += 50;
if (gameState.ai.HQ.isDangerousLocation(b.position()))
bb += 50;
}
let aBase = a.getMetadata(PlayerID, "base");
let bBase = b.getMetadata(PlayerID, "base");
if (wantedIndex)
{
if (!aBase || gameState.ai.HQ.baseManagers[aBase].accessIndex != wantedIndex)
aa += 30;
if (!bBase || gameState.ai.HQ.baseManagers[bBase].accessIndex != wantedIndex)
bb += 30;
}
// then, if worker, small preference for bases with less workers
if (workerUnit && aBase && bBase && aBase != bBase)
{
let apop = gameState.ai.HQ.baseManagers[aBase].workers.length;
let bpop = gameState.ai.HQ.baseManagers[bBase].workers.length;
if (apop > bpop)
aa++;
else if (bpop > apop)
bb++;
}
return (aa - bb);
});
if (this.metadata && this.metadata.base !== undefined && this.metadata.base == 0)
this.metadata.base = trainers[0].getMetadata(PlayerID, "base");
2014-07-22 23:23:25 +02:00
trainers[0].train(this.type, this.number, this.metadata, this.promotedTypes(gameState));
}
else if (gameState.ai.Config.debug > 1)
warn(" no trainers for this queue " + this.type);
this.onStart(gameState);
};
m.TrainingPlan.prototype.addItem = function(amount)
{
if (amount === undefined)
amount = 1;
this.number += amount;
};
2014-07-22 23:23:25 +02:00
// Find the promoted types corresponding to this.type
m.TrainingPlan.prototype.promotedTypes = function(gameState)
{
var types = [];
var promotion = this.template.promotion();
var previous;
2014-07-22 23:23:25 +02:00
while (promotion)
{
types.push(promotion);
previous = promotion;
promotion = gameState.getTemplate(promotion).promotion();
if (previous === promotion)
{
if (gameState.ai.Config.debug > 0)
API3.warn(" unit " + promotion + " is its own promoted unit");
promotion = undefined;
}
2014-07-22 23:23:25 +02:00
}
return types;
};
m.TrainingPlan.prototype.Serialize = function()
{
let prop = {
"category": this.category,
"type": this.type,
"ID": this.ID,
"metadata": this.metadata,
"cost": this.cost.Serialize(),
"number": this.number,
"maxMerge": this.maxMerge,
"lastIsGo": this.lastIsGo
};
return { "prop": prop };
};
m.TrainingPlan.prototype.Deserialize = function(gameState, data)
{
for (let key in data.prop)
this[key] = data.prop[key];
let cost = new API3.Resources();
cost.Deserialize(data.prop.cost);
this.cost = cost;
};
return m;
}(PETRA);