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 @@ -207,7 +207,7 @@ function armorLevelToPercentageString(level) { return sprintf(translate("%(percentage)s%%"), { - "percentage": (100 - Math.round(Math.pow(0.9, level) * 100)) + "percentage": level == "Infinity" ? 100 : (100 - Math.round(Math.pow(0.9, level) * 100)) }); } @@ -221,7 +221,7 @@ "details": Object.keys(template.armour).map( dmgType => sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), { - "damage": template.armour[dmgType].toFixed(1), + "damage": template.armour[dmgType] == "Infinity" ? "∞" : template.armour[dmgType].toFixed(1), "damageType": unitFont(translateWithContext("damage type", g_DamageTypes.GetNames()[dmgType])), "armorPercentage": '[font="sans-10"]' + 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 @@ -34,46 +34,52 @@ /** * Take damage according to the entity's armor. - * @param {Object} strengths - { "hack": number, "pierce": number, "crush": number } or something like that. + * @param {Object} attackStrengths - { "hack": number, "pierce": number, "crush": number } or something like that. * @param {number} multiplier - the damage multiplier. * Returns object of the form { "killed": false, "change": -12 }. */ -Armour.prototype.TakeDamage = function(strengths, multiplier = 1) +Armour.prototype.TakeDamage = function(attackStrengths, multiplier = 1) { if (this.invulnerable) return { "killed": false, "change": 0 }; // Adjust damage values based on armour; exponential armour: damage = attack * 0.9^armour - var armourStrengths = this.GetArmourStrengths(); + let armourStrengths = this.GetArmourStrengths(); // Total is sum of individual damages // Don't bother rounding, since HP is no longer integral. - var total = 0; - for (let type in strengths) - total += strengths[type] * multiplier * Math.pow(0.9, armourStrengths[type] || 0); + let total = 0; + for (let type in attackStrengths) + { + if (armourStrengths[type] == "Infinity") + continue; + + total += attackStrengths[type] * multiplier * Math.pow(0.9, armourStrengths[type] || 0); + } // Reduce health - var cmpHealth = Engine.QueryInterface(this.entity, IID_Health); + let cmpHealth = Engine.QueryInterface(this.entity, IID_Health); return cmpHealth.Reduce(total); }; Armour.prototype.GetArmourStrengths = function() { // Work out the armour values with technology effects - var applyMods = (type, foundation) => { - var strength; + let applyMods = (type, foundation) => { + let strength; if (foundation) { - strength = +this.template.Foundation[type]; + strength = this.template.Foundation[type]; type = "Foundation/" + type; } else - strength = +this.template[type]; + strength = this.template[type]; - return ApplyValueModificationsToEntity("Armour/" + type, strength, this.entity); + return strength == "Infinity" ? "Infinity" : + ApplyValueModificationsToEntity("Armour/" + type, +strength, this.entity); }; - var foundation = Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation; + let foundation = Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation; let ret = {}; for (let damageType of DamageTypes.GetTypes()) 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 @@ -315,6 +315,11 @@ // reach each other, no matter how close they come. let heightDiff = Math.abs(cmpThisPosition.GetHeightOffset() - cmpTargetPosition.GetHeightOffset()); + let armourStrengths; + let cmpTargetArmour = Engine.QueryInterface(target, IID_DamageReceiver); + if (cmpTargetArmour) + armourStrengths = cmpTargetArmour.GetArmourStrengths(); + for (let type of types) { if (type != "Capture" && (!cmpEntityPlayer.IsEnemy(targetOwner) || !cmpHealth || !cmpHealth.GetHitpoints())) @@ -326,6 +331,22 @@ if (heightDiff > this.GetRange(type).max) continue; + if (type != "Capture") + { + let attackStrengths = this.GetAttackStrengths(type); + let canDamage = false; + for (let damageType in attackStrengths) + { + if (attackStrengths[damageType] != 0 && armourStrengths[damageType] != "Infinity") + { + canDamage = true; + break; + } + } + if (!canDamage) + return false; + } + let restrictedClasses = this.GetRestrictedClasses(type); if (!restrictedClasses.length) return true; 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,7 +1,7 @@ DamageTypes.prototype.BuildSchema = function(helptext = "") { return "" + this.GetTypes().reduce((schema, type) => - schema + "", + schema + "Infinity", "") + ""; };