Index: binaries/data/mods/public/globalscripts/Templates.js =================================================================== --- binaries/data/mods/public/globalscripts/Templates.js +++ binaries/data/mods/public/globalscripts/Templates.js @@ -312,6 +312,29 @@ ret.speed.run = getEntityValue("UnitMotion/Run/Speed"); } + if (template.Upgrade) + { + ret.upgrades = []; + for (let upgradeName in template.Upgrade) + { + let upgrade = template.Upgrade[upgradeName]; + + let cost = {}; + for (let res in upgrade.Cost) + cost[res] = getEntityValue("Upgrade/" + upgradeName + "/Cost/" + res); + if (upgrade.Time) + cost.time = getEntityValue("Upgrade/" + upgradeName + "/Time"); + + ret.upgrades.push({ + "entity": upgrade.Entity, + "tooltip": upgrade.Tooltip, + "cost": cost, + "icon": upgrade.Icon || undefined, + "requiredTechnology": upgrade.RequiredTechnology || undefined + }); + } + } + if (template.ProductionQueue) { ret.techCostMultiplier = {}; Index: binaries/data/mods/public/gui/structree/draw.js =================================================================== --- binaries/data/mods/public/gui/structree/draw.js +++ binaries/data/mods/public/gui/structree/draw.js @@ -83,15 +83,23 @@ prod = g_ParsedData.units[prod]; if (!drawProdIcon(i, s, r, p, prod)) break; - p++; + ++p; + } + + if (stru.upgrades[prod_pha]) + for (let upgrade of stru.upgrades[prod_pha]) + { + if (!drawProdIcon(i, s, r, p, upgrade)) + break; + ++p; } if (stru.wallset && prod_pha == pha) - for (let prod of [stru.wallset.gate, stru.wallset.tower]) + for (let prod of [stru.wallset.tower]) { if (!drawProdIcon(i, s, r, p, prod)) break; - p++; + ++p; } if (stru.production.technology[prod_pha]) @@ -173,29 +181,37 @@ thisEle.hidden = false; let p = 0; - for (let prodType in trainer.production) - { - for (let prod of trainer.production[prodType]) - { - switch (prodType) + if (trainer.production) + for (let prodType in trainer.production) + for (let prod of trainer.production[prodType]) { - case "units": - prod = g_ParsedData.units[prod]; - break; - case "techs": - prod = clone(g_ParsedData.techs[civCode][prod]); - for (let res in trainer.techCostMultiplier) - if (prod.cost[res]) - prod.cost[res] *= trainer.techCostMultiplier[res]; - break; - default: - continue; + switch (prodType) + { + case "units": + prod = g_ParsedData.units[prod]; + break; + case "techs": + prod = clone(g_ParsedData.techs[civCode][prod]); + for (let res in trainer.techCostMultiplier) + if (prod.cost[res]) + prod.cost[res] *= trainer.techCostMultiplier[res]; + break; + default: + continue; + } + if (!drawProdIcon(null, t, null, p, prod)) + break; + ++p; } - if (!drawProdIcon(null, t, null, p, prod)) + + if (trainer.upgrades) + for (let upgrade of trainer.upgrades) + { + if (!drawProdIcon(null, t, null, p, upgrade.data)) break; ++p; } - } + hideRemaining("trainer["+t+"]_row", p); let size = thisEle.size; 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 @@ -49,6 +49,31 @@ } /** + * Provided with an array containing basic information about possible + * upgrades, such as that generated by globalscript's GetTemplateDataHelper, + * this function loads the actual template data of the upgrades, overwrites + * certain values within, then passes an array containing the template data + * back to caller. + */ +function getActualUpgradeData(upgradesInfo) +{ + let newUpgrades = []; + for (let upgrade of upgradesInfo) + { + upgrade.entity = upgrade.entity.replace("{civ}", g_SelectedCiv); + + let data = GetTemplateDataHelper(loadTemplate(upgrade.entity), null, g_AuraData, g_ResourceData); + data.cost = upgrade.cost + data.icon = upgrade.icon || data.icon; + data.tooltip = upgrade.tooltip || data.tooltip; + data.requiredTechnology = upgrade.requiredTechnology || data.requiredTechnology; + + newUpgrades.push(data); + } + return newUpgrades; +} + +/** * This is needed because getEntityCostTooltip in tooltip.js needs to get * the template data of the different wallSet pieces. In the session this * function does some caching, but here we do that in loadTemplate already. Index: binaries/data/mods/public/gui/structree/load.js =================================================================== --- binaries/data/mods/public/gui/structree/load.js +++ binaries/data/mods/public/gui/structree/load.js @@ -40,6 +40,9 @@ g_Lists.structures.push(build); } + if (unit.upgrades) + unit.upgrades = getActualUpgradeData(unit.upgrades); + return unit; } @@ -73,10 +76,16 @@ } } + if (structure.upgrades) + structure.upgrades = getActualUpgradeData(structure.upgrades); + if (structure.wallSet) { structure.wallset = {}; + if (!structure.upgrades) + structure.upgrades = []; + // Note: Assume wall segments of all lengths have the same armor and auras let struct = loadStructure(structure.wallSet.templates.long); structure.armour = struct.armour; @@ -96,6 +105,9 @@ for (let research of wPart.production.technology) structure.production.technology.push(research); + if (wPart.upgrades) + structure.upgrades = structure.upgrades.concat(wPart.upgrades); + if (["gate", "tower"].indexOf(wSegm) != -1) continue; 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 @@ -171,7 +171,7 @@ } } - // Group production lists of structures by phase + // Group production and upgrade lists of structures by phase for (let structCode of g_Lists.structures) { let structInfo = g_ParsedData.structures[structCode]; @@ -232,6 +232,22 @@ "technology": newProdTech, "units": newProdUnits }; + + // Sort upgrades by phase + let newUpgrades = {}; + if (structInfo.upgrades) + for (let upgrade of structInfo.upgrades) + { + let phase = GetPhaseOfTemplate(upgrade); + + if (g_ParsedData.phaseList.indexOf(phase) < structPhaseIdx) + phase = structInfo.phase; + + if (!newUpgrades[phase]) + newUpgrades[phase] = []; + newUpgrades[phase].push(upgrade); + } + g_ParsedData.structures[structCode].upgrades = newUpgrades; } // Determine the buildList for the civ (grouped by phase) @@ -244,8 +260,9 @@ let phase = g_ParsedData.structures[structCode].phase; buildList[phase].push(structCode); } + for (let unitCode of g_Lists.units) - if (g_ParsedData.units[unitCode] && g_ParsedData.units[unitCode].production) + if (g_ParsedData.units[unitCode] && (g_ParsedData.units[unitCode].production || g_ParsedData.units[unitCode].upgrades)) trainerList.push(unitCode); g_CivData[g_SelectedCiv].buildList = buildList; Index: binaries/data/mods/public/simulation/templates/template_structure_defense_wall_gate.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_structure_defense_wall_gate.xml +++ binaries/data/mods/public/simulation/templates/template_structure_defense_wall_gate.xml @@ -1,6 +1,7 @@ + 20