mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
Add 'Damage received' section
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
* Version URLs to handle changes to ship specifications over time
|
* Version URLs to handle changes to ship specifications over time
|
||||||
* Do not include disabled shield boosters in calculations
|
* Do not include disabled shield boosters in calculations
|
||||||
* Add 'Damage dealt' section
|
* Add 'Damage dealt' section
|
||||||
|
* Add 'Damage received' section
|
||||||
|
|
||||||
#2.2.5
|
#2.2.5
|
||||||
* Calculate rate of fire for multi-burst weapons
|
* Calculate rate of fire for multi-burst weapons
|
||||||
|
|||||||
@@ -1,9 +1,44 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import cn from 'classnames';
|
|
||||||
import TranslatedComponent from './TranslatedComponent';
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
import { Ships } from 'coriolis-data/dist';
|
import { Ships } from 'coriolis-data/dist';
|
||||||
import { slotName, slotComparator } from '../utils/SlotFunctions';
|
|
||||||
import ShipSelector from './ShipSelector';
|
import ShipSelector from './ShipSelector';
|
||||||
|
import { nameComparator } from '../utils/SlotFunctions';
|
||||||
|
import { MountFixed, MountGimballed, MountTurret } from './SvgIcons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an internationalization friendly weapon comparator that will
|
||||||
|
* sort by specified property (if provided) then by name/group, class, rating
|
||||||
|
* @param {function} translate Translation function
|
||||||
|
* @param {function} propComparator Optional property comparator
|
||||||
|
* @param {boolean} desc Use descending order
|
||||||
|
* @return {function} Comparator function for names
|
||||||
|
*/
|
||||||
|
export function weaponComparator(translate, propComparator, desc) {
|
||||||
|
return (a, b) => {
|
||||||
|
if (!desc) { // Flip A and B if ascending order
|
||||||
|
let t = a;
|
||||||
|
a = b;
|
||||||
|
b = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a property comparator is provided use it first
|
||||||
|
let diff = propComparator ? propComparator(a, b) : nameComparator(translate, a, b);
|
||||||
|
|
||||||
|
if (diff) {
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Property matches so sort by name / group, then class, rating
|
||||||
|
if (a.name === b.name && a.grp === b.grp) {
|
||||||
|
if(a.class == b.class) {
|
||||||
|
return a.rating > b.rating ? 1 : -1;
|
||||||
|
}
|
||||||
|
return a.class - b.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nameComparator(translate, a, b);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Damage against a selected ship
|
* Damage against a selected ship
|
||||||
@@ -14,6 +49,8 @@ export default class DamageDealt extends TranslatedComponent {
|
|||||||
code: React.PropTypes.string.isRequired
|
code: React.PropTypes.string.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static DEFAULT_AGAINST = Ships['anaconda'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {Object} props React Component properties
|
* @param {Object} props React Component properties
|
||||||
@@ -27,16 +64,63 @@ export default class DamageDealt extends TranslatedComponent {
|
|||||||
this.state = {
|
this.state = {
|
||||||
predicate: 'n',
|
predicate: 'n',
|
||||||
desc: true,
|
desc: true,
|
||||||
against: Ships['anaconda'],
|
against: DamageDealt.DEFAULT_AGAINST
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the initial weapons state
|
||||||
|
*/
|
||||||
|
componentWillMount() {
|
||||||
|
const weapons = this._calcWeapons(this.props.ship, this.state.against);
|
||||||
|
this.setState({ weapons: weapons });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the updated weapons state
|
||||||
|
*/
|
||||||
|
componentWillReceiveProps(nextProps, nextContext) {
|
||||||
|
const weapons = this._calcWeapons(this.props.ship, this.state.against);
|
||||||
|
this.setState({ weapons: weapons });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_calcWeapons(ship, against) {
|
||||||
|
// Create a list of the ship's weapons and include required stats - this is so that we muck around with re-ordering and the like on the fly
|
||||||
|
let weapons = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < ship.hardpoints.length; i++) {
|
||||||
|
if (ship.hardpoints[i].m) {
|
||||||
|
const m = ship.hardpoints[i].m;
|
||||||
|
const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
|
||||||
|
const effectiveness = m.getPiercing() >= against.properties.hardness ? 1 : m.getPiercing() / against.properties.hardness;
|
||||||
|
const effectiveDps = m.getDps() * effectiveness;
|
||||||
|
const effectiveSDps = m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectiveness : effectiveDps;
|
||||||
|
|
||||||
|
weapons.push({id: i,
|
||||||
|
mount: m.mount,
|
||||||
|
name: m.name || m.grp,
|
||||||
|
classRating: classRating,
|
||||||
|
effectiveDps: effectiveDps,
|
||||||
|
effectiveSDps: effectiveSDps,
|
||||||
|
effectiveness: effectiveness});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return weapons;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when the ship changes
|
* Triggered when the ship changes
|
||||||
* @param {string} s the new ship ID
|
* @param {string} s the new ship ID
|
||||||
*/
|
*/
|
||||||
_onShipChange(s) {
|
_onShipChange(s) {
|
||||||
this.setState({ against: Ships[s] });
|
const against = Ships[s];
|
||||||
|
const weapons = this._calcWeapons(this.props.ship, against);
|
||||||
|
// This is not the correct 'this'
|
||||||
|
console.log('1) State against is' + this.state.against.properties.name);
|
||||||
|
this.setState({ against: against, weapons: weapons });
|
||||||
|
console.log('2) State against is' + this.state.against.properties.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,53 +143,52 @@ export default class DamageDealt extends TranslatedComponent {
|
|||||||
/**
|
/**
|
||||||
* Sorts the weapon list
|
* Sorts the weapon list
|
||||||
* @param {Ship} ship Ship instance
|
* @param {Ship} ship Ship instance
|
||||||
* @param {Ship} against The ship to compare against
|
|
||||||
* @param {string} predicate Sort predicate
|
* @param {string} predicate Sort predicate
|
||||||
* @param {Boolean} desc Sort order descending
|
* @param {Boolean} desc Sort order descending
|
||||||
*/
|
*/
|
||||||
_sort(ship, against, predicate, desc) {
|
_sort(ship, predicate, desc) {
|
||||||
let weaponList = ship.hardpoints;
|
let comp = weaponComparator.bind(null, this.context.language.translate);
|
||||||
let comp = slotComparator.bind(null, this.context.language.translate);
|
|
||||||
|
|
||||||
switch (predicate) {
|
switch (predicate) {
|
||||||
case 'n': comp = comp(null, desc); break;
|
case 'n': comp = comp(null, desc); break;
|
||||||
case 'd': comp = comp((a, b) => a.m.getDps() - b.m.getDps(), desc); break;
|
case 'edps': comp = comp((a, b) => a.effectiveDps - b.effectiveDps, desc); break;
|
||||||
case 'e': comp = comp((a, b) => (a.m.getPiercing() > a.m.hardness ? a.m.getDps() : a.m.getDps() * a.m.getPiercing() / a.m.hardness) - (b.m.getPiercing() > b.m.hardness ? b.m.getDps() : b.m.getDps() * b.m.getPiercing() / b.m.hardness), desc); break;
|
case 'esdps': comp = comp((a, b) => a.effectiveSDps - b.effectiveSDps, desc); break;
|
||||||
|
case 'e': comp = comp((a, b) => a.effectiveness - b.effectiveness, desc); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
weaponList.sort(comp);
|
this.state.weapons.sort(comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render individual rows for hardpoints
|
* Render individual rows for hardpoints
|
||||||
* @param {Function} translate Translate function
|
* @param {Function} translate Translate function
|
||||||
* @param {Object} formats Localised formats map
|
* @param {Object} formats Localised formats map
|
||||||
* @param {Object} ship Our ship
|
|
||||||
* @param {Object} against The ship against which to compare
|
|
||||||
* @return {array} The individual rows
|
* @return {array} The individual rows
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
_renderRows(translate, formats, ship, against) {
|
_renderRows(translate, formats) {
|
||||||
|
const { termtip, tooltip } = this.context;
|
||||||
|
|
||||||
let rows = [];
|
let rows = [];
|
||||||
|
|
||||||
for (let hardpoint in ship.hardpoints) {
|
if (this.state.weapons) {
|
||||||
if (ship.hardpoints[hardpoint].m) {
|
for (let i = 0; i < this.state.weapons.length; i++) {
|
||||||
const m = ship.hardpoints[hardpoint].m;
|
const weapon = this.state.weapons[i];
|
||||||
const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
|
|
||||||
const effectiveness = m.getPiercing() >= against.properties.hardness ? 1 : m.getPiercing() / against.properties.hardness;
|
|
||||||
const effectiveDps = m.getDps() * effectiveness;
|
|
||||||
const effectiveSDps = m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectiveness : effectiveDps;
|
|
||||||
|
|
||||||
rows.push(<tr key={hardpoint}>
|
rows.push(<tr key={weapon.id}>
|
||||||
<td>{classRating} {slotName(translate, ship.hardpoints[hardpoint])}</td>
|
<td className='ri'>
|
||||||
<td>{formats.round1(effectiveDps)}</td>
|
{weapon.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')} onMouseOut={tooltip.bind(null, null)}><MountFixed className='icon'/></span> : null}
|
||||||
<td>{formats.round1(effectiveSDps)}</td>
|
{weapon.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : null}
|
||||||
<td>{formats.pct(effectiveness)}</td>
|
{weapon.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : null}
|
||||||
|
{weapon.classRating} {translate(weapon.name)}
|
||||||
|
</td>
|
||||||
|
<td className='ri'>{formats.round1(weapon.effectiveDps)}</td>
|
||||||
|
<td className='ri'>{formats.round1(weapon.effectiveSDps)}</td>
|
||||||
|
<td className='ri'>{formats.pct(weapon.effectiveness)}</td>
|
||||||
</tr>);
|
</tr>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,25 +200,23 @@ export default class DamageDealt extends TranslatedComponent {
|
|||||||
const { language, tooltip, termtip } = this.context;
|
const { language, tooltip, termtip } = this.context;
|
||||||
const { formats, translate } = language;
|
const { formats, translate } = language;
|
||||||
|
|
||||||
const ship = this.props.ship;
|
const sortOrder = this._sortOrder;
|
||||||
const against = this.state.against;
|
|
||||||
const hardness = against.properties.hardness;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<h1>{translate('damage dealt against')}</h1>
|
<h1>{translate('damage dealt against')}</h1>
|
||||||
<ShipSelector initial={this.state.against} currentMenu={this.props.currentMenu} onChange={this._onShipChange} />
|
<ShipSelector initial={this.state.against} currentMenu={this.props.currentMenu} onChange={this._onShipChange} />
|
||||||
<table style={{ width: '100%' }}>
|
<table className='summary' style={{ width: '100%' }}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr className='main'>
|
<tr className='main'>
|
||||||
<td>{translate('weapon')}</td>
|
<td className='sortable' onClick={sortOrder.bind(this, 'n')}>{translate('weapon')}</td>
|
||||||
<td>{translate('effective dps')}</td>
|
<td className='sortable' onClick={sortOrder.bind(this, 'edps')}>{translate('effective dps')}</td>
|
||||||
<td>{translate('effective sdps')}</td>
|
<td className='sortable' onClick={sortOrder.bind(this, 'esdps')}>{translate('effective sdps')}</td>
|
||||||
<td>{translate('effectiveness')}</td>
|
<td className='sortable' onClick={sortOrder.bind(this, 'e')}>{translate('effectiveness')}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{this._renderRows(translate, formats, ship, against)}
|
{this._renderRows(translate, formats)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
259
src/app/components/DamageReceived.jsx
Normal file
259
src/app/components/DamageReceived.jsx
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
|
import { Modules } from 'coriolis-data/dist';
|
||||||
|
import { nameComparator } from '../utils/SlotFunctions';
|
||||||
|
import { MountFixed, MountGimballed, MountTurret } from './SvgIcons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an internationalization friendly weapon comparator that will
|
||||||
|
* sort by specified property (if provided) then by name/group, class, rating
|
||||||
|
* @param {function} translate Translation function
|
||||||
|
* @param {function} propComparator Optional property comparator
|
||||||
|
* @param {boolean} desc Use descending order
|
||||||
|
* @return {function} Comparator function for names
|
||||||
|
*/
|
||||||
|
export function weaponComparator(translate, propComparator, desc) {
|
||||||
|
return (a, b) => {
|
||||||
|
if (!desc) { // Flip A and B if ascending order
|
||||||
|
let t = a;
|
||||||
|
a = b;
|
||||||
|
b = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a property comparator is provided use it first
|
||||||
|
let diff = propComparator ? propComparator(a, b) : nameComparator(translate, a, b);
|
||||||
|
|
||||||
|
if (diff) {
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Property matches so sort by name / group, then class, rating
|
||||||
|
if (a.name === b.name && a.grp === b.grp) {
|
||||||
|
if(a.class == b.class) {
|
||||||
|
return a.rating > b.rating ? 1 : -1;
|
||||||
|
}
|
||||||
|
return a.class - b.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nameComparator(translate, a, b);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Damage received by a selected ship
|
||||||
|
*/
|
||||||
|
export default class DamageReceived extends TranslatedComponent {
|
||||||
|
static PropTypes = {
|
||||||
|
ship: React.PropTypes.object.isRequired,
|
||||||
|
code: React.PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param {Object} props React Component properties
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this._sort = this._sort.bind(this);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
predicate: 'n',
|
||||||
|
desc: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the initial weapons state
|
||||||
|
*/
|
||||||
|
componentWillMount() {
|
||||||
|
this.setState({ weapons: this._calcWeapons(this.props.ship) });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the updated weapons state
|
||||||
|
*/
|
||||||
|
componentWillReceiveProps(nextProps, nextContext) {
|
||||||
|
this.setState({ weapons: this._calcWeapons(nextProps.ship) });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_calcWeapons(ship) {
|
||||||
|
// Create a list of all weapons and include their stats - this is so that we can muck around with re-ordering and the like on the fly
|
||||||
|
let weapons = [];
|
||||||
|
|
||||||
|
for (let grp in Modules.hardpoints) {
|
||||||
|
if (Modules.hardpoints[grp][0].damage && Modules.hardpoints[grp][0].type) {
|
||||||
|
for (let mId in Modules.hardpoints[grp]) {
|
||||||
|
const m = Modules.hardpoints[grp][mId];
|
||||||
|
const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
|
||||||
|
|
||||||
|
// Basic values
|
||||||
|
let damage = m.damage;
|
||||||
|
let rpshot = m.roundspershot || 1;
|
||||||
|
let rof = m.rof || 1;
|
||||||
|
|
||||||
|
// Base DPS
|
||||||
|
const baseDps = damage * rpshot * rof;
|
||||||
|
const baseSDps = m.clip ? (m.clip * baseDps / m.rof) / ((m.clip / m.rof) + m.reload) : baseDps;
|
||||||
|
|
||||||
|
// Effective DPS taking in to account shield resistance
|
||||||
|
let effectivenessShields = 0;
|
||||||
|
if (m.type.indexOf('E') != -1) {
|
||||||
|
effectivenessShields += ship.shieldExplRes;
|
||||||
|
}
|
||||||
|
if (m.type.indexOf('K') != -1) {
|
||||||
|
effectivenessShields += ship.shieldKinRes;
|
||||||
|
}
|
||||||
|
if (m.type.indexOf('T') != -1) {
|
||||||
|
effectivenessShields += ship.shieldThermRes;
|
||||||
|
}
|
||||||
|
effectivenessShields /= m.type.length;
|
||||||
|
// Plasma accelerators deal absolute damage
|
||||||
|
if (m.grp == 'pa') effectivenessShields = 1;
|
||||||
|
const effectiveDpsShields = baseDps * effectivenessShields;
|
||||||
|
const effectiveSDpsShields = baseSDps * effectivenessShields;
|
||||||
|
|
||||||
|
// Effective DPS taking in to account hull hardness and resistance
|
||||||
|
let effectivenessHull = 0;
|
||||||
|
if (m.type.indexOf('E') != -1) {
|
||||||
|
effectivenessHull += ship.hullExplRes;
|
||||||
|
}
|
||||||
|
if (m.type.indexOf('K') != -1) {
|
||||||
|
effectivenessHull += ship.hullKinRes;
|
||||||
|
}
|
||||||
|
if (m.type.indexOf('T') != -1) {
|
||||||
|
effectivenessHull += ship.hullThermRes;
|
||||||
|
}
|
||||||
|
effectivenessHull /= m.type.length;
|
||||||
|
// Plasma accelerators deal absolute damage (but could be reduced by hardness)
|
||||||
|
if (m.grp == 'pa') effectivenessHull = 1;
|
||||||
|
effectivenessHull *= Math.min(m.piercing / ship.hardness, 1);
|
||||||
|
const effectiveDpsHull = baseDps * effectivenessHull;
|
||||||
|
const effectiveSDpsHull = baseSDps * effectivenessHull;
|
||||||
|
|
||||||
|
weapons.push({id: m.id,
|
||||||
|
classRating: classRating,
|
||||||
|
name: m.name || m.grp,
|
||||||
|
mount: m.mount,
|
||||||
|
effectiveDpsShields: effectiveDpsShields,
|
||||||
|
effectiveSDpsShields: effectiveSDpsShields,
|
||||||
|
effectivenessShields: effectivenessShields,
|
||||||
|
effectiveDpsHull: effectiveDpsHull,
|
||||||
|
effectiveSDpsHull: effectiveSDpsHull,
|
||||||
|
effectivenessHull: effectivenessHull});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return weapons;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sort order and sort
|
||||||
|
* @param {string} predicate Sort predicate
|
||||||
|
*/
|
||||||
|
_sortOrder(predicate) {
|
||||||
|
let desc = this.state.desc;
|
||||||
|
|
||||||
|
if (predicate == this.state.predicate) {
|
||||||
|
desc = !desc;
|
||||||
|
} else {
|
||||||
|
desc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._sort(this.props.ship, predicate, desc);
|
||||||
|
this.setState({ predicate, desc });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts the weapon list
|
||||||
|
* @param {Ship} ship Ship instance
|
||||||
|
* @param {string} predicate Sort predicate
|
||||||
|
* @param {Boolean} desc Sort order descending
|
||||||
|
*/
|
||||||
|
_sort(ship, predicate, desc) {
|
||||||
|
let comp = weaponComparator.bind(null, this.context.language.translate);
|
||||||
|
|
||||||
|
switch (predicate) {
|
||||||
|
case 'n': comp = comp(null, desc); break;
|
||||||
|
case 'edpss': comp = comp((a, b) => a.effectiveDpsShields - b.effectiveDpsShields, desc); break;
|
||||||
|
case 'esdpss': comp = comp((a, b) => a.effectiveSDpsShields - b.effectiveSDpsShields, desc); break;
|
||||||
|
case 'es': comp = comp((a, b) => a.effectivenessShields - b.effectivenessShields, desc); break;
|
||||||
|
case 'edpsh': comp = comp((a, b) => a.effectiveDpsHull - b.effectiveDpsHull, desc); break;
|
||||||
|
case 'esdpsh': comp = comp((a, b) => a.effectiveSDpsHull - b.effectiveSDpsHull, desc); break;
|
||||||
|
case 'eh': comp = comp((a, b) => a.effectivenessHull - b.effectivenessHull, desc); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.weapons.sort(comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render individual rows for weapons
|
||||||
|
* @param {Function} translate Translate function
|
||||||
|
* @param {Object} formats Localised formats map
|
||||||
|
* @return {array} The individual rows
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
_renderRows(translate, formats) {
|
||||||
|
const { termtip, tooltip } = this.context;
|
||||||
|
|
||||||
|
let rows = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < this.state.weapons.length; i++) {
|
||||||
|
const weapon = this.state.weapons[i];
|
||||||
|
rows.push(<tr key={weapon.id}>
|
||||||
|
<td className='ri'>
|
||||||
|
{weapon.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')} onMouseOut={tooltip.bind(null, null)}><MountFixed className='icon'/></span> : null}
|
||||||
|
{weapon.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : null}
|
||||||
|
{weapon.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : null}
|
||||||
|
{weapon.classRating} {translate(weapon.name)}
|
||||||
|
</td>
|
||||||
|
<td>{formats.round1(weapon.effectiveDpsShields)}</td>
|
||||||
|
<td>{formats.round1(weapon.effectiveSDpsShields)}</td>
|
||||||
|
<td>{formats.pct(weapon.effectivenessShields)}</td>
|
||||||
|
<td>{formats.round1(weapon.effectiveDpsHull)}</td>
|
||||||
|
<td>{formats.round1(weapon.effectiveSDpsHull)}</td>
|
||||||
|
<td>{formats.pct(weapon.effectivenessHull)}</td>
|
||||||
|
</tr>);
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render damage received
|
||||||
|
* @return {React.Component} contents
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { language, tooltip, termtip } = this.context;
|
||||||
|
const { formats, translate } = language;
|
||||||
|
|
||||||
|
const sortOrder = this._sortOrder;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<h1>{translate('damage received by')}</h1>
|
||||||
|
<table className='summary' style={{ width: '100%' }}>
|
||||||
|
<thead>
|
||||||
|
<tr className='main'>
|
||||||
|
<th rowSpan={2} className='sortable' onClick={sortOrder.bind(this, 'n')} >{translate('weapon')}</th>
|
||||||
|
<th colSpan={3} >{translate('against shields')}</th>
|
||||||
|
<th colSpan={3} >{translate('against hull')}</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th className='sortable lft' onClick={sortOrder.bind(this, 'edpss')} onMouseOver={termtip.bind(null, 'dps')} onMouseOut={tooltip.bind(null, null)}>{translate('DPS')}</th>
|
||||||
|
<th className='sortable' onClick={sortOrder.bind(this, 'esdpss')} onMouseOver={termtip.bind(null, 'sdps')} onMouseOut={tooltip.bind(null, null)}>{translate('SDPS')}</th>
|
||||||
|
<th className='sortable' onClick={sortOrder.bind(this, 'es')} >{translate('effectiveness')}</th>
|
||||||
|
<th className='sortable lft' onClick={sortOrder.bind(this, 'edpsh')} onMouseOver={termtip.bind(null, 'dps')} onMouseOut={tooltip.bind(null, null)}>{translate('DPS')}</th>
|
||||||
|
<th className='sortable' onClick={sortOrder.bind(this, 'esdpsh')} onMouseOver={termtip.bind(null, 'sdps')} onMouseOut={tooltip.bind(null, null)}>{translate('SDPS')}</th>
|
||||||
|
<th className='sortable' onClick={sortOrder.bind(this, 'eh')} >{translate('effectiveness')}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{this._renderRows(translate, formats)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -90,6 +90,9 @@ export const terms = {
|
|||||||
// Notification of restricted slot
|
// Notification of restricted slot
|
||||||
emptyrestricted: 'empty (restricted)',
|
emptyrestricted: 'empty (restricted)',
|
||||||
'damage dealt against': 'Damage dealt against',
|
'damage dealt against': 'Damage dealt against',
|
||||||
|
'damage received by': 'Damage received by',
|
||||||
|
'against shields': 'Against shields',
|
||||||
|
'against hull': 'Against hull',
|
||||||
// 'ammo' was overloaded for outfitting page and modul info, so changed to ammunition for outfitting page
|
// 'ammo' was overloaded for outfitting page and modul info, so changed to ammunition for outfitting page
|
||||||
ammunition: 'Ammo',
|
ammunition: 'Ammo',
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import OffenceSummary from '../components/OffenceSummary';
|
|||||||
import DefenceSummary from '../components/DefenceSummary';
|
import DefenceSummary from '../components/DefenceSummary';
|
||||||
import MovementSummary from '../components/MovementSummary';
|
import MovementSummary from '../components/MovementSummary';
|
||||||
import DamageDealt from '../components/DamageDealt';
|
import DamageDealt from '../components/DamageDealt';
|
||||||
|
import DamageReceived from '../components/DamageReceived';
|
||||||
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';
|
||||||
@@ -353,6 +354,10 @@ export default class OutfittingPage extends Page {
|
|||||||
<DamageDealt ship={ship} code={code} currentMenu={menu}/>
|
<DamageDealt ship={ship} code={code} currentMenu={menu}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<DamageReceived ship={ship} code={code} currentMenu={menu}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import Module from './Module';
|
|||||||
import LZString from 'lz-string';
|
import LZString from 'lz-string';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import isEqual from 'lodash/lang';
|
import isEqual from 'lodash/lang';
|
||||||
import { Modifications } from 'coriolis-data/dist';
|
import { Ships, Modifications } from 'coriolis-data/dist';
|
||||||
const zlib = require('zlib');
|
const zlib = require('zlib');
|
||||||
|
|
||||||
const UNIQUE_MODULES = ['psg', 'sg', 'bsg', 'rf', 'fs', 'fh'];
|
const UNIQUE_MODULES = ['psg', 'sg', 'bsg', 'rf', 'fs', 'fh'];
|
||||||
@@ -660,7 +660,7 @@ export default class Ship {
|
|||||||
|
|
||||||
if (version != 2) {
|
if (version != 2) {
|
||||||
// Alter as required due to changes in the (build) code from one version to the next
|
// Alter as required due to changes in the (build) code from one version to the next
|
||||||
this.upgradeInternals(this.id, internal, 1 + this.standard.length + this.hardpoints.length, priorities, enabled, modifications, blueprints, version);
|
this.upgradeInternals(internal, 1 + this.standard.length + this.hardpoints.length, priorities, enabled, modifications, blueprints, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.buildWith(
|
return this.buildWith(
|
||||||
@@ -1675,13 +1675,13 @@ export default class Ship {
|
|||||||
* @param {array} blueprints the existing blueprints arrray
|
* @param {array} blueprints the existing blueprints arrray
|
||||||
* @param {int} version the version of the information
|
* @param {int} version the version of the information
|
||||||
*/
|
*/
|
||||||
upgradeInternals(shipId, internals, offset, priorities, enableds, modifications, blueprints, version) {
|
upgradeInternals(internals, offset, priorities, enableds, modifications, blueprints, version) {
|
||||||
if (version == 1) {
|
if (version == 1) {
|
||||||
// Version 2 reflects the addition of military slots. this means that we need to juggle the internals and their
|
// Version 2 reflects the addition of military slots. this means that we need to juggle the internals and their
|
||||||
// associated information around to make holes in the appropriate places
|
// associated information around to make holes in the appropriate places
|
||||||
for (let slotId = 0; slotId < this.internal.length; slotId++) {
|
for (let slotId = 0; slotId < this.internal.length; slotId++) {
|
||||||
if (this.internal[slotId].eligible && this.internal[slotId].eligible.mrp) {
|
if (this.internal[slotId].eligible && this.internal[slotId].eligible.mrp) {
|
||||||
// Found an MRP - push all of the existing items down one to compensate for the fact that they didn't exist before now
|
// Found a restricted military slot - push all of the existing items down one to compensate for the fact that they didn't exist before now
|
||||||
internals.push.apply(internals, [0].concat(internals.splice(slotId).slice(0, -1)));
|
internals.push.apply(internals, [0].concat(internals.splice(slotId).slice(0, -1)));
|
||||||
|
|
||||||
const offsetSlotId = offset + slotId;
|
const offsetSlotId = offset + slotId;
|
||||||
@@ -1693,6 +1693,8 @@ export default class Ship {
|
|||||||
if (blueprints) { blueprints.push.apply(blueprints, [null].concat(blueprints.splice(offsetSlotId).slice(0, -1))); }
|
if (blueprints) { blueprints.push.apply(blueprints, [null].concat(blueprints.splice(offsetSlotId).slice(0, -1))); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Ensure that all items are the correct length
|
||||||
|
internals.splice(Ships[this.id].slots.internal.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,10 @@
|
|||||||
width: 1.1em;
|
width: 1.1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
stoke: @fg;
|
stoke: @fg;
|
||||||
|
stroke-width: 20;
|
||||||
fill: transparent;
|
fill: transparent;
|
||||||
|
|
||||||
|
|
||||||
&.sm {
|
&.sm {
|
||||||
width: 0.8em;
|
width: 0.8em;
|
||||||
height: 0.75em;
|
height: 0.75em;
|
||||||
|
|||||||
Reference in New Issue
Block a user