diff --git a/binaries/data/mods/public/simulation/ai/petra/buildManager.js b/binaries/data/mods/public/simulation/ai/petra/buildManager.js index 801dec9e01..9e87bcf199 100644 --- a/binaries/data/mods/public/simulation/ai/petra/buildManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/buildManager.js @@ -10,40 +10,38 @@ import { aiWarn } from "simulation/ai/common-api/utils.js"; export function BuildManager() { // List of buildings we have builders for, with number of possible builders. - this.builderCounters = new Map(); + this.builders = new Map(); // List of buildings we can't currently build (because no room, no builder or whatever), // with time we should wait before trying again to build it. this.unbuildables = new Map(); } +function addBuilder(builders, civ, entity) +{ + for (const buildable of entity.buildableEntities(civ)) + { + if (!builders.has(buildable)) + builders.set(buildable, []); + builders.get(buildable).push(entity.id()); + } +} + +function removeBuilder(builders, entityId) +{ + for (const entities of builders.values()) + { + const entityIndex = entities.indexOf(entityId); + if (entityIndex !== -1) + entities.splice(entityIndex, 1); + } +} + /** Initialization at start of game */ BuildManager.prototype.init = function(gameState) { const civ = gameState.getPlayerCiv(); for (const ent of gameState.getOwnUnits().values()) - this.incrementBuilderCounters(civ, ent, 1); -}; - -BuildManager.prototype.incrementBuilderCounters = function(civ, ent, increment) -{ - for (const buildable of ent.buildableEntities(civ)) - { - if (this.builderCounters.has(buildable)) - { - const count = this.builderCounters.get(buildable) + increment; - if (count < 0) - { - aiWarn(" Petra error in incrementBuilderCounters for " + buildable + - " with count < 0"); - continue; - } - this.builderCounters.set(buildable, count); - } - else if (increment > 0) - this.builderCounters.set(buildable, increment); - else - aiWarn(" Petra error in incrementBuilderCounters for " + buildable + " not yet set"); - } + addBuilder(this.builders, civ, ent); }; /** Update the builders counters */ @@ -58,30 +56,25 @@ BuildManager.prototype.checkEvents = function(gameState, events) continue; const ent = gameState.getEntityById(evt.entity); if (ent && ent.isOwn(PlayerID) && ent.hasClass("Unit")) - this.incrementBuilderCounters(civ, ent, 1); + addBuilder(this.builders, civ, ent); } for (const evt of events.Destroy) - { - if (events.Create.some(e => e.entity == evt.entity) || !evt.entityObj) - continue; - const ent = evt.entityObj; - if (ent && ent.isOwn(PlayerID) && ent.hasClass("Unit")) - this.incrementBuilderCounters(civ, ent, -1); - } + removeBuilder(this.builders, evt.entity); for (const evt of events.OwnershipChanged) // capture events { - let increment; if (evt.from == PlayerID) - increment = -1; - else if (evt.to == PlayerID) - increment = 1; - else + { + removeBuilder(this.builders, evt.entity); continue; + } + else if (evt.to != PlayerID) + continue; + const ent = gameState.getEntityById(evt.entity); - if (ent && ent.hasClass("Unit")) - this.incrementBuilderCounters(civ, ent, increment); + if (ent?.hasClass("Unit")) + addBuilder(this.builders, civ, ent); } for (const evt of events.ValueModification) @@ -92,10 +85,10 @@ BuildManager.prototype.checkEvents = function(gameState, events) // Unfortunately there really is not an easy way to determine the changes // at this stage, so we simply have to dump the cache. - this.builderCounters = new Map(); + this.builders = new Map(); for (const ent of gameState.getOwnUnits().values()) - this.incrementBuilderCounters(civ, ent, 1); + addBuilder(this.builders, civ, ent); } }; @@ -106,9 +99,9 @@ BuildManager.prototype.checkEvents = function(gameState, events) BuildManager.prototype.findStructuresByFilter = function(gameState, filter) { const result = []; - for (const [templateName, count] of this.builderCounters) + for (const [templateName, entities] of this.builders) { - if (!count || gameState.isTemplateDisabled(templateName)) + if (!entities.length || gameState.isTemplateDisabled(templateName)) continue; const template = gameState.getTemplate(templateName); if (!template || !template.available(gameState)) @@ -130,8 +123,8 @@ BuildManager.prototype.findStructureWithClass = function(gameState, classes) BuildManager.prototype.hasBuilder = function(template) { - const numBuilders = this.builderCounters.get(template); - return numBuilders && numBuilders > 0; + const numBuilders = this.builders.get(template); + return numBuilders && numBuilders.length > 0; }; BuildManager.prototype.isUnbuildable = function(gameState, template) @@ -182,7 +175,7 @@ BuildManager.prototype.resetMissingRoom = function(gameState) BuildManager.prototype.Serialize = function() { return { - "builderCounters": this.builderCounters, + "builders": this.builders, "unbuildables": this.unbuildables }; }; @@ -192,3 +185,4 @@ BuildManager.prototype.Deserialize = function(data) for (const key in data) this[key] = data[key]; }; +