mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 22:33:24 +00:00
* Fix absolute setting of burst/burstrof * Improve change display for stats with overwrite * Module.getPretty takes synthetic getters into account * Allow custom higherbetter for changes of stats when formatted * Fix rof modding
134 lines
4.4 KiB
JavaScript
134 lines
4.4 KiB
JavaScript
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import TranslatedComponent from './TranslatedComponent';
|
|
import cn from 'classnames';
|
|
import NumberEditor from 'react-number-editor';
|
|
import { isChangeValueBeneficial } from '../utils/BlueprintFunctions';
|
|
import { Modifications } from 'coriolis-data/dist';
|
|
|
|
/**
|
|
* Modification
|
|
*/
|
|
export default class Modification extends TranslatedComponent {
|
|
static propTypes = {
|
|
ship: PropTypes.object.isRequired,
|
|
m: PropTypes.object.isRequired,
|
|
name: PropTypes.string.isRequired,
|
|
value: PropTypes.number.isRequired,
|
|
onChange: PropTypes.func.isRequired,
|
|
onKeyDown: PropTypes.func.isRequired,
|
|
modItems: PropTypes.array.isRequired,
|
|
handleModChange: 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 = props.value;
|
|
}
|
|
|
|
/**
|
|
* Update modification given a value.
|
|
* @param {Number} value The value to set. This comes in as a string and must be stored in state as a string,
|
|
* because it needs to allow illegal 'numbers' ('-', '1.', etc) when the user is typing
|
|
* in a value by hand
|
|
*/
|
|
_updateValue(value) {
|
|
this.setState({ value });
|
|
let reCast = String(Number(value));
|
|
if (reCast.endsWith(value) || reCast.startsWith(value)) {
|
|
let { m, name, ship } = this.props;
|
|
value = Math.max(Math.min(value, 50000), -50000);
|
|
ship.setModification(m, name, value, true, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Triggered when a key is pressed down with focus on the number editor.
|
|
* @param {SyntheticEvent} event Key down event
|
|
*/
|
|
_keyDown(event) {
|
|
if (event.key == 'Enter') {
|
|
this._updateFinished();
|
|
}
|
|
this.props.onKeyDown(event);
|
|
}
|
|
|
|
/**
|
|
* Triggered when an update to slider value is finished i.e. when losing focus
|
|
*
|
|
* pnellesen (24/05/2018): added value check below - this should prevent experimental effects from being recalculated
|
|
* with each onBlur event, even when no change has actually been made to the field.
|
|
*/
|
|
_updateFinished() {
|
|
if (this.props.value != this.state.value) {
|
|
this.props.handleModChange(true);
|
|
this.props.onChange();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render the modification
|
|
* @return {React.Component} modification
|
|
*/
|
|
render() {
|
|
let { translate, formats, units } = this.context.language;
|
|
let { m, name } = this.props;
|
|
let modValue = m.getChange(name);
|
|
let isOverwrite = Modifications.modifications[name].method === 'overwrite';
|
|
|
|
if (name === 'damagedist') {
|
|
// We don't show damage distribution
|
|
return null;
|
|
}
|
|
|
|
let inputClassNames = {
|
|
'cb': true,
|
|
'greyed-out': !this.props.highlight
|
|
};
|
|
|
|
return (
|
|
<div onBlur={this._updateFinished.bind(this)} key={name}
|
|
className={cn('cb', 'modification-container')}
|
|
ref={ modItem => this.props.modItems[name] = modItem }>
|
|
<span className={'cb'}>{translate(name, m.grp)}</span>
|
|
<span className={'header-adjuster'}></span>
|
|
<table style={{ width: '100%' }}>
|
|
<tbody>
|
|
<tr>
|
|
<td className={'input-container'}>
|
|
<span>
|
|
{this.props.editable ?
|
|
<NumberEditor className={cn(inputClassNames)} value={this.state.value}
|
|
decimals={2} style={{ textAlign: 'right' }} step={0.01}
|
|
stepModifier={1} onKeyDown={this._keyDown.bind(this)}
|
|
onValueChange={this._updateValue.bind(this)} /> :
|
|
<input type="text" value={formats.f2(this.state.value)}
|
|
disabled className={cn('number-editor', 'greyed-out')}
|
|
style={{ textAlign: 'right', cursor: 'inherit' }}/>
|
|
}
|
|
<span className={'unit-container'}>
|
|
{units[m.getStoredUnitFor(name)]}
|
|
</span>
|
|
</span>
|
|
</td>
|
|
<td style={{ textAlign: 'center' }} className={
|
|
modValue ?
|
|
isChangeValueBeneficial(name, modValue) ? 'secondary' : 'warning' :
|
|
''
|
|
}>
|
|
{formats.f2(modValue / 100) || 0}{isOverwrite ? '' : '%'}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
}
|
|
}
|