From 9368ffe3456bfb3c2499e20f4a66bde50400a62c Mon Sep 17 00:00:00 2001 From: sanderd17 Date: Fri, 20 May 2016 11:20:51 +0000 Subject: [PATCH] Fix tech modifications calculations so we don't bump into stupid mistakes again (f.e. multiplying two positive numbers is now guaranteed to stay positive). See 7f300bbf3d and 0b8845eb4f This was SVN commit r18207. --- .../mods/public/globalscripts/Technologies.js | 63 ++++++++----------- .../components/TechnologyManager.js | 16 ++--- .../data/technologies/elite_unit_bonus.json | 2 +- 3 files changed, 36 insertions(+), 45 deletions(-) diff --git a/binaries/data/mods/public/globalscripts/Technologies.js b/binaries/data/mods/public/globalscripts/Technologies.js index 061185b901..b6783e2ab5 100644 --- a/binaries/data/mods/public/globalscripts/Technologies.js +++ b/binaries/data/mods/public/globalscripts/Technologies.js @@ -6,50 +6,41 @@ */ /** - * Returns modified property value if at least one tech modification is found - * applicable to the given entity template; else, returns its original value. + * Returns modified property value modified by the applicable tech + * modifications. * - * currentTechModifications: mapping of property names to modification arrays, - * retrieved from the intended player's TechnologyManager. - * entityTemplateData: raw entity template object. - * propertyName: name of the tech modification to apply. - * propertyValue: original value of property to be modified. + * @param currentTechModifications Object with mapping of property names to + * modification arrays, retrieved from the intended player's TechnologyManager. + * @param classes Array contianing the class list of the template. + * @param propertyName String encoding the name of the value. + * @param propertyValue Number storing the original value. Can also be + * non-numberic, but then only "replace" techs can be supported. */ -function GetTechModifiedProperty(currentTechModifications, entityTemplateData, propertyName, propertyValue) +function GetTechModifiedProperty(currentTechModifications, classes, propertyName, propertyValue) { - // Get all modifications to this value - var modifications = currentTechModifications[propertyName]; - if (!modifications) // no modifications so return the original value - return propertyValue; + let modifications = currentTechModifications[propertyName] || []; - // TODO: will we ever need the full template? - // Get the classes which this entity template belongs to - var classes = []; - if (entityTemplateData && entityTemplateData.Identity) - classes = GetIdentityClasses(entityTemplateData.Identity); + let multiply = 1; + let add = 0; - var retValue = propertyValue; - - for (var i in modifications) + for (let modification of modifications) { - var modification = modifications[i]; - if (DoesModificationApply(modification, classes)) - { - // We found a match, apply the modification - - // Nothing is cumulative so that ordering doesn't matter as much as possible - if (modification.multiply) - retValue += (modification.multiply - 1) * propertyValue; - else if (modification.add) - retValue += modification.add; - else if (modification.replace !== undefined) // This will depend on ordering because there is no choice - retValue = modification.replace; - else - warn("GetTechModifiedProperty: modification format not recognised (modifying " + propertyName + "): " + uneval(modification)); - } + if (!DoesModificationApply(modification, classes)) + continue; + if (modification.replace !== undefined) + return modification.replace; + if (modification.multiply) + multiply *= modification.multiply; + else if (modification.add) + add += modification.add; + else + warn("GetTechModifiedProperty: modification format not recognised (modifying " + propertyName + "): " + uneval(modification)); } - return retValue; + // Note, some components pass non-numeric values (for which only the "replace" modification makes sense) + if (typeof propertyValue == "number") + return propertyValue * multiply + add; + return propertyValue; } /** diff --git a/binaries/data/mods/public/simulation/components/TechnologyManager.js b/binaries/data/mods/public/simulation/components/TechnologyManager.js index 31a466ea5c..11e96c255c 100644 --- a/binaries/data/mods/public/simulation/components/TechnologyManager.js +++ b/binaries/data/mods/public/simulation/components/TechnologyManager.js @@ -377,13 +377,11 @@ TechnologyManager.prototype.ApplyModifications = function(valueName, curValue, e if (!this.modificationCache[valueName][ent] || this.modificationCache[valueName][ent].origValue != curValue) { - this.modificationCache[valueName][ent] = {"origValue": curValue}; - var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); - var templateName = cmpTemplateManager.GetCurrentTemplateName(ent); - // Ensure that preview or construction entites have the same properties as the final building - if (templateName.indexOf("preview|") > -1 || templateName.indexOf("construction|") > -1 ) - templateName = templateName.slice(templateName.indexOf("|") + 1); - this.modificationCache[valueName][ent].newValue = GetTechModifiedProperty(this.modifications, cmpTemplateManager.GetTemplate(templateName), valueName, curValue); + this.modificationCache[valueName][ent] = { "origValue": curValue }; + let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); + if (!cmpIdentity) + return curValue; + this.modificationCache[valueName][ent].newValue = GetTechModifiedProperty(this.modifications, cmpIdentity.GetClassesList(), valueName, curValue); } return this.modificationCache[valueName][ent].newValue; @@ -392,7 +390,9 @@ TechnologyManager.prototype.ApplyModifications = function(valueName, curValue, e // Alternative version of ApplyModifications, applies to templates instead of entities TechnologyManager.prototype.ApplyModificationsTemplate = function(valueName, curValue, template) { - return GetTechModifiedProperty(this.modifications, template, valueName, curValue); + if (!template || !template.Identity) + return curValue; + return GetTechModifiedProperty(this.modifications, GetIdentityClasses(template.Identity), valueName, curValue); }; // Marks a technology as being queued for research diff --git a/binaries/data/mods/public/simulation/data/technologies/elite_unit_bonus.json b/binaries/data/mods/public/simulation/data/technologies/elite_unit_bonus.json index b4e3c2cfed..afe3519cd4 100644 --- a/binaries/data/mods/public/simulation/data/technologies/elite_unit_bonus.json +++ b/binaries/data/mods/public/simulation/data/technologies/elite_unit_bonus.json @@ -6,7 +6,7 @@ {"value": "Armour/Pierce", "add": 1 }, {"value": "Armour/Crush", "add": 1 }, {"value": "Attack/Capture/Value", "add": 0.4 }, - {"value": "ResourceGatherer/BaseSpeed", "multiply": 0.75 }, + {"value": "ResourceGatherer/BaseSpeed", "multiply": 0.5 }, {"value": "UnitMotion/WalkSpeed", "add": 0.5, "affects": "Infantry"}, {"value": "UnitMotion/WalkSpeed", "add": 1, "affects": "Cavalry" }, {"value": "Attack/Ranged/MaxRange", "add": 4, "affects": "Ranged" },