diff --git a/src/app/components/AvailableModulesMenu.jsx b/src/app/components/AvailableModulesMenu.jsx index fba8ad15..1d3df29c 100644 --- a/src/app/components/AvailableModulesMenu.jsx +++ b/src/app/components/AvailableModulesMenu.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import * as ModuleUtils from '../shipyard/ModuleUtils'; import { findDOMNode } from 'react-dom'; import TranslatedComponent from './TranslatedComponent'; import { stopCtxPropagation } from '../utils/UtilityFunctions'; @@ -213,7 +214,14 @@ export default class AvailableModulesMenu extends TranslatedComponent { for (let i = 0; i < sortedModules.length; i++) { let m = sortedModules[i]; let mount = null; - let disabled = m.maxmass && (mass + (m.mass ? m.mass : 0)) > m.maxmass; + let disabled = false; + if (ModuleUtils.isShieldGenerator(m.grp)) { + // Shield generators care about maximum hull mass + disabled = mass > m.maxmass; + } else if (m.maxmass) { + // Thrusters care about total mass + disabled = mass + m.mass > m.maxmass; + } let active = mountedModule && mountedModule.id === m.id; let classes = cn(m.name ? 'lc' : 'c', { warning: !disabled && warningFunc && warningFunc(m), diff --git a/src/app/components/OutfittingSubpages.jsx b/src/app/components/OutfittingSubpages.jsx index 2d25037c..e849ecfe 100644 --- a/src/app/components/OutfittingSubpages.jsx +++ b/src/app/components/OutfittingSubpages.jsx @@ -85,12 +85,12 @@ export default class OutfittingSubpages extends TranslatedComponent { _profilesTab() { const { ship, opponent, cargo, fuel, eng, boost, engagementRange, opponentSys } = this.props; const { translate } = this.context.language; - let realBoost = boost && ship.canBoost(); + let realBoost = boost && ship.canBoost(cargo, fuel); Persist.setOutfittingTab('profiles'); const engineProfileMarker = `${ship.toString()}:${cargo}:${fuel}:${eng}:${realBoost}`; const fsdProfileMarker = `${ship.toString()}:${cargo}:${fuel}`; - const movementMarker = `${ship.topSpeed}:${ship.pitch}:${ship.roll}:${ship.yaw}:${ship.canBoost()}`; + const movementMarker = `${ship.topSpeed}:${ship.pitch}:${ship.roll}:${ship.yaw}:${ship.canBoost(cargo, fuel)}`; const damageMarker = `${ship.toString()}:${opponent.toString()}:${engagementRange}:${opponentSys}`; return
diff --git a/src/app/components/ShipSummaryTable.jsx b/src/app/components/ShipSummaryTable.jsx index 9212bb1b..881a3b25 100644 --- a/src/app/components/ShipSummaryTable.jsx +++ b/src/app/components/ShipSummaryTable.jsx @@ -11,6 +11,8 @@ export default class ShipSummaryTable extends TranslatedComponent { static propTypes = { ship: React.PropTypes.object.isRequired, + cargo: React.PropTypes.number.isRequired, + fuel: React.PropTypes.number.isRequired, marker: React.PropTypes.string.isRequired, }; @@ -19,7 +21,7 @@ export default class ShipSummaryTable extends TranslatedComponent { * @return {React.Component} Summary table */ render() { - const { ship } = this.props; + const { ship, cargo, fuel } = this.props; let { language, tooltip, termtip } = this.context; let translate = language.translate; let u = language.units; @@ -31,9 +33,9 @@ export default class ShipSummaryTable extends TranslatedComponent { const sgClassNames = cn({ warning: shieldGenerator && !ship.shield, muted: !shieldGenerator }); const sgTooltip = shieldGenerator ? 'TT_SUMMARY_SHIELDS' : 'TT_SUMMARY_SHIELDS_NONFUNCTIONAL'; const timeToDrain = Calc.timeToDrainWep(ship, 4); - const canThrust = ship.canThrust(); + const canThrust = ship.canThrust(cargo, fuel); const speedTooltip = canThrust ? 'TT_SUMMARY_SPEED' : 'TT_SUMMARY_SPEED_NONFUNCTIONAL'; - const canBoost = ship.canBoost(); + const canBoost = ship.canBoost(cargo, fuel); const boostTooltip = canBoost ? 'TT_SUMMARY_BOOST' : canThrust ? 'TT_SUMMARY_BOOST_NONFUNCTIONAL' : 'TT_SUMMARY_SPEED_NONFUNCTIONAL'; return
diff --git a/src/app/components/StandardSlot.jsx b/src/app/components/StandardSlot.jsx index 2d1fda65..10d4a69c 100644 --- a/src/app/components/StandardSlot.jsx +++ b/src/app/components/StandardSlot.jsx @@ -5,6 +5,7 @@ import TranslatedComponent from './TranslatedComponent'; import { diffDetails } from '../utils/SlotFunctions'; import AvailableModulesMenu from './AvailableModulesMenu'; import ModificationsMenu from './ModificationsMenu'; +import * as ModuleUtils from '../shipyard/ModuleUtils'; import { ListModifications, Modified } from './SvgIcons'; import { Modifications } from 'coriolis-data/dist'; import { stopCtxPropagation } from '../utils/UtilityFunctions'; @@ -82,7 +83,7 @@ export default class StandardSlot extends TranslatedComponent { menu = m instanceof Module ? m.getMaxMass() < (ship.ladenMass - st[1].mass + m.mass) : m.maxmass < (ship.ladenMass - st[1].mass + m.mass)} + 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)} />; diff --git a/src/app/pages/OutfittingPage.jsx b/src/app/pages/OutfittingPage.jsx index 575b9f96..358443f3 100644 --- a/src/app/pages/OutfittingPage.jsx +++ b/src/app/pages/OutfittingPage.jsx @@ -545,11 +545,11 @@ export default class OutfittingPage extends Page { const _pStr = `${ship.getPowerEnabledString()}${ship.getPowerPrioritiesString()}`; const _mStr = ship.getModificationsString(); - const standardSlotMarker = `${ship.name}${_sStr}${_pStr}${_mStr}`; + const standardSlotMarker = `${ship.name}${_sStr}${_pStr}${_mStr}${ship.ladenMass}${cargo}${fuel}`; const internalSlotMarker = `${ship.name}${_iStr}${_pStr}${_mStr}`; const hardpointsSlotMarker = `${ship.name}${_hStr}${_pStr}${_mStr}`; - const boostMarker = `${ship.canBoost()}`; - const shipSummaryMarker = `${ship.name}${_sStr}${_iStr}${_hStr}${_pStr}${_mStr}`; + const boostMarker = `${ship.canBoost(cargo, fuel)}`; + const shipSummaryMarker = `${ship.name}${_sStr}${_iStr}${_hStr}${_pStr}${_mStr}${ship.ladenMass}${ship.cargo}${ship.fuel}`; return (
@@ -585,8 +585,8 @@ export default class OutfittingPage extends Page {
{/* Main tables */} - - + + diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js index 37984d85..db4cb8a1 100755 --- a/src/app/shipyard/Module.js +++ b/src/app/shipyard/Module.js @@ -162,14 +162,6 @@ 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/shipyard/Ship.js b/src/app/shipyard/Ship.js index 020e32bc..0de8b2ef 100755 --- a/src/app/shipyard/Ship.js +++ b/src/app/shipyard/Ship.js @@ -123,19 +123,23 @@ export default class Ship { /** * Can the ship thrust/move + * @param {Number} cargo Amount of cargo in the ship + * @param {Number} fuel Amount of fuel in the ship * @return {[type]} True if thrusters operational */ - canThrust() { + canThrust(cargo, fuel) { return this.getSlotStatus(this.standard[1]) == 3 && // Thrusters are powered - this.ladenMass < this.standard[1].m.getMaxMass(); // Max mass not exceeded + this.unladenMass + cargo + fuel < this.standard[1].m.getMaxMass(); // Max mass not exceeded } /** * Can the ship boost + * @param {Number} cargo Amount of cargo in the ship + * @param {Number} fuel Amount of fuel in the ship * @return {[type]} True if boost capable */ - canBoost() { - return this.canThrust() && // Thrusters operational + canBoost(cargo, fuel) { + return this.canThrust(cargo, fuel) && // Thrusters operational this.standard[4].m.getEnginesCapacity() > this.boostEnergy; // PD capacitor is sufficient for boost } @@ -1185,7 +1189,7 @@ export default class Ship { updateMovement() { this.speeds = Calc.speed(this.unladenMass + this.fuelCapacity, this.speed, this.standard[1].m, this.pipSpeed); this.topSpeed = this.speeds[4]; - this.topBoost = this.canBoost() ? this.speeds[4] * this.boost / this.speed : 0; + this.topBoost = this.canBoost(0, 0) ? this.speeds[4] * this.boost / this.speed : 0; this.pitches = Calc.pitch(this.unladenMass + this.fuelCapacity, this.pitch, this.standard[1].m, this.pipSpeed); this.topPitch = this.pitches[4]; @@ -1207,7 +1211,7 @@ export default class Ship { // Obtain shield metrics with 0 pips to sys (parts affected by SYS aren't used here) const metrics = Calc.shieldMetrics(this, 0); - this.shield = metrics.generator + metrics.boosters; + this.shield = metrics.generator ? metrics.generator + metrics.boosters : 0; this.shieldExplRes = this.shield > 0 ? 1 - metrics.explosive.total : null; this.shieldKinRes = this.shield > 0 ? 1 - metrics.kinetic.total : null; this.shieldThermRes = this.shield > 0 ? 1 - metrics.thermal.total : null; @@ -1639,11 +1643,11 @@ export default class Ship { let mass = this.hullMass; mass += m.pp ? m.pp.getMass() : ModuleUtils.standard(0, '2D').getMass(); mass += m.th ? m.th.getMass() : ModuleUtils.standard(1, '2D').getMass(); - mass += m.fsd ? m.fsd.getMass() : ModuleUtils.standard(2, this.standard[2].maxClass + 'D').getMass(); + mass += m.fsd ? m.fsd.getMass() : ModuleUtils.standard(2, '2D').getMass(); mass += m.ls ? m.ls.getMass() : ModuleUtils.standard(3, this.standard[3].maxClass + 'D').getMass() * 0.3; // Lightweight grade 4 mod reduces mass by up to 70% - mass += m.pd ? m.pd.getMass() : ModuleUtils.standard(4, '2D').getMass(); - mass += m.s ? m.s.getMass() : ModuleUtils.standard(5, this.standard[5].maxClass + 'D').getMass(); - mass += m.ft ? m.ft.getMass() : ModuleUtils.standard(6, '1C').getMass(); + mass += m.pd ? m.pd.getMass() : ModuleUtils.standard(4, '1D').getMass(); + mass += m.s ? m.s.getMass() : ModuleUtils.standard(5, this.standard[5].maxClass + 'D').getMass() * 0.2; // Lightweight grade 5 mod reduces mass by up to 80% + // Ignore fuel tank as it could be empty return mass; } diff --git a/src/app/utils/CompanionApiUtils.js b/src/app/utils/CompanionApiUtils.js index 5f6df7c5..25124864 100644 --- a/src/app/utils/CompanionApiUtils.js +++ b/src/app/utils/CompanionApiUtils.js @@ -3,6 +3,7 @@ import { Modifications, Modules, Ships } from 'coriolis-data/dist'; import Module from '../shipyard/Module'; import Ship from '../shipyard/Ship'; import { getBlueprint } from '../utils/BlueprintFunctions'; +import * as ModuleUtils from '../shipyard/ModuleUtils'; // mapping from fd's ship model names to coriolis' const SHIP_FD_NAME_TO_CORIOLIS_NAME = { @@ -378,7 +379,7 @@ function _addModifications(module, modifiers, blueprint, grade) { // 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 (ModuleUtils.isShieldGenerator(module.grp)) { if (module.getModValue('explres')) { module.setModValue('explres', ((1 - (1 - module.explres) * (1 + module.getModValue('explres') / 10000)) - module.explres) * 10000); } diff --git a/src/app/utils/SlotFunctions.js b/src/app/utils/SlotFunctions.js index 8a57e63e..c2f5f4ba 100644 --- a/src/app/utils/SlotFunctions.js +++ b/src/app/utils/SlotFunctions.js @@ -1,9 +1,9 @@ import React from 'react'; import cn from 'classnames'; -import { isShieldGenerator } from '../shipyard/ModuleUtils'; import Module from '../shipyard/Module'; import { Infinite } from '../components/SvgIcons'; import Persist from '../stores/Persist'; +import * as ModuleUtils from '../shipyard/ModuleUtils'; /** * Determine if a slot on a ship can mount a module of a particular class and group @@ -159,8 +159,8 @@ export function diffDetails(language, m, mm) { let mmDps = mm ? mm.getDps() || 0 : 0; if (mDps && mDps != mmDps) propDiffs.push(
{translate('dps')}: {diff(formats.round, mDps, mmDps)}
); - let mAffectsShield = isShieldGenerator(m.grp) || m.grp == 'sb'; - let mmAffectsShield = isShieldGenerator(mm ? mm.grp : null) || mm && mm.grp == 'sb'; + let mAffectsShield = ModuleUtils.isShieldGenerator(m.grp) || m.grp == 'sb'; + let mmAffectsShield = mm ? ModuleUtils.isShieldGenerator(m.grp) || mm.grp == 'sb' : false; if (mAffectsShield || mmAffectsShield) { let shield = this.calcShieldStrengthWith(); // Get shield strength regardless of slot active / inactive let newShield = 0;