Add 'Offence summary' and 'Defence summary' components

This commit is contained in:
Cmdr McDonald
2016-11-11 00:15:49 +00:00
parent cf6d32ea04
commit 87e903e473
7 changed files with 123 additions and 124 deletions

View File

@@ -12,3 +12,5 @@
* Ensure that retrofit tab only shows changed modules
* Fix import and export of ships with modifications, bump schema version to 4
* Enable boost display even if power distributor is disabled
* Calculate breakdown of ship offensive and defensive stats
* Add 'Offence summary' and 'Defence summary' components

View File

@@ -1,6 +1,7 @@
import React from 'react';
import cn from 'classnames';
import TranslatedComponent from './TranslatedComponent';
import { DamageKinetic, DamageThermal, DamageExplosive } from './SvgIcons';
/**
* Defence summary
@@ -28,62 +29,41 @@ export default class DefenceSummary extends TranslatedComponent {
let { formats, translate, units } = language;
let hide = tooltip.bind(null, null);
let sgClassNames = cn({ muted: !ship.findInternalByGroup('sg') });
return (
<div>
<h1>{translate('defence summary')}</h1>
<br/>
<table style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
<thead>
<tr>
<th rowSpan={2}>{translate('damage to')}</th>
<th colSpan={3}>{translate('damage from')}</th>
</tr>
<tr>
<th>{translate('explosive')}</th>
<th>{translate('kinetic')}</th>
<th>{translate('thermal')}</th>
</tr>
</thead>
<tbody>
{ ship.shield ?
<tr>
<td className='le {sgClassNames}'>{translate('shields')}</td>
<td className='ri {sgClassNames}'>{ship.shieldExplRes ? formats.pct(ship.shieldExplRes) : '-'}</td>
<td className='ri {sgClassNames}'>{ship.shieldKinRes ? formats.pct(ship.shieldKinRes) : '-'}</td>
<td className='ri {sgClassNames}'>{ship.shieldThermRes ? formats.pct(ship.shieldThermRes) : '-'}</td>
</tr> : null }
<tr>
<td className='le'>{translate('hull')}</td>
<td className='ri'>{formats.pct(ship.hullExplRes)}</td>
<td className='ri'>{formats.pct(ship.hullKinRes)}</td>
<td className='ri'>{formats.pct(ship.hullThermRes)}</td>
</tr>
</tbody>
</table>
<br />
{ ship.shield ?
<table style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
<thead>
<tr>
<th colSpan={3}>{translate('shields')}</th>
</tr>
<tr>
<th>{translate('strength')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_SG_RECOVER', { cap: 0 })} onMouseLeave={hide}>{translate('recovery')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_SG_RECHARGE', { cap: 0 })} onMouseLeave={hide}>{translate('recovery')}</th>
</tr>
</thead>
<span>
<h1>{translate('defence summary')}</h1>
<table className='summary' style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
<tbody>
{ship.shield ?
<tr>
<td className='ri'>{formats.int(ship.shield)} {units.MJ}</td>
<td className='ri'>{ship.shield ? formats.time(ship.calcShieldRecovery()) : '-'}</td>
<td className='ri'>{ship.shield ? formats.time(ship.calcShieldRecharge()) : '-'}</td>
<td colSpan='4' className='summary'><h2>{translate('shields')}: {formats.int(ship.shield)} {units.MJ}</h2></td>
</tr> : null }
{ship.shield ?
<tr>
<td className='le'>{translate('damage from')}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /> {formats.pct1(ship.shieldExplRes || 1)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /> {formats.pct1(ship.shieldKinRes || 1)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /> {formats.pct1(ship.shieldThermRes || 1)}</td>
</tr> : null }
{ ship.shield && ship.shieldCells ?
<tr>
<td colSpan='4'><h2>{translate('shield cells')}: {formats.int(ship.shieldCells)} {units.MJ}</h2></td>
</tr> : null }
<tr>
<td colSpan='4'><h2>{translate('armour')}: {formats.int(ship.armour)}</h2></td>
</tr>
<tr>
<td className='le'>{translate('damage from')}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /> {formats.pct1(ship.hullExplRes || 1)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /> {formats.pct1(ship.hullKinRes || 1)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /> {formats.pct1(ship.hullThermRes || 1)}</td>
</tr>
</tbody>
</table> : null }
</div>
</table>
</span>
);
}
}

View File

@@ -1,6 +1,7 @@
import React from 'react';
import cn from 'classnames';
import TranslatedComponent from './TranslatedComponent';
import { DamageKinetic, DamageThermal, DamageExplosive } from './SvgIcons';
/**
* Offence summary
@@ -29,75 +30,42 @@ export default class OffenceSummary extends TranslatedComponent {
let hide = tooltip.bind(null, null);
return (
<div>
<h1>{translate('offence summary')}</h1>
<br/>
<table style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
<thead>
<tr>
<th colSpan={4}>{translate('dps')}</th>
</tr>
<tr>
<th>{translate('explosive')}</th>
<th>{translate('kinetic')}</th>
<th>{translate('thermal')}</th>
<th>{translate('total')}</th>
</tr>
</thead>
<tbody>
<tr>
<td className='ri'>{formats.f1(ship.totalExplDps)}</td>
<td className='ri'>{formats.f1(ship.totalKinDps)}</td>
<td className='ri'>{formats.f1(ship.totalThermDps)}</td>
<td className='ri'>{formats.f1(ship.totalDps)}</td>
</tr>
</tbody>
</table>
<br/>
<table style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
<thead>
<tr>
<th colSpan={4}>{translate('sustained dps')}</th>
</tr>
<tr>
<th>{translate('explosive')}</th>
<th>{translate('kinetic')}</th>
<th>{translate('thermal')}</th>
<th>{translate('total')}</th>
</tr>
</thead>
<tbody>
<tr>
<td className='ri'>{formats.f1(ship.totalExplSDps)}</td>
<td className='ri'>{formats.f1(ship.totalKinSDps)}</td>
<td className='ri'>{formats.f1(ship.totalThermSDps)}</td>
<td className='ri'>{formats.f1(ship.totalSDps)}</td>
</tr>
</tbody>
</table>
<br/>
<table style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
<thead>
<tr>
<th colSpan={4}>{translate('dpe')}</th>
</tr>
<tr>
<th>{translate('explosive')}</th>
<th>{translate('kinetic')}</th>
<th>{translate('thermal')}</th>
<th>{translate('total')}</th>
</tr>
</thead>
<tbody>
<tr>
<td className='ri'>{formats.f1(ship.totalExplDpe)}</td>
<td className='ri'>{formats.f1(ship.totalKinDpe)}</td>
<td className='ri'>{formats.f1(ship.totalThermDpe)}</td>
<td className='ri'>{formats.f1(ship.totalDpe)}</td>
</tr>
</tbody>
</table>
</div>
<span>
<h1>{translate('offence summary')}</h1>
<table className='summary' style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
<tbody>
<tr>
<td colSpan='4' className='summary'><h2>{translate('dps')}: {formats.f1(ship.totalDps)}</h2></td>
</tr>
<tr>
<td className='le'>{translate('damage by')}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /> {formats.f1(ship.totalExplDps)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /> {formats.f1(ship.totalKinDps)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /> {formats.f1(ship.totalThermDps)}</td>
</tr>
<tr>
<td colSpan='4' className='summary'><h2>{translate('sdps')}: {formats.f1(ship.totalSDps)}</h2></td>
</tr>
<tr>
<td className='le'>{translate('damage by')}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /> {formats.f1(ship.totalExplSDps)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /> {formats.f1(ship.totalKinSDps)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /> {formats.f1(ship.totalThermSDps)}</td>
</tr>
<tr>
<td colSpan='4' className='summary'><h2>{translate('dpe')}: {formats.f1(ship.totalDpe)}</h2></td>
</tr>
<tr>
<td className='le'>{translate('damage by')}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /> {formats.f1(ship.totalExplDpe)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /> {formats.f1(ship.totalKinDpe)}</td>
<td className='ri' onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /> {formats.f1(ship.totalThermDpe)}</td>
</tr>
</tbody>
</table>
</span>
);
}
}

View File

@@ -92,14 +92,18 @@ export const terms = {
// Unit for seconds
secs: 's',
// Hardpoint abbreviations
// Weapon, offence and defence
dpe: 'Damage per MJ of energy',
dps: 'Damage per second',
sdps: 'Sustained damage per second',
dpssdps: 'Damage per second (sustained damage per second)',
eps: 'Energy per second',
epsseps: 'Energy per second (sustained energy per second)',
hps: 'Heat per second',
hpsshps: 'Heat per second (sustained heat per second)',
'damage by': 'Damage by',
'damage from': 'Damage from',
'shield cells': 'Shield cells',
// Modifications
ammo: 'Ammunition maximum',
@@ -134,6 +138,7 @@ export const terms = {
rof: 'Rate of fire',
shield: 'Shield',
shieldboost: 'Shield boost',
shieldreinforcement: 'Shield reinforcement',
spinup: 'Spin up time',
syscap: 'Systems capacity',
sysrate: 'Systems recharge rate',

View File

@@ -492,4 +492,20 @@ export default class Module {
return this._getModifiedValue('hullboost');
}
/**
* Get the shield reinforcement for this module, taking in to account modifications
* @return {Number} the shield reinforcement for this module
*/
getShieldReinforcement() {
return this._getModifiedValue('shieldreinforcement');
}
/**
* Get the cells for this module, taking in to account modifications
* @return {Number} the cells for this module
*/
getCells() {
return this._getModifiedValue('cells');
}
}

View File

@@ -236,9 +236,8 @@ export default class Ship {
sg = sgSlot.m;
}
// TODO obtain shield boost
// return Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sg, this.shieldMultiplier + (multiplierDelta || 0));
return Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sg, 0 + (multiplierDelta || 0));
// TODO Not accurate if the ship has modified shield boosters
return Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sg, 1 + (multiplierDelta || 0));
}
/**
@@ -442,6 +441,9 @@ export default class Ship {
} else if (name === 'hullboost' || name === 'hullreinforcement') {
m.setModValue(name, value);
this.recalculateArmour();
} else if (name === 'shieldreinforcement') {
m.setModValue(name, value);
this.recalculateShieldCells();
} else if (name === 'burst' || name === 'clip' || name === 'damage' || name === 'distdraw' || name === 'jitter' || name === 'piercing' || name === 'range' || name === 'reload' || name === 'rof' || name === 'thermload') {
m.setModValue(name, value);
this.recalculateDps();
@@ -479,6 +481,7 @@ export default class Ship {
this.ladenMass = 0;
this.armour = this.baseArmour;
this.shield = this.baseShieldStrength;
this.shieldCells = 0;
this.totalCost = this.m.incCost ? this.m.discountedCost : 0;
this.unladenMass = this.hullMass;
this.totalDpe = 0;
@@ -564,6 +567,7 @@ export default class Ship {
.updatePowerUsed()
.updateJumpStats()
.recalculateShield()
.recalculateShieldCells()
.recalculateArmour()
.recalculateDps()
.recalculateEps()
@@ -1097,6 +1101,24 @@ export default class Ship {
return this;
}
/**
* Update shield cells
* @return {this} The ship instance (for chaining operations)
*/
recalculateShieldCells() {
let shieldCells = 0;
for (let slot of this.internal) {
if (slot.m && slot.m.grp == 'scb') {
shieldCells += slot.m.getShieldReinforcement() * slot.m.getCells();
}
}
this.shieldCells = shieldCells;
return this;
}
/**
* Update armour and hull resistances
* @return {this} The ship instance (for chaining operations)

View File

@@ -56,3 +56,9 @@
height: 2em;
}
}
.summary {
stroke: @fg;
stroke-width: 10;
fill: @fg;
}