mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-11 08:43:02 +00:00
Added offence and defence summary
This commit is contained in:
89
src/app/components/DefenceSummary.jsx
Normal file
89
src/app/components/DefenceSummary.jsx
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import cn from 'classnames';
|
||||||
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defence summary
|
||||||
|
*/
|
||||||
|
export default class DefenceSummary extends TranslatedComponent {
|
||||||
|
static PropTypes = {
|
||||||
|
ship: React.PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param {Object} props React Component properties
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render defence summary
|
||||||
|
* @return {React.Component} contents
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
let ship = this.props.ship;
|
||||||
|
let { language, tooltip, termtip } = this.context;
|
||||||
|
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>
|
||||||
|
<tbody>
|
||||||
|
<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>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table> : null }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
103
src/app/components/OffenceSummary.jsx
Normal file
103
src/app/components/OffenceSummary.jsx
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import cn from 'classnames';
|
||||||
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offence summary
|
||||||
|
*/
|
||||||
|
export default class OffenceSummary extends TranslatedComponent {
|
||||||
|
static PropTypes = {
|
||||||
|
ship: React.PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param {Object} props React Component properties
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render offence summary
|
||||||
|
* @return {React.Component} contents
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
let ship = this.props.ship;
|
||||||
|
let { language, tooltip, termtip } = this.context;
|
||||||
|
let { formats, translate, units } = language;
|
||||||
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,20 +34,6 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
sgRecharge = time(ship.calcShieldRecharge());
|
sgRecharge = time(ship.calcShieldRecharge());
|
||||||
}
|
}
|
||||||
|
|
||||||
// <th colSpan={3}>{translate('shield resistance')}</th>
|
|
||||||
// <th colSpan={3}>{translate('hull resistance')}</th>
|
|
||||||
// <th className='lft'>{translate('explosive')}</th>
|
|
||||||
// <th className='lft'>{translate('kinetic')}</th>
|
|
||||||
// <th className='lft'>{translate('thermal')}</th>
|
|
||||||
// <th className='lft'>{translate('explosive')}</th>
|
|
||||||
// <th className='lft'>{translate('kinetic')}</th>
|
|
||||||
// <th className='lft'>{translate('thermal')}</th>
|
|
||||||
// <td>{pct(ship.shieldExplRes)}</td>
|
|
||||||
// <td>{pct(ship.shieldKinRes)}</td>
|
|
||||||
// <td>{pct(ship.shieldThermRes)}</td>
|
|
||||||
// <td>{pct(ship.hullExplRes)}</td>
|
|
||||||
// <td>{pct(ship.hullKinRes)}</td>
|
|
||||||
// <td>{pct(ship.hullThermRes)}</td>
|
|
||||||
return <div id='summary'>
|
return <div id='summary'>
|
||||||
<table id='summaryTable'>
|
<table id='summaryTable'>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -58,7 +44,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
<th onMouseEnter={termtip.bind(null, 'energy per second')} onMouseLeave={hide} rowSpan={2}>{translate('EPS')}</th>
|
<th onMouseEnter={termtip.bind(null, 'energy per second')} onMouseLeave={hide} rowSpan={2}>{translate('EPS')}</th>
|
||||||
<th onMouseEnter={termtip.bind(null, 'heat per second')} onMouseLeave={hide} rowSpan={2}>{translate('HPS')}</th>
|
<th onMouseEnter={termtip.bind(null, 'heat per second')} onMouseLeave={hide} rowSpan={2}>{translate('HPS')}</th>
|
||||||
<th rowSpan={2}>{translate('armour')}</th>
|
<th rowSpan={2}>{translate('armour')}</th>
|
||||||
<th colSpan={3}>{translate('shields')}</th>
|
<th rowSpan={2}>{translate('shields')}</th>
|
||||||
<th colSpan={3}>{translate('mass')}</th>
|
<th colSpan={3}>{translate('mass')}</th>
|
||||||
<th rowSpan={2}>{translate('cargo')}</th>
|
<th rowSpan={2}>{translate('cargo')}</th>
|
||||||
<th rowSpan={2}>{translate('fuel')}</th>
|
<th rowSpan={2}>{translate('fuel')}</th>
|
||||||
@@ -67,9 +53,6 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
<th onMouseEnter={termtip.bind(null, 'mass lock factor')} onMouseLeave={hide} rowSpan={2}>{translate('MLF')}</th>
|
<th onMouseEnter={termtip.bind(null, 'mass lock factor')} onMouseLeave={hide} rowSpan={2}>{translate('MLF')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th className='lft'>{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('recharge')}</th>
|
|
||||||
<th className='lft'>{translate('hull')}</th>
|
<th className='lft'>{translate('hull')}</th>
|
||||||
<th onMouseEnter={termtip.bind(null, 'PHRASE_UNLADEN', { cap: 0 })} onMouseLeave={hide}>{translate('unladen')}</th>
|
<th onMouseEnter={termtip.bind(null, 'PHRASE_UNLADEN', { cap: 0 })} onMouseLeave={hide}>{translate('unladen')}</th>
|
||||||
<th onMouseEnter={termtip.bind(null, 'PHRASE_LADEN', { cap: 0 })} onMouseLeave={hide}>{translate('laden')}</th>
|
<th onMouseEnter={termtip.bind(null, 'PHRASE_LADEN', { cap: 0 })} onMouseLeave={hide}>{translate('laden')}</th>
|
||||||
@@ -90,8 +73,6 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
<td>{f1(ship.totalHps)}</td>
|
<td>{f1(ship.totalHps)}</td>
|
||||||
<td>{int(ship.armour)}</td>
|
<td>{int(ship.armour)}</td>
|
||||||
<td className={sgClassNames}>{int(ship.shield)} {u.MJ}</td>
|
<td className={sgClassNames}>{int(ship.shield)} {u.MJ}</td>
|
||||||
<td className={sgClassNames}>{sgRecover}</td>
|
|
||||||
<td className={sgClassNames}>{sgRecharge}</td>
|
|
||||||
<td>{ship.hullMass} {u.T}</td>
|
<td>{ship.hullMass} {u.T}</td>
|
||||||
<td>{int(ship.unladenMass)} {u.T}</td>
|
<td>{int(ship.unladenMass)} {u.T}</td>
|
||||||
<td>{int(ship.ladenMass)} {u.T}</td>
|
<td>{int(ship.ladenMass)} {u.T}</td>
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ import Persist from '../stores/Persist';
|
|||||||
import Ship from '../shipyard/Ship';
|
import Ship from '../shipyard/Ship';
|
||||||
import { toDetailedBuild } from '../shipyard/Serializer';
|
import { toDetailedBuild } from '../shipyard/Serializer';
|
||||||
import { outfitURL } from '../utils/UrlGenerators';
|
import { outfitURL } from '../utils/UrlGenerators';
|
||||||
|
|
||||||
import { FloppyDisk, Bin, Switch, Download, Reload, Fuel } from '../components/SvgIcons';
|
import { FloppyDisk, Bin, Switch, Download, Reload, Fuel } from '../components/SvgIcons';
|
||||||
import ShipSummaryTable from '../components/ShipSummaryTable';
|
import ShipSummaryTable from '../components/ShipSummaryTable';
|
||||||
import StandardSlotSection from '../components/StandardSlotSection';
|
import StandardSlotSection from '../components/StandardSlotSection';
|
||||||
import HardpointsSlotSection from '../components/HardpointsSlotSection';
|
import HardpointsSlotSection from '../components/HardpointsSlotSection';
|
||||||
import InternalSlotSection from '../components/InternalSlotSection';
|
import InternalSlotSection from '../components/InternalSlotSection';
|
||||||
import UtilitySlotSection from '../components/UtilitySlotSection';
|
import UtilitySlotSection from '../components/UtilitySlotSection';
|
||||||
|
import OffenceSummary from '../components/OffenceSummary';
|
||||||
|
import DefenceSummary from '../components/DefenceSummary';
|
||||||
import LineChart from '../components/LineChart';
|
import LineChart from '../components/LineChart';
|
||||||
import PowerManagement from '../components/PowerManagement';
|
import PowerManagement from '../components/PowerManagement';
|
||||||
import CostSection from '../components/CostSection';
|
import CostSection from '../components/CostSection';
|
||||||
@@ -324,31 +325,11 @@ export default class OutfittingPage extends Page {
|
|||||||
<CostSection ship={ship} buildName={buildName} code={sStr + hStr + iStr} />
|
<CostSection ship={ship} buildName={buildName} code={sStr + hStr + iStr} />
|
||||||
|
|
||||||
<div ref='chartThird' className='group third'>
|
<div ref='chartThird' className='group third'>
|
||||||
<h1>{translate('jump range')}</h1>
|
<OffenceSummary ship={ship} code={code}/>
|
||||||
<LineChart
|
|
||||||
width={chartWidth}
|
|
||||||
xMax={ship.cargoCapacity}
|
|
||||||
yMax={ship.unladenRange}
|
|
||||||
xUnit={translate('T')}
|
|
||||||
yUnit={translate('LY')}
|
|
||||||
yLabel={translate('jump range')}
|
|
||||||
xLabel={translate('cargo')}
|
|
||||||
func={state.jumpRangeChartFunc}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='group third'>
|
<div className='group third'>
|
||||||
<h1>{translate('total range')}</h1>
|
<DefenceSummary ship={ship} code={code}/>
|
||||||
<LineChart
|
|
||||||
width={chartWidth}
|
|
||||||
xMax={ship.cargoCapacity}
|
|
||||||
yMax={ship.unladenFastestRange}
|
|
||||||
xUnit={translate('T')}
|
|
||||||
yUnit={translate('LY')}
|
|
||||||
yLabel={translate('fastest range')}
|
|
||||||
xLabel={translate('cargo')}
|
|
||||||
func={state.fastestRangeChartFunc}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='group third'>
|
<div className='group third'>
|
||||||
@@ -397,3 +378,16 @@ export default class OutfittingPage extends Page {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// <div ref='chartThird' className='group third'>
|
||||||
|
// <h1>{translate('jump range')}</h1>
|
||||||
|
// <LineChart
|
||||||
|
// width={chartWidth}
|
||||||
|
// xMax={ship.cargoCapacity}
|
||||||
|
// yMax={ship.unladenRange}
|
||||||
|
// xUnit={translate('T')}
|
||||||
|
// yUnit={translate('LY')}
|
||||||
|
// yLabel={translate('jump range')}
|
||||||
|
// xLabel={translate('cargo')}
|
||||||
|
// func={state.jumpRangeChartFunc}
|
||||||
|
// />
|
||||||
|
// </div>
|
||||||
|
|||||||
@@ -55,15 +55,22 @@ export default class Module {
|
|||||||
/**
|
/**
|
||||||
* Helper to obtain a modified value using standard multipliers
|
* Helper to obtain a modified value using standard multipliers
|
||||||
* @param {String} name the name of the modifier to obtain
|
* @param {String} name the name of the modifier to obtain
|
||||||
|
* @param {Boolean} additive Optional true if the value is additive rather than multiplicative
|
||||||
* @return {Number} the mass of this module
|
* @return {Number} the mass of this module
|
||||||
*/
|
*/
|
||||||
_getModifiedValue(name) {
|
_getModifiedValue(name, additive) {
|
||||||
let result = 0;
|
let result = 0;
|
||||||
if (this[name]) {
|
if (this[name]) {
|
||||||
result = this[name];
|
result = this[name];
|
||||||
if (result) {
|
if (result) {
|
||||||
let mult = this.getModValue(name);
|
const modValue = this.getModValue(name);
|
||||||
if (mult) { result = result * (1 + mult); }
|
if (modValue) {
|
||||||
|
if (additive) {
|
||||||
|
result = result + modValue;
|
||||||
|
} else {
|
||||||
|
result = result * (1 + modValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -193,7 +200,7 @@ export default class Module {
|
|||||||
* @return {Number} the kinetic resistance of this module
|
* @return {Number} the kinetic resistance of this module
|
||||||
*/
|
*/
|
||||||
getKineticResistance() {
|
getKineticResistance() {
|
||||||
return this._getModifiedValue('kinres');
|
return this._getModifiedValue('kinres', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -201,7 +208,7 @@ export default class Module {
|
|||||||
* @return {Number} the thermal resistance of this module
|
* @return {Number} the thermal resistance of this module
|
||||||
*/
|
*/
|
||||||
getThermalResistance() {
|
getThermalResistance() {
|
||||||
return this._getModifiedValue('thermres');
|
return this._getModifiedValue('thermres', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -209,7 +216,7 @@ export default class Module {
|
|||||||
* @return {Number} the explosive resistance of this module
|
* @return {Number} the explosive resistance of this module
|
||||||
*/
|
*/
|
||||||
getExplosiveResistance() {
|
getExplosiveResistance() {
|
||||||
return this._getModifiedValue('explres');
|
return this._getModifiedValue('explres', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -194,11 +194,13 @@ export default class Ship {
|
|||||||
*/
|
*/
|
||||||
calcShieldRecovery() {
|
calcShieldRecovery() {
|
||||||
if (this.shield > 0) {
|
if (this.shield > 0) {
|
||||||
let sgSlot = this.findInternalByGroup('sg');
|
const sgSlot = this.findInternalByGroup('sg');
|
||||||
|
if (sgSlot != null) {
|
||||||
let brokenRegenRate = 1 + sgSlot.m.getModValue('brokenregen');
|
let brokenRegenRate = 1 + sgSlot.m.getModValue('brokenregen');
|
||||||
// 50% of shield strength / recovery recharge rate + 15 second delay before recharge starts
|
// 50% of shield strength / recovery recharge rate + 15 second delay before recharge starts
|
||||||
return ((this.shield / 2) / (sgSlot.m.recover * brokenRegenRate)) + 15;
|
return ((this.shield / 2) / (sgSlot.m.recover * brokenRegenRate)) + 15;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,11 +212,13 @@ export default class Ship {
|
|||||||
*/
|
*/
|
||||||
calcShieldRecharge() {
|
calcShieldRecharge() {
|
||||||
if (this.shield > 0) {
|
if (this.shield > 0) {
|
||||||
let sgSlot = this.findInternalByGroup('sg');
|
const sgSlot = this.findInternalByGroup('sg');
|
||||||
|
if (sgSlot != null) {
|
||||||
let regenRate = 1 + sgSlot.m.getModValue('regen');
|
let regenRate = 1 + sgSlot.m.getModValue('regen');
|
||||||
// 50% -> 100% recharge time, Bi-Weave shields charge at 1.8 MJ/s
|
// 50% -> 100% recharge time, Bi-Weave shields charge at 1.8 MJ/s
|
||||||
return (this.shield / 2) / ((sgSlot.m.grp == 'bsg' ? 1.8 : 1) * regenRate);
|
return (this.shield / 2) / ((sgSlot.m.grp == 'bsg' ? 1.8 : 1) * regenRate);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,15 +405,15 @@ export default class Ship {
|
|||||||
*/
|
*/
|
||||||
setModification(m, name, value) {
|
setModification(m, name, value) {
|
||||||
// Handle special cases
|
// Handle special cases
|
||||||
if (name == 'pgen') {
|
if (name === 'pgen') {
|
||||||
// Power generation
|
// Power generation
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
this.updatePowerGenerated();
|
this.updatePowerGenerated();
|
||||||
} else if (name == 'power') {
|
} else if (name === 'power') {
|
||||||
// Power usage
|
// Power usage
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
this.updatePowerUsed();
|
this.updatePowerUsed();
|
||||||
} else if (name == 'mass') {
|
} else if (name === 'mass') {
|
||||||
// Mass
|
// Mass
|
||||||
let oldMass = m.getMass();
|
let oldMass = m.getMass();
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
@@ -418,32 +422,37 @@ export default class Ship {
|
|||||||
this.ladenMass = this.ladenMass - oldMass + newMass;
|
this.ladenMass = this.ladenMass - oldMass + newMass;
|
||||||
this.updateTopSpeed();
|
this.updateTopSpeed();
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
} else if (name == 'maxfuel') {
|
} else if (name === 'maxfuel') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
} else if (name == 'optmass') {
|
} else if (name === 'optmass') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
// Could be for any of thrusters, FSD or shield
|
// Could be for any of thrusters, FSD or shield
|
||||||
this.updateTopSpeed();
|
this.updateTopSpeed();
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
this.updateShield();
|
this.recalculateShield();
|
||||||
} else if (name == 'optmul') {
|
} else if (name === 'optmul') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
// Could be for any of thrusters, FSD or shield
|
// Could be for any of thrusters, FSD or shield
|
||||||
this.updateTopSpeed();
|
this.updateTopSpeed();
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
this.updateShield();
|
this.recalculateShield();
|
||||||
} else if (name == 'shieldboost') {
|
} else if (name === 'shieldboost') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
this.updateShield();
|
this.recalculateShield();
|
||||||
} else if (name == 'hullboost') {
|
} else if (name === 'hullboost' || name === 'hullreinforcement') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
this.updateArmour();
|
this.recalculateArmour();
|
||||||
} 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();
|
||||||
this.recalculateHps();
|
this.recalculateHps();
|
||||||
this.recalculateEps();
|
this.recalculateEps();
|
||||||
|
} else if (name === 'explres' || name === 'kinres' || name === 'thermres') {
|
||||||
|
m.setModValue(name, value);
|
||||||
|
// Could be for shields or armour
|
||||||
|
this.recalculateArmour();
|
||||||
|
this.recalculateShield();
|
||||||
} else {
|
} else {
|
||||||
// Generic
|
// Generic
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value);
|
||||||
@@ -473,7 +482,18 @@ export default class Ship {
|
|||||||
this.shield = this.baseShieldStrength;
|
this.shield = this.baseShieldStrength;
|
||||||
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.totalExplDpe = 0;
|
||||||
|
this.totalKinDpe = 0;
|
||||||
|
this.totalThermDpe = 0;
|
||||||
this.totalDps = 0;
|
this.totalDps = 0;
|
||||||
|
this.totalExplDps = 0;
|
||||||
|
this.totalKinDps = 0;
|
||||||
|
this.totalThermDps = 0;
|
||||||
|
this.totalSDps = 0;
|
||||||
|
this.totalExplSDps = 0;
|
||||||
|
this.totalKinSDps = 0;
|
||||||
|
this.totalThermSDps = 0;
|
||||||
this.totalEps = 0;
|
this.totalEps = 0;
|
||||||
this.totalHps = 0;
|
this.totalHps = 0;
|
||||||
this.shieldExplRes = 0;
|
this.shieldExplRes = 0;
|
||||||
@@ -544,8 +564,11 @@ export default class Ship {
|
|||||||
this.updatePowerGenerated()
|
this.updatePowerGenerated()
|
||||||
.updatePowerUsed()
|
.updatePowerUsed()
|
||||||
.updateJumpStats()
|
.updateJumpStats()
|
||||||
.updateShield()
|
.recalculateShield()
|
||||||
.updateArmour()
|
.recalculateArmour()
|
||||||
|
.recalculateDps()
|
||||||
|
.recalculateEps()
|
||||||
|
.recalculateHps()
|
||||||
.updateTopSpeed();
|
.updateTopSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,20 +711,23 @@ export default class Ship {
|
|||||||
slot.enabled = enabled;
|
slot.enabled = enabled;
|
||||||
if (slot.m) {
|
if (slot.m) {
|
||||||
if (ModuleUtils.isShieldGenerator(slot.m.grp) || slot.m.grp == 'sb') {
|
if (ModuleUtils.isShieldGenerator(slot.m.grp) || slot.m.grp == 'sb') {
|
||||||
this.updateShield();
|
this.recalculateShield();
|
||||||
}
|
|
||||||
if (slot.m.getDps()) {
|
|
||||||
this.totalDps += slot.m.getDps() * (enabled ? 1 : -1);
|
|
||||||
}
|
|
||||||
if (slot.m.getEps()) {
|
|
||||||
this.totalEps += slot.m.getEps() * (enabled ? 1 : -1);
|
|
||||||
}
|
|
||||||
if (slot.m.getHps()) {
|
|
||||||
this.totalHps += slot.m.getHps() * (enabled ? 1 : -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updatePowerUsed();
|
this.updatePowerUsed();
|
||||||
this.updatePowerEnabledString();
|
this.updatePowerEnabledString();
|
||||||
|
|
||||||
|
if (slot.m.getDps()) {
|
||||||
|
this.recalculateDps();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot.m.getHps()) {
|
||||||
|
this.recalculateHps();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot.m.getEps()) {
|
||||||
|
this.recalculateEps();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -738,6 +764,9 @@ export default class Ship {
|
|||||||
updateStats(slot, n, old, preventUpdate) {
|
updateStats(slot, n, old, preventUpdate) {
|
||||||
let powerGeneratedChange = slot == this.standard[0];
|
let powerGeneratedChange = slot == this.standard[0];
|
||||||
let powerUsedChange = false;
|
let powerUsedChange = false;
|
||||||
|
let dpsChanged = n && n.getDps() || old && old.getDps();
|
||||||
|
let epsChanged = n && n.getEps() || old && old.getEps();
|
||||||
|
let hpsChanged = n && n.getHps() || old && old.getHps();
|
||||||
|
|
||||||
let armourChange = (slot == this.bulkheads) || (n && n.grp == 'hr') || (old && old.grp == 'hr');
|
let armourChange = (slot == this.bulkheads) || (n && n.grp == 'hr') || (old && old.grp == 'hr');
|
||||||
|
|
||||||
@@ -761,16 +790,6 @@ export default class Ship {
|
|||||||
powerUsedChange = true;
|
powerUsedChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old.getDps()) {
|
|
||||||
this.totalDps -= old.getDps();
|
|
||||||
}
|
|
||||||
if (old.getEps()) {
|
|
||||||
this.totalEps -= old.getEps();
|
|
||||||
}
|
|
||||||
if (old.getHps()) {
|
|
||||||
this.totalHps -= old.getHps();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.unladenMass -= old.getMass() || 0;
|
this.unladenMass -= old.getMass() || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,22 +811,21 @@ export default class Ship {
|
|||||||
powerUsedChange = true;
|
powerUsedChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n.getDps()) {
|
|
||||||
this.totalDps += n.getDps();
|
|
||||||
}
|
|
||||||
if (n.getEps()) {
|
|
||||||
this.totalEps += n.getEps();
|
|
||||||
}
|
|
||||||
if (n.getHps()) {
|
|
||||||
this.totalHps += n.getHps();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.unladenMass += n.getMass() || 0;
|
this.unladenMass += n.getMass() || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ladenMass = this.unladenMass + this.cargoCapacity + this.fuelCapacity;
|
this.ladenMass = this.unladenMass + this.cargoCapacity + this.fuelCapacity;
|
||||||
|
|
||||||
if (!preventUpdate) {
|
if (!preventUpdate) {
|
||||||
|
if (dpsChanged) {
|
||||||
|
this.recalculateDps();
|
||||||
|
}
|
||||||
|
if (epsChanged) {
|
||||||
|
this.recalculateEps();
|
||||||
|
}
|
||||||
|
if (hpsChanged) {
|
||||||
|
this.recalculateHps();
|
||||||
|
}
|
||||||
if (powerGeneratedChange) {
|
if (powerGeneratedChange) {
|
||||||
this.updatePowerGenerated();
|
this.updatePowerGenerated();
|
||||||
}
|
}
|
||||||
@@ -815,10 +833,10 @@ export default class Ship {
|
|||||||
this.updatePowerUsed();
|
this.updatePowerUsed();
|
||||||
}
|
}
|
||||||
if (armourChange) {
|
if (armourChange) {
|
||||||
this.updateArmour();
|
this.recalculateArmour();
|
||||||
}
|
}
|
||||||
if (shieldChange) {
|
if (shieldChange) {
|
||||||
this.updateShield();
|
this.recalculateShield();
|
||||||
}
|
}
|
||||||
this.updateTopSpeed();
|
this.updateTopSpeed();
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
@@ -826,20 +844,108 @@ export default class Ship {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate diminishing returns value, where values below a given limit are returned
|
||||||
|
* as-is, and values between the lower and upper limit of the diminishing returns are
|
||||||
|
* given at half value.
|
||||||
|
* Commonly used for resistances.
|
||||||
|
* @param {Number} val The value
|
||||||
|
* @param {Number} drll The lower limit for diminishing returns
|
||||||
|
* @param {Number} drul The upper limit for diminishing returns
|
||||||
|
* @return {this} The ship instance (for chaining operations)
|
||||||
|
*/
|
||||||
|
diminishingReturns(val, drll, drul) {
|
||||||
|
if (val > drll) {
|
||||||
|
val = drll + (val - drll) / 2;
|
||||||
|
}
|
||||||
|
if (val > drul) {
|
||||||
|
val = drul;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate damage per second for weapons
|
* Calculate damage per second for weapons
|
||||||
* @return {this} The ship instance (for chaining operations)
|
* @return {this} The ship instance (for chaining operations)
|
||||||
*/
|
*/
|
||||||
recalculateDps() {
|
recalculateDps() {
|
||||||
|
let totalDpe = 0;
|
||||||
|
let totalExplDpe = 0;
|
||||||
|
let totalKinDpe = 0;
|
||||||
|
let totalThermDpe = 0;
|
||||||
let totalDps = 0;
|
let totalDps = 0;
|
||||||
|
let totalExplDps = 0;
|
||||||
|
let totalKinDps = 0;
|
||||||
|
let totalThermDps = 0;
|
||||||
|
let totalSDps = 0;
|
||||||
|
let totalExplSDps = 0;
|
||||||
|
let totalKinSDps = 0;
|
||||||
|
let totalThermSDps = 0;
|
||||||
|
|
||||||
for (let slotNum in this.hardpoints) {
|
for (let slotNum in this.hardpoints) {
|
||||||
const slot = this.hardpoints[slotNum];
|
const slot = this.hardpoints[slotNum];
|
||||||
if (slot.m && slot.enabled && slot.m.getDps()) {
|
if (slot.m && slot.enabled && slot.m.getDps()) {
|
||||||
totalDps += slot.m.getDps();
|
const dpe = slot.m.getDps() / slot.m.getEps();
|
||||||
|
const dps = slot.m.getDps();
|
||||||
|
const sdps = slot.m.getClip() ? (slot.m.getClip() * slot.m.getDps() / slot.m.getRoF()) / ((slot.m.getClip() / slot.m.getRoF()) + slot.m.getReload()) : dps;
|
||||||
|
|
||||||
|
totalDpe += dpe;
|
||||||
|
totalDps += dps;
|
||||||
|
totalSDps += sdps;
|
||||||
|
if (slot.m.type === 'E') {
|
||||||
|
totalExplDpe += dpe;
|
||||||
|
totalExplDps += dps;
|
||||||
|
totalExplSDps += sdps;
|
||||||
|
}
|
||||||
|
if (slot.m.type === 'K') {
|
||||||
|
totalKinDpe += dpe;
|
||||||
|
totalKinDps += dps;
|
||||||
|
totalKinSDps += sdps;
|
||||||
|
}
|
||||||
|
if (slot.m.type === 'T') {
|
||||||
|
totalThermDpe += dpe;
|
||||||
|
totalThermDps += dps;
|
||||||
|
totalThermSDps += sdps;
|
||||||
|
}
|
||||||
|
if (slot.m.type === 'EK') {
|
||||||
|
totalExplDpe += dpe / 2;
|
||||||
|
totalKinDpe += dpe / 2;
|
||||||
|
totalExplDps += dps / 2;
|
||||||
|
totalKinDps += dps / 2;
|
||||||
|
totalExplSDps += sdps / 2;
|
||||||
|
totalKinSDps += sdps / 2;
|
||||||
|
}
|
||||||
|
if (slot.m.type === 'ET') {
|
||||||
|
totalExplDpe += dpe / 2;
|
||||||
|
totalThermDpe += dpe / 2;
|
||||||
|
totalExplDps += dps / 2;
|
||||||
|
totalThermDps += dps / 2;
|
||||||
|
totalExplSDps += sdps / 2;
|
||||||
|
totalThermSDps += sdps / 2;
|
||||||
|
}
|
||||||
|
if (slot.m.type === 'KT') {
|
||||||
|
totalKinDpe += dpe / 2;
|
||||||
|
totalThermDpe += dpe / 2;
|
||||||
|
totalKinDps += dps / 2;
|
||||||
|
totalThermDps += dps / 2;
|
||||||
|
totalKinSDps += sdps / 2;
|
||||||
|
totalThermSDps += sdps / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.totalDpe = totalDpe;
|
||||||
|
this.totalExplDpe = totalExplDpe;
|
||||||
|
this.totalKinDpe = totalKinDpe;
|
||||||
|
this.totalThermDpe = totalThermDpe;
|
||||||
this.totalDps = totalDps;
|
this.totalDps = totalDps;
|
||||||
|
this.totalExplDps = totalExplDps;
|
||||||
|
this.totalKinDps = totalKinDps;
|
||||||
|
this.totalThermDps = totalThermDps;
|
||||||
|
this.totalSDps = totalSDps;
|
||||||
|
this.totalExplSDps = totalExplSDps;
|
||||||
|
this.totalKinSDps = totalKinSDps;
|
||||||
|
this.totalThermSDps = totalThermSDps;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -958,34 +1064,51 @@ export default class Ship {
|
|||||||
* Update shield
|
* Update shield
|
||||||
* @return {this} The ship instance (for chaining operations)
|
* @return {this} The ship instance (for chaining operations)
|
||||||
*/
|
*/
|
||||||
updateShield() {
|
recalculateShield() {
|
||||||
// Base shield from generator
|
let shield = 0;
|
||||||
let baseShield = 0;
|
let shieldExplRes = null;
|
||||||
let sgSlot = this.findInternalByGroup('sg');
|
let shieldKinRes = null;
|
||||||
if (sgSlot && sgSlot.enabled) {
|
let shieldThermRes = null;
|
||||||
baseShield = Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sgSlot.m, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let shield = baseShield;
|
const sgSlot = this.findInternalByGroup('sg');
|
||||||
|
if (sgSlot && sgSlot.enabled) {
|
||||||
|
// Shield from generator
|
||||||
|
const baseShield = Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sgSlot.m, 1);
|
||||||
|
shield = baseShield;
|
||||||
|
shieldExplRes = 1 - sgSlot.m.getExplosiveResistance();
|
||||||
|
shieldKinRes = 1 - sgSlot.m.getKineticResistance();
|
||||||
|
shieldThermRes = 1 - sgSlot.m.getThermalResistance();
|
||||||
|
|
||||||
// Shield from boosters
|
// Shield from boosters
|
||||||
for (let slot of this.hardpoints) {
|
for (let slot of this.hardpoints) {
|
||||||
if (slot.m && slot.m.grp == 'sb') {
|
if (slot.m && slot.m.grp == 'sb') {
|
||||||
shield += baseShield * slot.m.getShieldBoost();
|
shield += baseShield * slot.m.getShieldBoost();
|
||||||
|
shieldExplRes *= (1 - slot.m.getExplosiveResistance());
|
||||||
|
shieldKinRes *= (1 - slot.m.getKineticResistance());
|
||||||
|
shieldThermRes *= (1 - slot.m.getThermalResistance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.shield = shield;
|
this.shield = shield;
|
||||||
|
this.shieldExplRes = shieldExplRes ? 1 - this.diminishingReturns(1 - shieldExplRes, 0.5, 0.75) : null;
|
||||||
|
this.shieldKinRes = shieldKinRes ? 1 - this.diminishingReturns(1 - shieldKinRes, 0.5, 0.75) : null;
|
||||||
|
this.shieldThermRes = shieldThermRes ? 1 - this.diminishingReturns(1 - shieldThermRes, 0.5, 0.75) : null;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update armour
|
* Update armour and hull resistances
|
||||||
* @return {this} The ship instance (for chaining operations)
|
* @return {this} The ship instance (for chaining operations)
|
||||||
*/
|
*/
|
||||||
updateArmour() {
|
recalculateArmour() {
|
||||||
// Armour from bulkheads
|
// Armour from bulkheads
|
||||||
let bulkhead = this.bulkheads.m;
|
let bulkhead = this.bulkheads.m;
|
||||||
let armour = this.baseArmour + (this.baseArmour * bulkhead.getHullBoost());
|
let armour = this.baseArmour + (this.baseArmour * bulkhead.getHullBoost());
|
||||||
|
let hullExplRes = 1 - bulkhead.getExplosiveResistance();
|
||||||
|
let hullKinRes = 1 - bulkhead.getKineticResistance();
|
||||||
|
let hullThermRes = 1 - bulkhead.getThermalResistance();
|
||||||
|
|
||||||
// Armour from HRPs
|
// Armour from HRPs
|
||||||
for (let slot of this.internal) {
|
for (let slot of this.internal) {
|
||||||
@@ -993,9 +1116,18 @@ export default class Ship {
|
|||||||
armour += slot.m.getHullReinforcement();
|
armour += slot.m.getHullReinforcement();
|
||||||
// Hull boost for HRPs is applied against the ship's base armour
|
// Hull boost for HRPs is applied against the ship's base armour
|
||||||
armour += this.baseArmour * slot.m.getModValue('hullboost');
|
armour += this.baseArmour * slot.m.getModValue('hullboost');
|
||||||
|
|
||||||
|
hullExplRes *= (1 - slot.m.getExplosiveResistance());
|
||||||
|
hullKinRes *= (1 - slot.m.getKineticResistance());
|
||||||
|
hullThermRes *= (1 - slot.m.getThermalResistance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.armour = armour;
|
this.armour = armour;
|
||||||
|
this.hullExplRes = 1 - this.diminishingReturns(1 - hullExplRes, 0.5, 0.75);
|
||||||
|
this.hullKinRes = 1 - this.diminishingReturns(1 - hullKinRes, 0.5, 0.75);
|
||||||
|
this.hullThermRes = 1 - this.diminishingReturns(1 - hullThermRes, 0.5, 0.75);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user