mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 06:43:24 +00:00
Merge branch 'feature/fixes' into develop
This commit is contained in:
@@ -310,7 +310,7 @@
|
|||||||
"unladenRange": 18.74,
|
"unladenRange": 18.74,
|
||||||
"yaw": 10,
|
"yaw": 10,
|
||||||
"fullTankRange": 18.36,
|
"fullTankRange": 18.36,
|
||||||
"hardness": 170,
|
"hardness": 65,
|
||||||
"ladenRange": 16.59,
|
"ladenRange": 16.59,
|
||||||
"unladenFastestRange": 74.2,
|
"unladenFastestRange": 74.2,
|
||||||
"ladenFastestRange": 66.96,
|
"ladenFastestRange": 66.96,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import * as ModuleUtils from '../shipyard/ModuleUtils';
|
||||||
import { findDOMNode } from 'react-dom';
|
import { findDOMNode } from 'react-dom';
|
||||||
import TranslatedComponent from './TranslatedComponent';
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
||||||
@@ -213,7 +214,14 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
|||||||
for (let i = 0; i < sortedModules.length; i++) {
|
for (let i = 0; i < sortedModules.length; i++) {
|
||||||
let m = sortedModules[i];
|
let m = sortedModules[i];
|
||||||
let mount = null;
|
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 active = mountedModule && mountedModule.id === m.id;
|
||||||
let classes = cn(m.name ? 'lc' : 'c', {
|
let classes = cn(m.name ? 'lc' : 'c', {
|
||||||
warning: !disabled && warningFunc && warningFunc(m),
|
warning: !disabled && warningFunc && warningFunc(m),
|
||||||
|
|||||||
@@ -61,50 +61,90 @@ export default class Defence extends TranslatedComponent {
|
|||||||
const shieldSourcesData = [];
|
const shieldSourcesData = [];
|
||||||
const effectiveShieldData = [];
|
const effectiveShieldData = [];
|
||||||
const shieldDamageTakenData = [];
|
const shieldDamageTakenData = [];
|
||||||
const shieldTooltipDetails = [];
|
const shieldSourcesTt = [];
|
||||||
const shieldAbsoluteTooltipDetails = [];
|
const shieldDamageTakenAbsoluteTt = [];
|
||||||
const shieldExplosiveTooltipDetails = [];
|
const shieldDamageTakenExplosiveTt = [];
|
||||||
const shieldKineticTooltipDetails = [];
|
const shieldDamageTakenKineticTt = [];
|
||||||
const shieldThermalTooltipDetails = [];
|
const shieldDamageTakenThermalTt = [];
|
||||||
|
const effectiveShieldAbsoluteTt = [];
|
||||||
|
const effectiveShieldExplosiveTt = [];
|
||||||
|
const effectiveShieldKineticTt = [];
|
||||||
|
const effectiveShieldThermalTt = [];
|
||||||
let maxEffectiveShield = 0;
|
let maxEffectiveShield = 0;
|
||||||
if (shield.total) {
|
if (shield.total) {
|
||||||
shieldSourcesData.push({ value: Math.round(shield.generator), label: translate('generator') });
|
shieldSourcesData.push({ value: Math.round(shield.generator), label: translate('generator') });
|
||||||
shieldSourcesData.push({ value: Math.round(shield.boosters), label: translate('boosters') });
|
shieldSourcesData.push({ value: Math.round(shield.boosters), label: translate('boosters') });
|
||||||
shieldSourcesData.push({ value: Math.round(shield.cells), label: translate('cells') });
|
shieldSourcesData.push({ value: Math.round(shield.cells), label: translate('cells') });
|
||||||
|
|
||||||
if (shield.generator > 0) shieldTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}</div>);
|
if (shield.generator > 0) {
|
||||||
if (shield.boosters > 0) shieldTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}</div>);
|
shieldSourcesTt.push(<div key='generator'>{translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}</div>);
|
||||||
if (shield.cells > 0) shieldTooltipDetails.push(<div key='cells'>{translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}</div>);
|
effectiveShieldAbsoluteTt.push(<div key='generator'>{translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}</div>);
|
||||||
|
effectiveShieldExplosiveTt.push(<div key='generator'>{translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}</div>);
|
||||||
|
effectiveShieldKineticTt.push(<div key='generator'>{translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}</div>);
|
||||||
|
effectiveShieldThermalTt.push(<div key='generator'>{translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}</div>);
|
||||||
|
if (shield.boosters > 0) {
|
||||||
|
shieldSourcesTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}</div>);
|
||||||
|
effectiveShieldAbsoluteTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}</div>);
|
||||||
|
effectiveShieldExplosiveTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}</div>);
|
||||||
|
effectiveShieldKineticTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}</div>);
|
||||||
|
effectiveShieldThermalTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}</div>);
|
||||||
|
}
|
||||||
|
|
||||||
shieldAbsoluteTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(shield.absolute.generator)}</div>);
|
if (shield.cells > 0) {
|
||||||
shieldAbsoluteTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(shield.absolute.boosters)}</div>);
|
shieldSourcesTt.push(<div key='cells'>{translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}</div>);
|
||||||
shieldAbsoluteTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(shield.absolute.sys)}</div>);
|
effectiveShieldAbsoluteTt.push(<div key='cells'>{translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}</div>);
|
||||||
|
effectiveShieldExplosiveTt.push(<div key='cells'>{translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}</div>);
|
||||||
|
effectiveShieldKineticTt.push(<div key='cells'>{translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}</div>);
|
||||||
|
effectiveShieldThermalTt.push(<div key='cells'>{translate('cells') + ' ' + formats.int(shield.cells)}{units.MJ}</div>);
|
||||||
|
}
|
||||||
|
|
||||||
shieldExplosiveTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(shield.explosive.generator)}</div>);
|
// Add effective shield from resistances
|
||||||
shieldExplosiveTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(shield.explosive.boosters)}</div>);
|
const rawMj = shield.generator + shield.boosters + shield.cells;
|
||||||
shieldExplosiveTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(shield.explosive.sys)}</div>);
|
const explosiveMj = rawMj / (shield.explosive.generator * shield.explosive.boosters) - rawMj;
|
||||||
|
if (explosiveMj != 0) effectiveShieldExplosiveTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(explosiveMj)}{units.MJ}</div>);
|
||||||
|
const kineticMj = rawMj / (shield.kinetic.generator * shield.kinetic.boosters) - rawMj;
|
||||||
|
if (kineticMj != 0) effectiveShieldKineticTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(kineticMj)}{units.MJ}</div>);
|
||||||
|
const thermalMj = rawMj / (shield.thermal.generator * shield.thermal.boosters) - rawMj;
|
||||||
|
if (thermalMj != 0) effectiveShieldThermalTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(thermalMj)}{units.MJ}</div>);
|
||||||
|
|
||||||
shieldKineticTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(shield.kinetic.generator)}</div>);
|
// Add effective shield from power distributor SYS pips
|
||||||
shieldKineticTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(shield.kinetic.boosters)}</div>);
|
if (shield.absolute.sys != 1) {
|
||||||
shieldKineticTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(shield.kinetic.sys)}</div>);
|
effectiveShieldAbsoluteTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.absolute.sys - rawMj)}{units.MJ}</div>);
|
||||||
|
effectiveShieldExplosiveTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.explosive.sys - rawMj)}{units.MJ}</div>);
|
||||||
|
effectiveShieldKineticTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.kinetic.sys - rawMj)}{units.MJ}</div>);
|
||||||
|
effectiveShieldThermalTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.thermal.sys - rawMj)}{units.MJ}</div>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
shieldThermalTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(shield.thermal.generator)}</div>);
|
shieldDamageTakenAbsoluteTt.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(shield.absolute.generator)}</div>);
|
||||||
shieldThermalTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(shield.thermal.boosters)}</div>);
|
shieldDamageTakenAbsoluteTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(shield.absolute.boosters)}</div>);
|
||||||
shieldThermalTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(shield.thermal.sys)}</div>);
|
shieldDamageTakenAbsoluteTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(shield.absolute.sys)}</div>);
|
||||||
|
|
||||||
|
shieldDamageTakenExplosiveTt.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(shield.explosive.generator)}</div>);
|
||||||
|
shieldDamageTakenExplosiveTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(shield.explosive.boosters)}</div>);
|
||||||
|
shieldDamageTakenExplosiveTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(shield.explosive.sys)}</div>);
|
||||||
|
|
||||||
|
shieldDamageTakenKineticTt.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(shield.kinetic.generator)}</div>);
|
||||||
|
shieldDamageTakenKineticTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(shield.kinetic.boosters)}</div>);
|
||||||
|
shieldDamageTakenKineticTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(shield.kinetic.sys)}</div>);
|
||||||
|
|
||||||
|
shieldDamageTakenThermalTt.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(shield.thermal.generator)}</div>);
|
||||||
|
shieldDamageTakenThermalTt.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(shield.thermal.boosters)}</div>);
|
||||||
|
shieldDamageTakenThermalTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(shield.thermal.sys)}</div>);
|
||||||
|
|
||||||
const effectiveAbsoluteShield = shield.total / shield.absolute.total;
|
const effectiveAbsoluteShield = shield.total / shield.absolute.total;
|
||||||
effectiveShieldData.push({ value: Math.round(effectiveAbsoluteShield), label: translate('absolute') });
|
effectiveShieldData.push({ value: Math.round(effectiveAbsoluteShield), label: translate('absolute'), tooltip: effectiveShieldAbsoluteTt });
|
||||||
const effectiveExplosiveShield = shield.total / shield.explosive.total;
|
const effectiveExplosiveShield = shield.total / shield.explosive.total;
|
||||||
effectiveShieldData.push({ value: Math.round(effectiveExplosiveShield), label: translate('explosive') });
|
effectiveShieldData.push({ value: Math.round(effectiveExplosiveShield), label: translate('explosive'), tooltip: effectiveShieldExplosiveTt });
|
||||||
const effectiveKineticShield = shield.total / shield.kinetic.total;
|
const effectiveKineticShield = shield.total / shield.kinetic.total;
|
||||||
effectiveShieldData.push({ value: Math.round(effectiveKineticShield), label: translate('kinetic') });
|
effectiveShieldData.push({ value: Math.round(effectiveKineticShield), label: translate('kinetic'), tooltip: effectiveShieldKineticTt });
|
||||||
const effectiveThermalShield = shield.total / shield.thermal.total;
|
const effectiveThermalShield = shield.total / shield.thermal.total;
|
||||||
effectiveShieldData.push({ value: Math.round(effectiveThermalShield), label: translate('thermal') });
|
effectiveShieldData.push({ value: Math.round(effectiveThermalShield), label: translate('thermal'), tooltip: effectiveShieldThermalTt });
|
||||||
|
|
||||||
shieldDamageTakenData.push({ value: Math.round(shield.absolute.total * 100), label: translate('absolute'), tooltip: shieldAbsoluteTooltipDetails });
|
shieldDamageTakenData.push({ value: Math.round(shield.absolute.total * 100), label: translate('absolute'), tooltip: shieldDamageTakenAbsoluteTt });
|
||||||
shieldDamageTakenData.push({ value: Math.round(shield.explosive.total * 100), label: translate('explosive'), tooltip: shieldExplosiveTooltipDetails });
|
shieldDamageTakenData.push({ value: Math.round(shield.explosive.total * 100), label: translate('explosive'), tooltip: shieldDamageTakenExplosiveTt });
|
||||||
shieldDamageTakenData.push({ value: Math.round(shield.kinetic.total * 100), label: translate('kinetic'), tooltip: shieldKineticTooltipDetails });
|
shieldDamageTakenData.push({ value: Math.round(shield.kinetic.total * 100), label: translate('kinetic'), tooltip: shieldDamageTakenKineticTt });
|
||||||
shieldDamageTakenData.push({ value: Math.round(shield.thermal.total * 100), label: translate('thermal'), tooltip: shieldThermalTooltipDetails });
|
shieldDamageTakenData.push({ value: Math.round(shield.thermal.total * 100), label: translate('thermal'), tooltip: shieldDamageTakenThermalTt });
|
||||||
|
|
||||||
maxEffectiveShield = Math.max(shield.total / shield.absolute.max, shield.total / shield.explosive.max, shield.total / shield.kinetic.max, shield.total / shield.thermal.max);
|
maxEffectiveShield = Math.max(shield.total / shield.absolute.max, shield.total / shield.explosive.max, shield.total / shield.kinetic.max, shield.total / shield.thermal.max);
|
||||||
}
|
}
|
||||||
@@ -113,41 +153,62 @@ export default class Defence extends TranslatedComponent {
|
|||||||
armourSourcesData.push({ value: Math.round(armour.bulkheads), label: translate('bulkheads') });
|
armourSourcesData.push({ value: Math.round(armour.bulkheads), label: translate('bulkheads') });
|
||||||
armourSourcesData.push({ value: Math.round(armour.reinforcement), label: translate('reinforcement') });
|
armourSourcesData.push({ value: Math.round(armour.reinforcement), label: translate('reinforcement') });
|
||||||
|
|
||||||
const armourTooltipDetails = [];
|
const armourSourcesTt = [];
|
||||||
if (armour.bulkheads > 0) armourTooltipDetails.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}</div>);
|
const effectiveArmourAbsoluteTt = [];
|
||||||
if (armour.reinforcement > 0) armourTooltipDetails.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}</div>);
|
const effectiveArmourExplosiveTt = [];
|
||||||
|
const effectiveArmourKineticTt = [];
|
||||||
|
const effectiveArmourThermalTt = [];
|
||||||
|
if (armour.bulkheads > 0) {
|
||||||
|
armourSourcesTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}</div>);
|
||||||
|
effectiveArmourAbsoluteTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}</div>);
|
||||||
|
effectiveArmourExplosiveTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}</div>);
|
||||||
|
effectiveArmourKineticTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}</div>);
|
||||||
|
effectiveArmourThermalTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}</div>);
|
||||||
|
if (armour.reinforcement > 0) {
|
||||||
|
armourSourcesTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}</div>);
|
||||||
|
effectiveArmourAbsoluteTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}</div>);
|
||||||
|
effectiveArmourExplosiveTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}</div>);
|
||||||
|
effectiveArmourKineticTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}</div>);
|
||||||
|
effectiveArmourThermalTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.int(armour.reinforcement)}</div>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const armourAbsoluteTooltipDetails = [];
|
const rawArmour = armour.bulkheads + armour.reinforcement;
|
||||||
armourAbsoluteTooltipDetails.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.absolute.bulkheads)}</div>);
|
|
||||||
armourAbsoluteTooltipDetails.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.absolute.reinforcement)}</div>);
|
|
||||||
|
|
||||||
const armourExplosiveTooltipDetails = [];
|
const armourDamageTakenTt = [];
|
||||||
armourExplosiveTooltipDetails.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.explosive.bulkheads)}</div>);
|
armourDamageTakenTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.absolute.bulkheads)}</div>);
|
||||||
armourExplosiveTooltipDetails.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.explosive.reinforcement)}</div>);
|
armourDamageTakenTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.absolute.reinforcement)}</div>);
|
||||||
|
|
||||||
const armourKineticTooltipDetails = [];
|
const armourDamageTakenExplosiveTt = [];
|
||||||
armourKineticTooltipDetails.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.kinetic.bulkheads)}</div>);
|
armourDamageTakenExplosiveTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.explosive.bulkheads)}</div>);
|
||||||
armourKineticTooltipDetails.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.kinetic.reinforcement)}</div>);
|
armourDamageTakenExplosiveTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.explosive.reinforcement)}</div>);
|
||||||
|
if (armour.explosive.bulkheads * armour.explosive.reinforcement != 1) effectiveArmourExplosiveTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / (armour.explosive.bulkheads * armour.explosive.reinforcement) - rawArmour)}</div>);
|
||||||
|
|
||||||
const armourThermalTooltipDetails = [];
|
const armourDamageTakenKineticTt = [];
|
||||||
armourThermalTooltipDetails.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.thermal.bulkheads)}</div>);
|
armourDamageTakenKineticTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.kinetic.bulkheads)}</div>);
|
||||||
armourThermalTooltipDetails.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.thermal.reinforcement)}</div>);
|
armourDamageTakenKineticTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.kinetic.reinforcement)}</div>);
|
||||||
|
if (armour.kinetic.bulkheads * armour.kinetic.reinforcement != 1) effectiveArmourKineticTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / (armour.kinetic.bulkheads * armour.kinetic.reinforcement) - rawArmour)}</div>);
|
||||||
|
|
||||||
|
const armourDamageTakenThermalTt = [];
|
||||||
|
armourDamageTakenThermalTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.thermal.bulkheads)}</div>);
|
||||||
|
armourDamageTakenThermalTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.thermal.reinforcement)}</div>);
|
||||||
|
if (armour.thermal.bulkheads * armour.thermal.reinforcement != 1) effectiveArmourThermalTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / (armour.thermal.bulkheads * armour.thermal.reinforcement) - rawArmour)}</div>);
|
||||||
|
|
||||||
const effectiveArmourData = [];
|
const effectiveArmourData = [];
|
||||||
const effectiveAbsoluteArmour = armour.total / armour.absolute.total;
|
const effectiveAbsoluteArmour = armour.total / armour.absolute.total;
|
||||||
effectiveArmourData.push({ value: Math.round(effectiveAbsoluteArmour), label: translate('absolute') });
|
effectiveArmourData.push({ value: Math.round(effectiveAbsoluteArmour), label: translate('absolute'), tooltip: effectiveArmourAbsoluteTt });
|
||||||
const effectiveExplosiveArmour = armour.total / armour.explosive.total;
|
const effectiveExplosiveArmour = armour.total / armour.explosive.total;
|
||||||
effectiveArmourData.push({ value: Math.round(effectiveExplosiveArmour), label: translate('explosive') });
|
effectiveArmourData.push({ value: Math.round(effectiveExplosiveArmour), label: translate('explosive'), tooltip: effectiveArmourExplosiveTt });
|
||||||
const effectiveKineticArmour = armour.total / armour.kinetic.total;
|
const effectiveKineticArmour = armour.total / armour.kinetic.total;
|
||||||
effectiveArmourData.push({ value: Math.round(effectiveKineticArmour), label: translate('kinetic') });
|
effectiveArmourData.push({ value: Math.round(effectiveKineticArmour), label: translate('kinetic'), tooltip: effectiveArmourKineticTt });
|
||||||
const effectiveThermalArmour = armour.total / armour.thermal.total;
|
const effectiveThermalArmour = armour.total / armour.thermal.total;
|
||||||
effectiveArmourData.push({ value: Math.round(effectiveThermalArmour), label: translate('thermal') });
|
effectiveArmourData.push({ value: Math.round(effectiveThermalArmour), label: translate('thermal'), tooltip: effectiveArmourThermalTt });
|
||||||
|
|
||||||
const armourDamageTakenData = [];
|
const armourDamageTakenData = [];
|
||||||
armourDamageTakenData.push({ value: Math.round(armour.absolute.total * 100), label: translate('absolute'), tooltip: armourAbsoluteTooltipDetails });
|
armourDamageTakenData.push({ value: Math.round(armour.absolute.total * 100), label: translate('absolute'), tooltip: armourDamageTakenTt });
|
||||||
armourDamageTakenData.push({ value: Math.round(armour.explosive.total * 100), label: translate('explosive'), tooltip: armourExplosiveTooltipDetails });
|
armourDamageTakenData.push({ value: Math.round(armour.explosive.total * 100), label: translate('explosive'), tooltip: armourDamageTakenExplosiveTt });
|
||||||
armourDamageTakenData.push({ value: Math.round(armour.kinetic.total * 100), label: translate('kinetic'), tooltip: armourKineticTooltipDetails });
|
armourDamageTakenData.push({ value: Math.round(armour.kinetic.total * 100), label: translate('kinetic'), tooltip: armourDamageTakenKineticTt });
|
||||||
armourDamageTakenData.push({ value: Math.round(armour.thermal.total * 100), label: translate('thermal'), tooltip: armourThermalTooltipDetails });
|
armourDamageTakenData.push({ value: Math.round(armour.thermal.total * 100), label: translate('thermal'), tooltip: armourDamageTakenThermalTt });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span id='defence'>
|
<span id='defence'>
|
||||||
@@ -155,7 +216,7 @@ export default class Defence extends TranslatedComponent {
|
|||||||
<div className='group quarter'>
|
<div className='group quarter'>
|
||||||
<h2>{translate('shield metrics')}</h2>
|
<h2>{translate('shield metrics')}</h2>
|
||||||
<br/>
|
<br/>
|
||||||
<h2 onMouseOver={termtip.bind(null, <div>{shieldTooltipDetails}</div>)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw shield strength')}<br/>{formats.int(shield.total)}{units.MJ}</h2>
|
<h2 onMouseOver={termtip.bind(null, <div>{shieldSourcesTt}</div>)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw shield strength')}<br/>{formats.int(shield.total)}{units.MJ}</h2>
|
||||||
<h2 onMouseOver={termtip.bind(null, translate('TT_TIME_TO_LOSE_SHIELDS'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_LOSE_SHIELDS')}<br/>{shielddamage.totalsdps == 0 ? translate('ever') : formats.time(Calc.timeToDeplete(shield.total, shielddamage.totalsdps, shielddamage.totalseps, pd.getWeaponsCapacity(), pd.getWeaponsRechargeRate() * opponentWep / 4))}</h2>
|
<h2 onMouseOver={termtip.bind(null, translate('TT_TIME_TO_LOSE_SHIELDS'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_LOSE_SHIELDS')}<br/>{shielddamage.totalsdps == 0 ? translate('ever') : formats.time(Calc.timeToDeplete(shield.total, shielddamage.totalsdps, shielddamage.totalseps, pd.getWeaponsCapacity(), pd.getWeaponsRechargeRate() * opponentWep / 4))}</h2>
|
||||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SG_RECOVER'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_RECOVER_SHIELDS')}<br/>{shield.recover === Math.Inf ? translate('never') : formats.time(shield.recover)}</h2>
|
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SG_RECOVER'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_RECOVER_SHIELDS')}<br/>{shield.recover === Math.Inf ? translate('never') : formats.time(shield.recover)}</h2>
|
||||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SG_RECHARGE'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_RECHARGE_SHIELDS')}<br/>{shield.recharge === Math.Inf ? translate('never') : formats.time(shield.recharge)}</h2>
|
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SG_RECHARGE'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_RECHARGE_SHIELDS')}<br/>{shield.recharge === Math.Inf ? translate('never') : formats.time(shield.recharge)}</h2>
|
||||||
@@ -176,7 +237,7 @@ export default class Defence extends TranslatedComponent {
|
|||||||
|
|
||||||
<div className='group quarter'>
|
<div className='group quarter'>
|
||||||
<h2>{translate('armour metrics')}</h2>
|
<h2>{translate('armour metrics')}</h2>
|
||||||
<h2 onMouseOver={termtip.bind(null, <div>{armourTooltipDetails}</div>)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw armour strength')}<br/>{formats.int(armour.total)}</h2>
|
<h2 onMouseOver={termtip.bind(null, <div>{armourSourcesTt}</div>)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw armour strength')}<br/>{formats.int(armour.total)}</h2>
|
||||||
<h2 onMouseOver={termtip.bind(null, translate('TT_TIME_TO_LOSE_ARMOUR'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_LOSE_ARMOUR')}<br/>{armourdamage.totalsdps == 0 ? translate('ever') : formats.time(Calc.timeToDeplete(armour.total, armourdamage.totalsdps, armourdamage.totalseps, pd.getWeaponsCapacity(), pd.getWeaponsRechargeRate() * opponentWep / 4))}</h2>
|
<h2 onMouseOver={termtip.bind(null, translate('TT_TIME_TO_LOSE_ARMOUR'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_LOSE_ARMOUR')}<br/>{armourdamage.totalsdps == 0 ? translate('ever') : formats.time(Calc.timeToDeplete(armour.total, armourdamage.totalsdps, armourdamage.totalseps, pd.getWeaponsCapacity(), pd.getWeaponsRechargeRate() * opponentWep / 4))}</h2>
|
||||||
<h2 onMouseOver={termtip.bind(null, translate('TT_MODULE_ARMOUR'))} onMouseOut={tooltip.bind(null, null)}>{translate('raw module armour')}<br/>{formats.int(armour.modulearmour)}</h2>
|
<h2 onMouseOver={termtip.bind(null, translate('TT_MODULE_ARMOUR'))} onMouseOut={tooltip.bind(null, null)}>{translate('raw module armour')}<br/>{formats.int(armour.modulearmour)}</h2>
|
||||||
<h2 onMouseOver={termtip.bind(null, translate('TT_MODULE_PROTECTION_EXTERNAL'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_MODULE_PROTECTION_EXTERNAL')}<br/>{formats.pct1(armour.moduleprotection / 2)}</h2>
|
<h2 onMouseOver={termtip.bind(null, translate('TT_MODULE_PROTECTION_EXTERNAL'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_MODULE_PROTECTION_EXTERNAL')}<br/>{formats.pct1(armour.moduleprotection / 2)}</h2>
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ export default class HardpointSlot extends Slot {
|
|||||||
{ m.getFalloff() ? <div className={'l'}>{translate('falloff')} {formats.round(m.getFalloff() / 1000)}{u.km}</div> : null }
|
{ m.getFalloff() ? <div className={'l'}>{translate('falloff')} {formats.round(m.getFalloff() / 1000)}{u.km}</div> : null }
|
||||||
{ m.getShieldBoost() ? <div className={'l'}>+{formats.pct1(m.getShieldBoost())}</div> : null }
|
{ m.getShieldBoost() ? <div className={'l'}>+{formats.pct1(m.getShieldBoost())}</div> : null }
|
||||||
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.int(m.getClip())}/{formats.int(m.getAmmo())}</div> : null }
|
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.int(m.getClip())}/{formats.int(m.getAmmo())}</div> : null }
|
||||||
|
{ m.getReload() ? <div className={'l'}>{translate('reload')}: {formats.round(m.getReload())}{u.s}</div> : null }
|
||||||
{ m.getShotSpeed() ? <div className={'l'}>{translate('shotspeed')}: {formats.int(m.getShotSpeed())}{u.mps}</div> : null }
|
{ m.getShotSpeed() ? <div className={'l'}>{translate('shotspeed')}: {formats.int(m.getShotSpeed())}{u.mps}</div> : null }
|
||||||
{ m.getPiercing() ? <div className={'l'}>{translate('piercing')}: {formats.int(m.getPiercing())}</div> : null }
|
{ m.getPiercing() ? <div className={'l'}>{translate('piercing')}: {formats.int(m.getPiercing())}</div> : null }
|
||||||
{ m.getJitter() ? <div className={'l'}>{translate('jitter')}: {formats.f2(m.getJitter())}°</div> : null }
|
{ m.getJitter() ? <div className={'l'}>{translate('jitter')}: {formats.f2(m.getJitter())}°</div> : null }
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ export default class Modification extends TranslatedComponent {
|
|||||||
this.setState({ value });
|
this.setState({ value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when an update to slider value is finished i.e. when losing focus
|
||||||
|
*/
|
||||||
_updateFinished() {
|
_updateFinished() {
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,8 +230,8 @@ export default class Offence extends TranslatedComponent {
|
|||||||
<thead>
|
<thead>
|
||||||
<tr className='main'>
|
<tr className='main'>
|
||||||
<th rowSpan='2' className='sortable' onClick={sortOrder.bind(this, 'n')}>{translate('weapon')}</th>
|
<th rowSpan='2' className='sortable' onClick={sortOrder.bind(this, 'n')}>{translate('weapon')}</th>
|
||||||
<th colSpan='2'>{translate('opponent\`s shields')}</th>
|
<th colSpan='2'>{translate('opponent\'s shields')}</th>
|
||||||
<th colSpan='2'>{translate('opponent\`s armour')}</th>
|
<th colSpan='2'>{translate('opponent\'s armour')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th className='lft sortable' onMouseOver={termtip.bind(null, 'TT_EFFECTIVE_SDPS_SHIELDS')} onMouseOut={tooltip.bind(null, null)} onClick={sortOrder.bind(this, 'esdpss')}>{'sdps'}</th>
|
<th className='lft sortable' onMouseOver={termtip.bind(null, 'TT_EFFECTIVE_SDPS_SHIELDS')} onMouseOut={tooltip.bind(null, null)} onClick={sortOrder.bind(this, 'esdpss')}>{'sdps'}</th>
|
||||||
|
|||||||
@@ -85,12 +85,12 @@ export default class OutfittingSubpages extends TranslatedComponent {
|
|||||||
_profilesTab() {
|
_profilesTab() {
|
||||||
const { ship, opponent, cargo, fuel, eng, boost, engagementRange, opponentSys } = this.props;
|
const { ship, opponent, cargo, fuel, eng, boost, engagementRange, opponentSys } = this.props;
|
||||||
const { translate } = this.context.language;
|
const { translate } = this.context.language;
|
||||||
let realBoost = boost && ship.canBoost();
|
let realBoost = boost && ship.canBoost(cargo, fuel);
|
||||||
Persist.setOutfittingTab('profiles');
|
Persist.setOutfittingTab('profiles');
|
||||||
|
|
||||||
const engineProfileMarker = `${ship.toString()}:${cargo}:${fuel}:${eng}:${realBoost}`;
|
const engineProfileMarker = `${ship.toString()}:${cargo}:${fuel}:${eng}:${realBoost}`;
|
||||||
const fsdProfileMarker = `${ship.toString()}:${cargo}:${fuel}`;
|
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}`;
|
const damageMarker = `${ship.toString()}:${opponent.toString()}:${engagementRange}:${opponentSys}`;
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
ship: React.PropTypes.object.isRequired,
|
ship: React.PropTypes.object.isRequired,
|
||||||
|
cargo: React.PropTypes.number.isRequired,
|
||||||
|
fuel: React.PropTypes.number.isRequired,
|
||||||
marker: React.PropTypes.string.isRequired,
|
marker: React.PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
* @return {React.Component} Summary table
|
* @return {React.Component} Summary table
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const { ship } = this.props;
|
const { ship, cargo, fuel } = 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;
|
||||||
@@ -31,9 +33,9 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
const sgClassNames = cn({ warning: shieldGenerator && !ship.shield, muted: !shieldGenerator });
|
const sgClassNames = cn({ warning: shieldGenerator && !ship.shield, muted: !shieldGenerator });
|
||||||
const sgTooltip = shieldGenerator ? 'TT_SUMMARY_SHIELDS' : 'TT_SUMMARY_SHIELDS_NONFUNCTIONAL';
|
const sgTooltip = shieldGenerator ? 'TT_SUMMARY_SHIELDS' : 'TT_SUMMARY_SHIELDS_NONFUNCTIONAL';
|
||||||
const timeToDrain = Calc.timeToDrainWep(ship, 4);
|
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 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';
|
const boostTooltip = canBoost ? 'TT_SUMMARY_BOOST' : canThrust ? 'TT_SUMMARY_BOOST_NONFUNCTIONAL' : 'TT_SUMMARY_SPEED_NONFUNCTIONAL';
|
||||||
|
|
||||||
return <div id='summary'>
|
return <div id='summary'>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import TranslatedComponent from './TranslatedComponent';
|
|||||||
import { diffDetails } from '../utils/SlotFunctions';
|
import { diffDetails } from '../utils/SlotFunctions';
|
||||||
import AvailableModulesMenu from './AvailableModulesMenu';
|
import AvailableModulesMenu from './AvailableModulesMenu';
|
||||||
import ModificationsMenu from './ModificationsMenu';
|
import ModificationsMenu from './ModificationsMenu';
|
||||||
|
import * as ModuleUtils from '../shipyard/ModuleUtils';
|
||||||
import { ListModifications, Modified } from './SvgIcons';
|
import { ListModifications, Modified } from './SvgIcons';
|
||||||
import { Modifications } from 'coriolis-data/dist';
|
import { Modifications } from 'coriolis-data/dist';
|
||||||
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
||||||
@@ -82,7 +83,7 @@ export default class StandardSlot extends TranslatedComponent {
|
|||||||
menu = <AvailableModulesMenu
|
menu = <AvailableModulesMenu
|
||||||
className='standard'
|
className='standard'
|
||||||
modules={modules}
|
modules={modules}
|
||||||
shipMass={ship.ladenMass}
|
shipMass={ModuleUtils.isShieldGenerator(m.grp) ? ship.hullMass : ship.unladenMass}
|
||||||
m={m}
|
m={m}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
warning={warning}
|
warning={warning}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
* @return {Array} Array of Slots
|
* @return {Array} Array of Slots
|
||||||
*/
|
*/
|
||||||
_getSlots() {
|
_getSlots() {
|
||||||
let { ship, currentMenu } = this.props;
|
let { ship, currentMenu, cargo, fuel } = this.props;
|
||||||
let slots = new Array(8);
|
let slots = new Array(8);
|
||||||
let open = this._openMenu;
|
let open = this._openMenu;
|
||||||
let select = this._selectModule;
|
let select = this._selectModule;
|
||||||
@@ -135,7 +135,7 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
selected={currentMenu == st[1]}
|
selected={currentMenu == st[1]}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
warning={m => 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)}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -267,15 +267,29 @@ export default class OutfittingPage extends Page {
|
|||||||
*/
|
*/
|
||||||
_opponentUpdated(opponent, opponentBuild) {
|
_opponentUpdated(opponent, opponentBuild) {
|
||||||
const opponentShip = new Ship(opponent, Ships[opponent].properties, Ships[opponent].slots);
|
const opponentShip = new Ship(opponent, Ships[opponent].properties, Ships[opponent].slots);
|
||||||
|
let opponentSys = this.state.opponentSys;
|
||||||
|
let opponentEng = this.state.opponentEng;
|
||||||
|
let opponentWep = this.state.opponentWep;
|
||||||
if (opponentBuild && Persist.getBuild(opponent, opponentBuild)) {
|
if (opponentBuild && Persist.getBuild(opponent, opponentBuild)) {
|
||||||
// Ship is a particular build
|
// Ship is a particular build
|
||||||
opponentShip.buildFrom(Persist.getBuild(opponent, opponentBuild));
|
opponentShip.buildFrom(Persist.getBuild(opponent, opponentBuild));
|
||||||
|
// Set pips for opponent
|
||||||
|
const opponentParts = Persist.getBuild(opponent, opponentBuild).split('.');
|
||||||
|
if (opponentParts.length >= 5) {
|
||||||
|
const opponentControl = LZString.decompressFromBase64(Utils.fromUrlSafe(opponentParts[4])).split('/');
|
||||||
|
opponentSys = parseFloat(opponentControl[0]);
|
||||||
|
opponentEng = parseFloat(opponentControl[1]);
|
||||||
|
opponentWep = parseFloat(opponentControl[2]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Ship is a stock build
|
// Ship is a stock build
|
||||||
opponentShip.buildWith(Ships[opponent].defaults);
|
opponentShip.buildWith(Ships[opponent].defaults);
|
||||||
|
opponentSys = 2;
|
||||||
|
opponentEng = 2;
|
||||||
|
opponentWep = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ opponent: opponentShip, opponentBuild }, () => this._updateRouteOnControlChange());
|
this.setState({ opponent: opponentShip, opponentBuild, opponentSys, opponentEng, opponentWep }, () => this._updateRouteOnControlChange());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -531,11 +545,11 @@ export default class OutfittingPage extends Page {
|
|||||||
const _pStr = `${ship.getPowerEnabledString()}${ship.getPowerPrioritiesString()}`;
|
const _pStr = `${ship.getPowerEnabledString()}${ship.getPowerPrioritiesString()}`;
|
||||||
const _mStr = ship.getModificationsString();
|
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 internalSlotMarker = `${ship.name}${_iStr}${_pStr}${_mStr}`;
|
||||||
const hardpointsSlotMarker = `${ship.name}${_hStr}${_pStr}${_mStr}`;
|
const hardpointsSlotMarker = `${ship.name}${_hStr}${_pStr}${_mStr}`;
|
||||||
const boostMarker = `${ship.canBoost()}`;
|
const boostMarker = `${ship.canBoost(cargo, fuel)}`;
|
||||||
const shipSummaryMarker = `${ship.name}${_sStr}${_iStr}${_hStr}${_pStr}${_mStr}`;
|
const shipSummaryMarker = `${ship.name}${_sStr}${_iStr}${_hStr}${_pStr}${_mStr}${ship.ladenMass}${ship.cargo}${ship.fuel}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id='outfit' className={'page'} style={{ fontSize: (sizeRatio * 0.9) + 'em' }}>
|
<div id='outfit' className={'page'} style={{ fontSize: (sizeRatio * 0.9) + 'em' }}>
|
||||||
@@ -571,8 +585,8 @@ export default class OutfittingPage extends Page {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main tables */}
|
{/* Main tables */}
|
||||||
<ShipSummaryTable ship={ship} marker={shipSummaryMarker} />
|
<ShipSummaryTable ship={ship} fuel={fuel} cargo={cargo} marker={shipSummaryMarker} />
|
||||||
<StandardSlotSection ship={ship} code={standardSlotMarker} onChange={shipUpdated} currentMenu={menu} />
|
<StandardSlotSection ship={ship} fuel={fuel} cargo={cargo} code={standardSlotMarker} onChange={shipUpdated} currentMenu={menu} />
|
||||||
<InternalSlotSection ship={ship} code={internalSlotMarker} onChange={shipUpdated} currentMenu={menu} />
|
<InternalSlotSection ship={ship} code={internalSlotMarker} onChange={shipUpdated} currentMenu={menu} />
|
||||||
<HardpointSlotSection ship={ship} code={hardpointsSlotMarker} onChange={shipUpdated} currentMenu={menu} />
|
<HardpointSlotSection ship={ship} code={hardpointsSlotMarker} onChange={shipUpdated} currentMenu={menu} />
|
||||||
<UtilitySlotSection ship={ship} code={hardpointsSlotMarker} onChange={shipUpdated} currentMenu={menu} />
|
<UtilitySlotSection ship={ship} code={hardpointsSlotMarker} onChange={shipUpdated} currentMenu={menu} />
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ export function shieldMetrics(ship, sys) {
|
|||||||
|
|
||||||
// Calculate diminishing returns for boosters
|
// Calculate diminishing returns for boosters
|
||||||
// Diminishing returns not currently in-game
|
// Diminishing returns not currently in-game
|
||||||
//boost = Math.min(boost, (1 - Math.pow(Math.E, -0.7 * boost)) * 2.5);
|
// boost = Math.min(boost, (1 - Math.pow(Math.E, -0.7 * boost)) * 2.5);
|
||||||
|
|
||||||
// Remove base shield generator strength
|
// Remove base shield generator strength
|
||||||
boost -= 1;
|
boost -= 1;
|
||||||
|
|||||||
@@ -162,14 +162,6 @@ export default class Module {
|
|||||||
return result;
|
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
|
* Get the power generation of this module, taking in to account modifications
|
||||||
* @return {Number} the power generation of this module
|
* @return {Number} the power generation of this module
|
||||||
|
|||||||
@@ -123,19 +123,23 @@ export default class Ship {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Can the ship thrust/move
|
* 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
|
* @return {[type]} True if thrusters operational
|
||||||
*/
|
*/
|
||||||
canThrust() {
|
canThrust(cargo, fuel) {
|
||||||
return this.getSlotStatus(this.standard[1]) == 3 && // Thrusters are powered
|
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
|
* 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
|
* @return {[type]} True if boost capable
|
||||||
*/
|
*/
|
||||||
canBoost() {
|
canBoost(cargo, fuel) {
|
||||||
return this.canThrust() && // Thrusters operational
|
return this.canThrust(cargo, fuel) && // Thrusters operational
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1185,7 +1189,7 @@ export default class Ship {
|
|||||||
updateMovement() {
|
updateMovement() {
|
||||||
this.speeds = Calc.speed(this.unladenMass + this.fuelCapacity, this.speed, this.standard[1].m, this.pipSpeed);
|
this.speeds = Calc.speed(this.unladenMass + this.fuelCapacity, this.speed, this.standard[1].m, this.pipSpeed);
|
||||||
this.topSpeed = this.speeds[4];
|
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.pitches = Calc.pitch(this.unladenMass + this.fuelCapacity, this.pitch, this.standard[1].m, this.pipSpeed);
|
||||||
this.topPitch = this.pitches[4];
|
this.topPitch = this.pitches[4];
|
||||||
@@ -1204,53 +1208,13 @@ export default class Ship {
|
|||||||
* @return {this} The ship instance (for chaining operations)
|
* @return {this} The ship instance (for chaining operations)
|
||||||
*/
|
*/
|
||||||
recalculateShield() {
|
recalculateShield() {
|
||||||
let shield = 0;
|
// Obtain shield metrics with 0 pips to sys (parts affected by SYS aren't used here)
|
||||||
let shieldBoost = 1;
|
const metrics = Calc.shieldMetrics(this, 0);
|
||||||
let shieldExplRes = null;
|
|
||||||
let shieldKinRes = null;
|
|
||||||
let shieldThermRes = null;
|
|
||||||
let shieldExplDRStart = null;
|
|
||||||
let shieldExplDREnd = null;
|
|
||||||
let shieldKinDRStart = null;
|
|
||||||
let shieldKinDREnd = null;
|
|
||||||
let shieldThermDRStart = null;
|
|
||||||
let shieldThermDREnd = null;
|
|
||||||
|
|
||||||
const sgSlot = this.findInternalByGroup('sg');
|
|
||||||
if (sgSlot && sgSlot.enabled) {
|
|
||||||
// Shield from generator
|
|
||||||
shield = Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sgSlot.m, 1);
|
|
||||||
shieldExplRes = 1 - sgSlot.m.getExplosiveResistance();
|
|
||||||
shieldExplDRStart = shieldExplRes * 0.7;
|
|
||||||
shieldExplDREnd = 0;
|
|
||||||
shieldKinRes = 1 - sgSlot.m.getKineticResistance();
|
|
||||||
shieldKinDRStart = shieldKinRes * 0.7;
|
|
||||||
shieldKinDREnd = 0;
|
|
||||||
shieldThermRes = 1 - sgSlot.m.getThermalResistance();
|
|
||||||
shieldThermDRStart = shieldThermRes * 0.7;
|
|
||||||
shieldThermDREnd = 0;
|
|
||||||
|
|
||||||
// Shield from boosters
|
|
||||||
for (let slot of this.hardpoints) {
|
|
||||||
if (slot.enabled && slot.m && slot.m.grp == 'sb') {
|
|
||||||
shieldBoost += slot.m.getShieldBoost();
|
|
||||||
shieldExplRes *= (1 - slot.m.getExplosiveResistance());
|
|
||||||
shieldKinRes *= (1 - slot.m.getKineticResistance());
|
|
||||||
shieldThermRes *= (1 - slot.m.getThermalResistance());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We apply diminishing returns to the boosted value
|
|
||||||
shieldBoost = Math.min(shieldBoost, (1 - Math.pow(Math.E, -0.7 * shieldBoost)) * 2.5);
|
|
||||||
|
|
||||||
shield = shield * shieldBoost;
|
|
||||||
|
|
||||||
this.shield = shield;
|
|
||||||
this.shieldExplRes = shieldExplRes ? 1 - this.diminishingReturns(shieldExplRes, shieldExplDREnd, shieldExplDRStart) : null;
|
|
||||||
this.shieldKinRes = shieldKinRes ? 1 - this.diminishingReturns(shieldKinRes, shieldKinDREnd, shieldKinDRStart) : null;
|
|
||||||
this.shieldThermRes = shieldThermRes ? 1 - this.diminishingReturns(shieldThermRes, shieldThermDREnd, shieldThermDRStart) : null;
|
|
||||||
|
|
||||||
|
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;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1679,11 +1643,11 @@ export default class Ship {
|
|||||||
let mass = this.hullMass;
|
let mass = this.hullMass;
|
||||||
mass += m.pp ? m.pp.getMass() : ModuleUtils.standard(0, '2D').getMass();
|
mass += m.pp ? m.pp.getMass() : ModuleUtils.standard(0, '2D').getMass();
|
||||||
mass += m.th ? m.th.getMass() : ModuleUtils.standard(1, '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.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.pd ? m.pd.getMass() : ModuleUtils.standard(4, '1D').getMass();
|
||||||
mass += m.s ? m.s.getMass() : ModuleUtils.standard(5, this.standard[5].maxClass + 'D').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%
|
||||||
mass += m.ft ? m.ft.getMass() : ModuleUtils.standard(6, '1C').getMass();
|
// Ignore fuel tank as it could be empty
|
||||||
return mass;
|
return mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Modifications, Modules, Ships } from 'coriolis-data/dist';
|
|||||||
import Module from '../shipyard/Module';
|
import Module from '../shipyard/Module';
|
||||||
import Ship from '../shipyard/Ship';
|
import Ship from '../shipyard/Ship';
|
||||||
import { getBlueprint } from '../utils/BlueprintFunctions';
|
import { getBlueprint } from '../utils/BlueprintFunctions';
|
||||||
|
import * as ModuleUtils from '../shipyard/ModuleUtils';
|
||||||
|
|
||||||
// mapping from fd's ship model names to coriolis'
|
// mapping from fd's ship model names to coriolis'
|
||||||
const SHIP_FD_NAME_TO_CORIOLIS_NAME = {
|
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.
|
// 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
|
// 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')) {
|
if (module.getModValue('explres')) {
|
||||||
module.setModValue('explres', ((1 - (1 - module.explres) * (1 + module.getModValue('explres') / 10000)) - module.explres) * 10000);
|
module.setModValue('explres', ((1 - (1 - module.explres) * (1 + module.getModValue('explres') / 10000)) - module.explres) * 10000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
import { isShieldGenerator } from '../shipyard/ModuleUtils';
|
|
||||||
import Module from '../shipyard/Module';
|
import Module from '../shipyard/Module';
|
||||||
import { Infinite } from '../components/SvgIcons';
|
import { Infinite } from '../components/SvgIcons';
|
||||||
import Persist from '../stores/Persist';
|
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
|
* 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;
|
let mmDps = mm ? mm.getDps() || 0 : 0;
|
||||||
if (mDps && mDps != mmDps) propDiffs.push(<div key='dps'>{translate('dps')}: <span className={diffClass(mmDps, mDps, true)}>{diff(formats.round, mDps, mmDps)}</span></div>);
|
if (mDps && mDps != mmDps) propDiffs.push(<div key='dps'>{translate('dps')}: <span className={diffClass(mmDps, mDps, true)}>{diff(formats.round, mDps, mmDps)}</span></div>);
|
||||||
|
|
||||||
let mAffectsShield = isShieldGenerator(m.grp) || m.grp == 'sb';
|
let mAffectsShield = ModuleUtils.isShieldGenerator(m.grp) || m.grp == 'sb';
|
||||||
let mmAffectsShield = isShieldGenerator(mm ? mm.grp : null) || mm && mm.grp == 'sb';
|
let mmAffectsShield = mm ? ModuleUtils.isShieldGenerator(m.grp) || mm.grp == 'sb' : false;
|
||||||
if (mAffectsShield || mmAffectsShield) {
|
if (mAffectsShield || mmAffectsShield) {
|
||||||
let shield = this.calcShieldStrengthWith(); // Get shield strength regardless of slot active / inactive
|
let shield = this.calcShieldStrengthWith(); // Get shield strength regardless of slot active / inactive
|
||||||
let newShield = 0;
|
let newShield = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user