mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 14:33:22 +00:00
Merge pull request #301 from BenJuan26/feature/linting
Fix obvious lint issues
This commit is contained in:
@@ -356,7 +356,7 @@ export default class Coriolis extends React.Component {
|
||||
<div className="right cap">
|
||||
<a href="https://github.com/EDCD/coriolis" target="_blank" title="Coriolis Github Project">{window.CORIOLIS_VERSION} - {window.CORIOLIS_DATE}</a>
|
||||
<br/>
|
||||
<a href={"https://github.com/EDCD/coriolis/compare/edcd:develop@{" + window.CORIOLIS_DATE + "}...edcd:develop"} target="_blank" title={"Coriolis Commits since" + window.CORIOLIS_DATE}>Commits since last release ({window.CORIOLIS_DATE})</a>
|
||||
<a href={'https://github.com/EDCD/coriolis/compare/edcd:develop@{' + window.CORIOLIS_DATE + '}...edcd:develop'} target="_blank" title={'Coriolis Commits since' + window.CORIOLIS_DATE}>Commits since last release ({window.CORIOLIS_DATE})</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>;
|
||||
|
||||
@@ -137,7 +137,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
let translate = context.language.translate;
|
||||
let { m, warning, shipMass, onSelect, modules, firstSlotId, lastSlotId } = props;
|
||||
let list, currentGroup;
|
||||
|
||||
|
||||
let buildGroup = this._buildGroup.bind(
|
||||
this,
|
||||
translate,
|
||||
@@ -149,7 +149,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
onSelect(m);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
if (modules instanceof Array) {
|
||||
list = buildGroup(modules[0].grp, modules);
|
||||
} else {
|
||||
@@ -210,7 +210,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
}
|
||||
}
|
||||
let trackingFocus = false;
|
||||
return { list, currentGroup, trackingFocus};
|
||||
return { list, currentGroup, trackingFocus };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,10 +227,10 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
_buildGroup(translate, mountedModule, warningFunc, mass, onSelect, grp, modules, firstSlotId, lastSlotId) {
|
||||
let prevClass = null, prevRating = null, prevName;
|
||||
let elems = [];
|
||||
|
||||
|
||||
const sortedModules = modules.sort(this._moduleOrder);
|
||||
|
||||
|
||||
|
||||
|
||||
// Calculate the number of items per class. Used so we don't have long lists with only a few items in each row
|
||||
const tmp = sortedModules.map((v, i) => v['class']).reduce((count, cls) => { count[cls] = ++count[cls] || 1; return count; }, {});
|
||||
const itemsPerClass = Math.max.apply(null, Object.keys(tmp).map(key => tmp[key]));
|
||||
@@ -240,7 +240,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
let m = sortedModules[i];
|
||||
let mount = null;
|
||||
let disabled = false;
|
||||
prevName = m.name
|
||||
prevName = m.name;
|
||||
if (ModuleUtils.isShieldGenerator(m.grp)) {
|
||||
// Shield generators care about maximum hull mass
|
||||
disabled = mass > m.maxmass;
|
||||
@@ -305,7 +305,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
{(mount ? ' ' : '') + m.class + m.rating + (m.missile ? '/' + m.missile : '') + (m.name ? ' ' + translate(m.name) : '')}
|
||||
</li>
|
||||
);
|
||||
|
||||
|
||||
itemsOnThisRow++;
|
||||
prevClass = m.class;
|
||||
prevRating = m.rating;
|
||||
@@ -369,21 +369,21 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
*/
|
||||
|
||||
_keyDown(select, event) {
|
||||
var className = event.currentTarget.attributes['class'].value;
|
||||
if (event.key == 'Enter' && className.indexOf('disabled') < 0 && className.indexOf('active') < 0) {
|
||||
let className = event.currentTarget.attributes['class'].value;
|
||||
if (event.key == 'Enter' && className.indexOf('disabled') < 0 && className.indexOf('active') < 0) {
|
||||
select();
|
||||
return
|
||||
return;
|
||||
}
|
||||
var elemId = event.currentTarget.attributes['data-id'].value;
|
||||
let elemId = event.currentTarget.attributes['data-id'].value;
|
||||
if (className.indexOf('disabled') < 0 && event.key == 'Tab') {
|
||||
if (event.shiftKey && elemId == this.firstSlotId) {
|
||||
event.preventDefault();
|
||||
this.slotItems[this.lastSlotId].focus();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
if (!event.shiftKey && elemId == this.lastSlotId) {
|
||||
event.preventDefault();
|
||||
this.slotItems[this.firstSlotId].focus();
|
||||
this.slotItems[this.firstSlotId].focus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -391,10 +391,10 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
|
||||
/**
|
||||
* Key Up
|
||||
*
|
||||
*
|
||||
*/
|
||||
_keyUp(select,event) {
|
||||
//nothing here yet
|
||||
// nothing here yet
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -487,7 +487,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
* @return {React.Component} List
|
||||
*/
|
||||
render() {
|
||||
console.log("Tracking focus? " + this.state.trackingFocus);
|
||||
console.log('Tracking focus? ' + this.state.trackingFocus);
|
||||
return (
|
||||
<div ref={node => this.node = node}
|
||||
className={cn('select', this.props.className)}
|
||||
|
||||
@@ -505,8 +505,8 @@ export default class Header extends TranslatedComponent {
|
||||
return (
|
||||
<header>
|
||||
{this.props.appCacheUpdate && <div id="app-update" onClick={() => window.location.reload() }>{translate('PHRASE_UPDATE_RDY')}</div>}
|
||||
{this.props.appCache ? <a className={"view-changes"} href={"https://github.com/EDCD/coriolis/compare/edcd:develop@{" + window.CORIOLIS_DATE + "}...edcd:develop"} target="_blank">
|
||||
{"View Release Changes"}
|
||||
{this.props.appCache ? <a className={'view-changes'} href={'https://github.com/EDCD/coriolis/compare/edcd:develop@{' + window.CORIOLIS_DATE + '}...edcd:develop'} target="_blank">
|
||||
{'View Release Changes'}
|
||||
</a> : null}
|
||||
<Link className='l' href='/' style={{ marginRight: '1em' }} title='Home'><CoriolisLogo className='icon xl' /></Link>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
getPercent,
|
||||
setRandom,
|
||||
specialToolTip
|
||||
} from '../utils/BlueprintFunctions'
|
||||
} from '../utils/BlueprintFunctions';
|
||||
|
||||
/**
|
||||
* Modifications menu
|
||||
@@ -50,8 +50,8 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
this.firstModId = null;
|
||||
this.firstBPLabel = null;// First item in mod menu
|
||||
this.lastModId = null;
|
||||
this.lastNeId = null;//Last number editor id. Used to set focus to last number editor when shift-tab pressed on first element in mod menu.
|
||||
this.modValDidChange = false; //used to determine if component update was caused by change in modification value.
|
||||
this.lastNeId = null;// Last number editor id. Used to set focus to last number editor when shift-tab pressed on first element in mod menu.
|
||||
this.modValDidChange = false; // used to determine if component update was caused by change in modification value.
|
||||
this._handleModChange = this._handleModChange.bind(this);
|
||||
|
||||
this.state = {
|
||||
@@ -78,19 +78,19 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
// Grade is a string in the JSON so make it a number
|
||||
grade = Number(grade);
|
||||
const classes = cn('c', {
|
||||
active: m.blueprint && blueprint.id === m.blueprint.id && grade === m.blueprint.grade
|
||||
active: m.blueprint && blueprint.id === m.blueprint.id && grade === m.blueprint.grade
|
||||
});
|
||||
const close = this._blueprintSelected.bind(this, blueprintName, grade);
|
||||
const key = blueprintName + ':' + grade;
|
||||
const tooltipContent = blueprintTooltip(translate, blueprint.grades[grade], Modifications.modules[m.grp].blueprints[blueprintName].grades[grade].engineers, m.grp);
|
||||
|
||||
|
||||
|
||||
|
||||
blueprintGrades.unshift(<li key={key} tabIndex="0" data-id={key} className={classes} style={{ width: '2em' }} onMouseOver={termtip.bind(null, tooltipContent)} onMouseOut={tooltip.bind(null, null)} onClick={close} onKeyDown={this._keyDown} ref={modItem => this.modItems[key] = modItem}>{grade}</li>);
|
||||
}
|
||||
if (blueprintGrades) {
|
||||
const thisLen = blueprintGrades.length;
|
||||
if (this.firstModId == null) this.firstModId = blueprintGrades[0].key;
|
||||
this.lastModId = blueprintGrades[thisLen-1].key;
|
||||
this.lastModId = blueprintGrades[thisLen - 1].key;
|
||||
blueprints.push(<div key={blueprint.name} className={'select-group cap'}>{translate(blueprint.name)}</div>);
|
||||
blueprints.push(<ul key={blueprintName}>{blueprintGrades}</ul>);
|
||||
}
|
||||
@@ -104,37 +104,36 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
* @param {SyntheticEvent} event Event
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
_keyDown(event) {
|
||||
var className = null;
|
||||
var elemId = null;
|
||||
let className = null;
|
||||
let elemId = null;
|
||||
if (event.currentTarget.attributes['class']) className = event.currentTarget.attributes['class'].value;
|
||||
if (event.currentTarget.attributes['data-id']) elemId = event.currentTarget.attributes['data-id'].value;
|
||||
|
||||
|
||||
if (event.key == 'Enter' && className.indexOf('disabled') < 0 && className.indexOf('active') < 0) {
|
||||
event.stopPropagation();
|
||||
if (elemId != null) {
|
||||
this.modItems[elemId].click();
|
||||
} else {
|
||||
|
||||
event.currentTarget.click();
|
||||
}
|
||||
return
|
||||
return;
|
||||
}
|
||||
if (event.key == 'Tab') {
|
||||
//Shift-Tab
|
||||
// Shift-Tab
|
||||
if(event.shiftKey) {
|
||||
if (elemId == this.firstModId && elemId != null) {
|
||||
// Initial modification menu
|
||||
event.preventDefault();
|
||||
this.modItems[this.lastModId].focus();
|
||||
return;
|
||||
} else if (event.currentTarget.className.indexOf("button-inline-menu") >= 0 && event.currentTarget.previousElementSibling == null && this.lastNeId != null && this.modItems[this.lastNeId] != null) {
|
||||
return;
|
||||
} else if (event.currentTarget.className.indexOf('button-inline-menu') >= 0 && event.currentTarget.previousElementSibling == null && this.lastNeId != null && this.modItems[this.lastNeId] != null) {
|
||||
// shift-tab on first element in modifications menu. set focus to last number editor field if open
|
||||
event.preventDefault();
|
||||
this.modItems[this.lastNeId].lastChild.focus();
|
||||
return;
|
||||
} else if (event.currentTarget.className.indexOf("button-inline-menu") >= 0 && event.currentTarget.previousElementSibling == null) {
|
||||
} else if (event.currentTarget.className.indexOf('button-inline-menu') >= 0 && event.currentTarget.previousElementSibling == null) {
|
||||
// shift-tab on button-inline-menu with no number editor
|
||||
event.preventDefault();
|
||||
event.currentTarget.parentElement.lastElementChild.focus();
|
||||
@@ -143,9 +142,9 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
if (elemId == this.lastModId && elemId != null) {
|
||||
// Initial modification menu
|
||||
event.preventDefault();
|
||||
this.modItems[this.firstModId].focus();
|
||||
this.modItems[this.firstModId].focus();
|
||||
return;
|
||||
} else if (event.currentTarget.className.indexOf("button-inline-menu") >= 0 && event.currentTarget.nextSibling == null && event.currentTarget.nodeName != "TD") {
|
||||
} else if (event.currentTarget.className.indexOf('button-inline-menu') >= 0 && event.currentTarget.nextSibling == null && event.currentTarget.nodeName != 'TD') {
|
||||
// Experimental menu
|
||||
event.preventDefault();
|
||||
event.currentTarget.parentElement.firstElementChild.focus();
|
||||
@@ -154,11 +153,10 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
event.preventDefault();
|
||||
this.modItems[this.firstBPLabel].focus();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Render the specials
|
||||
@@ -167,7 +165,6 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
* @return {Object} list: Array of React Components
|
||||
*/
|
||||
_renderSpecials(props, context) {
|
||||
|
||||
const { m } = props;
|
||||
const { language, tooltip, termtip } = context;
|
||||
const translate = language.translate;
|
||||
@@ -181,7 +178,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
continue;
|
||||
}
|
||||
const classes = cn('button-inline-menu', {
|
||||
active: m.blueprint && m.blueprint.special && m.blueprint.special.edname == specialName
|
||||
active: m.blueprint && m.blueprint.special && m.blueprint.special.edname == specialName
|
||||
});
|
||||
const close = this._specialSelected.bind(this, specialName);
|
||||
if (m.blueprint && m.blueprint.name) {
|
||||
@@ -200,7 +197,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log("_renderSpecials. specials: %O", specials);
|
||||
console.log('_renderSpecials. specials: %O', specials);
|
||||
return specials;
|
||||
}
|
||||
|
||||
@@ -219,7 +216,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
modifications.push(<Modification key={ key } ship={ ship } m={ m } name={ modName } value={ m.getModValue(modName) / 100 || 0 } onChange={ onChange } onKeyDown={ this._keyDown } modItems={ this.modItems } handleModChange = {this._handleModChange} />);
|
||||
}
|
||||
}
|
||||
console.log("_renderModifications. modItems: %O", this.modItems);
|
||||
console.log('_renderModifications. modItems: %O', this.modItems);
|
||||
return modifications;
|
||||
}
|
||||
|
||||
@@ -280,10 +277,10 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
_rollFifty() {
|
||||
const { m, ship } = this.props;
|
||||
setPercent(ship, m, 50);
|
||||
|
||||
|
||||
// this will change the values in the modifications. Set modDidChange to true to prevent focus change when component updates
|
||||
this._handleModChange(true);
|
||||
|
||||
|
||||
this.props.onChange();
|
||||
}
|
||||
|
||||
@@ -293,10 +290,10 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
_rollRandom() {
|
||||
const { m, ship } = this.props;
|
||||
setRandom(ship, m);
|
||||
|
||||
|
||||
// this will change the values in the modifications. Set modDidChange to true to prevent focus change when component updates
|
||||
this._handleModChange(true);
|
||||
|
||||
|
||||
this.props.onChange();
|
||||
}
|
||||
|
||||
@@ -306,10 +303,10 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
_rollBest() {
|
||||
const { m, ship } = this.props;
|
||||
setPercent(ship, m, 100);
|
||||
|
||||
|
||||
// this will change the values in the modifications. Set modDidChange to true to prevent focus change when component updates
|
||||
this._handleModChange(true);
|
||||
|
||||
|
||||
this.props.onChange();
|
||||
}
|
||||
|
||||
@@ -319,13 +316,11 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
_rollWorst() {
|
||||
const { m, ship } = this.props;
|
||||
setPercent(ship, m, 0);
|
||||
|
||||
|
||||
// this will change the values in the modifications. Set modDidChange to true to prevent focus change when component updates
|
||||
this._handleModChange(true);
|
||||
|
||||
this.props.onChange();
|
||||
|
||||
|
||||
this.props.onChange();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,9 +369,8 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this._handleModChange(false);//Need to reset if component update due to value change
|
||||
this._handleModChange(false);// Need to reset if component update due to value change
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -407,7 +401,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
let haveBlueprint = false;
|
||||
let blueprintTt;
|
||||
let blueprintCv;
|
||||
//TODO: Fix this to actually find the correct blueprint.
|
||||
// TODO: Fix this to actually find the correct blueprint.
|
||||
if (!m.blueprint || !m.blueprint.name || !m.blueprint.fdname || !Modifications.modules[m.grp].blueprints || !Modifications.modules[m.grp].blueprints[m.blueprint.fdname]) {
|
||||
this.props.ship.clearModuleBlueprint(m);
|
||||
this.props.ship.clearModuleSpecial(m);
|
||||
@@ -440,7 +434,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
const showReset = !blueprintMenuOpened && (!specialMenuOpened || !specials.length) && haveBlueprint;
|
||||
const showMods = !blueprintMenuOpened && (!specialMenuOpened || !specials.length) && haveBlueprint;
|
||||
if (haveBlueprint) {
|
||||
this.firstBPLabel = blueprintLabel
|
||||
this.firstBPLabel = blueprintLabel;
|
||||
} else {
|
||||
this.firstBPLabel = 'selectBP';
|
||||
}
|
||||
@@ -451,20 +445,20 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
onContextMenu={stopCtxPropagation}
|
||||
ref={modItem => this.modItems['modMainDiv'] = modItem}
|
||||
>
|
||||
{ showBlueprintsMenu | showSpecialsMenu ? '' : haveBlueprint ?
|
||||
<div tabIndex="0" className={ cn('section-menu button-inline-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onMouseOver={termtip.bind(null, blueprintTt)} onMouseOut={tooltip.bind(null, null)} onClick={_toggleBlueprintsMenu} onKeyDown={ this._keyDown } ref={modItems => this.modItems[this.firstBPLabel] = modItems}>{blueprintLabel}</div> :
|
||||
{ showBlueprintsMenu | showSpecialsMenu ? '' : haveBlueprint ?
|
||||
<div tabIndex="0" className={ cn('section-menu button-inline-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onMouseOver={termtip.bind(null, blueprintTt)} onMouseOut={tooltip.bind(null, null)} onClick={_toggleBlueprintsMenu} onKeyDown={ this._keyDown } ref={modItems => this.modItems[this.firstBPLabel] = modItems}>{blueprintLabel}</div> :
|
||||
<div tabIndex="0" className={ cn('section-menu button-inline-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu} onKeyDown={ this._keyDown } ref={modItems => this.modItems[this.firstBPLabel] = modItems}>{translate('PHRASE_SELECT_BLUEPRINT')}</div> }
|
||||
{ showBlueprintsMenu ? this._renderBlueprints(this.props, this.context) : null }
|
||||
{ showSpecial & !showSpecialsMenu ? <div tabIndex="0" className={ cn('section-menu button-inline-menu', { selected: specialMenuOpened })} style={{ cursor: 'pointer' }} onMouseOver={specialTt ? termtip.bind(null, specialTt) : null} onMouseOut={specialTt ? tooltip.bind(null, null) : null} onClick={_toggleSpecialsMenu} onKeyDown={ this._keyDown }>{specialLabel}</div> : null }
|
||||
{ showSpecialsMenu ? specials : null }
|
||||
{ showReset ? <div tabIndex="0" className={'section-menu button-inline-menu warning'} style={{ cursor: 'pointer' }} onClick={_reset} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RESET')} onMouseOut={tooltip.bind(null, null)}> { translate('reset') } </div> : null }
|
||||
{ showRolls ?
|
||||
|
||||
|
||||
<table style={{ width: '100%', backgroundColor: 'transparent' }}>
|
||||
<tbody>
|
||||
{ showRolls ?
|
||||
<tr>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', {active: false})}> { translate('roll') }: </td>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: false })}> { translate('roll') }: </td>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 0 })} style={{ cursor: 'pointer' }} onClick={_rollWorst} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_WORST')} onMouseOut={tooltip.bind(null, null)}> { translate('0%') } </td>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 50 })} style={{ cursor: 'pointer' }} onClick={_rollFifty} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_FIFTY')} onMouseOut={tooltip.bind(null, null)}> { translate('50%') } </td>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 100 })} style={{ cursor: 'pointer' }} onClick={_rollFull} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('100%') } </td>
|
||||
|
||||
@@ -19,11 +19,11 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
super(props);
|
||||
this.didContextChange = this.didContextChange.bind(this);
|
||||
this.state = {
|
||||
shieldColour: 'blue'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
||||
}
|
||||
this.state = {
|
||||
shieldColour
|
||||
}
|
||||
};
|
||||
return <div id='summary'>
|
||||
<table className={'summaryTable'}>
|
||||
<thead>
|
||||
@@ -140,8 +140,8 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
||||
<td>{int(ship.shieldThermRes * 100) + '%'}</td>
|
||||
<td>{int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.absolute.total : 0)}</td>
|
||||
<td>{int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.explosive.total : 0)}</td>
|
||||
<td>{int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.kinetic.total : 0 )}</td>
|
||||
<td>{int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.thermal.total : 0 )}</td>
|
||||
<td>{int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.kinetic.total : 0)}</td>
|
||||
<td>{int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.thermal.total : 0)}</td>
|
||||
<td>{sgMetrics && sgMetrics.recover ? formats.time(sgMetrics.recover) : 0}</td>
|
||||
<td>{sgMetrics && sgMetrics.recharge ? formats.time(sgMetrics.recharge) : 0}</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,361 +1,353 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const MARGIN_LR = 8; // Left/ Right margin
|
||||
|
||||
/**
|
||||
* Horizontal Slider
|
||||
*/
|
||||
export default class Slider extends React.Component {
|
||||
|
||||
static defaultProps = {
|
||||
axis: false,
|
||||
min: 0,
|
||||
max: 1,
|
||||
scale: 1 // SVG render scale
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
axis: PropTypes.bool,
|
||||
axisUnit: PropTypes.string,//units (T, M, etc.)
|
||||
max: PropTypes.number,
|
||||
min: PropTypes.number,
|
||||
onChange: PropTypes.func.isRequired,// function which determins percent value
|
||||
onResize: PropTypes.func,
|
||||
percent: PropTypes.number.isRequired,//value of slider
|
||||
scale: PropTypes.number
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param {Object} props React Component properties
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._down = this._down.bind(this);
|
||||
this._move = this._move.bind(this);
|
||||
this._up = this._up.bind(this);
|
||||
this._keyup = this._keyup.bind(this);
|
||||
this._keydown = this._keydown.bind(this);
|
||||
this._touchstart = this._touchstart.bind(this);
|
||||
this._touchend = this._touchend.bind(this);
|
||||
|
||||
this._updatePercent = this._updatePercent.bind(this);
|
||||
this._updateDimensions = this._updateDimensions.bind(this);
|
||||
|
||||
this.state = { width: 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* On Mouse/Touch down handler
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_down(event) {
|
||||
|
||||
let rect = event.currentTarget.getBoundingClientRect();
|
||||
this.left = rect.left;
|
||||
this.width = rect.width;
|
||||
this._move(event);
|
||||
this.touchStartTimer = setTimeout(() => this.sliderInputBox._setDisplay('block'), 1500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the slider percentage on move
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_move(event) {
|
||||
if(this.width !== null && this.left != null) {
|
||||
let clientX = event.touches ? event.touches[0].clientX : event.clientX;
|
||||
event.preventDefault();
|
||||
this._updatePercent(clientX - this.left, this.width);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Mouse/Touch up handler
|
||||
* @param {Event} event DOM Event
|
||||
*/
|
||||
_up(event) {
|
||||
this.sliderInputBox.sliderVal.focus();
|
||||
clearTimeout(this.touchStartTimer);
|
||||
event.preventDefault();
|
||||
this.left = null;
|
||||
this.width = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Key up handler for keyboard.
|
||||
* display the number field then set focus to it
|
||||
* when "Enter" key is pressed
|
||||
* @param {Event} event Keyboard event
|
||||
*/
|
||||
_keyup(event) {
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
event.preventDefault();
|
||||
this.sliderInputBox._setDisplay('block');
|
||||
//this.enterTimer = setTimeout(() => this.sliderInputBox.sliderVal.focus(), 10);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Key down handler
|
||||
* increment slider position by +/- 1 when right/left arrow key is pressed or held
|
||||
* @param {Event} event
|
||||
*/
|
||||
_keydown(event) {
|
||||
|
||||
switch (event.key) {
|
||||
case 'ArrowRight':
|
||||
var newVal = this.props.percent*this.props.max + 1;
|
||||
if (newVal <= this.props.max) this.props.onChange(newVal/this.props.max);
|
||||
return;
|
||||
case 'ArrowLeft':
|
||||
var newVal = this.props.percent*this.props.max - 1;
|
||||
if (newVal >= 0) this.props.onChange(newVal/this.props.max);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Touch start handler
|
||||
* @param {Event} event DOM Event
|
||||
*
|
||||
*/
|
||||
_touchstart(event) {
|
||||
this.touchStartTimer = setTimeout(() => this.sliderInputBox._setDisplay('block'), 1500);
|
||||
}
|
||||
|
||||
_touchend(event) {
|
||||
this.sliderInputBox.sliderVal.focus();
|
||||
clearTimeout(this.touchStartTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user is still dragging
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_enter(event) {
|
||||
if(event.buttons !== 1) {
|
||||
this.left = null;
|
||||
this.width = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the slider percentage
|
||||
* @param {number} pos Slider drag position
|
||||
* @param {number} width Slider width
|
||||
* @param {Event} event DOM Event
|
||||
*/
|
||||
_updatePercent(pos, width) {
|
||||
this.props.onChange(Math.min(Math.max(pos / width, 0), 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update dimenions from rendered DOM
|
||||
*/
|
||||
_updateDimensions() {
|
||||
this.setState({
|
||||
outerWidth: this.node.getBoundingClientRect().width
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add listeners when about to mount
|
||||
*/
|
||||
componentWillMount() {
|
||||
if (this.props.onResize) {
|
||||
this.resizeListener = this.props.onResize(this._updateDimensions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger DOM updates on mount
|
||||
*/
|
||||
componentDidMount() {
|
||||
this._updateDimensions();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove listeners on unmount
|
||||
*/
|
||||
componentWillUnmount() {
|
||||
if (this.resizeListener) {
|
||||
this.resizeListener.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the slider
|
||||
* @return {React.Component} The slider
|
||||
*/
|
||||
render() {
|
||||
let outerWidth = this.state.outerWidth;
|
||||
let { axis, axisUnit, min, max, scale } = this.props;
|
||||
|
||||
let style = {
|
||||
width: '100%',
|
||||
height: axis ? '2.5em' : '1.5em',
|
||||
boxSizing: 'border-box'
|
||||
};
|
||||
|
||||
if (!outerWidth) {
|
||||
return <svg style={style} ref={node => this.node = node} />;
|
||||
}
|
||||
|
||||
let margin = MARGIN_LR * scale;
|
||||
let width = outerWidth - (margin * 2);
|
||||
let pctPos = width * this.props.percent;
|
||||
|
||||
return <div><svg
|
||||
onMouseUp={this._up} onMouseEnter={this._enter.bind(this)} onMouseMove={this._move} onKeyUp={this._keyup} onKeyDown={this._keydown} style={style} ref={node => this.node = node} tabIndex="0">
|
||||
<rect className='primary' style={{ opacity: 0.3 }} x={margin} y='0.25em' rx='0.3em' ry='0.3em' width={width} height='0.7em' />
|
||||
<rect className='primary-disabled' x={margin} y='0.45em' rx='0.15em' ry='0.15em' width={pctPos} height='0.3em' />
|
||||
<circle className='primary' r={margin} cy='0.6em' cx={pctPos + margin} />
|
||||
<rect x={margin} width={width} height='100%' fillOpacity='0' style={{ cursor: 'col-resize' }} onMouseDown={this._down} onTouchMove={this._move} onTouchStart={this._down} onTouchEnd={this._touchend} />
|
||||
{axis && <g style={{ fontSize: '.7em' }}>
|
||||
<text className='primary-disabled' y='3em' x={margin} style={{ textAnchor: 'middle' }}>{min + axisUnit}</text>
|
||||
<text className='primary-disabled' y='3em' x='50%' style={{ textAnchor: 'middle' }}>{(min + max / 2) + axisUnit}</text>
|
||||
<text className='primary-disabled' y='3em' x='100%' style={{ textAnchor: 'end' }}>{max + axisUnit}</text>
|
||||
</g>}
|
||||
</svg>
|
||||
<TextInputBox ref={(tb) => this.sliderInputBox = tb}
|
||||
onChange={this.props.onChange}
|
||||
percent={this.props.percent}
|
||||
axisUnit={this.props.axisUnit}
|
||||
scale={this.props.scale}
|
||||
max={this.props.max}
|
||||
|
||||
/>
|
||||
</div>;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* New component to add keyboard support for sliders - works on all devices (desktop, iOS, Android)
|
||||
**/
|
||||
class TextInputBox extends React.Component {
|
||||
static propTypes = {
|
||||
axisUnit: PropTypes.string,//units (T, M, etc.)
|
||||
max: PropTypes.number,
|
||||
onChange: PropTypes.func.isRequired,// function which determins percent value
|
||||
percent: PropTypes.number.isRequired,//value of slider
|
||||
scale: PropTypes.number
|
||||
};
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._handleFocus = this._handleFocus.bind(this);
|
||||
this._handleBlur = this._handleBlur.bind(this);
|
||||
this._handleChange = this._handleChange.bind(this);
|
||||
//this._keydown = this._keydown.bind(this);
|
||||
this._keyup = this._keyup.bind(this);
|
||||
this.state = this._getInitialState();
|
||||
this.percent = this.props.percent;
|
||||
this.max = this.props.max;
|
||||
this.state.inputValue = this.percent * this.max;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextState) {
|
||||
var nextValue = nextProps.percent * nextProps.max;
|
||||
// See https://stackoverflow.com/questions/32414308/updating-state-on-props-change-in-react-form
|
||||
if (nextValue !== this.state.inputValue && nextValue <= nextProps.max) {
|
||||
this.setState({ inputValue: nextValue });
|
||||
}
|
||||
}
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
|
||||
if (prevState.divStyle.display == 'none' && this.state.divStyle.display == 'block') {
|
||||
this.enterTimer = setTimeout(() => this.sliderVal.focus(), 10);
|
||||
}
|
||||
|
||||
if (prevProps.max !== this.props.max && this.state.inputValue > this.props.max) {
|
||||
// they chose a different module
|
||||
this.setState({ inputValue: this.props.max });
|
||||
}
|
||||
|
||||
if (this.state.inputValue != prevState.inputValue && prevProps.max == this.props.max) {
|
||||
this.props.onChange(this.state.inputValue/this.props.max);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_getInitialState() {
|
||||
return {
|
||||
divStyle: {display:'none'},
|
||||
inputStyle: {width:'4em'},
|
||||
labelStyle: {marginLeft: '.1em'},
|
||||
maxLength:5,
|
||||
size:5,
|
||||
min:0,
|
||||
tabIndex:-1,
|
||||
type:'number',
|
||||
readOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
_setDisplay(val) {
|
||||
this.setState({
|
||||
divStyle: {display:val}
|
||||
});
|
||||
}
|
||||
|
||||
_handleFocus() {
|
||||
this.setState({
|
||||
inputValue:this._getValue()
|
||||
});
|
||||
}
|
||||
|
||||
_handleBlur() {
|
||||
this._setDisplay('none');
|
||||
if (this.state.inputValue !== '') {
|
||||
this.props.onChange(this.state.inputValue/this.props.max);
|
||||
} else {
|
||||
this.state.inputValue = this.props.percent * this.props.max;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_getValue() {
|
||||
return this.state.inputValue;
|
||||
}
|
||||
|
||||
_handleChange(event) {
|
||||
if (event.target.value < 0) {
|
||||
this.setState({inputValue: 0});
|
||||
} else if (event.target.value <= this.props.max) {
|
||||
this.setState({inputValue: event.target.value});
|
||||
} else {
|
||||
this.setState({inputValue: this.props.max});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Key up handler for input field.
|
||||
* If user hits Enter key, blur/close the input field
|
||||
* @param {Event} event Keyboard event
|
||||
*/
|
||||
_keyup(event) {
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
this.sliderVal.blur();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
let { axisUnit, onChange, percent, scale } = this.props;
|
||||
return <div style={this.state.divStyle}><input style={this.state.inputStyle} value={this._getValue()} min={this.state.min} max={this.props.max} onChange={this._handleChange} onKeyUp={this._keyup} tabIndex={this.state.tabIndex} maxLength={this.state.maxLength} size={this.state.size} onBlur={() => {this._handleBlur()}} onFocus={() => {this._handleFocus()}} type={this.state.type} ref={(ip) => this.sliderVal = ip}/><text className="primary upp" style={this.state.labelStyle}>{this.props.axisUnit}</text></div>;
|
||||
}
|
||||
}
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const MARGIN_LR = 8; // Left/ Right margin
|
||||
|
||||
/**
|
||||
* Horizontal Slider
|
||||
*/
|
||||
export default class Slider extends React.Component {
|
||||
|
||||
static defaultProps = {
|
||||
axis: false,
|
||||
min: 0,
|
||||
max: 1,
|
||||
scale: 1 // SVG render scale
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
axis: PropTypes.bool,
|
||||
axisUnit: PropTypes.string,// units (T, M, etc.)
|
||||
max: PropTypes.number,
|
||||
min: PropTypes.number,
|
||||
onChange: PropTypes.func.isRequired,// function which determins percent value
|
||||
onResize: PropTypes.func,
|
||||
percent: PropTypes.number.isRequired,// value of slider
|
||||
scale: PropTypes.number
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param {Object} props React Component properties
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._down = this._down.bind(this);
|
||||
this._move = this._move.bind(this);
|
||||
this._up = this._up.bind(this);
|
||||
this._keyup = this._keyup.bind(this);
|
||||
this._keydown = this._keydown.bind(this);
|
||||
this._touchstart = this._touchstart.bind(this);
|
||||
this._touchend = this._touchend.bind(this);
|
||||
|
||||
this._updatePercent = this._updatePercent.bind(this);
|
||||
this._updateDimensions = this._updateDimensions.bind(this);
|
||||
|
||||
this.state = { width: 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* On Mouse/Touch down handler
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_down(event) {
|
||||
let rect = event.currentTarget.getBoundingClientRect();
|
||||
this.left = rect.left;
|
||||
this.width = rect.width;
|
||||
this._move(event);
|
||||
this.touchStartTimer = setTimeout(() => this.sliderInputBox._setDisplay('block'), 1500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the slider percentage on move
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_move(event) {
|
||||
if(this.width !== null && this.left != null) {
|
||||
let clientX = event.touches ? event.touches[0].clientX : event.clientX;
|
||||
event.preventDefault();
|
||||
this._updatePercent(clientX - this.left, this.width);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Mouse/Touch up handler
|
||||
* @param {Event} event DOM Event
|
||||
*/
|
||||
_up(event) {
|
||||
this.sliderInputBox.sliderVal.focus();
|
||||
clearTimeout(this.touchStartTimer);
|
||||
event.preventDefault();
|
||||
this.left = null;
|
||||
this.width = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Key up handler for keyboard.
|
||||
* display the number field then set focus to it
|
||||
* when "Enter" key is pressed
|
||||
* @param {Event} event Keyboard event
|
||||
*/
|
||||
_keyup(event) {
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
event.preventDefault();
|
||||
this.sliderInputBox._setDisplay('block');
|
||||
// this.enterTimer = setTimeout(() => this.sliderInputBox.sliderVal.focus(), 10);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Key down handler
|
||||
* increment slider position by +/- 1 when right/left arrow key is pressed or held
|
||||
* @param {Event} event
|
||||
*/
|
||||
_keydown(event) {
|
||||
switch (event.key) {
|
||||
case 'ArrowRight':
|
||||
let newVal = this.props.percent * this.props.max + 1;
|
||||
if (newVal <= this.props.max) this.props.onChange(newVal / this.props.max);
|
||||
return;
|
||||
case 'ArrowLeft':
|
||||
let newVal = this.props.percent * this.props.max - 1;
|
||||
if (newVal >= 0) this.props.onChange(newVal / this.props.max);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Touch start handler
|
||||
* @param {Event} event DOM Event
|
||||
*
|
||||
*/
|
||||
_touchstart(event) {
|
||||
this.touchStartTimer = setTimeout(() => this.sliderInputBox._setDisplay('block'), 1500);
|
||||
}
|
||||
|
||||
_touchend(event) {
|
||||
this.sliderInputBox.sliderVal.focus();
|
||||
clearTimeout(this.touchStartTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user is still dragging
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_enter(event) {
|
||||
if(event.buttons !== 1) {
|
||||
this.left = null;
|
||||
this.width = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the slider percentage
|
||||
* @param {number} pos Slider drag position
|
||||
* @param {number} width Slider width
|
||||
* @param {Event} event DOM Event
|
||||
*/
|
||||
_updatePercent(pos, width) {
|
||||
this.props.onChange(Math.min(Math.max(pos / width, 0), 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update dimenions from rendered DOM
|
||||
*/
|
||||
_updateDimensions() {
|
||||
this.setState({
|
||||
outerWidth: this.node.getBoundingClientRect().width
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add listeners when about to mount
|
||||
*/
|
||||
componentWillMount() {
|
||||
if (this.props.onResize) {
|
||||
this.resizeListener = this.props.onResize(this._updateDimensions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger DOM updates on mount
|
||||
*/
|
||||
componentDidMount() {
|
||||
this._updateDimensions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove listeners on unmount
|
||||
*/
|
||||
componentWillUnmount() {
|
||||
if (this.resizeListener) {
|
||||
this.resizeListener.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the slider
|
||||
* @return {React.Component} The slider
|
||||
*/
|
||||
render() {
|
||||
let outerWidth = this.state.outerWidth;
|
||||
let { axis, axisUnit, min, max, scale } = this.props;
|
||||
|
||||
let style = {
|
||||
width: '100%',
|
||||
height: axis ? '2.5em' : '1.5em',
|
||||
boxSizing: 'border-box'
|
||||
};
|
||||
|
||||
if (!outerWidth) {
|
||||
return <svg style={style} ref={node => this.node = node} />;
|
||||
}
|
||||
|
||||
let margin = MARGIN_LR * scale;
|
||||
let width = outerWidth - (margin * 2);
|
||||
let pctPos = width * this.props.percent;
|
||||
|
||||
return <div><svg
|
||||
onMouseUp={this._up} onMouseEnter={this._enter.bind(this)} onMouseMove={this._move} onKeyUp={this._keyup} onKeyDown={this._keydown} style={style} ref={node => this.node = node} tabIndex="0">
|
||||
<rect className='primary' style={{ opacity: 0.3 }} x={margin} y='0.25em' rx='0.3em' ry='0.3em' width={width} height='0.7em' />
|
||||
<rect className='primary-disabled' x={margin} y='0.45em' rx='0.15em' ry='0.15em' width={pctPos} height='0.3em' />
|
||||
<circle className='primary' r={margin} cy='0.6em' cx={pctPos + margin} />
|
||||
<rect x={margin} width={width} height='100%' fillOpacity='0' style={{ cursor: 'col-resize' }} onMouseDown={this._down} onTouchMove={this._move} onTouchStart={this._down} onTouchEnd={this._touchend} />
|
||||
{axis && <g style={{ fontSize: '.7em' }}>
|
||||
<text className='primary-disabled' y='3em' x={margin} style={{ textAnchor: 'middle' }}>{min + axisUnit}</text>
|
||||
<text className='primary-disabled' y='3em' x='50%' style={{ textAnchor: 'middle' }}>{(min + max / 2) + axisUnit}</text>
|
||||
<text className='primary-disabled' y='3em' x='100%' style={{ textAnchor: 'end' }}>{max + axisUnit}</text>
|
||||
</g>}
|
||||
</svg>
|
||||
<TextInputBox ref={(tb) => this.sliderInputBox = tb}
|
||||
onChange={this.props.onChange}
|
||||
percent={this.props.percent}
|
||||
axisUnit={this.props.axisUnit}
|
||||
scale={this.props.scale}
|
||||
max={this.props.max}
|
||||
|
||||
/>
|
||||
</div>;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* New component to add keyboard support for sliders - works on all devices (desktop, iOS, Android)
|
||||
**/
|
||||
class TextInputBox extends React.Component {
|
||||
static propTypes = {
|
||||
axisUnit: PropTypes.string,// units (T, M, etc.)
|
||||
max: PropTypes.number,
|
||||
onChange: PropTypes.func.isRequired,// function which determins percent value
|
||||
percent: PropTypes.number.isRequired,// value of slider
|
||||
scale: PropTypes.number
|
||||
};
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._handleFocus = this._handleFocus.bind(this);
|
||||
this._handleBlur = this._handleBlur.bind(this);
|
||||
this._handleChange = this._handleChange.bind(this);
|
||||
// this._keydown = this._keydown.bind(this);
|
||||
this._keyup = this._keyup.bind(this);
|
||||
this.state = this._getInitialState();
|
||||
this.percent = this.props.percent;
|
||||
this.max = this.props.max;
|
||||
this.state.inputValue = this.percent * this.max;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextState) {
|
||||
let nextValue = nextProps.percent * nextProps.max;
|
||||
// See https://stackoverflow.com/questions/32414308/updating-state-on-props-change-in-react-form
|
||||
if (nextValue !== this.state.inputValue && nextValue <= nextProps.max) {
|
||||
this.setState({ inputValue: nextValue });
|
||||
}
|
||||
}
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (prevState.divStyle.display == 'none' && this.state.divStyle.display == 'block') {
|
||||
this.enterTimer = setTimeout(() => this.sliderVal.focus(), 10);
|
||||
}
|
||||
|
||||
if (prevProps.max !== this.props.max && this.state.inputValue > this.props.max) {
|
||||
// they chose a different module
|
||||
this.setState({ inputValue: this.props.max });
|
||||
}
|
||||
|
||||
if (this.state.inputValue != prevState.inputValue && prevProps.max == this.props.max) {
|
||||
this.props.onChange(this.state.inputValue / this.props.max);
|
||||
}
|
||||
}
|
||||
|
||||
_getInitialState() {
|
||||
return {
|
||||
divStyle: { display:'none' },
|
||||
inputStyle: { width:'4em' },
|
||||
labelStyle: { marginLeft: '.1em' },
|
||||
maxLength:5,
|
||||
size:5,
|
||||
min:0,
|
||||
tabIndex:-1,
|
||||
type:'number',
|
||||
readOnly: true
|
||||
};
|
||||
}
|
||||
|
||||
_setDisplay(val) {
|
||||
this.setState({
|
||||
divStyle: { display:val }
|
||||
});
|
||||
}
|
||||
|
||||
_handleFocus() {
|
||||
this.setState({
|
||||
inputValue:this._getValue()
|
||||
});
|
||||
}
|
||||
|
||||
_handleBlur() {
|
||||
this._setDisplay('none');
|
||||
if (this.state.inputValue !== '') {
|
||||
this.props.onChange(this.state.inputValue / this.props.max);
|
||||
} else {
|
||||
this.state.inputValue = this.props.percent * this.props.max;
|
||||
}
|
||||
}
|
||||
|
||||
_getValue() {
|
||||
return this.state.inputValue;
|
||||
}
|
||||
|
||||
_handleChange(event) {
|
||||
if (event.target.value < 0) {
|
||||
this.setState({ inputValue: 0 });
|
||||
} else if (event.target.value <= this.props.max) {
|
||||
this.setState({ inputValue: event.target.value });
|
||||
} else {
|
||||
this.setState({ inputValue: this.props.max });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Key up handler for input field.
|
||||
* If user hits Enter key, blur/close the input field
|
||||
* @param {Event} event Keyboard event
|
||||
*/
|
||||
_keyup(event) {
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
this.sliderVal.blur();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let { axisUnit, onChange, percent, scale } = this.props;
|
||||
return <div style={this.state.divStyle}><input style={this.state.inputStyle} value={this._getValue()} min={this.state.min} max={this.props.max} onChange={this._handleChange} onKeyUp={this._keyup} tabIndex={this.state.tabIndex} maxLength={this.state.maxLength} size={this.state.size} onBlur={() => {this._handleBlur();}} onFocus={() => {this._handleFocus();}} type={this.state.type} ref={(ip) => this.sliderVal = ip}/><text className="primary upp" style={this.state.labelStyle}>{this.props.axisUnit}</text></div>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,17 +81,17 @@ export default class Slot extends TranslatedComponent {
|
||||
* we do more or less the same thing
|
||||
* in every section when Enter key is pressed
|
||||
* on a focusable item
|
||||
*
|
||||
*
|
||||
*/
|
||||
_keyDown(event) {
|
||||
if (event.key == 'Enter') {
|
||||
if(event.target.className == 'r') {
|
||||
console.log("Slot: Enter key pressed on mod icon");
|
||||
this._toggleModifications();
|
||||
} else {
|
||||
console.log("Slot: Enter key pressed on: %O", event.target);
|
||||
}
|
||||
this.props.onOpen(event);
|
||||
if(event.target.className == 'r') {
|
||||
console.log('Slot: Enter key pressed on mod icon');
|
||||
this._toggleModifications();
|
||||
} else {
|
||||
console.log('Slot: Enter key pressed on: %O', event.target);
|
||||
}
|
||||
this.props.onOpen(event);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -154,7 +154,7 @@ export default class Slot extends TranslatedComponent {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Toggle the modifications flag when selecting the modifications icon
|
||||
*/
|
||||
|
||||
@@ -40,12 +40,12 @@ export default class StandardSlot extends TranslatedComponent {
|
||||
this.slotDiv = null;
|
||||
}
|
||||
|
||||
_keyDown(event) {
|
||||
_keyDown(event) {
|
||||
if (event.key == 'Enter') {
|
||||
if(event.target.className == 'r') {
|
||||
this._toggleModifications();
|
||||
}
|
||||
this.props.onOpen(event);
|
||||
if(event.target.className == 'r') {
|
||||
this._toggleModifications();
|
||||
}
|
||||
this.props.onOpen(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,6 @@ export default class StandardSlot extends TranslatedComponent {
|
||||
* Toggle the modifications flag when selecting the modifications icon
|
||||
*/
|
||||
_toggleModifications() {
|
||||
|
||||
this._modificationsSelected = !this._modificationsSelected;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,17 +554,17 @@ export default class OutfittingPage extends Page {
|
||||
const shipSummaryMarker = `${ship.name}${_sStr}${_iStr}${_hStr}${_pStr}${_mStr}${ship.ladenMass}${cargo}${fuel}`;
|
||||
|
||||
const requirements = Ships[ship.id].requirements;
|
||||
var requirementElements = [];
|
||||
let requirementElements = [];
|
||||
|
||||
function renderRequirement(className, textKey, tooltipTextKey) {
|
||||
requirementElements.push(<div key={textKey} className={className} onMouseEnter={termtip.bind(null, tooltipTextKey)} onMouseLeave={hide}><a href={textKey.startsWith("empire") ? 'http://elite-dangerous.wikia.com/wiki/Empire/Ranks' : 'http://elite-dangerous.wikia.com/wiki/Federation/Ranks'} target="_blank" rel="noopener">{translate(textKey)}</a></div>);
|
||||
requirementElements.push(<div key={textKey} className={className} onMouseEnter={termtip.bind(null, tooltipTextKey)} onMouseLeave={hide}><a href={textKey.startsWith('empire') ? 'http://elite-dangerous.wikia.com/wiki/Empire/Ranks' : 'http://elite-dangerous.wikia.com/wiki/Federation/Ranks'} target="_blank" rel="noopener">{translate(textKey)}</a></div>);
|
||||
}
|
||||
|
||||
if (requirements) {
|
||||
requirements.federationRank && renderRequirement('federation', 'federation rank ' + requirements.federationRank, 'federation rank required');
|
||||
requirements.empireRank && renderRequirement('empire', 'empire rank ' + requirements.empireRank, 'empire rank required');
|
||||
requirements.horizons && renderRequirement('horizons', 'horizons', 'horizons required');
|
||||
requirements.horizonsEarlyAdoption && renderRequirement('horizons', 'horizons early adoption', 'horizons early adoption required');
|
||||
requirements.horizonsEarlyAdoption && renderRequirement('horizons', 'horizons early adoption', 'horizons early adoption required');
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -602,7 +602,7 @@ export default class OutfittingPage extends Page {
|
||||
</div>
|
||||
|
||||
{/* Main tables */}
|
||||
<ShipSummaryTable ship={ship} fuel={fuel} cargo={cargo} marker={shipSummaryMarker} pips={{sys: this.state.sys, wep: this.state.wep, eng: this.state.eng}} />
|
||||
<ShipSummaryTable ship={ship} fuel={fuel} cargo={cargo} marker={shipSummaryMarker} pips={{ sys: this.state.sys, wep: this.state.wep, eng: this.state.eng }} />
|
||||
<StandardSlotSection ship={ship} fuel={fuel} cargo={cargo} code={standardSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} />
|
||||
<InternalSlotSection ship={ship} code={internalSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} />
|
||||
<HardpointSlotSection ship={ship} code={hardpointsSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} />
|
||||
|
||||
@@ -274,11 +274,11 @@ export default class ShipyardPage extends Page {
|
||||
|
||||
for (let s of shipSummaries) {
|
||||
let shipSortValue = s[shipPredicate];
|
||||
if( shipPredicateIndex != undefined ) {
|
||||
if(shipPredicateIndex != undefined) {
|
||||
shipSortValue = shipSortValue[shipPredicateIndex];
|
||||
}
|
||||
|
||||
if( shipSortValue != lastShipSortValue ) {
|
||||
if(shipSortValue != lastShipSortValue) {
|
||||
backgroundHighlight = !backgroundHighlight;
|
||||
lastShipSortValue = shipSortValue;
|
||||
}
|
||||
@@ -396,4 +396,4 @@ export default class ShipyardPage extends Page {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ export default class Module {
|
||||
if (modification.type === 'percentage') {
|
||||
modValue = this.getModValue(name) / 10000;
|
||||
} else if (modification.type === 'numeric') {
|
||||
modValue = this.getModValue(name)/ 100;
|
||||
modValue = this.getModValue(name) / 100;
|
||||
} else {
|
||||
modValue = this.getModValue(name);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ModuleUtils from './ModuleUtils'
|
||||
import { canMount } from '../utils/SlotFunctions'
|
||||
import * as ModuleUtils from './ModuleUtils';
|
||||
import { canMount } from '../utils/SlotFunctions';
|
||||
|
||||
/**
|
||||
* Standard / typical role for multi-purpose or combat (if shielded with better bulkheads)
|
||||
@@ -7,20 +7,20 @@ import { canMount } from '../utils/SlotFunctions'
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
* @param {integer} bulkheadIndex Bulkhead to use see Constants.BulkheadNames
|
||||
*/
|
||||
export function multiPurpose (ship, shielded, bulkheadIndex) {
|
||||
export function multiPurpose(ship, shielded, bulkheadIndex) {
|
||||
ship.useStandard('A')
|
||||
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')) // D Sensors
|
||||
.useBulkhead(bulkheadIndex)
|
||||
.useBulkhead(bulkheadIndex);
|
||||
|
||||
if (shielded) {
|
||||
ship.internal.some(function (slot) {
|
||||
ship.internal.some(function(slot) {
|
||||
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'))
|
||||
ship.setSlotEnabled(slot, true)
|
||||
return true
|
||||
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
|
||||
ship.setSlotEnabled(slot, true);
|
||||
return true;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,51 +30,51 @@ export function multiPurpose (ship, shielded, bulkheadIndex) {
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
* @param {Object} standardOpts [Optional] Standard module optional overrides
|
||||
*/
|
||||
export function trader (ship, shielded, standardOpts) {
|
||||
let usedSlots = []
|
||||
let bstCount = 2
|
||||
let sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
|
||||
export function trader(ship, shielded, standardOpts) {
|
||||
let usedSlots = [];
|
||||
let bstCount = 2;
|
||||
let sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
ship.useStandard('A')
|
||||
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[1], ModuleUtils.standard(1, ship.standard[1].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[4], ModuleUtils.standard(4, ship.standard[4].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')) // D Sensors
|
||||
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')); // D Sensors
|
||||
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
|
||||
shieldInternals.some(function (slot) {
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
shieldInternals.some(function(slot) {
|
||||
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||
const shield = ModuleUtils.findInternal('sg', slot.maxClass, 'A')
|
||||
const shield = ModuleUtils.findInternal('sg', slot.maxClass, 'A');
|
||||
if (shield && shield.maxmass > ship.hullMass) {
|
||||
ship.use(slot, shield)
|
||||
ship.setSlotEnabled(slot, true)
|
||||
usedSlots.push(slot)
|
||||
return true
|
||||
ship.use(slot, shield);
|
||||
ship.setSlotEnabled(slot, true);
|
||||
usedSlots.push(slot);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// Fill the empty internals with cargo racks
|
||||
for (let i = ship.internal.length; i--;) {
|
||||
let slot = ship.internal[i]
|
||||
let slot = ship.internal[i];
|
||||
if (usedSlots.indexOf(slot) == -1 && canMount(ship, slot, 'cr')) {
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'))
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'));
|
||||
}
|
||||
}
|
||||
|
||||
// Empty the hardpoints
|
||||
for (let s of ship.hardpoints) {
|
||||
ship.use(s, null)
|
||||
ship.use(s, null);
|
||||
}
|
||||
for (let s of ship.hardpoints) {
|
||||
if (s.maxClass == 0 && bstCount) { // Mount up to 2 boosters
|
||||
ship.use(s, ModuleUtils.hardpoints('04'))
|
||||
bstCount--
|
||||
ship.use(s, ModuleUtils.hardpoints('04'));
|
||||
bstCount--;
|
||||
} else {
|
||||
ship.use(s, null)
|
||||
ship.use(s, null);
|
||||
}
|
||||
}
|
||||
// ship.useLightestStandard(standardOpts);
|
||||
@@ -85,127 +85,127 @@ export function trader (ship, shielded, standardOpts) {
|
||||
* @param {Ship} ship Ship instance
|
||||
* @param {Boolean} planetary True if Planetary Vehicle Hangar (PVH) should be included
|
||||
*/
|
||||
export function explorer (ship, planetary) {
|
||||
let standardOpts = {ppRating: 'A'},
|
||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
fuelScoopSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
|
||||
export function explorer(ship, planetary) {
|
||||
let standardOpts = { ppRating: 'A' },
|
||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
fuelScoopSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
|
||||
if (!planetary) { // Non-planetary explorers don't really need to boost
|
||||
standardOpts.pd = '1D'
|
||||
standardOpts.pd = '1D';
|
||||
}
|
||||
|
||||
// Cargo hatch can be disabled
|
||||
ship.setSlotEnabled(ship.cargoHatch, false)
|
||||
ship.setSlotEnabled(ship.cargoHatch, false);
|
||||
|
||||
// Advanced Discovery Scanner - class 1 or higher
|
||||
const adsOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const adsOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const adsInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sc)
|
||||
.sort((a, b) => adsOrder.indexOf(a.maxClass) - adsOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => adsOrder.indexOf(a.maxClass) - adsOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < adsInternals.length; i++) {
|
||||
if (canMount(ship, adsInternals[i], 'sc')) {
|
||||
ship.use(adsInternals[i], ModuleUtils.internal('2f'))
|
||||
usedSlots.push(adsInternals[i])
|
||||
break
|
||||
ship.use(adsInternals[i], ModuleUtils.internal('2f'));
|
||||
usedSlots.push(adsInternals[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (planetary) {
|
||||
// Planetary Vehicle Hangar - class 2 or higher
|
||||
const pvhOrder = [2, 3, 4, 5, 6, 7, 8, 1]
|
||||
const pvhOrder = [2, 3, 4, 5, 6, 7, 8, 1];
|
||||
const pvhInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.pv)
|
||||
.sort((a, b) => pvhOrder.indexOf(a.maxClass) - pvhOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => pvhOrder.indexOf(a.maxClass) - pvhOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < pvhInternals.length; i++) {
|
||||
if (canMount(ship, pvhInternals[i], 'pv')) {
|
||||
// Planetary Vehical Hangar only has even classes
|
||||
const pvhClass = pvhInternals[i].maxClass % 2 === 1 ? pvhInternals[i].maxClass - 1 : pvhInternals[i].maxClass
|
||||
ship.use(pvhInternals[i], ModuleUtils.findInternal('pv', pvhClass, 'G')) // G is lower mass
|
||||
ship.setSlotEnabled(pvhInternals[i], false) // Disable power for Planetary Vehical Hangar
|
||||
usedSlots.push(pvhInternals[i])
|
||||
break
|
||||
const pvhClass = pvhInternals[i].maxClass % 2 === 1 ? pvhInternals[i].maxClass - 1 : pvhInternals[i].maxClass;
|
||||
ship.use(pvhInternals[i], ModuleUtils.findInternal('pv', pvhClass, 'G')); // G is lower mass
|
||||
ship.setSlotEnabled(pvhInternals[i], false); // Disable power for Planetary Vehical Hangar
|
||||
usedSlots.push(pvhInternals[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shield generator
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < shieldInternals.length; i++) {
|
||||
if (canMount(ship, shieldInternals[i], 'sg')) {
|
||||
ship.use(shieldInternals[i], sg)
|
||||
usedSlots.push(shieldInternals[i])
|
||||
sgSlot = shieldInternals[i]
|
||||
break
|
||||
ship.use(shieldInternals[i], sg);
|
||||
usedSlots.push(shieldInternals[i]);
|
||||
sgSlot = shieldInternals[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Detailed Surface Scanner
|
||||
const dssOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const dssOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const dssInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sc)
|
||||
.sort((a, b) => dssOrder.indexOf(a.maxClass) - dssOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => dssOrder.indexOf(a.maxClass) - dssOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < dssInternals.length; i++) {
|
||||
if (canMount(ship, dssInternals[i], 'sc')) {
|
||||
ship.use(dssInternals[i], ModuleUtils.internal('2i'))
|
||||
usedSlots.push(dssInternals[i])
|
||||
break
|
||||
ship.use(dssInternals[i], ModuleUtils.internal('2i'));
|
||||
usedSlots.push(dssInternals[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fuel scoop - best possible
|
||||
const fuelScoopOrder = [8, 7, 6, 5, 4, 3, 2, 1]
|
||||
const fuelScoopOrder = [8, 7, 6, 5, 4, 3, 2, 1];
|
||||
const fuelScoopInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.fs)
|
||||
.sort((a, b) => fuelScoopOrder.indexOf(a.maxClass) - fuelScoopOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => fuelScoopOrder.indexOf(a.maxClass) - fuelScoopOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < fuelScoopInternals.length; i++) {
|
||||
if (canMount(ship, fuelScoopInternals[i], 'fs')) {
|
||||
ship.use(fuelScoopInternals[i], ModuleUtils.findInternal('fs', fuelScoopInternals[i].maxClass, 'A'))
|
||||
usedSlots.push(fuelScoopInternals[i])
|
||||
fuelScoopSlot = fuelScoopInternals[i]
|
||||
break
|
||||
ship.use(fuelScoopInternals[i], ModuleUtils.findInternal('fs', fuelScoopInternals[i].maxClass, 'A'));
|
||||
usedSlots.push(fuelScoopInternals[i]);
|
||||
fuelScoopSlot = fuelScoopInternals[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// AFMUs - fill as they are 0-weight
|
||||
const afmuOrder = [8, 7, 6, 5, 4, 3, 2, 1]
|
||||
const afmuOrder = [8, 7, 6, 5, 4, 3, 2, 1];
|
||||
const afmuInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.pc)
|
||||
.sort((a, b) => afmuOrder.indexOf(a.maxClass) - afmuOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => afmuOrder.indexOf(a.maxClass) - afmuOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < afmuInternals.length; i++) {
|
||||
if (canMount(ship, afmuInternals[i], 'am')) {
|
||||
ship.use(afmuInternals[i], ModuleUtils.findInternal('am', afmuInternals[i].maxClass, 'A'))
|
||||
usedSlots.push(afmuInternals[i])
|
||||
ship.setSlotEnabled(afmuInternals[i], false) // Disable power for AFM Unit
|
||||
ship.use(afmuInternals[i], ModuleUtils.findInternal('am', afmuInternals[i].maxClass, 'A'));
|
||||
usedSlots.push(afmuInternals[i]);
|
||||
ship.setSlotEnabled(afmuInternals[i], false); // Disable power for AFM Unit
|
||||
}
|
||||
}
|
||||
|
||||
for (let s of ship.hardpoints) {
|
||||
if (s.maxClass == 0 && heatSinkCount) { // Mount up to 2 heatsinks
|
||||
ship.use(s, ModuleUtils.hardpoints('02'))
|
||||
ship.setSlotEnabled(s, heatSinkCount == 2) // Only enable a single Heatsink
|
||||
heatSinkCount--
|
||||
ship.use(s, ModuleUtils.hardpoints('02'));
|
||||
ship.setSlotEnabled(s, heatSinkCount == 2); // Only enable a single Heatsink
|
||||
heatSinkCount--;
|
||||
} else {
|
||||
ship.use(s, null)
|
||||
ship.use(s, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (sgSlot && fuelScoopSlot) {
|
||||
// The SG and Fuel scoop to not need to be powered at the same time
|
||||
if (sgSlot.m.getPowerUsage() > fuelScoopSlot.m.getPowerUsage()) { // The Shield generator uses the most power
|
||||
ship.setSlotEnabled(fuelScoopSlot, false)
|
||||
ship.setSlotEnabled(fuelScoopSlot, false);
|
||||
} else { // The Fuel scoop uses the most power
|
||||
ship.setSlotEnabled(sgSlot, false)
|
||||
ship.setSlotEnabled(sgSlot, false);
|
||||
}
|
||||
}
|
||||
|
||||
ship.useLightestStandard(standardOpts)
|
||||
ship.useLightestStandard(standardOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,188 +213,188 @@ export function explorer (ship, planetary) {
|
||||
* @param {Ship} ship Ship instance
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
*/
|
||||
export function miner (ship, shielded) {
|
||||
shielded = true
|
||||
let standardOpts = {ppRating: 'A'},
|
||||
miningLaserCount = 2,
|
||||
usedSlots = [],
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
|
||||
export function miner(ship, shielded) {
|
||||
shielded = true;
|
||||
let standardOpts = { ppRating: 'A' },
|
||||
miningLaserCount = 2,
|
||||
usedSlots = [],
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
|
||||
// Cargo hatch should be enabled
|
||||
ship.setSlotEnabled(ship.cargoHatch, true)
|
||||
ship.setSlotEnabled(ship.cargoHatch, true);
|
||||
|
||||
// Largest possible refinery
|
||||
const refineryOrder = [4, 5, 6, 7, 8, 3, 2, 1]
|
||||
const refineryOrder = [4, 5, 6, 7, 8, 3, 2, 1];
|
||||
const refineryInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.rf)
|
||||
.sort((a, b) => refineryOrder.indexOf(a.maxClass) - refineryOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => refineryOrder.indexOf(a.maxClass) - refineryOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < refineryInternals.length; i++) {
|
||||
if (canMount(ship, refineryInternals[i], 'rf')) {
|
||||
ship.use(refineryInternals[i], ModuleUtils.findInternal('rf', Math.min(refineryInternals[i].maxClass, 4), 'A'))
|
||||
usedSlots.push(refineryInternals[i])
|
||||
break
|
||||
ship.use(refineryInternals[i], ModuleUtils.findInternal('rf', Math.min(refineryInternals[i].maxClass, 4), 'A'));
|
||||
usedSlots.push(refineryInternals[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prospector limpet controller - 3A if possible
|
||||
const prospectorOrder = [3, 4, 5, 6, 7, 8, 2, 1]
|
||||
const prospectorOrder = [3, 4, 5, 6, 7, 8, 2, 1];
|
||||
const prospectorInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.pc)
|
||||
.sort((a, b) => prospectorOrder.indexOf(a.maxClass) - prospectorOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => prospectorOrder.indexOf(a.maxClass) - prospectorOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < prospectorInternals.length; i++) {
|
||||
if (canMount(ship, prospectorInternals[i], 'pc')) {
|
||||
// Prospector only has odd classes
|
||||
const prospectorClass = prospectorInternals[i].maxClass % 2 === 0 ? prospectorInternals[i].maxClass - 1 : prospectorInternals[i].maxClass
|
||||
ship.use(prospectorInternals[i], ModuleUtils.findInternal('pc', prospectorClass, 'A'))
|
||||
usedSlots.push(prospectorInternals[i])
|
||||
break
|
||||
const prospectorClass = prospectorInternals[i].maxClass % 2 === 0 ? prospectorInternals[i].maxClass - 1 : prospectorInternals[i].maxClass;
|
||||
ship.use(prospectorInternals[i], ModuleUtils.findInternal('pc', prospectorClass, 'A'));
|
||||
usedSlots.push(prospectorInternals[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Shield generator if required
|
||||
if (shielded) {
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < shieldInternals.length; i++) {
|
||||
if (canMount(ship, shieldInternals[i], 'sg')) {
|
||||
ship.use(shieldInternals[i], sg)
|
||||
usedSlots.push(shieldInternals[i])
|
||||
break
|
||||
ship.use(shieldInternals[i], sg);
|
||||
usedSlots.push(shieldInternals[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dual mining lasers of highest possible class; remove anything else
|
||||
const miningLaserOrder = [2, 3, 4, 1, 0]
|
||||
const miningLaserHardpoints = ship.hardpoints.concat().sort(function (a, b) {
|
||||
return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass)
|
||||
})
|
||||
const miningLaserOrder = [2, 3, 4, 1, 0];
|
||||
const miningLaserHardpoints = ship.hardpoints.concat().sort(function(a, b) {
|
||||
return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass);
|
||||
});
|
||||
for (let s of miningLaserHardpoints) {
|
||||
if (s.maxClass >= 1 && miningLaserCount) {
|
||||
ship.use(s, ModuleUtils.hardpoints(s.maxClass >= 2 ? '2m' : '2l'))
|
||||
miningLaserCount--
|
||||
ship.use(s, ModuleUtils.hardpoints(s.maxClass >= 2 ? '2m' : '2l'));
|
||||
miningLaserCount--;
|
||||
} else {
|
||||
ship.use(s, null)
|
||||
ship.use(s, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Number of collector limpets required to be active is a function of the size of the ship and the power of the lasers
|
||||
const miningLaserDps = ship.hardpoints.filter(h => h.m != null)
|
||||
.reduce(function (a, b) {
|
||||
return a + b.m.getDps()
|
||||
}, 0)
|
||||
.reduce(function(a, b) {
|
||||
return a + b.m.getDps();
|
||||
}, 0);
|
||||
// Find out how many internal slots we have, and their potential cargo size
|
||||
const potentialCargo = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.cr)
|
||||
.map(b => Math.pow(2, b.maxClass))
|
||||
.map(b => Math.pow(2, b.maxClass));
|
||||
// One collector for each 1.25 DPS, multiply by 1.25 for medium ships and 1.5 for large ships as they have further to travel
|
||||
// 0 if we only have 1 cargo slot, otherwise minium of 1 and maximum of 6 (excluding size modifier)
|
||||
const sizeModifier = ship.class == 2 ? 1.2 : ship.class == 3 ? 1.5 : 1
|
||||
let collectorLimpetsRequired = potentialCargo.length == 1 ? 0 : Math.ceil(sizeModifier * Math.min(6, Math.floor(miningLaserDps / 1.25)))
|
||||
const sizeModifier = ship.class == 2 ? 1.2 : ship.class == 3 ? 1.5 : 1;
|
||||
let collectorLimpetsRequired = potentialCargo.length == 1 ? 0 : Math.ceil(sizeModifier * Math.min(6, Math.floor(miningLaserDps / 1.25)));
|
||||
|
||||
if (collectorLimpetsRequired > 0) {
|
||||
const collectorOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const collectorOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const collectorInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.cc)
|
||||
.sort((a, b) => collectorOrder.indexOf(a.maxClass) - collectorOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => collectorOrder.indexOf(a.maxClass) - collectorOrder.indexOf(b.maxClass));
|
||||
// Always keep at least 2 slots free for cargo racks (1 for shielded)
|
||||
for (let i = 0; i < collectorInternals.length - (shielded ? 1 : 2) && collectorLimpetsRequired > 0; i++) {
|
||||
if (canMount(ship, collectorInternals[i], 'cc')) {
|
||||
// Collector only has odd classes
|
||||
const collectorClass = collectorInternals[i].maxClass % 2 === 0 ? collectorInternals[i].maxClass - 1 : collectorInternals[i].maxClass
|
||||
ship.use(collectorInternals[i], ModuleUtils.findInternal('cc', collectorClass, 'D'))
|
||||
usedSlots.push(collectorInternals[i])
|
||||
collectorLimpetsRequired -= collectorInternals[i].m.maximum
|
||||
const collectorClass = collectorInternals[i].maxClass % 2 === 0 ? collectorInternals[i].maxClass - 1 : collectorInternals[i].maxClass;
|
||||
ship.use(collectorInternals[i], ModuleUtils.findInternal('cc', collectorClass, 'D'));
|
||||
usedSlots.push(collectorInternals[i]);
|
||||
collectorLimpetsRequired -= collectorInternals[i].m.maximum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Power distributor to power the mining lasers indefinitely
|
||||
const wepRateRequired = ship.hardpoints.filter(h => h.m != null)
|
||||
.reduce(function (a, b) {
|
||||
return a + b.m.getEps()
|
||||
}, 0)
|
||||
standardOpts.pd = ship.getAvailableModules().matchingPowerDist({weprate: wepRateRequired}).id
|
||||
.reduce(function(a, b) {
|
||||
return a + b.m.getEps();
|
||||
}, 0);
|
||||
standardOpts.pd = ship.getAvailableModules().matchingPowerDist({ weprate: wepRateRequired }).id;
|
||||
|
||||
// Fill the empty internals with cargo racks
|
||||
for (let i = ship.internal.length; i--;) {
|
||||
let slot = ship.internal[i]
|
||||
let slot = ship.internal[i];
|
||||
if (usedSlots.indexOf(slot) == -1 && canMount(ship, slot, 'cr')) {
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'))
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'));
|
||||
}
|
||||
}
|
||||
|
||||
ship.useLightestStandard(standardOpts)
|
||||
ship.useLightestStandard(standardOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Racer Role
|
||||
* @param {Ship} ship Ship instance
|
||||
*/
|
||||
export function racer (ship) {
|
||||
export function racer(ship) {
|
||||
let standardOpts = {},
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
|
||||
// Cargo hatch can be disabled
|
||||
ship.setSlotEnabled(ship.cargoHatch, false)
|
||||
ship.setSlotEnabled(ship.cargoHatch, false);
|
||||
|
||||
// Shield generator
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < shieldInternals.length; i++) {
|
||||
if (canMount(ship, shieldInternals[i], 'sg')) {
|
||||
ship.use(shieldInternals[i], sg)
|
||||
usedSlots.push(shieldInternals[i])
|
||||
sgSlot = shieldInternals[i]
|
||||
break
|
||||
ship.use(shieldInternals[i], sg);
|
||||
usedSlots.push(shieldInternals[i]);
|
||||
sgSlot = shieldInternals[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Empty the hardpoints
|
||||
for (let s of ship.hardpoints) {
|
||||
ship.use(s, null)
|
||||
ship.use(s, null);
|
||||
}
|
||||
|
||||
// Empty the internals
|
||||
for (let i = ship.internal.length; i--;) {
|
||||
let slot = ship.internal[i]
|
||||
let slot = ship.internal[i];
|
||||
if (usedSlots.indexOf(slot) == -1) {
|
||||
ship.use(slot, null)
|
||||
ship.use(slot, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Best thrusters
|
||||
if (ship.standard[1].maxClass === 3) {
|
||||
standardOpts.th = 'tz'
|
||||
standardOpts.th = 'tz';
|
||||
} else if (ship.standard[1].maxClass === 2) {
|
||||
standardOpts.th = 'u0'
|
||||
standardOpts.th = 'u0';
|
||||
} else {
|
||||
standardOpts.th = ship.standard[1].maxClass + 'A'
|
||||
standardOpts.th = ship.standard[1].maxClass + 'A';
|
||||
}
|
||||
|
||||
// Best power distributor for more boosting
|
||||
standardOpts.pd = ship.standard[4].maxClass + 'A'
|
||||
standardOpts.pd = ship.standard[4].maxClass + 'A';
|
||||
|
||||
// Smallest possible FSD drive
|
||||
standardOpts.fsd = '2D'
|
||||
standardOpts.fsd = '2D';
|
||||
// Minimal fuel tank
|
||||
standardOpts.ft = '1C'
|
||||
standardOpts.ft = '1C';
|
||||
|
||||
// Disable nearly everything
|
||||
standardOpts.fsdDisabled = true
|
||||
standardOpts.sDisabled = true
|
||||
standardOpts.pdDisabled = true
|
||||
standardOpts.lsDisabled = true
|
||||
standardOpts.fsdDisabled = true;
|
||||
standardOpts.sDisabled = true;
|
||||
standardOpts.pdDisabled = true;
|
||||
standardOpts.lsDisabled = true;
|
||||
|
||||
ship.useLightestStandard(standardOpts)
|
||||
ship.useLightestStandard(standardOpts);
|
||||
|
||||
// Apply engineering to each module
|
||||
// ship.standard[1].m.blueprint = getBlueprint('Engine_Dirty', ship.standard[0]);
|
||||
|
||||
@@ -18,36 +18,35 @@ export function specialToolTip(translate, blueprint, grp, m, specialName) {
|
||||
if (m) {
|
||||
// We also add in any benefits from specials that aren't covered above
|
||||
if (m.blueprint) {
|
||||
for (const feature in Modifications.modifierActions[specialName]) {
|
||||
for (const feature in Modifications.modifierActions[specialName]) {
|
||||
// if (!blueprint.features[feature] && !m.mods.feature) {
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (featureDef && !featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let current = m.getModValue(feature) - m.getModValue(feature, true);
|
||||
if (featureDef.type === 'percentage') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (featureDef && !featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let current = m.getModValue(feature) - m.getModValue(feature, true);
|
||||
if (featureDef.type === 'percentage') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
|
||||
effects.push(
|
||||
<tr key={feature + '_specialTT'}>
|
||||
<td style={{textAlign: 'left'}}>{translate(feature, grp)}</td>
|
||||
<td> </td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'}
|
||||
style={{textAlign: 'right'}}>{current}{symbol}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
effects.push(
|
||||
<tr key={feature + '_specialTT'}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td> </td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'}
|
||||
style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +288,7 @@ export function isValueBeneficial(feature, value) {
|
||||
*/
|
||||
export function getBlueprint(name, module) {
|
||||
// Start with a copy of the blueprint
|
||||
const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0)
|
||||
const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0);
|
||||
const found = Modifications.blueprints[findMod(name)];
|
||||
if (!found || !found.fdname) {
|
||||
return {};
|
||||
@@ -382,36 +381,35 @@ export function getPercent(m) {
|
||||
let result = null;
|
||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||
for (const featureName in features) {
|
||||
|
||||
if (features[featureName][0] === features[featureName][1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let value = _getValue(m, featureName);
|
||||
let mult;
|
||||
if (features[featureName][0] === features[featureName][1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let value = _getValue(m, featureName);
|
||||
let mult;
|
||||
if (Modifications.modifications[featureName].higherbetter) {
|
||||
// Higher is better, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||
} else {
|
||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||
}
|
||||
} else {
|
||||
// Higher is worse, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||
} else {
|
||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||
}
|
||||
}
|
||||
|
||||
if (result && result != mult) {
|
||||
return null;
|
||||
} else if (result != mult) {
|
||||
result = mult;
|
||||
}
|
||||
|
||||
if (result && result != mult) {
|
||||
return null;
|
||||
} else if (result != mult) {
|
||||
result = mult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -318,7 +318,7 @@ function _addModifications(module, modifiers, blueprint, grade, specialModificat
|
||||
if (!modifiers) return;
|
||||
let special;
|
||||
if (specialModifications) {
|
||||
special = Modifications.specials[Object.keys(specialModifications)[0]]
|
||||
special = Modifications.specials[Object.keys(specialModifications)[0]];
|
||||
}
|
||||
for (const i in modifiers) {
|
||||
// Some special modifications
|
||||
@@ -345,7 +345,7 @@ function _addModifications(module, modifiers, blueprint, grade, specialModificat
|
||||
let value;
|
||||
if (i === 'OutfittingFieldType_DefenceModifierShieldMultiplier') {
|
||||
value = modifiers[i].value - 1;
|
||||
} else if (i === 'OutfittingFieldType_DefenceModifierHealthMultiplier' && blueprint.startsWith('Armour_')) {
|
||||
} else if (i === 'OutfittingFieldType_DefenceModifierHealthMultiplier' && blueprint.startsWith('Armour_')) {
|
||||
value = (modifiers[i].value - module.hullboost) / module.hullboost;
|
||||
} else if (i === 'OutfittingFieldType_DefenceModifierHealthMultiplier') {
|
||||
value = modifiers[i].value / module.hullboost;
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import Ship from '../shipyard/Ship'
|
||||
import { HARDPOINT_NUM_TO_CLASS, shipModelFromJson } from './CompanionApiUtils'
|
||||
import { Ships } from 'coriolis-data/dist'
|
||||
import Module from '../shipyard/Module'
|
||||
import { Modules } from 'coriolis-data/dist'
|
||||
import { Modifications } from 'coriolis-data/dist'
|
||||
import { getBlueprint } from './BlueprintFunctions'
|
||||
import Ship from '../shipyard/Ship';
|
||||
import { HARDPOINT_NUM_TO_CLASS, shipModelFromJson } from './CompanionApiUtils';
|
||||
import { Ships } from 'coriolis-data/dist';
|
||||
import Module from '../shipyard/Module';
|
||||
import { Modules } from 'coriolis-data/dist';
|
||||
import { Modifications } from 'coriolis-data/dist';
|
||||
import { getBlueprint } from './BlueprintFunctions';
|
||||
|
||||
/**
|
||||
* Obtain a module given its FD Name
|
||||
* @param {string} fdname the FD Name of the module
|
||||
* @return {Module} the module
|
||||
*/
|
||||
function _moduleFromFdName (fdname) {
|
||||
if (!fdname) return null
|
||||
fdname = fdname.toLowerCase()
|
||||
function _moduleFromFdName(fdname) {
|
||||
if (!fdname) return null;
|
||||
fdname = fdname.toLowerCase();
|
||||
// Check standard modules
|
||||
for (const grp in Modules.standard) {
|
||||
if (Modules.standard.hasOwnProperty(grp)) {
|
||||
for (const i in Modules.standard[grp]) {
|
||||
if (Modules.standard[grp][i].symbol && Modules.standard[grp][i].symbol.toLowerCase() === fdname) {
|
||||
// Found it
|
||||
return new Module({template: Modules.standard[grp][i]})
|
||||
return new Module({ template: Modules.standard[grp][i] });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ function _moduleFromFdName (fdname) {
|
||||
for (const i in Modules.hardpoints[grp]) {
|
||||
if (Modules.hardpoints[grp][i].symbol && Modules.hardpoints[grp][i].symbol.toLowerCase() === fdname) {
|
||||
// Found it
|
||||
return new Module({template: Modules.hardpoints[grp][i]})
|
||||
return new Module({ template: Modules.hardpoints[grp][i] });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,14 +44,14 @@ function _moduleFromFdName (fdname) {
|
||||
for (const i in Modules.internal[grp]) {
|
||||
if (Modules.internal[grp][i].symbol && Modules.internal[grp][i].symbol.toLowerCase() === fdname) {
|
||||
// Found it
|
||||
return new Module({template: Modules.internal[grp][i]})
|
||||
return new Module({ template: Modules.internal[grp][i] });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not found
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,16 +59,16 @@ function _moduleFromFdName (fdname) {
|
||||
* @param {object} json the Loadout event JSON
|
||||
* @return {Ship} the built ship
|
||||
*/
|
||||
export function shipFromLoadoutJSON (json) {
|
||||
export function shipFromLoadoutJSON(json) {
|
||||
// Start off building a basic ship
|
||||
const shipModel = shipModelFromJson(json)
|
||||
const shipModel = shipModelFromJson(json);
|
||||
if (!shipModel) {
|
||||
throw 'No such ship found: "' + json.Ship + '"'
|
||||
throw 'No such ship found: "' + json.Ship + '"';
|
||||
}
|
||||
const shipTemplate = Ships[shipModel]
|
||||
const shipTemplate = Ships[shipModel];
|
||||
|
||||
let ship = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots)
|
||||
ship.buildWith(null)
|
||||
let ship = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots);
|
||||
ship.buildWith(null);
|
||||
// Initial Ship building, don't do engineering yet.
|
||||
let opts = [];
|
||||
|
||||
@@ -76,135 +76,135 @@ export function shipFromLoadoutJSON (json) {
|
||||
switch (module.Slot.toLowerCase()) {
|
||||
// Cargo Hatch.
|
||||
case 'cargohatch':
|
||||
ship.cargoHatch.enabled = module.On
|
||||
ship.cargoHatch.priority = module.Priority
|
||||
break
|
||||
ship.cargoHatch.enabled = module.On;
|
||||
ship.cargoHatch.priority = module.Priority;
|
||||
break;
|
||||
// Add the bulkheads
|
||||
case 'armour':
|
||||
if (module.Item.toLowerCase().endsWith('_armour_grade1')) {
|
||||
ship.useBulkhead(0, true)
|
||||
ship.useBulkhead(0, true);
|
||||
} else if (module.Item.toLowerCase().endsWith('_armour_grade2')) {
|
||||
ship.useBulkhead(1, true)
|
||||
ship.useBulkhead(1, true);
|
||||
} else if (module.Item.toLowerCase().endsWith('_armour_grade3')) {
|
||||
ship.useBulkhead(2, true)
|
||||
ship.useBulkhead(2, true);
|
||||
} else if (module.Item.toLowerCase().endsWith('_armour_mirrored')) {
|
||||
ship.useBulkhead(3, true)
|
||||
ship.useBulkhead(3, true);
|
||||
} else if (module.Item.toLowerCase().endsWith('_armour_reactive')) {
|
||||
ship.useBulkhead(4, true)
|
||||
ship.useBulkhead(4, true);
|
||||
} else {
|
||||
throw 'Unknown bulkheads "' + module.Item + '"'
|
||||
throw 'Unknown bulkheads "' + module.Item + '"';
|
||||
}
|
||||
ship.bulkheads.enabled = true
|
||||
if (module.Engineering) _addModifications(ship.bulkheads.m, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
|
||||
break
|
||||
ship.bulkheads.enabled = true;
|
||||
if (module.Engineering) _addModifications(ship.bulkheads.m, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
|
||||
break;
|
||||
case 'powerplant':
|
||||
const powerplant = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[0], powerplant, true)
|
||||
ship.standard[0].enabled = module.On
|
||||
ship.standard[0].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
|
||||
break
|
||||
const powerplant = _moduleFromFdName(module.Item);
|
||||
ship.use(ship.standard[0], powerplant, true);
|
||||
ship.standard[0].enabled = module.On;
|
||||
ship.standard[0].priority = module.Priority;
|
||||
if (module.Engineering) _addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
|
||||
break;
|
||||
case 'mainengines':
|
||||
const thrusters = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[1], thrusters, true)
|
||||
ship.standard[1].enabled = module.On
|
||||
ship.standard[1].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(thrusters, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
|
||||
break
|
||||
const thrusters = _moduleFromFdName(module.Item);
|
||||
ship.use(ship.standard[1], thrusters, true);
|
||||
ship.standard[1].enabled = module.On;
|
||||
ship.standard[1].priority = module.Priority;
|
||||
if (module.Engineering) _addModifications(thrusters, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
|
||||
break;
|
||||
case 'frameshiftdrive':
|
||||
const frameshiftdrive = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[2], frameshiftdrive, true)
|
||||
ship.standard[2].enabled = module.On
|
||||
ship.standard[2].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(frameshiftdrive, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
|
||||
break
|
||||
const frameshiftdrive = _moduleFromFdName(module.Item);
|
||||
ship.use(ship.standard[2], frameshiftdrive, true);
|
||||
ship.standard[2].enabled = module.On;
|
||||
ship.standard[2].priority = module.Priority;
|
||||
if (module.Engineering) _addModifications(frameshiftdrive, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
|
||||
break;
|
||||
case 'lifesupport':
|
||||
const lifesupport = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[3], lifesupport, true)
|
||||
ship.standard[3].enabled = module.On === true
|
||||
ship.standard[3].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(lifesupport, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
|
||||
break
|
||||
const lifesupport = _moduleFromFdName(module.Item);
|
||||
ship.use(ship.standard[3], lifesupport, true);
|
||||
ship.standard[3].enabled = module.On === true;
|
||||
ship.standard[3].priority = module.Priority;
|
||||
if (module.Engineering) _addModifications(lifesupport, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
|
||||
break;
|
||||
case 'powerdistributor':
|
||||
const powerdistributor = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[4], powerdistributor, true)
|
||||
ship.standard[4].enabled = module.On
|
||||
ship.standard[4].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(powerdistributor, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
|
||||
break
|
||||
const powerdistributor = _moduleFromFdName(module.Item);
|
||||
ship.use(ship.standard[4], powerdistributor, true);
|
||||
ship.standard[4].enabled = module.On;
|
||||
ship.standard[4].priority = module.Priority;
|
||||
if (module.Engineering) _addModifications(powerdistributor, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
|
||||
break;
|
||||
case 'radar':
|
||||
const sensors = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[5], sensors, true)
|
||||
ship.standard[5].enabled = module.On
|
||||
ship.standard[5].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(sensors, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
|
||||
break
|
||||
const sensors = _moduleFromFdName(module.Item);
|
||||
ship.use(ship.standard[5], sensors, true);
|
||||
ship.standard[5].enabled = module.On;
|
||||
ship.standard[5].priority = module.Priority;
|
||||
if (module.Engineering) _addModifications(sensors, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
|
||||
break;
|
||||
case 'fueltank':
|
||||
const fueltank = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[6], fueltank, true)
|
||||
ship.standard[6].enabled = true
|
||||
ship.standard[6].priority = 0
|
||||
break
|
||||
const fueltank = _moduleFromFdName(module.Item);
|
||||
ship.use(ship.standard[6], fueltank, true);
|
||||
ship.standard[6].enabled = true;
|
||||
ship.standard[6].priority = 0;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
for (const module of json.Modules) {
|
||||
if (module.Slot.toLowerCase().search(/hardpoint/) !== -1) {
|
||||
// Add hardpoints
|
||||
let hardpoint;
|
||||
let hardpointClassNum = -1
|
||||
let hardpointSlotNum = -1
|
||||
let hardpointArrayNum = 0
|
||||
let hardpointClassNum = -1;
|
||||
let hardpointSlotNum = -1;
|
||||
let hardpointArrayNum = 0;
|
||||
for (let i in shipTemplate.slots.hardpoints) {
|
||||
if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) {
|
||||
// Another slot of the same class
|
||||
hardpointSlotNum++
|
||||
hardpointSlotNum++;
|
||||
} else {
|
||||
// The first slot of a new class
|
||||
hardpointClassNum = shipTemplate.slots.hardpoints[i]
|
||||
hardpointSlotNum = 1
|
||||
hardpointClassNum = shipTemplate.slots.hardpoints[i];
|
||||
hardpointSlotNum = 1;
|
||||
}
|
||||
|
||||
// Now that we know what we're looking for, find it
|
||||
const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum
|
||||
const hardpointSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === hardpointName.toLowerCase())
|
||||
const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum;
|
||||
const hardpointSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === hardpointName.toLowerCase());
|
||||
if (!hardpointSlot) {
|
||||
// This can happen with old imports that don't contain new hardpoints
|
||||
} else if (!hardpointSlot) {
|
||||
// No module
|
||||
} else {
|
||||
hardpoint = _moduleFromFdName(hardpointSlot.Item)
|
||||
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true)
|
||||
ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On
|
||||
ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority
|
||||
opts.push({coriolisMod: hardpoint, json: hardpointSlot});
|
||||
hardpoint = _moduleFromFdName(hardpointSlot.Item);
|
||||
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true);
|
||||
ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On;
|
||||
ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority;
|
||||
opts.push({ coriolisMod: hardpoint, json: hardpointSlot });
|
||||
}
|
||||
hardpointArrayNum++
|
||||
hardpointArrayNum++;
|
||||
}
|
||||
}
|
||||
if (module.Slot.toLowerCase().search(/slot\d/) !== -1) {
|
||||
let internalSlotNum = 1
|
||||
let militarySlotNum = 1
|
||||
let internalSlotNum = 1;
|
||||
let militarySlotNum = 1;
|
||||
for (let i in shipTemplate.slots.internal) {
|
||||
const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name = 'military' : false
|
||||
const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name = 'military' : false;
|
||||
|
||||
// The internal slot might be a standard or a military slot. Military slots have a different naming system
|
||||
let internalSlot = null
|
||||
let internalSlot = null;
|
||||
if (isMilitary) {
|
||||
const internalName = 'Military0' + militarySlotNum
|
||||
internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase())
|
||||
militarySlotNum++
|
||||
const internalName = 'Military0' + militarySlotNum;
|
||||
internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
|
||||
militarySlotNum++;
|
||||
} else {
|
||||
// Slot numbers are not contiguous so handle skips.
|
||||
while (internalSlot === null && internalSlotNum < 99) {
|
||||
// Slot sizes have no relationship to the actual size, either, so check all possibilities
|
||||
for (let slotsize = 0; slotsize < 9; slotsize++) {
|
||||
const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + slotsize
|
||||
const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + slotsize;
|
||||
if (json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase())) {
|
||||
internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
internalSlotNum++
|
||||
internalSlotNum++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,12 +213,12 @@ export function shipFromLoadoutJSON (json) {
|
||||
} else if (!internalSlot) {
|
||||
// No module
|
||||
} else {
|
||||
const internalJson = internalSlot
|
||||
const internal = _moduleFromFdName(internalJson.Item)
|
||||
ship.use(ship.internal[i], internal, true)
|
||||
ship.internal[i].enabled = internalJson.On === true
|
||||
ship.internal[i].priority = internalJson.Priority
|
||||
opts.push({coriolisMod: internal, json: internalSlot});
|
||||
const internalJson = internalSlot;
|
||||
const internal = _moduleFromFdName(internalJson.Item);
|
||||
ship.use(ship.internal[i], internal, true);
|
||||
ship.internal[i].enabled = internalJson.On === true;
|
||||
ship.internal[i].priority = internalJson.Priority;
|
||||
opts.push({ coriolisMod: internal, json: internalSlot });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,17 +226,17 @@ export function shipFromLoadoutJSON (json) {
|
||||
}
|
||||
|
||||
for (const i of opts) {
|
||||
if (i.json.Engineering) _addModifications(i.coriolisMod, i.json.Engineering.Modifiers, i.json.Engineering.BlueprintName, i.json.Engineering.Level, i.json.Engineering.ExperimentalEffect)
|
||||
if (i.json.Engineering) _addModifications(i.coriolisMod, i.json.Engineering.Modifiers, i.json.Engineering.BlueprintName, i.json.Engineering.Level, i.json.Engineering.ExperimentalEffect);
|
||||
}
|
||||
// We don't have any information on it so guess it's priority 5 and disabled
|
||||
if (!ship.cargoHatch) {
|
||||
ship.cargoHatch.enabled = false
|
||||
ship.cargoHatch.priority = 4
|
||||
ship.cargoHatch.enabled = false;
|
||||
ship.cargoHatch.priority = 4;
|
||||
}
|
||||
console.log(ship)
|
||||
console.log(ship);
|
||||
|
||||
// Now update the ship's codes before returning it
|
||||
return ship.updatePowerPrioritesString().updatePowerEnabledString().updateModificationsString()
|
||||
return ship.updatePowerPrioritesString().updatePowerEnabledString().updateModificationsString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,18 +247,18 @@ export function shipFromLoadoutJSON (json) {
|
||||
* @param {Object} grade the grade of the modification
|
||||
* @param {Object} specialModifications special modification
|
||||
*/
|
||||
function _addModifications (module, modifiers, blueprint, grade, specialModifications) {
|
||||
if (!modifiers) return
|
||||
let special
|
||||
function _addModifications(module, modifiers, blueprint, grade, specialModifications) {
|
||||
if (!modifiers) return;
|
||||
let special;
|
||||
if (specialModifications) {
|
||||
special = Modifications.specials[specialModifications]
|
||||
special = Modifications.specials[specialModifications];
|
||||
}
|
||||
for (const i in modifiers) {
|
||||
// Some special modifications
|
||||
// Look up the modifiers to find what we need to do
|
||||
const findMod = val => Object.keys(Modifications.modifierActions).find(elem => elem.toString().toLowerCase().replace(/(outfittingfieldtype_|persecond)/igm, '') === val.toString().toLowerCase().replace(/(outfittingfieldtype_|persecond)/igm, ''))
|
||||
const modifierActions = Modifications.modifierActions[findMod(modifiers[i].Label)]
|
||||
//TODO: Figure out how to scale this value.
|
||||
const findMod = val => Object.keys(Modifications.modifierActions).find(elem => elem.toString().toLowerCase().replace(/(outfittingfieldtype_|persecond)/igm, '') === val.toString().toLowerCase().replace(/(outfittingfieldtype_|persecond)/igm, ''));
|
||||
const modifierActions = Modifications.modifierActions[findMod(modifiers[i].Label)];
|
||||
// TODO: Figure out how to scale this value.
|
||||
if (!!modifiers[i].LessIsGood) {
|
||||
|
||||
}
|
||||
@@ -267,26 +267,26 @@ function _addModifications (module, modifiers, blueprint, grade, specialModifica
|
||||
value = modifiers[i].Value * 100;
|
||||
}
|
||||
if (modifiers[i].Label.search('Resistance') >= 0) {
|
||||
value = (modifiers[i].Value * 100) - (modifiers[i].OriginalValue * 100)
|
||||
value = (modifiers[i].Value * 100) - (modifiers[i].OriginalValue * 100);
|
||||
}
|
||||
// Carry out the required changes
|
||||
for (const action in modifierActions) {
|
||||
if (isNaN(modifierActions[action])) {
|
||||
module.setModValue(action, modifierActions[action])
|
||||
module.setModValue(action, modifierActions[action]);
|
||||
} else {
|
||||
module.setModValue(action, value)
|
||||
module.setModValue(action, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the blueprint definition, grade and special
|
||||
if (blueprint) {
|
||||
module.blueprint = getBlueprint(blueprint, module)
|
||||
module.blueprint = getBlueprint(blueprint, module);
|
||||
if (grade) {
|
||||
module.blueprint.grade = Number(grade)
|
||||
module.blueprint.grade = Number(grade);
|
||||
}
|
||||
if (special) {
|
||||
module.blueprint.special = special
|
||||
module.blueprint.special = special;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user