diff --git a/src/app/components/HardpointSlot.jsx b/src/app/components/HardpointSlot.jsx
index e2589d5d..ede05551 100644
--- a/src/app/components/HardpointSlot.jsx
+++ b/src/app/components/HardpointSlot.jsx
@@ -60,7 +60,7 @@ export default class HardpointSlot extends Slot {
{ m.getEps() ?
- { m.getOptMass() ?
{translate('optimal mass')}: {m.getOptMass()}{u.T}
: null }
- { m.getMaxMass() ?
{translate('max mass')}: {m.getMaxMass()}{u.T}
: null }
+ { m.getOptMass() ?
{translate('optimal mass')}: {formats.int(m.getOptMass())}{u.T}
: null }
+ { m.getMaxMass() ?
{translate('max mass')}: {formats.int(m.getMaxMass())}{u.T}
: null }
{ m.bins ?
{m.bins} {translate('bins')}
: null }
{ m.bays ?
{translate('bays')}: {m.bays}
: null }
{ m.rate ?
{translate('rate')}: {m.rate}{u.kgs} {translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}
: null }
@@ -39,7 +39,7 @@ export default class InternalSlot extends Slot {
{ m.cells ?
{translate('cells')}: {m.cells}
: null }
{ m.recharge ?
{translate('recharge')}: {m.recharge} MJ {translate('total')}: {m.cells * m.recharge}{u.MJ}
: null }
{ m.repair ?
{translate('repair')}: {m.repair}
: null }
- { m.getRange() ?
{translate('range')} {m.getRange()}{u.km}
: null }
+ { m.getRange() ?
{translate('range')} {formats.f2(m.getRange())}{u.km}
: null }
{ m.time ?
{translate('time')}: {formats.time(m.time)}
: null }
{ m.maximum ?
{translate('max')}: {(m.maximum)}
: null }
{ m.rangeLS ?
{translate('range')}: {m.rangeLS}{u.Ls}
: null }
diff --git a/src/app/components/Modification.jsx b/src/app/components/Modification.jsx
new file mode 100644
index 00000000..072b6d92
--- /dev/null
+++ b/src/app/components/Modification.jsx
@@ -0,0 +1,60 @@
+import React from 'react';
+import { findDOMNode } from 'react-dom';
+import TranslatedComponent from './TranslatedComponent';
+import cn from 'classnames';
+import NumberEditor from 'react-number-editor';
+
+/**
+ * Modification
+ */
+export default class ModificationsMenu extends TranslatedComponent {
+
+ static propTypes = {
+ ship: React.PropTypes.object.isRequired,
+ m: React.PropTypes.object.isRequired,
+ name: React.PropTypes.string.isRequired,
+ onChange: React.PropTypes.func.isRequired
+ };
+
+ /**
+ * Constructor
+ * @param {Object} props React Component properties
+ * @param {Object} context React Component context
+ */
+ constructor(props, context) {
+ super(props);
+ this.state = {};
+ this.state.value = this.props.m.getModValue(this.props.name) * 100 || 0;
+ }
+
+ /**
+ * Update modification given a value.
+ * @param {Number} value The value to set
+ */
+ _updateValue(value) {
+ let scaledValue = Math.floor(Number(value) * 100) / 10000;
+ let m = this.props.m;
+ let name = this.props.name;
+ let ship = this.props.ship;
+ ship.setModification(m, name, scaledValue);
+
+ this.setState({ value });
+ this.props.onChange();
+ }
+
+ /**
+ * Render the modification
+ * @return {React.Component} modification
+ */
+ render() {
+ let translate = this.context.language.translate;
+ let name = this.props.name;
+
+ return (
+
+
{translate(name)}{' (%)'}
+
+
+ );
+ }
+}
diff --git a/src/app/components/ModificationsMenu.jsx b/src/app/components/ModificationsMenu.jsx
index a70de410..871b6a08 100644
--- a/src/app/components/ModificationsMenu.jsx
+++ b/src/app/components/ModificationsMenu.jsx
@@ -5,7 +5,7 @@ import { stopCtxPropagation } from '../utils/UtilityFunctions';
import cn from 'classnames';
import { MountFixed, MountGimballed, MountTurret } from './SvgIcons';
import { Modifications } from 'coriolis-data/dist';
-import NumberEditor from 'react-number-editor';
+import Modification from './Modification';
const PRESS_THRESHOLD = 500; // mouse/touch down threshold
@@ -39,59 +39,14 @@ export default class ModificationsMenu extends TranslatedComponent {
_initState(props, context) {
let translate = context.language.translate;
let formats = context.language.formats;
- let { m } = props;
+ let { m, onChange, ship } = props;
let list = [];
- let values = {};
for (let modName of Modifications.validity[m.grp]) {
- values[modName] = m.getModValue(modName) * 100;
- list.push(
-
{translate(modName)}{' (%)'}
-
-
);
+ list.push(
);
}
- return { list, values };
- }
-
- /**
- * Update state based on property and context changes
- * @param {Object} nextProps Incoming/Next properties
- * @param {Object} nextContext Incoming/Next conext
- */
- componentWillReceiveProps(nextProps, nextContext) {
- this.setState(this._initState(nextProps, nextContext));
- }
-
- /**
- * Get the locally stored value of the modifier
- * @param {string} name the name of the value to obtain
- * @param {Number} defaultValue the value to use if none is held locally
- * @return {Number} the value
- */
- _getValue(name, defaultValue) {
- let values = this.state ? this.state.values : null;
- return values ? values[name] : defaultValue;
- }
-
- /**
- * Update modification given a value.
- * @param {Number} name The name of the modification
- * @param {Number} value The value to set, in the range [0,1]
- */
- _updateValue(name, value) {
- let values = this.state.values;
- values[name] = value;
-
- // Only update the modification if this is a valid number
- if (!isNaN(Number(value)) && !value.endsWith('.')) {
- let scaledValue = Math.floor(Number(value) * 100) / 10000;
- let m = this.props.m;
- let ship = this.props.ship;
- ship.setModification(m, name, scaledValue);
- }
- this.props.onChange();
- this.setState({ values });
+ return { list };
}
/**
diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js
index c4eccac6..a8074409 100755
--- a/src/app/shipyard/Module.js
+++ b/src/app/shipyard/Module.js
@@ -405,8 +405,22 @@ export default class Module {
* @return {Number} the DPS of this module
*/
getDps() {
- // TODO this is not correct; need to include other factors such as rate of fire, damage, etc.
- return this._getModifiedValue('dps');
+ // Modifications are not made to DPS directly, but to damage and rate of fire
+
+ // Obtain unmodified rate of fire
+ let rof = this['rof'];
+
+ // Obtain unmodified damage
+ let damage = this['dps'] / rof;
+
+ // Obtain modified rate of fire
+ let modRof = this._getModifiedValue('rof');
+
+ // Obtain modified damage
+ let damageMult = this.getModValue('damage');
+ let modDamage = damageMult ? damage * (1 + damageMult) : damage;
+
+ return modDamage * modRof;
}
/**