Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/simulation/ai/petra/baseManager.js
Show First 20 Lines • Show All 246 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
/** | /** | ||||
* Returns the position of the best place to build a new dropsite for the specified resource | * Returns the position of the best place to build a new dropsite for the specified resource | ||||
*/ | */ | ||||
PETRA.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource) | PETRA.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource) | ||||
{ | { | ||||
let template = gameState.getTemplate(gameState.applyCiv("structures/{civ}_storehouse")); | let template = gameState.getTemplate(gameState.applyCiv("structures/{civ}/storehouse")); | ||||
let halfSize = 0; | let halfSize = 0; | ||||
if (template.get("Footprint/Square")) | if (template.get("Footprint/Square")) | ||||
halfSize = Math.max(+template.get("Footprint/Square/@depth"), +template.get("Footprint/Square/@width")) / 2; | halfSize = Math.max(+template.get("Footprint/Square/@depth"), +template.get("Footprint/Square/@width")) / 2; | ||||
else if (template.get("Footprint/Circle")) | else if (template.get("Footprint/Circle")) | ||||
halfSize = +template.get("Footprint/Circle/@radius"); | halfSize = +template.get("Footprint/Circle/@radius"); | ||||
// This builds a map. The procedure is fairly simple. It adds the resource maps | // This builds a map. The procedure is fairly simple. It adds the resource maps | ||||
// (which are dynamically updated and are made so that they will facilitate DP placement) | // (which are dynamically updated and are made so that they will facilitate DP placement) | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | |||||
/** check our resource levels and react accordingly */ | /** check our resource levels and react accordingly */ | ||||
PETRA.BaseManager.prototype.checkResourceLevels = function(gameState, queues) | PETRA.BaseManager.prototype.checkResourceLevels = function(gameState, queues) | ||||
{ | { | ||||
for (let type of Resources.GetCodes()) | for (let type of Resources.GetCodes()) | ||||
{ | { | ||||
if (type == "food") | if (type == "food") | ||||
{ | { | ||||
if (gameState.ai.HQ.canBuild(gameState, "structures/{civ}_field")) // let's see if we need to add new farms. | if (gameState.ai.HQ.canBuild(gameState, "structures/{civ}/field")) // let's see if we need to add new farms. | ||||
{ | { | ||||
let count = this.getResourceLevel(gameState, type, gameState.currentPhase() > 1); // animals are not accounted | let count = this.getResourceLevel(gameState, type, gameState.currentPhase() > 1); // animals are not accounted | ||||
let numFarms = gameState.getOwnStructures().filter(API3.Filters.byClass("Field")).length; // including foundations | let numFarms = gameState.getOwnStructures().filter(API3.Filters.byClass("Field")).length; // including foundations | ||||
let numQueue = queues.field.countQueuedUnits(); | let numQueue = queues.field.countQueuedUnits(); | ||||
// TODO if not yet farms, add a check on time used/lost and build farmstead if needed | // TODO if not yet farms, add a check on time used/lost and build farmstead if needed | ||||
if (numFarms + numQueue == 0) // starting game, rely on fruits as long as we have enough of them | if (numFarms + numQueue == 0) // starting game, rely on fruits as long as we have enough of them | ||||
{ | { | ||||
if (count < 600) | if (count < 600) | ||||
{ | { | ||||
queues.field.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_field", { "favoredBase": this.ID })); | queues.field.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}/field", { "favoredBase": this.ID })); | ||||
gameState.ai.HQ.needFarm = true; | gameState.ai.HQ.needFarm = true; | ||||
} | } | ||||
} | } | ||||
else if (!gameState.ai.HQ.maxFields || numFarms + numQueue < gameState.ai.HQ.maxFields) | else if (!gameState.ai.HQ.maxFields || numFarms + numQueue < gameState.ai.HQ.maxFields) | ||||
{ | { | ||||
let numFound = gameState.getOwnFoundations().filter(API3.Filters.byClass("Field")).length; | let numFound = gameState.getOwnFoundations().filter(API3.Filters.byClass("Field")).length; | ||||
let goal = this.Config.Economy.provisionFields; | let goal = this.Config.Economy.provisionFields; | ||||
if (gameState.ai.HQ.saveResources || gameState.ai.HQ.saveSpace || count > 300 || numFarms > 5) | if (gameState.ai.HQ.saveResources || gameState.ai.HQ.saveSpace || count > 300 || numFarms > 5) | ||||
goal = Math.max(goal-1, 1); | goal = Math.max(goal-1, 1); | ||||
if (numFound + numQueue < goal) | if (numFound + numQueue < goal) | ||||
queues.field.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_field", { "favoredBase": this.ID })); | queues.field.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}/field", { "favoredBase": this.ID })); | ||||
} | } | ||||
else if (gameState.ai.HQ.needCorral && !gameState.getOwnEntitiesByClass("Corral", true).hasEntities() && | else if (gameState.ai.HQ.needCorral && !gameState.getOwnEntitiesByClass("Corral", true).hasEntities() && | ||||
!queues.corral.hasQueuedUnits() && gameState.ai.HQ.canBuild(gameState, "structures/{civ}_corral")) | !queues.corral.hasQueuedUnits() && gameState.ai.HQ.canBuild(gameState, "structures/{civ}/corral")) | ||||
queues.corral.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_corral", { "favoredBase": this.ID })); | queues.corral.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}/corral", { "favoredBase": this.ID })); | ||||
continue; | continue; | ||||
} | } | ||||
if (!gameState.getOwnEntitiesByClass("Corral", true).hasEntities() && | if (!gameState.getOwnEntitiesByClass("Corral", true).hasEntities() && | ||||
!queues.corral.hasQueuedUnits() && gameState.ai.HQ.canBuild(gameState, "structures/{civ}_corral")) | !queues.corral.hasQueuedUnits() && gameState.ai.HQ.canBuild(gameState, "structures/{civ}/corral")) | ||||
{ | { | ||||
let count = this.getResourceLevel(gameState, type, gameState.currentPhase() > 1); // animals are not accounted | let count = this.getResourceLevel(gameState, type, gameState.currentPhase() > 1); // animals are not accounted | ||||
if (count < 900) | if (count < 900) | ||||
{ | { | ||||
queues.corral.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_corral", { "favoredBase": this.ID })); | queues.corral.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}/corral", { "favoredBase": this.ID })); | ||||
gameState.ai.HQ.needCorral = true; | gameState.ai.HQ.needCorral = true; | ||||
} | } | ||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
// Non food stuff | // Non food stuff | ||||
if (!gameState.sharedScript.resourceMaps[type] || queues.dropsites.hasQueuedUnits() || | if (!gameState.sharedScript.resourceMaps[type] || queues.dropsites.hasQueuedUnits() || | ||||
gameState.getOwnFoundations().filter(API3.Filters.byClass("Storehouse")).hasEntities()) | gameState.getOwnFoundations().filter(API3.Filters.byClass("Storehouse")).hasEntities()) | ||||
Show All 15 Lines | for (let type of Resources.GetCodes()) | ||||
// TODO add also a test on remaining resources. | // TODO add also a test on remaining resources. | ||||
let total = this.gatherers[type].used + this.gatherers[type].lost; | let total = this.gatherers[type].used + this.gatherers[type].lost; | ||||
if (total > 150 || total > 60 && type != "wood") | if (total > 150 || total > 60 && type != "wood") | ||||
{ | { | ||||
let ratio = this.gatherers[type].lost / total; | let ratio = this.gatherers[type].lost / total; | ||||
if (ratio > 0.15) | if (ratio > 0.15) | ||||
{ | { | ||||
let newDP = this.findBestDropsiteLocation(gameState, type); | let newDP = this.findBestDropsiteLocation(gameState, type); | ||||
if (newDP.quality > 50 && gameState.ai.HQ.canBuild(gameState, "structures/{civ}_storehouse")) | if (newDP.quality > 50 && gameState.ai.HQ.canBuild(gameState, "structures/{civ}/storehouse")) | ||||
queues.dropsites.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_storehouse", { "base": this.ID, "type": type }, newDP.pos)); | queues.dropsites.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}/storehouse", { "base": this.ID, "type": type }, newDP.pos)); | ||||
else if (!gameState.getOwnFoundations().filter(API3.Filters.byClass("CivCentre")).hasEntities() && !queues.civilCentre.hasQueuedUnits()) | else if (!gameState.getOwnFoundations().filter(API3.Filters.byClass("CivCentre")).hasEntities() && !queues.civilCentre.hasQueuedUnits()) | ||||
{ | { | ||||
// No good dropsite, try to build a new base if no base already planned, | // No good dropsite, try to build a new base if no base already planned, | ||||
// and if not possible, be less strict on dropsite quality. | // and if not possible, be less strict on dropsite quality. | ||||
if ((!gameState.ai.HQ.canExpand || !gameState.ai.HQ.buildNewBase(gameState, queues, type)) && | if ((!gameState.ai.HQ.canExpand || !gameState.ai.HQ.buildNewBase(gameState, queues, type)) && | ||||
newDP.quality > Math.min(25, 50*0.15/ratio) && | newDP.quality > Math.min(25, 50*0.15/ratio) && | ||||
gameState.ai.HQ.canBuild(gameState, "structures/{civ}_storehouse")) | gameState.ai.HQ.canBuild(gameState, "structures/{civ}/storehouse")) | ||||
queues.dropsites.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_storehouse", { "base": this.ID, "type": type }, newDP.pos)); | queues.dropsites.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}/storehouse", { "base": this.ID, "type": type }, newDP.pos)); | ||||
} | } | ||||
} | } | ||||
this.gatherers[type].nextCheck = gameState.ai.playedTurn + 20; | this.gatherers[type].nextCheck = gameState.ai.playedTurn + 20; | ||||
this.gatherers[type].used = 0; | this.gatherers[type].used = 0; | ||||
this.gatherers[type].lost = 0; | this.gatherers[type].lost = 0; | ||||
} | } | ||||
else if (total == 0) | else if (total == 0) | ||||
this.gatherers[type].nextCheck = gameState.ai.playedTurn + 10; | this.gatherers[type].nextCheck = gameState.ai.playedTurn + 10; | ||||
▲ Show 20 Lines • Show All 630 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator