Ticket #3747: 3747_promotionModifier.patch

File 3747_promotionModifier.patch, 9.4 KB (added by s0600204, 8 years ago)

Proposed patch.

  • binaries/data/mods/public/globalscripts/Technologies.js

    function GetTechModifiedProperty(currentTechModifications, entityTemplateData, p  
    5353}
    5454
    5555/**
     56 * Derives modifications (to be applied to entities) from a given technology
     57 *
     58 * @param techTemplate The technology template to derive the modifications from.
     59 * @return Object containing the relevant modifications.
     60 */
     61function DeriveModificationsFromTech(techTemplate)
     62{
     63    if (!techTemplate.modifications)
     64        return {};
     65
     66    let techMods = {};
     67    let techAffects = [];
     68    if (techTemplate.affects && techTemplate.affects.length > 0)
     69        for (let affected of techTemplate.affects)
     70            techAffects.push(affected.split(/\s+/));
     71    else
     72        techAffects.push([]);
     73
     74    for (let mod of techTemplate.modifications)
     75    {
     76        let affects = techAffects.slice();
     77        if (mod.affects)
     78        {
     79            let specAffects = mod.affects.split(/\s+/);
     80            for (let a in affects)
     81                affects[a] = affects[a].concat(specAffects);
     82        }
     83
     84        let newModifier = {
     85            "affects": affects
     86        };
     87        for (let idx in mod)
     88            if (idx !== "value" && idx !== "affects")
     89                newModifier[idx] = mod[idx];
     90
     91        if (!techMods[mod.value])
     92            techMods[mod.value] = [];
     93        techMods[mod.value].push(newModifier);
     94    }
     95    return techMods;
     96}
     97
     98/**
    5699 * Returns whether the given modification applies to the entity containing the given class list
    57100 */
    58101function DoesModificationApply(modification, classes)
  • binaries/data/mods/public/globalscripts/Templates.js

    function GetTemplateDataHelper(template, player)  
    7878    var func;
    7979    if (player)
    8080        func = ApplyValueModificationsToTemplate;
     81    else if (g_Modifiers)
     82        func = function(property, val, c, template) {
     83            return GetTechModifiedProperty(g_Modifiers, template, property, val);
     84        }
    8185    else
    8286        func = function(a, val, c, d) { return val; }
    8387
  • binaries/data/mods/public/gui/structree/load.js

    function getGatherRates(templateName)  
    3535    return rates;
    3636}
    3737
     38function preloadUnit(templateName)
     39{
     40    if (!Engine.TemplateExists(templateName))
     41        return;
     42    let template = loadTemplate(templateName);
     43
     44    if (template.Builder && template.Builder.Entities._string)
     45        for (let build of template.Builder.Entities._string.split(" "))
     46        {
     47            build = build.replace("{civ}", g_SelectedCiv);
     48            if (g_Lists.structures.indexOf(build) < 0)
     49                g_Lists.structures.push(build);
     50        }
     51
     52    if (template.ProductionQueue)
     53        for (let build of template.ProductionQueue.Entities._string.split(" "))
     54        {
     55            build = build.replace("{civ}", g_SelectedCiv);
     56            if (g_Lists.units.indexOf(build) === -1)
     57                g_Lists.units.push(build);
     58        }
     59
     60    if (template.Identity.Rank)
     61    {
     62        let promotionTech = template.Identity.Rank.toLowerCase() + "_unit_bonus";
     63        if (g_Lists.modifiers.indexOf(promotionTech) < 0)
     64            g_Lists.modifiers.push(promotionTech);
     65
     66        // recurse through promotions to get all techs
     67        if (template.Promotion)
     68            preloadUnit(template.Promotion.Entity);
     69    }
     70}
     71
    3872function loadUnit(templateName)
    3973{
    4074    if (!Engine.TemplateExists(templateName))
    function loadUnit(templateName)  
    5892    {
    5993        unit.trainer = [];
    6094        for (let build of template.ProductionQueue.Entities._string.split(" "))
    61         {
    62             build = build.replace("{civ}", g_SelectedCiv);
    63             unit.trainer.push(build);
    64             if (g_Lists.units.indexOf(build) === -1)
    65                 g_Lists.units.push(build);
    66         }
     95            unit.trainer.push(build.replace("{civ}", g_SelectedCiv));
    6796    }
    6897
    6998    if (template.Heal)
    function loadUnit(templateName)  
    84113    return unit;
    85114}
    86115
     116function preloadStructure(templateName)
     117{
     118    let template = loadTemplate(templateName);
     119
     120    if (template.ProductionQueue && template.ProductionQueue.Entities && template.ProductionQueue.Entities._string)
     121        for (let build of template.ProductionQueue.Entities._string.split(" "))
     122        {
     123            build = build.replace("{civ}", g_SelectedCiv);
     124            if (g_Lists.units.indexOf(build) < 0)
     125                g_Lists.units.push(build);
     126        }
     127}
     128
    87129function loadStructure(templateName)
    88130{
    89131    var template = loadTemplate(templateName);
    function loadStructure(templateName)  
    109151            {
    110152                build = build.replace("{civ}", g_SelectedCiv);
    111153                structure.production.units.push(build);
    112                 if (g_Lists.units.indexOf(build) < 0)
    113                     g_Lists.units.push(build);
    114154            }
    115155
    116156        if (template.ProductionQueue.Technologies && template.ProductionQueue.Technologies._string)
    function loadPhase(phaseCode)  
    242282    return phase;
    243283}
    244284
     285function loadModifierTech(modCode)
     286{
     287    if (!Engine.FileExists("simulation/data/technologies/"+modCode+".json"))
     288        return {};
     289    return loadTechData(modCode);
     290}
     291
    245292function loadTechnologyPair(pairCode)
    246293{
    247294    var pairInfo = loadTechData(pairCode);
  • binaries/data/mods/public/gui/structree/structree.js

    var g_ParsedData = {  
    66};
    77var g_Lists = {};
    88var g_CivData = {};
     9var g_Modifiers = {};
    910var g_SelectedCiv = "";
    1011var g_CallbackSet = false;
    1112
    function selectCiv(civCode)  
    5859    g_Lists.units = [];
    5960    g_Lists.structures = [];
    6061    g_Lists.techs = [];
     62    g_Lists.modifiers = [];
     63    g_Modifiers = {};
    6164
    6265    // get initial units
    63     var startStructs = [];
     66    let startStructs = [];
    6467    for (let entity of g_CivData[civCode].StartEntities)
    6568    {
    6669        if (entity.Template.slice(0, 5) == "units")
    function selectCiv(civCode)  
    7275        }
    7376    }
    7477
    75     // Load units and structures
    76     var unitCount = 0;
     78    // Compile lists of units and structures belonging to this civ
     79    let unitCount = 0;
    7780    do
    7881    {
    7982        for (let u of g_Lists.units)
    80             if (!g_ParsedData.units[u])
    81                 g_ParsedData.units[u] = loadUnit(u);
     83            preloadUnit(u);
    8284
    8385        unitCount = g_Lists.units.length;
    8486
    8587        for (let s of g_Lists.structures)
    86             if (!g_ParsedData.structures[s])
    87                 g_ParsedData.structures[s] = loadStructure(s);
     88            preloadStructure(s);
    8889
    8990    } while (unitCount < g_Lists.units.length);
    9091
     92
     93    // Load modifiers
     94    for (let modCode of g_Lists.modifiers)
     95    {
     96        let modTech = loadModifierTech(modCode);
     97        let derivedModifiers = DeriveModificationsFromTech(modTech);
     98
     99        for (let modPath in derivedModifiers)
     100        {
     101            if (!g_Modifiers[modPath])
     102                g_Modifiers[modPath] = [];
     103            g_Modifiers[modPath] = g_Modifiers[modPath].concat(derivedModifiers[modPath]);
     104        }
     105    }
     106
     107    // Properly load units and structures, now we have modifiers
     108    for (let u of g_Lists.units)
     109        if (!g_ParsedData.units[u])
     110            g_ParsedData.units[u] = loadUnit(u);
     111
     112    for (let s of g_Lists.structures)
     113        if (!g_ParsedData.structures[s])
     114            g_ParsedData.structures[s] = loadStructure(s);
     115
    91116    // Load technologies
    92     var techPairs = {};
     117    let techPairs = {};
    93118    for (let techcode of g_Lists.techs)
    94119    {
    95120        let realcode = depath(techcode);
  • binaries/data/mods/public/simulation/components/TechnologyManager.js

    TechnologyManager.prototype.ResearchTechnology = function(tech)  
    284284    // store the modifications in an easy to access structure
    285285    if (template.modifications)
    286286    {
    287         var affects = [];
    288         if (template.affects && template.affects.length > 0)
     287        let derivedModifiers = DeriveModificationsFromTech(template);
     288        for (let modifierPath in derivedModifiers)
    289289        {
    290             for (let affect of template.affects)
    291             {
    292                 // Put the list of classes into an array for convenient access
    293                 affects.push(affect.split(/\s+/));
    294             }
    295         }
    296         else
    297         {
    298             affects.push([]);
    299         }
    300 
    301         // We add an item to this.modifications for every modification in the template.modifications array
    302         for (var i in template.modifications)
    303         {
    304             var modification = template.modifications[i];
    305             if (!this.modifications[modification.value])
    306                 this.modifications[modification.value] = [];
    307            
    308             var modAffects = affects.slice();
    309             if (modification.affects)
    310             {
    311                 var extraAffects = modification.affects.split(/\s+/);
    312                 for (var a in modAffects)
    313                     modAffects[a] = modAffects[a].concat(extraAffects);
    314             }
    315 
    316             var mod = {"affects": modAffects};
    317 
    318             // copy the modification data into our new data structure
    319             for (var j in modification)
    320                 if (j !== "value" && j !== "affects")
    321                     mod[j] = modification[j];
     290            if (!this.modifications[modifierPath])
     291                this.modifications[modifierPath] = [];
     292            this.modifications[modifierPath] = this.modifications[modifierPath].concat(derivedModifiers[modifierPath]);
    322293
    323             this.modifications[modification.value].push(mod);
    324             var component = modification.value.split("/")[0];
     294            let component = modifierPath.split("/")[0];
    325295            if (!modifiedComponents[component])
    326296                modifiedComponents[component] = [];
    327             modifiedComponents[component].push(modification.value);
    328             this.modificationCache[modification.value] = {};
     297            modifiedComponents[component].push(modifierPath);
     298            this.modificationCache[modifierPath] = {};
    329299        }
    330300    }
    331301