Index: binaries/data/mods/public/globalscripts/Templates.js =================================================================== --- binaries/data/mods/public/globalscripts/Templates.js +++ binaries/data/mods/public/globalscripts/Templates.js @@ -478,6 +478,12 @@ ret.techCostMultiplier[res] = getEntityValue("ProductionQueue/TechCostMultiplier/" + res); } + if (template.Promotion) + ret.promotion = { + "entity": template.Promotion.Entity, + "requiredXp": getEntityValue("Promotion/RequiredXp") + }; + if (template.Trader) ret.trader = { "GainMultiplier": getEntityValue("Trader/GainMultiplier") Index: binaries/data/mods/public/gui/reference/common/ReferencePage.js =================================================================== --- binaries/data/mods/public/gui/reference/common/ReferencePage.js +++ binaries/data/mods/public/gui/reference/common/ReferencePage.js @@ -23,8 +23,13 @@ this.activeCiv = civCode; - this.currentTemplateLists = this.TemplateLister.compileTemplateLists(this.activeCiv, this.civData); this.TemplateParser.deriveModifications(this.activeCiv); + this.currentTemplateLists = + this.TemplateLister.compileTemplateLists( + this.activeCiv, + this.civData, + this.TemplateParser.modifiers[this.activeCiv] + ); this.TemplateParser.derivePhaseList(this.currentTemplateLists.techs.keys(), this.activeCiv); } Index: binaries/data/mods/public/gui/reference/common/TemplateLister.js =================================================================== --- binaries/data/mods/public/gui/reference/common/TemplateLister.js +++ binaries/data/mods/public/gui/reference/common/TemplateLister.js @@ -15,7 +15,7 @@ * @param {Object} civCode * @param {Object} civData - Data defining every civ in the game. */ - compileTemplateLists(civCode, civData) + compileTemplateLists(civCode, civData, civModifiers) { if (this.hasTemplateLists(civCode)) return this.templateLists.get(civCode); @@ -37,7 +37,7 @@ for (let templateBeingParsed of templatesThisIteration) { let baseOfTemplateBeingParsed = this.TemplateLoader.getVariantBaseAndType(templateBeingParsed, civCode)[0]; - let list = this.deriveTemplateListsFromTemplate(templateBeingParsed, civCode); + let list = this.deriveTemplateListsFromTemplate(templateBeingParsed, civCode, civModifiers); for (let type in list) for (let templateName of list[type]) { @@ -116,14 +116,14 @@ * Compiles lists of buildable, trainable, or researchable entities from * a named template. */ - deriveTemplateListsFromTemplate(templateName, civCode) + deriveTemplateListsFromTemplate(templateName, civCode, civModifiers) { if (!templateName || !Engine.TemplateExists(templateName)) return {}; let template = this.TemplateLoader.loadEntityTemplate(templateName, civCode); - let templateLists = this.TemplateLoader.deriveProductionQueue(template, civCode); + let templateLists = this.TemplateLoader.deriveProductionQueue(template, civCode, civModifiers); templateLists.structures = this.TemplateLoader.deriveBuildQueue(template, civCode); if (template.WallSet) Index: binaries/data/mods/public/gui/reference/common/TemplateLoader.js =================================================================== --- binaries/data/mods/public/gui/reference/common/TemplateLoader.js +++ binaries/data/mods/public/gui/reference/common/TemplateLoader.js @@ -137,7 +137,7 @@ }; } - deriveProductionQueue(template, civCode) + deriveProductionQueue(template, civCode, civModifiers) { let production = { "techs": [], @@ -152,7 +152,18 @@ { templateName = templateName.replace(/\{(civ|native)\}/g, civCode); if (Engine.TemplateExists(templateName)) + { + // Substitute units promoted automatically by autoresearched technologies + const unitTemplate = this.loadEntityTemplate(templateName, civCode); + if (unitTemplate.Promotion) + { + const unit = GetTemplateDataHelper(unitTemplate, null, this.auraData, civModifiers || {}); + if (unit.promotion.requiredXp == 0 && Engine.TemplateExists(unit.promotion.entity)) + templateName = unit.promotion.entity; + } + production.units.push(templateName); + } } let appendTechnology = (technologyName) => { Index: binaries/data/mods/public/gui/reference/common/TemplateParser.js =================================================================== --- binaries/data/mods/public/gui/reference/common/TemplateParser.js +++ binaries/data/mods/public/gui/reference/common/TemplateParser.js @@ -42,6 +42,28 @@ return this.auras[auraName]; } + /** + * Replaces names of entities that have been promoted by auto-researched technology. + * + * In the Simulation, this is done by `ProductionQueue::CalculateEntitiesMap()` + * + * @param {array} productionArray + * @param {string} civCode + */ + parseAutoPromotions (productionArray, civCode) + { + for (const idx in productionArray) + { + const templateName = productionArray[idx]; + const entity = this.getEntity(templateName, civCode); + if (!entity.promotion || entity.promotion.requiredXp > 0) + continue; + + productionArray.splice(idx, 1, entity.promotion.entity); + } + } + + /** * Load and parse a structure, unit, resource, etc from its entity template file. * @@ -66,6 +88,8 @@ parsed.history = template.Identity.History; parsed.production = this.TemplateLoader.deriveProductionQueue(template, civCode); + this.parseAutoPromotions(parsed.production.units, civCode); + if (template.Builder) parsed.builder = this.TemplateLoader.deriveBuildQueue(template, civCode); @@ -79,10 +103,11 @@ parsed.phase = this.getPhaseOfTechnology(parsed.requiredTechnology, civCode); if (template.Identity.Rank) - parsed.promotion = { - "current_rank": template.Identity.Rank, - "entity": template.Promotion && template.Promotion.Entity - }; + { + if (!template.Promotion) + parsed.promotion = {}; + parsed.promotion.current_rank = template.Identity.Rank; + } if (template.ResourceSupply) parsed.supply = {