Ticket #3689: techno.patch

File techno.patch, 19.9 KB (added by mimo, 8 years ago)
  • binaries/data/mods/public/globalscripts/Templates.js

     
    304304        "time": template.researchTime ? (+template.researchTime) : 0,
    305305    }
    306306    ret.tooltip = template.tooltip;
     307    ret.requirementsTooltip = template.requirementsTooltip || "";
     308    ret.pairRequirementsTooltip = template.pairRequirementsTooltip || "";
    307309
    308     if (template.requirementsTooltip)
    309         ret.requirementsTooltip = template.requirementsTooltip;
    310     else
    311         ret.requirementsTooltip = "";
    312 
    313310    if (template.requirements && template.requirements.class)
    314311        ret.classRequirements = {"class": template.requirements.class, "number": template.requirements.number};
    315312
  • binaries/data/mods/public/gui/session/selection_panels.js

     
    751751    },
    752752    "addData": function(data)
    753753    {
    754         data.entType = data.item.pair ? [data.item.top, data.item.bottom] : [data.item];
     754        // index one row below
     755        var shiftedIndex = data.i + data.rowLength;
     756        // when a pair, data.item.top=null when one item already searched for
     757        if (data.item.pair && data.item.top)
     758        {
     759            data.entType = [data.item.top, data.item.bottom];
     760            data.positions = [data.i, shiftedIndex];
     761            data.positionsToHide = [];
     762        }
     763        else
     764        {
     765            data.entType = data.item.pair ? [data.item.bottom] : [data.item];
     766            data.positions = [shiftedIndex];
     767            data.positionsToHide = [data.i];
     768        }
    755769        data.template = data.entType.map(GetTechnologyData);
    756770        // abort if no template found for any of the techs
    757         if (!data.template.every(function(v) { return v; }))
     771        if (!data.template.every(v => v))
    758772            return false;
    759         // index one row below
    760         var shiftedIndex = data.i + data.rowLength;
    761         data.positions = data.item.pair ? [data.i, shiftedIndex] : [shiftedIndex];
    762         data.positionsToHide = data.item.pair ? [] : [data.i];
    763773
    764774        // add top buttons to the data
    765         data.button = data.positions.map(function(p) {
    766             return Engine.GetGUIObjectByName("unitResearchButton["+p+"]");
    767         });
     775        data.button = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchButton["+p+"]"));
    768776
    769         data.buttonsToHide = data.positionsToHide.map(function(p) {
    770             return Engine.GetGUIObjectByName("unitResearchButton["+p+"]");
    771         });
     777        data.buttonsToHide = data.positionsToHide.map(p => Engine.GetGUIObjectByName("unitResearchButton["+p+"]"));
    772778
    773779
    774         data.affordableMask = data.positions.map(function(p) {
    775             return Engine.GetGUIObjectByName("unitResearchUnaffordable["+p+"]");
    776         });
     780        data.affordableMask = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchUnaffordable["+p+"]"));
    777781
    778         data.icon = data.positions.map(function(p) {
    779             return Engine.GetGUIObjectByName("unitResearchIcon["+p+"]");
    780         });
     782        data.icon = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchIcon["+p+"]"));
    781783
    782         data.unchosenIcon = data.positions.map(function(p) {
    783             return Engine.GetGUIObjectByName("unitResearchUnchosenIcon["+p+"]");
    784         });
     784        if (data.item.researchBoth)
     785            data.unchosenIcon = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchDelayedIcon["+p+"]"));
     786        else
     787            data.unchosenIcon = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchUnchosenIcon["+p+"]"));
    785788
    786         data.neededResources = data.template.map(function(t) {
    787             return Engine.GuiInterfaceCall("GetNeededResources", t.cost);
    788         });
     789        data.neededResources = data.template.map(t => Engine.GuiInterfaceCall("GetNeededResources", t.cost));
    789790
    790         data.requirementsPassed = data.entType.map(function(e) {
    791             return Engine.GuiInterfaceCall("CheckTechnologyRequirements",e);
    792         });
     791        data.requirementsPassed = data.entType.map(e => Engine.GuiInterfaceCall("CheckTechnologyRequirements",e));
    793792
    794793        data.pair = Engine.GetGUIObjectByName("unitResearchPair["+data.i+"]");
    795794
     
    808807            tooltip += "\n" + getEntityCostTooltip(template);
    809808            if (!data.requirementsPassed[i])
    810809            {
    811                 tooltip += "\n" + template.requirementsTooltip;
     810                if (!data.item.pair || data.item.top)
     811                    tooltip += "\n" + template.requirementsTooltip;
     812                else
     813                    tooltip += "\n" + template.pairRequirementsTooltip;
    812814                if (template.classRequirements)
    813815                {
    814816                    var player = Engine.GetPlayerID();
     
    819821            }
    820822            if (data.neededResources[i])
    821823                tooltip += getNeededResourcesTooltip(data.neededResources[i]);
     824            if (data.item.pair && data.item.top)
     825            {
     826                if (data.item.researchBoth && template.pairRequirementsTooltip)
     827                    tooltip += "\n(" + translate("second choice: ") + template.pairRequirementsTooltip +")";
     828                else if (!data.item.researchBoth)
     829                    tooltip += "\n(" + translate("no second choice") + ")";
     830            }
    822831            data.button[i].tooltip = tooltip;
    823832        }
    824833    },
     
    879888        for (var button of data.buttonsToHide)
    880889            button.hidden = true;
    881890        // show the tech connector
    882         data.pair.hidden = data.item.pair == null;
     891        data.pair.hidden = data.item.pair == null || data.item.top == null;
    883892    },
    884893    "setPosition": function(data)
    885894    {
  • binaries/data/mods/public/gui/session/selection_panels_right/research_panel.xml

     
    77        <object name="unitResearchButton[n]" hidden="true" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottom">
    88        <object name="unitResearchIcon[n]" type="image" ghost="true" size="3 3 43 43"/>
    99        <object name="unitResearchUnchosenIcon[n]" type="image" hidden="true" ghost="true" size="3 3 43 43" sprite="stretched:session/icons/tech_pair_would_be_unavailable.png"/>
     10        <object name="unitResearchDelayedIcon[n]" type="image" hidden="true" ghost="true" size="3 3 43 43" sprite="stretched:session/icons/tech_pair_would_be_delayed.png"/>
    1011        <object name="unitResearchUnaffordable[n]" hidden="true" type="image" ghost="true" size="3 3 43 43" sprite="color: 255 0 0 60"/>
    1112        </object>
    1213    </repeat>
  • binaries/data/mods/public/gui/session/session.js

     
    130130    if (!(technologyName in g_TechnologyData))
    131131    {
    132132        var template = Engine.GuiInterfaceCall("GetTechnologyData", technologyName);
    133         translateObjectKeys(template, ["specific", "generic", "description", "tooltip", "requirementsTooltip"]);
     133        translateObjectKeys(template, ["specific", "generic", "description", "tooltip", "requirementsTooltip", "pairRequirementsTooltip"]);
    134134        g_TechnologyData[technologyName] = template;
    135135    }
    136136
  • binaries/data/mods/public/simulation/components/ProductionQueue.js

     
    162162    var disabledTechnologies = cmpPlayer.GetDisabledTechnologies();
    163163   
    164164    // Add any top level technologies to an array which corresponds to the displayed icons
    165     // Also store what a technology is superceded by in the superceded object {"tech1":"techWhichSupercedesTech1", ...}
    166     for (var i in techs)
     165    // Also store what a technology is superseded by in the superseded object {"tech1":"techWhichSupersedesTech1", ...}
     166    for (let tech of techs)
    167167    {
    168         var tech = techs[i];
    169168        if (disabledTechnologies && disabledTechnologies[tech])
    170169            continue;
    171         var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
     170        let template = cmpTechnologyManager.GetTechnologyTemplate(tech);
    172171        if (!template.supersedes || techs.indexOf(template.supersedes) === -1)
    173172            techList.push(tech);
    174173        else
     
    176175    }
    177176   
    178177    // Now make researched/in progress techs invisible
    179     for (var i in techList)
     178    for (let i in techList)
    180179    {
    181         var tech = techList[i];
    182         while (this.IsTechnologyResearchedOrInProgress(tech))
    183         {
     180        let tech = techList[i];
     181        while (cmpTechnologyManager.IsTechnologyResearchedOrInProgress(tech))
    184182            tech = superseded[tech];
    185         }
    186        
    187183        techList[i] = tech;
    188184    }
    189185   
     
    190186    var ret = [];
    191187   
    192188    // This inserts the techs into the correct positions to line up the technology pairs
    193     for (var i = 0; i < techList.length; i++)
     189    for (let i = 0; i < techList.length; ++i)
    194190    {
    195         var tech = techList[i];
     191        let tech = techList[i];
    196192        if (!tech)
    197193        {
    198194            ret[i] = undefined;
     
    199195            continue;
    200196        }
    201197       
    202         var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
     198        let template = cmpTechnologyManager.GetTechnologyTemplate(tech);
    203199        if (template.top)
    204             ret[i] = {"pair": true, "top": template.top, "bottom": template.bottom};
     200        {
     201            if (cmpTechnologyManager.IsTechnologyResearchedOrInProgress(template.top))
     202                ret[i] = {"pair": tech, "top": null, "bottom": template.bottom};
     203            else if (cmpTechnologyManager.IsTechnologyResearchedOrInProgress(template.bottom))
     204                ret[i] = {"pair": tech, "top": null, "bottom": template.top};
     205            else
     206                ret[i] = {"pair": tech, "top": template.top, "bottom": template.bottom, "researchBoth": template.researchBoth};
     207        }
    205208        else
    206209            ret[i] = tech;
    207210    }
     
    209212    return ret;
    210213};
    211214
    212 ProductionQueue.prototype.IsTechnologyResearchedOrInProgress = function(tech)
    213 {
    214     if (!tech)
    215         return false;
    216    
    217     var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
    218    
    219     var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
    220     if (template.top)
    221     {
    222         return (cmpTechnologyManager.IsTechnologyResearched(template.top) || cmpTechnologyManager.IsInProgress(template.top)
    223             || cmpTechnologyManager.IsTechnologyResearched(template.bottom) || cmpTechnologyManager.IsInProgress(template.bottom));
    224     }
    225     else
    226     {
    227         return (cmpTechnologyManager.IsTechnologyResearched(tech) || cmpTechnologyManager.IsInProgress(tech));
    228     }
    229 };
    230 
    231215/*
    232216 * Adds a new batch of identical units to train or a technology to research to the production queue.
    233217 */
  • binaries/data/mods/public/simulation/components/TechnologyManager.js

     
    6464    {
    6565        var tech = cmpTechTempMan.GetTemplate(key);
    6666        if ((tech.autoResearch && this.CanResearch(key))
    67             || (tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
     67            || (tech.top && (this.IsTechnologyResearched(tech.top) && this.IsTechnologyResearched(tech.bottom))))
    6868        {
    6969            delete this.autoResearchTech[key];
    7070            this.ResearchTechnology(key);
     
    9595    return (this.researchedTechs[tech] !== undefined);
    9696};
    9797
     98// Checks of a technology or pair has already been researched or is in progress
     99TechnologyManager.prototype.IsTechnologyResearchedOrInProgress = function(tech)
     100{
     101    if (!tech)
     102        return false;
     103
     104    let template = this.GetTechnologyTemplate(tech);
     105    if (template.top)
     106    {
     107        if (template.researchBoth)
     108            return (this.IsTechnologyResearched(template.top) || this.IsInProgress(template.top))
     109             && (this.IsTechnologyResearched(template.bottom) || this.IsInProgress(template.bottom));
     110        else
     111            return  this.IsTechnologyResearched(template.top) || this.IsInProgress(template.top)
     112              || this.IsTechnologyResearched(template.bottom) || this.IsInProgress(template.bottom);
     113    }
     114
     115    return this.IsTechnologyResearched(tech) || this.IsInProgress(tech);
     116};
     117
    98118// Checks the requirements for a technology to see if it can be researched at the current time
    99119TechnologyManager.prototype.CanResearch = function(tech)
    100120{
     
    109129    if (template.supersedes && !this.IsTechnologyResearched(template.supersedes))
    110130        return false;
    111131
    112     if (template.top && this.IsInProgress(template.top) ||
    113         template.bottom && this.IsInProgress(template.bottom))
    114         return false;
     132    if (template.top)
     133    {
     134        if (template.researchBoth)
     135            return !this.IsTechnologyResearchedOrInProgress(template.top) || !this.IsTechnologyResearchedOrInProgress(template.bottom);
     136        else
     137            return !this.IsTechnologyResearchedOrInProgress(template.top) && !this.IsTechnologyResearchedOrInProgress(template.bottom);
     138    }
    115139
    116140    if (template.pair && !this.CanResearch(template.pair))
    117141        return false;
     
    122146    if (this.IsTechnologyResearched(tech))
    123147        return false;
    124148
    125     return this.CheckTechnologyRequirements(template.requirements || null);
     149    let requirements = template.requirements || null;
     150    if (template.pair)
     151    {
     152        let pairTemplate = this.GetTechnologyTemplate(template.pair);
     153        if (this.IsTechnologyResearchedOrInProgress(pairTemplate.top) || this.IsTechnologyResearchedOrInProgress(pairTemplate.bottom))
     154            requirements = template.pairRequirements || requirements;
     155    }
     156    return this.CheckTechnologyRequirements(requirements);
    126157};
    127158
    128159// Private function for checking a set of requirements is met
  • binaries/data/mods/public/simulation/data/technologies/attack_tower_murderholes.json

     
    11{
     2    "pair": "pair_tower_range",
    23    "genericName": "Murder Holes",
    34    "description": "Murder holes allow hitting enemies at the foot of the tower.",
    45    "cost": {"food": 0, "wood": 250, "stone": 100, "metal": 0},
    5     "requirements": {"tech": "phase_city"},
    6     "requirementsTooltip": "Unlocked in City Phase.",
     6    "requirements": {"tech": "phase_town"},
     7    "requirementsTooltip": "Unlocked in Town Phase.",
     8    "pairRequirements": {"tech": "phase_city"},
     9    "pairRequirementsTooltip": "Unlocked in City Phase.",
    710    "icon": "murder_holes.png",
    811    "researchTime": 40,
    912    "tooltip": "Removes defense tower minimum range.",
  • binaries/data/mods/public/simulation/data/technologies/attack_tower_range.json

     
    11{
     2    "pair": "pair_tower_range",
    23    "genericName": "Arrow Shooters",
    34    "description": "Arrow shooters increase the maximum range of the fire arrows.",
    45    "cost": {"food": 0, "wood": 500, "stone": 0, "metal": 250},
    56    "requirements": {"tech": "phase_town"},
    67    "requirementsTooltip": "Unlocked in Town Phase.",
     8    "pairRequirements": {"tech": "phase_city"},
     9    "pairRequirementsTooltip": "Unlocked in City Phase.",
    710    "icon": "arrow.png",
    811    "researchTime": 40,
    912    "tooltip": "Increases defense tower maximum range by 8 meters.",
  • binaries/data/mods/public/simulation/data/technologies/pair_tower_range.json

     
     1{
     2    "genericName": "Tower Range",
     3    "top": "attack_tower_range",
     4    "bottom": "attack_tower_murderholes",
     5    "researchBoth": true
     6}
  • binaries/data/mods/public/simulation/data/technologies/pair_trade_convoys.json

     
     1{
     2    "genericName": "Trade Convoys",
     3    "top": "trade_convoys_speed",
     4    "bottom": "trade_convoys_armor",
     5    "researchBoth": true
     6}
  • binaries/data/mods/public/simulation/data/technologies/trade_convoys_armor.json

     
    11{
     2    "pair": "pair_trade_convoys",
    23    "genericName": "Trade Convoys",
    34    "description": "Increases defensive capability of traders.",
    45    "cost": {"food": 0, "wood": 0, "stone": 0, "metal": 200},
    5     "requirements": {"tech": "phase_city"},
    6     "requirementsTooltip": "Unlocked in City Phase.",
    7     "supersedes": "trade_convoys_speed",
     6    "requirements": {"tech": "phase_town"},
     7    "requirementsTooltip": "Unlocked in Town Phase.",
     8    "pairRequirements": {"tech": "phase_city"},
     9    "pairRequirementsTooltip": "Unlocked in City Phase.",
    810    "icon": "wheel.png",
    911    "researchTime": 40,
    1012    "tooltip": "Traders +2 Hack and Pierce armor levels.",
  • binaries/data/mods/public/simulation/data/technologies/trade_convoys_speed.json

     
    11{
     2    "pair": "pair_trade_convoys",
    23    "genericName": "Trade Convoys",
    34    "description": "Increases movement rate of traders, which in turn increases trade income.",
    45    "cost": {"food": 0, "wood": 0, "stone": 0, "metal": 200},
    56    "requirements": {"tech": "phase_town"},
    67    "requirementsTooltip": "Unlocked in Town Phase.",
     8    "pairRequirements": {"tech": "phase_city"},
     9    "pairRequirementsTooltip": "Unlocked in City Phase.",
    710    "icon": "wheel.png",
    811    "researchTime": 40,
    912    "tooltip": "Traders +25% Walk Speed, which quickly increases trade income.",
  • binaries/data/mods/public/simulation/templates/template_structure_defense_defense_tower.xml

     
    7373    <Technologies datatype="tokens">
    7474      attack_tower_watch
    7575      attack_tower_crenellations
    76       attack_tower_range
    77       attack_tower_murderholes
     76      pair_tower_range
    7877      attack_tower_defense
    7978    </Technologies>
    8079  </ProductionQueue>
  • binaries/data/mods/public/simulation/templates/template_structure_defense_wooden_tower.xml

     
    5353  <ProductionQueue>
    5454    <Technologies datatype="tokens">
    5555      -attack_tower_crenellations
    56       -attack_tower_range
    57       -attack_tower_murderholes
     56      -pair_tower_range
    5857      -attack_tower_defense
    5958    </Technologies>
    6059  </ProductionQueue>
  • binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml

     
    5151    <BatchTimeModifier>0.7</BatchTimeModifier>
    5252    <Technologies datatype="tokens">
    5353      unlock_shared_los
    54       trade_convoys_speed
    55       trade_convoys_armor
     54      pair_trade_convoys
    5655      trade_gain_01
    5756      trade_gain_02
    5857    </Technologies>