Index: ps/trunk/binaries/data/mods/public/globalscripts/ModificationTemplates.js =================================================================== --- ps/trunk/binaries/data/mods/public/globalscripts/ModificationTemplates.js +++ ps/trunk/binaries/data/mods/public/globalscripts/ModificationTemplates.js @@ -0,0 +1,45 @@ +/** + * @file This provides a cache for Aura and Technology templates. + * They may not be serialized, otherwise rejoined clients would refer + * to different objects, triggering an Out-of-sync error. + */ +function ModificationTemplates(path) +{ + let suffix = ".json"; + + this.names = deepfreeze(listFiles(path, suffix, true)); + + this.templates = {}; + + for (let name of this.names) + this.templates[name] = Engine.ReadJSONFile(path + name + suffix); + + deepfreeze(this.templates); +} + +ModificationTemplates.prototype.GetNames = function() +{ + return this.names; +}; + +ModificationTemplates.prototype.Has = function(name) +{ + return this.names.indexOf(name) != -1; +}; + +ModificationTemplates.prototype.Get = function(name) +{ + return this.templates[name]; +}; + +ModificationTemplates.prototype.GetAll = function() +{ + return this.templates; +}; + + +function LoadModificationTemplates() +{ + global.AuraTemplates = new ModificationTemplates("simulation/data/auras/"); + global.TechnologyTemplates = new ModificationTemplates("simulation/data/technologies/"); +} Index: ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js @@ -347,7 +347,7 @@ if (tech.indexOf("{civ}") == -1) continue; let civTech = tech.replace("{civ}", civ); - techs[i] = gameState.techTemplates[civTech] ? + techs[i] = TechnologyTemplates.Has(civTech) ? civTech : tech.replace("{civ}", "generic"); } return techs; Index: ps/trunk/binaries/data/mods/public/simulation/ai/common-api/gamestate.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/common-api/gamestate.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/common-api/gamestate.js @@ -9,13 +9,13 @@ this.ai = null; // must be updated by the AIs. }; -m.GameState.prototype.init = function(SharedScript, state, player) { +m.GameState.prototype.init = function(SharedScript, state, player) +{ this.sharedScript = SharedScript; this.EntCollecNames = SharedScript._entityCollectionsName; this.timeElapsed = SharedScript.timeElapsed; this.circularMap = SharedScript.circularMap; this.templates = SharedScript._templates; - this.techTemplates = SharedScript._techTemplates; this.entities = SharedScript.entities; this.player = player; this.playerData = SharedScript.playersData[this.player]; @@ -150,8 +150,8 @@ m.GameState.prototype.getTemplate = function(type) { - if (this.techTemplates[type] !== undefined) - return new m.Technology(this.techTemplates, type); + if (TechnologyTemplates.Has(type)) + return new m.Technology(type); if (this.templates[type] === undefined) this.sharedScript.GetTemplate(type); Index: ps/trunk/binaries/data/mods/public/simulation/ai/common-api/shared.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/common-api/shared.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/common-api/shared.js @@ -9,7 +9,6 @@ this._players = Object.keys(settings.players).map(key => settings.players[key]); // TODO SM55 Object.values(settings.players) this._templates = settings.templates; - this._techTemplates = settings.techTemplates; this._entityMetadata = {}; for (let player of this._players) @@ -30,7 +29,6 @@ { return { "players": this._players, - "techTemplates": this._techTemplates, "templatesModifications": this._templatesModifications, "entitiesModifications": this._entitiesModifications, "metadata": this._entityMetadata @@ -44,7 +42,6 @@ m.SharedScript.prototype.Deserialize = function(data) { this._players = data.players; - this._techTemplates = data.techTemplates; this._templatesModifications = data.templatesModifications; this._entitiesModifications = data.entitiesModifications; this._entityMetadata = data.metadata; Index: ps/trunk/binaries/data/mods/public/simulation/ai/common-api/technology.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/common-api/technology.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/common-api/technology.js @@ -1,26 +1,26 @@ +LoadModificationTemplates(); + var API3 = function(m) { /** Wrapper around a technology template */ -m.Technology = function(allTemplates, templateName) +m.Technology = function(templateName) { this._templateName = templateName; - let template = allTemplates[templateName]; + let template = TechnologyTemplates.Get(templateName); // check if this is one of two paired technologies. this._isPair = template.pair !== undefined; if (this._isPair) { - if (allTemplates[template.pair].top == templateName) - this._pairedWith = allTemplates[template.pair].bottom; - else - this._pairedWith = allTemplates[template.pair].top; + let pairTech = TechnologyTemplates.Get(template.pair); + this._pairedWith = pairTech.top == templateName ? pairTech.bottom : pairTech.top; } + // check if it only defines a pair: this._definesPair = template.top !== undefined; this._template = template; - this._techTemplates = allTemplates; }; /** returns generic, or specific if civ provided. */ @@ -45,10 +45,10 @@ if (!this._definesPair) return undefined; - let techOne = new m.Technology(this._techTemplates, this._template.top); - let techTwo = new m.Technology(this._techTemplates, this._template.bottom); - - return [techOne,techTwo]; + return [ + new m.Technology(this._template.top), + new m.Technology(this._template.bottom) + ]; }; m.Technology.prototype.pair = function() Index: ps/trunk/binaries/data/mods/public/simulation/components/Auras.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Auras.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Auras.js @@ -8,14 +8,11 @@ Auras.prototype.Init = function() { - let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager); - this.auras = {}; this.affectedPlayers = {}; + for (let name of this.GetAuraNames()) - { this.affectedPlayers[name] = []; - this.auras[name] = cmpDataTemplateManager.GetAuraTemplate(name); - } + // In case of autogarrisoning, this component can be called before ownership is set. // So it needs to be completely initialised from the start. this.Clean(); @@ -24,7 +21,7 @@ // We can modify identifier if we want stackable auras in some case. Auras.prototype.GetModifierIdentifier = function(name) { - if (this.auras[name].stackable) + if (AuraTemplates.Get(name).stackable) return name + this.entity; return name; }; @@ -34,7 +31,7 @@ var ret = {}; for (let auraID of this.GetAuraNames()) { - let aura = this.auras[auraID]; + let aura = AuraTemplates.Get(auraID); ret[auraID] = { "name": aura.auraName, "description": aura.auraDescription || null, @@ -51,7 +48,7 @@ Auras.prototype.GetOverlayIcon = function(name) { - return this.auras[name].overlayIcon || ""; + return AuraTemplates.Get(name).overlayIcon || ""; }; Auras.prototype.GetAffectedEntities = function(name) @@ -62,18 +59,18 @@ Auras.prototype.GetRange = function(name) { if (this.IsRangeAura(name)) - return +this.auras[name].radius; + return +AuraTemplates.Get(name).radius; return undefined; }; Auras.prototype.GetClasses = function(name) { - return this.auras[name].affects; + return AuraTemplates.Get(name).affects; }; Auras.prototype.GetModifications = function(name) { - return this.auras[name].modifications; + return AuraTemplates.Get(name).modifications; }; Auras.prototype.GetAffectedPlayers = function(name) @@ -90,13 +87,15 @@ if (!this.IsRangeAura(name) || !this[name].isApplied) continue; + let rangeOverlay = AuraTemplates.Get(name).rangeOverlay; + rangeOverlays.push( - this.auras[name].rangeOverlay ? + rangeOverlay ? { "radius": this.GetRange(name), - "texture": this.auras[name].rangeOverlay.lineTexture, - "textureMask": this.auras[name].rangeOverlay.lineTextureMask, - "thickness": this.auras[name].rangeOverlay.lineThickness + "texture": rangeOverlay.lineTexture, + "textureMask": rangeOverlay.lineTextureMask, + "thickness": rangeOverlay.lineThickness } : // Specify default in order not to specify it in about 40 auras { @@ -112,7 +111,7 @@ Auras.prototype.CalculateAffectedPlayers = function(name) { - var affectedPlayers = this.auras[name].affectedPlayers || ["Player"]; + var affectedPlayers = AuraTemplates.Get(name).affectedPlayers || ["Player"]; this.affectedPlayers[name] = []; var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player); @@ -137,12 +136,14 @@ Auras.prototype.CanApply = function(name) { - if (!this.auras[name].requiredTechnology) + if (!AuraTemplates.Get(name).requiredTechnology) return true; + let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); if (!cmpTechnologyManager) return false; - return cmpTechnologyManager.IsTechnologyResearched(this.auras[name].requiredTechnology); + + return cmpTechnologyManager.IsTechnologyResearched(AuraTemplates.Get(name).requiredTechnology); }; Auras.prototype.HasFormationAura = function() @@ -162,7 +163,7 @@ Auras.prototype.GetType = function(name) { - return this.auras[name].type; + return AuraTemplates.Get(name).type; }; Auras.prototype.IsFormationAura = function(name) @@ -470,7 +471,7 @@ return; for (let name of this.GetAuraNames()) { - let requiredTech = this.auras[name].requiredTechnology; + let requiredTech = AuraTemplates.Get(name).requiredTechnology; if (requiredTech && requiredTech == msg.tech) { this.Clean(); Index: ps/trunk/binaries/data/mods/public/simulation/components/DataTemplateManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/DataTemplateManager.js +++ ps/trunk/binaries/data/mods/public/simulation/components/DataTemplateManager.js @@ -1,71 +0,0 @@ -/** - * System component which loads the technology and the aura data files - */ -function DataTemplateManager() {} - -DataTemplateManager.prototype.Schema = - ""; - -DataTemplateManager.prototype.Init = function() -{ - this.technologiesPath = "simulation/data/technologies/"; - this.aurasPath = "simulation/data/auras/"; - - this.allTechs = {}; - this.allAuras = {}; - - for (let techName of this.ListAllTechs()) - this.GetTechnologyTemplate(techName); - - for (let auraName of this.ListAllAuras()) - this.GetAuraTemplate(auraName); - - deepfreeze(this.allTechs); - deepfreeze(this.allAuras); -}; - -DataTemplateManager.prototype.GetTechnologyTemplate = function(template) -{ - if (!this.allTechs[template]) - { - this.allTechs[template] = Engine.ReadJSONFile(this.technologiesPath + template + ".json"); - if (!this.allTechs[template]) - error("Failed to load technology \"" + template + "\""); - } - - return this.allTechs[template]; -}; - -DataTemplateManager.prototype.GetAuraTemplate = function(template) -{ - if (!this.allAuras[template]) - { - this.allAuras[template] = Engine.ReadJSONFile(this.aurasPath + template + ".json"); - if (!this.allAuras[template]) - error("Failed to load aura \"" + template + "\""); - } - - return this.allAuras[template]; -}; - -DataTemplateManager.prototype.ListAllTechs = function() -{ - return listFiles(this.technologiesPath, ".json", true); -}; - -DataTemplateManager.prototype.ListAllAuras = function() -{ - return listFiles(this.aurasPath, ".json", true); -}; - -DataTemplateManager.prototype.GetAllTechs = function() -{ - return this.allTechs; -}; - -DataTemplateManager.prototype.TechnologyExists = function(template) -{ - return !!this.allTechs[template]; -}; - -Engine.RegisterSystemComponentType(IID_DataTemplateManager, "DataTemplateManager", DataTemplateManager); Index: ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js +++ ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js @@ -643,26 +643,17 @@ if (!template.Auras) return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes); - // Add aura name and description loaded from JSON file let auraNames = template.Auras._string.split(/\s+/); - let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager); + for (let name of auraNames) - aurasTemplate[name] = cmpDataTemplateManager.GetAuraTemplate(name); + aurasTemplate[name] = AuraTemplates.Get(name); + return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes); }; GuiInterface.prototype.GetTechnologyData = function(player, data) { - let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager); - let template = cmpDataTemplateManager.GetTechnologyTemplate(data.name); - - if (!template) - { - warn("Tried to get data for invalid technology: " + data.name); - return null; - } - - return GetTechnologyDataHelper(template, data.civ, Resources); + return GetTechnologyDataHelper(TechnologyTemplates.Get(data.name), data.civ, Resources); }; GuiInterface.prototype.IsTechnologyResearched = function(player, data) Index: ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js +++ ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js @@ -163,22 +163,20 @@ var techs = string.split(/\s+/); // Replace the civ specific technologies - let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager); for (let i = 0; i < techs.length; ++i) { let tech = techs[i]; if (tech.indexOf("{civ}") == -1) continue; let civTech = tech.replace("{civ}", cmpPlayer.GetCiv()); - techs[i] = cmpDataTemplateManager.TechnologyExists(civTech) ? - civTech : tech.replace("{civ}", "generic"); + techs[i] = TechnologyTemplates.Has(civTech) ? civTech : tech.replace("{civ}", "generic"); } // Remove any technologies that can't be researched by this civ - techs = techs.filter(tech => { - let reqs = DeriveTechnologyRequirements(cmpTechnologyManager.GetTechnologyTemplate(tech), cmpPlayer.GetCiv()); - return cmpTechnologyManager.CheckTechnologyRequirements(reqs, true); - }); + techs = techs.filter(tech => + cmpTechnologyManager.CheckTechnologyRequirements( + DeriveTechnologyRequirements(TechnologyTemplates.Get(tech), cmpPlayer.GetCiv()), + true)); var techList = []; var superseded = {}; // Stores the tech which supersedes the key @@ -192,7 +190,8 @@ var tech = techs[i]; if (disabledTechnologies && disabledTechnologies[tech]) continue; - var template = cmpTechnologyManager.GetTechnologyTemplate(tech); + + let template = TechnologyTemplates.Get(tech); if (!template.supersedes || techs.indexOf(template.supersedes) === -1) techList.push(tech); else @@ -223,7 +222,7 @@ continue; } - var template = cmpTechnologyManager.GetTechnologyTemplate(tech); + let template = TechnologyTemplates.Get(tech); if (template.top) ret[i] = {"pair": true, "top": template.top, "bottom": template.bottom}; else @@ -248,7 +247,7 @@ var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); - var template = cmpTechnologyManager.GetTechnologyTemplate(tech); + let template = TechnologyTemplates.Get(tech); if (template.top) { return (cmpTechnologyManager.IsTechnologyResearched(template.top) || cmpTechnologyManager.IsInProgress(template.top) @@ -346,10 +345,7 @@ } else if (type == "technology") { - // Load the technology template - var cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager); - var template = cmpDataTemplateManager.GetTechnologyTemplate(templateName); - if (!template) + if (!TechnologyTemplates.Has(templateName)) return; if (!this.GetTechnologiesList().some(tech => @@ -362,6 +358,7 @@ return; } + let template = TechnologyTemplates.Get(templateName); let techCostMultiplier = this.GetTechCostMultiplier(); let time = techCostMultiplier.time * template.researchTime * cmpPlayer.GetCheatTimeMultiplier(); @@ -811,7 +808,7 @@ var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); cmpTechnologyManager.ResearchTechnology(item.technologyTemplate); - var template = cmpTechnologyManager.GetTechnologyTemplate(item.technologyTemplate); + let template = TechnologyTemplates.Get(item.technologyTemplate); if (template && template.soundComplete) { Index: ps/trunk/binaries/data/mods/public/simulation/components/TechnologyManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/TechnologyManager.js +++ ps/trunk/binaries/data/mods/public/simulation/components/TechnologyManager.js @@ -46,8 +46,8 @@ // Some technologies are automatically researched when their conditions are met. They have no cost and are // researched instantly. This allows civ bonuses and more complicated technologies. this.unresearchedAutoResearchTechs = new Set(); - var allTechs = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager).GetAllTechs(); - for (var key in allTechs) + let allTechs = TechnologyTemplates.GetAll(); + for (let key in allTechs) if (allTechs[key].autoResearch || allTechs[key].top) this.unresearchedAutoResearchTechs.add(key); }; @@ -61,10 +61,9 @@ // This function checks if the requirements of any autoresearch techs are met and if they are it researches them TechnologyManager.prototype.UpdateAutoResearch = function() { - var cmpDataTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager); for (let key of this.unresearchedAutoResearchTechs) { - var tech = cmpDataTempMan.GetTechnologyTemplate(key); + let tech = TechnologyTemplates.Get(key); if ((tech.autoResearch && this.CanResearch(key)) || (tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom)))) { @@ -75,11 +74,6 @@ } }; -TechnologyManager.prototype.GetTechnologyTemplate = function(tech) -{ - return Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager).GetTechnologyTemplate(tech); -}; - // Checks an entity template to see if its technology requirements have been met TechnologyManager.prototype.CanProduce = function (templateName) { @@ -110,7 +104,7 @@ // Checks the requirements for a technology to see if it can be researched at the current time TechnologyManager.prototype.CanResearch = function(tech) { - let template = this.GetTechnologyTemplate(tech); + let template = TechnologyTemplates.Get(tech); if (!template) { @@ -270,17 +264,10 @@ { this.StoppedResearch(tech, false); - var template = this.GetTechnologyTemplate(tech); - - if (!template) - { - error("Tried to research invalid technology: " + uneval(tech)); - return; - } - var modifiedComponents = {}; this.researchedTechs.add(tech); // store the modifications in an easy to access structure + let template = TechnologyTemplates.Get(tech); if (template.modifications) { let derivedModifiers = DeriveModificationsFromTech(template); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Auras.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Auras.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Auras.js @@ -7,6 +7,22 @@ Engine.LoadComponentScript("Auras.js"); Engine.LoadComponentScript("AuraManager.js"); +global.AuraTemplates = { + "Get": name => { + let template = { + "type": name, + "affectedPlayers": ["Ally"], + "affects": ["CorrectClass"], + "modifications": [{ "value": "Component/Value", "add": 10 }], + "auraName": "name", + "auraDescription": "description" + }; + if (name == "range") + template.radius = auraRange; + return template; + } +}; + let playerID = [0, 1, 2]; let playerEnt = [10, 11, 12]; let playerState = "active"; @@ -34,22 +50,6 @@ "GetEntitiesByPlayer": id => [30, 31, 32] }); - AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, { - "GetAuraTemplate": (name) => { - let template = { - "type": name, - "affectedPlayers": ["Ally"], - "affects": ["CorrectClass"], - "modifications": [{ "value": "Component/Value", "add": 10 }], - "auraName": "name", - "auraDescription": "description" - }; - if (name == "range") - template.radius = auraRange; - return template; - } - }); - AddMock(playerEnt[1], IID_Player, { "IsAlly": id => id == playerID[1] || id == playerID[2], "IsEnemy": id => id != playerID[1] || id != playerID[2], Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js @@ -7,6 +7,11 @@ Engine.LoadComponentScript("interfaces/ProductionQueue.js"); Engine.LoadComponentScript("ProductionQueue.js"); +global.TechnologyTemplates = { + "Has": name => name == "phase_town_athen" || name == "phase_city_athen", + "Get": () => ({}) +}; + const productionQueueId = 6; const playerId = 1; const playerEntityID = 2; @@ -32,10 +37,6 @@ "GetPlayerByID": id => playerEntityID }); -AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, { - "TechnologyExists": name => name == "phase_town_athen" || name == "phase_city_athen" -}); - AddMock(playerEntityID, IID_Player, { "GetCiv": () => "iber", "GetDisabledTechnologies": () => ({}), @@ -45,7 +46,6 @@ AddMock(playerEntityID, IID_TechnologyManager, { "CheckTechnologyRequirements": () => true, - "GetTechnologyTemplate": tech => tech, "IsInProgress": () => false, "IsTechnologyResearched": () => false }); @@ -125,7 +125,6 @@ AddMock(playerEntityID, IID_TechnologyManager, { "CheckTechnologyRequirements": () => true, - "GetTechnologyTemplate": tech => tech, "IsInProgress": () => false, "IsTechnologyResearched": tech => tech == "phase_town_athen" }); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_TechnologyManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_TechnologyManager.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_TechnologyManager.js @@ -1,9 +1,9 @@ Engine.LoadComponentScript("interfaces/TechnologyManager.js"); Engine.LoadComponentScript("TechnologyManager.js"); - AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, { - "GetAllTechs": () => {} - }); +global.TechnologyTemplates = { + "GetAll": () => [] +}; let cmpTechnologyManager = ConstructComponent(SYSTEM_ENTITY, "TechnologyManager", {}); Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Cheat.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/Cheat.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/Cheat.js @@ -88,9 +88,7 @@ else return; - // check if specialised tech exists (like phase_town_athen) - var cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager); - if (cmpDataTemplateManager.ListAllTechs().indexOf(parameter + "_" + cmpPlayer.civ) > -1) + if (TechnologyTemplates.Has(parameter + "_" + cmpPlayer.civ)) parameter += "_" + cmpPlayer.civ; else parameter += "_generic"; @@ -140,13 +138,8 @@ } } - // check, if technology exists - var template = cmpTechnologyManager.GetTechnologyTemplate(techname); - if (!template) - return; - - // check, if technology is already researched - if (!cmpTechnologyManager.IsTechnologyResearched(techname)) + if (TechnologyTemplates.Has(techname) && + !cmpTechnologyManager.IsTechnologyResearched(techname)) cmpTechnologyManager.ResearchTechnology(techname); return; case "metaCheat": Index: ps/trunk/binaries/data/mods/public/simulation/helpers/ModificationTemplates.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/ModificationTemplates.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/ModificationTemplates.js @@ -0,0 +1,2 @@ +// Loads the Aura and Technology JSON files +LoadModificationTemplates(); Index: ps/trunk/source/graphics/MapGenerator.cpp =================================================================== --- ps/trunk/source/graphics/MapGenerator.cpp +++ ps/trunk/source/graphics/MapGenerator.cpp @@ -97,7 +97,6 @@ // Replace RNG with a seeded deterministic function m_ScriptInterface->ReplaceNondeterministicRNG(m_MapGenRNG); - m_ScriptInterface->LoadGlobalScripts(); // Functions for RMS JSI_VFS::RegisterScriptFunctions_Maps(*m_ScriptInterface); @@ -110,6 +109,9 @@ m_ScriptInterface->RegisterFunction, std::string, bool, CMapGeneratorWorker::FindActorTemplates>("FindActorTemplates"); m_ScriptInterface->RegisterFunction("GetTerrainTileSize"); + // Globalscripts may use VFS script functions + m_ScriptInterface->LoadGlobalScripts(); + // Parse settings JS::RootedValue settingsVal(cx); if (!m_ScriptInterface->ParseJSON(m_Settings, &settingsVal) && settingsVal.isUndefined()) Index: ps/trunk/source/simulation2/TypeList.h =================================================================== --- ps/trunk/source/simulation2/TypeList.h +++ ps/trunk/source/simulation2/TypeList.h @@ -165,9 +165,6 @@ INTERFACE(ValueModificationManager) COMPONENT(ValueModificationManagerScripted) -INTERFACE(DataTemplateManager) -COMPONENT(DataTemplateManagerScripted) - INTERFACE(Terrain) COMPONENT(Terrain) Index: ps/trunk/source/simulation2/components/CCmpAIManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpAIManager.cpp +++ ps/trunk/source/simulation2/components/CCmpAIManager.cpp @@ -37,7 +37,6 @@ #include "simulation2/components/ICmpObstructionManager.h" #include "simulation2/components/ICmpRangeManager.h" #include "simulation2/components/ICmpTemplateManager.h" -#include "simulation2/components/ICmpDataTemplateManager.h" #include "simulation2/components/ICmpTerritoryManager.h" #include "simulation2/helpers/LongPathfinder.h" #include "simulation2/serialization/DebugSerializer.h" @@ -216,14 +215,12 @@ m_HasSharedComponent(false), m_SerializablePrototypes(new ObjectIdCache(g_ScriptRuntime)), m_EntityTemplates(g_ScriptRuntime->m_rt), - m_TechTemplates(g_ScriptRuntime->m_rt), m_SharedAIObj(g_ScriptRuntime->m_rt), m_PassabilityMapVal(g_ScriptRuntime->m_rt), m_TerritoryMapVal(g_ScriptRuntime->m_rt) { m_ScriptInterface->ReplaceNondeterministicRNG(m_RNG); - m_ScriptInterface->LoadGlobalScripts(); m_ScriptInterface->SetCallbackData(static_cast (this)); @@ -240,6 +237,9 @@ m_ScriptInterface->RegisterFunction("GetTemplate"); JSI_VFS::RegisterScriptFunctions_Simulation(*(m_ScriptInterface.get())); + + // Globalscripts may use VFS script functions + m_ScriptInterface->LoadGlobalScripts(); } ~CAIWorker() @@ -400,7 +400,7 @@ m_RNG.seed(seed); } - bool TryLoadSharedComponent(bool hasTechs) + bool TryLoadSharedComponent() { JSContext* cx = m_ScriptInterface->GetContext(); JSAutoRequest rq(cx); @@ -455,18 +455,6 @@ ENSURE(m_HasLoadedEntityTemplates); m_ScriptInterface->SetProperty(settings, "templates", m_EntityTemplates, false); - if (hasTechs) - { - m_ScriptInterface->SetProperty(settings, "techTemplates", m_TechTemplates, false); - } - else - { - // won't get the tech templates directly. - JS::RootedValue fakeTech(cx); - m_ScriptInterface->Eval("({})", &fakeTech); - m_ScriptInterface->SetProperty(settings, "techTemplates", fakeTech, false); - } - JS::AutoValueVector argv(cx); argv.append(settings); m_ScriptInterface->CallConstructor(ctor, argv, &m_SharedAIObj); @@ -627,11 +615,6 @@ } } - void RegisterTechTemplates(const shared_ptr& techTemplates) - { - m_ScriptInterface->ReadStructuredClone(techTemplates, &m_TechTemplates); - } - void LoadEntityTemplates(const std::vector >& templates) { JSContext* cx = m_ScriptInterface->GetContext(); @@ -754,8 +737,7 @@ deserializer.Bool("useSharedScript", m_HasSharedComponent); if (m_HasSharedComponent) { - TryLoadSharedComponent(false); - + TryLoadSharedComponent(); JS::RootedValue sharedData(cx); deserializer.ScriptVal("sharedData", &sharedData); if (!m_ScriptInterface->CallFunctionVoid(m_SharedAIObj, "Deserialize", sharedData)) @@ -922,7 +904,6 @@ JS::PersistentRootedValue m_EntityTemplates; bool m_HasLoadedEntityTemplates; - JS::PersistentRootedValue m_TechTemplates; std::map > m_PlayerMetadata; std::vector > m_Players; // use shared_ptr just to avoid copying @@ -1026,19 +1007,7 @@ virtual void TryLoadSharedComponent() { - const ScriptInterface& scriptInterface = GetSimContext().GetScriptInterface(); - JSContext* cx = scriptInterface.GetContext(); - JSAutoRequest rq(cx); - - // load the technology templates - CmpPtr cmpDataTemplateManager(GetSystemEntity()); - ENSURE(cmpDataTemplateManager); - - JS::RootedValue techTemplates(cx); - cmpDataTemplateManager->GetAllTechs(&techTemplates); - m_Worker.RegisterTechTemplates(scriptInterface.WriteStructuredClone(techTemplates)); - - m_Worker.TryLoadSharedComponent(true); + m_Worker.TryLoadSharedComponent(); } virtual void RunGamestateInit() Index: ps/trunk/source/simulation2/components/ICmpDataTemplateManager.h =================================================================== --- ps/trunk/source/simulation2/components/ICmpDataTemplateManager.h +++ ps/trunk/source/simulation2/components/ICmpDataTemplateManager.h @@ -1,38 +0,0 @@ -/* Copyright (C) 2012 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#ifndef INCLUDED_ICMPDATATEMPLATEMANAGER -#define INCLUDED_ICMPDATATEMPLATEMANAGER - -#include "simulation2/system/Interface.h" - -#include "maths/Fixed.h" - -/** - * Data template manager interface. - * (This interface only includes the functions needed by native code for accessing - * json template data, the associated logic is handled in scripts) - */ -class ICmpDataTemplateManager : public IComponent -{ -public: - virtual void GetAllTechs(JS::MutableHandleValue ret) = 0; - - DECLARE_INTERFACE_TYPE(DataTemplateManager) -}; - -#endif // INCLUDED_ICMPDATATEMPLATEMANAGER Index: ps/trunk/source/simulation2/components/ICmpDataTemplateManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/ICmpDataTemplateManager.cpp +++ ps/trunk/source/simulation2/components/ICmpDataTemplateManager.cpp @@ -1,39 +0,0 @@ -/* Copyright (C) 2017 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" - -#include "ICmpDataTemplateManager.h" - -#include "simulation2/system/InterfaceScripted.h" -#include "simulation2/scripting/ScriptComponent.h" - -BEGIN_INTERFACE_WRAPPER(DataTemplateManager) -END_INTERFACE_WRAPPER(DataTemplateManager) - -class CCmpDataTemplateManagerScripted : public ICmpDataTemplateManager -{ -public: - DEFAULT_SCRIPT_WRAPPER(DataTemplateManagerScripted) - - virtual void GetAllTechs(JS::MutableHandleValue ret) - { - m_Script.CallRef("GetAllTechs", ret); - } -}; - -REGISTER_COMPONENT_SCRIPT_WRAPPER(DataTemplateManagerScripted) Index: ps/trunk/source/simulation2/system/ComponentManager.cpp =================================================================== --- ps/trunk/source/simulation2/system/ComponentManager.cpp +++ ps/trunk/source/simulation2/system/ComponentManager.cpp @@ -63,7 +63,6 @@ m_ScriptInterface.SetCallbackData(static_cast (this)); m_ScriptInterface.ReplaceNondeterministicRNG(m_RNG); - m_ScriptInterface.LoadGlobalScripts(); // For component script tests, the test system sets up its own scripted implementation of // these functions, so we skip registering them here in those cases @@ -87,6 +86,9 @@ m_ScriptInterface.RegisterFunction ("FlushDestroyedEntities"); } + // Globalscripts may use VFS script functions + m_ScriptInterface.LoadGlobalScripts(); + // Define MT_*, IID_* as script globals, and store their names #define MESSAGE(name) m_ScriptInterface.SetGlobal("MT_" #name, (int)MT_##name); #define INTERFACE(name) \