Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
Show First 20 Lines • Show All 1,537 Lines • ▼ Show 20 Lines | if (this.Config.debug > 1) | ||||
API3.warn("new base planned with resource " + resource); | API3.warn("new base planned with resource " + resource); | ||||
queues.civilCentre.addPlan(new m.ConstructionPlan(gameState, template, { "base": -1, "resource": resource })); | queues.civilCentre.addPlan(new m.ConstructionPlan(gameState, template, { "base": -1, "resource": resource })); | ||||
return true; | return true; | ||||
}; | }; | ||||
/** Deals with building fortresses and towers along our border with enemies. */ | /** Deals with building fortresses and towers along our border with enemies. */ | ||||
m.HQ.prototype.buildDefenses = function(gameState, queues) | m.HQ.prototype.buildDefenses = function(gameState, queues) | ||||
{ | { | ||||
if (this.saveResources || queues.defenseBuilding.hasQueuedUnits()) | if ((this.saveResources && !this.canBarter) || queues.defenseBuilding.hasQueuedUnits()) | ||||
return; | return; | ||||
if (gameState.currentPhase() > 2 || gameState.isResearching(gameState.cityPhase())) | if (!this.saveResources && (gameState.currentPhase() > 2 || gameState.isResearching(gameState.cityPhase()))) | ||||
{ | { | ||||
// try to build fortresses | // try to build fortresses | ||||
if (this.canBuild(gameState, "structures/{civ}_fortress")) | if (this.canBuild(gameState, "structures/{civ}_fortress")) | ||||
{ | { | ||||
let numFortresses = gameState.getOwnEntitiesByClass("Fortress", true).length; | let numFortresses = gameState.getOwnEntitiesByClass("Fortress", true).length; | ||||
if ((!numFortresses || gameState.ai.elapsedTime > (1 + 0.10*numFortresses)*this.fortressLapseTime + this.fortressStartTime) && | if ((!numFortresses || gameState.ai.elapsedTime > (1 + 0.10*numFortresses)*this.fortressLapseTime + this.fortressStartTime) && | ||||
numFortresses < this.numActiveBase() + 1 + this.extraFortresses && | numFortresses < this.numActiveBase() + 1 + this.extraFortresses && | ||||
gameState.getOwnFoundationsByClass("Fortress").length < 2) | gameState.getOwnFoundationsByClass("Fortress").length < 2) | ||||
{ | { | ||||
this.fortressStartTime = gameState.ai.elapsedTime; | this.fortressStartTime = gameState.ai.elapsedTime; | ||||
if (!numFortresses) | if (!numFortresses) | ||||
gameState.ai.queueManager.changePriority("defenseBuilding", 2*this.Config.priorities.defenseBuilding); | gameState.ai.queueManager.changePriority("defenseBuilding", 2*this.Config.priorities.defenseBuilding); | ||||
let plan = new m.ConstructionPlan(gameState, "structures/{civ}_fortress"); | let plan = new m.ConstructionPlan(gameState, "structures/{civ}_fortress"); | ||||
plan.onStart = function(gameState) { gameState.ai.queueManager.changePriority("defenseBuilding", gameState.ai.Config.priorities.defenseBuilding); }; | plan.onStart = function(gameState) { gameState.ai.queueManager.changePriority("defenseBuilding", gameState.ai.Config.priorities.defenseBuilding); }; | ||||
queues.defenseBuilding.addPlan(plan); | queues.defenseBuilding.addPlan(plan); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (this.Config.Military.numSentryTowers && gameState.currentPhase() < 2 && this.canBuild(gameState, "structures/{civ}_sentry_tower")) | if (this.Config.Military.numSentryTowers && gameState.currentPhase() < 2 && this.canBuild(gameState, "structures/{civ}_sentry_tower")) | ||||
{ | { | ||||
let numTowers = gameState.getOwnEntitiesByClass("Tower", true).length; // we count all towers, including wall towers | let numTowers = gameState.getOwnEntitiesByClass("Tower", true).length; // we count all towers, including wall towers | ||||
if (numTowers < this.Config.Military.numSentryTowers && gameState.ai.elapsedTime > this.towerLapseTime + this.fortStartTime) | let towerLapseTime = this.saveResource ? (1 + 0.5*numTowers) * this.towerLapseTime : this.towerLapseTime; | ||||
if (numTowers < this.Config.Military.numSentryTowers && gameState.ai.elapsedTime > towerLapseTime + this.fortStartTime) | |||||
{ | { | ||||
this.fortStartTime = gameState.ai.elapsedTime; | this.fortStartTime = gameState.ai.elapsedTime; | ||||
queues.defenseBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_sentry_tower")); | queues.defenseBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_sentry_tower")); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (gameState.currentPhase() < 2 || !this.canBuild(gameState, "structures/{civ}_defense_tower")) | if (gameState.currentPhase() < 2 || !this.canBuild(gameState, "structures/{civ}_defense_tower")) | ||||
return; | return; | ||||
let numTowers = gameState.getOwnEntitiesByClass("DefenseTower", true).filter(API3.Filters.byClass("Town")).length; | let numTowers = gameState.getOwnEntitiesByClass("DefenseTower", true).filter(API3.Filters.byClass("Town")).length; | ||||
if ((!numTowers || gameState.ai.elapsedTime > (1 + 0.10*numTowers)*this.towerLapseTime + this.towerStartTime) && | let towerLapseTime = this.saveResource ? (1 + numTowers) * this.towerLapseTime : this.towerLapseTime; | ||||
if ((!numTowers || gameState.ai.elapsedTime > (1 + 0.1*numTowers)*towerLapseTime + this.towerStartTime) && | |||||
numTowers < 2 * this.numActiveBase() + 3 + this.extraTowers && | numTowers < 2 * this.numActiveBase() + 3 + this.extraTowers && | ||||
gameState.getOwnFoundationsByClass("DefenseTower").length < 3) | gameState.getOwnFoundationsByClass("DefenseTower").length < 3) | ||||
{ | { | ||||
this.towerStartTime = gameState.ai.elapsedTime; | this.towerStartTime = gameState.ai.elapsedTime; | ||||
if (numTowers > 2 * this.numActiveBase() + 3) | if (numTowers > 2 * this.numActiveBase() + 3) | ||||
gameState.ai.queueManager.changePriority("defenseBuilding", Math.round(0.7*this.Config.priorities.defenseBuilding)); | gameState.ai.queueManager.changePriority("defenseBuilding", Math.round(0.7*this.Config.priorities.defenseBuilding)); | ||||
let plan = new m.ConstructionPlan(gameState, "structures/{civ}_defense_tower"); | let plan = new m.ConstructionPlan(gameState, "structures/{civ}_defense_tower"); | ||||
plan.onStart = function(gameState) { gameState.ai.queueManager.changePriority("defenseBuilding", gameState.ai.Config.priorities.defenseBuilding); }; | plan.onStart = function(gameState) { gameState.ai.queueManager.changePriority("defenseBuilding", gameState.ai.Config.priorities.defenseBuilding); }; | ||||
Show All 15 Lines | |||||
}; | }; | ||||
/** | /** | ||||
* Deals with constructing military buildings (barracks, stables…) | * Deals with constructing military buildings (barracks, stables…) | ||||
* They are mostly defined by Config.js. This is unreliable since changes could be done easily. | * They are mostly defined by Config.js. This is unreliable since changes could be done easily. | ||||
*/ | */ | ||||
m.HQ.prototype.constructTrainingBuildings = function(gameState, queues) | m.HQ.prototype.constructTrainingBuildings = function(gameState, queues) | ||||
{ | { | ||||
if (!queues.militaryBuilding.hasQueuedUnits() && this.canBuild(gameState, "structures/{civ}_barracks")) | if ((this.saveResources && !this.canBarter) || queues.militaryBuilding.hasQueuedUnits()) | ||||
return; | |||||
if (this.canBuild(gameState, "structures/{civ}_barracks")) | |||||
{ | { | ||||
let barrackNb = gameState.getOwnEntitiesByClass("Barracks", true).length; | let barrackNb = gameState.getOwnEntitiesByClass("Barracks", true).length; | ||||
if (this.saveResources && barrackNb > 0) | |||||
return; | |||||
// first barracks. | // first barracks. | ||||
if (!barrackNb && (gameState.getPopulation() > this.Config.Military.popForBarracks1 || | if (!barrackNb && (gameState.getPopulation() > this.Config.Military.popForBarracks1 || | ||||
(this.econState == "townPhasing" && gameState.getOwnStructures().filter(API3.Filters.byClass("Village")).length < 5))) | (this.econState == "townPhasing" && gameState.getOwnStructures().filter(API3.Filters.byClass("Village")).length < 5))) | ||||
{ | { | ||||
gameState.ai.queueManager.changePriority("militaryBuilding", 2*this.Config.priorities.militaryBuilding); | gameState.ai.queueManager.changePriority("militaryBuilding", 2*this.Config.priorities.militaryBuilding); | ||||
let preferredBase = this.findBestBaseForMilitary(gameState); | let preferredBase = this.findBestBaseForMilitary(gameState); | ||||
let plan = new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "preferredBase": preferredBase }); | let plan = new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "preferredBase": preferredBase }); | ||||
plan.onStart = function(gameState) { gameState.ai.queueManager.changePriority("militaryBuilding", gameState.ai.Config.priorities.militaryBuilding); }; | plan.onStart = function(gameState) { gameState.ai.queueManager.changePriority("militaryBuilding", gameState.ai.Config.priorities.militaryBuilding); }; | ||||
queues.militaryBuilding.addPlan(plan); | queues.militaryBuilding.addPlan(plan); | ||||
return; | |||||
} | } | ||||
// second barracks, then 3rd barrack, and optional 4th for some civs as they rely on barracks more. | // second barracks, then 3rd barrack, and optional 4th for some civs as they rely on barracks more. | ||||
else if (barrackNb == 1 && gameState.getPopulation() > this.Config.Military.popForBarracks2) | if (barrackNb == 1 && gameState.getPopulation() > this.Config.Military.popForBarracks2) | ||||
{ | { | ||||
let preferredBase = this.findBestBaseForMilitary(gameState); | let preferredBase = this.findBestBaseForMilitary(gameState); | ||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "preferredBase": preferredBase })); | queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "preferredBase": preferredBase })); | ||||
return; | |||||
} | } | ||||
else if (barrackNb == 2 && gameState.getPopulation() > this.Config.Military.popForBarracks2 + 20) | if (barrackNb == 2 && gameState.getPopulation() > this.Config.Military.popForBarracks2 + 20) | ||||
{ | { | ||||
let preferredBase = this.findBestBaseForMilitary(gameState); | let preferredBase = this.findBestBaseForMilitary(gameState); | ||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "preferredBase": preferredBase })); | queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "preferredBase": preferredBase })); | ||||
return; | |||||
} | } | ||||
else if (barrackNb == 3 && gameState.getPopulation() > this.Config.Military.popForBarracks2 + 50 && | if (barrackNb == 3 && gameState.getPopulation() > this.Config.Military.popForBarracks2 + 50 && | ||||
(gameState.getPlayerCiv() === "gaul" || gameState.getPlayerCiv() === "brit" || gameState.getPlayerCiv() === "iber")) | (gameState.getPlayerCiv() === "gaul" || gameState.getPlayerCiv() === "brit" || gameState.getPlayerCiv() === "iber")) | ||||
{ | { | ||||
let preferredBase = this.findBestBaseForMilitary(gameState); | let preferredBase = this.findBestBaseForMilitary(gameState); | ||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "preferredBase": preferredBase })); | queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_barracks", { "preferredBase": preferredBase })); | ||||
return; | |||||
} | } | ||||
} | } | ||||
if (this.saveResources) | |||||
return; | |||||
if (gameState.currentPhase() < 3 || gameState.getPopulation() < 80 || !this.bAdvanced.length) | |||||
return; | |||||
//build advanced military buildings | //build advanced military buildings | ||||
if (gameState.currentPhase() > 2 && gameState.getPopulation() > 80 && !queues.militaryBuilding.hasQueuedUnits() && this.bAdvanced.length !== 0) | |||||
{ | |||||
let nAdvanced = 0; | let nAdvanced = 0; | ||||
for (let advanced of this.bAdvanced) | for (let advanced of this.bAdvanced) | ||||
nAdvanced += gameState.countEntitiesAndQueuedByType(advanced, true); | nAdvanced += gameState.countEntitiesAndQueuedByType(advanced, true); | ||||
if (!nAdvanced || (nAdvanced < this.bAdvanced.length && gameState.getPopulation() > 110)) | if (!nAdvanced || (nAdvanced < this.bAdvanced.length && gameState.getPopulation() > 110)) | ||||
{ | { | ||||
for (let advanced of this.bAdvanced) | for (let advanced of this.bAdvanced) | ||||
{ | { | ||||
if (gameState.countEntitiesAndQueuedByType(advanced, true) > 0 || !this.canBuild(gameState, advanced)) | if (gameState.countEntitiesAndQueuedByType(advanced, true) > 0 || !this.canBuild(gameState, advanced)) | ||||
continue; | continue; | ||||
let template = gameState.getTemplate(advanced); | let template = gameState.getTemplate(advanced); | ||||
if (!template) | if (!template) | ||||
continue; | continue; | ||||
if (template.hasDefensiveFire() || template.trainableEntities()) | if (template.hasDefensiveFire() || template.trainableEntities()) | ||||
{ | { | ||||
let preferredBase = this.findBestBaseForMilitary(gameState); | let preferredBase = this.findBestBaseForMilitary(gameState); | ||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced, { "preferredBase": preferredBase })); | queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced, { "preferredBase": preferredBase })); | ||||
} | } | ||||
else // not a military building, but still use this queue | else // not a military building, but still use this queue | ||||
queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced)); | queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced)); | ||||
break; | return; | ||||
} | |||||
} | } | ||||
} | } | ||||
}; | }; | ||||
/** | /** | ||||
* Construct military building in bases nearest to the ennemies TODO revisit as the nearest one may not be accessible | * Construct military building in bases nearest to the ennemies TODO revisit as the nearest one may not be accessible | ||||
*/ | */ | ||||
m.HQ.prototype.findBestBaseForMilitary = function(gameState) | m.HQ.prototype.findBestBaseForMilitary = function(gameState) | ||||
▲ Show 20 Lines • Show All 507 Lines • ▼ Show 20 Lines | |||||
* Some functions are run every turn | * Some functions are run every turn | ||||
* Others once in a while | * Others once in a while | ||||
*/ | */ | ||||
m.HQ.prototype.update = function(gameState, queues, events) | m.HQ.prototype.update = function(gameState, queues, events) | ||||
{ | { | ||||
Engine.ProfileStart("Headquarters update"); | Engine.ProfileStart("Headquarters update"); | ||||
this.turnCache = {}; | this.turnCache = {}; | ||||
this.territoryMap = m.createTerritoryMap(gameState); | this.territoryMap = m.createTerritoryMap(gameState); | ||||
this.canBarter = gameState.getOwnEntitiesByClass("BarterMarket", true).filter(API3.Filters.isBuilt()).hasEntities(); | |||||
if (this.Config.debug > 1) | if (this.Config.debug > 1) | ||||
{ | { | ||||
gameState.getOwnUnits().forEach (function (ent) { | gameState.getOwnUnits().forEach (function (ent) { | ||||
if (!ent.position()) | if (!ent.position()) | ||||
return; | return; | ||||
m.dumpEntity(ent); | m.dumpEntity(ent); | ||||
}); | }); | ||||
Show All 9 Lines | m.HQ.prototype.update = function(gameState, queues, events) | ||||
if (this.numActiveBase() > 0) | if (this.numActiveBase() > 0) | ||||
{ | { | ||||
this.trainMoreWorkers(gameState, queues); | this.trainMoreWorkers(gameState, queues); | ||||
if (gameState.ai.playedTurn % 2 == 1) | if (gameState.ai.playedTurn % 2 == 1) | ||||
this.buildMoreHouses(gameState,queues); | this.buildMoreHouses(gameState,queues); | ||||
if (!this.saveResources && gameState.ai.playedTurn % 4 == 2) | if ((!this.saveResources || this.canBarter) && gameState.ai.playedTurn % 4 == 2) | ||||
this.buildFarmstead(gameState, queues); | this.buildFarmstead(gameState, queues); | ||||
if (this.needCorral && gameState.ai.playedTurn % 4 == 3) | if (this.needCorral && gameState.ai.playedTurn % 4 == 3) | ||||
this.manageCorral(gameState, queues); | this.manageCorral(gameState, queues); | ||||
if (!queues.minorTech.hasQueuedUnits() && gameState.ai.playedTurn % 5 == 1) | if (!queues.minorTech.hasQueuedUnits() && gameState.ai.playedTurn % 5 == 1) | ||||
this.researchManager.update(gameState, queues); | this.researchManager.update(gameState, queues); | ||||
} | } | ||||
if (this.numActiveBase() < 1 || | if (this.numActiveBase() < 1 || | ||||
(this.Config.difficulty > 0 && gameState.ai.playedTurn % 10 == 7 && gameState.currentPhase() > 1)) | (this.Config.difficulty > 0 && gameState.ai.playedTurn % 10 == 7 && gameState.currentPhase() > 1)) | ||||
this.checkBaseExpansion(gameState, queues); | this.checkBaseExpansion(gameState, queues); | ||||
if (gameState.currentPhase() > 1) | if (gameState.currentPhase() > 1) | ||||
{ | { | ||||
if (!this.canBarter) | |||||
this.buildMarket(gameState, queues); | |||||
if (!this.saveResources) | if (!this.saveResources) | ||||
{ | { | ||||
this.buildMarket(gameState, queues); | |||||
this.buildBlacksmith(gameState, queues); | this.buildBlacksmith(gameState, queues); | ||||
this.buildTemple(gameState, queues); | this.buildTemple(gameState, queues); | ||||
} | } | ||||
} | |||||
if (this.Config.difficulty > 1) | |||||
this.tradeManager.update(gameState, events, queues); | this.tradeManager.update(gameState, events, queues); | ||||
} | |||||
this.garrisonManager.update(gameState, events); | this.garrisonManager.update(gameState, events); | ||||
this.defenseManager.update(gameState, events); | this.defenseManager.update(gameState, events); | ||||
if (!this.saveResources) | |||||
this.constructTrainingBuildings(gameState, queues); | this.constructTrainingBuildings(gameState, queues); | ||||
if (this.Config.difficulty > 0) | if (this.Config.difficulty > 0) | ||||
this.buildDefenses(gameState, queues); | this.buildDefenses(gameState, queues); | ||||
this.assignGatherers(); | this.assignGatherers(); | ||||
for (let i = 0; i < this.baseManagers.length; ++i) | for (let i = 0; i < this.baseManagers.length; ++i) | ||||
{ | { | ||||
this.baseManagers[i].checkEvents(gameState, events, queues); | this.baseManagers[i].checkEvents(gameState, events, queues); | ||||
▲ Show 20 Lines • Show All 132 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator