Add engagement range to damage received panel

This commit is contained in:
Cmdr McDonald
2017-01-25 10:52:09 +00:00
parent ddc968129d
commit d6a687300c
3 changed files with 66 additions and 12 deletions

View File

@@ -5,6 +5,7 @@
* Update spacing for movement summary * Update spacing for movement summary
* Provide damage dealt statistics for both shields and hull * Provide damage dealt statistics for both shields and hull
* Damage dealt panel only shows enabled weapons * Damage dealt panel only shows enabled weapons
* Add engagement range to damage received panel
#2.2.10 #2.2.10
* Fix detailed export of module reinforcement packages * Fix detailed export of module reinforcement packages

View File

@@ -181,7 +181,7 @@ export default class DamageDealt extends TranslatedComponent {
*/ */
_onShipChange(s) { _onShipChange(s) {
const against = Ships[s]; const against = Ships[s];
const data = this._calcWeapons(this.props.ship, against); const data = this._calcWeapons(this.props.ship, against this.state.range * this.state.maxRange);
this.setState({ against, weapons: data.weapons, totals: data.totals }); this.setState({ against, weapons: data.weapons, totals: data.totals });
} }

View File

@@ -4,6 +4,7 @@ import { Modules } from 'coriolis-data/dist';
import { nameComparator } from '../utils/SlotFunctions'; import { nameComparator } from '../utils/SlotFunctions';
import { CollapseSection, ExpandSection, MountFixed, MountGimballed, MountTurret } from './SvgIcons'; import { CollapseSection, ExpandSection, MountFixed, MountGimballed, MountTurret } from './SvgIcons';
import Module from '../shipyard/Module'; import Module from '../shipyard/Module';
import Slider from '../components/Slider';
/** /**
* Generates an internationalization friendly weapon comparator that will * Generates an internationalization friendly weapon comparator that will
@@ -62,7 +63,9 @@ export default class DamageReceived extends TranslatedComponent {
this.state = { this.state = {
predicate: 'n', predicate: 'n',
desc: true, desc: true,
expanded: false expanded: false,
range: 0.1667,
maxRange: 6000
}; };
} }
@@ -70,7 +73,7 @@ export default class DamageReceived extends TranslatedComponent {
* Set the initial weapons state * Set the initial weapons state
*/ */
componentWillMount() { componentWillMount() {
this.setState({ weapons: this._calcWeapons(this.props.ship) }); this.setState({ weapons: this._calcWeapons(this.props.ship, this.state.range * this.state.maxRange) });
} }
/** /**
@@ -80,27 +83,47 @@ export default class DamageReceived extends TranslatedComponent {
* @return {boolean} Returns true if the component should be rerendered * @return {boolean} Returns true if the component should be rerendered
*/ */
componentWillReceiveProps(nextProps, nextContext) { componentWillReceiveProps(nextProps, nextContext) {
this.setState({ weapons: this._calcWeapons(nextProps.ship) }); if (nextProps.code != this.props.code) {
this.setState({ weapons: this._calcWeapons(nextProps.ship, this.state.range * this.state.maxRange) });
}
return true; return true;
} }
/** /**
* Calculate the damage received by a ship * Calculate the damage received by a ship
* @param {Object} ship The ship which will receive the damage * @param {Object} ship The ship which will receive the damage
* @param {Object} range The engagement range
* @return {boolean} Returns the per-weapon damage * @return {boolean} Returns the per-weapon damage
*/ */
_calcWeapons(ship) { _calcWeapons(ship, range) {
let weapons = []; // Tidy up the range so that it's to 4 decimal places
range = Math.round(10000 * range) / 10000;
let weapons = [];
for (let grp in Modules.hardpoints) { for (let grp in Modules.hardpoints) {
if (Modules.hardpoints[grp][0].damage && Modules.hardpoints[grp][0].damagedist) { if (Modules.hardpoints[grp][0].damage && Modules.hardpoints[grp][0].damagedist) {
for (let mId in Modules.hardpoints[grp]) { for (let mId in Modules.hardpoints[grp]) {
const m = new Module(Modules.hardpoints[grp][mId]); const m = new Module(Modules.hardpoints[grp][mId]);
let dropoff = 1;
if (m.getFalloff()) {
// Calculate the dropoff % due to range
if (range > m.getRange()) {
// Weapon is out of range
dropoff = 0;
} else {
const falloff = m.getFalloff();
if (range > falloff) {
const dropoffRange = m.getRange() - falloff;
// Assuming straight-line falloff
dropoff = 1 - (range - falloff) / dropoffRange;
}
}
}
const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`; const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
// Base DPS // Base DPS
const baseDps = m.getDps(); const baseDps = m.getDps() * dropoff;
const baseSDps = m.getClip() ? (m.getClip() * baseDps / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) : baseDps; const baseSDps = m.getClip() ? ((m.getClip() * baseDps / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) * dropoff : baseDps;
// Effective DPS taking in to account shield resistance // Effective DPS taking in to account shield resistance
let effectivenessShields = 0; let effectivenessShields = 0;
@@ -116,6 +139,7 @@ export default class DamageReceived extends TranslatedComponent {
if (m.getDamageDist().A) { if (m.getDamageDist().A) {
effectivenessShields += m.getDamageDist().A; effectivenessShields += m.getDamageDist().A;
} }
effectivenessShields *= dropoff;
const effectiveDpsShields = baseDps * effectivenessShields; const effectiveDpsShields = baseDps * effectivenessShields;
const effectiveSDpsShields = baseSDps * effectivenessShields; const effectiveSDpsShields = baseSDps * effectivenessShields;
@@ -133,7 +157,7 @@ export default class DamageReceived extends TranslatedComponent {
if (m.getDamageDist().A) { if (m.getDamageDist().A) {
effectivenessHull += m.getDamageDist().A; effectivenessHull += m.getDamageDist().A;
} }
effectivenessHull *= Math.min(m.getPiercing() / ship.hardness, 1); effectivenessHull *= Math.min(m.getPiercing() / ship.hardness, 1) * dropoff;
const effectiveDpsHull = baseDps * effectivenessHull; const effectiveDpsHull = baseDps * effectivenessHull;
const effectiveSDpsHull = baseSDps * effectivenessHull; const effectiveSDpsHull = baseSDps * effectivenessHull;
@@ -232,14 +256,22 @@ export default class DamageReceived extends TranslatedComponent {
return rows; return rows;
} }
/**
* Update current range
* @param {number} range Range 0-1
*/
_rangeChange(range) {
this.setState({ range, weapons: this._calcWeapons(this.props.ship, this.state.range * this.state.maxRange) });
}
/** /**
* Render damage received * Render damage received
* @return {React.Component} contents * @return {React.Component} contents
*/ */
render() { render() {
const { language, tooltip, termtip } = this.context; const { language, onWindowResize, sizeRatio, tooltip, termtip } = this.context;
const { formats, translate } = language; const { formats, translate, units } = language;
const { expanded } = this.state; const { expanded, maxRange, range } = this.state;
const sortOrder = this._sortOrder; const sortOrder = this._sortOrder;
const onCollapseExpand = this._onCollapseExpand; const onCollapseExpand = this._onCollapseExpand;
@@ -267,6 +299,27 @@ export default class DamageReceived extends TranslatedComponent {
<tbody> <tbody>
{this._renderRows(translate, formats)} {this._renderRows(translate, formats)}
</tbody> </tbody>
</table>
<table style={{ width: '80%', lineHeight: '1em', backgroundColor: 'transparent', margin: 'auto' }}>
<tbody >
<tr>
<td style={{ verticalAlign: 'top', padding: 0, width: '2.5em' }} onMouseEnter={termtip.bind(null, 'PHRASE_ENGAGEMENT_RANGE')} onMouseLeave={tooltip.bind(null, null)}>{translate('engagement range')}</td>
<td>
<Slider
axis={true}
onChange={this._rangeChange.bind(this)}
axisUnit={translate('m')}
percent={range}
max={maxRange}
scale={sizeRatio}
onResize={onWindowResize}
/>
</td>
<td className='primary' style={{ width: '10em', verticalAlign: 'top', fontSize: '0.9em', textAlign: 'left' }}>
{formats.f2(range * maxRange / 1000)}{units.km}
</td>
</tr>
</tbody>
</table></span> : null } </table></span> : null }
</span> </span>
); );