Index: binaries/data/mods/public/simulation/ai/common-api/shared.js =================================================================== --- binaries/data/mods/public/simulation/ai/common-api/shared.js +++ binaries/data/mods/public/simulation/ai/common-api/shared.js @@ -115,16 +115,6 @@ this.accessibility = new m.Accessibility(); this.accessibility.init(state, this.terrainAnalyzer); - // Resource types: ignore = not used for resource maps - // abundant = abundant resource with small amount each - // sparse = sparse resource, but huge amount each - // The following maps are defined in TerrainAnalysis.js and are used for some building placement (cc, dropsites) - // They are updated by checking for create and destroy events for all resources - this.normalizationFactor = { "abundant": 50, "sparse": 90 }; - this.influenceRadius = { "abundant": 36, "sparse": 48 }; - this.ccInfluenceRadius = { "abundant": 60, "sparse": 120 }; - this.resourceMaps = {}; // Contains maps showing the density of resources - this.ccResourceMaps = {}; // Contains maps showing the density of resources, optimized for CC placement. this.createResourceMaps(); this.gameState = {}; Index: binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js =================================================================== --- binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js +++ binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js @@ -383,6 +383,17 @@ /** creates a map of resource density */ m.SharedScript.prototype.createResourceMaps = function() { + // Resource types: ignore = not used for resource maps + // abundant = abundant resource with small amount each + // sparse = sparse resource, but huge amount each + // The following maps are used for some building placement (cc, dropsites) + // They are updated by checking for create and destroy events for all resources + this.normalizationFactor = { "abundant": 50, "sparse": 90 }; + this.influenceRadius = { "abundant": 36, "sparse": 48 }; + this.ccInfluenceRadius = { "abundant": 60, "sparse": 120 }; + this.resourceMaps = {}; // Contains maps showing the density of resources + this.ccResourceMaps = {}; // Contains maps showing the density of resources, optimized for CC placement. + for (let resource of Resources.GetCodes()) { if (!(Resources.GetResource(resource).aiAnalysisInfluenceGroup in this.normalizationFactor)) @@ -396,21 +407,7 @@ this.ccResourceMaps[resource] = new m.Map(this, "resource"); } for (let ent of this._entities.values()) - { - if (!ent || !ent.position() || !ent.resourceSupplyType()) - continue; - let resource = ent.resourceSupplyType().generic; - if (!this.resourceMaps[resource]) - continue; - let cellSize = this.resourceMaps[resource].cellSize; - let x = Math.floor(ent.position()[0] / cellSize); - let z = Math.floor(ent.position()[1] / cellSize); - let grp = Resources.GetResource(resource).aiAnalysisInfluenceGroup; - let strength = Math.floor(ent.resourceSupplyMax() / this.normalizationFactor[grp]); - this.resourceMaps[resource].addInfluence(x, z, this.influenceRadius[grp] / cellSize, strength/2, "constant"); - this.resourceMaps[resource].addInfluence(x, z, this.influenceRadius[grp] / cellSize, strength/2); - this.ccResourceMaps[resource].addInfluence(x, z, this.ccInfluenceRadius[grp] / cellSize, strength, "constant"); - } + this.addEntityToResourceMap(ent); }; /** @@ -420,60 +417,60 @@ */ m.SharedScript.prototype.updateResourceMaps = function(events) { - for (let resource of Resources.GetCodes()) - { - if (!(Resources.GetResource(resource).aiAnalysisInfluenceGroup in this.normalizationFactor)) - continue; - // if there is no resourceMap create one with an influence for everything with that resource - if (this.resourceMaps[resource]) - continue; - // We're creating them 8-bit. Things could go above 255 if there are really tons of resources - // But at that point the precision is not really important anyway. And it saves memory. - this.resourceMaps[resource] = new m.Map(this, "resource"); - this.ccResourceMaps[resource] = new m.Map(this, "resource"); - } - // Look for destroy (or create) events and subtract (or add) the entities original influence from the resourceMap for (let e of events.Destroy) { if (!e.entityObj) continue; - let ent = e.entityObj; - if (!ent || !ent.position() || !ent.resourceSupplyType()) - continue; - let resource = ent.resourceSupplyType().generic; - if (!this.resourceMaps[resource]) - continue; - let cellSize = this.resourceMaps[resource].cellSize; - let x = Math.floor(ent.position()[0] / cellSize); - let z = Math.floor(ent.position()[1] / cellSize); - let grp = Resources.GetResource(resource).aiAnalysisInfluenceGroup; - let strength = -Math.floor(ent.resourceSupplyMax() / this.normalizationFactor[grp]); - this.resourceMaps[resource].addInfluence(x, z, this.influenceRadius[grp] / cellSize, strength/2, "constant"); - this.resourceMaps[resource].addInfluence(x, z, this.influenceRadius[grp] / cellSize, strength/2); - this.ccResourceMaps[resource].addInfluence(x, z, this.ccInfluenceRadius[grp] / cellSize, strength, "constant"); + this.removeEntityFromResourceMap(e.entityObj); } for (let e of events.Create) { if (!e.entity || !this._entities.has(e.entity)) continue; - let ent = this._entities.get(e.entity); - if (!ent || !ent.position() || !ent.resourceSupplyType()) - continue; - let resource = ent.resourceSupplyType().generic; - if (!this.resourceMaps[resource]) - continue; - let cellSize = this.resourceMaps[resource].cellSize; - let x = Math.floor(ent.position()[0] / cellSize); - let z = Math.floor(ent.position()[1] / cellSize); - let grp = Resources.GetResource(resource).aiAnalysisInfluenceGroup; - let strength = Math.floor(ent.resourceSupplyMax() / this.normalizationFactor[grp]); - this.resourceMaps[resource].addInfluence(x, z, this.influenceRadius[grp] / cellSize, strength/2, "constant"); - this.resourceMaps[resource].addInfluence(x, z, this.influenceRadius[grp] / cellSize, strength/2); - this.ccResourceMaps[resource].addInfluence(x, z, this.ccInfluenceRadius[grp] / cellSize, strength, "constant"); + this.addEntityToResourceMap(this._entities.get(e.entity)); } }; +/** + * @param {entity} entity - The entity to add to the resource map. + */ +m.SharedScript.prototype.addEntityToResourceMap = function(entity) +{ + this.changeEntityInResourceMapHelper(entity, 1); +}; + +/** + * @param {entity} entity - The entity to remove from the resource map. + */ +m.SharedScript.prototype.removeEntityFromResourceMap = function(entity) +{ + this.changeEntityInResourceMapHelper(entity, -1); +}; + +/** + * @param {entity} ent - The entity to add to the resource map. + */ +m.SharedScript.prototype.changeEntityInResourceMapHelper = function(ent, multiplication = 1) +{ + if (!ent) + return; + let entPos = ent.position(); + if (!entPos) + return; + let resource = ent.resourceSupplyType()?.generic; + if (!resource || !this.resourceMaps[resource]) + return; + let cellSize = this.resourceMaps[resource].cellSize; + let x = Math.floor(entPos[0] / cellSize); + let z = Math.floor(entPos[1] / cellSize); + let grp = Resources.GetResource(resource).aiAnalysisInfluenceGroup; + let strength = multiplication * Math.floor(ent.resourceSupplyMax() / this.normalizationFactor[grp]); + this.resourceMaps[resource].addInfluence(x, z, this.influenceRadius[grp] / cellSize, strength/2, "constant"); + this.resourceMaps[resource].addInfluence(x, z, this.influenceRadius[grp] / cellSize, strength/2); + this.ccResourceMaps[resource].addInfluence(x, z, this.ccInfluenceRadius[grp] / cellSize, strength, "constant"); +}; + return m; }(API3);