diff --git a/src/app/components/HardpointSlot.jsx b/src/app/components/HardpointSlot.jsx index 00ddafb4..a9f4155c 100644 --- a/src/app/components/HardpointSlot.jsx +++ b/src/app/components/HardpointSlot.jsx @@ -1,5 +1,6 @@ import React from 'react'; import Slot from './Slot'; +import Persist from '../stores/Persist'; import { DamageKinetic, DamageThermal, DamageExplosive, MountFixed, MountGimballed, MountTurret, ListModifications, Modified } from './SvgIcons'; import { Modifications } from 'coriolis-data/dist'; import { stopCtxPropagation } from '../utils/UtilityFunctions'; @@ -41,6 +42,7 @@ export default class HardpointSlot extends Slot { let { drag, drop } = this.props; let { termtip, tooltip } = this.context; let validMods = Modifications.validity[m.grp] || []; + let showModuleResistances = Persist.showModuleResistances(); return
@@ -65,7 +67,11 @@ export default class HardpointSlot extends Slot { { m.getRange() && !m.getDps() ?
{translate('Range')} : {formats.round(m.getRange() / 1000)}{u.km}
: null } { m.getShieldBoost() ?
+{formats.pct1(m.getShieldBoost())}
: null } { m.getAmmo() ?
{translate('ammunition')}: {formats.int(m.getClip())}/{formats.int(m.getAmmo())}
: null } + { showModuleResistances && m.getExplosiveResistance() ?
{translate('explres')}: {formats.pct(m.getExplosiveResistance())}
: null } + { showModuleResistances && m.getKineticResistance() ?
{translate('kinres')}: {formats.pct(m.getKineticResistance())}
: null } + { showModuleResistances && m.getThermalResistance() ?
{translate('thermres')}: {formats.pct(m.getThermalResistance())}
: null } { m && validMods.length > 0 ?
: null } +
; } else { diff --git a/src/app/components/Header.jsx b/src/app/components/Header.jsx index db2294d5..8b679a6b 100644 --- a/src/app/components/Header.jsx +++ b/src/app/components/Header.jsx @@ -203,6 +203,13 @@ export default class Header extends TranslatedComponent { Persist.showTooltips(!Persist.showTooltips()); } + /** + * Toggle module resistances setting + */ + _toggleModuleResistances() { + Persist.showModuleResistances(!Persist.showModuleResistances()); + } + /** * Show delete all modal * @param {SyntheticEvent} e Event @@ -359,6 +366,7 @@ export default class Header extends TranslatedComponent { _getSettingsMenu() { let translate = this.context.language.translate; let tips = Persist.showTooltips(); + let moduleResistances = Persist.showModuleResistances(); return (
e.stopPropagation() }> @@ -376,6 +384,10 @@ export default class Header extends TranslatedComponent { {translate('tooltips')} {(tips ? '✓' : '✗')} + + {translate('module resistances')} + {(moduleResistances ? '✓' : '✗')} + {translate('insurance')} @@ -438,6 +450,7 @@ export default class Header extends TranslatedComponent { Persist.addListener('deletedAll', update); Persist.addListener('builds', update); Persist.addListener('tooltips', update); + Persist.addListener('moduleresistances', update); } /** diff --git a/src/app/components/InternalSlot.jsx b/src/app/components/InternalSlot.jsx index fb81b260..9cde4e9c 100644 --- a/src/app/components/InternalSlot.jsx +++ b/src/app/components/InternalSlot.jsx @@ -1,5 +1,6 @@ import React from 'react'; import Slot from './Slot'; +import Persist from '../stores/Persist'; import { ListModifications, Modified } from './SvgIcons'; import { Modifications } from 'coriolis-data/dist'; import { stopCtxPropagation } from '../utils/UtilityFunctions'; @@ -23,6 +24,7 @@ export default class InternalSlot extends Slot { let { drag, drop, ship } = this.props; let { termtip, tooltip } = this.context; let validMods = Modifications.validity[m.grp] || []; + let showModuleResistances = Persist.showModuleResistances(); let mass = m.getMass() || m.cargo || m.fuel || 0; return
@@ -51,6 +53,10 @@ export default class InternalSlot extends Slot { { m.rangeRating ?
{translate('range')}: {m.rangeRating}
: null } { m.getHullReinforcement() ?
+{formats.int(m.getHullReinforcement() + ship.baseArmour * m.getModValue('hullboost') / 10000)} {translate('armour')}
: null } { m.passengers ?
{translate('passengers')}: {m.passengers}
: null } + { showModuleResistances && m.getExplosiveResistance() ?
{translate('explres')}: {formats.pct(m.getExplosiveResistance())}
: null } + { showModuleResistances && m.getKineticResistance() ?
{translate('kinres')}: {formats.pct(m.getKineticResistance())}
: null } + { showModuleResistances && m.getThermalResistance() ?
{translate('thermres')}: {formats.pct(m.getThermalResistance())}
: null } + { m && validMods.length > 0 ?
: null }
diff --git a/src/app/components/ModalImport.jsx b/src/app/components/ModalImport.jsx index 1d1a56d4..b698a9d9 100644 --- a/src/app/components/ModalImport.jsx +++ b/src/app/components/ModalImport.jsx @@ -332,9 +332,9 @@ export default class ModalImport extends TranslatedComponent { throw 'Must be an object or array!'; } - if (importData.cockpitBreached != null) { // Only the companion API has this information + if (importData.modules != null && importData.modules.Armour != null) { // Only the companion API has this information this._importCompanionApiBuild(importData); // Single sihp definition - } else if (importData.ship != null && importData.ship.cockpitBreached != null) { // Only the companion API has this information + } else if (importData.ship != null && importData.ship.modules != null && importData.ship.modules.Armour != null) { // Only the companion API has this information this._importCompanionApiBuild(importData.ship); // Complete API dump } else if (importData instanceof Array) { // Must be detailed export json this._importDetailedArray(importData); diff --git a/src/app/components/StandardSlot.jsx b/src/app/components/StandardSlot.jsx index 8f8537eb..dc8cbe96 100644 --- a/src/app/components/StandardSlot.jsx +++ b/src/app/components/StandardSlot.jsx @@ -1,5 +1,6 @@ import React from 'react'; import cn from 'classnames'; +import Persist from '../stores/Persist'; import TranslatedComponent from './TranslatedComponent'; import { jumpRange } from '../shipyard/Calculations'; import { diffDetails } from '../utils/SlotFunctions'; @@ -46,6 +47,7 @@ export default class StandardSlot extends TranslatedComponent { let classRating = m.class + m.rating; let menu; let validMods = m == null ? [] : (Modifications.validity[m.grp] || []); + let showModuleResistances = Persist.showModuleResistances(); let mass = m.getMass() || m.cargo || m.fuel || 0; if (!selected) { @@ -94,6 +96,9 @@ export default class StandardSlot extends TranslatedComponent { { m.getWeaponsCapacity() ?
{translate('WEP')}: {formats.f1(m.getWeaponsCapacity())}{units.MJ} / {formats.f1(m.getWeaponsRechargeRate())}{units.MW}
: null } { m.getSystemsCapacity() ?
{translate('SYS')}: {formats.f1(m.getSystemsCapacity())}{units.MJ} / {formats.f1(m.getSystemsRechargeRate())}{units.MW}
: null } { m.getEnginesCapacity() ?
{translate('ENG')}: {formats.f1(m.getEnginesCapacity())}{units.MJ} / {formats.f1(m.getEnginesRechargeRate())}{units.MW}
: null } + { showModuleResistances && m.getExplosiveResistance() ?
{translate('explres')}: {formats.pct(m.getExplosiveResistance())}
: null } + { showModuleResistances && m.getKineticResistance() ?
{translate('kinres')}: {formats.pct(m.getKineticResistance())}
: null } + { showModuleResistances && m.getThermalResistance() ?
{translate('thermres')}: {formats.pct(m.getThermalResistance())}
: null } { validMods.length > 0 ?
: null }
diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js index 8eb3befc..b368115a 100755 --- a/src/app/shipyard/Module.js +++ b/src/app/shipyard/Module.js @@ -73,6 +73,14 @@ export default class Module { return result; } + /** + * Return true if this is a shield generator + * @return {Boolean} if this is a shield generator + */ + isShieldGenerator() { + return (this.grp === 'sg' || this.grp === 'psg' || this.grp === 'bsg'); + } + /** * Get the power generation of this module, taking in to account modifications * @return {Number} the power generation of this module diff --git a/src/app/stores/Persist.js b/src/app/stores/Persist.js index 63473691..4ef740f6 100644 --- a/src/app/stores/Persist.js +++ b/src/app/stores/Persist.js @@ -11,6 +11,7 @@ const LS_KEY_MOD_DISCOUNT = 'moduleDiscount'; const LS_KEY_STATE = 'state'; const LS_KEY_SIZE_RATIO = 'sizeRatio'; const LS_KEY_TOOLTIPS = 'tooltips'; +const LS_KEY_MODULE_RESISTANCES = 'moduleResistances'; let LS; @@ -81,6 +82,7 @@ export class Persist extends EventEmitter { LS = null; } + let moduleResistances = _get(LS_KEY_MODULE_RESISTANCES); let tips = _get(LS_KEY_TOOLTIPS); let insurance = _getString(LS_KEY_INSURANCE); let shipDiscount = _get(LS_KEY_SHIP_DISCOUNT); @@ -99,6 +101,7 @@ export class Persist extends EventEmitter { this.state = _get(LS_KEY_STATE); this.sizeRatio = _get(LS_KEY_SIZE_RATIO) || 1; this.tooltipsEnabled = tips === null ? true : tips; + this.moduleResistancesEnabled = moduleResistances === null ? true : moduleResistances; if (LS) { window.addEventListener('storage', this.onStorageChange); @@ -143,6 +146,10 @@ export class Persist extends EventEmitter { this.tooltipsEnabled = !!newValue && newValue.toLowerCase() == 'true'; this.emit('tooltips', this.tooltipsEnabled); break; + case LS_KEY_MODULE_RESISTANCES: + this.moduleResistancesEnabled = !!newValue && newValue.toLowerCase() == 'true'; + this.emit('moduleresistances', this.moduleResistancesEnabled); + break; } } catch (e) { // On JSON.Parse Error - don't sync or do anything @@ -183,6 +190,21 @@ export class Persist extends EventEmitter { return this.tooltipsEnabled; } + /** + * Show module resistances setting + * @param {boolean} show Optional - update setting + * @return {boolean} True if module resistances should be shown + */ + showModuleResistances(show) { + if (show !== undefined) { + this.moduleResistancesEnabled = !!show; + _put(LS_KEY_MODULE_RESISTANCES, this.moduleResistancesEnabled); + this.emit('moduleresistances', this.moduleResistancesEnabled); + } + + return this.moduleResistancesEnabled; + } + /** * Persist a ship build in local storage. * diff --git a/src/app/utils/CompanionApiUtils.js b/src/app/utils/CompanionApiUtils.js index c43bf815..7fed861f 100644 --- a/src/app/utils/CompanionApiUtils.js +++ b/src/app/utils/CompanionApiUtils.js @@ -247,12 +247,11 @@ export function shipFromJson(json) { let internalSlot = null; while (internalSlot === null && internalSlotNum < 99) { // Slot numbers are not contiguous so handle skips - const internalName = 'Slot' + (internalSlotNum < 9 ? '0' : '') + internalSlotNum + '_Size' + internalClassNum; + const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + internalClassNum; if (json.modules[internalName]) { internalSlot = json.modules[internalName]; - } else { - internalSlotNum++; } + internalSlotNum++; } if (!internalSlot.module) { // No module @@ -304,6 +303,35 @@ function _addModifications(module, modifiers) { module.setModValue('shieldboost', alteredBoost / module.shieldboost); } + // Shield booster resistance is actually a damage modifier, so needs to be inverted. + if (module.grp === 'sb') { + if (module.getModValue('explres')) { + module.setModValue('explres', module.getModValue('explres') * -1); + } + if (module.getModValue('kinres')) { + module.setModValue('kinres', module.getModValue('kinres') * -1); + } + if (module.getModValue('thermres')) { + module.setModValue('thermres', module.getModValue('thermres') * -1); + } + } + + // Shield generator resistance is actually a damage modifier, so needs to be inverted. + // In addition, the modification is based off the inherent resistance of the module + if (module.isShieldGenerator()) { + if (module.getModValue('explres')) { + module.setModValue('explres', (1 - (1 - module.explres) * (1 + module.getModValue('explres'))) - module.explres); + } + if (module.getModValue('kinres')) { + module.setModValue('kinres', (1 - (1 - module.kinres) * (1 + module.getModValue('kinres')))- module.kinres); + } + if (module.getModValue('thermres')) { + module.setModValue('thermres', (1 - (1 - module.thermres) * (1 + module.getModValue('thermres'))) - module.thermres); + } + } + + //TODO do this for armour resistances as well ? + // Jitter is in degrees not % so need to divide it by 100 to obtain the correct number if (module.getModValue('jitter')) { module.setModValue('jitter', module.getModValue('jitter') / 100); @@ -313,5 +341,5 @@ function _addModifications(module, modifiers) { if (module.getModValue('rof')) { module.setModValue('rof', (1 / (1 + module.getModValue('jitter'))) - 1); } -} +}