Make ship summary numbers react to pips/fuel/cargo/etc

This commit is contained in:
Cmdr McDonald
2017-03-17 14:04:07 +00:00
parent 7259a666eb
commit 23c4da55de
7 changed files with 48 additions and 72 deletions

View File

@@ -58,13 +58,13 @@ export default class Movement extends TranslatedComponent {
<path d="M342 450l.4 1.5-16.2 10.7-.4-.2-3.5-13 .3-.3L342 450zm-14.3 7.6l7.7-5-9.2-.6 1.5 5.6z"/> <path d="M342 450l.4 1.5-16.2 10.7-.4-.2-3.5-13 .3-.3L342 450zm-14.3 7.6l7.7-5-9.2-.6 1.5 5.6z"/>
// Speed // Speed
<text x="470" y="30" strokeWidth='1'>{formats.int(ship.calcSpeed(eng, fuel, cargo, boost))}m/s</text> <text x="470" y="30" strokeWidth='0'>{formats.int(ship.calcSpeed(eng, fuel, cargo, boost))}m/s</text>
// Pitch // Pitch
<text x="355" y="410" strokeWidth='1'>{formats.int(ship.calcPitch(eng, fuel, cargo, boost))}°/s</text> <text x="355" y="410" strokeWidth='0'>{formats.int(ship.calcPitch(eng, fuel, cargo, boost))}°/s</text>
// Roll // Roll
<text x="450" y="110" strokeWidth='1'>{formats.int(ship.calcRoll(eng, fuel, cargo, boost))}°/s</text> <text x="450" y="110" strokeWidth='0'>{formats.int(ship.calcRoll(eng, fuel, cargo, boost))}°/s</text>
// Yaw // Yaw
<text x="160" y="430" strokeWidth='1'>{formats.int(ship.calcYaw(eng, fuel, cargo, boost))}°/s</text> <text x="160" y="430" strokeWidth='0'>{formats.int(ship.calcYaw(eng, fuel, cargo, boost))}°/s</text>
</svg> </svg>
</span>); </span>);
} }

View File

@@ -138,7 +138,7 @@ export default class OutfittingSubpages extends TranslatedComponent {
} }
return ( return (
<div className='group full' style={{ minHeight: '900px' }}> <div className='group full' style={{ minHeight: '1000px' }}>
<table className='tabs'> <table className='tabs'>
<thead> <thead>
<tr> <tr>

View File

@@ -2,6 +2,7 @@ import React from 'react';
import TranslatedComponent from './TranslatedComponent'; import TranslatedComponent from './TranslatedComponent';
import cn from 'classnames'; import cn from 'classnames';
import { Warning } from './SvgIcons'; import { Warning } from './SvgIcons';
import * as Calc from '../shipyard/Calculations';
/** /**
* Ship Summary Table / Stats * Ship Summary Table / Stats
@@ -9,7 +10,13 @@ import { Warning } from './SvgIcons';
export default class ShipSummaryTable extends TranslatedComponent { export default class ShipSummaryTable extends TranslatedComponent {
static propTypes = { static propTypes = {
ship: React.PropTypes.object.isRequired ship: React.PropTypes.object.isRequired,
sys: React.PropTypes.number.isRequired,
eng: React.PropTypes.number.isRequired,
wep: React.PropTypes.number.isRequired,
cargo: React.PropTypes.number.isRequired,
fuel: React.PropTypes.number.isRequired,
marker: React.PropTypes.string.isRequired,
}; };
/** /**
@@ -17,7 +24,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
* @return {React.Component} Summary table * @return {React.Component} Summary table
*/ */
render() { render() {
let ship = this.props.ship; const { ship, fuel, eng, cargo, boost } = this.props;
let { language, tooltip, termtip } = this.context; let { language, tooltip, termtip } = this.context;
let translate = language.translate; let translate = language.translate;
let u = language.units; let u = language.units;
@@ -49,8 +56,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
<th colSpan={3}>{translate('mass')}</th> <th colSpan={3}>{translate('mass')}</th>
<th rowSpan={2}>{translate('cargo')}</th> <th rowSpan={2}>{translate('cargo')}</th>
<th rowSpan={2}>{translate('fuel')}</th> <th rowSpan={2}>{translate('fuel')}</th>
<th colSpan={3}>{translate('jump range')}</th> <th colSpan={2}>{translate('jump range')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_FASTEST_RANGE')} onMouseLeave={hide} colSpan={3}>{translate('fastest range')}</th>
<th rowSpan={2}>{translate('crew')}</th> <th rowSpan={2}>{translate('crew')}</th>
<th onMouseEnter={termtip.bind(null, 'mass lock factor')} onMouseLeave={hide} rowSpan={2}>{translate('MLF')}</th> <th onMouseEnter={termtip.bind(null, 'mass lock factor')} onMouseLeave={hide} rowSpan={2}>{translate('MLF')}</th>
</tr> </tr>
@@ -58,36 +64,28 @@ export default class ShipSummaryTable extends TranslatedComponent {
<th className='lft'>{translate('hull')}</th> <th className='lft'>{translate('hull')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_UNLADEN', { cap: 0 })} onMouseLeave={hide}>{translate('unladen')}</th> <th onMouseEnter={termtip.bind(null, 'PHRASE_UNLADEN', { cap: 0 })} onMouseLeave={hide}>{translate('unladen')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_LADEN', { cap: 0 })} onMouseLeave={hide}>{translate('laden')}</th> <th onMouseEnter={termtip.bind(null, 'PHRASE_LADEN', { cap: 0 })} onMouseLeave={hide}>{translate('laden')}</th>
<th className='lft'>{translate('max')}</th> <th className='lft'>{translate('single')}</th>
<th>{translate('full tank')}</th> <th>{translate('total')}</th>
<th>{translate('laden')}</th>
<th className='lft'>{translate('jumps')}</th>
<th>{translate('unladen')}</th>
<th>{translate('laden')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>{ ship.canThrust() ? <span>{int(ship.topSpeed)} {u['m/s']}</span> : <span className='warning'>0 <Warning/></span> }</td> <td>{ ship.canThrust() ? <span>{int(ship.calcSpeed(eng, fuel, cargo, false))}{u['m/s']}</span> : <span className='warning'>0 <Warning/></span> }</td>
<td>{ ship.canBoost() ? <span>{int(ship.topBoost)} {u['m/s']}</span> : <span className='warning'>0 <Warning/></span> }</td> <td>{ ship.canBoost() ? <span>{int(ship.calcSpeed(eng, fuel, cargo, true))}{u['m/s']}</span> : <span className='warning'>0 <Warning/></span> }</td>
<td>{f1(ship.totalDps)}</td> <td>{f1(ship.totalDps)}</td>
<td>{f1(ship.totalEps)}</td> <td>{f1(ship.totalEps)}</td>
<td>{ship.timeToDrain === Infinity ? '∞' : time(ship.timeToDrain)}</td> <td>{ship.timeToDrain === Infinity ? '∞' : time(ship.timeToDrain)}</td>
<td>{f1(ship.totalHps)}</td> <td>{f1(ship.totalHps)}</td>
<td>{int(ship.hardness)}</td> <td>{int(ship.hardness)}</td>
<td>{int(ship.armour)}</td> <td>{int(ship.armour)}</td>
<td className={sgClassNames}>{int(ship.shield)} {u.MJ}</td> <td className={sgClassNames}>{int(ship.shield)}{u.MJ}</td>
<td>{ship.hullMass} {u.T}</td> <td>{ship.hullMass}{u.T}</td>
<td>{int(ship.unladenMass)} {u.T}</td> <td>{int(ship.unladenMass)}{u.T}</td>
<td>{int(ship.ladenMass)} {u.T}</td> <td>{int(ship.ladenMass)}{u.T}</td>
<td>{round(ship.cargoCapacity)} {u.T}</td> <td>{round(ship.cargoCapacity)}{u.T}</td>
<td>{round(ship.fuelCapacity)} {u.T}</td> <td>{round(ship.fuelCapacity)}{u.T}</td>
<td>{f2(ship.unladenRange)} {u.LY}</td> <td>{f2(Calc.jumpRange(ship.unladenMass + fuel + cargo, ship.standard[2].m, fuel))}{u.LY}</td>
<td>{f2(ship.fullTankRange)} {u.LY}</td> <td>{f2(Calc.totalJumpRange(ship.unladenMass + fuel + cargo, ship.standard[2].m, fuel))}{u.LY}</td>
<td>{f2(ship.ladenRange)} {u.LY}</td>
<td>{int(ship.maxJumpCount)}</td>
<td>{f2(ship.unladenFastestRange)} {u.LY}</td>
<td>{f2(ship.ladenFastestRange)} {u.LY}</td>
<td>{ship.crew}</td> <td>{ship.crew}</td>
<td>{ship.masslock}</td> <td>{ship.masslock}</td>
</tr> </tr>

View File

@@ -375,6 +375,7 @@ export default class OutfittingPage extends Page {
// Markers are used to propagate state changes without requiring a deep comparison of the ship, as that takes a long time // Markers are used to propagate state changes without requiring a deep comparison of the ship, as that takes a long time
const boostMarker = `${ship.canBoost()}`; const boostMarker = `${ship.canBoost()}`;
const shipSummaryMarker = `${ship.toString()}:${eng}:${fuel}:${cargo}`;
return ( return (
<div id='outfit' className={'page'} style={{ fontSize: (sizeRatio * 0.9) + 'em' }}> <div id='outfit' className={'page'} style={{ fontSize: (sizeRatio * 0.9) + 'em' }}>
@@ -410,7 +411,7 @@ export default class OutfittingPage extends Page {
</div> </div>
{/* Main tables */} {/* Main tables */}
<ShipSummaryTable ship={ship} code={code} /> <ShipSummaryTable ship={ship} marker={shipSummaryMarker} eng={eng} sys={sys} wep={wep} cargo={cargo} fuel={fuel}/>
<StandardSlotSection ship={ship} code={code} onChange={shipUpdated} currentMenu={menu} /> <StandardSlotSection ship={ship} code={code} onChange={shipUpdated} currentMenu={menu} />
<InternalSlotSection ship={ship} code={iStr} onChange={shipUpdated} currentMenu={menu} /> <InternalSlotSection ship={ship} code={iStr} onChange={shipUpdated} currentMenu={menu} />
<HardpointsSlotSection ship={ship} code={hStr || ''} onChange={shipUpdated} currentMenu={menu} /> <HardpointsSlotSection ship={ship} code={hStr || ''} onChange={shipUpdated} currentMenu={menu} />

View File

@@ -9,33 +9,33 @@ import Module from './Module';
* @return {number} Distance in Light Years * @return {number} Distance in Light Years
*/ */
export function jumpRange(mass, fsd, fuel) { export function jumpRange(mass, fsd, fuel) {
let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel; const fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel;
let fsdOptimalMass = fsd instanceof Module ? fsd.getOptMass() : fsd.optmass; const fsdOptimalMass = fsd instanceof Module ? fsd.getOptMass() : fsd.optmass;
return Math.pow(Math.min(fuel === undefined ? fsdMaxFuelPerJump : fuel, fsdMaxFuelPerJump) / fsd.fuelmul, 1 / fsd.fuelpower) * fsdOptimalMass / mass; return Math.pow(Math.min(fuel === undefined ? fsdMaxFuelPerJump : fuel, fsdMaxFuelPerJump) / fsd.fuelmul, 1 / fsd.fuelpower) * fsdOptimalMass / mass;
} }
/** /**
* Calculate the fastest (total) range based on mass and a specific FSD, and all fuel available * Calculate the total jump range based on mass and a specific FSD, and all fuel available
* *
* @param {number} mass Mass of a ship: laden, unlanden, partially laden, etc * @param {number} mass Mass of a ship: laden, unlanden, partially laden, etc
* @param {object} fsd The FDS object/component with maxfuel, fuelmul, fuelpower, optmass * @param {object} fsd The FDS object/component with maxfuel, fuelmul, fuelpower, optmass
* @param {number} fuel The total fuel available * @param {number} fuel The total fuel available
* @return {number} Distance in Light Years * @return {number} Distance in Light Years
*/ */
export function fastestRange(mass, fsd, fuel) { export function totalJumpRange(mass, fsd, fuel) {
let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel; const fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel;
let fsdOptimalMass = fsd instanceof Module ? fsd.getOptMass() : fsd.optmass; const fsdOptimalMass = fsd instanceof Module ? fsd.getOptMass() : fsd.optmass;
let fuelRemaining = fuel % fsdMaxFuelPerJump; // Fuel left after making N max jumps
let jumps = Math.floor(fuel / fsdMaxFuelPerJump); let fuelRemaining = fuel;
mass += fuelRemaining; let totalRange = 0;
// Going backwards, start with the last jump using the remaining fuel while (fuelRemaining > 0) {
let fastestRange = fuelRemaining > 0 ? Math.pow(fuelRemaining / fsd.fuelmul, 1 / fsd.fuelpower) * fsdOptimalMass / mass : 0; const fuelForThisJump = Math.min(fuelRemaining, fsdMaxFuelPerJump);
// For each max fuel jump, calculate the max jump range based on fuel mass left in the tank totalRange += this.jumpRange(mass, fsd, fuelForThisJump);
for (let j = 0; j < jumps; j++) { // Mass is reduced
mass += fsd.maxfuel; mass -= fuelForThisJump;
fastestRange += Math.pow(fsdMaxFuelPerJump / fsd.fuelmul, 1 / fsd.fuelpower) * fsdOptimalMass / mass; fuelRemaining -= fuelForThisJump;
} }
return fastestRange; return totalRange;
}; };
/** /**

View File

@@ -138,17 +138,6 @@ export default class Ship {
this.standard[4].m.getEnginesCapacity() > this.boostEnergy; // PD capacitor is sufficient for boost this.standard[4].m.getEnginesCapacity() > this.boostEnergy; // PD capacitor is sufficient for boost
} }
/**
* Calculate hypothetical jump range using the installed FSD and the
* specified mass which can be more or less than ships actual mass
* @param {Number} fuel Fuel available in tons
* @param {Number} cargo Cargo in tons
* @return {Number} Jump range in Light Years
*/
calcJumpRangeWith(fuel, cargo) {
return Calc.jumpRange(this.unladenMass + fuel + cargo, this.standard[2].m, fuel);
}
/** /**
* Calculate the hypothetical laden jump range based on a potential change in mass, fuel, or FSD * Calculate the hypothetical laden jump range based on a potential change in mass, fuel, or FSD
* @param {Number} massDelta Optional - Change in laden mass (mass + cargo + fuel) * @param {Number} massDelta Optional - Change in laden mass (mass + cargo + fuel)
@@ -173,17 +162,6 @@ export default class Ship {
return Calc.jumpRange(this.unladenMass + (massDelta || 0) + Math.min(fsdMaxFuelPerJump, fuel || this.fuelCapacity), fsd || this.standard[2].m, fuel); return Calc.jumpRange(this.unladenMass + (massDelta || 0) + Math.min(fsdMaxFuelPerJump, fuel || this.fuelCapacity), fsd || this.standard[2].m, fuel);
} }
/**
* Calculate cumulative (total) jump range when making longest jumps using the installed FSD and the
* specified mass which can be more or less than ships actual mass
* @param {Number} fuel Fuel available in tons
* @param {Number} cargo Cargo in tons
* @return {Number} Total/Cumulative Jump range in Light Years
*/
calcFastestRangeWith(fuel, cargo) {
return Calc.fastestRange(this.unladenMass + fuel + cargo, this.standard[2].m, fuel);
}
/** /**
* Calculate the hypothetical top speeds at cargo and fuel tonnage * Calculate the hypothetical top speeds at cargo and fuel tonnage
* @param {Number} fuel Fuel available in tons * @param {Number} fuel Fuel available in tons
@@ -1398,9 +1376,9 @@ export default class Ship {
this.unladenRange = this.calcUnladenRange(); // Includes fuel weight for jump this.unladenRange = this.calcUnladenRange(); // Includes fuel weight for jump
this.fullTankRange = Calc.jumpRange(unladenMass + fuelCapacity, fsd); // Full Tank this.fullTankRange = Calc.jumpRange(unladenMass + fuelCapacity, fsd); // Full Tank
this.ladenRange = this.calcLadenRange(); // Includes full tank and caro this.ladenRange = this.calcLadenRange(); // Includes full tank and caro
this.unladenFastestRange = Calc.fastestRange(unladenMass, fsd, fuelCapacity); this.unladenFastestRange = Calc.totalJumpRange(unladenMass + this.fuelCapacity, fsd, fuelCapacity);
this.ladenFastestRange = Calc.fastestRange(unladenMass + this.cargoCapacity, fsd, fuelCapacity); this.ladenFastestRange = Calc.totalJumpRange(unladenMass + this.fuelCapacity + this.cargoCapacity, fsd, fuelCapacity);
this.maxJumpCount = Math.ceil(fuelCapacity / fsd.maxfuel); this.maxJumpCount = Math.ceil(fuelCapacity / fsd.getMaxFuelPerJump());
return this; return this;
} }

View File

@@ -11,7 +11,6 @@
.menu { .menu {
position: relative; position: relative;
z-index: 1;
cursor: default; cursor: default;
&.r { &.r {