Index: binaries/data/mods/public/globalscripts/Technologies.js =================================================================== --- binaries/data/mods/public/globalscripts/Technologies.js +++ binaries/data/mods/public/globalscripts/Technologies.js @@ -44,6 +44,49 @@ } /** + * Derives modifications (to be applied to entities) from a given technology + * + * @param techTemplate The technology template to derive the modifications from. + * @return Object containing the relevant modifications. + */ +function DeriveModificationsFromTech(techTemplate) +{ + if (!techTemplate.modifications) + return {}; + + let techMods = {}; + let techAffects = []; + if (techTemplate.affects && techTemplate.affects.length) + for (let affected of techTemplate.affects) + techAffects.push(affected.split(/\s+/)); + else + techAffects.push([]); + + for (let mod of techTemplate.modifications) + { + let affects = techAffects.slice(); + if (mod.affects) + { + let specAffects = mod.affects.split(/\s+/); + for (let a in affects) + affects[a] = affects[a].concat(specAffects); + } + + let newModifier = { + "affects": affects + }; + for (let idx in mod) + if (idx !== "value" && idx !== "affects") + newModifier[idx] = mod[idx]; + + if (!techMods[mod.value]) + techMods[mod.value] = []; + techMods[mod.value].push(newModifier); + } + return techMods; +} + +/** * Returns whether the given modification applies to the entity containing the given class list */ function DoesModificationApply(modification, classes) Index: binaries/data/mods/public/globalscripts/Templates.js =================================================================== --- binaries/data/mods/public/globalscripts/Templates.js +++ binaries/data/mods/public/globalscripts/Templates.js @@ -87,10 +87,13 @@ current_value = current_value[property] || 0; current_value = +current_value; - if (!player) - return current_value; + if (player) + return ApplyValueModificationsToTemplate(tech_type, current_value, player, template); - return ApplyValueModificationsToTemplate(tech_type, current_value, player, template); + if (typeof g_CurrentModifiers !== "undefined") + return GetTechModifiedProperty(g_CurrentModifiers, GetIdentityClasses(template.Identity), tech_type, current_value); + + return current_value; }; let ret = {}; @@ -299,7 +302,7 @@ "generic": template.Identity.GenericName }; ret.icon = template.Identity.Icon; - ret.tooltip = template.Identity.Tooltip; + ret.tooltip = template.Identity.Tooltip; ret.requiredTechnology = template.Identity.RequiredTechnology; ret.visibleIdentityClasses = GetVisibleIdentityClasses(template.Identity); } @@ -345,26 +348,39 @@ } /** - * Get information about a technology template. + * Get basic information about a technology template. * @param template A valid template as obtained by loading the tech JSON file. - * @param civ Civilization for which the specific name should be returned. - * @param resources An instance of the Resources prototype. */ -function GetTechnologyDataHelper(template, civ, resources) +function GetTechnologyBasicDataHelper(template, civ) { let ret = {}; - // Get specific name for this civ or else the generic specific name - let specific; - if (template.specificName) - specific = template.specificName[civ] || template.specificName.generic; - ret.name = { - "specific": specific, "generic": template.genericName, }; - ret.icon = template.icon ? "technologies/" + template.icon : null; + if (template.icon) + ret.icon = "technologies/" + template.icon; + else + ret.icon = null; + + ret.description = template.description; + ret.reqs = DeriveTechnologyRequirements(template, civ); + + return ret; +} + +/** + * Get information about a technology template. + * @param template A valid template as obtained by loading the tech JSON file. + * @param civ Civilization for which the specific name should be returned. + */ +function GetTechnologyDataHelper(template, civ, resources) +{ + let ret = GetTechnologyBasicDataHelper(template, civ); + + if (template.specificName) + ret.name.specific = template.specificName[civ] || template.specificName.generic; ret.cost = { "time": template.researchTime ? +template.researchTime : 0 }; for (let type of resources.GetCodes()) @@ -373,10 +389,6 @@ ret.tooltip = template.tooltip; ret.requirementsTooltip = template.requirementsTooltip || ""; - ret.reqs = DeriveTechnologyRequirements(template, civ); - - ret.description = template.description; - return ret; } Index: binaries/data/mods/public/gui/structree/helper.js =================================================================== --- binaries/data/mods/public/gui/structree/helper.js +++ binaries/data/mods/public/gui/structree/helper.js @@ -24,9 +24,9 @@ { if (!(templateName in g_TechnologyData)) { - var filename = "simulation/data/technologies/" + templateName + ".json"; - var data = Engine.ReadJSONFile(filename); - translateObjectKeys(data, ["genericName", "tooltip"]); + let filename = "simulation/data/technologies/" + templateName + ".json"; + let data = Engine.ReadJSONFile(filename); + translateObjectKeys(data, ["genericName", "tooltip", "description"]); g_TechnologyData[templateName] = data; } @@ -48,6 +48,50 @@ return g_AuraData[templateName]; } +function findAllAutoResearchedTechs() +{ + let path = "simulation/data/technologies/"; + let techFiles = Engine.BuildDirEntList(path, "*.json", true); + let techList = []; + + for (let filename of techFiles) + { + let templateName = filename.slice(path.length, -5); + let data = loadTechData(templateName); + + if (!data || !data.autoResearch) + continue; + + techList.push(templateName); + } + + return techList; +} + +function deriveCurrentModifications() +{ + g_CurrentModifiers = {}; + for (let templateName of g_AutoResearchTechList) + { + let data = loadTechData(templateName); + let modifier = GetTechnologyBasicDataHelper(data, g_SelectedCiv); + + if (!modifier.reqs) + continue; + + modifier.modifications = data.modifications; + modifier.affects = data.affects; + + let derivedModifiers = DeriveModificationsFromTech(modifier); + for (let modPath in derivedModifiers) + { + if (!g_CurrentModifiers[modPath]) + g_CurrentModifiers[modPath] = []; + g_CurrentModifiers[modPath] = g_CurrentModifiers[modPath].concat(derivedModifiers[modPath]); + } + } +} + /** * This is needed because getEntityCostTooltip in tooltip.js needs to get * the template data of the different wallSet pieces. In the session this Index: binaries/data/mods/public/gui/structree/structree.js =================================================================== --- binaries/data/mods/public/gui/structree/structree.js +++ binaries/data/mods/public/gui/structree/structree.js @@ -8,8 +8,10 @@ var g_Lists = {}; var g_CivData = {}; var g_SelectedCiv = ""; +var g_CurrentModifiers = {}; var g_CallbackSet = false; var g_ResourceData = new Resources(); +var g_AutoResearchTechList = []; /** * Initialize the dropdown containing all the available civs @@ -26,6 +28,8 @@ if (!civList.length) return; + g_AutoResearchTechList = findAllAutoResearchedTechs(); + var civSelection = Engine.GetGUIObjectByName("civSelection"); civSelection.list = civList.map(c => c.name); civSelection.list_data = civList.map(c => c.code); @@ -56,6 +60,8 @@ return; } + deriveCurrentModifications(); + g_Lists = { "units": [], "structures": [], Index: binaries/data/mods/public/simulation/components/TechnologyManager.js =================================================================== --- binaries/data/mods/public/simulation/components/TechnologyManager.js +++ binaries/data/mods/public/simulation/components/TechnologyManager.js @@ -270,48 +270,18 @@ // store the modifications in an easy to access structure if (template.modifications) { - var affects = []; - if (template.affects && template.affects.length > 0) + let derivedModifiers = DeriveModificationsFromTech(template); + for (let modifierPath in derivedModifiers) { - for (let affect of template.affects) - { - // Put the list of classes into an array for convenient access - affects.push(affect.split(/\s+/)); - } - } - else - { - affects.push([]); - } - - // We add an item to this.modifications for every modification in the template.modifications array - for (var i in template.modifications) - { - var modification = template.modifications[i]; - if (!this.modifications[modification.value]) - this.modifications[modification.value] = []; - - var modAffects = affects.slice(); - if (modification.affects) - { - var extraAffects = modification.affects.split(/\s+/); - for (var a in modAffects) - modAffects[a] = modAffects[a].concat(extraAffects); - } - - var mod = {"affects": modAffects}; - - // copy the modification data into our new data structure - for (var j in modification) - if (j !== "value" && j !== "affects") - mod[j] = modification[j]; + if (!this.modifications[modifierPath]) + this.modifications[modifierPath] = []; + this.modifications[modifierPath] = this.modifications[modifierPath].concat(derivedModifiers[modifierPath]); - this.modifications[modification.value].push(mod); - var component = modification.value.split("/")[0]; + let component = modifierPath.split("/")[0]; if (!modifiedComponents[component]) modifiedComponents[component] = []; - modifiedComponents[component].push(modification.value); - this.modificationCache[modification.value] = {}; + modifiedComponents[component].push(modifierPath); + this.modificationCache[modifierPath] = {}; } }