mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 22:55:35 +00:00
Add 'Offence summary' and 'Defence summary' components
This commit is contained in:
@@ -12,3 +12,5 @@
|
|||||||
* Ensure that retrofit tab only shows changed modules
|
* Ensure that retrofit tab only shows changed modules
|
||||||
* Fix import and export of ships with modifications, bump schema version to 4
|
* Fix import and export of ships with modifications, bump schema version to 4
|
||||||
* Enable boost display even if power distributor is disabled
|
* Enable boost display even if power distributor is disabled
|
||||||
|
* Calculate breakdown of ship offensive and defensive stats
|
||||||
|
* Add 'Offence summary' and 'Defence summary' components
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
import TranslatedComponent from './TranslatedComponent';
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
|
import { DamageKinetic, DamageThermal, DamageExplosive } from './SvgIcons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defence summary
|
* Defence summary
|
||||||
@@ -28,62 +29,41 @@ export default class DefenceSummary extends TranslatedComponent {
|
|||||||
let { formats, translate, units } = language;
|
let { formats, translate, units } = language;
|
||||||
let hide = tooltip.bind(null, null);
|
let hide = tooltip.bind(null, null);
|
||||||
|
|
||||||
let sgClassNames = cn({ muted: !ship.findInternalByGroup('sg') });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<span>
|
||||||
<h1>{translate('defence summary')}</h1>
|
<h1>{translate('defence summary')}</h1>
|
||||||
<br/>
|
<table className='summary' style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
|
||||||
<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>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{ship.shield ?
|
||||||
<tr>
|
<tr>
|
||||||
<td className='ri'>{formats.int(ship.shield)} {units.MJ}</td>
|
<td colSpan='4' className='summary'><h2>{translate('shields')}: {formats.int(ship.shield)} {units.MJ}</h2></td>
|
||||||
<td className='ri'>{ship.shield ? formats.time(ship.calcShieldRecovery()) : '-'}</td>
|
</tr> : null }
|
||||||
<td className='ri'>{ship.shield ? formats.time(ship.calcShieldRecharge()) : '-'}</td>
|
{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>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table> : null }
|
</table>
|
||||||
</div>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
import TranslatedComponent from './TranslatedComponent';
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
|
import { DamageKinetic, DamageThermal, DamageExplosive } from './SvgIcons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Offence summary
|
* Offence summary
|
||||||
@@ -29,75 +30,42 @@ export default class OffenceSummary extends TranslatedComponent {
|
|||||||
let hide = tooltip.bind(null, null);
|
let hide = tooltip.bind(null, null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<span>
|
||||||
<h1>{translate('offence summary')}</h1>
|
<h1>{translate('offence summary')}</h1>
|
||||||
<br/>
|
<table className='summary' style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
|
||||||
<table style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
|
<tbody>
|
||||||
<thead>
|
<tr>
|
||||||
<tr>
|
<td colSpan='4' className='summary'><h2>{translate('dps')}: {formats.f1(ship.totalDps)}</h2></td>
|
||||||
<th colSpan={4}>{translate('dps')}</th>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td className='le'>{translate('damage by')}</td>
|
||||||
<th>{translate('explosive')}</th>
|
<td className='ri' onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /> {formats.f1(ship.totalExplDps)}</td>
|
||||||
<th>{translate('kinetic')}</th>
|
<td className='ri' onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /> {formats.f1(ship.totalKinDps)}</td>
|
||||||
<th>{translate('thermal')}</th>
|
<td className='ri' onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /> {formats.f1(ship.totalThermDps)}</td>
|
||||||
<th>{translate('total')}</th>
|
</tr>
|
||||||
</tr>
|
|
||||||
</thead>
|
<tr>
|
||||||
<tbody>
|
<td colSpan='4' className='summary'><h2>{translate('sdps')}: {formats.f1(ship.totalSDps)}</h2></td>
|
||||||
<tr>
|
</tr>
|
||||||
<td className='ri'>{formats.f1(ship.totalExplDps)}</td>
|
<tr>
|
||||||
<td className='ri'>{formats.f1(ship.totalKinDps)}</td>
|
<td className='le'>{translate('damage by')}</td>
|
||||||
<td className='ri'>{formats.f1(ship.totalThermDps)}</td>
|
<td className='ri' onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /> {formats.f1(ship.totalExplSDps)}</td>
|
||||||
<td className='ri'>{formats.f1(ship.totalDps)}</td>
|
<td className='ri' onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /> {formats.f1(ship.totalKinSDps)}</td>
|
||||||
</tr>
|
<td className='ri' onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /> {formats.f1(ship.totalThermSDps)}</td>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
|
||||||
<br/>
|
<tr>
|
||||||
<table style={{ width: '100%', lineHeight: '1em', backgroundColor: 'transparent' }}>
|
<td colSpan='4' className='summary'><h2>{translate('dpe')}: {formats.f1(ship.totalDpe)}</h2></td>
|
||||||
<thead>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th colSpan={4}>{translate('sustained dps')}</th>
|
<td className='le'>{translate('damage by')}</td>
|
||||||
</tr>
|
<td className='ri' onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /> {formats.f1(ship.totalExplDpe)}</td>
|
||||||
<tr>
|
<td className='ri' onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /> {formats.f1(ship.totalKinDpe)}</td>
|
||||||
<th>{translate('explosive')}</th>
|
<td className='ri' onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /> {formats.f1(ship.totalThermDpe)}</td>
|
||||||
<th>{translate('kinetic')}</th>
|
</tr>
|
||||||
<th>{translate('thermal')}</th>
|
</tbody>
|
||||||
<th>{translate('total')}</th>
|
</table>
|
||||||
</tr>
|
</span>
|
||||||
</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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,14 +92,18 @@ export const terms = {
|
|||||||
// Unit for seconds
|
// Unit for seconds
|
||||||
secs: 's',
|
secs: 's',
|
||||||
|
|
||||||
// Hardpoint abbreviations
|
// Weapon, offence and defence
|
||||||
dpe: 'Damage per MJ of energy',
|
dpe: 'Damage per MJ of energy',
|
||||||
dps: 'Damage per second',
|
dps: 'Damage per second',
|
||||||
|
sdps: 'Sustained damage per second',
|
||||||
dpssdps: 'Damage per second (sustained damage per second)',
|
dpssdps: 'Damage per second (sustained damage per second)',
|
||||||
eps: 'Energy per second',
|
eps: 'Energy per second',
|
||||||
epsseps: 'Energy per second (sustained energy per second)',
|
epsseps: 'Energy per second (sustained energy per second)',
|
||||||
hps: 'Heat per second',
|
hps: 'Heat per second',
|
||||||
hpsshps: 'Heat per second (sustained heat per second)',
|
hpsshps: 'Heat per second (sustained heat per second)',
|
||||||
|
'damage by': 'Damage by',
|
||||||
|
'damage from': 'Damage from',
|
||||||
|
'shield cells': 'Shield cells',
|
||||||
|
|
||||||
// Modifications
|
// Modifications
|
||||||
ammo: 'Ammunition maximum',
|
ammo: 'Ammunition maximum',
|
||||||
@@ -134,6 +138,7 @@ export const terms = {
|
|||||||
rof: 'Rate of fire',
|
rof: 'Rate of fire',
|
||||||
shield: 'Shield',
|
shield: 'Shield',
|
||||||
shieldboost: 'Shield boost',
|
shieldboost: 'Shield boost',
|
||||||
|
shieldreinforcement: 'Shield reinforcement',
|
||||||
spinup: 'Spin up time',
|
spinup: 'Spin up time',
|
||||||
syscap: 'Systems capacity',
|
syscap: 'Systems capacity',
|
||||||
sysrate: 'Systems recharge rate',
|
sysrate: 'Systems recharge rate',
|
||||||
|
|||||||
@@ -492,4 +492,20 @@ export default class Module {
|
|||||||
return this._getModifiedValue('hullboost');
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,9 +236,8 @@ export default class Ship {
|
|||||||
sg = sgSlot.m;
|
sg = sgSlot.m;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO obtain shield boost
|
// TODO Not accurate if the ship has modified shield boosters
|
||||||
// return Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sg, this.shieldMultiplier + (multiplierDelta || 0));
|
return Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sg, 1 + (multiplierDelta || 0));
|
||||||
return Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sg, 0 + (multiplierDelta || 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -442,6 +441,9 @@ export default class Ship {
|
|||||||
} else if (name === 'hullboost' || name === 'hullreinforcement') {
|
} else if (name === 'hullboost' || name === 'hullreinforcement') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
this.recalculateArmour();
|
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') {
|
} 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);
|
m.setModValue(name, value);
|
||||||
this.recalculateDps();
|
this.recalculateDps();
|
||||||
@@ -479,6 +481,7 @@ export default class Ship {
|
|||||||
this.ladenMass = 0;
|
this.ladenMass = 0;
|
||||||
this.armour = this.baseArmour;
|
this.armour = this.baseArmour;
|
||||||
this.shield = this.baseShieldStrength;
|
this.shield = this.baseShieldStrength;
|
||||||
|
this.shieldCells = 0;
|
||||||
this.totalCost = this.m.incCost ? this.m.discountedCost : 0;
|
this.totalCost = this.m.incCost ? this.m.discountedCost : 0;
|
||||||
this.unladenMass = this.hullMass;
|
this.unladenMass = this.hullMass;
|
||||||
this.totalDpe = 0;
|
this.totalDpe = 0;
|
||||||
@@ -564,6 +567,7 @@ export default class Ship {
|
|||||||
.updatePowerUsed()
|
.updatePowerUsed()
|
||||||
.updateJumpStats()
|
.updateJumpStats()
|
||||||
.recalculateShield()
|
.recalculateShield()
|
||||||
|
.recalculateShieldCells()
|
||||||
.recalculateArmour()
|
.recalculateArmour()
|
||||||
.recalculateDps()
|
.recalculateDps()
|
||||||
.recalculateEps()
|
.recalculateEps()
|
||||||
@@ -1097,6 +1101,24 @@ export default class Ship {
|
|||||||
return this;
|
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
|
* Update armour and hull resistances
|
||||||
* @return {this} The ship instance (for chaining operations)
|
* @return {this} The ship instance (for chaining operations)
|
||||||
|
|||||||
@@ -56,3 +56,9 @@
|
|||||||
height: 2em;
|
height: 2em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.summary {
|
||||||
|
stroke: @fg;
|
||||||
|
stroke-width: 10;
|
||||||
|
fill: @fg;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user