mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 22:33:24 +00:00
Separate modification slider in to its own component
This commit is contained in:
@@ -60,7 +60,7 @@ export default class HardpointSlot extends Slot {
|
|||||||
{ m.getEps() ? <div className={'l'}>{translate('EPS')}: {formats.round1(m.getEps())}{u.MW} { m.getClip() ? <span>({formats.round1((m.getClip() * m.getEps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) }{u.MW})</span> : null }</div> : null }
|
{ m.getEps() ? <div className={'l'}>{translate('EPS')}: {formats.round1(m.getEps())}{u.MW} { m.getClip() ? <span>({formats.round1((m.getClip() * m.getEps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) }{u.MW})</span> : null }</div> : null }
|
||||||
{ m.getHps() ? <div className={'l'}>{translate('HPS')}: {formats.round1(m.getHps())} { m.getClip() ? <span>({formats.round1((m.getClip() * m.getHps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) })</span> : null }</div> : null }
|
{ m.getHps() ? <div className={'l'}>{translate('HPS')}: {formats.round1(m.getHps())} { m.getClip() ? <span>({formats.round1((m.getClip() * m.getHps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) })</span> : null }</div> : null }
|
||||||
{ m.getDps() && m.getEps() ? <div className={'l'}>{translate('DPE')}: {formats.round1(m.getDps() / m.getEps())}</div> : null }
|
{ m.getDps() && m.getEps() ? <div className={'l'}>{translate('DPE')}: {formats.round1(m.getDps() / m.getEps())}</div> : null }
|
||||||
{ m.getRoF() ? <div className={'l'}>{translate('ROF')}: {m.getRoF()}{u.ps}</div> : null }
|
{ m.getRoF() ? <div className={'l'}>{translate('ROF')}: {formats.f1(m.getRoF())}{u.ps}</div> : null }
|
||||||
{ m.getRange() && !m.getDps() ? <div className={'l'}>{translate('Range')} : {formats.round(m.getRange() / 1000)}{u.km}</div> : null }
|
{ m.getRange() && !m.getDps() ? <div className={'l'}>{translate('Range')} : {formats.round(m.getRange() / 1000)}{u.km}</div> : null }
|
||||||
{ m.getShieldMul() ? <div className={'l'}>+{formats.rPct(m.getShieldMul())}</div> : null }
|
{ m.getShieldMul() ? <div className={'l'}>+{formats.rPct(m.getShieldMul())}</div> : null }
|
||||||
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.int(m.getClip())}/{formats.int(m.getAmmo())}</div> : null }
|
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.int(m.getClip())}/{formats.int(m.getAmmo())}</div> : null }
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ export default class InternalSlot extends Slot {
|
|||||||
<div className={'r'}>{formats.round1(m.getMass()) || m.cargo || m.fuel || 0}{u.T}</div>
|
<div className={'r'}>{formats.round1(m.getMass()) || m.cargo || m.fuel || 0}{u.T}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
{ m.getOptMass() ? <div className={'l'}>{translate('optimal mass')}: {m.getOptMass()}{u.T}</div> : null }
|
{ m.getOptMass() ? <div className={'l'}>{translate('optimal mass')}: {formats.int(m.getOptMass())}{u.T}</div> : null }
|
||||||
{ m.getMaxMass() ? <div className={'l'}>{translate('max mass')}: {m.getMaxMass()}{u.T}</div> : null }
|
{ m.getMaxMass() ? <div className={'l'}>{translate('max mass')}: {formats.int(m.getMaxMass())}{u.T}</div> : null }
|
||||||
{ m.bins ? <div className={'l'}>{m.bins} <u>{translate('bins')}</u></div> : null }
|
{ m.bins ? <div className={'l'}>{m.bins} <u>{translate('bins')}</u></div> : null }
|
||||||
{ m.bays ? <div className={'l'}>{translate('bays')}: {m.bays}</div> : null }
|
{ m.bays ? <div className={'l'}>{translate('bays')}: {m.bays}</div> : null }
|
||||||
{ m.rate ? <div className={'l'}>{translate('rate')}: {m.rate}{u.kgs} {translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}</div> : null }
|
{ m.rate ? <div className={'l'}>{translate('rate')}: {m.rate}{u.kgs} {translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}</div> : null }
|
||||||
@@ -39,7 +39,7 @@ export default class InternalSlot extends Slot {
|
|||||||
{ m.cells ? <div className={'l'}>{translate('cells')}: {m.cells}</div> : null }
|
{ m.cells ? <div className={'l'}>{translate('cells')}: {m.cells}</div> : null }
|
||||||
{ m.recharge ? <div className={'l'}>{translate('recharge')}: {m.recharge} <u>MJ</u> {translate('total')}: {m.cells * m.recharge}{u.MJ}</div> : null }
|
{ m.recharge ? <div className={'l'}>{translate('recharge')}: {m.recharge} <u>MJ</u> {translate('total')}: {m.cells * m.recharge}{u.MJ}</div> : null }
|
||||||
{ m.repair ? <div className={'l'}>{translate('repair')}: {m.repair}</div> : null }
|
{ m.repair ? <div className={'l'}>{translate('repair')}: {m.repair}</div> : null }
|
||||||
{ m.getRange() ? <div className={'l'}>{translate('range')} {m.getRange()}{u.km}</div> : null }
|
{ m.getRange() ? <div className={'l'}>{translate('range')} {formats.f2(m.getRange())}{u.km}</div> : null }
|
||||||
{ m.time ? <div className={'l'}>{translate('time')}: {formats.time(m.time)}</div> : null }
|
{ m.time ? <div className={'l'}>{translate('time')}: {formats.time(m.time)}</div> : null }
|
||||||
{ m.maximum ? <div className={'l'}>{translate('max')}: {(m.maximum)}</div> : null }
|
{ m.maximum ? <div className={'l'}>{translate('max')}: {(m.maximum)}</div> : null }
|
||||||
{ m.rangeLS ? <div className={'l'}>{translate('range')}: {m.rangeLS}{u.Ls}</div> : null }
|
{ m.rangeLS ? <div className={'l'}>{translate('range')}: {m.rangeLS}{u.Ls}</div> : null }
|
||||||
|
|||||||
60
src/app/components/Modification.jsx
Normal file
60
src/app/components/Modification.jsx
Normal file
@@ -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 (
|
||||||
|
<div className={'cb'} key={name}>
|
||||||
|
<div className={'cb'}>{translate(name)}{' (%)'}</div>
|
||||||
|
<NumberEditor className={'cb'} style={{ width: '100%', textAlign: 'center' }} step={0.01} stepModifier={1} decimals={2} value={this.state.value} onValueChange={this._updateValue.bind(this)} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
|||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
import { MountFixed, MountGimballed, MountTurret } from './SvgIcons';
|
import { MountFixed, MountGimballed, MountTurret } from './SvgIcons';
|
||||||
import { Modifications } from 'coriolis-data/dist';
|
import { Modifications } from 'coriolis-data/dist';
|
||||||
import NumberEditor from 'react-number-editor';
|
import Modification from './Modification';
|
||||||
|
|
||||||
const PRESS_THRESHOLD = 500; // mouse/touch down threshold
|
const PRESS_THRESHOLD = 500; // mouse/touch down threshold
|
||||||
|
|
||||||
@@ -39,59 +39,14 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
_initState(props, context) {
|
_initState(props, context) {
|
||||||
let translate = context.language.translate;
|
let translate = context.language.translate;
|
||||||
let formats = context.language.formats;
|
let formats = context.language.formats;
|
||||||
let { m } = props;
|
let { m, onChange, ship } = props;
|
||||||
let list = [];
|
let list = [];
|
||||||
let values = {};
|
|
||||||
|
|
||||||
for (let modName of Modifications.validity[m.grp]) {
|
for (let modName of Modifications.validity[m.grp]) {
|
||||||
values[modName] = m.getModValue(modName) * 100;
|
list.push(<Modification key={ modName } ship={ ship } m={ m } name={ modName } onChange={ onChange }/>);
|
||||||
list.push(<div className={'cb'} key={modName}>
|
|
||||||
<div className={'cb'}>{translate(modName)}{' (%)'}</div>
|
|
||||||
<NumberEditor className={'cb'} style={{ width: '100%', textAlign: 'center' }} step={0.01} stepModifier={1} decimals={2} value={this._getValue(modName, values[modName])} onValueChange={this._updateValue.bind(this, modName)} />
|
|
||||||
</div>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { list, values };
|
return { list };
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -405,8 +405,22 @@ export default class Module {
|
|||||||
* @return {Number} the DPS of this module
|
* @return {Number} the DPS of this module
|
||||||
*/
|
*/
|
||||||
getDps() {
|
getDps() {
|
||||||
// TODO this is not correct; need to include other factors such as rate of fire, damage, etc.
|
// Modifications are not made to DPS directly, but to damage and rate of fire
|
||||||
return this._getModifiedValue('dps');
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user