Index: binaries/data/mods/public/globalscripts/Templates.js =================================================================== --- binaries/data/mods/public/globalscripts/Templates.js +++ binaries/data/mods/public/globalscripts/Templates.js @@ -166,11 +166,13 @@ { ret.armour = {}; for (let damageType of damageTypes.GetTypes()) - ret.armour[damageType] = getEntityValue("Armour/" + damageType); + ret.armour[damageType] = template.Armour[damageType] ? getEntityValue("Armour/" + damageType) : 0; } if (template.Attack) { + // Cache the damageTypes for they will be called often. + let allDamageTypes = damageTypes.GetTypes(); ret.attack = {}; for (let type in template.Attack) { @@ -189,8 +191,8 @@ "maxRange": getAttackStat("MaxRange"), "elevationBonus": getAttackStat("ElevationBonus") }; - for (let damageType of damageTypes.GetTypes()) - ret.attack[type][damageType] = getAttackStat(damageType); + for (let damageType of allDamageTypes) + ret.attack[type][damageType] = template.Attack[type][damageType] ? getAttackStat(damageType) : 0; ret.attack[type].elevationAdaptedRange = Math.sqrt(ret.attack[type].maxRange * (2 * ret.attack[type].elevationBonus + ret.attack[type].maxRange)); @@ -204,8 +206,8 @@ "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 of allDamageTypes) + ret.attack[type].splash[damageType] = template.Attack[type].Splash[damageType] ? getAttackStat("Splash/" + damageType) : 0; } } } @@ -216,7 +218,7 @@ "friendlyFire": template.DeathDamage.FriendlyFire != "false" }; for (let damageType of damageTypes.GetTypes()) - ret.deathDamage[damageType] = getEntityValue("DeathDamage/" + damageType); + ret.deathDamage[damageType] = template.DeathDamage[damageType] ? getEntityValue("DeathDamage/" + damageType) : 0; } 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/ai/common-api/damages.js =================================================================== --- /dev/null +++ binaries/data/mods/public/simulation/ai/common-api/damages.js @@ -0,0 +1 @@ +DamageTypes = new DamageTypes(); Index: binaries/data/mods/public/simulation/ai/common-api/entity.js =================================================================== --- binaries/data/mods/public/simulation/ai/common-api/entity.js +++ binaries/data/mods/public/simulation/ai/common-api/entity.js @@ -201,11 +201,11 @@ if (!this.get("Armour")) return undefined; - return { - "Hack": +this.get("Armour/Hack"), - "Pierce": +this.get("Armour/Pierce"), - "Crush": +this.get("Armour/Crush") - }; + let armours = {}; + for (let damageType of DamageTypes.GetTypes()) + armours[damageType] = +this.get("Armour/" + damageType) || 0; + + return armours; }, "attackTypes": function() { @@ -232,11 +232,11 @@ if (!this.get("Attack/" + type +"")) return undefined; - return { - "Hack": +(this.get("Attack/" + type + "/Hack") || 0), - "Pierce": +(this.get("Attack/" + type + "/Pierce") || 0), - "Crush": +(this.get("Attack/" + type + "/Crush") || 0) - }; + let damages = {}; + for (let damageType of DamageTypes.GetTypes()) + damages[damageType] = +this.get("Attack/" + type + "/" + damageType) || 0; + + return damages; }, "captureStrength": function() { 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 @@ -77,7 +77,7 @@ let ret = {}; for (let damageType of DamageTypes.GetTypes()) - ret[damageType] = applyMods(damageType, foundation); + ret[damageType] = this.template[damageType] ? applyMods(damageType, foundation) : 0; 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 @@ -455,7 +455,7 @@ let ret = {}; for (let damageType of DamageTypes.GetTypes()) - ret[damageType] = applyMods(damageType); + ret[damageType] = template[damageType] ? applyMods(damageType) : 0; 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 @@ -48,7 +48,7 @@ let ret = {}; for (let damageType of DamageTypes.GetTypes()) - ret[damageType] = applyMods(damageType); + ret[damageType] = this.template[damageType] ? applyMods(damageType) : 0; 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,24 @@ +/** + * Builds a RelaxRNG schema based on currently valid elements. + * + * To prevent validation errors, disabled damage types are included in the schema. + * + * @param {string} helptext - Text displayed as help + * @return {string} - RelaxNG schema string + */ DamageTypes.prototype.BuildSchema = function(helptext = "") { - return this.GetTypes().reduce((schema, type) => - schema + "", - ""); + let damageTypes = this.GetTypes(); + let schema = ""; + for (let damageType of damageTypes) + schema += + "" + + "" + + "" + + "" + + ""; + + return "" + schema + ""; }; DamageTypes = new DamageTypes();