Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/ai/petra/baseManager.js
Show First 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | for (let type of dropsite.resourceDropsiteTypes()) | ||||
let nearby = this.dropsiteSupplies[type].nearby; | let nearby = this.dropsiteSupplies[type].nearby; | ||||
let medium = this.dropsiteSupplies[type].medium; | let medium = this.dropsiteSupplies[type].medium; | ||||
let faraway = this.dropsiteSupplies[type].faraway; | let faraway = this.dropsiteSupplies[type].faraway; | ||||
resources.forEach(function(supply) | resources.forEach(function(supply) | ||||
{ | { | ||||
if (!supply.position()) | if (!supply.position()) | ||||
return; | return; | ||||
if (supply.hasClass("Animal")) // moving resources are treated differently | // Moving resources and fields are treated differently. | ||||
return; | if (supply.hasClasses(["Animal", "Field"])) | ||||
if (supply.hasClass("Field")) // fields are treated separately | |||||
return; | return; | ||||
// quick accessibility check | // quick accessibility check | ||||
if (PETRA.getLandAccess(gameState, supply) != accessIndex) | if (PETRA.getLandAccess(gameState, supply) != accessIndex) | ||||
return; | return; | ||||
let dist = API3.SquareVectorDistance(supply.position(), dropsitePos); | let dist = API3.SquareVectorDistance(supply.position(), dropsitePos); | ||||
if (dist < maxDistResourceSquare) | if (dist < maxDistResourceSquare) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | PETRA.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource) | ||||
// 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) | ||||
// Then checks for a good spot in the territory. If none, and town/city phase, checks outside | // Then checks for a good spot in the territory. If none, and town/city phase, checks outside | ||||
// The AI will currently not build a CC if it wouldn't connect with an existing CC. | // The AI will currently not build a CC if it wouldn't connect with an existing CC. | ||||
let obstructions = PETRA.createObstructionMap(gameState, this.accessIndex, template); | let obstructions = PETRA.createObstructionMap(gameState, this.accessIndex, template); | ||||
let ccEnts = gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).toEntityArray(); | let ccEnts = gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).toEntityArray(); | ||||
let dpEnts = gameState.getOwnStructures().filter(API3.Filters.byClassesOr(["Storehouse", "Dock"])).toEntityArray(); | let dpEnts = gameState.getOwnStructures().filter(API3.Filters.byClasses(["Storehouse", "Dock"])).toEntityArray(); | ||||
let bestIdx; | let bestIdx; | ||||
let bestVal = 0; | let bestVal = 0; | ||||
let radius = Math.ceil(template.obstructionRadius().max / obstructions.cellSize); | let radius = Math.ceil(template.obstructionRadius().max / obstructions.cellSize); | ||||
let territoryMap = gameState.ai.HQ.territoryMap; | let territoryMap = gameState.ai.HQ.territoryMap; | ||||
let width = territoryMap.width; | let width = territoryMap.width; | ||||
let cellSize = territoryMap.cellSize; | let cellSize = territoryMap.cellSize; | ||||
▲ Show 20 Lines • Show All 226 Lines • ▼ Show 20 Lines | |||||
PETRA.BaseManager.prototype.assignRolelessUnits = function(gameState, roleless) | PETRA.BaseManager.prototype.assignRolelessUnits = function(gameState, roleless) | ||||
{ | { | ||||
if (!roleless) | if (!roleless) | ||||
roleless = this.units.filter(API3.Filters.not(API3.Filters.byHasMetadata(PlayerID, "role"))).values(); | roleless = this.units.filter(API3.Filters.not(API3.Filters.byHasMetadata(PlayerID, "role"))).values(); | ||||
for (let ent of roleless) | for (let ent of roleless) | ||||
{ | { | ||||
if (ent.hasClass("Worker") || ent.hasClass("CitizenSoldier") || ent.hasClass("FishingBoat")) | if (ent.hasClasses(["Worker", "CitizenSoldier", "FishingBoat"])) | ||||
ent.setMetadata(PlayerID, "role", "worker"); | ent.setMetadata(PlayerID, "role", "worker"); | ||||
} | } | ||||
}; | }; | ||||
/** | /** | ||||
* If the numbers of workers on the resources is unbalanced then set some of workers to idle so | * If the numbers of workers on the resources is unbalanced then set some of workers to idle so | ||||
* they can be reassigned by reassignIdleWorkers. | * they can be reassigned by reassignIdleWorkers. | ||||
* TODO: actually this probably should be in the HQ. | * TODO: actually this probably should be in the HQ. | ||||
▲ Show 20 Lines • Show All 246 Lines • ▼ Show 20 Lines | PETRA.BaseManager.prototype.assignToFoundations = function(gameState, noRepair) | ||||
} | } | ||||
for (let target of foundations.values()) | for (let target of foundations.values()) | ||||
{ | { | ||||
if (target.hasClass("Field")) | if (target.hasClass("Field")) | ||||
continue; // we do not build fields | continue; // we do not build fields | ||||
if (gameState.ai.HQ.isNearInvadingArmy(target.position())) | if (gameState.ai.HQ.isNearInvadingArmy(target.position())) | ||||
if (!target.hasClass("CivCentre") && !target.hasClass("Wall") && | if (!target.hasClasses(["CivCentre", "Wall"]) && | ||||
(!target.hasClass("Wonder") || !gameState.getVictoryConditions().has("wonder"))) | (!target.hasClass("Wonder") || !gameState.getVictoryConditions().has("wonder"))) | ||||
continue; | continue; | ||||
// if our territory has shrinked since this foundation was positioned, do not build it | // if our territory has shrinked since this foundation was positioned, do not build it | ||||
if (PETRA.isNotWorthBuilding(gameState, target)) | if (PETRA.isNotWorthBuilding(gameState, target)) | ||||
continue; | continue; | ||||
let assigned = gameState.getOwnEntitiesByMetadata("target-foundation", target.id()).length; | let assigned = gameState.getOwnEntitiesByMetadata("target-foundation", target.id()).length; | ||||
let maxTotalBuilders = Math.ceil(workers.length * builderRatio); | let maxTotalBuilders = Math.ceil(workers.length * builderRatio); | ||||
if (maxTotalBuilders < 2 && workers.length > 1) | if (maxTotalBuilders < 2 && workers.length > 1) | ||||
maxTotalBuilders = 2; | maxTotalBuilders = 2; | ||||
if (target.hasClass("House") && gameState.getPopulationLimit() < gameState.getPopulation() + 5 && | if (target.hasClass("House") && gameState.getPopulationLimit() < gameState.getPopulation() + 5 && | ||||
gameState.getPopulationLimit() < gameState.getPopulationMax()) | gameState.getPopulationLimit() < gameState.getPopulationMax()) | ||||
maxTotalBuilders += 2; | maxTotalBuilders += 2; | ||||
let targetNB = 2; | let targetNB = 2; | ||||
if (target.hasClass("Fortress") || target.hasClass("Wonder") || | if (target.hasClasses(["Fortress", "Wonder"]) || | ||||
target.getMetadata(PlayerID, "phaseUp") == true) | target.getMetadata(PlayerID, "phaseUp") == true) | ||||
targetNB = 7; | targetNB = 7; | ||||
else if (target.hasClass("Barracks") || target.hasClass("Range") || target.hasClass("Stable") || | else if (target.hasClasses(["Barracks", "Range", "Stable", "Tower", "Market"])) | ||||
target.hasClass("Tower") || target.hasClass("Market")) | |||||
targetNB = 4; | targetNB = 4; | ||||
else if (target.hasClass("House") || target.hasClass("DropsiteWood")) | else if (target.hasClasses(["House", "DropsiteWood"])) | ||||
targetNB = 3; | targetNB = 3; | ||||
if (target.getMetadata(PlayerID, "baseAnchor") == true || | if (target.getMetadata(PlayerID, "baseAnchor") == true || | ||||
target.hasClass("Wonder") && gameState.getVictoryConditions().has("wonder")) | target.hasClass("Wonder") && gameState.getVictoryConditions().has("wonder")) | ||||
{ | { | ||||
targetNB = 15; | targetNB = 15; | ||||
maxTotalBuilders = Math.max(maxTotalBuilders, 15); | maxTotalBuilders = Math.max(maxTotalBuilders, 15); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | PETRA.BaseManager.prototype.assignToFoundations = function(gameState, noRepair) | ||||
for (let target of damagedBuildings.values()) | for (let target of damagedBuildings.values()) | ||||
{ | { | ||||
// Don't repair if we're still under attack, unless it's a vital (civcentre or wall) building | // Don't repair if we're still under attack, unless it's a vital (civcentre or wall) building | ||||
// that's being destroyed. | // that's being destroyed. | ||||
if (gameState.ai.HQ.isNearInvadingArmy(target.position())) | if (gameState.ai.HQ.isNearInvadingArmy(target.position())) | ||||
{ | { | ||||
if (target.healthLevel() > 0.5 || | if (target.healthLevel() > 0.5 || | ||||
!target.hasClass("CivCentre") && !target.hasClass("Wall") && | !target.hasClasses(["CivCentre", "Wall"]) && | ||||
(!target.hasClass("Wonder") || !gameState.getVictoryConditions().has("wonder"))) | (!target.hasClass("Wonder") || !gameState.getVictoryConditions().has("wonder"))) | ||||
continue; | continue; | ||||
} | } | ||||
else if (noRepair && !target.hasClass("CivCentre")) | else if (noRepair && !target.hasClass("CivCentre")) | ||||
continue; | continue; | ||||
if (target.decaying()) | if (target.decaying()) | ||||
continue; | continue; | ||||
let assigned = gameState.getOwnEntitiesByMetadata("target-foundation", target.id()).length; | let assigned = gameState.getOwnEntitiesByMetadata("target-foundation", target.id()).length; | ||||
let maxTotalBuilders = Math.ceil(workers.length * builderRatio); | let maxTotalBuilders = Math.ceil(workers.length * builderRatio); | ||||
let targetNB = 1; | let targetNB = 1; | ||||
if (target.hasClass("Fortress") || target.hasClass("Wonder")) | if (target.hasClasses(["Fortress", "Wonder"])) | ||||
targetNB = 3; | targetNB = 3; | ||||
if (target.getMetadata(PlayerID, "baseAnchor") == true || | if (target.getMetadata(PlayerID, "baseAnchor") == true || | ||||
target.hasClass("Wonder") && gameState.getVictoryConditions().has("wonder")) | target.hasClass("Wonder") && gameState.getVictoryConditions().has("wonder")) | ||||
{ | { | ||||
maxTotalBuilders = Math.ceil(workers.length * Math.max(0.3, builderRatio)); | maxTotalBuilders = Math.ceil(workers.length * Math.max(0.3, builderRatio)); | ||||
targetNB = 5; | targetNB = 5; | ||||
if (target.healthLevel() < 0.3) | if (target.healthLevel() < 0.3) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 202 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator