diff --git a/src/app/components/Defence.jsx b/src/app/components/Defence.jsx
index 7d6f5e78..545e6eac 100644
--- a/src/app/components/Defence.jsx
+++ b/src/app/components/Defence.jsx
@@ -61,50 +61,90 @@ export default class Defence extends TranslatedComponent {
const shieldSourcesData = [];
const effectiveShieldData = [];
const shieldDamageTakenData = [];
- const shieldTooltipDetails = [];
- const shieldAbsoluteTooltipDetails = [];
- const shieldExplosiveTooltipDetails = [];
- const shieldKineticTooltipDetails = [];
- const shieldThermalTooltipDetails = [];
+ const shieldSourcesTt = [];
+ const shieldDamageTakenAbsoluteTt = [];
+ const shieldDamageTakenExplosiveTt = [];
+ const shieldDamageTakenKineticTt = [];
+ const shieldDamageTakenThermalTt = [];
+ const effectiveShieldAbsoluteTt = [];
+ const effectiveShieldExplosiveTt = [];
+ const effectiveShieldKineticTt = [];
+ const effectiveShieldThermalTt = [];
let maxEffectiveShield = 0;
if (shield.total) {
shieldSourcesData.push({ value: Math.round(shield.generator), label: translate('generator') });
shieldSourcesData.push({ value: Math.round(shield.boosters), label: translate('boosters') });
shieldSourcesData.push({ value: Math.round(shield.cells), label: translate('cells') });
- if (shield.generator > 0) shieldTooltipDetails.push(
{translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}
);
- if (shield.boosters > 0) shieldTooltipDetails.push({translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}
);
- if (shield.cells > 0) shieldTooltipDetails.push({translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}
);
+ if (shield.generator > 0) {
+ shieldSourcesTt.push({translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}
);
+ effectiveShieldAbsoluteTt.push({translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}
);
+ effectiveShieldExplosiveTt.push({translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}
);
+ effectiveShieldKineticTt.push({translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}
);
+ effectiveShieldThermalTt.push({translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}
);
+ if (shield.boosters > 0) {
+ shieldSourcesTt.push({translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}
);
+ effectiveShieldAbsoluteTt.push({translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}
);
+ effectiveShieldExplosiveTt.push({translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}
);
+ effectiveShieldKineticTt.push({translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}
);
+ effectiveShieldThermalTt.push({translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}
);
+ }
- shieldAbsoluteTooltipDetails.push({translate('generator') + ' ' + formats.pct1(shield.absolute.generator)}
);
- shieldAbsoluteTooltipDetails.push({translate('boosters') + ' ' + formats.pct1(shield.absolute.boosters)}
);
- shieldAbsoluteTooltipDetails.push({translate('power distributor') + ' ' + formats.pct1(shield.absolute.sys)}
);
+ if (shield.cells > 0) {
+ shieldSourcesTt.push({translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}
);
+ effectiveShieldAbsoluteTt.push({translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}
);
+ effectiveShieldExplosiveTt.push({translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}
);
+ effectiveShieldKineticTt.push({translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}
);
+ effectiveShieldThermalTt.push({translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}
);
+ }
- shieldExplosiveTooltipDetails.push({translate('generator') + ' ' + formats.pct1(shield.explosive.generator)}
);
- shieldExplosiveTooltipDetails.push({translate('boosters') + ' ' + formats.pct1(shield.explosive.boosters)}
);
- shieldExplosiveTooltipDetails.push({translate('power distributor') + ' ' + formats.pct1(shield.explosive.sys)}
);
+ // Add effective shield from resistances
+ const rawMj = shield.generator + shield.boosters + shield.cells;
+ const explosiveMj = rawMj / (shield.explosive.generator * shield.explosive.boosters) - rawMj;
+ if (explosiveMj != 0) effectiveShieldExplosiveTt.push({translate('resistance') + ' ' + formats.int(explosiveMj)}{units.MJ}
);
+ const kineticMj = rawMj / (shield.kinetic.generator * shield.kinetic.boosters) - rawMj;
+ if (kineticMj != 0) effectiveShieldKineticTt.push({translate('resistance') + ' ' + formats.int(kineticMj)}{units.MJ}
);
+ const thermalMj = rawMj / (shield.thermal.generator * shield.thermal.boosters) - rawMj;
+ if (thermalMj != 0) effectiveShieldThermalTt.push({translate('resistance') + ' ' + formats.int(thermalMj)}{units.MJ}
);
- shieldKineticTooltipDetails.push({translate('generator') + ' ' + formats.pct1(shield.kinetic.generator)}
);
- shieldKineticTooltipDetails.push({translate('boosters') + ' ' + formats.pct1(shield.kinetic.boosters)}
);
- shieldKineticTooltipDetails.push({translate('power distributor') + ' ' + formats.pct1(shield.kinetic.sys)}
);
+ // Add effective shield from power distributor SYS pips
+ if (shield.absolute.sys != 1) {
+ effectiveShieldAbsoluteTt.push({translate('power distributor') + ' ' + formats.int(rawMj / shield.absolute.sys - rawMj)}{units.MJ}
);
+ effectiveShieldExplosiveTt.push({translate('power distributor') + ' ' + formats.int(rawMj / shield.explosive.sys - rawMj)}{units.MJ}
);
+ effectiveShieldKineticTt.push({translate('power distributor') + ' ' + formats.int(rawMj / shield.kinetic.sys - rawMj)}{units.MJ}
);
+ effectiveShieldThermalTt.push({translate('power distributor') + ' ' + formats.int(rawMj / shield.thermal.sys - rawMj)}{units.MJ}
);
+ }
+ }
- shieldThermalTooltipDetails.push({translate('generator') + ' ' + formats.pct1(shield.thermal.generator)}
);
- shieldThermalTooltipDetails.push({translate('boosters') + ' ' + formats.pct1(shield.thermal.boosters)}
);
- shieldThermalTooltipDetails.push({translate('power distributor') + ' ' + formats.pct1(shield.thermal.sys)}
);
+ shieldDamageTakenAbsoluteTt.push({translate('generator') + ' ' + formats.pct1(shield.absolute.generator)}
);
+ shieldDamageTakenAbsoluteTt.push({translate('boosters') + ' ' + formats.pct1(shield.absolute.boosters)}
);
+ shieldDamageTakenAbsoluteTt.push({translate('power distributor') + ' ' + formats.pct1(shield.absolute.sys)}
);
+
+ shieldDamageTakenExplosiveTt.push({translate('generator') + ' ' + formats.pct1(shield.explosive.generator)}
);
+ shieldDamageTakenExplosiveTt.push({translate('boosters') + ' ' + formats.pct1(shield.explosive.boosters)}
);
+ shieldDamageTakenExplosiveTt.push({translate('power distributor') + ' ' + formats.pct1(shield.explosive.sys)}
);
+
+ shieldDamageTakenKineticTt.push({translate('generator') + ' ' + formats.pct1(shield.kinetic.generator)}
);
+ shieldDamageTakenKineticTt.push({translate('boosters') + ' ' + formats.pct1(shield.kinetic.boosters)}
);
+ shieldDamageTakenKineticTt.push({translate('power distributor') + ' ' + formats.pct1(shield.kinetic.sys)}
);
+
+ shieldDamageTakenThermalTt.push({translate('generator') + ' ' + formats.pct1(shield.thermal.generator)}
);
+ shieldDamageTakenThermalTt.push({translate('boosters') + ' ' + formats.pct1(shield.thermal.boosters)}
);
+ shieldDamageTakenThermalTt.push({translate('power distributor') + ' ' + formats.pct1(shield.thermal.sys)}
);
const effectiveAbsoluteShield = shield.total / shield.absolute.total;
- effectiveShieldData.push({ value: Math.round(effectiveAbsoluteShield), label: translate('absolute') });
+ effectiveShieldData.push({ value: Math.round(effectiveAbsoluteShield), label: translate('absolute'), tooltip: effectiveShieldAbsoluteTt });
const effectiveExplosiveShield = shield.total / shield.explosive.total;
- effectiveShieldData.push({ value: Math.round(effectiveExplosiveShield), label: translate('explosive') });
+ effectiveShieldData.push({ value: Math.round(effectiveExplosiveShield), label: translate('explosive'), tooltip: effectiveShieldExplosiveTt });
const effectiveKineticShield = shield.total / shield.kinetic.total;
- effectiveShieldData.push({ value: Math.round(effectiveKineticShield), label: translate('kinetic') });
+ effectiveShieldData.push({ value: Math.round(effectiveKineticShield), label: translate('kinetic'), tooltip: effectiveShieldKineticTt });
const effectiveThermalShield = shield.total / shield.thermal.total;
- effectiveShieldData.push({ value: Math.round(effectiveThermalShield), label: translate('thermal') });
+ effectiveShieldData.push({ value: Math.round(effectiveThermalShield), label: translate('thermal'), tooltip: effectiveShieldThermalTt });
- shieldDamageTakenData.push({ value: Math.round(shield.absolute.total * 100), label: translate('absolute'), tooltip: shieldAbsoluteTooltipDetails });
- shieldDamageTakenData.push({ value: Math.round(shield.explosive.total * 100), label: translate('explosive'), tooltip: shieldExplosiveTooltipDetails });
- shieldDamageTakenData.push({ value: Math.round(shield.kinetic.total * 100), label: translate('kinetic'), tooltip: shieldKineticTooltipDetails });
- shieldDamageTakenData.push({ value: Math.round(shield.thermal.total * 100), label: translate('thermal'), tooltip: shieldThermalTooltipDetails });
+ shieldDamageTakenData.push({ value: Math.round(shield.absolute.total * 100), label: translate('absolute'), tooltip: shieldDamageTakenAbsoluteTt });
+ shieldDamageTakenData.push({ value: Math.round(shield.explosive.total * 100), label: translate('explosive'), tooltip: shieldDamageTakenExplosiveTt });
+ shieldDamageTakenData.push({ value: Math.round(shield.kinetic.total * 100), label: translate('kinetic'), tooltip: shieldDamageTakenKineticTt });
+ shieldDamageTakenData.push({ value: Math.round(shield.thermal.total * 100), label: translate('thermal'), tooltip: shieldDamageTakenThermalTt });
maxEffectiveShield = Math.max(shield.total / shield.absolute.max, shield.total / shield.explosive.max, shield.total / shield.kinetic.max, shield.total / shield.thermal.max);
}
@@ -113,41 +153,62 @@ export default class Defence extends TranslatedComponent {
armourSourcesData.push({ value: Math.round(armour.bulkheads), label: translate('bulkheads') });
armourSourcesData.push({ value: Math.round(armour.reinforcement), label: translate('reinforcement') });
- const armourTooltipDetails = [];
- if (armour.bulkheads > 0) armourTooltipDetails.push({translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}
);
- if (armour.reinforcement > 0) armourTooltipDetails.push({translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}
);
+ const armourSourcesTt = [];
+ const effectiveArmourAbsoluteTt = [];
+ const effectiveArmourExplosiveTt = [];
+ const effectiveArmourKineticTt = [];
+ const effectiveArmourThermalTt = [];
+ if (armour.bulkheads > 0) {
+ armourSourcesTt.push({translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}
);
+ effectiveArmourAbsoluteTt.push({translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}
);
+ effectiveArmourExplosiveTt.push({translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}
);
+ effectiveArmourKineticTt.push({translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}
);
+ effectiveArmourThermalTt.push({translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}
);
+ if (armour.reinforcement > 0) {
+ armourSourcesTt.push({translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}
);
+ effectiveArmourAbsoluteTt.push({translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}
);
+ effectiveArmourExplosiveTt.push({translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}
);
+ effectiveArmourKineticTt.push({translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}
);
+ effectiveArmourThermalTt.push({translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}
);
+ }
+ }
- const armourAbsoluteTooltipDetails = [];
- armourAbsoluteTooltipDetails.push({translate('bulkheads') + ' ' + formats.pct1(armour.absolute.bulkheads)}
);
- armourAbsoluteTooltipDetails.push({translate('reinforcement') + ' ' + formats.pct1(armour.absolute.reinforcement)}
);
+ const rawArmour = armour.bulkheads + armour.reinforcement;
- const armourExplosiveTooltipDetails = [];
- armourExplosiveTooltipDetails.push({translate('bulkheads') + ' ' + formats.pct1(armour.explosive.bulkheads)}
);
- armourExplosiveTooltipDetails.push({translate('reinforcement') + ' ' + formats.pct1(armour.explosive.reinforcement)}
);
+ const armourDamageTakenTt = [];
+ armourDamageTakenTt.push({translate('bulkheads') + ' ' + formats.pct1(armour.absolute.bulkheads)}
);
+ armourDamageTakenTt.push({translate('reinforcement') + ' ' + formats.pct1(armour.absolute.reinforcement)}
);
- const armourKineticTooltipDetails = [];
- armourKineticTooltipDetails.push({translate('bulkheads') + ' ' + formats.pct1(armour.kinetic.bulkheads)}
);
- armourKineticTooltipDetails.push({translate('reinforcement') + ' ' + formats.pct1(armour.kinetic.reinforcement)}
);
+ const armourDamageTakenExplosiveTt = [];
+ armourDamageTakenExplosiveTt.push({translate('bulkheads') + ' ' + formats.pct1(armour.explosive.bulkheads)}
);
+ armourDamageTakenExplosiveTt.push({translate('reinforcement') + ' ' + formats.pct1(armour.explosive.reinforcement)}
);
+ if (armour.explosive.bulkheads * armour.explosive.reinforcement != 1) effectiveArmourExplosiveTt.push({translate('resistance') + ' ' + formats.int(rawArmour / (armour.explosive.bulkheads * armour.explosive.reinforcement) - rawArmour)}
);
- const armourThermalTooltipDetails = [];
- armourThermalTooltipDetails.push({translate('bulkheads') + ' ' + formats.pct1(armour.thermal.bulkheads)}
);
- armourThermalTooltipDetails.push({translate('reinforcement') + ' ' + formats.pct1(armour.thermal.reinforcement)}
);
+ const armourDamageTakenKineticTt = [];
+ armourDamageTakenKineticTt.push({translate('bulkheads') + ' ' + formats.pct1(armour.kinetic.bulkheads)}
);
+ armourDamageTakenKineticTt.push({translate('reinforcement') + ' ' + formats.pct1(armour.kinetic.reinforcement)}
);
+ if (armour.kinetic.bulkheads * armour.kinetic.reinforcement != 1) effectiveArmourKineticTt.push({translate('resistance') + ' ' + formats.int(rawArmour / (armour.kinetic.bulkheads * armour.kinetic.reinforcement) - rawArmour)}
);
+
+ const armourDamageTakenThermalTt = [];
+ armourDamageTakenThermalTt.push({translate('bulkheads') + ' ' + formats.pct1(armour.thermal.bulkheads)}
);
+ armourDamageTakenThermalTt.push({translate('reinforcement') + ' ' + formats.pct1(armour.thermal.reinforcement)}
);
+ if (armour.thermal.bulkheads * armour.thermal.reinforcement != 1) effectiveArmourThermalTt.push({translate('resistance') + ' ' + formats.int(rawArmour / (armour.thermal.bulkheads * armour.thermal.reinforcement) - rawArmour)}
);
const effectiveArmourData = [];
const effectiveAbsoluteArmour = armour.total / armour.absolute.total;
- effectiveArmourData.push({ value: Math.round(effectiveAbsoluteArmour), label: translate('absolute') });
+ effectiveArmourData.push({ value: Math.round(effectiveAbsoluteArmour), label: translate('absolute'), tooltip: effectiveArmourAbsoluteTt });
const effectiveExplosiveArmour = armour.total / armour.explosive.total;
- effectiveArmourData.push({ value: Math.round(effectiveExplosiveArmour), label: translate('explosive') });
+ effectiveArmourData.push({ value: Math.round(effectiveExplosiveArmour), label: translate('explosive'), tooltip: effectiveArmourExplosiveTt });
const effectiveKineticArmour = armour.total / armour.kinetic.total;
- effectiveArmourData.push({ value: Math.round(effectiveKineticArmour), label: translate('kinetic') });
+ effectiveArmourData.push({ value: Math.round(effectiveKineticArmour), label: translate('kinetic'), tooltip: effectiveArmourKineticTt });
const effectiveThermalArmour = armour.total / armour.thermal.total;
- effectiveArmourData.push({ value: Math.round(effectiveThermalArmour), label: translate('thermal') });
+ effectiveArmourData.push({ value: Math.round(effectiveThermalArmour), label: translate('thermal'), tooltip: effectiveArmourThermalTt });
const armourDamageTakenData = [];
- armourDamageTakenData.push({ value: Math.round(armour.absolute.total * 100), label: translate('absolute'), tooltip: armourAbsoluteTooltipDetails });
- armourDamageTakenData.push({ value: Math.round(armour.explosive.total * 100), label: translate('explosive'), tooltip: armourExplosiveTooltipDetails });
- armourDamageTakenData.push({ value: Math.round(armour.kinetic.total * 100), label: translate('kinetic'), tooltip: armourKineticTooltipDetails });
- armourDamageTakenData.push({ value: Math.round(armour.thermal.total * 100), label: translate('thermal'), tooltip: armourThermalTooltipDetails });
+ armourDamageTakenData.push({ value: Math.round(armour.absolute.total * 100), label: translate('absolute'), tooltip: armourDamageTakenTt });
+ armourDamageTakenData.push({ value: Math.round(armour.explosive.total * 100), label: translate('explosive'), tooltip: armourDamageTakenExplosiveTt });
+ armourDamageTakenData.push({ value: Math.round(armour.kinetic.total * 100), label: translate('kinetic'), tooltip: armourDamageTakenKineticTt });
+ armourDamageTakenData.push({ value: Math.round(armour.thermal.total * 100), label: translate('thermal'), tooltip: armourDamageTakenThermalTt });
return (
@@ -155,7 +216,7 @@ export default class Defence extends TranslatedComponent {
{translate('shield metrics')}
- {shieldTooltipDetails}
)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw shield strength')}
{formats.int(shield.total)}{units.MJ}
+ {shieldSourcesTt})} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw shield strength')}
{formats.int(shield.total)}{units.MJ}
{translate('PHRASE_TIME_TO_LOSE_SHIELDS')}
{shielddamage.totalsdps == 0 ? translate('ever') : formats.time(Calc.timeToDeplete(shield.total, shielddamage.totalsdps, shielddamage.totalseps, pd.getWeaponsCapacity(), pd.getWeaponsRechargeRate() * opponentWep / 4))}
{translate('PHRASE_TIME_TO_RECOVER_SHIELDS')}
{shield.recover === Math.Inf ? translate('never') : formats.time(shield.recover)}
{translate('PHRASE_TIME_TO_RECHARGE_SHIELDS')}
{shield.recharge === Math.Inf ? translate('never') : formats.time(shield.recharge)}
@@ -176,7 +237,7 @@ export default class Defence extends TranslatedComponent {
{translate('armour metrics')}
- {armourTooltipDetails}
)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw armour strength')}
{formats.int(armour.total)}
+ {armourSourcesTt})} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw armour strength')}
{formats.int(armour.total)}
{translate('PHRASE_TIME_TO_LOSE_ARMOUR')}
{armourdamage.totalsdps == 0 ? translate('ever') : formats.time(Calc.timeToDeplete(armour.total, armourdamage.totalsdps, armourdamage.totalseps, pd.getWeaponsCapacity(), pd.getWeaponsRechargeRate() * opponentWep / 4))}
{translate('raw module armour')}
{formats.int(armour.modulearmour)}
{translate('PHRASE_MODULE_PROTECTION_EXTERNAL')}
{formats.pct1(armour.moduleprotection / 2)}