Changes in AI: Decrease a bit the required number of champions in attacks because of the recent increase of their cost,
Make more use of corrals when no fields and Cleanups This was SVN commit r18216.
This commit is contained in:
parent
682086b7fb
commit
9c9796d8ad
@ -7,7 +7,7 @@ m.EntityCollection = function(sharedAI, entities = new Map(), filters = [])
|
||||
this._entities = entities;
|
||||
this._filters = filters;
|
||||
this.dynamicProp = [];
|
||||
for (var filter of this._filters)
|
||||
for (let filter of this._filters)
|
||||
if (filter.dynamicProperties.length)
|
||||
this.dynamicProp = this.dynamicProp.concat(filter.dynamicProperties);
|
||||
|
||||
@ -21,8 +21,8 @@ m.EntityCollection = function(sharedAI, entities = new Map(), filters = [])
|
||||
|
||||
m.EntityCollection.prototype.Serialize = function()
|
||||
{
|
||||
var filters = [];
|
||||
for (var f of this._filters)
|
||||
let filters = [];
|
||||
for (let f of this._filters)
|
||||
filters.push(uneval(f));
|
||||
return {
|
||||
"ents": this.toIdArray(),
|
||||
@ -54,6 +54,7 @@ m.EntityCollection.prototype.freeze = function()
|
||||
{
|
||||
this.frozen = true;
|
||||
};
|
||||
|
||||
m.EntityCollection.prototype.defreeze = function()
|
||||
{
|
||||
this.frozen = false;
|
||||
@ -84,7 +85,7 @@ m.EntityCollection.prototype.filter = function(filter, thisp)
|
||||
if (typeof filter === "function")
|
||||
filter = {"func": filter, "dynamicProperties": []};
|
||||
|
||||
var ret = new Map();
|
||||
let ret = new Map();
|
||||
for (let [id, ent] of this._entities)
|
||||
if (filter.func.call(thisp, ent, id, this))
|
||||
ret.set(id, ent);
|
||||
@ -98,7 +99,7 @@ m.EntityCollection.prototype.filter = function(filter, thisp)
|
||||
m.EntityCollection.prototype.filterNearest = function(targetPos, n)
|
||||
{
|
||||
// Compute the distance of each entity
|
||||
var data = []; // [ [id, ent, distance], ... ]
|
||||
let data = []; // [ [id, ent, distance], ... ]
|
||||
for (let [id, ent] of this._entities)
|
||||
if (ent.position())
|
||||
data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
|
||||
@ -121,7 +122,7 @@ m.EntityCollection.prototype.filterNearest = function(targetPos, n)
|
||||
|
||||
m.EntityCollection.prototype.filter_raw = function(callback, thisp)
|
||||
{
|
||||
var ret = new Map();
|
||||
let ret = new Map();
|
||||
for (let [id, ent] of this._entities)
|
||||
{
|
||||
let val = ent._entity;
|
||||
@ -177,9 +178,8 @@ m.EntityCollection.prototype.destroy = function()
|
||||
return this;
|
||||
};
|
||||
|
||||
m.EntityCollection.prototype.attack = function(unit)
|
||||
m.EntityCollection.prototype.attack = function(unitId)
|
||||
{
|
||||
var unitId = unit;
|
||||
Engine.PostCommand(PlayerID,{"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false});
|
||||
return this;
|
||||
};
|
||||
@ -194,8 +194,8 @@ m.EntityCollection.prototype.setStance = function(stance)
|
||||
// Returns the average position of all units
|
||||
m.EntityCollection.prototype.getCentrePosition = function()
|
||||
{
|
||||
var sumPos = [0, 0];
|
||||
var count = 0;
|
||||
let sumPos = [0, 0];
|
||||
let count = 0;
|
||||
for (let ent of this._entities.values())
|
||||
{
|
||||
if (!ent.position())
|
||||
@ -213,8 +213,8 @@ m.EntityCollection.prototype.getCentrePosition = function()
|
||||
// always a risk that it'll be unprecise.
|
||||
m.EntityCollection.prototype.getApproximatePosition = function(sample)
|
||||
{
|
||||
var sumPos = [0, 0];
|
||||
var i = 0;
|
||||
let sumPos = [0, 0];
|
||||
let i = 0;
|
||||
for (let ent of this._entities.values())
|
||||
{
|
||||
if (!ent.position())
|
||||
@ -255,8 +255,8 @@ m.EntityCollection.prototype.addEnt = function(ent)
|
||||
// But can remove one.
|
||||
m.EntityCollection.prototype.updateEnt = function(ent, force)
|
||||
{
|
||||
var passesFilters = true;
|
||||
for (var filter of this._filters)
|
||||
let passesFilters = true;
|
||||
for (let filter of this._filters)
|
||||
passesFilters = passesFilters && filter.func(ent);
|
||||
|
||||
if (passesFilters)
|
||||
|
@ -53,7 +53,7 @@ m.Filters = {
|
||||
|
||||
byHasMetadata: function(player, key){
|
||||
return {"func" : function(ent){
|
||||
return ent.getMetadata(player, key) != undefined;
|
||||
return ent.getMetadata(player, key) !== undefined;
|
||||
},
|
||||
"dynamicProperties": ['metadata.' + key]};
|
||||
},
|
||||
@ -212,26 +212,22 @@ m.Filters = {
|
||||
|
||||
byResource: function(resourceType){
|
||||
return {"func" : function(ent){
|
||||
var type = ent.resourceSupplyType();
|
||||
if (!ent.resourceSupplyMax())
|
||||
return false;
|
||||
|
||||
let type = ent.resourceSupplyType();
|
||||
if (!type)
|
||||
return false;
|
||||
var amount = ent.resourceSupplyMax();
|
||||
if (!amount)
|
||||
return false;
|
||||
|
||||
|
||||
// Skip targets that are too hard to hunt
|
||||
if (!ent.isHuntable())
|
||||
if (!ent.isHuntable() || ent.hasClass("SeaCreature"))
|
||||
return false;
|
||||
|
||||
// And don't go for the bloody fish! TODO: better accessibility checks
|
||||
if (ent.hasClass("SeaCreature"))
|
||||
return false;
|
||||
|
||||
|
||||
// Don't go for floating treasures since we won't be able to reach them and it kills the pathfinder.
|
||||
if (ent.templateName() == "other/special_treasure_shipwreck_debris" ||
|
||||
ent.templateName() == "other/special_treasure_shipwreck" )
|
||||
ent.templateName() == "other/special_treasure_shipwreck" )
|
||||
return false;
|
||||
|
||||
|
||||
if (type.generic == "treasure")
|
||||
return resourceType == type.specific;
|
||||
|
||||
@ -244,8 +240,7 @@ m.Filters = {
|
||||
return {"func" : function(ent){
|
||||
if (!ent.hasClass("Animal"))
|
||||
return false;
|
||||
var amount = ent.resourceSupplyMax();
|
||||
if (!amount)
|
||||
if (!ent.resourceSupplyMax())
|
||||
return false;
|
||||
// Skip targets that are too hard to hunt
|
||||
if (!ent.isHuntable())
|
||||
|
@ -412,7 +412,7 @@ m.Map.prototype.getNonObstructedTile = function(i, radius, obstruction)
|
||||
m.Map.prototype.isObstructedTile = function(kx, ky, radius)
|
||||
{
|
||||
let w = this.width;
|
||||
if (kx < radius || kx >= w - radius || ky < radius || ky >= w - radius || this.map[kx+ky*w] == 0)
|
||||
if (kx < radius || kx >= w - radius || ky < radius || ky >= w - radius || this.map[kx+ky*w] === 0)
|
||||
return true;
|
||||
for (let dy = 0; dy <= radius; ++dy)
|
||||
{
|
||||
@ -420,7 +420,7 @@ m.Map.prototype.isObstructedTile = function(kx, ky, radius)
|
||||
let xp = kx + (ky + dy)*w;
|
||||
let xm = kx + (ky - dy)*w;
|
||||
for (let dx = -dxmax; dx <= dxmax; ++dx)
|
||||
if (this.map[xp + dx] == 0 || this.map[xm + dx] == 0)
|
||||
if (this.map[xp + dx] === 0 || this.map[xm + dx] === 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -52,7 +52,7 @@ m.SharedScript.prototype.Deserialize = function(data)
|
||||
this._techTemplates = data.techTp;
|
||||
this._techModifications = data.techModifications;
|
||||
this._entityMetadata = data.metadata;
|
||||
this._derivedTemplates = {};
|
||||
this._derivedTemplates = {};
|
||||
|
||||
this.isDeserialized = true;
|
||||
};
|
||||
@ -138,11 +138,11 @@ m.SharedScript.prototype.init = function(state, deserialization)
|
||||
this.barterPrices = state.barterPrices;
|
||||
|
||||
this.passabilityMap = state.passabilityMap;
|
||||
if (this.mapSize % this.passabilityMap.width != 0)
|
||||
if (this.mapSize % this.passabilityMap.width !== 0)
|
||||
error("AI shared component inconsistent sizes: map=" + this.mapSize + " while passability=" + this.passabilityMap.width);
|
||||
this.passabilityMap.cellSize = this.mapSize / this.passabilityMap.width;
|
||||
this.territoryMap = state.territoryMap;
|
||||
if (this.mapSize % this.territoryMap.width != 0)
|
||||
if (this.mapSize % this.territoryMap.width !== 0)
|
||||
error("AI shared component inconsistent sizes: map=" + this.mapSize + " while territory=" + this.territoryMap.width);
|
||||
this.territoryMap.cellSize = this.mapSize / this.territoryMap.width;
|
||||
|
||||
@ -425,13 +425,16 @@ m.SharedScript.prototype.deleteMetadata = function(player, ent, key)
|
||||
return true;
|
||||
};
|
||||
|
||||
m.copyPrototype = function(descendant, parent) {
|
||||
var sConstructor = parent.toString();
|
||||
var aMatch = sConstructor.match( /\s*function (.*)\(/ );
|
||||
if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
|
||||
for (var m in parent.prototype) {
|
||||
descendant.prototype[m] = parent.prototype[m];
|
||||
}
|
||||
m.copyPrototype = function(descendant, parent)
|
||||
{
|
||||
var sConstructor = parent.toString();
|
||||
var aMatch = sConstructor.match( /\s*function (.*)\(/ );
|
||||
|
||||
if ( aMatch != null )
|
||||
descendant.prototype[aMatch[1]] = parent;
|
||||
|
||||
for (let p in parent.prototype)
|
||||
descendant.prototype[p] = parent.prototype[p];
|
||||
};
|
||||
|
||||
return m;
|
||||
|
@ -124,21 +124,21 @@ 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": 20, "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": 20, "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": 3, "targetSize": 18, "batchSize": 3, "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": 3, "targetSize": 18, "batchSize": 3, "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.RangedCavalry = { "priority": 0.7, "minSize": 4, "targetSize": 20, "batchSize": 4, "classes": ["Cavalry", "Ranged", "CitizenSoldier"],
|
||||
"interests": [ ["strength",2], ["cost",1] ] };
|
||||
this.unitStat.RangedCavalry = { "priority": 0.7, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["Cavalry","Ranged", "CitizenSoldier"],
|
||||
this.unitStat.MeleeCavalry = { "priority": 0.7, "minSize": 4, "targetSize": 20, "batchSize": 4, "classes": ["Cavalry", "Melee", "CitizenSoldier"],
|
||||
"interests": [ ["strength",2], ["cost",1] ] };
|
||||
this.unitStat.ChampMeleeInfantry = { "priority": 1, "minSize": 3, "targetSize": 18, "batchSize": 3, "classes": ["Infantry","Melee", "Champion"],
|
||||
this.unitStat.ChampRangedCavalry = { "priority": 1, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["Cavalry", "Ranged", "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": 15, "batchSize": 3, "classes": ["Cavalry", "Melee", "Champion"],
|
||||
"interests": [ ["strength",2], ["cost",1] ] };
|
||||
this.unitStat.Hero = { "priority": 1, "minSize": 0, "targetSize": 1, "batchSize": 1, "classes": ["Hero"],
|
||||
"interests": [ ["strength",2], ["cost",1] ] };
|
||||
|
@ -756,7 +756,7 @@ m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair)
|
||||
var idleBuilderWorkers = builderWorkers.filter(API3.Filters.isIdle());
|
||||
|
||||
// if we're constructing and we have the foundations to our base anchor, only try building that.
|
||||
if (this.constructing == true && this.buildings.filter(API3.Filters.and(API3.Filters.isFoundation(), API3.Filters.byMetadata(PlayerID, "baseAnchor", true))).length != 0)
|
||||
if (this.constructing === true && this.buildings.filter(API3.Filters.and(API3.Filters.isFoundation(), API3.Filters.byMetadata(PlayerID, "baseAnchor", true))).hasEntities())
|
||||
{
|
||||
foundations = this.buildings.filter(API3.Filters.byMetadata(PlayerID, "baseAnchor", true)).toEntityArray();
|
||||
let tID = foundations[0].id();
|
||||
@ -813,7 +813,7 @@ m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair)
|
||||
targetNB = 4;
|
||||
else if (target.hasClass("Fortress"))
|
||||
targetNB = 7;
|
||||
if (target.getMetadata(PlayerID, "baseAnchor") == true || (target.hasClass("Wonder") && gameState.getGameType() === "wonder"))
|
||||
if (target.getMetadata(PlayerID, "baseAnchor") === true || (target.hasClass("Wonder") && gameState.getGameType() === "wonder"))
|
||||
{
|
||||
targetNB = 15;
|
||||
maxTotalBuilders = Math.max(maxTotalBuilders, 15);
|
||||
@ -898,7 +898,7 @@ m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair)
|
||||
let targetNB = 1;
|
||||
if (target.hasClass("Fortress"))
|
||||
targetNB = 3;
|
||||
if (target.getMetadata(PlayerID, "baseAnchor") == true || (target.hasClass("Wonder") && gameState.getGameType() === "wonder"))
|
||||
if (target.getMetadata(PlayerID, "baseAnchor") === true || (target.hasClass("Wonder") && gameState.getGameType() === "wonder"))
|
||||
{
|
||||
maxTotalBuilders = Math.ceil(workers.length * 0.3);
|
||||
targetNB = 5;
|
||||
|
@ -174,7 +174,7 @@ m.HQ.prototype.checkEvents = function (gameState, events, queues)
|
||||
if (!ent || !ent.isOwn(PlayerID))
|
||||
continue;
|
||||
|
||||
if (ent.getMetadata(PlayerID, "baseAnchor") == true)
|
||||
if (ent.getMetadata(PlayerID, "baseAnchor") === true)
|
||||
{
|
||||
let base = this.getBaseByID(ent.getMetadata(PlayerID, "base"));
|
||||
if (base.constructing)
|
||||
@ -426,7 +426,7 @@ m.HQ.prototype.trainMoreWorkers = function(gameState, queues)
|
||||
var numberOfWorkers = 0; // all workers
|
||||
var numberOfSupports = 0; // only support workers (i.e. non fighting)
|
||||
gameState.getOwnUnits().forEach (function (ent) {
|
||||
if (ent.getMetadata(PlayerID, "role") == "worker" && ent.getMetadata(PlayerID, "plan") == undefined)
|
||||
if (ent.getMetadata(PlayerID, "role") === "worker" && ent.getMetadata(PlayerID, "plan") === undefined)
|
||||
{
|
||||
++numberOfWorkers;
|
||||
if (ent.hasClass("Support"))
|
||||
@ -437,7 +437,7 @@ m.HQ.prototype.trainMoreWorkers = function(gameState, queues)
|
||||
gameState.getOwnTrainingFacilities().forEach(function(ent) {
|
||||
ent.trainingQueue().forEach(function(item) {
|
||||
numberInTraining += item.count;
|
||||
if (item.metadata && item.metadata.role && item.metadata.role == "worker" && item.metadata.plan == undefined)
|
||||
if (item.metadata && item.metadata.role && item.metadata.role === "worker" && item.metadata.plan === undefined)
|
||||
{
|
||||
numberOfWorkers += item.count;
|
||||
if (item.metadata.support)
|
||||
@ -1043,9 +1043,9 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
for (let j = 0; j < this.territoryMap.length; ++j)
|
||||
{
|
||||
// do not try on the border of our territory
|
||||
if (this.frontierMap.map[j] == 2)
|
||||
if (this.frontierMap.map[j] === 2)
|
||||
continue;
|
||||
if (this.basesMap.map[j] == 0) // only in our territory
|
||||
if (this.basesMap.map[j] === 0) // only in our territory
|
||||
continue;
|
||||
// with enough room around to build the cc
|
||||
let i = this.territoryMap.getNonObstructedTile(j, radius, obstructions);
|
||||
@ -1154,12 +1154,12 @@ m.HQ.prototype.findDefensiveLocation = function(gameState, template)
|
||||
if (!wonderMode)
|
||||
{
|
||||
// do not try if well inside or outside territory
|
||||
if (this.frontierMap.map[j] == 0)
|
||||
if (this.frontierMap.map[j] === 0)
|
||||
continue;
|
||||
if (this.frontierMap.map[j] == 1 && isTower)
|
||||
if (this.frontierMap.map[j] === 1 && isTower)
|
||||
continue;
|
||||
}
|
||||
if (this.basesMap.map[j] == 0) // inaccessible cell
|
||||
if (this.basesMap.map[j] === 0) // inaccessible cell
|
||||
continue;
|
||||
// with enough room around to build the cc
|
||||
var i = this.territoryMap.getNonObstructedTile(j, radius, obstructions);
|
||||
@ -1303,12 +1303,17 @@ m.HQ.prototype.manageCorral = function(gameState, queues)
|
||||
if (queues.corral.hasQueuedUnits())
|
||||
return;
|
||||
|
||||
// Only build one corral for the time being
|
||||
if (!gameState.getOwnEntitiesByClass("Corral", true).hasEntities())
|
||||
let nCorral = gameState.getOwnEntitiesByClass("Corral", true).length;
|
||||
if (nCorral === 0 ||
|
||||
(gameState.isDisabledTemplates(gameState.applyCiv("structures/{civ}_field")) &&
|
||||
nCorral < gameState.currentPhase() && gameState.getPopulation() > 30*nCorral))
|
||||
{
|
||||
if (this.canBuild(gameState, "structures/{civ}_corral"))
|
||||
{
|
||||
queues.corral.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_corral"));
|
||||
return;
|
||||
return;
|
||||
}
|
||||
if (nCorral === 0) return;
|
||||
}
|
||||
|
||||
// And train some animals
|
||||
@ -1327,7 +1332,7 @@ m.HQ.prototype.manageCorral = function(gameState, queues)
|
||||
let count = gameState.countEntitiesByType(trainable, true);
|
||||
for (let item of corral.trainingQueue())
|
||||
count += item.count;
|
||||
if (count > 1)
|
||||
if (count > nCorral)
|
||||
continue;
|
||||
queues.corral.addPlan(new m.TrainingPlan(gameState, trainable, { "trainer": corral.id() }));
|
||||
return;
|
||||
@ -1839,7 +1844,7 @@ m.HQ.prototype.updateTerritories = function(gameState)
|
||||
continue;
|
||||
if (this.territoryMap.getOwnerIndex(j) != PlayerID)
|
||||
{
|
||||
if (this.basesMap.map[j] == 0)
|
||||
if (this.basesMap.map[j] === 0)
|
||||
continue;
|
||||
let base = this.getBaseByID(this.basesMap.map[j]);
|
||||
let index = base.territoryIndices.indexOf(j);
|
||||
@ -1851,7 +1856,7 @@ m.HQ.prototype.updateTerritories = function(gameState)
|
||||
base.territoryIndices.splice(index, 1);
|
||||
this.basesMap.map[j] = 0;
|
||||
}
|
||||
else if (this.basesMap.map[j] == 0)
|
||||
else if (this.basesMap.map[j] === 0)
|
||||
{
|
||||
let landPassable = false;
|
||||
let ind = API3.getMapIndices(j, this.territoryMap, passabilityMap);
|
||||
|
@ -45,7 +45,7 @@ m.createObstructionMap = function(gameState, accessIndex, template)
|
||||
{
|
||||
let tilePlayer = (territoryMap.data[k] & m.TERRITORY_PLAYER_MASK);
|
||||
let isConnected = (territoryMap.data[k] & m.TERRITORY_BLINKING_MASK) == 0;
|
||||
if (tilePlayer == PlayerID)
|
||||
if (tilePlayer === PlayerID)
|
||||
{
|
||||
if (!buildOwn || !buildNeutral && !isConnected)
|
||||
continue;
|
||||
@ -55,7 +55,7 @@ m.createObstructionMap = function(gameState, accessIndex, template)
|
||||
if (!buildAlly || !buildNeutral && !isConnected)
|
||||
continue;
|
||||
}
|
||||
else if (tilePlayer == 0)
|
||||
else if (tilePlayer === 0)
|
||||
{
|
||||
if (!buildNeutral)
|
||||
continue;
|
||||
|
@ -42,7 +42,6 @@ m.Queue.prototype.check= function(gameState)
|
||||
return;
|
||||
this.plans.shift();
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
m.Queue.prototype.getNext = function()
|
||||
|
@ -148,7 +148,7 @@ m.QueueManager.prototype.printQueues = function(gameState)
|
||||
{
|
||||
var numWorkers = 0;
|
||||
gameState.getOwnUnits().forEach (function (ent) {
|
||||
if (ent.getMetadata(PlayerID, "role") == "worker" && ent.getMetadata(PlayerID, "plan") == undefined)
|
||||
if (ent.getMetadata(PlayerID, "role") === "worker" && ent.getMetadata(PlayerID, "plan") === undefined)
|
||||
numWorkers++;
|
||||
});
|
||||
API3.warn("---------- QUEUES ------------ with pop " + gameState.getPopulation() + " and workers " + numWorkers);
|
||||
|
@ -18,9 +18,6 @@ m.ConstructionPlan = function(gameState, type, metadata, position)
|
||||
|
||||
m.ConstructionPlan.prototype = Object.create(m.QueuePlan.prototype);
|
||||
|
||||
// checks other than resource ones.
|
||||
// TODO: change this.
|
||||
// TODO: if there are specific requirements here, maybe try to do them?
|
||||
m.ConstructionPlan.prototype.canStart = function(gameState)
|
||||
{
|
||||
if (gameState.ai.HQ.turnCache.buildingBuilt) // do not start another building if already one this turn
|
||||
@ -51,7 +48,8 @@ m.ConstructionPlan.prototype.start = function(gameState)
|
||||
Engine.ProfileStop();
|
||||
return;
|
||||
}
|
||||
else if (this.metadata && this.metadata.expectedGain)
|
||||
|
||||
if (this.metadata && this.metadata.expectedGain)
|
||||
{
|
||||
// Check if this market is still worth building (others may have been built making it useless)
|
||||
let tradeManager = gameState.ai.HQ.tradeManager;
|
||||
@ -93,7 +91,7 @@ m.ConstructionPlan.prototype.start = function(gameState)
|
||||
else // try with the lowest, move towards us unless we're same
|
||||
{
|
||||
for (let step = 0; step <= 1; step += 0.2)
|
||||
builder.construct(this.type, (step*pos.x + (1-step)*pos.xx), (step*pos.z + (1-step)*pos.zz),
|
||||
builder.construct(this.type, step*pos.x + (1-step)*pos.xx, step*pos.z + (1-step)*pos.zz,
|
||||
pos.angle, this.metadata);
|
||||
}
|
||||
this.onStart(gameState);
|
||||
@ -107,7 +105,6 @@ m.ConstructionPlan.prototype.start = function(gameState)
|
||||
// TODO for dock, we should allow building them outside territory, and we should check that we are along the right sea
|
||||
m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
{
|
||||
|
||||
var template = this.template;
|
||||
|
||||
if (template.buildCategory() === "Dock")
|
||||
@ -146,14 +143,14 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
else if (template.hasClass("DefenseTower") || template.hasClass("Fortress") || template.hasClass("ArmyCamp"))
|
||||
{
|
||||
let pos = gameState.ai.HQ.findDefensiveLocation(gameState, template);
|
||||
|
||||
if (pos)
|
||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "base": pos[2] };
|
||||
else if (template.hasClass("DefenseTower") || gameState.civ() === "mace" || gameState.civ() === "maur" ||
|
||||
|
||||
if (template.hasClass("DefenseTower") || gameState.civ() === "mace" || gameState.civ() === "maur" ||
|
||||
gameState.countEntitiesByType(gameState.applyCiv("structures/{civ}_fortress"), true) > 0 ||
|
||||
gameState.countEntitiesByType(gameState.applyCiv("structures/{civ}_army_camp"), true) > 0)
|
||||
return false;
|
||||
// if this fortress is our first siege unit builder, just try the standard placement as we want siege units
|
||||
// if this fortress is our first siege unit builder, just try the standard placement as we want siege units
|
||||
}
|
||||
else if (template.hasClass("Market")) // Docks (i.e. NavalMarket) are done before
|
||||
{
|
||||
@ -174,7 +171,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
|
||||
var placement = new API3.Map(gameState.sharedScript, "territory");
|
||||
var cellSize = placement.cellSize; // size of each tile
|
||||
|
||||
|
||||
var alreadyHasHouses = false;
|
||||
|
||||
if (this.position) // If a position was specified then place the building as close to it as possible
|
||||
@ -197,7 +194,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
else
|
||||
{
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
if (gameState.ai.HQ.basesMap.map[j] != 0)
|
||||
if (gameState.ai.HQ.basesMap.map[j] !== 0)
|
||||
placement.map[j] = 45;
|
||||
}
|
||||
|
||||
@ -262,7 +259,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
placement.map[j] = 0;
|
||||
else if (favorBorder && gameState.ai.HQ.borderMap.map[j] > 0)
|
||||
placement.map[j] += 50;
|
||||
else if (disfavorBorder && gameState.ai.HQ.borderMap.map[j] == 0 && placement.map[j] > 0)
|
||||
else if (disfavorBorder && gameState.ai.HQ.borderMap.map[j] === 0 && placement.map[j] > 0)
|
||||
placement.map[j] += 10;
|
||||
|
||||
if (placement.map[j] > 0)
|
||||
@ -278,11 +275,11 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
{
|
||||
for (let j = 0; j < placement.map.length; ++j)
|
||||
{
|
||||
if (gameState.ai.HQ.basesMap.map[j] == 0)
|
||||
if (gameState.ai.HQ.basesMap.map[j] === 0)
|
||||
placement.map[j] = 0;
|
||||
else if (favorBorder && gameState.ai.HQ.borderMap.map[j] > 0)
|
||||
placement.map[j] += 50;
|
||||
else if (disfavorBorder && gameState.ai.HQ.borderMap.map[j] == 0 && placement.map[j] > 0)
|
||||
else if (disfavorBorder && gameState.ai.HQ.borderMap.map[j] === 0 && placement.map[j] > 0)
|
||||
placement.map[j] += 10;
|
||||
|
||||
if (preferredBase && gameState.ai.HQ.basesMap.map[j] == this.metadata.preferredBase)
|
||||
@ -335,7 +332,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
if (bestVal <= 0)
|
||||
return false;
|
||||
|
||||
let x = ((bestIdx % obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
let x = (bestIdx % obstructions.width + 0.5) * obstructions.cellSize;
|
||||
let z = (Math.floor(bestIdx / obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
|
||||
if (template.hasClass("House") || template.hasClass("Field") || template.resourceDropsiteTypes() !== undefined)
|
||||
@ -343,7 +340,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
||||
let secondBest = obstructions.findNearestObstructed(bestIdx, radius);
|
||||
if (secondBest >= 0)
|
||||
{
|
||||
x = ((secondBest % obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
x = (secondBest % obstructions.width + 0.5) * obstructions.cellSize;
|
||||
z = (Math.floor(secondBest / obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
}
|
||||
}
|
||||
@ -445,7 +442,7 @@ m.ConstructionPlan.prototype.findDockPosition = function(gameState)
|
||||
if (bestIdx !== undefined && dist > bestVal + maxWater)
|
||||
continue;
|
||||
|
||||
let x = ((i % obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
let x = (i % obstructions.width + 0.5) * obstructions.cellSize;
|
||||
let z = (Math.floor(i / obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
let angle = this.getDockAngle(gameState, x, z, halfSize);
|
||||
if (angle === false)
|
||||
@ -476,7 +473,7 @@ m.ConstructionPlan.prototype.findDockPosition = function(gameState)
|
||||
if (!this.metadata.proximity && bestWater < 10 && gameState.currentPhase() == 1)
|
||||
return false;
|
||||
|
||||
var x = ((bestIdx % obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
var x = (bestIdx % obstructions.width + 0.5) * obstructions.cellSize;
|
||||
var z = (Math.floor(bestIdx / obstructions.width) + 0.5) * obstructions.cellSize;
|
||||
|
||||
// Assign this dock to a base
|
||||
@ -537,7 +534,7 @@ m.ConstructionPlan.prototype.getDockAngle = function(gameState, x, z, size)
|
||||
let count = 0;
|
||||
for (let j = 0; j < length-1; ++j)
|
||||
{
|
||||
if (((waterPoints[(i + j) % length]+1) % numPoints) == waterPoints[(i + j + 1) % length])
|
||||
if ((waterPoints[(i + j) % length]+1) % numPoints == waterPoints[(i + j + 1) % length])
|
||||
++count;
|
||||
else
|
||||
break;
|
||||
@ -741,7 +738,7 @@ m.ConstructionPlan.prototype.getResourcesAround = function(gameState, types, i,
|
||||
nbcell += weight;
|
||||
}
|
||||
}
|
||||
if (dy == 0)
|
||||
if (dy === 0)
|
||||
continue;
|
||||
ky = iy - dy;
|
||||
if (ky >= 0 && ky < w)
|
||||
@ -759,7 +756,7 @@ m.ConstructionPlan.prototype.getResourcesAround = function(gameState, types, i,
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbcell ? (total / nbcell) : 0;
|
||||
return nbcell ? total / nbcell : 0;
|
||||
};
|
||||
|
||||
m.ConstructionPlan.prototype.Serialize = function()
|
||||
|
@ -519,7 +519,7 @@ m.HQ.prototype.configFirstBase = function(gameState)
|
||||
gameState.ai.queues.dropsites.addPlan(new m.ConstructionPlan(gameState, template, { "base": this.baseManagers[1].ID }, newDP.pos));
|
||||
}
|
||||
}
|
||||
// and build immediately a corral if not much wood
|
||||
// and build immediately a corral if needed
|
||||
if (this.needCorral)
|
||||
{
|
||||
template = gameState.applyCiv("structures/{civ}_corral");
|
||||
|
@ -282,7 +282,7 @@ m.Worker.prototype.startGathering = function(gameState)
|
||||
continue;
|
||||
// not in ennemy territory
|
||||
let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(supplies[i].ent.position());
|
||||
if (territoryOwner != 0 && !gameState.isPlayerAlly(territoryOwner)) // player is its own ally
|
||||
if (territoryOwner !== 0 && !gameState.isPlayerAlly(territoryOwner)) // player is its own ally
|
||||
continue;
|
||||
gameState.ai.HQ.AddTCGatherer(supplies[i].id);
|
||||
ent.setMetadata(PlayerID, "supply", supplies[i].id);
|
||||
@ -588,14 +588,14 @@ m.Worker.prototype.startHunting = function(gameState, position)
|
||||
|
||||
// Avoid ennemy territory
|
||||
let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(supply.position());
|
||||
if (territoryOwner != 0 && !gameState.isPlayerAlly(territoryOwner)) // player is its own ally
|
||||
if (territoryOwner !== 0 && !gameState.isPlayerAlly(territoryOwner)) // player is its own ally
|
||||
return;
|
||||
|
||||
var dropsiteDist = nearestDropsiteDist(supply);
|
||||
if (dropsiteDist > 35000)
|
||||
return;
|
||||
// Only cavalry should hunt far from dropsite (specially for non domestic animals which flee)
|
||||
if (!isCavalry && (dropsiteDist > 12000 || ((dropsiteDist > 7000 || territoryOwner == 0 ) && canFlee)))
|
||||
if (!isCavalry && (dropsiteDist > 12000 || ((dropsiteDist > 7000 || territoryOwner === 0 ) && canFlee)))
|
||||
return;
|
||||
|
||||
if (dist < nearestSupplyDist)
|
||||
@ -681,7 +681,7 @@ m.Worker.prototype.startFishing = function(gameState)
|
||||
|
||||
// Avoid ennemy territory
|
||||
let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(supply.position());
|
||||
if (territoryOwner != 0 && !gameState.isPlayerAlly(territoryOwner)) // player is its own ally
|
||||
if (territoryOwner !== 0 && !gameState.isPlayerAlly(territoryOwner)) // player is its own ally
|
||||
return;
|
||||
|
||||
var dropsiteDist = nearestDropsiteDist(supply);
|
||||
|
Loading…
Reference in New Issue
Block a user