diff --git a/binaries/data/mods/public/simulation/ai/common-api/baseAI.js b/binaries/data/mods/public/simulation/ai/common-api/baseAI.js index ff13d58ffd..0f8d857b27 100644 --- a/binaries/data/mods/public/simulation/ai/common-api/baseAI.js +++ b/binaries/data/mods/public/simulation/ai/common-api/baseAI.js @@ -44,21 +44,12 @@ m.BaseAI.prototype.Init = function(state, playerID, sharedAI) this.accessibility = sharedAI.accessibility; this.terrainAnalyzer = sharedAI.terrainAnalyzer; - this.techModifications = sharedAI._techModifications[this.player]; - this.playerData = sharedAI.playersData[this.player]; - this.gameState = sharedAI.gameState[this.player]; this.gameState.ai = this; this.sharedScript = sharedAI; this.timeElapsed = sharedAI.timeElapsed; - this.circularMap = sharedAI.circularMap; - - this.gameType = sharedAI.gameType; - - this.barterPrices = sharedAI.barterPrices; - this.CustomInit(this.gameState, this.sharedScript); }; diff --git a/binaries/data/mods/public/simulation/ai/common-api/entity.js b/binaries/data/mods/public/simulation/ai/common-api/entity.js index ed4754253a..d1ca310bd1 100644 --- a/binaries/data/mods/public/simulation/ai/common-api/entity.js +++ b/binaries/data/mods/public/simulation/ai/common-api/entity.js @@ -16,10 +16,10 @@ m.Template = m.Class({ get: function(string) { var value = this._template; - if (this._auraTemplateModif && this._auraTemplateModif.has(string)) - return this._auraTemplateModif.get(string); - else if (this._techModif && this._techModif.has(string)) - return this._techModif.get(string); + if (this._entityModif && this._entityModif.has(string)) + return this._entityModif.get(string); + else if (this._templateModif && this._templateModif.has(string)) + return this._templateModif.get(string); if (!this._tpCache.has(string)) { @@ -565,11 +565,16 @@ m.Entity = m.Class({ this._templateName = entity.template; this._entity = entity; - this._auraTemplateModif = new Map(); // template modification from auras. this is only for this entity. + this._ai = sharedAI; - if (!sharedAI._techModifications[entity.owner][this._templateName]) - sharedAI._techModifications[entity.owner][this._templateName] = new Map(); - this._techModif = sharedAI._techModifications[entity.owner][this._templateName]; // save a reference to the template tech modifications + // save a reference to the template tech modifications + if (!sharedAI._templatesModifications[entity.owner][this._templateName]) + sharedAI._templatesModifications[entity.owner][this._templateName] = new Map(); + this._templateModif = sharedAI._templatesModifications[entity.owner][this._templateName]; + // save a reference to the entity tech/aura modifications + if (!sharedAI._entitiesModifications.has(entity.id)) + sharedAI._entitiesModifications.set(entity.id, new Map()); + this._entityModif = sharedAI._entitiesModifications.get(entity.id); }, toString: function() { diff --git a/binaries/data/mods/public/simulation/ai/common-api/gamestate.js b/binaries/data/mods/public/simulation/ai/common-api/gamestate.js index 74eb5b7ff7..752b92d915 100644 --- a/binaries/data/mods/public/simulation/ai/common-api/gamestate.js +++ b/binaries/data/mods/public/simulation/ai/common-api/gamestate.js @@ -20,7 +20,6 @@ m.GameState.prototype.init = function(SharedScript, state, player) { this.entities = SharedScript.entities; this.player = player; this.playerData = SharedScript.playersData[this.player]; - this.techModifications = SharedScript._techModifications[this.player]; this.barterPrices = SharedScript.barterPrices; this.gameType = SharedScript.gameType; @@ -61,7 +60,6 @@ m.GameState.prototype.update = function(SharedScript, state) { this._entities = SharedScript._entities; this.entities = SharedScript.entities; this.playerData = SharedScript.playersData[this.player]; - this.techModifications = SharedScript._techModifications[this.player]; this.barterPrices = SharedScript.barterPrices; }; @@ -129,11 +127,11 @@ m.GameState.prototype.getTemplate = function(type) { if (this.techTemplates[type] !== undefined) return new m.Technology(this.techTemplates, type); - + if (!this.templates[type]) return null; - - return new m.Template(this.templates[type], this.techModifications); + + return new m.Template(this.templates[type]); }; m.GameState.prototype.applyCiv = function(str) 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 7f1ab0daf0..9c41fbc1f0 100644 --- a/binaries/data/mods/public/simulation/ai/common-api/shared.js +++ b/binaries/data/mods/public/simulation/ai/common-api/shared.js @@ -18,7 +18,8 @@ m.SharedScript = function(settings) // array of entity collections this._entityCollections = new Map(); - this._techModifications = {}; + this._entitiesModifications = new Map(); // entities modifications + this._templatesModifications = {}; // template modifications // each name is a reference to the actual one. this._entityCollectionsName = new Map(); this._entityCollectionsByDynProp = {}; @@ -38,8 +39,9 @@ m.SharedScript.prototype.Serialize = function() { return { "players": this._players, - "techTp": this._techTemplates, - "techModifications": this._techModifications, + "techTemplates": this._techTemplates, + "templatesModifications": this._templatesModifications, + "entitiesModifications": this._entitiesModifications, "metadata": this._entityMetadata }; }; @@ -49,8 +51,9 @@ m.SharedScript.prototype.Serialize = function() m.SharedScript.prototype.Deserialize = function(data) { this._players = data.players; - this._techTemplates = data.techTp; - this._techModifications = data.techModifications; + this._techTemplates = data.techTemplates; + this._templatesModifications = data.templatesModifications; + this._entitiesModifications = data.entitiesModifications; this._entityMetadata = data.metadata; this._derivedTemplates = {}; @@ -83,10 +86,10 @@ m.SharedScript.prototype.GetTemplate = function(name) { if (this._templates[name]) return this._templates[name]; - + if (this._derivedTemplates[name]) return this._derivedTemplates[name]; - + // If this is a foundation template, construct it automatically if (name.indexOf("foundation|") !== -1) { @@ -112,7 +115,7 @@ m.SharedScript.prototype.GetTemplate = function(name) this._derivedTemplates[name] = resource; return resource; } - + error("Tried to retrieve invalid template '"+name+"'"); return null; }; @@ -123,8 +126,11 @@ m.SharedScript.prototype.GetTemplate = function(name) m.SharedScript.prototype.init = function(state, deserialization) { if (!deserialization) + { + this._entitiesModifications = new Map(); for (let i = 0; i < state.players.length; ++i) - this._techModifications[i] = {}; + this._templatesModifications[i] = {}; + } this.ApplyTemplatesDelta(state); @@ -310,6 +316,7 @@ m.SharedScript.prototype.ApplyEntitiesDelta = function(state) this.entities.removeEnt(entity); this._entities.delete(evt.entity); + this._entitiesModifications.delete(evt.entity) for (let j in this._players) delete this._entityMetadata[this._players[j]][evt.entity]; } @@ -332,9 +339,11 @@ m.SharedScript.prototype.ApplyEntitiesDelta = function(state) if (!this._entities.has(+id)) continue; // dead, presumably. let changes = state.changedEntityTemplateInfo[id]; - let entity = this._entities.get(+id); + if (!this._entitiesModifications.has(+id)) + this._entitiesModifications.set(+id, new Map()); + let modif = this._entitiesModifications.get(+id); for (let change of changes) - entity._auraTemplateModif.set(change.variable, change.value); + modif.set(change.variable, change.value); } Engine.ProfileStop(); }; @@ -349,10 +358,11 @@ m.SharedScript.prototype.ApplyTemplatesDelta = function(state) for (let template in playerDiff) { let changes = playerDiff[template]; - if (!this._techModifications[player][template]) - this._techModifications[player][template] = new Map(); + if (!this._templatesModifications[player][template]) + this._templatesModifications[player][template] = new Map(); + let modif = this._templatesModifications[player][template]; for (let change of changes) - this._techModifications[player][template].set(change.variable, change.value); + modif.set(change.variable, change.value); } } Engine.ProfileStop(); diff --git a/binaries/data/mods/public/simulation/ai/petra/mapModule.js b/binaries/data/mods/public/simulation/ai/petra/mapModule.js index 6c8c614afb..a724e87348 100644 --- a/binaries/data/mods/public/simulation/ai/petra/mapModule.js +++ b/binaries/data/mods/public/simulation/ai/petra/mapModule.js @@ -127,7 +127,7 @@ m.createBorderMap = function(gameState) var border = Math.round(80 / map.cellSize); var passabilityMap = gameState.sharedScript.passabilityMap; var obstructionMask = gameState.getPassabilityClassMask("unrestricted"); - if (gameState.ai.circularMap) + if (gameState.circularMap) { let ic = (width - 1) / 2; let radcut = (ic - border) * (ic - border); diff --git a/binaries/data/mods/public/simulation/components/AIInterface.js b/binaries/data/mods/public/simulation/components/AIInterface.js index 14cbdd0d54..e1826f4dd4 100644 --- a/binaries/data/mods/public/simulation/components/AIInterface.js +++ b/binaries/data/mods/public/simulation/components/AIInterface.js @@ -127,7 +127,9 @@ AIInterface.prototype.GetRepresentation = function() return state; }; -// Intended to be called first, during the map initialization: no caching +/** + * Intended to be called first, during the map initialization: no caching + */ AIInterface.prototype.GetFullRepresentation = function(flushEvents) { var state = this.GetNonEntityRepresentation(); @@ -157,10 +159,11 @@ AIInterface.prototype.ChangedEntity = function(ent) this.changedEntities[ent] = 1; }; -// AIProxy sets up a load of event handlers to capture interesting things going on -// in the world, which we will report to AI. Handle those, and add a few more handlers -// for events that AIProxy won't capture. - +/** + * AIProxy sets up a load of event handlers to capture interesting things going on + * in the world, which we will report to AI. Handle those, and add a few more handlers + * for events that AIProxy won't capture. + */ AIInterface.prototype.PushEvent = function(type, msg) { if (this.events[type] === undefined) @@ -195,11 +198,12 @@ AIInterface.prototype.OnTerritoriesChanged = function(msg) this.events.TerritoriesChanged.push(msg); }; -// When a new technology is researched, check which templates it affects, -// and send the updated values to the AI. -// this relies on the fact that any "value" in a technology can only ever change -// one template value, and that the naming is the same (with / in place of .) -// it's not incredibly fast but it's not incredibly slow. +/** + * When a new technology is researched, check which templates it affects, + * and send the updated values to the AI. + * this relies on the fact that any "value" in a technology can only ever change + * one template value, and that the naming is the same (with / in place of .) + */ AIInterface.prototype.OnTemplateModification = function(msg) { let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); @@ -223,7 +227,8 @@ AIInterface.prototype.OnTemplateModification = function(msg) for (let name of this.templates) { let template = cmpTemplateManager.GetTemplateWithoutValidation(name); - + if (!template || !template[msg.component]) + continue; for (let valName of msg.valueNames) { // let's get the base template value. @@ -243,9 +248,9 @@ AIInterface.prototype.OnTemplateModification = function(msg) let oldValue = +item; let newValue = ApplyValueModificationsToTemplate(valName, oldValue, msg.player, template); // Apply the same roundings as in the components - if (valName === "Player/MaxPopulation" || valName === "Cost/Population" || valName === "Cost/PopulationBonus") + if (valName === "Player/MaxPopulation" || valName === "Cost/Population" || + valName === "Cost/PopulationBonus") newValue = Math.round(newValue); - // TODO in some cases, we can have two opposite changes which bring us to the old value, // and we should keep it. But how to distinguish it ? if(newValue == oldValue) @@ -253,9 +258,9 @@ AIInterface.prototype.OnTemplateModification = function(msg) if (!this.changedTemplateInfo[msg.player]) this.changedTemplateInfo[msg.player] = {}; if (!this.changedTemplateInfo[msg.player][name]) - this.changedTemplateInfo[msg.player][name] = [{"variable": valName, "value": newValue}]; + this.changedTemplateInfo[msg.player][name] = [{ "variable": valName, "value": newValue }]; else - this.changedTemplateInfo[msg.player][name].push({"variable": valName, "value": newValue}); + this.changedTemplateInfo[msg.player][name].push({ "variable": valName, "value": newValue }); } } }; @@ -270,6 +275,8 @@ AIInterface.prototype.OnGlobalValueModification = function(msg) if (!templateName || !templateName.length) continue; let template = cmpTemplateManager.GetTemplateWithoutValidation(templateName); + if (!template || !template[msg.component]) + continue; for (let valName of msg.valueNames) { // let's get the base template value. @@ -289,16 +296,17 @@ AIInterface.prototype.OnGlobalValueModification = function(msg) let oldValue = +item; let newValue = ApplyValueModificationsToEntity(valName, oldValue, ent); // Apply the same roundings as in the components - if (valName === "Player/MaxPopulation" || valName === "Cost/Population" || valName === "Cost/PopulationBonus") + if (valName === "Player/MaxPopulation" || valName === "Cost/Population" || + valName === "Cost/PopulationBonus") newValue = Math.round(newValue); // TODO in some cases, we can have two opposite changes which bring us to the old value, // and we should keep it. But how to distinguish it ? if (newValue == oldValue) continue; if (!this.changedEntityTemplateInfo[ent]) - this.changedEntityTemplateInfo[ent] = [{"variable": valName, "value": newValue}]; + this.changedEntityTemplateInfo[ent] = [{ "variable": valName, "value": newValue }]; else - this.changedEntityTemplateInfo[ent].push({"variable": valName, "value": newValue}); + this.changedEntityTemplateInfo[ent].push({ "variable": valName, "value": newValue }); } } };