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;