From 38c2e1a61e1ef5162a17c7101f1b25fe01b4a2f6 Mon Sep 17 00:00:00 2001 From: JynLeazy1 Date: Fri, 2 Oct 2026 16:08:15 -0600 Subject: [PATCH] Remove destroyed resources from the AI resource maps again Since d18a6392b3 all resource maps were rebuilt whenever an entity in SharedScript.resources was destroyed. As every entity was listed there, not only resources, that happened on almost every turn and took most of the AI time in big games. Keep instead the influence of each resource on the maps, and subtract it when the resource is destroyed. Like d18a6392b3, this does not need entityObj. --- .../public/simulation/ai/common-api/shared.js | 68 +++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/binaries/data/mods/public/simulation/ai/common-api/shared.js b/binaries/data/mods/public/simulation/ai/common-api/shared.js index 09d71d8fbd..322baddded 100644 --- a/binaries/data/mods/public/simulation/ai/common-api/shared.js +++ b/binaries/data/mods/public/simulation/ai/common-api/shared.js @@ -127,7 +127,8 @@ export class SharedScript this.influenceRadius = { "abundant": 36, "sparse": 48 }; this.ccInfluenceRadius = { "abundant": 60, "sparse": 120 }; - this.resources = []; // Contains entityIds of all resources in the maps. + // The influence of each resource on the resource maps, by entity id, to remove it when the resource is destroyed. + this.resources = new Map(); this.resourceMaps = {}; // Contains maps showing the density of resources this.ccResourceMaps = {}; // Contains maps showing the density of resources, optimized for CC placement. this.createResourceMaps(); @@ -401,11 +402,13 @@ export class SharedScript */ updateResourceMaps(events) { - if (events.Destroy.some(e => this.resources.includes(e.entity))) + for (const e of events.Destroy) { - this.resources = []; - this.resourceMaps = {}; - this.createResourceMaps(); + const influence = this.resources.get(e.entity); + if (!influence) + continue; + this.applyResourceInfluence(influence, -1); + this.resources.delete(e.entity); } for (const e of events.Create) @@ -418,8 +421,13 @@ export class SharedScript */ addEntityToResourceMap(entity) { - this.changeEntityInResourceMapHelper(entity, 1); - this.resources.push(entity.id()); + if (this.resources.has(entity.id())) + return; + const influence = this.getResourceInfluence(entity); + if (!influence) + return; + this.applyResourceInfluence(influence, 1); + this.resources.set(entity.id(), influence); } /** @@ -427,29 +435,49 @@ export class SharedScript */ removeEntityFromResourceMap(entity) { - this.changeEntityInResourceMapHelper(entity, -1); + const influence = this.resources.get(entity.id()); + if (!influence) + return; + this.applyResourceInfluence(influence, -1); + this.resources.delete(entity.id()); } /** - * @param {entity} ent - The entity to add to the resource map. + * @param {entity} ent - A resource. + * @return {Object|undefined} - The influence of the resource on the resource maps, as + * { "resource", "x", "y", "strength" }, or undefined if it has none. */ - changeEntityInResourceMapHelper(ent, multiplication = 1) + getResourceInfluence(ent) { if (!ent) - return; + return undefined; const entPos = ent.position(); if (!entPos) - return; + return undefined; const resource = ent.resourceSupplyType()?.generic; if (!resource || !this.resourceMaps[resource]) - return; - const cellSize = this.resourceMaps[resource].cellSize; - const x = Math.floor(entPos[0] / cellSize); - const y = Math.floor(entPos[1] / cellSize); + return undefined; + const [x, y] = this.resourceMaps[resource].gamePosToMapPos(entPos); const grp = Resources.GetResource(resource).aiAnalysisInfluenceGroup; - const strength = multiplication * ent.resourceSupplyMax() / this.normalizationFactor[grp]; - this.resourceMaps[resource].addInfluence(x, y, this.influenceRadius[grp] / cellSize, strength / 2, "constant"); - this.resourceMaps[resource].addInfluence(x, y, this.influenceRadius[grp] / cellSize, strength / 2); - this.ccResourceMaps[resource].addInfluence(x, y, this.ccInfluenceRadius[grp] / cellSize, strength, "constant"); + return { + "resource": resource, + "x": x, + "y": y, + "strength": ent.resourceSupplyMax() / this.normalizationFactor[grp] + }; + } + + /** + * Add (multiplication 1) or remove (-1) the influence of a resource on the resource maps. + * @param {Object} influence - As returned by getResourceInfluence. + */ + applyResourceInfluence({ resource, x, y, strength }, multiplication) + { + const cellSize = this.resourceMaps[resource].cellSize; + const grp = Resources.GetResource(resource).aiAnalysisInfluenceGroup; + const amount = multiplication * strength; + this.resourceMaps[resource].addInfluence(x, y, this.influenceRadius[grp] / cellSize, amount / 2, "constant"); + this.resourceMaps[resource].addInfluence(x, y, this.influenceRadius[grp] / cellSize, amount / 2); + this.ccResourceMaps[resource].addInfluence(x, y, this.ccInfluenceRadius[grp] / cellSize, amount, "constant"); } }