Index: binaries/data/mods/public/globalscripts/Templates.js =================================================================== --- binaries/data/mods/public/globalscripts/Templates.js +++ binaries/data/mods/public/globalscripts/Templates.js @@ -153,6 +153,9 @@ */ function GetTemplateDataHelper(template, player, auraTemplates, resources, damageTypes, modifiers={}) { + // Cache the damageTypes for they will be called often. + let AllDamageTypes = DamageTypes.GetTypes(); + // Return data either from template (in tech tree) or sim state (ingame). // @param {string} value_path - Route to the value within the template. // @param {string} mod_key - Modification key, if not the same as the value_path. @@ -165,8 +168,9 @@ if (template.Armour) { ret.armour = {}; - for (let damageType of damageTypes.GetTypes()) - ret.armour[damageType] = getEntityValue("Armour/" + damageType); + for (let damageType in template.Armour) + if (AllDamageTypes.some(x => x == damageType)) + ret.armour[damageType] = getEntityValue("Armour/" + damageType); } if (template.Attack) @@ -189,8 +193,9 @@ "maxRange": getAttackStat("MaxRange"), "elevationBonus": getAttackStat("ElevationBonus") }; - for (let damageType of damageTypes.GetTypes()) - ret.attack[type][damageType] = getAttackStat(damageType); + for (let damageType in template.Attack[type]) + if (AllDamageTypes.some(x => x == damageType)) + ret.attack[type][damageType] = getAttackStat(damageType); ret.attack[type].elevationAdaptedRange = Math.sqrt(ret.attack[type].maxRange * (2 * ret.attack[type].elevationBonus + ret.attack[type].maxRange)); @@ -204,8 +209,9 @@ "friendlyFire": template.Attack[type].Splash.FriendlyFire != "false", "shape": template.Attack[type].Splash.Shape }; - for (let damageType of damageTypes.GetTypes()) - ret.attack[type].splash[damageType] = getAttackStat("Splash/" + damageType); + for (let damageType in template.Attack[type].Splash) + if (AllDamageTypes.some(x => x == damageType)) + ret.attack[type].splash[damageType] = getAttackStat("Splash/" + damageType); } } } @@ -215,8 +221,9 @@ ret.deathDamage = { "friendlyFire": template.DeathDamage.FriendlyFire != "false" }; - for (let damageType of damageTypes.GetTypes()) - ret.deathDamage[damageType] = getEntityValue("DeathDamage/" + damageType); + for (let damageType in template.DeathDamage) + if (AllDamageTypes.some(x => x == damageType)) + ret.deathDamage[damageType] = getEntityValue("DeathDamage/" + damageType); } if (template.Auras && auraTemplates) Index: binaries/data/mods/public/gui/common/tooltips.js =================================================================== --- binaries/data/mods/public/gui/common/tooltips.js +++ binaries/data/mods/public/gui/common/tooltips.js @@ -219,14 +219,14 @@ return sprintf(translate("%(label)s %(details)s"), { "label": headerFont(translate("Armor:")), "details": - Object.keys(template.armour).map( + g_DamageTypes.GetTypes().map( dmgType => sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), { - "damage": template.armour[dmgType].toFixed(1), + "damage": +(template.armour[dmgType] || 0).toFixed(1), "damageType": unitFont(translateWithContext("damage type", g_DamageTypes.GetNames()[dmgType])), "armorPercentage": '[font="sans-10"]' + sprintf(translate("(%(armorPercentage)s)"), { - "armorPercentage": armorLevelToPercentageString(template.armour[dmgType]) + "armorPercentage": armorLevelToPercentageString(+(template.armour[dmgType] || 0)) }) + '[/font]' }) ).join(commaFont(translate(", "))) @@ -239,11 +239,13 @@ return '[font="sans-12"]' + translate("(None)") + '[/font]'; return g_DamageTypes.GetTypes().filter( - dmgType => dmg[dmgType]).map( - dmgType => sprintf(translate("%(damage)s %(damageType)s"), { - "damage": dmg[dmgType].toFixed(1), - "damageType": unitFont(translateWithContext("damage type", g_DamageTypes.GetNames()[dmgType])) - })).join(commaFont(translate(", "))); + dmgType => !!dmg[dmgType]).map( + dmgType => sprintf(translate("%(damage)s %(damageType)s"), { + "damage": dmg[dmgType].toFixed(1), + "damageType": unitFont(translateWithContext("damage type", g_DamageTypes.GetNames()[dmgType])) + } + ) + ).join(commaFont(translate(", "))); } function getAttackTooltip(template) Index: binaries/data/mods/public/simulation/components/Armour.js =================================================================== --- binaries/data/mods/public/simulation/components/Armour.js +++ binaries/data/mods/public/simulation/components/Armour.js @@ -76,8 +76,9 @@ var foundation = Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation; let ret = {}; - for (let damageType of DamageTypes.GetTypes()) - ret[damageType] = applyMods(damageType, foundation); + for (let damageType in this.template) + if (DamageTypes.GetTypes().some(x => x == damageType)) + ret[damageType] = applyMods(damageType, foundation); return ret; }; Index: binaries/data/mods/public/simulation/components/Attack.js =================================================================== --- binaries/data/mods/public/simulation/components/Attack.js +++ binaries/data/mods/public/simulation/components/Attack.js @@ -454,8 +454,9 @@ return { "value": applyMods("Value") }; let ret = {}; - for (let damageType of DamageTypes.GetTypes()) - ret[damageType] = applyMods(damageType); + for (let damageType in template) + if (DamageTypes.GetTypes().some(x => x == damageType)) + ret[damageType] = applyMods(damageType); return ret; }; Index: binaries/data/mods/public/simulation/components/DeathDamage.js =================================================================== --- binaries/data/mods/public/simulation/components/DeathDamage.js +++ binaries/data/mods/public/simulation/components/DeathDamage.js @@ -47,8 +47,9 @@ ApplyValueModificationsToEntity("DeathDamage/" + damageType, +(this.template[damageType] || 0), this.entity); let ret = {}; - for (let damageType of DamageTypes.GetTypes()) - ret[damageType] = applyMods(damageType); + for (let damageType in this.template) + if (DamageTypes.GetTypes().some(x => x == damageType)) + ret[damageType] = applyMods(damageType); return ret; }; Index: binaries/data/mods/public/simulation/helpers/DamageTypes.js =================================================================== --- binaries/data/mods/public/simulation/helpers/DamageTypes.js +++ binaries/data/mods/public/simulation/helpers/DamageTypes.js @@ -1,8 +1,60 @@ -DamageTypes.prototype.BuildSchema = function(helptext = "") +/** + * Builds a RelaxRNG schema based on currently valid elements. + * + * To prevent validation errors, disabled resources are included in the schema. + * + * @param {string} helptext - Text displayed as help? + * @param additional - Array of additional data elements. Time, xp, treasure, etc. + * @param subtypes - If true, damageType subtypes will be included as well. + * @return RelaxNG schema string + */ +DamageTypes.prototype.BuildSchema = function(helptext = "", additional = [], subtypes = false) { - return this.GetTypes().reduce((schema, type) => - schema + "", - ""); + let datatype = ""; + + let damageTypes = this.GetTypes(); + let schema = ""; + for (let damageType of damageTypes.concat(additional)) + schema += + "" + + "" + + ""; + + if (!subtypes) + return "" + schema + ""; + + for (let damageType of damageTypes) + for (let damageSubType in damageType.subtypes) + schema += + "" + + "" + + datatype + + "" + + ""; + + return "" + schema + ""; +}; + +/** + * Builds the value choices for a RelaxNG `` object, based on currently valid resources. + * + * @oaram subtypes - If set to true, the choices returned will be damageType subtypes, rather than main types + * @return String of RelaxNG Schema `` values. + */ +DamageTypes.prototype.BuildChoicesSchema = function(subtypes = false) +{ + let schema = ""; + let damageTypes = this.GetTypes(); + + if (!subtypes) + for (let damageType of damageTypes) + schema += "" + damageType + ""; + else + for (let damageType of damageTypes) + for (let subtype in damageType.subtypes) + schema += "" + damageType.code + "." + subtype + ""; + + return "" + schema + ""; }; DamageTypes = new DamageTypes();