mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-10 07:05:35 +00:00
First steps towards ed-forge rewrite
This commit is contained in:
committed by
felixlinker
parent
cee4c32551
commit
9797a8d781
@@ -128,6 +128,7 @@
|
|||||||
"coriolis-data": "../coriolis-data",
|
"coriolis-data": "../coriolis-data",
|
||||||
"d3": "^5.7.0",
|
"d3": "^5.7.0",
|
||||||
"detect-browser": "^3.0.1",
|
"detect-browser": "^3.0.1",
|
||||||
|
"ed-forge": "github:EDCD/ed-forge",
|
||||||
"fbemitter": "^2.1.1",
|
"fbemitter": "^2.1.1",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"lz-string": "^1.4.4",
|
"lz-string": "^1.4.4",
|
||||||
|
|||||||
@@ -5,16 +5,14 @@ import { register } from 'register-service-worker';
|
|||||||
import { EventEmitter } from 'fbemitter';
|
import { EventEmitter } from 'fbemitter';
|
||||||
import { getLanguage } from './i18n/Language';
|
import { getLanguage } from './i18n/Language';
|
||||||
import Persist from './stores/Persist';
|
import Persist from './stores/Persist';
|
||||||
|
import { Ship } from 'ed-forge';
|
||||||
|
|
||||||
import Announcement from './components/Announcement';
|
import Announcement from './components/Announcement';
|
||||||
import Header from './components/Header';
|
import Header from './components/Header';
|
||||||
import Tooltip from './components/Tooltip';
|
import Tooltip from './components/Tooltip';
|
||||||
import ModalExport from './components/ModalExport';
|
|
||||||
import ModalHelp from './components/ModalHelp';
|
import ModalHelp from './components/ModalHelp';
|
||||||
import ModalImport from './components/ModalImport';
|
import ModalImport from './components/ModalImport';
|
||||||
import ModalPermalink from './components/ModalPermalink';
|
import ModalPermalink from './components/ModalPermalink';
|
||||||
import * as CompanionApiUtils from './utils/CompanionApiUtils';
|
|
||||||
import * as JournalUtils from './utils/JournalUtils';
|
|
||||||
import AboutPage from './pages/AboutPage';
|
import AboutPage from './pages/AboutPage';
|
||||||
import NotFoundPage from './pages/NotFoundPage';
|
import NotFoundPage from './pages/NotFoundPage';
|
||||||
import OutfittingPage from './pages/OutfittingPage';
|
import OutfittingPage from './pages/OutfittingPage';
|
||||||
@@ -22,7 +20,6 @@ import ComparisonPage from './pages/ComparisonPage';
|
|||||||
import ShipyardPage from './pages/ShipyardPage';
|
import ShipyardPage from './pages/ShipyardPage';
|
||||||
import ErrorDetails from './pages/ErrorDetails';
|
import ErrorDetails from './pages/ErrorDetails';
|
||||||
|
|
||||||
const zlib = require('pako');
|
|
||||||
const request = require('superagent');
|
const request = require('superagent');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,7 +58,6 @@ export default class Coriolis extends React.Component {
|
|||||||
this._onLanguageChange = this._onLanguageChange.bind(this);
|
this._onLanguageChange = this._onLanguageChange.bind(this);
|
||||||
this._onSizeRatioChange = this._onSizeRatioChange.bind(this);
|
this._onSizeRatioChange = this._onSizeRatioChange.bind(this);
|
||||||
this._keyDown = this._keyDown.bind(this);
|
this._keyDown = this._keyDown.bind(this);
|
||||||
this._importBuild = this._importBuild.bind(this);
|
|
||||||
|
|
||||||
this.emitter = new EventEmitter();
|
this.emitter = new EventEmitter();
|
||||||
this.state = {
|
this.state = {
|
||||||
@@ -93,19 +89,10 @@ export default class Coriolis extends React.Component {
|
|||||||
_importBuild(r) {
|
_importBuild(r) {
|
||||||
try {
|
try {
|
||||||
// Need to decode and gunzip the data, then build the ship
|
// Need to decode and gunzip the data, then build the ship
|
||||||
const data = zlib.inflate(new Buffer(r.params.data, 'base64'), { to: 'string' });
|
let ship = new Ship(r.params.data);
|
||||||
const json = JSON.parse(data);
|
r.params.ship = ship.getShipType();
|
||||||
console.info('Ship import data: ');
|
r.params.code = ship.compress();
|
||||||
console.info(json);
|
this._setPage(OutfittingPage, r);
|
||||||
let ship;
|
|
||||||
if (json && json.modules) {
|
|
||||||
ship = CompanionApiUtils.shipFromJson(json);
|
|
||||||
} else if (json && json.Modules) {
|
|
||||||
ship = JournalUtils.shipFromLoadoutJSON(json);
|
|
||||||
}
|
|
||||||
r.params.ship = ship.id;
|
|
||||||
r.params.code = ship.toString();
|
|
||||||
this._setPage(OutfittingPage, r)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._onError('Failed to import ship', r.path, 0, 0, err);
|
this._onError('Failed to import ship', r.path, 0, 0, err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ const CATEGORIES = {
|
|||||||
*/
|
*/
|
||||||
export default class AvailableModulesMenu extends TranslatedComponent {
|
export default class AvailableModulesMenu extends TranslatedComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
modules: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
|
|
||||||
onSelect: PropTypes.func.isRequired,
|
onSelect: PropTypes.func.isRequired,
|
||||||
diffDetails: PropTypes.func,
|
diffDetails: PropTypes.func,
|
||||||
m: PropTypes.object,
|
m: PropTypes.object,
|
||||||
@@ -155,7 +154,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
|||||||
*/
|
*/
|
||||||
_initState(props, context) {
|
_initState(props, context) {
|
||||||
let translate = context.language.translate;
|
let translate = context.language.translate;
|
||||||
let { m, warning, onSelect, modules, ship } = props;
|
let { m, warning, onSelect, ship } = props;
|
||||||
let list, currentGroup;
|
let list, currentGroup;
|
||||||
|
|
||||||
let buildGroup = this._buildGroup.bind(
|
let buildGroup = this._buildGroup.bind(
|
||||||
@@ -170,6 +169,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
let fuzzy = [];
|
let fuzzy = [];
|
||||||
|
let modules = m.getApplicableItems();
|
||||||
if (modules instanceof Array) {
|
if (modules instanceof Array) {
|
||||||
list = buildGroup(modules[0].grp, modules);
|
list = buildGroup(modules[0].grp, modules);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import { blueprintTooltip } from '../utils/BlueprintFunctions';
|
|||||||
* Hardpoint / Utility Slot
|
* Hardpoint / Utility Slot
|
||||||
*/
|
*/
|
||||||
export default class HardpointSlot extends Slot {
|
export default class HardpointSlot extends Slot {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the CSS class name for the slot.
|
* Get the CSS class name for the slot.
|
||||||
* @return {string} CSS Class name
|
* @return {string} CSS Class name
|
||||||
@@ -42,40 +41,38 @@ export default class HardpointSlot extends Slot {
|
|||||||
/**
|
/**
|
||||||
* Generate the slot contents
|
* Generate the slot contents
|
||||||
* @param {Object} m Mounted Module
|
* @param {Object} m Mounted Module
|
||||||
* @param {Boolean} enabled Slot enabled
|
|
||||||
* @param {Function} translate Translate function
|
* @param {Function} translate Translate function
|
||||||
* @param {Object} formats Localized Formats map
|
* @param {Object} formats Localized Formats map
|
||||||
* @param {Object} u Localized Units Map
|
* @param {Object} u Localized Units Map
|
||||||
* @return {React.Component} Slot contents
|
* @return {React.Component} Slot contents
|
||||||
*/
|
*/
|
||||||
_getSlotDetails(m, enabled, translate, formats, u) {
|
_getSlotDetails(m, translate, formats, u) {
|
||||||
if (m) {
|
if (m) {
|
||||||
let classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
|
let classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
|
||||||
let { drag, drop } = this.props;
|
let { drag, drop } = this.props;
|
||||||
let { termtip, tooltip } = this.context;
|
let { termtip, tooltip } = this.context;
|
||||||
let validMods = Modifications.modules[m.grp].modifications || [];
|
|
||||||
let showModuleResistances = Persist.showModuleResistances();
|
let showModuleResistances = Persist.showModuleResistances();
|
||||||
|
|
||||||
// Modifications tooltip shows blueprint and grade, if available
|
// Modifications tooltip shows blueprint and grade, if available
|
||||||
let modTT = translate('modified');
|
let modTT = translate('modified');
|
||||||
if (m && m.blueprint && m.blueprint.name) {
|
if (m && m.blueprint && m.blueprint.name) {
|
||||||
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
// modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||||
if (m.blueprint.special && m.blueprint.special.id >= 0) {
|
// if (m.blueprint.special && m.blueprint.special.id >= 0) {
|
||||||
modTT += ', ' + translate(m.blueprint.special.name);
|
// modTT += ', ' + translate(m.blueprint.special.name);
|
||||||
}
|
// }
|
||||||
modTT = (
|
// modTT = (
|
||||||
<div>
|
// <div>
|
||||||
<div>{modTT}</div>
|
// <div>{modTT}</div>
|
||||||
{blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade], null, m.grp, m)}
|
// {blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade], m)}
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
const className = cn('details', enabled ? '' : 'disabled');
|
const className = cn('details', m.isEnabled() ? '' : 'disabled');
|
||||||
return <div className={className} draggable='true' onDragStart={drag} onDragEnd={drop}>
|
return <div className={className} draggable='true' onDragStart={drag} onDragEnd={drop}>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
<div className={'l'}>
|
<div className={'l'}>
|
||||||
{m.mount && m.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')}
|
{/* {m.mount && m.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')}
|
||||||
onMouseOut={tooltip.bind(null, null)}><MountFixed/></span> : ''}
|
onMouseOut={tooltip.bind(null, null)}><MountFixed/></span> : ''}
|
||||||
{m.mount && m.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')}
|
{m.mount && m.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')}
|
||||||
onMouseOut={tooltip.bind(null, null)}><MountGimballed/></span> : ''}
|
onMouseOut={tooltip.bind(null, null)}><MountGimballed/></span> : ''}
|
||||||
@@ -91,13 +88,13 @@ export default class HardpointSlot extends Slot {
|
|||||||
onMouseOut={tooltip.bind(null, null)}><DamageAbsolute/></span> : ''}
|
onMouseOut={tooltip.bind(null, null)}><DamageAbsolute/></span> : ''}
|
||||||
{classRating} {translate(m.name || m.grp)}{m.mods && Object.keys(m.mods).length > 0 ? <span className='r'
|
{classRating} {translate(m.name || m.grp)}{m.mods && Object.keys(m.mods).length > 0 ? <span className='r'
|
||||||
onMouseOver={termtip.bind(null, modTT)}
|
onMouseOver={termtip.bind(null, modTT)}
|
||||||
onMouseOut={tooltip.bind(null, null)}><Modified/></span> : null}
|
onMouseOut={tooltip.bind(null, null)}><Modified/></span> : null} */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={'r'}>{formats.round(m.getMass())}{u.T}</div>
|
<div className={'r'}>{formats.round(m.get('mass'))}{u.T}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
{m.getDps() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getClip() ? 'dpssdps' : 'dps')}
|
{/* {m.getDps() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getClip() ? 'dpssdps' : 'dps')}
|
||||||
onMouseOut={tooltip.bind(null, null)}>{translate('DPS')}: {formats.round1(m.getDps())} {m.getClip() ?
|
onMouseOut={tooltip.bind(null, null)}>{translate('DPS')}: {formats.round1(m.getDps())} {m.getClip() ?
|
||||||
<span>({formats.round1(m.getSDps())})</span> : null}</div> : null}
|
<span>({formats.round1(m.getSDps())})</span> : null}</div> : null}
|
||||||
{m.getDamage() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getDamage() ? 'shotdmg' : 'shotdmg')}
|
{m.getDamage() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getDamage() ? 'shotdmg' : 'shotdmg')}
|
||||||
@@ -140,12 +137,11 @@ export default class HardpointSlot extends Slot {
|
|||||||
<button tabIndex="-1" onClick={this._toggleModifications.bind(this)} onContextMenu={stopCtxPropagation}
|
<button tabIndex="-1" onClick={this._toggleModifications.bind(this)} onContextMenu={stopCtxPropagation}
|
||||||
onMouseOver={termtip.bind(null, 'modifications')} onMouseOut={tooltip.bind(null, null)}>
|
onMouseOver={termtip.bind(null, 'modifications')} onMouseOut={tooltip.bind(null, null)}>
|
||||||
<ListModifications/></button>
|
<ListModifications/></button>
|
||||||
</div> : null}
|
</div> : null} */}
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
return <div className={'empty'}>{translate('empty')}</div>;
|
return <div className={'empty'}>{translate('empty')}</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,29 +68,23 @@ export default class HardpointSlotSection extends SlotSection {
|
|||||||
let { ship, currentMenu } = this.props;
|
let { ship, currentMenu } = this.props;
|
||||||
let { originSlot, targetSlot } = this.state;
|
let { originSlot, targetSlot } = this.state;
|
||||||
let slots = [];
|
let slots = [];
|
||||||
let hardpoints = ship.hardpoints;
|
|
||||||
let availableModules = ship.getAvailableModules();
|
|
||||||
|
|
||||||
for (let i = 0, l = hardpoints.length; i < l; i++) {
|
for (let h of ship.getHardpoints(undefined, true)) {
|
||||||
let h = hardpoints[i];
|
slots.push(<HardpointSlot
|
||||||
if (h.maxClass) {
|
key={h.object.Slot}
|
||||||
slots.push(<HardpointSlot
|
maxClass={h.getSize()}
|
||||||
key={i}
|
onOpen={this._openMenu.bind(this, h)}
|
||||||
maxClass={h.maxClass}
|
onSelect={this._selectModule.bind(this, h)}
|
||||||
availableModules={() => availableModules.getHps(h.maxClass)}
|
onChange={this.props.onChange}
|
||||||
onOpen={this._openMenu.bind(this, h)}
|
selected={currentMenu == h}
|
||||||
onSelect={this._selectModule.bind(this, h)}
|
drag={this._drag.bind(this, h)}
|
||||||
onChange={this.props.onChange}
|
dragOver={this._dragOverSlot.bind(this, h)}
|
||||||
selected={currentMenu == h}
|
drop={this._drop}
|
||||||
drag={this._drag.bind(this, h)}
|
dropClass={this._dropClass(h, originSlot, targetSlot)}
|
||||||
dragOver={this._dragOverSlot.bind(this, h)}
|
ship={ship}
|
||||||
drop={this._drop}
|
slot={h}
|
||||||
dropClass={this._dropClass(h, originSlot, targetSlot)}
|
enabled={h.enabled ? true : false}
|
||||||
ship={ship}
|
/>);
|
||||||
m={h.m}
|
|
||||||
enabled={h.enabled ? true : false}
|
|
||||||
/>);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return slots;
|
return slots;
|
||||||
|
|||||||
@@ -15,36 +15,39 @@ export default class InternalSlot extends Slot {
|
|||||||
/**
|
/**
|
||||||
* Generate the slot contents
|
* Generate the slot contents
|
||||||
* @param {Object} m Mounted Module
|
* @param {Object} m Mounted Module
|
||||||
* @param {Boolean} enabled Slot enabled
|
|
||||||
* @param {Function} translate Translate function
|
* @param {Function} translate Translate function
|
||||||
* @param {Object} formats Localized Formats map
|
* @param {Object} formats Localized Formats map
|
||||||
* @param {Object} u Localized Units Map
|
* @param {Object} u Localized Units Map
|
||||||
* @return {React.Component} Slot contents
|
* @return {React.Component} Slot contents
|
||||||
*/
|
*/
|
||||||
_getSlotDetails(m, enabled, translate, formats, u) {
|
_getSlotDetails(m, translate, formats, u) {
|
||||||
if (m) {
|
if (m) {
|
||||||
let classRating = m.class + m.rating;
|
let classRating = String(m.getSize()) + m.getRating();
|
||||||
let { drag, drop, ship } = this.props;
|
let { drag, drop, ship } = this.props;
|
||||||
let { termtip, tooltip } = this.context;
|
let { termtip, tooltip } = this.context;
|
||||||
let validMods = (Modifications.modules[m.grp] ? Modifications.modules[m.grp].modifications : []);
|
let validMods = m.getApplicableBlueprints();
|
||||||
let showModuleResistances = Persist.showModuleResistances();
|
let showModuleResistances = Persist.showModuleResistances();
|
||||||
|
|
||||||
// Modifications tooltip shows blueprint and grade, if available
|
// Modifications tooltip shows blueprint and grade, if available
|
||||||
let modTT = translate('modified');
|
// let modTT = translate('modified');
|
||||||
if (m && m.blueprint && m.blueprint.name) {
|
// const blueprint = m.getBlueprint();
|
||||||
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
// const experimental = m.getExperimental();
|
||||||
if (m.blueprint.special && m.blueprint.special.id >= 0) {
|
// const grade = m.getGrade();
|
||||||
modTT += ', ' + translate(m.blueprint.special.name);
|
// if (blueprint) {
|
||||||
}
|
// modTT = translate(blueprint) + ' ' + translate('grade') + ' ' + grade;
|
||||||
modTT = (
|
// if (experimental) {
|
||||||
<div>
|
// modTT += ', ' + translate(experimental);
|
||||||
<div>{modTT}</div>
|
// }
|
||||||
{blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade], null, m.grp, m)}
|
// modTT = (
|
||||||
</div>
|
// <div>
|
||||||
);
|
// <div>{modTT}</div>
|
||||||
}
|
// {blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade], m)}
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
let mass = m.getMass() || m.cargo || m.fuel || 0;
|
let mass = m.get('mass') || m.get('cargo') || m.get('fuel') || 0;
|
||||||
|
const enabled = m.isEnabled();
|
||||||
|
|
||||||
const className = cn('details', enabled ? '' : 'disabled');
|
const className = cn('details', enabled ? '' : 'disabled');
|
||||||
return <div className={className} draggable='true' onDragStart={drag} onDragEnd={drop}>
|
return <div className={className} draggable='true' onDragStart={drag} onDragEnd={drop}>
|
||||||
@@ -53,7 +56,7 @@ export default class InternalSlot extends Slot {
|
|||||||
<div className={'r'}>{formats.round(mass)}{u.T}</div>
|
<div className={'r'}>{formats.round(mass)}{u.T}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
{ m.getOptMass() ? <div className={'l'}>{translate('optmass', 'sg')}: {formats.int(m.getOptMass())}{u.T}</div> : null }
|
{/* { m.getOptMass() ? <div className={'l'}>{translate('optmass', 'sg')}: {formats.int(m.getOptMass())}{u.T}</div> : null }
|
||||||
{ m.getMaxMass() ? <div className={'l'}>{translate('maxmass', 'sg')}: {formats.int(m.getMaxMass())}{u.T}</div> : null }
|
{ m.getMaxMass() ? <div className={'l'}>{translate('maxmass', 'sg')}: {formats.int(m.getMaxMass())}{u.T}</div> : null }
|
||||||
{ m.bins ? <div className={'l'}>{m.bins} <u>{translate('bins')}</u></div> : null }
|
{ m.bins ? <div className={'l'}>{m.bins} <u>{translate('bins')}</u></div> : null }
|
||||||
{ m.bays ? <div className={'l'}>{translate('bays')}: {m.bays}</div> : null }
|
{ m.bays ? <div className={'l'}>{translate('bays')}: {m.bays}</div> : null }
|
||||||
@@ -88,7 +91,7 @@ export default class InternalSlot extends Slot {
|
|||||||
{ m.getHullReinforcement() ? <div className='l'>{translate('armour')}: {formats.int(m.getHullReinforcement() + ship.baseArmour * m.getModValue('hullboost') / 10000)}</div> : null }
|
{ m.getHullReinforcement() ? <div className='l'>{translate('armour')}: {formats.int(m.getHullReinforcement() + ship.baseArmour * m.getModValue('hullboost') / 10000)}</div> : null }
|
||||||
{ m.getProtection() ? <div className='l'>{translate('protection')}: {formats.rPct(m.getProtection())}</div> : null }
|
{ m.getProtection() ? <div className='l'>{translate('protection')}: {formats.rPct(m.getProtection())}</div> : null }
|
||||||
{ m.getIntegrity() ? <div className='l'>{translate('integrity')}: {formats.int(m.getIntegrity())}</div> : null }
|
{ m.getIntegrity() ? <div className='l'>{translate('integrity')}: {formats.int(m.getIntegrity())}</div> : null }
|
||||||
{ m && validMods.length > 0 ? <div className='r' tabIndex="0" ref={ modButton => this.modButton = modButton }><button tabIndex="-1" onClick={this._toggleModifications.bind(this)} onContextMenu={stopCtxPropagation} onMouseOver={termtip.bind(null, 'modifications')} onMouseOut={tooltip.bind(null, null)}><ListModifications /></button></div> : null }
|
{ m && validMods.length > 0 ? <div className='r' tabIndex="0" ref={ modButton => this.modButton = modButton }><button tabIndex="-1" onClick={this._toggleModifications.bind(this)} onContextMenu={stopCtxPropagation} onMouseOver={termtip.bind(null, 'modifications')} onMouseOut={tooltip.bind(null, null)}><ListModifications /></button></div> : null } */}
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { canMount } from '../utils/SlotFunctions';
|
|||||||
* Internal slot section
|
* Internal slot section
|
||||||
*/
|
*/
|
||||||
export default class InternalSlotSection extends SlotSection {
|
export default class InternalSlotSection extends SlotSection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {Object} props React Component properties
|
* @param {Object} props React Component properties
|
||||||
@@ -221,29 +220,24 @@ export default class InternalSlotSection extends SlotSection {
|
|||||||
let slots = [];
|
let slots = [];
|
||||||
let { currentMenu, ship } = this.props;
|
let { currentMenu, ship } = this.props;
|
||||||
let { originSlot, targetSlot } = this.state;
|
let { originSlot, targetSlot } = this.state;
|
||||||
let { internal, fuelCapacity } = ship;
|
let { fuelCapacity } = ship;
|
||||||
let availableModules = ship.getAvailableModules();
|
|
||||||
|
|
||||||
for (let i = 0, l = internal.length; i < l; i++) {
|
|
||||||
let s = internal[i];
|
|
||||||
|
|
||||||
|
for (const slot of ship.getInternals(undefined, true)) {
|
||||||
slots.push(<InternalSlot
|
slots.push(<InternalSlot
|
||||||
key={i}
|
key={slot.object.Slot}
|
||||||
maxClass={s.maxClass}
|
maxClass={slot.getSize()}
|
||||||
availableModules={() => availableModules.getInts(ship, s.maxClass, s.eligible)}
|
onOpen={this._openMenu.bind(this, slot)}
|
||||||
onOpen={this._openMenu.bind(this,s)}
|
onChange={this.props.onChange}
|
||||||
onChange={this.props.onChange}
|
onSelect={this._selectModule.bind(this, slot)}
|
||||||
onSelect={this._selectModule.bind(this, s)}
|
selected={currentMenu == slot}
|
||||||
selected={currentMenu == s}
|
slot={slot}
|
||||||
eligible={s.eligible}
|
drag={this._drag.bind(this, slot)}
|
||||||
m={s.m}
|
dragOver={this._dragOverSlot.bind(this, slot)}
|
||||||
drag={this._drag.bind(this, s)}
|
|
||||||
dragOver={this._dragOverSlot.bind(this, s)}
|
|
||||||
drop={this._drop}
|
drop={this._drop}
|
||||||
dropClass={this._dropClass(s, originSlot, targetSlot)}
|
dropClass={this._dropClass(slot, originSlot, targetSlot)}
|
||||||
fuel={fuelCapacity}
|
fuel={fuelCapacity}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
enabled={s.enabled ? true : false}
|
enabled={slot.isEnabled()}
|
||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,10 +262,9 @@ export default class InternalSlotSection extends SlotSection {
|
|||||||
<li className='lc' tabIndex='0' onClick={this._fillWithEconomyClassCabins} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['pce'] = smRef}>{translate('pce')}</li>
|
<li className='lc' tabIndex='0' onClick={this._fillWithEconomyClassCabins} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['pce'] = smRef}>{translate('pce')}</li>
|
||||||
<li className='lc' tabIndex='0' onClick={this._fillWithBusinessClassCabins} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['pci'] = smRef}>{translate('pci')}</li>
|
<li className='lc' tabIndex='0' onClick={this._fillWithBusinessClassCabins} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['pci'] = smRef}>{translate('pci')}</li>
|
||||||
<li className='lc' tabIndex='0' onClick={this._fillWithFirstClassCabins} onKeyDown={ship.luxuryCabins ? '' : this._keyDown} ref={smRef => this.sectionRefArr['pcm'] = smRef}>{translate('pcm')}</li>
|
<li className='lc' tabIndex='0' onClick={this._fillWithFirstClassCabins} onKeyDown={ship.luxuryCabins ? '' : this._keyDown} ref={smRef => this.sectionRefArr['pcm'] = smRef}>{translate('pcm')}</li>
|
||||||
{ ship.luxuryCabins ? <li className='lc' tabIndex='0' onClick={this._fillWithLuxuryCabins} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['pcq'] = smRef}>{translate('pcq')}</li> : ''}
|
{ ship.luxuryCabins ? <li className='lc' tabIndex='0' onClick={this._fillWithLuxuryCabins} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['pcq'] = smRef}>{translate('pcq')}</li> : ''}
|
||||||
<li className='optional-hide' style={{ textAlign: 'center', marginTop: '1em' }}>{translate('PHRASE_ALT_ALL')}</li>
|
<li className='optional-hide' style={{ textAlign: 'center', marginTop: '1em' }}>{translate('PHRASE_ALT_ALL')}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
});
|
});
|
||||||
const close = this._blueprintSelected.bind(this, blueprintName, grade);
|
const close = this._blueprintSelected.bind(this, blueprintName, grade);
|
||||||
const key = blueprintName + ':' + grade;
|
const key = blueprintName + ':' + grade;
|
||||||
const tooltipContent = blueprintTooltip(translate, blueprint.grades[grade], Modifications.modules[m.grp].blueprints[blueprintName].grades[grade].engineers, m.grp);
|
const tooltipContent = blueprintTooltip(translate, blueprint.grades[grade]);
|
||||||
if (classes.indexOf('active') >= 0) this.selectedModId = key;
|
if (classes.indexOf('active') >= 0) this.selectedModId = key;
|
||||||
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>);
|
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>);
|
||||||
}
|
}
|
||||||
@@ -429,7 +429,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
if (m.blueprint && m.blueprint.name && Modifications.modules[m.grp].blueprints[m.blueprint.fdname].grades[m.blueprint.grade]) {
|
if (m.blueprint && m.blueprint.name && Modifications.modules[m.grp].blueprints[m.blueprint.fdname].grades[m.blueprint.grade]) {
|
||||||
blueprintLabel = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
blueprintLabel = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||||
haveBlueprint = true;
|
haveBlueprint = true;
|
||||||
blueprintTt = blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade], Modifications.modules[m.grp].blueprints[m.blueprint.fdname].grades[m.blueprint.grade].engineers, m.grp);
|
blueprintTt = blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade]);
|
||||||
blueprintCv = getPercent(m);
|
blueprintCv = getPercent(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ import cn from 'classnames';
|
|||||||
import { Warning } from './SvgIcons';
|
import { Warning } from './SvgIcons';
|
||||||
import * as Calc from '../shipyard/Calculations';
|
import * as Calc from '../shipyard/Calculations';
|
||||||
|
|
||||||
|
import { ShipProps } from 'ed-forge';
|
||||||
|
const {
|
||||||
|
SPEED, JUMP_RANGE, TOTAL_RANGE, SHIELD_METRICS, ARMOUR_METRICS, MODULE_ARMOUR,
|
||||||
|
MODULE_PROTECTION
|
||||||
|
} = ShipProps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ship Summary Table / Stats
|
* Ship Summary Table / Stats
|
||||||
*/
|
*/
|
||||||
@@ -12,10 +18,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
ship: PropTypes.object.isRequired,
|
ship: PropTypes.object.isRequired,
|
||||||
cargo: PropTypes.number.isRequired,
|
|
||||||
fuel: PropTypes.number.isRequired,
|
|
||||||
marker: PropTypes.string.isRequired,
|
marker: PropTypes.string.isRequired,
|
||||||
pips: PropTypes.object.isRequired
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,14 +38,14 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
* @return {React.Component} Summary table
|
* @return {React.Component} Summary table
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const { ship, cargo, fuel, pips } = this.props;
|
const { ship } = this.props;
|
||||||
let { language, tooltip, termtip } = this.context;
|
let { language, tooltip, termtip } = this.context;
|
||||||
let translate = language.translate;
|
let translate = language.translate;
|
||||||
let u = language.units;
|
let u = language.units;
|
||||||
let formats = language.formats;
|
let formats = language.formats;
|
||||||
let { time, int, round, f1, f2 } = formats;
|
let { time, int, round, f1, f2 } = formats;
|
||||||
let hide = tooltip.bind(null, null);
|
let hide = tooltip.bind(null, null);
|
||||||
const shieldGenerator = ship.findInternalByGroup('sg') || ship.findInternalByGroup('psg');
|
const shieldGenerator = ship.getShieldGenerator();
|
||||||
const sgClassNames = cn({ warning: shieldGenerator && !ship.shield, muted: !shieldGenerator });
|
const sgClassNames = cn({ warning: shieldGenerator && !ship.shield, muted: !shieldGenerator });
|
||||||
const sgTooltip = shieldGenerator ? 'TT_SUMMARY_SHIELDS' : 'TT_SUMMARY_SHIELDS_NONFUNCTIONAL';
|
const sgTooltip = shieldGenerator ? 'TT_SUMMARY_SHIELDS' : 'TT_SUMMARY_SHIELDS_NONFUNCTIONAL';
|
||||||
const timeToDrain = Calc.timeToDrainWep(ship, 4);
|
const timeToDrain = Calc.timeToDrainWep(ship, 4);
|
||||||
@@ -64,15 +67,19 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
this.state = {
|
this.state = {
|
||||||
shieldColour
|
shieldColour
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let speed = ship.get(SPEED);
|
||||||
|
let jumpRange = ship.get(JUMP_RANGE);
|
||||||
|
|
||||||
return <div id='summary'>
|
return <div id='summary'>
|
||||||
<div style={{display: "table", width: "100%"}}>
|
<div style={{display: "table", width: "100%"}}>
|
||||||
<div style={{display: "table-row"}}>
|
<div style={{display: "table-row"}}>
|
||||||
<table className={'summaryTable'}>
|
<table className={'summaryTable'}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr className='main'>
|
<tr className='main'>
|
||||||
<th rowSpan={2} className={ cn({ 'bg-warning-disabled': !canThrust }) }>{translate('speed')}</th>
|
<th rowSpan={2} className={ cn({ 'bg-warning-disabled': speed == 0 }) }>{translate('speed')}</th>
|
||||||
<th rowSpan={2} className={ cn({ 'bg-warning-disabled': !canBoost }) }>{translate('boost')}</th>
|
<th rowSpan={2} className={ cn({ 'bg-warning-disabled': !canBoost }) }>{translate('boost')}</th>
|
||||||
<th colSpan={5} className={ cn({ 'bg-warning-disabled': !canJump }) }>{translate('jump range')}</th>
|
<th colSpan={5} className={ cn({ 'bg-warning-disabled': jumpRange == 0 }) }>{translate('jump range')}</th>
|
||||||
<th rowSpan={2}>{translate('shield')}</th>
|
<th rowSpan={2}>{translate('shield')}</th>
|
||||||
<th rowSpan={2}>{translate('integrity')}</th>
|
<th rowSpan={2}>{translate('integrity')}</th>
|
||||||
<th rowSpan={2}>{translate('DPS')}</th>
|
<th rowSpan={2}>{translate('DPS')}</th>
|
||||||
|
|||||||
@@ -6,22 +6,19 @@ import AvailableModulesMenu from './AvailableModulesMenu';
|
|||||||
import ModificationsMenu from './ModificationsMenu';
|
import ModificationsMenu from './ModificationsMenu';
|
||||||
import { diffDetails } from '../utils/SlotFunctions';
|
import { diffDetails } from '../utils/SlotFunctions';
|
||||||
import { wrapCtxMenu } from '../utils/UtilityFunctions';
|
import { wrapCtxMenu } from '../utils/UtilityFunctions';
|
||||||
|
import { Ship, Module } from 'ed-forge';
|
||||||
|
import { REG_MILITARY_SLOT } from 'ed-forge/lib/data/slots';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract Slot
|
* Abstract Slot
|
||||||
*/
|
*/
|
||||||
export default class Slot extends TranslatedComponent {
|
export default class Slot extends TranslatedComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
availableModules: PropTypes.func.isRequired,
|
|
||||||
onSelect: PropTypes.func.isRequired,
|
onSelect: PropTypes.func.isRequired,
|
||||||
onOpen: PropTypes.func.isRequired,
|
onOpen: PropTypes.func.isRequired,
|
||||||
maxClass: PropTypes.number.isRequired,
|
|
||||||
selected: PropTypes.bool,
|
selected: PropTypes.bool,
|
||||||
m: PropTypes.object,
|
slot: PropTypes.instanceOf(Module),
|
||||||
enabled: PropTypes.bool.isRequired,
|
ship: PropTypes.instanceOf(Ship),
|
||||||
ship: PropTypes.object.isRequired,
|
|
||||||
eligible: PropTypes.object,
|
|
||||||
warning: PropTypes.func,
|
warning: PropTypes.func,
|
||||||
drag: PropTypes.func,
|
drag: PropTypes.func,
|
||||||
drop: PropTypes.func,
|
drop: PropTypes.func,
|
||||||
@@ -61,7 +58,7 @@ export default class Slot extends TranslatedComponent {
|
|||||||
* @return {string} label
|
* @return {string} label
|
||||||
*/
|
*/
|
||||||
_getMaxClassLabel() {
|
_getMaxClassLabel() {
|
||||||
return this.props.maxClass;
|
return this.props.slot.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +94,7 @@ export default class Slot extends TranslatedComponent {
|
|||||||
render() {
|
render() {
|
||||||
let language = this.context.language;
|
let language = this.context.language;
|
||||||
let translate = language.translate;
|
let translate = language.translate;
|
||||||
let { ship, m, enabled, dropClass, dragOver, onOpen, onChange, selected, eligible, onSelect, warning, availableModules } = this.props;
|
let { ship, slot, dropClass, dragOver, onOpen, onChange, selected, onSelect, warning } = this.props;
|
||||||
let slotDetails, modificationsMarker, menu;
|
let slotDetails, modificationsMarker, menu;
|
||||||
|
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
@@ -105,36 +102,37 @@ export default class Slot extends TranslatedComponent {
|
|||||||
this._modificationsSelected = false;
|
this._modificationsSelected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m) {
|
if (!slot.isEmpty()) {
|
||||||
slotDetails = this._getSlotDetails(m, enabled, translate, language.formats, language.units); // Must be implemented by sub classes
|
slotDetails = this._getSlotDetails(slot, translate, language.formats, language.units); // Must be implemented by sub classes
|
||||||
modificationsMarker = JSON.stringify(m);
|
|
||||||
} else {
|
} else {
|
||||||
slotDetails = <div className={'empty'}>{translate(eligible ? 'emptyrestricted' : 'empty')}</div>;
|
slotDetails = <div className={'empty'}>
|
||||||
modificationsMarker = '';
|
{translate(
|
||||||
|
slot.getSlot().match(REG_MILITARY_SLOT) ? 'emptyrestricted' : 'empty'
|
||||||
|
)}
|
||||||
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
if (this._modificationsSelected) {
|
// if (this._modificationsSelected) {
|
||||||
menu = <ModificationsMenu
|
// menu = <ModificationsMenu
|
||||||
className={this._getClassNames()}
|
// className={this._getClassNames()}
|
||||||
onChange={onChange}
|
// onChange={onChange}
|
||||||
ship={ship}
|
// ship={ship}
|
||||||
m={m}
|
// m={m}
|
||||||
marker={modificationsMarker}
|
// marker={modificationsMarker}
|
||||||
modButton = {this.modButton}
|
// modButton = {this.modButton}
|
||||||
/>;
|
// />;
|
||||||
} else {
|
// } else {
|
||||||
menu = <AvailableModulesMenu
|
menu = <AvailableModulesMenu
|
||||||
className={this._getClassNames()}
|
className={this._getClassNames()}
|
||||||
modules={availableModules()}
|
m={slot}
|
||||||
m={m}
|
ship={ship}
|
||||||
ship={ship}
|
onSelect={onSelect}
|
||||||
onSelect={onSelect}
|
warning={warning}
|
||||||
warning={warning}
|
diffDetails={diffDetails.bind(ship, this.context.language)}
|
||||||
diffDetails={diffDetails.bind(ship, this.context.language)}
|
slotDiv = {this.slotDiv}
|
||||||
slotDiv = {this.slotDiv}
|
/>;
|
||||||
/>;
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement touch dragging
|
// TODO: implement touch dragging
|
||||||
@@ -143,14 +141,13 @@ export default class Slot extends TranslatedComponent {
|
|||||||
<div className={cn('slot', dropClass, { selected })} onClick={onOpen} onKeyDown={this._keyDown} onContextMenu={this._contextMenu} onDragOver={dragOver} tabIndex="0" ref={slotDiv => this.slotDiv = slotDiv}>
|
<div className={cn('slot', dropClass, { selected })} onClick={onOpen} onKeyDown={this._keyDown} onContextMenu={this._contextMenu} onDragOver={dragOver} tabIndex="0" ref={slotDiv => this.slotDiv = slotDiv}>
|
||||||
<div className='details-container'>
|
<div className='details-container'>
|
||||||
<div className='sz'>{this._getMaxClassLabel(translate)}</div>
|
<div className='sz'>{this._getMaxClassLabel(translate)}</div>
|
||||||
{slotDetails}
|
{slotDetails}
|
||||||
</div>
|
</div>
|
||||||
{menu}
|
{menu}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle the modifications flag when selecting the modifications icon
|
* Toggle the modifications flag when selecting the modifications icon
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,19 +5,17 @@ import { wrapCtxMenu } from '../utils/UtilityFunctions';
|
|||||||
import { canMount } from '../utils/SlotFunctions';
|
import { canMount } from '../utils/SlotFunctions';
|
||||||
import { Equalizer } from '../components/SvgIcons';
|
import { Equalizer } from '../components/SvgIcons';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
|
import { Ship } from 'ed-forge';
|
||||||
const browser = require('detect-browser');
|
const browser = require('detect-browser');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract Slot Section
|
* Abstract Slot Section
|
||||||
*/
|
*/
|
||||||
export default class SlotSection extends TranslatedComponent {
|
export default class SlotSection extends TranslatedComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
ship: PropTypes.object.isRequired,
|
ship: PropTypes.instanceOf(Ship),
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
onCargoChange: PropTypes.func.isRequired,
|
// code: PropTypes.string.isRequired,
|
||||||
onFuelChange: PropTypes.func.isRequired,
|
|
||||||
code: PropTypes.string.isRequired,
|
|
||||||
togglePwr: PropTypes.func,
|
togglePwr: PropTypes.func,
|
||||||
sectionMenuRefs: PropTypes.object
|
sectionMenuRefs: PropTypes.object
|
||||||
};
|
};
|
||||||
@@ -106,6 +104,7 @@ export default class SlotSection extends TranslatedComponent {
|
|||||||
this.sectionRefArr['ssHeadRef'].focus();
|
this.sectionRefArr['ssHeadRef'].focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a menu
|
* Open a menu
|
||||||
* @param {string} menu Menu name
|
* @param {string} menu Menu name
|
||||||
@@ -126,7 +125,7 @@ export default class SlotSection extends TranslatedComponent {
|
|||||||
* @param {Object} m Selected module
|
* @param {Object} m Selected module
|
||||||
*/
|
*/
|
||||||
_selectModule(slot, m) {
|
_selectModule(slot, m) {
|
||||||
this.props.ship.use(slot, m, false);
|
slot.setItem(m);
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,24 +6,22 @@ import TranslatedComponent from './TranslatedComponent';
|
|||||||
import { diffDetails } from '../utils/SlotFunctions';
|
import { diffDetails } from '../utils/SlotFunctions';
|
||||||
import AvailableModulesMenu from './AvailableModulesMenu';
|
import AvailableModulesMenu from './AvailableModulesMenu';
|
||||||
import ModificationsMenu from './ModificationsMenu';
|
import ModificationsMenu from './ModificationsMenu';
|
||||||
import * as ModuleUtils from '../shipyard/ModuleUtils';
|
|
||||||
import { ListModifications, Modified } from './SvgIcons';
|
import { ListModifications, Modified } from './SvgIcons';
|
||||||
import { Modifications } from 'coriolis-data/dist';
|
import { Modifications } from 'coriolis-data/dist';
|
||||||
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
||||||
import { blueprintTooltip } from '../utils/BlueprintFunctions';
|
import { blueprintTooltip } from '../utils/BlueprintFunctions';
|
||||||
|
import { Ship, Module } from 'ed-forge';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard Slot
|
* Standard Slot
|
||||||
*/
|
*/
|
||||||
export default class StandardSlot extends TranslatedComponent {
|
export default class StandardSlot extends TranslatedComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
slot: PropTypes.object,
|
slot: PropTypes.instanceOf(Module),
|
||||||
modules: PropTypes.array.isRequired,
|
|
||||||
onSelect: PropTypes.func.isRequired,
|
onSelect: PropTypes.func.isRequired,
|
||||||
onOpen: PropTypes.func.isRequired,
|
onOpen: PropTypes.func.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
ship: PropTypes.object.isRequired,
|
ship: PropTypes.instanceOf(Ship),
|
||||||
selected: PropTypes.bool,
|
selected: PropTypes.bool,
|
||||||
warning: PropTypes.func,
|
warning: PropTypes.func,
|
||||||
};
|
};
|
||||||
@@ -59,33 +57,28 @@ export default class StandardSlot extends TranslatedComponent {
|
|||||||
render() {
|
render() {
|
||||||
let { termtip, tooltip } = this.context;
|
let { termtip, tooltip } = this.context;
|
||||||
let { translate, formats, units } = this.context.language;
|
let { translate, formats, units } = this.context.language;
|
||||||
let { modules, slot, selected, warning, onSelect, onChange, ship } = this.props;
|
let { slot, selected, warning, onSelect, onChange, ship } = this.props;
|
||||||
let m = slot.m;
|
let classRating = String(slot.getClass()) + (slot.getRating() || '');
|
||||||
let classRating = m.class + m.rating;
|
|
||||||
let menu;
|
let menu;
|
||||||
let validMods = m == null || !Modifications.modules[m.grp] ? [] : (Modifications.modules[m.grp].modifications || []);
|
let validMods = slot.getApplicableBlueprints();
|
||||||
if (m && m.name && m.name === 'Guardian Hybrid Power Plant') {
|
|
||||||
validMods = [];
|
|
||||||
}
|
|
||||||
if (m && m.name && m.name === 'Guardian Power Distributor') {
|
|
||||||
validMods = [];
|
|
||||||
}
|
|
||||||
let showModuleResistances = Persist.showModuleResistances();
|
let showModuleResistances = Persist.showModuleResistances();
|
||||||
let mass = m.getMass() || m.cargo || m.fuel || 0;
|
let mass = slot.get('cargo') || slot.get('fuel') || slot.get('mass') || 0;
|
||||||
|
|
||||||
// Modifications tooltip shows blueprint and grade, if available
|
// Modifications tooltip shows blueprint and grade, if available
|
||||||
let modTT = translate('modified');
|
let modTT = translate('modified');
|
||||||
if (m && m.blueprint && m.blueprint.name) {
|
const appliedBlueprint = slot.getBlueprint();
|
||||||
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
const appliedExperimental = slot.getExperimental();
|
||||||
if (m.blueprint.special && m.blueprint.special.id >= 0) {
|
if (appliedBlueprint) {
|
||||||
modTT += ', ' + translate(m.blueprint.special.name);
|
modTT = translate(appliedBlueprint) + ' ' + translate('grade') + ' ' + slot.getBlueprintGrade();
|
||||||
|
if (appliedExperimental) {
|
||||||
|
modTT += ', ' + translate(appliedExperimental);
|
||||||
}
|
}
|
||||||
modTT = (
|
modTT = (
|
||||||
<div>
|
<div>
|
||||||
<div>{modTT}</div>
|
<div>{modTT}</div>
|
||||||
{blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade], null, m.grp, m)}
|
{blueprintTooltip(translate, slot)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
@@ -93,23 +86,19 @@ export default class StandardSlot extends TranslatedComponent {
|
|||||||
this._modificationsSelected = false;
|
this._modificationsSelected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const modificationsMarker = JSON.stringify(m);
|
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
if (this._modificationsSelected) {
|
if (this._modificationsSelected) {
|
||||||
menu = <ModificationsMenu
|
menu = <ModificationsMenu
|
||||||
className='standard'
|
className='standard'
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
m={m}
|
m={slot}
|
||||||
marker={modificationsMarker}
|
|
||||||
modButton = {this.modButton}
|
modButton = {this.modButton}
|
||||||
/>;
|
/>;
|
||||||
} else {
|
} else {
|
||||||
menu = <AvailableModulesMenu
|
menu = <AvailableModulesMenu
|
||||||
className='standard'
|
className='standard'
|
||||||
modules={modules}
|
m={slot}
|
||||||
m={m}
|
|
||||||
ship={ship}
|
ship={ship}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
warning={warning}
|
warning={warning}
|
||||||
@@ -121,30 +110,30 @@ export default class StandardSlot extends TranslatedComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('slot', { selected: this.props.selected })} onClick={this.props.onOpen} onKeyDown={this._keyDown} onContextMenu={stopCtxPropagation} tabIndex="0" ref={ slotDiv => this.slotDiv = slotDiv }>
|
<div className={cn('slot', { selected: this.props.selected })} onClick={this.props.onOpen} onKeyDown={this._keyDown} onContextMenu={stopCtxPropagation} tabIndex="0" ref={ slotDiv => this.slotDiv = slotDiv }>
|
||||||
<div className={cn('details-container', { warning: warning && warning(slot.m), disabled: m.grp !== 'bh' && !slot.enabled })}>
|
<div className={cn('details-container', { warning: warning && warning(slot), disabled: slot.isEnabled() })}>
|
||||||
<div className={'sz'}>{m.grp == 'bh' ? m.name.charAt(0) : slot.maxClass}</div>
|
<div className={'sz'}>{slot.getSize()}</div>
|
||||||
<div>
|
<div>
|
||||||
<div className={'l'}>{classRating} {translate(m.name || m.grp)}{m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }</div>
|
<div className={'l'}>{classRating} {translate(slot.getItem())}{appliedBlueprint ? <span className='r' onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }</div>
|
||||||
<div className={'r'}>{formats.round(mass)}{units.T}</div>
|
<div className={'r'}>{formats.round(mass)}{units.T}</div>
|
||||||
<div/>
|
<div/>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
{ m.getMinMass() ? <div className='l'>{translate('minimum mass')}: {formats.int(m.getMinMass())}{units.T}</div> : null }
|
{/* { m.getMinMass() ? <div className='l'>{translate('minimum mass')}: {formats.int(m.getMinMass())}{units.T}</div> : null }
|
||||||
{ m.getOptMass() ? <div className='l'>{translate('optimal mass')}: {formats.int(m.getOptMass())}{units.T}</div> : null }
|
{ m.getOptMass() ? <div className='l'>{translate('optimal mass')}: {formats.int(m.getOptMass())}{units.T}</div> : null }
|
||||||
{ m.getMaxMass() ? <div className='l'>{translate('max mass')}: {formats.int(m.getMaxMass())}{units.T}</div> : null }
|
{ m.getMaxMass() ? <div className='l'>{translate('max mass')}: {formats.int(m.getMaxMass())}{units.T}</div> : null }
|
||||||
{ m.getOptMul() ? <div className='l'>{translate('optimal multiplier')}: {formats.rPct(m.getOptMul())}</div> : null }
|
{ m.getOptMul() ? <div className='l'>{translate('optimal multiplier')}: {formats.rPct(m.getOptMul())}</div> : null }
|
||||||
{ m.getRange() ? <div className='l'>{translate('range', m.grp)}: {formats.f2(m.getRange())}{units.km}</div> : null }
|
{ m.getRange() ? <div className='l'>{translate('range', m.grp)}: {formats.f2(m.getRange())}{units.km}</div> : null }
|
||||||
{ m.time ? <div className='l'>{translate('time')}: {formats.time(m.time)}</div> : null }
|
{ m.time ? <div className='l'>{translate('time')}: {formats.time(m.time)}</div> : null }
|
||||||
{ m.getThermalEfficiency() ? <div className='l'>{translate('efficiency')}: {formats.f2(m.getThermalEfficiency())}</div> : null }
|
{ m.getThermalEfficiency() ? <div className='l'>{translate('efficiency')}: {formats.f2(m.getThermalEfficiency())}</div> : null }
|
||||||
{ m.getPowerGeneration() > 0 ? <div className='l'>{translate('pgen')}: {formats.f1(m.getPowerGeneration())}{units.MW}</div> : null }
|
{ m.getPowerGeneration() > 0 ? <div className='l'>{translate('pgen')}: {formats.f1(m.getPowerGeneration())}{units.MW}</div> : null }
|
||||||
{ m.getMaxFuelPerJump() ? <div className='l'>{translate('max')} {translate('fuel')}: {formats.f1(m.getMaxFuelPerJump())}{units.T}</div> : null }
|
{ m.getMaxFuelPerJump() ? <div className='l'>{translate('max')} {translate('fuel')}: {formats.f1(m.getMaxFuelPerJump())}{units.T}</div> : null }
|
||||||
{ m.getWeaponsCapacity() ? <div className='l'>{translate('WEP')}: {formats.f1(m.getWeaponsCapacity())}{units.MJ} / {formats.f1(m.getWeaponsRechargeRate())}{units.MW}</div> : null }
|
{ m.getWeaponsCapacity() ? <div className='l'>{translate('WEP')}: {formats.f1(m.getWeaponsCapacity())}{units.MJ} / {formats.f1(m.getWeaponsRechargeRate())}{units.MW}</div> : null }
|
||||||
{ m.getSystemsCapacity() ? <div className='l'>{translate('SYS')}: {formats.f1(m.getSystemsCapacity())}{units.MJ} / {formats.f1(m.getSystemsRechargeRate())}{units.MW}</div> : null }
|
{ m.getSystemsCapacity() ? <div className='l'>{translate('SYS')}: {formats.f1(m.getSystemsCapacity())}{units.MJ} / {formats.f1(m.getSystemsRechargeRate())}{units.MW}</div> : null }
|
||||||
{ m.getEnginesCapacity() ? <div className='l'>{translate('ENG')}: {formats.f1(m.getEnginesCapacity())}{units.MJ} / {formats.f1(m.getEnginesRechargeRate())}{units.MW}</div> : null }
|
{ m.getEnginesCapacity() ? <div className='l'>{translate('ENG')}: {formats.f1(m.getEnginesCapacity())}{units.MJ} / {formats.f1(m.getEnginesRechargeRate())}{units.MW}</div> : null }
|
||||||
{ showModuleResistances && m.getExplosiveResistance() ? <div className='l'>{translate('explres')}: {formats.pct(m.getExplosiveResistance())}</div> : null }
|
{ showModuleResistances && m.getExplosiveResistance() ? <div className='l'>{translate('explres')}: {formats.pct(m.getExplosiveResistance())}</div> : null }
|
||||||
{ showModuleResistances && m.getKineticResistance() ? <div className='l'>{translate('kinres')}: {formats.pct(m.getKineticResistance())}</div> : null }
|
{ showModuleResistances && m.getKineticResistance() ? <div className='l'>{translate('kinres')}: {formats.pct(m.getKineticResistance())}</div> : null }
|
||||||
{ showModuleResistances && m.getThermalResistance() ? <div className='l'>{translate('thermres')}: {formats.pct(m.getThermalResistance())}</div> : null }
|
{ showModuleResistances && m.getThermalResistance() ? <div className='l'>{translate('thermres')}: {formats.pct(m.getThermalResistance())}</div> : null }
|
||||||
{ m.getIntegrity() ? <div className='l'>{translate('integrity')}: {formats.int(m.getIntegrity())}</div> : null }
|
{ m.getIntegrity() ? <div className='l'>{translate('integrity')}: {formats.int(m.getIntegrity())}</div> : null } */}
|
||||||
{ validMods.length > 0 ? <div className='r' tabIndex="0" ref={ modButton => this.modButton = modButton }><button tabIndex="-1" onClick={this._toggleModifications.bind(this)} onContextMenu={stopCtxPropagation} onMouseOver={termtip.bind(null, 'modifications')} onMouseOut={tooltip.bind(null, null)}><ListModifications /></button></div> : null }
|
{/* { validMods.length > 0 ? <div className='r' tabIndex="0" ref={ modButton => this.modButton = modButton }><button tabIndex="-1" onClick={this._toggleModifications.bind(this)} onContextMenu={stopCtxPropagation} onMouseOver={termtip.bind(null, 'modifications')} onMouseOut={tooltip.bind(null, null)}><ListModifications /></button></div> : null } */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import StandardSlot from './StandardSlot';
|
|||||||
import Module from '../shipyard/Module';
|
import Module from '../shipyard/Module';
|
||||||
import * as ShipRoles from '../shipyard/ShipRoles';
|
import * as ShipRoles from '../shipyard/ShipRoles';
|
||||||
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
||||||
|
import { ShipProps } from 'ed-forge';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard Slot section
|
* Standard Slot section
|
||||||
*/
|
*/
|
||||||
export default class StandardSlotSection extends SlotSection {
|
export default class StandardSlotSection extends SlotSection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {Object} props React Component properties
|
* @param {Object} props React Component properties
|
||||||
@@ -39,8 +39,6 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
this.selectedRefId = 'maxjump';
|
this.selectedRefId = 'maxjump';
|
||||||
this.props.ship.useLightestStandard();
|
this.props.ship.useLightestStandard();
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
this.props.onCargoChange(this.props.ship.cargoCapacity);
|
|
||||||
this.props.onFuelChange(this.props.ship.fuelCapacity);
|
|
||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +52,6 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
if (bulkheadIndex === 2) this.selectedRefId = 'combat';
|
if (bulkheadIndex === 2) this.selectedRefId = 'combat';
|
||||||
ShipRoles.multiPurpose(this.props.ship, shielded, bulkheadIndex);
|
ShipRoles.multiPurpose(this.props.ship, shielded, bulkheadIndex);
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
this.props.onCargoChange(this.props.ship.cargoCapacity);
|
|
||||||
this.props.onFuelChange(this.props.ship.fuelCapacity);
|
|
||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,8 +63,6 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
this.selectedRefId = 'trader';
|
this.selectedRefId = 'trader';
|
||||||
ShipRoles.trader(this.props.ship, shielded);
|
ShipRoles.trader(this.props.ship, shielded);
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
this.props.onCargoChange(this.props.ship.cargoCapacity);
|
|
||||||
this.props.onFuelChange(this.props.ship.fuelCapacity);
|
|
||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,8 +74,6 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
this.selectedRefId = 'miner';
|
this.selectedRefId = 'miner';
|
||||||
ShipRoles.miner(this.props.ship, shielded);
|
ShipRoles.miner(this.props.ship, shielded);
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
this.props.onCargoChange(this.props.ship.cargoCapacity);
|
|
||||||
this.props.onFuelChange(this.props.ship.fuelCapacity);
|
|
||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +86,6 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
if (planetary) this.selectedRefId = 'planetary';
|
if (planetary) this.selectedRefId = 'planetary';
|
||||||
ShipRoles.explorer(this.props.ship, planetary);
|
ShipRoles.explorer(this.props.ship, planetary);
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
this.props.onCargoChange(this.props.ship.cargoCapacity);
|
|
||||||
this.props.onFuelChange(this.props.ship.fuelCapacity);
|
|
||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,8 +96,6 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
this.selectedRefId = 'racer';
|
this.selectedRefId = 'racer';
|
||||||
ShipRoles.racer(this.props.ship);
|
ShipRoles.racer(this.props.ship);
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
this.props.onCargoChange(this.props.ship.cargoCapacity);
|
|
||||||
this.props.onFuelChange(this.props.ship.fuelCapacity);
|
|
||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,105 +122,114 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
* @return {Array} Array of Slots
|
* @return {Array} Array of Slots
|
||||||
*/
|
*/
|
||||||
_getSlots() {
|
_getSlots() {
|
||||||
let { ship, currentMenu, cargo, fuel } = this.props;
|
let { ship, currentMenu } = this.props;
|
||||||
let slots = new Array(8);
|
let slots = new Array(8);
|
||||||
let open = this._openMenu;
|
let open = this._openMenu;
|
||||||
let select = this._selectModule;
|
let select = this._selectModule;
|
||||||
let st = ship.standard;
|
// let st = ship.standard;
|
||||||
let avail = ship.getAvailableModules().standard;
|
// let avail = ship.getAvailableModules().standard;
|
||||||
let bh = ship.bulkheads;
|
// let bh = ship.bulkheads;
|
||||||
|
|
||||||
|
let armour = ship.getAlloys();
|
||||||
slots[0] = <StandardSlot
|
slots[0] = <StandardSlot
|
||||||
key='bh'
|
key='bh'
|
||||||
slot={bh}
|
slot={armour}
|
||||||
modules={ship.getAvailableModules().bulkheads}
|
modules={armour.getApplicableItems()}
|
||||||
onOpen={open.bind(this, bh)}
|
onOpen={open.bind(this, armour)}
|
||||||
onSelect={this._selectBulkhead}
|
onSelect={this._selectBulkhead}
|
||||||
selected={currentMenu == bh}
|
selected={currentMenu == armour}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
const powerPlant = ship.getPowerPlant();
|
||||||
slots[1] = <StandardSlot
|
slots[1] = <StandardSlot
|
||||||
key='pp'
|
key='pp'
|
||||||
slot={st[0]}
|
slot={powerPlant}
|
||||||
modules={avail[0]}
|
modules={powerPlant.getApplicableItems()}
|
||||||
onOpen={open.bind(this, st[0])}
|
onOpen={open.bind(this, powerPlant)}
|
||||||
onSelect={select.bind(this, st[0])}
|
onSelect={select.bind(this, powerPlant)}
|
||||||
selected={currentMenu == st[0]}
|
selected={currentMenu == powerPlant}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
warning={m => m instanceof Module ? m.getPowerGeneration() < ship.powerRetracted : m.pgen < ship.powerRetracted}
|
warning={m => ship.get(ShipProps.CONSUMED_RETR) < m.get('powercapacity')}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
const thrusters = ship.getThrusters();
|
||||||
slots[2] = <StandardSlot
|
slots[2] = <StandardSlot
|
||||||
key='th'
|
key='th'
|
||||||
slot={st[1]}
|
slot={thrusters}
|
||||||
modules={avail[1]}
|
modules={thrusters.getApplicableItems()}
|
||||||
onOpen={open.bind(this, st[1])}
|
onOpen={open.bind(this, thrusters)}
|
||||||
onSelect={select.bind(this, st[1])}
|
onSelect={select.bind(this, thrusters)}
|
||||||
selected={currentMenu == st[1]}
|
selected={currentMenu == thrusters}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
warning={m => m instanceof Module ? m.getMaxMass() < (ship.unladenMass + cargo + fuel - st[1].m.mass + m.mass) : m.maxmass < (ship.unladenMass + cargo + fuel - st[1].m.mass + m.mass)}
|
warning={m => m.get('enginemaximalmass') < ship.get(ShipProps.LADEN_MASS)}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
|
||||||
|
const fsd = ship.getFSD();
|
||||||
slots[3] = <StandardSlot
|
slots[3] = <StandardSlot
|
||||||
key='fsd'
|
key='fsd'
|
||||||
slot={st[2]}
|
slot={fsd}
|
||||||
modules={avail[2]}
|
modules={fsd.getApplicableItems()}
|
||||||
onOpen={open.bind(this, st[2])}
|
onOpen={open.bind(this, fsd)}
|
||||||
onSelect={select.bind(this, st[2])}
|
onSelect={select.bind(this, fsd)}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
selected={currentMenu == st[2]}
|
selected={currentMenu == fsd}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
const lifeSupport = ship.getLifeSupport();
|
||||||
slots[4] = <StandardSlot
|
slots[4] = <StandardSlot
|
||||||
key='ls'
|
key='ls'
|
||||||
slot={st[3]}
|
slot={lifeSupport}
|
||||||
modules={avail[3]}
|
modules={lifeSupport.getApplicableItems()}
|
||||||
onOpen={open.bind(this, st[3])}
|
onOpen={open.bind(this, lifeSupport)}
|
||||||
onSelect={select.bind(this, st[3])}
|
onSelect={select.bind(this, lifeSupport)}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
selected={currentMenu == st[3]}
|
selected={currentMenu == lifeSupport}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
const powerDistributor = ship.getPowerDistributor();
|
||||||
slots[5] = <StandardSlot
|
slots[5] = <StandardSlot
|
||||||
key='pd'
|
key='pd'
|
||||||
slot={st[4]}
|
slot={powerDistributor}
|
||||||
modules={avail[4]}
|
modules={powerDistributor.getApplicableItems()}
|
||||||
onOpen={open.bind(this, st[4])}
|
onOpen={open.bind(this, powerDistributor)}
|
||||||
onSelect={select.bind(this, st[4])}
|
onSelect={select.bind(this, powerDistributor)}
|
||||||
selected={currentMenu == st[4]}
|
selected={currentMenu == powerDistributor}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
warning={m => m instanceof Module ? m.getEnginesCapacity() <= ship.boostEnergy : m.engcap <= ship.boostEnergy}
|
warning={m => m instanceof Module ? m.getEnginesCapacity() <= ship.boostEnergy : m.engcap <= ship.boostEnergy}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
const sensors = ship.getSensors();
|
||||||
slots[6] = <StandardSlot
|
slots[6] = <StandardSlot
|
||||||
key='ss'
|
key='ss'
|
||||||
slot={st[5]}
|
slot={sensors}
|
||||||
modules={avail[5]}
|
modules={sensors.getApplicableItems()}
|
||||||
onOpen={open.bind(this, st[5])}
|
onOpen={open.bind(this, sensors)}
|
||||||
onSelect={select.bind(this, st[5])}
|
onSelect={select.bind(this, sensors)}
|
||||||
selected={currentMenu == st[5]}
|
selected={currentMenu == sensors}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
const fuelTank = ship.getCoreFuelTank();
|
||||||
slots[7] = <StandardSlot
|
slots[7] = <StandardSlot
|
||||||
key='ft'
|
key='ft'
|
||||||
slot={st[6]}
|
slot={fuelTank}
|
||||||
modules={avail[6]}
|
modules={fuelTank.getApplicableItems()}
|
||||||
onOpen={open.bind(this, st[6])}
|
onOpen={open.bind(this, fuelTank)}
|
||||||
onSelect={select.bind(this, st[6])}
|
onSelect={select.bind(this, fuelTank)}
|
||||||
selected={currentMenu == st[6]}
|
selected={currentMenu == fuelTank}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
warning= {m => m.fuel < st[2].m.maxfuel} // Show warning when fuel tank is smaller than FSD Max Fuel
|
// Show warning when fuel tank is smaller than FSD Max Fuel
|
||||||
|
warning= {m => m.get('fuel') < fsd.get('maxfuel')}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
return slots;
|
return slots;
|
||||||
@@ -261,5 +258,4 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,30 +67,24 @@ export default class UtilitySlotSection extends SlotSection {
|
|||||||
_getSlots() {
|
_getSlots() {
|
||||||
let slots = [];
|
let slots = [];
|
||||||
let { ship, currentMenu } = this.props;
|
let { ship, currentMenu } = this.props;
|
||||||
let hardpoints = ship.hardpoints;
|
|
||||||
let { originSlot, targetSlot } = this.state;
|
let { originSlot, targetSlot } = this.state;
|
||||||
let availableModules = ship.getAvailableModules();
|
|
||||||
|
|
||||||
for (let i = 0, l = hardpoints.length; i < l; i++) {
|
for (let h of ship.getUtilities(undefined, true)) {
|
||||||
let h = hardpoints[i];
|
slots.push(<HardpointSlot
|
||||||
if (h.maxClass === 0) {
|
key={h.object.Slot}
|
||||||
slots.push(<HardpointSlot
|
maxClass={h.getSize()}
|
||||||
key={i}
|
onOpen={this._openMenu.bind(this,h)}
|
||||||
maxClass={h.maxClass}
|
onSelect={this._selectModule.bind(this, h)}
|
||||||
availableModules={() => availableModules.getHps(h.maxClass)}
|
onChange={this.props.onChange}
|
||||||
onOpen={this._openMenu.bind(this,h)}
|
selected={currentMenu == h}
|
||||||
onSelect={this._selectModule.bind(this, h)}
|
drag={this._drag.bind(this, h)}
|
||||||
onChange={this.props.onChange}
|
dragOver={this._dragOverSlot.bind(this, h)}
|
||||||
selected={currentMenu == h}
|
drop={this._drop}
|
||||||
drag={this._drag.bind(this, h)}
|
dropClass={this._dropClass(h, originSlot, targetSlot)}
|
||||||
dragOver={this._dragOverSlot.bind(this, h)}
|
ship={ship}
|
||||||
drop={this._drop}
|
slot={h}
|
||||||
dropClass={this._dropClass(h, originSlot, targetSlot)}
|
enabled={h.enabled ? true : false}
|
||||||
ship={ship}
|
/>);
|
||||||
m={h.m}
|
|
||||||
enabled={h.enabled ? true : false}
|
|
||||||
/>);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return slots;
|
return slots;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import Page from './Page';
|
|||||||
import Router from '../Router';
|
import Router from '../Router';
|
||||||
import Persist from '../stores/Persist';
|
import Persist from '../stores/Persist';
|
||||||
import * as Utils from '../utils/UtilityFunctions';
|
import * as Utils from '../utils/UtilityFunctions';
|
||||||
import Ship from '../shipyard/Ship';
|
import { Factory, Ship } from 'ed-forge';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { toDetailedBuild } from '../shipyard/Serializer';
|
import { toDetailedBuild } from '../shipyard/Serializer';
|
||||||
import { outfitURL } from '../utils/UrlGenerators';
|
import { outfitURL } from '../utils/UrlGenerators';
|
||||||
@@ -64,10 +64,6 @@ export default class OutfittingPage extends Page {
|
|||||||
this.state = this._initState(props, context);
|
this.state = this._initState(props, context);
|
||||||
this._keyDown = this._keyDown.bind(this);
|
this._keyDown = this._keyDown.bind(this);
|
||||||
this._exportBuild = this._exportBuild.bind(this);
|
this._exportBuild = this._exportBuild.bind(this);
|
||||||
this._pipsUpdated = this._pipsUpdated.bind(this);
|
|
||||||
this._boostUpdated = this._boostUpdated.bind(this);
|
|
||||||
this._cargoUpdated = this._cargoUpdated.bind(this);
|
|
||||||
this._fuelUpdated = this._fuelUpdated.bind(this);
|
|
||||||
this._opponentUpdated = this._opponentUpdated.bind(this);
|
this._opponentUpdated = this._opponentUpdated.bind(this);
|
||||||
this._engagementRangeUpdated = this._engagementRangeUpdated.bind(this);
|
this._engagementRangeUpdated = this._engagementRangeUpdated.bind(this);
|
||||||
this._sectionMenuRefs = {};
|
this._sectionMenuRefs = {};
|
||||||
@@ -82,40 +78,14 @@ export default class OutfittingPage extends Page {
|
|||||||
_initState(props, context) {
|
_initState(props, context) {
|
||||||
let params = context.route.params;
|
let params = context.route.params;
|
||||||
let shipId = params.ship;
|
let shipId = params.ship;
|
||||||
let code = params.code;
|
|
||||||
let buildName = params.bn;
|
let buildName = params.bn;
|
||||||
let data = Ships[shipId]; // Retrieve the basic ship properties, slots and defaults
|
|
||||||
let savedCode = Persist.getBuild(shipId, buildName);
|
let savedCode = Persist.getBuild(shipId, buildName);
|
||||||
if (!data) {
|
let code = params.code || savedCode;
|
||||||
return { error: { message: 'Ship not found: ' + shipId } };
|
let ship = code ? new Ship(code) : Factory.newShip(shipId); // Create a new Ship instance
|
||||||
}
|
code = ship.compress();
|
||||||
let ship = new Ship(shipId, data.properties, data.slots); // Create a new Ship instance
|
|
||||||
if (code) {
|
|
||||||
ship.buildFrom(code); // Populate modules from serialized 'code' URL param
|
|
||||||
} else {
|
|
||||||
ship.buildWith(data.defaults); // Populate with default components
|
|
||||||
}
|
|
||||||
|
|
||||||
this._getTitle = getTitle.bind(this, data.properties.name);
|
this._getTitle = getTitle.bind(this, ship.getShipType());
|
||||||
|
|
||||||
// Obtain ship control from code
|
|
||||||
const {
|
|
||||||
sys,
|
|
||||||
eng,
|
|
||||||
wep,
|
|
||||||
mcSys,
|
|
||||||
mcEng,
|
|
||||||
mcWep,
|
|
||||||
boost,
|
|
||||||
fuel,
|
|
||||||
cargo,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
opponentSys,
|
|
||||||
opponentEng,
|
|
||||||
opponentWep,
|
|
||||||
engagementRange
|
|
||||||
} = this._obtainControlFromCode(ship, code);
|
|
||||||
return {
|
return {
|
||||||
error: null,
|
error: null,
|
||||||
title: this._getTitle(buildName),
|
title: this._getTitle(buildName),
|
||||||
@@ -126,21 +96,6 @@ export default class OutfittingPage extends Page {
|
|||||||
ship,
|
ship,
|
||||||
code,
|
code,
|
||||||
savedCode,
|
savedCode,
|
||||||
sys,
|
|
||||||
eng,
|
|
||||||
wep,
|
|
||||||
mcSys,
|
|
||||||
mcEng,
|
|
||||||
mcWep,
|
|
||||||
boost,
|
|
||||||
fuel,
|
|
||||||
cargo,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
opponentSys,
|
|
||||||
opponentEng,
|
|
||||||
opponentWep,
|
|
||||||
engagementRange
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,170 +123,13 @@ export default class OutfittingPage extends Page {
|
|||||||
/**
|
/**
|
||||||
* Update the control part of the route
|
* Update the control part of the route
|
||||||
*/
|
*/
|
||||||
_updateRouteOnControlChange() {
|
_updateRoute() {
|
||||||
const { ship, shipId, buildName } = this.state;
|
const { ship, shipId, buildName } = this.state;
|
||||||
const code = this._fullCode(ship);
|
const code = ship.compress();
|
||||||
this._updateRoute(shipId, buildName, code);
|
this._updateRoute(shipId, buildName, code);
|
||||||
this.setState({ code });
|
this.setState({ code });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a full code for this ship, including any additions due to the outfitting page
|
|
||||||
* @param {Object} ship the ship
|
|
||||||
* @param {number} fuel the fuel carried by the ship (if different from that in state)
|
|
||||||
* @param {number} cargo the cargo carried by the ship (if different from that in state)
|
|
||||||
* @returns {string} the code for this ship
|
|
||||||
*/
|
|
||||||
_fullCode(ship, fuel, cargo) {
|
|
||||||
return `${ship.toString()}.${LZString.compressToBase64(
|
|
||||||
this._controlCode(fuel, cargo)
|
|
||||||
)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain the control information from the build code
|
|
||||||
* @param {Object} ship The ship
|
|
||||||
* @param {string} code The build code
|
|
||||||
* @returns {Object} The control information
|
|
||||||
*/
|
|
||||||
_obtainControlFromCode(ship, code) {
|
|
||||||
// Defaults
|
|
||||||
let sys = 2;
|
|
||||||
let eng = 2;
|
|
||||||
let wep = 2;
|
|
||||||
let mcSys = 0;
|
|
||||||
let mcEng = 0;
|
|
||||||
let mcWep = 0;
|
|
||||||
let boost = false;
|
|
||||||
let fuel = ship.fuelCapacity;
|
|
||||||
let cargo = ship.cargoCapacity;
|
|
||||||
let opponent = new Ship(
|
|
||||||
'eagle',
|
|
||||||
Ships['eagle'].properties,
|
|
||||||
Ships['eagle'].slots
|
|
||||||
).buildWith(Ships['eagle'].defaults);
|
|
||||||
let opponentSys = 2;
|
|
||||||
let opponentEng = 2;
|
|
||||||
let opponentWep = 2;
|
|
||||||
let opponentBuild;
|
|
||||||
let engagementRange = 1000;
|
|
||||||
|
|
||||||
// Obtain updates from code, if available
|
|
||||||
if (code) {
|
|
||||||
const parts = code.split('.');
|
|
||||||
if (parts.length >= 5) {
|
|
||||||
// We have control information in the code
|
|
||||||
const control = LZString.decompressFromBase64(
|
|
||||||
Utils.fromUrlSafe(parts[4])
|
|
||||||
).split('/');
|
|
||||||
sys = parseFloat(control[0]);
|
|
||||||
eng = parseFloat(control[1]);
|
|
||||||
wep = parseFloat(control[2]);
|
|
||||||
if (sys + eng + wep > 6) {
|
|
||||||
sys = eng = wep = 2;
|
|
||||||
}
|
|
||||||
boost = control[3] == 1 ? true : false;
|
|
||||||
fuel = parseFloat(control[4]) || fuel;
|
|
||||||
cargo = parseInt(control[5]) || cargo;
|
|
||||||
if (control[6]) {
|
|
||||||
const shipId = control[6];
|
|
||||||
opponent = new Ship(
|
|
||||||
shipId,
|
|
||||||
Ships[shipId].properties,
|
|
||||||
Ships[shipId].slots
|
|
||||||
);
|
|
||||||
if (control[7] && Persist.getBuild(shipId, control[7])) {
|
|
||||||
// Ship is a particular build
|
|
||||||
const opponentCode = Persist.getBuild(shipId, control[7]);
|
|
||||||
opponent.buildFrom(opponentCode);
|
|
||||||
opponentBuild = control[7];
|
|
||||||
if (opponentBuild) {
|
|
||||||
// Obtain opponent's sys/eng/wep pips from their code
|
|
||||||
const opponentParts = opponentCode.split('.');
|
|
||||||
if (opponentParts.length >= 5) {
|
|
||||||
const opponentControl = LZString.decompressFromBase64(
|
|
||||||
Utils.fromUrlSafe(opponentParts[4])
|
|
||||||
).split('/');
|
|
||||||
opponentSys = parseFloat(opponentControl[0]) || opponentSys;
|
|
||||||
opponentEng = parseFloat(opponentControl[1]) || opponentEng;
|
|
||||||
opponentWep = parseFloat(opponentControl[2]) || opponentWep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Ship is a stock build
|
|
||||||
opponent.buildWith(Ships[shipId].defaults);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
engagementRange = parseInt(control[8]) || engagementRange;
|
|
||||||
|
|
||||||
// Multi-crew pips were introduced later on so assign default values
|
|
||||||
// because those values might not be present.
|
|
||||||
mcSys = parseInt(control[9]) || mcSys;
|
|
||||||
mcEng = parseInt(control[10]) || mcEng;
|
|
||||||
mcWep = parseInt(control[11]) || mcWep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
sys,
|
|
||||||
eng,
|
|
||||||
wep,
|
|
||||||
mcSys,
|
|
||||||
mcEng,
|
|
||||||
mcWep,
|
|
||||||
boost,
|
|
||||||
fuel,
|
|
||||||
cargo,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
opponentSys,
|
|
||||||
opponentEng,
|
|
||||||
opponentWep,
|
|
||||||
engagementRange
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Triggered when pips have been updated. Multi-crew pips are already included
|
|
||||||
* in sys, eng and wep but mcSys, mcEng and mcWep make clear where each pip
|
|
||||||
* comes from.
|
|
||||||
* @param {number} sys SYS pips
|
|
||||||
* @param {number} eng ENG pips
|
|
||||||
* @param {number} wep WEP pips
|
|
||||||
* @param {number} mcSys SYS pips from multi-crew
|
|
||||||
* @param {number} mcEng ENG pips from multi-crew
|
|
||||||
* @param {number} mcWep WEP pips from multi-crew
|
|
||||||
*/
|
|
||||||
_pipsUpdated(sys, eng, wep, mcSys, mcEng, mcWep) {
|
|
||||||
this.setState({ sys, eng, wep, mcSys, mcEng, mcWep }, () =>
|
|
||||||
this._updateRouteOnControlChange()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Triggered when boost has been updated
|
|
||||||
* @param {boolean} boost true if boosting
|
|
||||||
*/
|
|
||||||
_boostUpdated(boost) {
|
|
||||||
this.setState({ boost }, () => this._updateRouteOnControlChange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Triggered when fuel has been updated
|
|
||||||
* @param {number} fuel the amount of fuel, in T
|
|
||||||
*/
|
|
||||||
_fuelUpdated(fuel) {
|
|
||||||
this.setState({ fuel }, () => this._updateRouteOnControlChange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Triggered when cargo has been updated
|
|
||||||
* @param {number} cargo the amount of cargo, in T
|
|
||||||
*/
|
|
||||||
_cargoUpdated(cargo) {
|
|
||||||
this.setState({ cargo }, () => this._updateRouteOnControlChange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when engagement range has been updated
|
* Triggered when engagement range has been updated
|
||||||
* @param {number} engagementRange the engagement range, in m
|
* @param {number} engagementRange the engagement range, in m
|
||||||
@@ -387,36 +185,10 @@ export default class OutfittingPage extends Page {
|
|||||||
opponentEng,
|
opponentEng,
|
||||||
opponentWep
|
opponentWep
|
||||||
},
|
},
|
||||||
() => this._updateRouteOnControlChange()
|
() => this._updateRoute()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the control code for this outfitting page
|
|
||||||
* @param {number} fuel the fuel carried by the ship (if different from that in state)
|
|
||||||
* @param {number} cargo the cargo carried by the ship (if different from that in state)
|
|
||||||
* @returns {string} The control code
|
|
||||||
*/
|
|
||||||
_controlCode(fuel, cargo) {
|
|
||||||
const {
|
|
||||||
sys,
|
|
||||||
eng,
|
|
||||||
wep,
|
|
||||||
mcSys,
|
|
||||||
mcEng,
|
|
||||||
mcWep,
|
|
||||||
boost,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
engagementRange
|
|
||||||
} = this.state;
|
|
||||||
const code = `${sys}/${eng}/${wep}/${boost ? 1 : 0}/${fuel ||
|
|
||||||
this.state.fuel}/${cargo || this.state.cargo}/${opponent.id}/${
|
|
||||||
opponentBuild ? opponentBuild : ''
|
|
||||||
}/${engagementRange}/${mcSys}/${mcEng}/${mcWep}`;
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the current build
|
* Save the current build
|
||||||
*/
|
*/
|
||||||
@@ -424,7 +196,7 @@ export default class OutfittingPage extends Page {
|
|||||||
const { ship, buildName, newBuildName, shipId } = this.state;
|
const { ship, buildName, newBuildName, shipId } = this.state;
|
||||||
|
|
||||||
// If this is a stock ship the code won't be set, so ensure that we have it
|
// If this is a stock ship the code won't be set, so ensure that we have it
|
||||||
const code = this.state.code || ship.toString();
|
const code = this.state.code || ship.compress();
|
||||||
|
|
||||||
Persist.saveBuild(shipId, newBuildName, code);
|
Persist.saveBuild(shipId, newBuildName, code);
|
||||||
this._updateRoute(shipId, newBuildName, code);
|
this._updateRoute(shipId, newBuildName, code);
|
||||||
@@ -497,39 +269,9 @@ export default class OutfittingPage extends Page {
|
|||||||
// Rebuild ship
|
// Rebuild ship
|
||||||
ship.buildWith(Ships[shipId].defaults);
|
ship.buildWith(Ships[shipId].defaults);
|
||||||
// Reset controls
|
// Reset controls
|
||||||
const code = ship.toString();
|
const code = ship.compress();
|
||||||
const {
|
|
||||||
sys,
|
|
||||||
eng,
|
|
||||||
wep,
|
|
||||||
mcSys,
|
|
||||||
mcEng,
|
|
||||||
mcWep,
|
|
||||||
boost,
|
|
||||||
fuel,
|
|
||||||
cargo,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
engagementRange
|
|
||||||
} = this._obtainControlFromCode(ship, code);
|
|
||||||
// Update state, and refresh the ship
|
// Update state, and refresh the ship
|
||||||
this.setState(
|
this._updateRoute(shipId, buildName, code);
|
||||||
{
|
|
||||||
sys,
|
|
||||||
eng,
|
|
||||||
wep,
|
|
||||||
mcSys,
|
|
||||||
mcEng,
|
|
||||||
mcWep,
|
|
||||||
boost,
|
|
||||||
fuel,
|
|
||||||
cargo,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
engagementRange
|
|
||||||
},
|
|
||||||
() => this._updateRoute(shipId, buildName, code)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -573,65 +315,22 @@ export default class OutfittingPage extends Page {
|
|||||||
* Called when the code for the ship has been updated, to synchronise the rest of the data
|
* Called when the code for the ship has been updated, to synchronise the rest of the data
|
||||||
*/
|
*/
|
||||||
_codeUpdated() {
|
_codeUpdated() {
|
||||||
const { code, ship, shipId, buildName } = this.state;
|
const { code, shipId, buildName } = this.state;
|
||||||
|
|
||||||
// Rebuild ship from the code
|
this.setState({
|
||||||
this.state.ship.buildFrom(code);
|
ship: new Ship(code),
|
||||||
|
}, () => this._updateRoute(shipId, buildName, code));
|
||||||
// Obtain controls from the code
|
|
||||||
const {
|
|
||||||
sys,
|
|
||||||
eng,
|
|
||||||
wep,
|
|
||||||
mcSys,
|
|
||||||
mcEng,
|
|
||||||
mcWep,
|
|
||||||
boost,
|
|
||||||
fuel,
|
|
||||||
cargo,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
engagementRange
|
|
||||||
} = this._obtainControlFromCode(ship, code);
|
|
||||||
// Update state, and refresh the route when complete
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
sys,
|
|
||||||
eng,
|
|
||||||
wep,
|
|
||||||
mcSys,
|
|
||||||
mcEng,
|
|
||||||
mcWep,
|
|
||||||
boost,
|
|
||||||
fuel,
|
|
||||||
cargo,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
engagementRange
|
|
||||||
},
|
|
||||||
() => this._updateRoute(shipId, buildName, code)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the ship has been updated, to set the code and then update accordingly
|
* Called when the ship has been updated, to set the code and then update accordingly
|
||||||
*/
|
*/
|
||||||
_shipUpdated() {
|
_shipUpdated() {
|
||||||
let { ship, shipId, buildName, cargo, fuel } = this.state;
|
let { ship, shipId, buildName } = this.state;
|
||||||
if (cargo > ship.cargoCapacity) {
|
const code = ship.compress();
|
||||||
cargo = ship.cargoCapacity;
|
|
||||||
}
|
|
||||||
if (fuel > ship.fuelCapacity) {
|
|
||||||
fuel = ship.fuelCapacity;
|
|
||||||
}
|
|
||||||
const code = this._fullCode(ship, fuel, cargo);
|
|
||||||
// Only update the state if this really has been updated
|
// Only update the state if this really has been updated
|
||||||
if (
|
if (this.state.code != code) {
|
||||||
this.state.code != code ||
|
this.setState({ code }, () =>
|
||||||
this.state.cargo != cargo ||
|
|
||||||
this.state.fuel != fuel
|
|
||||||
) {
|
|
||||||
this.setState({ code, cargo, fuel }, () =>
|
|
||||||
this._updateRoute(shipId, buildName, code)
|
this._updateRoute(shipId, buildName, code)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -747,29 +446,20 @@ export default class OutfittingPage extends Page {
|
|||||||
*/
|
*/
|
||||||
renderPage() {
|
renderPage() {
|
||||||
let state = this.state,
|
let state = this.state,
|
||||||
{ language, termtip, tooltip, sizeRatio, onWindowResize } = this.context,
|
{ language, termtip, tooltip, sizeRatio } = this.context,
|
||||||
{ translate, units, formats } = language,
|
{ translate } = language,
|
||||||
{
|
{
|
||||||
ship,
|
ship,
|
||||||
code,
|
code,
|
||||||
savedCode,
|
savedCode,
|
||||||
buildName,
|
buildName,
|
||||||
newBuildName,
|
newBuildName,
|
||||||
sys,
|
// opponent,
|
||||||
eng,
|
// opponentBuild,
|
||||||
wep,
|
// opponentSys,
|
||||||
mcSys,
|
// opponentEng,
|
||||||
mcEng,
|
// opponentWep,
|
||||||
mcWep,
|
// engagementRange
|
||||||
boost,
|
|
||||||
fuel,
|
|
||||||
cargo,
|
|
||||||
opponent,
|
|
||||||
opponentBuild,
|
|
||||||
opponentSys,
|
|
||||||
opponentEng,
|
|
||||||
opponentWep,
|
|
||||||
engagementRange
|
|
||||||
} = state,
|
} = state,
|
||||||
hide = tooltip.bind(null, null),
|
hide = tooltip.bind(null, null),
|
||||||
menu = this.props.currentMenu,
|
menu = this.props.currentMenu,
|
||||||
@@ -782,88 +472,88 @@ export default class OutfittingPage extends Page {
|
|||||||
code = ship.name + (code || '');
|
code = ship.name + (code || '');
|
||||||
|
|
||||||
// Markers are used to propagate state changes without requiring a deep comparison of the ship, as that takes a long time
|
// Markers are used to propagate state changes without requiring a deep comparison of the ship, as that takes a long time
|
||||||
const _sStr = ship.getStandardString();
|
// const _sStr = ship.getStandardString();
|
||||||
const _iStr = ship.getInternalString();
|
// const _iStr = ship.getInternalString();
|
||||||
const _hStr = ship.getHardpointsString();
|
// const _hStr = ship.getHardpointsString();
|
||||||
const _pStr = `${ship.getPowerEnabledString()}${ship.getPowerPrioritiesString()}`;
|
// const _pStr = `${ship.getPowerEnabledString()}${ship.getPowerPrioritiesString()}`;
|
||||||
const _mStr = ship.getModificationsString();
|
// const _mStr = ship.getModificationsString();
|
||||||
|
|
||||||
const standardSlotMarker = `${ship.name}${_sStr}${_pStr}${_mStr}${
|
// const standardSlotMarker = `${ship.name}${_sStr}${_pStr}${_mStr}${
|
||||||
ship.ladenMass
|
// ship.ladenMass
|
||||||
}${cargo}${fuel}`;
|
// }${cargo}${fuel}`;
|
||||||
const internalSlotMarker = `${ship.name}${_iStr}${_pStr}${_mStr}`;
|
// const internalSlotMarker = `${ship.name}${_iStr}${_pStr}${_mStr}`;
|
||||||
const hardpointsSlotMarker = `${ship.name}${_hStr}${_pStr}${_mStr}`;
|
// const hardpointsSlotMarker = `${ship.name}${_hStr}${_pStr}${_mStr}`;
|
||||||
const boostMarker = `${ship.canBoost(cargo, fuel)}`;
|
// const boostMarker = `${ship.canBoost(cargo, fuel)}`;
|
||||||
const shipSummaryMarker = `${
|
// const shipSummaryMarker = `${
|
||||||
ship.name
|
// ship.name
|
||||||
}${_sStr}${_iStr}${_hStr}${_pStr}${_mStr}${ship.ladenMass}${cargo}${fuel}`;
|
// }${_sStr}${_iStr}${_hStr}${_pStr}${_mStr}${ship.ladenMass}${cargo}${fuel}`;
|
||||||
|
|
||||||
const requirements = Ships[ship.id].requirements;
|
// const requirements = Ships[ship.id].requirements;
|
||||||
let requirementElements = [];
|
// let requirementElements = [];
|
||||||
/**
|
// /**
|
||||||
* Render the requirements for a ship / etc
|
// * Render the requirements for a ship / etc
|
||||||
* @param {string} className Class names
|
// * @param {string} className Class names
|
||||||
* @param {string} textKey The key for translating
|
// * @param {string} textKey The key for translating
|
||||||
* @param {String} tooltipTextKey Tooltip key
|
// * @param {String} tooltipTextKey Tooltip key
|
||||||
*/
|
// */
|
||||||
function renderRequirement(className, textKey, tooltipTextKey) {
|
// function renderRequirement(className, textKey, tooltipTextKey) {
|
||||||
if (textKey.startsWith('empire') || textKey.startsWith('federation')) {
|
// if (textKey.startsWith('empire') || textKey.startsWith('federation')) {
|
||||||
requirementElements.push(
|
// requirementElements.push(
|
||||||
<div
|
// <div
|
||||||
key={textKey}
|
// key={textKey}
|
||||||
className={className}
|
// className={className}
|
||||||
onMouseEnter={termtip.bind(null, tooltipTextKey)}
|
// onMouseEnter={termtip.bind(null, tooltipTextKey)}
|
||||||
onMouseLeave={hide}
|
// onMouseLeave={hide}
|
||||||
>
|
// >
|
||||||
<a
|
// <a
|
||||||
href={
|
// href={
|
||||||
textKey.startsWith('empire') ?
|
// textKey.startsWith('empire') ?
|
||||||
'http://elite-dangerous.wikia.com/wiki/Empire/Ranks' :
|
// 'http://elite-dangerous.wikia.com/wiki/Empire/Ranks' :
|
||||||
'http://elite-dangerous.wikia.com/wiki/Federation/Ranks'
|
// 'http://elite-dangerous.wikia.com/wiki/Federation/Ranks'
|
||||||
}
|
// }
|
||||||
target="_blank"
|
// target="_blank"
|
||||||
rel="noopener"
|
// rel="noopener"
|
||||||
>
|
// >
|
||||||
{translate(textKey)}
|
// {translate(textKey)}
|
||||||
</a>
|
// </a>
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
} else {
|
// } else {
|
||||||
requirementElements.push(
|
// requirementElements.push(
|
||||||
<div
|
// <div
|
||||||
key={textKey}
|
// key={textKey}
|
||||||
className={className}
|
// className={className}
|
||||||
onMouseEnter={termtip.bind(null, tooltipTextKey)}
|
// onMouseEnter={termtip.bind(null, tooltipTextKey)}
|
||||||
onMouseLeave={hide}
|
// onMouseLeave={hide}
|
||||||
>
|
// >
|
||||||
{translate(textKey)}
|
// {translate(textKey)}
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (requirements) {
|
// if (requirements) {
|
||||||
requirements.federationRank &&
|
// requirements.federationRank &&
|
||||||
renderRequirement(
|
// renderRequirement(
|
||||||
'federation',
|
// 'federation',
|
||||||
'federation rank ' + requirements.federationRank,
|
// 'federation rank ' + requirements.federationRank,
|
||||||
'federation rank required'
|
// 'federation rank required'
|
||||||
);
|
// );
|
||||||
requirements.empireRank &&
|
// requirements.empireRank &&
|
||||||
renderRequirement(
|
// renderRequirement(
|
||||||
'empire',
|
// 'empire',
|
||||||
'empire rank ' + requirements.empireRank,
|
// 'empire rank ' + requirements.empireRank,
|
||||||
'empire rank required'
|
// 'empire rank required'
|
||||||
);
|
// );
|
||||||
requirements.horizons &&
|
// requirements.horizons &&
|
||||||
renderRequirement('horizons', 'horizons', 'horizons required');
|
// renderRequirement('horizons', 'horizons', 'horizons required');
|
||||||
requirements.horizonsEarlyAdoption &&
|
// requirements.horizonsEarlyAdoption &&
|
||||||
renderRequirement(
|
// renderRequirement(
|
||||||
'horizons',
|
// 'horizons',
|
||||||
'horizons early adoption',
|
// 'horizons early adoption',
|
||||||
'horizons early adoption required'
|
// 'horizons early adoption required'
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -872,8 +562,8 @@ export default class OutfittingPage extends Page {
|
|||||||
style={{ fontSize: sizeRatio * 0.9 + 'em' }}
|
style={{ fontSize: sizeRatio * 0.9 + 'em' }}
|
||||||
>
|
>
|
||||||
<div id="overview">
|
<div id="overview">
|
||||||
<h1>{ship.name}</h1>
|
<h1>{ship.getShipType()}</h1>
|
||||||
<div id="requirements">{requirementElements}</div>
|
{/* <div id="requirements">{requirementElements}</div> */}
|
||||||
<div id="build">
|
<div id="build">
|
||||||
<input
|
<input
|
||||||
value={newBuildName || ''}
|
value={newBuildName || ''}
|
||||||
@@ -933,7 +623,7 @@ export default class OutfittingPage extends Page {
|
|||||||
<Download className="lg" />
|
<Download className="lg" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={this._eddbShoppingList}
|
// onClick={this._eddbShoppingList}
|
||||||
onMouseOver={termtip.bind(null, 'PHRASE_SHOPPING_LIST')}
|
onMouseOver={termtip.bind(null, 'PHRASE_SHOPPING_LIST')}
|
||||||
onMouseOut={hide}
|
onMouseOut={hide}
|
||||||
>
|
>
|
||||||
@@ -954,7 +644,7 @@ export default class OutfittingPage extends Page {
|
|||||||
<OrbisIcon className="lg" />
|
<OrbisIcon className="lg" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={this._genShoppingList}
|
// onClick={this._genShoppingList}
|
||||||
onMouseOver={termtip.bind(null, 'PHRASE_SHOPPING_MATS')}
|
onMouseOver={termtip.bind(null, 'PHRASE_SHOPPING_MATS')}
|
||||||
onMouseOut={hide}
|
onMouseOut={hide}
|
||||||
>
|
>
|
||||||
@@ -964,22 +654,13 @@ export default class OutfittingPage extends Page {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main tables */}
|
{/* Main tables */}
|
||||||
<ShipSummaryTable
|
{/* <ShipSummaryTable
|
||||||
ship={ship}
|
ship={ship}
|
||||||
fuel={fuel}
|
|
||||||
cargo={cargo}
|
|
||||||
marker={shipSummaryMarker}
|
marker={shipSummaryMarker}
|
||||||
pips={{
|
/> */}
|
||||||
sys: this.state.sys,
|
|
||||||
wep: this.state.wep,
|
|
||||||
eng: this.state.eng
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<StandardSlotSection
|
<StandardSlotSection
|
||||||
ship={ship}
|
ship={ship}
|
||||||
fuel={fuel}
|
// code={standardSlotMarker}
|
||||||
cargo={cargo}
|
|
||||||
code={standardSlotMarker}
|
|
||||||
onChange={shipUpdated}
|
onChange={shipUpdated}
|
||||||
onCargoChange={this._cargoUpdated}
|
onCargoChange={this._cargoUpdated}
|
||||||
onFuelChange={this._fuelUpdated}
|
onFuelChange={this._fuelUpdated}
|
||||||
@@ -988,7 +669,7 @@ export default class OutfittingPage extends Page {
|
|||||||
/>
|
/>
|
||||||
<InternalSlotSection
|
<InternalSlotSection
|
||||||
ship={ship}
|
ship={ship}
|
||||||
code={internalSlotMarker}
|
// code={internalSlotMarker}
|
||||||
onChange={shipUpdated}
|
onChange={shipUpdated}
|
||||||
onCargoChange={this._cargoUpdated}
|
onCargoChange={this._cargoUpdated}
|
||||||
onFuelChange={this._fuelUpdated}
|
onFuelChange={this._fuelUpdated}
|
||||||
@@ -997,7 +678,7 @@ export default class OutfittingPage extends Page {
|
|||||||
/>
|
/>
|
||||||
<HardpointSlotSection
|
<HardpointSlotSection
|
||||||
ship={ship}
|
ship={ship}
|
||||||
code={hardpointsSlotMarker}
|
// code={hardpointsSlotMarker}
|
||||||
onChange={shipUpdated}
|
onChange={shipUpdated}
|
||||||
onCargoChange={this._cargoUpdated}
|
onCargoChange={this._cargoUpdated}
|
||||||
onFuelChange={this._fuelUpdated}
|
onFuelChange={this._fuelUpdated}
|
||||||
@@ -1006,7 +687,7 @@ export default class OutfittingPage extends Page {
|
|||||||
/>
|
/>
|
||||||
<UtilitySlotSection
|
<UtilitySlotSection
|
||||||
ship={ship}
|
ship={ship}
|
||||||
code={hardpointsSlotMarker}
|
// code={hardpointsSlotMarker}
|
||||||
onChange={shipUpdated}
|
onChange={shipUpdated}
|
||||||
onCargoChange={this._cargoUpdated}
|
onCargoChange={this._cargoUpdated}
|
||||||
onFuelChange={this._fuelUpdated}
|
onFuelChange={this._fuelUpdated}
|
||||||
@@ -1015,7 +696,7 @@ export default class OutfittingPage extends Page {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Control of ship and opponent */}
|
{/* Control of ship and opponent */}
|
||||||
<div className="group quarter">
|
{/* <div className="group quarter">
|
||||||
<div className="group half">
|
<div className="group half">
|
||||||
<h2 style={{ verticalAlign: 'middle', textAlign: 'left' }}>
|
<h2 style={{ verticalAlign: 'middle', textAlign: 'left' }}>
|
||||||
{translate('ship control')}
|
{translate('ship control')}
|
||||||
@@ -1044,7 +725,6 @@ export default class OutfittingPage extends Page {
|
|||||||
<div className="group quarter">
|
<div className="group quarter">
|
||||||
<Fuel
|
<Fuel
|
||||||
fuelCapacity={ship.fuelCapacity}
|
fuelCapacity={ship.fuelCapacity}
|
||||||
fuel={fuel}
|
|
||||||
onChange={this._fuelUpdated}
|
onChange={this._fuelUpdated}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1052,7 +732,6 @@ export default class OutfittingPage extends Page {
|
|||||||
{ship.cargoCapacity > 0 ? (
|
{ship.cargoCapacity > 0 ? (
|
||||||
<Cargo
|
<Cargo
|
||||||
cargoCapacity={ship.cargoCapacity}
|
cargoCapacity={ship.cargoCapacity}
|
||||||
cargo={cargo}
|
|
||||||
onChange={this._cargoUpdated}
|
onChange={this._cargoUpdated}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
@@ -1077,10 +756,10 @@ export default class OutfittingPage extends Page {
|
|||||||
engagementRange={engagementRange}
|
engagementRange={engagementRange}
|
||||||
onChange={this._engagementRangeUpdated}
|
onChange={this._engagementRangeUpdated}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div> */}
|
||||||
|
|
||||||
{/* Tabbed subpages */}
|
{/* Tabbed subpages */}
|
||||||
<OutfittingSubpages
|
{/* <OutfittingSubpages
|
||||||
ship={ship}
|
ship={ship}
|
||||||
code={code}
|
code={code}
|
||||||
buildName={buildName}
|
buildName={buildName}
|
||||||
@@ -1097,7 +776,7 @@ export default class OutfittingPage extends Page {
|
|||||||
opponentSys={opponentSys}
|
opponentSys={opponentSys}
|
||||||
opponentEng={opponentEng}
|
opponentEng={opponentEng}
|
||||||
opponentWep={opponentWep}
|
opponentWep={opponentWep}
|
||||||
/>
|
/> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Page from './Page';
|
import Page from './Page';
|
||||||
import { Ships } from 'coriolis-data/dist';
|
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
import Ship from '../shipyard/Ship';
|
import { Factory } from 'ed-forge';
|
||||||
import * as ModuleUtils from '../shipyard/ModuleUtils';
|
import * as ModuleUtils from '../shipyard/ModuleUtils';
|
||||||
import { SizeMap } from '../shipyard/Constants';
|
import { SizeMap } from '../shipyard/Constants';
|
||||||
import Link from '../components/Link';
|
import Link from '../components/Link';
|
||||||
|
|
||||||
/**
|
|
||||||
* Counts the hardpoints by class/size
|
|
||||||
* @param {Object} slot Hardpoint Slot model
|
|
||||||
*/
|
|
||||||
function countHp(slot) {
|
|
||||||
this.hp[slot.maxClass]++;
|
|
||||||
this.hpCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts the internal slots and aggregated properties
|
* Counts the internal slots and aggregated properties
|
||||||
* @param {Object} slot Internal Slots
|
* @param {Object} slot Internal Slots
|
||||||
@@ -53,50 +43,55 @@ function countInt(slot) {
|
|||||||
/**
|
/**
|
||||||
* Generate Ship summary and aggregated properties
|
* Generate Ship summary and aggregated properties
|
||||||
* @param {String} shipId Ship Id
|
* @param {String} shipId Ship Id
|
||||||
* @param {Object} shipData Ship Default Data
|
|
||||||
* @return {Object} Ship summary and aggregated properties
|
* @return {Object} Ship summary and aggregated properties
|
||||||
*/
|
*/
|
||||||
function shipSummary(shipId, shipData) {
|
function shipSummary(shipId) {
|
||||||
|
// Build Ship
|
||||||
|
let ship = Factory.newShip(shipId);
|
||||||
|
|
||||||
let summary = {
|
let summary = {
|
||||||
id: shipId,
|
id: shipId,
|
||||||
hpCount: 0,
|
hpCount: 0,
|
||||||
intCount: 0,
|
intCount: 0,
|
||||||
beta: shipData.beta,
|
|
||||||
maxCargo: 0,
|
maxCargo: 0,
|
||||||
maxPassengers: 0,
|
maxPassengers: 0,
|
||||||
hp: [0, 0, 0, 0, 0], // Utility, Small, Medium, Large, Huge
|
hp: [0, 0, 0, 0, 0], // Utility, Small, Medium, Large, Huge
|
||||||
int: [0, 0, 0, 0, 0, 0, 0, 0], // Sizes 1 - 8
|
int: [0, 0, 0, 0, 0, 0, 0, 0], // Sizes 1 - 8
|
||||||
standard: shipData.slots.standard,
|
standard: ship.readMeta('coreSizes'),
|
||||||
agility:
|
agility:
|
||||||
shipData.properties.pitch +
|
ship.getBaseProperty('pitch') +
|
||||||
shipData.properties.yaw +
|
ship.getBaseProperty('yaw') +
|
||||||
shipData.properties.roll
|
ship.getBaseProperty('roll')
|
||||||
};
|
};
|
||||||
Object.assign(summary, shipData.properties);
|
|
||||||
let ship = new Ship(shipId, shipData.properties, shipData.slots);
|
|
||||||
|
|
||||||
// Build Ship
|
// Count Hardpoints by class
|
||||||
ship.buildWith(shipData.defaults); // Populate with stock/default components
|
ship.getHardpoints(undefined, true).forEach(hardpoint => {
|
||||||
ship.hardpoints.forEach(countHp.bind(summary)); // Count Hardpoints by class
|
summary.hp[hardpoint.getSize()]++;
|
||||||
ship.internal.forEach(countInt.bind(summary)); // Count Internal Compartments by class
|
summary.hpCount++;
|
||||||
summary.retailCost = ship.totalCost; // Record Stock/Default/retail cost
|
});
|
||||||
ship.optimizeMass({ pd: '1D' }); // Optimize Mass with 1D PD for maximum possible jump range
|
// Count Internal Compartments by class
|
||||||
summary.maxJumpRange = ship.unladenRange; // Record Jump Range
|
ship.getInternals(undefined, true).forEach(internal => {
|
||||||
|
summary.int[internal.getSize()]++;
|
||||||
|
summary.intCount++;
|
||||||
|
});
|
||||||
|
summary.retailCost = ship.readMeta('retailCost'); // Record Stock/Default/retail cost
|
||||||
|
// ship.optimizeMass({ pd: '1D' }); // Optimize Mass with 1D PD for maximum possible jump range
|
||||||
|
summary.maxJumpRange = -1; // ship.unladenRange; // Record Jump Range
|
||||||
|
|
||||||
// Best thrusters
|
// Best thrusters
|
||||||
let th;
|
// let th;
|
||||||
if (ship.standard[1].maxClass === 3) {
|
// if (ship.standard[1].maxClass === 3) {
|
||||||
th = 'tz';
|
// th = 'tz';
|
||||||
} else if (ship.standard[1].maxClass === 2) {
|
// } else if (ship.standard[1].maxClass === 2) {
|
||||||
th = 'u0';
|
// th = 'u0';
|
||||||
} else {
|
// } else {
|
||||||
th = ship.standard[1].maxClass + 'A';
|
// th = ship.standard[1].maxClass + 'A';
|
||||||
}
|
// }
|
||||||
|
|
||||||
ship.optimizeMass({ th, fsd: '2D', ft: '1C' }); // Optmize mass with Max Thrusters
|
// ship.optimizeMass({ th, fsd: '2D', ft: '1C' }); // Optmize mass with Max Thrusters
|
||||||
summary.topSpeed = ship.topSpeed;
|
summary.topSpeed = -1; // ship.topSpeed;
|
||||||
summary.topBoost = ship.topBoost;
|
summary.topBoost = -1; // ship.topBoost;
|
||||||
summary.baseArmour = ship.armour;
|
summary.baseArmour = -1; // ship.armour;
|
||||||
|
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
@@ -117,8 +112,8 @@ export default class ShipyardPage extends Page {
|
|||||||
|
|
||||||
if (!ShipyardPage.cachedShipSummaries) {
|
if (!ShipyardPage.cachedShipSummaries) {
|
||||||
ShipyardPage.cachedShipSummaries = [];
|
ShipyardPage.cachedShipSummaries = [];
|
||||||
for (let s in Ships) {
|
for (let s of Factory.getAllShipTypes()) {
|
||||||
ShipyardPage.cachedShipSummaries.push(shipSummary(s, Ships[s]));
|
ShipyardPage.cachedShipSummaries.push(shipSummary(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +330,7 @@ export default class ShipyardPage extends Page {
|
|||||||
onClick={() => this._toggleCompare(s.id)}
|
onClick={() => this._toggleCompare(s.id)}
|
||||||
>
|
>
|
||||||
<td className="le">
|
<td className="le">
|
||||||
<Link href={'/outfit/' + s.id}>{s.name} {s.beta === true ? '(Beta)' : null}</Link>
|
<Link href={'/outfit/' + s.id}>{s.id} {s.beta === true ? '(Beta)' : null}</Link>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -66,12 +66,10 @@ export function specialToolTip(translate, blueprint, grp, m, specialName) {
|
|||||||
* Generate a tooltip with details of a blueprint's effects
|
* Generate a tooltip with details of a blueprint's effects
|
||||||
* @param {Object} translate The translate object
|
* @param {Object} translate The translate object
|
||||||
* @param {Object} blueprint The blueprint at the required grade
|
* @param {Object} blueprint The blueprint at the required grade
|
||||||
* @param {Array} engineers The engineers supplying this blueprint
|
|
||||||
* @param {string} grp The group of the module
|
|
||||||
* @param {Object} m The module to compare with
|
* @param {Object} m The module to compare with
|
||||||
* @returns {Object} The react components
|
* @returns {Object} The react components
|
||||||
*/
|
*/
|
||||||
export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
export function blueprintTooltip(translate, blueprint, m) {
|
||||||
const effects = [];
|
const effects = [];
|
||||||
if (!blueprint || !blueprint.features) {
|
if (!blueprint || !blueprint.features) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -105,7 +103,7 @@ export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
|||||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature}>
|
<tr key={feature}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature)}</td>
|
||||||
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
||||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||||
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
||||||
@@ -115,7 +113,7 @@ export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
|||||||
// We do not have a module, no value
|
// We do not have a module, no value
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature}>
|
<tr key={feature}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature)}</td>
|
||||||
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
||||||
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -144,7 +142,7 @@ export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
|||||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature}>
|
<tr key={feature}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature)}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
@@ -175,7 +173,7 @@ export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
|||||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature}>
|
<tr key={feature}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature)}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
@@ -200,17 +198,18 @@ export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let engineersList;
|
let engineersList = [];
|
||||||
if (engineers) {
|
// TODO:
|
||||||
engineersList = [];
|
// if (engineers) {
|
||||||
for (const engineer of engineers) {
|
// engineersList = [];
|
||||||
engineersList.push(
|
// for (const engineer of engineers) {
|
||||||
<tr key={engineer}>
|
// engineersList.push(
|
||||||
<td style={{ textAlign: 'left' }}>{engineer}</td>
|
// <tr key={engineer}>
|
||||||
</tr>
|
// <td style={{ textAlign: 'left' }}>{engineer}</td>
|
||||||
);
|
// </tr>
|
||||||
}
|
// );
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -285,7 +284,7 @@ export function isValueBeneficial(feature, value) {
|
|||||||
* Is the change as shown beneficial?
|
* Is the change as shown beneficial?
|
||||||
* @param {string} feature The name of the feature
|
* @param {string} feature The name of the feature
|
||||||
* @param {number} value The value of the feature as percentage change
|
* @param {number} value The value of the feature as percentage change
|
||||||
* @returns True if the value is beneficial
|
* @returns {boolean} True if the value is beneficial
|
||||||
*/
|
*/
|
||||||
export function isChangeValueBeneficial(feature, value) {
|
export function isChangeValueBeneficial(feature, value) {
|
||||||
let changeHigherBetter = STATS_FORMATTING[feature].higherbetter;
|
let changeHigherBetter = STATS_FORMATTING[feature].higherbetter;
|
||||||
|
|||||||
Reference in New Issue
Block a user