petra cleanup

This was SVN commit r17677.
This commit is contained in:
mimo 2016-01-19 23:19:40 +00:00
parent 0a64bf25cd
commit dd545bdbf1
8 changed files with 217 additions and 229 deletions

View file

@ -194,8 +194,8 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
if (unexecutedAttacks.Rush === 0)
{
// we have a barracks and we want to rush, rush.
var data = { "targetSize": this.rushSize[this.rushNumber] };
var attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, "Rush", data);
let data = { "targetSize": this.rushSize[this.rushNumber] };
let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, "Rush", data);
if (!attackPlan.failed)
{
if (this.Config.debug > 1)
@ -210,15 +210,11 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
else if (unexecutedAttacks.Attack === 0 && unexecutedAttacks.HugeAttack === 0 &&
(this.startedAttacks.Attack.length + this.startedAttacks.HugeAttack.length < Math.min(2, 1 + Math.round(gameState.getPopulationMax()/100))))
{
if ((barracksNb >= 1 && (gameState.currentPhase() > 1 || gameState.isResearching(gameState.townPhase())))
|| !gameState.ai.HQ.baseManagers[1]) // if we have no base ... nothing else to do than attack
if ((barracksNb >= 1 && (gameState.currentPhase() > 1 || gameState.isResearching(gameState.townPhase()))) ||
!gameState.ai.HQ.baseManagers[1]) // if we have no base ... nothing else to do than attack
{
if (this.attackNumber < 2 || this.startedAttacks.HugeAttack.length > 0)
var type = "Attack";
else
var type = "HugeAttack";
var attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, type);
let type = (this.attackNumber < 2 || this.startedAttacks.HugeAttack.length > 0) ? "Attack" : "HugeAttack";
let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, type);
if (attackPlan.failed)
this.attackPlansEncounteredWater = true; // hack
else
@ -235,7 +231,7 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
if (unexecutedAttacks.Raid === 0 && gameState.ai.HQ.defenseManager.targetList.length)
{
var target = undefined;
let target;
for (let targetId of gameState.ai.HQ.defenseManager.targetList)
{
target = gameState.getEntityById(targetId);
@ -245,8 +241,8 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
if (target)
{
// prepare a raid against this target
var data = { "target": target };
var attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, "Raid", data);
let data = { "target": target };
let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, "Raid", data);
if (!attackPlan.failed)
{
if (this.Config.debug > 1)
@ -293,23 +289,23 @@ m.AttackManager.prototype.unpausePlan = function(planName)
m.AttackManager.prototype.pauseAllPlans = function()
{
for (var attackType in this.upcomingAttacks)
for (var attack of this.upcomingAttacks[attackType])
for (let attackType in this.upcomingAttacks)
for (let attack of this.upcomingAttacks[attackType])
attack.setPaused(true);
for (var attackType in this.startedAttacks)
for (var attack of this.startedAttacks[attackType])
for (let attackType in this.startedAttacks)
for (let attack of this.startedAttacks[attackType])
attack.setPaused(true);
};
m.AttackManager.prototype.unpauseAllPlans = function()
{
for (var attackType in this.upcomingAttacks)
for (var attack of this.upcomingAttacks[attackType])
for (let attackType in this.upcomingAttacks)
for (let attack of this.upcomingAttacks[attackType])
attack.setPaused(false);
for (var attackType in this.startedAttacks)
for (var attack of this.startedAttacks[attackType])
for (let attackType in this.startedAttacks)
for (let attack of this.startedAttacks[attackType])
attack.setPaused(false);
};

View file

@ -105,9 +105,9 @@ m.AttackPlan = function(gameState, Config, uniqueID, type, data)
if (type === "Rush")
{
priority = 250;
this.unitStat["Infantry"] = { "priority": 1, "minSize": 10, "targetSize": 20, "batchSize": 2, "classes": ["Infantry"],
this.unitStat.Infantry = { "priority": 1, "minSize": 10, "targetSize": 20, "batchSize": 2, "classes": ["Infantry"],
"interests": [ ["strength",1], ["cost",1], ["costsResource", 0.5, "stone"], ["costsResource", 0.6, "metal"] ] };
this.unitStat["Cavalry"] = { "priority": 1, "minSize": 2, "targetSize": 4, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"],
this.unitStat.Cavalry = { "priority": 1, "minSize": 2, "targetSize": 4, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"],
"interests": [ ["strength",1], ["cost",1] ] };
if (data && data.targetSize)
this.unitStat["Infantry"]["targetSize"] = data.targetSize;
@ -116,7 +116,7 @@ m.AttackPlan = function(gameState, Config, uniqueID, type, data)
else if (type === "Raid")
{
priority = 150;
this.unitStat["Cavalry"] = { "priority": 1, "minSize": 3, "targetSize": 4, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"],
this.unitStat.Cavalry = { "priority": 1, "minSize": 3, "targetSize": 4, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"],
"interests": [ ["strength",1], ["cost",1] ] };
this.neededShips = 1;
}
@ -124,34 +124,34 @@ m.AttackPlan = function(gameState, Config, uniqueID, type, data)
{
priority = 90;
// basically we want a mix of citizen soldiers so our barracks have a purpose, and champion units.
this.unitStat["RangedInfantry"] = { "priority": 0.7, "minSize": 5, "targetSize": 15, "batchSize": 5, "classes": ["Infantry","Ranged", "CitizenSoldier"],
this.unitStat.RangedInfantry = { "priority": 0.7, "minSize": 5, "targetSize": 15, "batchSize": 5, "classes": ["Infantry","Ranged", "CitizenSoldier"],
"interests": [["strength",3], ["cost",1] ] };
this.unitStat["MeleeInfantry"] = { "priority": 0.7, "minSize": 5, "targetSize": 15, "batchSize": 5, "classes": ["Infantry","Melee", "CitizenSoldier"],
this.unitStat.MeleeInfantry = { "priority": 0.7, "minSize": 5, "targetSize": 15, "batchSize": 5, "classes": ["Infantry","Melee", "CitizenSoldier"],
"interests": [ ["strength",3], ["cost",1] ] };
this.unitStat["ChampRangedInfantry"] = { "priority": 1, "minSize": 5, "targetSize": 25, "batchSize": 5, "classes": ["Infantry","Ranged", "Champion"],
this.unitStat.ChampRangedInfantry = { "priority": 1, "minSize": 5, "targetSize": 25, "batchSize": 5, "classes": ["Infantry","Ranged", "Champion"],
"interests": [["strength",3], ["cost",1] ] };
this.unitStat["ChampMeleeInfantry"] = { "priority": 1, "minSize": 5, "targetSize": 20, "batchSize": 5, "classes": ["Infantry","Melee", "Champion"],
this.unitStat.ChampMeleeInfantry = { "priority": 1, "minSize": 5, "targetSize": 20, "batchSize": 5, "classes": ["Infantry","Melee", "Champion"],
"interests": [ ["strength",3], ["cost",1] ] };
this.unitStat["MeleeCavalry"] = { "priority": 0.7, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["Cavalry","Melee", "CitizenSoldier"],
this.unitStat.MeleeCavalry = { "priority": 0.7, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["Cavalry","Melee", "CitizenSoldier"],
"interests": [ ["strength",2], ["cost",1] ] };
this.unitStat["RangedCavalry"] = { "priority": 0.7, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["Cavalry","Ranged", "CitizenSoldier"],
this.unitStat.RangedCavalry = { "priority": 0.7, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["Cavalry","Ranged", "CitizenSoldier"],
"interests": [ ["strength",2], ["cost",1] ] };
this.unitStat["ChampMeleeInfantry"] = { "priority": 1, "minSize": 3, "targetSize": 18, "batchSize": 3, "classes": ["Infantry","Melee", "Champion"],
this.unitStat.ChampMeleeInfantry = { "priority": 1, "minSize": 3, "targetSize": 18, "batchSize": 3, "classes": ["Infantry","Melee", "Champion"],
"interests": [ ["strength",3], ["cost",1] ] };
this.unitStat["ChampMeleeCavalry"] = { "priority": 1, "minSize": 3, "targetSize": 18, "batchSize": 3, "classes": ["Cavalry","Melee", "Champion"],
this.unitStat.ChampMeleeCavalry = { "priority": 1, "minSize": 3, "targetSize": 18, "batchSize": 3, "classes": ["Cavalry","Melee", "Champion"],
"interests": [ ["strength",2], ["cost",1] ] };
this.unitStat["Hero"] = { "priority": 1, "minSize": 0, "targetSize": 1, "batchSize": 1, "classes": ["Hero"],
this.unitStat.Hero = { "priority": 1, "minSize": 0, "targetSize": 1, "batchSize": 1, "classes": ["Hero"],
"interests": [ ["strength",2], ["cost",1] ] };
this.neededShips = 5;
}
else
{
priority = 70;
this.unitStat["RangedInfantry"] = { "priority": 1, "minSize": 6, "targetSize": 16, "batchSize": 3, "classes": ["Infantry","Ranged"],
this.unitStat.RangedInfantry = { "priority": 1, "minSize": 6, "targetSize": 16, "batchSize": 3, "classes": ["Infantry","Ranged"],
"interests": [ ["canGather", 1], ["strength",1.6], ["cost",1.5], ["costsResource", 0.3, "stone"], ["costsResource", 0.3, "metal"] ] };
this.unitStat["MeleeInfantry"] = { "priority": 1, "minSize": 6, "targetSize": 16, "batchSize": 3, "classes": ["Infantry","Melee"],
this.unitStat.MeleeInfantry = { "priority": 1, "minSize": 6, "targetSize": 16, "batchSize": 3, "classes": ["Infantry","Melee"],
"interests": [ ["canGather", 1], ["strength",1.6], ["cost",1.5], ["costsResource", 0.3, "stone"], ["costsResource", 0.3, "metal"] ] };
this.unitStat["Cavalry"] = { "priority": 1, "minSize": 2, "targetSize": 6, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"],
this.unitStat.Cavalry = { "priority": 1, "minSize": 2, "targetSize": 6, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"],
"interests": [ ["strength",1], ["cost",1] ] };
this.neededShips = 3;
}
@ -171,16 +171,16 @@ m.AttackPlan = function(gameState, Config, uniqueID, type, data)
}
for (let cat in this.unitStat)
{
this.unitStat[cat]["targetSize"] = Math.round(variation * this.unitStat[cat]["targetSize"]);
this.unitStat[cat]["minSize"] = Math.min(this.unitStat[cat]["minSize"], this.unitStat[cat]["targetSize"]);
this.unitStat[cat].targetSize = Math.round(variation * this.unitStat[cat].targetSize);
this.unitStat[cat].minSize = Math.min(this.unitStat[cat].minSize, this.unitStat[cat].targetSize);
}
// change the sizes according to max population
this.neededShips = Math.ceil(this.Config.popScaling * this.neededShips);
for (let cat in this.unitStat)
{
this.unitStat[cat]["targetSize"] = Math.round(this.Config.popScaling * this.unitStat[cat]["targetSize"]);
this.unitStat[cat]["minSize"] = Math.floor(this.Config.popScaling * this.unitStat[cat]["minSize"]);
this.unitStat[cat].targetSize = Math.round(this.Config.popScaling * this.unitStat[cat].targetSize);
this.unitStat[cat].minSize = Math.floor(this.Config.popScaling * this.unitStat[cat].minSize);
}
// TODO: there should probably be one queue per type of training building
@ -219,10 +219,10 @@ m.AttackPlan.prototype.init = function(gameState)
for (let cat in this.unitStat)
{
let Unit = this.unitStat[cat];
this.unit[cat] = this.unitCollection.filter(API3.Filters.byClassesAnd(Unit["classes"]));
this.unit[cat] = this.unitCollection.filter(API3.Filters.byClassesAnd(Unit.classes));
this.unit[cat].registerUpdates();
if (this.canBuildUnits)
this.buildOrder.push([0, Unit["classes"], this.unit[cat], Unit, cat]);
this.buildOrder.push([0, Unit.classes, this.unit[cat], Unit, cat]);
}
};
@ -259,11 +259,9 @@ m.AttackPlan.prototype.canStart = function()
return true;
for (let unitCat in this.unitStat)
{
let Unit = this.unitStat[unitCat];
if (this.unit[unitCat].length < Unit["minSize"])
if (this.unit[unitCat].length < this.unitStat[unitCat].minSize)
return false;
}
return true;
};
@ -280,9 +278,9 @@ m.AttackPlan.prototype.mustStart = function()
for (let unitCat in this.unitStat)
{
let Unit = this.unitStat[unitCat];
if (this.unit[unitCat].length < Unit["targetSize"])
if (this.unit[unitCat].length < Unit.targetSize)
MaxReachedEverywhere = false;
if (this.unit[unitCat].length < Unit["minSize"])
if (this.unit[unitCat].length < Unit.minSize)
{
MinReachedEverywhere = false;
break;
@ -304,8 +302,8 @@ m.AttackPlan.prototype.forceStart = function()
for (let unitCat in this.unitStat)
{
let Unit = this.unitStat[unitCat];
Unit["targetSize"] = 0;
Unit["minSize"] = 0;
Unit.targetSize = 0;
Unit.minSize = 0;
}
};
@ -317,9 +315,9 @@ m.AttackPlan.prototype.addBuildOrder = function(gameState, name, unitStats, rese
// no minsize as we don't want the plan to fail at the last minute though.
this.unitStat[name] = unitStats;
let Unit = this.unitStat[name];
this.unit[name] = this.unitCollection.filter(API3.Filters.byClassesAnd(Unit["classes"]));
this.unit[name] = this.unitCollection.filter(API3.Filters.byClassesAnd(Unit.classes));
this.unit[name].registerUpdates();
this.buildOrder.push([0, Unit["classes"], this.unit[name], Unit, name]);
this.buildOrder.push([0, Unit.classes, this.unit[name], Unit, name]);
if (resetQueue)
{
this.queue.empty();
@ -331,18 +329,18 @@ m.AttackPlan.prototype.addBuildOrder = function(gameState, name, unitStats, rese
m.AttackPlan.prototype.addSiegeUnits = function(gameState)
{
if (this.unitStat["Siege"] || this.state !== "unexecuted")
if (this.unitStat.Siege || this.state !== "unexecuted")
return false;
// no minsize as we don't want the plan to fail at the last minute though.
var stat = { "priority": 1., "minSize": 0, "targetSize": 4, "batchSize": 2, "classes": ["Siege"],
var stat = { "priority": 1, "minSize": 0, "targetSize": 4, "batchSize": 2, "classes": ["Siege"],
"interests": [ ["siegeStrength", 3], ["cost",1] ] };
if (gameState.civ() === "maur")
stat["classes"] = ["Elephant", "Champion"];
stat.classes = ["Elephant", "Champion"];
if (this.Config.difficulty < 2)
stat["targetSize"] = 1;
stat.targetSize = 1;
else if (this.Config.difficulty < 3)
stat["targetSize"] = 2;
stat["targetSize"] = Math.round(this.Config.popScaling * stat["targetSize"]);
stat.targetSize = 2;
stat.targetSize = Math.round(this.Config.popScaling * stat.targetSize);
this.addBuildOrder(gameState, "Siege", stat, true);
return true;
};
@ -372,7 +370,7 @@ m.AttackPlan.prototype.updatePreparation = function(gameState)
}
}
if (this.Config.debug > 3 && gameState.ai.playedTurn % 50 == 0)
if (this.Config.debug > 3 && gameState.ai.playedTurn % 50 === 0)
this.debugAttack();
// if we need a transport, wait for some transport ships
@ -400,14 +398,14 @@ m.AttackPlan.prototype.updatePreparation = function(gameState)
if (this.Config.debug > 1)
{
var am = gameState.ai.HQ.attackManager;
API3.warn(" attacks upcoming: raid " + am.upcomingAttacks["Raid"].length
+ " rush " + am.upcomingAttacks["Rush"].length
+ " attack " + am.upcomingAttacks["Attack"].length
+ " huge " + am.upcomingAttacks["HugeAttack"].length);
API3.warn(" attacks started: raid " + am.startedAttacks["Raid"].length
+ " rush " + am.startedAttacks["Rush"].length
+ " attack " + am.startedAttacks["Attack"].length
+ " huge " + am.startedAttacks["HugeAttack"].length);
API3.warn(" attacks upcoming: raid " + am.upcomingAttacks.Raid.length +
" rush " + am.upcomingAttacks.Rush.length +
" attack " + am.upcomingAttacks.Attack.length +
" huge " + am.upcomingAttacks.HugeAttack.length);
API3.warn(" attacks started: raid " + am.startedAttacks.Raid.length +
" rush " + am.startedAttacks.Rush.length +
" attack " + am.startedAttacks.Attack.length +
" huge " + am.startedAttacks.HugeAttack.length);
}
return 0;
}
@ -425,7 +423,7 @@ m.AttackPlan.prototype.updatePreparation = function(gameState)
if (this.canBuildUnits)
{
// We still have time left to recruit units and do stuffs.
if (!this.unitStat["Siege"])
if (!this.unitStat.Siege)
{
var numSiegeBuilder = 0;
if (gameState.civ() !== "mace" && gameState.civ() !== "maur")
@ -510,16 +508,16 @@ m.AttackPlan.prototype.trainMoreUnits = function(gameState)
this.buildOrder[i][0] = this.buildOrder[i][2].length + aQueued;
}
this.buildOrder.sort(function (a,b) {
let va = a[0]/a[3]["targetSize"] - a[3]["priority"];
if (a[0] >= a[3]["targetSize"])
let va = a[0]/a[3].targetSize - a[3].priority;
if (a[0] >= a[3].targetSize)
va += 1000;
let vb = b[0]/b[3]["targetSize"] - b[3]["priority"];
if (b[0] >= b[3]["targetSize"])
let vb = b[0]/b[3].targetSize - b[3].priority;
if (b[0] >= b[3].targetSize)
vb += 1000;
return va - vb;
});
if (this.Config.debug > 1 && gameState.ai.playedTurn%50 == 0)
if (this.Config.debug > 1 && gameState.ai.playedTurn%50 === 0)
{
API3.warn("====================================");
API3.warn("======== build order for plan " + this.name);
@ -530,51 +528,51 @@ m.AttackPlan.prototype.trainMoreUnits = function(gameState)
let queue1 = this.queue.countQueuedUnitsWithMetadata("special", specialData);
let queue2 = this.queueChamp.countQueuedUnitsWithMetadata("special", specialData);
let queue3 = this.queueSiege.countQueuedUnitsWithMetadata("special", specialData);
API3.warn(" >>> " + order[4] + " done " + order[2].length + " training " + inTraining
+ " queue " + queue1 + " champ " + queue2 + " siege " + queue3 + " >> need " + order[3].targetSize);
API3.warn(" >>> " + order[4] + " done " + order[2].length + " training " + inTraining +
" queue " + queue1 + " champ " + queue2 + " siege " + queue3 + " >> need " + order[3].targetSize);
}
API3.warn("====================================");
}
if (this.buildOrder[0][0] < this.buildOrder[0][3]["targetSize"])
let firstOrder = this.buildOrder[0];
if (firstOrder[0] < firstOrder[3].targetSize)
{
// find the actual queue we want
var queue = this.queue;
if (this.buildOrder[0][3]["classes"].indexOf("Siege") !== -1 ||
(gameState.civ() == "maur" && this.buildOrder[0][3]["classes"].indexOf("Elephant") !== -1 && this.buildOrder[0][3]["classes"].indexOf("Champion")))
let queue = this.queue;
if (firstOrder[3].classes.indexOf("Siege") !== -1 ||
(gameState.civ() == "maur" && firstOrder[3].classes.indexOf("Elephant") !== -1 && firstOrder[3].classes.indexOf("Champion")))
queue = this.queueSiege;
else if (this.buildOrder[0][3]["classes"].indexOf("Hero") !== -1)
else if (firstOrder[3].classes.indexOf("Hero") !== -1)
queue = this.queueSiege;
else if (this.buildOrder[0][3]["classes"].indexOf("Champion") !== -1)
else if (firstOrder[3].classes.indexOf("Champion") !== -1)
queue = this.queueChamp;
if (queue.length() <= 5)
{
var template = gameState.ai.HQ.findBestTrainableUnit(gameState, this.buildOrder[0][1], this.buildOrder[0][3]["interests"]);
let template = gameState.ai.HQ.findBestTrainableUnit(gameState, firstOrder[1], firstOrder[3].interests);
// HACK (TODO replace) : if we have no trainable template... Then we'll simply remove the buildOrder,
// effectively removing the unit from the plan.
if (template === undefined)
{
if (this.Config.debug > 1)
API3.warn("attack no template found " + this.buildOrder[0][1]);
delete this.unitStat[this.buildOrder[0][4]]; // deleting the associated unitstat.
API3.warn("attack no template found " + firstOrder[1]);
delete this.unitStat[firstOrder[4]]; // deleting the associated unitstat.
this.buildOrder.splice(0,1);
}
else
{
if (this.Config.debug > 2)
API3.warn("attack template " + template + " added for plan " + this.name);
var max = this.buildOrder[0][3]["batchSize"];
var specialData = "Plan_" + this.name + "_" + this.buildOrder[0][4];
if (gameState.getTemplate(template).hasClass("CitizenSoldier"))
var trainingPlan = new m.TrainingPlan(gameState, template, { "role": "worker", "plan": this.name, "special": specialData, "base": 0 }, max, max);
else
var trainingPlan = new m.TrainingPlan(gameState, template, { "role": "attack", "plan": this.name, "special": specialData, "base": 0 }, max, max);
let max = firstOrder[3].batchSize;
let specialData = "Plan_" + this.name + "_" + firstOrder[4];
let data = { "plan": this.name, "special": specialData, "base": 0 };
data.role = gameState.getTemplate(template).hasClass("CitizenSoldier") ? "worker" : "attack";
let trainingPlan = new m.TrainingPlan(gameState, template, data, max, max);
if (trainingPlan.template)
queue.addPlan(trainingPlan);
else if (this.Config.debug > 1)
API3.warn("training plan canceled because no template for " + template + " build1 " + uneval(this.buildOrder[0][1])
+ " build3 " + uneval(this.buildOrder[0][3]["interests"]));
API3.warn("training plan canceled because no template for " + template + " build1 " + uneval(firstOrder[1]) +
" build3 " + uneval(firstOrder[3].interests));
}
}
}
@ -1068,9 +1066,8 @@ m.AttackPlan.prototype.update = function(gameState, events)
{
if (IDs.indexOf(evt.target) == -1)
continue;
var attacker = gameState.getEntityById(evt.attacker);
var ourUnit = gameState.getEntityById(evt.target);
if (!attacker || !ourUnit)
let attacker = gameState.getEntityById(evt.attacker);
if (!attacker || !gameState.getEntityById(evt.target))
continue;
for (let ent of this.unitCollection.values())
{
@ -1096,11 +1093,9 @@ m.AttackPlan.prototype.update = function(gameState, events)
var attackedUnitNB = 0;
for (let evt of events.Attacked)
{
if (IDs.indexOf(evt.target) == -1)
if (IDs.indexOf(evt.target) === -1)
continue;
var attacker = gameState.getEntityById(evt.attacker);
var ourUnit = gameState.getEntityById(evt.target);
let attacker = gameState.getEntityById(evt.attacker);
if (attacker && (attacker.owner() !== 0 || this.targetPlayer === 0))
{
attackedNB++;
@ -1112,7 +1107,7 @@ m.AttackPlan.prototype.update = function(gameState, events)
var maybe = true;
if (attackedUnitNB == 0)
{
var siegeNB = 0;
let siegeNB = 0;
for (let ent of this.unitCollection.values())
if (this.isSiegeUnit(gameState, ent))
siegeNB++;
@ -1341,11 +1336,11 @@ m.AttackPlan.prototype.update = function(gameState, events)
{ // if units are attacked, abandon their target (if it was a structure or a support) and retaliate
// also if our unit is attacking a range unit and the attacker is a melee unit, retaliate
var orderData = ourUnit.unitAIOrderData();
if (orderData && orderData.length && orderData[0]["target"])
if (orderData && orderData.length && orderData[0].target)
{
if (orderData[0]["target"] === attacker.id())
if (orderData[0].target === attacker.id())
continue;
let target = gameState.getEntityById(orderData[0]["target"]);
let target = gameState.getEntityById(orderData[0].target);
if (target && !target.hasClass("Structure") && !target.hasClass("Support"))
{
if (!target.hasClass("Ranged") || !attacker.hasClass("Melee"))
@ -1368,9 +1363,9 @@ m.AttackPlan.prototype.update = function(gameState, events)
if (ent.hasClass("Ship")) // TODO What to do with ships
continue;
let orderData = ent.unitAIOrderData();
if (!orderData || !orderData.length || !orderData[0]["target"])
if (!orderData || !orderData.length || !orderData[0].target)
continue;
let targetId = orderData[0]["target"];
let targetId = orderData[0].target;
let target = gameState.getEntityById(targetId);
if (!target || target.hasClass("Structure"))
continue;
@ -1419,10 +1414,7 @@ m.AttackPlan.prototype.update = function(gameState, events)
this.unitCollUpdateArray = this.unitCollection.toIdArray();
// Let's check a few units each time we update (currently 10) except when attack starts
if (this.unitCollUpdateArray.length < 15 || this.startingAttack)
var lgth = this.unitCollUpdateArray.length;
else
var lgth = 10;
var lgth = (this.unitCollUpdateArray.length < 15 || this.startingAttack) ? this.unitCollUpdateArray.length : 10;
for (var check = 0; check < lgth; check++)
{
var ent = gameState.getEntityById(this.unitCollUpdateArray[check]);
@ -1431,8 +1423,8 @@ m.AttackPlan.prototype.update = function(gameState, events)
let targetId = undefined;
let orderData = ent.unitAIOrderData();
if (orderData && orderData.length && orderData[0]["target"])
targetId = orderData[0]["target"];
if (orderData && orderData.length && orderData[0].target)
targetId = orderData[0].target;
// update the order if needed
var needsUpdate = false;
@ -1569,14 +1561,14 @@ m.AttackPlan.prototype.update = function(gameState, events)
if (mUnit.length !== 0)
{
mUnit.sort(function (unitA,unitB) {
var vala = unitA.hasClass("Support") ? 50 : 0;
let vala = unitA.hasClass("Support") ? 50 : 0;
if (ent.countersClasses(unitA.classes()))
vala += 100;
var valb = unitB.hasClass("Support") ? 50 : 0;
let valb = unitB.hasClass("Support") ? 50 : 0;
if (ent.countersClasses(unitB.classes()))
valb += 100;
var distA = unitA.getMetadata(PlayerID, "distance");
var distB = unitB.getMetadata(PlayerID, "distance");
let distA = unitA.getMetadata(PlayerID, "distance");
let distB = unitB.getMetadata(PlayerID, "distance");
if( distA && distB)
{
vala -= distA;
@ -1620,12 +1612,12 @@ m.AttackPlan.prototype.update = function(gameState, events)
if (mStruct.length !== 0)
{
mStruct.sort(function (structa,structb) {
var vala = structa.costSum();
let vala = structa.costSum();
if (structa.hasClass("Gates") && ent.canAttackClass("StoneWall"))
vala += 10000;
else if (structa.hasClass("ConquestCritical"))
vala += 100;
var valb = structb.costSum();
let valb = structb.costSum();
if (structb.hasClass("Gates") && ent.canAttackClass("StoneWall"))
valb += 10000;
else if (structb.hasClass("ConquestCritical"))
@ -1643,19 +1635,19 @@ m.AttackPlan.prototype.update = function(gameState, events)
}
else if (needsUpdate) // really nothing let's try to help our nearest unit
{
var distmin = Math.min();
var attackerId = undefined;
let distmin = Math.min();
let attackerId;
this.unitCollection.forEach( function (unit) {
if (!unit.position())
return;
if (unit.unitAIState().split(".")[1] !== "COMBAT" || !unit.unitAIOrderData().length
|| !unit.unitAIOrderData()[0]["target"])
if (unit.unitAIState().split(".")[1] !== "COMBAT" || !unit.unitAIOrderData().length ||
!unit.unitAIOrderData()[0].target)
return;
var dist = API3.SquareVectorDistance(unit.position(), ent.position());
let dist = API3.SquareVectorDistance(unit.position(), ent.position());
if (dist > distmin)
return;
distmin = dist;
attackerId = unit.unitAIOrderData()[0]["target"];
attackerId = unit.unitAIOrderData()[0].target;
});
if (attackerId)
@ -1795,7 +1787,7 @@ m.AttackPlan.prototype.debugAttack = function()
for (var unitCat in this.unitStat)
{
var Unit = this.unitStat[unitCat];
API3.warn(unitCat + " num=" + this.unit[unitCat].length + " min=" + Unit["minSize"] + " need=" + Unit["targetSize"]);
API3.warn(unitCat + " num=" + this.unit[unitCat].length + " min=" + Unit.minSize + " need=" + Unit.targetSize);
}
API3.warn("------------------------------");
};
@ -1822,8 +1814,8 @@ m.AttackPlan.prototype.CheckCapture = function(gameState, ent)
if (!state || !state.split(".")[1] || state.split(".")[1] !== "COMBAT")
return true;
let orderData = ent.unitAIOrderData();
if (!orderData || !orderData.length || !orderData[0].target
|| !orderData[0].attackType || orderData[0].attackType !== "Capture")
if (!orderData || !orderData.length || !orderData[0].target ||
!orderData[0].attackType || orderData[0].attackType !== "Capture")
return true;
let targetId = orderData[0].target;

View file

@ -54,7 +54,7 @@ m.BaseManager.prototype.init = function(gameState, state)
this.dropsites = {};
this.dropsiteSupplies = {};
this.gatherers = {};
for (var type of this.Config.resources)
for (let type of this.Config.resources)
{
this.dropsiteSupplies[type] = {"nearby": [], "medium": [], "faraway": []};
this.gatherers[type] = {"nextCheck": 0, "used": 0, "lost": 0};
@ -85,7 +85,7 @@ m.BaseManager.prototype.setAnchor = function(gameState, anchorEntity)
this.buildings.updateEnt(this.anchor);
this.accessIndex = gameState.ai.accessibility.getAccessValue(this.anchor.position());
// in case some of our other bases were destroyed, reaffect these destroyed bases to this base
for (var base of gameState.ai.HQ.baseManagers)
for (let base of gameState.ai.HQ.baseManagers)
{
if (base.anchor || base.newbaseID)
continue;
@ -100,12 +100,12 @@ m.BaseManager.prototype.checkEvents = function (gameState, events, queues)
{
// let's check we haven't lost an important building here.
if (evt && !evt.SuccessfulFoundation && evt.entityObj && evt.metadata && evt.metadata[PlayerID] &&
evt.metadata[PlayerID]["base"] && evt.metadata[PlayerID]["base"] == this.ID)
evt.metadata[PlayerID].base && evt.metadata[PlayerID].base == this.ID)
{
let ent = evt.entityObj;
if (ent.resourceDropsiteTypes() && !ent.hasClass("Elephant"))
this.removeDropsite(gameState, ent);
if (evt.metadata[PlayerID]["baseAnchor"] && evt.metadata[PlayerID]["baseAnchor"] === true)
if (evt.metadata[PlayerID].baseAnchor && evt.metadata[PlayerID].baseAnchor === true)
this.anchorLost(gameState, ent);
}
}
@ -202,12 +202,12 @@ m.BaseManager.prototype.assignResourceToDropsite = function (gameState, dropsite
for (var type of dropsite.resourceDropsiteTypes())
{
var resources = gameState.getResourceSupplies(type);
if (resources.length == 0)
if (!resources.length)
continue;
var nearby = this.dropsiteSupplies[type]["nearby"];
var medium = this.dropsiteSupplies[type]["medium"];
var faraway = this.dropsiteSupplies[type]["faraway"];
var nearby = this.dropsiteSupplies[type].nearby;
var medium = this.dropsiteSupplies[type].medium;
var faraway = this.dropsiteSupplies[type].faraway;
resources.forEach(function(supply)
{
@ -217,7 +217,7 @@ m.BaseManager.prototype.assignResourceToDropsite = function (gameState, dropsite
return;
if (supply.hasClass("Field")) // fields are treated separately
return;
if (supply.resourceSupplyType()["generic"] === "treasure") // treasures are treated separately
if (supply.resourceSupplyType().generic === "treasure") // treasures are treated separately
return;
// quick accessibility check
let access = supply.getMetadata(PlayerID, "access");
@ -268,7 +268,7 @@ m.BaseManager.prototype.removeDropsite = function (gameState, ent)
return;
var removeSupply = function(entId, supply){
for (var i = 0; i < supply.length; ++i)
for (let i = 0; i < supply.length; ++i)
{
// exhausted resource, remove it from this list
if (!supply[i].ent || !gameState.getEntityById(supply[i].id))
@ -279,11 +279,11 @@ m.BaseManager.prototype.removeDropsite = function (gameState, ent)
}
};
for (var type in this.dropsiteSupplies)
for (let type in this.dropsiteSupplies)
{
removeSupply(ent.id(), this.dropsiteSupplies[type]["nearby"]);
removeSupply(ent.id(), this.dropsiteSupplies[type]["medium"]);
removeSupply(ent.id(), this.dropsiteSupplies[type]["faraway"]);
removeSupply(ent.id(), this.dropsiteSupplies[type].nearby);
removeSupply(ent.id(), this.dropsiteSupplies[type].medium);
removeSupply(ent.id(), this.dropsiteSupplies[type].faraway);
}
this.dropsites[ent.id()] = undefined;
@ -558,7 +558,7 @@ m.BaseManager.prototype.setWorkersIdleByPriority = function(gameState)
var mostNeeded = gameState.ai.HQ.pickMostNeededResources(gameState);
var sumWanted = 0;
var sumCurrent = 0;
for (var need of mostNeeded)
for (let need of mostNeeded)
{
sumWanted += need.wanted;
sumCurrent += need.current;
@ -611,7 +611,7 @@ m.BaseManager.prototype.reassignIdleWorkers = function(gameState, idleWorkers)
// Search for idle workers, and tell them to gather resources based on demand
if (!idleWorkers)
{
var filter = API3.Filters.byMetadata(PlayerID, "subrole", "idle");
let filter = API3.Filters.byMetadata(PlayerID, "subrole", "idle");
idleWorkers = gameState.updatingCollection("idle-workers-base-" + this.ID, filter, this.workers).values();
}

View file

@ -31,6 +31,8 @@ m.getMaxStrength = function(ent, againstClass)
case "pierce":
strength += (val * 0.065) / 3;
break;
default:
API3.warn("Petra: " + str + " unknown attackStrength in getMaxStrength");
}
}
@ -50,6 +52,8 @@ m.getMaxStrength = function(ent, againstClass)
case "prepare":
strength -= (val / 100000);
break;
default:
API3.warn("Petra: " + str + " unknown attackTimes in getMaxStrength");
}
}
}
@ -69,6 +73,8 @@ m.getMaxStrength = function(ent, againstClass)
case "pierce":
strength += (val * 0.065) / 3;
break;
default:
API3.warn("Petra: " + str + " unknown armourStrength in getMaxStrength");
}
}

View file

@ -230,7 +230,7 @@ m.QueueManager.prototype.distributeResources = function(gameState)
var total = gameState.getResources()[res];
var scale = total / (total - availableRes[res]);
availableRes[res] = total;
for (var j in this.queues)
for (let j in this.queues)
{
this.accounts[j][res] = Math.floor(scale * this.accounts[j][res]);
availableRes[res] -= this.accounts[j][res];
@ -255,7 +255,7 @@ m.QueueManager.prototype.distributeResources = function(gameState)
// -queues accounts are capped at "resources for the first + 60% of the next"
// This avoids getting a high priority queue with many elements hogging all of one resource
// uselessly while it awaits for other resources.
for (var j in this.queues)
for (let j in this.queues)
{
// returns exactly the correct amount, ie 0 if we're not go.
var queueCost = this.queues[j].maxAccountWanted(gameState, 0.6);
@ -281,10 +281,10 @@ m.QueueManager.prototype.distributeResources = function(gameState)
// But we'll sometimes allow less if that would overflow.
var available = availableRes[res];
var missing = false;
for (var j in tempPrio)
for (let j in tempPrio)
{
// we'll add at much what can be allowed to this queue.
var toAdd = Math.floor(availableRes[res] * tempPrio[j]/totalPriority);
let toAdd = Math.floor(availableRes[res] * tempPrio[j]/totalPriority);
if (toAdd >= maxNeed[j])
toAdd = maxNeed[j];
else
@ -295,9 +295,9 @@ m.QueueManager.prototype.distributeResources = function(gameState)
}
if (missing && available > 0) // distribute the rest (due to floor) in any queue
{
for (var j in tempPrio)
for (let j in tempPrio)
{
var toAdd = Math.min(maxNeed[j], available);
let toAdd = Math.min(maxNeed[j], available);
this.accounts[j][res] += toAdd;
available -= toAdd;
if (available <= 0)
@ -423,12 +423,12 @@ m.QueueManager.prototype.checkPausedQueues = function(gameState)
else if (numWorkers < workersMin / 3)
toBePaused = (q !== "citizenSoldier" && q !== "villager" && q !== "emergency");
else if (numWorkers < workersMin * 2 / 3)
toBePaused = (q === "civilCentre" || q === "economicBuilding"
|| q === "militaryBuilding" || q === "defenseBuilding"
|| q === "majorTech" || q === "minorTech" || q.indexOf("plan_") !== -1);
toBePaused = (q === "civilCentre" || q === "economicBuilding" ||
q === "militaryBuilding" || q === "defenseBuilding" ||
q === "majorTech" || q === "minorTech" || q.indexOf("plan_") !== -1);
else if (numWorkers < workersMin)
toBePaused = (q === "civilCentre" || q === "defenseBuilding"
|| q == "majorTech" || q.indexOf("_siege") != -1 || q.indexOf("_champ") != -1);
toBePaused = (q === "civilCentre" || q === "defenseBuilding" ||
q == "majorTech" || q.indexOf("_siege") != -1 || q.indexOf("_champ") != -1);
let queue = this.queues[q];
if (!queue.paused && toBePaused)
@ -547,8 +547,8 @@ m.QueueManager.prototype.Serialize = function()
queues[q] = this.queues[q].Serialize();
accounts[q] = this.accounts[q].Serialize();
if (this.Config.debug == -100)
API3.warn("queueManager serialization: queue " + q + " >>> " + uneval(queues[q])
+ " with accounts " + uneval(accounts[q]));
API3.warn("queueManager serialization: queue " + q + " >>> " +
uneval(queues[q]) + " with accounts " + uneval(accounts[q]));
}
return {

View file

@ -25,48 +25,45 @@ m.TrainingPlan.prototype.canStart = function(gameState)
if (this.invalidTemplate)
return false;
// TODO: we should probably check pop caps
let trainers = gameState.findTrainers(this.type);
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);
trainers = trainers.filter(API3.Filters.byMetadata(PlayerID, "sea", this.metadata.sea));
return (trainers.length != 0);
return (trainers.length !== 0);
};
m.TrainingPlan.prototype.start = function(gameState)
{
if (this.metadata && this.metadata.trainer)
{
var metadata = {};
for (var key in this.metadata)
let metadata = {};
for (let key in this.metadata)
if (key !== "trainer")
metadata[key] = this.metadata[key];
var trainer = gameState.getEntityById(this.metadata.trainer);
let trainer = gameState.getEntityById(this.metadata.trainer);
if (trainer)
trainer.train(gameState.civ(), this.type, this.number, metadata, this.promotedTypes(gameState));
this.onStart(gameState);
return;
}
let trainersColl = gameState.findTrainers(this.type);
if (this.metadata && this.metadata.sea)
var trainers = gameState.findTrainers(this.type).filter(API3.Filters.byMetadata(PlayerID, "sea", this.metadata.sea)).toEntityArray();
trainersColl = trainersColl.filter(API3.Filters.byMetadata(PlayerID, "sea", this.metadata.sea));
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();
trainersColl = trainersColl.filter(API3.Filters.byMetadata(PlayerID, "base", this.metadata.base));
// 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)
if (trainersColl.length > 0)
{
var wantedIndex = undefined;
let trainers = trainersColl.toEntityArray();
let wantedIndex;
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");
let workerUnit = (this.metadata && this.metadata.role && this.metadata.role == "worker");
let supportUnit = this.template.hasClass("Support");
trainers.sort(function(a, b) {
let aa = a.trainingQueueTime();
let bb = b.trainingQueueTime();
@ -102,7 +99,7 @@ m.TrainingPlan.prototype.start = function(gameState)
}
return (aa - bb);
});
if (this.metadata && this.metadata.base !== undefined && this.metadata.base == 0)
if (this.metadata && this.metadata.base !== undefined && this.metadata.base === 0)
this.metadata.base = trainers[0].getMetadata(PlayerID, "base");
trainers[0].train(gameState.civ(), this.type, this.number, this.metadata, this.promotedTypes(gameState));
}

View file

@ -54,18 +54,20 @@ m.TradeManager.prototype.trainMoreTraders = function(gameState, queues)
numLandTraders += item.count;
});
});
if (numTraders >= this.targetNumTraders
&& ((!this.tradeRoute.sea && numLandTraders >= Math.floor(this.targetNumTraders/2))
|| (this.tradeRoute.sea && numSeaTraders >= Math.floor(this.targetNumTraders/2))))
if (numTraders >= this.targetNumTraders &&
((!this.tradeRoute.sea && numLandTraders >= Math.floor(this.targetNumTraders/2)) ||
(this.tradeRoute.sea && numSeaTraders >= Math.floor(this.targetNumTraders/2))))
return;
let template;
let metadata = { "role": "trader" };
if (this.tradeRoute.sea)
{
// if we have some merchand ships affected to transport, try first to reaffect them
// May-be, there were produced at an early stage when no other ship were available
// and the naval manager will train now more appropriate ships.
var already = false;
var shipToSwitch;
let already = false;
let shipToSwitch;
gameState.ai.HQ.navalManager.seaTransportShips[this.tradeRoute.sea].forEach(function(ship) {
if (already || !ship.hasClass("Trader"))
return;
@ -87,16 +89,16 @@ m.TradeManager.prototype.trainMoreTraders = function(gameState, queues)
return;
}
var template = gameState.applyCiv("units/{civ}_ship_merchant");
var metadata = { "role": "trader", "sea": this.tradeRoute.sea };
template = gameState.applyCiv("units/{civ}_ship_merchant");
metadata.sea = this.tradeRoute.sea;
}
else
{
var template = gameState.applyCiv("units/{civ}_support_trader");
template = gameState.applyCiv("units/{civ}_support_trader");
if (!this.tradeRoute.source.hasClass("NavalMarket"))
var metadata = { "role": "trader", "base": this.tradeRoute.source.getMetadata(PlayerID, "base") };
metadata.base = this.tradeRoute.source.getMetadata(PlayerID, "base");
else
var metadata = { "role": "trader", "base": this.tradeRoute.target.getMetadata(PlayerID, "base") };
metadata.base = this.tradeRoute.target.getMetadata(PlayerID, "base");
}
if (!gameState.getTemplate(template))
@ -116,10 +118,7 @@ m.TradeManager.prototype.updateTrader = function(gameState, ent)
return;
Engine.ProfileStart("Trade Manager");
if (ent.hasClass("Ship"))
var access = ent.getMetadata(PlayerID, "sea");
else
var access = gameState.ai.accessibility.getAccessValue(ent.position());
var access = ent.hasClass("Ship") ? ent.getMetadata(PlayerID, "sea") : gameState.ai.accessibility.getAccessValue(ent.position());
var route = this.checkRoutes(gameState, access);
if (!route)
{
@ -215,27 +214,28 @@ m.TradeManager.prototype.performBarter = function(gameState)
var prices = gameState.getBarterPrices();
// calculates conversion rates
var getBarterRate = function (prices,buy,sell) { return Math.round(100 * prices["sell"][sell] / prices["buy"][buy]); };
var getBarterRate = function (prices,buy,sell) { return Math.round(100 * prices.sell[sell] / prices.buy[buy]); };
// loop through each missing resource checking if we could barter and help finishing a queue quickly.
for (var buy of needs.types)
{
if (needs[buy] == 0 || needs[buy] < rates[buy]*30) // check if our rate allows to gather it fast enough
if (needs[buy] === 0 || needs[buy] < rates[buy]*30) // check if our rate allows to gather it fast enough
continue;
// pick the best resource to barter.
var bestToSell = undefined;
var bestRate = 0;
for (var sell of needs.types)
for (let sell of needs.types)
{
if (sell === buy)
continue;
if (needs[sell] > 0 || available[sell] < 500) // do not sell if we need it or do not have enough buffer
continue;
let barterRateMin;
if (sell === "food")
{
var barterRateMin = 30;
barterRateMin = 30;
if (available[sell] > 40000)
barterRateMin = 0;
else if (available[sell] > 15000)
@ -245,14 +245,14 @@ m.TradeManager.prototype.performBarter = function(gameState)
}
else
{
var barterRateMin = 70;
barterRateMin = 70;
if (available[sell] > 1000)
barterRateMin = 50;
if (buy === "food")
barterRateMin += 20;
}
var barterRate = getBarterRate(prices, buy, sell);
let barterRate = getBarterRate(prices, buy, sell);
if (barterRate > bestRate && barterRate > barterRateMin)
{
bestRate = barterRate;
@ -263,29 +263,29 @@ m.TradeManager.prototype.performBarter = function(gameState)
{
barterers[0].barter(buy, bestToSell, 100);
if (this.Config.debug > 2)
API3.warn("Necessity bartering: sold " + bestToSell +" for " + buy + " >> need sell " + needs[bestToSell]
+ " need buy " + needs[buy] + " rate buy " + rates[buy] + " available sell " + available[bestToSell]
+ " available buy " + available[buy] + " barterRate " + bestRate);
API3.warn("Necessity bartering: sold " + bestToSell +" for " + buy + " >> need sell " + needs[bestToSell] +
" need buy " + needs[buy] + " rate buy " + rates[buy] + " available sell " + available[bestToSell] +
" available buy " + available[buy] + " barterRate " + bestRate);
return true;
}
}
// now do contingency bartering, selling food to buy finite resources (and annoy our ennemies by increasing prices)
if (available["food"] < 1000 || needs["food"] > 0)
if (available.food < 1000 || needs.food > 0)
return false;
var bestToBuy;
var bestChoice = 0;
for (var buy of needs.types)
for (let buy of needs.types)
{
if (buy === "food")
continue;
var barterRateMin = 80;
if (available[buy] < 5000 && available["food"] > 5000)
let barterRateMin = 80;
if (available[buy] < 5000 && available.food > 5000)
barterRateMin -= (20 - Math.floor(available[buy]/250));
var barterRate = getBarterRate(prices, buy, "food");
let barterRate = getBarterRate(prices, buy, "food");
if (barterRate < barterRateMin)
continue;
var choice = barterRate / (100 + available[buy]);
let choice = barterRate / (100 + available[buy]);
if (choice > bestChoice)
{
bestChoice = choice;
@ -296,8 +296,8 @@ m.TradeManager.prototype.performBarter = function(gameState)
{
barterers[0].barter(bestToBuy, "food", 100);
if (this.Config.debug > 2)
API3.warn("Contingency bartering: sold food for " + bestToBuy + " available sell " + available["food"]
+ " available buy " + available[bestToBuy] + " barterRate " + getBarterRate(prices, bestToBuy, "food"));
API3.warn("Contingency bartering: sold food for " + bestToBuy + " available sell " + available["food"] +
" available buy " + available[bestToBuy] + " barterRate " + getBarterRate(prices, bestToBuy, "food"));
return true;
}
@ -384,7 +384,7 @@ m.TradeManager.prototype.checkRoutes = function(gameState, accessIndex)
return false;
}
if (market2.length == 0)
if (!market2.length)
market2 = market1;
var candidate = { "gain": 0 };
var potential = { "gain": 0 };
@ -468,7 +468,7 @@ m.TradeManager.prototype.checkRoutes = function(gameState, accessIndex)
if (this.Config.chat)
{
var owner = this.tradeRoute.source.owner();
let owner = this.tradeRoute.source.owner();
if (owner === PlayerID)
owner = this.tradeRoute.target.owner();
if (owner !== PlayerID && !this.warnedAllies[owner])
@ -505,15 +505,12 @@ m.TradeManager.prototype.checkTrader = function(gameState, ent)
return;
}
if (ent.hasClass("Ship"))
var access = ent.getMetadata(PlayerID, "sea");
else
var access = gameState.ai.accessibility.getAccessValue(ent.position());
var access = ent.hasClass("Ship") ? ent.getMetadata(PlayerID, "sea") : gameState.ai.accessibility.getAccessValue(ent.position());
var possibleRoute = this.checkRoutes(gameState, access);
// Warning: presentRoute is from metadata, so contains entity ids
if (!possibleRoute
|| (possibleRoute.source.id() != presentRoute.source && possibleRoute.source.id() != presentRoute.target)
|| (possibleRoute.target.id() != presentRoute.source && possibleRoute.target.id() != presentRoute.target))
if (!possibleRoute ||
(possibleRoute.source.id() != presentRoute.source && possibleRoute.source.id() != presentRoute.target) ||
(possibleRoute.target.id() != presentRoute.source && possibleRoute.target.id() != presentRoute.target))
{
// Trader will be assigned in updateTrader
ent.stopMoving();
@ -535,7 +532,7 @@ m.TradeManager.prototype.prospectForNewMarket = function(gameState, queues)
return;
this.checkRoutes(gameState);
var marketPos = gameState.ai.HQ.findMarketLocation(gameState, template);
if (!marketPos || marketPos[3] == 0) // marketPos[3] is the expected gain
if (!marketPos || marketPos[3] === 0) // marketPos[3] is the expected gain
{ // no position found
gameState.ai.HQ.stopBuild(gameState, "structures/{civ}_market");
return;
@ -547,11 +544,11 @@ m.TradeManager.prototype.prospectForNewMarket = function(gameState, queues)
if (this.Config.debug > 1)
{
if (this.potentialTradeRoute)
API3.warn("turn " + gameState.ai.playedTurn + "we could have a new route with gain "
+ marketPos[3] + " instead of the present " + this.potentialTradeRoute.gain);
API3.warn("turn " + gameState.ai.playedTurn + "we could have a new route with gain " +
marketPos[3] + " instead of the present " + this.potentialTradeRoute.gain);
else
API3.warn("turn " + gameState.ai.playedTurn + "we could have a first route with gain "
+ marketPos[3]);
API3.warn("turn " + gameState.ai.playedTurn + "we could have a first route with gain " +
marketPos[3]);
}
if (!this.tradeRoute)
@ -564,8 +561,8 @@ m.TradeManager.prototype.prospectForNewMarket = function(gameState, queues)
m.TradeManager.prototype.isNewMarketWorth = function(expectedGain)
{
if (this.potentialTradeRoute && expectedGain < 2*this.potentialTradeRoute.gain
&& expectedGain < this.potentialTradeRoute.gain + 20)
if (this.potentialTradeRoute && expectedGain < 2*this.potentialTradeRoute.gain &&
expectedGain < this.potentialTradeRoute.gain + 20)
return false;
return true;
};
@ -588,11 +585,11 @@ m.TradeManager.prototype.update = function(gameState, events, queues)
if (this.tradeRoute)
{
this.traders.forEach(function(ent) { self.updateTrader(gameState, ent); });
if (gameState.ai.playedTurn % 5 == 0)
if (gameState.ai.playedTurn % 5 === 0)
this.trainMoreTraders(gameState, queues);
if (gameState.ai.playedTurn % 20 == 0 && this.traders.length >= 2)
if (gameState.ai.playedTurn % 20 === 0 && this.traders.length >= 2)
gameState.ai.HQ.researchManager.researchTradeBonus(gameState, queues);
if (gameState.ai.playedTurn % 60 == 0)
if (gameState.ai.playedTurn % 60 === 0)
this.setTradingGoods(gameState);
}
};

View file

@ -66,8 +66,8 @@ m.TransportPlan = function(gameState, units, startIndex, endIndex, endPos, ship)
}
if (this.debug > 1)
API3.warn("Starting a new transport plan with ID " + this.ID + " to index " + endIndex
+ " with units length " + units.length);
API3.warn("Starting a new transport plan with ID " + this.ID +
" to index " + endIndex + " with units length " + units.length);
this.state = "boarding";
this.boardingPos = {};
@ -102,8 +102,8 @@ m.TransportPlan.prototype.countFreeSlotsOnShip = function(ship)
{
if (ship.hitpoints() < ship.garrisonEjectHealth() * ship.maxHitpoints())
return 0;
let occupied = ship.garrisoned().length
+ this.units.filter(API3.Filters.byMetadata(PlayerID, "onBoard", ship.id())).length;
let occupied = ship.garrisoned().length +
this.units.filter(API3.Filters.byMetadata(PlayerID, "onBoard", ship.id())).length;
return Math.max(ship.garrisonMax() - occupied, 0);
};
@ -114,7 +114,7 @@ m.TransportPlan.prototype.assignUnitToShip = function(gameState, ent)
for (let ship of this.transportShips.values())
{
if (this.countFreeSlotsOnShip(ship) == 0)
if (this.countFreeSlotsOnShip(ship) === 0)
continue;
ent.setMetadata(PlayerID, "onBoard", ship.id());
if (this.debug > 1)
@ -386,7 +386,7 @@ m.TransportPlan.prototype.getBoardingPos = function(gameState, ship, landIndex,
if (avoidEnnemy)
{
let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(pos);
if (territoryOwner != 0 && !gameState.isPlayerAlly(territoryOwner))
if (territoryOwner !== 0 && !gameState.isPlayerAlly(territoryOwner))
dist += 100000000;
}
// require a small distance between all ships of the transport plan to avoid path finder problems