@@ -140,8 +144,8 @@ export default class ShipSummaryTable extends TranslatedComponent {
{int(ship.shieldThermRes * 100) + '%'}
{int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.absolute.total : 0)}
{int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.explosive.total : 0)}
- {int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.kinetic.total : 0 )}
- {int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.thermal.total : 0 )}
+ {int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.kinetic.total : 0)}
+ {int(sgMetrics && sgMetrics.generator ? sgMetrics.total / sgMetrics.thermal.total : 0)}
{sgMetrics && sgMetrics.recover ? formats.time(sgMetrics.recover) : 0}
{sgMetrics && sgMetrics.recharge ? formats.time(sgMetrics.recharge) : 0}
diff --git a/src/app/components/Slider.jsx b/src/app/components/Slider.jsx
index a1efbf94..7d6b5583 100644
--- a/src/app/components/Slider.jsx
+++ b/src/app/components/Slider.jsx
@@ -17,12 +17,12 @@ export default class Slider extends React.Component {
static propTypes = {
axis: PropTypes.bool,
- axisUnit: PropTypes.string,//units (T, M, etc.)
+ axisUnit: PropTypes.string,// units (T, M, etc.)
max: PropTypes.number,
min: PropTypes.number,
onChange: PropTypes.func.isRequired,// function which determins percent value
onResize: PropTypes.func,
- percent: PropTypes.number.isRequired,//value of slider
+ percent: PropTypes.number.isRequired,// value of slider
scale: PropTypes.number
};
@@ -51,7 +51,6 @@ export default class Slider extends React.Component {
* @param {SyntheticEvent} event Event
*/
_down(event) {
-
let rect = event.currentTarget.getBoundingClientRect();
this.left = rect.left;
this.width = rect.width;
@@ -95,28 +94,27 @@ export default class Slider extends React.Component {
case 'Enter':
event.preventDefault();
this.sliderInputBox._setDisplay('block');
- //this.enterTimer = setTimeout(() => this.sliderInputBox.sliderVal.focus(), 10);
+ // this.enterTimer = setTimeout(() => this.sliderInputBox.sliderVal.focus(), 10);
return;
default:
return;
}
-
}
/**
* Key down handler
* increment slider position by +/- 1 when right/left arrow key is pressed or held
- * @param {Event} event
+ * @param {Event} event The key down event.
*/
_keydown(event) {
-
+ let newVal;
switch (event.key) {
case 'ArrowRight':
- var newVal = this.props.percent*this.props.max + 1;
- if (newVal <= this.props.max) this.props.onChange(newVal/this.props.max);
+ newVal = this.props.percent * this.props.max + 1;
+ if (newVal <= this.props.max) this.props.onChange(newVal / this.props.max);
return;
case 'ArrowLeft':
- var newVal = this.props.percent*this.props.max - 1;
- if (newVal >= 0) this.props.onChange(newVal/this.props.max);
+ newVal = this.props.percent * this.props.max - 1;
+ if (newVal >= 0) this.props.onChange(newVal / this.props.max);
return;
default:
return;
@@ -126,12 +124,16 @@ export default class Slider extends React.Component {
/**
* Touch start handler
* @param {Event} event DOM Event
- *
+ *
*/
_touchstart(event) {
this.touchStartTimer = setTimeout(() => this.sliderInputBox._setDisplay('block'), 1500);
}
+ /**
+ * Touch end handler
+ * @param {Event} event DOM Event
+ */
_touchend(event) {
this.sliderInputBox.sliderVal.focus();
clearTimeout(this.touchStartTimer);
@@ -181,7 +183,6 @@ export default class Slider extends React.Component {
*/
componentDidMount() {
this._updateDimensions();
-
}
/**
@@ -215,7 +216,7 @@ export default class Slider extends React.Component {
let width = outerWidth - (margin * 2);
let pctPos = width * this.props.percent;
- return this.node = node} tabIndex="0">
@@ -233,7 +234,7 @@ export default class Slider extends React.Component {
axisUnit={this.props.axisUnit}
scale={this.props.scale}
max={this.props.max}
-
+
/>
;
}
@@ -242,100 +243,140 @@ export default class Slider extends React.Component {
/**
* New component to add keyboard support for sliders - works on all devices (desktop, iOS, Android)
**/
- class TextInputBox extends React.Component {
+class TextInputBox extends React.Component {
static propTypes = {
- axisUnit: PropTypes.string,//units (T, M, etc.)
+ axisUnit: PropTypes.string,// units (T, M, etc.)
max: PropTypes.number,
onChange: PropTypes.func.isRequired,// function which determins percent value
- percent: PropTypes.number.isRequired,//value of slider
+ percent: PropTypes.number.isRequired,// value of slider
scale: PropTypes.number
};
+
+ /**
+ * Constructor for TextInputBox
+ * @param {Object} props The props
+ */
constructor(props) {
super(props);
- this._handleFocus = this._handleFocus.bind(this);
- this._handleBlur = this._handleBlur.bind(this);
- this._handleChange = this._handleChange.bind(this);
- //this._keydown = this._keydown.bind(this);
- this._keyup = this._keyup.bind(this);
- this.state = this._getInitialState();
- this.percent = this.props.percent;
- this.max = this.props.max;
- this.state.inputValue = this.percent * this.max;
- }
+ this._handleFocus = this._handleFocus.bind(this);
+ this._handleBlur = this._handleBlur.bind(this);
+ this._handleChange = this._handleChange.bind(this);
+ // this._keydown = this._keydown.bind(this);
+ this._keyup = this._keyup.bind(this);
+ this.state = this._getInitialState();
+ this.percent = this.props.percent;
+ this.max = this.props.max;
+ this.setState({ inputValue: this.percent * this.max });
+ }
- componentWillReceiveProps(nextProps, nextState) {
- var nextValue = nextProps.percent * nextProps.max;
+ /**
+ * Slider willrecieveprops
+ * @param {Object} nextProps The next props
+ * @param {Object} nextState The next state
+ */
+ componentWillReceiveProps(nextProps, nextState) {
+ let nextValue = nextProps.percent * nextProps.max;
// See https://stackoverflow.com/questions/32414308/updating-state-on-props-change-in-react-form
- if (nextValue !== this.state.inputValue && nextValue <= nextProps.max) {
- this.setState({ inputValue: nextValue });
- }
+ if (nextValue !== this.state.inputValue && nextValue <= nextProps.max) {
+ this.setState({ inputValue: nextValue });
}
- componentDidUpdate(prevProps, prevState) {
+ }
- if (prevState.divStyle.display == 'none' && this.state.divStyle.display == 'block') {
- this.enterTimer = setTimeout(() => this.sliderVal.focus(), 10);
- }
-
- if (prevProps.max !== this.props.max && this.state.inputValue > this.props.max) {
+ /**
+ * Slider Component did update
+ * @param {Object} prevProps The prev props
+ * @param {Object} prevState The prev state
+ */
+ componentDidUpdate(prevProps, prevState) {
+ if (prevState.divStyle.display == 'none' && this.state.divStyle.display == 'block') {
+ this.enterTimer = setTimeout(() => this.sliderVal.focus(), 10);
+ }
+
+ if (prevProps.max !== this.props.max && this.state.inputValue > this.props.max) {
// they chose a different module
- this.setState({ inputValue: this.props.max });
- }
-
- if (this.state.inputValue != prevState.inputValue && prevProps.max == this.props.max) {
- this.props.onChange(this.state.inputValue/this.props.max);
- }
-
+ this.setState({ inputValue: this.props.max });
}
- _getInitialState() {
- return {
- divStyle: {display:'none'},
- inputStyle: {width:'4em'},
- labelStyle: {marginLeft: '.1em'},
- maxLength:5,
- size:5,
- min:0,
- tabIndex:-1,
- type:'number',
- readOnly: true
- }
+ if (this.state.inputValue != prevState.inputValue && prevProps.max == this.props.max) {
+ this.props.onChange(this.state.inputValue / this.props.max);
}
+ }
- _setDisplay(val) {
- this.setState({
- divStyle: {display:val}
- });
- }
+ /**
+ * Get the initial state.
+ * @returns {{divStyle: {display: string}, inputStyle: {width: string}, labelStyle: {marginLeft: string}, maxLength: number, size: number, min: number, tabIndex: number, type: string, readOnly: boolean}} Initial state.
+ * @private
+ */
+ _getInitialState() {
+ return {
+ divStyle: { display:'none' },
+ inputStyle: { width:'4em' },
+ labelStyle: { marginLeft: '.1em' },
+ maxLength:5,
+ size:5,
+ min:0,
+ tabIndex:-1,
+ type:'number',
+ readOnly: true
+ };
+ }
- _handleFocus() {
- this.setState({
- inputValue:this._getValue()
- });
- }
+ /**
+ * Set display style
+ * @param {string} val The display CSS code.
+ * @private
+ */
+ _setDisplay(val) {
+ this.setState({
+ divStyle: { display:val }
+ });
+ }
- _handleBlur() {
- this._setDisplay('none');
- if (this.state.inputValue !== '') {
- this.props.onChange(this.state.inputValue/this.props.max);
- } else {
- this.state.inputValue = this.props.percent * this.props.max;
- }
-
- }
+ /**
+ * Focus handler
+ * @private
+ */
+ _handleFocus() {
+ this.setState({
+ inputValue:this._getValue()
+ });
+ }
- _getValue() {
- return this.state.inputValue;
+ /**
+ * Handles blurring
+ */
+ _handleBlur() {
+ this._setDisplay('none');
+ if (this.state.inputValue !== '') {
+ this.props.onChange(this.state.inputValue / this.props.max);
+ } else {
+ this.setState({ inputValue: this.props.percent * this.props.max });
}
+ }
- _handleChange(event) {
- if (event.target.value < 0) {
- this.setState({inputValue: 0});
- } else if (event.target.value <= this.props.max) {
- this.setState({inputValue: event.target.value});
- } else {
- this.setState({inputValue: this.props.max});
- }
+ /**
+ * Get inputValue
+ * @returns {number|Number|*} inputValue
+ * @private
+ */
+ _getValue() {
+ return this.state.inputValue;
+ }
+
+ /**
+ * Handle changes
+ * @param {Event} event DOM Event
+ * @private
+ */
+ _handleChange(event) {
+ if (event.target.value < 0) {
+ this.setState({ inputValue: 0 });
+ } else if (event.target.value <= this.props.max) {
+ this.setState({ inputValue: event.target.value });
+ } else {
+ this.setState({ inputValue: this.props.max });
}
+ }
/**
* Key up handler for input field.
@@ -350,12 +391,15 @@ export default class Slider extends React.Component {
default:
return;
}
-
}
- render() {
- let { axisUnit, onChange, percent, scale } = this.props;
- return {this._handleBlur()}} onFocus={() => {this._handleFocus()}} type={this.state.type} ref={(ip) => this.sliderVal = ip}/>{this.props.axisUnit}
;
- }
+ /**
+ * JSX Render handler
+ * @returns {*} Slider
+ */
+ render() {
+ let { axisUnit, onChange, percent, scale } = this.props;
+ return {this._handleBlur();}} onFocus={() => {this._handleFocus();}} type={this.state.type} ref={(ip) => this.sliderVal = ip}/>{this.props.axisUnit}
;
+ }
}
diff --git a/src/app/components/Slot.jsx b/src/app/components/Slot.jsx
index c8b4c32f..206a06d3 100644
--- a/src/app/components/Slot.jsx
+++ b/src/app/components/Slot.jsx
@@ -85,13 +85,13 @@ export default class Slot extends TranslatedComponent {
*/
_keyDown(event) {
if (event.key == 'Enter') {
- if(event.target.className == 'r') {
- console.log("Slot: Enter key pressed on mod icon");
- this._toggleModifications();
- } else {
- console.log("Slot: Enter key pressed on: %O", event.target);
- }
- this.props.onOpen(event);
+ if(event.target.className == 'r') {
+ console.log('Slot: Enter key pressed on mod icon');
+ this._toggleModifications();
+ } else {
+ console.log('Slot: Enter key pressed on: %O', event.target);
+ }
+ this.props.onOpen(event);
}
}
/**
diff --git a/src/app/components/StandardSlot.jsx b/src/app/components/StandardSlot.jsx
index cfca8530..663a25b3 100644
--- a/src/app/components/StandardSlot.jsx
+++ b/src/app/components/StandardSlot.jsx
@@ -40,12 +40,17 @@ export default class StandardSlot extends TranslatedComponent {
this.slotDiv = null;
}
- _keyDown(event) {
+ /**
+ * Fired on key down
+ * @param {KeyboardEvent} event The keydown event
+ * @private
+ */
+ _keyDown(event) {
if (event.key == 'Enter') {
- if(event.target.className == 'r') {
- this._toggleModifications();
- }
- this.props.onOpen(event);
+ if(event.target.className == 'r') {
+ this._toggleModifications();
+ }
+ this.props.onOpen(event);
}
}
@@ -151,7 +156,6 @@ export default class StandardSlot extends TranslatedComponent {
* Toggle the modifications flag when selecting the modifications icon
*/
_toggleModifications() {
-
this._modificationsSelected = !this._modificationsSelected;
}
}
diff --git a/src/app/pages/OutfittingPage.jsx b/src/app/pages/OutfittingPage.jsx
index 5b6d5a61..afb7df89 100644
--- a/src/app/pages/OutfittingPage.jsx
+++ b/src/app/pages/OutfittingPage.jsx
@@ -554,17 +554,23 @@ export default class OutfittingPage extends Page {
const shipSummaryMarker = `${ship.name}${_sStr}${_iStr}${_hStr}${_pStr}${_mStr}${ship.ladenMass}${cargo}${fuel}`;
const requirements = Ships[ship.id].requirements;
- var requirementElements = [];
+ let requirementElements = [];
+ /**
+ * Render the requirements for a ship / etc
+ * @param {string} className Class names
+ * @param {string} textKey The key for translating
+ * @param {String} tooltipTextKey Tooltip key
+ */
function renderRequirement(className, textKey, tooltipTextKey) {
- requirementElements.push();
+ requirementElements.push();
}
if (requirements) {
requirements.federationRank && renderRequirement('federation', 'federation rank ' + requirements.federationRank, 'federation rank required');
requirements.empireRank && renderRequirement('empire', 'empire rank ' + requirements.empireRank, 'empire rank required');
requirements.horizons && renderRequirement('horizons', 'horizons', 'horizons required');
- requirements.horizonsEarlyAdoption && renderRequirement('horizons', 'horizons early adoption', 'horizons early adoption required');
+ requirements.horizonsEarlyAdoption && renderRequirement('horizons', 'horizons early adoption', 'horizons early adoption required');
}
return (
@@ -602,7 +608,7 @@ export default class OutfittingPage extends Page {
{/* Main tables */}
-
+
diff --git a/src/app/pages/ShipyardPage.jsx b/src/app/pages/ShipyardPage.jsx
index 09a09182..842ca5bf 100644
--- a/src/app/pages/ShipyardPage.jsx
+++ b/src/app/pages/ShipyardPage.jsx
@@ -274,11 +274,11 @@ export default class ShipyardPage extends Page {
for (let s of shipSummaries) {
let shipSortValue = s[shipPredicate];
- if( shipPredicateIndex != undefined ) {
+ if(shipPredicateIndex != undefined) {
shipSortValue = shipSortValue[shipPredicateIndex];
}
- if( shipSortValue != lastShipSortValue ) {
+ if(shipSortValue != lastShipSortValue) {
backgroundHighlight = !backgroundHighlight;
lastShipSortValue = shipSortValue;
}
diff --git a/src/app/shipyard/Calculations.js b/src/app/shipyard/Calculations.js
index 2976c794..fe1574e6 100644
--- a/src/app/shipyard/Calculations.js
+++ b/src/app/shipyard/Calculations.js
@@ -45,7 +45,8 @@ export function totalJumpRange(mass, fsd, fuel) {
* @param {number} baseShield Base Shield strength MJ for ship
* @param {object} sg The shield generator used
* @param {number} multiplier Shield multiplier for ship (1 + shield boosters if any)
- * @return {number} Approximate shield strengh in MJ
+ * @param {Object} ship The ship object
+ * @return {number} Approximate shield strengh in MJ
*/
export function shieldStrength(mass, baseShield, sg, multiplier, ship) {
// sg might be a module or a template; handle either here
diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js
index 440604b3..c5cde25d 100755
--- a/src/app/shipyard/Module.js
+++ b/src/app/shipyard/Module.js
@@ -136,7 +136,7 @@ export default class Module {
if (modification.type === 'percentage') {
modValue = this.getModValue(name) / 10000;
} else if (modification.type === 'numeric') {
- modValue = this.getModValue(name)/ 100;
+ modValue = this.getModValue(name) / 100;
} else {
modValue = this.getModValue(name);
}
diff --git a/src/app/shipyard/ShipRoles.js b/src/app/shipyard/ShipRoles.js
index a30cb5ae..62c4e00c 100644
--- a/src/app/shipyard/ShipRoles.js
+++ b/src/app/shipyard/ShipRoles.js
@@ -1,5 +1,5 @@
-import * as ModuleUtils from './ModuleUtils'
-import { canMount } from '../utils/SlotFunctions'
+import * as ModuleUtils from './ModuleUtils';
+import { canMount } from '../utils/SlotFunctions';
/**
* Standard / typical role for multi-purpose or combat (if shielded with better bulkheads)
@@ -7,20 +7,20 @@ import { canMount } from '../utils/SlotFunctions'
* @param {Boolean} shielded True if shield generator should be included
* @param {integer} bulkheadIndex Bulkhead to use see Constants.BulkheadNames
*/
-export function multiPurpose (ship, shielded, bulkheadIndex) {
+export function multiPurpose(ship, shielded, bulkheadIndex) {
ship.useStandard('A')
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')) // D Sensors
- .useBulkhead(bulkheadIndex)
+ .useBulkhead(bulkheadIndex);
if (shielded) {
- ship.internal.some(function (slot) {
+ ship.internal.some(function(slot) {
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
- ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'))
- ship.setSlotEnabled(slot, true)
- return true
+ ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
+ ship.setSlotEnabled(slot, true);
+ return true;
}
- })
+ });
}
}
@@ -30,51 +30,51 @@ export function multiPurpose (ship, shielded, bulkheadIndex) {
* @param {Boolean} shielded True if shield generator should be included
* @param {Object} standardOpts [Optional] Standard module optional overrides
*/
-export function trader (ship, shielded, standardOpts) {
- let usedSlots = []
- let bstCount = 2
- let sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
+export function trader(ship, shielded, standardOpts) {
+ let usedSlots = [];
+ let bstCount = 2;
+ let sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
ship.useStandard('A')
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
.use(ship.standard[1], ModuleUtils.standard(1, ship.standard[1].maxClass + 'D')) // D Life Support
.use(ship.standard[4], ModuleUtils.standard(4, ship.standard[4].maxClass + 'D')) // D Life Support
- .use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')) // D Sensors
+ .use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')); // D Sensors
- const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
+ const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.sg)
.filter(a => a.maxClass >= sg.class)
- .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
- shieldInternals.some(function (slot) {
+ .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
+ shieldInternals.some(function(slot) {
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
- const shield = ModuleUtils.findInternal('sg', slot.maxClass, 'A')
+ const shield = ModuleUtils.findInternal('sg', slot.maxClass, 'A');
if (shield && shield.maxmass > ship.hullMass) {
- ship.use(slot, shield)
- ship.setSlotEnabled(slot, true)
- usedSlots.push(slot)
- return true
+ ship.use(slot, shield);
+ ship.setSlotEnabled(slot, true);
+ usedSlots.push(slot);
+ return true;
}
}
- })
+ });
// Fill the empty internals with cargo racks
for (let i = ship.internal.length; i--;) {
- let slot = ship.internal[i]
+ let slot = ship.internal[i];
if (usedSlots.indexOf(slot) == -1 && canMount(ship, slot, 'cr')) {
- ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'))
+ ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'));
}
}
// Empty the hardpoints
for (let s of ship.hardpoints) {
- ship.use(s, null)
+ ship.use(s, null);
}
for (let s of ship.hardpoints) {
if (s.maxClass == 0 && bstCount) { // Mount up to 2 boosters
- ship.use(s, ModuleUtils.hardpoints('04'))
- bstCount--
+ ship.use(s, ModuleUtils.hardpoints('04'));
+ bstCount--;
} else {
- ship.use(s, null)
+ ship.use(s, null);
}
}
// ship.useLightestStandard(standardOpts);
@@ -85,127 +85,127 @@ export function trader (ship, shielded, standardOpts) {
* @param {Ship} ship Ship instance
* @param {Boolean} planetary True if Planetary Vehicle Hangar (PVH) should be included
*/
-export function explorer (ship, planetary) {
- let standardOpts = {ppRating: 'A'},
- heatSinkCount = 2, // Fit 2 heat sinks if possible
- usedSlots = [],
- sgSlot,
- fuelScoopSlot,
- sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
+export function explorer(ship, planetary) {
+ let standardOpts = { ppRating: 'A' },
+ heatSinkCount = 2, // Fit 2 heat sinks if possible
+ usedSlots = [],
+ sgSlot,
+ fuelScoopSlot,
+ sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
if (!planetary) { // Non-planetary explorers don't really need to boost
- standardOpts.pd = '1D'
+ standardOpts.pd = '1D';
}
// Cargo hatch can be disabled
- ship.setSlotEnabled(ship.cargoHatch, false)
+ ship.setSlotEnabled(ship.cargoHatch, false);
// Advanced Discovery Scanner - class 1 or higher
- const adsOrder = [1, 2, 3, 4, 5, 6, 7, 8]
+ const adsOrder = [1, 2, 3, 4, 5, 6, 7, 8];
const adsInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.sc)
- .sort((a, b) => adsOrder.indexOf(a.maxClass) - adsOrder.indexOf(b.maxClass))
+ .sort((a, b) => adsOrder.indexOf(a.maxClass) - adsOrder.indexOf(b.maxClass));
for (let i = 0; i < adsInternals.length; i++) {
if (canMount(ship, adsInternals[i], 'sc')) {
- ship.use(adsInternals[i], ModuleUtils.internal('2f'))
- usedSlots.push(adsInternals[i])
- break
+ ship.use(adsInternals[i], ModuleUtils.internal('2f'));
+ usedSlots.push(adsInternals[i]);
+ break;
}
}
if (planetary) {
// Planetary Vehicle Hangar - class 2 or higher
- const pvhOrder = [2, 3, 4, 5, 6, 7, 8, 1]
+ const pvhOrder = [2, 3, 4, 5, 6, 7, 8, 1];
const pvhInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.pv)
- .sort((a, b) => pvhOrder.indexOf(a.maxClass) - pvhOrder.indexOf(b.maxClass))
+ .sort((a, b) => pvhOrder.indexOf(a.maxClass) - pvhOrder.indexOf(b.maxClass));
for (let i = 0; i < pvhInternals.length; i++) {
if (canMount(ship, pvhInternals[i], 'pv')) {
// Planetary Vehical Hangar only has even classes
- const pvhClass = pvhInternals[i].maxClass % 2 === 1 ? pvhInternals[i].maxClass - 1 : pvhInternals[i].maxClass
- ship.use(pvhInternals[i], ModuleUtils.findInternal('pv', pvhClass, 'G')) // G is lower mass
- ship.setSlotEnabled(pvhInternals[i], false) // Disable power for Planetary Vehical Hangar
- usedSlots.push(pvhInternals[i])
- break
+ const pvhClass = pvhInternals[i].maxClass % 2 === 1 ? pvhInternals[i].maxClass - 1 : pvhInternals[i].maxClass;
+ ship.use(pvhInternals[i], ModuleUtils.findInternal('pv', pvhClass, 'G')); // G is lower mass
+ ship.setSlotEnabled(pvhInternals[i], false); // Disable power for Planetary Vehical Hangar
+ usedSlots.push(pvhInternals[i]);
+ break;
}
}
}
// Shield generator
- const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
+ const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.sg)
.filter(a => a.maxClass >= sg.class)
- .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
+ .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
for (let i = 0; i < shieldInternals.length; i++) {
if (canMount(ship, shieldInternals[i], 'sg')) {
- ship.use(shieldInternals[i], sg)
- usedSlots.push(shieldInternals[i])
- sgSlot = shieldInternals[i]
- break
+ ship.use(shieldInternals[i], sg);
+ usedSlots.push(shieldInternals[i]);
+ sgSlot = shieldInternals[i];
+ break;
}
}
// Detailed Surface Scanner
- const dssOrder = [1, 2, 3, 4, 5, 6, 7, 8]
+ const dssOrder = [1, 2, 3, 4, 5, 6, 7, 8];
const dssInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.sc)
- .sort((a, b) => dssOrder.indexOf(a.maxClass) - dssOrder.indexOf(b.maxClass))
+ .sort((a, b) => dssOrder.indexOf(a.maxClass) - dssOrder.indexOf(b.maxClass));
for (let i = 0; i < dssInternals.length; i++) {
if (canMount(ship, dssInternals[i], 'sc')) {
- ship.use(dssInternals[i], ModuleUtils.internal('2i'))
- usedSlots.push(dssInternals[i])
- break
+ ship.use(dssInternals[i], ModuleUtils.internal('2i'));
+ usedSlots.push(dssInternals[i]);
+ break;
}
}
// Fuel scoop - best possible
- const fuelScoopOrder = [8, 7, 6, 5, 4, 3, 2, 1]
+ const fuelScoopOrder = [8, 7, 6, 5, 4, 3, 2, 1];
const fuelScoopInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.fs)
- .sort((a, b) => fuelScoopOrder.indexOf(a.maxClass) - fuelScoopOrder.indexOf(b.maxClass))
+ .sort((a, b) => fuelScoopOrder.indexOf(a.maxClass) - fuelScoopOrder.indexOf(b.maxClass));
for (let i = 0; i < fuelScoopInternals.length; i++) {
if (canMount(ship, fuelScoopInternals[i], 'fs')) {
- ship.use(fuelScoopInternals[i], ModuleUtils.findInternal('fs', fuelScoopInternals[i].maxClass, 'A'))
- usedSlots.push(fuelScoopInternals[i])
- fuelScoopSlot = fuelScoopInternals[i]
- break
+ ship.use(fuelScoopInternals[i], ModuleUtils.findInternal('fs', fuelScoopInternals[i].maxClass, 'A'));
+ usedSlots.push(fuelScoopInternals[i]);
+ fuelScoopSlot = fuelScoopInternals[i];
+ break;
}
}
// AFMUs - fill as they are 0-weight
- const afmuOrder = [8, 7, 6, 5, 4, 3, 2, 1]
+ const afmuOrder = [8, 7, 6, 5, 4, 3, 2, 1];
const afmuInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.pc)
- .sort((a, b) => afmuOrder.indexOf(a.maxClass) - afmuOrder.indexOf(b.maxClass))
+ .sort((a, b) => afmuOrder.indexOf(a.maxClass) - afmuOrder.indexOf(b.maxClass));
for (let i = 0; i < afmuInternals.length; i++) {
if (canMount(ship, afmuInternals[i], 'am')) {
- ship.use(afmuInternals[i], ModuleUtils.findInternal('am', afmuInternals[i].maxClass, 'A'))
- usedSlots.push(afmuInternals[i])
- ship.setSlotEnabled(afmuInternals[i], false) // Disable power for AFM Unit
+ ship.use(afmuInternals[i], ModuleUtils.findInternal('am', afmuInternals[i].maxClass, 'A'));
+ usedSlots.push(afmuInternals[i]);
+ ship.setSlotEnabled(afmuInternals[i], false); // Disable power for AFM Unit
}
}
for (let s of ship.hardpoints) {
if (s.maxClass == 0 && heatSinkCount) { // Mount up to 2 heatsinks
- ship.use(s, ModuleUtils.hardpoints('02'))
- ship.setSlotEnabled(s, heatSinkCount == 2) // Only enable a single Heatsink
- heatSinkCount--
+ ship.use(s, ModuleUtils.hardpoints('02'));
+ ship.setSlotEnabled(s, heatSinkCount == 2); // Only enable a single Heatsink
+ heatSinkCount--;
} else {
- ship.use(s, null)
+ ship.use(s, null);
}
}
if (sgSlot && fuelScoopSlot) {
// The SG and Fuel scoop to not need to be powered at the same time
if (sgSlot.m.getPowerUsage() > fuelScoopSlot.m.getPowerUsage()) { // The Shield generator uses the most power
- ship.setSlotEnabled(fuelScoopSlot, false)
+ ship.setSlotEnabled(fuelScoopSlot, false);
} else { // The Fuel scoop uses the most power
- ship.setSlotEnabled(sgSlot, false)
+ ship.setSlotEnabled(sgSlot, false);
}
}
- ship.useLightestStandard(standardOpts)
+ ship.useLightestStandard(standardOpts);
}
/**
@@ -213,188 +213,188 @@ export function explorer (ship, planetary) {
* @param {Ship} ship Ship instance
* @param {Boolean} shielded True if shield generator should be included
*/
-export function miner (ship, shielded) {
- shielded = true
- let standardOpts = {ppRating: 'A'},
- miningLaserCount = 2,
- usedSlots = [],
- sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
+export function miner(ship, shielded) {
+ shielded = true;
+ let standardOpts = { ppRating: 'A' },
+ miningLaserCount = 2,
+ usedSlots = [],
+ sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
// Cargo hatch should be enabled
- ship.setSlotEnabled(ship.cargoHatch, true)
+ ship.setSlotEnabled(ship.cargoHatch, true);
// Largest possible refinery
- const refineryOrder = [4, 5, 6, 7, 8, 3, 2, 1]
+ const refineryOrder = [4, 5, 6, 7, 8, 3, 2, 1];
const refineryInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.rf)
- .sort((a, b) => refineryOrder.indexOf(a.maxClass) - refineryOrder.indexOf(b.maxClass))
+ .sort((a, b) => refineryOrder.indexOf(a.maxClass) - refineryOrder.indexOf(b.maxClass));
for (let i = 0; i < refineryInternals.length; i++) {
if (canMount(ship, refineryInternals[i], 'rf')) {
- ship.use(refineryInternals[i], ModuleUtils.findInternal('rf', Math.min(refineryInternals[i].maxClass, 4), 'A'))
- usedSlots.push(refineryInternals[i])
- break
+ ship.use(refineryInternals[i], ModuleUtils.findInternal('rf', Math.min(refineryInternals[i].maxClass, 4), 'A'));
+ usedSlots.push(refineryInternals[i]);
+ break;
}
}
// Prospector limpet controller - 3A if possible
- const prospectorOrder = [3, 4, 5, 6, 7, 8, 2, 1]
+ const prospectorOrder = [3, 4, 5, 6, 7, 8, 2, 1];
const prospectorInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.pc)
- .sort((a, b) => prospectorOrder.indexOf(a.maxClass) - prospectorOrder.indexOf(b.maxClass))
+ .sort((a, b) => prospectorOrder.indexOf(a.maxClass) - prospectorOrder.indexOf(b.maxClass));
for (let i = 0; i < prospectorInternals.length; i++) {
if (canMount(ship, prospectorInternals[i], 'pc')) {
// Prospector only has odd classes
- const prospectorClass = prospectorInternals[i].maxClass % 2 === 0 ? prospectorInternals[i].maxClass - 1 : prospectorInternals[i].maxClass
- ship.use(prospectorInternals[i], ModuleUtils.findInternal('pc', prospectorClass, 'A'))
- usedSlots.push(prospectorInternals[i])
- break
+ const prospectorClass = prospectorInternals[i].maxClass % 2 === 0 ? prospectorInternals[i].maxClass - 1 : prospectorInternals[i].maxClass;
+ ship.use(prospectorInternals[i], ModuleUtils.findInternal('pc', prospectorClass, 'A'));
+ usedSlots.push(prospectorInternals[i]);
+ break;
}
}
// Shield generator if required
if (shielded) {
- const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
+ const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.sg)
.filter(a => a.maxClass >= sg.class)
- .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
+ .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
for (let i = 0; i < shieldInternals.length; i++) {
if (canMount(ship, shieldInternals[i], 'sg')) {
- ship.use(shieldInternals[i], sg)
- usedSlots.push(shieldInternals[i])
- break
+ ship.use(shieldInternals[i], sg);
+ usedSlots.push(shieldInternals[i]);
+ break;
}
}
}
// Dual mining lasers of highest possible class; remove anything else
- const miningLaserOrder = [2, 3, 4, 1, 0]
- const miningLaserHardpoints = ship.hardpoints.concat().sort(function (a, b) {
- return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass)
- })
+ const miningLaserOrder = [2, 3, 4, 1, 0];
+ const miningLaserHardpoints = ship.hardpoints.concat().sort(function(a, b) {
+ return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass);
+ });
for (let s of miningLaserHardpoints) {
if (s.maxClass >= 1 && miningLaserCount) {
- ship.use(s, ModuleUtils.hardpoints(s.maxClass >= 2 ? '2m' : '2l'))
- miningLaserCount--
+ ship.use(s, ModuleUtils.hardpoints(s.maxClass >= 2 ? '2m' : '2l'));
+ miningLaserCount--;
} else {
- ship.use(s, null)
+ ship.use(s, null);
}
}
// Number of collector limpets required to be active is a function of the size of the ship and the power of the lasers
const miningLaserDps = ship.hardpoints.filter(h => h.m != null)
- .reduce(function (a, b) {
- return a + b.m.getDps()
- }, 0)
+ .reduce(function(a, b) {
+ return a + b.m.getDps();
+ }, 0);
// Find out how many internal slots we have, and their potential cargo size
const potentialCargo = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.cr)
- .map(b => Math.pow(2, b.maxClass))
+ .map(b => Math.pow(2, b.maxClass));
// One collector for each 1.25 DPS, multiply by 1.25 for medium ships and 1.5 for large ships as they have further to travel
// 0 if we only have 1 cargo slot, otherwise minium of 1 and maximum of 6 (excluding size modifier)
- const sizeModifier = ship.class == 2 ? 1.2 : ship.class == 3 ? 1.5 : 1
- let collectorLimpetsRequired = potentialCargo.length == 1 ? 0 : Math.ceil(sizeModifier * Math.min(6, Math.floor(miningLaserDps / 1.25)))
+ const sizeModifier = ship.class == 2 ? 1.2 : ship.class == 3 ? 1.5 : 1;
+ let collectorLimpetsRequired = potentialCargo.length == 1 ? 0 : Math.ceil(sizeModifier * Math.min(6, Math.floor(miningLaserDps / 1.25)));
if (collectorLimpetsRequired > 0) {
- const collectorOrder = [1, 2, 3, 4, 5, 6, 7, 8]
+ const collectorOrder = [1, 2, 3, 4, 5, 6, 7, 8];
const collectorInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.cc)
- .sort((a, b) => collectorOrder.indexOf(a.maxClass) - collectorOrder.indexOf(b.maxClass))
+ .sort((a, b) => collectorOrder.indexOf(a.maxClass) - collectorOrder.indexOf(b.maxClass));
// Always keep at least 2 slots free for cargo racks (1 for shielded)
for (let i = 0; i < collectorInternals.length - (shielded ? 1 : 2) && collectorLimpetsRequired > 0; i++) {
if (canMount(ship, collectorInternals[i], 'cc')) {
// Collector only has odd classes
- const collectorClass = collectorInternals[i].maxClass % 2 === 0 ? collectorInternals[i].maxClass - 1 : collectorInternals[i].maxClass
- ship.use(collectorInternals[i], ModuleUtils.findInternal('cc', collectorClass, 'D'))
- usedSlots.push(collectorInternals[i])
- collectorLimpetsRequired -= collectorInternals[i].m.maximum
+ const collectorClass = collectorInternals[i].maxClass % 2 === 0 ? collectorInternals[i].maxClass - 1 : collectorInternals[i].maxClass;
+ ship.use(collectorInternals[i], ModuleUtils.findInternal('cc', collectorClass, 'D'));
+ usedSlots.push(collectorInternals[i]);
+ collectorLimpetsRequired -= collectorInternals[i].m.maximum;
}
}
}
// Power distributor to power the mining lasers indefinitely
const wepRateRequired = ship.hardpoints.filter(h => h.m != null)
- .reduce(function (a, b) {
- return a + b.m.getEps()
- }, 0)
- standardOpts.pd = ship.getAvailableModules().matchingPowerDist({weprate: wepRateRequired}).id
+ .reduce(function(a, b) {
+ return a + b.m.getEps();
+ }, 0);
+ standardOpts.pd = ship.getAvailableModules().matchingPowerDist({ weprate: wepRateRequired }).id;
// Fill the empty internals with cargo racks
for (let i = ship.internal.length; i--;) {
- let slot = ship.internal[i]
+ let slot = ship.internal[i];
if (usedSlots.indexOf(slot) == -1 && canMount(ship, slot, 'cr')) {
- ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'))
+ ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'));
}
}
- ship.useLightestStandard(standardOpts)
+ ship.useLightestStandard(standardOpts);
}
/**
* Racer Role
* @param {Ship} ship Ship instance
*/
-export function racer (ship) {
+export function racer(ship) {
let standardOpts = {},
- usedSlots = [],
- sgSlot,
- sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
+ usedSlots = [],
+ sgSlot,
+ sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
// Cargo hatch can be disabled
- ship.setSlotEnabled(ship.cargoHatch, false)
+ ship.setSlotEnabled(ship.cargoHatch, false);
// Shield generator
- const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
+ const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
.filter(a => (!a.eligible) || a.eligible.sg)
.filter(a => a.maxClass >= sg.class)
- .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
+ .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
for (let i = 0; i < shieldInternals.length; i++) {
if (canMount(ship, shieldInternals[i], 'sg')) {
- ship.use(shieldInternals[i], sg)
- usedSlots.push(shieldInternals[i])
- sgSlot = shieldInternals[i]
- break
+ ship.use(shieldInternals[i], sg);
+ usedSlots.push(shieldInternals[i]);
+ sgSlot = shieldInternals[i];
+ break;
}
}
// Empty the hardpoints
for (let s of ship.hardpoints) {
- ship.use(s, null)
+ ship.use(s, null);
}
// Empty the internals
for (let i = ship.internal.length; i--;) {
- let slot = ship.internal[i]
+ let slot = ship.internal[i];
if (usedSlots.indexOf(slot) == -1) {
- ship.use(slot, null)
+ ship.use(slot, null);
}
}
// Best thrusters
if (ship.standard[1].maxClass === 3) {
- standardOpts.th = 'tz'
+ standardOpts.th = 'tz';
} else if (ship.standard[1].maxClass === 2) {
- standardOpts.th = 'u0'
+ standardOpts.th = 'u0';
} else {
- standardOpts.th = ship.standard[1].maxClass + 'A'
+ standardOpts.th = ship.standard[1].maxClass + 'A';
}
// Best power distributor for more boosting
- standardOpts.pd = ship.standard[4].maxClass + 'A'
+ standardOpts.pd = ship.standard[4].maxClass + 'A';
// Smallest possible FSD drive
- standardOpts.fsd = '2D'
+ standardOpts.fsd = '2D';
// Minimal fuel tank
- standardOpts.ft = '1C'
+ standardOpts.ft = '1C';
// Disable nearly everything
- standardOpts.fsdDisabled = true
- standardOpts.sDisabled = true
- standardOpts.pdDisabled = true
- standardOpts.lsDisabled = true
+ standardOpts.fsdDisabled = true;
+ standardOpts.sDisabled = true;
+ standardOpts.pdDisabled = true;
+ standardOpts.lsDisabled = true;
- ship.useLightestStandard(standardOpts)
+ ship.useLightestStandard(standardOpts);
// Apply engineering to each module
// ship.standard[1].m.blueprint = getBlueprint('Engine_Dirty', ship.standard[0]);
diff --git a/src/app/utils/BlueprintFunctions.js b/src/app/utils/BlueprintFunctions.js
index 53b02f69..a597dae7 100644
--- a/src/app/utils/BlueprintFunctions.js
+++ b/src/app/utils/BlueprintFunctions.js
@@ -7,7 +7,7 @@ import { Modifications } from 'coriolis-data/dist';
* @param {Object} blueprint The blueprint at the required grade
* @param {string} grp The group of the module
* @param {Object} m The module to compare with
- * @param specialName
+ * @param {string} specialName The name of the special
* @returns {Object} The react components
*/
export function specialToolTip(translate, blueprint, grp, m, specialName) {
@@ -18,36 +18,35 @@ export function specialToolTip(translate, blueprint, grp, m, specialName) {
if (m) {
// We also add in any benefits from specials that aren't covered above
if (m.blueprint) {
- for (const feature in Modifications.modifierActions[specialName]) {
+ for (const feature in Modifications.modifierActions[specialName]) {
// if (!blueprint.features[feature] && !m.mods.feature) {
- const featureDef = Modifications.modifications[feature];
- if (featureDef && !featureDef.hidden) {
- let symbol = '';
- if (feature === 'jitter') {
- symbol = '°';
- } else if (featureDef.type === 'percentage') {
- symbol = '%';
- }
- let current = m.getModValue(feature) - m.getModValue(feature, true);
- if (featureDef.type === 'percentage') {
- current = Math.round(current / 10) / 10;
- } else if (featureDef.type === 'numeric') {
- current /= 100;
- }
- const currentIsBeneficial = isValueBeneficial(feature, current);
+ const featureDef = Modifications.modifications[feature];
+ if (featureDef && !featureDef.hidden) {
+ let symbol = '';
+ if (feature === 'jitter') {
+ symbol = '°';
+ } else if (featureDef.type === 'percentage') {
+ symbol = '%';
+ }
+ let current = m.getModValue(feature) - m.getModValue(feature, true);
+ if (featureDef.type === 'percentage') {
+ current = Math.round(current / 10) / 10;
+ } else if (featureDef.type === 'numeric') {
+ current /= 100;
+ }
+ const currentIsBeneficial = isValueBeneficial(feature, current);
- effects.push(
+ effects.push(
- {translate(feature, grp)}
+ {translate(feature, grp)}
{current}{symbol}
+ style={{ textAlign: 'right' }}>{current}{symbol}
);
- }
+ }
}
-
}
}
@@ -289,7 +288,7 @@ export function isValueBeneficial(feature, value) {
*/
export function getBlueprint(name, module) {
// Start with a copy of the blueprint
- const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0)
+ const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0);
const found = Modifications.blueprints[findMod(name)];
if (!found || !found.fdname) {
return {};
@@ -382,36 +381,35 @@ export function getPercent(m) {
let result = null;
const features = m.blueprint.grades[m.blueprint.grade].features;
for (const featureName in features) {
-
- if (features[featureName][0] === features[featureName][1]) {
- continue;
- }
-
- let value = _getValue(m, featureName);
- let mult;
+ if (features[featureName][0] === features[featureName][1]) {
+ continue;
+ }
+
+ let value = _getValue(m, featureName);
+ let mult;
if (Modifications.modifications[featureName].higherbetter) {
// Higher is better, but is this making it better or worse?
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
- mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
+ mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
} else {
- mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
+ mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
}
} else {
// Higher is worse, but is this making it better or worse?
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
- mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
+ mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
} else {
- mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
+ mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
}
}
-
- if (result && result != mult) {
- return null;
- } else if (result != mult) {
- result = mult;
- }
+
+ if (result && result != mult) {
+ return null;
+ } else if (result != mult) {
+ result = mult;
+ }
}
-
+
return result;
}
@@ -419,6 +417,7 @@ export function getPercent(m) {
* Query a feature value
* @param {Object} m The module for which to perform the query
* @param {string} featureName The feature being queried
+ * @returns {number} The value of the modification as a %
*/
function _getValue(m, featureName) {
if (Modifications.modifications[featureName].type == 'percentage') {
diff --git a/src/app/utils/CompanionApiUtils.js b/src/app/utils/CompanionApiUtils.js
index 4f6d86e0..1755bb27 100644
--- a/src/app/utils/CompanionApiUtils.js
+++ b/src/app/utils/CompanionApiUtils.js
@@ -318,7 +318,7 @@ function _addModifications(module, modifiers, blueprint, grade, specialModificat
if (!modifiers) return;
let special;
if (specialModifications) {
- special = Modifications.specials[Object.keys(specialModifications)[0]]
+ special = Modifications.specials[Object.keys(specialModifications)[0]];
}
for (const i in modifiers) {
// Some special modifications
@@ -345,7 +345,7 @@ function _addModifications(module, modifiers, blueprint, grade, specialModificat
let value;
if (i === 'OutfittingFieldType_DefenceModifierShieldMultiplier') {
value = modifiers[i].value - 1;
- } else if (i === 'OutfittingFieldType_DefenceModifierHealthMultiplier' && blueprint.startsWith('Armour_')) {
+ } else if (i === 'OutfittingFieldType_DefenceModifierHealthMultiplier' && blueprint.startsWith('Armour_')) {
value = (modifiers[i].value - module.hullboost) / module.hullboost;
} else if (i === 'OutfittingFieldType_DefenceModifierHealthMultiplier') {
value = modifiers[i].value / module.hullboost;
diff --git a/src/app/utils/JournalUtils.js b/src/app/utils/JournalUtils.js
index 08b39a96..94c1b6be 100644
--- a/src/app/utils/JournalUtils.js
+++ b/src/app/utils/JournalUtils.js
@@ -1,292 +1,291 @@
-import Ship from '../shipyard/Ship'
-import { HARDPOINT_NUM_TO_CLASS, shipModelFromJson } from './CompanionApiUtils'
-import { Ships } from 'coriolis-data/dist'
-import Module from '../shipyard/Module'
-import { Modules } from 'coriolis-data/dist'
-import { Modifications } from 'coriolis-data/dist'
-import { getBlueprint } from './BlueprintFunctions'
-
-/**
- * Obtain a module given its FD Name
- * @param {string} fdname the FD Name of the module
- * @return {Module} the module
- */
-function _moduleFromFdName (fdname) {
- if (!fdname) return null
- fdname = fdname.toLowerCase()
- // Check standard modules
- for (const grp in Modules.standard) {
- if (Modules.standard.hasOwnProperty(grp)) {
- for (const i in Modules.standard[grp]) {
- if (Modules.standard[grp][i].symbol && Modules.standard[grp][i].symbol.toLowerCase() === fdname) {
- // Found it
- return new Module({template: Modules.standard[grp][i]})
- }
- }
- }
- }
-
- // Check hardpoint modules
- for (const grp in Modules.hardpoints) {
- if (Modules.hardpoints.hasOwnProperty(grp)) {
- for (const i in Modules.hardpoints[grp]) {
- if (Modules.hardpoints[grp][i].symbol && Modules.hardpoints[grp][i].symbol.toLowerCase() === fdname) {
- // Found it
- return new Module({template: Modules.hardpoints[grp][i]})
- }
- }
- }
- }
-
- // Check internal modules
- for (const grp in Modules.internal) {
- if (Modules.internal.hasOwnProperty(grp)) {
- for (const i in Modules.internal[grp]) {
- if (Modules.internal[grp][i].symbol && Modules.internal[grp][i].symbol.toLowerCase() === fdname) {
- // Found it
- return new Module({template: Modules.internal[grp][i]})
- }
- }
- }
- }
-
- // Not found
- return null
-}
-
-/**
- * Build a ship from the journal Loadout event JSON
- * @param {object} json the Loadout event JSON
- * @return {Ship} the built ship
- */
-export function shipFromLoadoutJSON (json) {
-// Start off building a basic ship
- const shipModel = shipModelFromJson(json)
- if (!shipModel) {
- throw 'No such ship found: "' + json.Ship + '"'
- }
- const shipTemplate = Ships[shipModel]
-
- let ship = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots)
- ship.buildWith(null)
- // Initial Ship building, don't do engineering yet.
- let opts = [];
-
- for (const module of json.Modules) {
- switch (module.Slot.toLowerCase()) {
- // Cargo Hatch.
- case 'cargohatch':
- ship.cargoHatch.enabled = module.On
- ship.cargoHatch.priority = module.Priority
- break
- // Add the bulkheads
- case 'armour':
- if (module.Item.toLowerCase().endsWith('_armour_grade1')) {
- ship.useBulkhead(0, true)
- } else if (module.Item.toLowerCase().endsWith('_armour_grade2')) {
- ship.useBulkhead(1, true)
- } else if (module.Item.toLowerCase().endsWith('_armour_grade3')) {
- ship.useBulkhead(2, true)
- } else if (module.Item.toLowerCase().endsWith('_armour_mirrored')) {
- ship.useBulkhead(3, true)
- } else if (module.Item.toLowerCase().endsWith('_armour_reactive')) {
- ship.useBulkhead(4, true)
- } else {
- throw 'Unknown bulkheads "' + module.Item + '"'
- }
- ship.bulkheads.enabled = true
- if (module.Engineering) _addModifications(ship.bulkheads.m, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
- break
- case 'powerplant':
- const powerplant = _moduleFromFdName(module.Item)
- ship.use(ship.standard[0], powerplant, true)
- ship.standard[0].enabled = module.On
- ship.standard[0].priority = module.Priority
- if (module.Engineering) _addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
- break
- case 'mainengines':
- const thrusters = _moduleFromFdName(module.Item)
- ship.use(ship.standard[1], thrusters, true)
- ship.standard[1].enabled = module.On
- ship.standard[1].priority = module.Priority
- if (module.Engineering) _addModifications(thrusters, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
- break
- case 'frameshiftdrive':
- const frameshiftdrive = _moduleFromFdName(module.Item)
- ship.use(ship.standard[2], frameshiftdrive, true)
- ship.standard[2].enabled = module.On
- ship.standard[2].priority = module.Priority
- if (module.Engineering) _addModifications(frameshiftdrive, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
- break
- case 'lifesupport':
- const lifesupport = _moduleFromFdName(module.Item)
- ship.use(ship.standard[3], lifesupport, true)
- ship.standard[3].enabled = module.On === true
- ship.standard[3].priority = module.Priority
- if (module.Engineering) _addModifications(lifesupport, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
- break
- case 'powerdistributor':
- const powerdistributor = _moduleFromFdName(module.Item)
- ship.use(ship.standard[4], powerdistributor, true)
- ship.standard[4].enabled = module.On
- ship.standard[4].priority = module.Priority
- if (module.Engineering) _addModifications(powerdistributor, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
- break
- case 'radar':
- const sensors = _moduleFromFdName(module.Item)
- ship.use(ship.standard[5], sensors, true)
- ship.standard[5].enabled = module.On
- ship.standard[5].priority = module.Priority
- if (module.Engineering) _addModifications(sensors, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect)
- break
- case 'fueltank':
- const fueltank = _moduleFromFdName(module.Item)
- ship.use(ship.standard[6], fueltank, true)
- ship.standard[6].enabled = true
- ship.standard[6].priority = 0
- break
- default:
- }
- for (const module of json.Modules) {
- if (module.Slot.toLowerCase().search(/hardpoint/) !== -1) {
- // Add hardpoints
- let hardpoint;
- let hardpointClassNum = -1
- let hardpointSlotNum = -1
- let hardpointArrayNum = 0
- for (let i in shipTemplate.slots.hardpoints) {
- if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) {
- // Another slot of the same class
- hardpointSlotNum++
- } else {
- // The first slot of a new class
- hardpointClassNum = shipTemplate.slots.hardpoints[i]
- hardpointSlotNum = 1
- }
-
- // Now that we know what we're looking for, find it
- const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum
- const hardpointSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === hardpointName.toLowerCase())
- if (!hardpointSlot) {
- // This can happen with old imports that don't contain new hardpoints
- } else if (!hardpointSlot) {
- // No module
- } else {
- hardpoint = _moduleFromFdName(hardpointSlot.Item)
- ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true)
- ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On
- ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority
- opts.push({coriolisMod: hardpoint, json: hardpointSlot});
- }
- hardpointArrayNum++
- }
- }
- if (module.Slot.toLowerCase().search(/slot\d/) !== -1) {
- let internalSlotNum = 1
- let militarySlotNum = 1
- for (let i in shipTemplate.slots.internal) {
- const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name = 'military' : false
-
- // The internal slot might be a standard or a military slot. Military slots have a different naming system
- let internalSlot = null
- if (isMilitary) {
- const internalName = 'Military0' + militarySlotNum
- internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase())
- militarySlotNum++
- } else {
- // Slot numbers are not contiguous so handle skips.
- while (internalSlot === null && internalSlotNum < 99) {
- // Slot sizes have no relationship to the actual size, either, so check all possibilities
- for (let slotsize = 0; slotsize < 9; slotsize++) {
- const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + slotsize
- if (json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase())) {
- internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
- break
- }
- }
- internalSlotNum++
- }
- }
-
- if (!internalSlot) {
- // This can happen with old imports that don't contain new slots
- } else if (!internalSlot) {
- // No module
- } else {
- const internalJson = internalSlot
- const internal = _moduleFromFdName(internalJson.Item)
- ship.use(ship.internal[i], internal, true)
- ship.internal[i].enabled = internalJson.On === true
- ship.internal[i].priority = internalJson.Priority
- opts.push({coriolisMod: internal, json: internalSlot});
- }
- }
- }
- }
- }
-
- for (const i of opts) {
- if (i.json.Engineering) _addModifications(i.coriolisMod, i.json.Engineering.Modifiers, i.json.Engineering.BlueprintName, i.json.Engineering.Level, i.json.Engineering.ExperimentalEffect)
- }
- // We don't have any information on it so guess it's priority 5 and disabled
- if (!ship.cargoHatch) {
- ship.cargoHatch.enabled = false
- ship.cargoHatch.priority = 4
- }
- console.log(ship)
-
- // Now update the ship's codes before returning it
- return ship.updatePowerPrioritesString().updatePowerEnabledString().updateModificationsString()
-}
-
-/**
- * Add the modifications for a module
- * @param {Module} module the module
- * @param {Object} modifiers the modifiers
- * @param {Object} blueprint the blueprint of the modification
- * @param {Object} grade the grade of the modification
- * @param {Object} specialModifications special modification
- */
-function _addModifications (module, modifiers, blueprint, grade, specialModifications) {
- if (!modifiers) return
- let special
- if (specialModifications) {
- special = Modifications.specials[specialModifications]
- }
- for (const i in modifiers) {
- // Some special modifications
- // Look up the modifiers to find what we need to do
- const findMod = val => Object.keys(Modifications.modifierActions).find(elem => elem.toString().toLowerCase().replace(/(outfittingfieldtype_|persecond)/igm, '') === val.toString().toLowerCase().replace(/(outfittingfieldtype_|persecond)/igm, ''))
- const modifierActions = Modifications.modifierActions[findMod(modifiers[i].Label)]
- //TODO: Figure out how to scale this value.
- if (!!modifiers[i].LessIsGood) {
-
- }
- let value = (modifiers[i].Value / modifiers[i].OriginalValue * 100 - 100) * 100;
- if (value === Infinity) {
- value = modifiers[i].Value * 100;
- }
- if (modifiers[i].Label.search('Resistance') >= 0) {
- value = (modifiers[i].Value * 100) - (modifiers[i].OriginalValue * 100)
- }
- // Carry out the required changes
- for (const action in modifierActions) {
- if (isNaN(modifierActions[action])) {
- module.setModValue(action, modifierActions[action])
- } else {
- module.setModValue(action, value)
- }
- }
- }
-
- // Add the blueprint definition, grade and special
- if (blueprint) {
- module.blueprint = getBlueprint(blueprint, module)
- if (grade) {
- module.blueprint.grade = Number(grade)
- }
- if (special) {
- module.blueprint.special = special
- }
- }
-}
+import Ship from '../shipyard/Ship';
+import { HARDPOINT_NUM_TO_CLASS, shipModelFromJson } from './CompanionApiUtils';
+import { Ships } from 'coriolis-data/dist';
+import Module from '../shipyard/Module';
+import { Modules } from 'coriolis-data/dist';
+import { Modifications } from 'coriolis-data/dist';
+import { getBlueprint } from './BlueprintFunctions';
+
+/**
+ * Obtain a module given its FD Name
+ * @param {string} fdname the FD Name of the module
+ * @return {Module} the module
+ */
+function _moduleFromFdName(fdname) {
+ if (!fdname) return null;
+ fdname = fdname.toLowerCase();
+ // Check standard modules
+ for (const grp in Modules.standard) {
+ if (Modules.standard.hasOwnProperty(grp)) {
+ for (const i in Modules.standard[grp]) {
+ if (Modules.standard[grp][i].symbol && Modules.standard[grp][i].symbol.toLowerCase() === fdname) {
+ // Found it
+ return new Module({ template: Modules.standard[grp][i] });
+ }
+ }
+ }
+ }
+
+ // Check hardpoint modules
+ for (const grp in Modules.hardpoints) {
+ if (Modules.hardpoints.hasOwnProperty(grp)) {
+ for (const i in Modules.hardpoints[grp]) {
+ if (Modules.hardpoints[grp][i].symbol && Modules.hardpoints[grp][i].symbol.toLowerCase() === fdname) {
+ // Found it
+ return new Module({ template: Modules.hardpoints[grp][i] });
+ }
+ }
+ }
+ }
+
+ // Check internal modules
+ for (const grp in Modules.internal) {
+ if (Modules.internal.hasOwnProperty(grp)) {
+ for (const i in Modules.internal[grp]) {
+ if (Modules.internal[grp][i].symbol && Modules.internal[grp][i].symbol.toLowerCase() === fdname) {
+ // Found it
+ return new Module({ template: Modules.internal[grp][i] });
+ }
+ }
+ }
+ }
+
+ // Not found
+ return null;
+}
+
+/**
+ * Build a ship from the journal Loadout event JSON
+ * @param {object} json the Loadout event JSON
+ * @return {Ship} the built ship
+ */
+export function shipFromLoadoutJSON(json) {
+// Start off building a basic ship
+ const shipModel = shipModelFromJson(json);
+ if (!shipModel) {
+ throw 'No such ship found: "' + json.Ship + '"';
+ }
+ const shipTemplate = Ships[shipModel];
+
+ let ship = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots);
+ ship.buildWith(null);
+ // Initial Ship building, don't do engineering yet.
+ let opts = [];
+
+ for (const module of json.Modules) {
+ switch (module.Slot.toLowerCase()) {
+ // Cargo Hatch.
+ case 'cargohatch':
+ ship.cargoHatch.enabled = module.On;
+ ship.cargoHatch.priority = module.Priority;
+ break;
+ // Add the bulkheads
+ case 'armour':
+ if (module.Item.toLowerCase().endsWith('_armour_grade1')) {
+ ship.useBulkhead(0, true);
+ } else if (module.Item.toLowerCase().endsWith('_armour_grade2')) {
+ ship.useBulkhead(1, true);
+ } else if (module.Item.toLowerCase().endsWith('_armour_grade3')) {
+ ship.useBulkhead(2, true);
+ } else if (module.Item.toLowerCase().endsWith('_armour_mirrored')) {
+ ship.useBulkhead(3, true);
+ } else if (module.Item.toLowerCase().endsWith('_armour_reactive')) {
+ ship.useBulkhead(4, true);
+ } else {
+ throw 'Unknown bulkheads "' + module.Item + '"';
+ }
+ ship.bulkheads.enabled = true;
+ if (module.Engineering) _addModifications(ship.bulkheads.m, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
+ break;
+ case 'powerplant':
+ const powerplant = _moduleFromFdName(module.Item);
+ ship.use(ship.standard[0], powerplant, true);
+ ship.standard[0].enabled = module.On;
+ ship.standard[0].priority = module.Priority;
+ if (module.Engineering) _addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
+ break;
+ case 'mainengines':
+ const thrusters = _moduleFromFdName(module.Item);
+ ship.use(ship.standard[1], thrusters, true);
+ ship.standard[1].enabled = module.On;
+ ship.standard[1].priority = module.Priority;
+ if (module.Engineering) _addModifications(thrusters, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
+ break;
+ case 'frameshiftdrive':
+ const frameshiftdrive = _moduleFromFdName(module.Item);
+ ship.use(ship.standard[2], frameshiftdrive, true);
+ ship.standard[2].enabled = module.On;
+ ship.standard[2].priority = module.Priority;
+ if (module.Engineering) _addModifications(frameshiftdrive, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
+ break;
+ case 'lifesupport':
+ const lifesupport = _moduleFromFdName(module.Item);
+ ship.use(ship.standard[3], lifesupport, true);
+ ship.standard[3].enabled = module.On === true;
+ ship.standard[3].priority = module.Priority;
+ if (module.Engineering) _addModifications(lifesupport, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
+ break;
+ case 'powerdistributor':
+ const powerdistributor = _moduleFromFdName(module.Item);
+ ship.use(ship.standard[4], powerdistributor, true);
+ ship.standard[4].enabled = module.On;
+ ship.standard[4].priority = module.Priority;
+ if (module.Engineering) _addModifications(powerdistributor, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
+ break;
+ case 'radar':
+ const sensors = _moduleFromFdName(module.Item);
+ ship.use(ship.standard[5], sensors, true);
+ ship.standard[5].enabled = module.On;
+ ship.standard[5].priority = module.Priority;
+ if (module.Engineering) _addModifications(sensors, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level, module.Engineering.ExperimentalEffect);
+ break;
+ case 'fueltank':
+ const fueltank = _moduleFromFdName(module.Item);
+ ship.use(ship.standard[6], fueltank, true);
+ ship.standard[6].enabled = true;
+ ship.standard[6].priority = 0;
+ break;
+ default:
+ }
+ for (const module of json.Modules) {
+ if (module.Slot.toLowerCase().search(/hardpoint/) !== -1) {
+ // Add hardpoints
+ let hardpoint;
+ let hardpointClassNum = -1;
+ let hardpointSlotNum = -1;
+ let hardpointArrayNum = 0;
+ for (let i in shipTemplate.slots.hardpoints) {
+ if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) {
+ // Another slot of the same class
+ hardpointSlotNum++;
+ } else {
+ // The first slot of a new class
+ hardpointClassNum = shipTemplate.slots.hardpoints[i];
+ hardpointSlotNum = 1;
+ }
+
+ // Now that we know what we're looking for, find it
+ const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum;
+ const hardpointSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === hardpointName.toLowerCase());
+ if (!hardpointSlot) {
+ // This can happen with old imports that don't contain new hardpoints
+ } else if (!hardpointSlot) {
+ // No module
+ } else {
+ hardpoint = _moduleFromFdName(hardpointSlot.Item);
+ ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true);
+ ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On;
+ ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority;
+ opts.push({ coriolisMod: hardpoint, json: hardpointSlot });
+ }
+ hardpointArrayNum++;
+ }
+ }
+ if (module.Slot.toLowerCase().search(/slot\d/) !== -1) {
+ let internalSlotNum = 1;
+ let militarySlotNum = 1;
+ for (let i in shipTemplate.slots.internal) {
+ const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name = 'military' : false;
+
+ // The internal slot might be a standard or a military slot. Military slots have a different naming system
+ let internalSlot = null;
+ if (isMilitary) {
+ const internalName = 'Military0' + militarySlotNum;
+ internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
+ militarySlotNum++;
+ } else {
+ // Slot numbers are not contiguous so handle skips.
+ while (internalSlot === null && internalSlotNum < 99) {
+ // Slot sizes have no relationship to the actual size, either, so check all possibilities
+ for (let slotsize = 0; slotsize < 9; slotsize++) {
+ const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + slotsize;
+ if (json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase())) {
+ internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
+ break;
+ }
+ }
+ internalSlotNum++;
+ }
+ }
+
+ if (!internalSlot) {
+ // This can happen with old imports that don't contain new slots
+ } else if (!internalSlot) {
+ // No module
+ } else {
+ const internalJson = internalSlot;
+ const internal = _moduleFromFdName(internalJson.Item);
+ ship.use(ship.internal[i], internal, true);
+ ship.internal[i].enabled = internalJson.On === true;
+ ship.internal[i].priority = internalJson.Priority;
+ opts.push({ coriolisMod: internal, json: internalSlot });
+ }
+ }
+ }
+ }
+ }
+
+ for (const i of opts) {
+ if (i.json.Engineering) _addModifications(i.coriolisMod, i.json.Engineering.Modifiers, i.json.Engineering.BlueprintName, i.json.Engineering.Level, i.json.Engineering.ExperimentalEffect);
+ }
+ // We don't have any information on it so guess it's priority 5 and disabled
+ if (!ship.cargoHatch) {
+ ship.cargoHatch.enabled = false;
+ ship.cargoHatch.priority = 4;
+ }
+
+ // Now update the ship's codes before returning it
+ return ship.updatePowerPrioritesString().updatePowerEnabledString().updateModificationsString();
+}
+
+/**
+ * Add the modifications for a module
+ * @param {Module} module the module
+ * @param {Object} modifiers the modifiers
+ * @param {Object} blueprint the blueprint of the modification
+ * @param {Object} grade the grade of the modification
+ * @param {Object} specialModifications special modification
+ */
+function _addModifications(module, modifiers, blueprint, grade, specialModifications) {
+ if (!modifiers) return;
+ let special;
+ if (specialModifications) {
+ special = Modifications.specials[specialModifications];
+ }
+ for (const i in modifiers) {
+ // Some special modifications
+ // Look up the modifiers to find what we need to do
+ const findMod = val => Object.keys(Modifications.modifierActions).find(elem => elem.toString().toLowerCase().replace(/(outfittingfieldtype_|persecond)/igm, '') === val.toString().toLowerCase().replace(/(outfittingfieldtype_|persecond)/igm, ''));
+ const modifierActions = Modifications.modifierActions[findMod(modifiers[i].Label)];
+ // TODO: Figure out how to scale this value.
+ if (!!modifiers[i].LessIsGood) {
+
+ }
+ let value = (modifiers[i].Value / modifiers[i].OriginalValue * 100 - 100) * 100;
+ if (value === Infinity) {
+ value = modifiers[i].Value * 100;
+ }
+ if (modifiers[i].Label.search('Resistance') >= 0) {
+ value = (modifiers[i].Value * 100) - (modifiers[i].OriginalValue * 100);
+ }
+ // Carry out the required changes
+ for (const action in modifierActions) {
+ if (isNaN(modifierActions[action])) {
+ module.setModValue(action, modifierActions[action]);
+ } else {
+ module.setModValue(action, value);
+ }
+ }
+ }
+
+ // Add the blueprint definition, grade and special
+ if (blueprint) {
+ module.blueprint = getBlueprint(blueprint, module);
+ if (grade) {
+ module.blueprint.grade = Number(grade);
+ }
+ if (special) {
+ module.blueprint.special = special;
+ }
+ }
+}